diff options
author | Simon Ser <contact@emersion.fr> | 2021-08-07 13:48:04 +0200 |
---|---|---|
committer | Kenny Levinsen <kl@kl.wtf> | 2021-09-05 22:06:25 +0200 |
commit | 62924cc52385357f9c865379ee9883107d0f7d63 (patch) | |
tree | 4820a4b3724a3826474b2c5a753bd1e70a02df94 | |
parent | 55ca93469cfaa5ca1d9b6e4c164b23ef55763eb5 (diff) |
keyboard: add wlr_keyboard.keymap_fd
This exposes a read-only FD with the keymap.
-rw-r--r-- | include/wlr/types/wlr_keyboard.h | 1 | ||||
-rw-r--r-- | types/wlr_keyboard.c | 34 |
2 files changed, 34 insertions, 1 deletions
diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index b5111462..ea16c432 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -53,6 +53,7 @@ struct wlr_keyboard { char *keymap_string; size_t keymap_size; + int keymap_fd; struct xkb_keymap *keymap; struct xkb_state *xkb_state; xkb_led_index_t led_indexes[WLR_LED_COUNT]; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index fe94330f..c54e33c6 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -1,12 +1,15 @@ -#include "util/array.h" #include <assert.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> +#include <unistd.h> #include <wayland-server-core.h> #include <wlr/interfaces/wlr_keyboard.h> #include <wlr/types/wlr_keyboard.h> #include <wlr/util/log.h> #include "types/wlr_keyboard.h" +#include "util/array.h" +#include "util/shm.h" #include "util/signal.h" void keyboard_led_update(struct wlr_keyboard *keyboard) { @@ -119,6 +122,8 @@ void wlr_keyboard_init(struct wlr_keyboard *kb, wl_signal_init(&kb->events.repeat_info); wl_signal_init(&kb->events.destroy); + kb->keymap_fd = -1; + // Sane defaults kb->repeat_info.rate = 25; kb->repeat_info.delay = 600; @@ -132,6 +137,9 @@ void wlr_keyboard_destroy(struct wlr_keyboard *kb) { xkb_state_unref(kb->xkb_state); xkb_keymap_unref(kb->keymap); free(kb->keymap_string); + if (kb->keymap_fd >= 0) { + close(kb->keymap_fd); + } if (kb->impl && kb->impl->destroy) { kb->impl->destroy(kb); } else { @@ -192,6 +200,30 @@ bool wlr_keyboard_set_keymap(struct wlr_keyboard *kb, kb->keymap_string = tmp_keymap_string; kb->keymap_size = strlen(kb->keymap_string) + 1; + int rw_fd = -1, ro_fd = -1; + if (!allocate_shm_file_pair(kb->keymap_size, &rw_fd, &ro_fd)) { + wlr_log(WLR_ERROR, "Failed to allocate shm file for keymap"); + goto err; + } + + void *dst = mmap(NULL, kb->keymap_size, PROT_READ | PROT_WRITE, + MAP_SHARED, rw_fd, 0); + if (dst == MAP_FAILED) { + wlr_log_errno(WLR_ERROR, "mmap failed"); + close(rw_fd); + close(ro_fd); + goto err; + } + + memcpy(dst, kb->keymap_string, kb->keymap_size); + munmap(dst, kb->keymap_size); + close(rw_fd); + + if (kb->keymap_fd >= 0) { + close(kb->keymap_fd); + } + kb->keymap_fd = ro_fd; + for (size_t i = 0; i < kb->num_keycodes; ++i) { xkb_keycode_t keycode = kb->keycodes[i] + 8; xkb_state_update_key(kb->xkb_state, keycode, XKB_KEY_DOWN); |