bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { SDLModToOSystemKeyFlags(SDL_GetModState(), event); // Handle scroll lock as a key modifier if (ev.key.keysym.sym == SDLK_SCROLLOCK) _scrollLock = !_scrollLock; if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; // Ctrl-m toggles mouse capture if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') { toggleMouseGrab(); return false; } #if defined(MACOSX) // On Macintosh, Cmd-Q quits if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') { event.type = Common::EVENT_QUIT; return true; } #elif defined(POSIX) // On other *nix systems, Control-Q quits if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'q') { event.type = Common::EVENT_QUIT; return true; } #else // Ctrl-z and Alt-X quit if ((event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'z') || (event.kbd.hasFlags(Common::KBD_ALT) && ev.key.keysym.sym == 'x')) { event.type = Common::EVENT_QUIT; return true; } #ifdef WIN32 // On Windows, also use the default Alt-F4 quit combination if ((ev.key.keysym.mod & KMOD_ALT) && ev.key.keysym.sym == SDLK_F4) { event.type = Common::EVENT_QUIT; return true; } #endif #endif // Ctrl-u toggles mute if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'u') { event.type = Common::EVENT_MUTE; return true; } if (remapKey(ev, event)) return true; event.type = Common::EVENT_KEYDOWN; event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym); event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, (Uint16)ev.key.keysym.unicode); return true; }
int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) { Common::KeyCode key = SDLToOSystemKeycode(sdlKey); // Keep unicode in case it's regular ASCII text or in case we didn't get a valid keycode // // We need to use unicode in those cases, simply because SDL1.x passes us non-layout-adjusted keycodes. // So unicode is the only way to get layout-adjusted keys. if (unicode < 0x20) { // don't use unicode, in case it's control characters unicode = 0; } else { // Use unicode, in case keycode is invalid. // Umlauts and others will set KEYCODE_INVALID on SDL2, so in such a case always keep unicode. if (key != Common::KEYCODE_INVALID) { // keycode is valid, check further also depending on modifiers if (mod & (KMOD_CTRL | KMOD_ALT)) { // Ctrl and/or Alt is active // // We need to restrict unicode to only up to 0x7E, because on macOS the option/alt key will switch to // an alternate keyboard, which will cause us to receive Unicode characters for some keys, which are outside // of the ASCII range (e.g. alt-x will get us U+2248). We need to return 'x' for alt-x, so using unicode // in that case would break alt-shortcuts. if (unicode > 0x7E) unicode = 0; // do not allow any characters above 0x7E } else { // We must not restrict as much as when Ctrl/Alt-modifiers are active, otherwise // we wouldn't let umlauts through for SDL1. For SDL1 umlauts may set for example KEYCODE_QUOTE, KEYCODE_MINUS, etc. if (unicode > 0xFF) unicode = 0; // do not allow any characters above 0xFF } } } // Attention: // When using SDL1.x, we will get scancodes via sdlKey, that are raw scancodes, so NOT adjusted to keyboard layout/ // mapping. So for example for certain locales, we will get KEYCODE_y, when 'z' is pressed and so on. // When using SDL2.x however, we will get scancodes based on the keyboard layout. if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) { return key - Common::KEYCODE_F1 + Common::ASCII_F1; } else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) { if ((mod & KMOD_NUM) == 0) return 0; // In case Num-Lock is NOT enabled, return 0 for ascii, so that directional keys on numpad work return key - Common::KEYCODE_KP0 + '0'; } else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) { return key; } else if (unicode) { // Return unicode in case it's still set and wasn't filtered. return unicode; } else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) { return key & ~0x20; } else if (key >= Common::KEYCODE_NUMLOCK && key <= Common::KEYCODE_EURO) { return 0; } else { return key; } }
bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) { if (remapKey(ev, event)) return true; SDLMod mod = SDL_GetModState(); // Check if this is an event handled by handleKeyDown(), and stop if it is // Check if the Ctrl key is down, so that we can trap cases where the // user has the Ctrl key down, and has just released a special key if (mod & KMOD_CTRL) { if (ev.key.keysym.sym == 'm' || // Ctrl-m toggles mouse capture #if defined(MACOSX) // Meta - Q, handled below #elif defined(POSIX) ev.key.keysym.sym == 'q' || // On other *nix systems, Control-Q quits #else ev.key.keysym.sym == 'z' || // Ctrl-z quit #endif ev.key.keysym.sym == 'u') // Ctrl-u toggles mute return false; } // Same for other keys (Meta and Alt) #if defined(MACOSX) if ((mod & KMOD_META) && ev.key.keysym.sym == 'q') return false; // On Macintosh, Cmd-Q quits #elif defined(POSIX) // Control Q has already been handled above #else if ((mod & KMOD_ALT) && ev.key.keysym.sym == 'x') return false; // Alt-x quit #endif // If we reached here, this isn't an event handled by handleKeyDown(), thus // continue normally event.type = Common::EVENT_KEYUP; event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym); event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, (Uint16)ev.key.keysym.unicode); // Ctrl-Alt-<key> will change the GFX mode SDLModToOSystemKeyFlags(mod, event); // Set the scroll lock sticky flag if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; return true; }
int AndroidSdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) { Common::KeyCode key = SDLToOSystemKeycode(sdlKey); if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) { return key - Common::KEYCODE_F1 + Common::ASCII_F1; } else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) { return key - Common::KEYCODE_KP0 + '0'; } else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) { return key; } else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) { return key & ~0x20; } else if (key >= Common::KEYCODE_NUMLOCK && key <= Common::KEYCODE_EURO) { return 0; } else { return key; } }
bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { SDLModToOSystemKeyFlags(SDL_GetModState(), event); SDLKey sdlKeycode = obtainKeycode(ev.key.keysym); // Handle scroll lock as a key modifier if (sdlKeycode == SDLK_SCROLLOCK) _scrollLock = !_scrollLock; if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; // Ctrl-m toggles mouse capture if (event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'm') { if (_graphicsManager) { _graphicsManager->getWindow()->toggleMouseGrab(); } return false; } #if defined(MACOSX) // On Macintosh, Cmd-Q quits if ((ev.key.keysym.mod & KMOD_META) && sdlKeycode == 'q') { event.type = Common::EVENT_QUIT; return true; } #elif defined(POSIX) // On other *nix systems, Control-Q quits if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'q') { event.type = Common::EVENT_QUIT; return true; } #else // Ctrl-z quits if ((event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'z')) { event.type = Common::EVENT_QUIT; return true; } #ifdef WIN32 // On Windows, also use the default Alt-F4 quit combination if ((ev.key.keysym.mod & KMOD_ALT) && sdlKeycode == SDLK_F4) { event.type = Common::EVENT_QUIT; return true; } #endif #endif // Ctrl-u toggles mute if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'u') { event.type = Common::EVENT_MUTE; return true; } if (remapKey(ev, event)) return true; event.type = Common::EVENT_KEYDOWN; event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode); event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym)); #if SDL_VERSION_ATLEAST(2, 0, 0) event.kbdRepeat = ev.key.repeat; #endif return true; }