From f4ed02f6c87d2689cb313c1911d846c0f6f1f7cc Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 14 Aug 2013 14:25:57 +0200 Subject: [PATCH 01/10] glfwGetKeyName(int key) - Windows version working with test in events.c --- include/GLFW/glfw3.h | 17 ++++ src/input.c | 14 +++ src/internal.h | 5 + src/win32_init.c | 2 + src/win32_platform.h | 1 + src/win32_window.c | 218 +++++++++++++++++++++++++++++++++++++++++++ tests/events.c | 25 ++++- 7 files changed, 280 insertions(+), 2 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index de2798b9..d1070b1c 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1772,6 +1772,23 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); +/*! @brief Returns the name of the specified key. + * + * This function returns the name, encoded as UTF-8, of the specified key. + * + * @param[in] key The key to query. + * @return The UTF-8 encoded name of the key, or `NULL` if there is an error. + * + * @note The returned string is allocated and freed by GLFW. You should not + * free it yourself. + * + * @note The returned string is valid only until the next call to @ref + * glfwGetKeyName. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetKeyName(int key); + /*! @brief Returns the last reported state of a keyboard key for the specified * window. * diff --git a/src/input.c b/src/input.c index 1bd7e6d8..3693167a 100644 --- a/src/input.c +++ b/src/input.c @@ -260,6 +260,20 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) } } +GLFWAPI const char* glfwGetKeyName(int key) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (key < 0 || key > GLFW_KEY_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "The specified key is invalid"); + return NULL; + } + + return _glfwPlatformGetKeyName(key); +} + + GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) { _GLFWwindow* window = (_GLFWwindow*) handle; diff --git a/src/internal.h b/src/internal.h index b6e2136b..644d8dc7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -367,6 +367,11 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); */ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); +/*! @copydoc glfwGetKeyName + * @ingroup platform + */ +const char*_glfwPlatformGetKeyName(int key); + /*! @copydoc glfwGetMonitors * @ingroup platform */ diff --git a/src/win32_init.c b/src/win32_init.c index 8e0c19b0..64e56afe 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -235,6 +235,8 @@ void _glfwPlatformTerminate(void) SPIF_SENDCHANGE); free(_glfw.win32.clipboardString); + free(_glfw.win32.keyName); + _glfwTerminateJoysticks(); _glfwTerminateContextAPI(); diff --git a/src/win32_platform.h b/src/win32_platform.h index e31abd9d..87ebaa8b 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -164,6 +164,7 @@ typedef struct _GLFWlibraryWin32 ATOM classAtom; DWORD foregroundLockTimeout; char* clipboardString; + char* keyName; // Timer data struct { diff --git a/src/win32_window.c b/src/win32_window.c index 7b1ce655..c23a8670 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1123,6 +1123,224 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) } } +const char*_glfwPlatformGetKeyName(int key) +{ + UINT charVK; + WCHAR keyName[2]; + int vkKey = 0; + + free(_glfw.win32.keyName); + _glfw.win32.keyName = NULL; + + switch( key ) + { + // Printable keys are handled via being turned into a win32 virtual key + // and then translated by MapVirtualKey. + // This correctly translates certain keys where hardcoding would not + // (A-Z are usually fine, but others may not be depending on locale). + case GLFW_KEY_SPACE: vkKey = VK_SPACE; break; + case GLFW_KEY_0: vkKey = 0x30; break; + case GLFW_KEY_1: vkKey = 0x31; break; + case GLFW_KEY_2: vkKey = 0x32; break; + case GLFW_KEY_3: vkKey = 0x33; break; + case GLFW_KEY_4: vkKey = 0x34; break; + case GLFW_KEY_5: vkKey = 0x35; break; + case GLFW_KEY_6: vkKey = 0x36; break; + case GLFW_KEY_7: vkKey = 0x37; break; + case GLFW_KEY_8: vkKey = 0x38; break; + case GLFW_KEY_9: vkKey = 0x39; break; + case GLFW_KEY_A: vkKey = 0x41; break; + case GLFW_KEY_B: vkKey = 0x42; break; + case GLFW_KEY_C: vkKey = 0x43; break; + case GLFW_KEY_D: vkKey = 0x44; break; + case GLFW_KEY_E: vkKey = 0x45; break; + case GLFW_KEY_F: vkKey = 0x46; break; + case GLFW_KEY_G: vkKey = 0x47; break; + case GLFW_KEY_H: vkKey = 0x48; break; + case GLFW_KEY_I: vkKey = 0x49; break; + case GLFW_KEY_J: vkKey = 0x4A; break; + case GLFW_KEY_K: vkKey = 0x4B; break; + case GLFW_KEY_L: vkKey = 0x4C; break; + case GLFW_KEY_M: vkKey = 0x4D; break; + case GLFW_KEY_N: vkKey = 0x4E; break; + case GLFW_KEY_O: vkKey = 0x4F; break; + case GLFW_KEY_P: vkKey = 0x50; break; + case GLFW_KEY_Q: vkKey = 0x51; break; + case GLFW_KEY_R: vkKey = 0x52; break; + case GLFW_KEY_S: vkKey = 0x53; break; + case GLFW_KEY_T: vkKey = 0x54; break; + case GLFW_KEY_U: vkKey = 0x55; break; + case GLFW_KEY_V: vkKey = 0x56; break; + case GLFW_KEY_W: vkKey = 0x57; break; + case GLFW_KEY_X: vkKey = 0x58; break; + case GLFW_KEY_Y: vkKey = 0x59; break; + case GLFW_KEY_Z: vkKey = 0x5A; break; + case GLFW_KEY_MINUS: vkKey = 0xBD; break; + case GLFW_KEY_EQUAL: vkKey = 0xBB; break; + case GLFW_KEY_LEFT_BRACKET: vkKey = 0xDB; break; + case GLFW_KEY_RIGHT_BRACKET: vkKey = 0xDD; break; + case GLFW_KEY_BACKSLASH: vkKey = 0xDC; break; + case GLFW_KEY_SEMICOLON: vkKey = 0xBA; break; + case GLFW_KEY_APOSTROPHE: vkKey = 0xDE; break; + case GLFW_KEY_GRAVE_ACCENT: vkKey = 0xC0; break; + case GLFW_KEY_COMMA: vkKey = 0xBC; break; + case GLFW_KEY_PERIOD: vkKey = 0xBE; break; + case GLFW_KEY_SLASH: vkKey = 0xBF; break; + case GLFW_KEY_WORLD_1: vkKey = 0xDF; break; + case GLFW_KEY_WORLD_2: vkKey = 0xE2; break; + default: break; + } + + if( vkKey ) + { + charVK = MapVirtualKey(vkKey, MAPVK_VK_TO_CHAR ); + if (charVK) + { + // construct null terminated wchar string from charachter for translation + keyName[0] = charVK; + keyName[1] = 0; + _glfw.win32.keyName = _glfwCreateUTF8FromWideString(keyName); + } + } + + if( NULL == _glfw.win32.keyName ) + { + // key could not be mapped or was not a printable key + // fall back to hard-coded values but do not set _glfw.win32.keyName + 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_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 "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"; + + // Function keys + case GLFW_KEY_ESCAPE: return "ESCAPE"; + case GLFW_KEY_F1: return "F1"; + case GLFW_KEY_F2: return "F2"; + case GLFW_KEY_F3: return "F3"; + case GLFW_KEY_F4: return "F4"; + case GLFW_KEY_F5: return "F5"; + case GLFW_KEY_F6: return "F6"; + case GLFW_KEY_F7: return "F7"; + case GLFW_KEY_F8: return "F8"; + case GLFW_KEY_F9: return "F9"; + case GLFW_KEY_F10: return "F10"; + case GLFW_KEY_F11: return "F11"; + case GLFW_KEY_F12: return "F12"; + case GLFW_KEY_F13: return "F13"; + case GLFW_KEY_F14: return "F14"; + case GLFW_KEY_F15: return "F15"; + case GLFW_KEY_F16: return "F16"; + case GLFW_KEY_F17: return "F17"; + case GLFW_KEY_F18: return "F18"; + case GLFW_KEY_F19: return "F19"; + case GLFW_KEY_F20: return "F20"; + case GLFW_KEY_F21: return "F21"; + case GLFW_KEY_F22: return "F22"; + 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 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_PRINT_SCREEN: return "PRINT SCREEN"; + 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_UNKNOWN: return "UNKNOWN"; + + default: return NULL; + } + } + + + return _glfw.win32.keyName; +} ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/tests/events.c b/tests/events.c index 320af621..b711b6ab 100644 --- a/tests/events.c +++ b/tests/events.c @@ -340,15 +340,36 @@ static void scroll_callback(GLFWwindow* window, double x, double y) printf("%08x at %0.3f: Scroll: %0.3f %0.3f\n", counter++, glfwGetTime(), x, y); } +// Work-around for windows console output of UTF-8 strings +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #include "Windows.h" + void PlatformPrintKeyName(const char* keyName) + { + WCHAR target[80]; + MultiByteToWideChar(CP_UTF8, 0, keyName, -1, target, 80); + printf(" (%ls)", target ); + } +#else + void PlatformPrintKeyName(const char* keyName) + { + printf(" (%s)", keyName ); + } +#endif + static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { - const char* name = get_key_name(key); + const char* name = glfwGetKeyName(key); + const char* glfwName = get_key_name(key); printf("%08x at %0.3f: Key 0x%04x Scancode 0x%04x", counter++, glfwGetTime(), key, scancode); if (name) - printf(" (%s)", name); + PlatformPrintKeyName( name ); + + if(glfwName) + printf(" GLFW Key Code Name: [%s]", glfwName); if (mods) printf(" (with%s)", get_mods_name(mods)); From 6edcc75a6bbe6f358a2ba5d5101c6872472cc211 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 14 Aug 2013 14:41:39 +0200 Subject: [PATCH 02/10] glfwGetKeyName(int key) - Added stub methods for X11 and Cocoa --- src/cocoa_window.m | 5 +++++ src/x11_window.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 4a2c0c35..47230249 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1094,6 +1094,11 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) } } +const char*_glfwPlatformGetKeyName(int key) +{ + // TODO: Implement. + return NULL; +} ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/x11_window.c b/src/x11_window.c index 9b3791c2..b15304bd 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1163,6 +1163,11 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) } } +const char*_glfwPlatformGetKeyName(int key) +{ + // TODO: Implement. + return NULL; +} ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// From 9c68e11f2fee44b867bf4d2291399a1915bfd08d Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 14 Aug 2013 17:12:11 +0200 Subject: [PATCH 03/10] glfwGetKeyName(int key) - Cocoa version working (adds dep to Carbon framework). --- CMakeLists.txt | 6 +- src/cocoa_window.m | 234 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e7983cb..7d12a870 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,13 +343,15 @@ if (_GLFW_COCOA AND _GLFW_NSGL) find_library(COCOA_FRAMEWORK Cocoa) find_library(IOKIT_FRAMEWORK IOKit) find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) + find_library(CARBON_FRAMEWORK Carbon) list(APPEND glfw_LIBRARIES ${COCOA_FRAMEWORK} ${OPENGL_gl_LIBRARY} ${IOKIT_FRAMEWORK} - ${CORE_FOUNDATION_FRAMEWORK}) + ${CORE_FOUNDATION_FRAMEWORK} + ${CARBON_FRAMEWORK}) set(GLFW_PKG_DEPS "") - set(GLFW_PKG_LIBS "-framework Cocoa -framework OpenGL -framework IOKit -framework CoreFoundation") + set(GLFW_PKG_LIBS "-framework Cocoa -framework OpenGL -framework IOKit -framework CoreFoundation -framework Carbon") endif() #-------------------------------------------------------------------- diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 47230249..454bd263 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -29,6 +29,8 @@ // Needed for _NSGetProgname #include +// Need for _glfwPlatformGetKeyName TIS* functions +#include // Enter fullscreen mode // @@ -1094,10 +1096,236 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) } } -const char*_glfwPlatformGetKeyName(int key) +const char* _glfwPlatformGetKeyName(int key) { - // TODO: Implement. - return NULL; + // First try to translate virtual key mac os x style + UInt16 vKey = 0; + switch(key) + { + case GLFW_KEY_A: vKey = 0; break; + case GLFW_KEY_S: vKey = 1; break; + case GLFW_KEY_D: vKey = 2; break; + case GLFW_KEY_F: vKey = 3; break; + case GLFW_KEY_H: vKey = 4; break; + case GLFW_KEY_G: vKey = 5; break; + case GLFW_KEY_Z: vKey = 6; break; + case GLFW_KEY_X: vKey = 7; break; + case GLFW_KEY_C: vKey = 8; break; + case GLFW_KEY_V: vKey = 9; break; + case GLFW_KEY_GRAVE_ACCENT: vKey = 10; break; + case GLFW_KEY_B: vKey = 11; break; + case GLFW_KEY_Q: vKey = 12; break; + case GLFW_KEY_W: vKey = 13; break; + case GLFW_KEY_E: vKey = 14; break; + case GLFW_KEY_R: vKey = 15; break; + case GLFW_KEY_Y: vKey = 16; break; + case GLFW_KEY_T: vKey = 17; break; + case GLFW_KEY_1: vKey = 18; break; + case GLFW_KEY_2: vKey = 19; break; + case GLFW_KEY_3: vKey = 20; break; + case GLFW_KEY_4: vKey = 21; break; + case GLFW_KEY_6: vKey = 22; break; + case GLFW_KEY_5: vKey = 23; break; + case GLFW_KEY_EQUAL: vKey = 24; break; + case GLFW_KEY_9: vKey = 25; break; + case GLFW_KEY_7: vKey = 26; break; + case GLFW_KEY_MINUS: vKey = 27; break; + case GLFW_KEY_8: vKey = 28; break; + case GLFW_KEY_0: vKey = 29; break; + case GLFW_KEY_RIGHT_BRACKET: vKey = 30; break; + case GLFW_KEY_O: vKey = 31; break; + case GLFW_KEY_U: vKey = 32; break; + case GLFW_KEY_LEFT_BRACKET: vKey = 33; break; + case GLFW_KEY_I: vKey = 34; break; + case GLFW_KEY_P: vKey = 35; break; + case GLFW_KEY_ENTER: vKey = 36; break; + case GLFW_KEY_L: vKey = 37; break; + case GLFW_KEY_J: vKey = 38; break; + case GLFW_KEY_APOSTROPHE: vKey = 39; break; + case GLFW_KEY_K: vKey = 40; break; + case GLFW_KEY_SEMICOLON: vKey = 41; break; + case GLFW_KEY_BACKSLASH: vKey = 42; break; + case GLFW_KEY_COMMA: vKey = 43; break; + case GLFW_KEY_SLASH: vKey = 44; break; + case GLFW_KEY_N: vKey = 45; break; + case GLFW_KEY_M: vKey = 46; break; + case GLFW_KEY_PERIOD: vKey = 47; break; + case GLFW_KEY_TAB: vKey = 48; break; + case GLFW_KEY_SPACE: vKey = 49; break; + case GLFW_KEY_WORLD_1: vKey = 50; break; + } + + if (vKey) + { + // get the current keyboard, need to do this every time + // in case keyboard has changed + TISInputSourceRef tisInputSource = TISCopyCurrentKeyboardInputSource(); + CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(tisInputSource, kTISPropertyUnicodeKeyLayoutData); + const UCKeyboardLayout *kbLayoutUC = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); + + if (kbLayoutUC) + { + UInt32 deadKeyState = 0; + UniCharCount maxStringLength = 255; + UniCharCount actualStringLength = 0; + UniChar unicodeString[maxStringLength]; + + OSStatus status = UCKeyTranslate(kbLayoutUC, + vKey, kUCKeyActionDown, 0, + LMGetKbdType(), 0, + &deadKeyState, + maxStringLength, + &actualStringLength, unicodeString); + + if (actualStringLength == 0 && deadKeyState) + { + status = UCKeyTranslate(kbLayoutUC, + kVK_Space, kUCKeyActionDown, 0, + LMGetKbdType(), 0, + &deadKeyState, + maxStringLength, + &actualStringLength, unicodeString); + } + if (actualStringLength > 0 && status == noErr) + { + NSString* tempNS = [[NSString stringWithCharacters:unicodeString length:(NSUInteger)actualStringLength] uppercaseString]; + char* pTodoFree = strdup([tempNS UTF8String]); + return pTodoFree; + } + } + } + + + // Fallback to hard coded + 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_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 "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"; + + // Function keys + case GLFW_KEY_ESCAPE: return "ESCAPE"; + case GLFW_KEY_F1: return "F1"; + case GLFW_KEY_F2: return "F2"; + case GLFW_KEY_F3: return "F3"; + case GLFW_KEY_F4: return "F4"; + case GLFW_KEY_F5: return "F5"; + case GLFW_KEY_F6: return "F6"; + case GLFW_KEY_F7: return "F7"; + case GLFW_KEY_F8: return "F8"; + case GLFW_KEY_F9: return "F9"; + case GLFW_KEY_F10: return "F10"; + case GLFW_KEY_F11: return "F11"; + case GLFW_KEY_F12: return "F12"; + case GLFW_KEY_F13: return "F13"; + case GLFW_KEY_F14: return "F14"; + case GLFW_KEY_F15: return "F15"; + case GLFW_KEY_F16: return "F16"; + case GLFW_KEY_F17: return "F17"; + case GLFW_KEY_F18: return "F18"; + case GLFW_KEY_F19: return "F19"; + case GLFW_KEY_F20: return "F20"; + case GLFW_KEY_F21: return "F21"; + case GLFW_KEY_F22: return "F22"; + 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 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_PRINT_SCREEN: return "PRINT SCREEN"; + 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_UNKNOWN: return "UNKNOWN"; + + default: return NULL; + } } ////////////////////////////////////////////////////////////////////////// From 363ec64321105a4cdb8a2bfb85de0b92c116fa5f Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 14 Aug 2013 18:35:32 +0200 Subject: [PATCH 04/10] Fixed memory leak in cocoa _glfwPlatformGetKeyName --- src/cocoa_platform.h | 1 + src/cocoa_window.m | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index b422e13c..a31a8463 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -108,6 +108,7 @@ typedef struct _GLFWlibraryNS GLboolean cursorHidden; char* clipboardString; + char* keyName; _GLFWjoy joysticks[GLFW_JOYSTICK_LAST + 1]; } _GLFWlibraryNS; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 454bd263..d118a717 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1098,7 +1098,11 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) const char* _glfwPlatformGetKeyName(int key) { - // First try to translate virtual key mac os x style + // free temp keyname + free(_glfw.ns.keyName); + _glfw.ns.keyName = 0; + + // Try to translate virtual key mac os x style UInt16 vKey = 0; switch(key) { @@ -1189,8 +1193,8 @@ const char* _glfwPlatformGetKeyName(int key) if (actualStringLength > 0 && status == noErr) { NSString* tempNS = [[NSString stringWithCharacters:unicodeString length:(NSUInteger)actualStringLength] uppercaseString]; - char* pTodoFree = strdup([tempNS UTF8String]); - return pTodoFree; + _glfw.ns.keyName = strdup([tempNS UTF8String]); + return _glfw.ns.keyName; } } } From b04b98986a6ebe4ba95b234b505525235c30712a Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Thu, 15 Aug 2013 15:22:35 +0200 Subject: [PATCH 05/10] X11 input fix for keypad issues. --- src/x11_init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index 1c28e5f3..4659c153 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -48,7 +48,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, 1, 0); + keySym = XkbKeycodeToKeysym(_glfw.x11.display, keyCode, 0, 1); switch (keySym) { case XK_KP_0: return GLFW_KEY_KP_0; @@ -68,6 +68,7 @@ static int translateKey(int keyCode) 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). @@ -307,7 +308,7 @@ static void updateKeyCodeLUT(void) // lookups for (keyCode = 0; keyCode < 256; keyCode++) { - if (_glfw.x11.keyCodeLUT[keyCode] < 0) + //if (_glfw.x11.keyCodeLUT[keyCode] < 0) _glfw.x11.keyCodeLUT[keyCode] = translateKey(keyCode); } } From 993e1acf699a7f610b3dbc6730653ebe82c036f7 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Thu, 15 Aug 2013 15:25:00 +0200 Subject: [PATCH 06/10] X11 fix for errorneous change in previous commit. --- src/x11_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11_init.c b/src/x11_init.c index 4659c153..98a47f27 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -308,7 +308,7 @@ static void updateKeyCodeLUT(void) // lookups for (keyCode = 0; keyCode < 256; keyCode++) { - //if (_glfw.x11.keyCodeLUT[keyCode] < 0) + if (_glfw.x11.keyCodeLUT[keyCode] < 0) _glfw.x11.keyCodeLUT[keyCode] = translateKey(keyCode); } } From 5205f071a40ec7444dd4209d1d57da7516aa1616 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Thu, 15 Aug 2013 17:26:33 +0200 Subject: [PATCH 07/10] X11 implementation. --- src/x11_init.c | 1 + src/x11_platform.h | 2 + src/x11_window.c | 269 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 270 insertions(+), 2 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index 98a47f27..f040c06a 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -673,6 +673,7 @@ void _glfwPlatformTerminate(void) } free(_glfw.x11.selection.string); + free(_glfw.x11.keyName); _glfwTerminateJoysticks(); _glfwTerminateContextAPI(); diff --git a/src/x11_platform.h b/src/x11_platform.h index 868429fa..cd1dc054 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -190,6 +190,8 @@ typedef struct _GLFWlibraryX11 char* string; } selection; + char* keyName; + struct { int present; int fd; diff --git a/src/x11_window.c b/src/x11_window.c index b15304bd..cf0bb449 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include // Action for EWMH client messages #define _NET_WM_STATE_REMOVE 0 @@ -1165,8 +1167,271 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) const char*_glfwPlatformGetKeyName(int key) { - // TODO: Implement. - return NULL; + int KeyCodeFound = -1; + int printable = 0; + int keySym, ucsChar, keyCode, length; + char* locale; + + switch(key) + { + case GLFW_KEY_A: printable=1; break; + case GLFW_KEY_B: printable=1; break; + case GLFW_KEY_C: printable=1; break; + case GLFW_KEY_D: printable=1; break; + case GLFW_KEY_E: printable=1; break; + case GLFW_KEY_F: printable=1; break; + case GLFW_KEY_G: printable=1; break; + case GLFW_KEY_H: printable=1; break; + case GLFW_KEY_I: printable=1; break; + case GLFW_KEY_J: printable=1; break; + case GLFW_KEY_K: printable=1; break; + case GLFW_KEY_L: printable=1; break; + case GLFW_KEY_M: printable=1; break; + case GLFW_KEY_N: printable=1; break; + case GLFW_KEY_O: printable=1; break; + case GLFW_KEY_P: printable=1; break; + case GLFW_KEY_Q: printable=1; break; + case GLFW_KEY_R: printable=1; break; + case GLFW_KEY_S: printable=1; break; + case GLFW_KEY_T: printable=1; break; + case GLFW_KEY_U: printable=1; break; + case GLFW_KEY_V: printable=1; break; + case GLFW_KEY_W: printable=1; break; + case GLFW_KEY_X: printable=1; break; + case GLFW_KEY_Y: printable=1; break; + case GLFW_KEY_Z: printable=1; break; + case GLFW_KEY_1: printable=1; break; + case GLFW_KEY_2: printable=1; break; + case GLFW_KEY_3: printable=1; break; + case GLFW_KEY_4: printable=1; break; + case GLFW_KEY_5: printable=1; break; + case GLFW_KEY_6: printable=1; break; + case GLFW_KEY_7: printable=1; break; + case GLFW_KEY_8: printable=1; break; + case GLFW_KEY_9: printable=1; break; + case GLFW_KEY_0: printable=1; break; + case GLFW_KEY_SPACE: printable=1; break; + case GLFW_KEY_MINUS: printable=1; break; + case GLFW_KEY_EQUAL: printable=1; break; + case GLFW_KEY_LEFT_BRACKET: printable=1; break; + case GLFW_KEY_RIGHT_BRACKET: printable=1; break; + case GLFW_KEY_BACKSLASH: printable=1; break; + case GLFW_KEY_SEMICOLON: printable=1; break; + case GLFW_KEY_APOSTROPHE: printable=1; break; + case GLFW_KEY_GRAVE_ACCENT: printable=1; break; + case GLFW_KEY_COMMA: printable=1; break; + case GLFW_KEY_PERIOD: printable=1; break; + case GLFW_KEY_SLASH: printable=1; break; + case GLFW_KEY_WORLD_1: printable=1; break; + default: break; + } + + if (printable) + { + // We now need to search for the keyCode. + // This could be sped up through a table, but this function should not be called that frequently + // Valid key code range is [8,255], according to the XLib manual + for(keyCode = 8; keyCode<=255; ++keyCode) + { + if( translateKey(keyCode) == key ) + { + KeyCodeFound = keyCode; + break; + } + } + + if(KeyCodeFound>=0) + { + // get keyboard group in use via state + XkbStateRec state; + XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state); + + keySym = XkbKeycodeToKeysym(_glfw.x11.display, KeyCodeFound, state.group, 0); + ucsChar = _glfwKeySym2Unicode( keySym ); + if( ucsChar > 0 ) + { + // get current locale and set to for wctomb + locale = setlocale(LC_CTYPE,NULL); + setlocale(LC_CTYPE,""); + if(!_glfw.x11.keyName) + { + // only need to allocate once + _glfw.x11.keyName = calloc(MB_CUR_MAX+1,sizeof(char)); + } + length = wctomb(_glfw.x11.keyName, ucsChar); + + // reset locale + setlocale(LC_CTYPE,locale); + + _glfw.x11.keyName[length]='\0'; + if(length>0) + { + // need to ensure common chars are interpreted similarily: + if(length=1) + { + if(_glfw.x11.keyName[0]>='a' && _glfw.x11.keyName[0]<='z') + { + // Capitalize + _glfw.x11.keyName[0] += 'A'-'a'; + } + + switch(_glfw.x11.keyName[0]) + { + case ' ': return "SPACE"; + case '-': return "MINUS"; + case '=': return "EQUAL"; + case '[': return "LEFT BRACKET"; + case ']': return "RIGHT BRACKET"; + case '\\': return "BACKSLASH"; + case ';': return "SEMICOLON"; + case '\'': return "APOSTROPHE"; + case '`': return "GRAVE ACCENT"; + case ',': return "COMMA"; + case '.': return "PERIOD"; + case '/': return "SLASH"; + default: break; + } + } + return _glfw.x11.keyName; + } + } + + } + } + + + // Fallback to hard coded + 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_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 "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"; + + // Function keys + case GLFW_KEY_ESCAPE: return "ESCAPE"; + case GLFW_KEY_F1: return "F1"; + case GLFW_KEY_F2: return "F2"; + case GLFW_KEY_F3: return "F3"; + case GLFW_KEY_F4: return "F4"; + case GLFW_KEY_F5: return "F5"; + case GLFW_KEY_F6: return "F6"; + case GLFW_KEY_F7: return "F7"; + case GLFW_KEY_F8: return "F8"; + case GLFW_KEY_F9: return "F9"; + case GLFW_KEY_F10: return "F10"; + case GLFW_KEY_F11: return "F11"; + case GLFW_KEY_F12: return "F12"; + case GLFW_KEY_F13: return "F13"; + case GLFW_KEY_F14: return "F14"; + case GLFW_KEY_F15: return "F15"; + case GLFW_KEY_F16: return "F16"; + case GLFW_KEY_F17: return "F17"; + case GLFW_KEY_F18: return "F18"; + case GLFW_KEY_F19: return "F19"; + case GLFW_KEY_F20: return "F20"; + case GLFW_KEY_F21: return "F21"; + case GLFW_KEY_F22: return "F22"; + 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 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_PRINT_SCREEN: return "PRINT SCREEN"; + 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_UNKNOWN: return "UNKNOWN"; + + default: break; + } + + return NULL; } ////////////////////////////////////////////////////////////////////////// From 2a59848c8f5db8e6d2035b2f887e026c5c2a7976 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Thu, 15 Aug 2013 17:41:29 +0200 Subject: [PATCH 08/10] glfwGetKeyName(int key) - Windows version consistency improvements --- src/win32_window.c | 291 ++++++++++++++++++++++++--------------------- 1 file changed, 158 insertions(+), 133 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index c23a8670..302dc3f6 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1128,6 +1128,7 @@ const char*_glfwPlatformGetKeyName(int key) UINT charVK; WCHAR keyName[2]; int vkKey = 0; + int length; free(_glfw.win32.keyName); _glfw.win32.keyName = NULL; @@ -1200,146 +1201,170 @@ const char*_glfwPlatformGetKeyName(int key) keyName[0] = charVK; keyName[1] = 0; _glfw.win32.keyName = _glfwCreateUTF8FromWideString(keyName); + + // need to ensure common chars are interpreted similarily: + length = strlen(_glfw.win32.keyName); + if(length=1) + { + if(_glfw.win32.keyName[0]>='a' && _glfw.win32.keyName[0]<='z') + { + // Capitalize + _glfw.win32.keyName[0] += 'A'-'a'; + } + + switch(_glfw.win32.keyName[0]) + { + case ' ': return "SPACE"; + case '-': return "MINUS"; + case '=': return "EQUAL"; + case '[': return "LEFT BRACKET"; + case ']': return "RIGHT BRACKET"; + case '\\': return "BACKSLASH"; + case ';': return "SEMICOLON"; + case '\'': return "APOSTROPHE"; + case '`': return "GRAVE ACCENT"; + case ',': return "COMMA"; + case '.': return "PERIOD"; + case '/': return "SLASH"; + default: break; + } + } + + return _glfw.win32.keyName; } } - if( NULL == _glfw.win32.keyName ) + // key could not be mapped or was not a printable key + // fall back to hard-coded values but do not set _glfw.win32.keyName + switch (key) { - // key could not be mapped or was not a printable key - // fall back to hard-coded values but do not set _glfw.win32.keyName - 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_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 "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"; + // 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 "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"; - // Function keys - case GLFW_KEY_ESCAPE: return "ESCAPE"; - case GLFW_KEY_F1: return "F1"; - case GLFW_KEY_F2: return "F2"; - case GLFW_KEY_F3: return "F3"; - case GLFW_KEY_F4: return "F4"; - case GLFW_KEY_F5: return "F5"; - case GLFW_KEY_F6: return "F6"; - case GLFW_KEY_F7: return "F7"; - case GLFW_KEY_F8: return "F8"; - case GLFW_KEY_F9: return "F9"; - case GLFW_KEY_F10: return "F10"; - case GLFW_KEY_F11: return "F11"; - case GLFW_KEY_F12: return "F12"; - case GLFW_KEY_F13: return "F13"; - case GLFW_KEY_F14: return "F14"; - case GLFW_KEY_F15: return "F15"; - case GLFW_KEY_F16: return "F16"; - case GLFW_KEY_F17: return "F17"; - case GLFW_KEY_F18: return "F18"; - case GLFW_KEY_F19: return "F19"; - case GLFW_KEY_F20: return "F20"; - case GLFW_KEY_F21: return "F21"; - case GLFW_KEY_F22: return "F22"; - 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 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_PRINT_SCREEN: return "PRINT SCREEN"; - 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_UNKNOWN: return "UNKNOWN"; - - default: return NULL; - } + // Function keys + case GLFW_KEY_ESCAPE: return "ESCAPE"; + case GLFW_KEY_F1: return "F1"; + case GLFW_KEY_F2: return "F2"; + case GLFW_KEY_F3: return "F3"; + case GLFW_KEY_F4: return "F4"; + case GLFW_KEY_F5: return "F5"; + case GLFW_KEY_F6: return "F6"; + case GLFW_KEY_F7: return "F7"; + case GLFW_KEY_F8: return "F8"; + case GLFW_KEY_F9: return "F9"; + case GLFW_KEY_F10: return "F10"; + case GLFW_KEY_F11: return "F11"; + case GLFW_KEY_F12: return "F12"; + case GLFW_KEY_F13: return "F13"; + case GLFW_KEY_F14: return "F14"; + case GLFW_KEY_F15: return "F15"; + case GLFW_KEY_F16: return "F16"; + case GLFW_KEY_F17: return "F17"; + case GLFW_KEY_F18: return "F18"; + case GLFW_KEY_F19: return "F19"; + case GLFW_KEY_F20: return "F20"; + case GLFW_KEY_F21: return "F21"; + case GLFW_KEY_F22: return "F22"; + 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 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_PRINT_SCREEN: return "PRINT SCREEN"; + 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_UNKNOWN: return "UNKNOWN"; } - - return _glfw.win32.keyName; + return NULL; } ////////////////////////////////////////////////////////////////////////// From c0fcb50e5fe5fe21a5067e98326d404192644d8e Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Thu, 15 Aug 2013 18:12:35 +0200 Subject: [PATCH 09/10] glfwGetKeyName(int key) - bugfix for previous commit. --- src/win32_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32_window.c b/src/win32_window.c index 302dc3f6..e1116a3a 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1204,7 +1204,7 @@ const char*_glfwPlatformGetKeyName(int key) // need to ensure common chars are interpreted similarily: length = strlen(_glfw.win32.keyName); - if(length=1) + if(1==length) { if(_glfw.win32.keyName[0]>='a' && _glfw.win32.keyName[0]<='z') { From ff8f9e3170f0afa8489cb0dfedde91d2009dc7e5 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Thu, 15 Aug 2013 18:09:07 +0200 Subject: [PATCH 10/10] _glfwPlatformGetKeyName improve consistency of returned values on Cocoa --- src/cocoa_window.m | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index d118a717..19810441 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1194,6 +1194,36 @@ const char* _glfwPlatformGetKeyName(int key) { NSString* tempNS = [[NSString stringWithCharacters:unicodeString length:(NSUInteger)actualStringLength] uppercaseString]; _glfw.ns.keyName = strdup([tempNS UTF8String]); + + // need to ensure common chars are interpreted similarily: + int length = strlen(_glfw.ns.keyName); + if(1==length) + { + if(_glfw.ns.keyName[0]>='a' && _glfw.ns.keyName[0]<='z') + { + // Capitalize + _glfw.ns.keyName[0] += 'A'-'a'; + } + + switch(_glfw.ns.keyName[0]) + { + case ' ': return "SPACE"; + case '-': return "MINUS"; + case '=': return "EQUAL"; + case '[': return "LEFT BRACKET"; + case ']': return "RIGHT BRACKET"; + case '\\': return "BACKSLASH"; + case ';': return "SEMICOLON"; + case '\'': return "APOSTROPHE"; + case '`': return "GRAVE ACCENT"; + case ',': return "COMMA"; + case '.': return "PERIOD"; + case '/': return "SLASH"; + default: break; + } + } + + return _glfw.ns.keyName; } }