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 int _devicemgr_error = -1;
90 static unsigned int _timestamp_get()
93 clock_gettime(CLOCK_MONOTONIC, &ts);
95 return ts.tv_sec * 1000 + (ts.tv_nsec / 1000000);
98 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
100 _ecore_wl2_input_convert_old_keys(unsigned int code)
104 // TIZEN ONLY(20160608) : Add option for key conversion
106 tmp = getenv("ECORE_WL_INPUT_KEY_CONVERSION_DISABLE");
107 if (tmp && atoi(tmp)) return code;
110 for (i = 0; i < _num_back_key_latest; i++)
112 if (code == _back_key_latest[i])
114 return _back_key_lt_24;
118 for (i=0; i<_num_menu_key_latest; i++)
120 if (code == _menu_key_latest[i])
122 return _menu_key_lt_24;
126 for (i=0; i<_num_home_key_latest; i++)
128 if (code == _home_key_latest[i])
130 return _home_key_lt_24;
138 _ecore_wl2_input_key_conversion_clean_up(void)
144 _num_back_key_latest = 0;
145 _num_menu_key_latest = 0;
146 _num_home_key_latest = 0;
148 if (_back_key_latest)
150 free(_back_key_latest);
151 _back_key_latest = NULL;
153 if (_menu_key_latest)
155 free(_menu_key_latest);
156 _menu_key_latest = NULL;
158 if (_home_key_latest)
160 free(_home_key_latest);
161 _home_key_latest = NULL;
166 _ecore_wl2_input_key_conversion_set(Ecore_Wl2_Input *input)
169 xkb_keycode_t *keycodes = NULL;
170 static int retry_cnt = 0;
172 if ((_tizen_api_version < 0.0) || (_tizen_api_version > 0.0)) return;
173 EINA_SAFETY_ON_NULL_RETURN(input);
174 EINA_SAFETY_ON_NULL_RETURN(input->xkb.keymap);
176 temp = getenv("TIZEN_API_VERSION");
180 _tizen_api_version = 0.0;
184 INF("No tizen api version.\n");
185 _tizen_api_version = -1.0;
190 char* lc_numeric = setlocale(LC_NUMERIC, NULL);
191 char* old_numeric = lc_numeric? strdup(lc_numeric) : NULL;
192 setlocale(LC_NUMERIC, "C");
193 _tizen_api_version = atof(temp);
196 setlocale(LC_NUMERIC, old_numeric);
199 INF("TIZEN_API_VERSION: %lf, Environment variable: %s\n", _tizen_api_version, temp);
200 if (_tizen_api_version < 2.4)
202 _ecore_wl2_input_key_conversion_clean_up();
204 ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
205 xkb_keysym_from_name("XF86Stop", XKB_KEYSYM_NO_FLAGS), &keycodes);
208 ERR("There is no entry available for the old name of back key. No conversion will be done for back key.\n");
212 _back_key_lt_24 = (int)keycodes[0];
216 _num_back_key_latest = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
217 xkb_keysym_from_name("XF86Back", XKB_KEYSYM_NO_FLAGS), &_back_key_latest);
220 ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
221 xkb_keysym_from_name("XF86Send", XKB_KEYSYM_NO_FLAGS), &keycodes);
224 ERR("There is no entry available for the old name of back key. No conversion will be done for menu key.\n");
228 _menu_key_lt_24 = (int)keycodes[0];
232 _num_menu_key_latest = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
233 xkb_keysym_from_name("XF86Menu", XKB_KEYSYM_NO_FLAGS), &_menu_key_latest);
236 ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
237 xkb_keysym_from_name("XF86Phone", XKB_KEYSYM_NO_FLAGS), &keycodes);
240 ERR("There is no entry available for the old name of back key. No conversion will be done for home key.\n");
244 _home_key_lt_24 = (int)keycodes[0];
248 _num_home_key_latest = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap,
249 xkb_keysym_from_name("XF86Home", XKB_KEYSYM_NO_FLAGS), &_home_key_latest);
252 if ((!_back_key_lt_24) && (!_menu_key_lt_24) && (!_home_key_lt_24)) _tizen_api_version = -1.0;
256 _ecore_wl2_input_key_conversion_clean_up();
261 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
263 _ecore_wl2_input_touch_radius_calc(double x, double y)
265 #define PI 3.14159265358979323846
270 _ecore_wl2_input_touch_axis_process(Ecore_Wl2_Input *input, int id)
272 if (id >= input->touch.max_count)
275 if (input->touch.last_touch_axis.radius_x)
277 input->touch.touch_axis[id].radius_x = input->touch.last_touch_axis.radius_x;
278 input->touch.last_touch_axis.radius_x = 0.0;
280 if (input->touch.last_touch_axis.radius_y)
282 input->touch.touch_axis[id].radius_y = input->touch.last_touch_axis.radius_y;
283 input->touch.last_touch_axis.radius_y = 0.0;
285 if (input->touch.last_touch_axis.pressure)
287 input->touch.touch_axis[id].pressure = input->touch.last_touch_axis.pressure;
288 input->touch.last_touch_axis.pressure = 0.0;
290 if (input->touch.last_touch_axis.angle)
292 input->touch.touch_axis[id].angle = input->touch.last_touch_axis.angle;
293 input->touch.last_touch_axis.angle = 0.0;
298 static Ecore_Wl2_Mouse_Down_Info *
299 _ecore_wl2_input_mouse_down_info_get(int device)
301 Eina_Inlist *l = NULL;
302 Ecore_Wl2_Mouse_Down_Info *info = NULL;
304 l = _ecore_wl2_mouse_down_info_list;
305 EINA_INLIST_FOREACH(l, info)
306 if (info->device == device) return info;
308 info = calloc(1, sizeof(Ecore_Wl2_Mouse_Down_Info));
309 if (!info) return NULL;
311 info->device = device;
312 l = eina_inlist_append(l, (Eina_Inlist *)info);
313 _ecore_wl2_mouse_down_info_list = l;
318 static Ecore_Wl2_Input_Devices *
319 _ecore_wl2_devices_get(const Ecore_Wl2_Input *input, int window_id)
321 Ecore_Wl2_Input_Devices *devices;
324 EINA_LIST_FOREACH(input->devices_list, l, devices)
326 if (devices->window_id == window_id)
334 _ecore_wl2_touch_dev_get(Ecore_Wl2_Input *input, int window_id)
336 Ecore_Wl2_Input_Devices *devices;
337 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
339 if (input->devmgr.last_device_touch && input->devmgr.last_device_touch->device)
341 return efl_ref(input->devmgr.last_device_touch->device);
345 devices = _ecore_wl2_devices_get(input, window_id);
346 if (devices && devices->touch_dev)
347 return efl_ref(devices->touch_dev);
353 _ecore_wl2_mouse_dev_get(Ecore_Wl2_Input *input, int window_id)
356 if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1))
357 return _ecore_wl2_touch_dev_get(input, window_id);
359 Ecore_Wl2_Input_Devices *devices;
360 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
362 if (input->devmgr.last_device_ptr && input->devmgr.last_device_ptr->device)
364 return efl_ref(input->devmgr.last_device_ptr->device);
368 devices = _ecore_wl2_devices_get(input, window_id);
369 if (devices && devices->pointer_dev)
370 return efl_ref(devices->pointer_dev);
376 _ecore_wl2_seat_dev_get(Ecore_Wl2_Input *input, int window_id)
378 Ecore_Wl2_Input_Devices *devices;
380 devices = _ecore_wl2_devices_get(input, window_id);
382 return efl_ref(devices->seat_dev);
387 //TIZEN_ONLY(20180118): support a Ecore_Device
389 _input_event_mouse_io_cb_free(void *data EINA_UNUSED, void *event)
391 Ecore_Event_Mouse_IO *ev = event;
398 _input_event_mouse_move_cb_free(void *data EINA_UNUSED, void *event)
400 Ecore_Event_Mouse_Move *ev = event;
407 _input_event_mouse_wheel_cb_free(void *data EINA_UNUSED, void *event)
409 Ecore_Event_Mouse_Wheel *ev = event;
416 _input_event_mouse_button_cb_free(void *data EINA_UNUSED, void *event)
418 Ecore_Event_Mouse_Button *ev = event;
425 _input_event_key_cb_free(void *data EINA_UNUSED, void *event)
427 Ecore_Event_Key *ev = event;
435 _ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
437 Ecore_Event_Mouse_IO *ev;
439 ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
442 ev->x = input->pointer.sx;
443 ev->y = input->pointer.sy;
444 ev->window = window->id;
445 ev->event_window = window->id;
446 ev->timestamp = input->timestamp;
447 ev->modifiers = input->keyboard.modifiers;
448 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
450 ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, _input_event_mouse_io_cb_free, ev->dev);
454 _ecore_wl2_input_mouse_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
456 Ecore_Event_Mouse_IO *ev;
458 ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
461 ev->x = input->pointer.sx;
462 ev->y = input->pointer.sy;
463 ev->window = window->id;
464 ev->event_window = window->id;
465 ev->timestamp = input->timestamp;
466 ev->modifiers = input->keyboard.modifiers;
467 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
469 ecore_event_add(ECORE_EVENT_MOUSE_OUT, ev, _input_event_mouse_io_cb_free, ev->dev);
473 _ecore_wl2_input_mouse_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device)
475 Ecore_Event_Mouse_Move *ev;
476 Ecore_Wl2_Mouse_Down_Info *info;
478 ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
481 ev->window = window->id;
482 ev->event_window = window->id;
483 ev->timestamp = input->timestamp;
484 ev->x = input->pointer.sx;
485 ev->y = input->pointer.sy;
486 ev->root.x = input->pointer.sx;
487 ev->root.y = input->pointer.sy;
488 ev->modifiers = input->keyboard.modifiers;
489 ev->multi.device = device;
491 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
492 if (device >= input->touch.max_count)
494 ev->multi.radius = 1;
495 ev->multi.radius_x = 1;
496 ev->multi.radius_y = 1;
497 ev->multi.pressure = 1.0;
498 ev->multi.angle = 0.0;
503 _ecore_wl2_input_touch_radius_calc(input->touch.touch_axis[device].radius_x,
504 input->touch.touch_axis[device].radius_y);
505 ev->multi.radius_x = input->touch.touch_axis[device].radius_x;
506 ev->multi.radius_y = input->touch.touch_axis[device].radius_y;
507 ev->multi.pressure = input->touch.touch_axis[device].pressure;
508 ev->multi.angle = input->touch.touch_axis[device].angle;
512 ev->multi.x = input->pointer.sx;
513 ev->multi.y = input->pointer.sy;
514 ev->multi.root.x = input->pointer.sx;
515 ev->multi.root.y = input->pointer.sy;
517 if ((input->focus.touch) && (input->focus.touch == window))
518 ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
519 else if ((input->focus.pointer) && (input->focus.pointer == window))
520 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
522 info = _ecore_wl2_input_mouse_down_info_get(device);
525 info->sx = input->pointer.sx;
526 info->sy = input->pointer.sy;
529 ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _input_event_mouse_move_cb_free, ev->dev);
533 _ecore_wl2_input_mouse_wheel_send(Ecore_Wl2_Input *input, unsigned int axis, int value, unsigned int timestamp)
535 Ecore_Event_Mouse_Wheel *ev;
537 ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
540 ev->timestamp = timestamp;
541 ev->modifiers = input->keyboard.modifiers;
542 ev->x = input->pointer.sx;
543 ev->y = input->pointer.sy;
544 //TIZEN_ONLY(20190306): revert upstream patch
548 if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
553 else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
559 if (input->grab.window)
561 ev->window = input->grab.window->id;
562 ev->event_window = input->grab.window->id;
564 else if (input->focus.pointer)
566 ev->window = input->focus.pointer->id;
567 ev->event_window = input->focus.pointer->id;
568 ev->dev = _ecore_wl2_mouse_dev_get(input, input->focus.pointer->id);
570 else if (input->focus.touch)
572 ev->window = input->focus.touch->id;
573 ev->event_window = input->focus.touch->id;
574 ev->dev = _ecore_wl2_touch_dev_get(input, input->focus.touch->id);
579 ev->dev = _ecore_wl2_mouse_dev_get(input, ev->window);
581 ev->dev = _ecore_wl2_touch_dev_get(input, ev->window);
584 ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _input_event_mouse_wheel_cb_free, ev->dev);
588 _ecore_wl2_input_mouse_down_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
590 Ecore_Event_Mouse_Button *ev;
591 Ecore_Wl2_Mouse_Down_Info *info;
593 ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
596 if (button == BTN_LEFT)
598 else if (button == BTN_MIDDLE)
600 else if (button == BTN_RIGHT)
603 ev->buttons = button;
605 ev->timestamp = timestamp;
606 ev->x = input->pointer.sx;
607 ev->y = input->pointer.sy;
608 ev->root.x = input->pointer.sx;
609 ev->root.y = input->pointer.sy;
610 ev->modifiers = input->keyboard.modifiers;
612 ev->double_click = 0;
613 ev->triple_click = 0;
615 info = _ecore_wl2_input_mouse_down_info_get(device);
618 info->sx = input->pointer.sx;
619 info->sy = input->pointer.sy;
620 if (info->triple_click)
623 info->last_last_win = 0;
624 info->last_event_win = 0;
625 info->last_last_event_win = 0;
627 info->last_last_time = 0;
630 if (((int)(timestamp - info->last_time) <= (int)(1000 * 0.25)) &&
631 ((window) && (window->id == info->last_win) &&
632 (window->id == info->last_event_win)))
634 ev->double_click = 1;
635 info->double_click = EINA_TRUE;
639 info->double_click = EINA_FALSE;
640 info->triple_click = EINA_FALSE;
643 if (((int)(timestamp - info->last_last_time) <=
644 (int)(2 * 1000 * 0.25)) &&
645 ((window) && (window->id == info->last_win) &&
646 (window->id == info->last_last_win) &&
647 (window->id == info->last_event_win) &&
648 (window->id == info->last_last_event_win)))
650 ev->triple_click = 1;
651 info->triple_click = EINA_TRUE;
654 info->triple_click = EINA_FALSE;
657 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
658 if (device >= input->touch.max_count)
660 ev->multi.radius = 1;
661 ev->multi.radius_x = 1;
662 ev->multi.radius_y = 1;
663 ev->multi.pressure = 1.0;
664 ev->multi.angle = 0.0;
669 _ecore_wl2_input_touch_radius_calc(input->touch.touch_axis[device].radius_x,
670 input->touch.touch_axis[device].radius_y);
671 ev->multi.radius_x = input->touch.touch_axis[device].radius_x;
672 ev->multi.radius_y = input->touch.touch_axis[device].radius_y;
673 ev->multi.pressure = input->touch.touch_axis[device].pressure;
674 ev->multi.angle = input->touch.touch_axis[device].angle;
677 ev->multi.device = device;
678 ev->multi.x = input->pointer.sx;
679 ev->multi.y = input->pointer.sy;
680 ev->multi.root.x = input->pointer.sx;
681 ev->multi.root.y = input->pointer.sy;
685 ev->window = window->id;
686 ev->event_window = window->id;
688 if ((input->focus.touch) && (input->focus.touch == window))
689 ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
690 else if ((input->focus.pointer) && (input->focus.pointer == window))
691 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
694 //TIZEN_ONLY(20200408): add debug
695 ERR("[press] window = %p, time=%u button=%d", window, (unsigned int)timestamp, device);
698 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev,
699 _input_event_mouse_button_cb_free, ev->dev);
701 if ((info) && (!info->triple_click))
703 info->last_last_win = info->last_win;
704 info->last_win = ev->window;
705 info->last_last_event_win = info->last_event_win;
706 info->last_event_win = ev->window;
707 info->last_last_time = info->last_time;
708 info->last_time = timestamp;
713 _ecore_wl2_input_mouse_up_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
715 Ecore_Event_Mouse_Button *ev;
716 Ecore_Wl2_Mouse_Down_Info *info;
718 ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
721 if (button == BTN_LEFT)
723 else if (button == BTN_MIDDLE)
725 else if (button == BTN_RIGHT)
728 ev->buttons = button;
730 ev->timestamp = timestamp;
731 ev->x = input->pointer.sx;
732 ev->y = input->pointer.sy;
733 ev->root.x = input->pointer.sx;
734 ev->root.y = input->pointer.sy;
735 ev->modifiers = input->keyboard.modifiers;
737 ev->double_click = 0;
738 ev->triple_click = 0;
740 info = _ecore_wl2_input_mouse_down_info_get(device);
743 ev->double_click = info->double_click;
744 ev->triple_click = info->triple_click;
747 ev->multi.x = info->sx;
748 ev->multi.y = info->sy;
752 ev->multi.x = input->pointer.sx;
753 ev->multi.y = input->pointer.sy;
756 ev->multi.device = device;
757 ev->multi.radius = 1;
758 ev->multi.radius_x = 1;
759 ev->multi.radius_y = 1;
760 ev->multi.pressure = 1.0;
761 ev->multi.angle = 0.0;
762 ev->multi.root.x = input->pointer.sx;
763 ev->multi.root.y = input->pointer.sy;
765 ev->window = window->id;
766 ev->event_window = window->id;
768 if ((input->focus.touch) && (input->focus.touch == window))
769 ev->dev = _ecore_wl2_touch_dev_get(input, window->id);
770 else if ((input->focus.pointer) && (input->focus.pointer == window))
771 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
773 //TIZEN_ONLY(20200408): add debug
774 ERR("[release] time=%u button=%d", (unsigned int)timestamp, device);
777 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev,
778 _input_event_mouse_button_cb_free, ev->dev);
781 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
782 if (device < input->touch.max_count)
784 input->touch.touch_axis[device].radius_x = 1.0;
785 input->touch.touch_axis[device].radius_y = 1.0;
786 input->touch.touch_axis[device].pressure = 1.0;
787 input->touch.touch_axis[device].angle = 0;
793 _input_event_focus_cb_free(void *data, void *event)
795 Ecore_Wl2_Event_Focus_In *ev = event;
798 ecore_wl2_display_disconnect(ev->display);
803 _ecore_wl2_input_focus_in_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
805 Ecore_Wl2_Event_Focus_In *ev;
807 ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_In));
810 ev->timestamp = input->timestamp;
811 ev->window = window->id;
812 ev->dev = _ecore_wl2_seat_dev_get(input, window->id);
813 ev->display = input->display;
815 ecore_event_add(ECORE_WL2_EVENT_FOCUS_IN, ev, _input_event_focus_cb_free,
820 _ecore_wl2_input_focus_out_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
822 Ecore_Wl2_Event_Focus_Out *ev;
824 ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_Out));
827 ev->timestamp = input->timestamp;
828 ev->window = window->id;
829 ev->dev = _ecore_wl2_seat_dev_get(input, window->id);
830 ev->display = input->display;
832 ecore_event_add(ECORE_WL2_EVENT_FOCUS_OUT, ev, _input_event_focus_cb_free,
837 _ecore_wl2_input_key_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes)
839 /* this function is copied, with slight changes in variable names, from KeyBind.c in libX11
840 * the license from that file can be found below:
844 Copyright 1985, 1987, 1998 The Open Group
846 Permission to use, copy, modify, distribute, and sell this software and its
847 documentation for any purpose is hereby granted without fee, provided that
848 the above copyright notice appear in all copies and that both that
849 copyright notice and this permission notice appear in supporting
852 The above copyright notice and this permission notice shall be included in
853 all copies or substantial portions of the Software.
855 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
856 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
857 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
858 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
859 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
860 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
862 Except as contained in this notice, the name of The Open Group shall not be
863 used in advertising or otherwise to promote the sale, use or other dealings
864 in this Software without prior written authorization from The Open Group.
867 if (!keysym) return 0;
869 /* check for possible control codes */
870 if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
872 Eina_Bool valid_control_code = EINA_TRUE;
873 unsigned long hbytes = 0;
876 hbytes = (keysym >> 8);
880 (((keysym >= XKB_KEY_BackSpace) && (keysym <= XKB_KEY_Clear)) ||
881 (keysym == XKB_KEY_Return) ||
882 (keysym == XKB_KEY_Escape) ||
883 (keysym == XKB_KEY_KP_Space) ||
884 (keysym == XKB_KEY_KP_Tab) ||
885 (keysym == XKB_KEY_KP_Enter) ||
886 ((keysym >= XKB_KEY_KP_Multiply) && (keysym <= XKB_KEY_KP_9)) ||
887 (keysym == XKB_KEY_KP_Equal) ||
888 (keysym == XKB_KEY_Delete))))))
891 if (keysym == XKB_KEY_KP_Space)
892 c = (XKB_KEY_space & 0x7F);
893 else if (hbytes == 0xFF)
898 /* We are building here a control code
899 for more details, read:
900 https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C0_.28ASCII_and_derivatives.29
903 if (((c >= '@') && (c <= '_')) || /* those are the one defined in C0 with capital letters */
904 ((c >= 'a') && (c <= 'z')) || /* the lowercase symbols (not part of the standard, but useful) */
907 else if (c == '\x7f')
909 /* following codes are alternatives, they are longer here, i dont want to change them */
911 c = '\000'; /* 0 code */
912 else if ((c >= '3') && (c <= '7'))
913 c -= ('3' - '\033'); /* from escape to unitseperator code*/
915 c = '\177'; /* delete code */
917 c = '_' & 0x1F; /* unit seperator code */
919 valid_control_code = EINA_FALSE;
921 if (valid_control_code)
928 /* if its not a control code, try to produce useful output */
929 if (!xkb_keysym_to_utf8(keysym, buffer, bytes))
937 _ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code)
939 if (xkb_keysym_get_name(keysym, buffer, size) != 0)
942 snprintf(buffer, size, "Keycode-%u", code);
946 _ecore_wl2_keyboard_dev_get(Ecore_Wl2_Input *input, int window_id)
948 Ecore_Wl2_Input_Devices *devices;
949 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
951 if (input->devmgr.last_device_kbd && input->devmgr.last_device_kbd->device)
953 return efl_ref(input->devmgr.last_device_kbd->device);
957 devices = _ecore_wl2_devices_get(input, window_id);
958 if (devices && devices->keyboard_dev)
959 return efl_ref(devices->keyboard_dev);
965 _ecore_wl2_input_key_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, xkb_keysym_t sym, xkb_keysym_t sym_name, unsigned int code, unsigned int state, unsigned int timestamp, Eina_Bool cancel, Eina_Bool repeat)
968 char key[256] = "", keyname[256] = "", compose[256] = "";
969 int name_len, key_len, comp_len;
971 /*try to get a name or utf char of the given symbol */
972 _ecore_wl2_input_symbol_rep_find(sym, key, sizeof(key), code);
973 _ecore_wl2_input_symbol_rep_find(sym_name, keyname, sizeof(keyname), code);
974 _ecore_wl2_input_key_translate(sym, input->keyboard.modifiers,
975 compose, sizeof(compose));
977 name_len = strlen(keyname);
978 key_len = strlen(key);
979 comp_len = strlen(compose);
981 ev = calloc(1, sizeof(Ecore_Event_Key) + key_len + name_len + comp_len + 3);
984 ev->keyname = (char *)(ev + 1);
985 ev->key = ev->keyname + name_len + 1;
986 ev->compose = comp_len ? ev->key + key_len + 1 : NULL;
987 ev->string = ev->compose;
988 ev->event_flags = ECORE_EVENT_FLAG_NONE;
990 ev->event_flags |= ECORE_EVENT_FLAG_CANCEL;
992 ev->event_flags |= ECORE_EVENT_FLAG_REPEAT;
994 strcpy((char *)ev->keyname, keyname);
995 strcpy((char *)ev->key, key);
996 if (comp_len) strcpy((char *)ev->compose, compose);
998 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1001 ev->window = window->id;
1002 ev->event_window = window->id;
1003 ev->dev = _ecore_wl2_keyboard_dev_get(input, window->id);
1007 ev->window = (uintptr_t)NULL;
1008 ev->event_window = (uintptr_t)NULL;
1009 ev->dev = _ecore_wl2_keyboard_dev_get(input, 0);
1012 ev->timestamp = timestamp;
1013 ev->modifiers = input->keyboard.modifiers;
1016 /* DBG("Emitting Key event (%s,%s,%s,%s)\n", ev->keyname, ev->key, ev->compose, ev->string); */
1019 ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, _input_event_key_cb_free, ev->dev);
1021 ecore_event_add(ECORE_EVENT_KEY_UP, ev, _input_event_key_cb_free, ev->dev);
1025 _ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, unsigned int button)
1027 input->grab.window = window;
1028 input->grab.button = button;
1032 _ecore_wl2_input_ungrab(Ecore_Wl2_Input *input)
1034 if ((input->grab.window) && (input->grab.button) && (input->grab.count))
1035 _ecore_wl2_input_mouse_up_send(input, input->grab.window, 0,
1036 input->grab.button, input->grab.timestamp);
1038 input->grab.window = NULL;
1039 input->grab.button = 0;
1040 input->grab.count = 0;
1041 input->grab.touch_count = 0;
1045 _pointer_cb_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy)
1047 Ecore_Wl2_Input *input;
1048 Ecore_Wl2_Window *window;
1049 const char *config_cursor_name;
1054 /* trap for a surface that was just destroyed */
1055 if (!surface) return;
1057 if (!input->timestamp)
1061 gettimeofday(&tv, NULL);
1062 input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
1065 input->display->serial = serial;
1066 input->pointer.enter_serial = serial;
1067 input->pointer.sx = wl_fixed_to_double(sx);
1068 input->pointer.sy = wl_fixed_to_double(sy);
1070 // Cursor change from configuration is applied only for default cursor
1071 if (eina_streq(input->cursor.theme_name, "default"))
1073 _ecore_wl2_cursor_config_reload();
1074 config_cursor_name = _ecore_wl2_cursor_config_name_get();
1075 if (config_cursor_name)
1077 if (!input->cursor.name || !eina_streq(input->cursor.name, config_cursor_name))
1078 eina_stringshare_replace(&input->cursor.name, config_cursor_name);
1082 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1083 // TIZEN_ONLY(20230330): support client that requests to unset cursor
1084 /* The cursor on the surface is undefined until we set it */
1085 if (!input->cursor.name)
1086 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
1088 ecore_wl2_input_cursor_from_name_set(input, input->cursor.name);
1092 /* find the window which this surface belongs to */
1093 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1094 if (!window) return;
1096 // TIZEN_ONLY(20190729): do not generate duplicated mouse in events
1097 if (input->focus.pointer == window) return;
1100 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1101 window->pointer.device = input;
1103 input->focus.prev_pointer = NULL;
1104 input->focus.pointer = window;
1106 _ecore_wl2_input_mouse_in_send(input, window);
1110 _pointer_cb_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
1112 Ecore_Wl2_Input *input;
1113 Ecore_Wl2_Window *window;
1118 input->display->serial = serial;
1119 input->focus.prev_pointer = input->focus.pointer;
1120 input->focus.pointer = NULL;
1122 /* trap for a surface that was just destroyed */
1123 if (!surface) return;
1125 /* find the window which this surface belongs to */
1126 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1127 if (!window) return;
1129 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
1130 window->pointer.device = NULL;
1133 _ecore_wl2_input_mouse_out_send(input, window);
1137 _pointer_cb_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy)
1139 Ecore_Wl2_Input *input;
1140 Ecore_Wl2_Window *window;
1145 input->timestamp = timestamp;
1146 input->pointer.sx = wl_fixed_to_double(sx);
1147 input->pointer.sy = wl_fixed_to_double(sy);
1149 /* get currently focused window */
1150 window = input->focus.pointer;
1151 if (!window) return;
1153 /* NB: Unsure if we need this just yet, so commented out for now */
1154 /* if ((input->pointer.sx > window->geometry.w) || */
1155 /* (input->pointer.sy > window->geometry.h)) */
1159 if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1) && (input->grab.count == 0))
1162 _ecore_wl2_input_mouse_move_send(input, window, 0);
1166 _pointer_cb_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state)
1168 Ecore_Wl2_Input *input;
1173 input->display->serial = serial;
1174 input->timestamp = timestamp;
1176 if (state == WL_POINTER_BUTTON_STATE_PRESSED)
1178 if ((input->focus.pointer) &&
1179 (!input->grab.window) && (!input->grab.count))
1181 _ecore_wl2_input_grab(input, input->focus.pointer, button);
1182 input->grab.timestamp = timestamp;
1185 if (input->focus.pointer)
1188 if ((tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1) && (input->grab.count == 0))
1189 _ecore_wl2_input_mouse_move_send(input, input->focus.pointer, 0);
1191 _ecore_wl2_input_mouse_down_send(input, input->focus.pointer,
1192 0, button, timestamp);
1195 input->grab.count++;
1199 if (input->focus.pointer)
1200 _ecore_wl2_input_mouse_up_send(input, input->focus.pointer,
1201 0, button, timestamp);
1203 if (input->grab.count) input->grab.count--;
1204 if ((input->grab.window) && (input->grab.button == button) &&
1205 (!input->grab.count))
1206 _ecore_wl2_input_ungrab(input);
1211 _pointer_cb_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value)
1213 Ecore_Wl2_Input *input;
1218 input->timestamp = timestamp;
1220 _ecore_wl2_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value),
1224 static const struct wl_pointer_listener _pointer_listener =
1232 NULL, /* axis_source */
1233 NULL, /* axis_stop */
1234 NULL, /* axis_discrete */
1237 // TIZEN_ONLY(20230802): ecore_input: add Ecore_Event_Mouse_Relative_Move struct
1239 _ecore_wl2_input_mouse_relative_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int dx, int dy, int dx_unaccel, int dy_unaccel)
1241 Ecore_Event_Mouse_Relative_Move *ev;
1243 ev = calloc(1, sizeof(Ecore_Event_Mouse_Relative_Move));
1246 ev->window = window->id;
1247 ev->event_window = window->id;
1248 ev->timestamp = input->timestamp;
1249 ev->modifiers = input->keyboard.modifiers;
1252 ev->dx_unaccel = dx_unaccel;
1253 ev->dy_unaccel = dy_unaccel;
1255 ev->dev = _ecore_wl2_mouse_dev_get(input, window->id);
1257 ERR("[Relative Move] timestamp=%u dx=%d, dy=%d, dx_unaccel=%d, dy_unaccel=%d", ev->timestamp, ev->dx, ev->dy, ev->dx_unaccel, ev->dy_unaccel);
1258 ecore_event_add(ECORE_EVENT_MOUSE_RELATIVE_MOVE, ev, NULL, NULL);
1262 // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
1264 _relative_pointer_cb_relative_motion(void *data, struct zwp_relative_pointer_v1* relative_pointer,
1265 uint32_t ts_high, uint32_t ts_low, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel)
1267 Ecore_Wl2_Input *input;
1268 Ecore_Wl2_Window *window;
1269 (void) relative_pointer;
1275 ERR("[relative_pointer] ts_high=%u, ts_low=%u, dx=%d, dy=%d, dx_unaccel=%d, dy_unaccel=%d",
1276 ts_high, ts_low, wl_fixed_to_int(dx), wl_fixed_to_int(dy), wl_fixed_to_int(dx_unaccel), wl_fixed_to_int(dy_unaccel));
1278 input->timestamp = (unsigned int)ts_low;
1280 /* get currently focused window */
1281 window = input->focus.pointer;
1282 if (!window) return;
1284 _ecore_wl2_input_mouse_relative_move_send(input, window, wl_fixed_to_int(dx), wl_fixed_to_int(dy),
1285 wl_fixed_to_int(dx_unaccel), wl_fixed_to_int(dy_unaccel));
1288 static const struct zwp_relative_pointer_v1_listener _relative_pointer_listener = {
1289 _relative_pointer_cb_relative_motion,
1293 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
1295 _locked_pointer_cb_locked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1 EINA_UNUSED)
1297 Ecore_Wl2_Input *input = (Ecore_Wl2_Input *)data;
1300 ERR("[locked pointer] locked");
1301 input->pointer_locked = EINA_TRUE;
1305 _locked_pointer_cb_unlocked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1 EINA_UNUSED)
1307 Ecore_Wl2_Input *input = (Ecore_Wl2_Input *)data;
1310 ERR("[locked pointer] unlocked");
1311 input->pointer_locked = EINA_FALSE;
1314 static const struct zwp_locked_pointer_v1_listener _locked_pointer_listener = {
1315 _locked_pointer_cb_locked,
1316 _locked_pointer_cb_unlocked,
1321 _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size)
1323 Ecore_Wl2_Input *input;
1324 Ecore_Wl2_Event_Seat_Keymap_Changed *ev;
1335 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
1341 map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1342 if (map == MAP_FAILED)
1348 /* free any existing keymap and state */
1349 if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
1350 if (input->xkb.state) xkb_state_unref(input->xkb.state);
1351 if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
1354 xkb_map_new_from_string(input->display->xkb_context, map,
1355 XKB_KEYMAP_FORMAT_TEXT_V1, 0);
1360 if (!input->xkb.keymap)
1362 ERR("Failed to compile keymap");
1366 input->xkb.state = xkb_state_new(input->xkb.keymap);
1367 input->xkb.maskless_state = xkb_state_new(input->xkb.keymap);
1369 if (!input->xkb.state || !input->xkb.maskless_state)
1371 ERR("Failed to create keymap state");
1372 xkb_map_unref(input->xkb.keymap);
1373 input->xkb.keymap = NULL;
1377 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
1378 _tizen_api_version = 0.0;
1381 if (!(locale = getenv("LC_ALL")))
1382 if (!(locale = getenv("LC_CTYPE")))
1383 if (!(locale = getenv("LANG")))
1386 if (input->xkb.compose_table)
1387 xkb_compose_table_unref(input->xkb.compose_table);
1389 input->xkb.compose_table =
1390 xkb_compose_table_new_from_locale(input->display->xkb_context,
1391 locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
1392 if (input->xkb.compose_state)
1393 xkb_compose_state_unref(input->xkb.compose_state);
1394 input->xkb.compose_state = NULL;
1396 if (input->xkb.compose_table)
1398 input->xkb.compose_state =
1399 xkb_compose_state_new(input->xkb.compose_table,
1400 XKB_COMPOSE_STATE_NO_FLAGS);
1403 ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1407 ev->display = input->display;
1408 input->display->refs++;
1409 ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYMAP_CHANGED, ev,
1410 _display_event_free, ev->display);
1413 input->xkb.control_mask =
1414 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CTRL);
1415 input->xkb.alt_mask =
1416 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_ALT);
1417 input->xkb.shift_mask =
1418 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_SHIFT);
1419 input->xkb.win_mask =
1420 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_LOGO);
1421 input->xkb.scroll_mask =
1422 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_SCROLL);
1423 input->xkb.num_mask =
1424 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_NUM);
1425 input->xkb.caps_mask =
1426 1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CAPS);
1427 input->xkb.altgr_mask =
1428 1 << xkb_map_mod_get_index(input->xkb.keymap, "ISO_Level3_Shift");
1432 _keyboard_cb_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED)
1434 Ecore_Wl2_Input *input;
1435 Ecore_Wl2_Window *window;
1440 input->display->serial = serial;
1442 if (!input->timestamp)
1446 gettimeofday(&tv, NULL);
1447 input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
1450 /* find the window which this surface belongs to */
1451 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1452 if (!window) return;
1454 input->focus.keyboard = window;
1455 _ecore_wl2_input_focus_in_send(window, input);
1459 _keyboard_cb_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
1461 Ecore_Wl2_Input *input;
1462 Ecore_Wl2_Window *window;
1467 input->display->serial = serial;
1469 // TIZEN_ONLY(20160615): Fix key repeat logic.
1471 input->repeat.sym = 0;
1472 input->repeat.key = 0;
1473 input->repeat.time = 0;
1474 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1475 input->repeat.timer = NULL;
1478 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1481 if (input->focus.keyboard != window)
1482 ERR("Received keyboard.leave when keyboard did not have enter");
1484 input->focus.keyboard = NULL;
1486 _ecore_wl2_input_focus_out_send(window, input);
1490 _keyboard_cb_repeat(void *data)
1492 Ecore_Wl2_Input *input;
1495 if (!input || !input->repeat.timer) return ECORE_CALLBACK_CANCEL;
1497 if (!input->repeat.repeating)
1500 double cur_time = ecore_time_get();
1501 if (cur_time > input->repeat.intime)
1503 input->repeat.intime = cur_time + (cur_time - input->repeat.intime) + 0.0166;
1504 ecore_timer_interval_set(input->repeat.timer, input->repeat.intime - cur_time);
1505 return ECORE_CALLBACK_RENEW;
1508 if (input->repeat.key == 105 || input->repeat.key == 106 ) // Left:105 Right:106
1509 ecore_timer_interval_set(input->repeat.timer, input->repeat.horizontal.rate);
1510 else if (input->repeat.key == 103 || input->repeat.key == 108) // UP:103 Down:108
1511 ecore_timer_interval_set(input->repeat.timer, input->repeat.vertical.rate);
1513 ecore_timer_interval_set(input->repeat.timer, input->repeat.rate);
1515 input->repeat.repeating = EINA_TRUE;
1518 if (input->repeat.key == 105 || input->repeat.key == 106 )
1519 input->repeat.time += (int)(input->repeat.horizontal.rate * 1000.0);
1520 else if (input->repeat.key == 103 || input->repeat.key == 108)
1521 input->repeat.time += (int)(input->repeat.vertical.rate * 1000.0);
1523 input->repeat.time += (int)(input->repeat.rate * 1000.0);
1525 _ecore_wl2_input_key_send(input, input->repeat_win,
1526 input->repeat.sym, input->repeat.sym_name,
1527 input->repeat.key + 8,
1528 WL_KEYBOARD_KEY_STATE_PRESSED,
1529 input->repeat.time, EINA_FALSE, EINA_TRUE);
1531 return ECORE_CALLBACK_RENEW;
1534 /* from weston/clients/window.c */
1535 /* Translate symbols appropriately if a compose sequence is being entered */
1537 process_key_press(xkb_keysym_t sym, Ecore_Wl2_Input *input)
1539 if (!input->xkb.compose_state)
1541 if (sym == XKB_KEY_NoSymbol)
1543 if (xkb_compose_state_feed(input->xkb.compose_state, sym) !=
1544 XKB_COMPOSE_FEED_ACCEPTED)
1547 switch (xkb_compose_state_get_status(input->xkb.compose_state))
1549 case XKB_COMPOSE_COMPOSING:
1550 return XKB_KEY_NoSymbol;
1551 case XKB_COMPOSE_COMPOSED:
1552 return xkb_compose_state_get_one_sym(input->xkb.compose_state);
1553 case XKB_COMPOSE_CANCELLED:
1554 return XKB_KEY_NoSymbol;
1555 case XKB_COMPOSE_NOTHING:
1562 _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state)
1564 Ecore_Wl2_Input *input;
1565 Ecore_Wl2_Window *window;
1567 xkb_keysym_t sym = XKB_KEY_NoSymbol, sym_name = XKB_KEY_NoSymbol;
1568 const xkb_keysym_t *syms;
1569 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1570 struct wl_surface *surface = NULL;
1572 static Eina_Bool _key_event_cancel = EINA_FALSE;
1577 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1580 window = input->key_win;
1582 else if ((input->repeat.key) && (keycode == input->repeat.key))
1584 window = input->repeat_win;
1588 window = input->focus.keyboard; /* try to get the window which has keyboard focus */
1590 input->display->serial = serial;
1591 input->timestamp = timestamp;
1593 /* xkb rules reflect X broken keycodes, so offset by 8 */
1596 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1599 INF("window is not focused");
1600 surface = (struct wl_surface *) eina_hash_find(_ecore_wl2_keygrab_hash_get(), &code);
1603 window = ecore_wl2_window_surface_find(surface);
1604 INF("keycode(%d) is grabbed in the window(%p)", code, window);
1608 //key event callback can be called even though surface is not exist.
1609 //TODO: Ecore_Event_Key have event_window info, so if (surface == NULL), we should generate proper window info
1610 INF("surface is not exist");
1615 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
1616 if (_tizen_api_version == 0.0) _ecore_wl2_input_key_conversion_set(input);
1618 // if it is one of the back/menu/home key and _tizen_api_version is less than 2.4.
1619 if (0.0 < _tizen_api_version && _tizen_api_version < 2.4)
1620 code = _ecore_wl2_input_convert_old_keys(code);
1623 //TIZEN_ONLY(20200408): add debug
1624 ERR("Key[%d] event occurs %u", code, timestamp);
1627 if (xkb_state_key_get_syms(input->xkb.state, code, &syms) == 1)
1629 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1630 sym = process_key_press(sym, input);
1631 sym_name = xkb_state_key_get_one_sym(input->xkb.maskless_state, code);
1633 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1634 if (input->key_win) input->key_win = NULL;
1636 if (sym == XKB_KEY_Cancel)
1638 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1639 _key_event_cancel = EINA_TRUE;
1641 _key_event_cancel = EINA_FALSE;
1645 _ecore_wl2_input_key_send(input, window, sym, sym_name, code,
1646 state, timestamp, _key_event_cancel, EINA_FALSE);
1648 if (!xkb_keymap_key_repeats(input->xkb.keymap, code)) return;
1650 if ((state == WL_KEYBOARD_KEY_STATE_RELEASED) &&
1651 (keycode == input->repeat.key))
1653 input->repeat.sym = 0;
1654 input->repeat.key = 0;
1655 input->repeat.time = 0;
1656 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1657 input->repeat.timer = NULL;
1658 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1659 input->repeat_win = NULL;
1662 else if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1664 /* don't setup key repeat timer if not enabled */
1665 if (!input->repeat.enabled) return;
1667 input->repeat.sym = sym;
1668 input->repeat.sym_name = sym;
1669 input->repeat.key = keycode;
1670 input->repeat.time = timestamp;
1671 // TIZEN_ONLY(20180404): support a tizen_keyrouter event surface event
1672 input->repeat_win = window;
1675 /* Delete this timer if there is still one */
1676 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1677 input->repeat.timer = NULL;
1679 if (!input->repeat.timer)
1681 input->repeat.repeating = EINA_FALSE;
1682 if (keycode == 105 || keycode == 106 )
1684 input->repeat.timer = ecore_timer_add(input->repeat.horizontal.delay, _keyboard_cb_repeat, input);
1685 input->repeat.intime = (ecore_time_get() + input->repeat.horizontal.delay + 0.0166);
1687 else if (keycode == 103 || keycode == 108)
1689 input->repeat.timer = ecore_timer_add(input->repeat.vertical.delay, _keyboard_cb_repeat, input);
1690 input->repeat.intime = (ecore_time_get() + input->repeat.vertical.delay + 0.0166);
1694 input->repeat.timer = ecore_timer_add(input->repeat.delay, _keyboard_cb_repeat, input);
1695 input->repeat.intime = (ecore_time_get() + input->repeat.delay + 0.0166);
1703 _keyboard_cb_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group)
1705 Ecore_Wl2_Input *input;
1706 xkb_mod_mask_t mask;
1711 /* skip PC style modifiers if we have no keymap */
1712 if (!input->xkb.keymap) return;
1714 xkb_state_update_mask(input->xkb.state,
1715 depressed, latched, locked, 0, 0, group);
1718 xkb_state_serialize_mods(input->xkb.state,
1719 XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
1721 /* reset modifiers to default */
1722 input->keyboard.modifiers = 0;
1724 if (mask & input->xkb.control_mask)
1725 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CTRL;
1726 if (mask & input->xkb.alt_mask)
1727 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALT;
1728 if (mask & input->xkb.shift_mask)
1729 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
1730 if (mask & input->xkb.win_mask)
1731 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_WIN;
1732 if (mask & input->xkb.altgr_mask)
1733 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
1734 if (mask & input->xkb.scroll_mask)
1735 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SCROLL;
1736 if (mask & input->xkb.num_mask)
1737 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_NUM;
1738 if (mask & input->xkb.caps_mask)
1739 input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CAPS;
1742 mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_LOCKED);
1743 if (mask & input->xkb.scroll_mask)
1744 input->keyboard.modifiers |= ECORE_EVENT_LOCK_SCROLL;
1745 if (mask & input->xkb.num_mask)
1746 input->keyboard.modifiers |= ECORE_EVENT_LOCK_NUM;
1747 if (mask & input->xkb.caps_mask)
1748 input->keyboard.modifiers |= ECORE_EVENT_LOCK_CAPS;
1752 _keyboard_cb_repeat_setup(void *data, struct wl_keyboard *keyboard EINA_UNUSED, int32_t rate, int32_t delay)
1754 Ecore_Wl2_Input *input;
1755 Ecore_Wl2_Event_Seat_Keyboard_Repeat_Changed *ev;
1762 input->repeat.enabled = EINA_FALSE;
1766 input->repeat.enabled = EINA_TRUE;
1767 if (!input->repeat.changed)
1769 //TIZEN_ONLY(20200128): Tizen calculates rate differently.
1770 //input->repeat.rate = (1.0 / rate);
1772 input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = (rate / 1000.0);
1773 input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = (delay / 1000.0);
1775 ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1779 ev->display = input->display;
1780 ev->display->refs++;
1781 ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYBOARD_REPEAT_CHANGED, ev,
1782 _display_event_free, ev->display);
1786 static const struct wl_keyboard_listener _keyboard_listener =
1788 _keyboard_cb_keymap,
1792 _keyboard_cb_modifiers,
1793 _keyboard_cb_repeat_setup
1797 _touch_cb_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface, int id, wl_fixed_t x, wl_fixed_t y)
1799 Ecore_Wl2_Input *input;
1800 Ecore_Wl2_Window *window;
1803 //TIZEN_ONLY(20200408): add debug
1806 ERR("input is NULL");
1810 /* find the window which this surface belongs to */
1811 window = _ecore_wl2_display_window_surface_find(input->display, surface);
1812 //TIZEN_ONLY(20200408): add debug
1815 ERR("window is NULL");
1820 input->focus.touch = window;
1821 input->timestamp = timestamp;
1822 input->grab.touch_count++;
1823 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1824 input->grab.touch_array[id] = EINA_TRUE;
1827 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1828 _ecore_wl2_input_touch_axis_process(input, id);
1831 // TIZEN_ONLY(20171207): do not send pointer enter about all of touch down
1833 _pointer_cb_enter(data, NULL, serial, surface, x, y);
1836 input->grab.count++;
1838 if ((!input->grab.window) && (input->focus.touch) && input->grab.touch_count == 1)
1840 _pointer_cb_enter(data, NULL, serial, surface, x, y);
1841 _ecore_wl2_input_grab(input, input->focus.touch, BTN_LEFT);
1842 input->grab.timestamp = timestamp;
1846 input->pointer.sx = wl_fixed_to_double(x);
1847 input->pointer.sy = wl_fixed_to_double(y);
1852 // TIZEN_ONLY(20171107): always send move event when touch down event is occurred
1853 _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1855 _ecore_wl2_input_mouse_down_send(input, input->focus.touch, id,
1856 BTN_LEFT, timestamp);
1860 _touch_cb_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id)
1862 Ecore_Wl2_Input *input;
1864 //TIZEN_ONLY(20200408): add debug
1865 //if (!input) return;
1866 //EINA_SAFETY_ON_NULL_RETURN(input->focus.touch); //if this is happening, then we are getting up events in a invalid state
1870 ERR("input is NULL");
1873 if (!input->focus.touch)
1875 ERR("touch_focus is false");
1879 input->timestamp = timestamp;
1880 input->display->serial = serial;
1882 _ecore_wl2_input_mouse_up_send(input, input->focus.touch, id,
1883 BTN_LEFT, timestamp);
1885 if (input->grab.count) input->grab.count--;
1886 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1887 if (input->grab.touch_array[id] && input->grab.touch_count) input->grab.touch_count--;
1888 if (input->grab.touch_array[id]) input->grab.touch_array[id] = EINA_FALSE;
1890 if ((input->grab.window) && (input->grab.button == BTN_LEFT) &&
1891 (!input->grab.count) && !input->grab.touch_count)
1892 _ecore_wl2_input_ungrab(input);
1894 if (input->grab.touch_count == 0) input->focus.touch = NULL;
1899 _touch_cb_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id, wl_fixed_t x, wl_fixed_t y)
1901 Ecore_Wl2_Input *input;
1904 //TIZEN_ONLY(20200408): add debug
1905 //if (!input) return;
1906 //if (!input->focus.touch) return;
1909 ERR("input is NULL");
1912 if (!input->focus.touch)
1914 ERR("touch_focus is false");
1918 input->timestamp = timestamp;
1919 input->pointer.sx = wl_fixed_to_int(x);
1920 input->pointer.sy = wl_fixed_to_int(y);
1922 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1923 _ecore_wl2_input_touch_axis_process(input, id);
1926 _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1930 _touch_cb_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED)
1936 _touch_cb_cancel(void *data, struct wl_touch *touch EINA_UNUSED)
1938 //TIZEN_ONLY(20171107): generate mouse button cancel event
1939 Ecore_Event_Mouse_Button *ev;
1940 Ecore_Wl2_Input *input;
1942 if (!(input = data)) return;
1943 if (!input->focus.touch) return;
1945 if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)))) return;
1946 EINA_SAFETY_ON_NULL_RETURN(ev);
1948 ev->timestamp = _timestamp_get();
1949 ev->same_screen = 1;
1950 ev->window = input->focus.touch->id;
1951 ev->event_window = ev->window;
1955 ev->root.x = input->pointer.sx;
1956 ev->root.y = input->pointer.sy;
1957 ev->x = input->pointer.sx;
1958 ev->y = input->pointer.sy;
1959 ev->modifiers = input->keyboard.modifiers;
1961 ev->dev = _ecore_wl2_touch_dev_get(input, ev->window);
1963 //TIZEN_ONLY(20200408): add debug
1964 ERR("[cancel] time=%u window=0x%x", ev->timestamp, ev->window);
1967 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
1968 for (int i = 0; i < ECORE_WL2_TOUCH_MAX; i++)
1969 input->grab.touch_array[i] = EINA_FALSE;
1970 input->focus.touch = NULL;
1971 input->grab.count = 0;
1972 _ecore_wl2_input_ungrab(input);
1975 ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev, NULL, _input_event_mouse_button_cb_free);
1979 static const struct wl_touch_listener _touch_listener =
1986 NULL, // XXX: FIXME: add shape
1987 NULL, // XXX: FIXME: add orientation
1991 _data_cb_offer(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
1993 Ecore_Wl2_Input *input;
1998 _ecore_wl2_dnd_add(input, offer);
2002 _data_cb_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer)
2004 Ecore_Wl2_Input *input;
2009 _ecore_wl2_dnd_enter(input, offer, surface,
2010 wl_fixed_to_int(x), wl_fixed_to_int(y), serial);
2014 _data_cb_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
2016 Ecore_Wl2_Input *input;
2021 _ecore_wl2_dnd_leave(input);
2025 _data_cb_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, wl_fixed_t x, wl_fixed_t y)
2027 Ecore_Wl2_Input *input;
2032 _ecore_wl2_dnd_motion(input, wl_fixed_to_int(x),
2033 wl_fixed_to_int(y), serial);
2037 _data_cb_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
2039 Ecore_Wl2_Input *input;
2044 _ecore_wl2_dnd_drop(input);
2048 _data_cb_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
2050 Ecore_Wl2_Input *input;
2055 _ecore_wl2_dnd_selection(input, offer);
2058 static const struct wl_data_device_listener _data_listener =
2069 _seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
2071 Ecore_Wl2_Event_Seat_Capabilities *ev;
2072 Ecore_Wl2_Input *input;
2077 if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->wl.pointer))
2079 input->wl.pointer = wl_seat_get_pointer(seat);
2080 wl_pointer_set_user_data(input->wl.pointer, input);
2081 wl_pointer_add_listener(input->wl.pointer, &_pointer_listener, input);
2083 // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
2084 if (input->display->wl.relative_pointer_manager)
2086 input->wl.relative_pointer =
2087 zwp_relative_pointer_manager_v1_get_relative_pointer(
2088 input->display->wl.relative_pointer_manager, input->wl.pointer);
2089 zwp_relative_pointer_v1_add_listener(input->wl.relative_pointer,
2090 &_relative_pointer_listener, input);
2094 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2095 if (!input->cursor.surface)
2097 input->cursor.surface =
2098 wl_compositor_create_surface(input->display->wl.compositor);
2100 if (input->cursor.surface)
2102 if (input->display->wl.tz_policy)
2104 tizen_policy_set_role(input->display->wl.tz_policy,
2105 input->cursor.surface, "wl_pointer-cursor");
2109 if (!input->cursor.theme)
2111 input->cursor.theme =
2112 wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size,
2113 input->display->wl.shm);
2117 else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer))
2119 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2120 if (input->cursor.surface) wl_surface_destroy(input->cursor.surface);
2121 input->cursor.surface = NULL;
2122 if (input->cursor.theme)
2123 wl_cursor_theme_destroy(input->cursor.theme);
2124 input->cursor.theme = NULL;
2126 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
2127 if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
2128 wl_pointer_release(input->wl.pointer);
2131 wl_pointer_destroy(input->wl.pointer);
2132 input->wl.pointer = NULL;
2135 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->wl.keyboard))
2137 input->wl.keyboard = wl_seat_get_keyboard(seat);
2138 wl_keyboard_set_user_data(input->wl.keyboard, input);
2139 wl_keyboard_add_listener(input->wl.keyboard, &_keyboard_listener, input);
2141 else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->wl.keyboard))
2143 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
2144 if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
2145 wl_keyboard_release(input->wl.keyboard);
2148 wl_keyboard_destroy(input->wl.keyboard);
2149 input->wl.keyboard = NULL;
2152 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->wl.touch))
2154 input->wl.touch = wl_seat_get_touch(seat);
2155 wl_touch_set_user_data(input->wl.touch, input);
2156 wl_touch_add_listener(input->wl.touch, &_touch_listener, input);
2158 else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->wl.touch))
2160 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
2161 if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
2162 wl_touch_release(input->wl.touch);
2165 wl_touch_destroy(input->wl.touch);
2166 input->wl.touch = NULL;
2167 // TIZEN ONLY(20160223) : Add back/menu/home key conversion support
2168 _ecore_wl2_input_key_conversion_clean_up();
2171 ecore_wl2_display_flush(input->display);
2173 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
2174 input->caps_update = EINA_TRUE;
2177 ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Capabilities));
2178 EINA_SAFETY_ON_NULL_RETURN(ev);
2181 ev->pointer_enabled = !!(caps & WL_SEAT_CAPABILITY_POINTER);
2182 ev->keyboard_enabled = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD);
2183 ev->touch_enabled = !!(caps & WL_SEAT_CAPABILITY_TOUCH);
2184 ev->display = input->display;
2185 ev->display->refs++;
2187 ecore_event_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED, ev,
2188 _display_event_free, ev->display);
2192 _cb_seat_event_free(void *data EINA_UNUSED, void *event)
2194 Ecore_Wl2_Event_Seat_Name *ev;
2197 eina_stringshare_del(ev->name);
2198 ecore_wl2_display_disconnect(ev->display);
2203 _seat_cb_name(void *data, struct wl_seat *seat EINA_UNUSED, const char *name)
2205 Ecore_Wl2_Event_Seat_Name *ev;
2206 Ecore_Wl2_Input *input;
2209 eina_stringshare_replace(&input->name, name);
2211 ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Name));
2212 EINA_SAFETY_ON_NULL_RETURN(ev);
2215 ev->name = eina_stringshare_add(name);
2216 ev->display = input->display;
2217 ev->display->refs++;
2219 ecore_event_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED, ev,
2220 _cb_seat_event_free, NULL);
2223 static const struct wl_seat_listener _seat_listener =
2225 _seat_cb_capabilities,
2230 _ecore_wl2_input_cursor_setup(Ecore_Wl2_Input *input)
2233 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2235 input->cursor.size = 32;
2236 tmp = getenv("ECORE_WL_CURSOR_SIZE");
2237 if (tmp) input->cursor.size = atoi(tmp);
2239 if (!input->cursor.name)
2240 input->cursor.name = eina_stringshare_add("left_ptr");
2242 unsigned int cursor_size;
2243 char *cursor_theme_name;
2245 tmp = getenv("ECORE_WL_CURSOR_SIZE");
2247 cursor_size = atoi(tmp);
2250 ecore_wl2_input_cursor_size_set(input, cursor_size);
2252 cursor_theme_name = getenv("ECORE_WL_CURSOR_THEME_NAME");
2253 ecore_wl2_input_cursor_theme_name_set(input, cursor_theme_name);
2255 // TIZEN_ONLY(20230330): support client that requests to unset cursor
2256 if (!input->cursor.name)
2257 input->cursor.name = eina_stringshare_add("left_ptr");
2263 // TIZEN_ONLY(20200219): cleanup cursor resources when a Ecore_Wl2_Input is destroy
2265 _ecore_wl2_input_cursor_cleanup(Ecore_Wl2_Input *input)
2267 /* If remove a cursor in this step,
2268 * it maybe occurred blink cursor so check this first
2270 // if (input->cursor.surface)
2271 // ecore_wl2_input_pointer_set(input, NULL, 0, 0);
2273 if (input->cursor.theme)
2274 wl_cursor_theme_destroy(input->cursor.theme);
2275 if (input->cursor.theme_name)
2276 eina_stringshare_del(input->cursor.theme_name);
2280 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2281 static const struct wl_callback_listener _pointer_surface_listener =
2287 _cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED)
2289 Ecore_Wl2_Input *input;
2291 if (!(input = data)) return;
2295 if (callback != input->cursor.frame_cb) return;
2296 wl_callback_destroy(callback);
2297 input->cursor.frame_cb = NULL;
2300 if (!input->cursor.name)
2302 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
2306 if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb))
2308 input->cursor.frame_cb = wl_surface_frame(input->cursor.surface);
2309 if (!input->cursor.frame_cb) return;
2311 wl_callback_add_listener(input->cursor.frame_cb,
2312 &_pointer_surface_listener, input);
2318 _ecore_wl2_input_cursor_update(void *data)
2320 Ecore_Wl2_Input *input;
2323 if (!input) return EINA_FALSE;
2325 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
2327 if (input->wl.pointer)
2328 wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
2329 input->cursor.surface,
2330 input->cursor.hot_x, input->cursor.hot_y);
2331 ecore_wl2_display_flush(input->display);
2333 return ECORE_CALLBACK_RENEW;
2335 struct wl_cursor_image *cursor_image;
2336 struct wl_buffer *buffer;
2339 if ((!input) || (!input->cursor.cursor) || (!input->cursor.surface))
2342 cursor_image = input->cursor.cursor->images[input->cursor.current_index];
2343 if (!cursor_image) return ECORE_CALLBACK_RENEW;
2345 if ((buffer = wl_cursor_image_get_buffer(cursor_image)))
2347 ecore_wl2_input_pointer_set(input, input->cursor.surface,
2348 cursor_image->hotspot_x,
2349 cursor_image->hotspot_y);
2350 wl_surface_attach(input->cursor.surface, buffer, 0, 0);
2351 wl_surface_damage(input->cursor.surface, 0, 0,
2352 cursor_image->width, cursor_image->height);
2353 wl_surface_commit(input->cursor.surface);
2355 if ((input->cursor.cursor->image_count > 1) && (!input->cursor.frame_cb))
2356 _cb_pointer_frame(input, NULL, 0);
2359 if (input->cursor.cursor->image_count <= 1)
2360 return ECORE_CALLBACK_CANCEL;
2362 delay = cursor_image->delay;
2363 input->cursor.current_index =
2364 (input->cursor.current_index + 1) % input->cursor.cursor->image_count;
2366 if (!input->cursor.timer)
2367 input->cursor.timer =
2368 ecore_timer_loop_add(delay / 1000.0,
2369 _ecore_wl2_input_cursor_update, input);
2371 ecore_timer_interval_set(input->cursor.timer, delay / 1000.0);
2373 return ECORE_CALLBACK_RENEW;
2379 _ecore_wl2_devices_free(Ecore_Wl2_Input_Devices *devices)
2381 if (devices->seat_dev)
2382 efl_unref(devices->seat_dev);
2383 if (devices->pointer_dev)
2384 efl_unref(devices->pointer_dev);
2385 if (devices->keyboard_dev)
2386 efl_unref(devices->keyboard_dev);
2387 if (devices->touch_dev)
2388 efl_unref(devices->touch_dev);
2394 _ecore_wl2_cb_device_event(void *data, int type, void *event)
2396 Ecore_Wl2_Input_Devices *devs, *devices = NULL;;
2397 Ecore_Wl2_Event_Device *ev = event;
2398 Ecore_Wl2_Input *input = data;
2401 if (input->id != ev->seat_id)
2402 return ECORE_CALLBACK_PASS_ON;
2404 EINA_LIST_FOREACH(input->devices_list, l, devs)
2406 if (devs->window_id == ev->window_id)
2413 if (type == ECORE_WL2_EVENT_DEVICE_ADDED)
2417 devices = calloc(1, sizeof(Ecore_Wl2_Input_Devices));
2418 EINA_SAFETY_ON_NULL_RETURN_VAL(devices, ECORE_CALLBACK_PASS_ON);
2419 input->devices_list =
2420 eina_list_append(input->devices_list, devices);
2421 devices->window_id = ev->window_id;
2424 if (ev->type == ECORE_WL2_DEVICE_TYPE_POINTER)
2425 devices->pointer_dev = efl_ref(ev->dev);
2426 else if (ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD)
2427 devices->keyboard_dev = efl_ref(ev->dev);
2428 else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH)
2429 devices->touch_dev = efl_ref(ev->dev);
2430 else if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
2431 devices->seat_dev = efl_ref(ev->dev);
2433 return ECORE_CALLBACK_PASS_ON;
2437 return ECORE_CALLBACK_PASS_ON;
2439 if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
2441 input->devices_list =
2442 eina_list_remove(input->devices_list, devices);
2443 _ecore_wl2_devices_free(devices);
2444 return ECORE_CALLBACK_PASS_ON;
2447 if ((ev->type == ECORE_WL2_DEVICE_TYPE_POINTER) &&
2448 (devices->pointer_dev == ev->dev))
2450 efl_unref(devices->pointer_dev);
2451 devices->pointer_dev = NULL;
2453 else if ((ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD) &&
2454 (devices->keyboard_dev == ev->dev))
2456 efl_unref(devices->keyboard_dev);
2457 devices->keyboard_dev = NULL;
2459 else if ((ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH) &&
2460 (devices->touch_dev == ev->dev))
2462 efl_unref(devices->touch_dev);
2463 devices->touch_dev = NULL;
2466 return ECORE_CALLBACK_PASS_ON;
2469 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
2471 _ecore_wl2_input_device_last_device_set(Ecore_Wl2_Tizen_Input_Device *dev)
2473 Ecore_Wl2_Input *input = dev->input;
2479 case ECORE_DEVICE_CLASS_MOUSE:
2480 input->devmgr.last_device_ptr = dev;
2482 case ECORE_DEVICE_CLASS_KEYBOARD:
2483 input->devmgr.last_device_kbd = dev;
2485 case ECORE_DEVICE_CLASS_TOUCH:
2486 input->devmgr.last_device_touch = dev;
2494 _ecore_wl2_input_device_last_device_unset(Ecore_Wl2_Tizen_Input_Device *dev)
2496 Ecore_Wl2_Input *input = dev->input;
2502 case ECORE_DEVICE_CLASS_MOUSE:
2503 if (input->devmgr.last_device_ptr == dev)
2504 input->devmgr.last_device_ptr = NULL;
2506 case ECORE_DEVICE_CLASS_KEYBOARD:
2507 if (input->devmgr.last_device_kbd == dev)
2508 input->devmgr.last_device_kbd = NULL;
2510 case ECORE_DEVICE_CLASS_TOUCH:
2511 if (input->devmgr.last_device_touch == dev)
2512 input->devmgr.last_device_touch = NULL;
2521 _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int version)
2523 Ecore_Wl2_Input *input;
2525 input = calloc(1, sizeof(Ecore_Wl2_Input));
2529 input->display = display;
2530 input->seat_version = version;
2531 input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = 0.025;
2532 input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = 0.4;
2533 input->repeat.enabled = EINA_TRUE;
2534 input->repeat.changed = EINA_FALSE;
2535 input->want_lock_pointer = EINA_FALSE;
2536 input->pointer_locked = EINA_FALSE;
2538 wl_array_init(&input->data.selection.types);
2539 wl_array_init(&input->data.drag.types);
2541 /* setup cursor size and theme */
2542 _ecore_wl2_input_cursor_setup(input);
2543 _ecore_wl2_cursor_config_init();
2546 wl_registry_bind(display->wl.registry, id, &wl_seat_interface, 4);
2549 eina_inlist_append(display->inputs, EINA_INLIST_GET(input));
2551 wl_seat_add_listener(input->wl.seat, &_seat_listener, input);
2552 wl_seat_set_user_data(input->wl.seat, input);
2554 input->dev_add_handler =
2555 ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_ADDED,
2556 _ecore_wl2_cb_device_event, input);
2558 input->dev_remove_handler =
2559 ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_REMOVED,
2560 _ecore_wl2_cb_device_event, input);
2562 if (!display->wl.data_device_manager) return;
2564 input->data.device =
2565 wl_data_device_manager_get_data_device(display->wl.data_device_manager,
2567 wl_data_device_add_listener(input->data.device, &_data_listener, input);
2571 _ecore_wl2_input_del(Ecore_Wl2_Input *input)
2573 Ecore_Wl2_Input_Devices *devices;
2574 Ecore_Wl2_Display *display;
2575 Eina_Inlist *l = NULL;
2576 Ecore_Wl2_Mouse_Down_Info *info = NULL;
2577 Ecore_Wl2_Window *window;
2581 display = input->display;
2583 l = _ecore_wl2_mouse_down_info_list;
2586 info = EINA_INLIST_CONTAINER_GET(l, Ecore_Wl2_Mouse_Down_Info);
2587 l = eina_inlist_remove(l, l);
2590 _ecore_wl2_mouse_down_info_list = NULL;
2592 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2594 _ecore_wl2_cursor_config_shutdown();
2596 if (input->cursor.name) eina_stringshare_del(input->cursor.name);
2597 // TIZEN_ONLY(20200219): cleanup cursor resources when a Ecore_Wl2_Input is destroy
2598 _ecore_wl2_input_cursor_cleanup(input);
2601 if (input->data.selection.types.data)
2605 wl_array_for_each(t, &input->data.selection.types)
2608 wl_array_release(&input->data.selection.types);
2610 if (input->data.drag.types.data)
2614 wl_array_for_each(t, &input->data.drag.types)
2617 wl_array_release(&input->data.drag.types);
2620 if (input->data.selection.source)
2621 wl_data_source_destroy(input->data.selection.source);
2622 if (input->data.drag.source)
2623 wl_data_source_destroy(input->data.drag.source);
2624 if (input->drag.offer) _ecore_wl2_offer_unref(input->drag.offer);
2625 if (input->selection.offer) _ecore_wl2_offer_unref(input->selection.offer);
2626 if (input->data.device) wl_data_device_destroy(input->data.device);
2628 if (input->xkb.state) xkb_state_unref(input->xkb.state);
2629 if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
2630 if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
2631 if (input->xkb.compose_table)
2632 xkb_compose_table_unref(input->xkb.compose_table);
2633 if (input->xkb.compose_state)
2634 xkb_compose_state_unref(input->xkb.compose_state);
2636 if (input->wl.seat) wl_seat_destroy(input->wl.seat);
2638 ecore_event_handler_del(input->dev_add_handler);
2639 ecore_event_handler_del(input->dev_remove_handler);
2640 EINA_LIST_FREE(input->devices_list, devices)
2641 _ecore_wl2_devices_free(devices);
2644 eina_inlist_remove(display->inputs, EINA_INLIST_GET(input));
2646 EINA_INLIST_FOREACH(display->windows, window)
2647 if (window->grab == input) window->grab = NULL;
2649 eina_stringshare_replace(&input->name, NULL);
2654 _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor)
2656 eina_stringshare_replace(&input->cursor.name, cursor);
2657 if (!cursor) eina_stringshare_replace(&input->cursor.name, "left_ptr");
2661 _ecore_wl2_input_window_remove(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
2663 Ecore_Wl2_Input_Devices *devices;
2664 Eina_List *l, *l_next;
2666 if ((input->focus.pointer) &&
2667 (input->focus.pointer == window))
2668 input->focus.pointer = NULL;
2669 if ((input->focus.keyboard) &&
2670 (input->focus.keyboard == window))
2671 input->focus.keyboard = NULL;
2672 //TIZEN_ONLY(20210208): add touch id slots for distinguishing single touch and multi touch.
2673 if ((input->focus.touch) &&
2674 (input->focus.touch == window))
2676 for (int i = 0; i < ECORE_WL2_TOUCH_MAX; i++)
2677 input->grab.touch_array[i] = EINA_FALSE;
2678 input->focus.touch = NULL;
2679 input->grab.count = 0;
2680 _ecore_wl2_input_ungrab(input);
2683 if ((input->repeat_win) &&
2684 (input->repeat_win == window))
2686 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2687 input->repeat.timer = NULL;
2688 input->repeat_win = NULL;
2691 EINA_LIST_FOREACH_SAFE(input->devices_list, l, l_next, devices)
2692 if (devices->window_id == window->id)
2694 _ecore_wl2_devices_free(devices);
2695 input->devices_list = eina_list_remove_list(input->devices_list, l);
2699 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
2701 _ecore_wl2_cb_keygrab_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t key, uint32_t mode, uint32_t error)
2703 _ecore_wl2_keygrab_error = error;
2704 INF("[PID:%d] key=%d, mode=%d, error=%d", getpid(), key, mode, error);
2708 _ecore_wl2_cb_keygrab_notify_list(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, struct wl_array *grab_result)
2710 wl_array_init(&_ecore_wl2_keygrab_result_list);
2711 wl_array_copy(&_ecore_wl2_keygrab_result_list, grab_result);
2715 _ecore_wl2_cb_getgrab_notify_list(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, struct wl_array *grab_result EINA_UNUSED)
2721 _ecore_wl2_cb_set_register_none_key(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t mode EINA_UNUSED)
2727 _ecore_wl2_cb_keyregister_notify(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t status EINA_UNUSED)
2733 _ecore_wl2_cb_set_input_config(void *data EINA_UNUSED, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t status EINA_UNUSED)
2739 _ecore_wl2_cb_key_cancel(void *data, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, uint32_t key)
2741 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
2742 Ecore_Wl2_Input *input;
2746 WRN("Failed to get Ecore_Wl2_Display\n");
2750 EINA_INLIST_FOREACH(ewd->inputs, input)
2752 if (input->repeat.key == key)
2754 input->repeat.sym = 0;
2755 input->repeat.key = 0;
2756 input->repeat.time = 0;
2758 if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
2759 input->repeat.timer = NULL;
2765 _ecore_wl2_cb_event_surface(void *data, struct tizen_keyrouter *tizen_keyrouter EINA_UNUSED, struct wl_surface *surface, uint32_t key EINA_UNUSED, uint32_t mode)
2767 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
2768 Ecore_Wl2_Input *input;
2772 WRN("Failed to get Ecore_Wl2_Display\n");
2776 EINA_INLIST_FOREACH(ewd->inputs, input)
2778 input->key_win = ecore_wl2_window_surface_find(surface);
2779 input->key_mode = mode;
2783 WRN("Get a event_surface(%p) but there was a no Ecore_Wl2_Window\n", surface);
2788 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
2789 static const struct tizen_keyrouter_listener _tz_keyrouter_listener =
2791 _ecore_wl2_cb_keygrab_notify,
2792 _ecore_wl2_cb_keygrab_notify_list,
2793 _ecore_wl2_cb_getgrab_notify_list,
2794 _ecore_wl2_cb_set_register_none_key,
2795 _ecore_wl2_cb_keyregister_notify,
2796 _ecore_wl2_cb_set_input_config,
2797 _ecore_wl2_cb_key_cancel,
2798 _ecore_wl2_cb_event_surface
2803 _ecore_wl2_keyrouter_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version EINA_UNUSED)
2805 ewd->wl.tz_keyrouter =
2806 wl_registry_bind(ewd->wl.registry, id, &tizen_keyrouter_interface, 2);
2807 if (ewd->wl.tz_keyrouter)
2808 tizen_keyrouter_add_listener(ewd->wl.tz_keyrouter, &_tz_keyrouter_listener, ewd);
2813 xkb_keysym_t keysym;
2814 xkb_keycode_t *keycodes;
2818 typedef struct _Keycode_Map Keycode_Map;
2820 static void find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
2822 Keycode_Map *found_keycodes = (Keycode_Map *)data;
2823 xkb_keysym_t keysym = found_keycodes->keysym;
2825 const xkb_keysym_t *syms_out = NULL;
2826 num_syms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
2827 if ((num_syms) && (syms_out))
2829 if ((*syms_out) == (keysym))
2831 found_keycodes->num_keycodes++;
2832 found_keycodes->keycodes = realloc(found_keycodes->keycodes, sizeof(int) * found_keycodes->num_keycodes);
2833 if (found_keycodes->keycodes)
2834 found_keycodes->keycodes[found_keycodes->num_keycodes - 1] = key;
2839 //If there are several keycodes, ecore_wl only deals with first keycode.
2841 ecore_wl2_input_keycode_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym, xkb_keycode_t **keycodes)
2843 Keycode_Map found_keycodes = {0,};
2844 found_keycodes.keysym = keysym;
2846 //called fewer (max_keycode - min_keycode +1) times.
2847 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
2849 *keycodes = found_keycodes.keycodes;
2850 INF("num of keycodes:%d ", found_keycodes.num_keycodes);
2851 return found_keycodes.num_keycodes;
2854 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
2855 //Currently this function is only used in sink call, so use global value(_ecore_wl_keygrab_error) and just check the error is ok.
2856 /* internal functions */
2858 _ecore_wl2_keygrab_hash_add(void *key, void *data)
2860 Eina_Bool ret = EINA_FALSE;
2862 if (!data) return ret;
2864 _keygrabs = eina_hash_int32_new(NULL);
2865 ret = eina_hash_add(_keygrabs, key, data);
2870 _ecore_wl2_keygrab_hash_del(void *key)
2872 Eina_Bool ret = EINA_FALSE;
2874 ret = eina_hash_del_by_key(_keygrabs, key);
2880 _ecore_wl2_keygrab_hash_get(void)
2886 _ecore_wl2_keygrab_error_set()
2888 if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_INVALID_SURFACE)
2889 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
2890 else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
2891 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
2892 else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY)
2893 set_last_result(TIZEN_ERROR_ALREADY_IN_PROGRESS);
2894 else if (_ecore_wl2_keygrab_error == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
2895 set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
2896 else set_last_result(TIZEN_ERROR_NONE);
2899 //I'm not sure that keygrab function should be changed to Ecore_evas_XXX.
2900 //In the future, keyrouter feature can be added upstream or finish stabilizing.
2901 //After that time, we maybe change API name or other thing.
2902 //So do not use this API if you have trouble catch keyrouter feature or rule changes.
2904 //Keyrouter support the situation when wl_win is not exist.
2905 //But keyrouter also can be meet situation when there are several surfaces.
2906 //So I decided to add keygrab feature into ecore_wl_window side like x system.
2908 //Mod, not_mod, priority will be used future.
2909 //But now we are not support, so just use 0 for this parameter.
2913 ecore_wl2_window_keygrab_set(Ecore_Wl2_Window *win, const char *key, int mod EINA_UNUSED, int not_mod EINA_UNUSED, int priority EINA_UNUSED, Ecore_Wl2_Window_Keygrab_Mode grab_mode)
2915 Ecore_Wl2_Display *ewd;
2916 xkb_keysym_t keysym = 0x0;
2917 int num_keycodes = 0;
2918 xkb_keycode_t *keycodes = NULL;
2920 Ecore_Wl2_Input *input;
2922 Eina_Bool ret = EINA_FALSE;
2923 struct wl_surface *surface = NULL;
2925 EINA_SAFETY_ON_NULL_GOTO(key, err);
2926 EINA_SAFETY_ON_TRUE_GOTO((grab_mode < ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN), err);
2927 EINA_SAFETY_ON_TRUE_GOTO((grab_mode > ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE), err);
2932 ewd = ecore_wl2_connected_display_get(NULL);
2934 EINA_SAFETY_ON_NULL_GOTO(ewd, err);
2936 while (!ewd->wl.tz_keyrouter)
2938 INF("Wait until keyrouter interface is ready");
2939 wl_display_roundtrip(ewd->wl.display);
2942 INF("win=%p key=%s mod=%d", win, key, grab_mode);
2944 keysym = xkb_keysym_from_name(key, XKB_KEYSYM_NO_FLAGS);
2945 if (keysym == XKB_KEY_NoSymbol)
2947 WRN("Keysym of key(\"%s\") doesn't exist", key);
2948 EINA_SAFETY_ON_TRUE_GOTO(EINA_TRUE, err);
2951 //We have to find the way to get keycode from keysym before keymap notify
2952 //keymap event occurs after minimum 3 roundtrips
2953 //1. ecore_wl_init: wl_registry_add_listener
2954 //2. _ecore_wl_cb_handle_global: wl_seat_add_listener
2955 //3. _ecore_wl_input_seat_handle_capabilities: wl_keyboard_add_listener
2956 while (eina_inlist_count(ewd->inputs) == 0)
2958 INF("Wait wl_registry_add_listener reply");
2959 wl_display_roundtrip(ewd->wl.display);
2962 input = ecore_wl2_input_default_input_get(ewd);
2963 EINA_SAFETY_ON_NULL_GOTO(input, err);
2965 while (!input->caps_update)
2967 INF("Wait until wl_seat_capabilities_update is ready");
2968 wl_display_roundtrip(ewd->wl.display);
2971 EINA_SAFETY_ON_NULL_GOTO(input->wl.keyboard, err);
2974 while (!input->xkb.keymap)
2976 wl_display_roundtrip(ewd->wl.display);
2977 INF("Wait until keymap event occurs");
2979 INF("Finish keymap event");
2981 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
2982 EINA_SAFETY_ON_TRUE_GOTO((num_keycodes == 0), err);
2984 /* Request to grab a key */
2986 surface = ecore_wl2_window_surface_get(win);
2988 for (i = 0; i < num_keycodes; i++)
2990 INF("keycode of key:(%d)", keycodes[i]);
2991 tizen_keyrouter_set_keygrab(ewd->wl.tz_keyrouter, surface, keycodes[i], grab_mode);
2992 /* Send sync to wayland compositor and register sync callback to exit while dispatch loop below */
2993 ecore_wl2_display_sync(ewd);
2995 INF("After keygrab _ecore_wl2_keygrab_error = %d", _ecore_wl2_keygrab_error);
2996 if (!_ecore_wl2_keygrab_error)
2998 INF("[PID:%d]Succeed to get return value !", getpid());
2999 if (_ecore_wl2_keygrab_hash_add(&keycodes[i], surface))
3000 INF("Succeed to add key to the keygrab hash!");
3001 //TODO: deal with if (win == NULL)
3003 WRN("Failed to add key to the keygrab hash!");
3008 WRN("[PID:%d]Failed to get return value ! ret=%d)", getpid(), _ecore_wl2_keygrab_error);
3016 _ecore_wl2_keygrab_error_set();
3017 _ecore_wl2_keygrab_error = -1;
3021 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3026 ecore_wl2_window_keygrab_unset(Ecore_Wl2_Window *win, const char *key, int mod EINA_UNUSED, int any_mod EINA_UNUSED)
3028 Ecore_Wl2_Display *ewd;
3029 xkb_keysym_t keysym = 0x0;
3030 int num_keycodes = 0;
3031 xkb_keycode_t *keycodes = NULL;
3034 Eina_Bool ret = EINA_FALSE;
3035 struct wl_surface *surface = NULL;
3036 Ecore_Wl2_Input *input;
3041 ewd = ecore_wl2_connected_display_get(NULL);
3045 if ((!ewd) || (!ewd->wl.tz_keyrouter)) goto err;
3047 INF("win=%p key=%s ", win, key);
3049 keysym = xkb_keysym_from_name(key, XKB_KEYSYM_NO_FLAGS);
3050 if (keysym == XKB_KEY_NoSymbol)
3052 WRN("Keysym of key(\"%s\") doesn't exist", key);
3056 while (eina_inlist_count(ewd->inputs) == 0)
3058 INF("Wait wl_registry_add_listener reply");
3059 wl_display_roundtrip(ewd->wl.display);
3062 input = ecore_wl2_input_default_input_get(ewd);
3064 //We have to find the way to get keycode from keysym before keymap notify
3065 if ((input) && (input->xkb.keymap))
3066 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3069 WRN("Keymap is not ready");
3073 if (num_keycodes == 0)
3075 WRN("Keycode of key(\"%s\") doesn't exist", key);
3079 /* Request to ungrab a key */
3081 surface = ecore_wl2_window_surface_get(win);
3083 for (i = 0; i < num_keycodes; i++)
3085 INF("keycode of key:(%d)", keycodes[i]);
3086 tizen_keyrouter_unset_keygrab(ewd->wl.tz_keyrouter, surface, keycodes[i]);
3088 /* Send sync to wayland compositor and register sync callback to exit while dispatch loop below */
3089 ecore_wl2_display_sync(ewd);
3091 INF("After keygrab unset _ecore_wl2_keygrab_error = %d", _ecore_wl2_keygrab_error);
3092 if (!_ecore_wl2_keygrab_error)
3094 INF("[PID:%d]Succeed to get return value !", getpid());
3095 if (_ecore_wl2_keygrab_hash_del(&keycodes[i]))
3096 INF("Succeed to delete key from the keygrab hash!");
3098 WRN("Failed to delete key from the keygrab hash!");
3104 WRN("[PID:%d] Failed to get return value ! (ret=%d)", getpid(), _ecore_wl2_keygrab_error);
3111 _ecore_wl2_keygrab_error_set();
3112 _ecore_wl2_keygrab_error = -1;
3116 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3121 _ecore_wl2_keyname_get(int keycode)
3123 xkb_keysym_t sym = XKB_KEY_NoSymbol;
3124 char name[256] = {0, };
3125 Ecore_Wl2_Display *ewd;
3126 Ecore_Wl2_Input *input;
3128 ewd = ecore_wl2_connected_display_get(NULL);
3129 input = ecore_wl2_input_default_input_get(ewd);
3130 if (!input) return NULL;
3132 sym = xkb_state_key_get_one_sym(input->xkb.state, keycode);
3133 xkb_keysym_get_name(sym, name, sizeof(name));
3135 return strdup(name);
3139 *ecore_wl2_window_keygrab_list_set(Ecore_Wl2_Window *win, Eina_List *infos)
3141 Ecore_Wl2_Display *ewd;
3142 xkb_keysym_t keysym = 0x0;
3143 int num_keycodes = 0;
3144 xkb_keycode_t *keycodes = NULL;
3146 struct wl_surface *surface = NULL;
3148 struct wl_array grab_list;
3149 int *grab_data = NULL;
3151 Eina_List *error_keys = NULL;
3153 Eina_Bool no_permission = EINA_FALSE;
3154 Eina_Bool invalid_key = EINA_FALSE;
3156 Ecore_Wl2_Keygrab_Info *info;
3157 Ecore_Wl2_Window_Keygrab_Info *grab_info;
3158 Ecore_Wl2_Input *input;
3163 ewd = ecore_wl2_connected_display_get(NULL);
3167 while (!ewd->wl.tz_keyrouter)
3169 INF("Wait until keyrouter interface is ready");
3170 wl_display_roundtrip(ewd->wl.display);
3173 while (eina_inlist_count(ewd->inputs) == 0)
3175 INF("Wait wl_registry_add_listener reply");
3176 wl_display_roundtrip(ewd->wl.display);
3179 input = ecore_wl2_input_default_input_get(ewd);
3181 if(!input) goto err;
3183 while (!input->caps_update)
3185 INF("Wait until wl_seat_capabilities_update is ready");
3186 wl_display_roundtrip(ewd->wl.display);
3188 if (input->wl.keyboard)
3190 while(!input->xkb.keymap)
3192 wl_display_roundtrip(ewd->wl.display);
3193 INF("Wait until keymap event occurs");
3195 INF("Finish keymap event");
3199 WRN("This device does not support key");
3204 surface = ecore_wl2_window_surface_get(win);
3206 wl_array_init(&grab_list);
3208 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3210 if (!grab_info->key) continue;
3211 if ((grab_info->mode < ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN) || (grab_info->mode > ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE))
3214 keysym = xkb_keysym_from_name(grab_info->key, XKB_KEYSYM_NO_FLAGS);
3216 if (keysym == XKB_KEYSYM_NO_FLAGS)
3218 WRN("Keysym of key(\"%s\") doesn't exist", grab_info->key);
3221 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3223 if (num_keycodes == 0)
3225 WRN("Keycode of key(\"%s\") doesn't exist", grab_info->key);
3228 for (i = 0; i < num_keycodes; i++)
3230 INF("keycode of key:(%d)", keycodes[i]);
3231 grab_data = wl_array_add(&grab_list, sizeof(int));
3232 *grab_data = keycodes[i];
3233 grab_data = wl_array_add(&grab_list, sizeof(int));
3234 *grab_data = grab_info->mode;
3235 grab_data = wl_array_add(&grab_list, sizeof(int));
3241 tizen_keyrouter_set_keygrab_list(ewd->wl.tz_keyrouter, surface, &grab_list);
3243 ecore_wl2_display_sync(ewd);
3245 wl_array_for_each(info, &_ecore_wl2_keygrab_result_list)
3250 INF("[PID:%d]Succeed to get return value !", getpid());
3251 if (_ecore_wl2_keygrab_hash_add(&info->key, surface))
3252 INF("Succeed to add key to the keygrab hash!");
3254 WRN("Failed to add key to the keygrab hash!");
3258 WRN("After keygrab keycode %d error = %d", info->key, info->err);
3259 if (info->err == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
3260 no_permission = EINA_TRUE;
3262 if (info->err == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
3263 invalid_key = EINA_TRUE;
3265 error_keys = eina_list_append(error_keys, _ecore_wl2_keyname_get(info->key));
3268 wl_array_release(&grab_list);
3269 wl_array_release(&_ecore_wl2_keygrab_result_list);
3271 set_last_result(TIZEN_ERROR_NONE);
3272 if (invalid_key) set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3273 if (no_permission) set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
3278 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3280 error_keys = eina_list_append(error_keys, strdup(grab_info->key));
3283 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3289 *ecore_wl2_window_keygrab_list_unset(Ecore_Wl2_Window *win, Eina_List *infos)
3291 Ecore_Wl2_Display *ewd;
3292 xkb_keysym_t keysym = 0x0;
3293 int num_keycodes = 0;
3294 xkb_keycode_t *keycodes = NULL;
3296 struct wl_surface *surface = NULL;
3298 struct wl_array ungrab_list;
3299 int *grab_data = NULL;
3301 Eina_List *error_keys = NULL;
3303 Eina_Bool no_permission = EINA_FALSE;
3304 Eina_Bool invalid_key = EINA_FALSE;
3306 Ecore_Wl2_Keyungrab_Info *info;
3307 Ecore_Wl2_Window_Keygrab_Info *grab_info;
3309 Ecore_Wl2_Input *input;
3314 ewd = ecore_wl2_connected_display_get(NULL);
3318 if ((!ewd->wl.tz_keyrouter)) goto err;
3320 input = ecore_wl2_input_default_input_get(ewd);
3322 if ((!input) || (!input->xkb.keymap))
3324 ERR("Keymap is not ready");
3329 surface = ecore_wl2_window_surface_get(win);
3331 wl_array_init(&ungrab_list);
3333 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3335 if (!grab_info->key) continue;
3337 keysym = xkb_keysym_from_name(grab_info->key, XKB_KEYSYM_NO_FLAGS);
3339 if (keysym == XKB_KEYSYM_NO_FLAGS)
3341 WRN("Keysym of key(\"%s\") doesn't exist", grab_info->key);
3344 num_keycodes = ecore_wl2_input_keycode_from_keysym(input->xkb.keymap, keysym, &keycodes);
3346 if (num_keycodes == 0)
3348 WRN("Keycode of key(\"%s\") doesn't exist", grab_info->key);
3351 for (i = 0; i < num_keycodes; i++)
3353 INF("keycode of key:(%d)", keycodes[i]);
3354 grab_data = wl_array_add(&ungrab_list, sizeof(int));
3355 *grab_data = keycodes[i];
3356 grab_data = wl_array_add(&ungrab_list, sizeof(int));
3362 tizen_keyrouter_unset_keygrab_list(ewd->wl.tz_keyrouter, surface, &ungrab_list);
3364 ecore_wl2_display_sync(ewd);
3366 wl_array_for_each(info, &_ecore_wl2_keygrab_result_list)
3370 INF("[PID:%d]Succeed to get return value !", getpid());
3371 if (_ecore_wl2_keygrab_hash_del(&info->key))
3372 INF("Succeed to delete key to the keygrab hash!");
3374 WRN("Failed to delete key to the keygrab hash!");
3378 WRN("After keyungrab keycode %d error = %d", info->key, info->err);
3379 if (info->err == TIZEN_KEYROUTER_ERROR_NO_PERMISSION)
3380 no_permission = EINA_TRUE;
3382 if (info->err == TIZEN_KEYROUTER_ERROR_INVALID_KEY)
3383 invalid_key = EINA_TRUE;
3385 error_keys = eina_list_append(error_keys, _ecore_wl2_keyname_get(info->key));
3388 wl_array_release(&ungrab_list);
3389 wl_array_release(&_ecore_wl2_keygrab_result_list);
3391 set_last_result(TIZEN_ERROR_NONE);
3392 if (invalid_key) set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3393 if (no_permission) set_last_result(TIZEN_ERROR_PERMISSION_DENIED);
3398 EINA_LIST_FOREACH_SAFE(infos, l1, l2, grab_info)
3400 error_keys = eina_list_append(error_keys, strdup(grab_info->key));
3403 set_last_result(TIZEN_ERROR_INVALID_PARAMETER);
3410 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
3412 _ecore_wl2_input_device_info_free(void *data EINA_UNUSED, void *ev)
3414 Ecore_Event_Device_Info *e;
3417 eina_stringshare_del(e->name);
3418 eina_stringshare_del(e->identifier);
3419 eina_stringshare_del(e->seatname);
3425 _ecore_wl2_input_device_info_send(Ecore_Window win_id, const char *name, const char *identifier, Ecore_Device_Class clas, Ecore_Device_Subclass subclas, Eina_Bool flag)
3427 Ecore_Event_Device_Info *e;
3429 if (!(e = calloc(1, sizeof(Ecore_Event_Device_Info)))) return;
3432 e->name = eina_stringshare_add(name);
3433 e->identifier = eina_stringshare_add(identifier);
3434 e->seatname = eina_stringshare_add(name);
3436 e->subclas = subclas;
3439 ecore_event_add(ECORE_EVENT_DEVICE_ADD, e, _ecore_wl2_input_device_info_free, NULL);
3441 ecore_event_add(ECORE_EVENT_DEVICE_DEL, e, _ecore_wl2_input_device_info_free, NULL);
3444 // TIZEN_ONLY(20180917): ecore/evas_device: update device info if subclas is changed
3446 _ecore_wl2_input_device_update_send(Ecore_Window win, Ecore_Device *dev)
3448 Ecore_Event_Device_Update *ev;
3450 ev = (Ecore_Event_Device_Update *)calloc(sizeof(Ecore_Event_Device_Update), 1);
3451 EINA_SAFETY_ON_NULL_RETURN(ev);
3455 ecore_event_add(ECORE_EVENT_DEVICE_SUBCLASS_UPDATE, ev, NULL, NULL);
3460 _ecore_wl2_input_device_ecore_device_update(Ecore_Device *dev, Ecore_Device_Subclass subclas)
3464 Ecore_Wl2_Window *win = NULL;
3466 Eina_Bool has_win = EINA_FALSE;
3468 ecore_device_subclass_set(dev, subclas);
3470 windows = _ecore_wl2_window_hash_get();
3473 itr = eina_hash_iterator_data_new(windows);
3474 while (eina_iterator_next(itr, &data))
3477 has_win = EINA_TRUE;
3478 _ecore_wl2_input_device_update_send(win->id, dev);
3481 eina_iterator_free(itr);
3485 _ecore_wl2_input_device_update_send((uintptr_t)NULL, dev);
3491 _ecore_wl2_input_device_ecore_device_add(Ecore_Wl2_Tizen_Input_Device *dev)
3493 Ecore_Device *ecdev;
3495 const char *ecdev_name;
3497 if (!dev->identifier) return EINA_FALSE;
3499 EINA_LIST_FOREACH((Eina_List *)ecore_device_list(), l, ecdev)
3501 ecdev_name = ecore_device_identifier_get(ecdev);
3502 if (!ecdev_name) continue;
3503 if ((ecore_device_class_get(ecdev) == dev->clas) && (!strcmp(ecdev_name, dev->identifier)))
3505 // TIZEN_ONLY(20180917): ecore/evas_device: update device info if subclas is changed
3506 _ecore_wl2_input_device_ecore_device_update(ecdev, dev->subclas);
3512 ecdev = ecore_device_add();
3515 ERR("Failed to add ecore device for name: %s (%s)\n", dev->name, dev->identifier);
3518 ecore_device_name_set(ecdev, dev->name);
3519 ecore_device_identifier_set(ecdev, dev->identifier);
3520 ecore_device_class_set(ecdev, dev->clas);
3521 ecore_device_subclass_set(ecdev, dev->subclas);
3523 dev->device = efl_ref(ecdev);
3529 _ecore_wl2_input_device_ecore_device_remove(Ecore_Wl2_Tizen_Input_Device *dev)
3531 Ecore_Device *ecdev;
3532 Eina_List *l, *clone;
3533 const char *ecdev_name;
3535 if (!dev->identifier) return EINA_FALSE;
3537 clone = eina_list_clone(ecore_device_list());
3539 EINA_LIST_FOREACH(clone, l, ecdev)
3541 ecdev_name = ecore_device_identifier_get(ecdev);
3542 if (!ecdev_name) continue;
3543 if ((ecore_device_class_get(ecdev) == dev->clas) &&
3544 (!strcmp(ecdev_name, dev->identifier)))
3546 efl_unref(dev->device);
3547 ecore_device_del(ecdev);
3549 eina_list_free(clone);
3553 eina_list_free(clone);
3559 _ecore_wl2_input_device_info_broadcast(Ecore_Wl2_Tizen_Input_Device *dev, Eina_Bool flag)
3561 Eina_Hash *windows = NULL;
3563 Ecore_Wl2_Window *win = NULL;
3565 Eina_Bool res, has_win = EINA_FALSE;
3568 if (!dev->name) return;
3569 if (!dev->identifier) return;
3570 if (!dev->input || !dev->input->display) return;
3573 res = _ecore_wl2_input_device_ecore_device_add(dev);
3575 res = _ecore_wl2_input_device_ecore_device_remove(dev);
3579 windows = _ecore_wl2_window_hash_get();
3582 itr = eina_hash_iterator_data_new(windows);
3583 while (eina_iterator_next(itr, &data))
3586 has_win = EINA_TRUE;
3587 _ecore_wl2_input_device_info_send(win->id, dev->name, dev->identifier, dev->clas, dev->subclas, flag);
3590 eina_iterator_free(itr);
3594 _ecore_wl2_input_device_info_send((uintptr_t)NULL, dev->name, dev->identifier, dev->clas, dev->subclas, flag);
3599 _ecore_wl2_input_devices_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *win)
3602 Ecore_Wl2_Tizen_Input_Device *dev;
3606 EINA_LIST_FOREACH(input->devmgr.devices, l, dev)
3608 if (!dev->name || !dev->identifier) continue;
3609 _ecore_wl2_input_device_info_send(win->id, dev->name, dev->identifier, dev->clas, dev->subclas, EINA_TRUE);
3615 _ecore_wl2_input_device_cb_device_info(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, const char *name, uint32_t clas, uint32_t subclas, struct wl_array *axes EINA_UNUSED)
3617 Ecore_Wl2_Tizen_Input_Device *dev;
3619 if (!(dev = data)) return;
3621 if (((Ecore_Device_Class)clas == ECORE_DEVICE_CLASS_MOUSE) && (tmp = getenv("DISABLE_HOVERING")) && (atoi(tmp) == 1))
3622 dev->clas = ECORE_DEVICE_CLASS_TOUCH;
3624 dev->clas = (Ecore_Device_Class)clas;
3625 dev->subclas = (Ecore_Device_Subclass)subclas;
3626 dev->name = eina_stringshare_add(name);
3628 _ecore_wl2_input_device_info_broadcast(dev, EINA_TRUE);
3632 _ecore_wl2_input_device_cb_event_device(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, unsigned int serial EINA_UNUSED, const char *name EINA_UNUSED, uint32_t time EINA_UNUSED)
3634 Ecore_Wl2_Tizen_Input_Device *dev;
3636 if (!(dev = data)) return;
3637 if (!dev->identifier) return;
3638 _ecore_wl2_input_device_last_device_set(dev);
3644 _ecore_wl2_input_detent_rotate_free(void *data EINA_UNUSED, void *ev)
3646 Ecore_Event_Detent_Rotate *e = ev;
3651 _ecore_wl2_input_device_cb_axis(void *data, struct tizen_input_device *tizen_input_device EINA_UNUSED, uint32_t axis_type, wl_fixed_t value)
3653 Ecore_Wl2_Input *input;
3654 Ecore_Wl2_Tizen_Input_Device *dev;
3655 double dvalue = wl_fixed_to_double(value);
3656 Ecore_Event_Detent_Rotate *e;
3658 dev = (Ecore_Wl2_Tizen_Input_Device *)data;
3665 case TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_X:
3666 input->touch.last_touch_axis.radius_x = dvalue;
3668 case TIZEN_INPUT_DEVICE_AXIS_TYPE_RADIUS_Y:
3669 input->touch.last_touch_axis.radius_y = dvalue;
3671 case TIZEN_INPUT_DEVICE_AXIS_TYPE_PRESSURE:
3672 input->touch.last_touch_axis.pressure = dvalue;
3674 case TIZEN_INPUT_DEVICE_AXIS_TYPE_ANGLE:
3675 input->touch.last_touch_axis.angle = dvalue;
3677 case TIZEN_INPUT_DEVICE_AXIS_TYPE_DETENT:
3678 /* Do something after get detent event.
3679 * value 1 is clockwise,
3680 * value -1 is counterclockwise,
3682 if (!(e = calloc(1, sizeof(Ecore_Event_Detent_Rotate))))
3684 ERR("detent: cannot allocate memory");
3688 e->direction = ECORE_DETENT_DIRECTION_CLOCKWISE;
3690 e->direction = ECORE_DETENT_DIRECTION_COUNTER_CLOCKWISE;
3691 e->timestamp = _timestamp_get();
3692 DBG("detent: dir: %d, time: %d", e->direction, e->timestamp);
3693 ecore_event_add(ECORE_EVENT_DETENT_ROTATE, e, _ecore_wl2_input_detent_rotate_free, NULL);
3696 WRN("Invalid type(%d) is ignored.\n", axis_type);
3702 static const struct tizen_input_device_listener _tz_input_device_listener =
3704 _ecore_wl2_input_device_cb_device_info,
3705 _ecore_wl2_input_device_cb_event_device,
3706 _ecore_wl2_input_device_cb_axis,
3710 _ecore_wl2_input_device_manager_cb_device_add(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
3711 unsigned int serial EINA_UNUSED, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
3713 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3714 Ecore_Wl2_Input *input;
3715 Ecore_Wl2_Tizen_Input_Device *dev;
3718 if ((!identifier) || (!device) || (!seat))
3720 ERR("Invalid arguments. return");
3724 input = wl_seat_get_user_data(seat);
3727 if (!(dev = calloc(1, sizeof(Ecore_Wl2_Tizen_Input_Device)))) return;
3729 dev->tz_device = device;
3730 tizen_input_device_add_listener(dev->tz_device, &_tz_input_device_listener, dev);
3732 dev->identifier = eina_stringshare_add(identifier);
3735 input->devmgr.devices = eina_list_append(input->devmgr.devices, dev);
3739 _ecore_wl2_input_device_manager_cb_device_remove(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED,
3740 unsigned int serial EINA_UNUSED, const char *identifier, struct tizen_input_device *device, struct wl_seat *seat)
3742 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3743 Ecore_Wl2_Input *input;
3744 Eina_List *l, *l_next;
3745 Ecore_Wl2_Tizen_Input_Device *dev;
3748 if ((!identifier) || (!device) || (!seat))
3750 ERR("Invalid arguments. return");
3754 input = wl_seat_get_user_data(seat);
3758 EINA_LIST_FOREACH_SAFE(input->devmgr.devices, l, l_next, dev)
3760 if (!dev->identifier) continue;
3761 if ((!strcmp(dev->identifier, identifier)) && (seat == dev->seat) && (device == dev->tz_device))
3763 _ecore_wl2_input_device_info_broadcast(dev, EINA_FALSE);
3765 _ecore_wl2_input_device_last_device_unset(dev);
3767 if (dev->tz_device) tizen_input_device_release(dev->tz_device);
3768 if (dev->name) eina_stringshare_del(dev->name);
3769 if (dev->identifier) eina_stringshare_del(dev->identifier);
3772 input->devmgr.devices = eina_list_remove_list(input->devmgr.devices, l);
3781 _ecore_wl2_input_device_manager_cb_error(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t errorcode)
3783 _devicemgr_error = errorcode;
3787 _ecore_wl2_input_device_manager_cb_block_expired(void *data EINA_UNUSED, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED)
3793 _ecore_wl2_input_device_manager_cb_max_touch_count(void *data, struct tizen_input_device_manager *tizen_input_device_manager EINA_UNUSED, uint32_t serial EINA_UNUSED, int32_t max_count, struct wl_seat *seat)
3795 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
3796 Ecore_Wl2_Input *input;
3800 input = wl_seat_get_user_data(seat);
3804 if (input->touch.max_count < max_count)
3806 if (input->touch.touch_axis)
3808 INF("Max touch value is changed %d to %d\n", input->touch.max_count, max_count);
3809 free(input->touch.touch_axis);
3811 input->touch.max_count = max_count;
3812 input->touch.touch_axis = (Ecore_Wl2_Touch_Axis *)calloc(max_count, sizeof(Ecore_Wl2_Touch_Axis));
3816 static const struct tizen_input_device_manager_listener _tz_input_device_mgr_listener =
3818 _ecore_wl2_input_device_manager_cb_device_add,
3819 _ecore_wl2_input_device_manager_cb_device_remove,
3820 _ecore_wl2_input_device_manager_cb_error,
3821 _ecore_wl2_input_device_manager_cb_block_expired,
3822 _ecore_wl2_input_device_manager_cb_max_touch_count,
3826 _ecore_wl2_input_device_manager_setup(Ecore_Wl2_Display *ewd, unsigned int id, unsigned int version EINA_UNUSED)
3828 ewd->wl.tz_input_device_manager =
3829 wl_registry_bind(ewd->wl.registry, id, &tizen_input_device_manager_interface, 6);
3831 tizen_input_device_manager_add_listener(ewd->wl.tz_input_device_manager,
3832 &_tz_input_device_mgr_listener, ewd);
3836 EAPI struct wl_seat *
3837 ecore_wl2_input_seat_get(Ecore_Wl2_Input *input)
3839 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3840 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3841 return input->wl.seat;
3844 EAPI Ecore_Wl2_Seat_Capabilities
3845 ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input)
3847 Ecore_Wl2_Seat_Capabilities cap = ECORE_WL2_SEAT_CAPABILITIES_NONE;
3849 EINA_SAFETY_ON_NULL_RETURN_VAL(input, cap);
3850 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
3851 if (input->wl.keyboard)
3852 cap |= ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD;
3853 if (input->wl.pointer)
3854 cap |= ECORE_WL2_SEAT_CAPABILITIES_POINTER;
3855 if (input->wl.touch)
3856 cap |= ECORE_WL2_SEAT_CAPABILITIES_TOUCH;
3860 EAPI Eina_Stringshare *
3861 ecore_wl2_input_name_get(Ecore_Wl2_Input *input)
3863 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3868 ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input)
3870 EINA_SAFETY_ON_NULL_RETURN_VAL(input, 0);
3871 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
3875 EAPI Ecore_Wl2_Display *
3876 ecore_wl2_input_display_get(const Ecore_Wl2_Input *input)
3878 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3879 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3880 return input->display;
3883 EAPI struct xkb_keymap *
3884 ecore_wl2_input_keymap_get(const Ecore_Wl2_Input *input)
3886 EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
3887 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
3888 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, NULL);
3889 return input->xkb.keymap;
3893 ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3895 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3896 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3897 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3898 input->repeat.rate = input->repeat.horizontal.rate = input->repeat.vertical.rate = rate;
3899 input->repeat.delay = input->repeat.horizontal.delay = input->repeat.vertical.delay = delay;
3900 input->repeat.changed = EINA_TRUE;
3901 return input->repeat.enabled;
3905 ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3907 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3908 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3909 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3910 if (rate) *rate = input->repeat.rate;
3911 if (delay) *delay = input->repeat.delay;
3912 return input->repeat.enabled;
3916 ecore_wl2_input_keyboard_horizontal_way_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3918 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3919 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3920 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3921 input->repeat.horizontal.rate = rate;
3922 input->repeat.horizontal.delay = delay;
3923 input->repeat.changed = EINA_TRUE;
3924 return input->repeat.enabled;
3928 ecore_wl2_input_keyboard_horizontal_way_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3930 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3931 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3932 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3933 if (rate) *rate = input->repeat.horizontal.rate;
3934 if (delay) *delay = input->repeat.horizontal.delay;
3935 return input->repeat.enabled;
3940 ecore_wl2_input_keyboard_vertical_way_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
3942 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3943 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3944 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3945 input->repeat.vertical.rate = rate;
3946 input->repeat.vertical.delay = delay;
3947 input->repeat.changed = EINA_TRUE;
3948 return input->repeat.enabled;
3952 ecore_wl2_input_keyboard_vertical_way_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
3954 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
3955 EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
3956 EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
3957 if (rate) *rate = input->repeat.vertical.rate;
3958 if (delay) *delay = input->repeat.vertical.delay;
3959 return input->repeat.enabled;
3962 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3964 _pointer_update_stop(Ecore_Wl2_Input *input)
3966 if (!input->cursor.timer) return;
3968 ecore_timer_del(input->cursor.timer);
3969 input->cursor.timer = NULL;
3974 ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y)
3976 EINA_SAFETY_ON_NULL_RETURN(input);
3978 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
3979 _pointer_update_stop(input);
3980 if (input->wl.pointer)
3981 wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
3982 surface, hot_x, hot_y);
3985 // TIZEN_ONLY(20230330): support client that requests to unset cursor
3988 if (input->cursor.name) eina_stringshare_del(input->cursor.name);
3989 input->cursor.name = NULL;
3990 ecore_wl2_display_flush(input->display);
3995 input->cursor.surface = surface;
3996 input->cursor.hot_x = hot_x;
3997 input->cursor.hot_y = hot_y;
3999 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4001 _ecore_wl2_input_cursor_update(input);
4006 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4007 EAPI struct wl_cursor *
4008 ecore_wl2_input_cursor_get(Ecore_Wl2_Input *input, const char *cursor_name)
4010 if ((!input) || (!input->cursor.theme))
4013 return wl_cursor_theme_get_cursor(input->cursor.theme,
4019 ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor_name)
4021 EINA_SAFETY_ON_NULL_RETURN(input);
4022 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4024 _ecore_wl2_input_cursor_set(input, cursor);
4026 struct wl_cursor *cursor;
4028 /* No pointer device. Don't need to set cursor and update it */
4029 if (!input->wl.pointer) return;
4031 _pointer_update_stop(input);
4033 eina_stringshare_replace(&input->cursor.name, cursor_name);
4035 /* No cursor. Set to default Left Pointer */
4037 eina_stringshare_replace(&input->cursor.name, "left_ptr");
4039 /* try to get this cursor from the theme */
4040 if (!(cursor = ecore_wl2_input_cursor_get(input, input->cursor.name)))
4042 /* if the theme does not have this cursor, default to left pointer */
4043 if (!(cursor = ecore_wl2_input_cursor_get(input, "left_ptr")))
4047 input->cursor.cursor = cursor;
4049 if ((!cursor->images) || (!cursor->images[0]))
4051 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
4055 input->cursor.current_index = 0;
4057 _ecore_wl2_input_cursor_update(input);
4061 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4063 ecore_wl2_input_cursor_size_set(Ecore_Wl2_Input *input, const int size)
4067 input->cursor.size = size;
4069 EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);
4071 if (input->cursor.theme)
4072 wl_cursor_theme_destroy(input->cursor.theme);
4074 input->cursor.theme =
4075 wl_cursor_theme_load(NULL, input->cursor.size, input->display->wl.shm);
4079 ecore_wl2_input_cursor_theme_name_set(Ecore_Wl2_Input *input, const char *cursor_theme_name)
4083 if (eina_streq(input->cursor.theme_name, cursor_theme_name))
4086 eina_stringshare_replace(&input->cursor.theme_name, cursor_theme_name);
4088 EINA_SAFETY_ON_NULL_RETURN(input->display->wl.shm);
4090 if (input->cursor.theme)
4091 wl_cursor_theme_destroy(input->cursor.theme);
4092 input->cursor.theme =
4093 wl_cursor_theme_load(input->cursor.theme_name, input->cursor.size,
4094 input->display->wl.shm);
4098 ecore_wl2_input_cursor_default_restore(Ecore_Wl2_Input *input)
4102 /* Restore to default wayland cursor */
4103 ecore_wl2_input_cursor_from_name_set(input, "left_ptr");
4108 ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int *x, int *y)
4110 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4114 if (!input->wl.pointer) return EINA_FALSE;
4115 if (x) *x = input->pointer.sx;
4116 if (y) *y = input->pointer.sy;
4120 EAPI Ecore_Wl2_Input *
4121 ecore_wl2_input_default_input_get(const Ecore_Wl2_Display *ewd)
4123 Ecore_Wl2_Input *input;
4125 EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
4126 if (!ewd->inputs) return NULL;
4128 input = ecore_wl2_display_input_find_by_name(ewd, "seat0");
4129 if (!input) input = ecore_wl2_display_input_find_by_name(ewd, "default");
4134 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
4136 ecore_wl2_window_pointer_constraints_lock_pointer(Ecore_Wl2_Window *win)
4138 Ecore_Wl2_Display *ewd;
4139 Ecore_Wl2_Input *input;
4141 EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4142 EINA_SAFETY_ON_NULL_RETURN_VAL(win->surface, EINA_FALSE);
4145 input = ecore_wl2_input_default_input_get(ewd);
4146 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4148 if (!ewd->wl.pointer_constraints)
4150 ERR("Failed to lock pointer. constraints is NULL");
4153 if (!input->wl.locked_pointer)
4155 INF("Pointer Constraint: lock pointer. (region: %p)", input->lock_region);
4156 input->wl.locked_pointer =
4157 zwp_pointer_constraints_v1_lock_pointer(ewd->wl.pointer_constraints,
4161 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
4162 zwp_locked_pointer_v1_add_listener(input->wl.locked_pointer,
4163 &_locked_pointer_listener, input);
4166 if (ewd->wl.relative_pointer_manager &&
4167 !input->wl.relative_pointer)
4169 input->wl.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
4170 ewd->wl.relative_pointer_manager,
4172 zwp_relative_pointer_v1_add_listener(input->wl.relative_pointer, &_relative_pointer_listener, input);
4174 input->want_lock_pointer = EINA_TRUE;
4180 ecore_wl2_window_pointer_constraints_unlock_pointer(Ecore_Wl2_Window *win)
4182 Ecore_Wl2_Display *ewd;
4183 Ecore_Wl2_Input *input;
4185 EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4188 input = ecore_wl2_input_default_input_get(ewd);
4189 EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
4191 if (input->wl.locked_pointer)
4193 INF("Pointer Constraint: Destroy locked pointer");
4194 zwp_locked_pointer_v1_destroy(input->wl.locked_pointer);
4195 input->wl.locked_pointer = NULL;
4197 input->want_lock_pointer = EINA_FALSE;
4203 ecore_wl2_window_locked_pointer_region_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
4205 Ecore_Wl2_Display *ewd;
4206 Ecore_Wl2_Input *input;
4208 EINA_SAFETY_ON_NULL_RETURN(win);
4211 input = ecore_wl2_input_default_input_get(ewd);
4212 EINA_SAFETY_ON_NULL_RETURN(input);
4214 if (input->lock_region)
4216 wl_region_destroy(input->lock_region);
4217 input->lock_region = NULL;
4220 if ((w > 0) && (h > 0))
4222 struct wl_region *region;
4224 region = wl_compositor_create_region(ewd->wl.compositor);
4227 ERR("Failed to create region of locked_pointer");
4231 input->lock_region = region;
4232 wl_region_add(input->lock_region, x, y, w, h);
4234 if (!input->wl.locked_pointer)
4236 INF("No locked_pointer available. region (%d, %d) (w:%d, h:%d)", x, y, w, h);
4240 INF("Set region for locked_pointer (%d, %d) (w:%d, h:%d)", x, y, w, h);
4241 zwp_locked_pointer_v1_set_region(input->wl.locked_pointer, input->lock_region);
4245 if (!input->wl.locked_pointer)
4247 INF("No locked_pointer available. region (%d, %d) (w:%d, h:%d)", x, y, w, h);
4250 INF("Set region for locked_pointer. NULL region");
4251 zwp_locked_pointer_v1_set_region(input->wl.locked_pointer, NULL);
4256 ecore_wl2_window_locked_pointer_cursor_position_hint_set(Ecore_Wl2_Window *win, int x, int y)
4258 Ecore_Wl2_Display *ewd;
4259 Ecore_Wl2_Input *input;
4261 EINA_SAFETY_ON_NULL_RETURN(win);
4264 input = ecore_wl2_input_default_input_get(ewd);
4265 EINA_SAFETY_ON_NULL_RETURN(input);
4267 if (!input->wl.locked_pointer)
4269 INF("No locked pointer available. cursor position hint (%d, %d)", x, y);
4273 INF("Set cursor position hint (%d, %d) for locked_pointer", x, y);
4274 zwp_locked_pointer_v1_set_cursor_position_hint(input->wl.locked_pointer,
4275 wl_fixed_from_int(x),
4276 wl_fixed_from_int(y));
4280 // TIZEN_ONLY(20230821) : add cursor_visible set API
4282 ecore_wl2_window_cursor_visible_set(Ecore_Wl2_Window *win, Eina_Bool visible)
4284 Ecore_Wl2_Display *ewd;
4285 Ecore_Wl2_Input *input;
4287 EINA_SAFETY_ON_NULL_RETURN(win);
4290 input = ecore_wl2_input_default_input_get(ewd);
4291 EINA_SAFETY_ON_NULL_RETURN(input);
4293 INF("Set cursor_visible to %s", visible ? "True" : "False");
4296 ecore_wl2_input_cursor_from_name_set(input, input->cursor.name);
4300 ecore_wl2_input_pointer_set(input, NULL, 0, 0);
4304 // TIZEN_ONLY(20230823) : add keyboard_grab/ungrab API
4306 ecore_wl2_window_keyboard_grab(Ecore_Wl2_Window *win, unsigned int subtype)
4308 Ecore_Wl2_Display *ewd;
4309 Ecore_Device_Subclass subclas = (Ecore_Device_Subclass)subtype;
4311 if (!win || !win->surface) return EINA_FALSE;
4313 if (!ewd || !ewd->wl.tz_input_device_manager) return EINA_FALSE;
4315 _devicemgr_error = -1;
4316 if (subclas == ECORE_DEVICE_SUBCLASS_NONE)
4318 tizen_input_device_manager_keyboard_grab(ewd->wl.tz_input_device_manager,
4320 TIZEN_INPUT_DEVICE_MANAGER_SUBCLAS_NONE);
4322 else if (subtype == ECORE_DEVICE_SUBCLASS_REMOCON)
4324 tizen_input_device_manager_keyboard_grab(ewd->wl.tz_input_device_manager,
4326 TIZEN_INPUT_DEVICE_MANAGER_SUBCLAS_REMOCON);
4328 else if (subtype == ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD)
4330 tizen_input_device_manager_keyboard_grab(ewd->wl.tz_input_device_manager,
4332 TIZEN_INPUT_DEVICE_MANAGER_SUBCLAS_VIRTUAL_KEYBOARD);
4334 ecore_wl2_display_sync(ewd);
4336 if (_devicemgr_error != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE)
4338 ERR("Keyboard grab failed. subtype: %d", subtype);
4342 INF("Keyboard grab succeeded. subtype: %d", subtype);
4347 ecore_wl2_window_keyboard_ungrab(Ecore_Wl2_Window *win)
4349 Ecore_Wl2_Display *ewd;
4351 if (!win || !win->surface) return EINA_FALSE;
4353 if (!ewd || !ewd->wl.tz_input_device_manager) return EINA_FALSE;
4355 _devicemgr_error = -1;
4356 tizen_input_device_manager_keyboard_ungrab(ewd->wl.tz_input_device_manager,
4358 ecore_wl2_display_sync(ewd);
4360 if (_devicemgr_error != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE)
4362 ERR("Keyboard ungrab failed.");
4366 INF("Keyboard ungrab succeeded.");