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.
master
Camilla Löwy ago%!(EXTRA string=5 years)
parent e47832ffcf
commit 6ce2070392
  1. 1
      README.md
  2. 2
      src/win32_platform.h
  3. 39
      src/win32_window.c

@ -152,6 +152,7 @@ information on what to include when reporting a bug.
invalid pointer invalid pointer
- [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN` - [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN`
(#1623) (#1623)
- [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649) - [Cocoa] Moved main menu creation to GLFW initialization time (#1649)

@ -311,6 +311,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;

@ -646,19 +646,28 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_CHAR: case WM_CHAR:
case WM_SYSCHAR: case WM_SYSCHAR:
case WM_UNICHAR:
{ {
const GLFWbool plain = (uMsg != WM_SYSCHAR); if (wParam >= 0xd800 && wParam <= 0xdbff)
window->win32.highSurrogate = (WCHAR) wParam;
else
{
unsigned int codepoint = 0;
if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR) if (wParam >= 0xdc00 && wParam <= 0xdfff)
{ {
// WM_UNICHAR is not sent by Windows, but is sent by some if (window->win32.highSurrogate)
// third-party input method engine {
// Returning TRUE here announces support for this message codepoint += (window->win32.highSurrogate - 0xd800) << 10;
return TRUE; codepoint += (WCHAR) wParam - 0xdc00;
codepoint += 0x10000;
}
} }
else
codepoint = (WCHAR) wParam;
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain); window->win32.highSurrogate = 0;
_glfwInputChar(window, codepoint, getKeyMods(), uMsg != WM_SYSCHAR);
}
if (uMsg == WM_SYSCHAR && window->win32.keymenu) if (uMsg == WM_SYSCHAR && window->win32.keymenu)
break; break;
@ -666,6 +675,20 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0; return 0;
} }
case WM_UNICHAR:
{
if (wParam == UNICODE_NOCHAR)
{
// WM_UNICHAR is not sent by Windows, but is sent by some
// third-party input method engine
// Returning TRUE here announces support for this message
return TRUE;
}
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE);
return 0;
}
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYUP: case WM_KEYUP:

Loading…
Cancel
Save