e_devicemgr: create tizen_input_devices only for first bound seat & manager
[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
5 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
6 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
7 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
8 static Eina_Bool use_cache_keymap = EINA_FALSE;
9
10 /* default XKB values from enviroment variables */
11 static char *_env_e_default_xkb_rules   = NULL;
12 static char *_env_e_default_xkb_model   = NULL;
13 static char *_env_e_default_xkb_layout  = NULL;
14 static char *_env_e_default_xkb_variant = NULL;
15 static char *_env_e_default_xkb_opts    = NULL;
16
17 static void
18 _e_comp_wl_input_update_seat_caps(struct wl_client *wc)
19 {
20    Eina_List *l;
21    struct wl_resource *res;
22    enum wl_seat_capability caps = 0;
23
24    if (e_comp_wl->ptr.enabled)
25      caps |= WL_SEAT_CAPABILITY_POINTER;
26    if (e_comp_wl->kbd.enabled)
27      caps |= WL_SEAT_CAPABILITY_KEYBOARD;
28    if (e_comp_wl->touch.enabled)
29      caps |= WL_SEAT_CAPABILITY_TOUCH;
30
31    EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
32      {
33         /* if a wc is null, send seat capability to all wl_seat resources */
34         if (wc && (wl_resource_get_client(res) != wc)) continue;
35         wl_seat_send_capabilities(res, caps);
36      }
37 }
38
39 static void
40 _e_comp_wl_input_pointer_map(struct wl_resource *resource)
41 {
42    E_Client *ec;
43    E_Pointer *ptr;
44    struct wl_client *wc;
45
46    if (!(ec = wl_resource_get_user_data(resource))) return;
47    if (e_object_is_del(E_OBJECT(ec))) return;
48
49    //if cursor ec have external content
50    e_comp_object_content_unset(ec->frame);
51
52    if (!e_comp_wl->ptr.ec || !e_comp_wl->ptr.ec->comp_data || !e_comp_wl->ptr.ec->comp_data->surface) return;
53    wc = wl_resource_get_client(resource);
54    if (wc != wl_resource_get_client(e_comp_wl->ptr.ec->comp_data->surface)) return;
55    if (!e_comp_wl->ptr.ec->pointer_enter_sent) return;
56
57    if ((ptr = e_comp->pointer))
58      e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
59 }
60
61 static void
62 _e_comp_wl_input_pointer_configure(struct wl_resource *resource,
63                                    Evas_Coord x, Evas_Coord y,
64                                    Evas_Coord w, Evas_Coord h)
65 {
66    E_Client *ec;
67
68    if (!(ec = wl_resource_get_user_data(resource))) return;
69    if (e_object_is_del(E_OBJECT(ec))) return;
70
71    e_client_util_resize_without_frame(ec, w, h);
72 }
73
74 static void
75 _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
76 {
77    wl_resource_destroy(resource);
78 }
79
80 static void
81 _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)
82 {
83    E_Client *ec;
84    Eina_Bool got_mouse = EINA_FALSE;
85
86    E_CLIENT_FOREACH(ec)
87      {
88        if (e_object_is_del(E_OBJECT(ec))) continue;
89        if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
90        if (!ec->comp_data->surface) continue;
91        if (client != wl_resource_get_client(ec->comp_data->surface)) continue;
92        if (ec->mouse.in && ec->pointer_enter_sent)
93          {
94             got_mouse = EINA_TRUE;
95             break;
96          }
97      }
98    if (!got_mouse) return;
99    if (!surface_resource)
100      {
101         e_pointer_object_set(e_comp->pointer, NULL, x, y);
102         return;
103      }
104    ec = wl_resource_get_user_data(surface_resource);
105    if (!ec->re_manage)
106      {
107         ec->re_manage = 1;
108         ec->ignored = 0;
109
110         ec->lock_focus_out = ec->layer_block = ec->visible = 1;
111         if (!e_config->show_cursor)  ec->override = 1;
112         ec->icccm.title = eina_stringshare_add("Cursor");
113         e_client_window_role_set(ec, "wl_pointer-cursor");
114         evas_object_pass_events_set(ec->frame, 1);
115         e_client_focus_stack_set(eina_list_remove(e_client_focus_stack_get(), ec));
116         /* wl_pointer-cursor surface is always alpha window */
117         ec->argb = EINA_TRUE;
118         ELOGF("COMP", "Set argb:%d", ec, ec->argb);
119         e_comp_object_alpha_set(ec->frame, EINA_TRUE);
120         EC_CHANGED(ec);
121
122         /* Set fuctions to prevent unwanted handling by shell */
123         ec->comp_data->shell.surface = surface_resource;
124         ec->comp_data->shell.configure = _e_comp_wl_input_pointer_configure;
125         ec->comp_data->shell.map = _e_comp_wl_input_pointer_map;
126
127         e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
128         ec->is_cursor = EINA_TRUE;
129      }
130
131    /* Set a pointer_object after wl_surface commit
132     * if cursor image is changed,
133     * changed information is sent using attach / damage
134     * So in commit, we can know real current cursor image.
135     */
136 #if 0
137    /* ignore cursor changes during resize/move I guess */
138    if (e_client_action_get()) return;
139    e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
140 #endif
141    if (e_comp->pointer)
142      {
143         e_comp->pointer->hot.x = x;
144         e_comp->pointer->hot.y = y;
145         ec->visible = EINA_TRUE;
146      }
147 }
148
149 static const struct wl_pointer_interface _e_pointer_interface =
150 {
151    _e_comp_wl_input_pointer_cb_cursor_set,
152    _e_comp_wl_input_cb_resource_destroy
153 };
154
155 static const struct wl_keyboard_interface _e_keyboard_interface =
156 {
157    _e_comp_wl_input_cb_resource_destroy
158 };
159
160 static const struct wl_touch_interface _e_touch_interface =
161 {
162    _e_comp_wl_input_cb_resource_destroy
163 };
164
165 static void
166 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
167 {
168    e_comp_wl->ptr.resources =
169      eina_list_remove(e_comp_wl->ptr.resources, resource);
170 }
171
172 static void
173 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
174 {
175    struct wl_resource *res;
176    struct wl_client *ptr_client = NULL;
177    E_Comp_Wl_Client_Data *cdata = NULL;
178
179    /* try to create pointer resource */
180    res = wl_resource_create(client, &wl_pointer_interface,
181                             wl_resource_get_version(resource), id);
182    if (!res)
183      {
184         ERR("Could not create pointer on seat %s: %m",
185             e_comp_wl->seat.name);
186         wl_client_post_no_memory(client);
187         return;
188      }
189
190    e_comp_wl->ptr.resources =
191      eina_list_append(e_comp_wl->ptr.resources, res);
192    wl_resource_set_implementation(res, &_e_pointer_interface,
193                                   e_comp->wl_comp_data,
194                                  _e_comp_wl_input_cb_pointer_unbind);
195
196    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)
197      {
198         cdata = (E_Comp_Wl_Client_Data*)e_comp_wl->ptr.ec->comp_data;
199         if (cdata && cdata->wl_surface)
200           ptr_client = wl_resource_get_client(cdata->wl_surface);
201
202         if (ptr_client == client)
203           {
204              Evas_Device *last_ptr = NULL, *dev;
205              Eina_List *list, *l;
206              const char *name, *desc;
207
208              list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
209              EINA_LIST_FOREACH(list, l, dev)
210                {
211                   name = evas_device_name_get(dev);
212                   desc = evas_device_description_get(dev);
213                   if (!name || !desc) continue;
214
215                   if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
216                       (!strncmp(desc, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
217                       (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
218                     {
219                        last_ptr = dev;
220                        break;
221                     }
222                }
223              if (last_ptr)
224                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);
225           }
226      }
227 }
228
229 static void
230 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
231 {
232    Eina_List *l, *ll;
233    struct wl_resource *res;
234
235    e_comp_wl->kbd.resources =
236      eina_list_remove(e_comp_wl->kbd.resources, resource);
237    EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
238      if (res == resource)
239        e_comp_wl->kbd.focused =
240          eina_list_remove_list(e_comp_wl->kbd.focused, l);
241 }
242
243 void
244 e_comp_wl_input_keyboard_enter_send(E_Client *ec)
245 {
246    struct wl_resource *res;
247    Eina_List *l;
248    uint32_t serial;
249
250    if (!ec->comp_data->surface) return;
251
252    if (!e_comp_wl->kbd.focused) return;
253
254    e_comp_wl_input_keyboard_modifiers_serialize();
255
256    serial = wl_display_next_serial(e_comp_wl->wl.disp);
257
258    EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
259      {
260         wl_keyboard_send_enter(res, serial, ec->comp_data->surface,
261                                &e_comp_wl->kbd.keys);
262         wl_keyboard_send_modifiers(res, serial,
263                                    e_comp_wl->kbd.mod_depressed,
264                                    e_comp_wl->kbd.mod_latched,
265                                    e_comp_wl->kbd.mod_locked,
266                                    e_comp_wl->kbd.mod_group);
267      }
268 }
269
270 static void
271 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
272 {
273    E_Client *focused;
274    struct wl_resource *res;
275
276    /* try to create keyboard resource */
277    res = wl_resource_create(client, &wl_keyboard_interface,
278                             wl_resource_get_version(resource), id);
279    if (!res)
280      {
281         ERR("Could not create keyboard on seat %s: %m",
282             e_comp_wl->seat.name);
283         wl_client_post_no_memory(client);
284         return;
285      }
286
287    e_comp_wl->kbd.resources =
288      eina_list_append(e_comp_wl->kbd.resources, res);
289    wl_resource_set_implementation(res, &_e_keyboard_interface,
290                                   e_comp->wl_comp_data,
291                                   _e_comp_wl_input_cb_keyboard_unbind);
292
293    /* send current repeat_info */
294    if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
295      wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate, e_comp_wl->kbd.repeat_delay);
296
297    /* send current keymap */
298    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap);
299    wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
300                            e_comp_wl->xkb.fd,
301                            e_comp_wl->xkb.size);
302    TRACE_INPUT_END();
303
304    /* if the client owns the focused surface, we need to send an enter */
305    focused = e_client_focused_get();
306    if ((!focused) || (e_object_is_del(E_OBJECT(focused))) ||
307        (!focused->comp_data) || (!focused->comp_data->surface)) return;
308
309    if (client != wl_resource_get_client(focused->comp_data->surface)) return;
310    e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
311
312    e_comp_wl_input_keyboard_enter_send(focused);
313 }
314
315 static void
316 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
317 {
318    e_comp_wl->touch.resources =
319      eina_list_remove(e_comp_wl->touch.resources, resource);
320 }
321
322 static void
323 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
324 {
325     struct wl_resource *res;
326
327     /* try to create pointer resource */
328     res = wl_resource_create(client, &wl_touch_interface,
329                              wl_resource_get_version(resource), id);
330     if (!res)
331       {
332          ERR("Could not create touch on seat %s: %m",
333              e_comp_wl->seat.name);
334          wl_client_post_no_memory(client);
335          return;
336       }
337
338     e_comp_wl->touch.resources =
339      eina_list_append(e_comp_wl->touch.resources, res);
340     wl_resource_set_implementation(res, &_e_touch_interface,
341                                    e_comp->wl_comp_data,
342                                   _e_comp_wl_input_cb_touch_unbind);
343 }
344
345 static const struct wl_seat_interface _e_seat_interface =
346 {
347    _e_comp_wl_input_cb_pointer_get,
348    _e_comp_wl_input_cb_keyboard_get,
349    _e_comp_wl_input_cb_touch_get,
350 };
351
352 static void
353 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
354 {
355    E_Comp_Wl_Seat *seat = wl_resource_get_user_data(resource);
356
357    DBG("Unbind seat: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
358
359    e_comp_wl->seat.resources =
360      eina_list_remove(e_comp_wl->seat.resources, resource);
361    E_FREE(seat);
362 }
363
364 static void
365 _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
366 {
367    struct wl_resource *res;
368    Eina_List *l;
369    struct wl_resource *tmp_res;
370    E_Comp_Wl_Seat *seat;
371
372    seat = E_NEW(E_Comp_Wl_Seat, 1);
373    if (!seat)
374      {
375         ERR("Failed to allocate memory for seat data\n");
376         wl_client_post_no_memory(client);
377         return;
378      }
379    seat->is_first_resource = 1;
380
381    EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, tmp_res)
382      {
383         if (wl_resource_get_client(tmp_res) != client) continue;
384         DBG("wl_seat (res: %d) is already bound to client (%p)",
385             wl_resource_get_id(tmp_res), client);
386         seat->is_first_resource = 0;
387      }
388
389    res = wl_resource_create(client, &wl_seat_interface, version, id);
390    if (!res)
391      {
392         ERR("Could not create seat resource: %m");
393         E_FREE(seat);
394         return;
395      }
396    DBG("Bind seat: %u (client: %p)", wl_resource_get_id(res), client);
397
398    /* store version of seat interface for reuse in updating capabilities */
399    e_comp_wl->seat.version = version;
400    e_comp_wl->seat.resources =
401      eina_list_append(e_comp_wl->seat.resources, res);
402
403    wl_resource_set_implementation(res, &_e_seat_interface,
404                                   seat,
405                                   _e_comp_wl_input_cb_unbind_seat);
406
407    _e_comp_wl_input_update_seat_caps(client);
408    if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
409      wl_seat_send_name(res, e_comp_wl->seat.name);
410 }
411
412 static void
413 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
414 {
415    FILE *file = NULL;
416    TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
417
418    if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
419      {
420         TRACE_INPUT_END();
421         return;
422      }
423
424    if (keymap_path)
425      {
426         if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
427           {
428              WRN("%s is maybe link, so delete it\n", keymap_path);
429           }
430
431         file = fopen(keymap_path, "w");
432         EINA_SAFETY_ON_NULL_RETURN(file);
433
434         if (fputs(keymap_data, file) < 0)
435           {
436              WRN("Failed  to write keymap file: %s\n", keymap_path);
437              fclose(file);
438              unlink(keymap_path);
439           }
440         else
441           {
442              INF("Success to make keymap file: %s\n", keymap_path);
443              fclose(file);
444           }
445      }
446    TRACE_INPUT_END();
447 }
448
449 static int
450 _e_comp_wl_input_keymap_fd_get(off_t size)
451 {
452    int fd = 0, blen = 0, len = 0;
453    char *path;
454    char tmp[PATH_MAX] = {0, };
455    long flags;
456    mode_t old_umask;
457
458    blen = sizeof(tmp) - 20;
459
460    path = e_util_env_get("XDG_RUNTIME_DIR");
461    if (!path) return -1;
462
463    len = strlen(path) + 19;
464    if (len < blen)
465      {
466         strncpy(tmp, path, PATH_MAX - 20);
467         strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
468         E_FREE(path);
469      }
470    else
471      {
472         E_FREE(path);
473         return -1;
474      }
475
476    old_umask = umask(S_IRWXG|S_IRWXO);
477    fd = mkstemp(tmp);
478    umask(old_umask);
479
480    EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
481
482    flags = fcntl(fd, F_GETFD);
483    if (flags < 0)
484      {
485         close(fd);
486         return -1;
487      }
488
489    if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
490      {
491         close(fd);
492         return -1;
493      }
494
495    if (ftruncate(fd, size) < 0)
496      {
497         close(fd);
498         return -1;
499      }
500
501    unlink(tmp);
502    return fd;
503 }
504
505 static void
506 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
507 {
508    char *tmp;
509    xkb_mod_mask_t latched = 0, locked = 0, group = 0;
510    struct wl_resource *res;
511    Eina_List *l;
512
513    /* unreference any existing keymap */
514    if (e_comp_wl->xkb.keymap)
515      xkb_map_unref(e_comp_wl->xkb.keymap);
516
517    /* unmap any existing keyboard area */
518    if (e_comp_wl->xkb.area)
519      munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
520    if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
521
522    /* unreference any existing keyboard state */
523    if (e_comp_wl->xkb.state)
524      {
525         latched =
526           xkb_state_serialize_mods(e_comp_wl->xkb.state,
527                                    XKB_STATE_MODS_LATCHED);
528         locked =
529           xkb_state_serialize_mods(e_comp_wl->xkb.state,
530                                    XKB_STATE_MODS_LOCKED);
531         group =
532           xkb_state_serialize_layout(e_comp_wl->xkb.state,
533                                      XKB_STATE_LAYOUT_EFFECTIVE);
534         xkb_state_unref(e_comp_wl->xkb.state);
535      }
536
537    /* create a new xkb state */
538    e_comp_wl->xkb.state = xkb_state_new(keymap);
539
540    if (!e_comp_wl->xkb.state) return;
541
542    if ((latched) || (locked) || (group))
543      xkb_state_update_mask(e_comp_wl->xkb.state, 0,
544                            latched, locked, 0, 0, group);
545
546    /* increment keymap reference */
547    e_comp_wl->xkb.keymap = keymap;
548
549    /* fetch updated modifiers */
550    e_comp_wl->kbd.mod_shift =
551      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
552    e_comp_wl->kbd.mod_caps =
553      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
554    e_comp_wl->kbd.mod_ctrl =
555      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
556    e_comp_wl->kbd.mod_alt =
557      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
558    e_comp_wl->kbd.mod_super =
559      xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
560
561    if (!(tmp = xkb_map_get_as_string(keymap)))
562      {
563         ERR("Could not get keymap string");
564         return;
565      }
566
567    e_comp_wl->xkb.size = strlen(tmp) + 1;
568    e_comp_wl->xkb.fd =
569      _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
570    if (e_comp_wl->xkb.fd < 0)
571      {
572         ERR("Could not create keymap file");
573         free(tmp);
574         return;
575      }
576
577    _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
578
579    e_comp_wl->xkb.area =
580      mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
581           MAP_SHARED, e_comp_wl->xkb.fd, 0);
582    if (e_comp_wl->xkb.area == MAP_FAILED)
583      {
584         ERR("Failed to mmap keymap area: %m");
585         free(tmp);
586         return;
587      }
588
589    strncpy(e_comp_wl->xkb.area, tmp, e_comp_wl->xkb.size);
590    free(tmp);
591
592    /* send updated keymap */
593    TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
594    EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
595      wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
596                              e_comp_wl->xkb.fd,
597                              e_comp_wl->xkb.size);
598    TRACE_INPUT_END();
599
600    /* update modifiers */
601    e_comp_wl_input_keyboard_modifiers_update();
602 }
603
604 EINTERN Eina_Bool
605 e_comp_wl_input_init(void)
606 {
607    /* set default seat name */
608    if (!e_comp_wl->seat.name)
609      e_comp_wl->seat.name = "default";
610
611    e_comp_wl->xkb.fd = -1;
612    dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
613    dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
614
615    /* get default keyboard repeat rate/delay from configuration */
616    e_comp_wl->kbd.repeat_delay = e_config->keyboard.repeat_delay;
617    e_comp_wl->kbd.repeat_rate = e_config->keyboard.repeat_rate;
618
619    /* check for valid repeat_delay and repeat_rate value */
620    /* if invalid, set the default value of repeat delay and rate value */
621    if (e_comp_wl->kbd.repeat_delay < 0) e_comp_wl->kbd.repeat_delay = 400;
622    if (e_comp_wl->kbd.repeat_rate < 0) e_comp_wl->kbd.repeat_rate = 25;
623
624    /* create the global resource for input seat */
625    e_comp_wl->seat.global =
626      wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
627                       e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
628    if (!e_comp_wl->seat.global)
629      {
630         ERR("Could not create global for seat: %m");
631         return EINA_FALSE;
632      }
633
634    wl_array_init(&e_comp_wl->kbd.keys);
635    wl_array_init(&e_comp_wl->kbd.routed_keys);
636
637    E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
638
639    /* get string values from environment variables */
640    _env_e_default_xkb_rules   = e_util_env_get("E_DEFAULT_XKB_RULES"  );
641    _env_e_default_xkb_model   = e_util_env_get("E_DEFAULT_XKB_MODEL"  );
642    _env_e_default_xkb_layout  = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
643    _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
644    _env_e_default_xkb_opts    = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
645
646    return EINA_TRUE;
647 }
648
649 EINTERN void
650 e_comp_wl_input_shutdown(void)
651 {
652    struct wl_resource *res;
653
654    /* free environment variable string */
655    E_FREE(_env_e_default_xkb_rules  );
656    E_FREE(_env_e_default_xkb_model  );
657    E_FREE(_env_e_default_xkb_layout );
658    E_FREE(_env_e_default_xkb_variant);
659    E_FREE(_env_e_default_xkb_opts   );
660
661    /* destroy pointer resources */
662    EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
663      wl_resource_destroy(res);
664
665    /* destroy keyboard resources */
666    EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
667      wl_resource_destroy(res);
668    e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
669
670    /* destroy touch resources */
671    EINA_LIST_FREE(e_comp_wl->touch.resources, res)
672      wl_resource_destroy(res);
673
674    /* destroy e_comp_wl->kbd.keys array */
675    wl_array_release(&e_comp_wl->kbd.keys);
676    wl_array_release(&e_comp_wl->kbd.routed_keys);
677
678    /* unmap any existing keyboard area */
679    if (e_comp_wl->xkb.area)
680      munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
681    if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
682
683    /* unreference any existing keyboard state */
684    if (e_comp_wl->xkb.state)
685      xkb_state_unref(e_comp_wl->xkb.state);
686
687    /* unreference any existing keymap */
688    if (e_comp_wl->xkb.keymap)
689      xkb_map_unref(e_comp_wl->xkb.keymap);
690
691    /* unreference any existing context */
692    if (e_comp_wl->xkb.context)
693      xkb_context_unref(e_comp_wl->xkb.context);
694
695    /* destroy the global seat resource */
696    if (e_comp_wl->seat.global)
697      wl_global_destroy(e_comp_wl->seat.global);
698    e_comp_wl->seat.global = NULL;
699
700    dont_set_e_input_keymap = EINA_FALSE;
701    dont_use_xkb_cache = EINA_FALSE;
702 }
703
704 EINTERN Eina_Bool
705 e_comp_wl_input_pointer_check(struct wl_resource *res)
706 {
707    return wl_resource_instance_of(res, &wl_pointer_interface,
708                                   &_e_pointer_interface);
709 }
710
711 EINTERN Eina_Bool
712 e_comp_wl_input_keyboard_check(struct wl_resource *res)
713 {
714    return wl_resource_instance_of(res, &wl_keyboard_interface,
715                                   &_e_keyboard_interface);
716 }
717
718 EINTERN Eina_Bool
719 e_comp_wl_input_keyboard_modifiers_serialize(void)
720 {
721    Eina_Bool changed = EINA_FALSE;
722    xkb_mod_mask_t mod;
723    xkb_layout_index_t grp;
724
725    mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
726                               XKB_STATE_DEPRESSED);
727    changed |= mod != e_comp_wl->kbd.mod_depressed;
728    e_comp_wl->kbd.mod_depressed = mod;
729
730    mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
731                               XKB_STATE_MODS_LATCHED);
732    changed |= mod != e_comp_wl->kbd.mod_latched;
733    e_comp_wl->kbd.mod_latched = mod;
734
735    mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
736                               XKB_STATE_MODS_LOCKED);
737    changed |= mod != e_comp_wl->kbd.mod_locked;
738    e_comp_wl->kbd.mod_locked = mod;
739
740    grp = xkb_state_serialize_layout(e_comp_wl->xkb.state,
741                                 XKB_STATE_LAYOUT_EFFECTIVE);
742    changed |= grp != e_comp_wl->kbd.mod_group;
743    e_comp_wl->kbd.mod_group = grp;
744    return changed;
745 }
746
747 EINTERN void
748 e_comp_wl_input_keyboard_modifiers_update(void)
749 {
750    uint32_t serial;
751    struct wl_resource *res;
752    Eina_List *l;
753
754    if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
755
756    if (!e_comp_wl->kbd.focused) return;
757
758    serial = wl_display_next_serial(e_comp_wl->wl.disp);
759    EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
760      wl_keyboard_send_modifiers(res, serial,
761                                 e_comp_wl->kbd.mod_depressed,
762                                 e_comp_wl->kbd.mod_latched,
763                                 e_comp_wl->kbd.mod_locked,
764                                 e_comp_wl->kbd.mod_group);
765 }
766
767 EINTERN void
768 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
769 {
770    enum xkb_key_direction dir;
771
772    if (!e_comp_wl->xkb.state) return;
773
774    if (pressed) dir = XKB_KEY_DOWN;
775    else dir = XKB_KEY_UP;
776
777    e_comp_wl->kbd.mod_changed =
778      xkb_state_update_key(e_comp_wl->xkb.state, keycode + 8, dir);
779
780    e_comp_wl_input_keyboard_modifiers_update();
781 }
782
783 E_API void
784 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
785 {
786    /* check for valid compositor data */
787    if (!e_comp->wl_comp_data)
788      {
789         ERR("No compositor data");
790         return;
791      }
792
793    e_comp_wl->ptr.enabled = !!enabled;
794    _e_comp_wl_input_update_seat_caps(NULL);
795 }
796
797 E_API void
798 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
799 {
800    /* check for valid compositor data */
801    if (!e_comp->wl_comp_data)
802      {
803         ERR("No compositor data");
804         return;
805      }
806
807    e_comp_wl->kbd.enabled = !!enabled;
808    _e_comp_wl_input_update_seat_caps(NULL);
809 }
810
811 E_API Eina_Bool
812 e_comp_wl_input_keymap_cache_file_use_get(void)
813 {
814    return use_cache_keymap;
815 }
816
817 E_API Eina_Stringshare *
818 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
819 {
820    return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
821             names.rules ? names.rules : "evdev",
822             names.model ? names.model : "pc105",
823             names.layout ? names.layout : "us",
824             names.variant ? names.variant : "",
825             names.options ? names.options : "");
826 }
827
828 E_API struct xkb_keymap *
829 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
830 {
831    struct xkb_keymap *keymap;
832    char *cache_path = NULL;
833    FILE *file = NULL;
834
835    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
836
837    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
838
839    if (e_config->xkb.use_cache && !dont_use_xkb_cache)
840      {
841         cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
842         file = fopen(cache_path, "r");
843      }
844
845    if (!file)
846      {
847         INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
848
849         /* fetch new keymap based on names */
850         keymap = xkb_map_new_from_names(ctx, &names, 0);
851         use_cache_keymap = EINA_FALSE;
852      }
853    else
854      {
855         INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
856         keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
857         if (!keymap)
858           {
859              WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
860              fclose(file);
861              if (remove(cache_path) != 0)
862                WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
863              keymap = xkb_map_new_from_names(ctx, &names, 0);
864              use_cache_keymap = EINA_FALSE;
865           }
866         else
867           {
868              eina_stringshare_del(cache_path);
869              cache_path = NULL;
870              fclose(file);
871              use_cache_keymap = EINA_TRUE;
872           }
873      }
874
875    *keymap_path = cache_path;
876    EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
877
878    TRACE_INPUT_END();
879
880    return keymap;
881 }
882
883 E_API void
884 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
885                            const char *variant, const char *options,
886                            struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
887 {
888    struct xkb_keymap *keymap;
889    struct xkb_rule_names names;
890    char *keymap_path = NULL;
891    Eina_Bool use_dflt_xkb = EINA_FALSE;
892    const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
893
894    /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
895    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
896
897    if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
898
899    /* unreference any existing context */
900    if (e_comp_wl->xkb.context)
901      xkb_context_unref(e_comp_wl->xkb.context);
902
903    /* create a new xkb context */
904    if (use_dflt_xkb) e_comp_wl->xkb.context = dflt_ctx;
905    else e_comp_wl->xkb.context = xkb_context_new(0);
906
907    if (!e_comp_wl->xkb.context)
908      {
909         TRACE_INPUT_END();
910         return;
911      }
912
913    if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
914      e_input_device_keyboard_cached_context_set(e_comp_wl->xkb.context);
915
916    /* assemble xkb_rule_names so we can fetch keymap */
917    memset(&names, 0, sizeof(names));
918    if (rules) names.rules = strdup(rules);
919    else
920      {
921         default_rules = e_comp_wl_input_keymap_default_rules_get();
922         names.rules = strdup(default_rules);
923      }
924    if (model) names.model = strdup(model);
925    else
926      {
927         default_model = e_comp_wl_input_keymap_default_model_get();
928         names.model = strdup(default_model);
929      }
930    if (layout) names.layout = strdup(layout);
931    else
932      {
933         default_layout = e_comp_wl_input_keymap_default_layout_get();
934         names.layout = strdup(default_layout);
935      }
936    if (variant) names.variant = strdup(variant);
937    else
938      {
939         default_variant = e_comp_wl_input_keymap_default_variant_get();
940         if (default_variant) names.variant = strdup(default_variant);
941      }
942    if (options) names.options = strdup(options);
943    else
944      {
945         default_options = e_comp_wl_input_keymap_default_options_get();
946         if (default_options) names.options = strdup(default_options);
947      }
948
949    TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
950    if (use_dflt_xkb)
951      {
952         keymap = dflt_map;
953         keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
954         if (access(keymap_path, R_OK) == 0)
955           {
956              eina_stringshare_del(keymap_path);
957              keymap_path = NULL;
958           }
959      }
960    else
961      keymap = e_comp_wl_input_keymap_compile(e_comp_wl->xkb.context, names, &keymap_path);
962    TRACE_INPUT_END();
963
964    /* update compositor keymap */
965    _e_comp_wl_input_keymap_update(keymap, keymap_path);
966
967    if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
968      e_input_device_keyboard_cached_keymap_set(keymap);
969
970    /* cleanup */
971    if (keymap_path) eina_stringshare_del(keymap_path);
972    free((char *)names.rules);
973    free((char *)names.model);
974    free((char *)names.layout);
975    if (names.variant) free((char *)names.variant);
976    if (names.options) free((char *)names.options);
977    TRACE_INPUT_END();
978 }
979
980 E_API const char*
981 e_comp_wl_input_keymap_default_rules_get(void)
982 {
983    if (e_config->xkb.default_rmlvo.rules)
984      return e_config->xkb.default_rmlvo.rules;
985
986    if (_env_e_default_xkb_rules)
987      return _env_e_default_xkb_rules;
988
989    return "evdev";
990 }
991
992 E_API const char*
993 e_comp_wl_input_keymap_default_model_get(void)
994 {
995    if (e_config->xkb.default_rmlvo.model)
996      return e_config->xkb.default_rmlvo.model;
997
998    if (_env_e_default_xkb_model)
999      return _env_e_default_xkb_model;
1000
1001    return "pc105";
1002 }
1003
1004 E_API const char*
1005 e_comp_wl_input_keymap_default_layout_get(void)
1006 {
1007    if (e_config->xkb.default_rmlvo.layout)
1008      return e_config->xkb.default_rmlvo.layout;
1009
1010    if (_env_e_default_xkb_layout)
1011      return _env_e_default_xkb_layout;
1012
1013    return "us";
1014 }
1015
1016 E_API const char*
1017 e_comp_wl_input_keymap_default_variant_get(void)
1018 {
1019    if (e_config->xkb.default_rmlvo.variant)
1020      return e_config->xkb.default_rmlvo.variant;
1021
1022    if (_env_e_default_xkb_variant)
1023      return _env_e_default_xkb_variant;
1024
1025    return NULL;
1026 }
1027
1028 E_API const char*
1029 e_comp_wl_input_keymap_default_options_get(void)
1030 {
1031    if (e_config->xkb.default_rmlvo.options)
1032      return e_config->xkb.default_rmlvo.options;
1033
1034    if (_env_e_default_xkb_opts)
1035      return _env_e_default_xkb_opts;
1036
1037    return NULL;
1038 }
1039
1040 E_API void
1041 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
1042 {
1043    /* check for valid compositor data */
1044    if (!e_comp->wl_comp_data)
1045      {
1046         ERR("No compositor data");
1047         return;
1048      }
1049
1050    e_comp_wl->touch.enabled = !!enabled;
1051    _e_comp_wl_input_update_seat_caps(NULL);
1052 }
1053
1054 E_API void
1055 e_comp_wl_input_seat_caps_set(unsigned int caps)
1056 {
1057    Eina_Bool need_update = EINA_FALSE;
1058
1059    /* check for valid compositor data */
1060    if (!e_comp->wl_comp_data)
1061      {
1062         ERR("No compositor data");
1063         return;
1064      }
1065
1066    if (caps & E_INPUT_SEAT_POINTER)
1067      e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
1068    if (caps & E_INPUT_SEAT_KEYBOARD)
1069      e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
1070    if (caps & E_INPUT_SEAT_TOUCH)
1071      e_comp_wl->touch.enabled = need_update = EINA_TRUE;
1072
1073    if (need_update)
1074      _e_comp_wl_input_update_seat_caps(NULL);
1075 }
1076
1077 EINTERN Eina_Bool
1078 e_comp_wl_input_touch_check(struct wl_resource *res)
1079 {
1080    return wl_resource_instance_of(res, &wl_touch_interface,
1081                                   &_e_touch_interface);
1082 }
1083
1084 E_API void
1085 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
1086 {
1087    struct wl_resource *res;
1088    Eina_List *l;
1089
1090    EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
1091
1092    e_comp_wl->kbd.repeat_delay = delay;
1093    e_comp_wl->kbd.repeat_rate = rate;
1094
1095    EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1096      {
1097         if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
1098           wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate,
1099                                        e_comp_wl->kbd.repeat_delay);
1100      }
1101 }
1102
1103 typedef struct _keycode_map{
1104     xkb_keysym_t keysym;
1105     xkb_keycode_t keycode;
1106 } keycode_map;
1107
1108 static void
1109 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
1110 {
1111    keycode_map *found_keycodes = (keycode_map *)data;
1112    xkb_keysym_t keysym = found_keycodes->keysym;
1113    int nsyms = 0;
1114    const xkb_keysym_t *syms_out = NULL;
1115
1116    nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
1117    if (nsyms && syms_out)
1118      {
1119         if (*syms_out == keysym)
1120           {
1121              found_keycodes->keycode = key;
1122           }
1123      }
1124 }
1125
1126 int
1127 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
1128 {
1129    keycode_map found_keycodes = {0,};
1130    found_keycodes.keysym = keysym;
1131    xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
1132
1133    return found_keycodes.keycode;
1134 }
1135
1136 E_API int
1137 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
1138 {
1139    struct xkb_keymap *keymap = NULL;
1140    xkb_keysym_t keysym = 0x0;
1141    int keycode = 0;
1142    char *name_tmp;
1143
1144    EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
1145    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
1146
1147    keymap = e_comp_wl->xkb.keymap;
1148    EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
1149
1150    keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
1151    if (keysym == XKB_KEY_NoSymbol)
1152      {
1153         if (strlen(name) <= sizeof("Keycode-")) goto finish;
1154
1155         if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
1156           {
1157              name_tmp = (char *)name + sizeof("Keycode-") - 1;
1158              keycode = atoi(name_tmp);
1159              if (keycode <= 8) goto finish;
1160
1161              return keycode;
1162           }
1163         else
1164           goto finish;
1165      }
1166
1167    keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
1168
1169    return keycode;
1170
1171 finish:
1172    return 0;
1173 }
1174
1175 E_API char *
1176 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
1177 {
1178    struct xkb_state *state;
1179    xkb_keysym_t sym = XKB_KEY_NoSymbol;
1180    char name[256] = {0, };
1181
1182    EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
1183    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
1184    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.state, NULL);
1185
1186    state = e_comp_wl->xkb.state;
1187    sym = xkb_state_key_get_one_sym(state, keycode);
1188    if (sym == XKB_KEY_NoSymbol)
1189      {
1190         snprintf(name, sizeof(name), "Keycode-%u", keycode);
1191      }
1192    else
1193      xkb_keysym_get_name(sym, name, sizeof(name));
1194
1195    return strdup(name);
1196 }