summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2016-05-20 16:28:08 +0100
committerFrediano Ziglio <fziglio@redhat.com>2017-02-01 15:15:34 +0000
commit02b268644f3d99b0fc897c6f13e6e8d116edff0f (patch)
tree09860f0178c76547bc95c41ab8fc15a8b032d621
parente336a20abec65ba7d9000ffe7a7fc45a80f1e739 (diff)
Add set_keyboard_lock_modifiers
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@redhat.com>
-rw-r--r--src/spice-gtk-keyboard.c73
-rw-r--r--src/spice-gtk-keyboard.h1
2 files changed, 74 insertions, 0 deletions
diff --git a/src/spice-gtk-keyboard.c b/src/spice-gtk-keyboard.c
index ab66e14..81498c5 100644
--- a/src/spice-gtk-keyboard.c
+++ b/src/spice-gtk-keyboard.c
@@ -92,3 +92,76 @@ G_GNUC_END_IGNORE_DEPRECATIONS
#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