diff options
author | Frediano Ziglio <fziglio@redhat.com> | 2016-05-20 16:28:08 +0100 |
---|---|---|
committer | Frediano Ziglio <fziglio@redhat.com> | 2017-02-01 15:15:34 +0000 |
commit | 02b268644f3d99b0fc897c6f13e6e8d116edff0f (patch) | |
tree | 09860f0178c76547bc95c41ab8fc15a8b032d621 | |
parent | e336a20abec65ba7d9000ffe7a7fc45a80f1e739 (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.c | 73 | ||||
-rw-r--r-- | src/spice-gtk-keyboard.h | 1 |
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 |