diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 11bc1ff88..e234e5d44 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -266,9 +266,8 @@ struct _E_Comp_Wl_Data struct xkb_keymap *keymap; struct xkb_context *context; struct xkb_state *state; - int fd; - size_t size; - char *area; + char *map_string; + int map_size; } xkb; E_Comp_Wl_Extension_Data *extensions; @@ -447,6 +446,8 @@ e_policy_wl_aux_message_send(E_Client *ec, const char *val, Eina_List *options); +E_API void e_comp_wl_input_keymap_send(struct wl_resource *res); + # ifndef HAVE_WAYLAND_ONLY EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec); static inline E_Comp_X_Client_Data * diff --git a/src/bin/e_comp_wl_input.c b/src/bin/e_comp_wl_input.c index d5870feb0..1f4a9ede9 100644 --- a/src/bin/e_comp_wl_input.c +++ b/src/bin/e_comp_wl_input.c @@ -227,8 +227,7 @@ _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *r wl_keyboard_send_repeat_info(res, e_config->keyboard.repeat_rate, e_config->keyboard.repeat_delay); /* send current keymap */ - wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - e_comp_wl->xkb.fd, e_comp_wl->xkb.size); + e_comp_wl_input_keymap_send(res); /* if the client owns the focused surface, we need to send an enter */ focused = e_client_focused_get(); @@ -317,13 +316,14 @@ _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, wl_seat_send_name(res, e_comp_wl->seat.name); } -static int -_e_comp_wl_input_keymap_fd_get(off_t size) +int +_e_comp_wl_input_keymap_fd_get(void) { int fd = 0, blen = 0, len = 0; const char *path; char tmp[PATH_MAX]; long flags; + void *mm; blen = sizeof(tmp) - 1; @@ -354,13 +354,25 @@ _e_comp_wl_input_keymap_fd_get(off_t size) return -1; } - if (ftruncate(fd, size) < 0) + if (ftruncate(fd, e_comp_wl->xkb.map_size) < 0) { close(fd); return -1; } unlink(tmp); + mm = mmap(NULL, e_comp_wl->xkb.map_size, (PROT_READ | PROT_WRITE), + MAP_SHARED, fd, 0); + if (mm == MAP_FAILED) + { + ERR("Failed to mmap keymap area: %m"); + close(fd); + return -1; + } + + memcpy(mm, e_comp_wl->xkb.map_string, e_comp_wl->xkb.map_size); + munmap(mm, e_comp_wl->xkb.map_size); + return fd; } @@ -389,6 +401,21 @@ _e_comp_wl_input_state_update(void) 0, 0); } +void +e_comp_wl_input_keymap_send(struct wl_resource *res) +{ + int fd; + + fd = _e_comp_wl_input_keymap_fd_get(); + if (fd == -1) + return; + + wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + fd, e_comp_wl->xkb.map_size); + + close(fd); +} + static void nested_keymap_update(void) { @@ -396,13 +423,12 @@ nested_keymap_update(void) Evas_Object *obj; EINA_LIST_FOREACH(e_comp_wl->efl_wls, l, obj) - efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.fd, e_comp_wl->xkb.size, &e_comp_wl->kbd.keys); + efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.map_string, &e_comp_wl->kbd.keys); } static void _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap) { - char *tmp; struct wl_resource *res; Eina_List *l; @@ -410,11 +436,9 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap) if (e_comp_wl->xkb.keymap) xkb_map_unref(e_comp_wl->xkb.keymap); - /* unmap any existing keyboard area */ - if (e_comp_wl->xkb.area) - munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size); - if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd); - + /* free any existing keyboard map string */ + free(e_comp_wl->xkb.map_string); + e_comp_wl->xkb.map_string = NULL; /* increment keymap reference */ e_comp_wl->xkb.keymap = keymap; @@ -422,39 +446,17 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap) /* update the state */ _e_comp_wl_input_state_update(); - if (!(tmp = xkb_map_get_as_string(keymap))) + if (!(e_comp_wl->xkb.map_string = xkb_map_get_as_string(keymap))) { ERR("Could not get keymap string"); return; } - e_comp_wl->xkb.size = strlen(tmp) + 1; - e_comp_wl->xkb.fd = - _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size); - if (e_comp_wl->xkb.fd < 0) - { - ERR("Could not create keymap file"); - free(tmp); - return; - } - - e_comp_wl->xkb.area = - mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE), - MAP_SHARED, e_comp_wl->xkb.fd, 0); - if (e_comp_wl->xkb.area == MAP_FAILED) - { - ERR("Failed to mmap keymap area: %m"); - free(tmp); - return; - } - - strcpy(e_comp_wl->xkb.area, tmp); - free(tmp); + e_comp_wl->xkb.map_size = strlen(e_comp_wl->xkb.map_string) + 1; /* send updated keymap */ EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res) - wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - e_comp_wl->xkb.fd, e_comp_wl->xkb.size); + e_comp_wl_input_keymap_send(res); /* update modifiers */ e_comp_wl_input_keyboard_modifiers_update(); @@ -468,8 +470,6 @@ e_comp_wl_input_init(void) if (!e_comp_wl->seat.name) e_comp_wl->seat.name = "seat0"; - e_comp_wl->xkb.fd = -1; - /* create the global resource for input seat */ e_comp_wl->seat.global = wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4, @@ -524,10 +524,8 @@ e_comp_wl_input_shutdown(void) /* destroy e_comp_wl->kbd.keys array */ wl_array_release(&e_comp_wl->kbd.keys); - /* unmap any existing keyboard area */ - if (e_comp_wl->xkb.area) - munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size); - if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd); + /* free the string copy of the keyboard map */ + free(e_comp_wl->xkb.map_string); /* unreference any existing keyboard state */ if (e_comp_wl->xkb.state) diff --git a/src/bin/e_comp_wl_input.h b/src/bin/e_comp_wl_input.h index e726aa0c1..2989d5b75 100644 --- a/src/bin/e_comp_wl_input.h +++ b/src/bin/e_comp_wl_input.h @@ -36,5 +36,8 @@ E_API void e_comp_wl_input_keymap_index_set(xkb_layout_index_t index); E_API void e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout, const char *variant, const char *options); E_API void e_comp_wl_input_keyboard_event_generate(const char *key, int mods, Eina_Bool up); + +EINTERN int _e_comp_wl_input_keymap_fd_get(void); + # endif #endif diff --git a/src/bin/e_gadget_runner.c b/src/bin/e_gadget_runner.c index cec75af4d..1d98f133c 100644 --- a/src/bin/e_gadget_runner.c +++ b/src/bin/e_gadget_runner.c @@ -786,7 +786,7 @@ popup_added(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) static void seat_added(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { - efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.fd, e_comp_wl->xkb.size, &e_comp_wl->kbd.keys); + efl_wl_seat_keymap_set(obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.map_string, &e_comp_wl->kbd.keys); efl_wl_seat_key_repeat_set(obj, NULL, e_config->keyboard.repeat_rate, e_config->keyboard.repeat_delay); } @@ -875,7 +875,7 @@ gadget_create(Evas_Object *parent, Config_Item *ci, int *id, E_Gadget_Site_Orien inst->obj = efl_wl_add(e_comp->evas); if (e_comp->comp_type == E_PIXMAP_TYPE_WL) { - efl_wl_seat_keymap_set(inst->obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.fd, e_comp_wl->xkb.size, &e_comp_wl->kbd.keys); + efl_wl_seat_keymap_set(inst->obj, NULL, e_comp_wl->xkb.state, e_comp_wl->xkb.map_string, &e_comp_wl->kbd.keys); efl_wl_seat_key_repeat_set(inst->obj, NULL, e_config->keyboard.repeat_rate, e_config->keyboard.repeat_delay); e_comp_wl->efl_wls = eina_list_append(e_comp_wl->efl_wls, inst->obj); } diff --git a/src/modules/wl_text_input/e_mod_main.c b/src/modules/wl_text_input/e_mod_main.c index 90d550a97..324f43173 100644 --- a/src/modules/wl_text_input/e_mod_main.c +++ b/src/modules/wl_text_input/e_mod_main.c @@ -324,9 +324,7 @@ _e_text_input_method_context_cb_keyboard_grab(struct wl_client *client, struct w wl_resource_set_implementation(new_resource, NULL, context, _e_text_input_method_context_keyboard_unbind); - wl_keyboard_send_keymap(new_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - e_comp_wl->xkb.fd, - e_comp_wl->xkb.size); + e_comp_wl_input_keymap_send(new_resource); context->kbd.resource = new_resource;