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 6ce2070392)
This commit is contained in:
Camilla Löwy 2020-06-29 20:43:28 +02:00
parent e6646c8508
commit d858e48860
3 changed files with 31 additions and 4 deletions

View File

@ -120,6 +120,7 @@ information on what to include when reporting a bug.
- Bugfix: Some extension loader headers did not prevent default OpenGL header - Bugfix: Some extension loader headers did not prevent default OpenGL header
inclusion (#1695) inclusion (#1695)
- [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
- [Cocoa] Changed `EGLNativeWindowType` from `NSView` to `CALayer` (#1169) - [Cocoa] Changed `EGLNativeWindowType` from `NSView` to `CALayer` (#1169)
- [Cocoa] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16 - [Cocoa] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
(#1635) (#1635)

View File

@ -318,6 +318,8 @@ typedef struct _GLFWwindowWin32
// The last received cursor position, regardless of source // The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY; int lastCursorPosX, lastCursorPosY;
// The last recevied high surrogate when decoding pairs of UTF-16 messages
WCHAR highSurrogate;
} _GLFWwindowWin32; } _GLFWwindowWin32;

View File

@ -645,11 +645,35 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_CHAR: case WM_CHAR:
case WM_SYSCHAR: 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: case WM_UNICHAR:
{ {
const GLFWbool plain = (uMsg != WM_SYSCHAR); if (wParam == UNICODE_NOCHAR)
if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
{ {
// WM_UNICHAR is not sent by Windows, but is sent by some // WM_UNICHAR is not sent by Windows, but is sent by some
// third-party input method engine // third-party input method engine
@ -657,7 +681,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return TRUE; return TRUE;
} }
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain); _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE);
return 0; return 0;
} }