| 2043 | } |
| 2044 | |
| 2045 | bool Core::doSdlInputEvent(SDL_Event* ev) |
| 2046 | { |
| 2047 | // this should only ever be called from the render thread |
| 2048 | assert(std::this_thread::get_id() == df_render_thread); |
| 2049 | |
| 2050 | static std::map<int, bool> hotkey_states; |
| 2051 | |
| 2052 | // do NOT process events before we are ready. |
| 2053 | if (!started || !ev) |
| 2054 | return false; |
| 2055 | |
| 2056 | if (ev->type == SDL_WINDOWEVENT && ev->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) { |
| 2057 | // clear modstate when gaining focus in case alt-tab was used when |
| 2058 | // losing focus and modstate is now incorrectly set |
| 2059 | modstate = 0; |
| 2060 | return false; |
| 2061 | } |
| 2062 | |
| 2063 | if (ev->type == SDL_KEYDOWN || ev->type == SDL_KEYUP) { |
| 2064 | auto &ke = ev->key; |
| 2065 | auto &sym = ke.keysym.sym; |
| 2066 | |
| 2067 | if (sym == SDLK_LSHIFT || sym == SDLK_RSHIFT) |
| 2068 | modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_SHIFT : modstate & ~DFH_MOD_SHIFT; |
| 2069 | else if (sym == SDLK_LCTRL || sym == SDLK_RCTRL) |
| 2070 | modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_CTRL : modstate & ~DFH_MOD_CTRL; |
| 2071 | else if (sym == SDLK_LALT || sym == SDLK_RALT) |
| 2072 | modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_ALT : modstate & ~DFH_MOD_ALT; |
| 2073 | else if (sym == SDLK_LGUI || sym == SDLK_RGUI) // Renamed to LMETA/RMETA in SDL3 |
| 2074 | modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_SUPER : modstate & ~DFH_MOD_SUPER; |
| 2075 | else if (ke.state == SDL_PRESSED && !hotkey_states[sym]) |
| 2076 | { |
| 2077 | // the check against hotkey_states[sym] ensures we only process keybindings once per keypress |
| 2078 | DEBUG(keybinding).print("key down: sym={}, char={}\n", sym, static_cast<char>(sym)); |
| 2079 | if ((hotkey_mgr->handleKeybind(sym, modstate))) { |
| 2080 | hotkey_states[sym] = true; |
| 2081 | if (modstate & (DFH_MOD_CTRL | DFH_MOD_ALT)) { |
| 2082 | DEBUG(keybinding).print("modifier key detected; not inhibiting SDL key down event\n"); |
| 2083 | return false; |
| 2084 | } |
| 2085 | DEBUG(keybinding).print("{}inhibiting SDL key down event\n", |
| 2086 | suppress_duplicate_keyboard_events ? "" : "not "); |
| 2087 | return suppress_duplicate_keyboard_events; |
| 2088 | } |
| 2089 | } |
| 2090 | else if (ke.state == SDL_RELEASED) |
| 2091 | { |
| 2092 | DEBUG(keybinding).print("key up: sym={}, char={}\n", sym, static_cast<char>(sym)); |
| 2093 | hotkey_states[sym] = false; |
| 2094 | } |
| 2095 | } else if (ev->type == SDL_MOUSEBUTTONDOWN) { |
| 2096 | auto &but = ev->button; |
| 2097 | DEBUG(keybinding).print("mouse button down: button={}\n", but.button); |
| 2098 | // don't mess with the first three buttons, which are critical elements of DF's control scheme |
| 2099 | if (but.button > 3) { |
| 2100 | // We represent mouse buttons as a negative number, permitting buttons 4-15 |
| 2101 | SDL_Keycode sym = -but.button; |
| 2102 | if (sym >= -15 && sym <= -4 && hotkey_mgr->handleKeybind(sym, modstate)) |
nothing calls this directly
no test coverage detected