diff --git a/README.md b/README.md index 90a1196f..64416958 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ information on what to include when reporting a bug. invalid pointer - [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN` (#1623) + - [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16 - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle - [Cocoa] Moved main menu creation to GLFW initialization time (#1649) diff --git a/src/win32_platform.h b/src/win32_platform.h index 5b260b82..76ea609a 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -311,6 +311,8 @@ typedef struct _GLFWwindowWin32 // The last received cursor position, regardless of source int lastCursorPosX, lastCursorPosY; + // The last recevied high surrogate when decoding pairs of UTF-16 messages + WCHAR highSurrogate; } _GLFWwindowWin32; diff --git a/src/win32_window.c b/src/win32_window.c index d9c30c55..9dc52bab 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -646,11 +646,38 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_CHAR: case WM_SYSCHAR: + { + if (wParam >= 0xd800 && wParam <= 0xdbff) + window->win32.highSurrogate = (WCHAR) wParam; + else + { + unsigned int codepoint = 0; + + if (wParam >= 0xdc00 && wParam <= 0xdfff) + { + if (window->win32.highSurrogate) + { + codepoint += (window->win32.highSurrogate - 0xd800) << 10; + codepoint += (WCHAR) wParam - 0xdc00; + codepoint += 0x10000; + } + } + else + codepoint = (WCHAR) wParam; + + window->win32.highSurrogate = 0; + _glfwInputChar(window, codepoint, getKeyMods(), uMsg != WM_SYSCHAR); + } + + if (uMsg == WM_SYSCHAR && window->win32.keymenu) + break; + + return 0; + } + case WM_UNICHAR: { - const GLFWbool plain = (uMsg != WM_SYSCHAR); - - if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR) + if (wParam == UNICODE_NOCHAR) { // WM_UNICHAR is not sent by Windows, but is sent by some // third-party input method engine @@ -658,11 +685,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return TRUE; } - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain); - - if (uMsg == WM_SYSCHAR && window->win32.keymenu) - break; - + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE); return 0; }