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