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