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