/** ** Handle interactive input event. ** ** @param callbacks Callback structure for events. ** @param event SDL event structure pointer. */ static void SdlDoEvent(const EventCallback &callbacks, SDL_Event &event) { #if (defined(USE_OPENGL) || defined(USE_GLES)) // Scale mouse-coordinates to viewport if (ZoomNoResize && (event.type & (SDL_MOUSEBUTTONUP | SDL_MOUSEBUTTONDOWN | SDL_MOUSEMOTION))) { event.button.x = (Uint16)floorf(event.button.x * float(Video.Width) / Video.ViewportWidth); event.button.y = (Uint16)floorf(event.button.y * float(Video.Height) / Video.ViewportHeight); } #endif switch (event.type) { case SDL_MOUSEBUTTONDOWN: InputMouseButtonPress(callbacks, SDL_GetTicks(), event.button.button); break; case SDL_MOUSEBUTTONUP: InputMouseButtonRelease(callbacks, SDL_GetTicks(), event.button.button); break; // FIXME: check if this is only useful for the cursor // FIXME: if this is the case we don't need this. case SDL_MOUSEMOTION: InputMouseMove(callbacks, SDL_GetTicks(), event.motion.x, event.motion.y); // FIXME: Same bug fix from X11 if ((UI.MouseWarpPos.x != -1 || UI.MouseWarpPos.y != -1) && (event.motion.x != UI.MouseWarpPos.x || event.motion.y != UI.MouseWarpPos.y)) { int xw = UI.MouseWarpPos.x; int yw = UI.MouseWarpPos.y; UI.MouseWarpPos.x = -1; UI.MouseWarpPos.y = -1; SDL_WarpMouse(xw, yw); } break; case SDL_ACTIVEEVENT: if (event.active.state & SDL_APPMOUSEFOCUS) { static bool InMainWindow = true; if (InMainWindow && !event.active.gain) { InputMouseExit(callbacks, SDL_GetTicks()); } InMainWindow = (event.active.gain != 0); } if (!IsNetworkGame() && Preference.PauseOnLeave && (event.active.state & SDL_APPACTIVE || SDL_GetAppState() & SDL_APPACTIVE)) { static bool DoTogglePause = false; if (IsSDLWindowVisible && !event.active.gain) { IsSDLWindowVisible = false; if (!GamePaused) { DoTogglePause = true; UiTogglePause(); } } else if (!IsSDLWindowVisible && event.active.gain) { IsSDLWindowVisible = true; if (GamePaused && DoTogglePause) { DoTogglePause = false; UiTogglePause(); } } } break; case SDL_KEYDOWN: if (GLShaderPipelineSupported && event.key.keysym.sym == SDLK_SLASH && event.key.keysym.mod & KMOD_ALT && event.key.keysym.mod & KMOD_CTRL) { LoadShaders(); break; } InputKeyButtonPress(callbacks, SDL_GetTicks(), event.key.keysym.sym, event.key.keysym.unicode); break; case SDL_KEYUP: InputKeyButtonRelease(callbacks, SDL_GetTicks(), event.key.keysym.sym, event.key.keysym.unicode); break; case SDL_QUIT: Exit(0); break; } if (&callbacks == GetCallbacks()) { handleInput(&event); } }
/** ** Handle keys in command mode. ** ** @param key Key scancode. ** ** @return True, if key is handled; otherwise false. */ static bool CommandKey(int key) { const char *ptr = strchr(UiGroupKeys.c_str(), key); // FIXME: don't handle unicode well. Should work on all latin keyboard. if (ptr) { key = '0' + ptr - UiGroupKeys.c_str(); if (key > '9') { key = SDLK_BACKQUOTE; } } switch (key) { // Return enters chat/input mode. case SDLK_RETURN: case SDLK_KP_ENTER: // RETURN UiBeginInput(); return true; // Unselect everything case SDLK_CARET: case SDLK_BACKQUOTE: UiUnselectAll(); break; // Group selection case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': CommandKey_Group(key - '0'); break; case SDLK_F2: case SDLK_F3: case SDLK_F4: // Set/Goto place CommandKey_MapPosition(key - SDLK_F2); break; case SDLK_SPACE: // center on last action CenterOnMessage(); break; case SDLK_EQUALS: // plus is shift-equals. case SDLK_KP_PLUS: UiIncreaseGameSpeed(); break; case SDLK_MINUS: // - Slower case SDLK_KP_MINUS: UiDecreaseGameSpeed(); break; case SDLK_KP_MULTIPLY: UiSetDefaultGameSpeed(); break; case 'b': // ALT+B, CTRL+B Toggle big map if (!(KeyModifiers & (ModifierAlt | ModifierControl))) { break; } UiToggleBigMap(); break; case 'c': // ALT+C, CTRL+C C center on units UiCenterOnSelected(); break; case 'f': // ALT+F, CTRL+F toggle fullscreen if (!(KeyModifiers & (ModifierAlt | ModifierControl))) { break; } ToggleFullScreen(); SavePreferences(); break; case 'g': // ALT+G, CTRL+G grab mouse pointer if (!(KeyModifiers & (ModifierAlt | ModifierControl))) { break; } UiToggleGrabMouse(); break; case 'i': if (!(KeyModifiers & (ModifierAlt | ModifierControl))) { break; } // FALL THROUGH case SDLK_PERIOD: // ., ALT+I, CTRL+I: Find idle worker UiFindIdleWorker(); break; case 'm': // CTRL+M Turn music on / off if (KeyModifiers & ModifierControl) { UiToggleMusic(); SavePreferences(); break; } break; case 'p': // CTRL+P, ALT+P Toggle pause if (!(KeyModifiers & (ModifierAlt | ModifierControl))) { break; } // FALL THROUGH (CTRL+P, ALT+P) case SDLK_PAUSE: UiTogglePause(); break; case 's': // CTRL+S - Turn sound on / off if (KeyModifiers & ModifierControl) { UiToggleSound(); SavePreferences(); break; } break; case 't': // ALT+T, CTRL+T Track unit if (!(KeyModifiers & (ModifierAlt | ModifierControl))) { break; } UiTrackUnit(); break; case 'v': // ALT+V, CTRL+V: Viewport if (KeyModifiers & ModifierControl) { CycleViewportMode(-1); } else if (KeyModifiers & ModifierAlt) { CycleViewportMode(1); } break; case 'e': // CTRL+E Turn messages on / off if (KeyModifiers & ModifierControl) { ToggleShowMessages(); } #ifdef DEBUG else if (KeyModifiers & ModifierAlt) { ToggleShowBuilListMessages(); } #endif break; case SDLK_TAB: // TAB toggles minimap. // FIXME: more... // FIXME: shift+TAB if (KeyModifiers & ModifierAlt) { break; } UiToggleTerrain(); break; case SDLK_UP: case SDLK_KP8: KeyScrollState |= ScrollUp; break; case SDLK_DOWN: case SDLK_KP2: KeyScrollState |= ScrollDown; break; case SDLK_LEFT: case SDLK_KP4: KeyScrollState |= ScrollLeft; break; case SDLK_RIGHT: case SDLK_KP6: KeyScrollState |= ScrollRight; break; default: if (HandleCommandKey(key)) { break; } return false; } return true; }
/** ** Handle interactive input event. ** ** @param callbacks Callback structure for events. ** @param event SDL event structure pointer. */ static void SdlDoEvent(const EventCallback *callbacks, const SDL_Event *event) { #ifdef DUMP_SDL_EVENTS DumpSdlEvent(event); #endif switch (event->type) { case SDL_MOUSEBUTTONDOWN: if (event->motion.which != 0) return; // temporary ignore multitouch InputMouseButtonPress(callbacks, SDL_GetTicks(), event->button.button); break; case SDL_MOUSEBUTTONUP: if (event->motion.which != 0) return; // temporary ignore multitouch InputMouseButtonRelease(callbacks, SDL_GetTicks(), event->button.button); break; // FIXME: check if this is only useful for the cursor // FIXME: if this is the case we don't need this. case SDL_MOUSEMOTION: if (event->motion.which != 0) return; // temporary ignore multitouch InputMouseMove(callbacks, SDL_GetTicks(), event->motion.x, event->motion.y); // FIXME: Same bug fix from X11 if ((UI.MouseWarpX != -1 || UI.MouseWarpY != -1) && (event->motion.x != UI.MouseWarpX || event->motion.y != UI.MouseWarpY)) { int xw = UI.MouseWarpX; int yw = UI.MouseWarpY; UI.MouseWarpX = -1; UI.MouseWarpY = -1; SDL_WarpMouse(xw, yw); } break; case SDL_ACTIVEEVENT: if (event->active.state & SDL_APPMOUSEFOCUS) { static bool InMainWindow = true; if (InMainWindow && !event->active.gain) { InputMouseExit(callbacks, SDL_GetTicks()); } InMainWindow = (event->active.gain != 0); } if (event->active.state & SDL_APPACTIVE) { static bool IsVisible = true; static bool DoTogglePause = false; if (IsVisible && !event->active.gain) { IsVisible = false; if (!GamePaused) { DoTogglePause = true; UiTogglePause(); } } else if (!IsVisible && event->active.gain) { IsVisible = true; if (GamePaused && DoTogglePause) { DoTogglePause = false; UiTogglePause(); } if (UseOpenGL) { Video.ResizeScreen(Video.Width, Video.Height); } } } break; case SDL_KEYDOWN: InputKeyButtonPress(callbacks, SDL_GetTicks(), event->key.keysym.sym, event->key.keysym.unicode); break; case SDL_KEYUP: InputKeyButtonRelease(callbacks, SDL_GetTicks(), event->key.keysym.sym, event->key.keysym.unicode); break; case SDL_QUIT: Exit(0); break; } if (callbacks == GetCallbacks()) { handleInput(event); } }