From d858e48860c7fb59aedac098003a5f3d436b2783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 29 Jun 2020 20:43:28 +0200 Subject: [PATCH] Win32: Fix non-BMP Unicode codepoint input Supplementary Plane codepoints from WM_CHAR and WM_SYSCHAR messages were reported as UTF-16 surrogate pairs. Related to #1635. (cherry picked from commit 6ce207039240a63120a91ee4ba4d39bd0a3ef8c8) --- README.md | 1 + src/win32_platform.h | 2 ++ src/win32_window.c | 32 ++++++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0569a4c..9f82fce2 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ information on what to include when reporting a bug. - Bugfix: Some extension loader headers did not prevent default OpenGL header inclusion (#1695) + - [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16 - [Cocoa] Changed `EGLNativeWindowType` from `NSView` to `CALayer` (#1169) - [Cocoa] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16 (#1635) diff --git a/src/win32_platform.h b/src/win32_platform.h index be1dc544..426c0efc 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -318,6 +318,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 0ce22ee7..b19f6c61 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -645,11 +645,35 @@ 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); + } + + 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 @@ -657,7 +681,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return TRUE; } - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain); + _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE); return 0; }