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"
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;
94 #define keyboard_from_device(_d) container_of((_d), idev_keyboard, device)
96 #define KBDCTX_KEY "keyboard.context" /* hashmap key for global kbdctx */
97 #define KBDXKB_SHIFT (8) /* xkb shifts evdev key-codes by 8 */
98 #define KBDKEY_UP (0) /* KEY UP event value */
99 #define KBDKEY_DOWN (1) /* KEY DOWN event value */
100 #define KBDKEY_REPEAT (2) /* KEY REPEAT event value */
102 static const idev_device_vtable keyboard_vtable;
104 static int keyboard_update_kbdmap(idev_keyboard *k);
105 static int keyboard_update_kbdtbl(idev_keyboard *k);
108 * Keyboard Compose Tables
111 static kbdtbl *kbdtbl_ref(kbdtbl *kt) {
113 assert_return(kt->ref > 0, NULL);
120 static kbdtbl *kbdtbl_unref(kbdtbl *kt) {
124 assert_return(kt->ref > 0, NULL);
129 xkb_compose_table_unref(kt->xkb_compose_table);
135 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdtbl*, kbdtbl_unref);
137 static int kbdtbl_new_from_locale(kbdtbl **out, kbdctx *kc, const char *locale) {
138 _cleanup_(kbdtbl_unrefp) kbdtbl *kt = NULL;
140 assert_return(out, -EINVAL);
141 assert_return(locale, -EINVAL);
143 kt = new0(kbdtbl, 1);
149 kt->xkb_compose_table = xkb_compose_table_new_from_locale(kc->xkb_context,
151 XKB_COMPOSE_COMPILE_NO_FLAGS);
152 if (!kt->xkb_compose_table)
153 return errno > 0 ? -errno : -EFAULT;
164 static const char * const kbdmap_modmap[IDEV_KBDMOD_CNT] = {
165 [IDEV_KBDMOD_IDX_SHIFT] = XKB_MOD_NAME_SHIFT,
166 [IDEV_KBDMOD_IDX_CTRL] = XKB_MOD_NAME_CTRL,
167 [IDEV_KBDMOD_IDX_ALT] = XKB_MOD_NAME_ALT,
168 [IDEV_KBDMOD_IDX_LINUX] = XKB_MOD_NAME_LOGO,
169 [IDEV_KBDMOD_IDX_CAPS] = XKB_MOD_NAME_CAPS,
172 static const char * const kbdmap_ledmap[IDEV_KBDLED_CNT] = {
173 [IDEV_KBDLED_IDX_NUM] = XKB_LED_NAME_NUM,
174 [IDEV_KBDLED_IDX_CAPS] = XKB_LED_NAME_CAPS,
175 [IDEV_KBDLED_IDX_SCROLL] = XKB_LED_NAME_SCROLL,
178 static kbdmap *kbdmap_ref(kbdmap *km) {
179 assert_return(km, NULL);
180 assert_return(km->ref > 0, NULL);
186 static kbdmap *kbdmap_unref(kbdmap *km) {
190 assert_return(km->ref > 0, NULL);
195 xkb_keymap_unref(km->xkb_keymap);
201 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdmap*, kbdmap_unref);
203 static int kbdmap_new_from_names(kbdmap **out,
208 const char *options) {
209 _cleanup_(kbdmap_unrefp) kbdmap *km = NULL;
210 struct xkb_rule_names rmlvo = { };
213 assert_return(out, -EINVAL);
215 km = new0(kbdmap, 1);
221 rmlvo.rules = "evdev";
223 rmlvo.layout = layout;
224 rmlvo.variant = variant;
225 rmlvo.options = options;
228 km->xkb_keymap = xkb_keymap_new_from_names(kc->xkb_context, &rmlvo, 0);
230 return errno > 0 ? -errno : -EFAULT;
232 for (i = 0; i < IDEV_KBDMOD_CNT; ++i) {
233 const char *t = kbdmap_modmap[i];
236 km->modmap[i] = xkb_keymap_mod_get_index(km->xkb_keymap, t);
238 km->modmap[i] = XKB_MOD_INVALID;
241 for (i = 0; i < IDEV_KBDLED_CNT; ++i) {
242 const char *t = kbdmap_ledmap[i];
245 km->ledmap[i] = xkb_keymap_led_get_index(km->xkb_keymap, t);
247 km->ledmap[i] = XKB_LED_INVALID;
259 static int kbdctx_refresh_compose_table(kbdctx *kc, const char *lang) {
269 if (streq_ptr(kc->locale_lang, lang))
272 r = free_and_strdup(&kc->locale_lang, lang);
276 log_debug("idev-keyboard: new default compose table: [ %s ]", lang);
278 r = kbdtbl_new_from_locale(&kt, kc, lang);
280 /* TODO: We need to catch the case where no compose-file is
281 * available. xkb doesn't tell us so far.. so we must not treat
282 * it as a hard-failure but just continue. Preferably, we want
283 * xkb to tell us exactly whether compilation failed or whether
284 * there is no compose file available for this locale. */
285 log_debug("idev-keyboard: cannot load compose-table for '%s': %s",
291 kbdtbl_unref(kc->kbdtbl);
294 HASHMAP_FOREACH(s, kc->context->session_map, i)
295 HASHMAP_FOREACH(d, s->device_map, j)
296 if (idev_is_keyboard(d))
297 keyboard_update_kbdtbl(keyboard_from_device(d));
302 static void move_str(char **dest, char **src) {
308 static int kbdctx_refresh_keymap(kbdctx *kc) {
316 streq_ptr(kc->locale_x11_model, kc->last_x11_model) &&
317 streq_ptr(kc->locale_x11_layout, kc->last_x11_layout) &&
318 streq_ptr(kc->locale_x11_variant, kc->last_x11_variant) &&
319 streq_ptr(kc->locale_x11_options, kc->last_x11_options))
322 move_str(&kc->last_x11_model, &kc->locale_x11_model);
323 move_str(&kc->last_x11_layout, &kc->locale_x11_layout);
324 move_str(&kc->last_x11_variant, &kc->locale_x11_variant);
325 move_str(&kc->last_x11_options, &kc->locale_x11_options);
327 log_debug("idev-keyboard: new default keymap: [%s / %s / %s / %s]",
328 kc->last_x11_model, kc->last_x11_layout, kc->last_x11_variant, kc->last_x11_options);
330 /* TODO: add a fallback keymap that's compiled-in */
331 r = kbdmap_new_from_names(&km, kc, kc->last_x11_model, kc->last_x11_layout,
332 kc->last_x11_variant, kc->last_x11_options);
334 log_debug("idev-keyboard: cannot create keymap from locale1: %s",
339 kbdmap_unref(kc->kbdmap);
342 HASHMAP_FOREACH(s, kc->context->session_map, i)
343 HASHMAP_FOREACH(d, s->device_map, j)
344 if (idev_is_keyboard(d))
345 keyboard_update_kbdmap(keyboard_from_device(d));
350 static int kbdctx_set_locale(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
351 kbdctx *kc = userdata;
352 const char *s, *ctype = NULL, *lang = NULL;
355 r = sd_bus_message_enter_container(m, 'a', "s");
359 while ((r = sd_bus_message_read(m, "s", &s)) > 0) {
361 ctype = startswith(s, "LC_CTYPE=");
363 lang = startswith(s, "LANG=");
369 r = sd_bus_message_exit_container(m);
373 kbdctx_refresh_compose_table(kc, ctype ? : lang);
378 log_debug("idev-keyboard: cannot parse locale property from locale1: %s", strerror(-r));
383 static const struct bus_properties_map kbdctx_locale_map[] = {
384 { "Locale", "as", kbdctx_set_locale, 0 },
385 { "X11Model", "s", NULL, offsetof(kbdctx, locale_x11_model) },
386 { "X11Layout", "s", NULL, offsetof(kbdctx, locale_x11_layout) },
387 { "X11Variant", "s", NULL, offsetof(kbdctx, locale_x11_variant) },
388 { "X11Options", "s", NULL, offsetof(kbdctx, locale_x11_options) },
391 static int kbdctx_locale_get_all_fn(sd_bus *bus,
394 sd_bus_error *ret_err) {
395 kbdctx *kc = userdata;
398 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
400 if (sd_bus_message_is_method_error(m, NULL)) {
401 const sd_bus_error *error = sd_bus_message_get_error(m);
403 log_debug("idev-keyboard: GetAll() on locale1 failed: %s: %s",
404 error->name, error->message);
408 r = bus_message_map_all_properties(bus, m, kbdctx_locale_map, kc);
410 log_debug("idev-keyboard: erroneous GetAll() reply from locale1");
414 kbdctx_refresh_keymap(kc);
418 static int kbdctx_query_locale(kbdctx *kc) {
419 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
422 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
424 r = sd_bus_message_new_method_call(kc->context->sysbus,
426 "org.freedesktop.locale1",
427 "/org/freedesktop/locale1",
428 "org.freedesktop.DBus.Properties",
433 r = sd_bus_message_append(m, "s", "org.freedesktop.locale1");
437 r = sd_bus_call_async(kc->context->sysbus,
438 &kc->slot_locale_get_all,
440 kbdctx_locale_get_all_fn,
449 log_debug("idev-keyboard: cannot send GetAll to locale1: %s", strerror(-r));
453 static int kbdctx_locale_props_changed_fn(sd_bus *bus,
454 sd_bus_message *signal,
456 sd_bus_error *ret_err) {
457 kbdctx *kc = userdata;
460 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
462 /* skip interface name */
463 r = sd_bus_message_skip(signal, "s");
467 r = bus_message_map_properties_changed(bus, signal, kbdctx_locale_map, kc);
472 r = kbdctx_query_locale(kc);
477 kbdctx_refresh_keymap(kc);
481 log_debug("idev-keyboard: cannot handle PropertiesChanged from locale1: %s", strerror(-r));
485 static int kbdctx_setup_bus(kbdctx *kc) {
488 r = sd_bus_add_match(kc->context->sysbus,
489 &kc->slot_locale_props_changed,
491 "sender='org.freedesktop.locale1',"
492 "interface='org.freedesktop.DBus.Properties',"
493 "member='PropertiesChanged',"
494 "path='/org/freedesktop/locale1'",
495 kbdctx_locale_props_changed_fn,
498 log_debug("idev-keyboard: cannot setup locale1 link: %s", strerror(-r));
502 return kbdctx_query_locale(kc);
505 static kbdctx *kbdctx_ref(kbdctx *kc) {
506 assert_return(kc, NULL);
507 assert_return(kc->ref > 0, NULL);
513 static kbdctx *kbdctx_unref(kbdctx *kc) {
517 assert_return(kc->ref > 0, NULL);
522 free(kc->last_x11_options);
523 free(kc->last_x11_variant);
524 free(kc->last_x11_layout);
525 free(kc->last_x11_model);
526 free(kc->locale_x11_options);
527 free(kc->locale_x11_variant);
528 free(kc->locale_x11_layout);
529 free(kc->locale_x11_model);
530 free(kc->locale_lang);
531 kc->slot_locale_get_all = sd_bus_slot_unref(kc->slot_locale_get_all);
532 kc->slot_locale_props_changed = sd_bus_slot_unref(kc->slot_locale_props_changed);
533 kc->kbdtbl = kbdtbl_unref(kc->kbdtbl);
534 kc->kbdmap = kbdmap_unref(kc->kbdmap);
535 xkb_context_unref(kc->xkb_context);
536 hashmap_remove_value(kc->context->data_map, KBDCTX_KEY, kc);
542 DEFINE_TRIVIAL_CLEANUP_FUNC(kbdctx*, kbdctx_unref);
544 static int kbdctx_new(kbdctx **out, idev_context *c) {
545 _cleanup_(kbdctx_unrefp) kbdctx *kc = NULL;
548 assert_return(out, -EINVAL);
549 assert_return(c, -EINVAL);
551 kc = new0(kbdctx, 1);
559 kc->xkb_context = xkb_context_new(0);
560 if (!kc->xkb_context)
561 return errno > 0 ? -errno : -EFAULT;
563 r = kbdctx_refresh_keymap(kc);
567 r = kbdctx_refresh_compose_table(kc, NULL);
572 r = kbdctx_setup_bus(kc);
577 r = hashmap_put(c->data_map, KBDCTX_KEY, kc);
586 static int get_kbdctx(idev_context *c, kbdctx **out) {
589 assert_return(c, -EINVAL);
590 assert_return(out, -EINVAL);
592 kc = hashmap_get(c->data_map, KBDCTX_KEY);
594 *out = kbdctx_ref(kc);
598 return kbdctx_new(out, c);
605 bool idev_is_keyboard(idev_device *d) {
606 return d && d->vtable == &keyboard_vtable;
609 idev_device *idev_find_keyboard(idev_session *s, const char *name) {
612 assert_return(s, NULL);
613 assert_return(name, NULL);
615 kname = strappenda("keyboard/", name);
616 return hashmap_get(s->device_map, kname);
619 static int keyboard_raise_data(idev_keyboard *k, idev_data *data) {
620 idev_device *d = &k->device;
623 r = idev_session_raise_device_data(d->session, d, data);
625 log_debug("idev-keyboard: %s/%s: error while raising data event: %s",
626 d->session->name, d->name, strerror(-r));
631 static void keyboard_arm(idev_keyboard *k, usec_t usecs) {
635 usecs += now(CLOCK_MONOTONIC);
636 r = sd_event_source_set_time(k->repeat_timer, usecs);
638 sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_ONESHOT);
640 sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_OFF);
644 static int keyboard_repeat_timer_fn(sd_event_source *source, uint64_t usec, void *userdata) {
645 idev_keyboard *k = userdata;
647 keyboard_arm(k, k->repeat_rate);
648 return keyboard_raise_data(k, &k->repdata);
651 int idev_keyboard_new(idev_device **out, idev_session *s, const char *name) {
652 _cleanup_(idev_device_freep) idev_device *d = NULL;
657 assert_return(out, -EINVAL);
658 assert_return(s, -EINVAL);
659 assert_return(name, -EINVAL);
661 k = new0(idev_keyboard, 1);
666 k->device = IDEV_DEVICE_INIT(&keyboard_vtable, s);
667 k->repeat_delay = 250 * USEC_PER_MSEC;
668 k->repeat_rate = 30 * USEC_PER_MSEC;
670 /* TODO: add key-repeat configuration */
672 r = get_kbdctx(s->context, &k->kbdctx);
676 r = keyboard_update_kbdmap(k);
680 r = keyboard_update_kbdtbl(k);
684 r = sd_event_add_time(s->context->event,
689 keyboard_repeat_timer_fn,
694 r = sd_event_source_set_enabled(k->repeat_timer, SD_EVENT_OFF);
698 kname = strappenda("keyboard/", name);
699 r = idev_device_add(d, kname);
709 static void keyboard_free(idev_device *d) {
710 idev_keyboard *k = keyboard_from_device(d);
712 xkb_compose_state_unref(k->xkb_compose);
713 xkb_state_unref(k->xkb_state);
714 free(k->repdata.keyboard.codepoints);
715 free(k->repdata.keyboard.keysyms);
716 free(k->evdata.keyboard.codepoints);
717 free(k->evdata.keyboard.keysyms);
718 k->repeat_timer = sd_event_source_unref(k->repeat_timer);
719 k->kbdtbl = kbdtbl_unref(k->kbdtbl);
720 k->kbdmap = kbdmap_unref(k->kbdmap);
721 k->kbdctx = kbdctx_unref(k->kbdctx);
725 static int8_t guess_ascii(struct xkb_state *state, uint32_t code, uint32_t n_syms, const uint32_t *syms) {
726 xkb_layout_index_t n_lo, lo;
727 xkb_level_index_t lv;
728 struct xkb_keymap *keymap;
729 const xkb_keysym_t *s;
732 if (n_syms == 1 && syms[0] < 128 && syms[0] > 0)
735 keymap = xkb_state_get_keymap(state);
736 n_lo = xkb_keymap_num_layouts_for_key(keymap, code + KBDXKB_SHIFT);
738 for (lo = 0; lo < n_lo; ++lo) {
739 lv = xkb_state_key_get_level(state, code + KBDXKB_SHIFT, lo);
740 num = xkb_keymap_key_get_syms_by_level(keymap, code + KBDXKB_SHIFT, lo, lv, &s);
741 if (num == 1 && s[0] < 128 && s[0] > 0)
748 static int keyboard_fill(idev_keyboard *k,
754 const uint32_t *keysyms) {
755 idev_data_keyboard *kev;
758 assert(dst == &k->evdata || dst == &k->repdata);
760 if (n_syms > k->n_syms) {
763 t = realloc(k->evdata.keyboard.keysyms, sizeof(*t) * n_syms);
766 k->evdata.keyboard.keysyms = t;
768 t = realloc(k->evdata.keyboard.codepoints, sizeof(*t) * n_syms);
771 k->evdata.keyboard.codepoints = t;
773 t = realloc(k->repdata.keyboard.keysyms, sizeof(*t) * n_syms);
776 k->repdata.keyboard.keysyms = t;
778 t = realloc(k->repdata.keyboard.codepoints, sizeof(*t) * n_syms);
781 k->repdata.keyboard.codepoints = t;
786 dst->type = IDEV_DATA_KEYBOARD;
787 dst->resync = resync;
788 kev = &dst->keyboard;
789 kev->ascii = guess_ascii(k->xkb_state, code, n_syms, keysyms);
793 kev->consumed_mods = 0;
794 kev->n_syms = n_syms;
795 memcpy(kev->keysyms, keysyms, sizeof(*keysyms) * n_syms);
797 for (i = 0; i < n_syms; ++i) {
798 kev->codepoints[i] = xkb_keysym_to_utf32(keysyms[i]);
799 if (!kev->codepoints[i])
800 kev->codepoints[i] = 0xffffffffUL;
803 for (i = 0; i < IDEV_KBDMOD_CNT; ++i) {
806 if (k->kbdmap->modmap[i] == XKB_MOD_INVALID)
809 r = xkb_state_mod_index_is_active(k->xkb_state, k->kbdmap->modmap[i], XKB_STATE_MODS_EFFECTIVE);
813 r = xkb_state_mod_index_is_consumed(k->xkb_state, code + KBDXKB_SHIFT, k->kbdmap->modmap[i]);
815 kev->consumed_mods |= 1 << i;
821 static void keyboard_repeat(idev_keyboard *k) {
822 idev_data *evdata = &k->evdata;
823 idev_data *repdata = &k->repdata;
824 idev_data_keyboard *evkbd = &evdata->keyboard;
825 idev_data_keyboard *repkbd = &repdata->keyboard;
826 const xkb_keysym_t *keysyms;
827 idev_device *d = &k->device;
831 if (evdata->resync) {
833 * We received a re-sync event. During re-sync, any number of
834 * key-events may have been lost and sync-events may be
835 * re-ordered. Always disable key-repeat for those events. Any
836 * following event will trigger it again.
839 k->repeating = false;
844 repeats = xkb_keymap_key_repeats(k->kbdmap->xkb_keymap, evkbd->keycode + KBDXKB_SHIFT);
846 if (k->repeating && repkbd->keycode == evkbd->keycode) {
848 * We received an event for the key we currently repeat. If it
849 * was released, stop key-repeat. Otherwise, ignore the event.
852 if (evkbd->value == KBDKEY_UP) {
853 k->repeating = false;
856 } else if (evkbd->value == KBDKEY_DOWN && repeats) {
858 * We received a key-down event for a key that repeats. The
859 * previous condition caught keys we already repeat, so we know
860 * this is a different key or no key-repeat is running. Start
865 num = xkb_state_key_get_syms(k->xkb_state, evkbd->keycode + KBDXKB_SHIFT, &keysyms);
867 r = errno > 0 ? errno : -EFAULT;
869 r = keyboard_fill(k, repdata, false, evkbd->keycode, KBDKEY_REPEAT, num, keysyms);
872 log_debug("idev-keyboard: %s/%s: cannot set key-repeat: %s",
873 d->session->name, d->name, strerror(-r));
874 k->repeating = false;
878 keyboard_arm(k, k->repeat_delay);
880 } else if (k->repeating && !repeats) {
882 * We received an event for a key that does not repeat, but we
883 * currently repeat a previously received key. The new key is
884 * usually a modifier, but might be any kind of key. In this
885 * case, we continue repeating the old key, but update the
886 * symbols according to the new state.
890 num = xkb_state_key_get_syms(k->xkb_state, repkbd->keycode + KBDXKB_SHIFT, &keysyms);
892 r = errno > 0 ? errno : -EFAULT;
894 r = keyboard_fill(k, repdata, false, repkbd->keycode, KBDKEY_REPEAT, num, keysyms);
897 log_debug("idev-keyboard: %s/%s: cannot update key-repeat: %s",
898 d->session->name, d->name, strerror(-r));
899 k->repeating = false;
905 static int keyboard_feed_evdev(idev_keyboard *k, idev_data *data) {
906 struct input_event *ev = &data->evdev.event;
907 enum xkb_state_component compch;
908 const xkb_keysym_t *keysyms;
909 idev_device *d = &k->device;
912 if (ev->type != EV_KEY || ev->value > KBDKEY_DOWN)
915 /* TODO: We should audit xkb-actions, whether they need @resync as
916 * flag. Most actions should just be executed, however, there might
917 * be actions that depend on modifier-orders. Those should be
920 num = xkb_state_key_get_syms(k->xkb_state, ev->code + KBDXKB_SHIFT, &keysyms);
921 compch = xkb_state_update_key(k->xkb_state, ev->code + KBDXKB_SHIFT, ev->value);
923 if (compch & XKB_STATE_LEDS) {
924 /* TODO: update LEDs */
932 r = keyboard_fill(k, &k->evdata, data->resync, ev->code, ev->value, num, keysyms);
937 return keyboard_raise_data(k, &k->evdata);
940 log_debug("idev-keyboard: %s/%s: cannot handle event: %s",
941 d->session->name, d->name, strerror(-r));
942 k->repeating = false;
947 static int keyboard_feed(idev_device *d, idev_data *data) {
948 idev_keyboard *k = keyboard_from_device(d);
950 switch (data->type) {
951 case IDEV_DATA_RESYNC:
953 * If the underlying device is re-synced, key-events might be
954 * sent re-ordered. Thus, we don't know which key was pressed
955 * last. Key-repeat might get confused, hence, disable it
956 * during re-syncs. The first following event will enable it
960 k->repeating = false;
963 case IDEV_DATA_EVDEV:
964 return keyboard_feed_evdev(k, data);
970 static int keyboard_update_kbdmap(idev_keyboard *k) {
971 idev_device *d = &k->device;
972 struct xkb_state *state;
978 km = k->kbdctx->kbdmap;
983 state = xkb_state_new(km->xkb_keymap);
985 r = errno > 0 ? -errno : -EFAULT;
989 kbdmap_unref(k->kbdmap);
990 k->kbdmap = kbdmap_ref(km);
991 xkb_state_unref(k->xkb_state);
992 k->xkb_state = state;
994 /* TODO: On state-change, we should trigger a resync so the whole
995 * event-state is flushed into the new xkb-state. libevdev currently
996 * does not support that, though. */
1001 log_debug("idev-keyboard: %s/%s: cannot adopt new keymap: %s",
1002 d->session->name, d->name, strerror(-r));
1006 static int keyboard_update_kbdtbl(idev_keyboard *k) {
1007 idev_device *d = &k->device;
1008 struct xkb_compose_state *compose = NULL;
1014 kt = k->kbdctx->kbdtbl;
1015 if (kt == k->kbdtbl)
1020 compose = xkb_compose_state_new(kt->xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS);
1022 r = errno > 0 ? -errno : -EFAULT;
1027 kbdtbl_unref(k->kbdtbl);
1028 k->kbdtbl = kbdtbl_ref(kt);
1029 xkb_compose_state_unref(k->xkb_compose);
1030 k->xkb_compose = compose;
1035 log_debug("idev-keyboard: %s/%s: cannot adopt new compose table: %s",
1036 d->session->name, d->name, strerror(-r));
1040 static const idev_device_vtable keyboard_vtable = {
1041 .free = keyboard_free,
1042 .feed = keyboard_feed,