e_input: intialze e_comp_input at e_input_init
[platform/upstream/enlightenment.git] / src / bin / server / e_comp_wl_input.c
1 #include "e_comp_wl_input_intern.h"
2 #include "e_utils_intern.h"
3 #include "e_comp_wl_intern.h"
4 #include "e_input_intern.h"
5 #include "e_input_device_intern.h"
6 #include "e_input_backend_intern.h"
7 #include "e_pointer_intern.h"
8 #include "e_comp_object_intern.h"
9 #include "e_comp_input_intern.h"
10 #include "e_policy_intern.h"
11 #include "e_keyrouter_intern.h"
12 #include "e_input_thread_client_intern.h"
13
14 #include <sys/mman.h>
15 #include <fcntl.h>
16 #include <pixman.h>
17
18 #include <relative-pointer-unstable-v1-server-protocol.h>
19 #include <pointer-constraints-unstable-v1-server-protocol.h>
20
21 #define EXECUTIVE_MODE_ENABLED
22
23 typedef struct _E_Comp_Wl_Pointer_Constraint E_Comp_Wl_Pointer_Constraint;
24
25 typedef enum _E_Comp_Wl_Pointer_Constraint_Type
26 {
27    E_COMP_WL_POINTER_CONSTRAINT_TYPE_NONE = 0,
28    E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK = 1,
29    E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE = 2,
30 } E_Comp_Wl_Pointer_Constraint_Type;
31
32 struct _E_Comp_Wl_Pointer_Constraint
33 {
34    struct wl_list link;
35
36    E_Client *ec;
37    struct wl_resource *surface;
38    struct wl_resource *resource;
39    struct wl_resource *pointer;
40    Eina_Bool active;
41
42    E_Comp_Wl_Pointer_Constraint_Type type;
43    int lifetime;
44
45    pixman_region32_t region;
46    pixman_region32_t region_pending;
47    Eina_Bool is_region_pending;
48    Eina_Bool has_region_set;
49
50    int hint_x;
51    int hint_y;
52    wl_fixed_t hint_x_pending;
53    wl_fixed_t hint_y_pending;
54    Eina_Bool is_hint_pending;
55    Eina_Bool has_hint_set;
56
57    struct wl_listener pointer_destroy_listener;
58    struct wl_listener surface_unmap_listener;
59    struct wl_listener surface_commit_listener;
60    struct wl_listener surface_mousein_listener;
61    struct wl_listener surface_mouseout_listener;
62 };
63
64 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
65 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
66 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
67 static Eina_Bool use_cache_keymap = EINA_FALSE;
68
69 static E_Comp_Wl_Hook *_surface_commit_hook = NULL;
70
71 /* default XKB values from environment variables */
72 static char *_env_e_default_xkb_rules   = NULL;
73 static char *_env_e_default_xkb_model   = NULL;
74 static char *_env_e_default_xkb_layout  = NULL;
75 static char *_env_e_default_xkb_variant = NULL;
76 static char *_env_e_default_xkb_opts    = NULL;
77
78 static Eina_Bool
79 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
80                                                       wl_fixed_t fx,
81                                                       wl_fixed_t fy);
82
83 static void
84 _e_comp_wl_input_update_seat_caps(struct wl_client *wc)
85 {
86    Eina_List *l;
87    struct wl_resource *res;
88    enum wl_seat_capability caps = 0;
89
90    if (e_comp_wl->ptr.enabled)
91      caps |= WL_SEAT_CAPABILITY_POINTER;
92    if (e_comp_input_key->kbd.enabled)
93      caps |= WL_SEAT_CAPABILITY_KEYBOARD;
94    if (e_comp_wl->touch.enabled)
95      caps |= WL_SEAT_CAPABILITY_TOUCH;
96
97    EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
98      {
99         /* if a wc is null, send seat capability to all wl_seat resources */
100         if (wc && (wl_resource_get_client(res) != wc)) continue;
101         wl_seat_send_capabilities(res, caps);
102      }
103 }
104
105 static void
106 _e_comp_wl_input_pointer_map(struct wl_resource *resource)
107 {
108    E_Client *ec;
109    E_Pointer *ptr;
110    struct wl_client *wc;
111
112    if (!(ec = e_client_from_surface_resource(resource))) return;
113    if (e_object_is_del(E_OBJECT(ec))) return;
114
115    //if cursor ec have external content
116    e_comp_object_content_unset(ec->frame);
117
118    if (!e_comp_wl->ptr.ec || !e_comp_wl->ptr.ec->comp_data) return;
119    struct wl_resource *surface = e_comp_wl_client_surface_get(e_comp_wl->ptr.ec);
120    if (!surface) return;
121
122    wc = wl_resource_get_client(resource);
123    if (wc != wl_resource_get_client(surface)) return;
124    if (!e_comp_wl->ptr.ec->pointer_enter_sent) return;
125
126    if ((ptr = e_comp->pointer))
127      e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
128 }
129
130 static void
131 _e_comp_wl_input_pointer_configure(struct wl_resource *resource,
132                                    Evas_Coord x, Evas_Coord y,
133                                    Evas_Coord w, Evas_Coord h)
134 {
135    E_Client *ec;
136
137    if (!(ec = e_client_from_surface_resource(resource))) return;
138    if (e_object_is_del(E_OBJECT(ec))) return;
139
140    e_client_util_resize_without_frame(ec, w, h);
141 }
142
143 static void
144 _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
145 {
146    wl_resource_destroy(resource);
147 }
148
149 static void
150 _e_comp_wl_input_thread_cursor_set(void *data)
151 {
152    E_Input_Thread_Request_EClient_Data *ec_data = data;
153    EINA_SAFETY_ON_NULL_RETURN(ec_data);
154
155    INF("[input thread|%s] ec(%p), layer_block(%d), is_cursor(%d)\n", __func__, ec_data->ec, ec_data->layer_block, ec_data->is_cursor);
156    e_input_thread_client_layer_block_set(e_input_thread_client_get(ec_data->ec), ec_data->layer_block);
157    e_input_thread_client_is_cursor_set(e_input_thread_client_get(ec_data->ec), ec_data->is_cursor);
158 }
159
160 static void
161 _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
162 {
163    E_Client *ec;
164    Eina_Bool got_mouse = EINA_FALSE;
165    struct wl_resource *surface;
166
167    E_Input_Thread_Request_EClient_Data ec_data;
168    memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
169
170    E_CLIENT_FOREACH(ec)
171      {
172        if (e_object_is_del(E_OBJECT(ec))) continue;
173        if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
174        surface = e_comp_wl_client_surface_get(ec);
175        if (!surface) continue;
176        if (client != wl_resource_get_client(surface)) continue;
177        if (ec->mouse.in && ec->pointer_enter_sent)
178          {
179             got_mouse = EINA_TRUE;
180             break;
181          }
182      }
183    if (!got_mouse)
184      {
185         ELOGF("COMP", "Cursor Set. got_mouse: false", NULL);
186         return;
187      }
188    if (!surface_resource || e_policy_client_is_waydroid(ec))
189      {
190         e_pointer_object_set(e_comp->pointer, NULL, x, y);
191         ec->has_cursor_unset = EINA_TRUE;
192         ELOGF("COMP", "Cursor Set. has_cursor_unset:TRUE", ec);
193         return;
194      }
195
196    ec->has_cursor_unset = EINA_FALSE;
197
198    ec = e_client_from_surface_resource(surface_resource);
199    if (!ec) return;
200
201    if (!ec->re_manage)
202      {
203         ec->re_manage = 1;
204         ec->ignored = 0;
205
206         ec->lock_focus_out = ec->layer_block = ec->visible = 1;
207         if (!e_config->show_cursor)
208           {
209              ELOGF("COMP", "Cursor Set. show_cursor: false", ec);
210              ec->override = 1;
211           }
212         e_client_icccm_title_set(ec, "Cursor");
213         e_client_window_role_set(ec, "wl_pointer-cursor");
214         evas_object_pass_events_set(ec->frame, 1);
215         /* wl_pointer-cursor surface is always alpha window */
216         ec->argb = EINA_TRUE;
217         ELOGF("COMP", "Cursor Set. argb:%d", ec, ec->argb);
218         e_comp_object_alpha_set(ec->frame, EINA_TRUE);
219         EC_CHANGED(ec);
220
221         /* Set fuctions to prevent unwanted handling by shell */
222         ec->comp_data->shell.surface = surface_resource;
223         ec->comp_data->shell.configure = _e_comp_wl_input_pointer_configure;
224         ec->comp_data->shell.map = _e_comp_wl_input_pointer_map;
225
226         e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
227         ec->is_cursor = EINA_TRUE;
228
229         ec_data.ec = ec;
230         ec_data.layer_block = ec->layer_block;
231         ec_data.is_cursor = ec->is_cursor;
232         INF("[%s] ec(%p), layer_block(%d), is_cursor(%d)\n", __func__, ec, ec->layer_block, ec->is_cursor);
233         e_input_backend_thread_safe_call(_e_comp_wl_input_thread_cursor_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
234      }
235
236    /* Set a pointer_object after wl_surface commit
237     * if cursor image is changed,
238     * changed information is sent using attach / damage
239     * So in commit, we can know real current cursor image.
240     */
241 #if 0
242    /* ignore cursor changes during resize/move I guess */
243    if (e_client_action_get()) return;
244    e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
245 #endif
246    if (e_comp->pointer)
247      {
248         e_comp->pointer->hot.x = x;
249         e_comp->pointer->hot.y = y;
250         if (e_config->show_cursor)
251           ec->visible = EINA_TRUE;
252      }
253 }
254
255 static const struct wl_pointer_interface _e_pointer_interface =
256 {
257    _e_comp_wl_input_pointer_cb_cursor_set,
258    _e_comp_wl_input_cb_resource_destroy
259 };
260
261 static const struct wl_keyboard_interface _e_keyboard_interface =
262 {
263    _e_comp_wl_input_cb_resource_destroy
264 };
265
266 static const struct wl_touch_interface _e_touch_interface =
267 {
268    _e_comp_wl_input_cb_resource_destroy
269 };
270
271 static void
272 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
273 {
274    e_comp_wl->ptr.resources =
275      eina_list_remove(e_comp_wl->ptr.resources, resource);
276
277    wl_signal_emit(&e_comp_wl->ptr_constraints.pointer_destroy_signal, resource);
278 }
279
280 static void
281 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
282 {
283    struct wl_resource *res;
284    struct wl_client *ptr_client = NULL;
285    E_Comp_Wl_Client_Data *cdata = NULL;
286
287    /* try to create pointer resource */
288    res = wl_resource_create(client, &wl_pointer_interface,
289                             wl_resource_get_version(resource), id);
290    if (!res)
291      {
292         ERR("Could not create pointer on seat %s: %m",
293             e_comp_wl->seat.name);
294         wl_client_post_no_memory(client);
295         return;
296      }
297
298    e_comp_wl->ptr.resources =
299      eina_list_append(e_comp_wl->ptr.resources, res);
300    wl_resource_set_implementation(res, &_e_pointer_interface,
301                                   e_comp->wl_comp_data,
302                                  _e_comp_wl_input_cb_pointer_unbind);
303
304    if ((e_comp_wl->ptr.num_devices == 1) && e_comp_wl->ptr.ec && !e_comp_wl->ptr.ec->pointer_enter_sent && !e_config->use_cursor_timer)
305      {
306         cdata = (E_Comp_Wl_Client_Data*)e_comp_wl->ptr.ec->comp_data;
307         if (cdata && cdata->wl_surface)
308           ptr_client = wl_resource_get_client(cdata->wl_surface);
309
310         if (ptr_client == client)
311           {
312              Evas_Device *last_ptr = NULL, *dev;
313              Eina_List *list, *l;
314              const char *name, *desc;
315
316              list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
317              EINA_LIST_FOREACH(list, l, dev)
318                {
319                   name = evas_device_name_get(dev);
320                   desc = evas_device_description_get(dev);
321                   if (!name || !desc) continue;
322
323                   if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
324                       (!strncmp(desc, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
325                       (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
326                     {
327                        last_ptr = dev;
328                        break;
329                     }
330                }
331              if (last_ptr)
332                e_comp_wl_mouse_in_renew(e_comp_wl->ptr.ec, 0, wl_fixed_to_int(e_comp_wl->ptr.x), wl_fixed_to_int(e_comp_wl->ptr.y), NULL, NULL, NULL, ecore_time_get(), EVAS_EVENT_FLAG_NONE, last_ptr, NULL);
333           }
334      }
335 }
336
337 static void
338 _e_comp_wl_input_thread_cb_keyboard_unbind(void *data)
339 {
340    Eina_List *l, *ll;
341    struct wl_resource *res;
342    struct wl_resource *resource = NULL;
343
344    EINA_SAFETY_ON_NULL_RETURN(data);
345
346    resource = *(struct wl_resource **)data;
347
348    e_comp_input_key->kbd.resources =
349      eina_list_remove(e_comp_input_key->kbd.resources, resource);
350
351    EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
352      if (res == resource)
353        e_comp_input_key->kbd.focused =
354          eina_list_remove_list(e_comp_input_key->kbd.focused, l);
355 }
356
357 static void
358 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
359 {
360    INF("[keyboard unbind] resource(%p)\n", resource);
361    _e_comp_wl_input_thread_cb_keyboard_unbind(&resource);
362 }
363
364 void
365 e_comp_wl_input_keyboard_enter_send(struct wl_resource *surface)
366 {
367    struct wl_resource *res;
368    Eina_List *l;
369    uint32_t serial;
370    xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
371    xkb_layout_index_t mod_group;
372
373    if (!e_comp_input_key->kbd.focused)
374      {
375         return;
376      }
377
378    e_comp_wl_input_keyboard_modifiers_serialize();
379
380    serial = wl_display_next_serial(e_comp_wl->wl.disp);
381
382    mod_depressed = atomic_load(&e_comp_input_key->kbd.mod_depressed);
383    mod_latched = atomic_load(&e_comp_input_key->kbd.mod_latched);
384    mod_locked = atomic_load(&e_comp_input_key->kbd.mod_locked);
385
386    mod_group = atomic_load(&e_comp_input_key->kbd.mod_group);
387
388    EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
389      {
390         wl_keyboard_send_enter(res, serial, surface,
391                                &e_comp_input_key->kbd.keys);
392
393         wl_keyboard_send_modifiers(res, serial,
394                                    mod_depressed,
395                                    mod_latched,
396                                    mod_locked,
397                                    mod_group);
398      }
399 }
400
401 static void
402 _e_comp_wl_input_thread_cb_keyboard_get(void *data)
403 {
404    E_Client *focused;
405    struct wl_resource *res;
406
407    E_Input_Thread_Request_Keyboard_Get_Data *keyboard_get_data = data;
408    EINA_SAFETY_ON_NULL_RETURN(keyboard_get_data);
409
410    INF("[input thread|%s] resource(%p), client(%p)\n", __func__, keyboard_get_data->resource, keyboard_get_data->client);
411
412    res = keyboard_get_data->resource;
413
414    e_comp_input_key->kbd.resources =
415      eina_list_append(e_comp_input_key->kbd.resources, res);
416
417    /* send current repeat_info */
418    if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
419      {
420         wl_keyboard_send_repeat_info(res, e_comp_input_key->kbd.repeat_rate, e_comp_input_key->kbd.repeat_delay);
421      }
422
423    /* if the client owns the focused surface, we need to send an enter */
424    focused = e_client_focused_get();
425    if ((!focused) || (e_object_is_del(E_OBJECT(focused))) ||
426        (!focused->comp_data)) return;
427
428    struct wl_resource *surface = e_comp_wl_client_surface_get(focused);
429    if (!surface) return;
430
431    if (keyboard_get_data->client != wl_resource_get_client(surface)) return;
432    e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
433
434    e_comp_wl_input_keyboard_enter_send(surface);
435 }
436
437 static void
438 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
439 {
440    struct wl_resource *res;
441    E_Input_Thread_Request_Keyboard_Get_Data keyboard_get_data;
442
443    /* try to create keyboard resource */
444    res = wl_resource_create(client, &wl_keyboard_interface,
445                             wl_resource_get_version(resource), id);
446    if (!res)
447      {
448         ERR("Could not create keyboard on seat %s: %m",
449             e_comp_wl->seat.name);
450         wl_client_post_no_memory(client);
451         return;
452      }
453
454    wl_resource_set_implementation(res, &_e_keyboard_interface,
455                                   e_comp->wl_comp_data,
456                                   _e_comp_wl_input_cb_keyboard_unbind);
457
458    /* send current keymap */
459    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap);
460    wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
461                            e_comp_input_key->xkb.fd,
462                            e_comp_input_key->xkb.size);
463    TRACE_INPUT_END();
464
465    keyboard_get_data.resource = res;
466    keyboard_get_data.client = client;
467
468    _e_comp_wl_input_thread_cb_keyboard_get(&keyboard_get_data);
469 }
470
471 static void
472 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
473 {
474    e_comp_wl->touch.resources =
475      eina_list_remove(e_comp_wl->touch.resources, resource);
476 }
477
478 static void
479 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
480 {
481     struct wl_resource *res;
482
483     /* try to create pointer resource */
484     res = wl_resource_create(client, &wl_touch_interface,
485                              wl_resource_get_version(resource), id);
486     if (!res)
487       {
488          ERR("Could not create touch on seat %s: %m",
489              e_comp_wl->seat.name);
490          wl_client_post_no_memory(client);
491          return;
492       }
493
494     e_comp_wl->touch.resources =
495      eina_list_append(e_comp_wl->touch.resources, res);
496     wl_resource_set_implementation(res, &_e_touch_interface,
497                                    e_comp->wl_comp_data,
498                                   _e_comp_wl_input_cb_touch_unbind);
499 }
500
501 static const struct wl_seat_interface _e_seat_interface =
502 {
503    _e_comp_wl_input_cb_pointer_get,
504    _e_comp_wl_input_cb_keyboard_get,
505    _e_comp_wl_input_cb_touch_get,
506 };
507
508 static void
509 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
510 {
511    E_Comp_Wl_Seat *seat = wl_resource_get_user_data(resource);
512
513    DBG("Unbind seat: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
514
515    e_comp_wl->seat.resources =
516      eina_list_remove(e_comp_wl->seat.resources, resource);
517    E_FREE(seat);
518 }
519
520 static void
521 _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
522 {
523    struct wl_resource *res;
524    Eina_List *l;
525    struct wl_resource *tmp_res;
526    E_Comp_Wl_Seat *seat;
527
528    seat = E_NEW(E_Comp_Wl_Seat, 1);
529    if (!seat)
530      {
531         ERR("Failed to allocate memory for seat data\n");
532         wl_client_post_no_memory(client);
533         return;
534      }
535    seat->is_first_resource = 1;
536
537    EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, tmp_res)
538      {
539         if (wl_resource_get_client(tmp_res) != client) continue;
540         DBG("wl_seat (res: %d) is already bound to client (%p)",
541             wl_resource_get_id(tmp_res), client);
542         seat->is_first_resource = 0;
543         break;
544      }
545
546    res = wl_resource_create(client, &wl_seat_interface, version, id);
547    if (!res)
548      {
549         ERR("Could not create seat resource: %m");
550         E_FREE(seat);
551         return;
552      }
553    DBG("Bind seat: %u (client: %p)", wl_resource_get_id(res), client);
554
555    /* store version of seat interface for reuse in updating capabilities */
556    e_comp_wl->seat.version = version;
557    e_comp_wl->seat.resources =
558      eina_list_append(e_comp_wl->seat.resources, res);
559
560    wl_resource_set_implementation(res, &_e_seat_interface,
561                                   seat,
562                                   _e_comp_wl_input_cb_unbind_seat);
563
564    _e_comp_wl_input_update_seat_caps(client);
565    if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
566      wl_seat_send_name(res, e_comp_wl->seat.name);
567 }
568
569 static void
570 _e_comp_wl_input_cb_relative_pointer_destroy(struct wl_client *client,
571                                              struct wl_resource *resource)
572 {
573    wl_resource_destroy(resource);
574 }
575
576 static const struct zwp_relative_pointer_v1_interface _e_relative_pointer_interface = {
577    _e_comp_wl_input_cb_relative_pointer_destroy
578 };
579
580 static void
581 _e_comp_wl_input_cb_relative_pointer_manager_destroy(struct wl_client *client,
582                                                      struct wl_resource *resource)
583 {
584    wl_resource_destroy(resource);
585 }
586
587 static void
588 _e_comp_wl_input_cb_unbind_relative_pointer(struct wl_resource *resource)
589 {
590    e_comp_wl->relative_ptr.resources =
591      eina_list_remove(e_comp_wl->relative_ptr.resources, resource);
592 }
593
594 static void
595 _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer(struct wl_client *client,
596                                                               struct wl_resource *resource,
597                                                               uint32_t id,
598                                                               struct wl_resource *pointer_resource)
599 {
600    struct wl_resource *res = NULL;
601
602    res = wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
603
604    if (!res)
605      {
606         ERR("Could not create the resource for relative pointer: %m");
607         wl_client_post_no_memory(client);
608         return;
609      }
610
611    e_comp_wl->relative_ptr.resources =
612      eina_list_append(e_comp_wl->relative_ptr.resources, res);
613
614    /* FIXME: must consider destroying relative pointer together
615              when the wl_pointer is destroyed */
616    (void) pointer_resource;
617    wl_resource_set_implementation(res, &_e_relative_pointer_interface,
618                                   NULL, _e_comp_wl_input_cb_unbind_relative_pointer);
619 }
620
621 static const struct zwp_relative_pointer_manager_v1_interface _e_relative_pointer_manager_interface = {
622    _e_comp_wl_input_cb_relative_pointer_manager_destroy,
623    _e_comp_wl_input_cb_relative_pointer_manager_get_relative_pointer,
624 };
625
626 static void
627 _e_comp_wl_input_cb_unbind_relative_pointer_manager(struct wl_resource *resource)
628 {
629    e_comp_wl->relative_ptr.manager_resources =
630      eina_list_remove(e_comp_wl->relative_ptr.manager_resources, resource);
631 }
632
633 static void
634 _e_comp_wl_input_cb_bind_relative_pointer_manager(struct wl_client *client,
635                                                   void *data EINA_UNUSED,
636                                                   uint32_t version,
637                                                   uint32_t id)
638 {
639    struct wl_resource *resource = NULL;
640
641    resource = wl_resource_create(client, &zwp_relative_pointer_manager_v1_interface, 1, id);
642
643    if (!resource)
644      {
645         ERR("Could not create resource for relative pointer manager: %m");
646         wl_client_post_no_memory(client);
647         return;
648      }
649
650    e_comp_wl->relative_ptr.manager_resources =
651      eina_list_append(e_comp_wl->relative_ptr.manager_resources, resource);
652    wl_resource_set_implementation(resource, &_e_relative_pointer_manager_interface,
653                                   NULL, _e_comp_wl_input_cb_unbind_relative_pointer_manager);
654 }
655
656 void
657 _e_comp_wl_input_relative_motion_handler(double dx[2], double dy[2], uint64_t time_us)
658 {
659    //intended to be empty just for now.
660 }
661
662 static void
663 _e_comp_wl_input_pointer_constraint_notify_deactivated(E_Comp_Wl_Pointer_Constraint *constraint)
664 {
665    struct wl_resource *resource = constraint->resource;
666    E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
667
668    if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
669      zwp_locked_pointer_v1_send_unlocked(resource);
670    else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
671      zwp_confined_pointer_v1_send_unconfined(resource);
672    else
673      ERR("unknown pointer constraint type (%d) !", type);
674
675    INF("Pointer Constraint deactivated.");
676
677    if (constraint->ec &&
678        constraint->has_hint_set)
679      {
680
681         INF("Pointer Constraint. Pointer Warp to (%d, %d)", constraint->hint_x, constraint->hint_y);
682         e_input_device_pointer_warp(NULL, constraint->hint_x, constraint->hint_y);
683      }
684 }
685
686 static void
687 _e_comp_wl_input_pointer_constraint_deactivate(E_Comp_Wl_Pointer_Constraint *constraint)
688 {
689    constraint->active = EINA_FALSE;
690    e_comp_wl->ptr_constraints.activated = EINA_FALSE;
691    e_comp_wl->ptr_constraints.ec = NULL;
692    e_comp_wl->relative_ptr.activated = EINA_FALSE;
693    e_comp_wl->relative_ptr.ec = NULL;
694    e_input_relative_motion_handler_set(NULL);
695    _e_comp_wl_input_pointer_constraint_notify_deactivated(constraint);
696    wl_list_remove(&constraint->surface_unmap_listener.link);
697    wl_list_init(&constraint->surface_unmap_listener.link);
698 }
699
700 static void
701 _e_comp_wl_input_pointer_constraint_destroy(E_Comp_Wl_Pointer_Constraint *constraint)
702 {
703    if (constraint->active)
704      _e_comp_wl_input_pointer_constraint_deactivate(constraint);
705
706    wl_list_remove(&constraint->pointer_destroy_listener.link);
707    wl_list_remove(&constraint->surface_unmap_listener.link);
708    wl_list_remove(&constraint->surface_commit_listener.link);
709    wl_list_remove(&constraint->surface_mousein_listener.link);
710    wl_list_remove(&constraint->surface_mouseout_listener.link);
711
712    wl_resource_set_user_data(constraint->resource, NULL);
713    pixman_region32_fini(&constraint->region);
714    wl_list_remove(&constraint->link);
715
716    free(constraint);
717 }
718
719 static Eina_Bool
720 _e_comp_wl_input_is_position_inside_constraint_region(E_Comp_Wl_Pointer_Constraint *constraint,
721                                                       wl_fixed_t fx,
722                                                       wl_fixed_t fy)
723 {
724    pixman_region32_t *region = &constraint->region;
725    pixman_region32_t cregion;
726    pixman_region32_t input_region;
727
728    pixman_region32_init(&cregion);
729    pixman_region32_init(&input_region);
730
731    //FIXME: get input_region from ec's input region
732    E_Client *ec = constraint->ec;
733    pixman_region32_init_rect(&input_region, 0, 0, ec->w, ec->h);
734    pixman_region32_intersect(&cregion, &input_region, region);
735
736    Eina_Bool inside = pixman_region32_contains_point(&cregion,
737                                                      wl_fixed_to_int(fx),
738                                                      wl_fixed_to_int(fy),
739                                                      NULL);
740
741    pixman_region32_fini(&cregion);
742    pixman_region32_fini(&input_region);
743
744    if (!inside)
745      INF("(%d, %d) is not inside of constraint region.", wl_fixed_to_int(fx), wl_fixed_to_int(fy));
746
747    return inside;
748 }
749
750 static void
751 _e_comp_wl_input_pointer_constraint_notify_activated(E_Comp_Wl_Pointer_Constraint *constraint)
752 {
753    struct wl_resource *resource = constraint->resource;
754    E_Comp_Wl_Pointer_Constraint_Type type = constraint->type;
755
756    if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK == type)
757      zwp_locked_pointer_v1_send_locked(resource);
758    else if (E_COMP_WL_POINTER_CONSTRAINT_TYPE_CONFINE == type)
759      zwp_confined_pointer_v1_send_confined(resource);
760    else
761      ERR("unknown pointer constraint type (%d) !", type);
762
763    INF("Pointer Constraint activated.");
764 }
765
766 static void
767 _e_comp_wl_input_pointer_constraint_enable(E_Comp_Wl_Pointer_Constraint *constraint)
768 {
769    if (constraint->active)
770      {
771         ERR("ERROR! Pointer constraint has been activated already !");
772         return;
773      }
774
775    constraint->active = EINA_TRUE;
776    E_Client *ec = constraint->ec;
777    e_comp_wl->ptr_constraints.activated = EINA_TRUE;
778    e_comp_wl->ptr_constraints.ec = ec;
779    e_comp_wl->relative_ptr.activated = EINA_TRUE;
780    e_comp_wl->relative_ptr.ec = ec;
781    _e_comp_wl_input_pointer_constraint_notify_activated(constraint);
782    wl_signal_add(&e_comp_wl->ptr_constraints.surface_unmap_signal,
783                  &constraint->surface_unmap_listener);
784    if (!e_input_relative_motion_handler_set(_e_comp_wl_input_relative_motion_handler))
785      ERR("ERROR! Could not set relative motion handler !");
786
787    E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
788 }
789
790 static void
791 _e_comp_wl_input_pointer_constraints_check_enable(E_Comp_Wl_Pointer_Constraint *constraint)
792 {
793    if (!constraint || !constraint->ec)
794      {
795         ERR("Invalid constraint or ec of it.");
796         return;
797      }
798
799    E_Client *ec = constraint->ec;
800    wl_fixed_t cx = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x);
801    wl_fixed_t cy = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y);
802
803    if ((!e_comp_wl->ptr.ec) || (e_comp_wl->ptr.ec != ec)
804         || (!ec->pointer_enter_sent))
805      return;
806
807    if (!_e_comp_wl_input_is_position_inside_constraint_region(constraint,
808                                                               cx,
809                                                               cy))
810      return;
811
812    _e_comp_wl_input_pointer_constraint_enable(constraint);
813 }
814
815 static void
816 _e_comp_wl_input_pointer_constraint_disable(E_Comp_Wl_Pointer_Constraint *constraint)
817 {
818    int lifetime = constraint->lifetime;
819
820    if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT)
821      _e_comp_wl_input_pointer_constraint_destroy(constraint);
822    else if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT)
823      _e_comp_wl_input_pointer_constraint_deactivate(constraint);
824    else
825      ERR("unknown pointer constraint lifetime (%d) !", lifetime);
826 }
827
828 static void
829 _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed(struct wl_listener *listener,
830                                                           void *data)
831 {
832    struct wl_resource *pointer_resource = (struct wl_resource *)data;
833    E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
834                                               E_Comp_Wl_Pointer_Constraint,
835                                               pointer_destroy_listener);
836
837    if (pointer_resource == constraint->pointer)
838      _e_comp_wl_input_pointer_constraint_destroy(constraint);
839 }
840
841 static void
842 _e_comp_wl_input_cb_pointer_constraints_surface_committed(struct wl_listener *listener,
843                                                           void *data)
844 {
845    E_Client *ec = (E_Client *)data;
846    E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
847                                               E_Comp_Wl_Pointer_Constraint,
848                                               surface_commit_listener);
849    int new_x, new_y;;
850
851    if (ec != constraint->ec)
852      return;
853
854    if (constraint->is_hint_pending)
855      {
856         constraint->is_hint_pending = EINA_FALSE;
857
858         new_x = wl_fixed_to_int(constraint->hint_x_pending);
859         new_y = wl_fixed_to_int(constraint->hint_y_pending);
860
861         if (new_x < 0) new_x = 0;
862         if ((ec->w > 0) && (new_x > ec->w - 1)) new_x = ec->w - 1;
863
864         if (new_y < 0) new_y = 0;
865         if ((ec->h > 0) && (new_y > ec->h - 1)) new_y = ec->h - 1;
866
867         new_x = ec->client.x + new_x;
868         new_y = ec->client.y + new_y;
869
870         if (e_client_transform_core_enable_get(ec))
871           {
872              e_comp_wl_map_inv_coord_get(ec, new_x, new_y, &constraint->hint_x, &constraint->hint_y);
873              WRN("Pointer Constraint. Committed. hint (%d, %d) -> map_inv_coord (%d, %d)",
874                  new_x, new_y, constraint->hint_x, constraint->hint_y);
875           }
876         else
877           {
878              constraint->hint_x = new_x;
879              constraint->hint_y = new_y;
880              WRN("Pointer Constraint. Committed. hint (%d, %d)",
881                  constraint->hint_x, constraint->hint_y);
882           }
883      }
884
885    if (constraint->is_region_pending)
886      {
887         constraint->is_region_pending = EINA_FALSE;
888         pixman_region32_copy(&constraint->region,
889                              &constraint->region_pending);
890         pixman_region32_fini(&constraint->region_pending);
891         pixman_region32_init(&constraint->region_pending);
892      }
893
894    //CHECKME: check if the updated region can take effect on the given constraint
895 }
896
897 static void
898 _e_comp_wl_input_cb_pointer_constraints_surface_mousein(struct wl_listener *listener,
899                                                         void *data)
900 {
901    E_Client *ec = (E_Client *)data;
902    E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
903                                               E_Comp_Wl_Pointer_Constraint,
904                                               surface_mousein_listener);
905
906    Eina_Bool found = EINA_FALSE;
907    E_Comp_Wl_Pointer_Constraint *tmp_constraint;
908
909    wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
910      {
911         if (tmp_constraint == constraint)
912           {
913              found = EINA_TRUE;
914              INF("Pointer Constraint. Mouse In ec: %p constraint: %p", ec, constraint);
915              break;
916           }
917      }
918
919    if (found && !constraint->active)
920      _e_comp_wl_input_pointer_constraints_check_enable(constraint);
921 }
922
923 static void
924 _e_comp_wl_input_cb_pointer_constraints_surface_mouseout(struct wl_listener *listener,
925                                                         void *data)
926 {
927    E_Client *ec = (E_Client *)data;
928    E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
929                                               E_Comp_Wl_Pointer_Constraint,
930                                               surface_mouseout_listener);
931
932    Eina_Bool found = EINA_FALSE;
933    E_Comp_Wl_Pointer_Constraint *tmp_constraint;
934
935    wl_list_for_each(tmp_constraint, &ec->comp_data->pointer_constraints, link)
936      {
937         if (tmp_constraint == constraint)
938           {
939              found = EINA_TRUE;
940              INF("Pointer Constraint. Mouse Out ec: %p constraint: %p", ec, constraint);
941              break;
942           }
943      }
944
945    if (found && constraint->active)
946      _e_comp_wl_input_pointer_constraint_disable(constraint);
947 }
948
949 static void
950 _e_comp_wl_input_cb_pointer_constraints_surface_unmapped(struct wl_listener *listener,
951                                                          void *data)
952 {
953    E_Client *ec = (E_Client *)data;
954    E_Comp_Wl_Pointer_Constraint *constraint = container_of(listener,
955                                               E_Comp_Wl_Pointer_Constraint,
956                                               surface_unmap_listener);
957
958    if (ec == constraint->ec)
959      _e_comp_wl_input_pointer_constraint_disable(constraint);
960 }
961
962 static E_Comp_Wl_Pointer_Constraint *
963 _e_comp_wl_input_pointer_constraint_create(E_Client *ec,
964                                            struct wl_resource *resource,
965                                            struct wl_resource *pointer,
966                                            struct wl_resource *region_resource,
967                                            enum zwp_pointer_constraints_v1_lifetime lifetime,
968                                            E_Comp_Wl_Pointer_Constraint_Type type)
969 {
970    E_Comp_Wl_Pointer_Constraint *constraint;
971
972    constraint = E_NEW(E_Comp_Wl_Pointer_Constraint, 1);
973
974    if (!constraint)
975      {
976         ERR("Could not allocate memory for pointer constraint: %m");
977         return NULL;
978      }
979
980    constraint->active = EINA_FALSE;
981    constraint->ec = ec;
982    constraint->lifetime = lifetime;
983    constraint->type = type;
984    constraint->pointer = pointer;
985    constraint->resource = resource;
986    constraint->surface = e_comp_wl_client_surface_get(ec);
987    wl_list_init(&constraint->link);
988    wl_list_insert(&ec->comp_data->pointer_constraints, &constraint->link);
989    pixman_region32_init(&constraint->region);
990    pixman_region32_init(&constraint->region_pending);
991
992    if (region_resource)
993      {
994         pixman_region32_t *region = wl_resource_get_user_data(region_resource);
995         if (region)
996           {
997              pixman_region32_copy(&constraint->region, region);
998              constraint->has_region_set = EINA_TRUE;
999           }
1000         else
1001           {
1002              //CHECKME: check whether this situation is a kind of bug
1003              ERR("Invalid pixman_region from region (pointer constraint region!");
1004              pixman_region32_fini(&constraint->region);
1005              pixman_region32_init_rect(&constraint->region,
1006                                        INT32_MIN, INT32_MIN,
1007                                        UINT32_MAX, UINT32_MAX);
1008           }
1009      }
1010    else
1011      {
1012         pixman_region32_fini(&constraint->region);
1013         pixman_region32_init_rect(&constraint->region,
1014                                   INT32_MIN, INT32_MIN,
1015                                   UINT32_MAX, UINT32_MAX);
1016         constraint->has_region_set = EINA_TRUE;
1017      }
1018
1019    ERR("Pointer Constraint created.");
1020
1021    constraint->pointer_destroy_listener.notify =
1022      _e_comp_wl_input_cb_pointer_constraints_pointer_destroyed;
1023    constraint->surface_commit_listener.notify =
1024      _e_comp_wl_input_cb_pointer_constraints_surface_committed;
1025    constraint->surface_unmap_listener.notify =
1026      _e_comp_wl_input_cb_pointer_constraints_surface_unmapped;
1027    constraint->surface_mousein_listener.notify =
1028      _e_comp_wl_input_cb_pointer_constraints_surface_mousein;
1029    constraint->surface_mouseout_listener.notify =
1030      _e_comp_wl_input_cb_pointer_constraints_surface_mouseout;
1031
1032    wl_signal_add(&e_comp_wl->ptr_constraints.pointer_destroy_signal,
1033                  &constraint->pointer_destroy_listener);
1034    wl_signal_add(&e_comp_wl->ptr_constraints.surface_commit_signal,
1035                  &constraint->surface_commit_listener);
1036    wl_signal_add(&e_comp_wl->ptr_constraints.surface_mousein_signal,
1037                  &constraint->surface_mousein_listener);
1038    wl_signal_add(&e_comp_wl->ptr_constraints.surface_mouseout_signal,
1039                  &constraint->surface_mouseout_listener);
1040    wl_list_init(&constraint->surface_unmap_listener.link);
1041
1042    return constraint;
1043 }
1044
1045 static Eina_Bool
1046 _e_comp_wl_input_has_pointer_constraints_for_pointer(E_Client *ec, struct wl_resource *pointer)
1047 {
1048    E_Comp_Wl_Pointer_Constraint *constraint;
1049
1050    wl_list_for_each(constraint, &ec->comp_data->pointer_constraints, link)
1051      {
1052         if (constraint->pointer == pointer)
1053           return EINA_TRUE;
1054      }
1055
1056    return EINA_FALSE;
1057 }
1058
1059 static void
1060 _e_comp_wl_input_cb_unbind_locked_pointer(struct wl_resource *resource)
1061 {
1062    E_Comp_Wl_Pointer_Constraint *constraint;
1063    constraint = wl_resource_get_user_data(resource);
1064
1065    if (!constraint)
1066      return;
1067
1068    _e_comp_wl_input_pointer_constraint_destroy(constraint);
1069 }
1070
1071 static void
1072 _e_comp_wl_input_cb_locked_pointer_destroy(struct wl_client *client,
1073                                            struct wl_resource *resource)
1074 {
1075    wl_resource_destroy(resource);
1076 }
1077
1078 static void
1079 _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint(struct wl_client *client,
1080                                                             struct wl_resource *resource,
1081                                                             wl_fixed_t surface_x,
1082                                                             wl_fixed_t surface_y)
1083 {
1084    E_Comp_Wl_Pointer_Constraint *constraint =
1085            (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1086
1087    if (!constraint)
1088      return;
1089
1090    constraint->hint_x_pending = surface_x;
1091    constraint->hint_y_pending = surface_y;
1092    constraint->is_hint_pending = EINA_TRUE;
1093    constraint->has_hint_set = EINA_TRUE;
1094 }
1095
1096 static void
1097 _e_comp_wl_input_cb_locked_pointer_set_region(struct wl_client *client,
1098                                               struct wl_resource *resource,
1099                                               struct wl_resource *region_resource)
1100 {
1101    E_Comp_Wl_Pointer_Constraint *constraint =
1102            (E_Comp_Wl_Pointer_Constraint *)wl_resource_get_user_data(resource);
1103
1104    if (!constraint)
1105      return;
1106
1107    if (region_resource)
1108      {
1109         pixman_region32_t *region = wl_resource_get_user_data(region_resource);
1110
1111         if (region)
1112           {
1113              pixman_region32_copy(&constraint->region_pending, region);
1114           }
1115         else
1116           {
1117              //CHECKME: check whether this situation is a kind of bug
1118              ERR("Invalid pixman_region from region (pointer constraint region!");
1119              pixman_region32_fini(&constraint->region_pending);
1120              pixman_region32_init_rect(&constraint->region_pending,
1121                                        INT32_MIN, INT32_MIN,
1122                                        UINT32_MAX, UINT32_MAX);
1123           }
1124
1125         constraint->has_region_set = EINA_TRUE;
1126      }
1127    else
1128      {
1129         pixman_region32_fini(&constraint->region_pending);
1130         pixman_region32_init_rect(&constraint->region_pending,
1131                                   INT32_MIN, INT32_MIN,
1132                                   UINT32_MAX, UINT32_MAX);
1133      }
1134
1135      constraint->is_region_pending = EINA_TRUE;
1136 }
1137
1138 static const struct zwp_locked_pointer_v1_interface _e_comp_wl_locked_pointer_interface =
1139 {
1140    _e_comp_wl_input_cb_locked_pointer_destroy,
1141    _e_comp_wl_input_cb_locked_pointer_set_cursor_position_hint,
1142    _e_comp_wl_input_cb_locked_pointer_set_region,
1143 };
1144
1145 static void
1146 _e_comp_wl_input_cb_pointer_constraints_lock_pointer(struct wl_client *client,
1147                                                      struct wl_resource *resource,
1148                                                      uint32_t id,
1149                                                      struct wl_resource *surface,
1150                                                      struct wl_resource *pointer,
1151                                                      struct wl_resource *region,
1152                                                      uint32_t lifetime)
1153 {
1154    if (!pointer || !surface)
1155      {
1156         ERR("Pointer resource or surface resource is invalid !");
1157         return;
1158      }
1159
1160    E_Client *ec = e_client_from_surface_resource(surface);
1161
1162    if (!ec)
1163      {
1164         ERR("Could not get ec from surface resource !");
1165         return;
1166      }
1167
1168    if (_e_comp_wl_input_has_pointer_constraints_for_pointer(ec, pointer))
1169      {
1170         ERR("Pointer constraints has been created already (ec: %p, pointer_resource: %u)",
1171              ec, wl_resource_get_id(resource));
1172         wl_resource_post_error(resource,
1173                                ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
1174                                "the pointer has a lock set already on this surface");
1175         return;
1176      }
1177
1178    struct wl_resource *res;
1179    res = wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
1180
1181    if (!res)
1182      {
1183         ERR("Could not create a resource for pointer constraints lock: %m");
1184         wl_client_post_no_memory(client);
1185         return;
1186      }
1187
1188    E_Comp_Wl_Pointer_Constraint *constraint;
1189    constraint = _e_comp_wl_input_pointer_constraint_create(ec, res, pointer, region, lifetime,
1190                                                            E_COMP_WL_POINTER_CONSTRAINT_TYPE_LOCK);
1191
1192    if (!constraint)
1193      {
1194         ERR("Could not create a pointer constraint.");
1195         wl_resource_destroy(res);
1196         wl_client_post_no_memory(client);
1197         return;
1198      }
1199
1200    wl_resource_set_implementation(res, &_e_comp_wl_locked_pointer_interface,
1201                                   constraint, _e_comp_wl_input_cb_unbind_locked_pointer);
1202
1203    _e_comp_wl_input_pointer_constraints_check_enable(constraint);
1204 }
1205
1206 static void
1207 _e_comp_wl_input_cb_pointer_constraints_confine_pointer(struct wl_client *client,
1208                                                         struct wl_resource *resource,
1209                                                         uint32_t id,
1210                                                         struct wl_resource *surface,
1211                                                         struct wl_resource *pointer,
1212                                                         struct wl_resource *region,
1213                                                         uint32_t lifetime)
1214 {
1215    (void) client;
1216    (void) resource;
1217    (void) id;
1218    (void) surface;
1219    (void) pointer;
1220    (void) region;
1221    (void) lifetime;
1222
1223    /* TODO: pointer constraints confine */
1224 }
1225
1226 static void
1227 _e_comp_wl_input_cb_pointer_constraints_destroy(struct wl_client *client,
1228                                           struct wl_resource *resource)
1229 {
1230    wl_resource_destroy(resource);
1231 }
1232
1233 static const struct zwp_pointer_constraints_v1_interface _e_pointer_constraints_interface = {
1234         _e_comp_wl_input_cb_pointer_constraints_destroy,
1235         _e_comp_wl_input_cb_pointer_constraints_lock_pointer,
1236         _e_comp_wl_input_cb_pointer_constraints_confine_pointer,
1237 };
1238
1239 static void
1240 _e_comp_wl_input_cb_unbind_pointer_constraints(struct wl_resource *resource)
1241 {
1242    e_comp_wl->ptr_constraints.resources =
1243      eina_list_remove(e_comp_wl->ptr_constraints.resources, resource);
1244 }
1245
1246 static void
1247 _e_comp_wl_input_cb_bind_pointer_constraints(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
1248 {
1249    struct wl_resource *resource;
1250
1251    resource = wl_resource_create(client, &zwp_pointer_constraints_v1_interface, version, id);
1252
1253    if (!resource)
1254      {
1255         ERR("Could not create pointer constraints resource: %m");
1256         return;
1257      }
1258
1259    e_comp_wl->ptr_constraints.resources =
1260      eina_list_append(e_comp_wl->ptr_constraints.resources, resource);
1261    wl_resource_set_implementation(resource, &_e_pointer_constraints_interface,
1262                                   NULL, _e_comp_wl_input_cb_unbind_pointer_constraints);
1263 }
1264
1265 static void
1266 _e_comp_wl_input_cb_surface_commit(void *data EINA_UNUSED, E_Client *ec)
1267 {
1268    wl_signal_emit(&e_comp_wl->ptr_constraints.surface_commit_signal, ec);
1269 }
1270
1271 static void
1272 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
1273 {
1274    FILE *file = NULL;
1275    TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
1276
1277    if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
1278      {
1279         TRACE_INPUT_END();
1280         return;
1281      }
1282
1283    if (keymap_path)
1284      {
1285         if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
1286           {
1287              WRN("%s is maybe link, so delete it\n", keymap_path);
1288           }
1289
1290         file = fopen(keymap_path, "w");
1291         EINA_SAFETY_ON_NULL_RETURN(file);
1292
1293         if (fputs(keymap_data, file) < 0)
1294           {
1295              WRN("Failed  to write keymap file: %s\n", keymap_path);
1296              fclose(file);
1297              unlink(keymap_path);
1298           }
1299         else
1300           {
1301              INF("Success to make keymap file: %s\n", keymap_path);
1302              fclose(file);
1303           }
1304      }
1305    TRACE_INPUT_END();
1306 }
1307
1308 static int
1309 _e_comp_wl_input_keymap_fd_get(off_t size)
1310 {
1311    int fd = 0, blen = 0, len = 0;
1312    char *path;
1313    char tmp[PATH_MAX] = {0, };
1314    long flags;
1315    mode_t old_umask;
1316
1317    blen = sizeof(tmp) - 20;
1318
1319    path = e_util_env_get("XDG_RUNTIME_DIR");
1320    if (!path) return -1;
1321
1322    len = strlen(path) + 19;
1323    if (len < blen)
1324      {
1325         strncpy(tmp, path, PATH_MAX - 20);
1326         strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
1327         E_FREE(path);
1328      }
1329    else
1330      {
1331         E_FREE(path);
1332         return -1;
1333      }
1334
1335    old_umask = umask(S_IRWXG|S_IRWXO);
1336    fd = mkstemp(tmp);
1337    umask(old_umask);
1338
1339    EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
1340
1341    flags = fcntl(fd, F_GETFD);
1342    if (flags < 0)
1343      {
1344         close(fd);
1345         return -1;
1346      }
1347
1348    if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
1349      {
1350         close(fd);
1351         return -1;
1352      }
1353
1354    if (ftruncate(fd, size) < 0)
1355      {
1356         close(fd);
1357         return -1;
1358      }
1359
1360    unlink(tmp);
1361    return fd;
1362 }
1363
1364 static void
1365 _e_comp_wl_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1366 {
1367    /* FIXME: will be deprecated after migration */
1368    char *tmp;
1369    xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1370
1371    /* unreference any existing keymap */
1372    if (e_comp_wl->xkb.keymap)
1373      xkb_map_unref(e_comp_wl->xkb.keymap);
1374
1375    /* unmap any existing keyboard area */
1376    if (e_comp_wl->xkb.area)
1377      munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1378    if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1379
1380    /* unreference any existing keyboard state */
1381    if (e_comp_wl->xkb.state)
1382      {
1383         latched =
1384            xkb_state_serialize_mods(e_comp_wl->xkb.state,
1385                                     XKB_STATE_MODS_LATCHED);
1386         locked =
1387            xkb_state_serialize_mods(e_comp_wl->xkb.state,
1388                                     XKB_STATE_MODS_LOCKED);
1389         group =
1390            xkb_state_serialize_layout(e_comp_wl->xkb.state,
1391                                       XKB_STATE_LAYOUT_EFFECTIVE);
1392         xkb_state_unref(e_comp_wl->xkb.state);
1393      }
1394
1395    /* create a new xkb state */
1396    e_comp_wl->xkb.state = xkb_state_new(keymap);
1397
1398    if (!e_comp_wl->xkb.state)
1399      {
1400         return;
1401      }
1402
1403    if ((latched) || (locked) || (group))
1404      xkb_state_update_mask(e_comp_wl->xkb.state, 0,
1405                            latched, locked, 0, 0, group);
1406
1407    /* increment keymap reference */
1408    e_comp_wl->xkb.keymap = keymap;
1409
1410    /* fetch updated modifiers */
1411    e_comp_wl->kbd.mod_shift =
1412       xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1413    e_comp_wl->kbd.mod_caps =
1414       xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1415    e_comp_wl->kbd.mod_ctrl =
1416       xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1417    e_comp_wl->kbd.mod_alt =
1418       xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1419    e_comp_wl->kbd.mod_super =
1420       xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1421
1422    if (!(tmp = xkb_map_get_as_string(keymap)))
1423      {
1424         ERR("Could not get keymap string");
1425         return;
1426      }
1427
1428    e_comp_wl->xkb.size = strlen(tmp) + 1;
1429    e_comp_wl->xkb.fd =
1430       _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
1431    if (e_comp_wl->xkb.fd < 0)
1432      {
1433         ERR("Could not create keymap file");
1434         free(tmp);
1435         return;
1436      }
1437
1438    e_comp_wl->xkb.area =
1439       mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
1440            MAP_SHARED, e_comp_wl->xkb.fd, 0);
1441    if (e_comp_wl->xkb.area == MAP_FAILED)
1442      {
1443         ERR("Failed to mmap keymap area: %m");
1444         free(tmp);
1445         return;
1446      }
1447
1448    strncpy(e_comp_wl->xkb.area, tmp, e_comp_wl->xkb.size);
1449    free(tmp);
1450 }
1451
1452 static void
1453 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1454 {
1455    char *tmp;
1456    xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1457    struct wl_resource *res;
1458    Eina_List *l;
1459
1460    /* unreference any existing keymap */
1461    if (e_comp_input_key->xkb.keymap)
1462      xkb_map_unref(e_comp_input_key->xkb.keymap);
1463
1464    /* unmap any existing keyboard area */
1465    if (e_comp_input_key->xkb.area)
1466      munmap(e_comp_input_key->xkb.area, e_comp_input_key->xkb.size);
1467    if (e_comp_input_key->xkb.fd >= 0) close(e_comp_input_key->xkb.fd);
1468
1469    /* unreference any existing keyboard state */
1470    if (e_comp_input_key->xkb.state)
1471      {
1472         latched =
1473           xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1474                                    XKB_STATE_MODS_LATCHED);
1475         locked =
1476           xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1477                                    XKB_STATE_MODS_LOCKED);
1478         group =
1479           xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1480                                      XKB_STATE_LAYOUT_EFFECTIVE);
1481         xkb_state_unref(e_comp_input_key->xkb.state);
1482      }
1483
1484    /* create a new xkb state */
1485    e_comp_input_key->xkb.state = xkb_state_new(keymap);
1486
1487    if (!e_comp_input_key->xkb.state)
1488      {
1489         return;
1490      }
1491
1492    if ((latched) || (locked) || (group))
1493      xkb_state_update_mask(e_comp_input_key->xkb.state, 0,
1494                            latched, locked, 0, 0, group);
1495
1496    /* increment keymap reference */
1497    e_comp_input_key->xkb.keymap = keymap;
1498
1499    /* fetch updated modifiers */
1500    e_comp_input_key->kbd.mod_shift =
1501      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1502    e_comp_input_key->kbd.mod_caps =
1503      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1504    e_comp_input_key->kbd.mod_ctrl =
1505      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1506    e_comp_input_key->kbd.mod_alt =
1507      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1508    e_comp_input_key->kbd.mod_super =
1509      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1510
1511    if (!(tmp = xkb_map_get_as_string(keymap)))
1512      {
1513         ERR("Could not get keymap string");
1514         return;
1515      }
1516
1517    e_comp_input_key->xkb.size = strlen(tmp) + 1;
1518    e_comp_input_key->xkb.fd =
1519      _e_comp_wl_input_keymap_fd_get(e_comp_input_key->xkb.size);
1520    if (e_comp_input_key->xkb.fd < 0)
1521      {
1522         ERR("Could not create keymap file");
1523         free(tmp);
1524         return;
1525      }
1526
1527    _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
1528
1529    e_comp_input_key->xkb.area =
1530      mmap(NULL, e_comp_input_key->xkb.size, (PROT_READ | PROT_WRITE),
1531           MAP_SHARED, e_comp_input_key->xkb.fd, 0);
1532    if (e_comp_input_key->xkb.area == MAP_FAILED)
1533      {
1534         ERR("Failed to mmap keymap area: %m");
1535         free(tmp);
1536         return;
1537      }
1538
1539    strncpy(e_comp_input_key->xkb.area, tmp, e_comp_input_key->xkb.size);
1540    free(tmp);
1541
1542    _e_comp_wl_keymap_update(keymap, keymap_path);
1543
1544    /* send updated keymap */
1545    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
1546    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
1547      wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1548                              e_comp_input_key->xkb.fd,
1549                              e_comp_input_key->xkb.size);
1550    TRACE_INPUT_END();
1551
1552    /* update modifiers */
1553    e_comp_wl_input_keyboard_modifiers_update();
1554 }
1555
1556 EINTERN Eina_Bool
1557 e_comp_wl_input_init(void)
1558 {
1559    /* set default seat name */
1560    if (!e_comp_wl->seat.name)
1561      e_comp_wl->seat.name = "default";
1562
1563    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1564    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1565
1566    g_mutex_init(&e_comp_wl->kbd.resource_mutex);
1567    g_mutex_init(&e_comp_wl->kbd.focused_mutex);
1568    g_mutex_init(&e_comp_wl->kbd.keys_mutex);
1569    g_mutex_init(&e_comp_wl->kbd.repeat_delay_mutex);
1570    g_mutex_init(&e_comp_wl->kbd.repeat_rate_mutex);
1571
1572    g_mutex_init(&e_comp_wl->xkb.keymap_mutex);
1573    g_mutex_init(&e_comp_wl->xkb.state_mutex);
1574
1575    /* get default keyboard repeat delay from configuration */
1576    atomic_store(&e_comp_input_key->kbd.repeat_delay, e_config->keyboard.repeat_delay);
1577    /* check for valid repeat_delay */
1578    /* if invalid, set the default value of repeat delay */
1579    if (e_comp_input_key->kbd.repeat_delay < 0)
1580      atomic_store(&e_comp_input_key->kbd.repeat_delay, 400);
1581
1582    /* get default keyboard repeat rate from configuration */
1583    atomic_store(&e_comp_input_key->kbd.repeat_rate, e_config->keyboard.repeat_rate);
1584    /* check for valid repeat_rate value */
1585    /* if invalid, set the default value of repeat rate value */
1586    if (e_comp_input_key->kbd.repeat_rate < 0)
1587      atomic_store(&e_comp_input_key->kbd.repeat_rate, 25);
1588
1589    /* create the global resource for input seat */
1590    e_comp_wl->seat.global =
1591      wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
1592                       e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
1593    if (!e_comp_wl->seat.global)
1594      {
1595         ERR("Could not create global for seat: %m");
1596         return EINA_FALSE;
1597      }
1598
1599    /* create the global resource for relative pointer */
1600    e_comp_wl->relative_ptr.global =
1601      wl_global_create(e_comp_wl->wl.disp,
1602                       &zwp_relative_pointer_manager_v1_interface, 1,
1603                       e_comp->wl_comp_data,
1604                       _e_comp_wl_input_cb_bind_relative_pointer_manager);
1605    if (!e_comp_wl->relative_ptr.global)
1606      {
1607         ERR("Could not create global for relative pointer: %m");
1608         return EINA_FALSE;
1609      }
1610
1611    /* create the global resource for pointer-constraints */
1612    e_comp_wl->ptr_constraints.global =
1613      wl_global_create(e_comp_wl->wl.disp,
1614                       &zwp_pointer_constraints_v1_interface, 1,
1615                       e_comp->wl_comp_data,
1616                       _e_comp_wl_input_cb_bind_pointer_constraints);
1617    if (!e_comp_wl->ptr_constraints.global)
1618      {
1619         ERR("Could not create global for pointer constraints: %m");
1620         return EINA_FALSE;
1621      }
1622
1623    e_comp_wl->ptr_constraints.ec = NULL;
1624    e_comp_wl->ptr_constraints.activated = EINA_FALSE;
1625    wl_signal_init(&e_comp_wl->ptr_constraints.pointer_destroy_signal);
1626    wl_signal_init(&e_comp_wl->ptr_constraints.surface_unmap_signal);
1627    wl_signal_init(&e_comp_wl->ptr_constraints.surface_commit_signal);
1628    wl_signal_init(&e_comp_wl->ptr_constraints.surface_mousein_signal);
1629    wl_signal_init(&e_comp_wl->ptr_constraints.surface_mouseout_signal);
1630
1631    _surface_commit_hook = e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
1632                                              _e_comp_wl_input_cb_surface_commit,
1633                                              NULL);
1634
1635    wl_array_init(&e_comp_input_key->kbd.keys);
1636    wl_array_init(&e_comp_input_key->kbd.routed_keys);
1637
1638    E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
1639
1640    /* get string values from environment variables */
1641    _env_e_default_xkb_rules   = e_util_env_get("E_DEFAULT_XKB_RULES"  );
1642    _env_e_default_xkb_model   = e_util_env_get("E_DEFAULT_XKB_MODEL"  );
1643    _env_e_default_xkb_layout  = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
1644    _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
1645    _env_e_default_xkb_opts    = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
1646
1647    return EINA_TRUE;
1648 }
1649
1650 EINTERN void
1651 e_comp_wl_input_shutdown(void)
1652 {
1653    struct wl_resource *res;
1654
1655    /* free environment variable string */
1656    E_FREE(_env_e_default_xkb_rules  );
1657    E_FREE(_env_e_default_xkb_model  );
1658    E_FREE(_env_e_default_xkb_layout );
1659    E_FREE(_env_e_default_xkb_variant);
1660    E_FREE(_env_e_default_xkb_opts   );
1661
1662    /* delete surface commit hook */
1663    if (_surface_commit_hook)
1664      {
1665         e_comp_wl_hook_del(_surface_commit_hook);
1666         _surface_commit_hook = NULL;
1667      }
1668
1669    /* destroy pointer resources */
1670    EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
1671      wl_resource_destroy(res);
1672
1673    /* destroy relative pointer resources */
1674    EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
1675      wl_resource_destroy(res);
1676
1677    /* destroy relative pointer manager resources */
1678    EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
1679      wl_resource_destroy(res);
1680
1681    /* destroy pointer constraints resources */
1682    EINA_LIST_FREE(e_comp_wl->ptr_constraints.resources, res)
1683      wl_resource_destroy(res);
1684
1685    /* destroy keyboard resources */
1686    EINA_LIST_FREE(e_comp_input_key->kbd.resources, res)
1687      wl_resource_destroy(res);
1688    e_comp_input_key->kbd.resources = eina_list_free(e_comp_input_key->kbd.resources);
1689
1690    g_mutex_clear(&e_comp_wl->kbd.resource_mutex);
1691    g_mutex_clear(&e_comp_wl->kbd.focused_mutex);
1692
1693    /* destroy touch resources */
1694    EINA_LIST_FREE(e_comp_wl->touch.resources, res)
1695      wl_resource_destroy(res);
1696
1697    /* destroy e_comp_input_key->kbd.keys array */
1698    wl_array_release(&e_comp_wl->kbd.keys);
1699
1700    wl_array_release(&e_comp_input_key->kbd.routed_keys);
1701
1702    /* unmap any existing keyboard area */
1703    if (e_comp_wl->xkb.area)
1704      munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
1705    if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
1706
1707    /* unreference any existing keyboard state */
1708    if (e_comp_wl->xkb.state)
1709      xkb_state_unref(e_comp_wl->xkb.state);
1710
1711    /* unreference any existing keymap */
1712    if (e_comp_wl->xkb.keymap)
1713      xkb_map_unref(e_comp_wl->xkb.keymap);
1714
1715    /* unreference any existing context */
1716    if (e_comp_wl->xkb.context)
1717      xkb_context_unref(e_comp_wl->xkb.context);
1718
1719    /* destroy the global relative pointer resource */
1720    if (e_comp_wl->relative_ptr.global)
1721      wl_global_destroy(e_comp_wl->relative_ptr.global);
1722    e_comp_wl->relative_ptr.global = NULL;
1723
1724    /* destroy the global pointer constraints resource */
1725    if (e_comp_wl->ptr_constraints.global)
1726      wl_global_destroy(e_comp_wl->ptr_constraints.global);
1727    e_comp_wl->ptr_constraints.global = NULL;
1728
1729    /* destroy the global seat resource */
1730    if (e_comp_wl->seat.global)
1731      wl_global_destroy(e_comp_wl->seat.global);
1732    e_comp_wl->seat.global = NULL;
1733
1734    dont_set_e_input_keymap = EINA_FALSE;
1735    dont_use_xkb_cache = EINA_FALSE;
1736
1737    g_mutex_clear(&e_comp_wl->xkb.keymap_mutex);
1738    g_mutex_clear(&e_comp_wl->xkb.state_mutex);
1739
1740    g_mutex_clear(&e_comp_wl->kbd.keys_mutex);
1741    g_mutex_clear(&e_comp_wl->kbd.repeat_delay_mutex);
1742    g_mutex_clear(&e_comp_wl->kbd.repeat_rate_mutex);
1743 }
1744
1745 EINTERN Eina_Bool
1746 e_comp_wl_input_pointer_check(struct wl_resource *res)
1747 {
1748    return wl_resource_instance_of(res, &wl_pointer_interface,
1749                                   &_e_pointer_interface);
1750 }
1751
1752 EINTERN Eina_Bool
1753 e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
1754 {
1755    return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
1756                                   &_e_relative_pointer_interface);
1757 }
1758
1759 EINTERN Eina_Bool
1760 e_comp_wl_input_keyboard_check(struct wl_resource *res)
1761 {
1762    return wl_resource_instance_of(res, &wl_keyboard_interface,
1763                                   &_e_keyboard_interface);
1764 }
1765
1766 EINTERN Eina_Bool
1767 e_comp_wl_input_keyboard_modifiers_serialize(void)
1768 {
1769    Eina_Bool changed = EINA_FALSE;
1770    xkb_mod_mask_t mod;
1771    xkb_layout_index_t grp;
1772
1773    xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
1774    xkb_layout_index_t mod_group;
1775
1776    mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1777                               XKB_STATE_DEPRESSED);
1778    mod_depressed = atomic_load(&e_comp_input_key->kbd.mod_depressed);
1779    changed |= mod != mod_depressed;
1780    atomic_store(&e_comp_input_key->kbd.mod_depressed, mod);
1781
1782    mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1783                               XKB_STATE_MODS_LATCHED);
1784
1785    mod_latched = atomic_load(&e_comp_input_key->kbd.mod_latched);
1786    changed |= mod != mod_latched;
1787    atomic_store(&e_comp_input_key->kbd.mod_latched, mod);
1788
1789    mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1790                               XKB_STATE_MODS_LOCKED);
1791    mod_locked = atomic_load(&e_comp_input_key->kbd.mod_locked);
1792    changed |= mod != mod_locked;
1793    atomic_store(&e_comp_input_key->kbd.mod_locked, mod);
1794
1795    grp = xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1796                                 XKB_STATE_LAYOUT_EFFECTIVE);
1797    mod_group = atomic_load(&e_comp_input_key->kbd.mod_group);
1798    changed |= grp != mod_group;
1799    atomic_store(&e_comp_input_key->kbd.mod_group, grp);
1800
1801    return changed;
1802 }
1803
1804 EINTERN void
1805 e_comp_wl_input_keyboard_modifiers_update(void)
1806 {
1807    uint32_t serial;
1808    struct wl_resource *res;
1809    Eina_List *l;
1810
1811    if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
1812    if (!e_comp_input_key->kbd.focused)
1813      {
1814        return;
1815      }
1816
1817    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1818    EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
1819      wl_keyboard_send_modifiers(res, serial,
1820                                 e_comp_input_key->kbd.mod_depressed,
1821                                 e_comp_input_key->kbd.mod_latched,
1822                                 e_comp_input_key->kbd.mod_locked,
1823                                 e_comp_input_key->kbd.mod_group);
1824 }
1825
1826 EINTERN void
1827 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
1828 {
1829    enum xkb_key_direction dir;
1830
1831    if (!e_comp_input_key->xkb.state)
1832      {
1833         return;
1834      }
1835
1836    if (pressed) dir = XKB_KEY_DOWN;
1837    else dir = XKB_KEY_UP;
1838
1839    atomic_store(&e_comp_input_key->kbd.mod_changed, xkb_state_update_key(e_comp_input_key->xkb.state, keycode + 8, dir));
1840
1841    e_comp_wl_input_keyboard_modifiers_update();
1842 }
1843
1844 EINTERN void
1845 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
1846 {
1847    /* check for valid compositor data */
1848    if (!e_comp->wl_comp_data)
1849      {
1850         ERR("No compositor data");
1851         return;
1852      }
1853
1854    e_comp_wl->ptr.enabled = !!enabled;
1855    _e_comp_wl_input_update_seat_caps(NULL);
1856 }
1857
1858 static void
1859 _e_comp_wl_input_thread_cb_keyboard_enabled_set(void *data)
1860 {
1861    Eina_Bool enabled;
1862    EINA_SAFETY_ON_NULL_RETURN(data);
1863
1864    enabled = *(Eina_Bool *)data;
1865
1866    e_comp_input_key->kbd.enabled = !!enabled;
1867 }
1868
1869 EINTERN void
1870 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
1871 {
1872    /* check for valid compositor data */
1873    if (!e_comp->wl_comp_data)
1874      {
1875         ERR("No compositor data");
1876         return;
1877      }
1878
1879    e_input_backend_thread_safe_call(_e_comp_wl_input_thread_cb_keyboard_enabled_set, &enabled, sizeof(Eina_Bool));
1880    _e_comp_wl_input_update_seat_caps(NULL);
1881 }
1882
1883 E_API Eina_Bool
1884 e_comp_wl_input_keymap_cache_file_use_get(void)
1885 {
1886    return use_cache_keymap;
1887 }
1888
1889 E_API Eina_Stringshare *
1890 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
1891 {
1892    return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
1893             names.rules ? names.rules : "evdev",
1894             names.model ? names.model : "pc105",
1895             names.layout ? names.layout : "us",
1896             names.variant ? names.variant : "",
1897             names.options ? names.options : "");
1898 }
1899
1900 EINTERN struct xkb_keymap *
1901 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
1902 {
1903    struct xkb_keymap *keymap;
1904    char *cache_path = NULL;
1905    FILE *file = NULL;
1906
1907    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1908
1909    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
1910
1911    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1912      {
1913         cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
1914         file = fopen(cache_path, "r");
1915      }
1916
1917    if (!file)
1918      {
1919         INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
1920
1921         /* fetch new keymap based on names */
1922         keymap = xkb_map_new_from_names(ctx, &names, 0);
1923         use_cache_keymap = EINA_FALSE;
1924      }
1925    else
1926      {
1927         INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
1928         keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1929         if (!keymap)
1930           {
1931              WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
1932              fclose(file);
1933              if (remove(cache_path) != 0)
1934                WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
1935              keymap = xkb_map_new_from_names(ctx, &names, 0);
1936              use_cache_keymap = EINA_FALSE;
1937           }
1938         else
1939           {
1940              eina_stringshare_del(cache_path);
1941              cache_path = NULL;
1942              fclose(file);
1943              use_cache_keymap = EINA_TRUE;
1944           }
1945      }
1946
1947    *keymap_path = cache_path;
1948    EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
1949
1950    TRACE_INPUT_END();
1951
1952    return keymap;
1953 }
1954
1955 E_API void
1956 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
1957                            const char *variant, const char *options,
1958                            struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
1959 {
1960    struct xkb_keymap *keymap;
1961    struct xkb_rule_names names;
1962    char *keymap_path = NULL;
1963    Eina_Bool use_dflt_xkb = EINA_FALSE;
1964    const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
1965
1966    /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
1967    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
1968
1969    if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
1970
1971    /* unreference any existing context */
1972    if (e_comp_input_key->xkb.context)
1973      xkb_context_unref(e_comp_input_key->xkb.context);
1974
1975    /* create a new xkb context */
1976    if (use_dflt_xkb) e_comp_input_key->xkb.context = dflt_ctx;
1977    else e_comp_input_key->xkb.context = xkb_context_new(0);
1978
1979    if (!e_comp_input_key->xkb.context)
1980      {
1981         TRACE_INPUT_END();
1982         return;
1983      }
1984
1985    if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1986      e_input_device_keyboard_cached_context_set(e_comp_input_key->xkb.context);
1987
1988    /* assemble xkb_rule_names so we can fetch keymap */
1989    memset(&names, 0, sizeof(names));
1990    if (rules) names.rules = strdup(rules);
1991    else
1992      {
1993         default_rules = e_comp_wl_input_keymap_default_rules_get();
1994         names.rules = strdup(default_rules);
1995      }
1996    if (model) names.model = strdup(model);
1997    else
1998      {
1999         default_model = e_comp_wl_input_keymap_default_model_get();
2000         names.model = strdup(default_model);
2001      }
2002    if (layout) names.layout = strdup(layout);
2003    else
2004      {
2005         default_layout = e_comp_wl_input_keymap_default_layout_get();
2006         names.layout = strdup(default_layout);
2007      }
2008    if (variant) names.variant = strdup(variant);
2009    else
2010      {
2011         default_variant = e_comp_wl_input_keymap_default_variant_get();
2012         if (default_variant) names.variant = strdup(default_variant);
2013      }
2014    if (options) names.options = strdup(options);
2015    else
2016      {
2017         default_options = e_comp_wl_input_keymap_default_options_get();
2018         if (default_options) names.options = strdup(default_options);
2019      }
2020
2021    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
2022    if (use_dflt_xkb)
2023      {
2024         keymap = dflt_map;
2025         keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
2026         if (access(keymap_path, R_OK) == 0)
2027           {
2028              eina_stringshare_del(keymap_path);
2029              keymap_path = NULL;
2030           }
2031      }
2032    else
2033      keymap = e_comp_wl_input_keymap_compile(e_comp_input_key->xkb.context, names, &keymap_path);
2034    TRACE_INPUT_END();
2035
2036    /* update compositor keymap */
2037    _e_comp_wl_input_keymap_update(keymap, keymap_path);
2038
2039    if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
2040      e_input_device_keyboard_cached_keymap_set(keymap);
2041
2042    /* cleanup */
2043    if (keymap_path) eina_stringshare_del(keymap_path);
2044    free((char *)names.rules);
2045    free((char *)names.model);
2046    free((char *)names.layout);
2047    if (names.variant) free((char *)names.variant);
2048    if (names.options) free((char *)names.options);
2049    TRACE_INPUT_END();
2050 }
2051
2052 EINTERN const char*
2053 e_comp_wl_input_keymap_default_rules_get(void)
2054 {
2055    if (e_config->xkb.default_rmlvo.rules)
2056      return e_config->xkb.default_rmlvo.rules;
2057
2058    if (_env_e_default_xkb_rules)
2059      return _env_e_default_xkb_rules;
2060
2061    return "evdev";
2062 }
2063
2064 EINTERN const char*
2065 e_comp_wl_input_keymap_default_model_get(void)
2066 {
2067    if (e_config->xkb.default_rmlvo.model)
2068      return e_config->xkb.default_rmlvo.model;
2069
2070    if (_env_e_default_xkb_model)
2071      return _env_e_default_xkb_model;
2072
2073    return "pc105";
2074 }
2075
2076 EINTERN const char*
2077 e_comp_wl_input_keymap_default_layout_get(void)
2078 {
2079    if (e_config->xkb.default_rmlvo.layout)
2080      return e_config->xkb.default_rmlvo.layout;
2081
2082    if (_env_e_default_xkb_layout)
2083      return _env_e_default_xkb_layout;
2084
2085    return "us";
2086 }
2087
2088 EINTERN const char*
2089 e_comp_wl_input_keymap_default_variant_get(void)
2090 {
2091    if (e_config->xkb.default_rmlvo.variant)
2092      return e_config->xkb.default_rmlvo.variant;
2093
2094    if (_env_e_default_xkb_variant)
2095      return _env_e_default_xkb_variant;
2096
2097    return NULL;
2098 }
2099
2100 EINTERN const char*
2101 e_comp_wl_input_keymap_default_options_get(void)
2102 {
2103    if (e_config->xkb.default_rmlvo.options)
2104      return e_config->xkb.default_rmlvo.options;
2105
2106    if (_env_e_default_xkb_opts)
2107      return _env_e_default_xkb_opts;
2108
2109    return NULL;
2110 }
2111
2112 EINTERN void
2113 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
2114 {
2115    /* check for valid compositor data */
2116    if (!e_comp->wl_comp_data)
2117      {
2118         ERR("No compositor data");
2119         return;
2120      }
2121
2122    e_comp_wl->touch.enabled = !!enabled;
2123    _e_comp_wl_input_update_seat_caps(NULL);
2124 }
2125
2126 EINTERN void
2127 e_comp_wl_input_seat_caps_set(unsigned int caps)
2128 {
2129    Eina_Bool need_update = EINA_FALSE;
2130
2131    /* check for valid compositor data */
2132    if (!e_comp->wl_comp_data)
2133      {
2134         ERR("No compositor data");
2135         return;
2136      }
2137
2138    if (caps & E_INPUT_SEAT_POINTER)
2139      e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
2140    if (caps & E_INPUT_SEAT_KEYBOARD)
2141      e_comp_input_key->kbd.enabled = need_update = EINA_TRUE;
2142    if (caps & E_INPUT_SEAT_TOUCH)
2143      e_comp_wl->touch.enabled = need_update = EINA_TRUE;
2144
2145    if (need_update)
2146      _e_comp_wl_input_update_seat_caps(NULL);
2147 }
2148
2149 EINTERN Eina_Bool
2150 e_comp_wl_input_touch_check(struct wl_resource *res)
2151 {
2152    return wl_resource_instance_of(res, &wl_touch_interface,
2153                                   &_e_touch_interface);
2154 }
2155
2156 E_API void
2157 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
2158 {
2159    struct wl_resource *res;
2160    Eina_List *l;
2161
2162    EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
2163
2164    atomic_store(&e_comp_input_key->kbd.repeat_delay, delay);
2165    atomic_store(&e_comp_input_key->kbd.repeat_rate, rate);
2166
2167    EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
2168      {
2169         if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
2170           wl_keyboard_send_repeat_info(res, e_comp_input_key->kbd.repeat_rate,
2171                                        e_comp_input_key->kbd.repeat_delay);
2172      }
2173 }
2174
2175 typedef struct _keycode_map{
2176     xkb_keysym_t keysym;
2177     xkb_keycode_t keycode;
2178 } keycode_map;
2179
2180 static void
2181 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2182 {
2183    keycode_map *found_keycodes = (keycode_map *)data;
2184    xkb_keysym_t keysym = found_keycodes->keysym;
2185    int nsyms = 0;
2186    const xkb_keysym_t *syms_out = NULL;
2187
2188    nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2189    if (nsyms && syms_out)
2190      {
2191         if (*syms_out == keysym)
2192           {
2193              found_keycodes->keycode = key;
2194           }
2195      }
2196 }
2197
2198 int
2199 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
2200 {
2201    keycode_map found_keycodes = {0,};
2202    found_keycodes.keysym = keysym;
2203    xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2204
2205    return found_keycodes.keycode;
2206 }
2207
2208 E_API int
2209 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
2210 {
2211    struct xkb_keymap *keymap = NULL;
2212    xkb_keysym_t keysym = 0x0;
2213    int keycode = 0;
2214    char *name_tmp;
2215
2216    EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
2217    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
2218
2219    keymap = e_comp_input_key->xkb.keymap;
2220    EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
2221
2222    keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
2223    if (keysym == XKB_KEY_NoSymbol)
2224      {
2225         if (strlen(name) <= sizeof("Keycode-")) goto finish;
2226
2227         if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
2228           {
2229              name_tmp = (char *)name + sizeof("Keycode-") - 1;
2230              keycode = atoi(name_tmp);
2231              if (keycode <= 8) goto finish;
2232
2233              return keycode;
2234           }
2235         else
2236           goto finish;
2237      }
2238
2239    keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
2240
2241    return keycode;
2242
2243 finish:
2244    return 0;
2245 }
2246
2247 EINTERN char *
2248 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
2249 {
2250    struct xkb_state *state;
2251    xkb_keysym_t sym = XKB_KEY_NoSymbol;
2252    char name[256] = {0, };
2253
2254    EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
2255    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
2256    if (!e_comp_input_key->xkb.state)
2257      {
2258         return NULL;
2259      }
2260
2261    state = e_comp_input_key->xkb.state;
2262
2263    sym = xkb_state_key_get_one_sym(state, keycode);
2264
2265    if (sym == XKB_KEY_NoSymbol)
2266      {
2267         snprintf(name, sizeof(name), "Keycode-%u", keycode);
2268      }
2269    else
2270      xkb_keysym_get_name(sym, name, sizeof(name));
2271
2272    return strdup(name);
2273 }
2274
2275 static void
2276 _e_comp_wl_input_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
2277 {
2278    char *keymap_path = NULL;
2279    struct xkb_context *context;
2280    struct xkb_keymap *keymap;
2281    struct xkb_rule_names names = {0,};
2282    const char* default_rules, *default_model, *default_layout, *default_variant, *default_options;
2283
2284    TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_set);
2285
2286    context = xkb_context_new(0);
2287    EINA_SAFETY_ON_NULL_RETURN(context);
2288
2289    /* assemble xkb_rule_names so we can fetch keymap */
2290    memset(&names, 0, sizeof(names));
2291
2292    default_rules = e_comp_wl_input_keymap_default_rules_get();
2293    default_model = e_comp_wl_input_keymap_default_model_get();
2294    default_layout = e_comp_wl_input_keymap_default_layout_get();
2295    default_variant = e_comp_wl_input_keymap_default_variant_get();
2296    default_options = e_comp_wl_input_keymap_default_options_get();
2297
2298    names.rules = strdup(default_rules);
2299    names.model = strdup(default_model);
2300    names.layout = strdup(default_layout);
2301    if (default_variant) names.variant = strdup(default_variant);
2302    if (default_options) names.options = strdup(default_options);
2303
2304    keymap = e_comp_wl_input_keymap_compile(context, names, &keymap_path);
2305    eina_stringshare_del(keymap_path);
2306    EINA_SAFETY_ON_NULL_GOTO(keymap, cleanup);
2307
2308    *ctx = context;
2309    *map = keymap;
2310
2311    if (dont_set_e_input_keymap == EINA_FALSE)
2312      {
2313         e_input_device_keyboard_cached_context_set(*ctx);
2314         e_input_device_keyboard_cached_keymap_set(*map);
2315      }
2316
2317 cleanup:
2318    free((char *)names.rules);
2319    free((char *)names.model);
2320    free((char *)names.layout);
2321    if (names.variant) free((char *)names.variant);
2322    if (names.options) free((char *)names.options);
2323
2324    TRACE_INPUT_END();
2325 }
2326
2327 E_API Eina_Bool
2328 e_comp_wl_input_pointer_constraint_activated_get(void)
2329 {
2330    return e_comp_wl->ptr_constraints.activated;
2331 }
2332
2333 EINTERN void
2334 e_comp_wl_input_keymap_init(void)
2335 {
2336    struct xkb_context *ctx = NULL;
2337    struct xkb_keymap *map = NULL;
2338
2339    /* keymap */
2340    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2341    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2342
2343    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
2344      {
2345         _e_comp_wl_input_keymap_set(&ctx, &map);
2346      }
2347
2348    e_comp_wl_input_keymap_set(e_comp_wl_input_keymap_default_rules_get(),
2349                               e_comp_wl_input_keymap_default_model_get(),
2350                               e_comp_wl_input_keymap_default_layout_get(),
2351                               e_comp_wl_input_keymap_default_variant_get(),
2352                               e_comp_wl_input_keymap_default_options_get(),
2353                               ctx, map);
2354 }
2355
2356 E_API struct xkb_keymap *
2357 e_comp_wl_input_xkb_keymap_get()
2358 {
2359    EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, NULL);
2360    return e_comp_input_key->xkb.keymap;
2361 }
2362
2363 E_API const Eina_List *
2364 e_comp_wl_input_kbd_resources_get()
2365 {
2366    EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, NULL);
2367    return e_comp_input_key->kbd.resources;
2368 }
2369
2370 E_API int
2371 e_comp_wl_input_kbd_repeat_delay_get()
2372 {
2373    EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, -1);
2374    return e_comp_input_key->kbd.repeat_delay;
2375 }
2376
2377 E_API int
2378 e_comp_wl_input_kbd_repeat_rate_get()
2379 {
2380    EINA_SAFETY_ON_FALSE_RETURN_VAL(e_comp_input_key, -1);
2381    return e_comp_input_key->kbd.repeat_rate;
2382 }