[gtk+] GDK W32: Support UTF-16 surrogate pairs passed via VK_PACKET
- From: Руслан Ижбулатов <ruslanizhb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GDK W32: Support UTF-16 surrogate pairs passed via VK_PACKET
- Date: Thu, 28 Jul 2016 15:55:53 +0000 (UTC)
commit 2233566f4854c07d89deeeb8505e82bad544787c
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date: Sun Jul 24 14:26:06 2016 +0000
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
gdk/win32/gdkevents-win32.c | 75 ++++++++++++++++++++++++++++++++++++------
gdk/win32/gdkwindow-win32.h | 8 ++++
2 files changed, 72 insertions(+), 11 deletions(-)
---
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 4f01da9..7f050a4 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -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);
+ }
+
+ if (msg->message == WM_KEYDOWN)
+ impl->leading_surrogate_keydown = 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);
+ impl->leading_surrogate_keyup = 0;
fill_key_event_string (event);
diff --git a/gdk/win32/gdkwindow-win32.h b/gdk/win32/gdkwindow-win32.h
index ab5f0fe..508087b 100644
--- a/gdk/win32/gdkwindow-win32.h
+++ b/gdk/win32/gdkwindow-win32.h
@@ -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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]