1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <systemd/sd-bus.h>
25 #include <systemd/sd-event.h>
26 #include <xkbcommon/xkbcommon.h>
27 #include <xkbcommon/xkbcommon-compose.h>
31 #include "idev-internal.h"
33 #include "term-internal.h"
36 typedef struct kbdtbl kbdtbl;
37 typedef struct kbdmap kbdmap;
38 typedef struct kbdctx kbdctx;
39 typedef struct idev_keyboard idev_keyboard;
43 struct xkb_compose_table *xkb_compose_table;
48 struct xkb_keymap *xkb_keymap;
49 xkb_mod_index_t modmap[IDEV_KBDMOD_CNT];
50 xkb_led_index_t ledmap[IDEV_KBDLED_CNT];
55 idev_context *context;
56 struct xkb_context *xkb_context;
57 struct kbdmap *kbdmap;
58 struct kbdtbl *kbdtbl;
60 sd_bus_slot *slot_locale_props_changed;
61 sd_bus_slot *slot_locale_get_all;
64 char *locale_x11_model;
65 char *locale_x11_layout;
66 char *locale_x11_variant;
67 char *locale_x11_options;
69 char *last_x11_layout;
70 char *last_x11_variant;
71 char *last_x11_options;
74 struct idev_keyboard {
80 struct xkb_state *xkb_state;
81 struct xkb_compose_state *xkb_compose;
85 sd_event_source *repeat_timer;
90 uint32_t *compose_res;
95 #define keyboard_from_device(_d) container_of((_d), idev_keyboard, device)
97 #define KBDCTX_KEY "keyboard.context" /* hashmap key for global kbdctx */
98 #define KBDXKB_SHIFT (8) /* xkb shifts evdev key-codes by 8 */
99 #define KBDKEY_UP (0) /* KEY UP event value */
100 #define KBDKEY_DOWN (1) /* KEY DOWN event value */
101 #define KBDKEY_REPEAT (2) /* KEY REPEAT event value */
103 static const idev_device_vtable keyboard_vtable;
105 static int keyboard_update_kbdmap(idev_keyboard *k);
106 static int keyboard_update_kbdtbl(idev_keyboard *k);
109 * Keyboard Compose Tables
112 static kbdtbl *kbdtbl_ref(kbdtbl *kt) {
114 assert_return(kt->ref > 0, NULL);
121 static kbdtbl *kbdtbl_unref(kbdtbl *kt) {
125 assert_return(kt->ref > 0, NULL);
130 xkb_compose_table_unref(kt->xkb_compose_table);
136 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdtbl*, kbdtbl_unref);
138 static int kbdtbl_new_from_locale(kbdtbl **out, kbdctx *kc, const char *locale) {
139 _cleanup_(kbdtbl_unrefp) kbdtbl *kt = NULL;
141 assert_return(out, -EINVAL);
142 assert_return(locale, -EINVAL);
144 kt = new0(kbdtbl, 1);
150 kt->xkb_compose_table = xkb_compose_table_new_from_locale(kc->xkb_context,
152 XKB_COMPOSE_COMPILE_NO_FLAGS);
153 if (!kt->xkb_compose_table)
154 return errno > 0 ? -errno : -EFAULT;
165 static const char * const kbdmap_modmap[IDEV_KBDMOD_CNT] = {
166 [IDEV_KBDMOD_IDX_SHIFT] = XKB_MOD_NAME_SHIFT,
167 [IDEV_KBDMOD_IDX_CTRL] = XKB_MOD_NAME_CTRL,
168 [IDEV_KBDMOD_IDX_ALT] = XKB_MOD_NAME_ALT,
169 [IDEV_KBDMOD_IDX_LINUX] = XKB_MOD_NAME_LOGO,
170 [IDEV_KBDMOD_IDX_CAPS] = XKB_MOD_NAME_CAPS,
173 static const char * const kbdmap_ledmap[IDEV_KBDLED_CNT] = {
174 [IDEV_KBDLED_IDX_NUM] = XKB_LED_NAME_NUM,
175 [IDEV_KBDLED_IDX_CAPS] = XKB_LED_NAME_CAPS,
176 [IDEV_KBDLED_IDX_SCROLL] = XKB_LED_NAME_SCROLL,
179 static kbdmap *kbdmap_ref(kbdmap *km) {
180 assert_return(km, NULL);
181 assert_return(km->ref > 0, NULL);
187 static kbdmap *kbdmap_unref(kbdmap *km) {
191 assert_return(km->ref > 0, NULL);
196 xkb_keymap_unref(km->xkb_keymap);
202 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdmap*, kbdmap_unref);
204 static int kbdmap_new_from_names(kbdmap **out,
209 const char *options) {
210 _cleanup_(kbdmap_unrefp) kbdmap *km = NULL;
211 struct xkb_rule_names rmlvo = { };
214 assert_return(out, -EINVAL);
216 km = new0(kbdmap, 1);
222 rmlvo.rules = "evdev";
224 rmlvo.layout = layout;
225 rmlvo.variant = variant;
226 rmlvo.options = options;
229 km->xkb_keymap = xkb_keymap_new_from_names(kc->xkb_context, &rmlvo, 0);
231 return errno > 0 ? -errno : -EFAULT;
233 for (i = 0; i < IDEV_KBDMOD_CNT; ++i) {
234 const char *t = kbdmap_modmap[i];
237 km->modmap[i] = xkb_keymap_mod_get_index(km->xkb_keymap, t);
239 km->modmap[i] = XKB_MOD_INVALID;
242 for (i = 0; i < IDEV_KBDLED_CNT; ++i) {
243 const char *t = kbdmap_ledmap[i];
246 km->ledmap[i] = xkb_keymap_led_get_index(km->xkb_keymap, t);
248 km->ledmap[i] = XKB_LED_INVALID;
260 static int kbdctx_refresh_compose_table(kbdctx *kc, const char *lang) {
270 if (streq_ptr(kc->locale_lang, lang))
273 r = free_and_strdup(&kc->locale_lang, lang);
277 log_debug("idev-keyboard: new default compose table: [ %s ]", lang);
279 r = kbdtbl_new_from_locale(&kt, kc, lang);
281 /* TODO: We need to catch the case where no compose-file is
282 * available. xkb doesn't tell us so far.. so we must not treat
283 * it as a hard-failure but just continue. Preferably, we want
284 * xkb to tell us exactly whether compilation failed or whether
285 * there is no compose file available for this locale. */
286 log_debug_errno(r, "idev-keyboard: cannot load compose-table for '%s': %m",
292 kbdtbl_unref(kc->kbdtbl);
295 HASHMAP_FOREACH(s, kc->context->session_map, i)
296 HASHMAP_FOREACH(d, s->device_map, j)
297 if (idev_is_keyboard(d))
298 keyboard_update_kbdtbl(keyboard_from_device(d));
303 static void move_str(char **dest, char **src) {
309 static int kbdctx_refresh_keymap(kbdctx *kc) {
317 streq_ptr(kc->locale_x11_model, kc->last_x11_model) &&
318 streq_ptr(kc->locale_x11_layout, kc->last_x11_layout) &&
319 streq_ptr(kc->locale_x11_variant, kc->last_x11_variant) &&
320 streq_ptr(kc->locale_x11_options, kc->last_x11_options))
323 move_str(&kc->last_x11_model, &kc->locale_x11_model);
324 move_str(&kc->last_x11_layout, &kc->locale_x11_layout);
325 move_str(&kc->last_x11_variant, &kc->locale_x11_variant);
326 move_str(&kc->last_x11_options, &kc->locale_x11_options);
328 log_debug("idev-keyboard: new default keymap: [%s / %s / %s / %s]",
329 kc->last_x11_model, kc->last_x11_layout, kc->last_x11_variant, kc->last_x11_options);
331 /* TODO: add a fallback keymap that's compiled-in */
332 r = kbdmap_new_from_names(&km, kc, kc->last_x11_model, kc->last_x11_layout,
333 kc->last_x11_variant, kc->last_x11_options);
335 return log_debug_errno(r, "idev-keyboard: cannot create keymap from locale1: %m");
337 kbdmap_unref(kc->kbdmap);
340 HASHMAP_FOREACH(s, kc->context->session_map, i)
341 HASHMAP_FOREACH(d, s->device_map, j)
342 if (idev_is_keyboard(d))
343 keyboard_update_kbdmap(keyboard_from_device(d));
348 static int kbdctx_set_locale(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
349 kbdctx *kc = userdata;
350 const char *s, *ctype = NULL, *lang = NULL;
353 r = sd_bus_message_enter_container(m, 'a', "s");
357 while ((r = sd_bus_message_read(m, "s", &s)) > 0) {
359 ctype = startswith(s, "LC_CTYPE=");
361 lang = startswith(s, "LANG=");
367 r = sd_bus_message_exit_container(m);
371 kbdctx_refresh_compose_table(kc, ctype ? : lang);
376 log_debug_errno(r, "idev-keyboard: cannot parse locale property from locale1: %m");
381 static const struct bus_properties_map kbdctx_locale_map[] = {
382 { "Locale", "as", kbdctx_set_locale, 0 },
383 { "X11Model", "s", NULL, offsetof(kbdctx, locale_x11_model) },
384 { "X11Layout", "s", NULL, offsetof(kbdctx, locale_x11_layout) },
385 { "X11Variant", "s", NULL, offsetof(kbdctx, locale_x11_variant) },
386 { "X11Options", "s", NULL, offsetof(kbdctx, locale_x11_options) },
389 static int kbdctx_locale_get_all_fn(sd_bus *bus,
392 sd_bus_error *ret_err) {
393 kbdctx *kc = userdata;
396 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
398 if (sd_bus_message_is_method_error(m, NULL)) {
399 const sd_bus_error *error = sd_bus_message_get_error(m);
401 log_debug("idev-keyboard: GetAll() on locale1 failed: %s: %s",
402 error->name, error->message);
406 r = bus_message_map_all_properties(bus, m, kbdctx_locale_map, kc);
408 log_debug("idev-keyboard: erroneous GetAll() reply from locale1");
412 kbdctx_refresh_keymap(kc);
416 static int kbdctx_query_locale(kbdctx *kc) {
417 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
420 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
422 r = sd_bus_message_new_method_call(kc->context->sysbus,
424 "org.freedesktop.locale1",
425 "/org/freedesktop/locale1",
426 "org.freedesktop.DBus.Properties",
431 r = sd_bus_message_append(m, "s", "org.freedesktop.locale1");
435 r = sd_bus_call_async(kc->context->sysbus,
436 &kc->slot_locale_get_all,
438 kbdctx_locale_get_all_fn,
447 return log_debug_errno(r, "idev-keyboard: cannot send GetAll to locale1: %m");
450 static int kbdctx_locale_props_changed_fn(sd_bus *bus,
451 sd_bus_message *signal,
453 sd_bus_error *ret_err) {
454 kbdctx *kc = userdata;
457 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
459 /* skip interface name */
460 r = sd_bus_message_skip(signal, "s");
464 r = bus_message_map_properties_changed(bus, signal, kbdctx_locale_map, kc);
469 r = kbdctx_query_locale(kc);
474 kbdctx_refresh_keymap(kc);
478 return log_debug_errno(r, "idev-keyboard: cannot handle PropertiesChanged from locale1: %m");
481 static int kbdctx_setup_bus(kbdctx *kc) {
484 r = sd_bus_add_match(kc->context->sysbus,
485 &kc->slot_locale_props_changed,
487 "sender='org.freedesktop.locale1',"
488 "interface='org.freedesktop.DBus.Properties',"
489 "member='PropertiesChanged',"
490 "path='/org/freedesktop/locale1'",
491 kbdctx_locale_props_changed_fn,
494 return log_debug_errno(r, "idev-keyboard: cannot setup locale1 link: %m");
496 return kbdctx_query_locale(kc);
499 static void kbdctx_log_fn(struct xkb_context *ctx, enum xkb_log_level lvl, const char *format, va_list args) {
503 if (lvl >= XKB_LOG_LEVEL_DEBUG)
505 else if (lvl >= XKB_LOG_LEVEL_INFO)
507 else if (lvl >= XKB_LOG_LEVEL_WARNING)
508 sd_lvl = LOG_INFO; /* most XKB warnings really are informational */
509 else if (lvl >= XKB_LOG_LEVEL_ERROR)
511 else if (lvl >= XKB_LOG_LEVEL_CRITICAL)
516 snprintf(buf, sizeof(buf), "idev-xkb: %s", format);
517 log_internalv(sd_lvl, 0, __FILE__, __LINE__, __func__, buf, args);
520 static kbdctx *kbdctx_ref(kbdctx *kc) {
521 assert_return(kc, NULL);
522 assert_return(kc->ref > 0, NULL);
528 static kbdctx *kbdctx_unref(kbdctx *kc) {
532 assert_return(kc->ref > 0, NULL);
537 free(kc->last_x11_options);
538 free(kc->last_x11_variant);
539 free(kc->last_x11_layout);
540 free(kc->last_x11_model);
541 free(kc->locale_x11_options);
542 free(kc->locale_x11_variant);
543 free(kc->locale_x11_layout);
544 free(kc->locale_x11_model);
545 free(kc->locale_lang);
546 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
547 kc->slot_locale_props_changed = sd_bus_slot_unref(kc->slot_locale_props_changed);
548 kc->kbdtbl = kbdtbl_unref(kc->kbdtbl);
549 kc->kbdmap = kbdmap_unref(kc->kbdmap);
550 xkb_context_unref(kc->xkb_context);
551 hashmap_remove_value(kc->context->data_map, KBDCTX_KEY, kc);
557 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdctx*, kbdctx_unref);
559 static int kbdctx_new(kbdctx **out, idev_context *c) {
560 _cleanup_(kbdctx_unrefp) kbdctx *kc = NULL;
563 assert_return(out, -EINVAL);
564 assert_return(c, -EINVAL);
566 kc = new0(kbdctx, 1);
574 kc->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
575 if (!kc->xkb_context)
576 return errno > 0 ? -errno : -EFAULT;
578 xkb_context_set_log_fn(kc->xkb_context, kbdctx_log_fn);
579 xkb_context_set_log_level(kc->xkb_context, XKB_LOG_LEVEL_DEBUG);
581 r = kbdctx_refresh_keymap(kc);
585 r = kbdctx_refresh_compose_table(kc, NULL);
590 r = kbdctx_setup_bus(kc);
595 r = hashmap_put(c->data_map, KBDCTX_KEY, kc);
604 static int get_kbdctx(idev_context *c, kbdctx **out) {
607 assert_return(c, -EINVAL);
608 assert_return(out, -EINVAL);
610 kc = hashmap_get(c->data_map, KBDCTX_KEY);
612 *out = kbdctx_ref(kc);
616 return kbdctx_new(out, c);
623 bool idev_is_keyboard(idev_device *d) {
624 return d && d->vtable == &keyboard_vtable;
627 idev_device *idev_find_keyboard(idev_session *s, const char *name) {
630 assert_return(s, NULL);
631 assert_return(name, NULL);
633 kname = strjoina("keyboard/", name);
634 return hashmap_get(s->device_map, kname);
637 static int keyboard_raise_data(idev_keyboard *k, idev_data *data) {
638 idev_device *d = &k->device;
641 r = idev_session_raise_device_data(d->session, d, data);
643 log_debug_errno(r, "idev-keyboard: %s/%s: error while raising data event: %m",
644 d->session->name, d->name);
649 static int keyboard_resize_bufs(idev_keyboard *k, uint32_t n_syms) {
652 if (n_syms <= k->n_syms)
655 t = realloc(k->compose_res, sizeof(*t) * n_syms);
660 t = realloc(k->evdata.keyboard.keysyms, sizeof(*t) * n_syms);
663 k->evdata.keyboard.keysyms = t;
665 t = realloc(k->evdata.keyboard.codepoints, sizeof(*t) * n_syms);
668 k->evdata.keyboard.codepoints = t;
670 t = realloc(k->repdata.keyboard.keysyms, sizeof(*t) * n_syms);
673 k->repdata.keyboard.keysyms = t;
675 t = realloc(k->repdata.keyboard.codepoints, sizeof(*t) * n_syms);
678 k->repdata.keyboard.codepoints = t;
684 static unsigned int keyboard_read_compose(idev_keyboard *k, const xkb_keysym_t **out) {
685 _cleanup_free_ char *t = NULL;
691 r = xkb_compose_state_get_utf8(k->xkb_compose, buf, sizeof(buf));
692 if (r >= (int)sizeof(buf)) {
697 xkb_compose_state_get_utf8(k->xkb_compose, t, r + 1);
703 for (i = 0; i < r; ++i) {
707 len = term_utf8_decode(&u8, &ucs, p[i]);
709 r = keyboard_resize_bufs(k, flen + len);
713 for (j = 0; j < len; ++j)
714 k->compose_res[flen++] = ucs[j];
718 *out = k->compose_res;
722 static void keyboard_arm(idev_keyboard *k, usec_t usecs) {
726 usecs += now(CLOCK_MONOTONIC);
727 r = sd_event_source_set_time(k->repeat_timer, usecs);
729 sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_ONESHOT);
731 sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_OFF);
735 static int keyboard_repeat_timer_fn(sd_event_source *source, uint64_t usec, void *userdata) {
736 idev_keyboard *k = userdata;
738 /* never feed REPEAT keys into COMPOSE */
740 keyboard_arm(k, k->repeat_rate);
741 return keyboard_raise_data(k, &k->repdata);
744 int idev_keyboard_new(idev_device **out, idev_session *s, const char *name) {
745 _cleanup_(idev_device_freep) idev_device *d = NULL;
750 assert_return(out, -EINVAL);
751 assert_return(s, -EINVAL);
752 assert_return(name, -EINVAL);
754 k = new0(idev_keyboard, 1);
759 k->device = IDEV_DEVICE_INIT(&keyboard_vtable, s);
760 k->repeat_delay = 250 * USEC_PER_MSEC;
761 k->repeat_rate = 30 * USEC_PER_MSEC;
763 /* TODO: add key-repeat configuration */
765 r = get_kbdctx(s->context, &k->kbdctx);
769 r = keyboard_update_kbdmap(k);
773 r = keyboard_update_kbdtbl(k);
777 r = keyboard_resize_bufs(k, 8);
781 r = sd_event_add_time(s->context->event,
786 keyboard_repeat_timer_fn,
791 r = sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_OFF);
795 kname = strjoina("keyboard/", name);
796 r = idev_device_add(d, kname);
806 static void keyboard_free(idev_device *d) {
807 idev_keyboard *k = keyboard_from_device(d);
809 xkb_compose_state_unref(k->xkb_compose);
810 xkb_state_unref(k->xkb_state);
811 free(k->repdata.keyboard.codepoints);
812 free(k->repdata.keyboard.keysyms);
813 free(k->evdata.keyboard.codepoints);
814 free(k->evdata.keyboard.keysyms);
815 free(k->compose_res);
816 k->repeat_timer = sd_event_source_unref(k->repeat_timer);
817 k->kbdtbl = kbdtbl_unref(k->kbdtbl);
818 k->kbdmap = kbdmap_unref(k->kbdmap);
819 k->kbdctx = kbdctx_unref(k->kbdctx);
823 static int8_t guess_ascii(struct xkb_state *state, uint32_t code, uint32_t n_syms, const uint32_t *syms) {
824 xkb_layout_index_t n_lo, lo;
825 xkb_level_index_t lv;
826 struct xkb_keymap *keymap;
827 const xkb_keysym_t *s;
830 if (n_syms == 1 && syms[0] < 128 && syms[0] > 0)
833 keymap = xkb_state_get_keymap(state);
834 n_lo = xkb_keymap_num_layouts_for_key(keymap, code + KBDXKB_SHIFT);
836 for (lo = 0; lo < n_lo; ++lo) {
837 lv = xkb_state_key_get_level(state, code + KBDXKB_SHIFT, lo);
838 num = xkb_keymap_key_get_syms_by_level(keymap, code + KBDXKB_SHIFT, lo, lv, &s);
839 if (num == 1 && s[0] < 128 && s[0] > 0)
846 static int keyboard_fill(idev_keyboard *k,
852 const uint32_t *keysyms) {
853 idev_data_keyboard *kev;
857 assert(dst == &k->evdata || dst == &k->repdata);
859 r = keyboard_resize_bufs(k, n_syms);
863 dst->type = IDEV_DATA_KEYBOARD;
864 dst->resync = resync;
865 kev = &dst->keyboard;
866 kev->ascii = guess_ascii(k->xkb_state, code, n_syms, keysyms);
870 kev->consumed_mods = 0;
871 kev->n_syms = n_syms;
872 memcpy(kev->keysyms, keysyms, sizeof(*keysyms) * n_syms);
874 for (i = 0; i < n_syms; ++i) {
875 kev->codepoints[i] = xkb_keysym_to_utf32(keysyms[i]);
876 if (!kev->codepoints[i])
877 kev->codepoints[i] = 0xffffffffUL;
880 for (i = 0; i < IDEV_KBDMOD_CNT; ++i) {
881 if (k->kbdmap->modmap[i] == XKB_MOD_INVALID)
884 r = xkb_state_mod_index_is_active(k->xkb_state, k->kbdmap->modmap[i], XKB_STATE_MODS_EFFECTIVE);
888 r = xkb_state_mod_index_is_consumed(k->xkb_state, code + KBDXKB_SHIFT, k->kbdmap->modmap[i]);
890 kev->consumed_mods |= 1 << i;
896 static void keyboard_repeat(idev_keyboard *k) {
897 idev_data *evdata = &k->evdata;
898 idev_data *repdata = &k->repdata;
899 idev_data_keyboard *evkbd = &evdata->keyboard;
900 idev_data_keyboard *repkbd = &repdata->keyboard;
901 const xkb_keysym_t *keysyms;
902 idev_device *d = &k->device;
906 if (evdata->resync) {
908 * We received a re-sync event. During re-sync, any number of
909 * key-events may have been lost and sync-events may be
910 * re-ordered. Always disable key-repeat for those events. Any
911 * following event will trigger it again.
914 k->repeating = false;
919 repeats = xkb_keymap_key_repeats(k->kbdmap->xkb_keymap, evkbd->keycode + KBDXKB_SHIFT);
921 if (k->repeating && repkbd->keycode == evkbd->keycode) {
923 * We received an event for the key we currently repeat. If it
924 * was released, stop key-repeat. Otherwise, ignore the event.
927 if (evkbd->value == KBDKEY_UP) {
928 k->repeating = false;
931 } else if (evkbd->value == KBDKEY_DOWN && repeats) {
933 * We received a key-down event for a key that repeats. The
934 * previous condition caught keys we already repeat, so we know
935 * this is a different key or no key-repeat is running. Start
940 num = xkb_state_key_get_syms(k->xkb_state, evkbd->keycode + KBDXKB_SHIFT, &keysyms);
942 r = errno > 0 ? errno : -EFAULT;
944 r = keyboard_fill(k, repdata, false, evkbd->keycode, KBDKEY_REPEAT, num, keysyms);
947 log_debug_errno(r, "idev-keyboard: %s/%s: cannot set key-repeat: %m",
948 d->session->name, d->name);
949 k->repeating = false;
953 keyboard_arm(k, k->repeat_delay);
955 } else if (k->repeating && !repeats) {
957 * We received an event for a key that does not repeat, but we
958 * currently repeat a previously received key. The new key is
959 * usually a modifier, but might be any kind of key. In this
960 * case, we continue repeating the old key, but update the
961 * symbols according to the new state.
965 num = xkb_state_key_get_syms(k->xkb_state, repkbd->keycode + KBDXKB_SHIFT, &keysyms);
967 r = errno > 0 ? errno : -EFAULT;
969 r = keyboard_fill(k, repdata, false, repkbd->keycode, KBDKEY_REPEAT, num, keysyms);
972 log_debug_errno(r, "idev-keyboard: %s/%s: cannot update key-repeat: %m",
973 d->session->name, d->name);
974 k->repeating = false;
980 static int keyboard_feed_evdev(idev_keyboard *k, idev_data *data) {
981 struct input_event *ev = &data->evdev.event;
982 enum xkb_state_component compch;
983 enum xkb_compose_status cstatus;
984 const xkb_keysym_t *keysyms;
985 idev_device *d = &k->device;
988 if (ev->type != EV_KEY || ev->value > KBDKEY_DOWN)
991 /* TODO: We should audit xkb-actions, whether they need @resync as
992 * flag. Most actions should just be executed, however, there might
993 * be actions that depend on modifier-orders. Those should be
996 num = xkb_state_key_get_syms(k->xkb_state, ev->code + KBDXKB_SHIFT, &keysyms);
997 compch = xkb_state_update_key(k->xkb_state, ev->code + KBDXKB_SHIFT, ev->value);
999 if (compch & XKB_STATE_LEDS) {
1000 /* TODO: update LEDs */
1008 if (k->xkb_compose && ev->value == KBDKEY_DOWN) {
1009 if (num == 1 && !data->resync) {
1010 xkb_compose_state_feed(k->xkb_compose, keysyms[0]);
1011 cstatus = xkb_compose_state_get_status(k->xkb_compose);
1013 cstatus = XKB_COMPOSE_CANCELLED;
1017 case XKB_COMPOSE_NOTHING:
1018 /* keep produced keysyms and forward unchanged */
1020 case XKB_COMPOSE_COMPOSING:
1021 /* consumed by compose-state, drop keysym */
1025 case XKB_COMPOSE_COMPOSED:
1026 /* compose-state produced sth, replace keysym */
1027 num = keyboard_read_compose(k, &keysyms);
1028 xkb_compose_state_reset(k->xkb_compose);
1030 case XKB_COMPOSE_CANCELLED:
1031 /* canceled compose, reset, forward cancellation sym */
1032 xkb_compose_state_reset(k->xkb_compose);
1035 } else if (k->xkb_compose &&
1037 keysyms[0] == XKB_KEY_Multi_key &&
1039 ev->value == KBDKEY_UP) {
1040 /* Reset compose state on Multi-Key UP events. This effectively
1041 * requires you to hold the key during the whole sequence. I
1042 * think it's pretty handy to avoid accidental
1043 * Compose-sequences, but this may break Compose for disabled
1044 * people. We really need to make this opional! (TODO) */
1045 xkb_compose_state_reset(k->xkb_compose);
1048 if (ev->value == KBDKEY_UP) {
1049 /* never produce keysyms for UP */
1054 r = keyboard_fill(k, &k->evdata, data->resync, ev->code, ev->value, num, keysyms);
1059 return keyboard_raise_data(k, &k->evdata);
1062 log_debug_errno(r, "idev-keyboard: %s/%s: cannot handle event: %m",
1063 d->session->name, d->name);
1064 k->repeating = false;
1069 static int keyboard_feed(idev_device *d, idev_data *data) {
1070 idev_keyboard *k = keyboard_from_device(d);
1072 switch (data->type) {
1073 case IDEV_DATA_RESYNC:
1075 * If the underlying device is re-synced, key-events might be
1076 * sent re-ordered. Thus, we don't know which key was pressed
1077 * last. Key-repeat might get confused, hence, disable it
1078 * during re-syncs. The first following event will enable it
1082 k->repeating = false;
1085 case IDEV_DATA_EVDEV:
1086 return keyboard_feed_evdev(k, data);
1092 static int keyboard_update_kbdmap(idev_keyboard *k) {
1093 idev_device *d = &k->device;
1094 struct xkb_state *state;
1100 km = k->kbdctx->kbdmap;
1101 if (km == k->kbdmap)
1105 state = xkb_state_new(km->xkb_keymap);
1107 r = errno > 0 ? -errno : -EFAULT;
1111 kbdmap_unref(k->kbdmap);
1112 k->kbdmap = kbdmap_ref(km);
1113 xkb_state_unref(k->xkb_state);
1114 k->xkb_state = state;
1116 /* TODO: On state-change, we should trigger a resync so the whole
1117 * event-state is flushed into the new xkb-state. libevdev currently
1118 * does not support that, though. */
1123 return log_debug_errno(r, "idev-keyboard: %s/%s: cannot adopt new keymap: %m",
1124 d->session->name, d->name);
1127 static int keyboard_update_kbdtbl(idev_keyboard *k) {
1128 idev_device *d = &k->device;
1129 struct xkb_compose_state *compose = NULL;
1135 kt = k->kbdctx->kbdtbl;
1136 if (kt == k->kbdtbl)
1141 compose = xkb_compose_state_new(kt->xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS);
1143 r = errno > 0 ? -errno : -EFAULT;
1148 kbdtbl_unref(k->kbdtbl);
1149 k->kbdtbl = kbdtbl_ref(kt);
1150 xkb_compose_state_unref(k->xkb_compose);
1151 k->xkb_compose = compose;
1156 return log_debug_errno(r, "idev-keyboard: %s/%s: cannot adopt new compose table: %m",
1157 d->session->name, d->name);
1160 static const idev_device_vtable keyboard_vtable = {
1161 .free = keyboard_free,
1162 .feed = keyboard_feed,