1 /* this file contains code copied from weston; the copyright notice is below */
3 * Copyright © 2008 Kristian Høgsberg
4 * Copyright © 2012-2013 Collabora, Ltd.
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:
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
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.
31 # include <linux/input.h>
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
44 #include "ecore_wl2_private.h"
45 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
49 typedef struct _Ecore_Wl2_Mouse_Down_Info
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;
63 static Eina_Inlist *_ecore_wl2_mouse_down_info_list = NULL;
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;
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;
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);
88 static unsigned int _timestamp_get()
91 clock_gettime(CLOCK_MONOTONIC, &ts);
93 return ts.tv_sec * 1000 + (ts.tv_nsec / 1000000);
96 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
98 _ecore_wl2_input_convert_old_keys(unsigned int code)
102 // TIZEN ONLY(20160608) : Add option for key conversion
104 tmp = getenv("ECORE_WL_INPUT_KEY_CONVERSION_DISABLE");
105 if (tmp && atoi(tmp)) return code;
108 for (i = 0; i < _num_back_key_latest; i++)
110 if (code == _back_key_latest[i])
112 return _back_key_lt_24;
116 for (i=0; i<_num_menu_key_latest; i++)
118 if (code == _menu_key_latest[i])
120 return _menu_key_lt_24;
124 for (i=0; i<_num_home_key_latest; i++)
126 if (code == _home_key_latest[i])
128 return _home_key_lt_24;
136 _ecore_wl2_input_key_conversion_clean_up(void)
142 _num_back_key_latest = 0;
143 _num_menu_key_latest = 0;
144 _num_home_key_latest = 0;
146 if (_back_key_latest)
148 free(_back_key_latest);
149 _back_key_latest = NULL;
151 if (_menu_key_latest)
153 free(_menu_key_latest);
154 _menu_key_latest = NULL;
156 if (_home_key_latest)
158 free(_home_key_latest);
159 _home_key_latest = NULL;
164 _ecore_wl2_input_key_conversion_set(Ecore_Wl2_Input *input)
167 xkb_keycode_t *keycodes = NULL;
168 static int retry_cnt = 0;
170 if ((_tizen_api_version < 0.0) || (_tizen_api_version > 0.0)) return;
171 EINA_SAFETY_ON_NULL_RETURN(input);
172 EINA_SAFETY_ON_NULL_RETURN(input->xkb.keymap);
174 temp = getenv("TIZEN_API_VERSION");
178 _tizen_api_version = 0.0;
182 INF("No tizen api version.\n");
183 _tizen_api_version = -1.0;
188 char* lc_numeric = setlocale(LC_NUMERIC, NULL);
189 char* old_numeric = lc_numeric? strdup(lc_numeric) : NULL;
190 setlocale(LC_NUMERIC, "C");
191 _tizen_api_version = atof(temp);
194 setlocale(LC_NUMERIC, old_numeric);
197 INF("TIZEN_API_VERSION: %lf, Environment variable: %s\n", _tizen_api_version, temp);
198 if (_tizen_api_version < 2.4)
200 _ecore_wl2_input_key_conversion_clean_up();
202 ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
203 xkb_keysym_from_name("XF86Stop", XKB_KEYSYM_NO_FLAGS), &keycodes);
206 ERR("There is no entry available for the old name of back key. No conversion will be done for back key.\n");
210 _back_key_lt_24 = (int)keycodes[0];
214 _num_back_key_latest = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
215 xkb_keysym_from_name("XF86Back", XKB_KEYSYM_NO_FLAGS), &_back_key_latest);
218 ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
219 xkb_keysym_from_name("XF86Send", XKB_KEYSYM_NO_FLAGS), &keycodes);
222 ERR("There is no entry available for the old name of back key. No conversion will be done for menu key.\n");
226 _menu_key_lt_24 = (int)keycodes[0];
230 _num_menu_key_latest = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
231 xkb_keysym_from_name("XF86Menu", XKB_KEYSYM_NO_FLAGS), &_menu_key_latest);
234 ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
235 xkb_keysym_from_name("XF86Phone", XKB_KEYSYM_NO_FLAGS), &keycodes);
238 ERR("There is no entry available for the old name of back key. No conversion will be done for home key.\n");
242 _home_key_lt_24 = (int)keycodes[0];
246 _num_home_key_latest = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
247 xkb_keysym_from_name("XF86Home", XKB_KEYSYM_NO_FLAGS), &_home_key_latest);
250 if ((!_back_key_lt_24) && (!_menu_key_lt_24) && (!_home_key_lt_24)) _tizen_api_version = -1.0;
254 _ecore_wl2_input_key_conversion_clean_up();
259 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
261 _ecore_wl2_input_touch_radius_calc(double x, double y)
263 #define PI 3.14159265358979323846
268 _ecore_wl2_input_touch_axis_process(Ecore_Wl2_Input *input, int id)
270 if (id >= input->touch.max_count)
273 if (input->touch.last_touch_axis.radius_x)
275 input->touch.touch_axis[id].radius_x = input->touch.last_touch_axis.radius_x;
276 input->touch.last_touch_axis.radius_x = 0.0;
278 if (input->touch.last_touch_axis.radius_y)
280 input->touch.touch_axis[id].radius_y = input->touch.last_touch_axis.radius_y;
281 input->touch.last_touch_axis.radius_y = 0.0;
283 if (input->touch.last_touch_axis.pressure)
285 input->touch.touch_axis[id].pressure = input->touch.last_touch_axis.pressure;
286 input->touch.last_touch_axis.pressure = 0.0;
288 if (input->touch.last_touch_axis.angle)
290 input->touch.touch_axis[id].angle = input->touch.last_touch_axis.angle;
291 input->touch.last_touch_axis.angle = 0.0;
296 static Ecore_Wl2_Mouse_Down_Info *
297 _ecore_wl2_input_mouse_down_info_get(int device)
299 Eina_Inlist *l = NULL;
300 Ecore_Wl2_Mouse_Down_Info *info = NULL;
302 l = _ecore_wl2_mouse_down_info_list;
303 EINA_INLIST_FOREACH(l, info)
304 if (info->device == device) return info;
306 info = calloc(1, sizeof(Ecore_Wl2_Mouse_Down_Info));
307 if (!info) return NULL;
309 info->device = device;
310 l = eina_inlist_append(l, (Eina_Inlist *)info);
311 _ecore_wl2_mouse_down_info_list = l;
316 static Ecore_Wl2_Input_Devices *
317 _ecore_wl2_devices_get(const Ecore_Wl2_Input *input, int window_id)
319 Ecore_Wl2_Input_Devices *devices;
322 EINA_LIST_FOREACH(input->devices_list, l, devices)
324 if (devices->window_id == window_id)
332 _ecore_wl2_touch_dev_get(Ecore_Wl2_Input *input, int window_id)
334 Ecore_Wl2_Input_Devices *devices;
335 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
337 if (input->devmgr.last_device_touch && input->devmgr.last_device_touch->device)
339 return efl_ref(input->devmgr.last_device_touch->device);
343 devices = _ecore_wl2_devices_get(input, window_id);
344 if (devices && devices->touch_dev)
345 return efl_ref(devices->touch_dev);
351 _ecore_wl2_mouse_dev_get(Ecore_Wl2_Input *input, int window_id)
354 if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1))
355 return _ecore_wl2_touch_dev_get(input, window_id);
357 Ecore_Wl2_Input_Devices *devices;
358 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
360 if (input->devmgr.last_device_ptr && input->devmgr.last_device_ptr->device)
362 return efl_ref(input->devmgr.last_device_ptr->device);
366 devices = _ecore_wl2_devices_get(input, window_id);
367 if (devices && devices->pointer_dev)
368 return efl_ref(devices->pointer_dev);
374 _ecore_wl2_seat_dev_get(Ecore_Wl2_Input *input, int window_id)
376 Ecore_Wl2_Input_Devices *devices;
378 devices = _ecore_wl2_devices_get(input, window_id);
380 return efl_ref(devices->seat_dev);
385 //TIZEN_ONLY(20180118): support a Ecore_Device
387 _input_event_mouse_io_cb_free(void *data EINA_UNUSED, void *event)
389 Ecore_Event_Mouse_IO *ev = event;
396 _input_event_mouse_move_cb_free(void *data EINA_UNUSED, void *event)
398 Ecore_Event_Mouse_Move *ev = event;
405 _input_event_mouse_wheel_cb_free(void *data EINA_UNUSED, void *event)
407 Ecore_Event_Mouse_Wheel *ev = event;
414 _input_event_mouse_button_cb_free(void *data EINA_UNUSED, void *event)
416 Ecore_Event_Mouse_Button *ev = event;
423 _input_event_key_cb_free(void *data EINA_UNUSED, void *event)
425 Ecore_Event_Key *ev = event;
433 _ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
435 Ecore_Event_Mouse_IO *ev;
437 ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
440 ev->x = input->pointer.sx;
441 ev->y = input->pointer.sy;
442 ev->window = window->id;
443 ev->event_window = window->id;
444 ev->timestamp = input->timestamp;
445 ev->modifiers = input->keyboard.modifiers;
446 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
448 ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, _input_event_mouse_io_cb_free, ev->dev);
452 _ecore_wl2_input_mouse_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
454 Ecore_Event_Mouse_IO *ev;
456 ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
459 ev->x = input->pointer.sx;
460 ev->y = input->pointer.sy;
461 ev->window = window->id;
462 ev->event_window = window->id;
463 ev->timestamp = input->timestamp;
464 ev->modifiers = input->keyboard.modifiers;
465 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
467 ecore_event_add(ECORE_EVENT_MOUSE_OUT, ev, _input_event_mouse_io_cb_free, ev->dev);
471 _ecore_wl2_input_mouse_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device)
473 Ecore_Event_Mouse_Move *ev;
474 Ecore_Wl2_Mouse_Down_Info *info;
476 ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
479 ev->window = window->id;
480 ev->event_window = window->id;
481 ev->timestamp = input->timestamp;
482 ev->x = input->pointer.sx;
483 ev->y = input->pointer.sy;
484 ev->root.x = input->pointer.sx;
485 ev->root.y = input->pointer.sy;
486 ev->modifiers = input->keyboard.modifiers;
487 ev->multi.device = device;
489 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
490 if (device >= input->touch.max_count)
492 ev->multi.radius = 1;
493 ev->multi.radius_x = 1;
494 ev->multi.radius_y = 1;
495 ev->multi.pressure = 1.0;
496 ev->multi.angle = 0.0;
501 _ecore_wl2_input_touch_radius_calc(input->touch.touch_axis[device].radius_x,
502 input->touch.touch_axis[device].radius_y);
503 ev->multi.radius_x = input->touch.touch_axis[device].radius_x;
504 ev->multi.radius_y = input->touch.touch_axis[device].radius_y;
505 ev->multi.pressure = input->touch.touch_axis[device].pressure;
506 ev->multi.angle = input->touch.touch_axis[device].angle;
510 ev->multi.x = input->pointer.sx;
511 ev->multi.y = input->pointer.sy;
512 ev->multi.root.x = input->pointer.sx;
513 ev->multi.root.y = input->pointer.sy;
515 if ((input->focus.touch) && (input->focus.touch == window))
516 ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
517 else if ((input->focus.pointer) && (input->focus.pointer == window))
518 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
520 info = _ecore_wl2_input_mouse_down_info_get(device);
523 info->sx = input->pointer.sx;
524 info->sy = input->pointer.sy;
527 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _input_event_mouse_move_cb_free, ev->dev);
531 _ecore_wl2_input_mouse_wheel_send(Ecore_Wl2_Input *input, unsigned int axis, int value, unsigned int timestamp)
533 Ecore_Event_Mouse_Wheel *ev;
535 ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
538 ev->timestamp = timestamp;
539 ev->modifiers = input->keyboard.modifiers;
540 ev->x = input->pointer.sx;
541 ev->y = input->pointer.sy;
542 //TIZEN_ONLY(20190306): revert upstream patch
546 if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
551 else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
557 if (input->grab.window)
559 ev->window = input->grab.window->id;
560 ev->event_window = input->grab.window->id;
562 else if (input->focus.pointer)
564 ev->window = input->focus.pointer->id;
565 ev->event_window = input->focus.pointer->id;
566 ev->dev = _ecore_wl2_mouse_dev_get(input, input->focus.pointer->id);
568 else if (input->focus.touch)
570 ev->window = input->focus.touch->id;
571 ev->event_window = input->focus.touch->id;
572 ev->dev = _ecore_wl2_touch_dev_get(input, input->focus.touch->id);
577 ev->dev = _ecore_wl2_mouse_dev_get(input, ev->window);
579 ev->dev = _ecore_wl2_touch_dev_get(input, ev->window);
582 ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _input_event_mouse_wheel_cb_free, ev->dev);
586 _ecore_wl2_input_mouse_down_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
588 Ecore_Event_Mouse_Button *ev;
589 Ecore_Wl2_Mouse_Down_Info *info;
591 ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
594 if (button == BTN_LEFT)
596 else if (button == BTN_MIDDLE)
598 else if (button == BTN_RIGHT)
601 ev->buttons = button;
603 ev->timestamp = timestamp;
604 ev->x = input->pointer.sx;
605 ev->y = input->pointer.sy;
606 ev->root.x = input->pointer.sx;
607 ev->root.y = input->pointer.sy;
608 ev->modifiers = input->keyboard.modifiers;
610 ev->double_click = 0;
611 ev->triple_click = 0;
613 info = _ecore_wl2_input_mouse_down_info_get(device);
616 info->sx = input->pointer.sx;
617 info->sy = input->pointer.sy;
618 if (info->triple_click)
621 info->last_last_win = 0;
622 info->last_event_win = 0;
623 info->last_last_event_win = 0;
625 info->last_last_time = 0;
628 if (((int)(timestamp - info->last_time) <= (int)(1000 * 0.25)) &&
629 ((window) && (window->id == info->last_win) &&
630 (window->id == info->last_event_win)))
632 ev->double_click = 1;
633 info->double_click = EINA_TRUE;
637 info->double_click = EINA_FALSE;
638 info->triple_click = EINA_FALSE;
641 if (((int)(timestamp - info->last_last_time) <=
642 (int)(2 * 1000 * 0.25)) &&
643 ((window) && (window->id == info->last_win) &&
644 (window->id == info->last_last_win) &&
645 (window->id == info->last_event_win) &&
646 (window->id == info->last_last_event_win)))
648 ev->triple_click = 1;
649 info->triple_click = EINA_TRUE;
652 info->triple_click = EINA_FALSE;
655 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
656 if (device >= input->touch.max_count)
658 ev->multi.radius = 1;
659 ev->multi.radius_x = 1;
660 ev->multi.radius_y = 1;
661 ev->multi.pressure = 1.0;
662 ev->multi.angle = 0.0;
667 _ecore_wl2_input_touch_radius_calc(input->touch.touch_axis[device].radius_x,
668 input->touch.touch_axis[device].radius_y);
669 ev->multi.radius_x = input->touch.touch_axis[device].radius_x;
670 ev->multi.radius_y = input->touch.touch_axis[device].radius_y;
671 ev->multi.pressure = input->touch.touch_axis[device].pressure;
672 ev->multi.angle = input->touch.touch_axis[device].angle;
675 ev->multi.device = device;
676 ev->multi.x = input->pointer.sx;
677 ev->multi.y = input->pointer.sy;
678 ev->multi.root.x = input->pointer.sx;
679 ev->multi.root.y = input->pointer.sy;
683 ev->window = window->id;
684 ev->event_window = window->id;
686 if ((input->focus.touch) && (input->focus.touch == window))
687 ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
688 else if ((input->focus.pointer) && (input->focus.pointer == window))
689 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
692 //TIZEN_ONLY(20200408): add debug
693 ERR("[press] window = %p, time=%u button=%d", window, (unsigned int)timestamp, device);
696 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev,
697 _input_event_mouse_button_cb_free, ev->dev);
699 if ((info) && (!info->triple_click))
701 info->last_last_win = info->last_win;
702 info->last_win = ev->window;
703 info->last_last_event_win = info->last_event_win;
704 info->last_event_win = ev->window;
705 info->last_last_time = info->last_time;
706 info->last_time = timestamp;
711 _ecore_wl2_input_mouse_up_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
713 Ecore_Event_Mouse_Button *ev;
714 Ecore_Wl2_Mouse_Down_Info *info;
716 ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
719 if (button == BTN_LEFT)
721 else if (button == BTN_MIDDLE)
723 else if (button == BTN_RIGHT)
726 ev->buttons = button;
728 ev->timestamp = timestamp;
729 ev->x = input->pointer.sx;
730 ev->y = input->pointer.sy;
731 ev->root.x = input->pointer.sx;
732 ev->root.y = input->pointer.sy;
733 ev->modifiers = input->keyboard.modifiers;
735 ev->double_click = 0;
736 ev->triple_click = 0;
738 info = _ecore_wl2_input_mouse_down_info_get(device);
741 ev->double_click = info->double_click;
742 ev->triple_click = info->triple_click;
745 ev->multi.x = info->sx;
746 ev->multi.y = info->sy;
750 ev->multi.x = input->pointer.sx;
751 ev->multi.y = input->pointer.sy;
754 ev->multi.device = device;
755 ev->multi.radius = 1;
756 ev->multi.radius_x = 1;
757 ev->multi.radius_y = 1;
758 ev->multi.pressure = 1.0;
759 ev->multi.angle = 0.0;
760 ev->multi.root.x = input->pointer.sx;
761 ev->multi.root.y = input->pointer.sy;
763 ev->window = window->id;
764 ev->event_window = window->id;
766 if ((input->focus.touch) && (input->focus.touch == window))
767 ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
768 else if ((input->focus.pointer) && (input->focus.pointer == window))
769 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
771 //TIZEN_ONLY(20200408): add debug
772 ERR("[release] time=%u button=%d", (unsigned int)timestamp, device);
775 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev,
776 _input_event_mouse_button_cb_free, ev->dev);
779 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
780 if (device < input->touch.max_count)
782 input->touch.touch_axis[device].radius_x = 1.0;
783 input->touch.touch_axis[device].radius_y = 1.0;
784 input->touch.touch_axis[device].pressure = 1.0;
785 input->touch.touch_axis[device].angle = 0;
791 _input_event_focus_cb_free(void *data, void *event)
793 Ecore_Wl2_Event_Focus_In *ev = event;
796 ecore_wl2_display_disconnect(ev->display);
801 _ecore_wl2_input_focus_in_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
803 Ecore_Wl2_Event_Focus_In *ev;
805 ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_In));
808 ev->timestamp = input->timestamp;
809 ev->window = window->id;
810 ev->dev = _ecore_wl2_seat_dev_get(input, window->id);
811 ev->display = input->display;
813 ecore_event_add(ECORE_WL2_EVENT_FOCUS_IN, ev, _input_event_focus_cb_free,
818 _ecore_wl2_input_focus_out_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
820 Ecore_Wl2_Event_Focus_Out *ev;
822 ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_Out));
825 ev->timestamp = input->timestamp;
826 ev->window = window->id;
827 ev->dev = _ecore_wl2_seat_dev_get(input, window->id);
828 ev->display = input->display;
830 ecore_event_add(ECORE_WL2_EVENT_FOCUS_OUT, ev, _input_event_focus_cb_free,
835 _ecore_wl2_input_key_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes)
837 /* this function is copied, with slight changes in variable names, from KeyBind.c in libX11
838 * the license from that file can be found below:
842 Copyright 1985, 1987, 1998 The Open Group
844 Permission to use, copy, modify, distribute, and sell this software and its
845 documentation for any purpose is hereby granted without fee, provided that
846 the above copyright notice appear in all copies and that both that
847 copyright notice and this permission notice appear in supporting
850 The above copyright notice and this permission notice shall be included in
851 all copies or substantial portions of the Software.
853 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
854 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
855 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
856 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
857 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
858 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
860 Except as contained in this notice, the name of The Open Group shall not be
861 used in advertising or otherwise to promote the sale, use or other dealings
862 in this Software without prior written authorization from The Open Group.
865 if (!keysym) return 0;
867 /* check for possible control codes */
868 if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
870 Eina_Bool valid_control_code = EINA_TRUE;
871 unsigned long hbytes = 0;
874 hbytes = (keysym >> 8);
878 (((keysym >= XKB_KEY_BackSpace) && (keysym <= XKB_KEY_Clear)) ||
879 (keysym == XKB_KEY_Return) ||
880 (keysym == XKB_KEY_Escape) ||
881 (keysym == XKB_KEY_KP_Space) ||
882 (keysym == XKB_KEY_KP_Tab) ||
883 (keysym == XKB_KEY_KP_Enter) ||
884 ((keysym >= XKB_KEY_KP_Multiply) && (keysym <= XKB_KEY_KP_9)) ||
885 (keysym == XKB_KEY_KP_Equal) ||
886 (keysym == XKB_KEY_Delete))))))
889 if (keysym == XKB_KEY_KP_Space)
890 c = (XKB_KEY_space & 0x7F);
891 else if (hbytes == 0xFF)
896 /* We are building here a control code
897 for more details, read:
898 https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C0_.28ASCII_and_derivatives.29
901 if (((c >= '@') && (c <= '_')) || /* those are the one defined in C0 with capital letters */
902 ((c >= 'a') && (c <= 'z')) || /* the lowercase symbols (not part of the standard, but useful) */
905 else if (c == '\x7f')
907 /* following codes are alternatives, they are longer here, i dont want to change them */
909 c = '\000'; /* 0 code */
910 else if ((c >= '3') && (c <= '7'))
911 c -= ('3' - '\033'); /* from escape to unitseperator code*/
913 c = '\177'; /* delete code */
915 c = '_' & 0x1F; /* unit seperator code */
917 valid_control_code = EINA_FALSE;
919 if (valid_control_code)
926 /* if its not a control code, try to produce useful output */
927 if (!xkb_keysym_to_utf8(keysym, buffer, bytes))
935 _ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code)
937 if (xkb_keysym_get_name(keysym, buffer, size) != 0)
940 snprintf(buffer, size, "Keycode-%u", code);
944 _ecore_wl2_keyboard_dev_get(Ecore_Wl2_Input *input, int window_id)
946 Ecore_Wl2_Input_Devices *devices;
947 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
949 if (input->devmgr.last_device_kbd && input->devmgr.last_device_kbd->device)
951 return efl_ref(input->devmgr.last_device_kbd->device);
955 devices = _ecore_wl2_devices_get(input, window_id);
956 if (devices && devices->keyboard_dev)
957 return efl_ref(devices->keyboard_dev);
963 _ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_keysym_t sym, xkb_keysym_t sym_name, unsigned int code, unsigned int state, unsigned int timestamp, Eina_Bool cancel, Eina_Bool repeat)
966 char key[256] = "", keyname[256] = "", compose[256] = "";
967 int name_len, key_len, comp_len;
969 /*try to get a name or utf char of the given symbol */
970 _ecore_wl2_input_symbol_rep_find(sym, key, sizeof(key), code);
971 _ecore_wl2_input_symbol_rep_find(sym_name, keyname, sizeof(keyname), code);
972 _ecore_wl2_input_key_translate(sym, input->keyboard.modifiers,
973 compose, sizeof(compose));
975 name_len = strlen(keyname);
976 key_len = strlen(key);
977 comp_len = strlen(compose);
979 ev = calloc(1, sizeof(Ecore_Event_Key) + key_len + name_len + comp_len + 3);
982 ev->keyname = (char *)(ev + 1);
983 ev->key = ev->keyname + name_len + 1;
984 ev->compose = comp_len ? ev->key + key_len + 1 : NULL;
985 ev->string = ev->compose;
986 ev->event_flags = ECORE_EVENT_FLAG_NONE;
988 ev->event_flags |= ECORE_EVENT_FLAG_CANCEL;
990 ev->event_flags |= ECORE_EVENT_FLAG_REPEAT;
992 strcpy((char *)ev->keyname, keyname);
993 strcpy((char *)ev->key, key);
994 if (comp_len) strcpy((char *)ev->compose, compose);
996 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
999 ev->window = window->id;
1000 ev->event_window = window->id;
1001 ev->dev = _ecore_wl2_keyboard_dev_get(input, window->id);
1005 ev->window = (uintptr_t)NULL;
1006 ev->event_window = (uintptr_t)NULL;
1007 ev->dev = _ecore_wl2_keyboard_dev_get(input, 0);
1010 ev->timestamp = timestamp;
1011 ev->modifiers = input->keyboard.modifiers;
1014 /* DBG("Emitting Key event (%s,%s,%s,%s)\n", ev->keyname, ev->key, ev->compose, ev->string); */
1017 ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, _input_event_key_cb_free, ev->dev);
1019 ecore_event_add(ECORE_EVENT_KEY_UP, ev, _input_event_key_cb_free, ev->dev);
1023 _ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, unsigned int button)
1025 input->grab.window = window;
1026 input->grab.button = button;
1030 _ecore_wl2_input_ungrab(Ecore_Wl2_Input *input)
1032 if ((input->grab.window) && (input->grab.button) && (input->grab.count))
1033 _ecore_wl2_input_mouse_up_send(input, input->grab.window, 0,
1034 input->grab.button, input->grab.timestamp);
1036 input->grab.window = NULL;
1037 input->grab.button = 0;
1038 input->grab.count = 0;
1039 input->grab.touch_count = 0;
1043 _pointer_cb_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy)
1045 Ecore_Wl2_Input *input;
1046 Ecore_Wl2_Window *window;
1047 const char *config_cursor_name;
1052 /* trap for a surface that was just destroyed */
1053 if (!surface) return;
1055 if (!input->timestamp)
1059 gettimeofday(&tv, NULL);
1060 input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
1063 input->display->serial = serial;
1064 input->pointer.enter_serial = serial;
1065 input->pointer.sx = wl_fixed_to_double(sx);
1066 input->pointer.sy = wl_fixed_to_double(sy);
1068 // Cursor change from configuration is applied only for default cursor
1069 if (eina_streq(input->cursor.theme_name, "default"))
1071 _ecore_wl2_cursor_config_reload();
1072 config_cursor_name = _ecore_wl2_cursor_config_name_get();
1073 if (config_cursor_name)
1075 if (!input->cursor.name || !eina_streq(input->cursor.name, config_cursor_name))
1076 eina_stringshare_replace(&input->cursor.name, config_cursor_name);
1080 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1081 // TIZEN_ONLY(20230330): support client that requests to unset cursor
1082 /* The cursor on the surface is undefined until we set it */
1083 if (!input->cursor.name)
1084 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
1086 ecore_wl2_input_cursor_from_name_set(input, input->cursor.name);
1090 /* find the window which this surface belongs to */
1091 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1092 if (!window) return;
1094 // TIZEN_ONLY(20190729): do not generate duplicated mouse in events
1095 if (input->focus.pointer == window) return;
1098 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1099 window->pointer.device = input;
1101 input->focus.prev_pointer = NULL;
1102 input->focus.pointer = window;
1104 _ecore_wl2_input_mouse_in_send(input, window);
1108 _pointer_cb_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
1110 Ecore_Wl2_Input *input;
1111 Ecore_Wl2_Window *window;
1116 input->display->serial = serial;
1117 input->focus.prev_pointer = input->focus.pointer;
1118 input->focus.pointer = NULL;
1120 /* trap for a surface that was just destroyed */
1121 if (!surface) return;
1123 /* find the window which this surface belongs to */
1124 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1125 if (!window) return;
1127 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1128 window->pointer.device = NULL;
1131 _ecore_wl2_input_mouse_out_send(input, window);
1135 _pointer_cb_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy)
1137 Ecore_Wl2_Input *input;
1138 Ecore_Wl2_Window *window;
1143 input->timestamp = timestamp;
1144 input->pointer.sx = wl_fixed_to_double(sx);
1145 input->pointer.sy = wl_fixed_to_double(sy);
1147 /* get currently focused window */
1148 window = input->focus.pointer;
1149 if (!window) return;
1151 /* NB: Unsure if we need this just yet, so commented out for now */
1152 /* if ((input->pointer.sx > window->geometry.w) || */
1153 /* (input->pointer.sy > window->geometry.h)) */
1157 if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1) && (input->grab.count == 0))
1160 _ecore_wl2_input_mouse_move_send(input, window, 0);
1164 _pointer_cb_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state)
1166 Ecore_Wl2_Input *input;
1171 input->display->serial = serial;
1172 input->timestamp = timestamp;
1174 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
1176 if ((input->focus.pointer) &&
1177 (!input->grab.window) && (!input->grab.count))
1179 _ecore_wl2_input_grab(input, input->focus.pointer, button);
1180 input->grab.timestamp = timestamp;
1183 if (input->focus.pointer)
1186 if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1) && (input->grab.count == 0))
1187 _ecore_wl2_input_mouse_move_send(input, input->focus.pointer, 0);
1189 _ecore_wl2_input_mouse_down_send(input, input->focus.pointer,
1190 0, button, timestamp);
1193 input->grab.count++;
1197 if (input->focus.pointer)
1198 _ecore_wl2_input_mouse_up_send(input, input->focus.pointer,
1199 0, button, timestamp);
1201 if (input->grab.count) input->grab.count--;
1202 if ((input->grab.window) && (input->grab.button == button) &&
1203 (!input->grab.count))
1204 _ecore_wl2_input_ungrab(input);
1209 _pointer_cb_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value)
1211 Ecore_Wl2_Input *input;
1216 input->timestamp = timestamp;
1218 _ecore_wl2_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value),
1222 static const struct wl_pointer_listener _pointer_listener =
1230 NULL, /* axis_source */
1231 NULL, /* axis_stop */
1232 NULL, /* axis_discrete */
1235 // TIZEN_ONLY(20230802): ecore_input: add Ecore_Event_Mouse_Relative_Move struct
1237 _ecore_wl2_input_mouse_relative_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int dx, int dy, int dx_unaccel, int dy_unaccel)
1239 Ecore_Event_Mouse_Relative_Move *ev;
1241 ev = calloc(1, sizeof(Ecore_Event_Mouse_Relative_Move));
1244 ev->window = window->id;
1245 ev->event_window = window->id;
1246 ev->timestamp = input->timestamp;
1247 ev->modifiers = input->keyboard.modifiers;
1250 ev->dx_unaccel = dx_unaccel;
1251 ev->dy_unaccel = dy_unaccel;
1253 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
1255 ERR("[Relative Move] timestamp=%u dx=%d, dy=%d, dx_unaccel=%d, dy_unaccel=%d", ev->timestamp, ev->dx, ev->dy, ev->dx_unaccel, ev->dy_unaccel);
1256 ecore_event_add(ECORE_EVENT_MOUSE_RELATIVE_MOVE, ev, NULL, NULL);
1260 // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
1262 _relative_pointer_cb_relative_motion(void *data, struct zwp_relative_pointer_v1* relative_pointer,
1263 uint32_t ts_high, uint32_t ts_low, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel)
1265 Ecore_Wl2_Input *input;
1266 Ecore_Wl2_Window *window;
1267 (void) relative_pointer;
1273 ERR("[relative_pointer] ts_high=%u, ts_low=%u, dx=%d, dy=%d, dx_unaccel=%d, dy_unaccel=%d",
1274 ts_high, ts_low, wl_fixed_to_int(dx), wl_fixed_to_int(dy), wl_fixed_to_int(dx_unaccel), wl_fixed_to_int(dy_unaccel));
1276 input->timestamp = (unsigned int)ts_low;
1278 /* get currently focused window */
1279 window = input->focus.pointer;
1280 if (!window) return;
1282 _ecore_wl2_input_mouse_relative_move_send(input, window, wl_fixed_to_int(dx), wl_fixed_to_int(dy),
1283 wl_fixed_to_int(dx_unaccel), wl_fixed_to_int(dy_unaccel));
1286 static const struct zwp_relative_pointer_v1_listener _relative_pointer_listener = {
1287 _relative_pointer_cb_relative_motion,
1291 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
1293 _locked_pointer_cb_locked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1 EINA_UNUSED)
1295 Ecore_Wl2_Input *input = (Ecore_Wl2_Input *)data;
1298 ERR("[locked pointer] locked");
1299 input->pointer_locked = EINA_TRUE;
1303 _locked_pointer_cb_unlocked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1 EINA_UNUSED)
1305 Ecore_Wl2_Input *input = (Ecore_Wl2_Input *)data;
1308 ERR("[locked pointer] unlocked");
1309 input->pointer_locked = EINA_FALSE;
1312 static const struct zwp_locked_pointer_v1_listener _locked_pointer_listener = {
1313 _locked_pointer_cb_locked,
1314 _locked_pointer_cb_unlocked,
1319 _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size)
1321 Ecore_Wl2_Input *input;
1322 Ecore_Wl2_Event_Seat_Keymap_Changed *ev;
1333 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
1339 map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1340 if (map == MAP_FAILED)
1346 /* free any existing keymap and state */
1347 if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
1348 if (input->xkb.state) xkb_state_unref(input->xkb.state);
1349 if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
1352 xkb_map_new_from_string(input->display->xkb_context, map,
1353 XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1358 if (!input->xkb.keymap)
1360 ERR("Failed to compile keymap");
1364 input->xkb.state = xkb_state_new(input->xkb.keymap);
1365 input->xkb.maskless_state = xkb_state_new(input->xkb.keymap);
1367 if (!input->xkb.state || !input->xkb.maskless_state)
1369 ERR("Failed to create keymap state");
1370 xkb_map_unref(input->xkb.keymap);
1371 input->xkb.keymap = NULL;
1375 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
1376 _tizen_api_version = 0.0;
1379 if (!(locale = getenv("LC_ALL")))
1380 if (!(locale = getenv("LC_CTYPE")))
1381 if (!(locale = getenv("LANG")))
1384 if (input->xkb.compose_table)
1385 xkb_compose_table_unref(input->xkb.compose_table);
1387 input->xkb.compose_table =
1388 xkb_compose_table_new_from_locale(input->display->xkb_context,
1389 locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
1390 if (input->xkb.compose_state)
1391 xkb_compose_state_unref(input->xkb.compose_state);
1392 input->xkb.compose_state = NULL;
1394 if (input->xkb.compose_table)
1396 input->xkb.compose_state =
1397 xkb_compose_state_new(input->xkb.compose_table,
1398 XKB_COMPOSE_STATE_NO_FLAGS);
1401 ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1405 ev->display = input->display;
1406 input->display->refs++;
1407 ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYMAP_CHANGED, ev,
1408 _display_event_free, ev->display);
1411 input->xkb.control_mask =
1412 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CTRL);
1413 input->xkb.alt_mask =
1414 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_ALT);
1415 input->xkb.shift_mask =
1416 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_SHIFT);
1417 input->xkb.win_mask =
1418 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_LOGO);
1419 input->xkb.scroll_mask =
1420 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_SCROLL);
1421 input->xkb.num_mask =
1422 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_NUM);
1423 input->xkb.caps_mask =
1424 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CAPS);
1425 input->xkb.altgr_mask =
1426 1 << xkb_map_mod_get_index(input->xkb.keymap, "ISO_Level3_Shift");
1430 _keyboard_cb_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED)
1432 Ecore_Wl2_Input *input;
1433 Ecore_Wl2_Window *window;
1438 input->display->serial = serial;
1440 if (!input->timestamp)
1444 gettimeofday(&tv, NULL);
1445 input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
1448 /* find the window which this surface belongs to */
1449 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1450 if (!window) return;
1452 input->focus.keyboard = window;
1453 _ecore_wl2_input_focus_in_send(window, input);
1457 _keyboard_cb_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
1459 Ecore_Wl2_Input *input;
1460 Ecore_Wl2_Window *window;
1465 input->display->serial = serial;
1467 // TIZEN_ONLY(20160615): Fix key repeat logic.
1469 input->repeat.sym = 0;
1470 input->repeat.key = 0;
1471 input->repeat.time = 0;
1472 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1473 input->repeat.timer = NULL;
1476 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1479 if (input->focus.keyboard != window)
1480 ERR("Received keyboard.leave when keyboard did not have enter");
1482 input->focus.keyboard = NULL;
1484 _ecore_wl2_input_focus_out_send(window, input);
1488 _keyboard_cb_repeat(void *data)
1490 Ecore_Wl2_Input *input;
1493 if (!input || !input->repeat.timer) return ECORE_CALLBACK_CANCEL;
1495 if (!input->repeat.repeating)
1498 double cur_time = ecore_time_get();
1499 if (cur_time > input->repeat.intime)
1501 input->repeat.intime = cur_time + (cur_time - input->repeat.intime) + 0.0166;
1502 ecore_timer_interval_set(input->repeat.timer, input->repeat.intime - cur_time);
1503 return ECORE_CALLBACK_RENEW;
1506 if (input->repeat.key == 105 || input->repeat.key == 106 ) // Left:105 Right:106
1507 ecore_timer_interval_set(input->repeat.timer, input->repeat.horizontal.rate);
1508 else if (input->repeat.key == 103 || input->repeat.key == 108) // UP:103 Down:108
1509 ecore_timer_interval_set(input->repeat.timer, input->repeat.vertical.rate);
1511 ecore_timer_interval_set(input->repeat.timer, input->repeat.rate);
1513 input->repeat.repeating = EINA_TRUE;
1516 if (input->repeat.key == 105 || input->repeat.key == 106 )
1517 input->repeat.time += (int)(input->repeat.horizontal.rate * 1000.0);
1518 else if (input->repeat.key == 103 || input->repeat.key == 108)
1519 input->repeat.time += (int)(input->repeat.vertical.rate * 1000.0);
1521 input->repeat.time += (int)(input->repeat.rate * 1000.0);
1523 _ecore_wl2_input_key_send(input, input->repeat_win,
1524 input->repeat.sym, input->repeat.sym_name,
1525 input->repeat.key + 8,
1526 WL_KEYBOARD_KEY_STATE_PRESSED,
1527 input->repeat.time, EINA_FALSE, EINA_TRUE);
1529 return ECORE_CALLBACK_RENEW;
1532 /* from weston/clients/window.c */
1533 /* Translate symbols appropriately if a compose sequence is being entered */
1535 process_key_press(xkb_keysym_t sym, Ecore_Wl2_Input *input)
1537 if (!input->xkb.compose_state)
1539 if (sym == XKB_KEY_NoSymbol)
1541 if (xkb_compose_state_feed(input->xkb.compose_state, sym) !=
1542 XKB_COMPOSE_FEED_ACCEPTED)
1545 switch (xkb_compose_state_get_status(input->xkb.compose_state))
1547 case XKB_COMPOSE_COMPOSING:
1548 return XKB_KEY_NoSymbol;
1549 case XKB_COMPOSE_COMPOSED:
1550 return xkb_compose_state_get_one_sym(input->xkb.compose_state);
1551 case XKB_COMPOSE_CANCELLED:
1552 return XKB_KEY_NoSymbol;
1553 case XKB_COMPOSE_NOTHING:
1560 _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state)
1562 Ecore_Wl2_Input *input;
1563 Ecore_Wl2_Window *window;
1565 xkb_keysym_t sym = XKB_KEY_NoSymbol, sym_name = XKB_KEY_NoSymbol;
1566 const xkb_keysym_t *syms;
1567 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1568 struct wl_surface *surface = NULL;
1570 static Eina_Bool _key_event_cancel = EINA_FALSE;
1575 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1578 window = input->key_win;
1580 else if ((input->repeat.key) && (keycode == input->repeat.key))
1582 window = input->repeat_win;
1586 window = input->focus.keyboard; /* try to get the window which has keyboard focus */
1588 input->display->serial = serial;
1589 input->timestamp = timestamp;
1591 /* xkb rules reflect X broken keycodes, so offset by 8 */
1594 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1597 INF("window is not focused");
1598 surface = (struct wl_surface *) eina_hash_find(_ecore_wl2_keygrab_hash_get(), &code);
1601 window = ecore_wl2_window_surface_find(surface);
1602 INF("keycode(%d) is grabbed in the window(%p)", code, window);
1606 //key event callback can be called even though surface is not exist.
1607 //TODO: Ecore_Event_Key have event_window info, so if (surface == NULL), we should generate proper window info
1608 INF("surface is not exist");
1613 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
1614 if (_tizen_api_version == 0.0) _ecore_wl2_input_key_conversion_set(input);
1616 // if it is one of the back/menu/home key and _tizen_api_version is less than 2.4.
1617 if (0.0 < _tizen_api_version && _tizen_api_version < 2.4)
1618 code = _ecore_wl2_input_convert_old_keys(code);
1621 //TIZEN_ONLY(20200408): add debug
1622 ERR("Key[%d] event occurs %u", code, timestamp);
1625 if (xkb_state_key_get_syms(input->xkb.state, code, &syms) == 1)
1627 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1628 sym = process_key_press(sym, input);
1629 sym_name = xkb_state_key_get_one_sym(input->xkb.maskless_state, code);
1631 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1632 if (input->key_win) input->key_win = NULL;
1634 if (sym == XKB_KEY_Cancel)
1636 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1637 _key_event_cancel = EINA_TRUE;
1639 _key_event_cancel = EINA_FALSE;
1643 _ecore_wl2_input_key_send(input, window, sym, sym_name, code,
1644 state, timestamp, _key_event_cancel, EINA_FALSE);
1646 if (!xkb_keymap_key_repeats(input->xkb.keymap, code)) return;
1648 if ((state == WL_KEYBOARD_KEY_STATE_RELEASED) &&
1649 (keycode == input->repeat.key))
1651 input->repeat.sym = 0;
1652 input->repeat.key = 0;
1653 input->repeat.time = 0;
1654 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1655 input->repeat.timer = NULL;
1656 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1657 input->repeat_win = NULL;
1660 else if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1662 /* don't setup key repeat timer if not enabled */
1663 if (!input->repeat.enabled) return;
1665 input->repeat.sym = sym;
1666 input->repeat.sym_name = sym;
1667 input->repeat.key = keycode;
1668 input->repeat.time = timestamp;
1669 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1670 input->repeat_win = window;
1673 /* Delete this timer if there is still one */
1674 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1675 input->repeat.timer = NULL;
1677 if (!input->repeat.timer)
1679 input->repeat.repeating = EINA_FALSE;
1680 if (keycode == 105 || keycode == 106 )
1682 input->repeat.timer = ecore_timer_add(input->repeat.horizontal.delay, _keyboard_cb_repeat, input);
1683 input->repeat.intime = (ecore_time_get() + input->repeat.horizontal.delay + 0.0166);
1685 else if (keycode == 103 || keycode == 108)
1687 input->repeat.timer = ecore_timer_add(input->repeat.vertical.delay, _keyboard_cb_repeat, input);
1688 input->repeat.intime = (ecore_time_get() + input->repeat.vertical.delay + 0.0166);
1692 input->repeat.timer = ecore_timer_add(input->repeat.delay, _keyboard_cb_repeat, input);
1693 input->repeat.intime = (ecore_time_get() + input->repeat.delay + 0.0166);
1701 _keyboard_cb_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group)
1703 Ecore_Wl2_Input *input;
1704 xkb_mod_mask_t mask;
1709 /* skip PC style modifiers if we have no keymap */
1710 if (!input->xkb.keymap) return;
1712 xkb_state_update_mask(input->xkb.state,
1713 depressed, latched, locked, 0, 0, group);
1716 xkb_state_serialize_mods(input->xkb.state,
1717 XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
1719 /* reset modifiers to default */
1720 input->keyboard.modifiers = 0;
1722 if (mask & input->xkb.control_mask)
1723 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CTRL;
1724 if (mask & input->xkb.alt_mask)
1725 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALT;
1726 if (mask & input->xkb.shift_mask)
1727 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
1728 if (mask & input->xkb.win_mask)
1729 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_WIN;
1730 if (mask & input->xkb.altgr_mask)
1731 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
1732 if (mask & input->xkb.scroll_mask)
1733 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SCROLL;
1734 if (mask & input->xkb.num_mask)
1735 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_NUM;
1736 if (mask & input->xkb.caps_mask)
1737 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CAPS;
1740 mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_LOCKED);
1741 if (mask & input->xkb.scroll_mask)
1742 input->keyboard.modifiers |= ECORE_EVENT_LOCK_SCROLL;
1743 if (mask & input->xkb.num_mask)
1744 input->keyboard.modifiers |= ECORE_EVENT_LOCK_NUM;
1745 if (mask & input->xkb.caps_mask)
1746 input->keyboard.modifiers |= ECORE_EVENT_LOCK_CAPS;
1750 _keyboard_cb_repeat_setup(void *data, struct wl_keyboard *keyboard EINA_UNUSED, int32_t rate, int32_t delay)
1752 Ecore_Wl2_Input *input;
1753 Ecore_Wl2_Event_Seat_Keyboard_Repeat_Changed *ev;
1760 input->repeat.enabled = EINA_FALSE;
1764 input->repeat.enabled = EINA_TRUE;
1765 if (!input->repeat.changed)
1767 //TIZEN_ONLY(20200128): Tizen calculates rate differently.
1768 //input->repeat.rate = (1.0 / rate);
1770 input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = (rate / 1000.0);
1771 input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = (delay / 1000.0);
1773 ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1777 ev->display = input->display;
1778 ev->display->refs++;
1779 ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYBOARD_REPEAT_CHANGED, ev,
1780 _display_event_free, ev->display);
1784 static const struct wl_keyboard_listener _keyboard_listener =
1786 _keyboard_cb_keymap,
1790 _keyboard_cb_modifiers,
1791 _keyboard_cb_repeat_setup
1795 _touch_cb_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface, int id, wl_fixed_t x, wl_fixed_t y)
1797 Ecore_Wl2_Input *input;
1798 Ecore_Wl2_Window *window;
1801 //TIZEN_ONLY(20200408): add debug
1804 ERR("input is NULL");
1808 /* find the window which this surface belongs to */
1809 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1810 //TIZEN_ONLY(20200408): add debug
1813 ERR("window is NULL");
1818 input->focus.touch = window;
1819 input->timestamp = timestamp;
1820 input->grab.touch_count++;
1821 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1822 input->grab.touch_array[id] = EINA_TRUE;
1825 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1826 _ecore_wl2_input_touch_axis_process(input, id);
1829 // TIZEN_ONLY(20171207): do not send pointer enter about all of touch down
1831 _pointer_cb_enter(data, NULL, serial, surface, x, y);
1834 input->grab.count++;
1836 if ((!input->grab.window) && (input->focus.touch) && input->grab.touch_count == 1)
1838 _pointer_cb_enter(data, NULL, serial, surface, x, y);
1839 _ecore_wl2_input_grab(input, input->focus.touch, BTN_LEFT);
1840 input->grab.timestamp = timestamp;
1844 input->pointer.sx = wl_fixed_to_double(x);
1845 input->pointer.sy = wl_fixed_to_double(y);
1850 // TIZEN_ONLY(20171107): always send move event when touch down event is occurred
1851 _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1853 _ecore_wl2_input_mouse_down_send(input, input->focus.touch, id,
1854 BTN_LEFT, timestamp);
1858 _touch_cb_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id)
1860 Ecore_Wl2_Input *input;
1862 //TIZEN_ONLY(20200408): add debug
1863 //if (!input) return;
1864 //EINA_SAFETY_ON_NULL_RETURN(input->focus.touch); //if this is happening, then we are getting up events in a invalid state
1868 ERR("input is NULL");
1871 if (!input->focus.touch)
1873 ERR("touch_focus is false");
1877 input->timestamp = timestamp;
1878 input->display->serial = serial;
1880 _ecore_wl2_input_mouse_up_send(input, input->focus.touch, id,
1881 BTN_LEFT, timestamp);
1883 if (input->grab.count) input->grab.count--;
1884 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1885 if (input->grab.touch_array[id] && input->grab.touch_count) input->grab.touch_count--;
1886 if (input->grab.touch_array[id]) input->grab.touch_array[id] = EINA_FALSE;
1888 if ((input->grab.window) && (input->grab.button == BTN_LEFT) &&
1889 (!input->grab.count) && !input->grab.touch_count)
1890 _ecore_wl2_input_ungrab(input);
1892 if (input->grab.touch_count == 0) input->focus.touch = NULL;
1897 _touch_cb_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id, wl_fixed_t x, wl_fixed_t y)
1899 Ecore_Wl2_Input *input;
1902 //TIZEN_ONLY(20200408): add debug
1903 //if (!input) return;
1904 //if (!input->focus.touch) return;
1907 ERR("input is NULL");
1910 if (!input->focus.touch)
1912 ERR("touch_focus is false");
1916 input->timestamp = timestamp;
1917 input->pointer.sx = wl_fixed_to_int(x);
1918 input->pointer.sy = wl_fixed_to_int(y);
1920 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1921 _ecore_wl2_input_touch_axis_process(input, id);
1924 _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1928 _touch_cb_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED)
1934 _touch_cb_cancel(void *data, struct wl_touch *touch EINA_UNUSED)
1936 //TIZEN_ONLY(20171107): generate mouse button cancel event
1937 Ecore_Event_Mouse_Button *ev;
1938 Ecore_Wl2_Input *input;
1940 if (!(input = data)) return;
1941 if (!input->focus.touch) return;
1943 if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
1944 EINA_SAFETY_ON_NULL_RETURN(ev);
1946 ev->timestamp = _timestamp_get();
1947 ev->same_screen = 1;
1948 ev->window = input->focus.touch->id;
1949 ev->event_window = ev->window;
1953 ev->root.x = input->pointer.sx;
1954 ev->root.y = input->pointer.sy;
1955 ev->x = input->pointer.sx;
1956 ev->y = input->pointer.sy;
1957 ev->modifiers = input->keyboard.modifiers;
1959 ev->dev = _ecore_wl2_touch_dev_get(input, ev->window);
1961 //TIZEN_ONLY(20200408): add debug
1962 ERR("[cancel] time=%u window=0x%x", ev->timestamp, ev->window);
1965 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1966 for (int i = 0; i < ECORE_WL2_TOUCH_MAX; i++)
1967 input->grab.touch_array[i] = EINA_FALSE;
1968 input->focus.touch = NULL;
1969 input->grab.count = 0;
1970 _ecore_wl2_input_ungrab(input);
1973 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, NULL, _input_event_mouse_button_cb_free);
1977 static const struct wl_touch_listener _touch_listener =
1984 NULL, // XXX: FIXME: add shape
1985 NULL, // XXX: FIXME: add orientation
1989 _data_cb_offer(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
1991 Ecore_Wl2_Input *input;
1996 _ecore_wl2_dnd_add(input, offer);
2000 _data_cb_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer)
2002 Ecore_Wl2_Input *input;
2007 _ecore_wl2_dnd_enter(input, offer, surface,
2008 wl_fixed_to_int(x), wl_fixed_to_int(y), serial);
2012 _data_cb_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
2014 Ecore_Wl2_Input *input;
2019 _ecore_wl2_dnd_leave(input);
2023 _data_cb_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, wl_fixed_t x, wl_fixed_t y)
2025 Ecore_Wl2_Input *input;
2030 _ecore_wl2_dnd_motion(input, wl_fixed_to_int(x),
2031 wl_fixed_to_int(y), serial);
2035 _data_cb_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
2037 Ecore_Wl2_Input *input;
2042 _ecore_wl2_dnd_drop(input);
2046 _data_cb_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
2048 Ecore_Wl2_Input *input;
2053 _ecore_wl2_dnd_selection(input, offer);
2056 static const struct wl_data_device_listener _data_listener =
2067 _seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
2069 Ecore_Wl2_Event_Seat_Capabilities *ev;
2070 Ecore_Wl2_Input *input;
2075 if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->wl.pointer))
2077 input->wl.pointer = wl_seat_get_pointer(seat);
2078 wl_pointer_set_user_data(input->wl.pointer, input);
2079 wl_pointer_add_listener(input->wl.pointer, &_pointer_listener, input);
2081 // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
2082 if (input->display->wl.relative_pointer_manager)
2084 input->wl.relative_pointer =
2085 zwp_relative_pointer_manager_v1_get_relative_pointer(
2086 input->display->wl.relative_pointer_manager, input->wl.pointer);
2087 zwp_relative_pointer_v1_add_listener(input->wl.relative_pointer,
2088 &_relative_pointer_listener, input);
2092 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2093 if (!input->cursor.surface)
2095 input->cursor.surface =
2096 wl_compositor_create_surface(input->display->wl.compositor);
2098 if (input->cursor.surface)
2100 if (input->display->wl.tz_policy)
2102 tizen_policy_set_role(input->display->wl.tz_policy,
2103 input->cursor.surface, "wl_pointer-cursor");
2107 if (!input->cursor.theme)
2109 input->cursor.theme =
2110 wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size,
2111 input->display->wl.shm);
2115 else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer))
2117 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2118 if (input->cursor.surface) wl_surface_destroy(input->cursor.surface);
2119 input->cursor.surface = NULL;
2120 if (input->cursor.theme)
2121 wl_cursor_theme_destroy(input->cursor.theme);
2122 input->cursor.theme = NULL;
2124 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
2125 if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
2126 wl_pointer_release(input->wl.pointer);
2129 wl_pointer_destroy(input->wl.pointer);
2130 input->wl.pointer = NULL;
2133 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->wl.keyboard))
2135 input->wl.keyboard = wl_seat_get_keyboard(seat);
2136 wl_keyboard_set_user_data(input->wl.keyboard, input);
2137 wl_keyboard_add_listener(input->wl.keyboard, &_keyboard_listener, input);
2139 else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->wl.keyboard))
2141 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
2142 if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
2143 wl_keyboard_release(input->wl.keyboard);
2146 wl_keyboard_destroy(input->wl.keyboard);
2147 input->wl.keyboard = NULL;
2150 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->wl.touch))
2152 input->wl.touch = wl_seat_get_touch(seat);
2153 wl_touch_set_user_data(input->wl.touch, input);
2154 wl_touch_add_listener(input->wl.touch, &_touch_listener, input);
2156 else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->wl.touch))
2158 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
2159 if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
2160 wl_touch_release(input->wl.touch);
2163 wl_touch_destroy(input->wl.touch);
2164 input->wl.touch = NULL;
2165 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
2166 _ecore_wl2_input_key_conversion_clean_up();
2169 ecore_wl2_display_flush(input->display);
2171 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
2172 input->caps_update = EINA_TRUE;
2175 ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Capabilities));
2176 EINA_SAFETY_ON_NULL_RETURN(ev);
2179 ev->pointer_enabled = !!(caps & WL_SEAT_CAPABILITY_POINTER);
2180 ev->keyboard_enabled = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD);
2181 ev->touch_enabled = !!(caps & WL_SEAT_CAPABILITY_TOUCH);
2182 ev->display = input->display;
2183 ev->display->refs++;
2185 ecore_event_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED, ev,
2186 _display_event_free, ev->display);
2190 _cb_seat_event_free(void *data EINA_UNUSED, void *event)
2192 Ecore_Wl2_Event_Seat_Name *ev;
2195 eina_stringshare_del(ev->name);
2196 ecore_wl2_display_disconnect(ev->display);
2201 _seat_cb_name(void *data, struct wl_seat *seat EINA_UNUSED, const char *name)
2203 Ecore_Wl2_Event_Seat_Name *ev;
2204 Ecore_Wl2_Input *input;
2207 eina_stringshare_replace(&input->name, name);
2209 ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Name));
2210 EINA_SAFETY_ON_NULL_RETURN(ev);
2213 ev->name = eina_stringshare_add(name);
2214 ev->display = input->display;
2215 ev->display->refs++;
2217 ecore_event_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED, ev,
2218 _cb_seat_event_free, NULL);
2221 static const struct wl_seat_listener _seat_listener =
2223 _seat_cb_capabilities,
2228 _ecore_wl2_input_cursor_setup(Ecore_Wl2_Input *input)
2231 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2233 input->cursor.size = 32;
2234 tmp = getenv("ECORE_WL_CURSOR_SIZE");
2235 if (tmp) input->cursor.size = atoi(tmp);
2237 if (!input->cursor.name)
2238 input->cursor.name = eina_stringshare_add("left_ptr");
2240 unsigned int cursor_size;
2241 char *cursor_theme_name;
2243 tmp = getenv("ECORE_WL_CURSOR_SIZE");
2245 cursor_size = atoi(tmp);
2248 ecore_wl2_input_cursor_size_set(input, cursor_size);
2250 cursor_theme_name = getenv("ECORE_WL_CURSOR_THEME_NAME");
2251 ecore_wl2_input_cursor_theme_name_set(input, cursor_theme_name);
2253 // TIZEN_ONLY(20230330): support client that requests to unset cursor
2254 if (!input->cursor.name)
2255 input->cursor.name = eina_stringshare_add("left_ptr");
2261 // TIZEN_ONLY(20200219): cleanup cursor resources when a Ecore_Wl2_Input is destroy
2263 _ecore_wl2_input_cursor_cleanup(Ecore_Wl2_Input *input)
2265 /* If remove a cursor in this step,
2266 * it maybe occurred blink cursor so check this first
2268 // if (input->cursor.surface)
2269 // ecore_wl2_input_pointer_set(input, NULL, 0, 0);
2271 if (input->cursor.theme)
2272 wl_cursor_theme_destroy(input->cursor.theme);
2273 if (input->cursor.theme_name)
2274 eina_stringshare_del(input->cursor.theme_name);
2278 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2279 static const struct wl_callback_listener _pointer_surface_listener =
2285 _cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED)
2287 Ecore_Wl2_Input *input;
2289 if (!(input = data)) return;
2293 if (callback != input->cursor.frame_cb) return;
2294 wl_callback_destroy(callback);
2295 input->cursor.frame_cb = NULL;
2298 if (!input->cursor.name)
2300 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
2304 if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb))
2306 input->cursor.frame_cb = wl_surface_frame(input->cursor.surface);
2307 if (!input->cursor.frame_cb) return;
2309 wl_callback_add_listener(input->cursor.frame_cb,
2310 &_pointer_surface_listener, input);
2316 _ecore_wl2_input_cursor_update(void *data)
2318 Ecore_Wl2_Input *input;
2321 if (!input) return EINA_FALSE;
2323 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2325 if (input->wl.pointer)
2326 wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
2327 input->cursor.surface,
2328 input->cursor.hot_x, input->cursor.hot_y);
2329 ecore_wl2_display_flush(input->display);
2331 return ECORE_CALLBACK_RENEW;
2333 struct wl_cursor_image *cursor_image;
2334 struct wl_buffer *buffer;
2337 if ((!input) || (!input->cursor.cursor) || (!input->cursor.surface))
2340 cursor_image = input->cursor.cursor->images[input->cursor.current_index];
2341 if (!cursor_image) return ECORE_CALLBACK_RENEW;
2343 if ((buffer = wl_cursor_image_get_buffer(cursor_image)))
2345 ecore_wl2_input_pointer_set(input, input->cursor.surface,
2346 cursor_image->hotspot_x,
2347 cursor_image->hotspot_y);
2348 wl_surface_attach(input->cursor.surface, buffer, 0, 0);
2349 wl_surface_damage(input->cursor.surface, 0, 0,
2350 cursor_image->width, cursor_image->height);
2351 wl_surface_commit(input->cursor.surface);
2353 if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb))
2354 _cb_pointer_frame(input, NULL, 0);
2357 if (input->cursor.cursor->image_count <= 1)
2358 return ECORE_CALLBACK_CANCEL;
2360 delay = cursor_image->delay;
2361 input->cursor.current_index =
2362 (input->cursor.current_index + 1) % input->cursor.cursor->image_count;
2364 if (!input->cursor.timer)
2365 input->cursor.timer =
2366 ecore_timer_loop_add(delay / 1000.0,
2367 _ecore_wl2_input_cursor_update, input);
2369 ecore_timer_interval_set(input->cursor.timer, delay / 1000.0);
2371 return ECORE_CALLBACK_RENEW;
2377 _ecore_wl2_devices_free(Ecore_Wl2_Input_Devices *devices)
2379 if (devices->seat_dev)
2380 efl_unref(devices->seat_dev);
2381 if (devices->pointer_dev)
2382 efl_unref(devices->pointer_dev);
2383 if (devices->keyboard_dev)
2384 efl_unref(devices->keyboard_dev);
2385 if (devices->touch_dev)
2386 efl_unref(devices->touch_dev);
2392 _ecore_wl2_cb_device_event(void *data, int type, void *event)
2394 Ecore_Wl2_Input_Devices *devs, *devices = NULL;;
2395 Ecore_Wl2_Event_Device *ev = event;
2396 Ecore_Wl2_Input *input = data;
2399 if (input->id != ev->seat_id)
2400 return ECORE_CALLBACK_PASS_ON;
2402 EINA_LIST_FOREACH(input->devices_list, l, devs)
2404 if (devs->window_id == ev->window_id)
2411 if (type == ECORE_WL2_EVENT_DEVICE_ADDED)
2415 devices = calloc(1, sizeof(Ecore_Wl2_Input_Devices));
2416 EINA_SAFETY_ON_NULL_RETURN_VAL(devices, ECORE_CALLBACK_PASS_ON);
2417 input->devices_list =
2418 eina_list_append(input->devices_list, devices);
2419 devices->window_id = ev->window_id;
2422 if (ev->type == ECORE_WL2_DEVICE_TYPE_POINTER)
2423 devices->pointer_dev = efl_ref(ev->dev);
2424 else if (ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD)
2425 devices->keyboard_dev = efl_ref(ev->dev);
2426 else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH)
2427 devices->touch_dev = efl_ref(ev->dev);
2428 else if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
2429 devices->seat_dev = efl_ref(ev->dev);
2431 return ECORE_CALLBACK_PASS_ON;
2435 return ECORE_CALLBACK_PASS_ON;
2437 if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
2439 input->devices_list =
2440 eina_list_remove(input->devices_list, devices);
2441 _ecore_wl2_devices_free(devices);
2442 return ECORE_CALLBACK_PASS_ON;
2445 if ((ev->type == ECORE_WL2_DEVICE_TYPE_POINTER) &&
2446 (devices->pointer_dev == ev->dev))
2448 efl_unref(devices->pointer_dev);
2449 devices->pointer_dev = NULL;
2451 else if ((ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD) &&
2452 (devices->keyboard_dev == ev->dev))
2454 efl_unref(devices->keyboard_dev);
2455 devices->keyboard_dev = NULL;
2457 else if ((ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH) &&
2458 (devices->touch_dev == ev->dev))
2460 efl_unref(devices->touch_dev);
2461 devices->touch_dev = NULL;
2464 return ECORE_CALLBACK_PASS_ON;
2467 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
2469 _ecore_wl2_input_device_last_device_set(Ecore_Wl2_Tizen_Input_Device *dev)
2471 Ecore_Wl2_Input *input = dev->input;
2477 case ECORE_DEVICE_CLASS_MOUSE:
2478 input->devmgr.last_device_ptr = dev;
2480 case ECORE_DEVICE_CLASS_KEYBOARD:
2481 input->devmgr.last_device_kbd = dev;
2483 case ECORE_DEVICE_CLASS_TOUCH:
2484 input->devmgr.last_device_touch = dev;
2492 _ecore_wl2_input_device_last_device_unset(Ecore_Wl2_Tizen_Input_Device *dev)
2494 Ecore_Wl2_Input *input = dev->input;
2500 case ECORE_DEVICE_CLASS_MOUSE:
2501 if (input->devmgr.last_device_ptr == dev)
2502 input->devmgr.last_device_ptr = NULL;
2504 case ECORE_DEVICE_CLASS_KEYBOARD:
2505 if (input->devmgr.last_device_kbd == dev)
2506 input->devmgr.last_device_kbd = NULL;
2508 case ECORE_DEVICE_CLASS_TOUCH:
2509 if (input->devmgr.last_device_touch == dev)
2510 input->devmgr.last_device_touch = NULL;
2519 _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int version)
2521 Ecore_Wl2_Input *input;
2523 input = calloc(1, sizeof(Ecore_Wl2_Input));
2527 input->display = display;
2528 input->seat_version = version;
2529 input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = 0.025;
2530 input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = 0.4;
2531 input->repeat.enabled = EINA_TRUE;
2532 input->repeat.changed = EINA_FALSE;
2533 input->want_lock_pointer = EINA_FALSE;
2534 input->pointer_locked = EINA_FALSE;
2536 wl_array_init(&input->data.selection.types);
2537 wl_array_init(&input->data.drag.types);
2539 /* setup cursor size and theme */
2540 _ecore_wl2_input_cursor_setup(input);
2541 _ecore_wl2_cursor_config_init();
2544 wl_registry_bind(display->wl.registry, id, &wl_seat_interface, 4);
2547 eina_inlist_append(display->inputs, EINA_INLIST_GET(input));
2549 wl_seat_add_listener(input->wl.seat, &_seat_listener, input);
2550 wl_seat_set_user_data(input->wl.seat, input);
2552 input->dev_add_handler =
2553 ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_ADDED,
2554 _ecore_wl2_cb_device_event, input);
2556 input->dev_remove_handler =
2557 ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_REMOVED,
2558 _ecore_wl2_cb_device_event, input);
2560 if (!display->wl.data_device_manager) return;
2562 input->data.device =
2563 wl_data_device_manager_get_data_device(display->wl.data_device_manager,
2565 wl_data_device_add_listener(input->data.device, &_data_listener, input);
2569 _ecore_wl2_input_del(Ecore_Wl2_Input *input)
2571 Ecore_Wl2_Input_Devices *devices;
2572 Ecore_Wl2_Display *display;
2573 Eina_Inlist *l = NULL;
2574 Ecore_Wl2_Mouse_Down_Info *info = NULL;
2575 Ecore_Wl2_Window *window;
2579 display = input->display;
2581 l = _ecore_wl2_mouse_down_info_list;
2584 info = EINA_INLIST_CONTAINER_GET(l, Ecore_Wl2_Mouse_Down_Info);
2585 l = eina_inlist_remove(l, l);
2588 _ecore_wl2_mouse_down_info_list = NULL;
2590 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2592 _ecore_wl2_cursor_config_shutdown();
2594 if (input->cursor.name) eina_stringshare_del(input->cursor.name);
2595 // TIZEN_ONLY(20200219): cleanup cursor resources when a Ecore_Wl2_Input is destroy
2596 _ecore_wl2_input_cursor_cleanup(input);
2599 if (input->data.selection.types.data)
2603 wl_array_for_each(t, &input->data.selection.types)
2606 wl_array_release(&input->data.selection.types);
2608 if (input->data.drag.types.data)
2612 wl_array_for_each(t, &input->data.drag.types)
2615 wl_array_release(&input->data.drag.types);
2618 if (input->data.selection.source)
2619 wl_data_source_destroy(input->data.selection.source);
2620 if (input->data.drag.source)
2621 wl_data_source_destroy(input->data.drag.source);
2622 if (input->drag.offer) _ecore_wl2_offer_unref(input->drag.offer);
2623 if (input->selection.offer) _ecore_wl2_offer_unref(input->selection.offer);
2624 if (input->data.device) wl_data_device_destroy(input->data.device);
2626 if (input->xkb.state) xkb_state_unref(input->xkb.state);
2627 if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
2628 if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
2629 if (input->xkb.compose_table)
2630 xkb_compose_table_unref(input->xkb.compose_table);
2631 if (input->xkb.compose_state)
2632 xkb_compose_state_unref(input->xkb.compose_state);
2634 if (input->wl.seat) wl_seat_destroy(input->wl.seat);
2636 ecore_event_handler_del(input->dev_add_handler);
2637 ecore_event_handler_del(input->dev_remove_handler);
2638 EINA_LIST_FREE(input->devices_list, devices)
2639 _ecore_wl2_devices_free(devices);
2642 eina_inlist_remove(display->inputs, EINA_INLIST_GET(input));
2644 EINA_INLIST_FOREACH(display->windows, window)
2645 if (window->grab == input) window->grab = NULL;
2647 eina_stringshare_replace(&input->name, NULL);
2652 _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor)
2654 eina_stringshare_replace(&input->cursor.name, cursor);
2655 if (!cursor) eina_stringshare_replace(&input->cursor.name, "left_ptr");
2659 _ecore_wl2_input_window_remove(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
2661 Ecore_Wl2_Input_Devices *devices;
2662 Eina_List *l, *l_next;
2664 if ((input->focus.pointer) &&
2665 (input->focus.pointer == window))
2666 input->focus.pointer = NULL;
2667 if ((input->focus.keyboard) &&
2668 (input->focus.keyboard == window))
2669 input->focus.keyboard = NULL;
2670 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
2671 if ((input->focus.touch) &&
2672 (input->focus.touch == window))
2674 for (int i = 0; i < ECORE_WL2_TOUCH_MAX; i++)
2675 input->grab.touch_array[i] = EINA_FALSE;
2676 input->focus.touch = NULL;
2677 input->grab.count = 0;
2678 _ecore_wl2_input_ungrab(input);
2681 if ((input->repeat_win) &&
2682 (input->repeat_win == window))
2684 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2685 input->repeat.timer = NULL;
2686 input->repeat_win = NULL;
2689 EINA_LIST_FOREACH_SAFE(input->devices_list, l, l_next, devices)
2690 if (devices->window_id == window->id)
2692 _ecore_wl2_devices_free(devices);
2693 input->devices_list = eina_list_remove_list(input->devices_list, l);
2697 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
2699 _ecore_wl2_cb_keygrab_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t key, uint32_t mode, uint32_t error)
2701 _ecore_wl2_keygrab_error = error;
2702 INF("[PID:%d] key=%d, mode=%d, error=%d", getpid(), key, mode, error);
2706 _ecore_wl2_cb_keygrab_notify_list(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, struct wl_array *grab_result)
2708 wl_array_init(&_ecore_wl2_keygrab_result_list);
2709 wl_array_copy(&_ecore_wl2_keygrab_result_list, grab_result);
2713 _ecore_wl2_cb_getgrab_notify_list(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, struct wl_array *grab_result EINA_UNUSED)
2719 _ecore_wl2_cb_set_register_none_key(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t mode EINA_UNUSED)
2725 _ecore_wl2_cb_keyregister_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t status EINA_UNUSED)
2731 _ecore_wl2_cb_set_input_config(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t status EINA_UNUSED)
2737 _ecore_wl2_cb_key_cancel(void *data, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t key)
2739 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
2740 Ecore_Wl2_Input *input;
2744 WRN("Failed to get Ecore_Wl2_Display\n");
2748 EINA_INLIST_FOREACH(ewd->inputs, input)
2750 if (input->repeat.key == key)
2752 input->repeat.sym = 0;
2753 input->repeat.key = 0;
2754 input->repeat.time = 0;
2756 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2757 input->repeat.timer = NULL;
2763 _ecore_wl2_cb_event_surface(void *data, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface, uint32_t key EINA_UNUSED, uint32_t mode)
2765 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
2766 Ecore_Wl2_Input *input;
2770 WRN("Failed to get Ecore_Wl2_Display\n");
2774 EINA_INLIST_FOREACH(ewd->inputs, input)
2776 input->key_win = ecore_wl2_window_surface_find(surface);
2777 input->key_mode = mode;
2781 WRN("Get a event_surface(%p) but there was a no Ecore_Wl2_Window\n", surface);
2786 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
2787 static const struct tizen_keyrouter_listener _tz_keyrouter_listener =
2789 _ecore_wl2_cb_keygrab_notify,
2790 _ecore_wl2_cb_keygrab_notify_list,
2791 _ecore_wl2_cb_getgrab_notify_list,
2792 _ecore_wl2_cb_set_register_none_key,
2793 _ecore_wl2_cb_keyregister_notify,
2794 _ecore_wl2_cb_set_input_config,
2795 _ecore_wl2_cb_key_cancel,
2796 _ecore_wl2_cb_event_surface
2801 _ecore_wl2_keyrouter_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version EINA_UNUSED)
2803 ewd->wl.tz_keyrouter =
2804 wl_registry_bind(ewd->wl.registry, id, &tizen_keyrouter_interface, 2);
2805 if (ewd->wl.tz_keyrouter)
2806 tizen_keyrouter_add_listener(ewd->wl.tz_keyrouter, &_tz_keyrouter_listener, ewd);
2811 xkb_keysym_t keysym;
2812 xkb_keycode_t *keycodes;
2816 typedef struct _Keycode_Map Keycode_Map;
2818 static void find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2820 Keycode_Map *found_keycodes = (Keycode_Map *)data;
2821 xkb_keysym_t keysym = found_keycodes->keysym;
2823 const xkb_keysym_t *syms_out = NULL;
2824 num_syms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2825 if ((num_syms) && (syms_out))
2827 if ((*syms_out) == (keysym))
2829 found_keycodes->num_keycodes++;
2830 found_keycodes->keycodes = realloc(found_keycodes->keycodes, sizeof(int) * found_keycodes->num_keycodes);
2831 if (found_keycodes->keycodes)
2832 found_keycodes->keycodes[found_keycodes->num_keycodes - 1] = key;
2837 //If there are several keycodes, ecore_wl only deals with first keycode.
2839 ecore_wl2_input_keycode_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym, xkb_keycode_t **keycodes)
2841 Keycode_Map found_keycodes = {0,};
2842 found_keycodes.keysym = keysym;
2844 //called fewer (max_keycode - min_keycode +1) times.
2845 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2847 *keycodes = found_keycodes.keycodes;
2848 INF("num of keycodes:%d ", found_keycodes.num_keycodes);
2849 return found_keycodes.num_keycodes;
2852 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
2853 //Currently this function is only used in sink call, so use global value(_ecore_wl_keygrab_error) and just check the error is ok.
2854 /* internal functions */
2856 _ecore_wl2_keygrab_hash_add(void *key, void *data)
2858 Eina_Bool ret = EINA_FALSE;
2860 if (!data) return ret;
2862 _keygrabs = eina_hash_int32_new(NULL);
2863 ret = eina_hash_add(_keygrabs, key, data);
2868 _ecore_wl2_keygrab_hash_del(void *key)
2870 Eina_Bool ret = EINA_FALSE;
2872 ret = eina_hash_del_by_key(_keygrabs, key);
2878 _ecore_wl2_keygrab_hash_get(void)
2884 _ecore_wl2_keygrab_error_set()
2886 if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_INVALID_SURFACE)
2887 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
2888 else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
2889 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
2890 else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY)
2891 set_last_result(TIZEN_ERROR_ALREADY_IN_PROGRESS);
2892 else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
2893 set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
2894 else set_last_result(TIZEN_ERROR_NONE);
2897 //I'm not sure that keygrab function should be changed to Ecore_evas_XXX.
2898 //In the future, keyrouter feature can be added upstream or finish stabilizing.
2899 //After that time, we maybe change API name or other thing.
2900 //So do not use this API if you have trouble catch keyrouter feature or rule changes.
2902 //Keyrouter support the situation when wl_win is not exist.
2903 //But keyrouter also can be meet situation when there are several surfaces.
2904 //So I decided to add keygrab feature into ecore_wl_window side like x system.
2906 //Mod, not_mod, priority will be used future.
2907 //But now we are not support, so just use 0 for this parameter.
2911 ecore_wl2_window_keygrab_set(Ecore_Wl2_Window *win, const char *key, int mod EINA_UNUSED, int not_mod EINA_UNUSED, int priority EINA_UNUSED, Ecore_Wl2_Window_Keygrab_Mode grab_mode)
2913 Ecore_Wl2_Display *ewd;
2914 xkb_keysym_t keysym = 0x0;
2915 int num_keycodes = 0;
2916 xkb_keycode_t *keycodes = NULL;
2918 Ecore_Wl2_Input *input;
2920 Eina_Bool ret = EINA_FALSE;
2921 struct wl_surface *surface = NULL;
2923 EINA_SAFETY_ON_NULL_GOTO(key, err);
2924 EINA_SAFETY_ON_TRUE_GOTO((grab_mode < ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN), err);
2925 EINA_SAFETY_ON_TRUE_GOTO((grab_mode > ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE), err);
2930 ewd = ecore_wl2_connected_display_get(NULL);
2932 EINA_SAFETY_ON_NULL_GOTO(ewd, err);
2934 while (!ewd->wl.tz_keyrouter)
2936 INF("Wait until keyrouter interface is ready");
2937 wl_display_roundtrip(ewd->wl.display);
2940 INF("win=%p key=%s mod=%d", win, key, grab_mode);
2942 keysym = xkb_keysym_from_name(key, XKB_KEYSYM_NO_FLAGS);
2943 if (keysym == XKB_KEY_NoSymbol)
2945 WRN("Keysym of key(\"%s\") doesn't exist", key);
2946 EINA_SAFETY_ON_TRUE_GOTO(EINA_TRUE, err);
2949 //We have to find the way to get keycode from keysym before keymap notify
2950 //keymap event occurs after minimum 3 roundtrips
2951 //1. ecore_wl_init: wl_registry_add_listener
2952 //2. _ecore_wl_cb_handle_global: wl_seat_add_listener
2953 //3. _ecore_wl_input_seat_handle_capabilities: wl_keyboard_add_listener
2954 while (eina_inlist_count(ewd->inputs) == 0)
2956 INF("Wait wl_registry_add_listener reply");
2957 wl_display_roundtrip(ewd->wl.display);
2960 input = ecore_wl2_input_default_input_get(ewd);
2961 EINA_SAFETY_ON_NULL_GOTO(input, err);
2963 while (!input->caps_update)
2965 INF("Wait until wl_seat_capabilities_update is ready");
2966 wl_display_roundtrip(ewd->wl.display);
2969 EINA_SAFETY_ON_NULL_GOTO(input->wl.keyboard, err);
2972 while (!input->xkb.keymap)
2974 wl_display_roundtrip(ewd->wl.display);
2975 INF("Wait until keymap event occurs");
2977 INF("Finish keymap event");
2979 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
2980 EINA_SAFETY_ON_TRUE_GOTO((num_keycodes == 0), err);
2982 /* Request to grab a key */
2984 surface = ecore_wl2_window_surface_get(win);
2986 for (i = 0; i < num_keycodes; i++)
2988 INF("keycode of key:(%d)", keycodes[i]);
2989 tizen_keyrouter_set_keygrab(ewd->wl.tz_keyrouter, surface, keycodes[i], grab_mode);
2990 /* Send sync to wayland compositor and register sync callback to exit while dispatch loop below */
2991 ecore_wl2_display_sync(ewd);
2993 INF("After keygrab _ecore_wl2_keygrab_error = %d", _ecore_wl2_keygrab_error);
2994 if (!_ecore_wl2_keygrab_error)
2996 INF("[PID:%d]Succeed to get return value !", getpid());
2997 if (_ecore_wl2_keygrab_hash_add(&keycodes[i], surface))
2998 INF("Succeed to add key to the keygrab hash!");
2999 //TODO: deal with if (win == NULL)
3001 WRN("Failed to add key to the keygrab hash!");
3006 WRN("[PID:%d]Failed to get return value ! ret=%d)", getpid(), _ecore_wl2_keygrab_error);
3014 _ecore_wl2_keygrab_error_set();
3015 _ecore_wl2_keygrab_error = -1;
3019 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3024 ecore_wl2_window_keygrab_unset(Ecore_Wl2_Window *win, const char *key, int mod EINA_UNUSED, int any_mod EINA_UNUSED)
3026 Ecore_Wl2_Display *ewd;
3027 xkb_keysym_t keysym = 0x0;
3028 int num_keycodes = 0;
3029 xkb_keycode_t *keycodes = NULL;
3032 Eina_Bool ret = EINA_FALSE;
3033 struct wl_surface *surface = NULL;
3034 Ecore_Wl2_Input *input;
3039 ewd = ecore_wl2_connected_display_get(NULL);
3043 if ((!ewd) || (!ewd->wl.tz_keyrouter)) goto err;
3045 INF("win=%p key=%s ", win, key);
3047 keysym = xkb_keysym_from_name(key, XKB_KEYSYM_NO_FLAGS);
3048 if (keysym == XKB_KEY_NoSymbol)
3050 WRN("Keysym of key(\"%s\") doesn't exist", key);
3054 while (eina_inlist_count(ewd->inputs) == 0)
3056 INF("Wait wl_registry_add_listener reply");
3057 wl_display_roundtrip(ewd->wl.display);
3060 input = ecore_wl2_input_default_input_get(ewd);
3062 //We have to find the way to get keycode from keysym before keymap notify
3063 if ((input) && (input->xkb.keymap))
3064 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3067 WRN("Keymap is not ready");
3071 if (num_keycodes == 0)
3073 WRN("Keycode of key(\"%s\") doesn't exist", key);
3077 /* Request to ungrab a key */
3079 surface = ecore_wl2_window_surface_get(win);
3081 for (i = 0; i < num_keycodes; i++)
3083 INF("keycode of key:(%d)", keycodes[i]);
3084 tizen_keyrouter_unset_keygrab(ewd->wl.tz_keyrouter, surface, keycodes[i]);
3086 /* Send sync to wayland compositor and register sync callback to exit while dispatch loop below */
3087 ecore_wl2_display_sync(ewd);
3089 INF("After keygrab unset _ecore_wl2_keygrab_error = %d", _ecore_wl2_keygrab_error);
3090 if (!_ecore_wl2_keygrab_error)
3092 INF("[PID:%d]Succeed to get return value !", getpid());
3093 if (_ecore_wl2_keygrab_hash_del(&keycodes[i]))
3094 INF("Succeed to delete key from the keygrab hash!");
3096 WRN("Failed to delete key from the keygrab hash!");
3102 WRN("[PID:%d] Failed to get return value ! (ret=%d)", getpid(), _ecore_wl2_keygrab_error);
3109 _ecore_wl2_keygrab_error_set();
3110 _ecore_wl2_keygrab_error = -1;
3114 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3119 _ecore_wl2_keyname_get(int keycode)
3121 xkb_keysym_t sym = XKB_KEY_NoSymbol;
3122 char name[256] = {0, };
3123 Ecore_Wl2_Display *ewd;
3124 Ecore_Wl2_Input *input;
3126 ewd = ecore_wl2_connected_display_get(NULL);
3127 input = ecore_wl2_input_default_input_get(ewd);
3128 if (!input) return NULL;
3130 sym = xkb_state_key_get_one_sym(input->xkb.state, keycode);
3131 xkb_keysym_get_name(sym, name, sizeof(name));
3133 return strdup(name);
3137 *ecore_wl2_window_keygrab_list_set(Ecore_Wl2_Window *win, Eina_List *infos)
3139 Ecore_Wl2_Display *ewd;
3140 xkb_keysym_t keysym = 0x0;
3141 int num_keycodes = 0;
3142 xkb_keycode_t *keycodes = NULL;
3144 struct wl_surface *surface = NULL;
3146 struct wl_array grab_list;
3147 int *grab_data = NULL;
3149 Eina_List *error_keys = NULL;
3151 Eina_Bool no_permission = EINA_FALSE;
3152 Eina_Bool invalid_key = EINA_FALSE;
3154 Ecore_Wl2_Keygrab_Info *info;
3155 Ecore_Wl2_Window_Keygrab_Info *grab_info;
3156 Ecore_Wl2_Input *input;
3161 ewd = ecore_wl2_connected_display_get(NULL);
3165 while (!ewd->wl.tz_keyrouter)
3167 INF("Wait until keyrouter interface is ready");
3168 wl_display_roundtrip(ewd->wl.display);
3171 while (eina_inlist_count(ewd->inputs) == 0)
3173 INF("Wait wl_registry_add_listener reply");
3174 wl_display_roundtrip(ewd->wl.display);
3177 input = ecore_wl2_input_default_input_get(ewd);
3179 if(!input) goto err;
3181 while (!input->caps_update)
3183 INF("Wait until wl_seat_capabilities_update is ready");
3184 wl_display_roundtrip(ewd->wl.display);
3186 if (input->wl.keyboard)
3188 while(!input->xkb.keymap)
3190 wl_display_roundtrip(ewd->wl.display);
3191 INF("Wait until keymap event occurs");
3193 INF("Finish keymap event");
3197 WRN("This device does not support key");
3202 surface = ecore_wl2_window_surface_get(win);
3204 wl_array_init(&grab_list);
3206 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3208 if (!grab_info->key) continue;
3209 if ((grab_info->mode < ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN) || (grab_info->mode > ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE))
3212 keysym = xkb_keysym_from_name(grab_info->key, XKB_KEYSYM_NO_FLAGS);
3214 if (keysym == XKB_KEYSYM_NO_FLAGS)
3216 WRN("Keysym of key(\"%s\") doesn't exist", grab_info->key);
3219 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3221 if (num_keycodes == 0)
3223 WRN("Keycode of key(\"%s\") doesn't exist", grab_info->key);
3226 for (i = 0; i < num_keycodes; i++)
3228 INF("keycode of key:(%d)", keycodes[i]);
3229 grab_data = wl_array_add(&grab_list, sizeof(int));
3230 *grab_data = keycodes[i];
3231 grab_data = wl_array_add(&grab_list, sizeof(int));
3232 *grab_data = grab_info->mode;
3233 grab_data = wl_array_add(&grab_list, sizeof(int));
3239 tizen_keyrouter_set_keygrab_list(ewd->wl.tz_keyrouter, surface, &grab_list);
3241 ecore_wl2_display_sync(ewd);
3243 wl_array_for_each(info, &_ecore_wl2_keygrab_result_list)
3248 INF("[PID:%d]Succeed to get return value !", getpid());
3249 if (_ecore_wl2_keygrab_hash_add(&info->key, surface))
3250 INF("Succeed to add key to the keygrab hash!");
3252 WRN("Failed to add key to the keygrab hash!");
3256 WRN("After keygrab keycode %d error = %d", info->key, info->err);
3257 if (info->err == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
3258 no_permission = EINA_TRUE;
3260 if (info->err == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
3261 invalid_key = EINA_TRUE;
3263 error_keys = eina_list_append(error_keys, _ecore_wl2_keyname_get(info->key));
3266 wl_array_release(&grab_list);
3267 wl_array_release(&_ecore_wl2_keygrab_result_list);
3269 set_last_result(TIZEN_ERROR_NONE);
3270 if (invalid_key) set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3271 if (no_permission) set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
3276 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3278 error_keys = eina_list_append(error_keys, strdup(grab_info->key));
3281 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3287 *ecore_wl2_window_keygrab_list_unset(Ecore_Wl2_Window *win, Eina_List *infos)
3289 Ecore_Wl2_Display *ewd;
3290 xkb_keysym_t keysym = 0x0;
3291 int num_keycodes = 0;
3292 xkb_keycode_t *keycodes = NULL;
3294 struct wl_surface *surface = NULL;
3296 struct wl_array ungrab_list;
3297 int *grab_data = NULL;
3299 Eina_List *error_keys = NULL;
3301 Eina_Bool no_permission = EINA_FALSE;
3302 Eina_Bool invalid_key = EINA_FALSE;
3304 Ecore_Wl2_Keyungrab_Info *info;
3305 Ecore_Wl2_Window_Keygrab_Info *grab_info;
3307 Ecore_Wl2_Input *input;
3312 ewd = ecore_wl2_connected_display_get(NULL);
3316 if ((!ewd->wl.tz_keyrouter)) goto err;
3318 input = ecore_wl2_input_default_input_get(ewd);
3320 if ((!input) || (!input->xkb.keymap))
3322 ERR("Keymap is not ready");
3327 surface = ecore_wl2_window_surface_get(win);
3329 wl_array_init(&ungrab_list);
3331 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3333 if (!grab_info->key) continue;
3335 keysym = xkb_keysym_from_name(grab_info->key, XKB_KEYSYM_NO_FLAGS);
3337 if (keysym == XKB_KEYSYM_NO_FLAGS)
3339 WRN("Keysym of key(\"%s\") doesn't exist", grab_info->key);
3342 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3344 if (num_keycodes == 0)
3346 WRN("Keycode of key(\"%s\") doesn't exist", grab_info->key);
3349 for (i = 0; i < num_keycodes; i++)
3351 INF("keycode of key:(%d)", keycodes[i]);
3352 grab_data = wl_array_add(&ungrab_list, sizeof(int));
3353 *grab_data = keycodes[i];
3354 grab_data = wl_array_add(&ungrab_list, sizeof(int));
3360 tizen_keyrouter_unset_keygrab_list(ewd->wl.tz_keyrouter, surface, &ungrab_list);
3362 ecore_wl2_display_sync(ewd);
3364 wl_array_for_each(info, &_ecore_wl2_keygrab_result_list)
3368 INF("[PID:%d]Succeed to get return value !", getpid());
3369 if (_ecore_wl2_keygrab_hash_del(&info->key))
3370 INF("Succeed to delete key to the keygrab hash!");
3372 WRN("Failed to delete key to the keygrab hash!");
3376 WRN("After keyungrab keycode %d error = %d", info->key, info->err);
3377 if (info->err == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
3378 no_permission = EINA_TRUE;
3380 if (info->err == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
3381 invalid_key = EINA_TRUE;
3383 error_keys = eina_list_append(error_keys, _ecore_wl2_keyname_get(info->key));
3386 wl_array_release(&ungrab_list);
3387 wl_array_release(&_ecore_wl2_keygrab_result_list);
3389 set_last_result(TIZEN_ERROR_NONE);
3390 if (invalid_key) set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3391 if (no_permission) set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
3396 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3398 error_keys = eina_list_append(error_keys, strdup(grab_info->key));
3401 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3408 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
3410 _ecore_wl2_input_device_info_free(void *data EINA_UNUSED, void *ev)
3412 Ecore_Event_Device_Info *e;
3415 eina_stringshare_del(e->name);
3416 eina_stringshare_del(e->identifier);
3417 eina_stringshare_del(e->seatname);
3423 _ecore_wl2_input_device_info_send(Ecore_Window win_id, const char *name, const char *identifier, Ecore_Device_Class clas, Ecore_Device_Subclass subclas, Eina_Bool flag)
3425 Ecore_Event_Device_Info *e;
3427 if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) return;
3430 e->name = eina_stringshare_add(name);
3431 e->identifier = eina_stringshare_add(identifier);
3432 e->seatname = eina_stringshare_add(name);
3434 e->subclas = subclas;
3437 ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _ecore_wl2_input_device_info_free, NULL);
3439 ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _ecore_wl2_input_device_info_free, NULL);
3442 // TIZEN_ONLY(20180917): ecore/evas_device: update device info if subclas is changed
3444 _ecore_wl2_input_device_update_send(Ecore_Window win, Ecore_Device *dev)
3446 Ecore_Event_Device_Update *ev;
3448 ev = (Ecore_Event_Device_Update *)calloc(sizeof(Ecore_Event_Device_Update), 1);
3449 EINA_SAFETY_ON_NULL_RETURN(ev);
3453 ecore_event_add(ECORE_EVENT_DEVICE_SUBCLASS_UPDATE, ev, NULL, NULL);
3458 _ecore_wl2_input_device_ecore_device_update(Ecore_Device *dev, Ecore_Device_Subclass subclas)
3462 Ecore_Wl2_Window *win = NULL;
3464 Eina_Bool has_win = EINA_FALSE;
3466 ecore_device_subclass_set(dev, subclas);
3468 windows = _ecore_wl2_window_hash_get();
3471 itr = eina_hash_iterator_data_new(windows);
3472 while (eina_iterator_next(itr, &data))
3475 has_win = EINA_TRUE;
3476 _ecore_wl2_input_device_update_send(win->id, dev);
3479 eina_iterator_free(itr);
3483 _ecore_wl2_input_device_update_send((uintptr_t)NULL, dev);
3489 _ecore_wl2_input_device_ecore_device_add(Ecore_Wl2_Tizen_Input_Device *dev)
3491 Ecore_Device *ecdev;
3493 const char *ecdev_name;
3495 if (!dev->identifier) return EINA_FALSE;
3497 EINA_LIST_FOREACH((Eina_List *)ecore_device_list(), l, ecdev)
3499 ecdev_name = ecore_device_identifier_get(ecdev);
3500 if (!ecdev_name) continue;
3501 if ((ecore_device_class_get(ecdev) == dev->clas) && (!strcmp(ecdev_name, dev->identifier)))
3503 // TIZEN_ONLY(20180917): ecore/evas_device: update device info if subclas is changed
3504 _ecore_wl2_input_device_ecore_device_update(ecdev, dev->subclas);
3510 ecdev = ecore_device_add();
3513 ERR("Failed to add ecore device for name: %s (%s)\n", dev->name, dev->identifier);
3516 ecore_device_name_set(ecdev, dev->name);
3517 ecore_device_identifier_set(ecdev, dev->identifier);
3518 ecore_device_class_set(ecdev, dev->clas);
3519 ecore_device_subclass_set(ecdev, dev->subclas);
3521 dev->device = efl_ref(ecdev);
3527 _ecore_wl2_input_device_ecore_device_remove(Ecore_Wl2_Tizen_Input_Device *dev)
3529 Ecore_Device *ecdev;
3530 Eina_List *l, *clone;
3531 const char *ecdev_name;
3533 if (!dev->identifier) return EINA_FALSE;
3535 clone = eina_list_clone(ecore_device_list());
3537 EINA_LIST_FOREACH(clone, l, ecdev)
3539 ecdev_name = ecore_device_identifier_get(ecdev);
3540 if (!ecdev_name) continue;
3541 if ((ecore_device_class_get(ecdev) == dev->clas) &&
3542 (!strcmp(ecdev_name, dev->identifier)))
3544 efl_unref(dev->device);
3545 ecore_device_del(ecdev);
3547 eina_list_free(clone);
3551 eina_list_free(clone);
3557 _ecore_wl2_input_device_info_broadcast(Ecore_Wl2_Tizen_Input_Device *dev, Eina_Bool flag)
3559 Eina_Hash *windows = NULL;
3561 Ecore_Wl2_Window *win = NULL;
3563 Eina_Bool res, has_win = EINA_FALSE;
3566 if (!dev->name) return;
3567 if (!dev->identifier) return;
3568 if (!dev->input || !dev->input->display) return;
3571 res = _ecore_wl2_input_device_ecore_device_add(dev);
3573 res = _ecore_wl2_input_device_ecore_device_remove(dev);
3577 windows = _ecore_wl2_window_hash_get();
3580 itr = eina_hash_iterator_data_new(windows);
3581 while (eina_iterator_next(itr, &data))
3584 has_win = EINA_TRUE;
3585 _ecore_wl2_input_device_info_send(win->id, dev->name, dev->identifier, dev->clas, dev->subclas, flag);
3588 eina_iterator_free(itr);
3592 _ecore_wl2_input_device_info_send((uintptr_t)NULL, dev->name, dev->identifier, dev->clas, dev->subclas, flag);
3597 _ecore_wl2_input_devices_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *win)
3600 Ecore_Wl2_Tizen_Input_Device *dev;
3604 EINA_LIST_FOREACH(input->devmgr.devices, l, dev)
3606 if (!dev->name || !dev->identifier) continue;
3607 _ecore_wl2_input_device_info_send(win->id, dev->name, dev->identifier, dev->clas, dev->subclas, EINA_TRUE);
3613 _ecore_wl2_input_device_cb_device_info(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, const char *name, uint32_t clas, uint32_t subclas, struct wl_array *axes EINA_UNUSED)
3615 Ecore_Wl2_Tizen_Input_Device *dev;
3617 if (!(dev = data)) return;
3619 if (((Ecore_Device_Class)clas == ECORE_DEVICE_CLASS_MOUSE) && (tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1))
3620 dev->clas = ECORE_DEVICE_CLASS_TOUCH;
3622 dev->clas = (Ecore_Device_Class)clas;
3623 dev->subclas = (Ecore_Device_Subclass)subclas;
3624 dev->name = eina_stringshare_add(name);
3626 _ecore_wl2_input_device_info_broadcast(dev, EINA_TRUE);
3630 _ecore_wl2_input_device_cb_event_device(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, unsigned int serial EINA_UNUSED, const char *name EINA_UNUSED, uint32_t time EINA_UNUSED)
3632 Ecore_Wl2_Tizen_Input_Device *dev;
3634 if (!(dev = data)) return;
3635 if (!dev->identifier) return;
3636 _ecore_wl2_input_device_last_device_set(dev);
3642 _ecore_wl2_input_detent_rotate_free(void *data EINA_UNUSED, void *ev)
3644 Ecore_Event_Detent_Rotate *e = ev;
3649 _ecore_wl2_input_device_cb_axis(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, uint32_t axis_type, wl_fixed_t value)
3651 Ecore_Wl2_Input *input;
3652 Ecore_Wl2_Tizen_Input_Device *dev;
3653 double dvalue = wl_fixed_to_double(value);
3654 Ecore_Event_Detent_Rotate *e;
3656 dev = (Ecore_Wl2_Tizen_Input_Device *)data;
3663 case TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_X:
3664 input->touch.last_touch_axis.radius_x = dvalue;
3666 case TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_Y:
3667 input->touch.last_touch_axis.radius_y = dvalue;
3669 case TIZEN_INPUT_DEVICE_AXIS_TYPE_PRESSURE:
3670 input->touch.last_touch_axis.pressure = dvalue;
3672 case TIZEN_INPUT_DEVICE_AXIS_TYPE_ANGLE:
3673 input->touch.last_touch_axis.angle = dvalue;
3675 case TIZEN_INPUT_DEVICE_AXIS_TYPE_DETENT:
3676 /* Do something after get detent event.
3677 * value 1 is clockwise,
3678 * value -1 is counterclockwise,
3680 if (!(e = calloc(1, sizeof(Ecore_Event_Detent_Rotate))))
3682 ERR("detent: cannot allocate memory");
3686 e->direction = ECORE_DETENT_DIRECTION_CLOCKWISE;
3688 e->direction = ECORE_DETENT_DIRECTION_COUNTER_CLOCKWISE;
3689 e->timestamp = _timestamp_get();
3690 DBG("detent: dir: %d, time: %d", e->direction, e->timestamp);
3691 ecore_event_add(ECORE_EVENT_DETENT_ROTATE, e, _ecore_wl2_input_detent_rotate_free, NULL);
3694 WRN("Invalid type(%d) is ignored.\n", axis_type);
3700 static const struct tizen_input_device_listener _tz_input_device_listener =
3702 _ecore_wl2_input_device_cb_device_info,
3703 _ecore_wl2_input_device_cb_event_device,
3704 _ecore_wl2_input_device_cb_axis,
3708 _ecore_wl2_input_device_manager_cb_device_add(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
3709 unsigned int serial EINA_UNUSED, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
3711 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3712 Ecore_Wl2_Input *input;
3713 Ecore_Wl2_Tizen_Input_Device *dev;
3716 if ((!identifier) || (!device) || (!seat))
3718 ERR("Invalid arguments. return");
3722 input = wl_seat_get_user_data(seat);
3725 if (!(dev = calloc(1, sizeof(Ecore_Wl2_Tizen_Input_Device)))) return;
3727 dev->tz_device = device;
3728 tizen_input_device_add_listener(dev->tz_device, &_tz_input_device_listener, dev);
3730 dev->identifier = eina_stringshare_add(identifier);
3733 input->devmgr.devices = eina_list_append(input->devmgr.devices, dev);
3737 _ecore_wl2_input_device_manager_cb_device_remove(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
3738 unsigned int serial EINA_UNUSED, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
3740 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3741 Ecore_Wl2_Input *input;
3742 Eina_List *l, *l_next;
3743 Ecore_Wl2_Tizen_Input_Device *dev;
3746 if ((!identifier) || (!device) || (!seat))
3748 ERR("Invalid arguments. return");
3752 input = wl_seat_get_user_data(seat);
3756 EINA_LIST_FOREACH_SAFE(input->devmgr.devices, l, l_next, dev)
3758 if (!dev->identifier) continue;
3759 if ((!strcmp(dev->identifier, identifier)) && (seat == dev->seat) && (device == dev->tz_device))
3761 _ecore_wl2_input_device_info_broadcast(dev, EINA_FALSE);
3763 _ecore_wl2_input_device_last_device_unset(dev);
3765 if (dev->tz_device) tizen_input_device_release(dev->tz_device);
3766 if (dev->name) eina_stringshare_del(dev->name);
3767 if (dev->identifier) eina_stringshare_del(dev->identifier);
3770 input->devmgr.devices = eina_list_remove_list(input->devmgr.devices, l);
3779 _ecore_wl2_input_device_manager_cb_error(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t errorcode EINA_UNUSED)
3785 _ecore_wl2_input_device_manager_cb_block_expired(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED)
3791 _ecore_wl2_input_device_manager_cb_max_touch_count(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t serial EINA_UNUSED, int32_t max_count, struct wl_seat *seat)
3793 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3794 Ecore_Wl2_Input *input;
3798 input = wl_seat_get_user_data(seat);
3802 if (input->touch.max_count < max_count)
3804 if (input->touch.touch_axis)
3806 INF("Max touch value is changed %d to %d\n", input->touch.max_count, max_count);
3807 free(input->touch.touch_axis);
3809 input->touch.max_count = max_count;
3810 input->touch.touch_axis = (Ecore_Wl2_Touch_Axis *)calloc(max_count, sizeof(Ecore_Wl2_Touch_Axis));
3814 static const struct tizen_input_device_manager_listener _tz_input_device_mgr_listener =
3816 _ecore_wl2_input_device_manager_cb_device_add,
3817 _ecore_wl2_input_device_manager_cb_device_remove,
3818 _ecore_wl2_input_device_manager_cb_error,
3819 _ecore_wl2_input_device_manager_cb_block_expired,
3820 _ecore_wl2_input_device_manager_cb_max_touch_count,
3824 _ecore_wl2_input_device_manager_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version EINA_UNUSED)
3826 ewd->wl.tz_input_device_manager =
3827 wl_registry_bind(ewd->wl.registry, id, &tizen_input_device_manager_interface, 4);
3829 tizen_input_device_manager_add_listener(ewd->wl.tz_input_device_manager,
3830 &_tz_input_device_mgr_listener, ewd);
3834 EAPI struct wl_seat *
3835 ecore_wl2_input_seat_get(Ecore_Wl2_Input *input)
3837 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3838 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3839 return input->wl.seat;
3842 EAPI Ecore_Wl2_Seat_Capabilities
3843 ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input)
3845 Ecore_Wl2_Seat_Capabilities cap = ECORE_WL2_SEAT_CAPABILITIES_NONE;
3847 EINA_SAFETY_ON_NULL_RETURN_VAL(input, cap);
3848 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
3849 if (input->wl.keyboard)
3850 cap |= ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD;
3851 if (input->wl.pointer)
3852 cap |= ECORE_WL2_SEAT_CAPABILITIES_POINTER;
3853 if (input->wl.touch)
3854 cap |= ECORE_WL2_SEAT_CAPABILITIES_TOUCH;
3858 EAPI Eina_Stringshare *
3859 ecore_wl2_input_name_get(Ecore_Wl2_Input *input)
3861 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3866 ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input)
3868 EINA_SAFETY_ON_NULL_RETURN_VAL(input, 0);
3869 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
3873 EAPI Ecore_Wl2_Display *
3874 ecore_wl2_input_display_get(const Ecore_Wl2_Input *input)
3876 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3877 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3878 return input->display;
3881 EAPI struct xkb_keymap *
3882 ecore_wl2_input_keymap_get(const Ecore_Wl2_Input *input)
3884 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3885 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3886 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, NULL);
3887 return input->xkb.keymap;
3891 ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3893 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3894 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3895 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3896 input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = rate;
3897 input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = delay;
3898 input->repeat.changed = EINA_TRUE;
3899 return input->repeat.enabled;
3903 ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3905 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3906 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3907 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3908 if (rate) *rate = input->repeat.rate;
3909 if (delay) *delay = input->repeat.delay;
3910 return input->repeat.enabled;
3914 ecore_wl2_input_keyboard_horizontal_way_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3916 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3917 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3918 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3919 input->repeat.horizontal.rate = rate;
3920 input->repeat.horizontal.delay = delay;
3921 input->repeat.changed = EINA_TRUE;
3922 return input->repeat.enabled;
3926 ecore_wl2_input_keyboard_horizontal_way_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3928 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3929 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3930 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3931 if (rate) *rate = input->repeat.horizontal.rate;
3932 if (delay) *delay = input->repeat.horizontal.delay;
3933 return input->repeat.enabled;
3938 ecore_wl2_input_keyboard_vertical_way_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3940 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3941 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3942 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3943 input->repeat.vertical.rate = rate;
3944 input->repeat.vertical.delay = delay;
3945 input->repeat.changed = EINA_TRUE;
3946 return input->repeat.enabled;
3950 ecore_wl2_input_keyboard_vertical_way_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3952 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3953 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3954 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3955 if (rate) *rate = input->repeat.vertical.rate;
3956 if (delay) *delay = input->repeat.vertical.delay;
3957 return input->repeat.enabled;
3960 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3962 _pointer_update_stop(Ecore_Wl2_Input *input)
3964 if (!input->cursor.timer) return;
3966 ecore_timer_del(input->cursor.timer);
3967 input->cursor.timer = NULL;
3972 ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y)
3974 EINA_SAFETY_ON_NULL_RETURN(input);
3976 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3977 _pointer_update_stop(input);
3978 if (input->wl.pointer)
3979 wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
3980 surface, hot_x, hot_y);
3983 // TIZEN_ONLY(20230330): support client that requests to unset cursor
3986 if (input->cursor.name) eina_stringshare_del(input->cursor.name);
3987 input->cursor.name = NULL;
3988 ecore_wl2_display_flush(input->display);
3993 input->cursor.surface = surface;
3994 input->cursor.hot_x = hot_x;
3995 input->cursor.hot_y = hot_y;
3997 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3999 _ecore_wl2_input_cursor_update(input);
4004 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4005 EAPI struct wl_cursor *
4006 ecore_wl2_input_cursor_get(Ecore_Wl2_Input *input, const char *cursor_name)
4008 if ((!input) || (!input->cursor.theme))
4011 return wl_cursor_theme_get_cursor(input->cursor.theme,
4017 ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor_name)
4019 EINA_SAFETY_ON_NULL_RETURN(input);
4020 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4022 _ecore_wl2_input_cursor_set(input, cursor);
4024 struct wl_cursor *cursor;
4026 /* No pointer device. Don't need to set cursor and update it */
4027 if (!input->wl.pointer) return;
4029 _pointer_update_stop(input);
4031 eina_stringshare_replace(&input->cursor.name, cursor_name);
4033 /* No cursor. Set to default Left Pointer */
4035 eina_stringshare_replace(&input->cursor.name, "left_ptr");
4037 /* try to get this cursor from the theme */
4038 if (!(cursor = ecore_wl2_input_cursor_get(input, input->cursor.name)))
4040 /* if the theme does not have this cursor, default to left pointer */
4041 if (!(cursor = ecore_wl2_input_cursor_get(input, "left_ptr")))
4045 input->cursor.cursor = cursor;
4047 if ((!cursor->images) || (!cursor->images[0]))
4049 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
4053 input->cursor.current_index = 0;
4055 _ecore_wl2_input_cursor_update(input);
4059 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4061 ecore_wl2_input_cursor_size_set(Ecore_Wl2_Input *input, const int size)
4065 input->cursor.size = size;
4067 EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);
4069 if (input->cursor.theme)
4070 wl_cursor_theme_destroy(input->cursor.theme);
4072 input->cursor.theme =
4073 wl_cursor_theme_load(NULL, input->cursor.size, input->display->wl.shm);
4077 ecore_wl2_input_cursor_theme_name_set(Ecore_Wl2_Input *input, const char *cursor_theme_name)
4081 if (eina_streq(input->cursor.theme_name, cursor_theme_name))
4084 eina_stringshare_replace(&input->cursor.theme_name, cursor_theme_name);
4086 EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);
4088 if (input->cursor.theme)
4089 wl_cursor_theme_destroy(input->cursor.theme);
4090 input->cursor.theme =
4091 wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size,
4092 input->display->wl.shm);
4096 ecore_wl2_input_cursor_default_restore(Ecore_Wl2_Input *input)
4100 /* Restore to default wayland cursor */
4101 ecore_wl2_input_cursor_from_name_set(input, "left_ptr");
4106 ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int *x, int *y)
4108 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4112 if (!input->wl.pointer) return EINA_FALSE;
4113 if (x) *x = input->pointer.sx;
4114 if (y) *y = input->pointer.sy;
4118 EAPI Ecore_Wl2_Input *
4119 ecore_wl2_input_default_input_get(const Ecore_Wl2_Display *ewd)
4121 Ecore_Wl2_Input *input;
4123 EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
4124 if (!ewd->inputs) return NULL;
4126 input = ecore_wl2_display_input_find_by_name(ewd, "seat0");
4127 if (!input) input = ecore_wl2_display_input_find_by_name(ewd, "default");
4132 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
4134 ecore_wl2_window_pointer_constraints_lock_pointer(Ecore_Wl2_Window *win)
4136 Ecore_Wl2_Display *ewd;
4137 Ecore_Wl2_Input *input;
4139 EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4140 EINA_SAFETY_ON_NULL_RETURN_VAL(win->surface, EINA_FALSE);
4143 input = ecore_wl2_input_default_input_get(ewd);
4144 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4146 if (!ewd->wl.pointer_constraints)
4148 ERR("Failed to lock pointer. constraints is NULL");
4151 if (!input->wl.locked_pointer)
4153 INF("Pointer Constraint: lock pointer. (region: %p)", input->lock_region);
4154 input->wl.locked_pointer =
4155 zwp_pointer_constraints_v1_lock_pointer(ewd->wl.pointer_constraints,
4159 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
4160 zwp_locked_pointer_v1_add_listener(input->wl.locked_pointer,
4161 &_locked_pointer_listener, input);
4164 if (ewd->wl.relative_pointer_manager &&
4165 !input->wl.relative_pointer)
4167 input->wl.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
4168 ewd->wl.relative_pointer_manager,
4170 zwp_relative_pointer_v1_add_listener(input->wl.relative_pointer, &_relative_pointer_listener, input);
4172 input->want_lock_pointer = EINA_TRUE;
4178 ecore_wl2_window_pointer_constraints_unlock_pointer(Ecore_Wl2_Window *win)
4180 Ecore_Wl2_Display *ewd;
4181 Ecore_Wl2_Input *input;
4183 EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4186 input = ecore_wl2_input_default_input_get(ewd);
4187 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4189 if (input->wl.locked_pointer)
4191 INF("Pointer Constraint: Destroy locked pointer");
4192 zwp_locked_pointer_v1_destroy(input->wl.locked_pointer);
4193 input->wl.locked_pointer = NULL;
4195 input->want_lock_pointer = EINA_FALSE;
4201 ecore_wl2_window_locked_pointer_region_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
4203 Ecore_Wl2_Display *ewd;
4204 Ecore_Wl2_Input *input;
4206 EINA_SAFETY_ON_NULL_RETURN(win);
4209 input = ecore_wl2_input_default_input_get(ewd);
4210 EINA_SAFETY_ON_NULL_RETURN(input);
4212 if (input->lock_region)
4214 wl_region_destroy(input->lock_region);
4215 input->lock_region = NULL;
4218 if ((w > 0) && (h > 0))
4220 struct wl_region *region;
4222 region = wl_compositor_create_region(ewd->wl.compositor);
4225 ERR("Failed to create region of locked_pointer");
4229 input->lock_region = region;
4230 wl_region_add(input->lock_region, x, y, w, h);
4232 if (!input->wl.locked_pointer)
4234 INF("No locked_pointer available. region (%d, %d) (w:%d, h:%d)", x, y, w, h);
4238 INF("Set region for locked_pointer (%d, %d) (w:%d, h:%d)", x, y, w, h);
4239 zwp_locked_pointer_v1_set_region(input->wl.locked_pointer, input->lock_region);
4243 if (!input->wl.locked_pointer)
4245 INF("No locked_pointer available. region (%d, %d) (w:%d, h:%d)", x, y, w, h);
4248 INF("Set region for locked_pointer. NULL region");
4249 zwp_locked_pointer_v1_set_region(input->wl.locked_pointer, NULL);
4254 ecore_wl2_window_locked_pointer_cursor_position_hint_set(Ecore_Wl2_Window *win, int x, int y)
4256 Ecore_Wl2_Display *ewd;
4257 Ecore_Wl2_Input *input;
4259 EINA_SAFETY_ON_NULL_RETURN(win);
4262 input = ecore_wl2_input_default_input_get(ewd);
4263 EINA_SAFETY_ON_NULL_RETURN(input);
4265 if (!input->wl.locked_pointer)
4267 INF("No locked pointer available. cursor position hint (%d, %d)", x, y);
4271 INF("Set cursor position hint (%d, %d) for locked_pointer", x, y);
4272 zwp_locked_pointer_v1_set_cursor_position_hint(input->wl.locked_pointer,
4273 wl_fixed_from_int(x),
4274 wl_fixed_from_int(y));
4278 // TIZEN_ONLY(20230821) : add cursor_visible set API
4280 ecore_wl2_window_cursor_visible_set(Ecore_Wl2_Window *win, Eina_Bool visible)
4282 Ecore_Wl2_Display *ewd;
4283 Ecore_Wl2_Input *input;
4285 EINA_SAFETY_ON_NULL_RETURN(win);
4288 input = ecore_wl2_input_default_input_get(ewd);
4289 EINA_SAFETY_ON_NULL_RETURN(input);
4291 INF("Set cursor_visible to %s", visible ? "True" : "False");
4294 ecore_wl2_input_cursor_from_name_set(input, input->cursor.name);
4298 ecore_wl2_input_pointer_set(input, NULL, 0, 0);