Win32: Fix key names not matching other platforms

This brings printable key names more in line with the results provided
on other platforms.

Fixes #943.
This commit is contained in:
Camilla Löwy 2017-02-07 03:29:57 +01:00
parent 1955c37c48
commit f8668c5a9f
4 changed files with 65 additions and 15 deletions

View File

@ -193,6 +193,7 @@ information on what to include when reporting a bug.
- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
(#650,#1071)
- [Win32] Bugfix: Returned key names did not match other platforms (#943)
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X

View File

@ -429,6 +429,60 @@ void _glfwInputErrorWin32(int error, const char* description)
_glfwInputError(error, "%s: %s", description, message);
}
// Updates key names according to the current keyboard layout
//
void _glfwUpdateKeyNamesWin32(void)
{
int key;
BYTE state[256] = {0};
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
{
UINT vk;
int scancode, length;
WCHAR chars[16];
scancode = _glfw.win32.scancodes[key];
if (scancode == -1)
continue;
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
{
const UINT vks[] = {
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
};
vk = vks[key - GLFW_KEY_KP_0];
}
else
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
{
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_glfw.win32.keynames[key],
sizeof(_glfw.win32.keynames[key]),
NULL, NULL);
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
@ -448,6 +502,7 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
createKeyTables();
_glfwUpdateKeyNamesWin32();
if (_glfw_SetProcessDpiAwareness)
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);

View File

@ -250,9 +250,9 @@ typedef struct _GLFWlibraryWin32
DWORD foregroundLockTimeout;
int acquiredMonitorCount;
char* clipboardString;
char keyName[64];
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
@ -353,6 +353,7 @@ void _glfwUnregisterWindowClassWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void);
void _glfwInitTimerWin32(void);

View File

@ -584,6 +584,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0;
}
case WM_INPUTLANGCHANGE:
{
_glfwUpdateKeyNamesWin32();
break;
}
case WM_CHAR:
case WM_SYSCHAR:
case WM_UNICHAR:
@ -1652,20 +1658,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
const char* _glfwPlatformGetScancodeName(int scancode)
{
WCHAR name[16];
if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR)))
return NULL;
if (!WideCharToMultiByte(CP_UTF8, 0, name, -1,
_glfw.win32.keyName,
sizeof(_glfw.win32.keyName),
NULL, NULL))
{
return NULL;
}
return _glfw.win32.keyName;
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
}
int _glfwPlatformGetKeyScancode(int key)