1 #include "e_comp_wl_input_intern.h"
2 #include "e_utils_intern.h"
3 #include "e_comp_wl_intern.h"
4 #include "e_input_intern.h"
5 #include "e_input_device_intern.h"
6 #include "e_input_backend_intern.h"
7 #include "e_pointer_intern.h"
8 #include "e_comp_object_intern.h"
9 #include "e_comp_input_intern.h"
10 #include "e_policy_intern.h"
11 #include "e_keyrouter_intern.h"
12 #include "e_input_thread_client_intern.h"
18 #include <relative-pointer-unstable-v1-server-protocol.h>
19 #include <pointer-constraints-unstable-v1-server-protocol.h>
21 #define EXECUTIVE_MODE_ENABLED
23 typedef struct _E_Comp_Wl_Pointer_Constraint E_Comp_Wl_Pointer_Constraint;
25 typedef enum _E_Comp_Wl_Pointer_Constraint_Type
27 E_COMP_WL_POINTER_CONSTRAINT_TYPE_NONE = 0,
28 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK = 1,
29 E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE = 2,
30 } E_Comp_Wl_Pointer_Constraint_Type;
32 struct _E_Comp_Wl_Pointer_Constraint
37 struct wl_resource *surface;
38 struct wl_resource *resource;
39 struct wl_resource *pointer;
42 E_Comp_Wl_Pointer_Constraint_Type type;
45 pixman_region32_t region;
46 pixman_region32_t region_pending;
47 Eina_Bool is_region_pending;
48 Eina_Bool has_region_set;
52 wl_fixed_t hint_x_pending;
53 wl_fixed_t hint_y_pending;
54 Eina_Bool is_hint_pending;
55 Eina_Bool has_hint_set;
57 struct wl_listener pointer_destroy_listener;
58 struct wl_listener surface_unmap_listener;
59 struct wl_listener surface_commit_listener;
60 struct wl_listener surface_mousein_listener;
61 struct wl_listener surface_mouseout_listener;
64 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
65 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
66 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
67 static Eina_Bool use_cache_keymap = EINA_FALSE;
69 static E_Comp_Wl_Hook *_surface_commit_hook = NULL;
71 /* default XKB values from environment variables */
72 static char *_env_e_default_xkb_rules = NULL;
73 static char *_env_e_default_xkb_model = NULL;
74 static char *_env_e_default_xkb_layout = NULL;
75 static char *_env_e_default_xkb_variant = NULL;
76 static char *_env_e_default_xkb_opts = NULL;
79 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
84 _e_comp_wl_input_update_seat_caps(struct wl_client *wc)
87 struct wl_resource *res;
88 enum wl_seat_capability caps = 0;
90 if (e_comp_wl->ptr.enabled)
91 caps |= WL_SEAT_CAPABILITY_POINTER;
92 if (e_comp_input_key->kbd.enabled)
93 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
94 if (e_comp_wl->touch.enabled)
95 caps |= WL_SEAT_CAPABILITY_TOUCH;
97 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
99 /* if a wc is null, send seat capability to all wl_seat resources */
100 if (wc && (wl_resource_get_client(res) != wc)) continue;
101 wl_seat_send_capabilities(res, caps);
106 _e_comp_wl_input_pointer_map(struct wl_resource *resource)
110 struct wl_client *wc;
112 if (!(ec = e_client_from_surface_resource(resource))) return;
113 if (e_object_is_del(E_OBJECT(ec))) return;
115 //if cursor ec have external content
116 e_comp_object_content_unset(ec->frame);
118 if (!e_comp_wl->ptr.ec || !e_comp_wl->ptr.ec->comp_data) return;
119 struct wl_resource *surface = e_comp_wl_client_surface_get(e_comp_wl->ptr.ec);
120 if (!surface) return;
122 wc = wl_resource_get_client(resource);
123 if (wc != wl_resource_get_client(surface)) return;
124 if (!e_comp_wl->ptr.ec->pointer_enter_sent) return;
126 if ((ptr = e_comp->pointer))
127 e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
131 _e_comp_wl_input_pointer_configure(struct wl_resource *resource,
132 Evas_Coord x, Evas_Coord y,
133 Evas_Coord w, Evas_Coord h)
137 if (!(ec = e_client_from_surface_resource(resource))) return;
138 if (e_object_is_del(E_OBJECT(ec))) return;
140 e_client_util_resize_without_frame(ec, w, h);
144 _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
146 wl_resource_destroy(resource);
150 _e_comp_wl_input_thread_cursor_set(void *data)
152 E_Input_Thread_Request_EClient_Data *ec_data = data;
153 EINA_SAFETY_ON_NULL_RETURN(ec_data);
155 INF("[input thread|%s] ec(%p), layer_block(%d), is_cursor(%d)\n", __func__, ec_data->ec, ec_data->layer_block, ec_data->is_cursor);
156 e_input_thread_client_layer_block_set(e_input_thread_client_get(ec_data->ec), ec_data->layer_block);
157 e_input_thread_client_is_cursor_set(e_input_thread_client_get(ec_data->ec), ec_data->is_cursor);
161 _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
164 Eina_Bool got_mouse = EINA_FALSE;
165 struct wl_resource *surface;
167 E_Input_Thread_Request_EClient_Data ec_data;
168 memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
172 if (e_object_is_del(E_OBJECT(ec))) continue;
173 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
174 surface = e_comp_wl_client_surface_get(ec);
175 if (!surface) continue;
176 if (client != wl_resource_get_client(surface)) continue;
177 if (ec->mouse.in && ec->pointer_enter_sent)
179 got_mouse = EINA_TRUE;
185 ELOGF("COMP", "Cursor Set. got_mouse: false", NULL);
188 if (!surface_resource || e_policy_client_is_waydroid(ec))
190 e_pointer_object_set(e_comp->pointer, NULL, x, y);
191 ec->has_cursor_unset = EINA_TRUE;
192 ELOGF("COMP", "Cursor Set. has_cursor_unset:TRUE", ec);
196 ec->has_cursor_unset = EINA_FALSE;
198 ec = e_client_from_surface_resource(surface_resource);
206 ec->lock_focus_out = ec->layer_block = ec->visible = 1;
207 if (!e_config->show_cursor)
209 ELOGF("COMP", "Cursor Set. show_cursor: false", ec);
212 e_client_icccm_title_set(ec, "Cursor");
213 e_client_window_role_set(ec, "wl_pointer-cursor");
214 evas_object_pass_events_set(ec->frame, 1);
215 /* wl_pointer-cursor surface is always alpha window */
216 ec->argb = EINA_TRUE;
217 ELOGF("COMP", "Cursor Set. argb:%d", ec, ec->argb);
218 e_comp_object_alpha_set(ec->frame, EINA_TRUE);
221 /* Set fuctions to prevent unwanted handling by shell */
222 ec->comp_data->shell.surface = surface_resource;
223 ec->comp_data->shell.configure = _e_comp_wl_input_pointer_configure;
224 ec->comp_data->shell.map = _e_comp_wl_input_pointer_map;
226 e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
227 ec->is_cursor = EINA_TRUE;
230 ec_data.layer_block = ec->layer_block;
231 ec_data.is_cursor = ec->is_cursor;
232 INF("[%s] ec(%p), layer_block(%d), is_cursor(%d)\n", __func__, ec, ec->layer_block, ec->is_cursor);
233 e_input_backend_thread_safe_call(_e_comp_wl_input_thread_cursor_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
236 /* Set a pointer_object after wl_surface commit
237 * if cursor image is changed,
238 * changed information is sent using attach / damage
239 * So in commit, we can know real current cursor image.
242 /* ignore cursor changes during resize/move I guess */
243 if (e_client_action_get()) return;
244 e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
248 e_comp->pointer->hot.x = x;
249 e_comp->pointer->hot.y = y;
250 if (e_config->show_cursor)
251 ec->visible = EINA_TRUE;
255 static const struct wl_pointer_interface _e_pointer_interface =
257 _e_comp_wl_input_pointer_cb_cursor_set,
258 _e_comp_wl_input_cb_resource_destroy
261 static const struct wl_keyboard_interface _e_keyboard_interface =
263 _e_comp_wl_input_cb_resource_destroy
266 static const struct wl_touch_interface _e_touch_interface =
268 _e_comp_wl_input_cb_resource_destroy
272 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
274 e_comp_wl->ptr.resources =
275 eina_list_remove(e_comp_wl->ptr.resources, resource);
277 wl_signal_emit(&e_comp_wl->ptr_constraints.pointer_destroy_signal, resource);
281 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
283 struct wl_resource *res;
284 struct wl_client *ptr_client = NULL;
285 E_Comp_Wl_Client_Data *cdata = NULL;
287 /* try to create pointer resource */
288 res = wl_resource_create(client, &wl_pointer_interface,
289 wl_resource_get_version(resource), id);
292 ERR("Could not create pointer on seat %s: %m",
293 e_comp_wl->seat.name);
294 wl_client_post_no_memory(client);
298 e_comp_wl->ptr.resources =
299 eina_list_append(e_comp_wl->ptr.resources, res);
300 wl_resource_set_implementation(res, &_e_pointer_interface,
301 e_comp->wl_comp_data,
302 _e_comp_wl_input_cb_pointer_unbind);
304 if ((e_comp_wl->ptr.num_devices == 1) && e_comp_wl->ptr.ec && !e_comp_wl->ptr.ec->pointer_enter_sent && !e_config->use_cursor_timer)
306 cdata = (E_Comp_Wl_Client_Data*)e_comp_wl->ptr.ec->comp_data;
307 if (cdata && cdata->wl_surface)
308 ptr_client = wl_resource_get_client(cdata->wl_surface);
310 if (ptr_client == client)
312 Evas_Device *last_ptr = NULL, *dev;
314 const char *name, *desc;
316 list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
317 EINA_LIST_FOREACH(list, l, dev)
319 name = evas_device_name_get(dev);
320 desc = evas_device_description_get(dev);
321 if (!name || !desc) continue;
323 if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
324 (!strncmp(desc, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
325 (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
332 e_comp_wl_mouse_in_renew(e_comp_wl->ptr.ec, 0, wl_fixed_to_int(e_comp_wl->ptr.x), wl_fixed_to_int(e_comp_wl->ptr.y), NULL, NULL, NULL, ecore_time_get(), EVAS_EVENT_FLAG_NONE, last_ptr, NULL);
338 _e_comp_wl_input_thread_cb_keyboard_unbind(void *data)
341 struct wl_resource *res;
342 struct wl_resource *resource = NULL;
344 EINA_SAFETY_ON_NULL_RETURN(data);
346 resource = *(struct wl_resource **)data;
348 e_comp_input_key->kbd.resources =
349 eina_list_remove(e_comp_input_key->kbd.resources, resource);
351 EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
353 e_comp_input_key->kbd.focused =
354 eina_list_remove_list(e_comp_input_key->kbd.focused, l);
358 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
360 INF("[keyboard unbind] resource(%p)\n", resource);
361 _e_comp_wl_input_thread_cb_keyboard_unbind(&resource);
365 e_comp_wl_input_keyboard_enter_send(struct wl_resource *surface)
367 struct wl_resource *res;
370 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
371 xkb_layout_index_t mod_group;
373 if (!e_comp_input_key->kbd.focused)
378 e_comp_wl_input_keyboard_modifiers_serialize();
380 serial = wl_display_next_serial(e_comp_wl->wl.disp);
382 mod_depressed = atomic_load(&e_comp_input_key->kbd.mod_depressed);
383 mod_latched = atomic_load(&e_comp_input_key->kbd.mod_latched);
384 mod_locked = atomic_load(&e_comp_input_key->kbd.mod_locked);
386 mod_group = atomic_load(&e_comp_input_key->kbd.mod_group);
388 EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
390 wl_keyboard_send_enter(res, serial, surface,
391 &e_comp_input_key->kbd.keys);
393 wl_keyboard_send_modifiers(res, serial,
402 _e_comp_wl_input_thread_cb_keyboard_get(void *data)
405 struct wl_resource *res;
407 E_Input_Thread_Request_Keyboard_Get_Data *keyboard_get_data = data;
408 EINA_SAFETY_ON_NULL_RETURN(keyboard_get_data);
410 INF("[input thread|%s] resource(%p), client(%p)\n", __func__, keyboard_get_data->resource, keyboard_get_data->client);
412 res = keyboard_get_data->resource;
414 e_comp_input_key->kbd.resources =
415 eina_list_append(e_comp_input_key->kbd.resources, res);
417 /* send current repeat_info */
418 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
420 wl_keyboard_send_repeat_info(res, e_comp_input_key->kbd.repeat_rate, e_comp_input_key->kbd.repeat_delay);
423 /* if the client owns the focused surface, we need to send an enter */
424 focused = e_client_focused_get();
425 if ((!focused) || (e_object_is_del(E_OBJECT(focused))) ||
426 (!focused->comp_data)) return;
428 struct wl_resource *surface = e_comp_wl_client_surface_get(focused);
429 if (!surface) return;
431 if (keyboard_get_data->client != wl_resource_get_client(surface)) return;
432 e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
434 e_comp_wl_input_keyboard_enter_send(surface);
438 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
440 struct wl_resource *res;
441 E_Input_Thread_Request_Keyboard_Get_Data keyboard_get_data;
443 /* try to create keyboard resource */
444 res = wl_resource_create(client, &wl_keyboard_interface,
445 wl_resource_get_version(resource), id);
448 ERR("Could not create keyboard on seat %s: %m",
449 e_comp_wl->seat.name);
450 wl_client_post_no_memory(client);
454 wl_resource_set_implementation(res, &_e_keyboard_interface,
455 e_comp->wl_comp_data,
456 _e_comp_wl_input_cb_keyboard_unbind);
458 /* send current keymap */
459 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap);
460 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
461 e_comp_input_key->xkb.fd,
462 e_comp_input_key->xkb.size);
465 keyboard_get_data.resource = res;
466 keyboard_get_data.client = client;
468 _e_comp_wl_input_thread_cb_keyboard_get(&keyboard_get_data);
472 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
474 e_comp_wl->touch.resources =
475 eina_list_remove(e_comp_wl->touch.resources, resource);
479 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
481 struct wl_resource *res;
483 /* try to create pointer resource */
484 res = wl_resource_create(client, &wl_touch_interface,
485 wl_resource_get_version(resource), id);
488 ERR("Could not create touch on seat %s: %m",
489 e_comp_wl->seat.name);
490 wl_client_post_no_memory(client);
494 e_comp_wl->touch.resources =
495 eina_list_append(e_comp_wl->touch.resources, res);
496 wl_resource_set_implementation(res, &_e_touch_interface,
497 e_comp->wl_comp_data,
498 _e_comp_wl_input_cb_touch_unbind);
501 static const struct wl_seat_interface _e_seat_interface =
503 _e_comp_wl_input_cb_pointer_get,
504 _e_comp_wl_input_cb_keyboard_get,
505 _e_comp_wl_input_cb_touch_get,
509 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
511 E_Comp_Wl_Seat *seat = wl_resource_get_user_data(resource);
513 DBG("Unbind seat: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
515 e_comp_wl->seat.resources =
516 eina_list_remove(e_comp_wl->seat.resources, resource);
521 _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
523 struct wl_resource *res;
525 struct wl_resource *tmp_res;
526 E_Comp_Wl_Seat *seat;
528 seat = E_NEW(E_Comp_Wl_Seat, 1);
531 ERR("Failed to allocate memory for seat data\n");
532 wl_client_post_no_memory(client);
535 seat->is_first_resource = 1;
537 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, tmp_res)
539 if (wl_resource_get_client(tmp_res) != client) continue;
540 DBG("wl_seat (res: %d) is already bound to client (%p)",
541 wl_resource_get_id(tmp_res), client);
542 seat->is_first_resource = 0;
546 res = wl_resource_create(client, &wl_seat_interface, version, id);
549 ERR("Could not create seat resource: %m");
553 DBG("Bind seat: %u (client: %p)", wl_resource_get_id(res), client);
555 /* store version of seat interface for reuse in updating capabilities */
556 e_comp_wl->seat.version = version;
557 e_comp_wl->seat.resources =
558 eina_list_append(e_comp_wl->seat.resources, res);
560 wl_resource_set_implementation(res, &_e_seat_interface,
562 _e_comp_wl_input_cb_unbind_seat);
564 _e_comp_wl_input_update_seat_caps(client);
565 if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
566 wl_seat_send_name(res, e_comp_wl->seat.name);
570 _e_comp_wl_input_cb_relative_pointer_destroy(struct wl_client *client,
571 struct wl_resource *resource)
573 wl_resource_destroy(resource);
576 static const struct zwp_relative_pointer_v1_interface _e_relative_pointer_interface = {
577 _e_comp_wl_input_cb_relative_pointer_destroy
581 _e_comp_wl_input_cb_relative_pointer_manager_destroy(struct wl_client *client,
582 struct wl_resource *resource)
584 wl_resource_destroy(resource);
588 _e_comp_wl_input_cb_unbind_relative_pointer(struct wl_resource *resource)
590 e_comp_wl->relative_ptr.resources =
591 eina_list_remove(e_comp_wl->relative_ptr.resources, resource);
595 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer(struct wl_client *client,
596 struct wl_resource *resource,
598 struct wl_resource *pointer_resource)
600 struct wl_resource *res = NULL;
602 res = wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
606 ERR("Could not create the resource for relative pointer: %m");
607 wl_client_post_no_memory(client);
611 e_comp_wl->relative_ptr.resources =
612 eina_list_append(e_comp_wl->relative_ptr.resources, res);
614 /* FIXME: must consider destroying relative pointer together
615 when the wl_pointer is destroyed */
616 (void) pointer_resource;
617 wl_resource_set_implementation(res, &_e_relative_pointer_interface,
618 NULL, _e_comp_wl_input_cb_unbind_relative_pointer);
621 static const struct zwp_relative_pointer_manager_v1_interface _e_relative_pointer_manager_interface = {
622 _e_comp_wl_input_cb_relative_pointer_manager_destroy,
623 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer,
627 _e_comp_wl_input_cb_unbind_relative_pointer_manager(struct wl_resource *resource)
629 e_comp_wl->relative_ptr.manager_resources =
630 eina_list_remove(e_comp_wl->relative_ptr.manager_resources, resource);
634 _e_comp_wl_input_cb_bind_relative_pointer_manager(struct wl_client *client,
635 void *data EINA_UNUSED,
639 struct wl_resource *resource = NULL;
641 resource = wl_resource_create(client, &zwp_relative_pointer_manager_v1_interface, 1, id);
645 ERR("Could not create resource for relative pointer manager: %m");
646 wl_client_post_no_memory(client);
650 e_comp_wl->relative_ptr.manager_resources =
651 eina_list_append(e_comp_wl->relative_ptr.manager_resources, resource);
652 wl_resource_set_implementation(resource, &_e_relative_pointer_manager_interface,
653 NULL, _e_comp_wl_input_cb_unbind_relative_pointer_manager);
657 _e_comp_wl_input_relative_motion_handler(double dx[2], double dy[2], uint64_t time_us)
659 //intended to be empty just for now.
663 _e_comp_wl_input_pointer_constraint_notify_deactivated(E_Comp_Wl_Pointer_Constraint *constraint)
665 struct wl_resource *resource = constraint->resource;
666 E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
668 if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
669 zwp_locked_pointer_v1_send_unlocked(resource);
670 else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
671 zwp_confined_pointer_v1_send_unconfined(resource);
673 ERR("unknown pointer constraint type (%d) !", type);
675 INF("Pointer Constraint deactivated.");
677 if (constraint->ec &&
678 constraint->has_hint_set)
681 INF("Pointer Constraint. Pointer Warp to (%d, %d)", constraint->hint_x, constraint->hint_y);
682 e_input_device_pointer_warp(NULL, constraint->hint_x, constraint->hint_y);
687 _e_comp_wl_input_pointer_constraint_deactivate(E_Comp_Wl_Pointer_Constraint *constraint)
689 constraint->active = EINA_FALSE;
690 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
691 e_comp_wl->ptr_constraints.ec = NULL;
692 e_comp_wl->relative_ptr.activated = EINA_FALSE;
693 e_comp_wl->relative_ptr.ec = NULL;
694 e_input_relative_motion_handler_set(NULL);
695 _e_comp_wl_input_pointer_constraint_notify_deactivated(constraint);
696 wl_list_remove(&constraint->surface_unmap_listener.link);
697 wl_list_init(&constraint->surface_unmap_listener.link);
701 _e_comp_wl_input_pointer_constraint_destroy(E_Comp_Wl_Pointer_Constraint *constraint)
703 if (constraint->active)
704 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
706 wl_list_remove(&constraint->pointer_destroy_listener.link);
707 wl_list_remove(&constraint->surface_unmap_listener.link);
708 wl_list_remove(&constraint->surface_commit_listener.link);
709 wl_list_remove(&constraint->surface_mousein_listener.link);
710 wl_list_remove(&constraint->surface_mouseout_listener.link);
712 wl_resource_set_user_data(constraint->resource, NULL);
713 pixman_region32_fini(&constraint->region);
714 wl_list_remove(&constraint->link);
720 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
724 pixman_region32_t *region = &constraint->region;
725 pixman_region32_t cregion;
726 pixman_region32_t input_region;
728 pixman_region32_init(&cregion);
729 pixman_region32_init(&input_region);
731 //FIXME: get input_region from ec's input region
732 E_Client *ec = constraint->ec;
733 pixman_region32_init_rect(&input_region, 0, 0, ec->w, ec->h);
734 pixman_region32_intersect(&cregion, &input_region, region);
736 Eina_Bool inside = pixman_region32_contains_point(&cregion,
741 pixman_region32_fini(&cregion);
742 pixman_region32_fini(&input_region);
745 INF("(%d, %d) is not inside of constraint region.", wl_fixed_to_int(fx), wl_fixed_to_int(fy));
751 _e_comp_wl_input_pointer_constraint_notify_activated(E_Comp_Wl_Pointer_Constraint *constraint)
753 struct wl_resource *resource = constraint->resource;
754 E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
756 if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
757 zwp_locked_pointer_v1_send_locked(resource);
758 else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
759 zwp_confined_pointer_v1_send_confined(resource);
761 ERR("unknown pointer constraint type (%d) !", type);
763 INF("Pointer Constraint activated.");
767 _e_comp_wl_input_pointer_constraint_enable(E_Comp_Wl_Pointer_Constraint *constraint)
769 if (constraint->active)
771 ERR("ERROR! Pointer constraint has been activated already !");
775 constraint->active = EINA_TRUE;
776 E_Client *ec = constraint->ec;
777 e_comp_wl->ptr_constraints.activated = EINA_TRUE;
778 e_comp_wl->ptr_constraints.ec = ec;
779 e_comp_wl->relative_ptr.activated = EINA_TRUE;
780 e_comp_wl->relative_ptr.ec = ec;
781 _e_comp_wl_input_pointer_constraint_notify_activated(constraint);
782 wl_signal_add(&e_comp_wl->ptr_constraints.surface_unmap_signal,
783 &constraint->surface_unmap_listener);
784 if (!e_input_relative_motion_handler_set(_e_comp_wl_input_relative_motion_handler))
785 ERR("ERROR! Could not set relative motion handler !");
787 E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
791 _e_comp_wl_input_pointer_constraints_check_enable(E_Comp_Wl_Pointer_Constraint *constraint)
793 if (!constraint || !constraint->ec)
795 ERR("Invalid constraint or ec of it.");
799 E_Client *ec = constraint->ec;
800 wl_fixed_t cx = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
801 wl_fixed_t cy = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
803 if ((!e_comp_wl->ptr.ec) || (e_comp_wl->ptr.ec != ec)
804 || (!ec->pointer_enter_sent))
807 if (!_e_comp_wl_input_is_position_inside_constraint_region(constraint,
812 _e_comp_wl_input_pointer_constraint_enable(constraint);
816 _e_comp_wl_input_pointer_constraint_disable(E_Comp_Wl_Pointer_Constraint *constraint)
818 int lifetime = constraint->lifetime;
820 if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT)
821 _e_comp_wl_input_pointer_constraint_destroy(constraint);
822 else if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT)
823 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
825 ERR("unknown pointer constraint lifetime (%d) !", lifetime);
829 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed(struct wl_listener *listener,
832 struct wl_resource *pointer_resource = (struct wl_resource *)data;
833 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
834 E_Comp_Wl_Pointer_Constraint,
835 pointer_destroy_listener);
837 if (pointer_resource == constraint->pointer)
838 _e_comp_wl_input_pointer_constraint_destroy(constraint);
842 _e_comp_wl_input_cb_pointer_constraints_surface_committed(struct wl_listener *listener,
845 E_Client *ec = (E_Client *)data;
846 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
847 E_Comp_Wl_Pointer_Constraint,
848 surface_commit_listener);
851 if (ec != constraint->ec)
854 if (constraint->is_hint_pending)
856 constraint->is_hint_pending = EINA_FALSE;
858 new_x = wl_fixed_to_int(constraint->hint_x_pending);
859 new_y = wl_fixed_to_int(constraint->hint_y_pending);
861 if (new_x < 0) new_x = 0;
862 if ((ec->w > 0) && (new_x > ec->w - 1)) new_x = ec->w - 1;
864 if (new_y < 0) new_y = 0;
865 if ((ec->h > 0) && (new_y > ec->h - 1)) new_y = ec->h - 1;
867 new_x = ec->client.x + new_x;
868 new_y = ec->client.y + new_y;
870 if (e_client_transform_core_enable_get(ec))
872 e_comp_wl_map_inv_coord_get(ec, new_x, new_y, &constraint->hint_x, &constraint->hint_y);
873 WRN("Pointer Constraint. Committed. hint (%d, %d) -> map_inv_coord (%d, %d)",
874 new_x, new_y, constraint->hint_x, constraint->hint_y);
878 constraint->hint_x = new_x;
879 constraint->hint_y = new_y;
880 WRN("Pointer Constraint. Committed. hint (%d, %d)",
881 constraint->hint_x, constraint->hint_y);
885 if (constraint->is_region_pending)
887 constraint->is_region_pending = EINA_FALSE;
888 pixman_region32_copy(&constraint->region,
889 &constraint->region_pending);
890 pixman_region32_fini(&constraint->region_pending);
891 pixman_region32_init(&constraint->region_pending);
894 //CHECKME: check if the updated region can take effect on the given constraint
898 _e_comp_wl_input_cb_pointer_constraints_surface_mousein(struct wl_listener *listener,
901 E_Client *ec = (E_Client *)data;
902 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
903 E_Comp_Wl_Pointer_Constraint,
904 surface_mousein_listener);
906 Eina_Bool found = EINA_FALSE;
907 E_Comp_Wl_Pointer_Constraint *tmp_constraint;
909 wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
911 if (tmp_constraint == constraint)
914 INF("Pointer Constraint. Mouse In ec: %p constraint: %p", ec, constraint);
919 if (found && !constraint->active)
920 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
924 _e_comp_wl_input_cb_pointer_constraints_surface_mouseout(struct wl_listener *listener,
927 E_Client *ec = (E_Client *)data;
928 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
929 E_Comp_Wl_Pointer_Constraint,
930 surface_mouseout_listener);
932 Eina_Bool found = EINA_FALSE;
933 E_Comp_Wl_Pointer_Constraint *tmp_constraint;
935 wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
937 if (tmp_constraint == constraint)
940 INF("Pointer Constraint. Mouse Out ec: %p constraint: %p", ec, constraint);
945 if (found && constraint->active)
946 _e_comp_wl_input_pointer_constraint_disable(constraint);
950 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped(struct wl_listener *listener,
953 E_Client *ec = (E_Client *)data;
954 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
955 E_Comp_Wl_Pointer_Constraint,
956 surface_unmap_listener);
958 if (ec == constraint->ec)
959 _e_comp_wl_input_pointer_constraint_disable(constraint);
962 static E_Comp_Wl_Pointer_Constraint *
963 _e_comp_wl_input_pointer_constraint_create(E_Client *ec,
964 struct wl_resource *resource,
965 struct wl_resource *pointer,
966 struct wl_resource *region_resource,
967 enum zwp_pointer_constraints_v1_lifetime lifetime,
968 E_Comp_Wl_Pointer_Constraint_Type type)
970 E_Comp_Wl_Pointer_Constraint *constraint;
972 constraint = E_NEW(E_Comp_Wl_Pointer_Constraint, 1);
976 ERR("Could not allocate memory for pointer constraint: %m");
980 constraint->active = EINA_FALSE;
982 constraint->lifetime = lifetime;
983 constraint->type = type;
984 constraint->pointer = pointer;
985 constraint->resource = resource;
986 constraint->surface = e_comp_wl_client_surface_get(ec);
987 wl_list_init(&constraint->link);
988 wl_list_insert(&ec->comp_data->pointer_constraints, &constraint->link);
989 pixman_region32_init(&constraint->region);
990 pixman_region32_init(&constraint->region_pending);
994 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
997 pixman_region32_copy(&constraint->region, region);
998 constraint->has_region_set = EINA_TRUE;
1002 //CHECKME: check whether this situation is a kind of bug
1003 ERR("Invalid pixman_region from region (pointer constraint region!");
1004 pixman_region32_fini(&constraint->region);
1005 pixman_region32_init_rect(&constraint->region,
1006 INT32_MIN, INT32_MIN,
1007 UINT32_MAX, UINT32_MAX);
1012 pixman_region32_fini(&constraint->region);
1013 pixman_region32_init_rect(&constraint->region,
1014 INT32_MIN, INT32_MIN,
1015 UINT32_MAX, UINT32_MAX);
1016 constraint->has_region_set = EINA_TRUE;
1019 ERR("Pointer Constraint created.");
1021 constraint->pointer_destroy_listener.notify =
1022 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed;
1023 constraint->surface_commit_listener.notify =
1024 _e_comp_wl_input_cb_pointer_constraints_surface_committed;
1025 constraint->surface_unmap_listener.notify =
1026 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped;
1027 constraint->surface_mousein_listener.notify =
1028 _e_comp_wl_input_cb_pointer_constraints_surface_mousein;
1029 constraint->surface_mouseout_listener.notify =
1030 _e_comp_wl_input_cb_pointer_constraints_surface_mouseout;
1032 wl_signal_add(&e_comp_wl->ptr_constraints.pointer_destroy_signal,
1033 &constraint->pointer_destroy_listener);
1034 wl_signal_add(&e_comp_wl->ptr_constraints.surface_commit_signal,
1035 &constraint->surface_commit_listener);
1036 wl_signal_add(&e_comp_wl->ptr_constraints.surface_mousein_signal,
1037 &constraint->surface_mousein_listener);
1038 wl_signal_add(&e_comp_wl->ptr_constraints.surface_mouseout_signal,
1039 &constraint->surface_mouseout_listener);
1040 wl_list_init(&constraint->surface_unmap_listener.link);
1046 _e_comp_wl_input_has_pointer_constraints_for_pointer(E_Client *ec, struct wl_resource *pointer)
1048 E_Comp_Wl_Pointer_Constraint *constraint;
1050 wl_list_for_each(constraint, &ec->comp_data->pointer_constraints, link)
1052 if (constraint->pointer == pointer)
1060 _e_comp_wl_input_cb_unbind_locked_pointer(struct wl_resource *resource)
1062 E_Comp_Wl_Pointer_Constraint *constraint;
1063 constraint = wl_resource_get_user_data(resource);
1068 _e_comp_wl_input_pointer_constraint_destroy(constraint);
1072 _e_comp_wl_input_cb_locked_pointer_destroy(struct wl_client *client,
1073 struct wl_resource *resource)
1075 wl_resource_destroy(resource);
1079 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint(struct wl_client *client,
1080 struct wl_resource *resource,
1081 wl_fixed_t surface_x,
1082 wl_fixed_t surface_y)
1084 E_Comp_Wl_Pointer_Constraint *constraint =
1085 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1090 constraint->hint_x_pending = surface_x;
1091 constraint->hint_y_pending = surface_y;
1092 constraint->is_hint_pending = EINA_TRUE;
1093 constraint->has_hint_set = EINA_TRUE;
1097 _e_comp_wl_input_cb_locked_pointer_set_region(struct wl_client *client,
1098 struct wl_resource *resource,
1099 struct wl_resource *region_resource)
1101 E_Comp_Wl_Pointer_Constraint *constraint =
1102 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1107 if (region_resource)
1109 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
1113 pixman_region32_copy(&constraint->region_pending, region);
1117 //CHECKME: check whether this situation is a kind of bug
1118 ERR("Invalid pixman_region from region (pointer constraint region!");
1119 pixman_region32_fini(&constraint->region_pending);
1120 pixman_region32_init_rect(&constraint->region_pending,
1121 INT32_MIN, INT32_MIN,
1122 UINT32_MAX, UINT32_MAX);
1125 constraint->has_region_set = EINA_TRUE;
1129 pixman_region32_fini(&constraint->region_pending);
1130 pixman_region32_init_rect(&constraint->region_pending,
1131 INT32_MIN, INT32_MIN,
1132 UINT32_MAX, UINT32_MAX);
1135 constraint->is_region_pending = EINA_TRUE;
1138 static const struct zwp_locked_pointer_v1_interface _e_comp_wl_locked_pointer_interface =
1140 _e_comp_wl_input_cb_locked_pointer_destroy,
1141 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint,
1142 _e_comp_wl_input_cb_locked_pointer_set_region,
1146 _e_comp_wl_input_cb_pointer_constraints_lock_pointer(struct wl_client *client,
1147 struct wl_resource *resource,
1149 struct wl_resource *surface,
1150 struct wl_resource *pointer,
1151 struct wl_resource *region,
1154 if (!pointer || !surface)
1156 ERR("Pointer resource or surface resource is invalid !");
1160 E_Client *ec = e_client_from_surface_resource(surface);
1164 ERR("Could not get ec from surface resource !");
1168 if (_e_comp_wl_input_has_pointer_constraints_for_pointer(ec, pointer))
1170 ERR("Pointer constraints has been created already (ec: %p, pointer_resource: %u)",
1171 ec, wl_resource_get_id(resource));
1172 wl_resource_post_error(resource,
1173 ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
1174 "the pointer has a lock set already on this surface");
1178 struct wl_resource *res;
1179 res = wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
1183 ERR("Could not create a resource for pointer constraints lock: %m");
1184 wl_client_post_no_memory(client);
1188 E_Comp_Wl_Pointer_Constraint *constraint;
1189 constraint = _e_comp_wl_input_pointer_constraint_create(ec, res, pointer, region, lifetime,
1190 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK);
1194 ERR("Could not create a pointer constraint.");
1195 wl_resource_destroy(res);
1196 wl_client_post_no_memory(client);
1200 wl_resource_set_implementation(res, &_e_comp_wl_locked_pointer_interface,
1201 constraint, _e_comp_wl_input_cb_unbind_locked_pointer);
1203 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
1207 _e_comp_wl_input_cb_pointer_constraints_confine_pointer(struct wl_client *client,
1208 struct wl_resource *resource,
1210 struct wl_resource *surface,
1211 struct wl_resource *pointer,
1212 struct wl_resource *region,
1223 /* TODO: pointer constraints confine */
1227 _e_comp_wl_input_cb_pointer_constraints_destroy(struct wl_client *client,
1228 struct wl_resource *resource)
1230 wl_resource_destroy(resource);
1233 static const struct zwp_pointer_constraints_v1_interface _e_pointer_constraints_interface = {
1234 _e_comp_wl_input_cb_pointer_constraints_destroy,
1235 _e_comp_wl_input_cb_pointer_constraints_lock_pointer,
1236 _e_comp_wl_input_cb_pointer_constraints_confine_pointer,
1240 _e_comp_wl_input_cb_unbind_pointer_constraints(struct wl_resource *resource)
1242 e_comp_wl->ptr_constraints.resources =
1243 eina_list_remove(e_comp_wl->ptr_constraints.resources, resource);
1247 _e_comp_wl_input_cb_bind_pointer_constraints(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
1249 struct wl_resource *resource;
1251 resource = wl_resource_create(client, &zwp_pointer_constraints_v1_interface, version, id);
1255 ERR("Could not create pointer constraints resource: %m");
1259 e_comp_wl->ptr_constraints.resources =
1260 eina_list_append(e_comp_wl->ptr_constraints.resources, resource);
1261 wl_resource_set_implementation(resource, &_e_pointer_constraints_interface,
1262 NULL, _e_comp_wl_input_cb_unbind_pointer_constraints);
1266 _e_comp_wl_input_cb_surface_commit(void *data EINA_UNUSED, E_Client *ec)
1268 wl_signal_emit(&e_comp_wl->ptr_constraints.surface_commit_signal, ec);
1272 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
1275 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
1277 if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
1285 if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
1287 WRN("%s is maybe link, so delete it\n", keymap_path);
1290 file = fopen(keymap_path, "w");
1291 EINA_SAFETY_ON_NULL_RETURN(file);
1293 if (fputs(keymap_data, file) < 0)
1295 WRN("Failed to write keymap file: %s\n", keymap_path);
1297 unlink(keymap_path);
1301 INF("Success to make keymap file: %s\n", keymap_path);
1309 _e_comp_wl_input_keymap_fd_get(off_t size)
1311 int fd = 0, blen = 0, len = 0;
1313 char tmp[PATH_MAX] = {0, };
1317 blen = sizeof(tmp) - 20;
1319 path = e_util_env_get("XDG_RUNTIME_DIR");
1320 if (!path) return -1;
1322 len = strlen(path) + 19;
1325 strncpy(tmp, path, PATH_MAX - 20);
1326 strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
1335 old_umask = umask(S_IRWXG|S_IRWXO);
1339 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
1341 flags = fcntl(fd, F_GETFD);
1348 if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
1354 if (ftruncate(fd, size) < 0)
1365 _e_comp_wl_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1367 /* FIXME: will be deprecated after migration */
1369 xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1371 /* unreference any existing keymap */
1372 if (e_comp_wl->xkb.keymap)
1373 xkb_map_unref(e_comp_wl->xkb.keymap);
1375 /* unmap any existing keyboard area */
1376 if (e_comp_wl->xkb.area)
1377 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1378 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1380 /* unreference any existing keyboard state */
1381 if (e_comp_wl->xkb.state)
1384 xkb_state_serialize_mods(e_comp_wl->xkb.state,
1385 XKB_STATE_MODS_LATCHED);
1387 xkb_state_serialize_mods(e_comp_wl->xkb.state,
1388 XKB_STATE_MODS_LOCKED);
1390 xkb_state_serialize_layout(e_comp_wl->xkb.state,
1391 XKB_STATE_LAYOUT_EFFECTIVE);
1392 xkb_state_unref(e_comp_wl->xkb.state);
1395 /* create a new xkb state */
1396 e_comp_wl->xkb.state = xkb_state_new(keymap);
1398 if (!e_comp_wl->xkb.state)
1403 if ((latched) || (locked) || (group))
1404 xkb_state_update_mask(e_comp_wl->xkb.state, 0,
1405 latched, locked, 0, 0, group);
1407 /* increment keymap reference */
1408 e_comp_wl->xkb.keymap = keymap;
1410 /* fetch updated modifiers */
1411 e_comp_wl->kbd.mod_shift =
1412 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1413 e_comp_wl->kbd.mod_caps =
1414 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1415 e_comp_wl->kbd.mod_ctrl =
1416 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1417 e_comp_wl->kbd.mod_alt =
1418 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1419 e_comp_wl->kbd.mod_super =
1420 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1422 if (!(tmp = xkb_map_get_as_string(keymap)))
1424 ERR("Could not get keymap string");
1428 e_comp_wl->xkb.size = strlen(tmp) + 1;
1430 _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
1431 if (e_comp_wl->xkb.fd < 0)
1433 ERR("Could not create keymap file");
1438 e_comp_wl->xkb.area =
1439 mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
1440 MAP_SHARED, e_comp_wl->xkb.fd, 0);
1441 if (e_comp_wl->xkb.area == MAP_FAILED)
1443 ERR("Failed to mmap keymap area: %m");
1448 strncpy(e_comp_wl->xkb.area, tmp, e_comp_wl->xkb.size);
1453 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1456 xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1457 struct wl_resource *res;
1460 /* unreference any existing keymap */
1461 if (e_comp_input_key->xkb.keymap)
1462 xkb_map_unref(e_comp_input_key->xkb.keymap);
1464 /* unmap any existing keyboard area */
1465 if (e_comp_input_key->xkb.area)
1466 munmap(e_comp_input_key->xkb.area, e_comp_input_key->xkb.size);
1467 if (e_comp_input_key->xkb.fd >= 0) close(e_comp_input_key->xkb.fd);
1469 /* unreference any existing keyboard state */
1470 if (e_comp_input_key->xkb.state)
1473 xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1474 XKB_STATE_MODS_LATCHED);
1476 xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1477 XKB_STATE_MODS_LOCKED);
1479 xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1480 XKB_STATE_LAYOUT_EFFECTIVE);
1481 xkb_state_unref(e_comp_input_key->xkb.state);
1484 /* create a new xkb state */
1485 e_comp_input_key->xkb.state = xkb_state_new(keymap);
1487 if (!e_comp_input_key->xkb.state)
1492 if ((latched) || (locked) || (group))
1493 xkb_state_update_mask(e_comp_input_key->xkb.state, 0,
1494 latched, locked, 0, 0, group);
1496 /* increment keymap reference */
1497 e_comp_input_key->xkb.keymap = keymap;
1499 /* fetch updated modifiers */
1500 e_comp_input_key->kbd.mod_shift =
1501 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1502 e_comp_input_key->kbd.mod_caps =
1503 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1504 e_comp_input_key->kbd.mod_ctrl =
1505 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1506 e_comp_input_key->kbd.mod_alt =
1507 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1508 e_comp_input_key->kbd.mod_super =
1509 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1511 if (!(tmp = xkb_map_get_as_string(keymap)))
1513 ERR("Could not get keymap string");
1517 e_comp_input_key->xkb.size = strlen(tmp) + 1;
1518 e_comp_input_key->xkb.fd =
1519 _e_comp_wl_input_keymap_fd_get(e_comp_input_key->xkb.size);
1520 if (e_comp_input_key->xkb.fd < 0)
1522 ERR("Could not create keymap file");
1527 _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
1529 e_comp_input_key->xkb.area =
1530 mmap(NULL, e_comp_input_key->xkb.size, (PROT_READ | PROT_WRITE),
1531 MAP_SHARED, e_comp_input_key->xkb.fd, 0);
1532 if (e_comp_input_key->xkb.area == MAP_FAILED)
1534 ERR("Failed to mmap keymap area: %m");
1539 strncpy(e_comp_input_key->xkb.area, tmp, e_comp_input_key->xkb.size);
1542 _e_comp_wl_keymap_update(keymap, keymap_path);
1544 /* send updated keymap */
1545 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
1546 EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
1547 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1548 e_comp_input_key->xkb.fd,
1549 e_comp_input_key->xkb.size);
1552 /* update modifiers */
1553 e_comp_wl_input_keyboard_modifiers_update();
1557 e_comp_wl_input_init(void)
1559 /* set default seat name */
1560 if (!e_comp_wl->seat.name)
1561 e_comp_wl->seat.name = "default";
1563 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1564 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1566 g_mutex_init(&e_comp_wl->kbd.resource_mutex);
1567 g_mutex_init(&e_comp_wl->kbd.focused_mutex);
1568 g_mutex_init(&e_comp_wl->kbd.keys_mutex);
1569 g_mutex_init(&e_comp_wl->kbd.repeat_delay_mutex);
1570 g_mutex_init(&e_comp_wl->kbd.repeat_rate_mutex);
1572 g_mutex_init(&e_comp_wl->xkb.keymap_mutex);
1573 g_mutex_init(&e_comp_wl->xkb.state_mutex);
1575 /* get default keyboard repeat delay from configuration */
1576 atomic_store(&e_comp_input_key->kbd.repeat_delay, e_config->keyboard.repeat_delay);
1577 /* check for valid repeat_delay */
1578 /* if invalid, set the default value of repeat delay */
1579 if (e_comp_input_key->kbd.repeat_delay < 0)
1580 atomic_store(&e_comp_input_key->kbd.repeat_delay, 400);
1582 /* get default keyboard repeat rate from configuration */
1583 atomic_store(&e_comp_input_key->kbd.repeat_rate, e_config->keyboard.repeat_rate);
1584 /* check for valid repeat_rate value */
1585 /* if invalid, set the default value of repeat rate value */
1586 if (e_comp_input_key->kbd.repeat_rate < 0)
1587 atomic_store(&e_comp_input_key->kbd.repeat_rate, 25);
1589 /* create the global resource for input seat */
1590 e_comp_wl->seat.global =
1591 wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
1592 e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
1593 if (!e_comp_wl->seat.global)
1595 ERR("Could not create global for seat: %m");
1599 /* create the global resource for relative pointer */
1600 e_comp_wl->relative_ptr.global =
1601 wl_global_create(e_comp_wl->wl.disp,
1602 &zwp_relative_pointer_manager_v1_interface, 1,
1603 e_comp->wl_comp_data,
1604 _e_comp_wl_input_cb_bind_relative_pointer_manager);
1605 if (!e_comp_wl->relative_ptr.global)
1607 ERR("Could not create global for relative pointer: %m");
1611 /* create the global resource for pointer-constraints */
1612 e_comp_wl->ptr_constraints.global =
1613 wl_global_create(e_comp_wl->wl.disp,
1614 &zwp_pointer_constraints_v1_interface, 1,
1615 e_comp->wl_comp_data,
1616 _e_comp_wl_input_cb_bind_pointer_constraints);
1617 if (!e_comp_wl->ptr_constraints.global)
1619 ERR("Could not create global for pointer constraints: %m");
1623 e_comp_wl->ptr_constraints.ec = NULL;
1624 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
1625 wl_signal_init(&e_comp_wl->ptr_constraints.pointer_destroy_signal);
1626 wl_signal_init(&e_comp_wl->ptr_constraints.surface_unmap_signal);
1627 wl_signal_init(&e_comp_wl->ptr_constraints.surface_commit_signal);
1628 wl_signal_init(&e_comp_wl->ptr_constraints.surface_mousein_signal);
1629 wl_signal_init(&e_comp_wl->ptr_constraints.surface_mouseout_signal);
1631 _surface_commit_hook = e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
1632 _e_comp_wl_input_cb_surface_commit,
1635 wl_array_init(&e_comp_input_key->kbd.keys);
1636 wl_array_init(&e_comp_input_key->kbd.routed_keys);
1638 E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
1640 /* get string values from environment variables */
1641 _env_e_default_xkb_rules = e_util_env_get("E_DEFAULT_XKB_RULES" );
1642 _env_e_default_xkb_model = e_util_env_get("E_DEFAULT_XKB_MODEL" );
1643 _env_e_default_xkb_layout = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
1644 _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
1645 _env_e_default_xkb_opts = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
1651 e_comp_wl_input_shutdown(void)
1653 struct wl_resource *res;
1655 /* free environment variable string */
1656 E_FREE(_env_e_default_xkb_rules );
1657 E_FREE(_env_e_default_xkb_model );
1658 E_FREE(_env_e_default_xkb_layout );
1659 E_FREE(_env_e_default_xkb_variant);
1660 E_FREE(_env_e_default_xkb_opts );
1662 /* delete surface commit hook */
1663 if (_surface_commit_hook)
1665 e_comp_wl_hook_del(_surface_commit_hook);
1666 _surface_commit_hook = NULL;
1669 /* destroy pointer resources */
1670 EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
1671 wl_resource_destroy(res);
1673 /* destroy relative pointer resources */
1674 EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
1675 wl_resource_destroy(res);
1677 /* destroy relative pointer manager resources */
1678 EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
1679 wl_resource_destroy(res);
1681 /* destroy pointer constraints resources */
1682 EINA_LIST_FREE(e_comp_wl->ptr_constraints.resources, res)
1683 wl_resource_destroy(res);
1685 /* destroy keyboard resources */
1686 EINA_LIST_FREE(e_comp_input_key->kbd.resources, res)
1687 wl_resource_destroy(res);
1688 e_comp_input_key->kbd.resources = eina_list_free(e_comp_input_key->kbd.resources);
1690 g_mutex_clear(&e_comp_wl->kbd.resource_mutex);
1691 g_mutex_clear(&e_comp_wl->kbd.focused_mutex);
1693 /* destroy touch resources */
1694 EINA_LIST_FREE(e_comp_wl->touch.resources, res)
1695 wl_resource_destroy(res);
1697 /* destroy e_comp_input_key->kbd.keys array */
1698 wl_array_release(&e_comp_wl->kbd.keys);
1700 wl_array_release(&e_comp_input_key->kbd.routed_keys);
1702 /* unmap any existing keyboard area */
1703 if (e_comp_wl->xkb.area)
1704 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1705 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1707 /* unreference any existing keyboard state */
1708 if (e_comp_wl->xkb.state)
1709 xkb_state_unref(e_comp_wl->xkb.state);
1711 /* unreference any existing keymap */
1712 if (e_comp_wl->xkb.keymap)
1713 xkb_map_unref(e_comp_wl->xkb.keymap);
1715 /* unreference any existing context */
1716 if (e_comp_wl->xkb.context)
1717 xkb_context_unref(e_comp_wl->xkb.context);
1719 /* destroy the global relative pointer resource */
1720 if (e_comp_wl->relative_ptr.global)
1721 wl_global_destroy(e_comp_wl->relative_ptr.global);
1722 e_comp_wl->relative_ptr.global = NULL;
1724 /* destroy the global pointer constraints resource */
1725 if (e_comp_wl->ptr_constraints.global)
1726 wl_global_destroy(e_comp_wl->ptr_constraints.global);
1727 e_comp_wl->ptr_constraints.global = NULL;
1729 /* destroy the global seat resource */
1730 if (e_comp_wl->seat.global)
1731 wl_global_destroy(e_comp_wl->seat.global);
1732 e_comp_wl->seat.global = NULL;
1734 dont_set_e_input_keymap = EINA_FALSE;
1735 dont_use_xkb_cache = EINA_FALSE;
1737 g_mutex_clear(&e_comp_wl->xkb.keymap_mutex);
1738 g_mutex_clear(&e_comp_wl->xkb.state_mutex);
1740 g_mutex_clear(&e_comp_wl->kbd.keys_mutex);
1741 g_mutex_clear(&e_comp_wl->kbd.repeat_delay_mutex);
1742 g_mutex_clear(&e_comp_wl->kbd.repeat_rate_mutex);
1746 e_comp_wl_input_pointer_check(struct wl_resource *res)
1748 return wl_resource_instance_of(res, &wl_pointer_interface,
1749 &_e_pointer_interface);
1753 e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
1755 return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
1756 &_e_relative_pointer_interface);
1760 e_comp_wl_input_keyboard_check(struct wl_resource *res)
1762 return wl_resource_instance_of(res, &wl_keyboard_interface,
1763 &_e_keyboard_interface);
1767 e_comp_wl_input_keyboard_modifiers_serialize(void)
1769 Eina_Bool changed = EINA_FALSE;
1771 xkb_layout_index_t grp;
1773 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
1774 xkb_layout_index_t mod_group;
1776 mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1777 XKB_STATE_DEPRESSED);
1778 mod_depressed = atomic_load(&e_comp_input_key->kbd.mod_depressed);
1779 changed |= mod != mod_depressed;
1780 atomic_store(&e_comp_input_key->kbd.mod_depressed, mod);
1782 mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1783 XKB_STATE_MODS_LATCHED);
1785 mod_latched = atomic_load(&e_comp_input_key->kbd.mod_latched);
1786 changed |= mod != mod_latched;
1787 atomic_store(&e_comp_input_key->kbd.mod_latched, mod);
1789 mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1790 XKB_STATE_MODS_LOCKED);
1791 mod_locked = atomic_load(&e_comp_input_key->kbd.mod_locked);
1792 changed |= mod != mod_locked;
1793 atomic_store(&e_comp_input_key->kbd.mod_locked, mod);
1795 grp = xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1796 XKB_STATE_LAYOUT_EFFECTIVE);
1797 mod_group = atomic_load(&e_comp_input_key->kbd.mod_group);
1798 changed |= grp != mod_group;
1799 atomic_store(&e_comp_input_key->kbd.mod_group, grp);
1805 e_comp_wl_input_keyboard_modifiers_update(void)
1808 struct wl_resource *res;
1811 if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
1812 if (!e_comp_input_key->kbd.focused)
1817 serial = wl_display_next_serial(e_comp_wl->wl.disp);
1818 EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
1819 wl_keyboard_send_modifiers(res, serial,
1820 e_comp_input_key->kbd.mod_depressed,
1821 e_comp_input_key->kbd.mod_latched,
1822 e_comp_input_key->kbd.mod_locked,
1823 e_comp_input_key->kbd.mod_group);
1827 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
1829 enum xkb_key_direction dir;
1831 if (!e_comp_input_key->xkb.state)
1836 if (pressed) dir = XKB_KEY_DOWN;
1837 else dir = XKB_KEY_UP;
1839 atomic_store(&e_comp_input_key->kbd.mod_changed, xkb_state_update_key(e_comp_input_key->xkb.state, keycode + 8, dir));
1841 e_comp_wl_input_keyboard_modifiers_update();
1845 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
1847 /* check for valid compositor data */
1848 if (!e_comp->wl_comp_data)
1850 ERR("No compositor data");
1854 e_comp_wl->ptr.enabled = !!enabled;
1855 _e_comp_wl_input_update_seat_caps(NULL);
1859 _e_comp_wl_input_thread_cb_keyboard_enabled_set(void *data)
1862 EINA_SAFETY_ON_NULL_RETURN(data);
1864 enabled = *(Eina_Bool *)data;
1866 e_comp_input_key->kbd.enabled = !!enabled;
1870 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
1872 /* check for valid compositor data */
1873 if (!e_comp->wl_comp_data)
1875 ERR("No compositor data");
1879 e_input_backend_thread_safe_call(_e_comp_wl_input_thread_cb_keyboard_enabled_set, &enabled, sizeof(Eina_Bool));
1880 _e_comp_wl_input_update_seat_caps(NULL);
1884 e_comp_wl_input_keymap_cache_file_use_get(void)
1886 return use_cache_keymap;
1889 E_API Eina_Stringshare *
1890 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
1892 return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
1893 names.rules ? names.rules : "evdev",
1894 names.model ? names.model : "pc105",
1895 names.layout ? names.layout : "us",
1896 names.variant ? names.variant : "",
1897 names.options ? names.options : "");
1900 EINTERN struct xkb_keymap *
1901 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
1903 struct xkb_keymap *keymap;
1904 char *cache_path = NULL;
1907 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1909 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
1911 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1913 cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
1914 file = fopen(cache_path, "r");
1919 INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
1921 /* fetch new keymap based on names */
1922 keymap = xkb_map_new_from_names(ctx, &names, 0);
1923 use_cache_keymap = EINA_FALSE;
1927 INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
1928 keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1931 WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
1933 if (remove(cache_path) != 0)
1934 WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
1935 keymap = xkb_map_new_from_names(ctx, &names, 0);
1936 use_cache_keymap = EINA_FALSE;
1940 eina_stringshare_del(cache_path);
1943 use_cache_keymap = EINA_TRUE;
1947 *keymap_path = cache_path;
1948 EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
1956 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
1957 const char *variant, const char *options,
1958 struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
1960 struct xkb_keymap *keymap;
1961 struct xkb_rule_names names;
1962 char *keymap_path = NULL;
1963 Eina_Bool use_dflt_xkb = EINA_FALSE;
1964 const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
1966 /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
1967 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
1969 if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
1971 /* unreference any existing context */
1972 if (e_comp_input_key->xkb.context)
1973 xkb_context_unref(e_comp_input_key->xkb.context);
1975 /* create a new xkb context */
1976 if (use_dflt_xkb) e_comp_input_key->xkb.context = dflt_ctx;
1977 else e_comp_input_key->xkb.context = xkb_context_new(0);
1979 if (!e_comp_input_key->xkb.context)
1985 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1986 e_input_device_keyboard_cached_context_set(e_comp_input_key->xkb.context);
1988 /* assemble xkb_rule_names so we can fetch keymap */
1989 memset(&names, 0, sizeof(names));
1990 if (rules) names.rules = strdup(rules);
1993 default_rules = e_comp_wl_input_keymap_default_rules_get();
1994 names.rules = strdup(default_rules);
1996 if (model) names.model = strdup(model);
1999 default_model = e_comp_wl_input_keymap_default_model_get();
2000 names.model = strdup(default_model);
2002 if (layout) names.layout = strdup(layout);
2005 default_layout = e_comp_wl_input_keymap_default_layout_get();
2006 names.layout = strdup(default_layout);
2008 if (variant) names.variant = strdup(variant);
2011 default_variant = e_comp_wl_input_keymap_default_variant_get();
2012 if (default_variant) names.variant = strdup(default_variant);
2014 if (options) names.options = strdup(options);
2017 default_options = e_comp_wl_input_keymap_default_options_get();
2018 if (default_options) names.options = strdup(default_options);
2021 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
2025 keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
2026 if (access(keymap_path, R_OK) == 0)
2028 eina_stringshare_del(keymap_path);
2033 keymap = e_comp_wl_input_keymap_compile(e_comp_input_key->xkb.context, names, &keymap_path);
2036 /* update compositor keymap */
2037 _e_comp_wl_input_keymap_update(keymap, keymap_path);
2039 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
2040 e_input_device_keyboard_cached_keymap_set(keymap);
2043 if (keymap_path) eina_stringshare_del(keymap_path);
2044 free((char *)names.rules);
2045 free((char *)names.model);
2046 free((char *)names.layout);
2047 if (names.variant) free((char *)names.variant);
2048 if (names.options) free((char *)names.options);
2053 e_comp_wl_input_keymap_default_rules_get(void)
2055 if (e_config->xkb.default_rmlvo.rules)
2056 return e_config->xkb.default_rmlvo.rules;
2058 if (_env_e_default_xkb_rules)
2059 return _env_e_default_xkb_rules;
2065 e_comp_wl_input_keymap_default_model_get(void)
2067 if (e_config->xkb.default_rmlvo.model)
2068 return e_config->xkb.default_rmlvo.model;
2070 if (_env_e_default_xkb_model)
2071 return _env_e_default_xkb_model;
2077 e_comp_wl_input_keymap_default_layout_get(void)
2079 if (e_config->xkb.default_rmlvo.layout)
2080 return e_config->xkb.default_rmlvo.layout;
2082 if (_env_e_default_xkb_layout)
2083 return _env_e_default_xkb_layout;
2089 e_comp_wl_input_keymap_default_variant_get(void)
2091 if (e_config->xkb.default_rmlvo.variant)
2092 return e_config->xkb.default_rmlvo.variant;
2094 if (_env_e_default_xkb_variant)
2095 return _env_e_default_xkb_variant;
2101 e_comp_wl_input_keymap_default_options_get(void)
2103 if (e_config->xkb.default_rmlvo.options)
2104 return e_config->xkb.default_rmlvo.options;
2106 if (_env_e_default_xkb_opts)
2107 return _env_e_default_xkb_opts;
2113 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
2115 /* check for valid compositor data */
2116 if (!e_comp->wl_comp_data)
2118 ERR("No compositor data");
2122 e_comp_wl->touch.enabled = !!enabled;
2123 _e_comp_wl_input_update_seat_caps(NULL);
2127 e_comp_wl_input_seat_caps_set(unsigned int caps)
2129 Eina_Bool need_update = EINA_FALSE;
2131 /* check for valid compositor data */
2132 if (!e_comp->wl_comp_data)
2134 ERR("No compositor data");
2138 if (caps & E_INPUT_SEAT_POINTER)
2139 e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
2140 if (caps & E_INPUT_SEAT_KEYBOARD)
2141 e_comp_input_key->kbd.enabled = need_update = EINA_TRUE;
2142 if (caps & E_INPUT_SEAT_TOUCH)
2143 e_comp_wl->touch.enabled = need_update = EINA_TRUE;
2146 _e_comp_wl_input_update_seat_caps(NULL);
2150 e_comp_wl_input_touch_check(struct wl_resource *res)
2152 return wl_resource_instance_of(res, &wl_touch_interface,
2153 &_e_touch_interface);
2157 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
2159 struct wl_resource *res;
2162 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
2164 atomic_store(&e_comp_input_key->kbd.repeat_delay, delay);
2165 atomic_store(&e_comp_input_key->kbd.repeat_rate, rate);
2167 EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
2169 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
2170 wl_keyboard_send_repeat_info(res, e_comp_input_key->kbd.repeat_rate,
2171 e_comp_input_key->kbd.repeat_delay);
2175 typedef struct _keycode_map{
2176 xkb_keysym_t keysym;
2177 xkb_keycode_t keycode;
2181 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2183 keycode_map *found_keycodes = (keycode_map *)data;
2184 xkb_keysym_t keysym = found_keycodes->keysym;
2186 const xkb_keysym_t *syms_out = NULL;
2188 nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2189 if (nsyms && syms_out)
2191 if (*syms_out == keysym)
2193 found_keycodes->keycode = key;
2199 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
2201 keycode_map found_keycodes = {0,};
2202 found_keycodes.keysym = keysym;
2203 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2205 return found_keycodes.keycode;
2209 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
2211 struct xkb_keymap *keymap = NULL;
2212 xkb_keysym_t keysym = 0x0;
2216 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
2217 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
2219 keymap = e_comp_input_key->xkb.keymap;
2220 EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
2222 keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
2223 if (keysym == XKB_KEY_NoSymbol)
2225 if (strlen(name) <= sizeof("Keycode-")) goto finish;
2227 if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
2229 name_tmp = (char *)name + sizeof("Keycode-") - 1;
2230 keycode = atoi(name_tmp);
2231 if (keycode <= 8) goto finish;
2239 keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
2248 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
2250 struct xkb_state *state;
2251 xkb_keysym_t sym = XKB_KEY_NoSymbol;
2252 char name[256] = {0, };
2254 EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
2255 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
2256 if (!e_comp_input_key->xkb.state)
2261 state = e_comp_input_key->xkb.state;
2263 sym = xkb_state_key_get_one_sym(state, keycode);
2265 if (sym == XKB_KEY_NoSymbol)
2267 snprintf(name, sizeof(name), "Keycode-%u", keycode);
2270 xkb_keysym_get_name(sym, name, sizeof(name));
2272 return strdup(name);
2276 _e_comp_wl_input_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
2278 char *keymap_path = NULL;
2279 struct xkb_context *context;
2280 struct xkb_keymap *keymap;
2281 struct xkb_rule_names names = {0,};
2282 const char* default_rules, *default_model, *default_layout, *default_variant, *default_options;
2284 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_set);
2286 context = xkb_context_new(0);
2287 EINA_SAFETY_ON_NULL_RETURN(context);
2289 /* assemble xkb_rule_names so we can fetch keymap */
2290 memset(&names, 0, sizeof(names));
2292 default_rules = e_comp_wl_input_keymap_default_rules_get();
2293 default_model = e_comp_wl_input_keymap_default_model_get();
2294 default_layout = e_comp_wl_input_keymap_default_layout_get();
2295 default_variant = e_comp_wl_input_keymap_default_variant_get();
2296 default_options = e_comp_wl_input_keymap_default_options_get();
2298 names.rules = strdup(default_rules);
2299 names.model = strdup(default_model);
2300 names.layout = strdup(default_layout);
2301 if (default_variant) names.variant = strdup(default_variant);
2302 if (default_options) names.options = strdup(default_options);
2304 keymap = e_comp_wl_input_keymap_compile(context, names, &keymap_path);
2305 eina_stringshare_del(keymap_path);
2306 EINA_SAFETY_ON_NULL_GOTO(keymap, cleanup);
2311 if (dont_set_e_input_keymap == EINA_FALSE)
2313 e_input_device_keyboard_cached_context_set(*ctx);
2314 e_input_device_keyboard_cached_keymap_set(*map);
2318 free((char *)names.rules);
2319 free((char *)names.model);
2320 free((char *)names.layout);
2321 if (names.variant) free((char *)names.variant);
2322 if (names.options) free((char *)names.options);
2328 e_comp_wl_input_pointer_constraint_activated_get(void)
2330 return e_comp_wl->ptr_constraints.activated;
2334 e_comp_wl_input_keymap_init(void)
2336 struct xkb_context *ctx = NULL;
2337 struct xkb_keymap *map = NULL;
2340 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2341 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2343 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
2345 _e_comp_wl_input_keymap_set(&ctx, &map);
2348 e_comp_wl_input_keymap_set(e_comp_wl_input_keymap_default_rules_get(),
2349 e_comp_wl_input_keymap_default_model_get(),
2350 e_comp_wl_input_keymap_default_layout_get(),
2351 e_comp_wl_input_keymap_default_variant_get(),
2352 e_comp_wl_input_keymap_default_options_get(),
2356 E_API struct xkb_keymap *
2357 e_comp_wl_input_xkb_keymap_get()
2359 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, NULL);
2360 return e_comp_input_key->xkb.keymap;
2363 E_API const Eina_List *
2364 e_comp_wl_input_kbd_resources_get()
2366 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, NULL);
2367 return e_comp_input_key->kbd.resources;
2371 e_comp_wl_input_kbd_repeat_delay_get()
2373 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, -1);
2374 return e_comp_input_key->kbd.repeat_delay;
2378 e_comp_wl_input_kbd_repeat_rate_get()
2380 EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, -1);
2381 return e_comp_input_key->kbd.repeat_rate;