X11: Check XKB key aliases in addition to names

This commit is contained in:
Camilla Löwy 2020-03-25 18:16:15 +01:00
parent ee45b58647
commit 9ecacf1d7f

View File

@ -196,7 +196,7 @@ static int translateKeyCode(int scancode)
//
static void createKeyTables(void)
{
int scancode, key, scancodeMin, scancodeMax;
int scancode, scancodeMin, scancodeMax;
memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
@ -206,143 +206,183 @@ static void createKeyTables(void)
// Use XKB to determine physical key locations independently of the
// current keyboard layout
char name[XkbKeyNameLength + 1];
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc);
XkbGetNames(_glfw.x11.display, XkbKeyNamesMask | XkbKeyAliasesMask, desc);
scancodeMin = desc->min_key_code;
scancodeMax = desc->max_key_code;
const struct
{
int key;
char* name;
} keymap[] =
{
{ GLFW_KEY_GRAVE_ACCENT, "TLDE" },
{ GLFW_KEY_1, "AE01" },
{ GLFW_KEY_2, "AE02" },
{ GLFW_KEY_3, "AE03" },
{ GLFW_KEY_4, "AE04" },
{ GLFW_KEY_5, "AE05" },
{ GLFW_KEY_6, "AE06" },
{ GLFW_KEY_7, "AE07" },
{ GLFW_KEY_8, "AE08" },
{ GLFW_KEY_9, "AE09" },
{ GLFW_KEY_0, "AE10" },
{ GLFW_KEY_MINUS, "AE11" },
{ GLFW_KEY_EQUAL, "AE12" },
{ GLFW_KEY_Q, "AD01" },
{ GLFW_KEY_W, "AD02" },
{ GLFW_KEY_E, "AD03" },
{ GLFW_KEY_R, "AD04" },
{ GLFW_KEY_T, "AD05" },
{ GLFW_KEY_Y, "AD06" },
{ GLFW_KEY_U, "AD07" },
{ GLFW_KEY_I, "AD08" },
{ GLFW_KEY_O, "AD09" },
{ GLFW_KEY_P, "AD10" },
{ GLFW_KEY_LEFT_BRACKET, "AD11" },
{ GLFW_KEY_RIGHT_BRACKET, "AD12" },
{ GLFW_KEY_A, "AC01" },
{ GLFW_KEY_S, "AC02" },
{ GLFW_KEY_D, "AC03" },
{ GLFW_KEY_F, "AC04" },
{ GLFW_KEY_G, "AC05" },
{ GLFW_KEY_H, "AC06" },
{ GLFW_KEY_J, "AC07" },
{ GLFW_KEY_K, "AC08" },
{ GLFW_KEY_L, "AC09" },
{ GLFW_KEY_SEMICOLON, "AC10" },
{ GLFW_KEY_APOSTROPHE, "AC11" },
{ GLFW_KEY_Z, "AB01" },
{ GLFW_KEY_X, "AB02" },
{ GLFW_KEY_C, "AB03" },
{ GLFW_KEY_V, "AB04" },
{ GLFW_KEY_B, "AB05" },
{ GLFW_KEY_N, "AB06" },
{ GLFW_KEY_M, "AB07" },
{ GLFW_KEY_COMMA, "AB08" },
{ GLFW_KEY_PERIOD, "AB09" },
{ GLFW_KEY_SLASH, "AB10" },
{ GLFW_KEY_BACKSLASH, "BKSL" },
{ GLFW_KEY_WORLD_1, "LSGT" },
{ GLFW_KEY_SPACE, "SPCE" },
{ GLFW_KEY_ESCAPE, "ESC" },
{ GLFW_KEY_ENTER, "RTRN" },
{ GLFW_KEY_TAB, "TAB" },
{ GLFW_KEY_BACKSPACE, "BKSP" },
{ GLFW_KEY_INSERT, "INS" },
{ GLFW_KEY_DELETE, "DELE" },
{ GLFW_KEY_RIGHT, "RGHT" },
{ GLFW_KEY_LEFT, "LEFT" },
{ GLFW_KEY_DOWN, "DOWN" },
{ GLFW_KEY_UP, "UP" },
{ GLFW_KEY_PAGE_UP, "PGUP" },
{ GLFW_KEY_PAGE_DOWN, "PGDN" },
{ GLFW_KEY_HOME, "HOME" },
{ GLFW_KEY_END, "END" },
{ GLFW_KEY_CAPS_LOCK, "CAPS" },
{ GLFW_KEY_SCROLL_LOCK, "SCLK" },
{ GLFW_KEY_NUM_LOCK, "NMLK" },
{ GLFW_KEY_PRINT_SCREEN, "PRSC" },
{ GLFW_KEY_PAUSE, "PAUS" },
{ GLFW_KEY_F1, "FK01" },
{ GLFW_KEY_F2, "FK02" },
{ GLFW_KEY_F3, "FK03" },
{ GLFW_KEY_F4, "FK04" },
{ GLFW_KEY_F5, "FK05" },
{ GLFW_KEY_F6, "FK06" },
{ GLFW_KEY_F7, "FK07" },
{ GLFW_KEY_F8, "FK08" },
{ GLFW_KEY_F9, "FK09" },
{ GLFW_KEY_F10, "FK10" },
{ GLFW_KEY_F11, "FK11" },
{ GLFW_KEY_F12, "FK12" },
{ GLFW_KEY_F13, "FK13" },
{ GLFW_KEY_F14, "FK14" },
{ GLFW_KEY_F15, "FK15" },
{ GLFW_KEY_F16, "FK16" },
{ GLFW_KEY_F17, "FK17" },
{ GLFW_KEY_F18, "FK18" },
{ GLFW_KEY_F19, "FK19" },
{ GLFW_KEY_F20, "FK20" },
{ GLFW_KEY_F21, "FK21" },
{ GLFW_KEY_F22, "FK22" },
{ GLFW_KEY_F23, "FK23" },
{ GLFW_KEY_F24, "FK24" },
{ GLFW_KEY_F25, "FK25" },
{ GLFW_KEY_KP_0, "KP0" },
{ GLFW_KEY_KP_1, "KP1" },
{ GLFW_KEY_KP_2, "KP2" },
{ GLFW_KEY_KP_3, "KP3" },
{ GLFW_KEY_KP_4, "KP4" },
{ GLFW_KEY_KP_5, "KP5" },
{ GLFW_KEY_KP_6, "KP6" },
{ GLFW_KEY_KP_7, "KP7" },
{ GLFW_KEY_KP_8, "KP8" },
{ GLFW_KEY_KP_9, "KP9" },
{ GLFW_KEY_KP_DECIMAL, "KPDL" },
{ GLFW_KEY_KP_DIVIDE, "KPDV" },
{ GLFW_KEY_KP_MULTIPLY, "KPMU" },
{ GLFW_KEY_KP_SUBTRACT, "KPSU" },
{ GLFW_KEY_KP_ADD, "KPAD" },
{ GLFW_KEY_KP_ENTER, "KPEN" },
{ GLFW_KEY_KP_EQUAL, "KPEQ" },
{ GLFW_KEY_LEFT_SHIFT, "LFSH" },
{ GLFW_KEY_LEFT_CONTROL, "LCTL" },
{ GLFW_KEY_LEFT_ALT, "LALT" },
{ GLFW_KEY_LEFT_SUPER, "LWIN" },
{ GLFW_KEY_RIGHT_SHIFT, "RTSH" },
{ GLFW_KEY_RIGHT_CONTROL, "RCTL" },
{ GLFW_KEY_RIGHT_ALT, "RALT" },
{ GLFW_KEY_RIGHT_SUPER, "RWIN" },
{ GLFW_KEY_MENU, "COMP" }
};
// Find the X11 key code -> GLFW key code mapping
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
{
memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
name[XkbKeyNameLength] = '\0';
int key = GLFW_KEY_UNKNOWN;
// 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;
else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3;
else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4;
else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5;
else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6;
else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7;
else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8;
else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9;
else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0;
else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS;
else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL;
else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q;
else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W;
else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E;
else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R;
else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T;
else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y;
else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U;
else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I;
else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O;
else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P;
else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET;
else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET;
else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A;
else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S;
else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D;
else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F;
else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G;
else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H;
else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J;
else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K;
else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L;
else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON;
else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE;
else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z;
else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X;
else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C;
else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V;
else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B;
else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N;
else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M;
else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA;
else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD;
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;
for (int i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
{
if (strncmp(desc->names->keys[scancode].name,
keymap[i].name,
XkbKeyNameLength) == 0)
{
key = keymap[i].key;
break;
}
}
// Fall back to key aliases in case the key name did not match
for (int i = 0; i < desc->names->num_key_aliases; i++)
{
if (key != GLFW_KEY_UNKNOWN)
break;
if (strncmp(desc->names->key_aliases[i].real,
desc->names->keys[scancode].name,
XkbKeyNameLength) != 0)
{
continue;
}
for (int j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
{
if (strncmp(desc->names->key_aliases[i].alias,
keymap[j].name,
XkbKeyNameLength) == 0)
{
key = keymap[j].key;
break;
}
}
}
_glfw.x11.keycodes[scancode] = key;
}