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_pointer_intern.h"
6 #include "e_comp_object_intern.h"
7 #include "e_comp_input_intern.h"
13 #include <relative-pointer-unstable-v1-server-protocol.h>
14 #include <pointer-constraints-unstable-v1-server-protocol.h>
16 #define EXECUTIVE_MODE_ENABLED
18 typedef struct _E_Comp_Wl_Pointer_Constraint E_Comp_Wl_Pointer_Constraint;
20 typedef enum _E_Comp_Wl_Pointer_Constraint_Type
22 E_COMP_WL_POINTER_CONSTRAINT_TYPE_NONE = 0,
23 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK = 1,
24 E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE = 2,
25 } E_Comp_Wl_Pointer_Constraint_Type;
27 struct _E_Comp_Wl_Pointer_Constraint
32 struct wl_resource *surface;
33 struct wl_resource *resource;
34 struct wl_resource *pointer;
37 E_Comp_Wl_Pointer_Constraint_Type type;
40 pixman_region32_t region;
41 pixman_region32_t region_pending;
42 Eina_Bool is_region_pending;
43 Eina_Bool has_region_set;
47 wl_fixed_t hint_x_pending;
48 wl_fixed_t hint_y_pending;
49 Eina_Bool is_hint_pending;
50 Eina_Bool has_hint_set;
52 struct wl_listener pointer_destroy_listener;
53 struct wl_listener surface_unmap_listener;
54 struct wl_listener surface_commit_listener;
55 struct wl_listener surface_mousein_listener;
58 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
59 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
60 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
61 static Eina_Bool use_cache_keymap = EINA_FALSE;
63 static E_Comp_Wl_Hook *_surface_commit_hook = NULL;
65 /* default XKB values from environment variables */
66 static char *_env_e_default_xkb_rules = NULL;
67 static char *_env_e_default_xkb_model = NULL;
68 static char *_env_e_default_xkb_layout = NULL;
69 static char *_env_e_default_xkb_variant = NULL;
70 static char *_env_e_default_xkb_opts = NULL;
73 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
78 _e_comp_wl_input_update_seat_caps(struct wl_client *wc)
81 struct wl_resource *res;
82 enum wl_seat_capability caps = 0;
84 if (e_comp_wl->ptr.enabled)
85 caps |= WL_SEAT_CAPABILITY_POINTER;
86 if (e_comp_wl->kbd.enabled)
87 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
88 if (e_comp_wl->touch.enabled)
89 caps |= WL_SEAT_CAPABILITY_TOUCH;
91 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
93 /* if a wc is null, send seat capability to all wl_seat resources */
94 if (wc && (wl_resource_get_client(res) != wc)) continue;
95 wl_seat_send_capabilities(res, caps);
100 _e_comp_wl_input_pointer_map(struct wl_resource *resource)
104 struct wl_client *wc;
106 if (!(ec = e_client_from_surface_resource(resource))) return;
107 if (e_object_is_del(E_OBJECT(ec))) return;
109 //if cursor ec have external content
110 e_comp_object_content_unset(ec->frame);
112 if (!e_comp_wl->ptr.ec || !e_comp_wl->ptr.ec->comp_data) return;
113 struct wl_resource *surface = e_comp_wl_client_surface_get(e_comp_wl->ptr.ec);
114 if (!surface) return;
116 wc = wl_resource_get_client(resource);
117 if (wc != wl_resource_get_client(surface)) return;
118 if (!e_comp_wl->ptr.ec->pointer_enter_sent) return;
120 if ((ptr = e_comp->pointer))
121 e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
125 _e_comp_wl_input_pointer_configure(struct wl_resource *resource,
126 Evas_Coord x, Evas_Coord y,
127 Evas_Coord w, Evas_Coord h)
131 if (!(ec = e_client_from_surface_resource(resource))) return;
132 if (e_object_is_del(E_OBJECT(ec))) return;
134 e_client_util_resize_without_frame(ec, w, h);
138 _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
140 wl_resource_destroy(resource);
144 _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)
147 Eina_Bool got_mouse = EINA_FALSE;
148 struct wl_resource *surface;
152 if (e_object_is_del(E_OBJECT(ec))) continue;
153 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
154 surface = e_comp_wl_client_surface_get(ec);
155 if (!surface) continue;
156 if (client != wl_resource_get_client(surface)) continue;
157 if (ec->mouse.in && ec->pointer_enter_sent)
159 got_mouse = EINA_TRUE;
165 ELOGF("COMP", "Cursor Set. got_mouse: false", NULL);
168 if (!surface_resource)
170 e_pointer_object_set(e_comp->pointer, NULL, x, y);
171 ec->has_cursor_unset = EINA_TRUE;
175 ec->has_cursor_unset = EINA_FALSE;
177 ec = e_client_from_surface_resource(surface_resource);
185 ec->lock_focus_out = ec->layer_block = ec->visible = 1;
186 if (!e_config->show_cursor)
188 ELOGF("COMP", "Cursor Set. show_cursor: false", ec);
191 ec->icccm.title = eina_stringshare_add("Cursor");
192 e_client_window_role_set(ec, "wl_pointer-cursor");
193 evas_object_pass_events_set(ec->frame, 1);
194 /* wl_pointer-cursor surface is always alpha window */
195 ec->argb = EINA_TRUE;
196 ELOGF("COMP", "Cursor Set. argb:%d", ec, ec->argb);
197 e_comp_object_alpha_set(ec->frame, EINA_TRUE);
200 /* Set fuctions to prevent unwanted handling by shell */
201 ec->comp_data->shell.surface = surface_resource;
202 ec->comp_data->shell.configure = _e_comp_wl_input_pointer_configure;
203 ec->comp_data->shell.map = _e_comp_wl_input_pointer_map;
205 e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
206 ec->is_cursor = EINA_TRUE;
209 /* Set a pointer_object after wl_surface commit
210 * if cursor image is changed,
211 * changed information is sent using attach / damage
212 * So in commit, we can know real current cursor image.
215 /* ignore cursor changes during resize/move I guess */
216 if (e_client_action_get()) return;
217 e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
221 e_comp->pointer->hot.x = x;
222 e_comp->pointer->hot.y = y;
223 if (e_config->show_cursor)
224 ec->visible = EINA_TRUE;
228 static const struct wl_pointer_interface _e_pointer_interface =
230 _e_comp_wl_input_pointer_cb_cursor_set,
231 _e_comp_wl_input_cb_resource_destroy
234 static const struct wl_keyboard_interface _e_keyboard_interface =
236 _e_comp_wl_input_cb_resource_destroy
239 static const struct wl_touch_interface _e_touch_interface =
241 _e_comp_wl_input_cb_resource_destroy
245 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
247 e_comp_wl->ptr.resources =
248 eina_list_remove(e_comp_wl->ptr.resources, resource);
250 wl_signal_emit(&e_comp_wl->ptr_constraints.pointer_destroy_signal, resource);
254 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
256 struct wl_resource *res;
257 struct wl_client *ptr_client = NULL;
258 E_Comp_Wl_Client_Data *cdata = NULL;
260 /* try to create pointer resource */
261 res = wl_resource_create(client, &wl_pointer_interface,
262 wl_resource_get_version(resource), id);
265 ERR("Could not create pointer on seat %s: %m",
266 e_comp_wl->seat.name);
267 wl_client_post_no_memory(client);
271 e_comp_wl->ptr.resources =
272 eina_list_append(e_comp_wl->ptr.resources, res);
273 wl_resource_set_implementation(res, &_e_pointer_interface,
274 e_comp->wl_comp_data,
275 _e_comp_wl_input_cb_pointer_unbind);
277 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)
279 cdata = (E_Comp_Wl_Client_Data*)e_comp_wl->ptr.ec->comp_data;
280 if (cdata && cdata->wl_surface)
281 ptr_client = wl_resource_get_client(cdata->wl_surface);
283 if (ptr_client == client)
285 Evas_Device *last_ptr = NULL, *dev;
287 const char *name, *desc;
289 list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
290 EINA_LIST_FOREACH(list, l, dev)
292 name = evas_device_name_get(dev);
293 desc = evas_device_description_get(dev);
294 if (!name || !desc) continue;
296 if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
297 (!strncmp(desc, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
298 (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
305 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);
311 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
314 struct wl_resource *res;
316 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
318 e_comp_wl->kbd.resources =
319 eina_list_remove(e_comp_wl->kbd.resources, resource);
321 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
323 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
325 EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
327 e_comp_wl->kbd.focused =
328 eina_list_remove_list(e_comp_wl->kbd.focused, l);
330 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
334 e_comp_wl_input_keyboard_enter_send(E_Client *ec)
336 struct wl_resource *res;
339 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
340 xkb_layout_index_t mod_group;
342 struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
343 if (!surface) return;
345 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
347 if (!e_comp_wl->kbd.focused)
349 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
353 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
355 e_comp_wl_input_keyboard_modifiers_serialize();
357 serial = wl_display_next_serial(e_comp_wl->wl.disp);
359 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
360 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
362 mod_depressed = atomic_load(&e_comp_wl->kbd.mod_depressed);
363 mod_latched = atomic_load(&e_comp_wl->kbd.mod_latched);
364 mod_locked = atomic_load(&e_comp_wl->kbd.mod_locked);
366 mod_group = atomic_load(&e_comp_wl->kbd.mod_group);
368 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
370 wl_keyboard_send_enter(res, serial, surface,
371 &e_comp_wl->kbd.keys);
373 wl_keyboard_send_modifiers(res, serial,
379 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
380 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
384 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
387 struct wl_resource *res;
389 /* try to create keyboard resource */
390 res = wl_resource_create(client, &wl_keyboard_interface,
391 wl_resource_get_version(resource), id);
394 ERR("Could not create keyboard on seat %s: %m",
395 e_comp_wl->seat.name);
396 wl_client_post_no_memory(client);
400 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
401 e_comp_wl->kbd.resources =
402 eina_list_append(e_comp_wl->kbd.resources, res);
403 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
404 wl_resource_set_implementation(res, &_e_keyboard_interface,
405 e_comp->wl_comp_data,
406 _e_comp_wl_input_cb_keyboard_unbind);
408 /* send current repeat_info */
409 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
411 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate, e_comp_wl->kbd.repeat_delay);
414 /* send current keymap */
415 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap);
416 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
417 e_comp_input_key->xkb.fd,
418 e_comp_input_key->xkb.size);
421 /* if the client owns the focused surface, we need to send an enter */
422 focused = e_client_focused_get();
423 if ((!focused) || (e_object_is_del(E_OBJECT(focused))) ||
424 (!focused->comp_data)) return;
426 struct wl_resource *surface = e_comp_wl_client_surface_get(focused);
427 if (!surface) return;
429 if (client != wl_resource_get_client(surface)) return;
430 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
431 e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
432 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
434 e_comp_wl_input_keyboard_enter_send(focused);
438 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
440 e_comp_wl->touch.resources =
441 eina_list_remove(e_comp_wl->touch.resources, resource);
445 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
447 struct wl_resource *res;
449 /* try to create pointer resource */
450 res = wl_resource_create(client, &wl_touch_interface,
451 wl_resource_get_version(resource), id);
454 ERR("Could not create touch on seat %s: %m",
455 e_comp_wl->seat.name);
456 wl_client_post_no_memory(client);
460 e_comp_wl->touch.resources =
461 eina_list_append(e_comp_wl->touch.resources, res);
462 wl_resource_set_implementation(res, &_e_touch_interface,
463 e_comp->wl_comp_data,
464 _e_comp_wl_input_cb_touch_unbind);
467 static const struct wl_seat_interface _e_seat_interface =
469 _e_comp_wl_input_cb_pointer_get,
470 _e_comp_wl_input_cb_keyboard_get,
471 _e_comp_wl_input_cb_touch_get,
475 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
477 E_Comp_Wl_Seat *seat = wl_resource_get_user_data(resource);
479 DBG("Unbind seat: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
481 e_comp_wl->seat.resources =
482 eina_list_remove(e_comp_wl->seat.resources, resource);
487 _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
489 struct wl_resource *res;
491 struct wl_resource *tmp_res;
492 E_Comp_Wl_Seat *seat;
494 seat = E_NEW(E_Comp_Wl_Seat, 1);
497 ERR("Failed to allocate memory for seat data\n");
498 wl_client_post_no_memory(client);
501 seat->is_first_resource = 1;
503 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, tmp_res)
505 if (wl_resource_get_client(tmp_res) != client) continue;
506 DBG("wl_seat (res: %d) is already bound to client (%p)",
507 wl_resource_get_id(tmp_res), client);
508 seat->is_first_resource = 0;
512 res = wl_resource_create(client, &wl_seat_interface, version, id);
515 ERR("Could not create seat resource: %m");
519 DBG("Bind seat: %u (client: %p)", wl_resource_get_id(res), client);
521 /* store version of seat interface for reuse in updating capabilities */
522 e_comp_wl->seat.version = version;
523 e_comp_wl->seat.resources =
524 eina_list_append(e_comp_wl->seat.resources, res);
526 wl_resource_set_implementation(res, &_e_seat_interface,
528 _e_comp_wl_input_cb_unbind_seat);
530 _e_comp_wl_input_update_seat_caps(client);
531 if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
532 wl_seat_send_name(res, e_comp_wl->seat.name);
536 _e_comp_wl_input_cb_relative_pointer_destroy(struct wl_client *client,
537 struct wl_resource *resource)
539 wl_resource_destroy(resource);
542 static const struct zwp_relative_pointer_v1_interface _e_relative_pointer_interface = {
543 _e_comp_wl_input_cb_relative_pointer_destroy
547 _e_comp_wl_input_cb_relative_pointer_manager_destroy(struct wl_client *client,
548 struct wl_resource *resource)
550 wl_resource_destroy(resource);
554 _e_comp_wl_input_cb_unbind_relative_pointer(struct wl_resource *resource)
556 e_comp_wl->relative_ptr.resources =
557 eina_list_remove(e_comp_wl->relative_ptr.resources, resource);
561 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer(struct wl_client *client,
562 struct wl_resource *resource,
564 struct wl_resource *pointer_resource)
566 struct wl_resource *res = NULL;
568 res = wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
572 ERR("Could not create the resource for relative pointer: %m");
573 wl_client_post_no_memory(client);
577 e_comp_wl->relative_ptr.resources =
578 eina_list_append(e_comp_wl->relative_ptr.resources, res);
580 /* FIXME: must consider destroying relative pointer together
581 when the wl_pointer is destroyed */
582 (void) pointer_resource;
583 wl_resource_set_implementation(res, &_e_relative_pointer_interface,
584 NULL, _e_comp_wl_input_cb_unbind_relative_pointer);
587 static const struct zwp_relative_pointer_manager_v1_interface _e_relative_pointer_manager_interface = {
588 _e_comp_wl_input_cb_relative_pointer_manager_destroy,
589 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer,
593 _e_comp_wl_input_cb_unbind_relative_pointer_manager(struct wl_resource *resource)
595 e_comp_wl->relative_ptr.manager_resources =
596 eina_list_remove(e_comp_wl->relative_ptr.manager_resources, resource);
600 _e_comp_wl_input_cb_bind_relative_pointer_manager(struct wl_client *client,
601 void *data EINA_UNUSED,
605 struct wl_resource *resource = NULL;
607 resource = wl_resource_create(client, &zwp_relative_pointer_manager_v1_interface, 1, id);
611 ERR("Could not create resource for relative pointer manager: %m");
612 wl_client_post_no_memory(client);
616 e_comp_wl->relative_ptr.manager_resources =
617 eina_list_append(e_comp_wl->relative_ptr.manager_resources, resource);
618 wl_resource_set_implementation(resource, &_e_relative_pointer_manager_interface,
619 NULL, _e_comp_wl_input_cb_unbind_relative_pointer_manager);
623 _e_comp_wl_input_relative_motion_handler(double dx[2], double dy[2], uint64_t time_us)
625 //intended to be empty just for now.
629 _e_comp_wl_input_pointer_constraint_notify_deactivated(E_Comp_Wl_Pointer_Constraint *constraint)
631 struct wl_resource *resource = constraint->resource;
632 E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
634 if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
635 zwp_locked_pointer_v1_send_unlocked(resource);
636 else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
637 zwp_confined_pointer_v1_send_unconfined(resource);
639 ERR("unknown pointer constraint type (%d) !", type);
641 INF("Pointer Constraint deactivated.");
643 if (constraint->ec &&
644 constraint->has_hint_set)
647 INF("Pointer Constraint. Pointer Warp to (%d, %d)", constraint->hint_x, constraint->hint_y);
648 e_input_device_pointer_warp(NULL, constraint->hint_x, constraint->hint_y);
653 _e_comp_wl_input_pointer_constraint_deactivate(E_Comp_Wl_Pointer_Constraint *constraint)
655 constraint->active = EINA_FALSE;
656 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
657 e_comp_wl->ptr_constraints.ec = NULL;
658 e_comp_wl->relative_ptr.activated = EINA_FALSE;
659 e_comp_wl->relative_ptr.ec = NULL;
660 e_input_relative_motion_handler_set(NULL);
661 _e_comp_wl_input_pointer_constraint_notify_deactivated(constraint);
662 wl_list_remove(&constraint->surface_unmap_listener.link);
663 wl_list_init(&constraint->surface_unmap_listener.link);
667 _e_comp_wl_input_pointer_constraint_destroy(E_Comp_Wl_Pointer_Constraint *constraint)
669 if (constraint->active)
670 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
672 wl_list_remove(&constraint->pointer_destroy_listener.link);
673 wl_list_remove(&constraint->surface_unmap_listener.link);
674 wl_list_remove(&constraint->surface_commit_listener.link);
675 wl_list_remove(&constraint->surface_mousein_listener.link);
677 wl_resource_set_user_data(constraint->resource, NULL);
678 pixman_region32_fini(&constraint->region);
679 wl_list_remove(&constraint->link);
685 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
689 pixman_region32_t *region = &constraint->region;
690 pixman_region32_t cregion;
691 pixman_region32_t input_region;
693 pixman_region32_init(&cregion);
694 pixman_region32_init(&input_region);
696 //FIXME: get input_region from ec's input region
697 E_Client *ec = constraint->ec;
698 pixman_region32_init_rect(&input_region, 0, 0, ec->w, ec->h);
699 pixman_region32_intersect(&cregion, &input_region, region);
701 Eina_Bool inside = pixman_region32_contains_point(&cregion,
706 pixman_region32_fini(&cregion);
707 pixman_region32_fini(&input_region);
710 INF("(%d, %d) is not inside of constraint region.", wl_fixed_to_int(fx), wl_fixed_to_int(fy));
716 _e_comp_wl_input_pointer_constraint_notify_activated(E_Comp_Wl_Pointer_Constraint *constraint)
718 struct wl_resource *resource = constraint->resource;
719 E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
721 if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
722 zwp_locked_pointer_v1_send_locked(resource);
723 else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
724 zwp_confined_pointer_v1_send_confined(resource);
726 ERR("unknown pointer constraint type (%d) !", type);
728 INF("Pointer Constraint activated.");
732 _e_comp_wl_input_pointer_constraint_enable(E_Comp_Wl_Pointer_Constraint *constraint)
734 if (constraint->active)
736 ERR("ERROR! Pointer constraint has been activated already !");
740 constraint->active = EINA_TRUE;
741 E_Client *ec = constraint->ec;
742 e_comp_wl->ptr_constraints.activated = EINA_TRUE;
743 e_comp_wl->ptr_constraints.ec = ec;
744 e_comp_wl->relative_ptr.activated = EINA_TRUE;
745 e_comp_wl->relative_ptr.ec = ec;
746 _e_comp_wl_input_pointer_constraint_notify_activated(constraint);
747 wl_signal_add(&e_comp_wl->ptr_constraints.surface_unmap_signal,
748 &constraint->surface_unmap_listener);
749 if (!e_input_relative_motion_handler_set(_e_comp_wl_input_relative_motion_handler))
750 ERR("ERROR! Could not set relative motion handler !");
752 E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
756 _e_comp_wl_input_pointer_constraints_check_enable(E_Comp_Wl_Pointer_Constraint *constraint)
758 if (!constraint || !constraint->ec)
760 ERR("Invalid constraint or ec of it.");
764 E_Client *ec = constraint->ec;
765 wl_fixed_t cx = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
766 wl_fixed_t cy = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
768 if ((!e_comp_wl->ptr.ec) || (e_comp_wl->ptr.ec != ec)
769 || (!ec->pointer_enter_sent))
772 if (!_e_comp_wl_input_is_position_inside_constraint_region(constraint,
777 _e_comp_wl_input_pointer_constraint_enable(constraint);
781 _e_comp_wl_input_pointer_constraint_disable(E_Comp_Wl_Pointer_Constraint *constraint)
783 int lifetime = constraint->lifetime;
785 if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT)
786 _e_comp_wl_input_pointer_constraint_destroy(constraint);
787 else if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT)
788 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
790 ERR("unknown pointer constraint lifetime (%d) !", lifetime);
794 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed(struct wl_listener *listener,
797 struct wl_resource *pointer_resource = (struct wl_resource *)data;
798 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
799 E_Comp_Wl_Pointer_Constraint,
800 pointer_destroy_listener);
802 if (pointer_resource == constraint->pointer)
803 _e_comp_wl_input_pointer_constraint_destroy(constraint);
807 _e_comp_wl_input_cb_pointer_constraints_surface_committed(struct wl_listener *listener,
810 E_Client *ec = (E_Client *)data;
811 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
812 E_Comp_Wl_Pointer_Constraint,
813 surface_commit_listener);
816 if (ec != constraint->ec)
819 if (constraint->is_hint_pending)
821 constraint->is_hint_pending = EINA_FALSE;
823 new_x = ec->client.x + wl_fixed_to_int(constraint->hint_x_pending);
824 new_y = ec->client.y + wl_fixed_to_int(constraint->hint_y_pending);
826 if (e_client_transform_core_enable_get(ec))
828 e_comp_wl_map_inv_coord_get(ec, new_x, new_y, &constraint->hint_x, &constraint->hint_y);
829 WRN("Pointer Constraint. Committed. hint (%d, %d) -> map_inv_coord (%d, %d)",
830 new_x, new_y, constraint->hint_x, constraint->hint_y);
834 constraint->hint_x = new_x;
835 constraint->hint_y = new_y;
836 WRN("Pointer Constraint. Committed. hint (%d, %d)",
837 constraint->hint_x, constraint->hint_y);
840 // Workaround: Feed mouse out/in to make sure that mouse in to correct client.
841 // Since Mouse move event doesn't generate mouse in/out if mouse(input) is grabbed,
842 // ungrab input before warping a pointer to cursor position hint.
843 e_comp_ungrab_input(1,1);
846 if (constraint->is_region_pending)
848 constraint->is_region_pending = EINA_FALSE;
849 pixman_region32_copy(&constraint->region,
850 &constraint->region_pending);
851 pixman_region32_fini(&constraint->region_pending);
852 pixman_region32_init(&constraint->region_pending);
855 //CHECKME: check if the updated region can take effect on the given constraint
859 _e_comp_wl_input_cb_pointer_constraints_surface_mousein(struct wl_listener *listener,
862 E_Client *ec = (E_Client *)data;
863 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
864 E_Comp_Wl_Pointer_Constraint,
865 surface_mousein_listener);
867 Eina_Bool found = EINA_FALSE;
868 E_Comp_Wl_Pointer_Constraint *tmp_constraint;
869 wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
871 if (tmp_constraint == constraint)
878 if (found && !constraint->active)
879 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
880 else if (!found && constraint->active)
881 _e_comp_wl_input_pointer_constraint_disable(constraint);
885 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped(struct wl_listener *listener,
888 E_Client *ec = (E_Client *)data;
889 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
890 E_Comp_Wl_Pointer_Constraint,
891 surface_unmap_listener);
893 if (ec == constraint->ec)
894 _e_comp_wl_input_pointer_constraint_disable(constraint);
897 static E_Comp_Wl_Pointer_Constraint *
898 _e_comp_wl_input_pointer_constraint_create(E_Client *ec,
899 struct wl_resource *resource,
900 struct wl_resource *pointer,
901 struct wl_resource *region_resource,
902 enum zwp_pointer_constraints_v1_lifetime lifetime,
903 E_Comp_Wl_Pointer_Constraint_Type type)
905 E_Comp_Wl_Pointer_Constraint *constraint;
907 constraint = E_NEW(E_Comp_Wl_Pointer_Constraint, 1);
911 ERR("Could not allocate memory for pointer constraint: %m");
915 constraint->active = EINA_FALSE;
917 constraint->lifetime = lifetime;
918 constraint->type = type;
919 constraint->pointer = pointer;
920 constraint->resource = resource;
921 constraint->surface = e_comp_wl_client_surface_get(ec);
922 wl_list_init(&constraint->link);
923 wl_list_insert(&ec->comp_data->pointer_constraints, &constraint->link);
924 pixman_region32_init(&constraint->region);
925 pixman_region32_init(&constraint->region_pending);
929 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
932 pixman_region32_copy(&constraint->region, region);
933 constraint->has_region_set = EINA_TRUE;
937 //CHECKME: check whether this situation is a kind of bug
938 ERR("Invalid pixman_region from region (pointer constraint region!");
939 pixman_region32_fini(&constraint->region);
940 pixman_region32_init_rect(&constraint->region,
941 INT32_MIN, INT32_MIN,
942 UINT32_MAX, UINT32_MAX);
947 pixman_region32_fini(&constraint->region);
948 pixman_region32_init_rect(&constraint->region,
949 INT32_MIN, INT32_MIN,
950 UINT32_MAX, UINT32_MAX);
951 constraint->has_region_set = EINA_TRUE;
954 ERR("Pointer Constraint created.");
956 constraint->pointer_destroy_listener.notify =
957 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed;
958 constraint->surface_commit_listener.notify =
959 _e_comp_wl_input_cb_pointer_constraints_surface_committed;
960 constraint->surface_unmap_listener.notify =
961 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped;
962 constraint->surface_mousein_listener.notify =
963 _e_comp_wl_input_cb_pointer_constraints_surface_mousein;
965 wl_signal_add(&e_comp_wl->ptr_constraints.pointer_destroy_signal,
966 &constraint->pointer_destroy_listener);
967 wl_signal_add(&e_comp_wl->ptr_constraints.surface_commit_signal,
968 &constraint->surface_commit_listener);
969 wl_signal_add(&e_comp_wl->ptr_constraints.surface_mousein_signal,
970 &constraint->surface_mousein_listener);
971 wl_list_init(&constraint->surface_unmap_listener.link);
977 _e_comp_wl_input_has_pointer_constraints_for_pointer(E_Client *ec, struct wl_resource *pointer)
979 E_Comp_Wl_Pointer_Constraint *constraint;
981 wl_list_for_each(constraint, &ec->comp_data->pointer_constraints, link)
983 if (constraint->pointer == pointer)
991 _e_comp_wl_input_cb_unbind_locked_pointer(struct wl_resource *resource)
993 E_Comp_Wl_Pointer_Constraint *constraint;
994 constraint = wl_resource_get_user_data(resource);
999 _e_comp_wl_input_pointer_constraint_destroy(constraint);
1003 _e_comp_wl_input_cb_locked_pointer_destroy(struct wl_client *client,
1004 struct wl_resource *resource)
1006 wl_resource_destroy(resource);
1010 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint(struct wl_client *client,
1011 struct wl_resource *resource,
1012 wl_fixed_t surface_x,
1013 wl_fixed_t surface_y)
1015 E_Comp_Wl_Pointer_Constraint *constraint =
1016 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1021 constraint->hint_x_pending = surface_x;
1022 constraint->hint_y_pending = surface_y;
1023 constraint->is_hint_pending = EINA_TRUE;
1024 constraint->has_hint_set = EINA_TRUE;
1028 _e_comp_wl_input_cb_locked_pointer_set_region(struct wl_client *client,
1029 struct wl_resource *resource,
1030 struct wl_resource *region_resource)
1032 E_Comp_Wl_Pointer_Constraint *constraint =
1033 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1038 if (region_resource)
1040 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
1044 pixman_region32_copy(&constraint->region_pending, region);
1048 //CHECKME: check whether this situation is a kind of bug
1049 ERR("Invalid pixman_region from region (pointer constraint region!");
1050 pixman_region32_fini(&constraint->region_pending);
1051 pixman_region32_init_rect(&constraint->region_pending,
1052 INT32_MIN, INT32_MIN,
1053 UINT32_MAX, UINT32_MAX);
1056 constraint->has_region_set = EINA_TRUE;
1060 pixman_region32_fini(&constraint->region_pending);
1061 pixman_region32_init_rect(&constraint->region_pending,
1062 INT32_MIN, INT32_MIN,
1063 UINT32_MAX, UINT32_MAX);
1066 constraint->is_region_pending = EINA_TRUE;
1069 static const struct zwp_locked_pointer_v1_interface _e_comp_wl_locked_pointer_interface =
1071 _e_comp_wl_input_cb_locked_pointer_destroy,
1072 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint,
1073 _e_comp_wl_input_cb_locked_pointer_set_region,
1077 _e_comp_wl_input_cb_pointer_constraints_lock_pointer(struct wl_client *client,
1078 struct wl_resource *resource,
1080 struct wl_resource *surface,
1081 struct wl_resource *pointer,
1082 struct wl_resource *region,
1085 if (!pointer || !surface)
1087 ERR("Pointer resource or surface resource is invalid !");
1091 E_Client *ec = e_client_from_surface_resource(surface);
1095 ERR("Could not get ec from surface resource !");
1099 if (_e_comp_wl_input_has_pointer_constraints_for_pointer(ec, pointer))
1101 ERR("Pointer constraints has been created already (ec: %p, pointer_resource: %u)",
1102 ec, wl_resource_get_id(resource));
1103 wl_resource_post_error(resource,
1104 ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
1105 "the pointer has a lock set already on this surface");
1109 struct wl_resource *res;
1110 res = wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
1114 ERR("Could not create a resource for pointer constraints lock: %m");
1115 wl_client_post_no_memory(client);
1119 E_Comp_Wl_Pointer_Constraint *constraint;
1120 constraint = _e_comp_wl_input_pointer_constraint_create(ec, res, pointer, region, lifetime,
1121 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK);
1125 ERR("Could not create a pointer constraint.");
1126 wl_resource_destroy(res);
1127 wl_client_post_no_memory(client);
1131 wl_resource_set_implementation(res, &_e_comp_wl_locked_pointer_interface,
1132 constraint, _e_comp_wl_input_cb_unbind_locked_pointer);
1134 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
1138 _e_comp_wl_input_cb_pointer_constraints_confine_pointer(struct wl_client *client,
1139 struct wl_resource *resource,
1141 struct wl_resource *surface,
1142 struct wl_resource *pointer,
1143 struct wl_resource *region,
1154 /* TODO: pointer constraints confine */
1158 _e_comp_wl_input_cb_pointer_constraints_destroy(struct wl_client *client,
1159 struct wl_resource *resource)
1161 wl_resource_destroy(resource);
1164 static const struct zwp_pointer_constraints_v1_interface _e_pointer_constraints_interface = {
1165 _e_comp_wl_input_cb_pointer_constraints_destroy,
1166 _e_comp_wl_input_cb_pointer_constraints_lock_pointer,
1167 _e_comp_wl_input_cb_pointer_constraints_confine_pointer,
1171 _e_comp_wl_input_cb_unbind_pointer_constraints(struct wl_resource *resource)
1173 e_comp_wl->ptr_constraints.resources =
1174 eina_list_remove(e_comp_wl->ptr_constraints.resources, resource);
1178 _e_comp_wl_input_cb_bind_pointer_constraints(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
1180 struct wl_resource *resource;
1182 resource = wl_resource_create(client, &zwp_pointer_constraints_v1_interface, version, id);
1186 ERR("Could not create pointer constraints resource: %m");
1190 e_comp_wl->ptr_constraints.resources =
1191 eina_list_append(e_comp_wl->ptr_constraints.resources, resource);
1192 wl_resource_set_implementation(resource, &_e_pointer_constraints_interface,
1193 NULL, _e_comp_wl_input_cb_unbind_pointer_constraints);
1197 _e_comp_wl_input_cb_surface_commit(void *data EINA_UNUSED, E_Client *ec)
1199 wl_signal_emit(&e_comp_wl->ptr_constraints.surface_commit_signal, ec);
1203 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
1206 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
1208 if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
1216 if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
1218 WRN("%s is maybe link, so delete it\n", keymap_path);
1221 file = fopen(keymap_path, "w");
1222 EINA_SAFETY_ON_NULL_RETURN(file);
1224 if (fputs(keymap_data, file) < 0)
1226 WRN("Failed to write keymap file: %s\n", keymap_path);
1228 unlink(keymap_path);
1232 INF("Success to make keymap file: %s\n", keymap_path);
1240 _e_comp_wl_input_keymap_fd_get(off_t size)
1242 int fd = 0, blen = 0, len = 0;
1244 char tmp[PATH_MAX] = {0, };
1248 blen = sizeof(tmp) - 20;
1250 path = e_util_env_get("XDG_RUNTIME_DIR");
1251 if (!path) return -1;
1253 len = strlen(path) + 19;
1256 strncpy(tmp, path, PATH_MAX - 20);
1257 strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
1266 old_umask = umask(S_IRWXG|S_IRWXO);
1270 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
1272 flags = fcntl(fd, F_GETFD);
1279 if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
1285 if (ftruncate(fd, size) < 0)
1296 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1299 xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1300 struct wl_resource *res;
1303 /* unreference any existing keymap */
1304 if (e_comp_input_key->xkb.keymap)
1305 xkb_map_unref(e_comp_input_key->xkb.keymap);
1307 /* unmap any existing keyboard area */
1308 if (e_comp_input_key->xkb.area)
1309 munmap(e_comp_input_key->xkb.area, e_comp_input_key->xkb.size);
1310 if (e_comp_input_key->xkb.fd >= 0) close(e_comp_input_key->xkb.fd);
1312 /* unreference any existing keyboard state */
1313 if (e_comp_input_key->xkb.state)
1316 xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1317 XKB_STATE_MODS_LATCHED);
1319 xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1320 XKB_STATE_MODS_LOCKED);
1322 xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1323 XKB_STATE_LAYOUT_EFFECTIVE);
1324 xkb_state_unref(e_comp_input_key->xkb.state);
1327 /* create a new xkb state */
1328 e_comp_input_key->xkb.state = xkb_state_new(keymap);
1330 if (!e_comp_input_key->xkb.state)
1335 if ((latched) || (locked) || (group))
1336 xkb_state_update_mask(e_comp_input_key->xkb.state, 0,
1337 latched, locked, 0, 0, group);
1339 /* increment keymap reference */
1340 e_comp_input_key->xkb.keymap = keymap;
1342 /* fetch updated modifiers */
1343 e_comp_wl->kbd.mod_shift =
1344 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1345 e_comp_wl->kbd.mod_caps =
1346 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1347 e_comp_wl->kbd.mod_ctrl =
1348 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1349 e_comp_wl->kbd.mod_alt =
1350 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1351 e_comp_wl->kbd.mod_super =
1352 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1354 if (!(tmp = xkb_map_get_as_string(keymap)))
1356 ERR("Could not get keymap string");
1360 e_comp_input_key->xkb.size = strlen(tmp) + 1;
1361 e_comp_input_key->xkb.fd =
1362 _e_comp_wl_input_keymap_fd_get(e_comp_input_key->xkb.size);
1363 if (e_comp_input_key->xkb.fd < 0)
1365 ERR("Could not create keymap file");
1370 _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
1372 e_comp_input_key->xkb.area =
1373 mmap(NULL, e_comp_input_key->xkb.size, (PROT_READ | PROT_WRITE),
1374 MAP_SHARED, e_comp_input_key->xkb.fd, 0);
1375 if (e_comp_input_key->xkb.area == MAP_FAILED)
1377 ERR("Failed to mmap keymap area: %m");
1382 strncpy(e_comp_input_key->xkb.area, tmp, e_comp_input_key->xkb.size);
1385 /* send updated keymap */
1386 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
1387 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1388 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1389 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1390 e_comp_input_key->xkb.fd,
1391 e_comp_input_key->xkb.size);
1392 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1395 /* update modifiers */
1396 e_comp_wl_input_keyboard_modifiers_update();
1400 e_comp_wl_input_init(void)
1402 /* set default seat name */
1403 if (!e_comp_wl->seat.name)
1404 e_comp_wl->seat.name = "default";
1406 e_comp_input_init();
1408 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1409 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1411 g_mutex_init(&e_comp_wl->kbd.resource_mutex);
1412 g_mutex_init(&e_comp_wl->kbd.focused_mutex);
1413 g_mutex_init(&e_comp_wl->kbd.keys_mutex);
1414 g_mutex_init(&e_comp_wl->kbd.repeat_delay_mutex);
1415 g_mutex_init(&e_comp_wl->kbd.repeat_rate_mutex);
1417 /* get default keyboard repeat delay from configuration */
1418 atomic_store(&e_comp_wl->kbd.repeat_delay, e_config->keyboard.repeat_delay);
1419 /* check for valid repeat_delay */
1420 /* if invalid, set the default value of repeat delay */
1421 if (e_comp_wl->kbd.repeat_delay < 0)
1422 atomic_store(&e_comp_wl->kbd.repeat_delay, 400);
1424 /* get default keyboard repeat rate from configuration */
1425 atomic_store(&e_comp_wl->kbd.repeat_rate, e_config->keyboard.repeat_rate);
1426 /* check for valid repeat_rate value */
1427 /* if invalid, set the default value of repeat rate value */
1428 if (e_comp_wl->kbd.repeat_rate < 0)
1429 atomic_store(&e_comp_wl->kbd.repeat_rate, 25);
1431 /* create the global resource for input seat */
1432 e_comp_wl->seat.global =
1433 wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
1434 e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
1435 if (!e_comp_wl->seat.global)
1437 ERR("Could not create global for seat: %m");
1441 /* create the global resource for relative pointer */
1442 e_comp_wl->relative_ptr.global =
1443 wl_global_create(e_comp_wl->wl.disp,
1444 &zwp_relative_pointer_manager_v1_interface, 1,
1445 e_comp->wl_comp_data,
1446 _e_comp_wl_input_cb_bind_relative_pointer_manager);
1447 if (!e_comp_wl->relative_ptr.global)
1449 ERR("Could not create global for relative pointer: %m");
1453 /* create the global resource for pointer-constraints */
1454 e_comp_wl->ptr_constraints.global =
1455 wl_global_create(e_comp_wl->wl.disp,
1456 &zwp_pointer_constraints_v1_interface, 1,
1457 e_comp->wl_comp_data,
1458 _e_comp_wl_input_cb_bind_pointer_constraints);
1459 if (!e_comp_wl->ptr_constraints.global)
1461 ERR("Could not create global for pointer constraints: %m");
1465 e_comp_wl->ptr_constraints.ec = NULL;
1466 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
1467 wl_signal_init(&e_comp_wl->ptr_constraints.pointer_destroy_signal);
1468 wl_signal_init(&e_comp_wl->ptr_constraints.surface_unmap_signal);
1469 wl_signal_init(&e_comp_wl->ptr_constraints.surface_commit_signal);
1470 wl_signal_init(&e_comp_wl->ptr_constraints.surface_mousein_signal);
1472 _surface_commit_hook = e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
1473 _e_comp_wl_input_cb_surface_commit,
1476 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1477 wl_array_init(&e_comp_wl->kbd.keys);
1478 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1480 wl_array_init(&e_comp_wl->kbd.routed_keys);
1482 E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
1484 /* get string values from environment variables */
1485 _env_e_default_xkb_rules = e_util_env_get("E_DEFAULT_XKB_RULES" );
1486 _env_e_default_xkb_model = e_util_env_get("E_DEFAULT_XKB_MODEL" );
1487 _env_e_default_xkb_layout = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
1488 _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
1489 _env_e_default_xkb_opts = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
1495 e_comp_wl_input_shutdown(void)
1497 struct wl_resource *res;
1499 /* free environment variable string */
1500 E_FREE(_env_e_default_xkb_rules );
1501 E_FREE(_env_e_default_xkb_model );
1502 E_FREE(_env_e_default_xkb_layout );
1503 E_FREE(_env_e_default_xkb_variant);
1504 E_FREE(_env_e_default_xkb_opts );
1506 /* delete surface commit hook */
1507 if (_surface_commit_hook)
1509 e_comp_wl_hook_del(_surface_commit_hook);
1510 _surface_commit_hook = NULL;
1513 /* destroy pointer resources */
1514 EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
1515 wl_resource_destroy(res);
1517 /* destroy relative pointer resources */
1518 EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
1519 wl_resource_destroy(res);
1521 /* destroy relative pointer manager resources */
1522 EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
1523 wl_resource_destroy(res);
1525 /* destroy pointer constraints resources */
1526 EINA_LIST_FREE(e_comp_wl->ptr_constraints.resources, res)
1527 wl_resource_destroy(res);
1529 /* destroy keyboard resources */
1530 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1531 EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
1532 wl_resource_destroy(res);
1533 e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
1534 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1536 g_mutex_clear(&e_comp_wl->kbd.resource_mutex);
1537 g_mutex_clear(&e_comp_wl->kbd.focused_mutex);
1539 /* destroy touch resources */
1540 EINA_LIST_FREE(e_comp_wl->touch.resources, res)
1541 wl_resource_destroy(res);
1543 /* destroy e_comp_wl->kbd.keys array */
1544 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1545 wl_array_release(&e_comp_wl->kbd.keys);
1546 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1548 wl_array_release(&e_comp_wl->kbd.routed_keys);
1550 e_comp_input_shutdown();
1552 /* destroy the global relative pointer resource */
1553 if (e_comp_wl->relative_ptr.global)
1554 wl_global_destroy(e_comp_wl->relative_ptr.global);
1555 e_comp_wl->relative_ptr.global = NULL;
1557 /* destroy the global pointer constraints resource */
1558 if (e_comp_wl->ptr_constraints.global)
1559 wl_global_destroy(e_comp_wl->ptr_constraints.global);
1560 e_comp_wl->ptr_constraints.global = NULL;
1562 /* destroy the global seat resource */
1563 if (e_comp_wl->seat.global)
1564 wl_global_destroy(e_comp_wl->seat.global);
1565 e_comp_wl->seat.global = NULL;
1567 dont_set_e_input_keymap = EINA_FALSE;
1568 dont_use_xkb_cache = EINA_FALSE;
1570 g_mutex_clear(&e_comp_wl->kbd.keys_mutex);
1571 g_mutex_clear(&e_comp_wl->kbd.repeat_delay_mutex);
1572 g_mutex_clear(&e_comp_wl->kbd.repeat_rate_mutex);
1576 e_comp_wl_input_pointer_check(struct wl_resource *res)
1578 return wl_resource_instance_of(res, &wl_pointer_interface,
1579 &_e_pointer_interface);
1583 e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
1585 return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
1586 &_e_relative_pointer_interface);
1590 e_comp_wl_input_keyboard_check(struct wl_resource *res)
1592 return wl_resource_instance_of(res, &wl_keyboard_interface,
1593 &_e_keyboard_interface);
1597 e_comp_wl_input_keyboard_modifiers_serialize(void)
1599 Eina_Bool changed = EINA_FALSE;
1601 xkb_layout_index_t grp;
1603 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
1604 xkb_layout_index_t mod_group;
1606 mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1607 XKB_STATE_DEPRESSED);
1608 mod_depressed = atomic_load(&e_comp_wl->kbd.mod_depressed);
1609 changed |= mod != mod_depressed;
1610 atomic_store(&e_comp_wl->kbd.mod_depressed, mod);
1612 mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1613 XKB_STATE_MODS_LATCHED);
1615 mod_latched = atomic_load(&e_comp_wl->kbd.mod_latched);
1616 changed |= mod != mod_latched;
1617 atomic_store(&e_comp_wl->kbd.mod_latched, mod);
1619 mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1620 XKB_STATE_MODS_LOCKED);
1621 mod_locked = atomic_load(&e_comp_wl->kbd.mod_locked);
1622 changed |= mod != mod_locked;
1623 atomic_store(&e_comp_wl->kbd.mod_locked, mod);
1625 grp = xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1626 XKB_STATE_LAYOUT_EFFECTIVE);
1627 mod_group = atomic_load(&e_comp_wl->kbd.mod_group);
1628 changed |= grp != mod_group;
1629 atomic_store(&e_comp_wl->kbd.mod_group, grp);
1635 e_comp_wl_input_keyboard_modifiers_update(void)
1638 struct wl_resource *res;
1641 if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
1642 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1643 if (!e_comp_wl->kbd.focused)
1645 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1649 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1651 serial = wl_display_next_serial(e_comp_wl->wl.disp);
1652 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1653 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
1654 wl_keyboard_send_modifiers(res, serial,
1655 e_comp_wl->kbd.mod_depressed,
1656 e_comp_wl->kbd.mod_latched,
1657 e_comp_wl->kbd.mod_locked,
1658 e_comp_wl->kbd.mod_group);
1659 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1663 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
1665 enum xkb_key_direction dir;
1667 if (!e_comp_input_key->xkb.state)
1672 if (pressed) dir = XKB_KEY_DOWN;
1673 else dir = XKB_KEY_UP;
1675 atomic_store(&e_comp_wl->kbd.mod_changed, xkb_state_update_key(e_comp_input_key->xkb.state, keycode + 8, dir));
1677 e_comp_wl_input_keyboard_modifiers_update();
1681 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
1683 /* check for valid compositor data */
1684 if (!e_comp->wl_comp_data)
1686 ERR("No compositor data");
1690 e_comp_wl->ptr.enabled = !!enabled;
1691 _e_comp_wl_input_update_seat_caps(NULL);
1695 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
1697 /* check for valid compositor data */
1698 if (!e_comp->wl_comp_data)
1700 ERR("No compositor data");
1704 e_comp_wl->kbd.enabled = !!enabled;
1705 _e_comp_wl_input_update_seat_caps(NULL);
1709 e_comp_wl_input_keymap_cache_file_use_get(void)
1711 return use_cache_keymap;
1714 E_API Eina_Stringshare *
1715 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
1717 return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
1718 names.rules ? names.rules : "evdev",
1719 names.model ? names.model : "pc105",
1720 names.layout ? names.layout : "us",
1721 names.variant ? names.variant : "",
1722 names.options ? names.options : "");
1725 EINTERN struct xkb_keymap *
1726 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
1728 struct xkb_keymap *keymap;
1729 char *cache_path = NULL;
1732 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1734 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
1736 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1738 cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
1739 file = fopen(cache_path, "r");
1744 INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
1746 /* fetch new keymap based on names */
1747 keymap = xkb_map_new_from_names(ctx, &names, 0);
1748 use_cache_keymap = EINA_FALSE;
1752 INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
1753 keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1756 WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
1758 if (remove(cache_path) != 0)
1759 WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
1760 keymap = xkb_map_new_from_names(ctx, &names, 0);
1761 use_cache_keymap = EINA_FALSE;
1765 eina_stringshare_del(cache_path);
1768 use_cache_keymap = EINA_TRUE;
1772 *keymap_path = cache_path;
1773 EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
1781 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
1782 const char *variant, const char *options,
1783 struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
1785 struct xkb_keymap *keymap;
1786 struct xkb_rule_names names;
1787 char *keymap_path = NULL;
1788 Eina_Bool use_dflt_xkb = EINA_FALSE;
1789 const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
1791 /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
1792 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
1794 if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
1796 /* unreference any existing context */
1797 if (e_comp_input_key->xkb.context)
1798 xkb_context_unref(e_comp_input_key->xkb.context);
1800 /* create a new xkb context */
1801 if (use_dflt_xkb) e_comp_input_key->xkb.context = dflt_ctx;
1802 else e_comp_input_key->xkb.context = xkb_context_new(0);
1804 if (!e_comp_input_key->xkb.context)
1810 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1811 e_input_device_keyboard_cached_context_set(e_comp_input_key->xkb.context);
1813 /* assemble xkb_rule_names so we can fetch keymap */
1814 memset(&names, 0, sizeof(names));
1815 if (rules) names.rules = strdup(rules);
1818 default_rules = e_comp_wl_input_keymap_default_rules_get();
1819 names.rules = strdup(default_rules);
1821 if (model) names.model = strdup(model);
1824 default_model = e_comp_wl_input_keymap_default_model_get();
1825 names.model = strdup(default_model);
1827 if (layout) names.layout = strdup(layout);
1830 default_layout = e_comp_wl_input_keymap_default_layout_get();
1831 names.layout = strdup(default_layout);
1833 if (variant) names.variant = strdup(variant);
1836 default_variant = e_comp_wl_input_keymap_default_variant_get();
1837 if (default_variant) names.variant = strdup(default_variant);
1839 if (options) names.options = strdup(options);
1842 default_options = e_comp_wl_input_keymap_default_options_get();
1843 if (default_options) names.options = strdup(default_options);
1846 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
1850 keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
1851 if (access(keymap_path, R_OK) == 0)
1853 eina_stringshare_del(keymap_path);
1858 keymap = e_comp_wl_input_keymap_compile(e_comp_input_key->xkb.context, names, &keymap_path);
1861 /* update compositor keymap */
1862 _e_comp_wl_input_keymap_update(keymap, keymap_path);
1864 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1865 e_input_device_keyboard_cached_keymap_set(keymap);
1868 if (keymap_path) eina_stringshare_del(keymap_path);
1869 free((char *)names.rules);
1870 free((char *)names.model);
1871 free((char *)names.layout);
1872 if (names.variant) free((char *)names.variant);
1873 if (names.options) free((char *)names.options);
1878 e_comp_wl_input_keymap_default_rules_get(void)
1880 if (e_config->xkb.default_rmlvo.rules)
1881 return e_config->xkb.default_rmlvo.rules;
1883 if (_env_e_default_xkb_rules)
1884 return _env_e_default_xkb_rules;
1890 e_comp_wl_input_keymap_default_model_get(void)
1892 if (e_config->xkb.default_rmlvo.model)
1893 return e_config->xkb.default_rmlvo.model;
1895 if (_env_e_default_xkb_model)
1896 return _env_e_default_xkb_model;
1902 e_comp_wl_input_keymap_default_layout_get(void)
1904 if (e_config->xkb.default_rmlvo.layout)
1905 return e_config->xkb.default_rmlvo.layout;
1907 if (_env_e_default_xkb_layout)
1908 return _env_e_default_xkb_layout;
1914 e_comp_wl_input_keymap_default_variant_get(void)
1916 if (e_config->xkb.default_rmlvo.variant)
1917 return e_config->xkb.default_rmlvo.variant;
1919 if (_env_e_default_xkb_variant)
1920 return _env_e_default_xkb_variant;
1926 e_comp_wl_input_keymap_default_options_get(void)
1928 if (e_config->xkb.default_rmlvo.options)
1929 return e_config->xkb.default_rmlvo.options;
1931 if (_env_e_default_xkb_opts)
1932 return _env_e_default_xkb_opts;
1938 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
1940 /* check for valid compositor data */
1941 if (!e_comp->wl_comp_data)
1943 ERR("No compositor data");
1947 e_comp_wl->touch.enabled = !!enabled;
1948 _e_comp_wl_input_update_seat_caps(NULL);
1952 e_comp_wl_input_seat_caps_set(unsigned int caps)
1954 Eina_Bool need_update = EINA_FALSE;
1956 /* check for valid compositor data */
1957 if (!e_comp->wl_comp_data)
1959 ERR("No compositor data");
1963 if (caps & E_INPUT_SEAT_POINTER)
1964 e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
1965 if (caps & E_INPUT_SEAT_KEYBOARD)
1966 e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
1967 if (caps & E_INPUT_SEAT_TOUCH)
1968 e_comp_wl->touch.enabled = need_update = EINA_TRUE;
1971 _e_comp_wl_input_update_seat_caps(NULL);
1975 e_comp_wl_input_touch_check(struct wl_resource *res)
1977 return wl_resource_instance_of(res, &wl_touch_interface,
1978 &_e_touch_interface);
1982 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
1984 struct wl_resource *res;
1987 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
1989 atomic_store(&e_comp_wl->kbd.repeat_delay, delay);
1990 atomic_store(&e_comp_wl->kbd.repeat_rate, rate);
1992 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1993 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1995 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
1996 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate,
1997 e_comp_wl->kbd.repeat_delay);
2000 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
2003 typedef struct _keycode_map{
2004 xkb_keysym_t keysym;
2005 xkb_keycode_t keycode;
2009 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2011 keycode_map *found_keycodes = (keycode_map *)data;
2012 xkb_keysym_t keysym = found_keycodes->keysym;
2014 const xkb_keysym_t *syms_out = NULL;
2016 nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2017 if (nsyms && syms_out)
2019 if (*syms_out == keysym)
2021 found_keycodes->keycode = key;
2027 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
2029 keycode_map found_keycodes = {0,};
2030 found_keycodes.keysym = keysym;
2031 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2033 return found_keycodes.keycode;
2037 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
2039 struct xkb_keymap *keymap = NULL;
2040 xkb_keysym_t keysym = 0x0;
2044 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
2045 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
2047 keymap = e_comp_input_key->xkb.keymap;
2048 EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
2050 keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
2051 if (keysym == XKB_KEY_NoSymbol)
2053 if (strlen(name) <= sizeof("Keycode-")) goto finish;
2055 if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
2057 name_tmp = (char *)name + sizeof("Keycode-") - 1;
2058 keycode = atoi(name_tmp);
2059 if (keycode <= 8) goto finish;
2067 keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
2076 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
2078 struct xkb_state *state;
2079 xkb_keysym_t sym = XKB_KEY_NoSymbol;
2080 char name[256] = {0, };
2082 EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
2083 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
2084 if (!e_comp_input_key->xkb.state)
2089 state = e_comp_input_key->xkb.state;
2091 sym = xkb_state_key_get_one_sym(state, keycode);
2093 if (sym == XKB_KEY_NoSymbol)
2095 snprintf(name, sizeof(name), "Keycode-%u", keycode);
2098 xkb_keysym_get_name(sym, name, sizeof(name));
2100 return strdup(name);
2104 _e_comp_wl_input_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
2106 char *keymap_path = NULL;
2107 struct xkb_context *context;
2108 struct xkb_keymap *keymap;
2109 struct xkb_rule_names names = {0,};
2110 const char* default_rules, *default_model, *default_layout, *default_variant, *default_options;
2112 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_set);
2114 context = xkb_context_new(0);
2115 EINA_SAFETY_ON_NULL_RETURN(context);
2117 /* assemble xkb_rule_names so we can fetch keymap */
2118 memset(&names, 0, sizeof(names));
2120 default_rules = e_comp_wl_input_keymap_default_rules_get();
2121 default_model = e_comp_wl_input_keymap_default_model_get();
2122 default_layout = e_comp_wl_input_keymap_default_layout_get();
2123 default_variant = e_comp_wl_input_keymap_default_variant_get();
2124 default_options = e_comp_wl_input_keymap_default_options_get();
2126 names.rules = strdup(default_rules);
2127 names.model = strdup(default_model);
2128 names.layout = strdup(default_layout);
2129 if (default_variant) names.variant = strdup(default_variant);
2130 if (default_options) names.options = strdup(default_options);
2132 keymap = e_comp_wl_input_keymap_compile(context, names, &keymap_path);
2133 eina_stringshare_del(keymap_path);
2134 EINA_SAFETY_ON_NULL_GOTO(keymap, cleanup);
2139 if (dont_set_e_input_keymap == EINA_FALSE)
2141 e_input_device_keyboard_cached_context_set(*ctx);
2142 e_input_device_keyboard_cached_keymap_set(*map);
2146 free((char *)names.rules);
2147 free((char *)names.model);
2148 free((char *)names.layout);
2149 if (names.variant) free((char *)names.variant);
2150 if (names.options) free((char *)names.options);
2156 e_comp_wl_input_pointer_constraint_activated_get(void)
2158 return e_comp_wl->ptr_constraints.activated;
2162 e_comp_wl_input_keymap_init(void)
2164 struct xkb_context *ctx = NULL;
2165 struct xkb_keymap *map = NULL;
2168 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2169 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2171 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
2173 _e_comp_wl_input_keymap_set(&ctx, &map);
2176 e_comp_wl_input_keymap_set(e_comp_wl_input_keymap_default_rules_get(),
2177 e_comp_wl_input_keymap_default_model_get(),
2178 e_comp_wl_input_keymap_default_layout_get(),
2179 e_comp_wl_input_keymap_default_variant_get(),
2180 e_comp_wl_input_keymap_default_options_get(),