mirror of
https://github.com/glfw/glfw.git
synced 2025-10-03 13:20:58 +00:00
X11: Fix bug that mapped all function keys to GLFW_KEY_UNKNOWN
This commit is contained in:
parent
a80788c17f
commit
e94412d726
274
src/x11_init.c
274
src/x11_init.c
@ -38,196 +38,6 @@
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
// Translate an X11 key code to a GLFW key code.
|
||||
//
|
||||
static int translateKeyCode(int scancode)
|
||||
{
|
||||
int keySym;
|
||||
|
||||
// Valid key code range is [8,255], according to the Xlib manual
|
||||
if (scancode < 8 || scancode > 255)
|
||||
return GLFW_KEY_UNKNOWN;
|
||||
|
||||
if (_glfw.x11.xkb.available)
|
||||
{
|
||||
// Try secondary keysym, for numeric keypad keys
|
||||
// Note: This way we always force "NumLock = ON", which is intentional
|
||||
// since the returned key code should correspond to a physical
|
||||
// location.
|
||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 1);
|
||||
switch (keySym)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Now try primary keysym for function keys (non-printable keys)
|
||||
// These should not depend on the current keyboard layout
|
||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int dummy;
|
||||
KeySym* keySyms;
|
||||
|
||||
keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy);
|
||||
keySym = keySyms[0];
|
||||
XFree(keySyms);
|
||||
}
|
||||
|
||||
switch (keySym)
|
||||
{
|
||||
case XK_Escape: return GLFW_KEY_ESCAPE;
|
||||
case XK_Tab: return GLFW_KEY_TAB;
|
||||
case XK_Shift_L: return GLFW_KEY_LEFT_SHIFT;
|
||||
case XK_Shift_R: return GLFW_KEY_RIGHT_SHIFT;
|
||||
case XK_Control_L: return GLFW_KEY_LEFT_CONTROL;
|
||||
case XK_Control_R: return GLFW_KEY_RIGHT_CONTROL;
|
||||
case XK_Meta_L:
|
||||
case XK_Alt_L: return GLFW_KEY_LEFT_ALT;
|
||||
case XK_Mode_switch: // Mapped to Alt_R on many keyboards
|
||||
case XK_ISO_Level3_Shift: // AltGr on at least some machines
|
||||
case XK_Meta_R:
|
||||
case XK_Alt_R: return GLFW_KEY_RIGHT_ALT;
|
||||
case XK_Super_L: return GLFW_KEY_LEFT_SUPER;
|
||||
case XK_Super_R: return GLFW_KEY_RIGHT_SUPER;
|
||||
case XK_Menu: return GLFW_KEY_MENU;
|
||||
case XK_Num_Lock: return GLFW_KEY_NUM_LOCK;
|
||||
case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK;
|
||||
case XK_Print: return GLFW_KEY_PRINT_SCREEN;
|
||||
case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK;
|
||||
case XK_Pause: return GLFW_KEY_PAUSE;
|
||||
case XK_Delete: return GLFW_KEY_DELETE;
|
||||
case XK_BackSpace: return GLFW_KEY_BACKSPACE;
|
||||
case XK_Return: return GLFW_KEY_ENTER;
|
||||
case XK_Home: return GLFW_KEY_HOME;
|
||||
case XK_End: return GLFW_KEY_END;
|
||||
case XK_Page_Up: return GLFW_KEY_PAGE_UP;
|
||||
case XK_Page_Down: return GLFW_KEY_PAGE_DOWN;
|
||||
case XK_Insert: return GLFW_KEY_INSERT;
|
||||
case XK_Left: return GLFW_KEY_LEFT;
|
||||
case XK_Right: return GLFW_KEY_RIGHT;
|
||||
case XK_Down: return GLFW_KEY_DOWN;
|
||||
case XK_Up: return GLFW_KEY_UP;
|
||||
case XK_F1: return GLFW_KEY_F1;
|
||||
case XK_F2: return GLFW_KEY_F2;
|
||||
case XK_F3: return GLFW_KEY_F3;
|
||||
case XK_F4: return GLFW_KEY_F4;
|
||||
case XK_F5: return GLFW_KEY_F5;
|
||||
case XK_F6: return GLFW_KEY_F6;
|
||||
case XK_F7: return GLFW_KEY_F7;
|
||||
case XK_F8: return GLFW_KEY_F8;
|
||||
case XK_F9: return GLFW_KEY_F9;
|
||||
case XK_F10: return GLFW_KEY_F10;
|
||||
case XK_F11: return GLFW_KEY_F11;
|
||||
case XK_F12: return GLFW_KEY_F12;
|
||||
case XK_F13: return GLFW_KEY_F13;
|
||||
case XK_F14: return GLFW_KEY_F14;
|
||||
case XK_F15: return GLFW_KEY_F15;
|
||||
case XK_F16: return GLFW_KEY_F16;
|
||||
case XK_F17: return GLFW_KEY_F17;
|
||||
case XK_F18: return GLFW_KEY_F18;
|
||||
case XK_F19: return GLFW_KEY_F19;
|
||||
case XK_F20: return GLFW_KEY_F20;
|
||||
case XK_F21: return GLFW_KEY_F21;
|
||||
case XK_F22: return GLFW_KEY_F22;
|
||||
case XK_F23: return GLFW_KEY_F23;
|
||||
case XK_F24: return GLFW_KEY_F24;
|
||||
case XK_F25: return GLFW_KEY_F25;
|
||||
|
||||
// Numeric keypad
|
||||
case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE;
|
||||
case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY;
|
||||
case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT;
|
||||
case XK_KP_Add: return GLFW_KEY_KP_ADD;
|
||||
|
||||
// These should have been detected in secondary keysym test above!
|
||||
case XK_KP_Insert: return GLFW_KEY_KP_0;
|
||||
case XK_KP_End: return GLFW_KEY_KP_1;
|
||||
case XK_KP_Down: return GLFW_KEY_KP_2;
|
||||
case XK_KP_Page_Down: return GLFW_KEY_KP_3;
|
||||
case XK_KP_Left: return GLFW_KEY_KP_4;
|
||||
case XK_KP_Right: return GLFW_KEY_KP_6;
|
||||
case XK_KP_Home: return GLFW_KEY_KP_7;
|
||||
case XK_KP_Up: return GLFW_KEY_KP_8;
|
||||
case XK_KP_Page_Up: return GLFW_KEY_KP_9;
|
||||
case XK_KP_Delete: return GLFW_KEY_KP_DECIMAL;
|
||||
case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
|
||||
case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
|
||||
|
||||
// Last resort: Check for printable keys (should not happen if the XKB
|
||||
// extension is available). This will give a layout dependent mapping
|
||||
// (which is wrong, and we may miss some keys, especially on non-US
|
||||
// keyboards), but it's better than nothing...
|
||||
case XK_a: return GLFW_KEY_A;
|
||||
case XK_b: return GLFW_KEY_B;
|
||||
case XK_c: return GLFW_KEY_C;
|
||||
case XK_d: return GLFW_KEY_D;
|
||||
case XK_e: return GLFW_KEY_E;
|
||||
case XK_f: return GLFW_KEY_F;
|
||||
case XK_g: return GLFW_KEY_G;
|
||||
case XK_h: return GLFW_KEY_H;
|
||||
case XK_i: return GLFW_KEY_I;
|
||||
case XK_j: return GLFW_KEY_J;
|
||||
case XK_k: return GLFW_KEY_K;
|
||||
case XK_l: return GLFW_KEY_L;
|
||||
case XK_m: return GLFW_KEY_M;
|
||||
case XK_n: return GLFW_KEY_N;
|
||||
case XK_o: return GLFW_KEY_O;
|
||||
case XK_p: return GLFW_KEY_P;
|
||||
case XK_q: return GLFW_KEY_Q;
|
||||
case XK_r: return GLFW_KEY_R;
|
||||
case XK_s: return GLFW_KEY_S;
|
||||
case XK_t: return GLFW_KEY_T;
|
||||
case XK_u: return GLFW_KEY_U;
|
||||
case XK_v: return GLFW_KEY_V;
|
||||
case XK_w: return GLFW_KEY_W;
|
||||
case XK_x: return GLFW_KEY_X;
|
||||
case XK_y: return GLFW_KEY_Y;
|
||||
case XK_z: return GLFW_KEY_Z;
|
||||
case XK_1: return GLFW_KEY_1;
|
||||
case XK_2: return GLFW_KEY_2;
|
||||
case XK_3: return GLFW_KEY_3;
|
||||
case XK_4: return GLFW_KEY_4;
|
||||
case XK_5: return GLFW_KEY_5;
|
||||
case XK_6: return GLFW_KEY_6;
|
||||
case XK_7: return GLFW_KEY_7;
|
||||
case XK_8: return GLFW_KEY_8;
|
||||
case XK_9: return GLFW_KEY_9;
|
||||
case XK_0: return GLFW_KEY_0;
|
||||
case XK_space: return GLFW_KEY_SPACE;
|
||||
case XK_minus: return GLFW_KEY_MINUS;
|
||||
case XK_equal: return GLFW_KEY_EQUAL;
|
||||
case XK_bracketleft: return GLFW_KEY_LEFT_BRACKET;
|
||||
case XK_bracketright: return GLFW_KEY_RIGHT_BRACKET;
|
||||
case XK_backslash: return GLFW_KEY_BACKSLASH;
|
||||
case XK_semicolon: return GLFW_KEY_SEMICOLON;
|
||||
case XK_apostrophe: return GLFW_KEY_APOSTROPHE;
|
||||
case XK_grave: return GLFW_KEY_GRAVE_ACCENT;
|
||||
case XK_comma: return GLFW_KEY_COMMA;
|
||||
case XK_period: return GLFW_KEY_PERIOD;
|
||||
case XK_slash: return GLFW_KEY_SLASH;
|
||||
case XK_less: return GLFW_KEY_WORLD_1; // At least in some layouts...
|
||||
default: break;
|
||||
}
|
||||
|
||||
// No matching translation was found
|
||||
return GLFW_KEY_UNKNOWN;
|
||||
}
|
||||
|
||||
// Create key code translation tables
|
||||
//
|
||||
static void createKeyTables(void)
|
||||
@ -252,10 +62,10 @@ static void createKeyTables(void)
|
||||
memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
|
||||
name[XkbKeyNameLength] = '\0';
|
||||
|
||||
// Map the key name to a GLFW key code. Note: We only map printable
|
||||
// keys here, and we use the US keyboard layout. The rest of the
|
||||
// keys (function keys) are mapped using traditional KeySym
|
||||
// translations.
|
||||
// Map the key name to a GLFW key code. Note: We use the US
|
||||
// keyboard layout. Because function keys aren't mapped correctly
|
||||
// when using traditional KeySym translations, they are mapped
|
||||
// here instead.
|
||||
if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT;
|
||||
else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1;
|
||||
else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2;
|
||||
@ -304,6 +114,77 @@ static void createKeyTables(void)
|
||||
else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH;
|
||||
else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH;
|
||||
else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1;
|
||||
else if (strcmp(name, "SPCE") == 0) key = GLFW_KEY_SPACE;
|
||||
else if (strcmp(name, "ESC") == 0) key = GLFW_KEY_ESCAPE;
|
||||
else if (strcmp(name, "RTRN") == 0) key = GLFW_KEY_ENTER;
|
||||
else if (strcmp(name, "TAB") == 0) key = GLFW_KEY_TAB;
|
||||
else if (strcmp(name, "BKSP") == 0) key = GLFW_KEY_BACKSPACE;
|
||||
else if (strcmp(name, "INS") == 0) key = GLFW_KEY_INSERT;
|
||||
else if (strcmp(name, "DELE") == 0) key = GLFW_KEY_DELETE;
|
||||
else if (strcmp(name, "RGHT") == 0) key = GLFW_KEY_RIGHT;
|
||||
else if (strcmp(name, "LEFT") == 0) key = GLFW_KEY_LEFT;
|
||||
else if (strcmp(name, "DOWN") == 0) key = GLFW_KEY_DOWN;
|
||||
else if (strcmp(name, "UP") == 0) key = GLFW_KEY_UP;
|
||||
else if (strcmp(name, "PGUP") == 0) key = GLFW_KEY_PAGE_UP;
|
||||
else if (strcmp(name, "PGDN") == 0) key = GLFW_KEY_PAGE_DOWN;
|
||||
else if (strcmp(name, "HOME") == 0) key = GLFW_KEY_HOME;
|
||||
else if (strcmp(name, "END") == 0) key = GLFW_KEY_END;
|
||||
else if (strcmp(name, "CAPS") == 0) key = GLFW_KEY_CAPS_LOCK;
|
||||
else if (strcmp(name, "SCLK") == 0) key = GLFW_KEY_SCROLL_LOCK;
|
||||
else if (strcmp(name, "NMLK") == 0) key = GLFW_KEY_NUM_LOCK;
|
||||
else if (strcmp(name, "PRSC") == 0) key = GLFW_KEY_PRINT_SCREEN;
|
||||
else if (strcmp(name, "PAUS") == 0) key = GLFW_KEY_PAUSE;
|
||||
else if (strcmp(name, "FK01") == 0) key = GLFW_KEY_F1;
|
||||
else if (strcmp(name, "FK02") == 0) key = GLFW_KEY_F2;
|
||||
else if (strcmp(name, "FK03") == 0) key = GLFW_KEY_F3;
|
||||
else if (strcmp(name, "FK04") == 0) key = GLFW_KEY_F4;
|
||||
else if (strcmp(name, "FK05") == 0) key = GLFW_KEY_F5;
|
||||
else if (strcmp(name, "FK06") == 0) key = GLFW_KEY_F6;
|
||||
else if (strcmp(name, "FK07") == 0) key = GLFW_KEY_F7;
|
||||
else if (strcmp(name, "FK08") == 0) key = GLFW_KEY_F8;
|
||||
else if (strcmp(name, "FK09") == 0) key = GLFW_KEY_F9;
|
||||
else if (strcmp(name, "FK10") == 0) key = GLFW_KEY_F10;
|
||||
else if (strcmp(name, "FK11") == 0) key = GLFW_KEY_F11;
|
||||
else if (strcmp(name, "FK12") == 0) key = GLFW_KEY_F12;
|
||||
else if (strcmp(name, "FK13") == 0) key = GLFW_KEY_F13;
|
||||
else if (strcmp(name, "FK14") == 0) key = GLFW_KEY_F14;
|
||||
else if (strcmp(name, "FK15") == 0) key = GLFW_KEY_F15;
|
||||
else if (strcmp(name, "FK16") == 0) key = GLFW_KEY_F16;
|
||||
else if (strcmp(name, "FK17") == 0) key = GLFW_KEY_F17;
|
||||
else if (strcmp(name, "FK18") == 0) key = GLFW_KEY_F18;
|
||||
else if (strcmp(name, "FK19") == 0) key = GLFW_KEY_F19;
|
||||
else if (strcmp(name, "FK20") == 0) key = GLFW_KEY_F20;
|
||||
else if (strcmp(name, "FK21") == 0) key = GLFW_KEY_F21;
|
||||
else if (strcmp(name, "FK22") == 0) key = GLFW_KEY_F22;
|
||||
else if (strcmp(name, "FK23") == 0) key = GLFW_KEY_F23;
|
||||
else if (strcmp(name, "FK24") == 0) key = GLFW_KEY_F24;
|
||||
else if (strcmp(name, "FK25") == 0) key = GLFW_KEY_F25;
|
||||
else if (strcmp(name, "KP0") == 0) key = GLFW_KEY_KP_0;
|
||||
else if (strcmp(name, "KP1") == 0) key = GLFW_KEY_KP_1;
|
||||
else if (strcmp(name, "KP2") == 0) key = GLFW_KEY_KP_2;
|
||||
else if (strcmp(name, "KP3") == 0) key = GLFW_KEY_KP_3;
|
||||
else if (strcmp(name, "KP4") == 0) key = GLFW_KEY_KP_4;
|
||||
else if (strcmp(name, "KP5") == 0) key = GLFW_KEY_KP_5;
|
||||
else if (strcmp(name, "KP6") == 0) key = GLFW_KEY_KP_6;
|
||||
else if (strcmp(name, "KP7") == 0) key = GLFW_KEY_KP_7;
|
||||
else if (strcmp(name, "KP8") == 0) key = GLFW_KEY_KP_8;
|
||||
else if (strcmp(name, "KP9") == 0) key = GLFW_KEY_KP_9;
|
||||
else if (strcmp(name, "KPDL") == 0) key = GLFW_KEY_KP_DECIMAL;
|
||||
else if (strcmp(name, "KPDV") == 0) key = GLFW_KEY_KP_DIVIDE;
|
||||
else if (strcmp(name, "KPMU") == 0) key = GLFW_KEY_KP_MULTIPLY;
|
||||
else if (strcmp(name, "KPSU") == 0) key = GLFW_KEY_KP_SUBTRACT;
|
||||
else if (strcmp(name, "KPAD") == 0) key = GLFW_KEY_KP_ADD;
|
||||
else if (strcmp(name, "KPEN") == 0) key = GLFW_KEY_KP_ENTER;
|
||||
else if (strcmp(name, "KPEQ") == 0) key = GLFW_KEY_KP_EQUAL;
|
||||
else if (strcmp(name, "LFSH") == 0) key = GLFW_KEY_LEFT_SHIFT;
|
||||
else if (strcmp(name, "LCTL") == 0) key = GLFW_KEY_LEFT_CONTROL;
|
||||
else if (strcmp(name, "LALT") == 0) key = GLFW_KEY_LEFT_ALT;
|
||||
else if (strcmp(name, "LWIN") == 0) key = GLFW_KEY_LEFT_SUPER;
|
||||
else if (strcmp(name, "RTSH") == 0) key = GLFW_KEY_RIGHT_SHIFT;
|
||||
else if (strcmp(name, "RCTL") == 0) key = GLFW_KEY_RIGHT_CONTROL;
|
||||
else if (strcmp(name, "RALT") == 0) key = GLFW_KEY_RIGHT_ALT;
|
||||
else if (strcmp(name, "RWIN") == 0) key = GLFW_KEY_RIGHT_SUPER;
|
||||
else if (strcmp(name, "COMP") == 0) key = GLFW_KEY_MENU;
|
||||
else key = GLFW_KEY_UNKNOWN;
|
||||
|
||||
if ((scancode >= 0) && (scancode < 256))
|
||||
@ -316,11 +197,6 @@ static void createKeyTables(void)
|
||||
|
||||
for (scancode = 0; scancode < 256; scancode++)
|
||||
{
|
||||
// Translate the un-translated key codes using traditional X11 KeySym
|
||||
// lookups
|
||||
if (_glfw.x11.keycodes[scancode] < 0)
|
||||
_glfw.x11.keycodes[scancode] = translateKeyCode(scancode);
|
||||
|
||||
// Store the reverse translation for faster key name lookup
|
||||
if (_glfw.x11.keycodes[scancode] > 0)
|
||||
_glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode;
|
||||
|
Loading…
Reference in New Issue
Block a user