[Spice-devel] [spice-gtk v3] Spice-widget: Use new gdk_event_get_scancode if available

Frediano Ziglio fziglio at redhat.com
Mon Apr 25 15:36:45 UTC 2016


This new Gdk API allows in Windows to retrieve the raw scancodes sent
by Windows.
This allows us to do some translations getting the right value without
many hacks and supporting all possible layouts.
Windows convert the scancodes into virtual key codes. The translation is
1 -> N based on different condition. Also a single virtual key code can
be originated from different scancodes. This make quite complicated
(if not impossible) to get the original scancode from the hardware_keycode
field (which in Windows is the virtual key).
The additional check for native_scancode after calling this function
allows to support key injection.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 configure.ac       | 12 ++++++++++++
 src/spice-widget.c | 22 +++++++++++++++++++---
 2 files changed, 31 insertions(+), 3 deletions(-)

Changes from v2:
- remove GTK_CHECK_VERSION check, use just a single check;
- added some comment to configure.ac;
- extend commit message.

Changes from v1:
- added configure.ac code so users using Gdk from
  master can use it.

diff --git a/configure.ac b/configure.ac
index ce80d88..ef60604 100644
--- a/configure.ac
+++ b/configure.ac
@@ -142,6 +142,18 @@ AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)
 SPICE_GTK_REQUIRES="${SPICE_GTK_REQUIRES} gtk+-3.0 >= $GTK_REQUIRED"
 
+# Check for gdk_event_get_scancode function
+# This was added in Gdk 3.22
+# The check allows the usage of the function in case the function is
+# backported or in case of compilation from Gdk master branch
+old_LIBS="$LIBS"
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $GTK_CFLAGS"
+LIBS="$LIBS $GTK_LIBS"
+AC_CHECK_FUNCS(gdk_event_get_scancode)
+LIBS="$old_LIBS"
+CFLAGS="$old_CFLAGS"
+
 PKG_CHECK_EXISTS([gtk+-quartz-$with_gtk], [have_quartz=yes], [have_quartz=no])
 AS_IF([test "x$have_quartz" = "xyes"], [AC_DEFINE([HAVE_QUARTZ], 1, [Have Quartz?])])
 AM_CONDITIONAL([WITH_DISPLAY_QUARTZ], [test "x$have_quartz" = "xyes"])
diff --git a/src/spice-widget.c b/src/spice-widget.c
index b458909..1299ae4 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1455,9 +1455,25 @@ 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);
-    /* MapVirtualKey doesn't return scancode with needed higher byte */
-    scancode = native_scancode | (scancode & 0xff00);
+    /* 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 */
+        scancode = native_scancode | (scancode & 0xff00);
+    }
 
     /* Some virtual-key codes are missed in MapVirtualKey(). */
     switch (langid) {
-- 
2.5.5



More information about the Spice-devel mailing list