From cab41529da42f46dc6d6aec159a9b8d1d1331652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 23 Apr 2020 21:27:28 +0200 Subject: [PATCH] X11: Improve non-XKB fallback for key mapping A regression introduced by b889aa784129b3e7d1219a55a1008bd6518183db broke the special handling of numpad keys for the non-XKB fallback path. The non-functional remains were later removed. This restores the original behavior. --- src/x11_init.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index 84906183..e5bd578d 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -37,22 +37,35 @@ #include -// Translate an X11 key code to a GLFW key code. +// Translate the X11 KeySyms for a key to a GLFW key code +// NOTE: This is only used as a fallback, in case the XKB method fails +// It is layout-dependent and will fail partially on most non-US layouts // -static int translateKeyCode(int scancode) +static int translateKeySyms(const KeySym* keysyms, int width) { - int keySym; - + if (width > 1) { - int dummy; - KeySym* keySyms; - - keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy); - keySym = keySyms[0]; - XFree(keySyms); + switch (keysyms[1]) + { + case XK_KP_0: return GLFW_KEY_KP_0; + case XK_KP_1: return GLFW_KEY_KP_1; + case XK_KP_2: return GLFW_KEY_KP_2; + case XK_KP_3: return GLFW_KEY_KP_3; + case XK_KP_4: return GLFW_KEY_KP_4; + case XK_KP_5: return GLFW_KEY_KP_5; + case XK_KP_6: return GLFW_KEY_KP_6; + case XK_KP_7: return GLFW_KEY_KP_7; + case XK_KP_8: return GLFW_KEY_KP_8; + case XK_KP_9: return GLFW_KEY_KP_9; + case XK_KP_Separator: + case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL; + case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; + case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + default: break; + } } - switch (keySym) + switch (keysyms[0]) { case XK_Escape: return GLFW_KEY_ESCAPE; case XK_Tab: return GLFW_KEY_TAB; @@ -395,17 +408,28 @@ static void createKeyTables(void) else XDisplayKeycodes(_glfw.x11.display, &scancodeMin, &scancodeMax); + int width; + KeySym* keysyms = XGetKeyboardMapping(_glfw.x11.display, + scancodeMin, + scancodeMax - scancodeMin + 1, + &width); + for (scancode = scancodeMin; scancode <= scancodeMax; scancode++) { // Translate the un-translated key codes using traditional X11 KeySym // lookups if (_glfw.x11.keycodes[scancode] < 0) - _glfw.x11.keycodes[scancode] = translateKeyCode(scancode); + { + const size_t base = (scancode - scancodeMin) * width; + _glfw.x11.keycodes[scancode] = translateKeySyms(&keysyms[base], width); + } // Store the reverse translation for faster key name lookup if (_glfw.x11.keycodes[scancode] > 0) _glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode; } + + XFree(keysyms); } // Check whether the IM has a usable style