diff --git a/src/cocoa_init.m b/src/cocoa_init.m index afb1a542..a496cd3e 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -68,6 +68,128 @@ static void changeToResourcesDirectory(void) #endif /* _GLFW_USE_CHDIR */ +// Create key code translation tables +// +static void createKeyTables(void) +{ + memset(_glfw.ns.publicKeys, -1, sizeof(_glfw.ns.publicKeys)); + + _glfw.ns.publicKeys[0x1D] = GLFW_KEY_0; + _glfw.ns.publicKeys[0x12] = GLFW_KEY_1; + _glfw.ns.publicKeys[0x13] = GLFW_KEY_2; + _glfw.ns.publicKeys[0x14] = GLFW_KEY_3; + _glfw.ns.publicKeys[0x15] = GLFW_KEY_4; + _glfw.ns.publicKeys[0x17] = GLFW_KEY_5; + _glfw.ns.publicKeys[0x16] = GLFW_KEY_6; + _glfw.ns.publicKeys[0x1A] = GLFW_KEY_7; + _glfw.ns.publicKeys[0x1C] = GLFW_KEY_8; + _glfw.ns.publicKeys[0x19] = GLFW_KEY_9; + _glfw.ns.publicKeys[0x00] = GLFW_KEY_A; + _glfw.ns.publicKeys[0x0B] = GLFW_KEY_B; + _glfw.ns.publicKeys[0x08] = GLFW_KEY_C; + _glfw.ns.publicKeys[0x02] = GLFW_KEY_D; + _glfw.ns.publicKeys[0x0E] = GLFW_KEY_E; + _glfw.ns.publicKeys[0x03] = GLFW_KEY_F; + _glfw.ns.publicKeys[0x05] = GLFW_KEY_G; + _glfw.ns.publicKeys[0x04] = GLFW_KEY_H; + _glfw.ns.publicKeys[0x22] = GLFW_KEY_I; + _glfw.ns.publicKeys[0x26] = GLFW_KEY_J; + _glfw.ns.publicKeys[0x28] = GLFW_KEY_K; + _glfw.ns.publicKeys[0x25] = GLFW_KEY_L; + _glfw.ns.publicKeys[0x2E] = GLFW_KEY_M; + _glfw.ns.publicKeys[0x2D] = GLFW_KEY_N; + _glfw.ns.publicKeys[0x1F] = GLFW_KEY_O; + _glfw.ns.publicKeys[0x23] = GLFW_KEY_P; + _glfw.ns.publicKeys[0x0C] = GLFW_KEY_Q; + _glfw.ns.publicKeys[0x0F] = GLFW_KEY_R; + _glfw.ns.publicKeys[0x01] = GLFW_KEY_S; + _glfw.ns.publicKeys[0x11] = GLFW_KEY_T; + _glfw.ns.publicKeys[0x20] = GLFW_KEY_U; + _glfw.ns.publicKeys[0x09] = GLFW_KEY_V; + _glfw.ns.publicKeys[0x0D] = GLFW_KEY_W; + _glfw.ns.publicKeys[0x07] = GLFW_KEY_X; + _glfw.ns.publicKeys[0x10] = GLFW_KEY_Y; + _glfw.ns.publicKeys[0x06] = GLFW_KEY_Z; + + _glfw.ns.publicKeys[0x27] = GLFW_KEY_APOSTROPHE; + _glfw.ns.publicKeys[0x2A] = GLFW_KEY_BACKSLASH; + _glfw.ns.publicKeys[0x2B] = GLFW_KEY_COMMA; + _glfw.ns.publicKeys[0x18] = GLFW_KEY_EQUAL; + _glfw.ns.publicKeys[0x32] = GLFW_KEY_GRAVE_ACCENT; + _glfw.ns.publicKeys[0x21] = GLFW_KEY_LEFT_BRACKET; + _glfw.ns.publicKeys[0x1B] = GLFW_KEY_MINUS; + _glfw.ns.publicKeys[0x2F] = GLFW_KEY_PERIOD; + _glfw.ns.publicKeys[0x1E] = GLFW_KEY_RIGHT_BRACKET; + _glfw.ns.publicKeys[0x29] = GLFW_KEY_SEMICOLON; + _glfw.ns.publicKeys[0x2C] = GLFW_KEY_SLASH; + _glfw.ns.publicKeys[0x0A] = GLFW_KEY_WORLD_1; + + _glfw.ns.publicKeys[0x33] = GLFW_KEY_BACKSPACE; + _glfw.ns.publicKeys[0x39] = GLFW_KEY_CAPS_LOCK; + _glfw.ns.publicKeys[0x75] = GLFW_KEY_DELETE; + _glfw.ns.publicKeys[0x7D] = GLFW_KEY_DOWN; + _glfw.ns.publicKeys[0x77] = GLFW_KEY_END; + _glfw.ns.publicKeys[0x24] = GLFW_KEY_ENTER; + _glfw.ns.publicKeys[0x35] = GLFW_KEY_ESCAPE; + _glfw.ns.publicKeys[0x7A] = GLFW_KEY_F1; + _glfw.ns.publicKeys[0x78] = GLFW_KEY_F2; + _glfw.ns.publicKeys[0x63] = GLFW_KEY_F3; + _glfw.ns.publicKeys[0x76] = GLFW_KEY_F4; + _glfw.ns.publicKeys[0x60] = GLFW_KEY_F5; + _glfw.ns.publicKeys[0x61] = GLFW_KEY_F6; + _glfw.ns.publicKeys[0x62] = GLFW_KEY_F7; + _glfw.ns.publicKeys[0x64] = GLFW_KEY_F8; + _glfw.ns.publicKeys[0x65] = GLFW_KEY_F9; + _glfw.ns.publicKeys[0x6D] = GLFW_KEY_F10; + _glfw.ns.publicKeys[0x67] = GLFW_KEY_F11; + _glfw.ns.publicKeys[0x6F] = GLFW_KEY_F12; + _glfw.ns.publicKeys[0x69] = GLFW_KEY_F13; + _glfw.ns.publicKeys[0x6B] = GLFW_KEY_F14; + _glfw.ns.publicKeys[0x71] = GLFW_KEY_F15; + _glfw.ns.publicKeys[0x6A] = GLFW_KEY_F16; + _glfw.ns.publicKeys[0x40] = GLFW_KEY_F17; + _glfw.ns.publicKeys[0x4F] = GLFW_KEY_F18; + _glfw.ns.publicKeys[0x50] = GLFW_KEY_F19; + _glfw.ns.publicKeys[0x5A] = GLFW_KEY_F20; + _glfw.ns.publicKeys[0x73] = GLFW_KEY_HOME; + _glfw.ns.publicKeys[0x72] = GLFW_KEY_INSERT; + _glfw.ns.publicKeys[0x7B] = GLFW_KEY_LEFT; + _glfw.ns.publicKeys[0x3A] = GLFW_KEY_LEFT_ALT; + _glfw.ns.publicKeys[0x3B] = GLFW_KEY_LEFT_CONTROL; + _glfw.ns.publicKeys[0x38] = GLFW_KEY_LEFT_SHIFT; + _glfw.ns.publicKeys[0x37] = GLFW_KEY_LEFT_SUPER; + _glfw.ns.publicKeys[0x6E] = GLFW_KEY_MENU; + _glfw.ns.publicKeys[0x47] = GLFW_KEY_NUM_LOCK; + _glfw.ns.publicKeys[0x79] = GLFW_KEY_PAGE_DOWN; + _glfw.ns.publicKeys[0x74] = GLFW_KEY_PAGE_UP; + _glfw.ns.publicKeys[0x7C] = GLFW_KEY_RIGHT; + _glfw.ns.publicKeys[0x3D] = GLFW_KEY_RIGHT_ALT; + _glfw.ns.publicKeys[0x3E] = GLFW_KEY_RIGHT_CONTROL; + _glfw.ns.publicKeys[0x3C] = GLFW_KEY_RIGHT_SHIFT; + _glfw.ns.publicKeys[0x36] = GLFW_KEY_RIGHT_SUPER; + _glfw.ns.publicKeys[0x31] = GLFW_KEY_SPACE; + _glfw.ns.publicKeys[0x30] = GLFW_KEY_TAB; + _glfw.ns.publicKeys[0x7E] = GLFW_KEY_UP; + + _glfw.ns.publicKeys[0x52] = GLFW_KEY_KP_0; + _glfw.ns.publicKeys[0x53] = GLFW_KEY_KP_1; + _glfw.ns.publicKeys[0x54] = GLFW_KEY_KP_2; + _glfw.ns.publicKeys[0x55] = GLFW_KEY_KP_3; + _glfw.ns.publicKeys[0x56] = GLFW_KEY_KP_4; + _glfw.ns.publicKeys[0x57] = GLFW_KEY_KP_5; + _glfw.ns.publicKeys[0x58] = GLFW_KEY_KP_6; + _glfw.ns.publicKeys[0x59] = GLFW_KEY_KP_7; + _glfw.ns.publicKeys[0x5B] = GLFW_KEY_KP_8; + _glfw.ns.publicKeys[0x5C] = GLFW_KEY_KP_9; + _glfw.ns.publicKeys[0x45] = GLFW_KEY_KP_ADD; + _glfw.ns.publicKeys[0x41] = GLFW_KEY_KP_DECIMAL; + _glfw.ns.publicKeys[0x4B] = GLFW_KEY_KP_DIVIDE; + _glfw.ns.publicKeys[0x4C] = GLFW_KEY_KP_ENTER; + _glfw.ns.publicKeys[0x51] = GLFW_KEY_KP_EQUAL; + _glfw.ns.publicKeys[0x43] = GLFW_KEY_KP_MULTIPLY; + _glfw.ns.publicKeys[0x4E] = GLFW_KEY_KP_SUBTRACT; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -81,6 +203,8 @@ int _glfwPlatformInit(void) changeToResourcesDirectory(); #endif + createKeyTables(); + _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); if (!_glfw.ns.eventSource) return GL_FALSE; diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 6b768c78..f977f220 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -76,6 +76,7 @@ typedef struct _GLFWlibraryNS id autoreleasePool; id cursor; + short int publicKeys[256]; char* clipboardString; } _GLFWlibraryNS; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 84c3a331..b73bc00b 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -263,143 +263,10 @@ static int translateFlags(NSUInteger flags) // static int translateKey(unsigned int key) { - // Keyboard symbol translation table - static const unsigned int table[128] = - { - /* 00 */ GLFW_KEY_A, - /* 01 */ GLFW_KEY_S, - /* 02 */ GLFW_KEY_D, - /* 03 */ GLFW_KEY_F, - /* 04 */ GLFW_KEY_H, - /* 05 */ GLFW_KEY_G, - /* 06 */ GLFW_KEY_Z, - /* 07 */ GLFW_KEY_X, - /* 08 */ GLFW_KEY_C, - /* 09 */ GLFW_KEY_V, - /* 0a */ GLFW_KEY_WORLD_1, - /* 0b */ GLFW_KEY_B, - /* 0c */ GLFW_KEY_Q, - /* 0d */ GLFW_KEY_W, - /* 0e */ GLFW_KEY_E, - /* 0f */ GLFW_KEY_R, - /* 10 */ GLFW_KEY_Y, - /* 11 */ GLFW_KEY_T, - /* 12 */ GLFW_KEY_1, - /* 13 */ GLFW_KEY_2, - /* 14 */ GLFW_KEY_3, - /* 15 */ GLFW_KEY_4, - /* 16 */ GLFW_KEY_6, - /* 17 */ GLFW_KEY_5, - /* 18 */ GLFW_KEY_EQUAL, - /* 19 */ GLFW_KEY_9, - /* 1a */ GLFW_KEY_7, - /* 1b */ GLFW_KEY_MINUS, - /* 1c */ GLFW_KEY_8, - /* 1d */ GLFW_KEY_0, - /* 1e */ GLFW_KEY_RIGHT_BRACKET, - /* 1f */ GLFW_KEY_O, - /* 20 */ GLFW_KEY_U, - /* 21 */ GLFW_KEY_LEFT_BRACKET, - /* 22 */ GLFW_KEY_I, - /* 23 */ GLFW_KEY_P, - /* 24 */ GLFW_KEY_ENTER, - /* 25 */ GLFW_KEY_L, - /* 26 */ GLFW_KEY_J, - /* 27 */ GLFW_KEY_APOSTROPHE, - /* 28 */ GLFW_KEY_K, - /* 29 */ GLFW_KEY_SEMICOLON, - /* 2a */ GLFW_KEY_BACKSLASH, - /* 2b */ GLFW_KEY_COMMA, - /* 2c */ GLFW_KEY_SLASH, - /* 2d */ GLFW_KEY_N, - /* 2e */ GLFW_KEY_M, - /* 2f */ GLFW_KEY_PERIOD, - /* 30 */ GLFW_KEY_TAB, - /* 31 */ GLFW_KEY_SPACE, - /* 32 */ GLFW_KEY_GRAVE_ACCENT, - /* 33 */ GLFW_KEY_BACKSPACE, - /* 34 */ GLFW_KEY_UNKNOWN, - /* 35 */ GLFW_KEY_ESCAPE, - /* 36 */ GLFW_KEY_RIGHT_SUPER, - /* 37 */ GLFW_KEY_LEFT_SUPER, - /* 38 */ GLFW_KEY_LEFT_SHIFT, - /* 39 */ GLFW_KEY_CAPS_LOCK, - /* 3a */ GLFW_KEY_LEFT_ALT, - /* 3b */ GLFW_KEY_LEFT_CONTROL, - /* 3c */ GLFW_KEY_RIGHT_SHIFT, - /* 3d */ GLFW_KEY_RIGHT_ALT, - /* 3e */ GLFW_KEY_RIGHT_CONTROL, - /* 3f */ GLFW_KEY_UNKNOWN, /* Function */ - /* 40 */ GLFW_KEY_F17, - /* 41 */ GLFW_KEY_KP_DECIMAL, - /* 42 */ GLFW_KEY_UNKNOWN, - /* 43 */ GLFW_KEY_KP_MULTIPLY, - /* 44 */ GLFW_KEY_UNKNOWN, - /* 45 */ GLFW_KEY_KP_ADD, - /* 46 */ GLFW_KEY_UNKNOWN, - /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */ - /* 48 */ GLFW_KEY_UNKNOWN, /* VolumeUp */ - /* 49 */ GLFW_KEY_UNKNOWN, /* VolumeDown */ - /* 4a */ GLFW_KEY_UNKNOWN, /* Mute */ - /* 4b */ GLFW_KEY_KP_DIVIDE, - /* 4c */ GLFW_KEY_KP_ENTER, - /* 4d */ GLFW_KEY_UNKNOWN, - /* 4e */ GLFW_KEY_KP_SUBTRACT, - /* 4f */ GLFW_KEY_F18, - /* 50 */ GLFW_KEY_F19, - /* 51 */ GLFW_KEY_KP_EQUAL, - /* 52 */ GLFW_KEY_KP_0, - /* 53 */ GLFW_KEY_KP_1, - /* 54 */ GLFW_KEY_KP_2, - /* 55 */ GLFW_KEY_KP_3, - /* 56 */ GLFW_KEY_KP_4, - /* 57 */ GLFW_KEY_KP_5, - /* 58 */ GLFW_KEY_KP_6, - /* 59 */ GLFW_KEY_KP_7, - /* 5a */ GLFW_KEY_F20, - /* 5b */ GLFW_KEY_KP_8, - /* 5c */ GLFW_KEY_KP_9, - /* 5d */ GLFW_KEY_UNKNOWN, - /* 5e */ GLFW_KEY_UNKNOWN, - /* 5f */ GLFW_KEY_UNKNOWN, - /* 60 */ GLFW_KEY_F5, - /* 61 */ GLFW_KEY_F6, - /* 62 */ GLFW_KEY_F7, - /* 63 */ GLFW_KEY_F3, - /* 64 */ GLFW_KEY_F8, - /* 65 */ GLFW_KEY_F9, - /* 66 */ GLFW_KEY_UNKNOWN, - /* 67 */ GLFW_KEY_F11, - /* 68 */ GLFW_KEY_UNKNOWN, - /* 69 */ GLFW_KEY_F13, - /* 6a */ GLFW_KEY_F16, - /* 6b */ GLFW_KEY_F14, - /* 6c */ GLFW_KEY_UNKNOWN, - /* 6d */ GLFW_KEY_F10, - /* 6e */ GLFW_KEY_UNKNOWN, - /* 6f */ GLFW_KEY_F12, - /* 70 */ GLFW_KEY_UNKNOWN, - /* 71 */ GLFW_KEY_F15, - /* 72 */ GLFW_KEY_INSERT, /* Really Help... */ - /* 73 */ GLFW_KEY_HOME, - /* 74 */ GLFW_KEY_PAGE_UP, - /* 75 */ GLFW_KEY_DELETE, - /* 76 */ GLFW_KEY_F4, - /* 77 */ GLFW_KEY_END, - /* 78 */ GLFW_KEY_F2, - /* 79 */ GLFW_KEY_PAGE_DOWN, - /* 7a */ GLFW_KEY_F1, - /* 7b */ GLFW_KEY_LEFT, - /* 7c */ GLFW_KEY_RIGHT, - /* 7d */ GLFW_KEY_DOWN, - /* 7e */ GLFW_KEY_UP, - /* 7f */ GLFW_KEY_UNKNOWN, - }; - - if (key >= 128) + if (key >= sizeof(_glfw.ns.publicKeys) / sizeof(_glfw.ns.publicKeys[0])) return GLFW_KEY_UNKNOWN; - return table[key]; + return _glfw.ns.publicKeys[key]; } @@ -605,7 +472,13 @@ static int translateKey(unsigned int key) const int plain = !(mods & GLFW_MOD_SUPER); for (i = 0; i < length; i++) - _glfwInputChar(window, [characters characterAtIndex:i], mods, plain); + { + const unichar codepoint = [characters characterAtIndex:i]; + if ((codepoint & 0xff00) == 0xf700) + continue; + + _glfwInputChar(window, codepoint, mods, plain); + } } - (void)flagsChanged:(NSEvent *)event diff --git a/src/win32_init.c b/src/win32_init.c index f84754f8..a963689d 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -120,6 +120,134 @@ static void terminateLibraries(void) FreeLibrary(_glfw.win32.dwmapi.instance); } +// Create key code translation tables +// +static void createKeyTables(void) +{ + memset(_glfw.win32.publicKeys, -1, sizeof(_glfw.win32.publicKeys)); + + _glfw.win32.publicKeys[0x00B] = GLFW_KEY_0; + _glfw.win32.publicKeys[0x002] = GLFW_KEY_1; + _glfw.win32.publicKeys[0x003] = GLFW_KEY_2; + _glfw.win32.publicKeys[0x004] = GLFW_KEY_3; + _glfw.win32.publicKeys[0x005] = GLFW_KEY_4; + _glfw.win32.publicKeys[0x006] = GLFW_KEY_5; + _glfw.win32.publicKeys[0x007] = GLFW_KEY_6; + _glfw.win32.publicKeys[0x008] = GLFW_KEY_7; + _glfw.win32.publicKeys[0x009] = GLFW_KEY_8; + _glfw.win32.publicKeys[0x00A] = GLFW_KEY_9; + _glfw.win32.publicKeys[0x01E] = GLFW_KEY_A; + _glfw.win32.publicKeys[0x030] = GLFW_KEY_B; + _glfw.win32.publicKeys[0x02E] = GLFW_KEY_C; + _glfw.win32.publicKeys[0x020] = GLFW_KEY_D; + _glfw.win32.publicKeys[0x012] = GLFW_KEY_E; + _glfw.win32.publicKeys[0x021] = GLFW_KEY_F; + _glfw.win32.publicKeys[0x022] = GLFW_KEY_G; + _glfw.win32.publicKeys[0x023] = GLFW_KEY_H; + _glfw.win32.publicKeys[0x017] = GLFW_KEY_I; + _glfw.win32.publicKeys[0x024] = GLFW_KEY_J; + _glfw.win32.publicKeys[0x025] = GLFW_KEY_K; + _glfw.win32.publicKeys[0x026] = GLFW_KEY_L; + _glfw.win32.publicKeys[0x032] = GLFW_KEY_M; + _glfw.win32.publicKeys[0x031] = GLFW_KEY_N; + _glfw.win32.publicKeys[0x018] = GLFW_KEY_O; + _glfw.win32.publicKeys[0x019] = GLFW_KEY_P; + _glfw.win32.publicKeys[0x010] = GLFW_KEY_Q; + _glfw.win32.publicKeys[0x013] = GLFW_KEY_R; + _glfw.win32.publicKeys[0x01F] = GLFW_KEY_S; + _glfw.win32.publicKeys[0x014] = GLFW_KEY_T; + _glfw.win32.publicKeys[0x016] = GLFW_KEY_U; + _glfw.win32.publicKeys[0x02F] = GLFW_KEY_V; + _glfw.win32.publicKeys[0x011] = GLFW_KEY_W; + _glfw.win32.publicKeys[0x02D] = GLFW_KEY_X; + _glfw.win32.publicKeys[0x015] = GLFW_KEY_Y; + _glfw.win32.publicKeys[0x02C] = GLFW_KEY_Z; + + _glfw.win32.publicKeys[0x028] = GLFW_KEY_APOSTROPHE; + _glfw.win32.publicKeys[0x02B] = GLFW_KEY_BACKSLASH; + _glfw.win32.publicKeys[0x033] = GLFW_KEY_COMMA; + _glfw.win32.publicKeys[0x00D] = GLFW_KEY_EQUAL; + _glfw.win32.publicKeys[0x029] = GLFW_KEY_GRAVE_ACCENT; + _glfw.win32.publicKeys[0x01A] = GLFW_KEY_LEFT_BRACKET; + _glfw.win32.publicKeys[0x00C] = GLFW_KEY_MINUS; + _glfw.win32.publicKeys[0x034] = GLFW_KEY_PERIOD; + _glfw.win32.publicKeys[0x01B] = GLFW_KEY_RIGHT_BRACKET; + _glfw.win32.publicKeys[0x027] = GLFW_KEY_SEMICOLON; + _glfw.win32.publicKeys[0x035] = GLFW_KEY_SLASH; + _glfw.win32.publicKeys[0x056] = GLFW_KEY_WORLD_2; + + _glfw.win32.publicKeys[0x00E] = GLFW_KEY_BACKSPACE; + _glfw.win32.publicKeys[0x153] = GLFW_KEY_DELETE; + _glfw.win32.publicKeys[0x14F] = GLFW_KEY_END; + _glfw.win32.publicKeys[0x01C] = GLFW_KEY_ENTER; + _glfw.win32.publicKeys[0x001] = GLFW_KEY_ESCAPE; + _glfw.win32.publicKeys[0x147] = GLFW_KEY_HOME; + _glfw.win32.publicKeys[0x152] = GLFW_KEY_INSERT; + _glfw.win32.publicKeys[0x15D] = GLFW_KEY_MENU; + _glfw.win32.publicKeys[0x151] = GLFW_KEY_PAGE_DOWN; + _glfw.win32.publicKeys[0x149] = GLFW_KEY_PAGE_UP; + _glfw.win32.publicKeys[0x045] = GLFW_KEY_PAUSE; + _glfw.win32.publicKeys[0x039] = GLFW_KEY_SPACE; + _glfw.win32.publicKeys[0x00F] = GLFW_KEY_TAB; + _glfw.win32.publicKeys[0x03A] = GLFW_KEY_CAPS_LOCK; + _glfw.win32.publicKeys[0x145] = GLFW_KEY_NUM_LOCK; + _glfw.win32.publicKeys[0x046] = GLFW_KEY_SCROLL_LOCK; + _glfw.win32.publicKeys[0x03B] = GLFW_KEY_F1; + _glfw.win32.publicKeys[0x03C] = GLFW_KEY_F2; + _glfw.win32.publicKeys[0x03D] = GLFW_KEY_F3; + _glfw.win32.publicKeys[0x03E] = GLFW_KEY_F4; + _glfw.win32.publicKeys[0x03F] = GLFW_KEY_F5; + _glfw.win32.publicKeys[0x040] = GLFW_KEY_F6; + _glfw.win32.publicKeys[0x041] = GLFW_KEY_F7; + _glfw.win32.publicKeys[0x042] = GLFW_KEY_F8; + _glfw.win32.publicKeys[0x043] = GLFW_KEY_F9; + _glfw.win32.publicKeys[0x044] = GLFW_KEY_F10; + _glfw.win32.publicKeys[0x057] = GLFW_KEY_F11; + _glfw.win32.publicKeys[0x058] = GLFW_KEY_F12; + _glfw.win32.publicKeys[0x064] = GLFW_KEY_F13; + _glfw.win32.publicKeys[0x065] = GLFW_KEY_F14; + _glfw.win32.publicKeys[0x066] = GLFW_KEY_F15; + _glfw.win32.publicKeys[0x067] = GLFW_KEY_F16; + _glfw.win32.publicKeys[0x068] = GLFW_KEY_F17; + _glfw.win32.publicKeys[0x069] = GLFW_KEY_F18; + _glfw.win32.publicKeys[0x06A] = GLFW_KEY_F19; + _glfw.win32.publicKeys[0x06B] = GLFW_KEY_F20; + _glfw.win32.publicKeys[0x06C] = GLFW_KEY_F21; + _glfw.win32.publicKeys[0x06D] = GLFW_KEY_F22; + _glfw.win32.publicKeys[0x06E] = GLFW_KEY_F23; + _glfw.win32.publicKeys[0x076] = GLFW_KEY_F24; + _glfw.win32.publicKeys[0x038] = GLFW_KEY_LEFT_ALT; + _glfw.win32.publicKeys[0x01D] = GLFW_KEY_LEFT_CONTROL; + _glfw.win32.publicKeys[0x02A] = GLFW_KEY_LEFT_SHIFT; + _glfw.win32.publicKeys[0x15B] = GLFW_KEY_LEFT_SUPER; + _glfw.win32.publicKeys[0x137] = GLFW_KEY_PRINT_SCREEN; + _glfw.win32.publicKeys[0x138] = GLFW_KEY_RIGHT_ALT; + _glfw.win32.publicKeys[0x11D] = GLFW_KEY_RIGHT_CONTROL; + _glfw.win32.publicKeys[0x036] = GLFW_KEY_RIGHT_SHIFT; + _glfw.win32.publicKeys[0x15C] = GLFW_KEY_RIGHT_SUPER; + _glfw.win32.publicKeys[0x150] = GLFW_KEY_DOWN; + _glfw.win32.publicKeys[0x14B] = GLFW_KEY_LEFT; + _glfw.win32.publicKeys[0x14D] = GLFW_KEY_RIGHT; + _glfw.win32.publicKeys[0x148] = GLFW_KEY_UP; + + _glfw.win32.publicKeys[0x052] = GLFW_KEY_KP_0; + _glfw.win32.publicKeys[0x04F] = GLFW_KEY_KP_1; + _glfw.win32.publicKeys[0x050] = GLFW_KEY_KP_2; + _glfw.win32.publicKeys[0x051] = GLFW_KEY_KP_3; + _glfw.win32.publicKeys[0x04B] = GLFW_KEY_KP_4; + _glfw.win32.publicKeys[0x04C] = GLFW_KEY_KP_5; + _glfw.win32.publicKeys[0x04D] = GLFW_KEY_KP_6; + _glfw.win32.publicKeys[0x047] = GLFW_KEY_KP_7; + _glfw.win32.publicKeys[0x048] = GLFW_KEY_KP_8; + _glfw.win32.publicKeys[0x049] = GLFW_KEY_KP_9; + _glfw.win32.publicKeys[0x04E] = GLFW_KEY_KP_ADD; + _glfw.win32.publicKeys[0x053] = GLFW_KEY_KP_DECIMAL; + _glfw.win32.publicKeys[0x135] = GLFW_KEY_KP_DIVIDE; + _glfw.win32.publicKeys[0x11C] = GLFW_KEY_KP_ENTER; + _glfw.win32.publicKeys[0x037] = GLFW_KEY_KP_MULTIPLY; + _glfw.win32.publicKeys[0x04A] = GLFW_KEY_KP_SUBTRACT; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// @@ -202,6 +330,8 @@ int _glfwPlatformInit(void) if (!initLibraries()) return GL_FALSE; + createKeyTables(); + if (_glfw_SetProcessDPIAware) _glfw_SetProcessDPIAware(); diff --git a/src/win32_platform.h b/src/win32_platform.h index 5eb61d37..564c8611 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -172,6 +172,7 @@ typedef struct _GLFWlibraryWin32 { DWORD foregroundLockTimeout; char* clipboardString; + short int publicKeys[512]; // winmm.dll struct { diff --git a/src/win32_window.c b/src/win32_window.c index f7c531dd..edae668a 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -152,242 +152,44 @@ static int getAsyncKeyMods(void) // static int translateKey(WPARAM wParam, LPARAM lParam) { - // Check 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. - if ((HIWORD(lParam) & 0x100) == 0) + if (wParam == VK_CONTROL) { - switch (MapVirtualKey(HIWORD(lParam) & 0xFF, 1)) - { - case VK_INSERT: return GLFW_KEY_KP_0; - case VK_END: return GLFW_KEY_KP_1; - case VK_DOWN: return GLFW_KEY_KP_2; - case VK_NEXT: return GLFW_KEY_KP_3; - case VK_LEFT: return GLFW_KEY_KP_4; - case VK_CLEAR: return GLFW_KEY_KP_5; - case VK_RIGHT: return GLFW_KEY_KP_6; - case VK_HOME: return GLFW_KEY_KP_7; - case VK_UP: return GLFW_KEY_KP_8; - case VK_PRIOR: return GLFW_KEY_KP_9; - case VK_DIVIDE: return GLFW_KEY_KP_DIVIDE; - case VK_MULTIPLY: return GLFW_KEY_KP_MULTIPLY; - case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT; - case VK_ADD: return GLFW_KEY_KP_ADD; - case VK_DELETE: return GLFW_KEY_KP_DECIMAL; - default: break; - } - } - - switch (HIWORD(lParam) & 0xFF) - { - // handle printable chars except space in a language independent way, - // using scancodes rather than virtual keys - // as virtual keys are language dependent. - // Printable keys are mapped according to US layout. - - // Row 0: - case 0x29: return GLFW_KEY_GRAVE_ACCENT; - case 0x02: return GLFW_KEY_1; - case 0x03: return GLFW_KEY_2; - case 0x04: return GLFW_KEY_3; - case 0x05: return GLFW_KEY_4; - case 0x06: return GLFW_KEY_5; - case 0x07: return GLFW_KEY_6; - case 0x08: return GLFW_KEY_7; - case 0x09: return GLFW_KEY_8; - case 0x0A: return GLFW_KEY_9; - case 0x0B: return GLFW_KEY_0; - case 0x0C: return GLFW_KEY_MINUS; - case 0x0D: return GLFW_KEY_EQUAL; - - // Row 1: - case 0x10: return GLFW_KEY_Q; - case 0x11: return GLFW_KEY_W; - case 0x12: return GLFW_KEY_E; - case 0x13: return GLFW_KEY_R; - case 0x14: return GLFW_KEY_T; - case 0x15: return GLFW_KEY_Y; - case 0x16: return GLFW_KEY_U; - case 0x17: return GLFW_KEY_I; - case 0x18: return GLFW_KEY_O; - case 0x19: return GLFW_KEY_P; - case 0x1A: return GLFW_KEY_LEFT_BRACKET; - case 0x1B: return GLFW_KEY_RIGHT_BRACKET; - // We do not map 0x2B as this is only on US - use vKeys for this to prevent confusion with 0x56 - - // Row 2: - case 0x1E: return GLFW_KEY_A; - case 0x1F: return GLFW_KEY_S; - case 0x20: return GLFW_KEY_D; - case 0x21: return GLFW_KEY_F; - case 0x22: return GLFW_KEY_G; - case 0x23: return GLFW_KEY_H; - case 0x24: return GLFW_KEY_J; - case 0x25: return GLFW_KEY_K; - case 0x26: return GLFW_KEY_L; - case 0x27: return GLFW_KEY_SEMICOLON; - case 0x28: return GLFW_KEY_APOSTROPHE; - - // Row 3: - case 0x2C: return GLFW_KEY_Z; - case 0x2D: return GLFW_KEY_X; - case 0x2E: return GLFW_KEY_C; - case 0x2F: return GLFW_KEY_V; - case 0x30: return GLFW_KEY_B; - case 0x31: return GLFW_KEY_N; - case 0x32: return GLFW_KEY_M; - case 0x33: return GLFW_KEY_COMMA; - case 0x34: return GLFW_KEY_PERIOD; - case 0x35: return GLFW_KEY_SLASH; - default: break; - } - - // Check which key was pressed or released - switch (wParam) - { - // The SHIFT keys require special handling - case VK_SHIFT: - { - // Compare scan code for this key with that of VK_RSHIFT in - // order to determine which shift key was pressed (left or - // right) - const DWORD scancode = MapVirtualKey(VK_RSHIFT, 0); - if ((DWORD) ((lParam & 0x01ff0000) >> 16) == scancode) - return GLFW_KEY_RIGHT_SHIFT; - - return GLFW_KEY_LEFT_SHIFT; - } - // The CTRL keys require special handling - case VK_CONTROL: + + MSG next; + DWORD time; + + // Is this an extended key (i.e. right key)? + if (lParam & 0x01000000) + return GLFW_KEY_RIGHT_CONTROL; + + // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only + // want the RALT message, so we try to see if the next message + // is a RALT message. In that case, this is a false LCTRL! + time = GetMessageTime(); + + if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE)) { - MSG next; - DWORD time; - - // Is this an extended key (i.e. right key)? - if (lParam & 0x01000000) - return GLFW_KEY_RIGHT_CONTROL; - - // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only - // want the RALT message, so we try to see if the next message - // is a RALT message. In that case, this is a false LCTRL! - time = GetMessageTime(); - - if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE)) + if (next.message == WM_KEYDOWN || + next.message == WM_SYSKEYDOWN || + next.message == WM_KEYUP || + next.message == WM_SYSKEYUP) { - if (next.message == WM_KEYDOWN || - next.message == WM_SYSKEYDOWN || - next.message == WM_KEYUP || - next.message == WM_SYSKEYUP) + if (next.wParam == VK_MENU && + (next.lParam & 0x01000000) && + next.time == time) { - if (next.wParam == VK_MENU && - (next.lParam & 0x01000000) && - next.time == time) - { - // Next message is a RALT down message, which - // means that this is not a proper LCTRL message - return _GLFW_KEY_INVALID; - } + // Next message is a RALT down message, which + // means that this is not a proper LCTRL message + return _GLFW_KEY_INVALID; } } - - return GLFW_KEY_LEFT_CONTROL; } - // The ALT keys require special handling - case VK_MENU: - { - // Is this an extended key (i.e. right key)? - if (lParam & 0x01000000) - return GLFW_KEY_RIGHT_ALT; - - return GLFW_KEY_LEFT_ALT; - } - - // The ENTER keys require special handling - case VK_RETURN: - { - // Is this an extended key (i.e. right key)? - if (lParam & 0x01000000) - return GLFW_KEY_KP_ENTER; - - return GLFW_KEY_ENTER; - } - - // Funcion keys (non-printable keys) - case VK_ESCAPE: return GLFW_KEY_ESCAPE; - case VK_TAB: return GLFW_KEY_TAB; - case VK_BACK: return GLFW_KEY_BACKSPACE; - case VK_HOME: return GLFW_KEY_HOME; - case VK_END: return GLFW_KEY_END; - case VK_PRIOR: return GLFW_KEY_PAGE_UP; - case VK_NEXT: return GLFW_KEY_PAGE_DOWN; - case VK_INSERT: return GLFW_KEY_INSERT; - case VK_DELETE: return GLFW_KEY_DELETE; - case VK_LEFT: return GLFW_KEY_LEFT; - case VK_UP: return GLFW_KEY_UP; - case VK_RIGHT: return GLFW_KEY_RIGHT; - case VK_DOWN: return GLFW_KEY_DOWN; - case VK_F1: return GLFW_KEY_F1; - case VK_F2: return GLFW_KEY_F2; - case VK_F3: return GLFW_KEY_F3; - case VK_F4: return GLFW_KEY_F4; - case VK_F5: return GLFW_KEY_F5; - case VK_F6: return GLFW_KEY_F6; - case VK_F7: return GLFW_KEY_F7; - case VK_F8: return GLFW_KEY_F8; - case VK_F9: return GLFW_KEY_F9; - case VK_F10: return GLFW_KEY_F10; - case VK_F11: return GLFW_KEY_F11; - case VK_F12: return GLFW_KEY_F12; - case VK_F13: return GLFW_KEY_F13; - case VK_F14: return GLFW_KEY_F14; - case VK_F15: return GLFW_KEY_F15; - case VK_F16: return GLFW_KEY_F16; - case VK_F17: return GLFW_KEY_F17; - case VK_F18: return GLFW_KEY_F18; - case VK_F19: return GLFW_KEY_F19; - case VK_F20: return GLFW_KEY_F20; - case VK_F21: return GLFW_KEY_F21; - case VK_F22: return GLFW_KEY_F22; - case VK_F23: return GLFW_KEY_F23; - case VK_F24: return GLFW_KEY_F24; - case VK_NUMLOCK: return GLFW_KEY_NUM_LOCK; - case VK_CAPITAL: return GLFW_KEY_CAPS_LOCK; - case VK_SNAPSHOT: return GLFW_KEY_PRINT_SCREEN; - case VK_SCROLL: return GLFW_KEY_SCROLL_LOCK; - case VK_PAUSE: return GLFW_KEY_PAUSE; - case VK_LWIN: return GLFW_KEY_LEFT_SUPER; - case VK_RWIN: return GLFW_KEY_RIGHT_SUPER; - case VK_APPS: return GLFW_KEY_MENU; - - // Numeric keypad - case VK_NUMPAD0: return GLFW_KEY_KP_0; - case VK_NUMPAD1: return GLFW_KEY_KP_1; - case VK_NUMPAD2: return GLFW_KEY_KP_2; - case VK_NUMPAD3: return GLFW_KEY_KP_3; - case VK_NUMPAD4: return GLFW_KEY_KP_4; - case VK_NUMPAD5: return GLFW_KEY_KP_5; - case VK_NUMPAD6: return GLFW_KEY_KP_6; - case VK_NUMPAD7: return GLFW_KEY_KP_7; - case VK_NUMPAD8: return GLFW_KEY_KP_8; - case VK_NUMPAD9: return GLFW_KEY_KP_9; - case VK_DIVIDE: return GLFW_KEY_KP_DIVIDE; - case VK_MULTIPLY: return GLFW_KEY_KP_MULTIPLY; - case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT; - case VK_ADD: return GLFW_KEY_KP_ADD; - case VK_DECIMAL: return GLFW_KEY_KP_DECIMAL; - - // Printable keys are mapped according to US layout - case VK_SPACE: return GLFW_KEY_SPACE; - case 0xDC: return GLFW_KEY_BACKSLASH; - case 0xDF: return GLFW_KEY_WORLD_1; - case 0xE2: return GLFW_KEY_WORLD_2; - default: break; + return GLFW_KEY_LEFT_CONTROL; } - // No matching translation was found - return GLFW_KEY_UNKNOWN; + return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF]; } // Enter fullscreen mode diff --git a/src/x11_init.c b/src/x11_init.c index ea0b6934..7430765c 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -37,12 +37,12 @@ // Translate an X11 key code to a GLFW key code. // -static int translateKey(int keyCode) +static int translateKey(int scancode) { int keySym; // Valid key code range is [8,255], according to the XLib manual - if (keyCode < 8 || keyCode > 255) + if (scancode < 8 || scancode > 255) return GLFW_KEY_UNKNOWN; if (_glfw.x11.xkb.available) @@ -51,7 +51,7 @@ static int translateKey(int keyCode) // 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, keyCode, 0, 1); + keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1); switch (keySym) { case XK_KP_0: return GLFW_KEY_KP_0; @@ -74,14 +74,14 @@ static int translateKey(int keyCode) // Now try pimary keysym for function keys (non-printable keys). These // should not be layout dependent (i.e. US layout and international // layouts should give the same result). - keySym = XkbKeycodeToKeysym(_glfw.x11.display, keyCode, 0, 0); + keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0); } else { int dummy; KeySym* keySyms; - keySyms = XGetKeyboardMapping(_glfw.x11.display, keyCode, 1, &dummy); + keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy); keySym = keySyms[0]; XFree(keySyms); } @@ -226,106 +226,97 @@ static int translateKey(int keyCode) return GLFW_KEY_UNKNOWN; } -// Update the key code LUT +// Create key code translation tables // -static void updateKeyCodeLUT(void) +static void createKeyTables(void) { - int i, keyCode, keyCodeGLFW; - char name[XkbKeyNameLength + 1]; - XkbDescPtr descr; + int scancode, key; - // Clear the LUT - for (keyCode = 0; keyCode < 256; keyCode++) - _glfw.x11.keyCodeLUT[keyCode] = GLFW_KEY_UNKNOWN; + memset(_glfw.x11.publicKeys, -1, sizeof(_glfw.x11.publicKeys)); if (_glfw.x11.xkb.available) { // Use XKB to determine physical key locations independently of the current // keyboard layout - // Get keyboard description - descr = XkbGetKeyboard(_glfw.x11.display, - XkbAllComponentsMask, - XkbUseCoreKbd); + char name[XkbKeyNameLength + 1]; + XkbDescPtr descr = XkbGetKeyboard(_glfw.x11.display, + XkbAllComponentsMask, + XkbUseCoreKbd); // Find the X11 key code -> GLFW key code mapping - for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode) + for (scancode = descr->min_key_code; scancode <= descr->max_key_code; scancode++) { - // Get the key name - for (i = 0; i < XkbKeyNameLength; i++) - name[i] = descr->names->keys[keyCode].name[i]; - + memcpy(name, descr->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. - if (strcmp(name, "TLDE") == 0) keyCodeGLFW = GLFW_KEY_GRAVE_ACCENT; - else if (strcmp(name, "AE01") == 0) keyCodeGLFW = GLFW_KEY_1; - else if (strcmp(name, "AE02") == 0) keyCodeGLFW = GLFW_KEY_2; - else if (strcmp(name, "AE03") == 0) keyCodeGLFW = GLFW_KEY_3; - else if (strcmp(name, "AE04") == 0) keyCodeGLFW = GLFW_KEY_4; - else if (strcmp(name, "AE05") == 0) keyCodeGLFW = GLFW_KEY_5; - else if (strcmp(name, "AE06") == 0) keyCodeGLFW = GLFW_KEY_6; - else if (strcmp(name, "AE07") == 0) keyCodeGLFW = GLFW_KEY_7; - else if (strcmp(name, "AE08") == 0) keyCodeGLFW = GLFW_KEY_8; - else if (strcmp(name, "AE09") == 0) keyCodeGLFW = GLFW_KEY_9; - else if (strcmp(name, "AE10") == 0) keyCodeGLFW = GLFW_KEY_0; - else if (strcmp(name, "AE11") == 0) keyCodeGLFW = GLFW_KEY_MINUS; - else if (strcmp(name, "AE12") == 0) keyCodeGLFW = GLFW_KEY_EQUAL; - else if (strcmp(name, "AD01") == 0) keyCodeGLFW = GLFW_KEY_Q; - else if (strcmp(name, "AD02") == 0) keyCodeGLFW = GLFW_KEY_W; - else if (strcmp(name, "AD03") == 0) keyCodeGLFW = GLFW_KEY_E; - else if (strcmp(name, "AD04") == 0) keyCodeGLFW = GLFW_KEY_R; - else if (strcmp(name, "AD05") == 0) keyCodeGLFW = GLFW_KEY_T; - else if (strcmp(name, "AD06") == 0) keyCodeGLFW = GLFW_KEY_Y; - else if (strcmp(name, "AD07") == 0) keyCodeGLFW = GLFW_KEY_U; - else if (strcmp(name, "AD08") == 0) keyCodeGLFW = GLFW_KEY_I; - else if (strcmp(name, "AD09") == 0) keyCodeGLFW = GLFW_KEY_O; - else if (strcmp(name, "AD10") == 0) keyCodeGLFW = GLFW_KEY_P; - else if (strcmp(name, "AD11") == 0) keyCodeGLFW = GLFW_KEY_LEFT_BRACKET; - else if (strcmp(name, "AD12") == 0) keyCodeGLFW = GLFW_KEY_RIGHT_BRACKET; - else if (strcmp(name, "AC01") == 0) keyCodeGLFW = GLFW_KEY_A; - else if (strcmp(name, "AC02") == 0) keyCodeGLFW = GLFW_KEY_S; - else if (strcmp(name, "AC03") == 0) keyCodeGLFW = GLFW_KEY_D; - else if (strcmp(name, "AC04") == 0) keyCodeGLFW = GLFW_KEY_F; - else if (strcmp(name, "AC05") == 0) keyCodeGLFW = GLFW_KEY_G; - else if (strcmp(name, "AC06") == 0) keyCodeGLFW = GLFW_KEY_H; - else if (strcmp(name, "AC07") == 0) keyCodeGLFW = GLFW_KEY_J; - else if (strcmp(name, "AC08") == 0) keyCodeGLFW = GLFW_KEY_K; - else if (strcmp(name, "AC09") == 0) keyCodeGLFW = GLFW_KEY_L; - else if (strcmp(name, "AC10") == 0) keyCodeGLFW = GLFW_KEY_SEMICOLON; - else if (strcmp(name, "AC11") == 0) keyCodeGLFW = GLFW_KEY_APOSTROPHE; - else if (strcmp(name, "AB01") == 0) keyCodeGLFW = GLFW_KEY_Z; - else if (strcmp(name, "AB02") == 0) keyCodeGLFW = GLFW_KEY_X; - else if (strcmp(name, "AB03") == 0) keyCodeGLFW = GLFW_KEY_C; - else if (strcmp(name, "AB04") == 0) keyCodeGLFW = GLFW_KEY_V; - else if (strcmp(name, "AB05") == 0) keyCodeGLFW = GLFW_KEY_B; - else if (strcmp(name, "AB06") == 0) keyCodeGLFW = GLFW_KEY_N; - else if (strcmp(name, "AB07") == 0) keyCodeGLFW = GLFW_KEY_M; - else if (strcmp(name, "AB08") == 0) keyCodeGLFW = GLFW_KEY_COMMA; - else if (strcmp(name, "AB09") == 0) keyCodeGLFW = GLFW_KEY_PERIOD; - else if (strcmp(name, "AB10") == 0) keyCodeGLFW = GLFW_KEY_SLASH; - else if (strcmp(name, "BKSL") == 0) keyCodeGLFW = GLFW_KEY_BACKSLASH; - else if (strcmp(name, "LSGT") == 0) keyCodeGLFW = GLFW_KEY_WORLD_1; - else keyCodeGLFW = GLFW_KEY_UNKNOWN; + 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 key = GLFW_KEY_UNKNOWN; - // Update the key code LUT - if ((keyCode >= 0) && (keyCode < 256)) - _glfw.x11.keyCodeLUT[keyCode] = keyCodeGLFW; + if ((scancode >= 0) && (scancode < 256)) + _glfw.x11.publicKeys[scancode] = key; } - // Free the keyboard description XkbFreeKeyboard(descr, 0, True); } // Translate the un-translated key codes using traditional X11 KeySym // lookups - for (keyCode = 0; keyCode < 256; keyCode++) + for (scancode = 0; scancode < 256; scancode++) { - if (_glfw.x11.keyCodeLUT[keyCode] < 0) - _glfw.x11.keyCodeLUT[keyCode] = translateKey(keyCode); + if (_glfw.x11.publicKeys[scancode] < 0) + _glfw.x11.publicKeys[scancode] = translateKey(scancode); } } @@ -585,7 +576,7 @@ static GLboolean initExtensions(void) // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to // the keyboard mapping. - updateKeyCodeLUT(); + createKeyTables(); // Detect whether an EWMH-conformant window manager is running detectEWMH(); diff --git a/src/x11_platform.h b/src/x11_platform.h index bed461f7..20be5c62 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -117,9 +117,8 @@ typedef struct _GLFWlibraryX11 int errorCode; // Clipboard string (while the selection is owned) char* clipboardString; - - // LUT for mapping X11 key codes to GLFW key codes - int keyCodeLUT[256]; + // X11 keycode to GLFW key LUT + short int publicKeys[256]; // Window manager atoms Atom WM_PROTOCOLS; diff --git a/src/x11_window.c b/src/x11_window.c index a3ff88de..1b38daae 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -86,13 +86,13 @@ static int translateState(int state) // Translates an X Window key to internal coding // -static int translateKey(int keycode) +static int translateKey(int scancode) { - // Use the pre-filled LUT (see updateKeyCodeLUT() in x11_init.c) - if (keycode < 0 || keycode > 255) + // Use the pre-filled LUT (see createKeyTables() in x11_init.c) + if (scancode < 0 || scancode > 255) return GLFW_KEY_UNKNOWN; - return _glfw.x11.keyCodeLUT[keycode]; + return _glfw.x11.publicKeys[scancode]; } // Return the GLFW window corresponding to the specified X11 window