[Spice-devel] [spice-gtk v3 1/3] Send Zenkaku_Hankaku key in JP keyboard

Frediano Ziglio fziglio at redhat.com
Thu Apr 14 10:52:58 UTC 2016


From: Takao Fujiwara <tfujiwar at redhat.com>

Zenkaku_Hankaku key has the different virtual-key codes between WM_KEYDOWN
and WM_KEYUP and MapVirtualKey() cannot get the scancode from virtual-key
code of WM_KEYDOWN (VK_DBE_DBCSCHAR) and spice-gtk didn't send the key
press events and caused the desktop freeze with unlimited key release
events.

The fix is to get the scancode from virtual-key code of WM_KEYUP
(VK_DBE_SBCSCHAR) and Zenkaku_Hankaku key works fine.

Alt + Zenkaku_Hankaku key also has the different virtual-key code and
MapVirtualKey() cannot get the scancode from the virtual-key and
spice-gtk didn't send the key press events and Alt+Zenkaku_Hankaku
could not be used.

The fix is to get the scancode from virtual-key code of Zenkaku_Hankaku key
(VK_DBE_SBCSCHAR).

VK_CAPITAL, VK_DBE_ROMAN are also applied the similar fixes.
---
 src/spice-widget.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

Changes from v2:
- do not use hooks or filter but just read layout
  directly for every key.

diff --git a/src/spice-widget.c b/src/spice-widget.c
index 19753e7..7f19bb8 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -30,6 +30,7 @@
 #endif
 #ifdef G_OS_WIN32
 #include <windows.h>
+#include <ime.h>
 #include <gdk/gdkwin32.h>
 #ifndef MAPVK_VK_TO_VSC /* may be undefined in older mingw-headers */
 #define MAPVK_VK_TO_VSC 0
@@ -1340,6 +1341,10 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
     SpiceDisplay *display = SPICE_DISPLAY(widget);
     SpiceDisplayPrivate *d = display->priv;
     int scancode;
+#ifdef G_OS_WIN32
+    int native_scancode;
+    WORD langid = LOWORD(GetKeyboardLayout(0));
+#endif
 
 #ifdef G_OS_WIN32
     /* on windows, we ought to ignore the reserved key event? */
@@ -1386,9 +1391,48 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
     scancode = vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen,
                                             key->hardware_keycode);
 #ifdef G_OS_WIN32
+    native_scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC);
+
+    /* Some virtual-key codes are missed in MapVirtualKey(). */
+    switch (langid) {
+    case MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN):
+        if (native_scancode == 0) {
+            switch (key->hardware_keycode) {
+            case VK_DBE_DBCSCHAR:       /* from Pressed Zenkaku_Hankaku */
+            case VK_KANJI:              /* from Alt + Zenkaku_Hankaku */
+            case VK_DBE_ENTERIMECONFIGMODE:
+                                        /* from Ctrl+Alt+Zenkaku_Hankaku */
+                scancode = MapVirtualKey(VK_DBE_SBCSCHAR, MAPVK_VK_TO_VSC);
+                                        /* to Released Zenkaku_Hankaku */
+                goto got_scancode;
+            case VK_CAPITAL:            /* from Shift + Eisu_toggle */
+            case VK_DBE_CODEINPUT:      /* from Pressed Ctrl+Alt+Eisu_toggle */
+            case VK_DBE_NOCODEINPUT:    /* from Released Ctrl+Alt+Eisu_toggle */
+                scancode = MapVirtualKey(VK_DBE_ALPHANUMERIC, MAPVK_VK_TO_VSC);
+                                        /* to Eisu_toggle */
+                goto got_scancode;
+            case VK_DBE_ROMAN:          /* from Pressed Alt+Hiragana_Katakana */
+            case VK_KANA:               /* from Ctrl+Shift+Hiragana_Katakana */
+                scancode = MapVirtualKey(VK_DBE_HIRAGANA, MAPVK_VK_TO_VSC);
+                                        /* to Hiragana_Katakana */
+                goto got_scancode;
+            case VK_DBE_ENTERWORDREGISTERMODE:
+                                        /* from Ctrl + Alt + Muhenkan */
+                scancode = MapVirtualKey(VK_NONCONVERT, MAPVK_VK_TO_VSC);
+                                        /* to Muhenkan */
+                goto got_scancode;
+            default:;
+            }
+        }
+        break;
+    default:;
+    }
+
     /* MapVirtualKey doesn't return scancode with needed higher byte */
-    scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC) |
-        (scancode & 0xff00);
+    scancode = native_scancode | (scancode & 0xff00);
+
+got_scancode:
+
 #endif
 
     switch (key->type) {
-- 
2.5.5



More information about the Spice-devel mailing list