This adds a function weston_keyboard_set_leds() which can be used to change the state of the num lock and the caps lock leds. Currently works only with compositor-x11 and evdev. ---
I think some protocol is needed for the wayland backend, to tell the parent compositor to turn them on/off. src/compositor-x11.c | 34 ++++++++++++++++++++++++++++++++++ src/compositor.h | 3 +++ src/input.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/src/compositor-x11.c b/src/compositor-x11.c index b81dac0..2f983be 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -43,6 +43,8 @@ #include <X11/Xlib.h> #include <X11/Xlib-xcb.h> +#include <X11/XKBlib.h> + #include <xkbcommon/xkbcommon.h> @@ -281,6 +283,9 @@ x11_compositor_setup_xkb(struct x11_compositor *c) 0, state_reply->group); + notify_modifiers(&c->core_seat, + wl_display_next_serial(c->base.wl_display)); + free(state_reply); xcb_change_window_attributes(c->conn, c->screen->root, @@ -306,6 +311,33 @@ update_xkb_keymap(struct x11_compositor *c) } #endif +static void +x11_compositor_led_update(struct weston_seat *seat, enum weston_led leds) +{ + struct x11_compositor *c = container_of(seat->compositor, struct x11_compositor, base); + unsigned int mask, mask_on, mod, i; + + static const struct { + enum weston_led weston; + int x11; + } map[] = { + { LED_NUM_LOCK, XK_Num_Lock }, + { LED_CAPS_LOCK, XK_Caps_Lock }, + { LED_SCROLL_LOCK, XK_Scroll_Lock }, + }; + + mask = 0; + mask_on = 0; + for (i = 0; i < ARRAY_LENGTH(map); i++) { + mod = XkbKeysymToModifiers(c->dpy, map[i].x11); + mask |= mod; + if (leds & map[i].weston) + mask_on |= mod; + } + + XkbLockModifiers(c->dpy, XkbUseCoreKbd, mask, mask_on); +} + static int x11_input_create(struct x11_compositor *c, int no_input) { @@ -1582,6 +1614,8 @@ x11_compositor_create(struct wl_display *display, x11_compositor_handle_event, c); wl_event_source_check(c->xcb_source); + c->core_seat.led_update = x11_compositor_led_update; + return &c->base; err_x11_input: diff --git a/src/compositor.h b/src/compositor.h index b6bf78d..676963b 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -385,6 +385,9 @@ weston_keyboard_start_grab(struct weston_keyboard *device, struct weston_keyboard_grab *grab); void weston_keyboard_end_grab(struct weston_keyboard *keyboard); +void +weston_keyboard_set_leds(struct weston_keyboard *keyboard, + enum weston_led leds, enum weston_led active); struct weston_touch * weston_touch_create(void); diff --git a/src/input.c b/src/input.c index f4944b6..8e7139e 100644 --- a/src/input.c +++ b/src/input.c @@ -994,6 +994,47 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis, value); } +WL_EXPORT void +weston_keyboard_set_leds(struct weston_keyboard *keyboard, + enum weston_led leds, enum weston_led active) +{ + /* We don't want the leds to go out of sync with the actual state + * so if the backend has no way to change the leds don't try to + * change the state */ + if (!keyboard->seat->led_update) + return; + + uint32_t mods_depressed, mods_latched, mods_locked, group; + uint32_t serial; + int num, caps; + mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state, + XKB_STATE_DEPRESSED); + mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state, + XKB_STATE_LATCHED); + mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state, + XKB_STATE_LOCKED); + group = xkb_state_serialize_group(keyboard->xkb_state.state, + XKB_STATE_EFFECTIVE); + + num = (1 << keyboard->xkb_info->mod2_mod); + caps = (1 << keyboard->xkb_info->caps_mod); + if (leds & LED_NUM_LOCK) + mods_locked = (active & LED_NUM_LOCK) ? mods_locked | num + : mods_locked & ~num; + if (leds & LED_CAPS_LOCK) + mods_locked = (active & LED_CAPS_LOCK) ? mods_locked | caps + : mods_locked & ~caps; + if (leds & LED_SCROLL_LOCK) + weston_log("Changing the LED_SCROLL_LOCK value is not supported."); + + xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed, + mods_latched, mods_locked, 0, 0, group); + + serial = wl_display_next_serial( + keyboard->seat->compositor->wl_display); + notify_modifiers(keyboard->seat, serial); +} + #ifdef ENABLE_XKBCOMMON WL_EXPORT void notify_modifiers(struct weston_seat *seat, uint32_t serial) -- 1.8.5.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel