GDK W32: Support UTF-16 surrogate pairs passed via VK_PACKET
This is, essentially, a piece of g_utf16_to_ucs4() built into GDK W32 keyboard message processing. https://bugzilla.gnome.org/show_bug.cgi?id=769126
This commit is contained in:
parent
5ccc0e40f5
commit
2233566f48
@ -2288,6 +2288,8 @@ gdk_event_translate (MSG *msg,
|
||||
if (GDK_WINDOW_DESTROYED (window))
|
||||
break;
|
||||
|
||||
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||
|
||||
if (msg->message == WM_KEYUP &&
|
||||
!GDK_WINDOW_DESTROYED (gdk_window_get_toplevel (window)) &&
|
||||
_gdk_win32_window_lacks_wm_decorations (gdk_window_get_toplevel (window)) && /* For CSD only */
|
||||
@ -2330,6 +2332,33 @@ gdk_event_translate (MSG *msg,
|
||||
}
|
||||
}
|
||||
|
||||
API_CALL (GetKeyboardState, (key_state));
|
||||
|
||||
ccount = 0;
|
||||
|
||||
if (msg->wParam == VK_PACKET)
|
||||
{
|
||||
ccount = ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0);
|
||||
if (ccount == 1)
|
||||
{
|
||||
if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
|
||||
{
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
impl->leading_surrogate_keydown = wbuf[0];
|
||||
else
|
||||
impl->leading_surrogate_keyup = wbuf[0];
|
||||
|
||||
/* don't emit an event */
|
||||
return_val = TRUE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wait until an event is created */;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event = gdk_event_new ((msg->message == WM_KEYDOWN ||
|
||||
msg->message == WM_SYSKEYDOWN) ?
|
||||
GDK_KEY_PRESS : GDK_KEY_RELEASE);
|
||||
@ -2365,22 +2394,46 @@ gdk_event_translate (MSG *msg,
|
||||
LOBYTE (HIWORD (msg->lParam)) == _scancode_rshift)
|
||||
event->key.hardware_keycode = VK_RSHIFT;
|
||||
|
||||
API_CALL (GetKeyboardState, (key_state));
|
||||
|
||||
/* g_print ("ctrl:%02x lctrl:%02x rctrl:%02x alt:%02x lalt:%02x ralt:%02x\n", key_state[VK_CONTROL], key_state[VK_LCONTROL], key_state[VK_RCONTROL], key_state[VK_MENU], key_state[VK_LMENU], key_state[VK_RMENU]); */
|
||||
|
||||
build_key_event_state (event, key_state);
|
||||
|
||||
if (msg->wParam == VK_PACKET &&
|
||||
ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0) == 1)
|
||||
event->key.keyval = gdk_unicode_to_keyval (wbuf[0]);
|
||||
if (msg->wParam == VK_PACKET && ccount == 1)
|
||||
{
|
||||
if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
else if (wbuf[0] >= 0xDC00 && wbuf[0] < 0xE000)
|
||||
{
|
||||
wchar_t leading;
|
||||
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
leading = impl->leading_surrogate_keydown;
|
||||
else
|
||||
leading = impl->leading_surrogate_keyup;
|
||||
|
||||
event->key.keyval = gdk_unicode_to_keyval ((leading - 0xD800) * 0x400 + wbuf[0] - 0xDC00 + 0x10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
event->key.keyval = gdk_unicode_to_keyval (wbuf[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
gdk_keymap_translate_keyboard_state (_gdk_win32_display_get_keymap (display),
|
||||
event->key.hardware_keycode,
|
||||
event->key.state,
|
||||
event->key.group,
|
||||
&event->key.keyval,
|
||||
NULL, NULL, NULL);
|
||||
{
|
||||
gdk_keymap_translate_keyboard_state (_gdk_win32_display_get_keymap (display),
|
||||
event->key.hardware_keycode,
|
||||
event->key.state,
|
||||
event->key.group,
|
||||
&event->key.keyval,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
impl->leading_surrogate_keydown = 0;
|
||||
else
|
||||
impl->leading_surrogate_keyup = 0;
|
||||
|
||||
fill_key_event_string (event);
|
||||
|
||||
|
@ -228,6 +228,14 @@ struct _GdkWindowImplWin32
|
||||
HICON hicon_big;
|
||||
HICON hicon_small;
|
||||
|
||||
/* When VK_PACKET sends us a leading surrogate, it's stashed here.
|
||||
* Later, when another VK_PACKET sends a tailing surrogate, we make up
|
||||
* a full unicode character from them, or discard the leading surrogate,
|
||||
* if the next key is not a tailing surrogate.
|
||||
*/
|
||||
wchar_t leading_surrogate_keydown;
|
||||
wchar_t leading_surrogate_keyup;
|
||||
|
||||
/* Window size hints */
|
||||
gint hint_flags;
|
||||
GdkGeometry hints;
|
||||
|
Loading…
Reference in New Issue
Block a user