c2c27c95726639e86ddb8a51549e3208f51b6939
[platform/upstream/efl.git] / src / lib / ecore_wl2 / ecore_wl2_input.c
1 /* this file contains code copied from weston; the copyright notice is below */
2 /*
3  * Copyright © 2008 Kristian Høgsberg
4  * Copyright © 2012-2013 Collabora, Ltd.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #ifdef __linux__
31 # include <linux/input.h>
32 #else
33 # define BTN_LEFT 0x110
34 # define BTN_RIGHT 0x111
35 # define BTN_MIDDLE 0x112
36 # define BTN_SIDE 0x113
37 # define BTN_EXTRA 0x114
38 # define BTN_FORWARD 0x115
39 # define BTN_BACK 0x116
40 #endif
41
42 #include <unistd.h>
43 #include <sys/mman.h>
44 #include "ecore_wl2_private.h"
45 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
46 #include <locale.h>
47 //
48
49 typedef struct _Ecore_Wl2_Mouse_Down_Info
50 {
51    EINA_INLIST;
52    int device, sx, sy;
53    int last_win;
54    int last_last_win;
55    int last_event_win;
56    int last_last_event_win;
57    unsigned int last_time;
58    unsigned int last_last_time;
59    Eina_Bool double_click : 1;
60    Eina_Bool triple_click : 1;
61 } Ecore_Wl2_Mouse_Down_Info;
62
63 static Eina_Inlist *_ecore_wl2_mouse_down_info_list = NULL;
64
65 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
66 static double _tizen_api_version = 0.0;
67 static int _back_key_lt_24 = 0;
68 static int _menu_key_lt_24 = 0;
69 static int _home_key_lt_24 = 0;
70 static int _num_back_key_latest = 0;
71 static int _num_menu_key_latest = 0;
72 static int _num_home_key_latest = 0;
73 static xkb_keycode_t *_back_key_latest = NULL;
74 static xkb_keycode_t *_menu_key_latest = NULL;
75 static xkb_keycode_t *_home_key_latest = NULL;
76 //
77 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
78 static Eina_Hash *_keygrabs = NULL;
79 static int _ecore_wl2_keygrab_error = -1;
80 static struct wl_array _ecore_wl2_keygrab_result_list;
81 //
82
83 static void _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state);
84 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
85 static void _cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED);
86 //
87
88 static unsigned int _timestamp_get()
89 {
90    struct timespec ts;
91    clock_gettime(CLOCK_MONOTONIC, &ts);
92
93    return ts.tv_sec * 1000 + (ts.tv_nsec / 1000000);
94 }
95
96 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
97 static int
98 _ecore_wl2_input_convert_old_keys(unsigned int code)
99 {
100    int i;
101
102    // TIZEN ONLY(20160608) : Add option for key conversion
103    const char *tmp;
104    tmp = getenv("ECORE_WL_INPUT_KEY_CONVERSION_DISABLE");
105    if (tmp && atoi(tmp)) return code;
106    //
107
108    for (i = 0; i < _num_back_key_latest; i++)
109      {
110         if (code == _back_key_latest[i])
111           {
112              return _back_key_lt_24;
113           }
114      }
115
116    for (i=0; i<_num_menu_key_latest; i++)
117      {
118         if (code == _menu_key_latest[i])
119           {
120              return _menu_key_lt_24;
121           }
122      }
123
124    for (i=0; i<_num_home_key_latest; i++)
125      {
126         if (code == _home_key_latest[i])
127           {
128              return _home_key_lt_24;
129           }
130      }
131
132    return code;
133 }
134
135 static void
136 _ecore_wl2_input_key_conversion_clean_up(void)
137 {
138    _back_key_lt_24 = 0;
139    _menu_key_lt_24 = 0;
140    _home_key_lt_24 = 0;
141
142    _num_back_key_latest = 0;
143    _num_menu_key_latest = 0;
144    _num_home_key_latest = 0;
145
146    if (_back_key_latest)
147      {
148         free(_back_key_latest);
149         _back_key_latest = NULL;
150      }
151    if (_menu_key_latest)
152      {
153         free(_menu_key_latest);
154         _menu_key_latest = NULL;
155      }
156    if (_home_key_latest)
157      {
158         free(_home_key_latest);
159         _home_key_latest = NULL;
160      }
161 }
162
163 static void
164 _ecore_wl2_input_key_conversion_set(Ecore_Wl2_Input *input)
165 {
166    char *temp;
167    xkb_keycode_t *keycodes = NULL;
168    static int retry_cnt = 0;
169
170    if ((_tizen_api_version < 0.0) || (_tizen_api_version > 0.0)) return;
171    EINA_SAFETY_ON_NULL_RETURN(input);
172    EINA_SAFETY_ON_NULL_RETURN(input->xkb.keymap);
173
174    temp = getenv("TIZEN_API_VERSION");
175
176    if (!temp)
177      {
178         _tizen_api_version = 0.0;
179         retry_cnt++;
180         if (retry_cnt > 20)
181           {
182              INF("No tizen api version.\n");
183              _tizen_api_version = -1.0;
184           }
185      }
186    else
187      {
188         char* lc_numeric = setlocale(LC_NUMERIC, NULL);
189         char* old_numeric = lc_numeric? strdup(lc_numeric) : NULL;
190         setlocale(LC_NUMERIC, "C");
191         _tizen_api_version = atof(temp);
192         if(old_numeric)
193           {
194              setlocale(LC_NUMERIC, old_numeric);
195              free(old_numeric);
196           }
197         INF("TIZEN_API_VERSION: %lf, Environment variable: %s\n", _tizen_api_version, temp);
198         if (_tizen_api_version < 2.4)
199           {
200              _ecore_wl2_input_key_conversion_clean_up();
201
202              ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
203                 xkb_keysym_from_name("XF86Stop", XKB_KEYSYM_NO_FLAGS), &keycodes);
204              if (!keycodes)
205                {
206                   ERR("There is no entry available for the old name of back key. No conversion will be done for back key.\n");
207                }
208              else
209                {
210                   _back_key_lt_24 = (int)keycodes[0];
211                   free(keycodes);
212                   keycodes = NULL;
213
214                   _num_back_key_latest  = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
215                     xkb_keysym_from_name("XF86Back", XKB_KEYSYM_NO_FLAGS), &_back_key_latest);
216                }
217
218              ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
219                 xkb_keysym_from_name("XF86Send", XKB_KEYSYM_NO_FLAGS), &keycodes);
220              if (!keycodes)
221                {
222                   ERR("There is no entry available for the old name of back key. No conversion will be done for menu key.\n");
223                }
224              else
225                {
226                   _menu_key_lt_24 = (int)keycodes[0];
227                   free(keycodes);
228                   keycodes = NULL;
229
230                   _num_menu_key_latest  = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
231                     xkb_keysym_from_name("XF86Menu", XKB_KEYSYM_NO_FLAGS), &_menu_key_latest);
232                }
233
234              ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
235                 xkb_keysym_from_name("XF86Phone", XKB_KEYSYM_NO_FLAGS), &keycodes);
236              if (!keycodes)
237                {
238                   ERR("There is no entry available for the old name of back key. No conversion will be done for home key.\n");
239                }
240              else
241                {
242                   _home_key_lt_24 = (int)keycodes[0];
243                   free(keycodes);
244                   keycodes = NULL;
245
246                   _num_home_key_latest  = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
247                     xkb_keysym_from_name("XF86Home", XKB_KEYSYM_NO_FLAGS), &_home_key_latest);
248                }
249
250              if ((!_back_key_lt_24) && (!_menu_key_lt_24) && (!_home_key_lt_24)) _tizen_api_version = -1.0;
251           }
252         else
253           {
254              _ecore_wl2_input_key_conversion_clean_up();
255           }
256      }
257 }
258 //
259 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
260 static double
261 _ecore_wl2_input_touch_radius_calc(double x, double y)
262 {
263 #define PI 3.14159265358979323846
264    return x*y*PI/4;
265 }
266
267 static void
268 _ecore_wl2_input_touch_axis_process(Ecore_Wl2_Input *input, int id)
269 {
270    if (id >= input->touch.max_count)
271       return;
272
273    if (input->touch.last_touch_axis.radius_x)
274      {
275         input->touch.touch_axis[id].radius_x = input->touch.last_touch_axis.radius_x;
276         input->touch.last_touch_axis.radius_x = 0.0;
277      }
278    if (input->touch.last_touch_axis.radius_y)
279      {
280         input->touch.touch_axis[id].radius_y = input->touch.last_touch_axis.radius_y;
281         input->touch.last_touch_axis.radius_y = 0.0;
282      }
283    if (input->touch.last_touch_axis.pressure)
284      {
285         input->touch.touch_axis[id].pressure = input->touch.last_touch_axis.pressure;
286         input->touch.last_touch_axis.pressure = 0.0;
287      }
288    if (input->touch.last_touch_axis.angle)
289      {
290         input->touch.touch_axis[id].angle = input->touch.last_touch_axis.angle;
291         input->touch.last_touch_axis.angle = 0.0;
292      }
293 }
294 //
295
296 static Ecore_Wl2_Mouse_Down_Info *
297 _ecore_wl2_input_mouse_down_info_get(int device)
298 {
299    Eina_Inlist *l = NULL;
300    Ecore_Wl2_Mouse_Down_Info *info = NULL;
301
302    l = _ecore_wl2_mouse_down_info_list;
303    EINA_INLIST_FOREACH(l, info)
304      if (info->device == device) return info;
305
306    info = calloc(1, sizeof(Ecore_Wl2_Mouse_Down_Info));
307    if (!info) return NULL;
308
309    info->device = device;
310    l = eina_inlist_append(l, (Eina_Inlist *)info);
311    _ecore_wl2_mouse_down_info_list = l;
312
313    return info;
314 }
315
316 static Ecore_Wl2_Input_Devices *
317 _ecore_wl2_devices_get(const Ecore_Wl2_Input *input, int window_id)
318 {
319    Ecore_Wl2_Input_Devices *devices;
320    Eina_List *l;
321
322    EINA_LIST_FOREACH(input->devices_list, l, devices)
323      {
324         if (devices->window_id == window_id)
325           return devices;
326      }
327
328    return NULL;
329 }
330
331 static Eo *
332 _ecore_wl2_touch_dev_get(Ecore_Wl2_Input *input, int window_id)
333 {
334    Ecore_Wl2_Input_Devices *devices;
335    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
336
337    if (input->devmgr.last_device_touch && input->devmgr.last_device_touch->device)
338      {
339         return efl_ref(input->devmgr.last_device_touch->device);
340      }
341    //
342
343    devices = _ecore_wl2_devices_get(input, window_id);
344    if (devices && devices->touch_dev)
345      return efl_ref(devices->touch_dev);
346
347    return NULL;
348 }
349
350 static Eo *
351 _ecore_wl2_mouse_dev_get(Ecore_Wl2_Input *input, int window_id)
352 {
353    const char *tmp;
354    if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1))
355      return _ecore_wl2_touch_dev_get(input, window_id);
356
357    Ecore_Wl2_Input_Devices *devices;
358    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
359
360    if (input->devmgr.last_device_ptr && input->devmgr.last_device_ptr->device)
361      {
362         return efl_ref(input->devmgr.last_device_ptr->device);
363      }
364    //
365
366    devices = _ecore_wl2_devices_get(input, window_id);
367    if (devices && devices->pointer_dev)
368      return efl_ref(devices->pointer_dev);
369
370    return NULL;
371 }
372
373 static Eo *
374 _ecore_wl2_seat_dev_get(Ecore_Wl2_Input *input, int window_id)
375 {
376    Ecore_Wl2_Input_Devices *devices;
377
378    devices = _ecore_wl2_devices_get(input, window_id);
379    if (devices)
380      return efl_ref(devices->seat_dev);
381
382    return NULL;
383 }
384
385 //TIZEN_ONLY(20180118): support a Ecore_Device
386 static void
387 _input_event_mouse_io_cb_free(void *data EINA_UNUSED, void *event)
388 {
389    Ecore_Event_Mouse_IO *ev = event;
390    if (ev->dev)
391      efl_unref(ev->dev);
392    free(ev);
393 }
394
395 static void
396 _input_event_mouse_move_cb_free(void *data EINA_UNUSED, void *event)
397 {
398    Ecore_Event_Mouse_Move *ev = event;
399    if (ev->dev)
400      efl_unref(ev->dev);
401    free(ev);
402 }
403
404 static void
405 _input_event_mouse_wheel_cb_free(void *data EINA_UNUSED, void *event)
406 {
407    Ecore_Event_Mouse_Wheel *ev = event;
408    if (ev->dev)
409      efl_unref(ev->dev);
410    free(ev);
411 }
412
413 static void
414 _input_event_mouse_button_cb_free(void *data EINA_UNUSED, void *event)
415 {
416    Ecore_Event_Mouse_Button *ev = event;
417    if (ev->dev)
418      efl_unref(ev->dev);
419    free(ev);
420 }
421
422 static void
423 _input_event_key_cb_free(void *data EINA_UNUSED, void *event)
424 {
425    Ecore_Event_Key *ev = event;
426    if (ev->dev)
427      efl_unref(ev->dev);
428    free(ev);
429 }
430 //
431
432 static void
433 _ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
434 {
435    Ecore_Event_Mouse_IO *ev;
436
437    ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
438    if (!ev) return;
439
440    ev->x = input->pointer.sx;
441    ev->y = input->pointer.sy;
442    ev->window = window->id;
443    ev->event_window = window->id;
444    ev->timestamp = input->timestamp;
445    ev->modifiers = input->keyboard.modifiers;
446    ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
447
448    ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, _input_event_mouse_io_cb_free, ev->dev);
449 }
450
451 static void
452 _ecore_wl2_input_mouse_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
453 {
454    Ecore_Event_Mouse_IO *ev;
455
456    ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
457    if (!ev) return;
458
459    ev->x = input->pointer.sx;
460    ev->y = input->pointer.sy;
461    ev->window = window->id;
462    ev->event_window = window->id;
463    ev->timestamp = input->timestamp;
464    ev->modifiers = input->keyboard.modifiers;
465    ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
466
467    ecore_event_add(ECORE_EVENT_MOUSE_OUT, ev, _input_event_mouse_io_cb_free, ev->dev);
468 }
469
470 static void
471 _ecore_wl2_input_mouse_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device)
472 {
473    Ecore_Event_Mouse_Move *ev;
474    Ecore_Wl2_Mouse_Down_Info *info;
475
476    ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
477    if (!ev) return;
478
479    ev->window = window->id;
480    ev->event_window = window->id;
481    ev->timestamp = input->timestamp;
482    ev->x = input->pointer.sx;
483    ev->y = input->pointer.sy;
484    ev->root.x = input->pointer.sx;
485    ev->root.y = input->pointer.sy;
486    ev->modifiers = input->keyboard.modifiers;
487    ev->multi.device = device;
488
489    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
490    if (device >= input->touch.max_count)
491      {
492         ev->multi.radius = 1;
493         ev->multi.radius_x = 1;
494         ev->multi.radius_y = 1;
495         ev->multi.pressure = 1.0;
496         ev->multi.angle = 0.0;
497      }
498    else
499      {
500         ev->multi.radius =
501            _ecore_wl2_input_touch_radius_calc(input->touch.touch_axis[device].radius_x,
502                                              input->touch.touch_axis[device].radius_y);
503         ev->multi.radius_x = input->touch.touch_axis[device].radius_x;
504         ev->multi.radius_y = input->touch.touch_axis[device].radius_y;
505         ev->multi.pressure = input->touch.touch_axis[device].pressure;
506         ev->multi.angle = input->touch.touch_axis[device].angle;
507      }
508    //
509
510    ev->multi.x = input->pointer.sx;
511    ev->multi.y = input->pointer.sy;
512    ev->multi.root.x = input->pointer.sx;
513    ev->multi.root.y = input->pointer.sy;
514
515    if ((input->focus.touch) && (input->focus.touch == window))
516      ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
517    else if ((input->focus.pointer) && (input->focus.pointer == window))
518      ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
519
520    info = _ecore_wl2_input_mouse_down_info_get(device);
521    if (info)
522      {
523         info->sx = input->pointer.sx;
524         info->sy = input->pointer.sy;
525      }
526
527    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _input_event_mouse_move_cb_free, ev->dev);
528 }
529
530 static void
531 _ecore_wl2_input_mouse_wheel_send(Ecore_Wl2_Input *input, unsigned int axis, int value, unsigned int timestamp)
532 {
533    Ecore_Event_Mouse_Wheel *ev;
534
535    ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
536    if (!ev) return;
537
538    ev->timestamp = timestamp;
539    ev->modifiers = input->keyboard.modifiers;
540    ev->x = input->pointer.sx;
541    ev->y = input->pointer.sy;
542    //TIZEN_ONLY(20190306): revert upstream patch
543    //value /= 10;
544    //
545
546    if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
547      {
548         ev->direction = 0;
549         ev->z = value;
550      }
551    else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
552      {
553         ev->direction = 1;
554         ev->z = value;
555      }
556
557    if (input->grab.window)
558      {
559         ev->window = input->grab.window->id;
560         ev->event_window = input->grab.window->id;
561      }
562    else if (input->focus.pointer)
563      {
564         ev->window = input->focus.pointer->id;
565         ev->event_window = input->focus.pointer->id;
566         ev->dev = _ecore_wl2_mouse_dev_get(input, input->focus.pointer->id);
567      }
568    else if (input->focus.touch)
569      {
570         ev->window = input->focus.touch->id;
571         ev->event_window = input->focus.touch->id;
572         ev->dev = _ecore_wl2_touch_dev_get(input, input->focus.touch->id);
573      }
574
575    if (!ev->dev)
576      {
577         ev->dev = _ecore_wl2_mouse_dev_get(input, ev->window);
578         if (!ev->dev)
579           ev->dev = _ecore_wl2_touch_dev_get(input, ev->window);
580      }
581
582    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _input_event_mouse_wheel_cb_free, ev->dev);
583 }
584
585 static void
586 _ecore_wl2_input_mouse_down_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
587 {
588    Ecore_Event_Mouse_Button *ev;
589    Ecore_Wl2_Mouse_Down_Info *info;
590
591    ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
592    if (!ev) return;
593
594    if (button == BTN_LEFT)
595      ev->buttons = 1;
596    else if (button == BTN_MIDDLE)
597      ev->buttons = 2;
598    else if (button == BTN_RIGHT)
599      ev->buttons = 3;
600    else
601      ev->buttons = button;
602
603    ev->timestamp = timestamp;
604    ev->x = input->pointer.sx;
605    ev->y = input->pointer.sy;
606    ev->root.x = input->pointer.sx;
607    ev->root.y = input->pointer.sy;
608    ev->modifiers = input->keyboard.modifiers;
609
610    ev->double_click = 0;
611    ev->triple_click = 0;
612
613    info = _ecore_wl2_input_mouse_down_info_get(device);
614    if (info)
615      {
616         info->sx = input->pointer.sx;
617         info->sy = input->pointer.sy;
618         if (info->triple_click)
619           {
620              info->last_win = 0;
621              info->last_last_win = 0;
622              info->last_event_win = 0;
623              info->last_last_event_win = 0;
624              info->last_time = 0;
625              info->last_last_time = 0;
626           }
627
628         if (((int)(timestamp - info->last_time) <= (int)(1000 * 0.25)) &&
629             ((window) && (window->id == info->last_win) &&
630                 (window->id == info->last_event_win)))
631           {
632              ev->double_click = 1;
633              info->double_click = EINA_TRUE;
634           }
635         else
636           {
637              info->double_click = EINA_FALSE;
638              info->triple_click = EINA_FALSE;
639           }
640
641         if (((int)(timestamp - info->last_last_time) <=
642              (int)(2 * 1000 * 0.25)) &&
643             ((window) && (window->id == info->last_win) &&
644                 (window->id == info->last_last_win) &&
645                 (window->id == info->last_event_win) &&
646                 (window->id == info->last_last_event_win)))
647           {
648              ev->triple_click = 1;
649              info->triple_click = EINA_TRUE;
650           }
651         else
652           info->triple_click = EINA_FALSE;
653      }
654
655    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
656    if (device >= input->touch.max_count)
657      {
658         ev->multi.radius = 1;
659         ev->multi.radius_x = 1;
660         ev->multi.radius_y = 1;
661         ev->multi.pressure = 1.0;
662         ev->multi.angle = 0.0;
663      }
664    else
665      {
666         ev->multi.radius =
667            _ecore_wl2_input_touch_radius_calc(input->touch.touch_axis[device].radius_x,
668                                              input->touch.touch_axis[device].radius_y);
669         ev->multi.radius_x = input->touch.touch_axis[device].radius_x;
670         ev->multi.radius_y = input->touch.touch_axis[device].radius_y;
671         ev->multi.pressure = input->touch.touch_axis[device].pressure;
672         ev->multi.angle = input->touch.touch_axis[device].angle;
673      }
674    //
675    ev->multi.device = device;
676    ev->multi.x = input->pointer.sx;
677    ev->multi.y = input->pointer.sy;
678    ev->multi.root.x = input->pointer.sx;
679    ev->multi.root.y = input->pointer.sy;
680
681    if (window)
682      {
683         ev->window = window->id;
684         ev->event_window = window->id;
685
686         if ((input->focus.touch) && (input->focus.touch == window))
687           ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
688         else if ((input->focus.pointer) && (input->focus.pointer == window))
689           ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
690      }
691
692    //TIZEN_ONLY(20200408): add debug
693    ERR("[press] window = %p, time=%u button=%d", window, (unsigned int)timestamp, device);
694    //
695
696    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev,
697                    _input_event_mouse_button_cb_free, ev->dev);
698
699    if ((info) && (!info->triple_click))
700      {
701         info->last_last_win = info->last_win;
702         info->last_win = ev->window;
703         info->last_last_event_win = info->last_event_win;
704         info->last_event_win = ev->window;
705         info->last_last_time = info->last_time;
706         info->last_time = timestamp;
707      }
708 }
709
710 static void
711 _ecore_wl2_input_mouse_up_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
712 {
713    Ecore_Event_Mouse_Button *ev;
714    Ecore_Wl2_Mouse_Down_Info *info;
715
716    ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
717    if (!ev) return;
718
719    if (button == BTN_LEFT)
720      ev->buttons = 1;
721    else if (button == BTN_MIDDLE)
722      ev->buttons = 2;
723    else if (button == BTN_RIGHT)
724      ev->buttons = 3;
725    else
726      ev->buttons = button;
727
728    ev->timestamp = timestamp;
729    ev->x = input->pointer.sx;
730    ev->y = input->pointer.sy;
731    ev->root.x = input->pointer.sx;
732    ev->root.y = input->pointer.sy;
733    ev->modifiers = input->keyboard.modifiers;
734
735    ev->double_click = 0;
736    ev->triple_click = 0;
737
738    info = _ecore_wl2_input_mouse_down_info_get(device);
739    if (info)
740      {
741         ev->double_click = info->double_click;
742         ev->triple_click = info->triple_click;
743         ev->x = info->sx;
744         ev->y = info->sy;
745         ev->multi.x = info->sx;
746         ev->multi.y = info->sy;
747      }
748    else
749      {
750         ev->multi.x = input->pointer.sx;
751         ev->multi.y = input->pointer.sy;
752      }
753
754    ev->multi.device = device;
755    ev->multi.radius = 1;
756    ev->multi.radius_x = 1;
757    ev->multi.radius_y = 1;
758    ev->multi.pressure = 1.0;
759    ev->multi.angle = 0.0;
760    ev->multi.root.x = input->pointer.sx;
761    ev->multi.root.y = input->pointer.sy;
762
763    ev->window = window->id;
764    ev->event_window = window->id;
765
766    if ((input->focus.touch) && (input->focus.touch == window))
767      ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
768    else if ((input->focus.pointer) && (input->focus.pointer == window))
769      ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
770
771    //TIZEN_ONLY(20200408): add debug
772    ERR("[release] time=%u button=%d", (unsigned int)timestamp, device);
773    //
774
775    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev,
776                    _input_event_mouse_button_cb_free, ev->dev);
777
778
779    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
780    if (device < input->touch.max_count)
781      {
782         input->touch.touch_axis[device].radius_x = 1.0;
783         input->touch.touch_axis[device].radius_y = 1.0;
784         input->touch.touch_axis[device].pressure = 1.0;
785         input->touch.touch_axis[device].angle = 0;
786      }
787    //
788 }
789
790 static void
791 _input_event_focus_cb_free(void *data, void *event)
792 {
793    Ecore_Wl2_Event_Focus_In *ev = event;
794    if (data)
795      efl_unref(data);
796    ecore_wl2_display_disconnect(ev->display);
797    free(event);
798 }
799
800 static void
801 _ecore_wl2_input_focus_in_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
802 {
803    Ecore_Wl2_Event_Focus_In *ev;
804
805    ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_In));
806    if (!ev) return;
807
808    ev->timestamp = input->timestamp;
809    ev->window = window->id;
810    ev->dev = _ecore_wl2_seat_dev_get(input, window->id);
811    ev->display = input->display;
812    ev->display->refs++;
813    ecore_event_add(ECORE_WL2_EVENT_FOCUS_IN, ev, _input_event_focus_cb_free,
814                    ev->dev);
815 }
816
817 static void
818 _ecore_wl2_input_focus_out_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
819 {
820    Ecore_Wl2_Event_Focus_Out *ev;
821
822    ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_Out));
823    if (!ev) return;
824
825    ev->timestamp = input->timestamp;
826    ev->window = window->id;
827    ev->dev = _ecore_wl2_seat_dev_get(input, window->id);
828    ev->display = input->display;
829    ev->display->refs++;
830    ecore_event_add(ECORE_WL2_EVENT_FOCUS_OUT, ev, _input_event_focus_cb_free,
831                    ev->dev);
832 }
833
834 static int
835 _ecore_wl2_input_key_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes)
836 {
837 /* this function is copied, with slight changes in variable names, from KeyBind.c in libX11
838  * the license from that file can be found below:
839  */
840 /*
841
842 Copyright 1985, 1987, 1998  The Open Group
843
844 Permission to use, copy, modify, distribute, and sell this software and its
845 documentation for any purpose is hereby granted without fee, provided that
846 the above copyright notice appear in all copies and that both that
847 copyright notice and this permission notice appear in supporting
848 documentation.
849
850 The above copyright notice and this permission notice shall be included in
851 all copies or substantial portions of the Software.
852
853 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
854 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
855 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
856 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
857 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
858 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
859
860 Except as contained in this notice, the name of The Open Group shall not be
861 used in advertising or otherwise to promote the sale, use or other dealings
862 in this Software without prior written authorization from The Open Group.
863
864 */
865    if (!keysym) return 0;
866
867    /* check for possible control codes */
868    if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
869      {
870         Eina_Bool valid_control_code = EINA_TRUE;
871         unsigned long hbytes = 0;
872         unsigned char c;
873
874         hbytes = (keysym >> 8);
875         if (!(bytes &&
876         ((hbytes == 0) ||
877         ((hbytes == 0xFF) &&
878         (((keysym >= XKB_KEY_BackSpace) && (keysym <= XKB_KEY_Clear)) ||
879         (keysym == XKB_KEY_Return) ||
880         (keysym == XKB_KEY_Escape) ||
881         (keysym == XKB_KEY_KP_Space) ||
882         (keysym == XKB_KEY_KP_Tab) ||
883         (keysym == XKB_KEY_KP_Enter) ||
884         ((keysym >= XKB_KEY_KP_Multiply) && (keysym <= XKB_KEY_KP_9)) ||
885         (keysym == XKB_KEY_KP_Equal) ||
886         (keysym == XKB_KEY_Delete))))))
887           return 0;
888
889         if (keysym == XKB_KEY_KP_Space)
890           c = (XKB_KEY_space & 0x7F);
891         else if (hbytes == 0xFF)
892           c = (keysym & 0x7F);
893         else
894           c = (keysym & 0xFF);
895
896         /* We are building here a control code
897            for more details, read:
898            https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C0_.28ASCII_and_derivatives.29
899          */
900
901         if (((c >= '@') && (c <= '_')) || /* those are the one defined in C0 with capital letters */
902              ((c >= 'a') && (c <= 'z')) ||  /* the lowercase symbols (not part of the standard, but useful) */
903               c == ' ')
904           c &= 0x1F;
905         else if (c == '\x7f')
906           c = '\177';
907         /* following codes are alternatives, they are longer here, i dont want to change them */
908         else if (c == '2')
909           c = '\000'; /* 0 code */
910         else if ((c >= '3') && (c <= '7'))
911           c -= ('3' - '\033'); /* from escape to unitseperator code*/
912         else if (c == '8')
913           c = '\177'; /* delete code */
914         else if (c == '/')
915           c = '_' & 0x1F; /* unit seperator code */
916         else
917           valid_control_code = EINA_FALSE;
918
919         if (valid_control_code)
920           buffer[0] = c;
921         else
922           return 0;
923      }
924    else
925      {
926         /* if its not a control code, try to produce useful output */
927         if (!xkb_keysym_to_utf8(keysym, buffer, bytes))
928           return 0;
929      }
930
931    return 1;
932 }
933
934 static void
935 _ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code)
936 {
937     if (xkb_keysym_get_name(keysym, buffer, size) != 0)
938       return;
939
940     snprintf(buffer, size, "Keycode-%u", code);
941 }
942
943 static Eo *
944 _ecore_wl2_keyboard_dev_get(Ecore_Wl2_Input *input, int window_id)
945 {
946    Ecore_Wl2_Input_Devices *devices;
947    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
948
949    if (input->devmgr.last_device_kbd && input->devmgr.last_device_kbd->device)
950      {
951         return efl_ref(input->devmgr.last_device_kbd->device);
952      }
953    //
954
955    devices = _ecore_wl2_devices_get(input, window_id);
956    if (devices && devices->keyboard_dev)
957      return efl_ref(devices->keyboard_dev);
958
959    return NULL;
960 }
961
962 static void
963 _ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_keysym_t sym, xkb_keysym_t sym_name, unsigned int code, unsigned int state, unsigned int timestamp, Eina_Bool cancel, Eina_Bool repeat)
964 {
965    Ecore_Event_Key *ev;
966    char key[256] = "", keyname[256] = "", compose[256] = "";
967    int name_len, key_len, comp_len;
968
969    /*try to get a name or utf char of the given symbol */
970    _ecore_wl2_input_symbol_rep_find(sym, key, sizeof(key), code);
971    _ecore_wl2_input_symbol_rep_find(sym_name, keyname, sizeof(keyname), code);
972    _ecore_wl2_input_key_translate(sym, input->keyboard.modifiers,
973                                   compose, sizeof(compose));
974
975    name_len = strlen(keyname);
976    key_len = strlen(key);
977    comp_len = strlen(compose);
978
979    ev = calloc(1, sizeof(Ecore_Event_Key) + key_len + name_len + comp_len + 3);
980    if (!ev) return;
981
982    ev->keyname = (char *)(ev + 1);
983    ev->key = ev->keyname + name_len + 1;
984    ev->compose = comp_len ? ev->key + key_len + 1 : NULL;
985    ev->string = ev->compose;
986    ev->event_flags = ECORE_EVENT_FLAG_NONE;
987    if (cancel)
988      ev->event_flags |= ECORE_EVENT_FLAG_CANCEL;
989    if (repeat)
990      ev->event_flags |= ECORE_EVENT_FLAG_REPEAT;
991
992    strcpy((char *)ev->keyname, keyname);
993    strcpy((char *)ev->key, key);
994    if (comp_len) strcpy((char *)ev->compose, compose);
995
996    // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
997    if (window)
998      {
999         ev->window = window->id;
1000         ev->event_window = window->id;
1001         ev->dev = _ecore_wl2_keyboard_dev_get(input, window->id);
1002      }
1003    else
1004      {
1005         ev->window = (uintptr_t)NULL;
1006         ev->event_window = (uintptr_t)NULL;
1007         ev->dev = _ecore_wl2_keyboard_dev_get(input, 0);
1008      }
1009    //
1010    ev->timestamp = timestamp;
1011    ev->modifiers = input->keyboard.modifiers;
1012    ev->keycode = code;
1013
1014    /* DBG("Emitting Key event (%s,%s,%s,%s)\n", ev->keyname, ev->key, ev->compose, ev->string); */
1015
1016    if (state)
1017      ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, _input_event_key_cb_free, ev->dev);
1018    else
1019      ecore_event_add(ECORE_EVENT_KEY_UP, ev, _input_event_key_cb_free, ev->dev);
1020 }
1021
1022 void
1023 _ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, unsigned int button)
1024 {
1025    input->grab.window = window;
1026    input->grab.button = button;
1027 }
1028
1029 void
1030 _ecore_wl2_input_ungrab(Ecore_Wl2_Input *input)
1031 {
1032    if ((input->grab.window) && (input->grab.button) && (input->grab.count))
1033      _ecore_wl2_input_mouse_up_send(input, input->grab.window, 0,
1034                                     input->grab.button, input->grab.timestamp);
1035
1036    input->grab.window = NULL;
1037    input->grab.button = 0;
1038    input->grab.count = 0;
1039    input->grab.touch_count = 0;
1040 }
1041
1042 static void
1043 _pointer_cb_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy)
1044 {
1045    Ecore_Wl2_Input *input;
1046    Ecore_Wl2_Window *window;
1047    const char *config_cursor_name;
1048
1049    input = data;
1050    if (!input) return;
1051
1052    /* trap for a surface that was just destroyed */
1053    if (!surface) return;
1054
1055    if (!input->timestamp)
1056      {
1057         struct timeval tv;
1058
1059         gettimeofday(&tv, NULL);
1060         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
1061      }
1062
1063    input->display->serial = serial;
1064    input->pointer.enter_serial = serial;
1065    input->pointer.sx = wl_fixed_to_double(sx);
1066    input->pointer.sy = wl_fixed_to_double(sy);
1067
1068    // Cursor change from configuration is applied only for default cursor
1069    if (eina_streq(input->cursor.theme_name, "default"))
1070      {
1071         _ecore_wl2_cursor_config_reload();
1072         config_cursor_name = _ecore_wl2_cursor_config_name_get();
1073         if (config_cursor_name)
1074           {
1075              if (!input->cursor.name || !eina_streq(input->cursor.name, config_cursor_name))
1076                eina_stringshare_replace(&input->cursor.name, config_cursor_name);
1077           }
1078      }
1079
1080    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1081    // TIZEN_ONLY(20230330): support client that requests to unset cursor
1082    /* The cursor on the surface is undefined until we set it */
1083    if (!input->cursor.name)
1084      ecore_wl2_input_pointer_set(input, NULL, 0, 0);
1085    else
1086      ecore_wl2_input_cursor_from_name_set(input, input->cursor.name);
1087    //
1088    //
1089
1090    /* find the window which this surface belongs to */
1091    window = _ecore_wl2_display_window_surface_find(input->display, surface);
1092    if (!window) return;
1093
1094    // TIZEN_ONLY(20190729): do not generate duplicated mouse in events
1095    if (input->focus.pointer == window) return;
1096    //
1097
1098    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1099    window->pointer.device = input;
1100    //
1101    input->focus.prev_pointer = NULL;
1102    input->focus.pointer = window;
1103
1104    _ecore_wl2_input_mouse_in_send(input, window);
1105 }
1106
1107 static void
1108 _pointer_cb_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
1109 {
1110    Ecore_Wl2_Input *input;
1111    Ecore_Wl2_Window *window;
1112
1113    input = data;
1114    if (!input) return;
1115
1116    input->display->serial = serial;
1117    input->focus.prev_pointer = input->focus.pointer;
1118    input->focus.pointer = NULL;
1119
1120    /* trap for a surface that was just destroyed */
1121    if (!surface) return;
1122
1123    /* find the window which this surface belongs to */
1124    window = _ecore_wl2_display_window_surface_find(input->display, surface);
1125    if (!window) return;
1126
1127    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1128    window->pointer.device = NULL;
1129    //
1130
1131    _ecore_wl2_input_mouse_out_send(input, window);
1132 }
1133
1134 static void
1135 _pointer_cb_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy)
1136 {
1137    Ecore_Wl2_Input *input;
1138    Ecore_Wl2_Window *window;
1139
1140    input = data;
1141    if (!input) return;
1142
1143    input->timestamp = timestamp;
1144    input->pointer.sx = wl_fixed_to_double(sx);
1145    input->pointer.sy = wl_fixed_to_double(sy);
1146
1147    /* get currently focused window */
1148    window = input->focus.pointer;
1149    if (!window) return;
1150
1151    /* NB: Unsure if we need this just yet, so commented out for now */
1152    /* if ((input->pointer.sx > window->geometry.w) || */
1153    /*     (input->pointer.sy > window->geometry.h)) */
1154    /*   return; */
1155
1156    const char *tmp;
1157    if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1) && (input->grab.count == 0))
1158      return;
1159
1160    _ecore_wl2_input_mouse_move_send(input, window, 0);
1161 }
1162
1163 static void
1164 _pointer_cb_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state)
1165 {
1166    Ecore_Wl2_Input *input;
1167
1168    input = data;
1169    if (!input) return;
1170
1171    input->display->serial = serial;
1172    input->timestamp = timestamp;
1173
1174    if (state == WL_POINTER_BUTTON_STATE_PRESSED)
1175      {
1176         if ((input->focus.pointer) &&
1177             (!input->grab.window) && (!input->grab.count))
1178           {
1179              _ecore_wl2_input_grab(input, input->focus.pointer, button);
1180              input->grab.timestamp = timestamp;
1181           }
1182
1183         if (input->focus.pointer)
1184           {
1185              const char *tmp;
1186              if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1) && (input->grab.count == 0))
1187                _ecore_wl2_input_mouse_move_send(input, input->focus.pointer, 0);
1188
1189              _ecore_wl2_input_mouse_down_send(input, input->focus.pointer,
1190                                               0, button, timestamp);
1191           }
1192
1193         input->grab.count++;
1194      }
1195    else
1196      {
1197         if (input->focus.pointer)
1198           _ecore_wl2_input_mouse_up_send(input, input->focus.pointer,
1199                                          0, button, timestamp);
1200
1201         if (input->grab.count) input->grab.count--;
1202         if ((input->grab.window) && (input->grab.button == button) &&
1203             (!input->grab.count))
1204           _ecore_wl2_input_ungrab(input);
1205      }
1206 }
1207
1208 static void
1209 _pointer_cb_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value)
1210 {
1211    Ecore_Wl2_Input *input;
1212
1213    input = data;
1214    if (!input) return;
1215
1216    input->timestamp = timestamp;
1217
1218    _ecore_wl2_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value),
1219                                      timestamp);
1220 }
1221
1222 static const struct wl_pointer_listener _pointer_listener =
1223 {
1224    _pointer_cb_enter,
1225    _pointer_cb_leave,
1226    _pointer_cb_motion,
1227    _pointer_cb_button,
1228    _pointer_cb_axis,
1229    NULL, /* frame */
1230    NULL, /* axis_source */
1231    NULL, /* axis_stop */
1232    NULL, /* axis_discrete */
1233 };
1234
1235 // TIZEN_ONLY(20230802): ecore_input: add Ecore_Event_Mouse_Relative_Move struct
1236 static void
1237 _ecore_wl2_input_mouse_relative_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int dx, int dy, int dx_unaccel, int dy_unaccel)
1238 {
1239    Ecore_Event_Mouse_Relative_Move *ev;
1240
1241    ev = calloc(1, sizeof(Ecore_Event_Mouse_Relative_Move));
1242    if (!ev) return;
1243
1244    ev->window = window->id;
1245    ev->event_window = window->id;
1246    ev->timestamp = input->timestamp;
1247    ev->modifiers = input->keyboard.modifiers;
1248    ev->dx = dx;
1249    ev->dy = dy;
1250    ev->dx_unaccel = dx_unaccel;
1251    ev->dy_unaccel = dy_unaccel;
1252
1253    ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
1254
1255    ERR("[Relative Move] timestamp=%u dx=%d, dy=%d, dx_unaccel=%d, dy_unaccel=%d", ev->timestamp, ev->dx, ev->dy, ev->dx_unaccel, ev->dy_unaccel);
1256    ecore_event_add(ECORE_EVENT_MOUSE_RELATIVE_MOVE, ev, NULL, NULL);
1257 }
1258 //
1259
1260 // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
1261 static void
1262 _relative_pointer_cb_relative_motion(void *data, struct zwp_relative_pointer_v1* relative_pointer,
1263                                      uint32_t ts_high, uint32_t ts_low, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel)
1264 {
1265    Ecore_Wl2_Input *input;
1266    Ecore_Wl2_Window *window;
1267     (void) relative_pointer;
1268
1269    input = data;
1270    if (!input) return;
1271
1272    // For Debug
1273    ERR("[relative_pointer] ts_high=%u, ts_low=%u, dx=%d, dy=%d, dx_unaccel=%d, dy_unaccel=%d",
1274        ts_high, ts_low, wl_fixed_to_int(dx), wl_fixed_to_int(dy), wl_fixed_to_int(dx_unaccel), wl_fixed_to_int(dy_unaccel));
1275
1276    input->timestamp = (unsigned int)ts_low;
1277
1278    /* get currently focused window */
1279    window = input->focus.pointer;
1280    if (!window) return;
1281
1282    _ecore_wl2_input_mouse_relative_move_send(input, window, wl_fixed_to_int(dx), wl_fixed_to_int(dy),
1283                                              wl_fixed_to_int(dx_unaccel), wl_fixed_to_int(dy_unaccel));
1284 }
1285
1286 static const struct zwp_relative_pointer_v1_listener _relative_pointer_listener = {
1287    _relative_pointer_cb_relative_motion,
1288 };
1289 //
1290
1291 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
1292 static void
1293 _locked_pointer_cb_locked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1 EINA_UNUSED)
1294 {
1295    Ecore_Wl2_Input *input = (Ecore_Wl2_Input *)data;
1296
1297    // For Debug
1298    ERR("[locked pointer] locked");
1299    input->pointer_locked = EINA_TRUE;
1300 }
1301
1302 static void
1303 _locked_pointer_cb_unlocked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1 EINA_UNUSED)
1304 {
1305    Ecore_Wl2_Input *input = (Ecore_Wl2_Input *)data;
1306
1307    // For Debug
1308    ERR("[locked pointer] unlocked");
1309    input->pointer_locked = EINA_FALSE;
1310 }
1311
1312 static const struct zwp_locked_pointer_v1_listener _locked_pointer_listener = {
1313    _locked_pointer_cb_locked,
1314    _locked_pointer_cb_unlocked,
1315 };
1316 //
1317
1318 static void
1319 _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size)
1320 {
1321    Ecore_Wl2_Input *input;
1322    Ecore_Wl2_Event_Seat_Keymap_Changed *ev;
1323    char *map = NULL;
1324    const char *locale;
1325
1326    input = data;
1327    if (!input)
1328      {
1329         close(fd);
1330         return;
1331      }
1332
1333    if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
1334      {
1335         close(fd);
1336         return;
1337      }
1338
1339    map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1340    if (map == MAP_FAILED)
1341      {
1342         close(fd);
1343         return;
1344      }
1345
1346    /* free any existing keymap and state */
1347    if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
1348    if (input->xkb.state) xkb_state_unref(input->xkb.state);
1349    if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
1350
1351    input->xkb.keymap =
1352      xkb_map_new_from_string(input->display->xkb_context, map,
1353                              XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1354
1355    munmap(map, size);
1356    close(fd);
1357
1358    if (!input->xkb.keymap)
1359      {
1360         ERR("Failed to compile keymap");
1361         return;
1362      }
1363
1364    input->xkb.state = xkb_state_new(input->xkb.keymap);
1365    input->xkb.maskless_state = xkb_state_new(input->xkb.keymap);
1366
1367    if (!input->xkb.state || !input->xkb.maskless_state)
1368      {
1369         ERR("Failed to create keymap state");
1370         xkb_map_unref(input->xkb.keymap);
1371         input->xkb.keymap = NULL;
1372         return;
1373      }
1374
1375 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
1376    _tizen_api_version = 0.0;
1377 //
1378
1379    if (!(locale = getenv("LC_ALL")))
1380      if (!(locale = getenv("LC_CTYPE")))
1381        if (!(locale = getenv("LANG")))
1382          locale = "C";
1383
1384    if (input->xkb.compose_table)
1385      xkb_compose_table_unref(input->xkb.compose_table);
1386
1387    input->xkb.compose_table =
1388      xkb_compose_table_new_from_locale(input->display->xkb_context,
1389                                        locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
1390    if (input->xkb.compose_state)
1391      xkb_compose_state_unref(input->xkb.compose_state);
1392    input->xkb.compose_state = NULL;
1393
1394    if (input->xkb.compose_table)
1395      {
1396         input->xkb.compose_state =
1397           xkb_compose_state_new(input->xkb.compose_table,
1398                                 XKB_COMPOSE_STATE_NO_FLAGS);
1399      }
1400
1401    ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1402    if (ev)
1403      {
1404         ev->id = input->id;
1405         ev->display = input->display;
1406         input->display->refs++;
1407         ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYMAP_CHANGED, ev,
1408                         _display_event_free, ev->display);
1409      }
1410
1411    input->xkb.control_mask =
1412      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CTRL);
1413    input->xkb.alt_mask =
1414      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_ALT);
1415    input->xkb.shift_mask =
1416      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_SHIFT);
1417    input->xkb.win_mask =
1418      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_LOGO);
1419    input->xkb.scroll_mask =
1420      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_SCROLL);
1421    input->xkb.num_mask =
1422      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_NUM);
1423    input->xkb.caps_mask =
1424      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CAPS);
1425    input->xkb.altgr_mask =
1426      1 << xkb_map_mod_get_index(input->xkb.keymap, "ISO_Level3_Shift");
1427 }
1428
1429 static void
1430 _keyboard_cb_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED)
1431 {
1432    Ecore_Wl2_Input *input;
1433    Ecore_Wl2_Window *window;
1434
1435    input = data;
1436    if (!input) return;
1437
1438    input->display->serial = serial;
1439
1440    if (!input->timestamp)
1441      {
1442         struct timeval tv;
1443
1444         gettimeofday(&tv, NULL);
1445         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
1446      }
1447
1448    /* find the window which this surface belongs to */
1449    window = _ecore_wl2_display_window_surface_find(input->display, surface);
1450    if (!window) return;
1451
1452    input->focus.keyboard = window;
1453    _ecore_wl2_input_focus_in_send(window, input);
1454 }
1455
1456 static void
1457 _keyboard_cb_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
1458 {
1459    Ecore_Wl2_Input *input;
1460    Ecore_Wl2_Window *window;
1461
1462    input = data;
1463    if (!input) return;
1464
1465    input->display->serial = serial;
1466
1467 // TIZEN_ONLY(20160615): Fix key repeat logic. 
1468 /*
1469    input->repeat.sym = 0;
1470    input->repeat.key = 0;
1471    input->repeat.time = 0;
1472    if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1473    input->repeat.timer = NULL;
1474 */
1475 //
1476    window = _ecore_wl2_display_window_surface_find(input->display, surface);
1477    if (window)
1478      {
1479         if (input->focus.keyboard != window)
1480           ERR("Received keyboard.leave when keyboard did not have enter");
1481      }
1482    input->focus.keyboard = NULL;
1483    if (window)
1484      _ecore_wl2_input_focus_out_send(window, input);
1485 }
1486
1487 static Eina_Bool
1488 _keyboard_cb_repeat(void *data)
1489 {
1490    Ecore_Wl2_Input *input;
1491
1492    input = data;
1493    if (!input || !input->repeat.timer) return ECORE_CALLBACK_CANCEL;
1494
1495    if (!input->repeat.repeating)
1496      {
1497         //A bit slow...
1498         double cur_time = ecore_time_get();
1499         if (cur_time > input->repeat.intime)
1500           {
1501              input->repeat.intime = cur_time + (cur_time - input->repeat.intime) + 0.0166;
1502              ecore_timer_interval_set(input->repeat.timer, input->repeat.intime - cur_time);
1503              return ECORE_CALLBACK_RENEW;
1504           }
1505
1506         if (input->repeat.key == 105 || input->repeat.key == 106 ) // Left:105 Right:106
1507           ecore_timer_interval_set(input->repeat.timer, input->repeat.horizontal.rate);
1508         else if (input->repeat.key == 103 || input->repeat.key == 108)  // UP:103 Down:108
1509           ecore_timer_interval_set(input->repeat.timer, input->repeat.vertical.rate);
1510         else
1511           ecore_timer_interval_set(input->repeat.timer, input->repeat.rate);
1512
1513         input->repeat.repeating = EINA_TRUE;
1514      }
1515
1516    if (input->repeat.key == 105 || input->repeat.key == 106 )
1517      input->repeat.time += (int)(input->repeat.horizontal.rate * 1000.0);
1518    else if (input->repeat.key == 103 || input->repeat.key == 108)
1519     input->repeat.time += (int)(input->repeat.vertical.rate * 1000.0);
1520    else
1521     input->repeat.time += (int)(input->repeat.rate * 1000.0);
1522
1523    _ecore_wl2_input_key_send(input, input->repeat_win,
1524                              input->repeat.sym, input->repeat.sym_name,
1525                              input->repeat.key + 8,
1526                              WL_KEYBOARD_KEY_STATE_PRESSED,
1527                              input->repeat.time, EINA_FALSE, EINA_TRUE);
1528
1529    return ECORE_CALLBACK_RENEW;
1530 }
1531
1532 /* from weston/clients/window.c */
1533 /* Translate symbols appropriately if a compose sequence is being entered */
1534 static xkb_keysym_t
1535 process_key_press(xkb_keysym_t sym, Ecore_Wl2_Input *input)
1536 {
1537    if (!input->xkb.compose_state)
1538      return sym;
1539    if (sym == XKB_KEY_NoSymbol)
1540      return sym;
1541    if (xkb_compose_state_feed(input->xkb.compose_state, sym) !=
1542        XKB_COMPOSE_FEED_ACCEPTED)
1543      return sym;
1544
1545    switch (xkb_compose_state_get_status(input->xkb.compose_state))
1546      {
1547       case XKB_COMPOSE_COMPOSING:
1548         return XKB_KEY_NoSymbol;
1549       case XKB_COMPOSE_COMPOSED:
1550         return xkb_compose_state_get_one_sym(input->xkb.compose_state);
1551       case XKB_COMPOSE_CANCELLED:
1552         return XKB_KEY_NoSymbol;
1553       case XKB_COMPOSE_NOTHING:
1554       default: break;
1555      }
1556    return sym;
1557 }
1558
1559 static void
1560 _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state)
1561 {
1562    Ecore_Wl2_Input *input;
1563    Ecore_Wl2_Window *window;
1564    unsigned int code;
1565    xkb_keysym_t sym = XKB_KEY_NoSymbol, sym_name = XKB_KEY_NoSymbol;
1566    const xkb_keysym_t *syms;
1567    // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1568    struct wl_surface *surface = NULL;
1569    //
1570    static Eina_Bool _key_event_cancel = EINA_FALSE;
1571
1572    input = data;
1573    if (!input) return;
1574
1575 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1576    if (input->key_win)
1577      {
1578         window = input->key_win;
1579      }
1580    else if ((input->repeat.key) && (keycode == input->repeat.key))
1581      {
1582         window = input->repeat_win;
1583      }
1584    else
1585 //
1586       window = input->focus.keyboard; /* try to get the window which has keyboard focus */
1587
1588    input->display->serial = serial;
1589    input->timestamp = timestamp;
1590
1591    /* xkb rules reflect X broken keycodes, so offset by 8 */
1592    code = keycode + 8;
1593
1594    // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1595    if (!window)
1596      {
1597         INF("window is not focused");
1598         surface = (struct wl_surface *) eina_hash_find(_ecore_wl2_keygrab_hash_get(), &code);
1599         if (surface)
1600           {
1601              window = ecore_wl2_window_surface_find(surface);
1602              INF("keycode(%d) is grabbed in the window(%p)", code, window);
1603           }
1604         else
1605           {
1606              //key event callback can be called even though surface is not exist.
1607              //TODO: Ecore_Event_Key have event_window info, so if (surface == NULL), we should generate proper window info
1608              INF("surface is not exist");
1609           }
1610      }
1611    //
1612    //
1613 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
1614    if (_tizen_api_version == 0.0) _ecore_wl2_input_key_conversion_set(input);
1615
1616 // if it is one of the back/menu/home key and _tizen_api_version is less than 2.4.
1617    if (0.0 < _tizen_api_version && _tizen_api_version < 2.4)
1618       code = _ecore_wl2_input_convert_old_keys(code);
1619 //
1620
1621    //TIZEN_ONLY(20200408): add debug
1622    ERR("Key[%d] event occurs %u", code, timestamp);
1623    //
1624
1625    if (xkb_state_key_get_syms(input->xkb.state, code, &syms) == 1)
1626      sym = syms[0];
1627    if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1628      sym = process_key_press(sym, input);
1629    sym_name = xkb_state_key_get_one_sym(input->xkb.maskless_state, code);
1630
1631 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1632    if (input->key_win) input->key_win = NULL;
1633 //
1634    if (sym == XKB_KEY_Cancel)
1635      {
1636         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1637           _key_event_cancel = EINA_TRUE;
1638         else
1639           _key_event_cancel = EINA_FALSE;
1640      }
1641    else
1642      {
1643         _ecore_wl2_input_key_send(input, window, sym, sym_name, code,
1644                                   state, timestamp, _key_event_cancel, EINA_FALSE);
1645
1646         if (!xkb_keymap_key_repeats(input->xkb.keymap, code)) return;
1647
1648         if ((state == WL_KEYBOARD_KEY_STATE_RELEASED) &&
1649             (keycode == input->repeat.key))
1650           {
1651              input->repeat.sym = 0;
1652              input->repeat.key = 0;
1653              input->repeat.time = 0;
1654              if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1655              input->repeat.timer = NULL;
1656              // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1657              input->repeat_win = NULL;
1658              //
1659           }
1660         else if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1661           {
1662              /* don't setup key repeat timer if not enabled */
1663              if (!input->repeat.enabled) return;
1664
1665              input->repeat.sym = sym;
1666              input->repeat.sym_name = sym;
1667              input->repeat.key = keycode;
1668              input->repeat.time = timestamp;
1669              // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1670              input->repeat_win = window;
1671              //
1672
1673              /* Delete this timer if there is still one */
1674              if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1675              input->repeat.timer = NULL;
1676
1677              if (!input->repeat.timer)
1678                {
1679                   input->repeat.repeating = EINA_FALSE;
1680                   if (keycode == 105 || keycode == 106 )
1681                     {
1682                        input->repeat.timer = ecore_timer_add(input->repeat.horizontal.delay, _keyboard_cb_repeat, input);
1683                        input->repeat.intime = (ecore_time_get() + input->repeat.horizontal.delay + 0.0166);
1684                     }
1685                   else if (keycode == 103 || keycode == 108)
1686                     {
1687                        input->repeat.timer = ecore_timer_add(input->repeat.vertical.delay, _keyboard_cb_repeat, input);
1688                        input->repeat.intime = (ecore_time_get() + input->repeat.vertical.delay + 0.0166);
1689                     }
1690                   else
1691                     {
1692                        input->repeat.timer = ecore_timer_add(input->repeat.delay, _keyboard_cb_repeat, input);
1693                        input->repeat.intime = (ecore_time_get() + input->repeat.delay + 0.0166);
1694                     }
1695                }
1696           }
1697      }
1698 }
1699
1700 static void
1701 _keyboard_cb_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group)
1702 {
1703    Ecore_Wl2_Input *input;
1704    xkb_mod_mask_t mask;
1705
1706    input = data;
1707    if (!input) return;
1708
1709    /* skip PC style modifiers if we have no keymap */
1710    if (!input->xkb.keymap) return;
1711
1712    xkb_state_update_mask(input->xkb.state,
1713                          depressed, latched, locked, 0, 0, group);
1714
1715    mask =
1716      xkb_state_serialize_mods(input->xkb.state,
1717                               XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
1718
1719    /* reset modifiers to default */
1720    input->keyboard.modifiers = 0;
1721
1722    if (mask & input->xkb.control_mask)
1723      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CTRL;
1724    if (mask & input->xkb.alt_mask)
1725      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALT;
1726    if (mask & input->xkb.shift_mask)
1727      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
1728    if (mask & input->xkb.win_mask)
1729      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_WIN;
1730    if (mask & input->xkb.altgr_mask)
1731      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
1732    if (mask & input->xkb.scroll_mask)
1733      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SCROLL;
1734    if (mask & input->xkb.num_mask)
1735      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_NUM;
1736    if (mask & input->xkb.caps_mask)
1737      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CAPS;
1738
1739
1740    mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_LOCKED);
1741    if (mask & input->xkb.scroll_mask)
1742      input->keyboard.modifiers |= ECORE_EVENT_LOCK_SCROLL;
1743    if (mask & input->xkb.num_mask)
1744      input->keyboard.modifiers |= ECORE_EVENT_LOCK_NUM;
1745    if (mask & input->xkb.caps_mask)
1746      input->keyboard.modifiers |= ECORE_EVENT_LOCK_CAPS;
1747 }
1748
1749 static void
1750 _keyboard_cb_repeat_setup(void *data, struct wl_keyboard *keyboard EINA_UNUSED, int32_t rate, int32_t delay)
1751 {
1752    Ecore_Wl2_Input *input;
1753    Ecore_Wl2_Event_Seat_Keyboard_Repeat_Changed *ev;
1754
1755    input = data;
1756    if (!input) return;
1757
1758    if (rate == 0)
1759      {
1760         input->repeat.enabled = EINA_FALSE;
1761         return;
1762      }
1763
1764    input->repeat.enabled = EINA_TRUE;
1765    if (!input->repeat.changed)
1766      {
1767         //TIZEN_ONLY(20200128): Tizen calculates rate differently.
1768         //input->repeat.rate = (1.0 / rate);
1769         //
1770         input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = (rate / 1000.0);
1771         input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = (delay / 1000.0);
1772      }
1773    ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1774    if (ev)
1775      {
1776         ev->id = input->id;
1777         ev->display = input->display;
1778         ev->display->refs++;
1779         ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYBOARD_REPEAT_CHANGED, ev,
1780                         _display_event_free, ev->display);
1781      }
1782 }
1783
1784 static const struct wl_keyboard_listener _keyboard_listener =
1785 {
1786    _keyboard_cb_keymap,
1787    _keyboard_cb_enter,
1788    _keyboard_cb_leave,
1789    _keyboard_cb_key,
1790    _keyboard_cb_modifiers,
1791    _keyboard_cb_repeat_setup
1792 };
1793
1794 static void
1795 _touch_cb_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface, int id, wl_fixed_t x, wl_fixed_t y)
1796 {
1797    Ecore_Wl2_Input *input;
1798    Ecore_Wl2_Window *window;
1799
1800    input = data;
1801    //TIZEN_ONLY(20200408): add debug
1802    if (!input)
1803      {
1804         ERR("input is NULL");
1805         return;
1806      }
1807    //
1808    /* find the window which this surface belongs to */
1809    window = _ecore_wl2_display_window_surface_find(input->display, surface);
1810    //TIZEN_ONLY(20200408): add debug
1811    if (!window)
1812      {
1813         ERR("window is NULL");
1814         return;
1815      }
1816    //
1817
1818    input->focus.touch = window;
1819    input->timestamp = timestamp;
1820    input->grab.touch_count++;
1821    //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1822    input->grab.touch_array[id] = EINA_TRUE;
1823    //
1824
1825    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1826    _ecore_wl2_input_touch_axis_process(input, id);
1827    //
1828
1829    // TIZEN_ONLY(20171207): do not send pointer enter about all of touch down
1830    #if 0
1831     _pointer_cb_enter(data, NULL, serial, surface, x, y);
1832    #else
1833
1834    input->grab.count++;
1835
1836    if ((!input->grab.window) && (input->focus.touch) && input->grab.touch_count == 1)
1837      {
1838         _pointer_cb_enter(data, NULL, serial, surface, x, y);
1839         _ecore_wl2_input_grab(input, input->focus.touch, BTN_LEFT);
1840         input->grab.timestamp = timestamp;
1841      }
1842    else
1843      {
1844         input->pointer.sx = wl_fixed_to_double(x);
1845         input->pointer.sy = wl_fixed_to_double(y);
1846      }
1847    #endif
1848    //
1849
1850 // TIZEN_ONLY(20171107): always send move event when touch down event is occurred
1851    _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1852 //
1853    _ecore_wl2_input_mouse_down_send(input, input->focus.touch, id,
1854                                     BTN_LEFT, timestamp);
1855 }
1856
1857 static void
1858 _touch_cb_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id)
1859 {
1860    Ecore_Wl2_Input *input;
1861
1862    //TIZEN_ONLY(20200408): add debug
1863    //if (!input) return;
1864    //EINA_SAFETY_ON_NULL_RETURN(input->focus.touch); //if this is happening, then we are getting up events in a invalid state
1865    input = data;
1866    if (!input)
1867      {
1868         ERR("input is NULL");
1869         return;
1870      }
1871    if (!input->focus.touch)
1872      {
1873         ERR("touch_focus is false");
1874         return;
1875      }
1876    //
1877    input->timestamp = timestamp;
1878    input->display->serial = serial;
1879
1880    _ecore_wl2_input_mouse_up_send(input, input->focus.touch, id,
1881                                   BTN_LEFT, timestamp);
1882
1883    if (input->grab.count) input->grab.count--;
1884    //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1885    if (input->grab.touch_array[id] && input->grab.touch_count) input->grab.touch_count--;
1886    if (input->grab.touch_array[id]) input->grab.touch_array[id] = EINA_FALSE;
1887    //
1888    if ((input->grab.window) && (input->grab.button == BTN_LEFT) &&
1889        (!input->grab.count) && !input->grab.touch_count)
1890      _ecore_wl2_input_ungrab(input);
1891
1892    if (input->grab.touch_count == 0) input->focus.touch = NULL;
1893
1894 }
1895
1896 static void
1897 _touch_cb_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id, wl_fixed_t x, wl_fixed_t y)
1898 {
1899    Ecore_Wl2_Input *input;
1900
1901    input = data;
1902    //TIZEN_ONLY(20200408): add debug
1903    //if (!input) return;
1904    //if (!input->focus.touch) return;
1905    if (!input)
1906      {
1907         ERR("input is NULL");
1908         return;
1909      }
1910    if (!input->focus.touch)
1911      {
1912         ERR("touch_focus is false");
1913         return;
1914      }
1915    //
1916    input->timestamp = timestamp;
1917    input->pointer.sx = wl_fixed_to_int(x);
1918    input->pointer.sy = wl_fixed_to_int(y);
1919
1920    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1921    _ecore_wl2_input_touch_axis_process(input, id);
1922    //
1923
1924    _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1925 }
1926
1927 static void
1928 _touch_cb_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED)
1929 {
1930
1931 }
1932
1933 static void
1934 _touch_cb_cancel(void *data, struct wl_touch *touch EINA_UNUSED)
1935 {
1936 //TIZEN_ONLY(20171107): generate mouse button cancel event
1937    Ecore_Event_Mouse_Button *ev;
1938    Ecore_Wl2_Input *input;
1939
1940    if (!(input = data)) return;
1941    if (!input->focus.touch) return;
1942
1943    if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
1944    EINA_SAFETY_ON_NULL_RETURN(ev);
1945
1946    ev->timestamp = _timestamp_get();
1947    ev->same_screen = 1;
1948    ev->window = input->focus.touch->id;
1949    ev->event_window = ev->window;
1950
1951    ev->buttons = 1;
1952
1953    ev->root.x = input->pointer.sx;
1954    ev->root.y = input->pointer.sy;
1955    ev->x = input->pointer.sx;
1956    ev->y = input->pointer.sy;
1957    ev->modifiers = input->keyboard.modifiers;
1958
1959    ev->dev = _ecore_wl2_touch_dev_get(input, ev->window);
1960
1961    //TIZEN_ONLY(20200408): add debug
1962    ERR("[cancel] time=%u window=0x%x", ev->timestamp, ev->window);
1963    //
1964
1965    //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1966    for (int i = 0; i < ECORE_WL2_TOUCH_MAX; i++)
1967      input->grab.touch_array[i] = EINA_FALSE;
1968    input->focus.touch = NULL;
1969    input->grab.count = 0;
1970    _ecore_wl2_input_ungrab(input);
1971    //
1972
1973    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, NULL, _input_event_mouse_button_cb_free);
1974 //
1975 }
1976
1977 static const struct wl_touch_listener _touch_listener =
1978 {
1979    _touch_cb_down,
1980    _touch_cb_up,
1981    _touch_cb_motion,
1982    _touch_cb_frame,
1983    _touch_cb_cancel,
1984    NULL, // XXX: FIXME: add shape
1985    NULL, // XXX: FIXME: add orientation
1986 };
1987
1988 static void
1989 _data_cb_offer(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
1990 {
1991    Ecore_Wl2_Input *input;
1992
1993    input = data;
1994    if (!input) return;
1995
1996    _ecore_wl2_dnd_add(input, offer);
1997 }
1998
1999 static void
2000 _data_cb_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer)
2001 {
2002    Ecore_Wl2_Input *input;
2003
2004    input = data;
2005    if (!input) return;
2006
2007    _ecore_wl2_dnd_enter(input, offer, surface,
2008                         wl_fixed_to_int(x), wl_fixed_to_int(y), serial);
2009 }
2010
2011 static void
2012 _data_cb_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
2013 {
2014    Ecore_Wl2_Input *input;
2015
2016    input = data;
2017    if (!input) return;
2018
2019    _ecore_wl2_dnd_leave(input);
2020 }
2021
2022 static void
2023 _data_cb_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, wl_fixed_t x, wl_fixed_t y)
2024 {
2025    Ecore_Wl2_Input *input;
2026
2027    input = data;
2028    if (!input) return;
2029
2030    _ecore_wl2_dnd_motion(input, wl_fixed_to_int(x),
2031                          wl_fixed_to_int(y), serial);
2032 }
2033
2034 static void
2035 _data_cb_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
2036 {
2037    Ecore_Wl2_Input *input;
2038
2039    input = data;
2040    if (!input) return;
2041
2042    _ecore_wl2_dnd_drop(input);
2043 }
2044
2045 static void
2046 _data_cb_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
2047 {
2048    Ecore_Wl2_Input *input;
2049
2050    input = data;
2051    if (!input) return;
2052
2053    _ecore_wl2_dnd_selection(input, offer);
2054 }
2055
2056 static const struct wl_data_device_listener _data_listener =
2057 {
2058    _data_cb_offer,
2059    _data_cb_enter,
2060    _data_cb_leave,
2061    _data_cb_motion,
2062    _data_cb_drop,
2063    _data_cb_selection
2064 };
2065
2066 static void
2067 _seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
2068 {
2069    Ecore_Wl2_Event_Seat_Capabilities *ev;
2070    Ecore_Wl2_Input *input;
2071
2072    input = data;
2073    if (!input) return;
2074
2075    if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->wl.pointer))
2076      {
2077         input->wl.pointer = wl_seat_get_pointer(seat);
2078         wl_pointer_set_user_data(input->wl.pointer, input);
2079         wl_pointer_add_listener(input->wl.pointer, &_pointer_listener, input);
2080
2081         // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
2082         if (input->display->wl.relative_pointer_manager)
2083           {
2084              input->wl.relative_pointer =
2085                zwp_relative_pointer_manager_v1_get_relative_pointer(
2086                     input->display->wl.relative_pointer_manager, input->wl.pointer);
2087              zwp_relative_pointer_v1_add_listener(input->wl.relative_pointer,
2088                                                   &_relative_pointer_listener, input);
2089           }
2090         //
2091
2092         // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2093         if (!input->cursor.surface)
2094           {
2095              input->cursor.surface =
2096                wl_compositor_create_surface(input->display->wl.compositor);
2097
2098              if (input->cursor.surface)
2099                {
2100                   if (input->display->wl.tz_policy)
2101                     {
2102                        tizen_policy_set_role(input->display->wl.tz_policy,
2103                                              input->cursor.surface, "wl_pointer-cursor");
2104                     }
2105                }
2106           }
2107         if (!input->cursor.theme)
2108           {
2109              input->cursor.theme =
2110                wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size,
2111                                     input->display->wl.shm);
2112           }
2113         //
2114      }
2115    else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer))
2116      {
2117         // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2118         if (input->cursor.surface) wl_surface_destroy(input->cursor.surface);
2119         input->cursor.surface = NULL;
2120         if (input->cursor.theme)
2121           wl_cursor_theme_destroy(input->cursor.theme);
2122         input->cursor.theme = NULL;
2123         //
2124 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
2125         if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
2126           wl_pointer_release(input->wl.pointer);
2127         else
2128 #endif
2129           wl_pointer_destroy(input->wl.pointer);
2130         input->wl.pointer = NULL;
2131      }
2132
2133    if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->wl.keyboard))
2134      {
2135         input->wl.keyboard = wl_seat_get_keyboard(seat);
2136         wl_keyboard_set_user_data(input->wl.keyboard, input);
2137         wl_keyboard_add_listener(input->wl.keyboard, &_keyboard_listener, input);
2138      }
2139    else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->wl.keyboard))
2140      {
2141 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
2142         if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
2143           wl_keyboard_release(input->wl.keyboard);
2144         else
2145 #endif
2146           wl_keyboard_destroy(input->wl.keyboard);
2147         input->wl.keyboard = NULL;
2148      }
2149
2150    if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->wl.touch))
2151      {
2152         input->wl.touch = wl_seat_get_touch(seat);
2153         wl_touch_set_user_data(input->wl.touch, input);
2154         wl_touch_add_listener(input->wl.touch, &_touch_listener, input);
2155      }
2156    else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->wl.touch))
2157      {
2158 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
2159         if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
2160           wl_touch_release(input->wl.touch);
2161         else
2162 #endif
2163           wl_touch_destroy(input->wl.touch);
2164         input->wl.touch = NULL;
2165 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
2166         _ecore_wl2_input_key_conversion_clean_up();
2167 //
2168      }
2169    ecore_wl2_display_flush(input->display);
2170
2171 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
2172    input->caps_update = EINA_TRUE;
2173 //
2174
2175    ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Capabilities));
2176    EINA_SAFETY_ON_NULL_RETURN(ev);
2177
2178    ev->id = input->id;
2179    ev->pointer_enabled = !!(caps & WL_SEAT_CAPABILITY_POINTER);
2180    ev->keyboard_enabled = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD);
2181    ev->touch_enabled = !!(caps & WL_SEAT_CAPABILITY_TOUCH);
2182    ev->display = input->display;
2183    ev->display->refs++;
2184
2185    ecore_event_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED, ev,
2186                    _display_event_free, ev->display);
2187 }
2188
2189 static void
2190 _cb_seat_event_free(void *data EINA_UNUSED, void *event)
2191 {
2192    Ecore_Wl2_Event_Seat_Name *ev;
2193
2194    ev = event;
2195    eina_stringshare_del(ev->name);
2196    ecore_wl2_display_disconnect(ev->display);
2197    free(ev);
2198 }
2199
2200 static void
2201 _seat_cb_name(void *data, struct wl_seat *seat EINA_UNUSED, const char *name)
2202 {
2203    Ecore_Wl2_Event_Seat_Name *ev;
2204    Ecore_Wl2_Input *input;
2205
2206    input = data;
2207    eina_stringshare_replace(&input->name, name);
2208
2209    ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Name));
2210    EINA_SAFETY_ON_NULL_RETURN(ev);
2211
2212    ev->id = input->id;
2213    ev->name = eina_stringshare_add(name);
2214    ev->display = input->display;
2215    ev->display->refs++;
2216
2217    ecore_event_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED, ev,
2218                    _cb_seat_event_free, NULL);
2219 }
2220
2221 static const struct wl_seat_listener _seat_listener =
2222 {
2223    _seat_cb_capabilities,
2224    _seat_cb_name,
2225 };
2226
2227 static void
2228 _ecore_wl2_input_cursor_setup(Ecore_Wl2_Input *input)
2229 {
2230    char *tmp;
2231    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2232    #if 0
2233    input->cursor.size = 32;
2234    tmp = getenv("ECORE_WL_CURSOR_SIZE");
2235    if (tmp) input->cursor.size = atoi(tmp);
2236
2237    if (!input->cursor.name)
2238      input->cursor.name = eina_stringshare_add("left_ptr");
2239    #else
2240    unsigned int cursor_size;
2241    char *cursor_theme_name;
2242
2243    tmp = getenv("ECORE_WL_CURSOR_SIZE");
2244    if (tmp)
2245      cursor_size = atoi(tmp);
2246    else
2247      cursor_size = 32;
2248    ecore_wl2_input_cursor_size_set(input, cursor_size);
2249
2250    cursor_theme_name = getenv("ECORE_WL_CURSOR_THEME_NAME");
2251    ecore_wl2_input_cursor_theme_name_set(input, cursor_theme_name);
2252
2253    // TIZEN_ONLY(20230330): support client that requests to unset cursor
2254    if (!input->cursor.name)
2255      input->cursor.name = eina_stringshare_add("left_ptr");
2256    //
2257    #endif
2258    //
2259 }
2260
2261 // TIZEN_ONLY(20200219): cleanup cursor resources when a Ecore_Wl2_Input is destroy
2262 static void
2263 _ecore_wl2_input_cursor_cleanup(Ecore_Wl2_Input *input)
2264 {
2265    /* If remove a cursor in this step,
2266     * it maybe occurred blink cursor so check this first
2267     */
2268    // if (input->cursor.surface)
2269      // ecore_wl2_input_pointer_set(input, NULL, 0, 0);
2270
2271    if (input->cursor.theme)
2272      wl_cursor_theme_destroy(input->cursor.theme);
2273    if (input->cursor.theme_name)
2274      eina_stringshare_del(input->cursor.theme_name);
2275 }
2276 //
2277
2278 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2279 static const struct wl_callback_listener _pointer_surface_listener =
2280 {
2281    _cb_pointer_frame
2282 };
2283
2284 static void
2285 _cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED)
2286 {
2287    Ecore_Wl2_Input *input;
2288
2289    if (!(input = data)) return;
2290
2291    if (callback)
2292      {
2293         if (callback != input->cursor.frame_cb) return;
2294         wl_callback_destroy(callback);
2295         input->cursor.frame_cb = NULL;
2296      }
2297
2298    if (!input->cursor.name)
2299      {
2300         ecore_wl2_input_pointer_set(input, NULL, 0, 0);
2301         return;
2302      }
2303
2304    if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb))
2305      {
2306         input->cursor.frame_cb = wl_surface_frame(input->cursor.surface);
2307         if (!input->cursor.frame_cb) return;
2308
2309         wl_callback_add_listener(input->cursor.frame_cb,
2310                                  &_pointer_surface_listener, input);
2311      }
2312 }
2313 //
2314
2315 Eina_Bool
2316 _ecore_wl2_input_cursor_update(void *data)
2317 {
2318    Ecore_Wl2_Input *input;
2319
2320    input = data;
2321    if (!input) return EINA_FALSE;
2322
2323    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2324    #if 0
2325    if (input->wl.pointer)
2326      wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
2327                            input->cursor.surface,
2328                            input->cursor.hot_x, input->cursor.hot_y);
2329    ecore_wl2_display_flush(input->display);
2330
2331    return ECORE_CALLBACK_RENEW;
2332    #else
2333    struct wl_cursor_image *cursor_image;
2334    struct wl_buffer *buffer;
2335    unsigned int delay;
2336
2337    if ((!input) || (!input->cursor.cursor) || (!input->cursor.surface))
2338      return EINA_FALSE;
2339
2340    cursor_image = input->cursor.cursor->images[input->cursor.current_index];
2341    if (!cursor_image) return ECORE_CALLBACK_RENEW;
2342
2343    if ((buffer = wl_cursor_image_get_buffer(cursor_image)))
2344      {
2345         ecore_wl2_input_pointer_set(input, input->cursor.surface,
2346                                    cursor_image->hotspot_x,
2347                                    cursor_image->hotspot_y);
2348         wl_surface_attach(input->cursor.surface, buffer, 0, 0);
2349         wl_surface_damage(input->cursor.surface, 0, 0,
2350                           cursor_image->width, cursor_image->height);
2351         wl_surface_commit(input->cursor.surface);
2352
2353         if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb))
2354           _cb_pointer_frame(input, NULL, 0);
2355      }
2356
2357    if (input->cursor.cursor->image_count <= 1)
2358      return ECORE_CALLBACK_CANCEL;
2359
2360    delay = cursor_image->delay;
2361    input->cursor.current_index =
2362       (input->cursor.current_index + 1) % input->cursor.cursor->image_count;
2363
2364    if (!input->cursor.timer)
2365      input->cursor.timer =
2366         ecore_timer_loop_add(delay / 1000.0,
2367                              _ecore_wl2_input_cursor_update, input);
2368    else
2369      ecore_timer_interval_set(input->cursor.timer, delay / 1000.0);
2370
2371    return ECORE_CALLBACK_RENEW;
2372    #endif
2373    //
2374 }
2375
2376 static void
2377 _ecore_wl2_devices_free(Ecore_Wl2_Input_Devices *devices)
2378 {
2379    if (devices->seat_dev)
2380      efl_unref(devices->seat_dev);
2381    if (devices->pointer_dev)
2382      efl_unref(devices->pointer_dev);
2383    if (devices->keyboard_dev)
2384      efl_unref(devices->keyboard_dev);
2385    if (devices->touch_dev)
2386      efl_unref(devices->touch_dev);
2387
2388    free(devices);
2389 }
2390
2391 static Eina_Bool
2392 _ecore_wl2_cb_device_event(void *data, int type, void *event)
2393 {
2394    Ecore_Wl2_Input_Devices *devs, *devices = NULL;;
2395    Ecore_Wl2_Event_Device *ev = event;
2396    Ecore_Wl2_Input *input = data;
2397    Eina_List *l;
2398
2399    if (input->id != ev->seat_id)
2400      return ECORE_CALLBACK_PASS_ON;
2401
2402    EINA_LIST_FOREACH(input->devices_list, l, devs)
2403      {
2404         if (devs->window_id == ev->window_id)
2405           {
2406              devices = devs;
2407              break;
2408           }
2409      }
2410
2411    if (type == ECORE_WL2_EVENT_DEVICE_ADDED)
2412      {
2413         if (!devices)
2414           {
2415              devices = calloc(1, sizeof(Ecore_Wl2_Input_Devices));
2416              EINA_SAFETY_ON_NULL_RETURN_VAL(devices, ECORE_CALLBACK_PASS_ON);
2417              input->devices_list =
2418                eina_list_append(input->devices_list, devices);
2419              devices->window_id = ev->window_id;
2420           }
2421
2422         if (ev->type == ECORE_WL2_DEVICE_TYPE_POINTER)
2423           devices->pointer_dev = efl_ref(ev->dev);
2424         else if (ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD)
2425           devices->keyboard_dev = efl_ref(ev->dev);
2426         else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH)
2427           devices->touch_dev = efl_ref(ev->dev);
2428         else if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
2429           devices->seat_dev = efl_ref(ev->dev);
2430
2431         return ECORE_CALLBACK_PASS_ON;
2432      }
2433
2434    if (!devices)
2435      return ECORE_CALLBACK_PASS_ON;
2436
2437    if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
2438      {
2439         input->devices_list =
2440           eina_list_remove(input->devices_list, devices);
2441         _ecore_wl2_devices_free(devices);
2442         return ECORE_CALLBACK_PASS_ON;
2443      }
2444
2445    if ((ev->type == ECORE_WL2_DEVICE_TYPE_POINTER) &&
2446        (devices->pointer_dev == ev->dev))
2447      {
2448         efl_unref(devices->pointer_dev);
2449         devices->pointer_dev = NULL;
2450      }
2451    else if ((ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD) &&
2452             (devices->keyboard_dev == ev->dev))
2453      {
2454         efl_unref(devices->keyboard_dev);
2455         devices->keyboard_dev = NULL;
2456      }
2457    else if ((ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH) &&
2458             (devices->touch_dev == ev->dev))
2459      {
2460         efl_unref(devices->touch_dev);
2461         devices->touch_dev = NULL;
2462      }
2463
2464    return ECORE_CALLBACK_PASS_ON;
2465 }
2466
2467 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
2468 static void
2469 _ecore_wl2_input_device_last_device_set(Ecore_Wl2_Tizen_Input_Device *dev)
2470 {
2471    Ecore_Wl2_Input *input = dev->input;
2472
2473    if (!input) return;
2474
2475    switch(dev->clas)
2476      {
2477       case ECORE_DEVICE_CLASS_MOUSE:
2478          input->devmgr.last_device_ptr = dev;
2479          break;
2480       case ECORE_DEVICE_CLASS_KEYBOARD:
2481          input->devmgr.last_device_kbd = dev;
2482          break;
2483       case ECORE_DEVICE_CLASS_TOUCH:
2484          input->devmgr.last_device_touch = dev;
2485          break;
2486       default:
2487          break;
2488      }
2489 }
2490
2491 static void
2492 _ecore_wl2_input_device_last_device_unset(Ecore_Wl2_Tizen_Input_Device *dev)
2493 {
2494    Ecore_Wl2_Input *input = dev->input;
2495
2496    if (!input) return;
2497
2498    switch(dev->clas)
2499      {
2500       case ECORE_DEVICE_CLASS_MOUSE:
2501          if (input->devmgr.last_device_ptr == dev)
2502            input->devmgr.last_device_ptr = NULL;
2503          break;
2504       case ECORE_DEVICE_CLASS_KEYBOARD:
2505          if (input->devmgr.last_device_kbd == dev)
2506            input->devmgr.last_device_kbd = NULL;
2507          break;
2508       case ECORE_DEVICE_CLASS_TOUCH:
2509          if (input->devmgr.last_device_touch == dev)
2510            input->devmgr.last_device_touch = NULL;
2511          break;
2512       default:
2513          break;
2514      }
2515 }
2516 //
2517
2518 void
2519 _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int version)
2520 {
2521    Ecore_Wl2_Input *input;
2522
2523    input = calloc(1, sizeof(Ecore_Wl2_Input));
2524    if (!input) return;
2525
2526    input->id = id;
2527    input->display = display;
2528    input->seat_version = version;
2529    input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = 0.025;
2530    input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = 0.4;
2531    input->repeat.enabled = EINA_TRUE;
2532    input->repeat.changed = EINA_FALSE;
2533    input->want_lock_pointer = EINA_FALSE;
2534    input->pointer_locked = EINA_FALSE;
2535
2536    wl_array_init(&input->data.selection.types);
2537    wl_array_init(&input->data.drag.types);
2538
2539    /* setup cursor size and theme */
2540    _ecore_wl2_input_cursor_setup(input);
2541    _ecore_wl2_cursor_config_init();
2542
2543    input->wl.seat =
2544      wl_registry_bind(display->wl.registry, id, &wl_seat_interface, 4);
2545
2546    display->inputs =
2547      eina_inlist_append(display->inputs, EINA_INLIST_GET(input));
2548
2549    wl_seat_add_listener(input->wl.seat, &_seat_listener, input);
2550    wl_seat_set_user_data(input->wl.seat, input);
2551
2552    input->dev_add_handler =
2553      ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_ADDED,
2554                              _ecore_wl2_cb_device_event, input);
2555
2556    input->dev_remove_handler =
2557      ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_REMOVED,
2558                              _ecore_wl2_cb_device_event, input);
2559
2560    if (!display->wl.data_device_manager) return;
2561
2562    input->data.device =
2563      wl_data_device_manager_get_data_device(display->wl.data_device_manager,
2564                                             input->wl.seat);
2565    wl_data_device_add_listener(input->data.device, &_data_listener, input);
2566 }
2567
2568 void
2569 _ecore_wl2_input_del(Ecore_Wl2_Input *input)
2570 {
2571    Ecore_Wl2_Input_Devices *devices;
2572    Ecore_Wl2_Display *display;
2573    Eina_Inlist *l = NULL;
2574    Ecore_Wl2_Mouse_Down_Info *info = NULL;
2575    Ecore_Wl2_Window *window;
2576
2577    if (!input) return;
2578
2579    display = input->display;
2580
2581    l = _ecore_wl2_mouse_down_info_list;
2582    while (l)
2583      {
2584         info = EINA_INLIST_CONTAINER_GET(l, Ecore_Wl2_Mouse_Down_Info);
2585         l = eina_inlist_remove(l, l);
2586         free(info);
2587      }
2588    _ecore_wl2_mouse_down_info_list = NULL;
2589
2590    if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2591
2592    _ecore_wl2_cursor_config_shutdown();
2593
2594    if (input->cursor.name) eina_stringshare_del(input->cursor.name);
2595 // TIZEN_ONLY(20200219): cleanup cursor resources when a Ecore_Wl2_Input is destroy
2596    _ecore_wl2_input_cursor_cleanup(input);
2597 //
2598
2599    if (input->data.selection.types.data)
2600      {
2601         char **t;
2602
2603         wl_array_for_each(t, &input->data.selection.types)
2604           free(*t);
2605
2606         wl_array_release(&input->data.selection.types);
2607      }
2608    if (input->data.drag.types.data)
2609      {
2610         char **t;
2611
2612         wl_array_for_each(t, &input->data.drag.types)
2613           free(*t);
2614
2615         wl_array_release(&input->data.drag.types);
2616      }
2617
2618    if (input->data.selection.source)
2619      wl_data_source_destroy(input->data.selection.source);
2620    if (input->data.drag.source)
2621      wl_data_source_destroy(input->data.drag.source);
2622    if (input->drag.offer) _ecore_wl2_offer_unref(input->drag.offer);
2623    if (input->selection.offer) _ecore_wl2_offer_unref(input->selection.offer);
2624    if (input->data.device) wl_data_device_destroy(input->data.device);
2625
2626    if (input->xkb.state) xkb_state_unref(input->xkb.state);
2627    if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
2628    if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
2629    if (input->xkb.compose_table)
2630      xkb_compose_table_unref(input->xkb.compose_table);
2631    if (input->xkb.compose_state)
2632      xkb_compose_state_unref(input->xkb.compose_state);
2633
2634    if (input->wl.seat) wl_seat_destroy(input->wl.seat);
2635
2636    ecore_event_handler_del(input->dev_add_handler);
2637    ecore_event_handler_del(input->dev_remove_handler);
2638    EINA_LIST_FREE(input->devices_list, devices)
2639       _ecore_wl2_devices_free(devices);
2640
2641    display->inputs =
2642      eina_inlist_remove(display->inputs, EINA_INLIST_GET(input));
2643
2644    EINA_INLIST_FOREACH(display->windows, window)
2645      if (window->grab == input) window->grab = NULL;
2646
2647    eina_stringshare_replace(&input->name, NULL);
2648    free(input);
2649 }
2650
2651 void
2652 _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor)
2653 {
2654    eina_stringshare_replace(&input->cursor.name, cursor);
2655    if (!cursor) eina_stringshare_replace(&input->cursor.name, "left_ptr");
2656 }
2657
2658 void
2659 _ecore_wl2_input_window_remove(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
2660 {
2661    Ecore_Wl2_Input_Devices *devices;
2662    Eina_List *l, *l_next;
2663
2664    if ((input->focus.pointer) &&
2665        (input->focus.pointer == window))
2666      input->focus.pointer = NULL;
2667    if ((input->focus.keyboard) &&
2668        (input->focus.keyboard == window))
2669      input->focus.keyboard = NULL;
2670    //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
2671    if ((input->focus.touch) &&
2672        (input->focus.touch == window))
2673      {
2674         for (int i = 0; i < ECORE_WL2_TOUCH_MAX; i++)
2675           input->grab.touch_array[i] = EINA_FALSE;
2676         input->focus.touch = NULL;
2677         input->grab.count = 0;
2678         _ecore_wl2_input_ungrab(input);
2679      }
2680    //
2681    if ((input->repeat_win) &&
2682        (input->repeat_win == window))
2683      {
2684         if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2685         input->repeat.timer = NULL;
2686         input->repeat_win = NULL;
2687      }
2688
2689    EINA_LIST_FOREACH_SAFE(input->devices_list, l, l_next, devices)
2690       if (devices->window_id == window->id)
2691         {
2692            _ecore_wl2_devices_free(devices);
2693            input->devices_list = eina_list_remove_list(input->devices_list, l);
2694         }
2695 }
2696
2697 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
2698 static void
2699 _ecore_wl2_cb_keygrab_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t key, uint32_t mode, uint32_t error)
2700 {
2701    _ecore_wl2_keygrab_error = error;
2702    INF("[PID:%d] key=%d, mode=%d, error=%d", getpid(), key, mode, error);
2703 }
2704
2705 static void
2706 _ecore_wl2_cb_keygrab_notify_list(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, struct wl_array *grab_result)
2707 {
2708    wl_array_init(&_ecore_wl2_keygrab_result_list);
2709    wl_array_copy(&_ecore_wl2_keygrab_result_list, grab_result);
2710 }
2711
2712 static void
2713 _ecore_wl2_cb_getgrab_notify_list(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, struct wl_array *grab_result EINA_UNUSED)
2714 {
2715    ;
2716 }
2717
2718 static void
2719 _ecore_wl2_cb_set_register_none_key(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t mode EINA_UNUSED)
2720 {
2721    ;
2722 }
2723
2724 static void
2725 _ecore_wl2_cb_keyregister_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t status EINA_UNUSED)
2726 {
2727    ;
2728 }
2729
2730 static void
2731 _ecore_wl2_cb_set_input_config(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t status EINA_UNUSED)
2732 {
2733    ;
2734 }
2735
2736 static void
2737 _ecore_wl2_cb_key_cancel(void *data, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t key)
2738 {
2739    Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
2740    Ecore_Wl2_Input *input;
2741
2742    if (!ewd)
2743      {
2744         WRN("Failed to get Ecore_Wl2_Display\n");
2745         return;
2746      }
2747
2748    EINA_INLIST_FOREACH(ewd->inputs, input)
2749      {
2750         if (input->repeat.key == key)
2751           {
2752              input->repeat.sym = 0;
2753              input->repeat.key = 0;
2754              input->repeat.time = 0;
2755
2756              if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2757              input->repeat.timer = NULL;
2758           }
2759      }
2760 }
2761
2762 static void
2763 _ecore_wl2_cb_event_surface(void *data, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface, uint32_t key EINA_UNUSED, uint32_t mode)
2764 {
2765    Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
2766    Ecore_Wl2_Input *input;
2767
2768    if (!ewd)
2769      {
2770         WRN("Failed to get Ecore_Wl2_Display\n");
2771         return;
2772      }
2773
2774    EINA_INLIST_FOREACH(ewd->inputs, input)
2775      {
2776         input->key_win = ecore_wl2_window_surface_find(surface);
2777         input->key_mode = mode;
2778
2779         if(!input->key_win)
2780           {
2781              WRN("Get a event_surface(%p) but there was a no Ecore_Wl2_Window\n", surface);
2782           }
2783      }
2784 }
2785
2786 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
2787 static const struct tizen_keyrouter_listener _tz_keyrouter_listener =
2788 {
2789    _ecore_wl2_cb_keygrab_notify,
2790    _ecore_wl2_cb_keygrab_notify_list,
2791    _ecore_wl2_cb_getgrab_notify_list,
2792    _ecore_wl2_cb_set_register_none_key,
2793    _ecore_wl2_cb_keyregister_notify,
2794    _ecore_wl2_cb_set_input_config,
2795    _ecore_wl2_cb_key_cancel,
2796    _ecore_wl2_cb_event_surface
2797 };
2798 //
2799
2800 void
2801 _ecore_wl2_keyrouter_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version EINA_UNUSED)
2802 {
2803    ewd->wl.tz_keyrouter =
2804           wl_registry_bind(ewd->wl.registry, id, &tizen_keyrouter_interface, 2);
2805    if (ewd->wl.tz_keyrouter)
2806      tizen_keyrouter_add_listener(ewd->wl.tz_keyrouter, &_tz_keyrouter_listener, ewd);
2807 }
2808
2809 struct _Keycode_Map
2810 {
2811    xkb_keysym_t keysym;
2812    xkb_keycode_t *keycodes;
2813    int num_keycodes;
2814 };
2815
2816 typedef struct _Keycode_Map Keycode_Map;
2817
2818 static void find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2819 {
2820    Keycode_Map *found_keycodes = (Keycode_Map *)data;
2821    xkb_keysym_t keysym = found_keycodes->keysym;
2822    int num_syms = 0;
2823    const xkb_keysym_t *syms_out = NULL;
2824    num_syms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2825    if ((num_syms) && (syms_out))
2826      {
2827         if ((*syms_out) == (keysym))
2828           {
2829              found_keycodes->num_keycodes++;
2830              found_keycodes->keycodes = realloc(found_keycodes->keycodes, sizeof(int) * found_keycodes->num_keycodes);
2831              if (found_keycodes->keycodes)
2832                found_keycodes->keycodes[found_keycodes->num_keycodes - 1] = key;
2833           }
2834      }
2835 }
2836
2837 //If there are several keycodes, ecore_wl only deals with first keycode.
2838 int
2839 ecore_wl2_input_keycode_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym, xkb_keycode_t **keycodes)
2840 {
2841    Keycode_Map found_keycodes = {0,};
2842    found_keycodes.keysym = keysym;
2843
2844    //called fewer (max_keycode - min_keycode +1) times.
2845    xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2846
2847    *keycodes = found_keycodes.keycodes;
2848    INF("num of keycodes:%d ", found_keycodes.num_keycodes);
2849    return found_keycodes.num_keycodes;
2850 }
2851
2852 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
2853 //Currently this function is only used in sink call, so use global value(_ecore_wl_keygrab_error) and just check the error is ok.
2854 /* internal functions */
2855 static Eina_Bool
2856 _ecore_wl2_keygrab_hash_add(void *key, void *data)
2857 {
2858    Eina_Bool ret = EINA_FALSE;
2859
2860    if (!data) return ret;
2861    if (!_keygrabs)
2862      _keygrabs = eina_hash_int32_new(NULL);
2863    ret = eina_hash_add(_keygrabs, key, data);
2864    return ret;
2865 }
2866
2867 static Eina_Bool
2868 _ecore_wl2_keygrab_hash_del(void *key)
2869 {
2870    Eina_Bool ret = EINA_FALSE;
2871
2872    ret = eina_hash_del_by_key(_keygrabs, key);
2873
2874    return ret;
2875 }
2876
2877 Eina_Hash *
2878 _ecore_wl2_keygrab_hash_get(void)
2879 {
2880    return _keygrabs;
2881 }
2882
2883 static void
2884 _ecore_wl2_keygrab_error_set()
2885 {
2886    if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_INVALID_SURFACE)
2887      set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
2888    else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
2889      set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
2890    else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY)
2891      set_last_result(TIZEN_ERROR_ALREADY_IN_PROGRESS);
2892    else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
2893      set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
2894    else set_last_result(TIZEN_ERROR_NONE);
2895 }
2896
2897 //I'm not sure that keygrab function should be changed to Ecore_evas_XXX.
2898 //In the future, keyrouter feature can be added upstream or finish stabilizing.
2899 //After that time, we maybe change API name or other thing.
2900 //So do not use this API if you have trouble catch keyrouter feature or rule changes.
2901
2902 //Keyrouter support the situation when wl_win is not exist.
2903 //But keyrouter also can be meet situation when there are several surfaces.
2904 //So I decided to add keygrab feature into ecore_wl_window side like x system.
2905
2906 //Mod, not_mod, priority will be used future.
2907 //But now we are not support, so just use 0 for this parameter.
2908 //win can be NULL
2909
2910 EAPI Eina_Bool
2911 ecore_wl2_window_keygrab_set(Ecore_Wl2_Window *win, const char *key, int mod EINA_UNUSED, int not_mod EINA_UNUSED, int priority EINA_UNUSED, Ecore_Wl2_Window_Keygrab_Mode grab_mode)
2912 {
2913    Ecore_Wl2_Display *ewd;
2914    xkb_keysym_t keysym = 0x0;
2915    int num_keycodes = 0;
2916    xkb_keycode_t *keycodes = NULL;
2917    int i;
2918    Ecore_Wl2_Input *input;
2919
2920    Eina_Bool ret = EINA_FALSE;
2921    struct wl_surface *surface = NULL;
2922
2923    EINA_SAFETY_ON_NULL_GOTO(key, err);
2924    EINA_SAFETY_ON_TRUE_GOTO((grab_mode < ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN), err);
2925    EINA_SAFETY_ON_TRUE_GOTO((grab_mode > ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE), err);
2926
2927    if (win)
2928      ewd = win->display;
2929    else
2930      ewd = ecore_wl2_connected_display_get(NULL);
2931
2932    EINA_SAFETY_ON_NULL_GOTO(ewd, err);
2933
2934    while (!ewd->wl.tz_keyrouter)
2935      {
2936         INF("Wait until keyrouter interface is ready");
2937         wl_display_roundtrip(ewd->wl.display);
2938      }
2939
2940    INF("win=%p key=%s mod=%d", win, key, grab_mode);
2941
2942    keysym = xkb_keysym_from_name(key, XKB_KEYSYM_NO_FLAGS);
2943    if (keysym == XKB_KEY_NoSymbol)
2944      {
2945         WRN("Keysym of key(\"%s\") doesn't exist", key);
2946         EINA_SAFETY_ON_TRUE_GOTO(EINA_TRUE, err);
2947      }
2948
2949    //We have to find the way to get keycode from keysym before keymap notify
2950    //keymap event occurs after minimum 3 roundtrips
2951    //1. ecore_wl_init: wl_registry_add_listener
2952    //2. _ecore_wl_cb_handle_global: wl_seat_add_listener
2953    //3. _ecore_wl_input_seat_handle_capabilities: wl_keyboard_add_listener
2954    while (eina_inlist_count(ewd->inputs) == 0)
2955      {
2956         INF("Wait wl_registry_add_listener reply");
2957         wl_display_roundtrip(ewd->wl.display);
2958      }
2959
2960    input = ecore_wl2_input_default_input_get(ewd);
2961    EINA_SAFETY_ON_NULL_GOTO(input, err);
2962
2963    while (!input->caps_update)
2964      {
2965         INF("Wait until wl_seat_capabilities_update is ready");
2966         wl_display_roundtrip(ewd->wl.display);
2967      }
2968
2969    EINA_SAFETY_ON_NULL_GOTO(input->wl.keyboard, err);
2970
2971
2972    while (!input->xkb.keymap)
2973      {
2974         wl_display_roundtrip(ewd->wl.display);
2975         INF("Wait until keymap event occurs");
2976      }
2977    INF("Finish keymap event");
2978
2979    num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
2980    EINA_SAFETY_ON_TRUE_GOTO((num_keycodes == 0), err);
2981
2982    /* Request to grab a key */
2983    if (win)
2984      surface = ecore_wl2_window_surface_get(win);
2985
2986    for (i = 0; i < num_keycodes; i++)
2987      {
2988         INF("keycode of key:(%d)", keycodes[i]);
2989         tizen_keyrouter_set_keygrab(ewd->wl.tz_keyrouter, surface, keycodes[i], grab_mode);
2990         /* Send sync to wayland compositor and register sync callback to exit while dispatch loop below */
2991         ecore_wl2_display_sync(ewd);
2992
2993         INF("After keygrab _ecore_wl2_keygrab_error = %d", _ecore_wl2_keygrab_error);
2994         if (!_ecore_wl2_keygrab_error)
2995           {
2996              INF("[PID:%d]Succeed to get return value !", getpid());
2997              if (_ecore_wl2_keygrab_hash_add(&keycodes[i], surface))
2998                INF("Succeed to add key to the keygrab hash!");
2999              //TODO: deal with if (win == NULL)
3000              else
3001                WRN("Failed to add key to the keygrab hash!");
3002              ret = EINA_TRUE;
3003           }
3004         else
3005           {
3006              WRN("[PID:%d]Failed to get return value ! ret=%d)", getpid(), _ecore_wl2_keygrab_error);
3007              ret = EINA_FALSE;
3008           }
3009      }
3010
3011    free(keycodes);
3012    keycodes = NULL;
3013
3014    _ecore_wl2_keygrab_error_set();
3015    _ecore_wl2_keygrab_error = -1;
3016    return ret;
3017
3018 err:
3019    set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3020    return EINA_FALSE;
3021 }
3022
3023 EAPI Eina_Bool
3024 ecore_wl2_window_keygrab_unset(Ecore_Wl2_Window *win, const char *key, int mod EINA_UNUSED, int any_mod EINA_UNUSED)
3025 {
3026    Ecore_Wl2_Display *ewd;
3027    xkb_keysym_t keysym = 0x0;
3028    int num_keycodes = 0;
3029    xkb_keycode_t *keycodes = NULL;
3030    int i;
3031
3032    Eina_Bool ret = EINA_FALSE;
3033    struct wl_surface *surface = NULL;
3034    Ecore_Wl2_Input *input;
3035
3036    if (win)
3037      ewd = win->display;
3038    else
3039      ewd = ecore_wl2_connected_display_get(NULL);
3040
3041    if (!ewd) goto err;
3042
3043    if ((!ewd) || (!ewd->wl.tz_keyrouter)) goto err;
3044    if (!key) goto err;
3045    INF("win=%p key=%s ", win, key);
3046
3047    keysym = xkb_keysym_from_name(key, XKB_KEYSYM_NO_FLAGS);
3048    if (keysym == XKB_KEY_NoSymbol)
3049      {
3050         WRN("Keysym of key(\"%s\") doesn't exist", key);
3051         goto err;
3052      }
3053
3054    while (eina_inlist_count(ewd->inputs) == 0)
3055      {
3056         INF("Wait wl_registry_add_listener reply");
3057         wl_display_roundtrip(ewd->wl.display);
3058      }
3059
3060    input = ecore_wl2_input_default_input_get(ewd);
3061
3062    //We have to find the way to get keycode from keysym before keymap notify
3063    if ((input) && (input->xkb.keymap))
3064      num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3065    else
3066      {
3067         WRN("Keymap is not ready");
3068         goto err;
3069      }
3070
3071    if (num_keycodes == 0)
3072      {
3073         WRN("Keycode of key(\"%s\") doesn't exist", key);
3074         goto err;
3075      }
3076
3077    /* Request to ungrab a key */
3078    if (win)
3079      surface = ecore_wl2_window_surface_get(win);
3080
3081    for (i = 0; i < num_keycodes; i++)
3082      {
3083         INF("keycode of key:(%d)", keycodes[i]);
3084         tizen_keyrouter_unset_keygrab(ewd->wl.tz_keyrouter, surface, keycodes[i]);
3085
3086         /* Send sync to wayland compositor and register sync callback to exit while dispatch loop below */
3087         ecore_wl2_display_sync(ewd);
3088
3089         INF("After keygrab unset  _ecore_wl2_keygrab_error = %d", _ecore_wl2_keygrab_error);
3090         if (!_ecore_wl2_keygrab_error)
3091           {
3092              INF("[PID:%d]Succeed to get return value !", getpid());
3093              if (_ecore_wl2_keygrab_hash_del(&keycodes[i]))
3094                INF("Succeed to delete key from the keygrab hash!");
3095              else
3096                WRN("Failed to delete key from the keygrab hash!");
3097              ret = EINA_TRUE;
3098           }
3099         else
3100           {
3101              ret = EINA_FALSE;
3102              WRN("[PID:%d] Failed to get return value ! (ret=%d)", getpid(), _ecore_wl2_keygrab_error);
3103           }
3104      }
3105
3106    free(keycodes);
3107    keycodes = NULL;
3108
3109    _ecore_wl2_keygrab_error_set();
3110    _ecore_wl2_keygrab_error = -1;
3111    return ret;
3112
3113 err:
3114    set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3115    return EINA_FALSE;
3116 }
3117
3118 char *
3119 _ecore_wl2_keyname_get(int keycode)
3120 {
3121    xkb_keysym_t sym = XKB_KEY_NoSymbol;
3122    char name[256] = {0, };
3123    Ecore_Wl2_Display *ewd;
3124    Ecore_Wl2_Input *input;
3125
3126    ewd = ecore_wl2_connected_display_get(NULL);
3127    input = ecore_wl2_input_default_input_get(ewd);
3128    if (!input) return NULL;
3129
3130    sym = xkb_state_key_get_one_sym(input->xkb.state, keycode);
3131    xkb_keysym_get_name(sym, name, sizeof(name));
3132
3133    return strdup(name);
3134 }
3135
3136 EAPI Eina_List
3137 *ecore_wl2_window_keygrab_list_set(Ecore_Wl2_Window *win, Eina_List *infos)
3138 {
3139    Ecore_Wl2_Display *ewd;
3140    xkb_keysym_t keysym = 0x0;
3141    int num_keycodes = 0;
3142    xkb_keycode_t *keycodes = NULL;
3143
3144    struct wl_surface *surface = NULL;
3145
3146    struct wl_array grab_list;
3147    int *grab_data = NULL;
3148    Eina_List *l1, *l2;
3149    Eina_List *error_keys = NULL;
3150    int i;
3151    Eina_Bool no_permission = EINA_FALSE;
3152    Eina_Bool invalid_key = EINA_FALSE;
3153
3154    Ecore_Wl2_Keygrab_Info *info;
3155    Ecore_Wl2_Window_Keygrab_Info *grab_info;
3156    Ecore_Wl2_Input *input;
3157
3158    if (win)
3159      ewd = win->display;
3160    else
3161      ewd = ecore_wl2_connected_display_get(NULL);
3162
3163    if (!ewd) goto err;
3164
3165    while (!ewd->wl.tz_keyrouter)
3166      {
3167         INF("Wait until keyrouter interface is ready");
3168         wl_display_roundtrip(ewd->wl.display);
3169      }
3170
3171    while (eina_inlist_count(ewd->inputs) == 0)
3172      {
3173         INF("Wait wl_registry_add_listener reply");
3174         wl_display_roundtrip(ewd->wl.display);
3175      }
3176
3177    input = ecore_wl2_input_default_input_get(ewd);
3178
3179    if(!input) goto err;
3180
3181    while (!input->caps_update)
3182      {
3183         INF("Wait until wl_seat_capabilities_update is ready");
3184         wl_display_roundtrip(ewd->wl.display);
3185      }
3186    if (input->wl.keyboard)
3187      {
3188         while(!input->xkb.keymap)
3189           {
3190              wl_display_roundtrip(ewd->wl.display);
3191              INF("Wait until keymap event occurs");
3192           }
3193         INF("Finish keymap event");
3194      }
3195    else
3196      {
3197         WRN("This device does not support key");
3198         goto err;
3199      }
3200
3201    if (win)
3202      surface = ecore_wl2_window_surface_get(win);
3203
3204    wl_array_init(&grab_list);
3205
3206    EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3207      {
3208         if (!grab_info->key) continue;
3209         if ((grab_info->mode < ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN) || (grab_info->mode > ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE))
3210           continue;
3211
3212         keysym = xkb_keysym_from_name(grab_info->key, XKB_KEYSYM_NO_FLAGS);
3213
3214         if (keysym == XKB_KEYSYM_NO_FLAGS)
3215           {
3216              WRN("Keysym of key(\"%s\") doesn't exist", grab_info->key);
3217              continue;
3218           }
3219         num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3220
3221         if (num_keycodes == 0)
3222           {
3223              WRN("Keycode of key(\"%s\") doesn't exist", grab_info->key);
3224              continue;
3225           }
3226         for (i = 0; i < num_keycodes; i++)
3227           {
3228              INF("keycode of key:(%d)", keycodes[i]);
3229              grab_data = wl_array_add(&grab_list, sizeof(int));
3230              *grab_data = keycodes[i];
3231              grab_data = wl_array_add(&grab_list, sizeof(int));
3232              *grab_data = grab_info->mode;
3233              grab_data = wl_array_add(&grab_list, sizeof(int));
3234              *grab_data = 0;
3235           }
3236         free(keycodes);
3237         keycodes = NULL;
3238      }
3239    tizen_keyrouter_set_keygrab_list(ewd->wl.tz_keyrouter, surface, &grab_list);
3240
3241    ecore_wl2_display_sync(ewd);
3242
3243    wl_array_for_each(info, &_ecore_wl2_keygrab_result_list)
3244      {
3245
3246         if (!info->err)
3247           {
3248              INF("[PID:%d]Succeed to get return value !", getpid());
3249              if (_ecore_wl2_keygrab_hash_add(&info->key, surface))
3250                INF("Succeed to add key to the keygrab hash!");
3251              else
3252                WRN("Failed to add key to the keygrab hash!");
3253           }
3254         else
3255           {
3256              WRN("After keygrab keycode %d error = %d", info->key, info->err);
3257              if (info->err == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
3258                no_permission = EINA_TRUE;
3259
3260              if (info->err == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
3261                invalid_key = EINA_TRUE;
3262
3263              error_keys = eina_list_append(error_keys, _ecore_wl2_keyname_get(info->key));
3264           }
3265      }
3266    wl_array_release(&grab_list);
3267    wl_array_release(&_ecore_wl2_keygrab_result_list);
3268
3269    set_last_result(TIZEN_ERROR_NONE);
3270    if (invalid_key) set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3271    if (no_permission) set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
3272
3273    return error_keys;
3274
3275 err:
3276    EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3277      {
3278         error_keys = eina_list_append(error_keys, strdup(grab_info->key));
3279      }
3280
3281    set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3282
3283    return error_keys;
3284 }
3285
3286 EAPI Eina_List
3287 *ecore_wl2_window_keygrab_list_unset(Ecore_Wl2_Window *win, Eina_List *infos)
3288 {
3289    Ecore_Wl2_Display *ewd;
3290    xkb_keysym_t keysym = 0x0;
3291    int num_keycodes = 0;
3292    xkb_keycode_t *keycodes = NULL;
3293
3294    struct wl_surface *surface = NULL;
3295
3296    struct wl_array ungrab_list;
3297    int *grab_data = NULL;
3298    Eina_List *l1, *l2;
3299    Eina_List *error_keys = NULL;
3300    int i;
3301    Eina_Bool no_permission = EINA_FALSE;
3302    Eina_Bool invalid_key = EINA_FALSE;
3303
3304    Ecore_Wl2_Keyungrab_Info *info;
3305    Ecore_Wl2_Window_Keygrab_Info *grab_info;
3306
3307    Ecore_Wl2_Input *input;
3308
3309    if (win)
3310      ewd = win->display;
3311    else
3312      ewd = ecore_wl2_connected_display_get(NULL);
3313
3314    if (!ewd) goto err;
3315
3316    if ((!ewd->wl.tz_keyrouter)) goto err;
3317
3318    input = ecore_wl2_input_default_input_get(ewd);
3319
3320    if ((!input) || (!input->xkb.keymap))
3321      {
3322         ERR("Keymap is not ready");
3323         goto err;
3324      }
3325
3326    if (win)
3327      surface = ecore_wl2_window_surface_get(win);
3328
3329    wl_array_init(&ungrab_list);
3330
3331    EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3332      {
3333         if (!grab_info->key) continue;
3334
3335         keysym = xkb_keysym_from_name(grab_info->key, XKB_KEYSYM_NO_FLAGS);
3336
3337         if (keysym == XKB_KEYSYM_NO_FLAGS)
3338           {
3339              WRN("Keysym of key(\"%s\") doesn't exist", grab_info->key);
3340              continue;
3341           }
3342         num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3343
3344         if (num_keycodes == 0)
3345           {
3346              WRN("Keycode of key(\"%s\") doesn't exist", grab_info->key);
3347              continue;
3348           }
3349         for (i = 0; i < num_keycodes; i++)
3350           {
3351              INF("keycode of key:(%d)", keycodes[i]);
3352              grab_data = wl_array_add(&ungrab_list, sizeof(int));
3353              *grab_data = keycodes[i];
3354              grab_data = wl_array_add(&ungrab_list, sizeof(int));
3355              *grab_data = 0;
3356           }
3357         free(keycodes);
3358         keycodes = NULL;
3359      }
3360    tizen_keyrouter_unset_keygrab_list(ewd->wl.tz_keyrouter, surface, &ungrab_list);
3361
3362    ecore_wl2_display_sync(ewd);
3363
3364    wl_array_for_each(info, &_ecore_wl2_keygrab_result_list)
3365      {
3366         if (!info->err)
3367           {
3368              INF("[PID:%d]Succeed to get return value !", getpid());
3369              if (_ecore_wl2_keygrab_hash_del(&info->key))
3370                INF("Succeed to delete key to the keygrab hash!");
3371              else
3372                WRN("Failed to delete key to the keygrab hash!");
3373           }
3374         else
3375           {
3376              WRN("After keyungrab keycode %d error = %d", info->key, info->err);
3377              if (info->err == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
3378                no_permission = EINA_TRUE;
3379
3380              if (info->err == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
3381                invalid_key = EINA_TRUE;
3382
3383              error_keys = eina_list_append(error_keys, _ecore_wl2_keyname_get(info->key));
3384           }
3385      }
3386    wl_array_release(&ungrab_list);
3387    wl_array_release(&_ecore_wl2_keygrab_result_list);
3388
3389    set_last_result(TIZEN_ERROR_NONE);
3390    if (invalid_key) set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3391    if (no_permission) set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
3392
3393    return error_keys;
3394
3395 err:
3396    EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3397      {
3398         error_keys = eina_list_append(error_keys, strdup(grab_info->key));
3399      }
3400
3401    set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3402
3403    return error_keys;
3404 }
3405 //
3406 //
3407
3408 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
3409 static void
3410 _ecore_wl2_input_device_info_free(void *data EINA_UNUSED, void *ev)
3411 {
3412    Ecore_Event_Device_Info *e;
3413
3414    e = ev;
3415    eina_stringshare_del(e->name);
3416    eina_stringshare_del(e->identifier);
3417    eina_stringshare_del(e->seatname);
3418
3419    free(e);
3420 }
3421
3422 void
3423 _ecore_wl2_input_device_info_send(Ecore_Window win_id, const char *name,  const char *identifier, Ecore_Device_Class clas, Ecore_Device_Subclass subclas, Eina_Bool flag)
3424 {
3425    Ecore_Event_Device_Info *e;
3426
3427    if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) return;
3428
3429    e->window = win_id;
3430    e->name = eina_stringshare_add(name);
3431    e->identifier = eina_stringshare_add(identifier);
3432    e->seatname = eina_stringshare_add(name);
3433    e->clas = clas;
3434    e->subclas = subclas;
3435
3436    if (flag)
3437      ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _ecore_wl2_input_device_info_free, NULL);
3438    else
3439      ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _ecore_wl2_input_device_info_free, NULL);
3440 }
3441
3442 // TIZEN_ONLY(20180917): ecore/evas_device: update device info if subclas is changed
3443 static void
3444 _ecore_wl2_input_device_update_send(Ecore_Window win, Ecore_Device *dev)
3445 {
3446    Ecore_Event_Device_Update *ev;
3447
3448    ev = (Ecore_Event_Device_Update *)calloc(sizeof(Ecore_Event_Device_Update), 1);
3449    EINA_SAFETY_ON_NULL_RETURN(ev);
3450
3451    ev->window = win;
3452    ev->dev = dev;
3453    ecore_event_add(ECORE_EVENT_DEVICE_SUBCLASS_UPDATE, ev, NULL, NULL);
3454 }
3455
3456
3457 static void
3458 _ecore_wl2_input_device_ecore_device_update(Ecore_Device *dev, Ecore_Device_Subclass subclas)
3459 {
3460    Eina_Hash *windows;
3461    Eina_Iterator *itr;
3462    Ecore_Wl2_Window *win = NULL;
3463    void *data;
3464    Eina_Bool has_win = EINA_FALSE;
3465
3466    ecore_device_subclass_set(dev, subclas);
3467
3468    windows = _ecore_wl2_window_hash_get();
3469    if (windows)
3470      {
3471         itr = eina_hash_iterator_data_new(windows);
3472         while (eina_iterator_next(itr, &data))
3473           {
3474              win = data;
3475              has_win = EINA_TRUE;
3476              _ecore_wl2_input_device_update_send(win->id, dev);
3477           }
3478
3479         eina_iterator_free(itr);
3480      }
3481    if (!has_win)
3482      {
3483         _ecore_wl2_input_device_update_send((uintptr_t)NULL, dev);
3484      }
3485 }
3486 //
3487
3488 static Eina_Bool
3489 _ecore_wl2_input_device_ecore_device_add(Ecore_Wl2_Tizen_Input_Device *dev)
3490 {
3491    Ecore_Device *ecdev;
3492    Eina_List *l;
3493    const char *ecdev_name;
3494
3495    if (!dev->identifier) return EINA_FALSE;
3496
3497    EINA_LIST_FOREACH((Eina_List *)ecore_device_list(), l, ecdev)
3498      {
3499         ecdev_name = ecore_device_identifier_get(ecdev);
3500         if (!ecdev_name) continue;
3501         if ((ecore_device_class_get(ecdev) == dev->clas) && (!strcmp(ecdev_name, dev->identifier)))
3502           {
3503              // TIZEN_ONLY(20180917): ecore/evas_device: update device info if subclas is changed
3504              _ecore_wl2_input_device_ecore_device_update(ecdev, dev->subclas);
3505              //
3506              return EINA_FALSE;
3507           }
3508      }
3509
3510    ecdev = ecore_device_add();
3511    if (!ecdev)
3512      {
3513         ERR("Failed to add ecore device for name: %s (%s)\n", dev->name, dev->identifier);
3514         return EINA_FALSE;
3515      }
3516    ecore_device_name_set(ecdev, dev->name);
3517    ecore_device_identifier_set(ecdev, dev->identifier);
3518    ecore_device_class_set(ecdev, dev->clas);
3519    ecore_device_subclass_set(ecdev, dev->subclas);
3520
3521    dev->device = efl_ref(ecdev);
3522
3523    return EINA_TRUE;
3524 }
3525
3526 static Eina_Bool
3527 _ecore_wl2_input_device_ecore_device_remove(Ecore_Wl2_Tizen_Input_Device *dev)
3528 {
3529    Ecore_Device *ecdev;
3530    Eina_List *l, *clone;
3531    const char *ecdev_name;
3532
3533    if (!dev->identifier) return EINA_FALSE;
3534
3535    clone = eina_list_clone(ecore_device_list());
3536
3537    EINA_LIST_FOREACH(clone, l, ecdev)
3538      {
3539         ecdev_name = ecore_device_identifier_get(ecdev);
3540         if (!ecdev_name) continue;
3541         if ((ecore_device_class_get(ecdev) == dev->clas) &&
3542             (!strcmp(ecdev_name, dev->identifier)))
3543            {
3544               efl_unref(dev->device);
3545               ecore_device_del(ecdev);
3546               dev->device = NULL;
3547               eina_list_free(clone);
3548               return EINA_TRUE;
3549            }
3550       }
3551     eina_list_free(clone);
3552
3553     return EINA_FALSE;
3554 }
3555
3556 static void
3557 _ecore_wl2_input_device_info_broadcast(Ecore_Wl2_Tizen_Input_Device *dev, Eina_Bool flag)
3558 {
3559    Eina_Hash *windows = NULL;
3560    Eina_Iterator *itr;
3561    Ecore_Wl2_Window *win = NULL;
3562    void *data;
3563    Eina_Bool res, has_win = EINA_FALSE;
3564
3565    if (!dev) return;
3566    if (!dev->name) return;
3567    if (!dev->identifier) return;
3568    if (!dev->input || !dev->input->display) return;
3569
3570    if (flag)
3571      res = _ecore_wl2_input_device_ecore_device_add(dev);
3572    else
3573      res = _ecore_wl2_input_device_ecore_device_remove(dev);
3574
3575    if (!res) return;
3576
3577    windows = _ecore_wl2_window_hash_get();
3578    if (windows)
3579      {
3580         itr = eina_hash_iterator_data_new(windows);
3581         while (eina_iterator_next(itr, &data))
3582           {
3583              win = data;
3584              has_win = EINA_TRUE;
3585              _ecore_wl2_input_device_info_send(win->id, dev->name, dev->identifier, dev->clas, dev->subclas, flag);
3586           }
3587
3588         eina_iterator_free(itr);
3589      }
3590    if (!has_win)
3591      {
3592         _ecore_wl2_input_device_info_send((uintptr_t)NULL, dev->name, dev->identifier, dev->clas, dev->subclas, flag);
3593      }
3594 }
3595
3596 void
3597 _ecore_wl2_input_devices_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *win)
3598 {
3599    Eina_List *l;
3600    Ecore_Wl2_Tizen_Input_Device *dev;
3601
3602    if (!input) return;
3603
3604    EINA_LIST_FOREACH(input->devmgr.devices, l, dev)
3605      {
3606         if (!dev->name || !dev->identifier) continue;
3607         _ecore_wl2_input_device_info_send(win->id, dev->name, dev->identifier, dev->clas, dev->subclas, EINA_TRUE);
3608      }
3609 }
3610
3611
3612 static void
3613 _ecore_wl2_input_device_cb_device_info(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, const char *name, uint32_t clas, uint32_t subclas, struct wl_array *axes EINA_UNUSED)
3614 {
3615    Ecore_Wl2_Tizen_Input_Device *dev;
3616
3617    if (!(dev = data)) return;
3618    const char *tmp;
3619    if (((Ecore_Device_Class)clas == ECORE_DEVICE_CLASS_MOUSE) && (tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1))
3620      dev->clas = ECORE_DEVICE_CLASS_TOUCH;
3621    else
3622      dev->clas = (Ecore_Device_Class)clas;
3623    dev->subclas = (Ecore_Device_Subclass)subclas;
3624    dev->name = eina_stringshare_add(name);
3625
3626    _ecore_wl2_input_device_info_broadcast(dev, EINA_TRUE);
3627 }
3628
3629 static void
3630 _ecore_wl2_input_device_cb_event_device(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, unsigned int serial EINA_UNUSED, const char *name EINA_UNUSED, uint32_t time EINA_UNUSED)
3631 {
3632    Ecore_Wl2_Tizen_Input_Device *dev;
3633
3634    if (!(dev = data)) return;
3635    if (!dev->identifier) return;
3636    _ecore_wl2_input_device_last_device_set(dev);
3637
3638    return;
3639 }
3640
3641 static void
3642 _ecore_wl2_input_detent_rotate_free(void *data EINA_UNUSED, void *ev)
3643 {
3644    Ecore_Event_Detent_Rotate *e = ev;
3645    free(e);
3646 }
3647
3648 static void
3649 _ecore_wl2_input_device_cb_axis(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, uint32_t axis_type, wl_fixed_t value)
3650 {
3651    Ecore_Wl2_Input *input;
3652    Ecore_Wl2_Tizen_Input_Device *dev;
3653    double dvalue = wl_fixed_to_double(value);
3654    Ecore_Event_Detent_Rotate *e;
3655
3656    dev = (Ecore_Wl2_Tizen_Input_Device *)data;
3657    input = dev->input;
3658
3659    if (!input) return;
3660
3661    switch (axis_type)
3662      {
3663         case TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_X:
3664            input->touch.last_touch_axis.radius_x = dvalue;
3665            break;
3666         case TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_Y:
3667            input->touch.last_touch_axis.radius_y = dvalue;
3668            break;
3669         case TIZEN_INPUT_DEVICE_AXIS_TYPE_PRESSURE:
3670            input->touch.last_touch_axis.pressure = dvalue;
3671            break;
3672         case TIZEN_INPUT_DEVICE_AXIS_TYPE_ANGLE:
3673            input->touch.last_touch_axis.angle = dvalue;
3674            break;
3675         case TIZEN_INPUT_DEVICE_AXIS_TYPE_DETENT:
3676            /* Do something after get detent event.
3677             * value 1 is clockwise,
3678             * value -1 is counterclockwise,
3679             */
3680            if (!(e = calloc(1, sizeof(Ecore_Event_Detent_Rotate))))
3681              {
3682                 ERR("detent: cannot allocate memory");
3683                 return;
3684              }
3685            if (dvalue == 1)
3686              e->direction = ECORE_DETENT_DIRECTION_CLOCKWISE;
3687            else
3688              e->direction = ECORE_DETENT_DIRECTION_COUNTER_CLOCKWISE;
3689            e->timestamp = _timestamp_get();
3690            DBG("detent: dir: %d, time: %d", e->direction, e->timestamp);
3691            ecore_event_add(ECORE_EVENT_DETENT_ROTATE, e, _ecore_wl2_input_detent_rotate_free, NULL);
3692            break;
3693         default:
3694            WRN("Invalid type(%d) is ignored.\n", axis_type);
3695            break;
3696      }
3697    return;
3698 }
3699
3700 static const struct tizen_input_device_listener _tz_input_device_listener =
3701 {
3702    _ecore_wl2_input_device_cb_device_info,
3703    _ecore_wl2_input_device_cb_event_device,
3704    _ecore_wl2_input_device_cb_axis,
3705 };
3706
3707 static void
3708 _ecore_wl2_input_device_manager_cb_device_add(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
3709                           unsigned int serial EINA_UNUSED, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
3710 {
3711    Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3712    Ecore_Wl2_Input *input;
3713    Ecore_Wl2_Tizen_Input_Device *dev;
3714
3715    if (!ewd) return;
3716    if ((!identifier) || (!device) || (!seat))
3717      {
3718         ERR("Invalid arguments. return");
3719         return;
3720      }
3721
3722    input = wl_seat_get_user_data(seat);
3723
3724    if (!input) return;
3725    if (!(dev = calloc(1, sizeof(Ecore_Wl2_Tizen_Input_Device)))) return;
3726
3727    dev->tz_device = device;
3728    tizen_input_device_add_listener(dev->tz_device, &_tz_input_device_listener, dev);
3729    dev->input = input;
3730    dev->identifier = eina_stringshare_add(identifier);
3731    dev->seat = seat;
3732
3733    input->devmgr.devices = eina_list_append(input->devmgr.devices, dev);
3734 }
3735
3736 static void
3737 _ecore_wl2_input_device_manager_cb_device_remove(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
3738                             unsigned int serial EINA_UNUSED, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
3739 {
3740    Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3741    Ecore_Wl2_Input *input;
3742    Eina_List *l, *l_next;
3743    Ecore_Wl2_Tizen_Input_Device *dev;
3744
3745    if (!ewd) return;
3746    if ((!identifier) || (!device) || (!seat))
3747      {
3748         ERR("Invalid arguments. return");
3749         return;
3750      }
3751
3752    input = wl_seat_get_user_data(seat);
3753
3754    if (!input) return;
3755
3756    EINA_LIST_FOREACH_SAFE(input->devmgr.devices, l, l_next, dev)
3757      {
3758         if (!dev->identifier) continue;
3759         if ((!strcmp(dev->identifier, identifier)) && (seat == dev->seat) && (device == dev->tz_device))
3760           {
3761              _ecore_wl2_input_device_info_broadcast(dev, EINA_FALSE);
3762
3763              _ecore_wl2_input_device_last_device_unset(dev);
3764
3765              if (dev->tz_device) tizen_input_device_release(dev->tz_device);
3766              if (dev->name) eina_stringshare_del(dev->name);
3767              if (dev->identifier) eina_stringshare_del(dev->identifier);
3768              dev->seat = NULL;
3769
3770              input->devmgr.devices = eina_list_remove_list(input->devmgr.devices, l);
3771
3772              free(dev);
3773              break;
3774           }
3775      }
3776 }
3777
3778 static void
3779 _ecore_wl2_input_device_manager_cb_error(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t errorcode EINA_UNUSED)
3780 {
3781    ;
3782 }
3783
3784 static void
3785 _ecore_wl2_input_device_manager_cb_block_expired(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED)
3786 {
3787    ;
3788 }
3789
3790 static void
3791 _ecore_wl2_input_device_manager_cb_max_touch_count(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t serial EINA_UNUSED, int32_t max_count, struct wl_seat *seat)
3792 {
3793    Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3794    Ecore_Wl2_Input *input;
3795
3796    if (!ewd) return;
3797
3798    input = wl_seat_get_user_data(seat);
3799
3800    if (!input) return;
3801
3802    if (input->touch.max_count < max_count)
3803      {
3804         if (input->touch.touch_axis)
3805           {
3806              INF("Max touch value is changed %d to %d\n", input->touch.max_count, max_count);
3807              free(input->touch.touch_axis);
3808           }
3809         input->touch.max_count = max_count;
3810         input->touch.touch_axis = (Ecore_Wl2_Touch_Axis *)calloc(max_count, sizeof(Ecore_Wl2_Touch_Axis));
3811      }
3812 }
3813
3814 static const struct tizen_input_device_manager_listener _tz_input_device_mgr_listener =
3815 {
3816    _ecore_wl2_input_device_manager_cb_device_add,
3817    _ecore_wl2_input_device_manager_cb_device_remove,
3818    _ecore_wl2_input_device_manager_cb_error,
3819    _ecore_wl2_input_device_manager_cb_block_expired,
3820    _ecore_wl2_input_device_manager_cb_max_touch_count,
3821 };
3822
3823 void
3824 _ecore_wl2_input_device_manager_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version EINA_UNUSED)
3825 {
3826    ewd->wl.tz_input_device_manager =
3827    wl_registry_bind(ewd->wl.registry, id, &tizen_input_device_manager_interface, 4);
3828
3829    tizen_input_device_manager_add_listener(ewd->wl.tz_input_device_manager,
3830                                        &_tz_input_device_mgr_listener, ewd);
3831 }
3832 //
3833
3834 EAPI struct wl_seat *
3835 ecore_wl2_input_seat_get(Ecore_Wl2_Input *input)
3836 {
3837    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3838    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3839    return input->wl.seat;
3840 }
3841
3842 EAPI Ecore_Wl2_Seat_Capabilities
3843 ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input)
3844 {
3845    Ecore_Wl2_Seat_Capabilities cap = ECORE_WL2_SEAT_CAPABILITIES_NONE;
3846
3847    EINA_SAFETY_ON_NULL_RETURN_VAL(input, cap);
3848    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
3849    if (input->wl.keyboard)
3850      cap |= ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD;
3851    if (input->wl.pointer)
3852      cap |= ECORE_WL2_SEAT_CAPABILITIES_POINTER;
3853    if (input->wl.touch)
3854      cap |= ECORE_WL2_SEAT_CAPABILITIES_TOUCH;
3855    return cap;
3856 }
3857
3858 EAPI Eina_Stringshare *
3859 ecore_wl2_input_name_get(Ecore_Wl2_Input *input)
3860 {
3861    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3862    return input->name;
3863 }
3864
3865 EAPI unsigned int
3866 ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input)
3867 {
3868    EINA_SAFETY_ON_NULL_RETURN_VAL(input, 0);
3869    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
3870    return input->id;
3871 }
3872
3873 EAPI Ecore_Wl2_Display *
3874 ecore_wl2_input_display_get(const Ecore_Wl2_Input *input)
3875 {
3876    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3877    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3878    return input->display;
3879 }
3880
3881 EAPI struct xkb_keymap *
3882 ecore_wl2_input_keymap_get(const Ecore_Wl2_Input *input)
3883 {
3884    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3885    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3886    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, NULL);
3887    return input->xkb.keymap;
3888 }
3889
3890 EAPI Eina_Bool
3891 ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3892 {
3893    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3894    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3895    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3896    input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = rate;
3897    input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = delay;
3898    input->repeat.changed = EINA_TRUE;
3899    return input->repeat.enabled;
3900 }
3901
3902 EAPI Eina_Bool
3903 ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3904 {
3905    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3906    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3907    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3908    if (rate) *rate = input->repeat.rate;
3909    if (delay) *delay = input->repeat.delay;
3910    return input->repeat.enabled;
3911 }
3912
3913 EAPI Eina_Bool
3914 ecore_wl2_input_keyboard_horizontal_way_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3915 {
3916    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3917    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3918    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3919    input->repeat.horizontal.rate = rate;
3920    input->repeat.horizontal.delay = delay;
3921    input->repeat.changed = EINA_TRUE;
3922    return input->repeat.enabled;
3923 }
3924
3925 EAPI Eina_Bool
3926 ecore_wl2_input_keyboard_horizontal_way_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3927 {
3928    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3929    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3930    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3931    if (rate) *rate = input->repeat.horizontal.rate;
3932    if (delay) *delay = input->repeat.horizontal.delay;
3933    return input->repeat.enabled;
3934 }
3935
3936
3937 EAPI Eina_Bool
3938 ecore_wl2_input_keyboard_vertical_way_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3939 {
3940    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3941    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3942    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3943    input->repeat.vertical.rate = rate;
3944    input->repeat.vertical.delay = delay;
3945    input->repeat.changed = EINA_TRUE;
3946    return input->repeat.enabled;
3947 }
3948
3949 EAPI Eina_Bool
3950 ecore_wl2_input_keyboard_vertical_way_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3951 {
3952    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3953    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3954    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3955    if (rate) *rate = input->repeat.vertical.rate;
3956    if (delay) *delay = input->repeat.vertical.delay;
3957    return input->repeat.enabled;
3958 }
3959
3960 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3961 static void
3962 _pointer_update_stop(Ecore_Wl2_Input *input)
3963 {
3964    if (!input->cursor.timer) return;
3965
3966    ecore_timer_del(input->cursor.timer);
3967    input->cursor.timer = NULL;
3968 }
3969 //
3970
3971 EAPI void
3972 ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y)
3973 {
3974    EINA_SAFETY_ON_NULL_RETURN(input);
3975
3976    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3977    _pointer_update_stop(input);
3978    if (input->wl.pointer)
3979      wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
3980                            surface, hot_x, hot_y);
3981    //
3982
3983    // TIZEN_ONLY(20230330): support client that requests to unset cursor
3984    if (!surface)
3985      {
3986         if (input->cursor.name) eina_stringshare_del(input->cursor.name);
3987         input->cursor.name = NULL;
3988         ecore_wl2_display_flush(input->display);
3989         return;
3990      }
3991    //
3992
3993    input->cursor.surface = surface;
3994    input->cursor.hot_x = hot_x;
3995    input->cursor.hot_y = hot_y;
3996
3997    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3998    #if 0
3999    _ecore_wl2_input_cursor_update(input);
4000    #endif
4001    //
4002 }
4003
4004 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4005 EAPI struct wl_cursor *
4006 ecore_wl2_input_cursor_get(Ecore_Wl2_Input *input, const char *cursor_name)
4007 {
4008    if ((!input) || (!input->cursor.theme))
4009      return NULL;
4010
4011    return wl_cursor_theme_get_cursor(input->cursor.theme,
4012                                      cursor_name);
4013 }
4014 //
4015
4016 EAPI void
4017 ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor_name)
4018 {
4019    EINA_SAFETY_ON_NULL_RETURN(input);
4020    // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4021    #if 0
4022    _ecore_wl2_input_cursor_set(input, cursor);
4023    #else
4024    struct wl_cursor *cursor;
4025
4026    /* No pointer device. Don't need to set cursor and update it */
4027    if (!input->wl.pointer) return;
4028
4029    _pointer_update_stop(input);
4030
4031    eina_stringshare_replace(&input->cursor.name, cursor_name);
4032
4033    /* No cursor. Set to default Left Pointer */
4034    if (!cursor_name)
4035      eina_stringshare_replace(&input->cursor.name, "left_ptr");
4036
4037    /* try to get this cursor from the theme */
4038    if (!(cursor = ecore_wl2_input_cursor_get(input, input->cursor.name)))
4039      {
4040         /* if the theme does not have this cursor, default to left pointer */
4041         if (!(cursor = ecore_wl2_input_cursor_get(input, "left_ptr")))
4042           return;
4043      }
4044
4045    input->cursor.cursor = cursor;
4046
4047    if ((!cursor->images) || (!cursor->images[0]))
4048      {
4049         ecore_wl2_input_pointer_set(input, NULL, 0, 0);
4050         return;
4051      }
4052
4053    input->cursor.current_index = 0;
4054
4055    _ecore_wl2_input_cursor_update(input);
4056    #endif
4057 }
4058
4059 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4060 EAPI void
4061 ecore_wl2_input_cursor_size_set(Ecore_Wl2_Input *input, const int size)
4062 {
4063    if (!input) return;
4064
4065    input->cursor.size = size;
4066
4067    EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);
4068
4069    if (input->cursor.theme)
4070      wl_cursor_theme_destroy(input->cursor.theme);
4071
4072    input->cursor.theme =
4073      wl_cursor_theme_load(NULL, input->cursor.size, input->display->wl.shm);
4074 }
4075
4076 EAPI void
4077 ecore_wl2_input_cursor_theme_name_set(Ecore_Wl2_Input *input, const char *cursor_theme_name)
4078 {
4079    if (!input) return;
4080
4081    if (eina_streq(input->cursor.theme_name, cursor_theme_name))
4082      return;
4083
4084    eina_stringshare_replace(&input->cursor.theme_name, cursor_theme_name);
4085
4086    EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);
4087
4088    if (input->cursor.theme)
4089      wl_cursor_theme_destroy(input->cursor.theme);
4090    input->cursor.theme =
4091      wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size,
4092                           input->display->wl.shm);
4093 }
4094
4095 EAPI void
4096 ecore_wl2_input_cursor_default_restore(Ecore_Wl2_Input *input)
4097 {
4098    if (!input) return;
4099
4100    /* Restore to default wayland cursor */
4101    ecore_wl2_input_cursor_from_name_set(input, "left_ptr");
4102 }
4103 //
4104
4105 EAPI Eina_Bool
4106 ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int *x, int *y)
4107 {
4108    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4109
4110    if (x) *x = 0;
4111    if (y) *y = 0;
4112    if (!input->wl.pointer) return EINA_FALSE;
4113    if (x) *x = input->pointer.sx;
4114    if (y) *y = input->pointer.sy;
4115    return EINA_TRUE;
4116 }
4117
4118 EAPI Ecore_Wl2_Input *
4119 ecore_wl2_input_default_input_get(const Ecore_Wl2_Display *ewd)
4120 {
4121    Ecore_Wl2_Input *input;
4122
4123    EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
4124    if (!ewd->inputs) return NULL;
4125
4126    input = ecore_wl2_display_input_find_by_name(ewd, "seat0");
4127    if (!input) input = ecore_wl2_display_input_find_by_name(ewd, "default");
4128
4129    return input;
4130 }
4131
4132 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
4133 EAPI Eina_Bool
4134 ecore_wl2_window_pointer_constraints_lock_pointer(Ecore_Wl2_Window *win)
4135 {
4136    Ecore_Wl2_Display *ewd;
4137    Ecore_Wl2_Input *input;
4138
4139    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4140    EINA_SAFETY_ON_NULL_RETURN_VAL(win->surface, EINA_FALSE);
4141
4142    ewd = win->display;
4143    input = ecore_wl2_input_default_input_get(ewd);
4144    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4145
4146    if (!ewd->wl.pointer_constraints)
4147      {
4148         ERR("Failed to lock pointer. constraints is NULL");
4149         return EINA_FALSE;
4150      }
4151    if (!input->wl.locked_pointer)
4152      {
4153         INF("Pointer Constraint: lock pointer. (region: %p)", input->lock_region);
4154         input->wl.locked_pointer =
4155           zwp_pointer_constraints_v1_lock_pointer(ewd->wl.pointer_constraints,
4156                                                   win->surface,
4157                                                   input->wl.pointer,
4158                                                   input->lock_region,
4159                                                   ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
4160         zwp_locked_pointer_v1_add_listener(input->wl.locked_pointer,
4161                                            &_locked_pointer_listener, input);
4162      }
4163
4164    if (ewd->wl.relative_pointer_manager &&
4165        !input->wl.relative_pointer)
4166      {
4167         input->wl.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
4168                                        ewd->wl.relative_pointer_manager,
4169                                        input->wl.pointer);
4170         zwp_relative_pointer_v1_add_listener(input->wl.relative_pointer, &_relative_pointer_listener, input);
4171      }
4172    input->want_lock_pointer = EINA_TRUE;
4173
4174    return EINA_TRUE;
4175 }
4176
4177 EAPI Eina_Bool
4178 ecore_wl2_window_pointer_constraints_unlock_pointer(Ecore_Wl2_Window *win)
4179 {
4180    Ecore_Wl2_Display *ewd;
4181    Ecore_Wl2_Input *input;
4182
4183    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4184
4185    ewd = win->display;
4186    input = ecore_wl2_input_default_input_get(ewd);
4187    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4188
4189    if (input->wl.locked_pointer)
4190      {
4191         INF("Pointer Constraint: Destroy locked pointer");
4192         zwp_locked_pointer_v1_destroy(input->wl.locked_pointer);
4193         input->wl.locked_pointer = NULL;
4194      }
4195    input->want_lock_pointer = EINA_FALSE;
4196
4197    return EINA_TRUE;
4198 }
4199
4200 EAPI void
4201 ecore_wl2_window_locked_pointer_region_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
4202 {
4203    Ecore_Wl2_Display *ewd;
4204    Ecore_Wl2_Input *input;
4205
4206    EINA_SAFETY_ON_NULL_RETURN(win);
4207
4208    ewd = win->display;
4209    input = ecore_wl2_input_default_input_get(ewd);
4210    EINA_SAFETY_ON_NULL_RETURN(input);
4211
4212    if (input->lock_region)
4213      {
4214         wl_region_destroy(input->lock_region);
4215         input->lock_region = NULL;
4216      }
4217
4218    if ((w > 0) && (h > 0))
4219      {
4220         struct wl_region *region;
4221
4222         region = wl_compositor_create_region(ewd->wl.compositor);
4223         if (!region)
4224           {
4225              ERR("Failed to create region of locked_pointer");
4226              return;
4227           }
4228
4229         input->lock_region = region;
4230         wl_region_add(input->lock_region, x, y, w, h);
4231
4232         if (!input->wl.locked_pointer)
4233           {
4234              INF("No locked_pointer available. region (%d, %d) (w:%d, h:%d)", x, y, w, h);
4235              return;
4236           }
4237
4238         INF("Set region for locked_pointer (%d, %d) (w:%d, h:%d)", x, y, w, h);
4239         zwp_locked_pointer_v1_set_region(input->wl.locked_pointer, input->lock_region);
4240      }
4241    else
4242      {
4243         if (!input->wl.locked_pointer)
4244           {
4245              INF("No locked_pointer available. region (%d, %d) (w:%d, h:%d)", x, y, w, h);
4246              return;
4247           }
4248         INF("Set region for locked_pointer. NULL region");
4249         zwp_locked_pointer_v1_set_region(input->wl.locked_pointer, NULL);
4250      }
4251 }
4252
4253 EAPI void
4254 ecore_wl2_window_locked_pointer_cursor_position_hint_set(Ecore_Wl2_Window *win, int x, int y)
4255 {
4256    Ecore_Wl2_Display *ewd;
4257    Ecore_Wl2_Input *input;
4258
4259    EINA_SAFETY_ON_NULL_RETURN(win);
4260
4261    ewd = win->display;
4262    input = ecore_wl2_input_default_input_get(ewd);
4263    EINA_SAFETY_ON_NULL_RETURN(input);
4264
4265    if (!input->wl.locked_pointer)
4266      {
4267         INF("No locked pointer available. cursor position hint (%d, %d)", x, y);
4268         return;
4269      }
4270
4271    INF("Set cursor position hint (%d, %d) for locked_pointer", x, y);
4272    zwp_locked_pointer_v1_set_cursor_position_hint(input->wl.locked_pointer,
4273                                                   wl_fixed_from_int(x),
4274                                                   wl_fixed_from_int(y));
4275 }
4276 //
4277
4278 // TIZEN_ONLY(20230821) : add cursor_visible set API
4279 EAPI void
4280 ecore_wl2_window_cursor_visible_set(Ecore_Wl2_Window *win, Eina_Bool visible)
4281 {
4282    Ecore_Wl2_Display *ewd;
4283    Ecore_Wl2_Input *input;
4284
4285    EINA_SAFETY_ON_NULL_RETURN(win);
4286
4287    ewd = win->display;
4288    input = ecore_wl2_input_default_input_get(ewd);
4289    EINA_SAFETY_ON_NULL_RETURN(input);
4290
4291    INF("Set cursor_visible to %s", visible ? "True" : "False");
4292    if (visible)
4293      {
4294         ecore_wl2_input_cursor_from_name_set(input, input->cursor.name);
4295      }
4296    else
4297      {
4298         ecore_wl2_input_pointer_set(input, NULL, 0, 0);
4299      }
4300 }
4301 //