diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 3e207523..ae279541 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -50,7 +50,7 @@ struct wlr_keyboard_modifiers { struct wlr_keyboard { const struct wlr_keyboard_impl *impl; - int keymap_fd; + char *keymap_string; size_t keymap_size; struct xkb_keymap *keymap; struct xkb_state *xkb_state; diff --git a/types/seat/wlr_seat_keyboard.c b/types/seat/wlr_seat_keyboard.c index e8ea300e..0400db14 100644 --- a/types/seat/wlr_seat_keyboard.c +++ b/types/seat/wlr_seat_keyboard.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include @@ -10,6 +12,7 @@ #include #include "types/wlr_seat.h" #include "util/signal.h" +#include "util/os-compatibility.h" static void default_keyboard_enter(struct wlr_seat_keyboard_grab *grab, struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes, @@ -338,9 +341,28 @@ static void seat_client_send_keymap(struct wlr_seat_client *client, continue; } + int keymap_fd = os_create_anonymous_file(keyboard->keymap_size); + if (keymap_fd < 0) { + wlr_log(WLR_ERROR, "creating a keymap file for %zu bytes failed", keyboard->keymap_size); + continue; + } + + void *ptr = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE, + MAP_SHARED, keymap_fd, 0); + if (ptr == MAP_FAILED) { + wlr_log(WLR_ERROR, "failed to mmap() %zu bytes", keyboard->keymap_size); + close(keymap_fd); + continue; + } + + strcpy(ptr, keyboard->keymap_string); + munmap(ptr, keyboard->keymap_size); + wl_keyboard_send_keymap(resource, - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keyboard->keymap_fd, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd, keyboard->keymap_size); + + close(keymap_fd); } } diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 3a4f5f67..89c7ca50 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -2,16 +2,12 @@ #include #include #include -#include -#include #include #include #include #include #include "util/signal.h" -int os_create_anonymous_file(off_t size); - static void keyboard_led_update(struct wlr_keyboard *keyboard) { if (keyboard->xkb_state == NULL) { return; @@ -126,7 +122,6 @@ void wlr_keyboard_init(struct wlr_keyboard *kb, wl_signal_init(&kb->events.modifiers); wl_signal_init(&kb->events.keymap); wl_signal_init(&kb->events.repeat_info); - kb->keymap_fd = -1; // Sane defaults kb->repeat_info.rate = 25; @@ -139,9 +134,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *kb) { } xkb_state_unref(kb->xkb_state); xkb_keymap_unref(kb->keymap); - if (kb->keymap_fd >= 0) { - close(kb->keymap_fd); - } + free(kb->keymap_string); if (kb->impl && kb->impl->destroy) { kb->impl->destroy(kb); } else { @@ -158,8 +151,6 @@ void wlr_keyboard_led_update(struct wlr_keyboard *kb, uint32_t leds) { void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap) { - char *keymap_str = NULL; - xkb_keymap_unref(kb->keymap); kb->keymap = xkb_keymap_ref(keymap); @@ -194,26 +185,15 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, kb->mod_indexes[i] = xkb_map_mod_get_index(kb->keymap, mod_names[i]); } - keymap_str = xkb_keymap_get_as_string(kb->keymap, + char *tmp_keymap_string = xkb_keymap_get_as_string(kb->keymap, XKB_KEYMAP_FORMAT_TEXT_V1); - kb->keymap_size = strlen(keymap_str) + 1; - if (kb->keymap_fd >= 0) { - close(kb->keymap_fd); - } - kb->keymap_fd = os_create_anonymous_file(kb->keymap_size); - if (kb->keymap_fd < 0) { - wlr_log(WLR_ERROR, "creating a keymap file for %zu bytes failed", kb->keymap_size); + if (tmp_keymap_string == NULL) { + wlr_log(WLR_ERROR, "Failed to get string version of keymap"); goto err; } - void *ptr = mmap(NULL, kb->keymap_size, - PROT_READ | PROT_WRITE, MAP_SHARED, kb->keymap_fd, 0); - if (ptr == (void*)-1) { - wlr_log(WLR_ERROR, "failed to mmap() %zu bytes", kb->keymap_size); - goto err; - } - strcpy(ptr, keymap_str); - free(keymap_str); - munmap(ptr, kb->keymap_size); + free(kb->keymap_string); + kb->keymap_string = tmp_keymap_string; + kb->keymap_size = strlen(kb->keymap_string) + 1; for (size_t i = 0; i < kb->num_keycodes; ++i) { xkb_keycode_t keycode = kb->keycodes[i] + 8; @@ -230,11 +210,8 @@ err: kb->xkb_state = NULL; xkb_keymap_unref(keymap); kb->keymap = NULL; - if (kb->keymap_fd >= 0) { - close(kb->keymap_fd); - kb->keymap_fd = -1; - } - free(keymap_str); + free(kb->keymap_string); + kb->keymap_string = NULL; } void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate,