[Spice-commits] src/spice-widget.c

Frediano Ziglio fziglio at kemper.freedesktop.org
Thu Jun 9 10:29:53 UTC 2016


 src/spice-widget.c |   38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

New commits:
commit 3e08aef2d30580b32e4024bcdc9d8a95dcccea87
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Jun 6 14:08:06 2016 +0100

    widget: Do not ignore unsupported keys from keyboard
    
    If Windows layout does not support a given key the resulting virtual code
    is set to 0xFF. To avoid losing this raw key (causing the key not been
    sent to remote machine) detect this condition and handle the key.
    The check for raw scancode is there to understand if we can handle
    correctly the key in following code.
    This problem can happen for instance using a 106 key Japanese keyboard
    while the layout is set in English; in this case keys like CONVERT not
    forwarded correctly.
    
    Some note on how to reproduce and test this problem.
    
    Physical way:
    1- get a 106 key Japanese keyboard for your Windows client machine;
    2- setup your client to English keyboard layout;
    3- connect to a Linux machine (no matter the distro or version or
       keyboard configuration);
    4- open "xinput test-xi2 <device>" command on Linux (device is
       the "AT" device in this case);
    5- press CONVERT or other keys not present on an English keyboard.
    
    Virtual way (Windows machine on a VM):
    - set machine remote to VNC;
    - assure Qmeu has lock-key-sync=off option to vnc;
    - connect to Windows machine with a VNC client (I suggest TigerVNC
      as remote-viewer do some keyboard insertion);
    - do steps 2, 3, 4 above
    - press the CONVERT key. If you don't have you can simulate, either
      - change VNC client code to insert scancode 0x70 instead of another
        key and press this key;
      - disconnect main VNC client and use some tool to inject keys
        (I use a modifier version of vncdotool).
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Christophe Fergeau <cfergeau at redhat.com>

diff --git a/src/spice-widget.c b/src/spice-widget.c
index 51a2055..b5936bc 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1406,7 +1406,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
 {
     SpiceDisplay *display = SPICE_DISPLAY(widget);
     SpiceDisplayPrivate *d = display->priv;
-    int scancode;
+    int scancode = 0;
 #ifdef G_OS_WIN32
     int native_scancode;
     WORD langid = LOWORD(GetKeyboardLayout(0));
@@ -1414,8 +1414,23 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
 #endif
 
 #ifdef G_OS_WIN32
+    /* Try to get scancode with gdk_event_get_scancode.
+     * This API is available from 3.22 or if backported.
+     */
+#if HAVE_GDK_EVENT_GET_SCANCODE
+    native_scancode = gdk_event_get_scancode((GdkEvent *) key);
+    if (native_scancode) {
+        scancode = native_scancode & 0x1ff;
+        /* Windows always set extended attribute for these keys */
+        if (scancode == (0x100|DIK_NUMLOCK) || scancode == (0x100|DIK_RSHIFT))
+            scancode &= 0xff;
+    }
+#else
+    native_scancode = 0;
+#endif
+
     /* on windows, we ought to ignore the reserved key event? */
-    if (key->hardware_keycode == 0xff)
+    if (!native_scancode && key->hardware_keycode == 0xff)
         return false;
 
     if (!d->keyboard_grab_active) {
@@ -1455,23 +1470,10 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
     if (!d->inputs)
         return true;
 
-    scancode = vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen,
-                                            key->hardware_keycode);
+    if (!scancode)
+        scancode = vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen,
+                                                key->hardware_keycode);
 #ifdef G_OS_WIN32
-    /* Try to get scancode with gdk_event_get_scancode.
-     * This API is available from 3.22 or if backported.
-     */
-#if HAVE_GDK_EVENT_GET_SCANCODE
-    native_scancode = gdk_event_get_scancode((GdkEvent *) key);
-    if (native_scancode) {
-        scancode = native_scancode & 0x1ff;
-        /* Windows always set extended attribute for these keys */
-        if (scancode == (0x100|DIK_NUMLOCK) || scancode == (0x100|DIK_RSHIFT))
-            scancode &= 0xff;
-    }
-#else
-    native_scancode = 0;
-#endif
     if (!native_scancode) {
         native_scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC);
         /* MapVirtualKey doesn't return scancode with needed higher byte */


More information about the Spice-commits mailing list