a64fe788b68501f724fc0f0aaa7be1fb36b25caf
[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_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
1297 {
1298    char *tmp;
1299    xkb_mod_mask_t latched = 0, locked = 0, group = 0;
1300    struct wl_resource *res;
1301    Eina_List *l;
1302
1303    /* unreference any existing keymap */
1304    if (e_comp_input_key->xkb.keymap)
1305      xkb_map_unref(e_comp_input_key->xkb.keymap);
1306
1307    /* unmap any existing keyboard area */
1308    if (e_comp_input_key->xkb.area)
1309      munmap(e_comp_input_key->xkb.area, e_comp_input_key->xkb.size);
1310    if (e_comp_input_key->xkb.fd >= 0) close(e_comp_input_key->xkb.fd);
1311
1312    /* unreference any existing keyboard state */
1313    if (e_comp_input_key->xkb.state)
1314      {
1315         latched =
1316           xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1317                                    XKB_STATE_MODS_LATCHED);
1318         locked =
1319           xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1320                                    XKB_STATE_MODS_LOCKED);
1321         group =
1322           xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1323                                      XKB_STATE_LAYOUT_EFFECTIVE);
1324         xkb_state_unref(e_comp_input_key->xkb.state);
1325      }
1326
1327    /* create a new xkb state */
1328    e_comp_input_key->xkb.state = xkb_state_new(keymap);
1329
1330    if (!e_comp_input_key->xkb.state)
1331      {
1332         return;
1333      }
1334
1335    if ((latched) || (locked) || (group))
1336      xkb_state_update_mask(e_comp_input_key->xkb.state, 0,
1337                            latched, locked, 0, 0, group);
1338
1339    /* increment keymap reference */
1340    e_comp_input_key->xkb.keymap = keymap;
1341
1342    /* fetch updated modifiers */
1343    e_comp_wl->kbd.mod_shift =
1344      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
1345    e_comp_wl->kbd.mod_caps =
1346      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
1347    e_comp_wl->kbd.mod_ctrl =
1348      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
1349    e_comp_wl->kbd.mod_alt =
1350      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
1351    e_comp_wl->kbd.mod_super =
1352      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
1353
1354    if (!(tmp = xkb_map_get_as_string(keymap)))
1355      {
1356         ERR("Could not get keymap string");
1357         return;
1358      }
1359
1360    e_comp_input_key->xkb.size = strlen(tmp) + 1;
1361    e_comp_input_key->xkb.fd =
1362      _e_comp_wl_input_keymap_fd_get(e_comp_input_key->xkb.size);
1363    if (e_comp_input_key->xkb.fd < 0)
1364      {
1365         ERR("Could not create keymap file");
1366         free(tmp);
1367         return;
1368      }
1369
1370    _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
1371
1372    e_comp_input_key->xkb.area =
1373      mmap(NULL, e_comp_input_key->xkb.size, (PROT_READ | PROT_WRITE),
1374           MAP_SHARED, e_comp_input_key->xkb.fd, 0);
1375    if (e_comp_input_key->xkb.area == MAP_FAILED)
1376      {
1377         ERR("Failed to mmap keymap area: %m");
1378         free(tmp);
1379         return;
1380      }
1381
1382    strncpy(e_comp_input_key->xkb.area, tmp, e_comp_input_key->xkb.size);
1383    free(tmp);
1384
1385    /* send updated keymap */
1386    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
1387    g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1388    EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1389      wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1390                              e_comp_input_key->xkb.fd,
1391                              e_comp_input_key->xkb.size);
1392    g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1393    TRACE_INPUT_END();
1394
1395    /* update modifiers */
1396    e_comp_wl_input_keyboard_modifiers_update();
1397 }
1398
1399 EINTERN Eina_Bool
1400 e_comp_wl_input_init(void)
1401 {
1402    /* set default seat name */
1403    if (!e_comp_wl->seat.name)
1404      e_comp_wl->seat.name = "default";
1405
1406    e_comp_input_init();
1407
1408    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1409    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
1410
1411    g_mutex_init(&e_comp_wl->kbd.resource_mutex);
1412    g_mutex_init(&e_comp_wl->kbd.focused_mutex);
1413    g_mutex_init(&e_comp_wl->kbd.keys_mutex);
1414    g_mutex_init(&e_comp_wl->kbd.repeat_delay_mutex);
1415    g_mutex_init(&e_comp_wl->kbd.repeat_rate_mutex);
1416
1417    /* get default keyboard repeat delay from configuration */
1418    atomic_store(&e_comp_wl->kbd.repeat_delay, e_config->keyboard.repeat_delay);
1419    /* check for valid repeat_delay */
1420    /* if invalid, set the default value of repeat delay */
1421    if (e_comp_wl->kbd.repeat_delay < 0)
1422      atomic_store(&e_comp_wl->kbd.repeat_delay, 400);
1423
1424    /* get default keyboard repeat rate from configuration */
1425    atomic_store(&e_comp_wl->kbd.repeat_rate, e_config->keyboard.repeat_rate);
1426    /* check for valid repeat_rate value */
1427    /* if invalid, set the default value of repeat rate value */
1428    if (e_comp_wl->kbd.repeat_rate < 0)
1429      atomic_store(&e_comp_wl->kbd.repeat_rate, 25);
1430
1431    /* create the global resource for input seat */
1432    e_comp_wl->seat.global =
1433      wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
1434                       e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
1435    if (!e_comp_wl->seat.global)
1436      {
1437         ERR("Could not create global for seat: %m");
1438         return EINA_FALSE;
1439      }
1440
1441    /* create the global resource for relative pointer */
1442    e_comp_wl->relative_ptr.global =
1443      wl_global_create(e_comp_wl->wl.disp,
1444                       &zwp_relative_pointer_manager_v1_interface, 1,
1445                       e_comp->wl_comp_data,
1446                       _e_comp_wl_input_cb_bind_relative_pointer_manager);
1447    if (!e_comp_wl->relative_ptr.global)
1448      {
1449         ERR("Could not create global for relative pointer: %m");
1450         return EINA_FALSE;
1451      }
1452
1453    /* create the global resource for pointer-constraints */
1454    e_comp_wl->ptr_constraints.global =
1455      wl_global_create(e_comp_wl->wl.disp,
1456                       &zwp_pointer_constraints_v1_interface, 1,
1457                       e_comp->wl_comp_data,
1458                       _e_comp_wl_input_cb_bind_pointer_constraints);
1459    if (!e_comp_wl->ptr_constraints.global)
1460      {
1461         ERR("Could not create global for pointer constraints: %m");
1462         return EINA_FALSE;
1463      }
1464
1465    e_comp_wl->ptr_constraints.ec = NULL;
1466    e_comp_wl->ptr_constraints.activated = EINA_FALSE;
1467    wl_signal_init(&e_comp_wl->ptr_constraints.pointer_destroy_signal);
1468    wl_signal_init(&e_comp_wl->ptr_constraints.surface_unmap_signal);
1469    wl_signal_init(&e_comp_wl->ptr_constraints.surface_commit_signal);
1470    wl_signal_init(&e_comp_wl->ptr_constraints.surface_mousein_signal);
1471
1472    _surface_commit_hook = e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
1473                                              _e_comp_wl_input_cb_surface_commit,
1474                                              NULL);
1475
1476    g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1477    wl_array_init(&e_comp_wl->kbd.keys);
1478    g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1479
1480    wl_array_init(&e_comp_wl->kbd.routed_keys);
1481
1482    E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
1483
1484    /* get string values from environment variables */
1485    _env_e_default_xkb_rules   = e_util_env_get("E_DEFAULT_XKB_RULES"  );
1486    _env_e_default_xkb_model   = e_util_env_get("E_DEFAULT_XKB_MODEL"  );
1487    _env_e_default_xkb_layout  = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
1488    _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
1489    _env_e_default_xkb_opts    = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
1490
1491    return EINA_TRUE;
1492 }
1493
1494 EINTERN void
1495 e_comp_wl_input_shutdown(void)
1496 {
1497    struct wl_resource *res;
1498
1499    /* free environment variable string */
1500    E_FREE(_env_e_default_xkb_rules  );
1501    E_FREE(_env_e_default_xkb_model  );
1502    E_FREE(_env_e_default_xkb_layout );
1503    E_FREE(_env_e_default_xkb_variant);
1504    E_FREE(_env_e_default_xkb_opts   );
1505
1506    /* delete surface commit hook */
1507    if (_surface_commit_hook)
1508      {
1509         e_comp_wl_hook_del(_surface_commit_hook);
1510         _surface_commit_hook = NULL;
1511      }
1512
1513    /* destroy pointer resources */
1514    EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
1515      wl_resource_destroy(res);
1516
1517    /* destroy relative pointer resources */
1518    EINA_LIST_FREE(e_comp_wl->relative_ptr.resources, res)
1519      wl_resource_destroy(res);
1520
1521    /* destroy relative pointer manager resources */
1522    EINA_LIST_FREE(e_comp_wl->relative_ptr.manager_resources, res)
1523      wl_resource_destroy(res);
1524
1525    /* destroy pointer constraints resources */
1526    EINA_LIST_FREE(e_comp_wl->ptr_constraints.resources, res)
1527      wl_resource_destroy(res);
1528
1529    /* destroy keyboard resources */
1530    g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1531    EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
1532      wl_resource_destroy(res);
1533    e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
1534    g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
1535
1536    g_mutex_clear(&e_comp_wl->kbd.resource_mutex);
1537    g_mutex_clear(&e_comp_wl->kbd.focused_mutex);
1538
1539    /* destroy touch resources */
1540    EINA_LIST_FREE(e_comp_wl->touch.resources, res)
1541      wl_resource_destroy(res);
1542
1543    /* destroy e_comp_wl->kbd.keys array */
1544    g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
1545    wl_array_release(&e_comp_wl->kbd.keys);
1546    g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
1547
1548    wl_array_release(&e_comp_wl->kbd.routed_keys);
1549
1550    e_comp_input_shutdown();
1551
1552    /* destroy the global relative pointer resource */
1553    if (e_comp_wl->relative_ptr.global)
1554      wl_global_destroy(e_comp_wl->relative_ptr.global);
1555    e_comp_wl->relative_ptr.global = NULL;
1556
1557    /* destroy the global pointer constraints resource */
1558    if (e_comp_wl->ptr_constraints.global)
1559      wl_global_destroy(e_comp_wl->ptr_constraints.global);
1560    e_comp_wl->ptr_constraints.global = NULL;
1561
1562    /* destroy the global seat resource */
1563    if (e_comp_wl->seat.global)
1564      wl_global_destroy(e_comp_wl->seat.global);
1565    e_comp_wl->seat.global = NULL;
1566
1567    dont_set_e_input_keymap = EINA_FALSE;
1568    dont_use_xkb_cache = EINA_FALSE;
1569
1570    g_mutex_clear(&e_comp_wl->kbd.keys_mutex);
1571    g_mutex_clear(&e_comp_wl->kbd.repeat_delay_mutex);
1572    g_mutex_clear(&e_comp_wl->kbd.repeat_rate_mutex);
1573 }
1574
1575 EINTERN Eina_Bool
1576 e_comp_wl_input_pointer_check(struct wl_resource *res)
1577 {
1578    return wl_resource_instance_of(res, &wl_pointer_interface,
1579                                   &_e_pointer_interface);
1580 }
1581
1582 EINTERN Eina_Bool
1583 e_comp_wl_input_relative_pointer_check(struct wl_resource *res)
1584 {
1585    return wl_resource_instance_of(res, &zwp_relative_pointer_v1_interface,
1586                                   &_e_relative_pointer_interface);
1587 }
1588
1589 EINTERN Eina_Bool
1590 e_comp_wl_input_keyboard_check(struct wl_resource *res)
1591 {
1592    return wl_resource_instance_of(res, &wl_keyboard_interface,
1593                                   &_e_keyboard_interface);
1594 }
1595
1596 EINTERN Eina_Bool
1597 e_comp_wl_input_keyboard_modifiers_serialize(void)
1598 {
1599    Eina_Bool changed = EINA_FALSE;
1600    xkb_mod_mask_t mod;
1601    xkb_layout_index_t grp;
1602
1603    xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
1604    xkb_layout_index_t mod_group;
1605
1606    mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1607                               XKB_STATE_DEPRESSED);
1608    mod_depressed = atomic_load(&e_comp_wl->kbd.mod_depressed);
1609    changed |= mod != mod_depressed;
1610    atomic_store(&e_comp_wl->kbd.mod_depressed, mod);
1611
1612    mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1613                               XKB_STATE_MODS_LATCHED);
1614
1615    mod_latched = atomic_load(&e_comp_wl->kbd.mod_latched);
1616    changed |= mod != mod_latched;
1617    atomic_store(&e_comp_wl->kbd.mod_latched, mod);
1618
1619    mod = xkb_state_serialize_mods(e_comp_input_key->xkb.state,
1620                               XKB_STATE_MODS_LOCKED);
1621    mod_locked = atomic_load(&e_comp_wl->kbd.mod_locked);
1622    changed |= mod != mod_locked;
1623    atomic_store(&e_comp_wl->kbd.mod_locked, mod);
1624
1625    grp = xkb_state_serialize_layout(e_comp_input_key->xkb.state,
1626                                 XKB_STATE_LAYOUT_EFFECTIVE);
1627    mod_group = atomic_load(&e_comp_wl->kbd.mod_group);
1628    changed |= grp != mod_group;
1629    atomic_store(&e_comp_wl->kbd.mod_group, grp);
1630
1631    return changed;
1632 }
1633
1634 EINTERN void
1635 e_comp_wl_input_keyboard_modifiers_update(void)
1636 {
1637    uint32_t serial;
1638    struct wl_resource *res;
1639    Eina_List *l;
1640
1641    if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
1642    g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1643    if (!e_comp_wl->kbd.focused)
1644      {
1645        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1646        return;
1647      }
1648
1649    g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1650
1651    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1652    g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
1653    EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
1654      wl_keyboard_send_modifiers(res, serial,
1655                                 e_comp_wl->kbd.mod_depressed,
1656                                 e_comp_wl->kbd.mod_latched,
1657                                 e_comp_wl->kbd.mod_locked,
1658                                 e_comp_wl->kbd.mod_group);
1659    g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
1660 }
1661
1662 EINTERN void
1663 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
1664 {
1665    enum xkb_key_direction dir;
1666
1667    if (!e_comp_input_key->xkb.state)
1668      {
1669         return;
1670      }
1671
1672    if (pressed) dir = XKB_KEY_DOWN;
1673    else dir = XKB_KEY_UP;
1674
1675    atomic_store(&e_comp_wl->kbd.mod_changed, xkb_state_update_key(e_comp_input_key->xkb.state, keycode + 8, dir));
1676
1677    e_comp_wl_input_keyboard_modifiers_update();
1678 }
1679
1680 EINTERN void
1681 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
1682 {
1683    /* check for valid compositor data */
1684    if (!e_comp->wl_comp_data)
1685      {
1686         ERR("No compositor data");
1687         return;
1688      }
1689
1690    e_comp_wl->ptr.enabled = !!enabled;
1691    _e_comp_wl_input_update_seat_caps(NULL);
1692 }
1693
1694 EINTERN void
1695 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
1696 {
1697    /* check for valid compositor data */
1698    if (!e_comp->wl_comp_data)
1699      {
1700         ERR("No compositor data");
1701         return;
1702      }
1703
1704    e_comp_wl->kbd.enabled = !!enabled;
1705    _e_comp_wl_input_update_seat_caps(NULL);
1706 }
1707
1708 E_API Eina_Bool
1709 e_comp_wl_input_keymap_cache_file_use_get(void)
1710 {
1711    return use_cache_keymap;
1712 }
1713
1714 E_API Eina_Stringshare *
1715 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
1716 {
1717    return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
1718             names.rules ? names.rules : "evdev",
1719             names.model ? names.model : "pc105",
1720             names.layout ? names.layout : "us",
1721             names.variant ? names.variant : "",
1722             names.options ? names.options : "");
1723 }
1724
1725 EINTERN struct xkb_keymap *
1726 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
1727 {
1728    struct xkb_keymap *keymap;
1729    char *cache_path = NULL;
1730    FILE *file = NULL;
1731
1732    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1733
1734    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
1735
1736    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
1737      {
1738         cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
1739         file = fopen(cache_path, "r");
1740      }
1741
1742    if (!file)
1743      {
1744         INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
1745
1746         /* fetch new keymap based on names */
1747         keymap = xkb_map_new_from_names(ctx, &names, 0);
1748         use_cache_keymap = EINA_FALSE;
1749      }
1750    else
1751      {
1752         INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
1753         keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1754         if (!keymap)
1755           {
1756              WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
1757              fclose(file);
1758              if (remove(cache_path) != 0)
1759                WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
1760              keymap = xkb_map_new_from_names(ctx, &names, 0);
1761              use_cache_keymap = EINA_FALSE;
1762           }
1763         else
1764           {
1765              eina_stringshare_del(cache_path);
1766              cache_path = NULL;
1767              fclose(file);
1768              use_cache_keymap = EINA_TRUE;
1769           }
1770      }
1771
1772    *keymap_path = cache_path;
1773    EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
1774
1775    TRACE_INPUT_END();
1776
1777    return keymap;
1778 }
1779
1780 E_API void
1781 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
1782                            const char *variant, const char *options,
1783                            struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
1784 {
1785    struct xkb_keymap *keymap;
1786    struct xkb_rule_names names;
1787    char *keymap_path = NULL;
1788    Eina_Bool use_dflt_xkb = EINA_FALSE;
1789    const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
1790
1791    /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
1792    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
1793
1794    if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
1795
1796    /* unreference any existing context */
1797    if (e_comp_input_key->xkb.context)
1798      xkb_context_unref(e_comp_input_key->xkb.context);
1799
1800    /* create a new xkb context */
1801    if (use_dflt_xkb) e_comp_input_key->xkb.context = dflt_ctx;
1802    else e_comp_input_key->xkb.context = xkb_context_new(0);
1803
1804    if (!e_comp_input_key->xkb.context)
1805      {
1806         TRACE_INPUT_END();
1807         return;
1808      }
1809
1810    if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1811      e_input_device_keyboard_cached_context_set(e_comp_input_key->xkb.context);
1812
1813    /* assemble xkb_rule_names so we can fetch keymap */
1814    memset(&names, 0, sizeof(names));
1815    if (rules) names.rules = strdup(rules);
1816    else
1817      {
1818         default_rules = e_comp_wl_input_keymap_default_rules_get();
1819         names.rules = strdup(default_rules);
1820      }
1821    if (model) names.model = strdup(model);
1822    else
1823      {
1824         default_model = e_comp_wl_input_keymap_default_model_get();
1825         names.model = strdup(default_model);
1826      }
1827    if (layout) names.layout = strdup(layout);
1828    else
1829      {
1830         default_layout = e_comp_wl_input_keymap_default_layout_get();
1831         names.layout = strdup(default_layout);
1832      }
1833    if (variant) names.variant = strdup(variant);
1834    else
1835      {
1836         default_variant = e_comp_wl_input_keymap_default_variant_get();
1837         if (default_variant) names.variant = strdup(default_variant);
1838      }
1839    if (options) names.options = strdup(options);
1840    else
1841      {
1842         default_options = e_comp_wl_input_keymap_default_options_get();
1843         if (default_options) names.options = strdup(default_options);
1844      }
1845
1846    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
1847    if (use_dflt_xkb)
1848      {
1849         keymap = dflt_map;
1850         keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
1851         if (access(keymap_path, R_OK) == 0)
1852           {
1853              eina_stringshare_del(keymap_path);
1854              keymap_path = NULL;
1855           }
1856      }
1857    else
1858      keymap = e_comp_wl_input_keymap_compile(e_comp_input_key->xkb.context, names, &keymap_path);
1859    TRACE_INPUT_END();
1860
1861    /* update compositor keymap */
1862    _e_comp_wl_input_keymap_update(keymap, keymap_path);
1863
1864    if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
1865      e_input_device_keyboard_cached_keymap_set(keymap);
1866
1867    /* cleanup */
1868    if (keymap_path) eina_stringshare_del(keymap_path);
1869    free((char *)names.rules);
1870    free((char *)names.model);
1871    free((char *)names.layout);
1872    if (names.variant) free((char *)names.variant);
1873    if (names.options) free((char *)names.options);
1874    TRACE_INPUT_END();
1875 }
1876
1877 EINTERN const char*
1878 e_comp_wl_input_keymap_default_rules_get(void)
1879 {
1880    if (e_config->xkb.default_rmlvo.rules)
1881      return e_config->xkb.default_rmlvo.rules;
1882
1883    if (_env_e_default_xkb_rules)
1884      return _env_e_default_xkb_rules;
1885
1886    return "evdev";
1887 }
1888
1889 EINTERN const char*
1890 e_comp_wl_input_keymap_default_model_get(void)
1891 {
1892    if (e_config->xkb.default_rmlvo.model)
1893      return e_config->xkb.default_rmlvo.model;
1894
1895    if (_env_e_default_xkb_model)
1896      return _env_e_default_xkb_model;
1897
1898    return "pc105";
1899 }
1900
1901 EINTERN const char*
1902 e_comp_wl_input_keymap_default_layout_get(void)
1903 {
1904    if (e_config->xkb.default_rmlvo.layout)
1905      return e_config->xkb.default_rmlvo.layout;
1906
1907    if (_env_e_default_xkb_layout)
1908      return _env_e_default_xkb_layout;
1909
1910    return "us";
1911 }
1912
1913 EINTERN const char*
1914 e_comp_wl_input_keymap_default_variant_get(void)
1915 {
1916    if (e_config->xkb.default_rmlvo.variant)
1917      return e_config->xkb.default_rmlvo.variant;
1918
1919    if (_env_e_default_xkb_variant)
1920      return _env_e_default_xkb_variant;
1921
1922    return NULL;
1923 }
1924
1925 EINTERN const char*
1926 e_comp_wl_input_keymap_default_options_get(void)
1927 {
1928    if (e_config->xkb.default_rmlvo.options)
1929      return e_config->xkb.default_rmlvo.options;
1930
1931    if (_env_e_default_xkb_opts)
1932      return _env_e_default_xkb_opts;
1933
1934    return NULL;
1935 }
1936
1937 EINTERN void
1938 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
1939 {
1940    /* check for valid compositor data */
1941    if (!e_comp->wl_comp_data)
1942      {
1943         ERR("No compositor data");
1944         return;
1945      }
1946
1947    e_comp_wl->touch.enabled = !!enabled;
1948    _e_comp_wl_input_update_seat_caps(NULL);
1949 }
1950
1951 EINTERN void
1952 e_comp_wl_input_seat_caps_set(unsigned int caps)
1953 {
1954    Eina_Bool need_update = EINA_FALSE;
1955
1956    /* check for valid compositor data */
1957    if (!e_comp->wl_comp_data)
1958      {
1959         ERR("No compositor data");
1960         return;
1961      }
1962
1963    if (caps & E_INPUT_SEAT_POINTER)
1964      e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
1965    if (caps & E_INPUT_SEAT_KEYBOARD)
1966      e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
1967    if (caps & E_INPUT_SEAT_TOUCH)
1968      e_comp_wl->touch.enabled = need_update = EINA_TRUE;
1969
1970    if (need_update)
1971      _e_comp_wl_input_update_seat_caps(NULL);
1972 }
1973
1974 EINTERN Eina_Bool
1975 e_comp_wl_input_touch_check(struct wl_resource *res)
1976 {
1977    return wl_resource_instance_of(res, &wl_touch_interface,
1978                                   &_e_touch_interface);
1979 }
1980
1981 E_API void
1982 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
1983 {
1984    struct wl_resource *res;
1985    Eina_List *l;
1986
1987    EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
1988
1989    atomic_store(&e_comp_wl->kbd.repeat_delay, delay);
1990    atomic_store(&e_comp_wl->kbd.repeat_rate, rate);
1991
1992    g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
1993    EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1994      {
1995         if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
1996           wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate,
1997                                        e_comp_wl->kbd.repeat_delay);
1998      }
1999
2000    g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
2001 }
2002
2003 typedef struct _keycode_map{
2004     xkb_keysym_t keysym;
2005     xkb_keycode_t keycode;
2006 } keycode_map;
2007
2008 static void
2009 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2010 {
2011    keycode_map *found_keycodes = (keycode_map *)data;
2012    xkb_keysym_t keysym = found_keycodes->keysym;
2013    int nsyms = 0;
2014    const xkb_keysym_t *syms_out = NULL;
2015
2016    nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2017    if (nsyms && syms_out)
2018      {
2019         if (*syms_out == keysym)
2020           {
2021              found_keycodes->keycode = key;
2022           }
2023      }
2024 }
2025
2026 int
2027 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
2028 {
2029    keycode_map found_keycodes = {0,};
2030    found_keycodes.keysym = keysym;
2031    xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2032
2033    return found_keycodes.keycode;
2034 }
2035
2036 E_API int
2037 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
2038 {
2039    struct xkb_keymap *keymap = NULL;
2040    xkb_keysym_t keysym = 0x0;
2041    int keycode = 0;
2042    char *name_tmp;
2043
2044    EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
2045    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
2046
2047    keymap = e_comp_input_key->xkb.keymap;
2048    EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
2049
2050    keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
2051    if (keysym == XKB_KEY_NoSymbol)
2052      {
2053         if (strlen(name) <= sizeof("Keycode-")) goto finish;
2054
2055         if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
2056           {
2057              name_tmp = (char *)name + sizeof("Keycode-") - 1;
2058              keycode = atoi(name_tmp);
2059              if (keycode <= 8) goto finish;
2060
2061              return keycode;
2062           }
2063         else
2064           goto finish;
2065      }
2066
2067    keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
2068
2069    return keycode;
2070
2071 finish:
2072    return 0;
2073 }
2074
2075 EINTERN char *
2076 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
2077 {
2078    struct xkb_state *state;
2079    xkb_keysym_t sym = XKB_KEY_NoSymbol;
2080    char name[256] = {0, };
2081
2082    EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
2083    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
2084    if (!e_comp_input_key->xkb.state)
2085      {
2086         return NULL;
2087      }
2088
2089    state = e_comp_input_key->xkb.state;
2090
2091    sym = xkb_state_key_get_one_sym(state, keycode);
2092
2093    if (sym == XKB_KEY_NoSymbol)
2094      {
2095         snprintf(name, sizeof(name), "Keycode-%u", keycode);
2096      }
2097    else
2098      xkb_keysym_get_name(sym, name, sizeof(name));
2099
2100    return strdup(name);
2101 }
2102
2103 static void
2104 _e_comp_wl_input_keymap_set(struct xkb_context **ctx, struct xkb_keymap **map)
2105 {
2106    char *keymap_path = NULL;
2107    struct xkb_context *context;
2108    struct xkb_keymap *keymap;
2109    struct xkb_rule_names names = {0,};
2110    const char* default_rules, *default_model, *default_layout, *default_variant, *default_options;
2111
2112    TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_set);
2113
2114    context = xkb_context_new(0);
2115    EINA_SAFETY_ON_NULL_RETURN(context);
2116
2117    /* assemble xkb_rule_names so we can fetch keymap */
2118    memset(&names, 0, sizeof(names));
2119
2120    default_rules = e_comp_wl_input_keymap_default_rules_get();
2121    default_model = e_comp_wl_input_keymap_default_model_get();
2122    default_layout = e_comp_wl_input_keymap_default_layout_get();
2123    default_variant = e_comp_wl_input_keymap_default_variant_get();
2124    default_options = e_comp_wl_input_keymap_default_options_get();
2125
2126    names.rules = strdup(default_rules);
2127    names.model = strdup(default_model);
2128    names.layout = strdup(default_layout);
2129    if (default_variant) names.variant = strdup(default_variant);
2130    if (default_options) names.options = strdup(default_options);
2131
2132    keymap = e_comp_wl_input_keymap_compile(context, names, &keymap_path);
2133    eina_stringshare_del(keymap_path);
2134    EINA_SAFETY_ON_NULL_GOTO(keymap, cleanup);
2135
2136    *ctx = context;
2137    *map = keymap;
2138
2139    if (dont_set_e_input_keymap == EINA_FALSE)
2140      {
2141         e_input_device_keyboard_cached_context_set(*ctx);
2142         e_input_device_keyboard_cached_keymap_set(*map);
2143      }
2144
2145 cleanup:
2146    free((char *)names.rules);
2147    free((char *)names.model);
2148    free((char *)names.layout);
2149    if (names.variant) free((char *)names.variant);
2150    if (names.options) free((char *)names.options);
2151
2152    TRACE_INPUT_END();
2153 }
2154
2155 E_API Eina_Bool
2156 e_comp_wl_input_pointer_constraint_activated_get(void)
2157 {
2158    return e_comp_wl->ptr_constraints.activated;
2159 }
2160
2161 EINTERN void
2162 e_comp_wl_input_keymap_init(void)
2163 {
2164    struct xkb_context *ctx = NULL;
2165    struct xkb_keymap *map = NULL;
2166
2167    /* keymap */
2168    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2169    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
2170
2171    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
2172      {
2173         _e_comp_wl_input_keymap_set(&ctx, &map);
2174      }
2175
2176    e_comp_wl_input_keymap_set(e_comp_wl_input_keymap_default_rules_get(),
2177                               e_comp_wl_input_keymap_default_model_get(),
2178                               e_comp_wl_input_keymap_default_layout_get(),
2179                               e_comp_wl_input_keymap_default_variant_get(),
2180                               e_comp_wl_input_keymap_default_options_get(),
2181                               ctx, map);
2182 }