From c0cb4c2fe1e158f45ec46d54f15c597a30b7cdcd Mon Sep 17 00:00:00 2001 From: Marcus Date: Sun, 2 Jan 2011 11:18:14 +0100 Subject: [PATCH 1/8] Implemented raw key code support for X11. --- include/GL/glfw3.h | 230 ++++++++++++++++++++++++------------ src/x11/platform.h | 13 ++ src/x11/x11_init.c | 117 ++++++++++++++++++ src/x11/x11_window.c | 274 +++++++++++++++++++++++++++---------------- tests/events.c | 83 ++++++++++--- 5 files changed, 522 insertions(+), 195 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index a8e3866c..e94e49a1 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -184,83 +184,161 @@ extern "C" { #define GLFW_RELEASE 0 #define GLFW_PRESS 1 -/* Keyboard key definitions: 8-bit ISO-8859-1 (Latin 1) encoding is used - * for printable keys (such as A-Z, 0-9 etc), and values above 256 - * represent special (non-printable) keys (e.g. F1, Page Up etc). +/* Keyboard raw key codes. + * These key codes are inspired by the USB HID Usage Tables v1.12 (p. 53-60), + * but re-arranged to map to 7-bit ASCII for printable keys (function keys are + * put in the 256+ range). + * The naming of the key codes follow these rules: + * - The US keyboard layout is used. + * - Names of printable alpha-numeric characters are used (e.g. "A", "R", + * "3", etc). + * - For non-alphanumeric characters, Unicode:ish names are used (e.g. + * "COMMA", "LEFT_SQUARE_BRACKET", etc). Note that some names do not + * correspond to the Unicode standard (usually for brevity). + * - Keys that lack a clear US mapping are named "WORLD_x". + * - For non-printable keys, custom names are used (e.g. "F4", + * "BACKSPACE", etc). */ -#define GLFW_KEY_UNKNOWN -1 -#define GLFW_KEY_SPACE 32 -#define GLFW_KEY_SPECIAL 256 -#define GLFW_KEY_ESC (GLFW_KEY_SPECIAL+1) -#define GLFW_KEY_F1 (GLFW_KEY_SPECIAL+2) -#define GLFW_KEY_F2 (GLFW_KEY_SPECIAL+3) -#define GLFW_KEY_F3 (GLFW_KEY_SPECIAL+4) -#define GLFW_KEY_F4 (GLFW_KEY_SPECIAL+5) -#define GLFW_KEY_F5 (GLFW_KEY_SPECIAL+6) -#define GLFW_KEY_F6 (GLFW_KEY_SPECIAL+7) -#define GLFW_KEY_F7 (GLFW_KEY_SPECIAL+8) -#define GLFW_KEY_F8 (GLFW_KEY_SPECIAL+9) -#define GLFW_KEY_F9 (GLFW_KEY_SPECIAL+10) -#define GLFW_KEY_F10 (GLFW_KEY_SPECIAL+11) -#define GLFW_KEY_F11 (GLFW_KEY_SPECIAL+12) -#define GLFW_KEY_F12 (GLFW_KEY_SPECIAL+13) -#define GLFW_KEY_F13 (GLFW_KEY_SPECIAL+14) -#define GLFW_KEY_F14 (GLFW_KEY_SPECIAL+15) -#define GLFW_KEY_F15 (GLFW_KEY_SPECIAL+16) -#define GLFW_KEY_F16 (GLFW_KEY_SPECIAL+17) -#define GLFW_KEY_F17 (GLFW_KEY_SPECIAL+18) -#define GLFW_KEY_F18 (GLFW_KEY_SPECIAL+19) -#define GLFW_KEY_F19 (GLFW_KEY_SPECIAL+20) -#define GLFW_KEY_F20 (GLFW_KEY_SPECIAL+21) -#define GLFW_KEY_F21 (GLFW_KEY_SPECIAL+22) -#define GLFW_KEY_F22 (GLFW_KEY_SPECIAL+23) -#define GLFW_KEY_F23 (GLFW_KEY_SPECIAL+24) -#define GLFW_KEY_F24 (GLFW_KEY_SPECIAL+25) -#define GLFW_KEY_F25 (GLFW_KEY_SPECIAL+26) -#define GLFW_KEY_UP (GLFW_KEY_SPECIAL+27) -#define GLFW_KEY_DOWN (GLFW_KEY_SPECIAL+28) -#define GLFW_KEY_LEFT (GLFW_KEY_SPECIAL+29) -#define GLFW_KEY_RIGHT (GLFW_KEY_SPECIAL+30) -#define GLFW_KEY_LSHIFT (GLFW_KEY_SPECIAL+31) -#define GLFW_KEY_RSHIFT (GLFW_KEY_SPECIAL+32) -#define GLFW_KEY_LCTRL (GLFW_KEY_SPECIAL+33) -#define GLFW_KEY_RCTRL (GLFW_KEY_SPECIAL+34) -#define GLFW_KEY_LALT (GLFW_KEY_SPECIAL+35) -#define GLFW_KEY_RALT (GLFW_KEY_SPECIAL+36) -#define GLFW_KEY_TAB (GLFW_KEY_SPECIAL+37) -#define GLFW_KEY_ENTER (GLFW_KEY_SPECIAL+38) -#define GLFW_KEY_BACKSPACE (GLFW_KEY_SPECIAL+39) -#define GLFW_KEY_INSERT (GLFW_KEY_SPECIAL+40) -#define GLFW_KEY_DEL (GLFW_KEY_SPECIAL+41) -#define GLFW_KEY_PAGEUP (GLFW_KEY_SPECIAL+42) -#define GLFW_KEY_PAGEDOWN (GLFW_KEY_SPECIAL+43) -#define GLFW_KEY_HOME (GLFW_KEY_SPECIAL+44) -#define GLFW_KEY_END (GLFW_KEY_SPECIAL+45) -#define GLFW_KEY_KP_0 (GLFW_KEY_SPECIAL+46) -#define GLFW_KEY_KP_1 (GLFW_KEY_SPECIAL+47) -#define GLFW_KEY_KP_2 (GLFW_KEY_SPECIAL+48) -#define GLFW_KEY_KP_3 (GLFW_KEY_SPECIAL+49) -#define GLFW_KEY_KP_4 (GLFW_KEY_SPECIAL+50) -#define GLFW_KEY_KP_5 (GLFW_KEY_SPECIAL+51) -#define GLFW_KEY_KP_6 (GLFW_KEY_SPECIAL+52) -#define GLFW_KEY_KP_7 (GLFW_KEY_SPECIAL+53) -#define GLFW_KEY_KP_8 (GLFW_KEY_SPECIAL+54) -#define GLFW_KEY_KP_9 (GLFW_KEY_SPECIAL+55) -#define GLFW_KEY_KP_DIVIDE (GLFW_KEY_SPECIAL+56) -#define GLFW_KEY_KP_MULTIPLY (GLFW_KEY_SPECIAL+57) -#define GLFW_KEY_KP_SUBTRACT (GLFW_KEY_SPECIAL+58) -#define GLFW_KEY_KP_ADD (GLFW_KEY_SPECIAL+59) -#define GLFW_KEY_KP_DECIMAL (GLFW_KEY_SPECIAL+60) -#define GLFW_KEY_KP_EQUAL (GLFW_KEY_SPECIAL+61) -#define GLFW_KEY_KP_ENTER (GLFW_KEY_SPECIAL+62) -#define GLFW_KEY_KP_NUM_LOCK (GLFW_KEY_SPECIAL+63) -#define GLFW_KEY_CAPS_LOCK (GLFW_KEY_SPECIAL+64) -#define GLFW_KEY_SCROLL_LOCK (GLFW_KEY_SPECIAL+65) -#define GLFW_KEY_PAUSE (GLFW_KEY_SPECIAL+66) -#define GLFW_KEY_LSUPER (GLFW_KEY_SPECIAL+67) -#define GLFW_KEY_RSUPER (GLFW_KEY_SPECIAL+68) -#define GLFW_KEY_MENU (GLFW_KEY_SPECIAL+69) -#define GLFW_KEY_LAST GLFW_KEY_MENU + +/* Printable keys */ +#define GLFW_KEY_SPACE 32 +#define GLFW_KEY_APOSTROPHE 39 /* ' */ +#define GLFW_KEY_COMMA 44 /* , */ +#define GLFW_KEY_MINUS 45 /* - */ +#define GLFW_KEY_PERIOD 46 /* . */ +#define GLFW_KEY_SLASH 47 /* / */ +#define GLFW_KEY_0 48 +#define GLFW_KEY_1 49 +#define GLFW_KEY_2 50 +#define GLFW_KEY_3 51 +#define GLFW_KEY_4 52 +#define GLFW_KEY_5 53 +#define GLFW_KEY_6 54 +#define GLFW_KEY_7 55 +#define GLFW_KEY_8 56 +#define GLFW_KEY_9 57 +#define GLFW_KEY_SEMICOLON 59 /* ; */ +#define GLFW_KEY_EQUAL 61 /* = */ +#define GLFW_KEY_A 65 +#define GLFW_KEY_B 66 +#define GLFW_KEY_C 67 +#define GLFW_KEY_D 68 +#define GLFW_KEY_E 69 +#define GLFW_KEY_F 70 +#define GLFW_KEY_G 71 +#define GLFW_KEY_H 72 +#define GLFW_KEY_I 73 +#define GLFW_KEY_J 74 +#define GLFW_KEY_K 75 +#define GLFW_KEY_L 76 +#define GLFW_KEY_M 77 +#define GLFW_KEY_N 78 +#define GLFW_KEY_O 79 +#define GLFW_KEY_P 80 +#define GLFW_KEY_Q 81 +#define GLFW_KEY_R 82 +#define GLFW_KEY_S 83 +#define GLFW_KEY_T 84 +#define GLFW_KEY_U 85 +#define GLFW_KEY_V 86 +#define GLFW_KEY_W 87 +#define GLFW_KEY_X 88 +#define GLFW_KEY_Y 89 +#define GLFW_KEY_Z 90 +#define GLFW_KEY_LEFT_SQUARE_BRACKET 91 /* [ */ +#define GLFW_KEY_BACKSLASH 92 /* \ */ +#define GLFW_KEY_RIGHT_SQUARE_BRACKET 93 /* ] */ +#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ +#define GLFW_KEY_WORLD_1 161 /* non-US #1 */ +#define GLFW_KEY_WORLD_2 162 /* non-US #2 */ + +/* Function keys */ +#define GLFW_KEY_ESCAPE 256 +#define GLFW_KEY_ENTER 257 +#define GLFW_KEY_TAB 258 +#define GLFW_KEY_BACKSPACE 259 +#define GLFW_KEY_INSERT 260 +#define GLFW_KEY_DELETE 261 +#define GLFW_KEY_RIGHT 262 +#define GLFW_KEY_LEFT 263 +#define GLFW_KEY_DOWN 264 +#define GLFW_KEY_UP 265 +#define GLFW_KEY_PAGE_UP 266 +#define GLFW_KEY_PAGE_DOWN 267 +#define GLFW_KEY_HOME 268 +#define GLFW_KEY_END 269 +#define GLFW_KEY_CAPS_LOCK 280 +#define GLFW_KEY_SCROLL_LOCK 281 +#define GLFW_KEY_NUM_LOCK 282 +#define GLFW_KEY_PRINT_SCREEN 283 +#define GLFW_KEY_PAUSE 284 +#define GLFW_KEY_F1 290 +#define GLFW_KEY_F2 291 +#define GLFW_KEY_F3 292 +#define GLFW_KEY_F4 293 +#define GLFW_KEY_F5 294 +#define GLFW_KEY_F6 295 +#define GLFW_KEY_F7 296 +#define GLFW_KEY_F8 297 +#define GLFW_KEY_F9 298 +#define GLFW_KEY_F10 299 +#define GLFW_KEY_F11 300 +#define GLFW_KEY_F12 301 +#define GLFW_KEY_F13 302 +#define GLFW_KEY_F14 303 +#define GLFW_KEY_F15 304 +#define GLFW_KEY_F16 305 +#define GLFW_KEY_F17 306 +#define GLFW_KEY_F18 307 +#define GLFW_KEY_F19 308 +#define GLFW_KEY_F20 309 +#define GLFW_KEY_F21 310 +#define GLFW_KEY_F22 311 +#define GLFW_KEY_F23 312 +#define GLFW_KEY_F24 313 +#define GLFW_KEY_F25 314 +#define GLFW_KEY_KP_0 320 +#define GLFW_KEY_KP_1 321 +#define GLFW_KEY_KP_2 322 +#define GLFW_KEY_KP_3 323 +#define GLFW_KEY_KP_4 324 +#define GLFW_KEY_KP_5 325 +#define GLFW_KEY_KP_6 326 +#define GLFW_KEY_KP_7 327 +#define GLFW_KEY_KP_8 328 +#define GLFW_KEY_KP_9 329 +#define GLFW_KEY_KP_DECIMAL 330 +#define GLFW_KEY_KP_DIVIDE 331 +#define GLFW_KEY_KP_MULTIPLY 332 +#define GLFW_KEY_KP_SUBTRACT 333 +#define GLFW_KEY_KP_ADD 334 +#define GLFW_KEY_KP_ENTER 335 +#define GLFW_KEY_KP_EQUAL 336 +#define GLFW_KEY_LEFT_SHIFT 340 +#define GLFW_KEY_LEFT_CONTROL 341 +#define GLFW_KEY_LEFT_ALT 342 +#define GLFW_KEY_LEFT_SUPER 343 +#define GLFW_KEY_RIGHT_SHIFT 344 +#define GLFW_KEY_RIGHT_CONTROL 345 +#define GLFW_KEY_RIGHT_ALT 346 +#define GLFW_KEY_RIGHT_SUPER 347 +#define GLFW_KEY_MENU 348 +#define GLFW_KEY_LAST GLFW_KEY_MENU + +/* GLFW 2.x key name aliases (deprecated) */ +#define GLFW_KEY_ESC GLFW_KEY_ESCAPE +#define GLFW_KEY_DEL GLFW_KEY_DELETE +#define GLFW_KEY_PAGEUP GLFW_KEY_PAGE_UP +#define GLFW_KEY_PAGEDOWN GLFW_KEY_PAGE_DOWN +#define GLFW_KEY_KP_NUM_LOCK GLFW_KEY_NUM_LOCK +#define GLFW_KEY_LCTRL GLFW_KEY_LEFT_CONTROL +#define GLFW_KEY_LSHIFT GLFW_KEY_LEFT_SHIFT +#define GLFW_KEY_LALT GLFW_KEY_LEFT_ALT +#define GLFW_KEY_LSUPER GLFW_KEY_LEFT_SUPER +#define GLFW_KEY_RCTRL GLFW_KEY_RIGHT_CONTROL +#define GLFW_KEY_RSHIFT GLFW_KEY_RIGHT_SHIFT +#define GLFW_KEY_RALT GLFW_KEY_RIGHT_ALT +#define GLFW_KEY_RSUPER GLFW_KEY_RIGHT_SUPER /* Mouse button definitions */ #define GLFW_MOUSE_BUTTON_1 0 diff --git a/src/x11/platform.h b/src/x11/platform.h index a243bffd..a370df0b 100644 --- a/src/x11/platform.h +++ b/src/x11/platform.h @@ -66,6 +66,9 @@ #include #endif +// The Xkb extension provides improved keyboard support +#include + #ifndef GL_VERSION_3_0 @@ -173,6 +176,16 @@ typedef struct _GLFWlibraryX11 GLboolean gammaBroken; } RandR; + struct { + GLboolean available; + int majorOpcode; + int eventBase; + int errorBase; + int majorVersion; + int minorVersion; + int keyCodeLUT[256]; + } Xkb; + // Screensaver data struct { GLboolean changed; diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index ac5c3054..2f23e334 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -62,6 +62,107 @@ static void initLibraries(void) } +//======================================================================== +// Update the key code LUT +//======================================================================== + +static void updateKeyCodeLUT(void) +{ + int i, keyCode, keyCodeGLFW; + char name[XkbKeyNameLength+1]; + XkbDescPtr descr; + + // Clear the LUT + for (i = 0; i < 256; ++i) + { + _glfwLibrary.X11.Xkb.keyCodeLUT[i] = -1; + } + + // This functionality requires the Xkb extension + if (!_glfwLibrary.X11.Xkb.available) + { + return; + } + + // Get keyboard description + descr = XkbGetKeyboard(_glfwLibrary.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) + { + // Get the key name + for (i = 0; i < XkbKeyNameLength; ++i) + { + name[i] = descr->names->keys[keyCode].name[i]; + } + 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. + 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_SQUARE_BRACKET; + else if (strcmp(name, "AD12") == 0) keyCodeGLFW = GLFW_KEY_RIGHT_SQUARE_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 = -1; + + // Update the key code LUT + if ((keyCode >= 0) && (keyCode < 256)) + { + _glfwLibrary.X11.Xkb.keyCodeLUT[keyCode] = keyCodeGLFW; + } + } + + // Free the keyboard description + XkbFreeKeyboard(descr, 0, True); +} + + //======================================================================== // Initialize X11 display and look for supported X11 extensions //======================================================================== @@ -126,6 +227,22 @@ static GLboolean initDisplay(void) return GL_FALSE; } + // Check if Xkb is supported on this display + _glfwLibrary.X11.Xkb.majorVersion = 1; + _glfwLibrary.X11.Xkb.minorVersion = 0; + _glfwLibrary.X11.Xkb.available = + XkbQueryExtension(_glfwLibrary.X11.display, + &_glfwLibrary.X11.Xkb.majorOpcode, + &_glfwLibrary.X11.Xkb.eventBase, + &_glfwLibrary.X11.Xkb.errorBase, + &_glfwLibrary.X11.Xkb.majorVersion, + &_glfwLibrary.X11.Xkb.minorVersion); + + // Update the key code LUT + // FIXME: We should listen to XkbMapNotify events to track changes to + // the keyboard mapping. + updateKeyCodeLUT(); + return GL_TRUE; } diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c index 0b026b16..2879ecb0 100644 --- a/src/x11/x11_window.c +++ b/src/x11/x11_window.c @@ -35,6 +35,12 @@ #include #include +#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB + #define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#endif +#ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT + #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#endif // Action for EWMH client messages #define _NET_WM_STATE_REMOVE 0 @@ -213,124 +219,188 @@ static GLboolean checkForEWMH(_GLFWwindow* window) static int translateKey(int keycode) { - KeySym key, key_lc, key_uc; + KeySym key; // Try secondary keysym, for numeric keypad keys - // Note: This way we always force "NumLock = ON", which at least - // enables GLFW users to detect 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. key = XKeycodeToKeysym(_glfwLibrary.X11.display, keycode, 1); switch (key) { - // Numeric keypad - 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_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; + 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 pimary keysym + // 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). key = XKeycodeToKeysym(_glfwLibrary.X11.display, keycode, 0); switch (key) { - // Special keys (non character keys) - case XK_Escape: return GLFW_KEY_ESC; - case XK_Tab: return GLFW_KEY_TAB; - case XK_Shift_L: return GLFW_KEY_LSHIFT; - case XK_Shift_R: return GLFW_KEY_RSHIFT; - case XK_Control_L: return GLFW_KEY_LCTRL; - case XK_Control_R: return GLFW_KEY_RCTRL; + 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_LALT; - case XK_Mode_switch: // Mapped to Alt_R on many keyboards - case XK_Meta_R: + 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_Alt_R: return GLFW_KEY_RALT; - case XK_Super_L: return GLFW_KEY_LSUPER; - case XK_Super_R: return GLFW_KEY_RSUPER; - case XK_Menu: return GLFW_KEY_MENU; - case XK_Num_Lock: return GLFW_KEY_KP_NUM_LOCK; - case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK; - case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK; - case XK_Pause: return GLFW_KEY_PAUSE; - case XK_KP_Delete: - case XK_Delete: return GLFW_KEY_DEL; - case XK_BackSpace: return GLFW_KEY_BACKSPACE; - case XK_Return: return GLFW_KEY_ENTER; - case XK_KP_Home: - case XK_Home: return GLFW_KEY_HOME; - case XK_KP_End: - case XK_End: return GLFW_KEY_END; - case XK_KP_Page_Up: - case XK_Page_Up: return GLFW_KEY_PAGEUP; - case XK_KP_Page_Down: - case XK_Page_Down: return GLFW_KEY_PAGEDOWN; - case XK_KP_Insert: - case XK_Insert: return GLFW_KEY_INSERT; - case XK_KP_Left: - case XK_Left: return GLFW_KEY_LEFT; - case XK_KP_Right: - case XK_Right: return GLFW_KEY_RIGHT; - case XK_KP_Down: - case XK_Down: return GLFW_KEY_DOWN; - case XK_KP_Up: - 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; + 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_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 (should have been detected in secondary keysym!) - 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; - case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; - case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + // 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; - // The rest (should be printable keys) - default: - // Make uppercase - XConvertCase(key, &key_lc, &key_uc); - key = key_uc; - - // Valid ISO 8859-1 character? - if ((key >= 32 && key <= 126) || (key >= 160 && key <= 255)) - return (int) key; - - return GLFW_KEY_UNKNOWN; + // 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; + default: break; } + + // At this point we should only have printable keys left. We try the + // pre-filled LUT first (which is layout independent), which should give + // a positive result if we have the Xkb extension. + if ((keycode >= 0) && (keycode < 256)) + { + int result = _glfwLibrary.X11.Xkb.keyCodeLUT[keycode]; + if (result >= 0) + { + return result; + } + } + + // Last resort: Check the pimary keysym for printable keys. 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... + switch (key) + { + 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_SQUARE_BRACKET; + case XK_bracketright: return GLFW_KEY_RIGHT_SQUARE_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, so return -1 + return -1; } diff --git a/tests/events.c b/tests/events.c index e6fda25e..2998027d 100644 --- a/tests/events.c +++ b/tests/events.c @@ -46,8 +46,59 @@ static const char* get_key_name(int key) { switch (key) { - case GLFW_KEY_UNKNOWN: return "unknown"; + // Printable keys + case GLFW_KEY_A: return "a"; + case GLFW_KEY_B: return "b"; + case GLFW_KEY_C: return "c"; + case GLFW_KEY_D: return "d"; + case GLFW_KEY_E: return "e"; + case GLFW_KEY_F: return "f"; + case GLFW_KEY_G: return "g"; + case GLFW_KEY_H: return "h"; + case GLFW_KEY_I: return "i"; + case GLFW_KEY_J: return "j"; + case GLFW_KEY_K: return "k"; + case GLFW_KEY_L: return "l"; + case GLFW_KEY_M: return "m"; + case GLFW_KEY_N: return "n"; + case GLFW_KEY_O: return "o"; + case GLFW_KEY_P: return "p"; + case GLFW_KEY_Q: return "q"; + case GLFW_KEY_R: return "r"; + case GLFW_KEY_S: return "s"; + case GLFW_KEY_T: return "t"; + case GLFW_KEY_U: return "u"; + case GLFW_KEY_V: return "v"; + case GLFW_KEY_W: return "w"; + case GLFW_KEY_X: return "x"; + case GLFW_KEY_Y: return "y"; + case GLFW_KEY_Z: return "z"; + case GLFW_KEY_1: return "1"; + case GLFW_KEY_2: return "2"; + case GLFW_KEY_3: return "3"; + case GLFW_KEY_4: return "4"; + case GLFW_KEY_5: return "5"; + case GLFW_KEY_6: return "6"; + case GLFW_KEY_7: return "7"; + case GLFW_KEY_8: return "8"; + case GLFW_KEY_9: return "9"; + case GLFW_KEY_0: return "0"; case GLFW_KEY_SPACE: return "space"; + case GLFW_KEY_MINUS: return "-"; + case GLFW_KEY_EQUAL: return "="; + case GLFW_KEY_LEFT_SQUARE_BRACKET: return "["; + case GLFW_KEY_RIGHT_SQUARE_BRACKET: return "]"; + case GLFW_KEY_BACKSLASH: return "\\"; + case GLFW_KEY_SEMICOLON: return ";"; + case GLFW_KEY_APOSTROPHE: return "'"; + case GLFW_KEY_GRAVE_ACCENT: return "`"; + case GLFW_KEY_COMMA: return ","; + case GLFW_KEY_PERIOD: return "."; + case GLFW_KEY_SLASH: return "/"; + case GLFW_KEY_WORLD_1: return "world 1"; + case GLFW_KEY_WORLD_2: return "world 2"; + + // Special keys case GLFW_KEY_ESC: return "escape"; case GLFW_KEY_F1: return "F1"; case GLFW_KEY_F2: return "F2"; @@ -78,19 +129,19 @@ static const char* get_key_name(int key) case GLFW_KEY_DOWN: return "down"; case GLFW_KEY_LEFT: return "left"; case GLFW_KEY_RIGHT: return "right"; - case GLFW_KEY_LSHIFT: return "left shift"; - case GLFW_KEY_RSHIFT: return "right shift"; - case GLFW_KEY_LCTRL: return "left control"; - case GLFW_KEY_RCTRL: return "right control"; - case GLFW_KEY_LALT: return "left alt"; - case GLFW_KEY_RALT: return "right alt"; + case GLFW_KEY_LEFT_SHIFT: return "left shift"; + case GLFW_KEY_RIGHT_SHIFT: return "right shift"; + case GLFW_KEY_LEFT_CONTROL: return "left control"; + case GLFW_KEY_RIGHT_CONTROL: return "right control"; + case GLFW_KEY_LEFT_ALT: return "left alt"; + case GLFW_KEY_RIGHT_ALT: return "right alt"; case GLFW_KEY_TAB: return "tab"; case GLFW_KEY_ENTER: return "enter"; case GLFW_KEY_BACKSPACE: return "backspace"; case GLFW_KEY_INSERT: return "insert"; - case GLFW_KEY_DEL: return "delete"; - case GLFW_KEY_PAGEUP: return "page up"; - case GLFW_KEY_PAGEDOWN: return "page down"; + case GLFW_KEY_DELETE: return "delete"; + case GLFW_KEY_PAGE_UP: return "page up"; + case GLFW_KEY_PAGE_DOWN: return "page down"; case GLFW_KEY_HOME: return "home"; case GLFW_KEY_END: return "end"; case GLFW_KEY_KP_0: return "keypad 0"; @@ -110,12 +161,12 @@ static const char* get_key_name(int key) case GLFW_KEY_KP_DECIMAL: return "keypad decimal"; case GLFW_KEY_KP_EQUAL: return "keypad equal"; case GLFW_KEY_KP_ENTER: return "keypad enter"; - case GLFW_KEY_KP_NUM_LOCK: return "keypad num lock"; + case GLFW_KEY_NUM_LOCK: return "num lock"; case GLFW_KEY_CAPS_LOCK: return "caps lock"; case GLFW_KEY_SCROLL_LOCK: return "scroll lock"; case GLFW_KEY_PAUSE: return "pause"; - case GLFW_KEY_LSUPER: return "left super"; - case GLFW_KEY_RSUPER: return "right super"; + case GLFW_KEY_LEFT_SUPER: return "left super"; + case GLFW_KEY_RIGHT_SUPER: return "right super"; case GLFW_KEY_MENU: return "menu"; } @@ -231,8 +282,6 @@ static void key_callback(GLFWwindow window, int key, int action) if (name) printf(" (%s) was %s\n", name, get_action_name(action)); - else if (isgraph(key)) - printf(" (%c) was %s\n", key, get_action_name(action)); else printf(" was %s\n", get_action_name(action)); @@ -241,7 +290,7 @@ static void key_callback(GLFWwindow window, int key, int action) switch (key) { - case 'R': + case GLFW_KEY_R: { keyrepeat = !keyrepeat; if (keyrepeat) @@ -253,7 +302,7 @@ static void key_callback(GLFWwindow window, int key, int action) break; } - case 'S': + case GLFW_KEY_S: { systemkeys = !systemkeys; if (systemkeys) From a44d56605748fe225d100417b874b7a3afe1a34e Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 3 Jan 2011 21:44:05 +0100 Subject: [PATCH 2/8] Added compile time detection of the XKB X11 extension. --- CMakeLists.txt | 4 ++++ src/config.h.in | 3 +++ src/x11/platform.h | 9 ++++++--- src/x11/x11_init.c | 15 ++++++++++++--- src/x11/x11_window.c | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c99d1fc8..65b494f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,10 @@ if (UNIX AND NOT APPLE AND NOT CYGWIN) list(APPEND GLFW_LIBRARIES ${X11_XF86VIDMODE_LIBRARIES}) endif(X11_XF86VIDMODE_FOUND) + # Check for Xkb (X keyboard extension) + CHECK_FUNCTION_EXISTS(XkbQueryExtension _GLFW_HAS_XKB) + + # Check for glXGetProcAddress CHECK_FUNCTION_EXISTS(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) if (NOT _GLFW_HAS_GLXGETPROCADDRESS) diff --git a/src/config.h.in b/src/config.h.in index b1c77e73..0c547597 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -40,6 +40,9 @@ // Define this to 1 if Xf86VidMode is available #cmakedefine _GLFW_HAS_XF86VIDMODE 1 +// Define this to 1 if Xkb is available +#cmakedefine _GLFW_HAS_XKB 1 + // Define this to 1 if glXGetProcAddress is available #cmakedefine _GLFW_HAS_GLXGETPROCADDRESS 1 // Define this to 1 if glXGetProcAddressARB is available diff --git a/src/x11/platform.h b/src/x11/platform.h index a370df0b..b5e18e90 100644 --- a/src/x11/platform.h +++ b/src/x11/platform.h @@ -67,8 +67,9 @@ #endif // The Xkb extension provides improved keyboard support -#include - +#if defined(_GLFW_HAS_XKB) + #include +#endif #ifndef GL_VERSION_3_0 @@ -183,9 +184,11 @@ typedef struct _GLFWlibraryX11 int errorBase; int majorVersion; int minorVersion; - int keyCodeLUT[256]; } Xkb; + // Key code LUT (mapping X11 key codes to GLFW key codes) + int keyCodeLUT[256]; + // Screensaver data struct { GLboolean changed; diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index 2f23e334..f4f9d0b8 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -68,16 +68,20 @@ static void initLibraries(void) static void updateKeyCodeLUT(void) { - int i, keyCode, keyCodeGLFW; +#if defined(_GLFW_HAS_XKB) + int keyCode, keyCodeGLFW; char name[XkbKeyNameLength+1]; XkbDescPtr descr; +#endif + int i; // Clear the LUT for (i = 0; i < 256; ++i) { - _glfwLibrary.X11.Xkb.keyCodeLUT[i] = -1; + _glfwLibrary.X11.keyCodeLUT[i] = -1; } +#if defined(_GLFW_HAS_XKB) // This functionality requires the Xkb extension if (!_glfwLibrary.X11.Xkb.available) { @@ -154,12 +158,13 @@ static void updateKeyCodeLUT(void) // Update the key code LUT if ((keyCode >= 0) && (keyCode < 256)) { - _glfwLibrary.X11.Xkb.keyCodeLUT[keyCode] = keyCodeGLFW; + _glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW; } } // Free the keyboard description XkbFreeKeyboard(descr, 0, True); +#endif /* _GLFW_HAS_XKB */ } @@ -228,6 +233,7 @@ static GLboolean initDisplay(void) } // Check if Xkb is supported on this display +#if defined(_GLFW_HAS_XKB) _glfwLibrary.X11.Xkb.majorVersion = 1; _glfwLibrary.X11.Xkb.minorVersion = 0; _glfwLibrary.X11.Xkb.available = @@ -237,6 +243,9 @@ static GLboolean initDisplay(void) &_glfwLibrary.X11.Xkb.errorBase, &_glfwLibrary.X11.Xkb.majorVersion, &_glfwLibrary.X11.Xkb.minorVersion); +#else + _glfwLibrary.X11.Xkb.available = GL_FALSE; +#endif /* _GLFW_HAS_XKB */ // Update the key code LUT // FIXME: We should listen to XkbMapNotify events to track changes to diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c index 2879ecb0..5e1c15c6 100644 --- a/src/x11/x11_window.c +++ b/src/x11/x11_window.c @@ -335,7 +335,7 @@ static int translateKey(int keycode) // a positive result if we have the Xkb extension. if ((keycode >= 0) && (keycode < 256)) { - int result = _glfwLibrary.X11.Xkb.keyCodeLUT[keycode]; + int result = _glfwLibrary.X11.keyCodeLUT[keycode]; if (result >= 0) { return result; From 3b0084799cdc32c7ec98bfead3719f778de6fea1 Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 3 Jan 2011 22:07:01 +0100 Subject: [PATCH 3/8] Shortened the names of the left/right square bracket keys. --- include/GL/glfw3.h | 4 +- src/x11/x11_init.c | 4 +- src/x11/x11_window.c | 4 +- tests/events.c | 174 +++++++++++++++++++++---------------------- 4 files changed, 93 insertions(+), 93 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index e94e49a1..84e7a605 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -245,9 +245,9 @@ extern "C" { #define GLFW_KEY_X 88 #define GLFW_KEY_Y 89 #define GLFW_KEY_Z 90 -#define GLFW_KEY_LEFT_SQUARE_BRACKET 91 /* [ */ +#define GLFW_KEY_LEFT_BRACKET 91 /* [ */ #define GLFW_KEY_BACKSLASH 92 /* \ */ -#define GLFW_KEY_RIGHT_SQUARE_BRACKET 93 /* ] */ +#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ #define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ #define GLFW_KEY_WORLD_1 161 /* non-US #1 */ #define GLFW_KEY_WORLD_2 162 /* non-US #2 */ diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index f4f9d0b8..6fa0f440 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -128,8 +128,8 @@ static void updateKeyCodeLUT(void) 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_SQUARE_BRACKET; - else if (strcmp(name, "AD12") == 0) keyCodeGLFW = GLFW_KEY_RIGHT_SQUARE_BRACKET; + 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; diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c index 5e1c15c6..8a580bd7 100644 --- a/src/x11/x11_window.c +++ b/src/x11/x11_window.c @@ -386,8 +386,8 @@ static int translateKey(int keycode) 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_SQUARE_BRACKET; - case XK_bracketright: return GLFW_KEY_RIGHT_SQUARE_BRACKET; + 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; diff --git a/tests/events.c b/tests/events.c index 2998027d..7898751b 100644 --- a/tests/events.c +++ b/tests/events.c @@ -47,32 +47,32 @@ static const char* get_key_name(int key) switch (key) { // Printable keys - case GLFW_KEY_A: return "a"; - case GLFW_KEY_B: return "b"; - case GLFW_KEY_C: return "c"; - case GLFW_KEY_D: return "d"; - case GLFW_KEY_E: return "e"; - case GLFW_KEY_F: return "f"; - case GLFW_KEY_G: return "g"; - case GLFW_KEY_H: return "h"; - case GLFW_KEY_I: return "i"; - case GLFW_KEY_J: return "j"; - case GLFW_KEY_K: return "k"; - case GLFW_KEY_L: return "l"; - case GLFW_KEY_M: return "m"; - case GLFW_KEY_N: return "n"; - case GLFW_KEY_O: return "o"; - case GLFW_KEY_P: return "p"; - case GLFW_KEY_Q: return "q"; - case GLFW_KEY_R: return "r"; - case GLFW_KEY_S: return "s"; - case GLFW_KEY_T: return "t"; - case GLFW_KEY_U: return "u"; - case GLFW_KEY_V: return "v"; - case GLFW_KEY_W: return "w"; - case GLFW_KEY_X: return "x"; - case GLFW_KEY_Y: return "y"; - case GLFW_KEY_Z: return "z"; + case GLFW_KEY_A: return "A"; + case GLFW_KEY_B: return "B"; + case GLFW_KEY_C: return "C"; + case GLFW_KEY_D: return "D"; + case GLFW_KEY_E: return "E"; + case GLFW_KEY_F: return "F"; + case GLFW_KEY_G: return "G"; + case GLFW_KEY_H: return "H"; + case GLFW_KEY_I: return "I"; + case GLFW_KEY_J: return "J"; + case GLFW_KEY_K: return "K"; + case GLFW_KEY_L: return "L"; + case GLFW_KEY_M: return "M"; + case GLFW_KEY_N: return "N"; + case GLFW_KEY_O: return "O"; + case GLFW_KEY_P: return "P"; + case GLFW_KEY_Q: return "Q"; + case GLFW_KEY_R: return "R"; + case GLFW_KEY_S: return "S"; + case GLFW_KEY_T: return "T"; + case GLFW_KEY_U: return "U"; + case GLFW_KEY_V: return "V"; + case GLFW_KEY_W: return "W"; + case GLFW_KEY_X: return "X"; + case GLFW_KEY_Y: return "Y"; + case GLFW_KEY_Z: return "Z"; case GLFW_KEY_1: return "1"; case GLFW_KEY_2: return "2"; case GLFW_KEY_3: return "3"; @@ -83,23 +83,23 @@ static const char* get_key_name(int key) case GLFW_KEY_8: return "8"; case GLFW_KEY_9: return "9"; case GLFW_KEY_0: return "0"; - case GLFW_KEY_SPACE: return "space"; - case GLFW_KEY_MINUS: return "-"; - case GLFW_KEY_EQUAL: return "="; - case GLFW_KEY_LEFT_SQUARE_BRACKET: return "["; - case GLFW_KEY_RIGHT_SQUARE_BRACKET: return "]"; - case GLFW_KEY_BACKSLASH: return "\\"; - case GLFW_KEY_SEMICOLON: return ";"; - case GLFW_KEY_APOSTROPHE: return "'"; - case GLFW_KEY_GRAVE_ACCENT: return "`"; - case GLFW_KEY_COMMA: return ","; - case GLFW_KEY_PERIOD: return "."; - case GLFW_KEY_SLASH: return "/"; - case GLFW_KEY_WORLD_1: return "world 1"; - case GLFW_KEY_WORLD_2: return "world 2"; + case GLFW_KEY_SPACE: return "SPACE"; + case GLFW_KEY_MINUS: return "MINUS"; + case GLFW_KEY_EQUAL: return "EQUAL"; + case GLFW_KEY_LEFT_BRACKET: return "LEFT BRACKET"; + case GLFW_KEY_RIGHT_BRACKET: return "RIGHT BRACKET"; + case GLFW_KEY_BACKSLASH: return "BACKSLASH"; + case GLFW_KEY_SEMICOLON: return "SEMICOLON"; + case GLFW_KEY_APOSTROPHE: return "APOSTROPHE"; + case GLFW_KEY_GRAVE_ACCENT: return "GRAVE ACCENT"; + case GLFW_KEY_COMMA: return "COMMA"; + case GLFW_KEY_PERIOD: return "PERIOD"; + case GLFW_KEY_SLASH: return "SLASH"; + case GLFW_KEY_WORLD_1: return "WORLD 1"; + case GLFW_KEY_WORLD_2: return "WORLD 2"; - // Special keys - case GLFW_KEY_ESC: return "escape"; + // Function keys + case GLFW_KEY_ESC: return "ESCAPE"; case GLFW_KEY_F1: return "F1"; case GLFW_KEY_F2: return "F2"; case GLFW_KEY_F3: return "F3"; @@ -125,52 +125,52 @@ static const char* get_key_name(int key) case GLFW_KEY_F23: return "F23"; case GLFW_KEY_F24: return "F24"; case GLFW_KEY_F25: return "F25"; - case GLFW_KEY_UP: return "up"; - case GLFW_KEY_DOWN: return "down"; - case GLFW_KEY_LEFT: return "left"; - case GLFW_KEY_RIGHT: return "right"; - case GLFW_KEY_LEFT_SHIFT: return "left shift"; - case GLFW_KEY_RIGHT_SHIFT: return "right shift"; - case GLFW_KEY_LEFT_CONTROL: return "left control"; - case GLFW_KEY_RIGHT_CONTROL: return "right control"; - case GLFW_KEY_LEFT_ALT: return "left alt"; - case GLFW_KEY_RIGHT_ALT: return "right alt"; - case GLFW_KEY_TAB: return "tab"; - case GLFW_KEY_ENTER: return "enter"; - case GLFW_KEY_BACKSPACE: return "backspace"; - case GLFW_KEY_INSERT: return "insert"; - case GLFW_KEY_DELETE: return "delete"; - case GLFW_KEY_PAGE_UP: return "page up"; - case GLFW_KEY_PAGE_DOWN: return "page down"; - case GLFW_KEY_HOME: return "home"; - case GLFW_KEY_END: return "end"; - case GLFW_KEY_KP_0: return "keypad 0"; - case GLFW_KEY_KP_1: return "keypad 1"; - case GLFW_KEY_KP_2: return "keypad 2"; - case GLFW_KEY_KP_3: return "keypad 3"; - case GLFW_KEY_KP_4: return "keypad 4"; - case GLFW_KEY_KP_5: return "keypad 5"; - case GLFW_KEY_KP_6: return "keypad 6"; - case GLFW_KEY_KP_7: return "keypad 7"; - case GLFW_KEY_KP_8: return "keypad 8"; - case GLFW_KEY_KP_9: return "keypad 9"; - case GLFW_KEY_KP_DIVIDE: return "keypad divide"; - case GLFW_KEY_KP_MULTIPLY: return "keypad multiply"; - case GLFW_KEY_KP_SUBTRACT: return "keypad subtract"; - case GLFW_KEY_KP_ADD: return "keypad add"; - case GLFW_KEY_KP_DECIMAL: return "keypad decimal"; - case GLFW_KEY_KP_EQUAL: return "keypad equal"; - case GLFW_KEY_KP_ENTER: return "keypad enter"; - case GLFW_KEY_NUM_LOCK: return "num lock"; - case GLFW_KEY_CAPS_LOCK: return "caps lock"; - case GLFW_KEY_SCROLL_LOCK: return "scroll lock"; - case GLFW_KEY_PAUSE: return "pause"; - case GLFW_KEY_LEFT_SUPER: return "left super"; - case GLFW_KEY_RIGHT_SUPER: return "right super"; - case GLFW_KEY_MENU: return "menu"; - } + case GLFW_KEY_UP: return "UP"; + case GLFW_KEY_DOWN: return "DOWN"; + case GLFW_KEY_LEFT: return "LEFT"; + case GLFW_KEY_RIGHT: return "RIGHT"; + case GLFW_KEY_LEFT_SHIFT: return "LEFT SHIFT"; + case GLFW_KEY_RIGHT_SHIFT: return "RIGHT SHIFT"; + case GLFW_KEY_LEFT_CONTROL: return "LEFT CONTROL"; + case GLFW_KEY_RIGHT_CONTROL: return "RIGHT CONTROL"; + case GLFW_KEY_LEFT_ALT: return "LEFT ALT"; + case GLFW_KEY_RIGHT_ALT: return "RIGHT ALT"; + case GLFW_KEY_TAB: return "TAB"; + case GLFW_KEY_ENTER: return "ENTER"; + case GLFW_KEY_BACKSPACE: return "BACKSPACE"; + case GLFW_KEY_INSERT: return "INSERT"; + case GLFW_KEY_DELETE: return "DELETE"; + case GLFW_KEY_PAGE_UP: return "PAGE UP"; + case GLFW_KEY_PAGE_DOWN: return "PAGE DOWN"; + case GLFW_KEY_HOME: return "HOME"; + case GLFW_KEY_END: return "END"; + case GLFW_KEY_KP_0: return "KEYPAD 0"; + case GLFW_KEY_KP_1: return "KEYPAD 1"; + case GLFW_KEY_KP_2: return "KEYPAD 2"; + case GLFW_KEY_KP_3: return "KEYPAD 3"; + case GLFW_KEY_KP_4: return "KEYPAD 4"; + case GLFW_KEY_KP_5: return "KEYPAD 5"; + case GLFW_KEY_KP_6: return "KEYPAD 6"; + case GLFW_KEY_KP_7: return "KEYPAD 7"; + case GLFW_KEY_KP_8: return "KEYPAD 8"; + case GLFW_KEY_KP_9: return "KEYPAD 9"; + case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE"; + case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY"; + case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT"; + case GLFW_KEY_KP_ADD: return "KEYPAD ADD"; + case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL"; + case GLFW_KEY_KP_EQUAL: return "KEYPAD EQUAL"; + case GLFW_KEY_KP_ENTER: return "KEYPAD ENTER"; + case GLFW_KEY_NUM_LOCK: return "NUM LOCK"; + case GLFW_KEY_CAPS_LOCK: return "CAPS LOCK"; + case GLFW_KEY_SCROLL_LOCK: return "SCROLL LOCK"; + case GLFW_KEY_PAUSE: return "PAUSE"; + case GLFW_KEY_LEFT_SUPER: return "LEFT SUPER"; + case GLFW_KEY_RIGHT_SUPER: return "RIGHT SUPER"; + case GLFW_KEY_MENU: return "MENU"; - return NULL; + default: return NULL; + } } static const char* get_action_name(int action) From e3cb563a28a875efc28fd8b25012c56079affb51 Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 3 Jan 2011 22:22:14 +0100 Subject: [PATCH 4/8] Fixed key names in the example and test programs. --- examples/boing.c | 2 +- examples/gears.c | 6 +++--- examples/heightmap.c | 2 +- examples/splitview.c | 2 +- examples/triangle.c | 2 +- examples/wave.c | 6 +++--- tests/events.c | 2 +- tests/fsfocus.c | 2 +- tests/gamma.c | 14 +++++++------- tests/iconify.c | 2 +- tests/peter.c | 2 +- tests/reopen.c | 4 ++-- tests/sharing.c | 2 +- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/boing.c b/examples/boing.c index b90f3732..914d1291 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -608,7 +608,7 @@ int main( void ) glfwPollEvents(); /* Check if we are still running */ - running = glfwIsWindow(window) && !glfwGetKey( window, GLFW_KEY_ESC ); + running = glfwIsWindow(window) && !glfwGetKey( window, GLFW_KEY_ESCAPE ); } while( running ); diff --git a/examples/gears.c b/examples/gears.c index 7271cf64..cb31b1f8 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -220,13 +220,13 @@ void key( GLFWwindow window, int k, int action ) if( action != GLFW_PRESS ) return; switch (k) { - case 'Z': - if( glfwGetKey( window, GLFW_KEY_LSHIFT ) ) + case GLFW_KEY_Z: + if( glfwGetKey( window, GLFW_KEY_LEFT_SHIFT ) ) view_rotz -= 5.0; else view_rotz += 5.0; break; - case GLFW_KEY_ESC: + case GLFW_KEY_ESCAPE: running = 0; break; case GLFW_KEY_UP: diff --git a/examples/heightmap.c b/examples/heightmap.c index 4f8c1c0a..f37c732f 100644 --- a/examples/heightmap.c +++ b/examples/heightmap.c @@ -497,7 +497,7 @@ static void key_callback(GLFWwindow window, int key, int action) { switch(key) { - case GLFW_KEY_ESC: + case GLFW_KEY_ESCAPE: /* Exit program on Escape */ running = GL_FALSE; break; diff --git a/examples/splitview.c b/examples/splitview.c index d05b078c..d7fd4820 100644 --- a/examples/splitview.c +++ b/examples/splitview.c @@ -493,7 +493,7 @@ int main(void) } // Check if the ESC key was pressed or the window was closed while (glfwIsWindow(window) && - glfwGetKey(window, GLFW_KEY_ESC) != GLFW_PRESS); + glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS); // Close OpenGL window and terminate GLFW glfwTerminate(); diff --git a/examples/triangle.c b/examples/triangle.c index 31438813..c61baeff 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -83,7 +83,7 @@ int main(void) } // Check if the ESC key was pressed or the window was closed while (glfwIsWindow(window) && - glfwGetKey(window, GLFW_KEY_ESC) != GLFW_PRESS); + glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS); // Close OpenGL window and terminate GLFW glfwTerminate(); diff --git a/examples/wave.c b/examples/wave.c index 49bf1a68..87faa79c 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -262,7 +262,7 @@ void key_callback(GLFWwindow window, int key, int action) switch (key) { - case GLFW_KEY_ESC: + case GLFW_KEY_ESCAPE: running = 0; break; case GLFW_KEY_SPACE: @@ -280,11 +280,11 @@ void key_callback(GLFWwindow window, int key, int action) case GLFW_KEY_DOWN: beta += 5; break; - case GLFW_KEY_PAGEUP: + case GLFW_KEY_PAGE_UP: if (zoom > 1) zoom -= 1; break; - case GLFW_KEY_PAGEDOWN: + case GLFW_KEY_PAGE_DOWN: zoom += 1; break; default: diff --git a/tests/events.c b/tests/events.c index 7898751b..ec3d001a 100644 --- a/tests/events.c +++ b/tests/events.c @@ -99,7 +99,7 @@ static const char* get_key_name(int key) case GLFW_KEY_WORLD_2: return "WORLD 2"; // Function keys - case GLFW_KEY_ESC: return "ESCAPE"; + case GLFW_KEY_ESCAPE: return "ESCAPE"; case GLFW_KEY_F1: return "F1"; case GLFW_KEY_F2: return "F2"; case GLFW_KEY_F3: return "F3"; diff --git a/tests/fsfocus.c b/tests/fsfocus.c index 21631f25..2cce078f 100644 --- a/tests/fsfocus.c +++ b/tests/fsfocus.c @@ -49,7 +49,7 @@ static void window_key_callback(GLFWwindow window, int key, int action) switch (key) { - case GLFW_KEY_ESC: + case GLFW_KEY_ESCAPE: { printf("%0.3f: User pressed Escape\n", glfwGetTime()); running = GL_FALSE; diff --git a/tests/gamma.c b/tests/gamma.c index 0d2ff09b..0c567b22 100644 --- a/tests/gamma.c +++ b/tests/gamma.c @@ -51,35 +51,35 @@ static void key_callback(GLFWwindow window, int key, int action) switch (key) { - case GLFW_KEY_ESC: + case GLFW_KEY_ESCAPE: glfwCloseWindow(window); break; - case 'Q': + case GLFW_KEY_Q: ggamma += 0.1f; printf("Gamma: %f\n", ggamma); glfwSetGammaFormula( ggamma, gblacklevel, ggain ); break; - case 'W': + case GLFW_KEY_W: ggamma -= 0.1f; printf("Gamma: %f\n", ggamma); glfwSetGammaFormula( ggamma, gblacklevel, ggain ); break; - case 'A': + case GLFW_KEY_A: ggain += 0.1f; printf("Gain: %f\n", ggain); glfwSetGammaFormula( ggamma, gblacklevel, ggain ); break; - case 'S': + case GLFW_KEY_S: ggain -= 0.1f; printf("Gain: %f\n", ggain); glfwSetGammaFormula( ggamma, gblacklevel, ggain ); break; - case 'Z': + case GLFW_KEY_Z: gblacklevel += 0.1f; printf("Black Level: %f\n", gblacklevel); glfwSetGammaFormula( ggamma, gblacklevel, ggain ); break; - case 'X': + case GLFW_KEY_X: gblacklevel -= 0.1f; printf("Black Level: %f\n", gblacklevel); glfwSetGammaFormula( ggamma, gblacklevel, ggain ); diff --git a/tests/iconify.c b/tests/iconify.c index 6868c9ad..6d001ea5 100644 --- a/tests/iconify.c +++ b/tests/iconify.c @@ -54,7 +54,7 @@ static void key_callback(GLFWwindow window, int key, int action) case GLFW_KEY_SPACE: glfwIconifyWindow(window); break; - case GLFW_KEY_ESC: + case GLFW_KEY_ESCAPE: glfwCloseWindow(window); break; } diff --git a/tests/peter.c b/tests/peter.c index e2671248..0f61af8e 100644 --- a/tests/peter.c +++ b/tests/peter.c @@ -67,7 +67,7 @@ static void key_callback(GLFWwindow window, int key, int action) break; } - case 'R': + case GLFW_KEY_R: { if (action == GLFW_PRESS) { diff --git a/tests/reopen.c b/tests/reopen.c index 76f914ae..e9637680 100644 --- a/tests/reopen.c +++ b/tests/reopen.c @@ -73,8 +73,8 @@ static void key_callback(GLFWwindow window, int key, int action) switch (key) { - case 'Q': - case GLFW_KEY_ESC: + case GLFW_KEY_Q: + case GLFW_KEY_ESCAPE: closed = GL_TRUE; break; } diff --git a/tests/sharing.c b/tests/sharing.c index b1b335c9..f81580c2 100644 --- a/tests/sharing.c +++ b/tests/sharing.c @@ -37,7 +37,7 @@ static void key_callback(GLFWwindow window, int key, int action) { - if (action == GLFW_PRESS && key == GLFW_KEY_ESC) + if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) glfwCloseWindow(window); } From 2c169997f5765d053121face8bfaba2809c9de74 Mon Sep 17 00:00:00 2001 From: Marcus Date: Tue, 4 Jan 2011 23:07:34 +0100 Subject: [PATCH 5/8] Moved all the key code translation logic into the LUT (cleaner & less overhead). --- src/x11/x11_init.c | 355 +++++++++++++++++++++++++++++++++---------- src/x11/x11_window.c | 181 +--------------------- 2 files changed, 277 insertions(+), 259 deletions(-) diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c index 6fa0f440..86b47f84 100644 --- a/src/x11/x11_init.c +++ b/src/x11/x11_init.c @@ -62,109 +62,300 @@ static void initLibraries(void) } +//======================================================================== +// Translate an X11 key code to a GLFW key code. +//======================================================================== + +static int keyCodeToGLFWKeyCode(int keyCode) +{ + int keySym; + + // Valid key code range is [8,255], according to the XLib manual + if (keyCode < 8 || keyCode > 255) + return -1; + + // 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 = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 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 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 = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0); + 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_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, so return -1 + return -1; +} + + //======================================================================== // Update the key code LUT //======================================================================== static void updateKeyCodeLUT(void) { -#if defined(_GLFW_HAS_XKB) - int keyCode, keyCodeGLFW; - char name[XkbKeyNameLength+1]; - XkbDescPtr descr; -#endif - int i; + int keyCode; // Clear the LUT - for (i = 0; i < 256; ++i) + for (keyCode = 0; keyCode < 256; ++keyCode) { - _glfwLibrary.X11.keyCodeLUT[i] = -1; + _glfwLibrary.X11.keyCodeLUT[keyCode] = -1; } #if defined(_GLFW_HAS_XKB) - // This functionality requires the Xkb extension - if (!_glfwLibrary.X11.Xkb.available) + // If the Xkb extension is available, use it to determine physical key + // locations independently of the current keyboard layout + if (_glfwLibrary.X11.Xkb.available) { - return; - } + int i, keyCodeGLFW; + char name[XkbKeyNameLength+1]; + XkbDescPtr descr; - // Get keyboard description - descr = XkbGetKeyboard(_glfwLibrary.X11.display, - XkbAllComponentsMask, - XkbUseCoreKbd); + // Get keyboard description + descr = XkbGetKeyboard(_glfwLibrary.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) - { - // Get the key name - for (i = 0; i < XkbKeyNameLength; ++i) + // Find the X11 key code -> GLFW key code mapping + for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode) { - name[i] = descr->names->keys[keyCode].name[i]; - } - name[XkbKeyNameLength] = 0; + // Get the key name + for (i = 0; i < XkbKeyNameLength; ++i) + { + name[i] = descr->names->keys[keyCode].name[i]; + } + 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. - 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 = -1; + // 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 = -1; - // Update the key code LUT - if ((keyCode >= 0) && (keyCode < 256)) - { - _glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW; + // Update the key code LUT + if ((keyCode >= 0) && (keyCode < 256)) + { + _glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW; + } } + + // Free the keyboard description + XkbFreeKeyboard(descr, 0, True); } - - // Free the keyboard description - XkbFreeKeyboard(descr, 0, True); #endif /* _GLFW_HAS_XKB */ + + // Translate the un-translated key codes using traditional X11 KeySym + // lookups + for (keyCode = 0; keyCode < 256; ++keyCode) + { + if (_glfwLibrary.X11.keyCodeLUT[keyCode] < 0) + { + _glfwLibrary.X11.keyCodeLUT[keyCode] = + keyCodeToGLFWKeyCode(keyCode); + } + } } diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c index 8a580bd7..ad261acd 100644 --- a/src/x11/x11_window.c +++ b/src/x11/x11_window.c @@ -219,188 +219,15 @@ static GLboolean checkForEWMH(_GLFWwindow* window) static int translateKey(int keycode) { - KeySym key; - - // 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. - key = XKeycodeToKeysym(_glfwLibrary.X11.display, keycode, 1); - switch (key) - { - 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 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). - key = XKeycodeToKeysym(_glfwLibrary.X11.display, keycode, 0); - switch (key) - { - 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_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; - default: break; - } - - // At this point we should only have printable keys left. We try the - // pre-filled LUT first (which is layout independent), which should give - // a positive result if we have the Xkb extension. + // Use the pre-filled LUT (see updateKeyCodeLUT() ). if ((keycode >= 0) && (keycode < 256)) { - int result = _glfwLibrary.X11.keyCodeLUT[keycode]; - if (result >= 0) - { - return result; - } + return _glfwLibrary.X11.keyCodeLUT[keycode]; } - - // Last resort: Check the pimary keysym for printable keys. 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... - switch (key) + else { - 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; + return -1; } - - // No matching translation was found, so return -1 - return -1; } From 62e4ff1e91e4dfc60246b733e0e7d7822e395905 Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 10 Jan 2011 21:19:27 +0100 Subject: [PATCH 6/8] Updated the key translation logic for Win32. --- src/win32/win32_window.c | 127 +++++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 46 deletions(-) diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c index 1fcad004..cd6295a0 100644 --- a/src/win32/win32_window.c +++ b/src/win32/win32_window.c @@ -440,11 +440,11 @@ static int translateKey(WPARAM wParam, LPARAM lParam) DWORD msg_time; DWORD scan_code; - // Check for numeric keypad keys - // Note: This way we always force "NumLock = ON", which at least - // enables GLFW users to detect numeric keypad keys + // 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. int hiFlags = HIWORD(lParam); - if (!(hiFlags & 0x100)) { switch (MapVirtualKey(hiFlags & 0xFF, 1)) @@ -464,6 +464,7 @@ static int translateKey(WPARAM wParam, LPARAM lParam) 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; } } @@ -478,9 +479,9 @@ static int translateKey(WPARAM wParam, LPARAM lParam) // right) scan_code = MapVirtualKey(VK_RSHIFT, 0); if (((lParam & 0x01ff0000) >> 16) == scan_code) - return GLFW_KEY_RSHIFT; + return GLFW_KEY_RIGHT_SHIFT; - return GLFW_KEY_LSHIFT; + return GLFW_KEY_LEFT_SHIFT; } // The CTRL keys require special handling @@ -488,7 +489,7 @@ static int translateKey(WPARAM wParam, LPARAM lParam) { // Is this an extended key (i.e. right key)? if (lParam & 0x01000000) - return GLFW_KEY_RCTRL; + return GLFW_KEY_RIGHT_CTRL; // 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 @@ -505,12 +506,12 @@ static int translateKey(WPARAM wParam, LPARAM lParam) { // Next message is a RALT down message, which // means that this is NOT a proper LCTRL message! - return GLFW_KEY_UNKNOWN; + return -1; } } } - return GLFW_KEY_LCTRL; + return GLFW_KEY_LEFT_CTRL; } // The ALT keys require special handling @@ -518,9 +519,9 @@ static int translateKey(WPARAM wParam, LPARAM lParam) { // Is this an extended key (i.e. right key)? if (lParam & 0x01000000) - return GLFW_KEY_RALT; + return GLFW_KEY_RIGHT_ALT; - return GLFW_KEY_LALT; + return GLFW_KEY_LEFT_ALT; } // The ENTER keys require special handling @@ -533,16 +534,16 @@ static int translateKey(WPARAM wParam, LPARAM lParam) return GLFW_KEY_ENTER; } - // Special keys (non character keys) - case VK_ESCAPE: return GLFW_KEY_ESC; + // 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_PAGEUP; - case VK_NEXT: return GLFW_KEY_PAGEDOWN; + 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_DEL; + 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; @@ -571,7 +572,13 @@ static int translateKey(WPARAM wParam, LPARAM lParam) case VK_F22: return GLFW_KEY_F22; case VK_F23: return GLFW_KEY_F23; case VK_F24: return GLFW_KEY_F24; - case VK_SPACE: return GLFW_KEY_SPACE; + case VK_NUMLOCK: return GLFW_KEY_NUM_LOCK; + case VK_CAPITAL: return GLFW_KEY_CAPS_LOCK; + 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; @@ -589,35 +596,63 @@ static int translateKey(WPARAM wParam, LPARAM lParam) case VK_SUBTRACT: return GLFW_KEY_KP_SUBTRACT; case VK_ADD: return GLFW_KEY_KP_ADD; case VK_DECIMAL: return GLFW_KEY_KP_DECIMAL; - case VK_NUMLOCK: return GLFW_KEY_KP_NUM_LOCK; - case VK_CAPITAL: return GLFW_KEY_CAPS_LOCK; - case VK_SCROLL: return GLFW_KEY_SCROLL_LOCK; - case VK_PAUSE: return GLFW_KEY_PAUSE; - - case VK_LWIN: return GLFW_KEY_LSUPER; - case VK_RWIN: return GLFW_KEY_RSUPER; - case VK_APPS: return GLFW_KEY_MENU; - - // The rest (should be printable keys) - default: - { - // Convert to printable character (ISO-8859-1 or Unicode) - wParam = MapVirtualKey((UINT) wParam, 2) & 0x0000FFFF; - - // Make sure that the character is uppercase - wParam = (WPARAM) CharUpperW((LPWSTR) wParam); - - // Valid ISO-8859-1 character? - if ((wParam >= 32 && wParam <= 126) || - (wParam >= 160 && wParam <= 255)) - { - return (int) wParam; - } - - return GLFW_KEY_UNKNOWN; - } + // Printable keys are mapped according to US layout + case VK_SPACE: return GLFW_KEY_SPACE; + case 0x30: return GLFW_KEY_0; + case 0x31: return GLFW_KEY_1; + case 0x32: return GLFW_KEY_2; + case 0x33: return GLFW_KEY_3; + case 0x34: return GLFW_KEY_4; + case 0x35: return GLFW_KEY_5; + case 0x36: return GLFW_KEY_6; + case 0x37: return GLFW_KEY_7; + case 0x38: return GLFW_KEY_8; + case 0x39: return GLFW_KEY_9; + case 0x41: return GLFW_KEY_A; + case 0x42: return GLFW_KEY_B; + case 0x43: return GLFW_KEY_C; + case 0x44: return GLFW_KEY_D; + case 0x45: return GLFW_KEY_E; + case 0x46: return GLFW_KEY_F; + case 0x47: return GLFW_KEY_G; + case 0x48: return GLFW_KEY_H; + case 0x49: return GLFW_KEY_I; + case 0x4A: return GLFW_KEY_J; + case 0x4B: return GLFW_KEY_K; + case 0x4C: return GLFW_KEY_L; + case 0x4D: return GLFW_KEY_M; + case 0x4E: return GLFW_KEY_N; + case 0x4F: return GLFW_KEY_O; + case 0x50: return GLFW_KEY_P; + case 0x51: return GLFW_KEY_Q; + case 0x52: return GLFW_KEY_R; + case 0x53: return GLFW_KEY_S; + case 0x54: return GLFW_KEY_T; + case 0x55: return GLFW_KEY_U; + case 0x56: return GLFW_KEY_V; + case 0x57: return GLFW_KEY_W; + case 0x58: return GLFW_KEY_X; + case 0x59: return GLFW_KEY_Y; + case 0x5A: return GLFW_KEY_Z; + case 0xBD: return GLFW_KEY_MINUS; + case 0xBB: return GLFW_KEY_EQUAL; + case 0xDB: return GLFW_KEY_LEFT_BRACKET; + case 0xDD: return GLFW_KEY_RIGHT_BRACKET; + case 0xDC: return GLFW_KEY_BACKSLASH; + case 0xBA: return GLFW_KEY_SEMICOLON; + case 0xDE: return GLFW_KEY_APOSTROPHE; + case 0xC0: return GLFW_KEY_GRAVE_ACCENT; + case 0xBC: return GLFW_KEY_COMMA; + case 0xBE: return GLFW_KEY_PERIOD; + case 0xBF: return GLFW_KEY_SLASH; + case 0xDF: return GLFW_KEY_WORLD_1; + case 0xE2: return GLFW_KEY_WORLD_2; + default: break; } + + // No matching translation was found, so return -1 + return -1; } @@ -791,8 +826,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // Special trick: release both shift keys on SHIFT up event if (wParam == VK_SHIFT) { - _glfwInputKey(window, GLFW_KEY_LSHIFT, GLFW_RELEASE); - _glfwInputKey(window, GLFW_KEY_RSHIFT, GLFW_RELEASE); + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, GLFW_RELEASE); + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE); } else _glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE); From 518b3d95265572072997ccdfbb0c34c912db8f8b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 10 Jan 2011 21:38:08 +0100 Subject: [PATCH 7/8] Fixed some compiler errors under Win32. --- src/win32/win32_window.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c index cd6295a0..24f763dd 100644 --- a/src/win32/win32_window.c +++ b/src/win32/win32_window.c @@ -489,7 +489,7 @@ static int translateKey(WPARAM wParam, LPARAM lParam) { // Is this an extended key (i.e. right key)? if (lParam & 0x01000000) - return GLFW_KEY_RIGHT_CTRL; + 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 @@ -511,7 +511,7 @@ static int translateKey(WPARAM wParam, LPARAM lParam) } } - return GLFW_KEY_LEFT_CTRL; + return GLFW_KEY_LEFT_CONTROL; } // The ALT keys require special handling @@ -1798,11 +1798,11 @@ void _glfwPlatformPollEvents(void) // See if this differs from our belief of what has happened // (we only have to check for lost key up events) - if (!lshift_down && window->key[GLFW_KEY_LSHIFT] == 1) - _glfwInputKey(window, GLFW_KEY_LSHIFT, GLFW_RELEASE); + if (!lshift_down && window->key[GLFW_KEY_LEFT_SHIFT] == 1) + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, GLFW_RELEASE); - if (!rshift_down && window->key[GLFW_KEY_RSHIFT] == 1) - _glfwInputKey(window, GLFW_KEY_RSHIFT, GLFW_RELEASE); + if (!rshift_down && window->key[GLFW_KEY_RIGHT_SHIFT] == 1) + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, GLFW_RELEASE); } // Did we have mouse movement in locked cursor mode? From 6095e906abf906f0a22673b6a5d2e7d1392249ea Mon Sep 17 00:00:00 2001 From: Marcus Date: Mon, 10 Jan 2011 21:56:31 +0100 Subject: [PATCH 8/8] Implemented new key codes for Mac/Cocoa. --- src/cocoa/cocoa_window.m | 130 +++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/cocoa/cocoa_window.m b/src/cocoa/cocoa_window.m index 2b389e4d..f89fba79 100644 --- a/src/cocoa/cocoa_window.m +++ b/src/cocoa/cocoa_window.m @@ -147,70 +147,70 @@ // TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject. static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = { - /* 00 */ 'A', - /* 01 */ 'S', - /* 02 */ 'D', - /* 03 */ 'F', - /* 04 */ 'H', - /* 05 */ 'G', - /* 06 */ 'Z', - /* 07 */ 'X', - /* 08 */ 'C', - /* 09 */ 'V', + /* 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 */ -1, - /* 0b */ 'B', - /* 0c */ 'Q', - /* 0d */ 'W', - /* 0e */ 'E', - /* 0f */ 'R', - /* 10 */ 'Y', - /* 11 */ 'T', - /* 12 */ '1', - /* 13 */ '2', - /* 14 */ '3', - /* 15 */ '4', - /* 16 */ '6', - /* 17 */ '5', - /* 18 */ '=', - /* 19 */ '9', - /* 1a */ '7', - /* 1b */ '-', - /* 1c */ '8', - /* 1d */ '0', - /* 1e */ ']', - /* 1f */ 'O', - /* 20 */ 'U', - /* 21 */ '[', - /* 22 */ 'I', - /* 23 */ 'P', + /* 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 */ 'L', - /* 26 */ 'J', - /* 27 */ '\'', - /* 28 */ 'K', - /* 29 */ ';', - /* 2a */ '\\', - /* 2b */ ',', - /* 2c */ '/', - /* 2d */ 'N', - /* 2e */ 'M', - /* 2f */ '.', + /* 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 */ '`', + /* 32 */ GLFW_KEY_GRAVE_ACCENT, /* 33 */ GLFW_KEY_BACKSPACE, /* 34 */ -1, - /* 35 */ GLFW_KEY_ESC, - /* 36 */ GLFW_KEY_RSUPER, - /* 37 */ GLFW_KEY_LSUPER, - /* 38 */ GLFW_KEY_LSHIFT, + /* 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_LALT, - /* 3b */ GLFW_KEY_LCTRL, - /* 3c */ GLFW_KEY_RSHIFT, - /* 3d */ GLFW_KEY_RALT, - /* 3e */ GLFW_KEY_RCTRL, - /* 3f */ -1, /*Function*/ + /* 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 */ -1, /* Function */ /* 40 */ GLFW_KEY_F17, /* 41 */ GLFW_KEY_KP_DECIMAL, /* 42 */ -1, @@ -218,10 +218,10 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = /* 44 */ -1, /* 45 */ GLFW_KEY_KP_ADD, /* 46 */ -1, - /* 47 */ -1, /*KeypadClear*/ - /* 48 */ -1, /*VolumeUp*/ - /* 49 */ -1, /*VolumeDown*/ - /* 4a */ -1, /*Mute*/ + /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */ + /* 48 */ -1, /* VolumeUp */ + /* 49 */ -1, /* VolumeDown */ + /* 4a */ -1, /* Mute */ /* 4b */ GLFW_KEY_KP_DIVIDE, /* 4c */ GLFW_KEY_KP_ENTER, /* 4d */ -1, @@ -261,14 +261,14 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = /* 6f */ GLFW_KEY_F12, /* 70 */ -1, /* 71 */ GLFW_KEY_F15, - /* 72 */ GLFW_KEY_INSERT, /*Help*/ + /* 72 */ GLFW_KEY_INSERT, /* Really Help... */ /* 73 */ GLFW_KEY_HOME, - /* 74 */ GLFW_KEY_PAGEUP, - /* 75 */ GLFW_KEY_DEL, + /* 74 */ GLFW_KEY_PAGE_UP, + /* 75 */ GLFW_KEY_DELETE, /* 76 */ GLFW_KEY_F4, /* 77 */ GLFW_KEY_END, /* 78 */ GLFW_KEY_F2, - /* 79 */ GLFW_KEY_PAGEDOWN, + /* 79 */ GLFW_KEY_PAGE_DOWN, /* 7a */ GLFW_KEY_F1, /* 7b */ GLFW_KEY_LEFT, /* 7c */ GLFW_KEY_RIGHT,