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