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 !");
740 _e_comp_wl_input_pointer_constraints_check_enable(E_Comp_Wl_Pointer_Constraint *constraint)
742 if (!constraint || !constraint->ec)
744 ERR("Invalid constraint or ec of it.");
748 E_Client *ec = constraint->ec;
749 wl_fixed_t cx = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
750 wl_fixed_t cy = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
752 if ((!e_comp_wl->ptr.ec) || (e_comp_wl->ptr.ec != ec)
753 || (!ec->pointer_enter_sent))
756 if (!_e_comp_wl_input_is_position_inside_constraint_region(constraint,
761 _e_comp_wl_input_pointer_constraint_enable(constraint);
765 _e_comp_wl_input_pointer_constraint_disable(E_Comp_Wl_Pointer_Constraint *constraint)
767 int lifetime = constraint->lifetime;
769 if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT)
770 _e_comp_wl_input_pointer_constraint_destroy(constraint);
771 else if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT)
772 _e_comp_wl_input_pointer_constraint_deactivate(constraint);
774 ERR("unknown pointer constraint lifetime (%d) !", lifetime);
778 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed(struct wl_listener *listener,
781 struct wl_resource *pointer_resource = (struct wl_resource *)data;
782 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
783 E_Comp_Wl_Pointer_Constraint,
784 pointer_destroy_listener);
786 if (pointer_resource == constraint->pointer)
787 _e_comp_wl_input_pointer_constraint_destroy(constraint);
791 _e_comp_wl_input_cb_pointer_constraints_surface_committed(struct wl_listener *listener,
794 E_Client *ec = (E_Client *)data;
795 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
796 E_Comp_Wl_Pointer_Constraint,
797 surface_commit_listener);
800 if (ec != constraint->ec)
803 if (constraint->is_hint_pending)
805 constraint->is_hint_pending = EINA_FALSE;
807 new_x = ec->client.x + wl_fixed_to_int(constraint->hint_x_pending);
808 new_y = ec->client.y + wl_fixed_to_int(constraint->hint_y_pending);
810 if (e_client_transform_core_enable_get(ec))
812 e_comp_wl_map_inv_coord_get(ec, new_x, new_y, &constraint->hint_x, &constraint->hint_y);
813 WRN("Pointer Constraint. Committed. hint (%d, %d) -> map_inv_coord (%d, %d)",
814 new_x, new_y, constraint->hint_x, constraint->hint_y);
818 constraint->hint_x = new_x;
819 constraint->hint_y = new_y;
820 WRN("Pointer Constraint. Committed. hint (%d, %d)",
821 constraint->hint_x, constraint->hint_y);
825 if (constraint->is_region_pending)
827 constraint->is_region_pending = EINA_FALSE;
828 pixman_region32_copy(&constraint->region,
829 &constraint->region_pending);
830 pixman_region32_fini(&constraint->region_pending);
831 pixman_region32_init(&constraint->region_pending);
834 //CHECKME: check if the updated region can take effect on the given constraint
838 _e_comp_wl_input_cb_pointer_constraints_surface_mousein(struct wl_listener *listener,
841 E_Client *ec = (E_Client *)data;
842 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
843 E_Comp_Wl_Pointer_Constraint,
844 surface_mousein_listener);
846 Eina_Bool found = EINA_FALSE;
847 E_Comp_Wl_Pointer_Constraint *tmp_constraint;
848 wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
850 if (tmp_constraint == constraint)
857 if (found && !constraint->active)
858 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
859 else if (!found && constraint->active)
860 _e_comp_wl_input_pointer_constraint_disable(constraint);
864 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped(struct wl_listener *listener,
867 E_Client *ec = (E_Client *)data;
868 E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
869 E_Comp_Wl_Pointer_Constraint,
870 surface_unmap_listener);
872 if (ec == constraint->ec)
873 _e_comp_wl_input_pointer_constraint_disable(constraint);
876 static E_Comp_Wl_Pointer_Constraint *
877 _e_comp_wl_input_pointer_constraint_create(E_Client *ec,
878 struct wl_resource *resource,
879 struct wl_resource *pointer,
880 struct wl_resource *region_resource,
881 enum zwp_pointer_constraints_v1_lifetime lifetime,
882 E_Comp_Wl_Pointer_Constraint_Type type)
884 E_Comp_Wl_Pointer_Constraint *constraint;
886 constraint = E_NEW(E_Comp_Wl_Pointer_Constraint, 1);
890 ERR("Could not allocate memory for pointer constraint: %m");
894 constraint->active = EINA_FALSE;
896 constraint->lifetime = lifetime;
897 constraint->type = type;
898 constraint->pointer = pointer;
899 constraint->resource = resource;
900 constraint->surface = e_comp_wl_client_surface_get(ec);
901 wl_list_init(&constraint->link);
902 wl_list_insert(&ec->comp_data->pointer_constraints, &constraint->link);
903 pixman_region32_init(&constraint->region);
904 pixman_region32_init(&constraint->region_pending);
908 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
911 pixman_region32_copy(&constraint->region, region);
912 constraint->has_region_set = EINA_TRUE;
916 //CHECKME: check whether this situation is a kind of bug
917 ERR("Invalid pixman_region from region (pointer constraint region!");
918 pixman_region32_fini(&constraint->region);
919 pixman_region32_init_rect(&constraint->region,
920 INT32_MIN, INT32_MIN,
921 UINT32_MAX, UINT32_MAX);
926 pixman_region32_fini(&constraint->region);
927 pixman_region32_init_rect(&constraint->region,
928 INT32_MIN, INT32_MIN,
929 UINT32_MAX, UINT32_MAX);
930 constraint->has_region_set = EINA_TRUE;
933 ERR("Pointer Constraint created.");
935 constraint->pointer_destroy_listener.notify =
936 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed;
937 constraint->surface_commit_listener.notify =
938 _e_comp_wl_input_cb_pointer_constraints_surface_committed;
939 constraint->surface_unmap_listener.notify =
940 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped;
941 constraint->surface_mousein_listener.notify =
942 _e_comp_wl_input_cb_pointer_constraints_surface_mousein;
944 wl_signal_add(&e_comp_wl->ptr_constraints.pointer_destroy_signal,
945 &constraint->pointer_destroy_listener);
946 wl_signal_add(&e_comp_wl->ptr_constraints.surface_commit_signal,
947 &constraint->surface_commit_listener);
948 wl_signal_add(&e_comp_wl->ptr_constraints.surface_mousein_signal,
949 &constraint->surface_mousein_listener);
950 wl_list_init(&constraint->surface_unmap_listener.link);
956 _e_comp_wl_input_has_pointer_constraints_for_pointer(E_Client *ec, struct wl_resource *pointer)
958 E_Comp_Wl_Pointer_Constraint *constraint;
960 wl_list_for_each(constraint, &ec->comp_data->pointer_constraints, link)
962 if (constraint->pointer == pointer)
970 _e_comp_wl_input_cb_unbind_locked_pointer(struct wl_resource *resource)
972 E_Comp_Wl_Pointer_Constraint *constraint;
973 constraint = wl_resource_get_user_data(resource);
978 _e_comp_wl_input_pointer_constraint_destroy(constraint);
982 _e_comp_wl_input_cb_locked_pointer_destroy(struct wl_client *client,
983 struct wl_resource *resource)
985 wl_resource_destroy(resource);
989 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint(struct wl_client *client,
990 struct wl_resource *resource,
991 wl_fixed_t surface_x,
992 wl_fixed_t surface_y)
994 E_Comp_Wl_Pointer_Constraint *constraint =
995 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1000 constraint->hint_x_pending = surface_x;
1001 constraint->hint_y_pending = surface_y;
1002 constraint->is_hint_pending = EINA_TRUE;
1003 constraint->has_hint_set = EINA_TRUE;
1007 _e_comp_wl_input_cb_locked_pointer_set_region(struct wl_client *client,
1008 struct wl_resource *resource,
1009 struct wl_resource *region_resource)
1011 E_Comp_Wl_Pointer_Constraint *constraint =
1012 (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1017 if (region_resource)
1019 pixman_region32_t *region = wl_resource_get_user_data(region_resource);
1023 pixman_region32_copy(&constraint->region_pending, region);
1027 //CHECKME: check whether this situation is a kind of bug
1028 ERR("Invalid pixman_region from region (pointer constraint region!");
1029 pixman_region32_fini(&constraint->region_pending);
1030 pixman_region32_init_rect(&constraint->region_pending,
1031 INT32_MIN, INT32_MIN,
1032 UINT32_MAX, UINT32_MAX);
1035 constraint->has_region_set = EINA_TRUE;
1039 pixman_region32_fini(&constraint->region_pending);
1040 pixman_region32_init_rect(&constraint->region_pending,
1041 INT32_MIN, INT32_MIN,
1042 UINT32_MAX, UINT32_MAX);
1045 constraint->is_region_pending = EINA_TRUE;
1048 static const struct zwp_locked_pointer_v1_interface _e_comp_wl_locked_pointer_interface =
1050 _e_comp_wl_input_cb_locked_pointer_destroy,
1051 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint,
1052 _e_comp_wl_input_cb_locked_pointer_set_region,
1056 _e_comp_wl_input_cb_pointer_constraints_lock_pointer(struct wl_client *client,
1057 struct wl_resource *resource,
1059 struct wl_resource *surface,
1060 struct wl_resource *pointer,
1061 struct wl_resource *region,
1064 if (!pointer || !surface)
1066 ERR("Pointer resource or surface resource is invalid !");
1070 E_Client *ec = e_client_from_surface_resource(surface);
1074 ERR("Could not get ec from surface resource !");
1078 if (_e_comp_wl_input_has_pointer_constraints_for_pointer(ec, pointer))
1080 ERR("Pointer constraints has been created already (ec: %p, pointer_resource: %u)",
1081 ec, wl_resource_get_id(resource));
1082 wl_resource_post_error(resource,
1083 ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
1084 "the pointer has a lock set already on this surface");
1088 struct wl_resource *res;
1089 res = wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
1093 ERR("Could not create a resource for pointer constraints lock: %m");
1094 wl_client_post_no_memory(client);
1098 E_Comp_Wl_Pointer_Constraint *constraint;
1099 constraint = _e_comp_wl_input_pointer_constraint_create(ec, res, pointer, region, lifetime,
1100 E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK);
1104 ERR("Could not create a pointer constraint.");
1105 wl_resource_destroy(res);
1106 wl_client_post_no_memory(client);
1110 wl_resource_set_implementation(res, &_e_comp_wl_locked_pointer_interface,
1111 constraint, _e_comp_wl_input_cb_unbind_locked_pointer);
1113 _e_comp_wl_input_pointer_constraints_check_enable(constraint);
1117 _e_comp_wl_input_cb_pointer_constraints_confine_pointer(struct wl_client *client,
1118 struct wl_resource *resource,
1120 struct wl_resource *surface,
1121 struct wl_resource *pointer,
1122 struct wl_resource *region,
1133 /* TODO: pointer constraints confine */
1137 _e_comp_wl_input_cb_pointer_constraints_destroy(struct wl_client *client,
1138 struct wl_resource *resource)
1140 wl_resource_destroy(resource);
1143 static const struct zwp_pointer_constraints_v1_interface _e_pointer_constraints_interface = {
1144 _e_comp_wl_input_cb_pointer_constraints_destroy,
1145 _e_comp_wl_input_cb_pointer_constraints_lock_pointer,
1146 _e_comp_wl_input_cb_pointer_constraints_confine_pointer,
1150 _e_comp_wl_input_cb_unbind_pointer_constraints(struct wl_resource *resource)
1152 e_comp_wl->ptr_constraints.resources =
1153 eina_list_remove(e_comp_wl->ptr_constraints.resources, resource);
1157 _e_comp_wl_input_cb_bind_pointer_constraints(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
1159 struct wl_resource *resource;
1161 resource = wl_resource_create(client, &zwp_pointer_constraints_v1_interface, version, id);
1165 ERR("Could not create pointer constraints resource: %m");
1169 e_comp_wl->ptr_constraints.resources =
1170 eina_list_append(e_comp_wl->ptr_constraints.resources, resource);
1171 wl_resource_set_implementation(resource, &_e_pointer_constraints_interface,
1172 NULL, _e_comp_wl_input_cb_unbind_pointer_constraints);
1176 _e_comp_wl_input_cb_surface_commit(void *data EINA_UNUSED, E_Client *ec)
1178 wl_signal_emit(&e_comp_wl->ptr_constraints.surface_commit_signal, ec);
1182 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
1185 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
1187 if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
1195 if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
1197 WRN("%s is maybe link, so delete it\n", keymap_path);
1200 file = fopen(keymap_path, "w");
1201 EINA_SAFETY_ON_NULL_RETURN(file);
1203 if (fputs(keymap_data, file) < 0)
1205 WRN("Failed to write keymap file: %s\n", keymap_path);
1207 unlink(keymap_path);
1211 INF("Success to make keymap file: %s\n", keymap_path);
1219 _e_comp_wl_input_keymap_fd_get(off_t size)
1221 int fd = 0, blen = 0, len = 0;
1223 char tmp[PATH_MAX] = {0, };
1227 blen = sizeof(tmp) - 20;
1229 path = e_util_env_get("XDG_RUNTIME_DIR");
1230 if (!path) return -1;
1232 len = strlen(path) + 19;
1235 strncpy(tmp, path, PATH_MAX - 20);
1236 strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
1245 old_umask = umask(S_IRWXG|S_IRWXO);
1249 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
1251 flags = fcntl(fd, F_GETFD);
1258 if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
1264 if (ftruncate(fd, size) < 0)
1275 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1278 xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1279 struct wl_resource *res;
1282 /* unreference any existing keymap */
1283 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
1284 if (e_comp_wl->xkb.keymap)
1285 xkb_map_unref(e_comp_wl->xkb.keymap);
1287 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
1289 /* unmap any existing keyboard area */
1290 if (e_comp_wl->xkb.area)
1291 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1292 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1294 /* unreference any existing keyboard state */
1295 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1296 if (e_comp_wl->xkb.state)
1299 xkb_state_serialize_mods(e_comp_wl->xkb.state,
1300 XKB_STATE_MODS_LATCHED);
1302 xkb_state_serialize_mods(e_comp_wl->xkb.state,
1303 XKB_STATE_MODS_LOCKED);
1305 xkb_state_serialize_layout(e_comp_wl->xkb.state,
1306 XKB_STATE_LAYOUT_EFFECTIVE);
1307 xkb_state_unref(e_comp_wl->xkb.state);
1310 /* create a new xkb state */
1311 e_comp_wl->xkb.state = xkb_state_new(keymap);
1313 if (!e_comp_wl->xkb.state)
1315 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1319 if ((latched) || (locked) || (group))
1320 xkb_state_update_mask(e_comp_wl->xkb.state, 0,
1321 latched, locked, 0, 0, group);
1323 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1325 /* increment keymap reference */
1326 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
1327 e_comp_wl->xkb.keymap = keymap;
1328 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
1330 /* fetch updated modifiers */
1331 e_comp_wl->kbd.mod_shift =
1332 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1333 e_comp_wl->kbd.mod_caps =
1334 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1335 e_comp_wl->kbd.mod_ctrl =
1336 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1337 e_comp_wl->kbd.mod_alt =
1338 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1339 e_comp_wl->kbd.mod_super =
1340 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1342 if (!(tmp = xkb_map_get_as_string(keymap)))
1344 ERR("Could not get keymap string");
1348 e_comp_wl->xkb.size = strlen(tmp) + 1;
1350 _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
1351 if (e_comp_wl->xkb.fd < 0)
1353 ERR("Could not create keymap file");
1358 _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
1360 e_comp_wl->xkb.area =
1361 mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
1362 MAP_SHARED, e_comp_wl->xkb.fd, 0);
1363 if (e_comp_wl->xkb.area == MAP_FAILED)
1365 ERR("Failed to mmap keymap area: %m");
1370 strncpy(e_comp_wl->xkb.area, tmp, e_comp_wl->xkb.size);
1373 /* send updated keymap */
1374 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
1375 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1376 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1377 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1379 e_comp_wl->xkb.size);
1380 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1383 /* update modifiers */
1384 e_comp_wl_input_keyboard_modifiers_update();
1388 e_comp_wl_input_init(void)
1390 /* set default seat name */
1391 if (!e_comp_wl->seat.name)
1392 e_comp_wl->seat.name = "default";
1394 e_comp_wl->xkb.fd = -1;
1395 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1396 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1398 g_mutex_init(&e_comp_wl->kbd.mod_changed_mutex);
1399 g_mutex_init(&e_comp_wl->kbd.resource_mutex);
1400 g_mutex_init(&e_comp_wl->kbd.focused_mutex);
1401 g_mutex_init(&e_comp_wl->kbd.keys_mutex);
1402 g_mutex_init(&e_comp_wl->kbd.repeat_delay_mutex);
1403 g_mutex_init(&e_comp_wl->kbd.repeat_rate_mutex);
1405 g_mutex_init(&e_comp_wl->xkb.keymap_mutex);
1406 g_mutex_init(&e_comp_wl->xkb.state_mutex);
1408 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
1409 /* get default keyboard repeat delay from configuration */
1410 e_comp_wl->kbd.repeat_delay = e_config->keyboard.repeat_delay;
1411 /* check for valid repeat_delay */
1412 /* if invalid, set the default value of repeat delay */
1413 if (e_comp_wl->kbd.repeat_delay < 0) e_comp_wl->kbd.repeat_delay = 400;
1414 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
1416 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
1417 /* get default keyboard repeat rate from configuration */
1418 e_comp_wl->kbd.repeat_rate = e_config->keyboard.repeat_rate;
1419 /* check for valid repeat_rate value */
1420 /* if invalid, set the default value of repeat rate value */
1421 if (e_comp_wl->kbd.repeat_rate < 0) e_comp_wl->kbd.repeat_rate = 25;
1422 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
1424 /* create the global resource for input seat */
1425 e_comp_wl->seat.global =
1426 wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
1427 e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
1428 if (!e_comp_wl->seat.global)
1430 ERR("Could not create global for seat: %m");
1434 /* create the global resource for relative pointer */
1435 e_comp_wl->relative_ptr.global =
1436 wl_global_create(e_comp_wl->wl.disp,
1437 &zwp_relative_pointer_manager_v1_interface, 1,
1438 e_comp->wl_comp_data,
1439 _e_comp_wl_input_cb_bind_relative_pointer_manager);
1440 if (!e_comp_wl->relative_ptr.global)
1442 ERR("Could not create global for relative pointer: %m");
1446 /* create the global resource for pointer-constraints */
1447 e_comp_wl->ptr_constraints.global =
1448 wl_global_create(e_comp_wl->wl.disp,
1449 &zwp_pointer_constraints_v1_interface, 1,
1450 e_comp->wl_comp_data,
1451 _e_comp_wl_input_cb_bind_pointer_constraints);
1452 if (!e_comp_wl->ptr_constraints.global)
1454 ERR("Could not create global for pointer constraints: %m");
1458 e_comp_wl->ptr_constraints.ec = NULL;
1459 e_comp_wl->ptr_constraints.activated = EINA_FALSE;
1460 wl_signal_init(&e_comp_wl->ptr_constraints.pointer_destroy_signal);
1461 wl_signal_init(&e_comp_wl->ptr_constraints.surface_unmap_signal);
1462 wl_signal_init(&e_comp_wl->ptr_constraints.surface_commit_signal);
1463 wl_signal_init(&e_comp_wl->ptr_constraints.surface_mousein_signal);
1465 _surface_commit_hook = e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
1466 _e_comp_wl_input_cb_surface_commit,
1469 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1470 wl_array_init(&e_comp_wl->kbd.keys);
1471 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1473 wl_array_init(&e_comp_wl->kbd.routed_keys);
1475 E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
1477 /* get string values from environment variables */
1478 _env_e_default_xkb_rules = e_util_env_get("E_DEFAULT_XKB_RULES" );
1479 _env_e_default_xkb_model = e_util_env_get("E_DEFAULT_XKB_MODEL" );
1480 _env_e_default_xkb_layout = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
1481 _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
1482 _env_e_default_xkb_opts = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
1488 e_comp_wl_input_shutdown(void)
1490 struct wl_resource *res;
1492 /* free environment variable string */
1493 E_FREE(_env_e_default_xkb_rules );
1494 E_FREE(_env_e_default_xkb_model );
1495 E_FREE(_env_e_default_xkb_layout );
1496 E_FREE(_env_e_default_xkb_variant);
1497 E_FREE(_env_e_default_xkb_opts );
1499 /* delete surface commit hook */
1500 if (_surface_commit_hook)
1502 e_comp_wl_hook_del(_surface_commit_hook);
1503 _surface_commit_hook = NULL;
1506 g_mutex_clear(&e_comp_wl->kbd.mod_changed_mutex);
1508 /* destroy pointer resources */
1509 EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
1510 wl_resource_destroy(res);
1512 /* destroy relative pointer resources */
1513 EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
1514 wl_resource_destroy(res);
1516 /* destroy relative pointer manager resources */
1517 EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
1518 wl_resource_destroy(res);
1520 /* destroy pointer constraints resources */
1521 EINA_LIST_FREE(e_comp_wl->ptr_constraints.resources, res)
1522 wl_resource_destroy(res);
1524 /* destroy keyboard resources */
1525 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1526 EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
1527 wl_resource_destroy(res);
1528 e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
1529 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1531 g_mutex_clear(&e_comp_wl->kbd.resource_mutex);
1532 g_mutex_clear(&e_comp_wl->kbd.focused_mutex);
1534 /* destroy touch resources */
1535 EINA_LIST_FREE(e_comp_wl->touch.resources, res)
1536 wl_resource_destroy(res);
1538 /* destroy e_comp_wl->kbd.keys array */
1539 g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1540 wl_array_release(&e_comp_wl->kbd.keys);
1541 g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1543 wl_array_release(&e_comp_wl->kbd.routed_keys);
1545 /* unmap any existing keyboard area */
1546 if (e_comp_wl->xkb.area)
1547 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1548 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1550 /* unreference any existing keyboard state */
1551 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1552 if (e_comp_wl->xkb.state)
1553 xkb_state_unref(e_comp_wl->xkb.state);
1555 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1557 /* unreference any existing keymap */
1558 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
1559 if (e_comp_wl->xkb.keymap)
1560 xkb_map_unref(e_comp_wl->xkb.keymap);
1561 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
1563 /* unreference any existing context */
1564 if (e_comp_wl->xkb.context)
1565 xkb_context_unref(e_comp_wl->xkb.context);
1567 /* destroy the global relative pointer resource */
1568 if (e_comp_wl->relative_ptr.global)
1569 wl_global_destroy(e_comp_wl->relative_ptr.global);
1570 e_comp_wl->relative_ptr.global = NULL;
1572 /* destroy the global pointer constraints resource */
1573 if (e_comp_wl->ptr_constraints.global)
1574 wl_global_destroy(e_comp_wl->ptr_constraints.global);
1575 e_comp_wl->ptr_constraints.global = NULL;
1577 /* destroy the global seat resource */
1578 if (e_comp_wl->seat.global)
1579 wl_global_destroy(e_comp_wl->seat.global);
1580 e_comp_wl->seat.global = NULL;
1582 dont_set_e_input_keymap = EINA_FALSE;
1583 dont_use_xkb_cache = EINA_FALSE;
1585 g_mutex_clear(&e_comp_wl->xkb.keymap_mutex);
1586 g_mutex_clear(&e_comp_wl->xkb.state_mutex);
1588 g_mutex_clear(&e_comp_wl->kbd.keys_mutex);
1589 g_mutex_clear(&e_comp_wl->kbd.repeat_delay_mutex);
1590 g_mutex_clear(&e_comp_wl->kbd.repeat_rate_mutex);
1594 e_comp_wl_input_pointer_check(struct wl_resource *res)
1596 return wl_resource_instance_of(res, &wl_pointer_interface,
1597 &_e_pointer_interface);
1601 e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
1603 return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
1604 &_e_relative_pointer_interface);
1608 e_comp_wl_input_keyboard_check(struct wl_resource *res)
1610 return wl_resource_instance_of(res, &wl_keyboard_interface,
1611 &_e_keyboard_interface);
1615 e_comp_wl_input_keyboard_modifiers_serialize(void)
1617 Eina_Bool changed = EINA_FALSE;
1619 xkb_layout_index_t grp;
1621 g_mutex_lock(&e_comp_wl->kbd.mod_changed_mutex);
1622 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1624 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
1625 XKB_STATE_DEPRESSED);
1626 changed |= mod != e_comp_wl->kbd.mod_depressed;
1627 e_comp_wl->kbd.mod_depressed = mod;
1629 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
1630 XKB_STATE_MODS_LATCHED);
1631 changed |= mod != e_comp_wl->kbd.mod_latched;
1632 e_comp_wl->kbd.mod_latched = mod;
1634 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
1635 XKB_STATE_MODS_LOCKED);
1636 changed |= mod != e_comp_wl->kbd.mod_locked;
1637 e_comp_wl->kbd.mod_locked = mod;
1639 grp = xkb_state_serialize_layout(e_comp_wl->xkb.state,
1640 XKB_STATE_LAYOUT_EFFECTIVE);
1641 changed |= grp != e_comp_wl->kbd.mod_group;
1642 e_comp_wl->kbd.mod_group = grp;
1644 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1645 g_mutex_unlock(&e_comp_wl->kbd.mod_changed_mutex);
1651 e_comp_wl_input_keyboard_modifiers_update(void)
1654 struct wl_resource *res;
1657 if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
1658 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1659 if (!e_comp_wl->kbd.focused)
1661 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1665 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1667 serial = wl_display_next_serial(e_comp_wl->wl.disp);
1668 g_mutex_lock(&e_comp_wl->kbd.mod_changed_mutex);
1669 g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1670 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
1671 wl_keyboard_send_modifiers(res, serial,
1672 e_comp_wl->kbd.mod_depressed,
1673 e_comp_wl->kbd.mod_latched,
1674 e_comp_wl->kbd.mod_locked,
1675 e_comp_wl->kbd.mod_group);
1676 g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1677 g_mutex_unlock(&e_comp_wl->kbd.mod_changed_mutex);
1681 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
1683 enum xkb_key_direction dir;
1685 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
1686 if (!e_comp_wl->xkb.state)
1688 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1692 if (pressed) dir = XKB_KEY_DOWN;
1693 else dir = XKB_KEY_UP;
1695 e_comp_wl->kbd.mod_changed =
1696 xkb_state_update_key(e_comp_wl->xkb.state, keycode + 8, dir);
1698 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
1700 e_comp_wl_input_keyboard_modifiers_update();
1704 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
1706 /* check for valid compositor data */
1707 if (!e_comp->wl_comp_data)
1709 ERR("No compositor data");
1713 e_comp_wl->ptr.enabled = !!enabled;
1714 _e_comp_wl_input_update_seat_caps(NULL);
1718 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
1720 /* check for valid compositor data */
1721 if (!e_comp->wl_comp_data)
1723 ERR("No compositor data");
1727 e_comp_wl->kbd.enabled = !!enabled;
1728 _e_comp_wl_input_update_seat_caps(NULL);
1732 e_comp_wl_input_keymap_cache_file_use_get(void)
1734 return use_cache_keymap;
1737 E_API Eina_Stringshare *
1738 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
1740 return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
1741 names.rules ? names.rules : "evdev",
1742 names.model ? names.model : "pc105",
1743 names.layout ? names.layout : "us",
1744 names.variant ? names.variant : "",
1745 names.options ? names.options : "");
1748 EINTERN struct xkb_keymap *
1749 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
1751 struct xkb_keymap *keymap;
1752 char *cache_path = NULL;
1755 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1757 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
1759 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1761 cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
1762 file = fopen(cache_path, "r");
1767 INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
1769 /* fetch new keymap based on names */
1770 keymap = xkb_map_new_from_names(ctx, &names, 0);
1771 use_cache_keymap = EINA_FALSE;
1775 INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
1776 keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1779 WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
1781 if (remove(cache_path) != 0)
1782 WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
1783 keymap = xkb_map_new_from_names(ctx, &names, 0);
1784 use_cache_keymap = EINA_FALSE;
1788 eina_stringshare_del(cache_path);
1791 use_cache_keymap = EINA_TRUE;
1795 *keymap_path = cache_path;
1796 EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
1804 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
1805 const char *variant, const char *options,
1806 struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
1808 struct xkb_keymap *keymap;
1809 struct xkb_rule_names names;
1810 char *keymap_path = NULL;
1811 Eina_Bool use_dflt_xkb = EINA_FALSE;
1812 const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
1814 /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
1815 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
1817 if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
1819 /* unreference any existing context */
1820 if (e_comp_wl->xkb.context)
1821 xkb_context_unref(e_comp_wl->xkb.context);
1823 /* create a new xkb context */
1824 if (use_dflt_xkb) e_comp_wl->xkb.context = dflt_ctx;
1825 else e_comp_wl->xkb.context = xkb_context_new(0);
1827 if (!e_comp_wl->xkb.context)
1833 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1834 e_input_device_keyboard_cached_context_set(e_comp_wl->xkb.context);
1836 /* assemble xkb_rule_names so we can fetch keymap */
1837 memset(&names, 0, sizeof(names));
1838 if (rules) names.rules = strdup(rules);
1841 default_rules = e_comp_wl_input_keymap_default_rules_get();
1842 names.rules = strdup(default_rules);
1844 if (model) names.model = strdup(model);
1847 default_model = e_comp_wl_input_keymap_default_model_get();
1848 names.model = strdup(default_model);
1850 if (layout) names.layout = strdup(layout);
1853 default_layout = e_comp_wl_input_keymap_default_layout_get();
1854 names.layout = strdup(default_layout);
1856 if (variant) names.variant = strdup(variant);
1859 default_variant = e_comp_wl_input_keymap_default_variant_get();
1860 if (default_variant) names.variant = strdup(default_variant);
1862 if (options) names.options = strdup(options);
1865 default_options = e_comp_wl_input_keymap_default_options_get();
1866 if (default_options) names.options = strdup(default_options);
1869 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
1873 keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
1874 if (access(keymap_path, R_OK) == 0)
1876 eina_stringshare_del(keymap_path);
1881 keymap = e_comp_wl_input_keymap_compile(e_comp_wl->xkb.context, names, &keymap_path);
1884 /* update compositor keymap */
1885 _e_comp_wl_input_keymap_update(keymap, keymap_path);
1887 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1888 e_input_device_keyboard_cached_keymap_set(keymap);
1891 if (keymap_path) eina_stringshare_del(keymap_path);
1892 free((char *)names.rules);
1893 free((char *)names.model);
1894 free((char *)names.layout);
1895 if (names.variant) free((char *)names.variant);
1896 if (names.options) free((char *)names.options);
1901 e_comp_wl_input_keymap_default_rules_get(void)
1903 if (e_config->xkb.default_rmlvo.rules)
1904 return e_config->xkb.default_rmlvo.rules;
1906 if (_env_e_default_xkb_rules)
1907 return _env_e_default_xkb_rules;
1913 e_comp_wl_input_keymap_default_model_get(void)
1915 if (e_config->xkb.default_rmlvo.model)
1916 return e_config->xkb.default_rmlvo.model;
1918 if (_env_e_default_xkb_model)
1919 return _env_e_default_xkb_model;
1925 e_comp_wl_input_keymap_default_layout_get(void)
1927 if (e_config->xkb.default_rmlvo.layout)
1928 return e_config->xkb.default_rmlvo.layout;
1930 if (_env_e_default_xkb_layout)
1931 return _env_e_default_xkb_layout;
1937 e_comp_wl_input_keymap_default_variant_get(void)
1939 if (e_config->xkb.default_rmlvo.variant)
1940 return e_config->xkb.default_rmlvo.variant;
1942 if (_env_e_default_xkb_variant)
1943 return _env_e_default_xkb_variant;
1949 e_comp_wl_input_keymap_default_options_get(void)
1951 if (e_config->xkb.default_rmlvo.options)
1952 return e_config->xkb.default_rmlvo.options;
1954 if (_env_e_default_xkb_opts)
1955 return _env_e_default_xkb_opts;
1961 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
1963 /* check for valid compositor data */
1964 if (!e_comp->wl_comp_data)
1966 ERR("No compositor data");
1970 e_comp_wl->touch.enabled = !!enabled;
1971 _e_comp_wl_input_update_seat_caps(NULL);
1975 e_comp_wl_input_seat_caps_set(unsigned int caps)
1977 Eina_Bool need_update = EINA_FALSE;
1979 /* check for valid compositor data */
1980 if (!e_comp->wl_comp_data)
1982 ERR("No compositor data");
1986 if (caps & E_INPUT_SEAT_POINTER)
1987 e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
1988 if (caps & E_INPUT_SEAT_KEYBOARD)
1989 e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
1990 if (caps & E_INPUT_SEAT_TOUCH)
1991 e_comp_wl->touch.enabled = need_update = EINA_TRUE;
1994 _e_comp_wl_input_update_seat_caps(NULL);
1998 e_comp_wl_input_touch_check(struct wl_resource *res)
2000 return wl_resource_instance_of(res, &wl_touch_interface,
2001 &_e_touch_interface);
2005 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
2007 struct wl_resource *res;
2010 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
2012 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
2013 e_comp_wl->kbd.repeat_delay = delay;
2014 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
2016 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
2017 e_comp_wl->kbd.repeat_rate = rate;
2018 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
2020 g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
2021 g_mutex_lock(&e_comp_wl->kbd.repeat_delay_mutex);
2022 g_mutex_lock(&e_comp_wl->kbd.repeat_rate_mutex);
2023 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
2025 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
2026 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate,
2027 e_comp_wl->kbd.repeat_delay);
2029 g_mutex_unlock(&e_comp_wl->kbd.repeat_rate_mutex);
2030 g_mutex_unlock(&e_comp_wl->kbd.repeat_delay_mutex);
2031 g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
2034 typedef struct _keycode_map{
2035 xkb_keysym_t keysym;
2036 xkb_keycode_t keycode;
2040 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2042 keycode_map *found_keycodes = (keycode_map *)data;
2043 xkb_keysym_t keysym = found_keycodes->keysym;
2045 const xkb_keysym_t *syms_out = NULL;
2047 nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2048 if (nsyms && syms_out)
2050 if (*syms_out == keysym)
2052 found_keycodes->keycode = key;
2058 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
2060 keycode_map found_keycodes = {0,};
2061 found_keycodes.keysym = keysym;
2062 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2064 return found_keycodes.keycode;
2068 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
2070 struct xkb_keymap *keymap = NULL;
2071 xkb_keysym_t keysym = 0x0;
2075 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
2076 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
2078 g_mutex_lock(&e_comp_wl->xkb.keymap_mutex);
2079 keymap = e_comp_wl->xkb.keymap;
2080 g_mutex_unlock(&e_comp_wl->xkb.keymap_mutex);
2081 EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
2083 keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
2084 if (keysym == XKB_KEY_NoSymbol)
2086 if (strlen(name) <= sizeof("Keycode-")) goto finish;
2088 if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
2090 name_tmp = (char *)name + sizeof("Keycode-") - 1;
2091 keycode = atoi(name_tmp);
2092 if (keycode <= 8) goto finish;
2100 keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
2109 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
2111 struct xkb_state *state;
2112 xkb_keysym_t sym = XKB_KEY_NoSymbol;
2113 char name[256] = {0, };
2115 EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
2116 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
2117 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.state, NULL);
2119 g_mutex_lock(&e_comp_wl->xkb.state_mutex);
2120 state = e_comp_wl->xkb.state;
2121 g_mutex_unlock(&e_comp_wl->xkb.state_mutex);
2123 sym = xkb_state_key_get_one_sym(state, keycode);
2124 if (sym == XKB_KEY_NoSymbol)
2126 snprintf(name, sizeof(name), "Keycode-%u", keycode);
2129 xkb_keysym_get_name(sym, name, sizeof(name));
2131 return strdup(name);