[PATCH weston 2/3] compositor: add a way to change the keyboard leds
Giulio Camuffo
giuliocamuffo at gmail.com
Sat Dec 14 10:05:39 PST 2013
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
More information about the wayland-devel
mailing list