mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
Merge pull request #782 from bgK/sdl-win32-keycode
SDL: Fix Windows SDL1 keycodes to use the active keyboard layout
This commit is contained in:
commit
c11cf08745
@ -517,15 +517,17 @@ 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 (ev.key.keysym.sym == SDLK_SCROLLOCK)
|
||||
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) && ev.key.keysym.sym == 'm') {
|
||||
if (event.kbd.hasFlags(Common::KBD_CTRL) && sdlKeycode == 'm') {
|
||||
if (_graphicsManager) {
|
||||
_graphicsManager->getWindow()->toggleMouseGrab();
|
||||
}
|
||||
@ -534,26 +536,26 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
|
||||
|
||||
#if defined(MACOSX)
|
||||
// On Macintosh, Cmd-Q quits
|
||||
if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') {
|
||||
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) && ev.key.keysym.sym == 'q') {
|
||||
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) && ev.key.keysym.sym == 'z')) {
|
||||
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) && ev.key.keysym.sym == SDLK_F4) {
|
||||
if ((ev.key.keysym.mod & KMOD_ALT) && sdlKeycode == SDLK_F4) {
|
||||
event.type = Common::EVENT_QUIT;
|
||||
return true;
|
||||
}
|
||||
@ -561,7 +563,7 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
|
||||
#endif
|
||||
|
||||
// Ctrl-u toggles mute
|
||||
if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'u') {
|
||||
if ((ev.key.keysym.mod & KMOD_CTRL) && sdlKeycode == 'u') {
|
||||
event.type = Common::EVENT_MUTE;
|
||||
return true;
|
||||
}
|
||||
@ -570,8 +572,8 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &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, obtainUnicode(ev.key.keysym));
|
||||
event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode);
|
||||
event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -580,6 +582,7 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
|
||||
if (remapKey(ev, event))
|
||||
return true;
|
||||
|
||||
SDLKey sdlKeycode = obtainKeycode(ev.key.keysym);
|
||||
SDLMod mod = SDL_GetModState();
|
||||
|
||||
// Check if this is an event handled by handleKeyDown(), and stop if it is
|
||||
@ -587,21 +590,21 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
|
||||
// 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 (sdlKeycode == '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
|
||||
sdlKeycode == 'q' || // On other *nix systems, Control-Q quits
|
||||
#else
|
||||
ev.key.keysym.sym == 'z' || // Ctrl-z quit
|
||||
sdlKeycode == 'z' || // Ctrl-z quit
|
||||
#endif
|
||||
ev.key.keysym.sym == 'u') // Ctrl-u toggles mute
|
||||
sdlKeycode == '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')
|
||||
if ((mod & KMOD_META) && sdlKeycode == 'q')
|
||||
return false; // On Macintosh, Cmd-Q quits
|
||||
#endif
|
||||
|
||||
@ -609,8 +612,8 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
|
||||
// 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, 0);
|
||||
event.kbd.keycode = SDLToOSystemKeycode(sdlKeycode);
|
||||
event.kbd.ascii = mapKey(sdlKeycode, (SDLMod)ev.key.keysym.mod, 0);
|
||||
|
||||
// Ctrl-Alt-<key> will change the GFX mode
|
||||
SDLModToOSystemKeyFlags(mod, event);
|
||||
@ -868,6 +871,44 @@ bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDLKey SdlEventSource::obtainKeycode(const SDL_keysym keySym) {
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(WIN32)
|
||||
// WORKAROUND: SDL 1.2 on Windows does not use the user configured keyboard layout,
|
||||
// resulting in "keySym.sym" values to always be those expected for an US keyboard.
|
||||
// For example, SDL returns SDLK_Q when pressing the 'A' key on an AZERTY keyboard.
|
||||
// This defeats the purpose of keycodes which is to be able to refer to a key without
|
||||
// knowing where it is physically located.
|
||||
// We work around this issue by querying the currently active Windows keyboard layout
|
||||
// using the scancode provided by SDL.
|
||||
|
||||
if (keySym.sym >= SDLK_0 && keySym.sym <= SDLK_9) {
|
||||
// The keycode returned by SDL is kept for the number keys.
|
||||
// Querying the keyboard layout for those would return the base key values
|
||||
// for AZERTY keyboards, which are not numbers. For example, SDLK_1 would
|
||||
// map to SDLK_AMPERSAND. This is theoratically correct but practically unhelpful,
|
||||
// because it makes it impossible to handle key combinations such as "ctrl-1".
|
||||
return keySym.sym;
|
||||
}
|
||||
|
||||
int vk = MapVirtualKey(keySym.scancode, MAPVK_VSC_TO_VK);
|
||||
if (vk) {
|
||||
int ch = (MapVirtualKey(vk, MAPVK_VK_TO_CHAR) & 0x7FFF);
|
||||
// The top bit of the result of MapVirtualKey with MAPVK_VSC_TO_VK signals
|
||||
// a dead key was pressed. In that case we keep the value of the accent alone.
|
||||
if (ch) {
|
||||
if (ch >= 'A' && ch <= 'Z') {
|
||||
// Windows returns uppercase ASCII whereas SDL expects lowercase
|
||||
return (SDLKey)(SDLK_a + (ch - 'A'));
|
||||
} else {
|
||||
return (SDLKey)ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return keySym.sym;
|
||||
}
|
||||
|
||||
uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
SDL_Event events[2];
|
||||
|
@ -148,6 +148,11 @@ protected:
|
||||
*/
|
||||
uint32 obtainUnicode(const SDL_keysym keySym);
|
||||
|
||||
/**
|
||||
* Extracts the keycode for the specified key sym.
|
||||
*/
|
||||
SDLKey obtainKeycode(const SDL_keysym keySym);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
/**
|
||||
* Whether _fakeKeyUp contains an event we need to send.
|
||||
|
Loading…
Reference in New Issue
Block a user