1 #define EXECUTIVE_MODE_ENABLED
6 #include <relative-pointer-unstable-v1-server-protocol.h>
7 #include <pointer-constraints-unstable-v1-server-protocol.h>
9 typedef struct _E_Comp_Wl_Pointer_Constraint E_Comp_Wl_Pointer_Constraint;
11 typedef enum _E_Comp_Wl_Pointer_Constraint_Type
13 E_COMP_WL_POINTER_CONSTRAINT_TYPE_NONE = 0,
14 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK = 1,
15 E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE = 2,
16 } E_Comp_Wl_Pointer_Constraint_Type;
18 struct _E_Comp_Wl_Pointer_Constraint
23 struct wl_resource *surface;
24 struct wl_resource *resource;
25 struct wl_resource *pointer;
28 E_Comp_Wl_Pointer_Constraint_Type type;
31 pixman_region32_t region;
32 pixman_region32_t region_pending;
33 Eina_Bool is_region_pending;
34 Eina_Bool has_region_set;
38 wl_fixed_t hint_x_pending;
39 wl_fixed_t hint_y_pending;
40 Eina_Bool is_hint_pending;
41 Eina_Bool has_hint_set;
43 struct wl_listener pointer_destroy_listener;
44 struct wl_listener surface_unmap_listener;
45 struct wl_listener surface_commit_listener;
46 struct wl_listener surface_mousein_listener;
49 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
50 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
51 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
52 static Eina_Bool use_cache_keymap = EINA_FALSE;
54 static E_Comp_Wl_Hook *_surface_commit_hook = NULL;
56 /* default XKB values from environment variables */
57 static char *_env_e_default_xkb_rules = NULL;
58 static char *_env_e_default_xkb_model = NULL;
59 static char *_env_e_default_xkb_layout = NULL;
60 static char *_env_e_default_xkb_variant = NULL;
61 static char *_env_e_default_xkb_opts = NULL;
64 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
69 _e_comp_wl_input_update_seat_caps(struct wl_client *wc)
72 struct wl_resource *res;
73 enum wl_seat_capability caps = 0;
75 if (e_comp_wl->ptr.enabled)
76 caps |= WL_SEAT_CAPABILITY_POINTER;
77 if (e_comp_wl->kbd.enabled)
78 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
79 if (e_comp_wl->touch.enabled)
80 caps |= WL_SEAT_CAPABILITY_TOUCH;
82 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
84 /* if a wc is null, send seat capability to all wl_seat resources */
85 if (wc && (wl_resource_get_client(res) != wc)) continue;
86 wl_seat_send_capabilities(res, caps);
91 _e_comp_wl_input_pointer_map(struct wl_resource *resource)
97 if (!(ec = e_client_from_surface_resource(resource))) return;
98 if (e_object_is_del(E_OBJECT(ec))) return;
100 //if cursor ec have external content
101 e_comp_object_content_unset(ec->frame);
103 if (!e_comp_wl->ptr.ec || !e_comp_wl->ptr.ec->comp_data) return;
104 struct wl_resource *surface = e_comp_wl_client_surface_get(e_comp_wl->ptr.ec);
105 if (!surface) return;
107 wc = wl_resource_get_client(resource);
108 if (wc != wl_resource_get_client(surface)) return;
109 if (!e_comp_wl->ptr.ec->pointer_enter_sent) return;
111 if ((ptr = e_comp->pointer))
112 e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
116 _e_comp_wl_input_pointer_configure(struct wl_resource *resource,
117 Evas_Coord x, Evas_Coord y,
118 Evas_Coord w, Evas_Coord h)
122 if (!(ec = e_client_from_surface_resource(resource))) return;
123 if (e_object_is_del(E_OBJECT(ec))) return;
125 e_client_util_resize_without_frame(ec, w, h);
129 _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
131 wl_resource_destroy(resource);
135 _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)
138 Eina_Bool got_mouse = EINA_FALSE;
139 struct wl_resource *surface;
143 if (e_object_is_del(E_OBJECT(ec))) continue;
144 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
145 surface = e_comp_wl_client_surface_get(ec);
146 if (!surface) continue;
147 if (client != wl_resource_get_client(surface)) continue;
148 if (ec->mouse.in && ec->pointer_enter_sent)
150 got_mouse = EINA_TRUE;
156 ELOGF("COMP", "Cursor Set. got_mouse: false", NULL);
159 if (!surface_resource)
161 e_pointer_object_set(e_comp->pointer, NULL, x, y);
162 ec->has_cursor_unset = EINA_TRUE;
166 ec->has_cursor_unset = EINA_FALSE;
168 ec = e_client_from_surface_resource(surface_resource);
176 ec->lock_focus_out = ec->layer_block = ec->visible = 1;
177 if (!e_config->show_cursor)
179 ELOGF("COMP", "Cursor Set. show_cursor: false", ec);
182 ec->icccm.title = eina_stringshare_add("Cursor");
183 e_client_window_role_set(ec, "wl_pointer-cursor");
184 evas_object_pass_events_set(ec->frame, 1);
185 /* wl_pointer-cursor surface is always alpha window */
186 ec->argb = EINA_TRUE;
187 ELOGF("COMP", "Cursor Set. argb:%d", ec, ec->argb);
188 e_comp_object_alpha_set(ec->frame, EINA_TRUE);
191 /* Set fuctions to prevent unwanted handling by shell */
192 ec->comp_data->shell.surface = surface_resource;
193 ec->comp_data->shell.configure = _e_comp_wl_input_pointer_configure;
194 ec->comp_data->shell.map = _e_comp_wl_input_pointer_map;
196 e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
197 ec->is_cursor = EINA_TRUE;
200 /* Set a pointer_object after wl_surface commit
201 * if cursor image is changed,
202 * changed information is sent using attach / damage
203 * So in commit, we can know real current cursor image.
206 /* ignore cursor changes during resize/move I guess */
207 if (e_client_action_get()) return;
208 e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
212 e_comp->pointer->hot.x = x;
213 e_comp->pointer->hot.y = y;
214 if (e_config->show_cursor)
215 ec->visible = EINA_TRUE;
219 static const struct wl_pointer_interface _e_pointer_interface =
221 _e_comp_wl_input_pointer_cb_cursor_set,
222 _e_comp_wl_input_cb_resource_destroy
225 static const struct wl_keyboard_interface _e_keyboard_interface =
227 _e_comp_wl_input_cb_resource_destroy
230 static const struct wl_touch_interface _e_touch_interface =
232 _e_comp_wl_input_cb_resource_destroy
236 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
238 e_comp_wl->ptr.resources =
239 eina_list_remove(e_comp_wl->ptr.resources, resource);
241 wl_signal_emit(&e_comp_wl->ptr_constraints.pointer_destroy_signal, resource);
245 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
247 struct wl_resource *res;
248 struct wl_client *ptr_client = NULL;
249 E_Comp_Wl_Client_Data *cdata = NULL;
251 /* try to create pointer resource */
252 res = wl_resource_create(client, &wl_pointer_interface,
253 wl_resource_get_version(resource), id);
256 ERR("Could not create pointer on seat %s: %m",
257 e_comp_wl->seat.name);
258 wl_client_post_no_memory(client);
262 e_comp_wl->ptr.resources =
263 eina_list_append(e_comp_wl->ptr.resources, res);
264 wl_resource_set_implementation(res, &_e_pointer_interface,
265 e_comp->wl_comp_data,
266 _e_comp_wl_input_cb_pointer_unbind);
268 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)
270 cdata = (E_Comp_Wl_Client_Data*)e_comp_wl->ptr.ec->comp_data;
271 if (cdata && cdata->wl_surface)
272 ptr_client = wl_resource_get_client(cdata->wl_surface);
274 if (ptr_client == client)
276 Evas_Device *last_ptr = NULL, *dev;
278 const char *name, *desc;
280 list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
281 EINA_LIST_FOREACH(list, l, dev)
283 name = evas_device_name_get(dev);
284 desc = evas_device_description_get(dev);
285 if (!name || !desc) continue;
287 if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
288 (!strncmp(desc, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
289 (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
296 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);
302 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
305 struct wl_resource *res;
307 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
309 e_comp_wl->kbd.resources =
310 eina_list_remove(e_comp_wl->kbd.resources, resource);
312 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
314 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
316 EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
318 e_comp_wl->kbd.focused =
319 eina_list_remove_list(e_comp_wl->kbd.focused, l);
321 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
325 e_comp_wl_input_keyboard_enter_send(E_Client *ec)
327 struct wl_resource *res;
330 struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
331 if (!surface) return;
333 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
335 if (!e_comp_wl->kbd.focused)
337 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
341 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
343 e_comp_wl_input_keyboard_modifiers_serialize();
345 serial = wl_display_next_serial(e_comp_wl->wl.disp);
347 g_mutex_lock(&e_comp_wl->kbd.mod_changed_mutex);
348 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
349 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
350 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
352 wl_keyboard_send_enter(res, serial, surface,
353 &e_comp_wl->kbd.keys);
354 wl_keyboard_send_modifiers(res, serial,
355 e_comp_wl->kbd.mod_depressed,
356 e_comp_wl->kbd.mod_latched,
357 e_comp_wl->kbd.mod_locked,
358 e_comp_wl->kbd.mod_group);
360 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
361 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
362 g_mutex_unlock(&e_comp_wl->kbd.mod_changed_mutex);
366 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
369 struct wl_resource *res;
371 /* try to create keyboard resource */
372 res = wl_resource_create(client, &wl_keyboard_interface,
373 wl_resource_get_version(resource), id);
376 ERR("Could not create keyboard on seat %s: %m",
377 e_comp_wl->seat.name);
378 wl_client_post_no_memory(client);
382 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
383 e_comp_wl->kbd.resources =
384 eina_list_append(e_comp_wl->kbd.resources, res);
385 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
386 wl_resource_set_implementation(res, &_e_keyboard_interface,
387 e_comp->wl_comp_data,
388 _e_comp_wl_input_cb_keyboard_unbind);
390 /* send current repeat_info */
391 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
393 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
394 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
395 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate, e_comp_wl->kbd.repeat_delay);
396 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
397 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
400 /* send current keymap */
401 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap);
402 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
404 e_comp_wl->xkb.size);
407 /* if the client owns the focused surface, we need to send an enter */
408 focused = e_client_focused_get();
409 if ((!focused) || (e_object_is_del(E_OBJECT(focused))) ||
410 (!focused->comp_data)) return;
412 struct wl_resource *surface = e_comp_wl_client_surface_get(focused);
413 if (!surface) return;
415 if (client != wl_resource_get_client(surface)) return;
416 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
417 e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
418 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
420 e_comp_wl_input_keyboard_enter_send(focused);
424 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
426 e_comp_wl->touch.resources =
427 eina_list_remove(e_comp_wl->touch.resources, resource);
431 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
433 struct wl_resource *res;
435 /* try to create pointer resource */
436 res = wl_resource_create(client, &wl_touch_interface,
437 wl_resource_get_version(resource), id);
440 ERR("Could not create touch on seat %s: %m",
441 e_comp_wl->seat.name);
442 wl_client_post_no_memory(client);
446 e_comp_wl->touch.resources =
447 eina_list_append(e_comp_wl->touch.resources, res);
448 wl_resource_set_implementation(res, &_e_touch_interface,
449 e_comp->wl_comp_data,
450 _e_comp_wl_input_cb_touch_unbind);
453 static const struct wl_seat_interface _e_seat_interface =
455 _e_comp_wl_input_cb_pointer_get,
456 _e_comp_wl_input_cb_keyboard_get,
457 _e_comp_wl_input_cb_touch_get,
461 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
463 E_Comp_Wl_Seat *seat = wl_resource_get_user_data(resource);
465 DBG("Unbind seat: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
467 e_comp_wl->seat.resources =
468 eina_list_remove(e_comp_wl->seat.resources, resource);
473 _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
475 struct wl_resource *res;
477 struct wl_resource *tmp_res;
478 E_Comp_Wl_Seat *seat;
480 seat = E_NEW(E_Comp_Wl_Seat, 1);
483 ERR("Failed to allocate memory for seat data\n");
484 wl_client_post_no_memory(client);
487 seat->is_first_resource = 1;
489 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, tmp_res)
491 if (wl_resource_get_client(tmp_res) != client) continue;
492 DBG("wl_seat (res: %d) is already bound to client (%p)",
493 wl_resource_get_id(tmp_res), client);
494 seat->is_first_resource = 0;
498 res = wl_resource_create(client, &wl_seat_interface, version, id);
501 ERR("Could not create seat resource: %m");
505 DBG("Bind seat: %u (client: %p)", wl_resource_get_id(res), client);
507 /* store version of seat interface for reuse in updating capabilities */
508 e_comp_wl->seat.version = version;
509 e_comp_wl->seat.resources =
510 eina_list_append(e_comp_wl->seat.resources, res);
512 wl_resource_set_implementation(res, &_e_seat_interface,
514 _e_comp_wl_input_cb_unbind_seat);
516 _e_comp_wl_input_update_seat_caps(client);
517 if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
518 wl_seat_send_name(res, e_comp_wl->seat.name);
522 _e_comp_wl_input_cb_relative_pointer_destroy(struct wl_client *client,
523 struct wl_resource *resource)
525 wl_resource_destroy(resource);
528 static const struct zwp_relative_pointer_v1_interface _e_relative_pointer_interface = {
529 _e_comp_wl_input_cb_relative_pointer_destroy
533 _e_comp_wl_input_cb_relative_pointer_manager_destroy(struct wl_client *client,
534 struct wl_resource *resource)
536 wl_resource_destroy(resource);
540 _e_comp_wl_input_cb_unbind_relative_pointer(struct wl_resource *resource)
542 e_comp_wl->relative_ptr.resources =
543 eina_list_remove(e_comp_wl->relative_ptr.resources, resource);
547 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer(struct wl_client *client,
548 struct wl_resource *resource,
550 struct wl_resource *pointer_resource)
552 struct wl_resource *res = NULL;
554 res = wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
558 ERR("Could not create the resource for relative pointer: %m");
559 wl_client_post_no_memory(client);
563 e_comp_wl->relative_ptr.resources =
564 eina_list_append(e_comp_wl->relative_ptr.resources, res);
566 /* FIXME: must consider destroying relative pointer together
567 when the wl_pointer is destroyed */
568 (void) pointer_resource;
569 wl_resource_set_implementation(res, &_e_relative_pointer_interface,
570 NULL, _e_comp_wl_input_cb_unbind_relative_pointer);
573 static const struct zwp_relative_pointer_manager_v1_interface _e_relative_pointer_manager_interface = {
574 _e_comp_wl_input_cb_relative_pointer_manager_destroy,
575 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer,
579 _e_comp_wl_input_cb_unbind_relative_pointer_manager(struct wl_resource *resource)
581 e_comp_wl->relative_ptr.manager_resources =
582 eina_list_remove(e_comp_wl->relative_ptr.manager_resources, resource);
586 _e_comp_wl_input_cb_bind_relative_pointer_manager(struct wl_client *client,
587 void *data EINA_UNUSED,
591 struct wl_resource *resource = NULL;
593 resource = wl_resource_create(client, &zwp_relative_pointer_manager_v1_interface, 1, id);
597 ERR("Could not create resource for relative pointer manager: %m");
598 wl_client_post_no_memory(client);
602 e_comp_wl->relative_ptr.manager_resources =
603 eina_list_append(e_comp_wl->relative_ptr.manager_resources, resource);
604 wl_resource_set_implementation(resource, &_e_relative_pointer_manager_interface,
605 NULL, _e_comp_wl_input_cb_unbind_relative_pointer_manager);
609 _e_comp_wl_input_relative_motion_handler(double dx[2], double dy[2], uint64_t time_us)
611 //intended to be empty just for now.
615 _e_comp_wl_input_pointer_constraint_notify_deactivated(E_Comp_Wl_Pointer_Constraint *constraint)
617 struct wl_resource *resource = constraint->resource;
618 E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
620 if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
621 zwp_locked_pointer_v1_send_unlocked(resource);
622 else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
623 zwp_confined_pointer_v1_send_unconfined(resource);
625 ERR("unknown pointer constraint type (%d) !", type);
627 INF("Pointer Constraint deactivated.");
629 if (constraint->ec &&
630 constraint->has_hint_set)
633 INF("Pointer Constraint. Pointer Warp to (%d, %d)", constraint->hint_x, constraint->hint_y);
634 e_input_device_pointer_warp(NULL, constraint->hint_x, constraint->hint_y);
639 _e_comp_wl_input_pointer_constraint_deactivate(E_Comp_Wl_Pointer_Constraint *constraint)
641 constraint->active = EINA_FALSE;
642 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
643 e_comp_wl->ptr_constraints.ec = NULL;
644 e_comp_wl->relative_ptr.activated = EINA_FALSE;
645 e_comp_wl->relative_ptr.ec = NULL;
646 e_input_relative_motion_handler_set(NULL);
647 _e_comp_wl_input_pointer_constraint_notify_deactivated(constraint);
648 wl_list_remove(&constraint->surface_unmap_listener.link);
649 wl_list_init(&constraint->surface_unmap_listener.link);
653 _e_comp_wl_input_pointer_constraint_destroy(E_Comp_Wl_Pointer_Constraint *constraint)
655 if (constraint->active)
656 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
658 wl_list_remove(&constraint->pointer_destroy_listener.link);
659 wl_list_remove(&constraint->surface_unmap_listener.link);
660 wl_list_remove(&constraint->surface_commit_listener.link);
661 wl_list_remove(&constraint->surface_mousein_listener.link);
663 wl_resource_set_user_data(constraint->resource, NULL);
664 pixman_region32_fini(&constraint->region);
665 wl_list_remove(&constraint->link);
671 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
675 pixman_region32_t *region = &constraint->region;
676 pixman_region32_t cregion;
677 pixman_region32_t input_region;
679 pixman_region32_init(&cregion);
680 pixman_region32_init(&input_region);
682 //FIXME: get input_region from ec's input region
683 E_Client *ec = constraint->ec;
684 pixman_region32_init_rect(&input_region, 0, 0, ec->w, ec->h);
685 pixman_region32_intersect(&cregion, &input_region, region);
687 Eina_Bool inside = pixman_region32_contains_point(&cregion,
692 pixman_region32_fini(&cregion);
693 pixman_region32_fini(&input_region);
696 INF("(%d, %d) is not inside of constraint region.", wl_fixed_to_int(fx), wl_fixed_to_int(fy));
702 _e_comp_wl_input_pointer_constraint_notify_activated(E_Comp_Wl_Pointer_Constraint *constraint)
704 struct wl_resource *resource = constraint->resource;
705 E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
707 if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
708 zwp_locked_pointer_v1_send_locked(resource);
709 else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
710 zwp_confined_pointer_v1_send_confined(resource);
712 ERR("unknown pointer constraint type (%d) !", type);
714 INF("Pointer Constraint activated.");
718 _e_comp_wl_input_pointer_constraint_enable(E_Comp_Wl_Pointer_Constraint *constraint)
720 if (constraint->active)
722 ERR("ERROR! Pointer constraint has been activated already !");
726 constraint->active = EINA_TRUE;
727 E_Client *ec = constraint->ec;
728 e_comp_wl->ptr_constraints.activated = EINA_TRUE;
729 e_comp_wl->ptr_constraints.ec = ec;
730 e_comp_wl->relative_ptr.activated = EINA_TRUE;
731 e_comp_wl->relative_ptr.ec = ec;
732 _e_comp_wl_input_pointer_constraint_notify_activated(constraint);
733 wl_signal_add(&e_comp_wl->ptr_constraints.surface_unmap_signal,
734 &constraint->surface_unmap_listener);
735 if (!e_input_relative_motion_handler_set(_e_comp_wl_input_relative_motion_handler))
736 ERR("ERROR! Could not set relative motion handler !");
738 E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
742 _e_comp_wl_input_pointer_constraints_check_enable(E_Comp_Wl_Pointer_Constraint *constraint)
744 if (!constraint || !constraint->ec)
746 ERR("Invalid constraint or ec of it.");
750 E_Client *ec = constraint->ec;
751 wl_fixed_t cx = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
752 wl_fixed_t cy = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
754 if ((!e_comp_wl->ptr.ec) || (e_comp_wl->ptr.ec != ec)
755 || (!ec->pointer_enter_sent))
758 if (!_e_comp_wl_input_is_position_inside_constraint_region(constraint,
763 _e_comp_wl_input_pointer_constraint_enable(constraint);
767 _e_comp_wl_input_pointer_constraint_disable(E_Comp_Wl_Pointer_Constraint *constraint)
769 int lifetime = constraint->lifetime;
771 if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT)
772 _e_comp_wl_input_pointer_constraint_destroy(constraint);
773 else if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT)
774 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
776 ERR("unknown pointer constraint lifetime (%d) !", lifetime);
780 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed(struct wl_listener *listener,
783 struct wl_resource *pointer_resource = (struct wl_resource *)data;
784 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
785 E_Comp_Wl_Pointer_Constraint,
786 pointer_destroy_listener);
788 if (pointer_resource == constraint->pointer)
789 _e_comp_wl_input_pointer_constraint_destroy(constraint);
793 _e_comp_wl_input_cb_pointer_constraints_surface_committed(struct wl_listener *listener,
796 E_Client *ec = (E_Client *)data;
797 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
798 E_Comp_Wl_Pointer_Constraint,
799 surface_commit_listener);
802 if (ec != constraint->ec)
805 if (constraint->is_hint_pending)
807 constraint->is_hint_pending = EINA_FALSE;
809 new_x = ec->client.x + wl_fixed_to_int(constraint->hint_x_pending);
810 new_y = ec->client.y + wl_fixed_to_int(constraint->hint_y_pending);
812 if (e_client_transform_core_enable_get(ec))
814 e_comp_wl_map_inv_coord_get(ec, new_x, new_y, &constraint->hint_x, &constraint->hint_y);
815 WRN("Pointer Constraint. Committed. hint (%d, %d) -> map_inv_coord (%d, %d)",
816 new_x, new_y, constraint->hint_x, constraint->hint_y);
820 constraint->hint_x = new_x;
821 constraint->hint_y = new_y;
822 WRN("Pointer Constraint. Committed. hint (%d, %d)",
823 constraint->hint_x, constraint->hint_y);
827 if (constraint->is_region_pending)
829 constraint->is_region_pending = EINA_FALSE;
830 pixman_region32_copy(&constraint->region,
831 &constraint->region_pending);
832 pixman_region32_fini(&constraint->region_pending);
833 pixman_region32_init(&constraint->region_pending);
836 //CHECKME: check if the updated region can take effect on the given constraint
840 _e_comp_wl_input_cb_pointer_constraints_surface_mousein(struct wl_listener *listener,
843 E_Client *ec = (E_Client *)data;
844 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
845 E_Comp_Wl_Pointer_Constraint,
846 surface_mousein_listener);
848 Eina_Bool found = EINA_FALSE;
849 E_Comp_Wl_Pointer_Constraint *tmp_constraint;
850 wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
852 if (tmp_constraint == constraint)
859 if (found && !constraint->active)
860 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
861 else if (!found && constraint->active)
862 _e_comp_wl_input_pointer_constraint_disable(constraint);
866 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped(struct wl_listener *listener,
869 E_Client *ec = (E_Client *)data;
870 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
871 E_Comp_Wl_Pointer_Constraint,
872 surface_unmap_listener);
874 if (ec == constraint->ec)
875 _e_comp_wl_input_pointer_constraint_disable(constraint);
878 static E_Comp_Wl_Pointer_Constraint *
879 _e_comp_wl_input_pointer_constraint_create(E_Client *ec,
880 struct wl_resource *resource,
881 struct wl_resource *pointer,
882 struct wl_resource *region_resource,
883 enum zwp_pointer_constraints_v1_lifetime lifetime,
884 E_Comp_Wl_Pointer_Constraint_Type type)
886 E_Comp_Wl_Pointer_Constraint *constraint;
888 constraint = E_NEW(E_Comp_Wl_Pointer_Constraint, 1);
892 ERR("Could not allocate memory for pointer constraint: %m");
896 constraint->active = EINA_FALSE;
898 constraint->lifetime = lifetime;
899 constraint->type = type;
900 constraint->pointer = pointer;
901 constraint->resource = resource;
902 constraint->surface = e_comp_wl_client_surface_get(ec);
903 wl_list_init(&constraint->link);
904 wl_list_insert(&ec->comp_data->pointer_constraints, &constraint->link);
905 pixman_region32_init(&constraint->region);
906 pixman_region32_init(&constraint->region_pending);
910 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
913 pixman_region32_copy(&constraint->region, region);
914 constraint->has_region_set = EINA_TRUE;
918 //CHECKME: check whether this situation is a kind of bug
919 ERR("Invalid pixman_region from region (pointer constraint region!");
920 pixman_region32_fini(&constraint->region);
921 pixman_region32_init_rect(&constraint->region,
922 INT32_MIN, INT32_MIN,
923 UINT32_MAX, UINT32_MAX);
928 pixman_region32_fini(&constraint->region);
929 pixman_region32_init_rect(&constraint->region,
930 INT32_MIN, INT32_MIN,
931 UINT32_MAX, UINT32_MAX);
932 constraint->has_region_set = EINA_TRUE;
935 ERR("Pointer Constraint created.");
937 constraint->pointer_destroy_listener.notify =
938 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed;
939 constraint->surface_commit_listener.notify =
940 _e_comp_wl_input_cb_pointer_constraints_surface_committed;
941 constraint->surface_unmap_listener.notify =
942 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped;
943 constraint->surface_mousein_listener.notify =
944 _e_comp_wl_input_cb_pointer_constraints_surface_mousein;
946 wl_signal_add(&e_comp_wl->ptr_constraints.pointer_destroy_signal,
947 &constraint->pointer_destroy_listener);
948 wl_signal_add(&e_comp_wl->ptr_constraints.surface_commit_signal,
949 &constraint->surface_commit_listener);
950 wl_signal_add(&e_comp_wl->ptr_constraints.surface_mousein_signal,
951 &constraint->surface_mousein_listener);
952 wl_list_init(&constraint->surface_unmap_listener.link);
958 _e_comp_wl_input_has_pointer_constraints_for_pointer(E_Client *ec, struct wl_resource *pointer)
960 E_Comp_Wl_Pointer_Constraint *constraint;
962 wl_list_for_each(constraint, &ec->comp_data->pointer_constraints, link)
964 if (constraint->pointer == pointer)
972 _e_comp_wl_input_cb_unbind_locked_pointer(struct wl_resource *resource)
974 E_Comp_Wl_Pointer_Constraint *constraint;
975 constraint = wl_resource_get_user_data(resource);
980 _e_comp_wl_input_pointer_constraint_destroy(constraint);
984 _e_comp_wl_input_cb_locked_pointer_destroy(struct wl_client *client,
985 struct wl_resource *resource)
987 wl_resource_destroy(resource);
991 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint(struct wl_client *client,
992 struct wl_resource *resource,
993 wl_fixed_t surface_x,
994 wl_fixed_t surface_y)
996 E_Comp_Wl_Pointer_Constraint *constraint =
997 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1002 constraint->hint_x_pending = surface_x;
1003 constraint->hint_y_pending = surface_y;
1004 constraint->is_hint_pending = EINA_TRUE;
1005 constraint->has_hint_set = EINA_TRUE;
1009 _e_comp_wl_input_cb_locked_pointer_set_region(struct wl_client *client,
1010 struct wl_resource *resource,
1011 struct wl_resource *region_resource)
1013 E_Comp_Wl_Pointer_Constraint *constraint =
1014 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1019 if (region_resource)
1021 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
1025 pixman_region32_copy(&constraint->region_pending, region);
1029 //CHECKME: check whether this situation is a kind of bug
1030 ERR("Invalid pixman_region from region (pointer constraint region!");
1031 pixman_region32_fini(&constraint->region_pending);
1032 pixman_region32_init_rect(&constraint->region_pending,
1033 INT32_MIN, INT32_MIN,
1034 UINT32_MAX, UINT32_MAX);
1037 constraint->has_region_set = EINA_TRUE;
1041 pixman_region32_fini(&constraint->region_pending);
1042 pixman_region32_init_rect(&constraint->region_pending,
1043 INT32_MIN, INT32_MIN,
1044 UINT32_MAX, UINT32_MAX);
1047 constraint->is_region_pending = EINA_TRUE;
1050 static const struct zwp_locked_pointer_v1_interface _e_comp_wl_locked_pointer_interface =
1052 _e_comp_wl_input_cb_locked_pointer_destroy,
1053 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint,
1054 _e_comp_wl_input_cb_locked_pointer_set_region,
1058 _e_comp_wl_input_cb_pointer_constraints_lock_pointer(struct wl_client *client,
1059 struct wl_resource *resource,
1061 struct wl_resource *surface,
1062 struct wl_resource *pointer,
1063 struct wl_resource *region,
1066 if (!pointer || !surface)
1068 ERR("Pointer resource or surface resource is invalid !");
1072 E_Client *ec = e_client_from_surface_resource(surface);
1076 ERR("Could not get ec from surface resource !");
1080 if (_e_comp_wl_input_has_pointer_constraints_for_pointer(ec, pointer))
1082 ERR("Pointer constraints has been created already (ec: %p, pointer_resource: %u)",
1083 ec, wl_resource_get_id(resource));
1084 wl_resource_post_error(resource,
1085 ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
1086 "the pointer has a lock set already on this surface");
1090 struct wl_resource *res;
1091 res = wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
1095 ERR("Could not create a resource for pointer constraints lock: %m");
1096 wl_client_post_no_memory(client);
1100 E_Comp_Wl_Pointer_Constraint *constraint;
1101 constraint = _e_comp_wl_input_pointer_constraint_create(ec, res, pointer, region, lifetime,
1102 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK);
1106 ERR("Could not create a pointer constraint.");
1107 wl_resource_destroy(res);
1108 wl_client_post_no_memory(client);
1112 wl_resource_set_implementation(res, &_e_comp_wl_locked_pointer_interface,
1113 constraint, _e_comp_wl_input_cb_unbind_locked_pointer);
1115 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
1119 _e_comp_wl_input_cb_pointer_constraints_confine_pointer(struct wl_client *client,
1120 struct wl_resource *resource,
1122 struct wl_resource *surface,
1123 struct wl_resource *pointer,
1124 struct wl_resource *region,
1135 /* TODO: pointer constraints confine */
1139 _e_comp_wl_input_cb_pointer_constraints_destroy(struct wl_client *client,
1140 struct wl_resource *resource)
1142 wl_resource_destroy(resource);
1145 static const struct zwp_pointer_constraints_v1_interface _e_pointer_constraints_interface = {
1146 _e_comp_wl_input_cb_pointer_constraints_destroy,
1147 _e_comp_wl_input_cb_pointer_constraints_lock_pointer,
1148 _e_comp_wl_input_cb_pointer_constraints_confine_pointer,
1152 _e_comp_wl_input_cb_unbind_pointer_constraints(struct wl_resource *resource)
1154 e_comp_wl->ptr_constraints.resources =
1155 eina_list_remove(e_comp_wl->ptr_constraints.resources, resource);
1159 _e_comp_wl_input_cb_bind_pointer_constraints(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
1161 struct wl_resource *resource;
1163 resource = wl_resource_create(client, &zwp_pointer_constraints_v1_interface, version, id);
1167 ERR("Could not create pointer constraints resource: %m");
1171 e_comp_wl->ptr_constraints.resources =
1172 eina_list_append(e_comp_wl->ptr_constraints.resources, resource);
1173 wl_resource_set_implementation(resource, &_e_pointer_constraints_interface,
1174 NULL, _e_comp_wl_input_cb_unbind_pointer_constraints);
1178 _e_comp_wl_input_cb_surface_commit(void *data EINA_UNUSED, E_Client *ec)
1180 wl_signal_emit(&e_comp_wl->ptr_constraints.surface_commit_signal, ec);
1184 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
1187 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
1189 if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
1197 if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
1199 WRN("%s is maybe link, so delete it\n", keymap_path);
1202 file = fopen(keymap_path, "w");
1203 EINA_SAFETY_ON_NULL_RETURN(file);
1205 if (fputs(keymap_data, file) < 0)
1207 WRN("Failed to write keymap file: %s\n", keymap_path);
1209 unlink(keymap_path);
1213 INF("Success to make keymap file: %s\n", keymap_path);
1221 _e_comp_wl_input_keymap_fd_get(off_t size)
1223 int fd = 0, blen = 0, len = 0;
1225 char tmp[PATH_MAX] = {0, };
1229 blen = sizeof(tmp) - 20;
1231 path = e_util_env_get("XDG_RUNTIME_DIR");
1232 if (!path) return -1;
1234 len = strlen(path) + 19;
1237 strncpy(tmp, path, PATH_MAX - 20);
1238 strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
1247 old_umask = umask(S_IRWXG|S_IRWXO);
1251 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
1253 flags = fcntl(fd, F_GETFD);
1260 if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
1266 if (ftruncate(fd, size) < 0)
1277 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1280 xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1281 struct wl_resource *res;
1284 /* unreference any existing keymap */
1285 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
1286 if (e_comp_wl->xkb.keymap)
1287 xkb_map_unref(e_comp_wl->xkb.keymap);
1289 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
1291 /* unmap any existing keyboard area */
1292 if (e_comp_wl->xkb.area)
1293 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1294 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1296 /* unreference any existing keyboard state */
1297 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1298 if (e_comp_wl->xkb.state)
1301 xkb_state_serialize_mods(e_comp_wl->xkb.state,
1302 XKB_STATE_MODS_LATCHED);
1304 xkb_state_serialize_mods(e_comp_wl->xkb.state,
1305 XKB_STATE_MODS_LOCKED);
1307 xkb_state_serialize_layout(e_comp_wl->xkb.state,
1308 XKB_STATE_LAYOUT_EFFECTIVE);
1309 xkb_state_unref(e_comp_wl->xkb.state);
1312 /* create a new xkb state */
1313 e_comp_wl->xkb.state = xkb_state_new(keymap);
1315 if (!e_comp_wl->xkb.state)
1317 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1321 if ((latched) || (locked) || (group))
1322 xkb_state_update_mask(e_comp_wl->xkb.state, 0,
1323 latched, locked, 0, 0, group);
1325 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1327 /* increment keymap reference */
1328 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
1329 e_comp_wl->xkb.keymap = keymap;
1330 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
1332 /* fetch updated modifiers */
1333 e_comp_wl->kbd.mod_shift =
1334 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1335 e_comp_wl->kbd.mod_caps =
1336 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1337 e_comp_wl->kbd.mod_ctrl =
1338 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1339 e_comp_wl->kbd.mod_alt =
1340 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1341 e_comp_wl->kbd.mod_super =
1342 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1344 if (!(tmp = xkb_map_get_as_string(keymap)))
1346 ERR("Could not get keymap string");
1350 e_comp_wl->xkb.size = strlen(tmp) + 1;
1352 _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
1353 if (e_comp_wl->xkb.fd < 0)
1355 ERR("Could not create keymap file");
1360 _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
1362 e_comp_wl->xkb.area =
1363 mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
1364 MAP_SHARED, e_comp_wl->xkb.fd, 0);
1365 if (e_comp_wl->xkb.area == MAP_FAILED)
1367 ERR("Failed to mmap keymap area: %m");
1372 strncpy(e_comp_wl->xkb.area, tmp, e_comp_wl->xkb.size);
1375 /* send updated keymap */
1376 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
1377 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1378 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1379 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1381 e_comp_wl->xkb.size);
1382 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1385 /* update modifiers */
1386 e_comp_wl_input_keyboard_modifiers_update();
1390 e_comp_wl_input_init(void)
1392 /* set default seat name */
1393 if (!e_comp_wl->seat.name)
1394 e_comp_wl->seat.name = "default";
1396 e_comp_wl->xkb.fd = -1;
1397 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1398 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1400 g_mutex_init(&e_comp_wl->kbd.mod_changed_mutex);
1401 g_mutex_init(&e_comp_wl->kbd.resource_mutex);
1402 g_mutex_init(&e_comp_wl->kbd.focused_mutex);
1403 g_mutex_init(&e_comp_wl->kbd.keys_mutex);
1404 g_mutex_init(&e_comp_wl->kbd.repeat_delay_mutex);
1405 g_mutex_init(&e_comp_wl->kbd.repeat_rate_mutex);
1407 g_mutex_init(&e_comp_wl->xkb.keymap_mutex);
1408 g_mutex_init(&e_comp_wl->xkb.state_mutex);
1410 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
1411 /* get default keyboard repeat delay from configuration */
1412 e_comp_wl->kbd.repeat_delay = e_config->keyboard.repeat_delay;
1413 /* check for valid repeat_delay */
1414 /* if invalid, set the default value of repeat delay */
1415 if (e_comp_wl->kbd.repeat_delay < 0) e_comp_wl->kbd.repeat_delay = 400;
1416 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
1418 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
1419 /* get default keyboard repeat rate from configuration */
1420 e_comp_wl->kbd.repeat_rate = e_config->keyboard.repeat_rate;
1421 /* check for valid repeat_rate value */
1422 /* if invalid, set the default value of repeat rate value */
1423 if (e_comp_wl->kbd.repeat_rate < 0) e_comp_wl->kbd.repeat_rate = 25;
1424 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
1426 /* create the global resource for input seat */
1427 e_comp_wl->seat.global =
1428 wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
1429 e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
1430 if (!e_comp_wl->seat.global)
1432 ERR("Could not create global for seat: %m");
1436 /* create the global resource for relative pointer */
1437 e_comp_wl->relative_ptr.global =
1438 wl_global_create(e_comp_wl->wl.disp,
1439 &zwp_relative_pointer_manager_v1_interface, 1,
1440 e_comp->wl_comp_data,
1441 _e_comp_wl_input_cb_bind_relative_pointer_manager);
1442 if (!e_comp_wl->relative_ptr.global)
1444 ERR("Could not create global for relative pointer: %m");
1448 /* create the global resource for pointer-constraints */
1449 e_comp_wl->ptr_constraints.global =
1450 wl_global_create(e_comp_wl->wl.disp,
1451 &zwp_pointer_constraints_v1_interface, 1,
1452 e_comp->wl_comp_data,
1453 _e_comp_wl_input_cb_bind_pointer_constraints);
1454 if (!e_comp_wl->ptr_constraints.global)
1456 ERR("Could not create global for pointer constraints: %m");
1460 e_comp_wl->ptr_constraints.ec = NULL;
1461 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
1462 wl_signal_init(&e_comp_wl->ptr_constraints.pointer_destroy_signal);
1463 wl_signal_init(&e_comp_wl->ptr_constraints.surface_unmap_signal);
1464 wl_signal_init(&e_comp_wl->ptr_constraints.surface_commit_signal);
1465 wl_signal_init(&e_comp_wl->ptr_constraints.surface_mousein_signal);
1467 _surface_commit_hook = e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
1468 _e_comp_wl_input_cb_surface_commit,
1471 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1472 wl_array_init(&e_comp_wl->kbd.keys);
1473 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1475 wl_array_init(&e_comp_wl->kbd.routed_keys);
1477 E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
1479 /* get string values from environment variables */
1480 _env_e_default_xkb_rules = e_util_env_get("E_DEFAULT_XKB_RULES" );
1481 _env_e_default_xkb_model = e_util_env_get("E_DEFAULT_XKB_MODEL" );
1482 _env_e_default_xkb_layout = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
1483 _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
1484 _env_e_default_xkb_opts = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
1490 e_comp_wl_input_shutdown(void)
1492 struct wl_resource *res;
1494 /* free environment variable string */
1495 E_FREE(_env_e_default_xkb_rules );
1496 E_FREE(_env_e_default_xkb_model );
1497 E_FREE(_env_e_default_xkb_layout );
1498 E_FREE(_env_e_default_xkb_variant);
1499 E_FREE(_env_e_default_xkb_opts );
1501 /* delete surface commit hook */
1502 if (_surface_commit_hook)
1504 e_comp_wl_hook_del(_surface_commit_hook);
1505 _surface_commit_hook = NULL;
1508 g_mutex_clear(&e_comp_wl->kbd.mod_changed_mutex);
1510 /* destroy pointer resources */
1511 EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
1512 wl_resource_destroy(res);
1514 /* destroy relative pointer resources */
1515 EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
1516 wl_resource_destroy(res);
1518 /* destroy relative pointer manager resources */
1519 EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
1520 wl_resource_destroy(res);
1522 /* destroy pointer constraints resources */
1523 EINA_LIST_FREE(e_comp_wl->ptr_constraints.resources, res)
1524 wl_resource_destroy(res);
1526 /* destroy keyboard resources */
1527 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1528 EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
1529 wl_resource_destroy(res);
1530 e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
1531 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1533 g_mutex_clear(&e_comp_wl->kbd.resource_mutex);
1534 g_mutex_clear(&e_comp_wl->kbd.focused_mutex);
1536 /* destroy touch resources */
1537 EINA_LIST_FREE(e_comp_wl->touch.resources, res)
1538 wl_resource_destroy(res);
1540 /* destroy e_comp_wl->kbd.keys array */
1541 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1542 wl_array_release(&e_comp_wl->kbd.keys);
1543 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1545 wl_array_release(&e_comp_wl->kbd.routed_keys);
1547 /* unmap any existing keyboard area */
1548 if (e_comp_wl->xkb.area)
1549 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1550 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1552 /* unreference any existing keyboard state */
1553 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1554 if (e_comp_wl->xkb.state)
1555 xkb_state_unref(e_comp_wl->xkb.state);
1557 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1559 /* unreference any existing keymap */
1560 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
1561 if (e_comp_wl->xkb.keymap)
1562 xkb_map_unref(e_comp_wl->xkb.keymap);
1563 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
1565 /* unreference any existing context */
1566 if (e_comp_wl->xkb.context)
1567 xkb_context_unref(e_comp_wl->xkb.context);
1569 /* destroy the global relative pointer resource */
1570 if (e_comp_wl->relative_ptr.global)
1571 wl_global_destroy(e_comp_wl->relative_ptr.global);
1572 e_comp_wl->relative_ptr.global = NULL;
1574 /* destroy the global pointer constraints resource */
1575 if (e_comp_wl->ptr_constraints.global)
1576 wl_global_destroy(e_comp_wl->ptr_constraints.global);
1577 e_comp_wl->ptr_constraints.global = NULL;
1579 /* destroy the global seat resource */
1580 if (e_comp_wl->seat.global)
1581 wl_global_destroy(e_comp_wl->seat.global);
1582 e_comp_wl->seat.global = NULL;
1584 dont_set_e_input_keymap = EINA_FALSE;
1585 dont_use_xkb_cache = EINA_FALSE;
1587 g_mutex_clear(&e_comp_wl->xkb.keymap_mutex);
1588 g_mutex_clear(&e_comp_wl->xkb.state_mutex);
1590 g_mutex_clear(&e_comp_wl->kbd.keys_mutex);
1591 g_mutex_clear(&e_comp_wl->kbd.repeat_delay_mutex);
1592 g_mutex_clear(&e_comp_wl->kbd.repeat_rate_mutex);
1596 e_comp_wl_input_pointer_check(struct wl_resource *res)
1598 return wl_resource_instance_of(res, &wl_pointer_interface,
1599 &_e_pointer_interface);
1603 e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
1605 return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
1606 &_e_relative_pointer_interface);
1610 e_comp_wl_input_keyboard_check(struct wl_resource *res)
1612 return wl_resource_instance_of(res, &wl_keyboard_interface,
1613 &_e_keyboard_interface);
1617 e_comp_wl_input_keyboard_modifiers_serialize(void)
1619 Eina_Bool changed = EINA_FALSE;
1621 xkb_layout_index_t grp;
1623 g_mutex_lock(&e_comp_wl->kbd.mod_changed_mutex);
1624 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1626 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
1627 XKB_STATE_DEPRESSED);
1628 changed |= mod != e_comp_wl->kbd.mod_depressed;
1629 e_comp_wl->kbd.mod_depressed = mod;
1631 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
1632 XKB_STATE_MODS_LATCHED);
1633 changed |= mod != e_comp_wl->kbd.mod_latched;
1634 e_comp_wl->kbd.mod_latched = mod;
1636 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
1637 XKB_STATE_MODS_LOCKED);
1638 changed |= mod != e_comp_wl->kbd.mod_locked;
1639 e_comp_wl->kbd.mod_locked = mod;
1641 grp = xkb_state_serialize_layout(e_comp_wl->xkb.state,
1642 XKB_STATE_LAYOUT_EFFECTIVE);
1643 changed |= grp != e_comp_wl->kbd.mod_group;
1644 e_comp_wl->kbd.mod_group = grp;
1646 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1647 g_mutex_unlock(&e_comp_wl->kbd.mod_changed_mutex);
1653 e_comp_wl_input_keyboard_modifiers_update(void)
1656 struct wl_resource *res;
1659 if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
1660 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1661 if (!e_comp_wl->kbd.focused)
1663 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1667 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1669 serial = wl_display_next_serial(e_comp_wl->wl.disp);
1670 g_mutex_lock(&e_comp_wl->kbd.mod_changed_mutex);
1671 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1672 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
1673 wl_keyboard_send_modifiers(res, serial,
1674 e_comp_wl->kbd.mod_depressed,
1675 e_comp_wl->kbd.mod_latched,
1676 e_comp_wl->kbd.mod_locked,
1677 e_comp_wl->kbd.mod_group);
1678 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1679 g_mutex_unlock(&e_comp_wl->kbd.mod_changed_mutex);
1683 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
1685 enum xkb_key_direction dir;
1687 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1688 if (!e_comp_wl->xkb.state)
1690 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1694 if (pressed) dir = XKB_KEY_DOWN;
1695 else dir = XKB_KEY_UP;
1697 e_comp_wl->kbd.mod_changed =
1698 xkb_state_update_key(e_comp_wl->xkb.state, keycode + 8, dir);
1700 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1702 e_comp_wl_input_keyboard_modifiers_update();
1706 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
1708 /* check for valid compositor data */
1709 if (!e_comp->wl_comp_data)
1711 ERR("No compositor data");
1715 e_comp_wl->ptr.enabled = !!enabled;
1716 _e_comp_wl_input_update_seat_caps(NULL);
1720 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
1722 /* check for valid compositor data */
1723 if (!e_comp->wl_comp_data)
1725 ERR("No compositor data");
1729 e_comp_wl->kbd.enabled = !!enabled;
1730 _e_comp_wl_input_update_seat_caps(NULL);
1734 e_comp_wl_input_keymap_cache_file_use_get(void)
1736 return use_cache_keymap;
1739 E_API Eina_Stringshare *
1740 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
1742 return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
1743 names.rules ? names.rules : "evdev",
1744 names.model ? names.model : "pc105",
1745 names.layout ? names.layout : "us",
1746 names.variant ? names.variant : "",
1747 names.options ? names.options : "");
1750 EINTERN struct xkb_keymap *
1751 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
1753 struct xkb_keymap *keymap;
1754 char *cache_path = NULL;
1757 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1759 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
1761 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1763 cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
1764 file = fopen(cache_path, "r");
1769 INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
1771 /* fetch new keymap based on names */
1772 keymap = xkb_map_new_from_names(ctx, &names, 0);
1773 use_cache_keymap = EINA_FALSE;
1777 INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
1778 keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1781 WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
1783 if (remove(cache_path) != 0)
1784 WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
1785 keymap = xkb_map_new_from_names(ctx, &names, 0);
1786 use_cache_keymap = EINA_FALSE;
1790 eina_stringshare_del(cache_path);
1793 use_cache_keymap = EINA_TRUE;
1797 *keymap_path = cache_path;
1798 EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
1806 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
1807 const char *variant, const char *options,
1808 struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
1810 struct xkb_keymap *keymap;
1811 struct xkb_rule_names names;
1812 char *keymap_path = NULL;
1813 Eina_Bool use_dflt_xkb = EINA_FALSE;
1814 const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
1816 /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
1817 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
1819 if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
1821 /* unreference any existing context */
1822 if (e_comp_wl->xkb.context)
1823 xkb_context_unref(e_comp_wl->xkb.context);
1825 /* create a new xkb context */
1826 if (use_dflt_xkb) e_comp_wl->xkb.context = dflt_ctx;
1827 else e_comp_wl->xkb.context = xkb_context_new(0);
1829 if (!e_comp_wl->xkb.context)
1835 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1836 e_input_device_keyboard_cached_context_set(e_comp_wl->xkb.context);
1838 /* assemble xkb_rule_names so we can fetch keymap */
1839 memset(&names, 0, sizeof(names));
1840 if (rules) names.rules = strdup(rules);
1843 default_rules = e_comp_wl_input_keymap_default_rules_get();
1844 names.rules = strdup(default_rules);
1846 if (model) names.model = strdup(model);
1849 default_model = e_comp_wl_input_keymap_default_model_get();
1850 names.model = strdup(default_model);
1852 if (layout) names.layout = strdup(layout);
1855 default_layout = e_comp_wl_input_keymap_default_layout_get();
1856 names.layout = strdup(default_layout);
1858 if (variant) names.variant = strdup(variant);
1861 default_variant = e_comp_wl_input_keymap_default_variant_get();
1862 if (default_variant) names.variant = strdup(default_variant);
1864 if (options) names.options = strdup(options);
1867 default_options = e_comp_wl_input_keymap_default_options_get();
1868 if (default_options) names.options = strdup(default_options);
1871 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
1875 keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
1876 if (access(keymap_path, R_OK) == 0)
1878 eina_stringshare_del(keymap_path);
1883 keymap = e_comp_wl_input_keymap_compile(e_comp_wl->xkb.context, names, &keymap_path);
1886 /* update compositor keymap */
1887 _e_comp_wl_input_keymap_update(keymap, keymap_path);
1889 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1890 e_input_device_keyboard_cached_keymap_set(keymap);
1893 if (keymap_path) eina_stringshare_del(keymap_path);
1894 free((char *)names.rules);
1895 free((char *)names.model);
1896 free((char *)names.layout);
1897 if (names.variant) free((char *)names.variant);
1898 if (names.options) free((char *)names.options);
1903 e_comp_wl_input_keymap_default_rules_get(void)
1905 if (e_config->xkb.default_rmlvo.rules)
1906 return e_config->xkb.default_rmlvo.rules;
1908 if (_env_e_default_xkb_rules)
1909 return _env_e_default_xkb_rules;
1915 e_comp_wl_input_keymap_default_model_get(void)
1917 if (e_config->xkb.default_rmlvo.model)
1918 return e_config->xkb.default_rmlvo.model;
1920 if (_env_e_default_xkb_model)
1921 return _env_e_default_xkb_model;
1927 e_comp_wl_input_keymap_default_layout_get(void)
1929 if (e_config->xkb.default_rmlvo.layout)
1930 return e_config->xkb.default_rmlvo.layout;
1932 if (_env_e_default_xkb_layout)
1933 return _env_e_default_xkb_layout;
1939 e_comp_wl_input_keymap_default_variant_get(void)
1941 if (e_config->xkb.default_rmlvo.variant)
1942 return e_config->xkb.default_rmlvo.variant;
1944 if (_env_e_default_xkb_variant)
1945 return _env_e_default_xkb_variant;
1951 e_comp_wl_input_keymap_default_options_get(void)
1953 if (e_config->xkb.default_rmlvo.options)
1954 return e_config->xkb.default_rmlvo.options;
1956 if (_env_e_default_xkb_opts)
1957 return _env_e_default_xkb_opts;
1963 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
1965 /* check for valid compositor data */
1966 if (!e_comp->wl_comp_data)
1968 ERR("No compositor data");
1972 e_comp_wl->touch.enabled = !!enabled;
1973 _e_comp_wl_input_update_seat_caps(NULL);
1977 e_comp_wl_input_seat_caps_set(unsigned int caps)
1979 Eina_Bool need_update = EINA_FALSE;
1981 /* check for valid compositor data */
1982 if (!e_comp->wl_comp_data)
1984 ERR("No compositor data");
1988 if (caps & E_INPUT_SEAT_POINTER)
1989 e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
1990 if (caps & E_INPUT_SEAT_KEYBOARD)
1991 e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
1992 if (caps & E_INPUT_SEAT_TOUCH)
1993 e_comp_wl->touch.enabled = need_update = EINA_TRUE;
1996 _e_comp_wl_input_update_seat_caps(NULL);
2000 e_comp_wl_input_touch_check(struct wl_resource *res)
2002 return wl_resource_instance_of(res, &wl_touch_interface,
2003 &_e_touch_interface);
2007 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
2009 struct wl_resource *res;
2012 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
2014 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
2015 e_comp_wl->kbd.repeat_delay = delay;
2016 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
2018 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
2019 e_comp_wl->kbd.repeat_rate = rate;
2020 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
2022 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
2023 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
2024 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
2025 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
2027 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
2028 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate,
2029 e_comp_wl->kbd.repeat_delay);
2031 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
2032 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
2033 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
2036 typedef struct _keycode_map{
2037 xkb_keysym_t keysym;
2038 xkb_keycode_t keycode;
2042 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2044 keycode_map *found_keycodes = (keycode_map *)data;
2045 xkb_keysym_t keysym = found_keycodes->keysym;
2047 const xkb_keysym_t *syms_out = NULL;
2049 nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2050 if (nsyms && syms_out)
2052 if (*syms_out == keysym)
2054 found_keycodes->keycode = key;
2060 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
2062 keycode_map found_keycodes = {0,};
2063 found_keycodes.keysym = keysym;
2064 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2066 return found_keycodes.keycode;
2070 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
2072 struct xkb_keymap *keymap = NULL;
2073 xkb_keysym_t keysym = 0x0;
2077 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
2078 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
2080 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
2081 keymap = e_comp_wl->xkb.keymap;
2082 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
2083 EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
2085 keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
2086 if (keysym == XKB_KEY_NoSymbol)
2088 if (strlen(name) <= sizeof("Keycode-")) goto finish;
2090 if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
2092 name_tmp = (char *)name + sizeof("Keycode-") - 1;
2093 keycode = atoi(name_tmp);
2094 if (keycode <= 8) goto finish;
2102 keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
2111 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
2113 struct xkb_state *state;
2114 xkb_keysym_t sym = XKB_KEY_NoSymbol;
2115 char name[256] = {0, };
2117 EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
2118 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
2119 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.state, NULL);
2121 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
2122 state = e_comp_wl->xkb.state;
2123 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
2125 sym = xkb_state_key_get_one_sym(state, keycode);
2126 if (sym == XKB_KEY_NoSymbol)
2128 snprintf(name, sizeof(name), "Keycode-%u", keycode);
2131 xkb_keysym_get_name(sym, name, sizeof(name));
2133 return strdup(name);