forked from enlightenment/enlightenment
Send unique keymap fds to clients
Summary: Prevent wayland clients from being able to destroy the compositor's singleton keymap by making individual copies for each client. Reviewers: zmike, devilhorns Reviewed By: zmike, devilhorns Subscribers: cedric Tags: #enlightenment-git Differential Revision: https://phab.enlightenment.org/D6861
This commit is contained in:
parent
0fd5552c3b
commit
a037001031
|
@ -266,9 +266,8 @@ struct _E_Comp_Wl_Data
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
struct xkb_context *context;
|
struct xkb_context *context;
|
||||||
struct xkb_state *state;
|
struct xkb_state *state;
|
||||||
int fd;
|
char *map_string;
|
||||||
size_t size;
|
int map_size;
|
||||||
char *area;
|
|
||||||
} xkb;
|
} xkb;
|
||||||
|
|
||||||
E_Comp_Wl_Extension_Data *extensions;
|
E_Comp_Wl_Extension_Data *extensions;
|
||||||
|
@ -447,6 +446,8 @@ e_policy_wl_aux_message_send(E_Client *ec,
|
||||||
const char *val,
|
const char *val,
|
||||||
Eina_List *options);
|
Eina_List *options);
|
||||||
|
|
||||||
|
E_API void e_comp_wl_input_keymap_send(struct wl_resource *res);
|
||||||
|
|
||||||
# ifndef HAVE_WAYLAND_ONLY
|
# ifndef HAVE_WAYLAND_ONLY
|
||||||
EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec);
|
EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec);
|
||||||
static inline E_Comp_X_Client_Data *
|
static inline E_Comp_X_Client_Data *
|
||||||
|
|
|
@ -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);
|
wl_keyboard_send_repeat_info(res, e_config->keyboard.repeat_rate, e_config->keyboard.repeat_delay);
|
||||||
|
|
||||||
/* send current keymap */
|
/* send current keymap */
|
||||||
wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
e_comp_wl_input_keymap_send(res);
|
||||||
e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
|
|
||||||
|
|
||||||
/* if the client owns the focused surface, we need to send an enter */
|
/* if the client owns the focused surface, we need to send an enter */
|
||||||
focused = e_client_focused_get();
|
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);
|
wl_seat_send_name(res, e_comp_wl->seat.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
_e_comp_wl_input_keymap_fd_get(off_t size)
|
_e_comp_wl_input_keymap_fd_get(void)
|
||||||
{
|
{
|
||||||
int fd = 0, blen = 0, len = 0;
|
int fd = 0, blen = 0, len = 0;
|
||||||
const char *path;
|
const char *path;
|
||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
long flags;
|
long flags;
|
||||||
|
void *mm;
|
||||||
|
|
||||||
blen = sizeof(tmp) - 1;
|
blen = sizeof(tmp) - 1;
|
||||||
|
|
||||||
|
@ -354,13 +354,25 @@ _e_comp_wl_input_keymap_fd_get(off_t size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftruncate(fd, size) < 0)
|
if (ftruncate(fd, e_comp_wl->xkb.map_size) < 0)
|
||||||
{
|
{
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink(tmp);
|
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;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,6 +401,21 @@ _e_comp_wl_input_state_update(void)
|
||||||
0, 0);
|
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
|
static void
|
||||||
nested_keymap_update(void)
|
nested_keymap_update(void)
|
||||||
{
|
{
|
||||||
|
@ -396,13 +423,12 @@ nested_keymap_update(void)
|
||||||
Evas_Object *obj;
|
Evas_Object *obj;
|
||||||
|
|
||||||
EINA_LIST_FOREACH(e_comp_wl->efl_wls, l, 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
|
static void
|
||||||
_e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
|
_e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
|
||||||
{
|
{
|
||||||
char *tmp;
|
|
||||||
struct wl_resource *res;
|
struct wl_resource *res;
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
|
|
||||||
|
@ -410,11 +436,9 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
|
||||||
if (e_comp_wl->xkb.keymap)
|
if (e_comp_wl->xkb.keymap)
|
||||||
xkb_map_unref(e_comp_wl->xkb.keymap);
|
xkb_map_unref(e_comp_wl->xkb.keymap);
|
||||||
|
|
||||||
/* unmap any existing keyboard area */
|
/* free any existing keyboard map string */
|
||||||
if (e_comp_wl->xkb.area)
|
free(e_comp_wl->xkb.map_string);
|
||||||
munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
|
e_comp_wl->xkb.map_string = NULL;
|
||||||
if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
|
|
||||||
|
|
||||||
|
|
||||||
/* increment keymap reference */
|
/* increment keymap reference */
|
||||||
e_comp_wl->xkb.keymap = keymap;
|
e_comp_wl->xkb.keymap = keymap;
|
||||||
|
@ -422,39 +446,17 @@ _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap)
|
||||||
/* update the state */
|
/* update the state */
|
||||||
_e_comp_wl_input_state_update();
|
_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");
|
ERR("Could not get keymap string");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e_comp_wl->xkb.size = strlen(tmp) + 1;
|
e_comp_wl->xkb.map_size = strlen(e_comp_wl->xkb.map_string) + 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);
|
|
||||||
|
|
||||||
/* send updated keymap */
|
/* send updated keymap */
|
||||||
EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
|
EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
|
||||||
wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
e_comp_wl_input_keymap_send(res);
|
||||||
e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
|
|
||||||
|
|
||||||
/* update modifiers */
|
/* update modifiers */
|
||||||
e_comp_wl_input_keyboard_modifiers_update();
|
e_comp_wl_input_keyboard_modifiers_update();
|
||||||
|
@ -468,8 +470,6 @@ e_comp_wl_input_init(void)
|
||||||
if (!e_comp_wl->seat.name)
|
if (!e_comp_wl->seat.name)
|
||||||
e_comp_wl->seat.name = "seat0";
|
e_comp_wl->seat.name = "seat0";
|
||||||
|
|
||||||
e_comp_wl->xkb.fd = -1;
|
|
||||||
|
|
||||||
/* create the global resource for input seat */
|
/* create the global resource for input seat */
|
||||||
e_comp_wl->seat.global =
|
e_comp_wl->seat.global =
|
||||||
wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
|
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 */
|
/* destroy e_comp_wl->kbd.keys array */
|
||||||
wl_array_release(&e_comp_wl->kbd.keys);
|
wl_array_release(&e_comp_wl->kbd.keys);
|
||||||
|
|
||||||
/* unmap any existing keyboard area */
|
/* free the string copy of the keyboard map */
|
||||||
if (e_comp_wl->xkb.area)
|
free(e_comp_wl->xkb.map_string);
|
||||||
munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
|
|
||||||
if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
|
|
||||||
|
|
||||||
/* unreference any existing keyboard state */
|
/* unreference any existing keyboard state */
|
||||||
if (e_comp_wl->xkb.state)
|
if (e_comp_wl->xkb.state)
|
||||||
|
|
|
@ -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_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);
|
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
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -786,7 +786,7 @@ popup_added(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
|
||||||
static void
|
static void
|
||||||
seat_added(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
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);
|
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);
|
inst->obj = efl_wl_add(e_comp->evas);
|
||||||
if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
|
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);
|
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);
|
e_comp_wl->efl_wls = eina_list_append(e_comp_wl->efl_wls, inst->obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
wl_resource_set_implementation(new_resource, NULL, context,
|
||||||
_e_text_input_method_context_keyboard_unbind);
|
_e_text_input_method_context_keyboard_unbind);
|
||||||
|
|
||||||
wl_keyboard_send_keymap(new_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
e_comp_wl_input_keymap_send(new_resource);
|
||||||
e_comp_wl->xkb.fd,
|
|
||||||
e_comp_wl->xkb.size);
|
|
||||||
|
|
||||||
context->kbd.resource = new_resource;
|
context->kbd.resource = new_resource;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue