[Spice-devel] [spice-gtk v3 2/7] Add set_keyboard_lock_modifiers

Frediano Ziglio fziglio at redhat.com
Sat Sep 3 16:10:02 UTC 2016


Code from commit 063c1b9c0627c87eb7f5369c4a6b9776a22e5c7d.
This code will be used to set local key modifiers
allowing syncronization from guest to client.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 src/spice-gtk-keyboard.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/spice-gtk-keyboard.h |  1 +
 2 files changed, 74 insertions(+)

diff --git a/src/spice-gtk-keyboard.c b/src/spice-gtk-keyboard.c
index 0ebcb41..af9c81e 100644
--- a/src/spice-gtk-keyboard.c
+++ b/src/spice-gtk-keyboard.c
@@ -89,3 +89,76 @@ guint32 get_keyboard_lock_modifiers(void)
 #endif // GTK_CHECK_VERSION(3,18,0)
     return modifiers;
 }
+
+#if defined(HAVE_X11_XKBLIB_H)
+typedef enum SpiceLed {
+    CAPS_LOCK_LED = 1,
+    NUM_LOCK_LED,
+    SCROLL_LOCK_LED,
+} SpiceLed;
+
+static guint get_modifier_mask(Display *x_display, KeySym modifier)
+{
+    int mask = 0;
+    int i;
+
+    XModifierKeymap* map = XGetModifierMapping(x_display);
+    KeyCode keycode = XKeysymToKeycode(x_display, modifier);
+    if (keycode == NoSymbol) {
+        return 0;
+    }
+
+    for (i = 0; i < 8; i++) {
+        if (map->modifiermap[map->max_keypermod * i] == keycode) {
+            mask = 1 << i;
+        }
+    }
+    XFreeModifiermap(map);
+    return mask;
+}
+
+static void set_keyboard_led(Display *x_display, SpiceLed led, int set)
+{
+    guint mask;
+    XKeyboardControl keyboard_control;
+
+    switch (led) {
+    case CAPS_LOCK_LED:
+        if ((mask = get_modifier_mask(x_display, XK_Caps_Lock)) != 0) {
+            XkbLockModifiers(x_display, XkbUseCoreKbd, mask, set ? mask : 0);
+        }
+        return;
+    case NUM_LOCK_LED:
+        if ((mask = get_modifier_mask(x_display, XK_Num_Lock)) != 0) {
+            XkbLockModifiers(x_display, XkbUseCoreKbd, mask, set ? mask : 0);
+        }
+        return;
+    case SCROLL_LOCK_LED:
+        keyboard_control.led_mode = set ? LedModeOn : LedModeOff;
+        keyboard_control.led = led;
+        XChangeKeyboardControl(x_display, KBLed | KBLedMode, &keyboard_control);
+        return;
+    }
+}
+#endif
+
+void set_keyboard_lock_modifiers(guint32 modifiers)
+{
+#if defined(HAVE_X11_XKBLIB_H)
+    Display *x_display;
+
+    GdkScreen *screen = gdk_screen_get_default();
+    if (!GDK_IS_X11_DISPLAY(gdk_screen_get_display(screen))) {
+        SPICE_DEBUG("FIXME: gtk backend is not X11");
+        return;
+    }
+
+    x_display = GDK_SCREEN_XDISPLAY(screen);
+
+    set_keyboard_led(x_display, CAPS_LOCK_LED, !!(modifiers & SPICE_INPUTS_CAPS_LOCK));
+    set_keyboard_led(x_display, NUM_LOCK_LED, !!(modifiers & SPICE_INPUTS_NUM_LOCK));
+    set_keyboard_led(x_display, SCROLL_LOCK_LED, !!(modifiers & SPICE_INPUTS_SCROLL_LOCK));
+#else
+    g_warning("set_keyboard_lock_modifiers not implemented");
+#endif
+}
diff --git a/src/spice-gtk-keyboard.h b/src/spice-gtk-keyboard.h
index d87a930..016be84 100644
--- a/src/spice-gtk-keyboard.h
+++ b/src/spice-gtk-keyboard.h
@@ -28,6 +28,7 @@
 G_BEGIN_DECLS
 
 guint32 get_keyboard_lock_modifiers(void);
+void set_keyboard_lock_modifiers(guint32 modifiers);
 
 G_END_DECLS
 
-- 
2.7.4



More information about the Spice-devel mailing list