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@xxxxxxxxxx> --- 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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel