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/>.
25 #include <systemd/sd-bus.h>
26 #include <systemd/sd-event.h>
27 #include <xkbcommon/xkbcommon.h>
28 #include <xkbcommon/xkbcommon-compose.h>
32 #include "idev-internal.h"
34 #include "term-internal.h"
37 typedef struct kbdtbl kbdtbl;
38 typedef struct kbdmap kbdmap;
39 typedef struct kbdctx kbdctx;
40 typedef struct idev_keyboard idev_keyboard;
44 struct xkb_compose_table *xkb_compose_table;
49 struct xkb_keymap *xkb_keymap;
50 xkb_mod_index_t modmap[IDEV_KBDMOD_CNT];
51 xkb_led_index_t ledmap[IDEV_KBDLED_CNT];
56 idev_context *context;
57 struct xkb_context *xkb_context;
58 struct kbdmap *kbdmap;
59 struct kbdtbl *kbdtbl;
61 sd_bus_slot *slot_locale_props_changed;
62 sd_bus_slot *slot_locale_get_all;
65 char *locale_x11_model;
66 char *locale_x11_layout;
67 char *locale_x11_variant;
68 char *locale_x11_options;
70 char *last_x11_layout;
71 char *last_x11_variant;
72 char *last_x11_options;
75 struct idev_keyboard {
81 struct xkb_state *xkb_state;
82 struct xkb_compose_state *xkb_compose;
86 sd_event_source *repeat_timer;
91 uint32_t *compose_res;
96 #define keyboard_from_device(_d) container_of((_d), idev_keyboard, device)
98 #define KBDCTX_KEY "keyboard.context" /* hashmap key for global kbdctx */
99 #define KBDXKB_SHIFT (8) /* xkb shifts evdev key-codes by 8 */
100 #define KBDKEY_UP (0) /* KEY UP event value */
101 #define KBDKEY_DOWN (1) /* KEY DOWN event value */
102 #define KBDKEY_REPEAT (2) /* KEY REPEAT event value */
104 static const idev_device_vtable keyboard_vtable;
106 static int keyboard_update_kbdmap(idev_keyboard *k);
107 static int keyboard_update_kbdtbl(idev_keyboard *k);
110 * Keyboard Compose Tables
113 static kbdtbl *kbdtbl_ref(kbdtbl *kt) {
115 assert_return(kt->ref > 0, NULL);
122 static kbdtbl *kbdtbl_unref(kbdtbl *kt) {
126 assert_return(kt->ref > 0, NULL);
131 xkb_compose_table_unref(kt->xkb_compose_table);
137 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdtbl*, kbdtbl_unref);
139 static int kbdtbl_new_from_locale(kbdtbl **out, kbdctx *kc, const char *locale) {
140 _cleanup_(kbdtbl_unrefp) kbdtbl *kt = NULL;
142 assert_return(out, -EINVAL);
143 assert_return(locale, -EINVAL);
145 kt = new0(kbdtbl, 1);
151 kt->xkb_compose_table = xkb_compose_table_new_from_locale(kc->xkb_context,
153 XKB_COMPOSE_COMPILE_NO_FLAGS);
154 if (!kt->xkb_compose_table)
155 return errno > 0 ? -errno : -EFAULT;
166 static const char * const kbdmap_modmap[IDEV_KBDMOD_CNT] = {
167 [IDEV_KBDMOD_IDX_SHIFT] = XKB_MOD_NAME_SHIFT,
168 [IDEV_KBDMOD_IDX_CTRL] = XKB_MOD_NAME_CTRL,
169 [IDEV_KBDMOD_IDX_ALT] = XKB_MOD_NAME_ALT,
170 [IDEV_KBDMOD_IDX_LINUX] = XKB_MOD_NAME_LOGO,
171 [IDEV_KBDMOD_IDX_CAPS] = XKB_MOD_NAME_CAPS,
174 static const char * const kbdmap_ledmap[IDEV_KBDLED_CNT] = {
175 [IDEV_KBDLED_IDX_NUM] = XKB_LED_NAME_NUM,
176 [IDEV_KBDLED_IDX_CAPS] = XKB_LED_NAME_CAPS,
177 [IDEV_KBDLED_IDX_SCROLL] = XKB_LED_NAME_SCROLL,
180 static kbdmap *kbdmap_ref(kbdmap *km) {
181 assert_return(km, NULL);
182 assert_return(km->ref > 0, NULL);
188 static kbdmap *kbdmap_unref(kbdmap *km) {
192 assert_return(km->ref > 0, NULL);
197 xkb_keymap_unref(km->xkb_keymap);
203 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdmap*, kbdmap_unref);
205 static int kbdmap_new_from_names(kbdmap **out,
210 const char *options) {
211 _cleanup_(kbdmap_unrefp) kbdmap *km = NULL;
212 struct xkb_rule_names rmlvo = { };
215 assert_return(out, -EINVAL);
217 km = new0(kbdmap, 1);
223 rmlvo.rules = "evdev";
225 rmlvo.layout = layout;
226 rmlvo.variant = variant;
227 rmlvo.options = options;
230 km->xkb_keymap = xkb_keymap_new_from_names(kc->xkb_context, &rmlvo, 0);
232 return errno > 0 ? -errno : -EFAULT;
234 for (i = 0; i < IDEV_KBDMOD_CNT; ++i) {
235 const char *t = kbdmap_modmap[i];
238 km->modmap[i] = xkb_keymap_mod_get_index(km->xkb_keymap, t);
240 km->modmap[i] = XKB_MOD_INVALID;
243 for (i = 0; i < IDEV_KBDLED_CNT; ++i) {
244 const char *t = kbdmap_ledmap[i];
247 km->ledmap[i] = xkb_keymap_led_get_index(km->xkb_keymap, t);
249 km->ledmap[i] = XKB_LED_INVALID;
261 static int kbdctx_refresh_compose_table(kbdctx *kc, const char *lang) {
271 if (streq_ptr(kc->locale_lang, lang))
274 r = free_and_strdup(&kc->locale_lang, lang);
278 log_debug("idev-keyboard: new default compose table: [ %s ]", lang);
280 r = kbdtbl_new_from_locale(&kt, kc, lang);
282 /* TODO: We need to catch the case where no compose-file is
283 * available. xkb doesn't tell us so far.. so we must not treat
284 * it as a hard-failure but just continue. Preferably, we want
285 * xkb to tell us exactly whether compilation failed or whether
286 * there is no compose file available for this locale. */
287 log_debug_errno(r, "idev-keyboard: cannot load compose-table for '%s': %m",
293 kbdtbl_unref(kc->kbdtbl);
296 HASHMAP_FOREACH(s, kc->context->session_map, i)
297 HASHMAP_FOREACH(d, s->device_map, j)
298 if (idev_is_keyboard(d))
299 keyboard_update_kbdtbl(keyboard_from_device(d));
304 static void move_str(char **dest, char **src) {
310 static int kbdctx_refresh_keymap(kbdctx *kc) {
318 streq_ptr(kc->locale_x11_model, kc->last_x11_model) &&
319 streq_ptr(kc->locale_x11_layout, kc->last_x11_layout) &&
320 streq_ptr(kc->locale_x11_variant, kc->last_x11_variant) &&
321 streq_ptr(kc->locale_x11_options, kc->last_x11_options))
324 move_str(&kc->last_x11_model, &kc->locale_x11_model);
325 move_str(&kc->last_x11_layout, &kc->locale_x11_layout);
326 move_str(&kc->last_x11_variant, &kc->locale_x11_variant);
327 move_str(&kc->last_x11_options, &kc->locale_x11_options);
329 log_debug("idev-keyboard: new default keymap: [%s / %s / %s / %s]",
330 kc->last_x11_model, kc->last_x11_layout, kc->last_x11_variant, kc->last_x11_options);
332 /* TODO: add a fallback keymap that's compiled-in */
333 r = kbdmap_new_from_names(&km, kc, kc->last_x11_model, kc->last_x11_layout,
334 kc->last_x11_variant, kc->last_x11_options);
336 return log_debug_errno(r, "idev-keyboard: cannot create keymap from locale1: %m");
338 kbdmap_unref(kc->kbdmap);
341 HASHMAP_FOREACH(s, kc->context->session_map, i)
342 HASHMAP_FOREACH(d, s->device_map, j)
343 if (idev_is_keyboard(d))
344 keyboard_update_kbdmap(keyboard_from_device(d));
349 static int kbdctx_set_locale(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
350 kbdctx *kc = userdata;
351 const char *s, *ctype = NULL, *lang = NULL;
354 r = sd_bus_message_enter_container(m, 'a', "s");
358 while ((r = sd_bus_message_read(m, "s", &s)) > 0) {
360 ctype = startswith(s, "LC_CTYPE=");
362 lang = startswith(s, "LANG=");
368 r = sd_bus_message_exit_container(m);
372 kbdctx_refresh_compose_table(kc, ctype ? : lang);
377 log_debug_errno(r, "idev-keyboard: cannot parse locale property from locale1: %m");
382 static const struct bus_properties_map kbdctx_locale_map[] = {
383 { "Locale", "as", kbdctx_set_locale, 0 },
384 { "X11Model", "s", NULL, offsetof(kbdctx, locale_x11_model) },
385 { "X11Layout", "s", NULL, offsetof(kbdctx, locale_x11_layout) },
386 { "X11Variant", "s", NULL, offsetof(kbdctx, locale_x11_variant) },
387 { "X11Options", "s", NULL, offsetof(kbdctx, locale_x11_options) },
390 static int kbdctx_locale_get_all_fn(sd_bus *bus,
393 sd_bus_error *ret_err) {
394 kbdctx *kc = userdata;
397 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
399 if (sd_bus_message_is_method_error(m, NULL)) {
400 const sd_bus_error *error = sd_bus_message_get_error(m);
402 log_debug("idev-keyboard: GetAll() on locale1 failed: %s: %s",
403 error->name, error->message);
407 r = bus_message_map_all_properties(bus, m, kbdctx_locale_map, kc);
409 log_debug("idev-keyboard: erroneous GetAll() reply from locale1");
413 kbdctx_refresh_keymap(kc);
417 static int kbdctx_query_locale(kbdctx *kc) {
418 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
421 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
423 r = sd_bus_message_new_method_call(kc->context->sysbus,
425 "org.freedesktop.locale1",
426 "/org/freedesktop/locale1",
427 "org.freedesktop.DBus.Properties",
432 r = sd_bus_message_append(m, "s", "org.freedesktop.locale1");
436 r = sd_bus_call_async(kc->context->sysbus,
437 &kc->slot_locale_get_all,
439 kbdctx_locale_get_all_fn,
448 return log_debug_errno(r, "idev-keyboard: cannot send GetAll to locale1: %m");
451 static int kbdctx_locale_props_changed_fn(sd_bus *bus,
452 sd_bus_message *signal,
454 sd_bus_error *ret_err) {
455 kbdctx *kc = userdata;
458 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
460 /* skip interface name */
461 r = sd_bus_message_skip(signal, "s");
465 r = bus_message_map_properties_changed(bus, signal, kbdctx_locale_map, kc);
470 r = kbdctx_query_locale(kc);
475 kbdctx_refresh_keymap(kc);
479 return log_debug_errno(r, "idev-keyboard: cannot handle PropertiesChanged from locale1: %m");
482 static int kbdctx_setup_bus(kbdctx *kc) {
485 r = sd_bus_add_match(kc->context->sysbus,
486 &kc->slot_locale_props_changed,
488 "sender='org.freedesktop.locale1',"
489 "interface='org.freedesktop.DBus.Properties',"
490 "member='PropertiesChanged',"
491 "path='/org/freedesktop/locale1'",
492 kbdctx_locale_props_changed_fn,
495 return log_debug_errno(r, "idev-keyboard: cannot setup locale1 link: %m");
497 return kbdctx_query_locale(kc);
500 static void kbdctx_log_fn(struct xkb_context *ctx, enum xkb_log_level lvl, const char *format, va_list args) {
504 if (lvl >= XKB_LOG_LEVEL_DEBUG)
506 else if (lvl >= XKB_LOG_LEVEL_INFO)
508 else if (lvl >= XKB_LOG_LEVEL_WARNING)
509 sd_lvl = LOG_INFO; /* most XKB warnings really are informational */
510 else if (lvl >= XKB_LOG_LEVEL_ERROR)
512 else if (lvl >= XKB_LOG_LEVEL_CRITICAL)
517 snprintf(buf, sizeof(buf), "idev-xkb: %s", format);
518 log_internalv(sd_lvl, 0, __FILE__, __LINE__, __func__, buf, args);
521 static kbdctx *kbdctx_ref(kbdctx *kc) {
522 assert_return(kc, NULL);
523 assert_return(kc->ref > 0, NULL);
529 static kbdctx *kbdctx_unref(kbdctx *kc) {
533 assert_return(kc->ref > 0, NULL);
538 free(kc->last_x11_options);
539 free(kc->last_x11_variant);
540 free(kc->last_x11_layout);
541 free(kc->last_x11_model);
542 free(kc->locale_x11_options);
543 free(kc->locale_x11_variant);
544 free(kc->locale_x11_layout);
545 free(kc->locale_x11_model);
546 free(kc->locale_lang);
547 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
548 kc->slot_locale_props_changed = sd_bus_slot_unref(kc->slot_locale_props_changed);
549 kc->kbdtbl = kbdtbl_unref(kc->kbdtbl);
550 kc->kbdmap = kbdmap_unref(kc->kbdmap);
551 xkb_context_unref(kc->xkb_context);
552 hashmap_remove_value(kc->context->data_map, KBDCTX_KEY, kc);
558 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdctx*, kbdctx_unref);
560 static int kbdctx_new(kbdctx **out, idev_context *c) {
561 _cleanup_(kbdctx_unrefp) kbdctx *kc = NULL;
564 assert_return(out, -EINVAL);
565 assert_return(c, -EINVAL);
567 kc = new0(kbdctx, 1);
575 kc->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
576 if (!kc->xkb_context)
577 return errno > 0 ? -errno : -EFAULT;
579 xkb_context_set_log_fn(kc->xkb_context, kbdctx_log_fn);
580 xkb_context_set_log_level(kc->xkb_context, XKB_LOG_LEVEL_DEBUG);
582 r = kbdctx_refresh_keymap(kc);
586 r = kbdctx_refresh_compose_table(kc, NULL);
591 r = kbdctx_setup_bus(kc);
596 r = hashmap_put(c->data_map, KBDCTX_KEY, kc);
605 static int get_kbdctx(idev_context *c, kbdctx **out) {
608 assert_return(c, -EINVAL);
609 assert_return(out, -EINVAL);
611 kc = hashmap_get(c->data_map, KBDCTX_KEY);
613 *out = kbdctx_ref(kc);
617 return kbdctx_new(out, c);
624 bool idev_is_keyboard(idev_device *d) {
625 return d && d->vtable == &keyboard_vtable;
628 idev_device *idev_find_keyboard(idev_session *s, const char *name) {
631 assert_return(s, NULL);
632 assert_return(name, NULL);
634 kname = strjoina("keyboard/", name);
635 return hashmap_get(s->device_map, kname);
638 static int keyboard_raise_data(idev_keyboard *k, idev_data *data) {
639 idev_device *d = &k->device;
642 r = idev_session_raise_device_data(d->session, d, data);
644 log_debug_errno(r, "idev-keyboard: %s/%s: error while raising data event: %m",
645 d->session->name, d->name);
650 static int keyboard_resize_bufs(idev_keyboard *k, uint32_t n_syms) {
653 if (n_syms <= k->n_syms)
656 t = realloc(k->compose_res, sizeof(*t) * n_syms);
661 t = realloc(k->evdata.keyboard.keysyms, sizeof(*t) * n_syms);
664 k->evdata.keyboard.keysyms = t;
666 t = realloc(k->evdata.keyboard.codepoints, sizeof(*t) * n_syms);
669 k->evdata.keyboard.codepoints = t;
671 t = realloc(k->repdata.keyboard.keysyms, sizeof(*t) * n_syms);
674 k->repdata.keyboard.keysyms = t;
676 t = realloc(k->repdata.keyboard.codepoints, sizeof(*t) * n_syms);
679 k->repdata.keyboard.codepoints = t;
685 static unsigned int keyboard_read_compose(idev_keyboard *k, const xkb_keysym_t **out) {
686 _cleanup_free_ char *t = NULL;
692 r = xkb_compose_state_get_utf8(k->xkb_compose, buf, sizeof(buf));
693 if (r >= (int)sizeof(buf)) {
698 xkb_compose_state_get_utf8(k->xkb_compose, t, r + 1);
704 for (i = 0; i < r; ++i) {
708 len = term_utf8_decode(&u8, &ucs, p[i]);
710 r = keyboard_resize_bufs(k, flen + len);
714 for (j = 0; j < len; ++j)
715 k->compose_res[flen++] = ucs[j];
719 *out = k->compose_res;
723 static void keyboard_arm(idev_keyboard *k, usec_t usecs) {
727 usecs += now(CLOCK_MONOTONIC);
728 r = sd_event_source_set_time(k->repeat_timer, usecs);
730 sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_ONESHOT);
732 sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_OFF);
736 static int keyboard_repeat_timer_fn(sd_event_source *source, uint64_t usec, void *userdata) {
737 idev_keyboard *k = userdata;
739 /* never feed REPEAT keys into COMPOSE */
741 keyboard_arm(k, k->repeat_rate);
742 return keyboard_raise_data(k, &k->repdata);
745 int idev_keyboard_new(idev_device **out, idev_session *s, const char *name) {
746 _cleanup_(idev_device_freep) idev_device *d = NULL;
751 assert_return(out, -EINVAL);
752 assert_return(s, -EINVAL);
753 assert_return(name, -EINVAL);
755 k = new0(idev_keyboard, 1);
760 k->device = IDEV_DEVICE_INIT(&keyboard_vtable, s);
761 k->repeat_delay = 250 * USEC_PER_MSEC;
762 k->repeat_rate = 30 * USEC_PER_MSEC;
764 /* TODO: add key-repeat configuration */
766 r = get_kbdctx(s->context, &k->kbdctx);
770 r = keyboard_update_kbdmap(k);
774 r = keyboard_update_kbdtbl(k);
778 r = keyboard_resize_bufs(k, 8);
782 r = sd_event_add_time(s->context->event,
787 keyboard_repeat_timer_fn,
792 r = sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_OFF);
796 kname = strjoina("keyboard/", name);
797 r = idev_device_add(d, kname);
807 static void keyboard_free(idev_device *d) {
808 idev_keyboard *k = keyboard_from_device(d);
810 xkb_compose_state_unref(k->xkb_compose);
811 xkb_state_unref(k->xkb_state);
812 free(k->repdata.keyboard.codepoints);
813 free(k->repdata.keyboard.keysyms);
814 free(k->evdata.keyboard.codepoints);
815 free(k->evdata.keyboard.keysyms);
816 free(k->compose_res);
817 k->repeat_timer = sd_event_source_unref(k->repeat_timer);
818 k->kbdtbl = kbdtbl_unref(k->kbdtbl);
819 k->kbdmap = kbdmap_unref(k->kbdmap);
820 k->kbdctx = kbdctx_unref(k->kbdctx);
824 static int8_t guess_ascii(struct xkb_state *state, uint32_t code, uint32_t n_syms, const uint32_t *syms) {
825 xkb_layout_index_t n_lo, lo;
826 xkb_level_index_t lv;
827 struct xkb_keymap *keymap;
828 const xkb_keysym_t *s;
831 if (n_syms == 1 && syms[0] < 128 && syms[0] > 0)
834 keymap = xkb_state_get_keymap(state);
835 n_lo = xkb_keymap_num_layouts_for_key(keymap, code + KBDXKB_SHIFT);
837 for (lo = 0; lo < n_lo; ++lo) {
838 lv = xkb_state_key_get_level(state, code + KBDXKB_SHIFT, lo);
839 num = xkb_keymap_key_get_syms_by_level(keymap, code + KBDXKB_SHIFT, lo, lv, &s);
840 if (num == 1 && s[0] < 128 && s[0] > 0)
847 static int keyboard_fill(idev_keyboard *k,
853 const uint32_t *keysyms) {
854 idev_data_keyboard *kev;
858 assert(dst == &k->evdata || dst == &k->repdata);
860 r = keyboard_resize_bufs(k, n_syms);
864 dst->type = IDEV_DATA_KEYBOARD;
865 dst->resync = resync;
866 kev = &dst->keyboard;
867 kev->ascii = guess_ascii(k->xkb_state, code, n_syms, keysyms);
871 kev->consumed_mods = 0;
872 kev->n_syms = n_syms;
873 memcpy(kev->keysyms, keysyms, sizeof(*keysyms) * n_syms);
875 for (i = 0; i < n_syms; ++i) {
876 kev->codepoints[i] = xkb_keysym_to_utf32(keysyms[i]);
877 if (!kev->codepoints[i])
878 kev->codepoints[i] = 0xffffffffUL;
881 for (i = 0; i < IDEV_KBDMOD_CNT; ++i) {
882 if (k->kbdmap->modmap[i] == XKB_MOD_INVALID)
885 r = xkb_state_mod_index_is_active(k->xkb_state, k->kbdmap->modmap[i], XKB_STATE_MODS_EFFECTIVE);
889 r = xkb_state_mod_index_is_consumed(k->xkb_state, code + KBDXKB_SHIFT, k->kbdmap->modmap[i]);
891 kev->consumed_mods |= 1 << i;
897 static void keyboard_repeat(idev_keyboard *k) {
898 idev_data *evdata = &k->evdata;
899 idev_data *repdata = &k->repdata;
900 idev_data_keyboard *evkbd = &evdata->keyboard;
901 idev_data_keyboard *repkbd = &repdata->keyboard;
902 const xkb_keysym_t *keysyms;
903 idev_device *d = &k->device;
907 if (evdata->resync) {
909 * We received a re-sync event. During re-sync, any number of
910 * key-events may have been lost and sync-events may be
911 * re-ordered. Always disable key-repeat for those events. Any
912 * following event will trigger it again.
915 k->repeating = false;
920 repeats = xkb_keymap_key_repeats(k->kbdmap->xkb_keymap, evkbd->keycode + KBDXKB_SHIFT);
922 if (k->repeating && repkbd->keycode == evkbd->keycode) {
924 * We received an event for the key we currently repeat. If it
925 * was released, stop key-repeat. Otherwise, ignore the event.
928 if (evkbd->value == KBDKEY_UP) {
929 k->repeating = false;
932 } else if (evkbd->value == KBDKEY_DOWN && repeats) {
934 * We received a key-down event for a key that repeats. The
935 * previous condition caught keys we already repeat, so we know
936 * this is a different key or no key-repeat is running. Start
941 num = xkb_state_key_get_syms(k->xkb_state, evkbd->keycode + KBDXKB_SHIFT, &keysyms);
943 r = errno > 0 ? errno : -EFAULT;
945 r = keyboard_fill(k, repdata, false, evkbd->keycode, KBDKEY_REPEAT, num, keysyms);
948 log_debug_errno(r, "idev-keyboard: %s/%s: cannot set key-repeat: %m",
949 d->session->name, d->name);
950 k->repeating = false;
954 keyboard_arm(k, k->repeat_delay);
956 } else if (k->repeating && !repeats) {
958 * We received an event for a key that does not repeat, but we
959 * currently repeat a previously received key. The new key is
960 * usually a modifier, but might be any kind of key. In this
961 * case, we continue repeating the old key, but update the
962 * symbols according to the new state.
966 num = xkb_state_key_get_syms(k->xkb_state, repkbd->keycode + KBDXKB_SHIFT, &keysyms);
968 r = errno > 0 ? errno : -EFAULT;
970 r = keyboard_fill(k, repdata, false, repkbd->keycode, KBDKEY_REPEAT, num, keysyms);
973 log_debug_errno(r, "idev-keyboard: %s/%s: cannot update key-repeat: %m",
974 d->session->name, d->name);
975 k->repeating = false;
981 static int keyboard_feed_evdev(idev_keyboard *k, idev_data *data) {
982 struct input_event *ev = &data->evdev.event;
983 enum xkb_state_component compch;
984 enum xkb_compose_status cstatus;
985 const xkb_keysym_t *keysyms;
986 idev_device *d = &k->device;
989 if (ev->type != EV_KEY || ev->value > KBDKEY_DOWN)
992 /* TODO: We should audit xkb-actions, whether they need @resync as
993 * flag. Most actions should just be executed, however, there might
994 * be actions that depend on modifier-orders. Those should be
997 num = xkb_state_key_get_syms(k->xkb_state, ev->code + KBDXKB_SHIFT, &keysyms);
998 compch = xkb_state_update_key(k->xkb_state, ev->code + KBDXKB_SHIFT, ev->value);
1000 if (compch & XKB_STATE_LEDS) {
1001 /* TODO: update LEDs */
1009 if (k->xkb_compose && ev->value == KBDKEY_DOWN) {
1010 if (num == 1 && !data->resync) {
1011 xkb_compose_state_feed(k->xkb_compose, keysyms[0]);
1012 cstatus = xkb_compose_state_get_status(k->xkb_compose);
1014 cstatus = XKB_COMPOSE_CANCELLED;
1018 case XKB_COMPOSE_NOTHING:
1019 /* keep produced keysyms and forward unchanged */
1021 case XKB_COMPOSE_COMPOSING:
1022 /* consumed by compose-state, drop keysym */
1026 case XKB_COMPOSE_COMPOSED:
1027 /* compose-state produced sth, replace keysym */
1028 num = keyboard_read_compose(k, &keysyms);
1029 xkb_compose_state_reset(k->xkb_compose);
1031 case XKB_COMPOSE_CANCELLED:
1032 /* canceled compose, reset, forward cancellation sym */
1033 xkb_compose_state_reset(k->xkb_compose);
1036 } else if (k->xkb_compose &&
1038 keysyms[0] == XKB_KEY_Multi_key &&
1040 ev->value == KBDKEY_UP) {
1041 /* Reset compose state on Multi-Key UP events. This effectively
1042 * requires you to hold the key during the whole sequence. I
1043 * think it's pretty handy to avoid accidental
1044 * Compose-sequences, but this may break Compose for disabled
1045 * people. We really need to make this opional! (TODO) */
1046 xkb_compose_state_reset(k->xkb_compose);
1049 if (ev->value == KBDKEY_UP) {
1050 /* never produce keysyms for UP */
1055 r = keyboard_fill(k, &k->evdata, data->resync, ev->code, ev->value, num, keysyms);
1060 return keyboard_raise_data(k, &k->evdata);
1063 log_debug_errno(r, "idev-keyboard: %s/%s: cannot handle event: %m",
1064 d->session->name, d->name);
1065 k->repeating = false;
1070 static int keyboard_feed(idev_device *d, idev_data *data) {
1071 idev_keyboard *k = keyboard_from_device(d);
1073 switch (data->type) {
1074 case IDEV_DATA_RESYNC:
1076 * If the underlying device is re-synced, key-events might be
1077 * sent re-ordered. Thus, we don't know which key was pressed
1078 * last. Key-repeat might get confused, hence, disable it
1079 * during re-syncs. The first following event will enable it
1083 k->repeating = false;
1086 case IDEV_DATA_EVDEV:
1087 return keyboard_feed_evdev(k, data);
1093 static int keyboard_update_kbdmap(idev_keyboard *k) {
1094 idev_device *d = &k->device;
1095 struct xkb_state *state;
1101 km = k->kbdctx->kbdmap;
1102 if (km == k->kbdmap)
1106 state = xkb_state_new(km->xkb_keymap);
1108 r = errno > 0 ? -errno : -EFAULT;
1112 kbdmap_unref(k->kbdmap);
1113 k->kbdmap = kbdmap_ref(km);
1114 xkb_state_unref(k->xkb_state);
1115 k->xkb_state = state;
1117 /* TODO: On state-change, we should trigger a resync so the whole
1118 * event-state is flushed into the new xkb-state. libevdev currently
1119 * does not support that, though. */
1124 return log_debug_errno(r, "idev-keyboard: %s/%s: cannot adopt new keymap: %m",
1125 d->session->name, d->name);
1128 static int keyboard_update_kbdtbl(idev_keyboard *k) {
1129 idev_device *d = &k->device;
1130 struct xkb_compose_state *compose = NULL;
1136 kt = k->kbdctx->kbdtbl;
1137 if (kt == k->kbdtbl)
1142 compose = xkb_compose_state_new(kt->xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS);
1144 r = errno > 0 ? -errno : -EFAULT;
1149 kbdtbl_unref(k->kbdtbl);
1150 k->kbdtbl = kbdtbl_ref(kt);
1151 xkb_compose_state_unref(k->xkb_compose);
1152 k->xkb_compose = compose;
1157 return log_debug_errno(r, "idev-keyboard: %s/%s: cannot adopt new compose table: %m",
1158 d->session->name, d->name);
1161 static const idev_device_vtable keyboard_vtable = {
1162 .free = keyboard_free,
1163 .feed = keyboard_feed,