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))
|
if (GDK_WINDOW_DESTROYED (window))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
|
||||||
|
|
||||||
if (msg->message == WM_KEYUP &&
|
if (msg->message == WM_KEYUP &&
|
||||||
!GDK_WINDOW_DESTROYED (gdk_window_get_toplevel (window)) &&
|
!GDK_WINDOW_DESTROYED (gdk_window_get_toplevel (window)) &&
|
||||||
_gdk_win32_window_lacks_wm_decorations (gdk_window_get_toplevel (window)) && /* For CSD only */
|
_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 ||
|
event = gdk_event_new ((msg->message == WM_KEYDOWN ||
|
||||||
msg->message == WM_SYSKEYDOWN) ?
|
msg->message == WM_SYSKEYDOWN) ?
|
||||||
GDK_KEY_PRESS : GDK_KEY_RELEASE);
|
GDK_KEY_PRESS : GDK_KEY_RELEASE);
|
||||||
@ -2365,22 +2394,46 @@ gdk_event_translate (MSG *msg,
|
|||||||
LOBYTE (HIWORD (msg->lParam)) == _scancode_rshift)
|
LOBYTE (HIWORD (msg->lParam)) == _scancode_rshift)
|
||||||
event->key.hardware_keycode = VK_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]); */
|
/* 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);
|
build_key_event_state (event, key_state);
|
||||||
|
|
||||||
if (msg->wParam == VK_PACKET &&
|
if (msg->wParam == VK_PACKET && ccount == 1)
|
||||||
ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0) == 1)
|
{
|
||||||
event->key.keyval = gdk_unicode_to_keyval (wbuf[0]);
|
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
|
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),
|
gdk_keymap_translate_keyboard_state (_gdk_win32_display_get_keymap (display),
|
||||||
event->key.hardware_keycode,
|
event->key.hardware_keycode,
|
||||||
event->key.state,
|
event->key.state,
|
||||||
event->key.group,
|
event->key.group,
|
||||||
&event->key.keyval,
|
&event->key.keyval,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->message == WM_KEYDOWN)
|
||||||
|
impl->leading_surrogate_keydown = 0;
|
||||||
|
else
|
||||||
|
impl->leading_surrogate_keyup = 0;
|
||||||
|
|
||||||
fill_key_event_string (event);
|
fill_key_event_string (event);
|
||||||
|
|
||||||
|
@ -228,6 +228,14 @@ struct _GdkWindowImplWin32
|
|||||||
HICON hicon_big;
|
HICON hicon_big;
|
||||||
HICON hicon_small;
|
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 */
|
/* Window size hints */
|
||||||
gint hint_flags;
|
gint hint_flags;
|
||||||
GdkGeometry hints;
|
GdkGeometry hints;
|
||||||
|
Loading…
Reference in New Issue
Block a user