1 /* this file contains code copied from weston; the copyright notice is below */
2 /*
3  * Copyright © 2008 Kristian Høgsberg
4  * Copyright © 2012-2013 Collabora, Ltd.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #ifdef __linux__
31 # include <linux/input.h>
32 #else
33 # define BTN_LEFT 0x110
34 # define BTN_RIGHT 0x111
35 # define BTN_MIDDLE 0x112
36 # define BTN_SIDE 0x113
37 # define BTN_EXTRA 0x114
38 # define BTN_FORWARD 0x115
39 # define BTN_BACK 0x116
40 #endif
41 
42 #include <unistd.h>
43 #include <sys/mman.h>
44 #include "ecore_wl2_private.h"
45 
46 typedef struct _Ecore_Wl2_Mouse_Down_Info
47 {
48    EINA_INLIST;
49    int device, sx, sy;
50    Ecore_Wl2_Window *last_win;
51    Ecore_Wl2_Window *last_last_win;
52    Ecore_Wl2_Window *last_event_win;
53    Ecore_Wl2_Window *last_last_event_win;
54    unsigned int last_time;
55    unsigned int last_last_time;
56    Eina_Bool double_click : 1;
57    Eina_Bool triple_click : 1;
58 } Ecore_Wl2_Mouse_Down_Info;
59 
60 static Eina_Inlist *_ecore_wl2_mouse_down_info_list = NULL;
61 
62 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);
63 
64 static Ecore_Wl2_Mouse_Down_Info *
_ecore_wl2_input_mouse_down_info_get(int device)65 _ecore_wl2_input_mouse_down_info_get(int device)
66 {
67    Eina_Inlist *l = NULL;
68    Ecore_Wl2_Mouse_Down_Info *info = NULL;
69 
70    l = _ecore_wl2_mouse_down_info_list;
71    EINA_INLIST_FOREACH(l, info)
72      if (info->device == device) return info;
73 
74    info = calloc(1, sizeof(Ecore_Wl2_Mouse_Down_Info));
75    if (!info) return NULL;
76 
77    info->device = device;
78    l = eina_inlist_append(l, (Eina_Inlist *)info);
79    _ecore_wl2_mouse_down_info_list = l;
80 
81    return info;
82 }
83 
84 static Ecore_Wl2_Input_Devices *
_ecore_wl2_devices_get(const Ecore_Wl2_Input * input,const Ecore_Wl2_Window * window)85 _ecore_wl2_devices_get(const Ecore_Wl2_Input *input, const Ecore_Wl2_Window *window)
86 {
87    Ecore_Wl2_Input_Devices *devices;
88    Eina_List *l;
89 
90    EINA_LIST_FOREACH(input->devices_list, l, devices)
91      {
92         if (devices->window == window)
93           return devices;
94      }
95 
96    return NULL;
97 }
98 
99 static Eo *
_ecore_wl2_mouse_dev_get(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)100 _ecore_wl2_mouse_dev_get(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
101 {
102    Ecore_Wl2_Input_Devices *devices;
103 
104    devices = _ecore_wl2_devices_get(input, window);
105    if (devices && devices->pointer_dev)
106      return efl_ref(devices->pointer_dev);
107 
108    return NULL;
109 }
110 
111 static Eo *
_ecore_wl2_touch_dev_get(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)112 _ecore_wl2_touch_dev_get(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
113 {
114    Ecore_Wl2_Input_Devices *devices;
115 
116    devices = _ecore_wl2_devices_get(input, window);
117    if (devices && devices->touch_dev)
118      return efl_ref(devices->touch_dev);
119 
120    return NULL;
121 }
122 
123 static Eo *
_ecore_wl2_seat_dev_get(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)124 _ecore_wl2_seat_dev_get(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
125 {
126    Ecore_Wl2_Input_Devices *devices;
127 
128    devices = _ecore_wl2_devices_get(input, window);
129    if (devices)
130      return efl_ref(devices->seat_dev);
131 
132    return NULL;
133 }
134 
135 static void
_input_event_cb_free(void * data,void * event)136 _input_event_cb_free(void *data, void *event)
137 {
138    if (data)
139      efl_unref(data);
140    free(event);
141 }
142 
143 static void
_ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)144 _ecore_wl2_input_mouse_in_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
145 {
146    Ecore_Event_Mouse_IO *ev;
147 
148    ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
149    if (!ev) return;
150 
151    ev->x = input->pointer.sx;
152    ev->y = input->pointer.sy;
153    ev->window = (Ecore_Window)window;
154    ev->event_window = (Ecore_Window)window;
155    ev->timestamp = input->timestamp;
156    ev->modifiers = input->keyboard.modifiers;
157    ev->dev = _ecore_wl2_mouse_dev_get(input, window);
158 
159    ecore_event_add(ECORE_EVENT_MOUSE_IN, ev, _input_event_cb_free, ev->dev);
160 }
161 
162 static void
_ecore_wl2_input_mouse_out_send(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)163 _ecore_wl2_input_mouse_out_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
164 {
165    Ecore_Event_Mouse_IO *ev;
166 
167    ev = calloc(1, sizeof(Ecore_Event_Mouse_IO));
168    if (!ev) return;
169 
170    ev->x = input->pointer.sx;
171    ev->y = input->pointer.sy;
172    ev->window = (Ecore_Window)window;
173    ev->event_window = (Ecore_Window)window;
174    ev->timestamp = input->timestamp;
175    ev->modifiers = input->keyboard.modifiers;
176    ev->dev = _ecore_wl2_mouse_dev_get(input, window);
177 
178    ecore_event_add(ECORE_EVENT_MOUSE_OUT, ev, _input_event_cb_free, ev->dev);
179 }
180 
181 static void
_ecore_wl2_input_mouse_move_send(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window,int device)182 _ecore_wl2_input_mouse_move_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device)
183 {
184    Ecore_Event_Mouse_Move *ev;
185    Ecore_Wl2_Mouse_Down_Info *info;
186 
187    ev = calloc(1, sizeof(Ecore_Event_Mouse_Move));
188    if (!ev) return;
189 
190    ev->window = (Ecore_Window)window;
191    ev->event_window = (Ecore_Window)window;
192    ev->timestamp = input->timestamp;
193    ev->x = input->pointer.sx;
194    ev->y = input->pointer.sy;
195    ev->root.x = input->pointer.sx;
196    ev->root.y = input->pointer.sy;
197    ev->modifiers = input->keyboard.modifiers;
198    ev->multi.device = device;
199    ev->multi.radius = 1;
200    ev->multi.radius_x = 1;
201    ev->multi.radius_y = 1;
202    ev->multi.pressure = 1.0;
203    ev->multi.angle = 0.0;
204    ev->multi.x = input->pointer.sx;
205    ev->multi.y = input->pointer.sy;
206    ev->multi.root.x = input->pointer.sx;
207    ev->multi.root.y = input->pointer.sy;
208 
209    if ((input->focus.touch) && (input->focus.touch == window))
210      ev->dev = _ecore_wl2_touch_dev_get(input, window);
211    else if ((input->focus.pointer) && (input->focus.pointer == window))
212      ev->dev = _ecore_wl2_mouse_dev_get(input, window);
213 
214    info = _ecore_wl2_input_mouse_down_info_get(device);
215    if (info)
216      {
217         info->sx = input->pointer.sx;
218         info->sy = input->pointer.sy;
219      }
220 
221    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _input_event_cb_free, ev->dev);
222 }
223 
224 static void
_ecore_wl2_input_mouse_wheel_send(Ecore_Wl2_Input * input,unsigned int axis,int value,unsigned int timestamp)225 _ecore_wl2_input_mouse_wheel_send(Ecore_Wl2_Input *input, unsigned int axis, int value, unsigned int timestamp)
226 {
227    Ecore_Event_Mouse_Wheel *ev;
228 
229    ev = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
230    if (!ev) return;
231 
232    ev->timestamp = timestamp;
233    ev->modifiers = input->keyboard.modifiers;
234    ev->x = input->pointer.sx;
235    ev->y = input->pointer.sy;
236    value /= 10;
237 
238    if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
239      {
240         ev->direction = 0;
241         ev->z = value;
242      }
243    else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
244      {
245         ev->direction = 1;
246         ev->z = value;
247      }
248 
249    if (input->grab.window)
250      {
251         ev->window = (Ecore_Window)input->grab.window;
252         ev->event_window = (Ecore_Window)input->grab.window;
253      }
254    else if (input->focus.pointer)
255      {
256         ev->window = (Ecore_Window)input->focus.pointer;
257         ev->event_window = (Ecore_Window)input->focus.pointer;
258         ev->dev = _ecore_wl2_mouse_dev_get(input, input->focus.pointer);
259      }
260    else if (input->focus.touch)
261      {
262         ev->window = (Ecore_Window)input->focus.touch;
263         ev->event_window = (Ecore_Window)input->focus.touch;
264         ev->dev = _ecore_wl2_touch_dev_get(input, input->focus.touch);
265      }
266 
267    if (!ev->dev)
268      {
269         ev->dev = _ecore_wl2_mouse_dev_get(input, (Ecore_Wl2_Window *)ev->window);
270         if (!ev->dev)
271           ev->dev = _ecore_wl2_touch_dev_get(input, (Ecore_Wl2_Window *)ev->window);
272      }
273 
274    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, _input_event_cb_free, ev->dev);
275 }
276 
277 static void
_ecore_wl2_input_mouse_down_send(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window,int device,unsigned int button,unsigned int timestamp)278 _ecore_wl2_input_mouse_down_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
279 {
280    Ecore_Event_Mouse_Button *ev;
281    Ecore_Wl2_Mouse_Down_Info *info;
282 
283    ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
284    if (!ev) return;
285 
286    if (button == BTN_LEFT)
287      ev->buttons = 1;
288    else if (button == BTN_MIDDLE)
289      ev->buttons = 2;
290    else if (button == BTN_RIGHT)
291      ev->buttons = 3;
292    else
293      ev->buttons = button;
294 
295    ev->timestamp = timestamp;
296    ev->x = input->pointer.sx;
297    ev->y = input->pointer.sy;
298    ev->root.x = input->pointer.sx;
299    ev->root.y = input->pointer.sy;
300    ev->modifiers = input->keyboard.modifiers;
301 
302    ev->double_click = 0;
303    ev->triple_click = 0;
304 
305    info = _ecore_wl2_input_mouse_down_info_get(device);
306    if (info)
307      {
308         info->sx = input->pointer.sx;
309         info->sy = input->pointer.sy;
310         if (info->triple_click)
311           {
312              info->last_win = 0;
313              info->last_last_win = 0;
314              info->last_event_win = 0;
315              info->last_last_event_win = 0;
316              info->last_time = 0;
317              info->last_last_time = 0;
318           }
319 
320         if (((int)(timestamp - info->last_time) <= (int)(1000 * 0.25)) &&
321             ((window) && (window == info->last_win) &&
322                 (window == info->last_event_win)))
323           {
324              ev->double_click = 1;
325              info->double_click = EINA_TRUE;
326           }
327         else
328           {
329              info->double_click = EINA_FALSE;
330              info->triple_click = EINA_FALSE;
331           }
332 
333         if (((int)(timestamp - info->last_last_time) <=
334              (int)(2 * 1000 * 0.25)) &&
335             ((window) && (window == info->last_win) &&
336                 (window == info->last_last_win) &&
337                 (window == info->last_event_win) &&
338                 (window == info->last_last_event_win)))
339           {
340              ev->triple_click = 1;
341              info->triple_click = EINA_TRUE;
342           }
343         else
344           info->triple_click = EINA_FALSE;
345      }
346 
347    ev->multi.device = device;
348    ev->multi.radius = 1;
349    ev->multi.radius_x = 1;
350    ev->multi.radius_y = 1;
351    ev->multi.pressure = 1.0;
352    ev->multi.angle = 0.0;
353    ev->multi.x = input->pointer.sx;
354    ev->multi.y = input->pointer.sy;
355    ev->multi.root.x = input->pointer.sx;
356    ev->multi.root.y = input->pointer.sy;
357 
358    if (window)
359      {
360         ev->window = (Ecore_Window)window;
361         ev->event_window = (Ecore_Window)window;
362 
363         if ((input->focus.touch) && (input->focus.touch == window))
364           ev->dev = _ecore_wl2_touch_dev_get(input, window);
365         else if ((input->focus.pointer) && (input->focus.pointer == window))
366           ev->dev = _ecore_wl2_mouse_dev_get(input, window);
367      }
368 
369    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev,
370                    _input_event_cb_free, ev->dev);
371 
372    if ((info) && (!info->triple_click))
373      {
374         info->last_last_win = info->last_win;
375         info->last_win = (Ecore_Wl2_Window *)ev->window;
376         info->last_last_event_win = info->last_event_win;
377         info->last_event_win = (Ecore_Wl2_Window *)ev->window;
378         info->last_last_time = info->last_time;
379         info->last_time = timestamp;
380      }
381 }
382 
383 static void
_ecore_wl2_input_mouse_up_send(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window,int device,unsigned int button,unsigned int timestamp)384 _ecore_wl2_input_mouse_up_send(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, int device, unsigned int button, unsigned int timestamp)
385 {
386    Ecore_Event_Mouse_Button *ev;
387    Ecore_Wl2_Mouse_Down_Info *info;
388 
389    ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
390    if (!ev) return;
391 
392    if (button == BTN_LEFT)
393      ev->buttons = 1;
394    else if (button == BTN_MIDDLE)
395      ev->buttons = 2;
396    else if (button == BTN_RIGHT)
397      ev->buttons = 3;
398    else
399      ev->buttons = button;
400 
401    ev->timestamp = timestamp;
402    ev->x = input->pointer.sx;
403    ev->y = input->pointer.sy;
404    ev->root.x = input->pointer.sx;
405    ev->root.y = input->pointer.sy;
406    ev->modifiers = input->keyboard.modifiers;
407 
408    ev->double_click = 0;
409    ev->triple_click = 0;
410 
411    info = _ecore_wl2_input_mouse_down_info_get(device);
412    if (info)
413      {
414         ev->double_click = info->double_click;
415         ev->triple_click = info->triple_click;
416         ev->x = info->sx;
417         ev->y = info->sy;
418         ev->multi.x = info->sx;
419         ev->multi.y = info->sy;
420      }
421    else
422      {
423         ev->multi.x = input->pointer.sx;
424         ev->multi.y = input->pointer.sy;
425      }
426 
427    ev->multi.device = device;
428    ev->multi.radius = 1;
429    ev->multi.radius_x = 1;
430    ev->multi.radius_y = 1;
431    ev->multi.pressure = 1.0;
432    ev->multi.angle = 0.0;
433    ev->multi.root.x = input->pointer.sx;
434    ev->multi.root.y = input->pointer.sy;
435 
436    ev->window = (Ecore_Window)window;
437    ev->event_window = (Ecore_Window)window;
438 
439    if ((input->focus.touch) && (input->focus.touch == window))
440      ev->dev = _ecore_wl2_touch_dev_get(input, window);
441    else if ((input->focus.pointer) && (input->focus.pointer == window))
442      ev->dev = _ecore_wl2_mouse_dev_get(input, window);
443 
444    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev,
445                    _input_event_cb_free, ev->dev);
446 }
447 
448 static void
_input_event_focus_cb_free(void * data,void * event)449 _input_event_focus_cb_free(void *data, void *event)
450 {
451    Ecore_Wl2_Event_Focus_In *ev = event;
452    if (data)
453      efl_unref(data);
454    ecore_wl2_display_disconnect(ev->display);
455    free(event);
456 }
457 
458 static void
_ecore_wl2_input_focus_in_send(Ecore_Wl2_Window * window,Ecore_Wl2_Input * input)459 _ecore_wl2_input_focus_in_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
460 {
461    Ecore_Wl2_Event_Focus_In *ev;
462 
463    ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_In));
464    if (!ev) return;
465 
466    ev->timestamp = input->timestamp;
467    ev->window = window;
468    ev->dev = _ecore_wl2_seat_dev_get(input, window);
469    ev->display = input->display;
470    ev->display->refs++;
471    ecore_event_add(ECORE_WL2_EVENT_FOCUS_IN, ev, _input_event_focus_cb_free,
472                    ev->dev);
473 }
474 
475 static void
_ecore_wl2_input_focus_out_send(Ecore_Wl2_Window * window,Ecore_Wl2_Input * input)476 _ecore_wl2_input_focus_out_send(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
477 {
478    Ecore_Wl2_Event_Focus_Out *ev;
479 
480    ev = calloc(1, sizeof(Ecore_Wl2_Event_Focus_Out));
481    if (!ev) return;
482 
483    ev->timestamp = input->timestamp;
484    ev->window = window;
485    ev->dev = _ecore_wl2_seat_dev_get(input, window);
486    ev->display = input->display;
487    ev->display->refs++;
488    ecore_event_add(ECORE_WL2_EVENT_FOCUS_OUT, ev, _input_event_focus_cb_free,
489                    ev->dev);
490 }
491 
492 static int
_ecore_wl2_input_key_translate(xkb_keysym_t keysym,unsigned int modifiers,char * buffer,int bytes)493 _ecore_wl2_input_key_translate(xkb_keysym_t keysym, unsigned int modifiers, char *buffer, int bytes)
494 {
495 /* this function is copied, with slight changes in variable names, from KeyBind.c in libX11
496  * the license from that file can be found below:
497  */
498 /*
499 
500 Copyright 1985, 1987, 1998  The Open Group
501 
502 Permission to use, copy, modify, distribute, and sell this software and its
503 documentation for any purpose is hereby granted without fee, provided that
504 the above copyright notice appear in all copies and that both that
505 copyright notice and this permission notice appear in supporting
506 documentation.
507 
508 The above copyright notice and this permission notice shall be included in
509 all copies or substantial portions of the Software.
510 
511 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
512 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
513 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
514 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
515 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
516 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
517 
518 Except as contained in this notice, the name of The Open Group shall not be
519 used in advertising or otherwise to promote the sale, use or other dealings
520 in this Software without prior written authorization from The Open Group.
521 
522 */
523    if (!keysym) return 0;
524 
525    /* check for possible control codes */
526    if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
527      {
528         Eina_Bool valid_control_code = EINA_TRUE;
529         unsigned long hbytes = 0;
530         unsigned char c;
531 
532         hbytes = (keysym >> 8);
533         if (!(bytes &&
534         ((hbytes == 0) ||
535         ((hbytes == 0xFF) &&
536         (((keysym >= XKB_KEY_BackSpace) && (keysym <= XKB_KEY_Clear)) ||
537         (keysym == XKB_KEY_Return) ||
538         (keysym == XKB_KEY_Escape) ||
539         (keysym == XKB_KEY_KP_Space) ||
540         (keysym == XKB_KEY_KP_Tab) ||
541         (keysym == XKB_KEY_KP_Enter) ||
542         ((keysym >= XKB_KEY_KP_Multiply) && (keysym <= XKB_KEY_KP_9)) ||
543         (keysym == XKB_KEY_KP_Equal) ||
544         (keysym == XKB_KEY_Delete))))))
545           return 0;
546 
547         if (keysym == XKB_KEY_KP_Space)
548           c = (XKB_KEY_space & 0x7F);
549         else if (hbytes == 0xFF)
550           c = (keysym & 0x7F);
551         else
552           c = (keysym & 0xFF);
553 
554         /* We are building here a control code
555            for more details, read:
556            https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C0_.28ASCII_and_derivatives.29
557          */
558 
559         if (((c >= '@') && (c <= '_')) || /* those are the one defined in C0 with capital letters */
560              ((c >= 'a') && (c <= 'z')) ||  /* the lowercase symbols (not part of the standard, but useful) */
561               c == ' ')
562           c &= 0x1F;
563         else if (c == '\x7f')
564           c = '\177';
565         /* following codes are alternatives, they are longer here, i dont want to change them */
566         else if (c == '2')
567           c = '\000'; /* 0 code */
568         else if ((c >= '3') && (c <= '7'))
569           c -= ('3' - '\033'); /* from escape to unitseperator code*/
570         else if (c == '8')
571           c = '\177'; /* delete code */
572         else if (c == '/')
573           c = '_' & 0x1F; /* unit seperator code */
574         else
575           valid_control_code = EINA_FALSE;
576 
577         if (valid_control_code)
578           buffer[0] = c;
579         else
580           return 0;
581      }
582    else
583      {
584         /* if its not a control code, try to produce useful output */
585         if (!xkb_keysym_to_utf8(keysym, buffer, bytes))
586           return 0;
587      }
588 
589    return 1;
590 }
591 
592 static void
_ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym,char * buffer,int size,unsigned int code)593 _ecore_wl2_input_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code)
594 {
595     if (xkb_keysym_get_name(keysym, buffer, size) != 0)
596       return;
597 
598     snprintf(buffer, size, "Keycode-%u", code);
599 }
600 
601 static Eo *
_ecore_wl2_keyboard_dev_get(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)602 _ecore_wl2_keyboard_dev_get(Ecore_Wl2_Input *input, Ecore_Wl2_Window * window)
603 {
604    Ecore_Wl2_Input_Devices *devices;
605 
606    devices = _ecore_wl2_devices_get(input, window);
607    if (devices && devices->keyboard_dev)
608      return efl_ref(devices->keyboard_dev);
609 
610    return NULL;
611 }
612 
613 static void
_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)614 _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)
615 {
616    Ecore_Event_Key *ev;
617    char key[256] = "", keyname[256] = "", compose[256] = "";
618    int name_len, key_len, comp_len;
619 
620    /*try to get a name or utf char of the given symbol */
621    _ecore_wl2_input_symbol_rep_find(sym, key, sizeof(key), code);
622    _ecore_wl2_input_symbol_rep_find(sym_name, keyname, sizeof(keyname), code);
623    _ecore_wl2_input_key_translate(sym, input->keyboard.modifiers,
624                                   compose, sizeof(compose));
625 
626    name_len = strlen(keyname);
627    key_len = strlen(key);
628    comp_len = strlen(compose);
629 
630    ev = calloc(1, sizeof(Ecore_Event_Key) + key_len + name_len + comp_len + 3);
631    if (!ev) return;
632 
633    ev->keyname = (char *)(ev + 1);
634    ev->key = ev->keyname + name_len + 1;
635    ev->compose = comp_len ? ev->key + key_len + 1 : NULL;
636    ev->string = ev->compose;
637 
638    strcpy((char *)ev->keyname, keyname);
639    strcpy((char *)ev->key, key);
640    if (comp_len) strcpy((char *)ev->compose, compose);
641 
642    ev->window = (Ecore_Window)window;
643    ev->event_window = (Ecore_Window)window;
644    ev->timestamp = timestamp;
645    ev->modifiers = input->keyboard.modifiers;
646    ev->keycode = code;
647    ev->dev = _ecore_wl2_keyboard_dev_get(input, window);
648 
649    /* DBG("Emitting Key event (%s,%s,%s,%s)\n", ev->keyname, ev->key, ev->compose, ev->string); */
650 
651    if (state)
652      ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, _input_event_cb_free, ev->dev);
653    else
654      ecore_event_add(ECORE_EVENT_KEY_UP, ev, _input_event_cb_free, ev->dev);
655 }
656 
657 void
_ecore_wl2_input_grab(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window,unsigned int button)658 _ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, unsigned int button)
659 {
660    input->grab.window = window;
661    input->grab.button = button;
662 }
663 
664 void
_ecore_wl2_input_ungrab(Ecore_Wl2_Input * input)665 _ecore_wl2_input_ungrab(Ecore_Wl2_Input *input)
666 {
667    if ((input->grab.window) && (input->grab.button) && (input->grab.count))
668      _ecore_wl2_input_mouse_up_send(input, input->grab.window, 0,
669                                     input->grab.button, input->grab.timestamp);
670 
671    input->grab.window = NULL;
672    input->grab.button = 0;
673    input->grab.count = 0;
674    input->grab.touch_count = 0;
675 }
676 
677 static void
_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)678 _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)
679 {
680    Ecore_Wl2_Input *input;
681    Ecore_Wl2_Window *window;
682 
683    input = data;
684    if (!input) return;
685 
686    /* trap for a surface that was just destroyed */
687    if (!surface) return;
688 
689    if (!input->timestamp)
690      {
691         struct timeval tv;
692 
693         gettimeofday(&tv, NULL);
694         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
695      }
696 
697    input->display->serial = serial;
698    input->pointer.enter_serial = serial;
699    input->pointer.sx = wl_fixed_to_double(sx);
700    input->pointer.sy = wl_fixed_to_double(sy);
701 
702    /* find the window which this surface belongs to */
703    window = _ecore_wl2_display_window_surface_find(input->display, surface);
704    if (!window) return;
705 
706    input->focus.prev_pointer = NULL;
707    input->focus.pointer = window;
708 
709    _ecore_wl2_input_mouse_in_send(input, window);
710 }
711 
712 static void
_pointer_cb_leave(void * data,struct wl_pointer * pointer EINA_UNUSED,unsigned int serial,struct wl_surface * surface)713 _pointer_cb_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
714 {
715    Ecore_Wl2_Input *input;
716    Ecore_Wl2_Window *window;
717 
718    input = data;
719    if (!input) return;
720 
721    input->display->serial = serial;
722    input->focus.prev_pointer = input->focus.pointer;
723    input->focus.pointer = NULL;
724 
725    /* trap for a surface that was just destroyed */
726    if (!surface) return;
727 
728    /* find the window which this surface belongs to */
729    window = _ecore_wl2_display_window_surface_find(input->display, surface);
730    if (!window) return;
731 
732    _ecore_wl2_input_mouse_out_send(input, window);
733 }
734 
735 static void
_pointer_cb_motion(void * data,struct wl_pointer * pointer EINA_UNUSED,unsigned int timestamp,wl_fixed_t sx,wl_fixed_t sy)736 _pointer_cb_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy)
737 {
738    Ecore_Wl2_Input *input;
739    Ecore_Wl2_Window *window;
740 
741    input = data;
742    if (!input) return;
743 
744    input->timestamp = timestamp;
745    input->pointer.sx = wl_fixed_to_double(sx);
746    input->pointer.sy = wl_fixed_to_double(sy);
747 
748    /* get currently focused window */
749    window = input->focus.pointer;
750    if (!window) return;
751 
752    /* NB: Unsure if we need this just yet, so commented out for now */
753    /* if ((input->pointer.sx > window->geometry.w) || */
754    /*     (input->pointer.sy > window->geometry.h)) */
755    /*   return; */
756 
757    _ecore_wl2_input_mouse_move_send(input, window, 0);
758 }
759 
760 static void
_pointer_cb_button(void * data,struct wl_pointer * pointer EINA_UNUSED,unsigned int serial,unsigned int timestamp,unsigned int button,unsigned int state)761 _pointer_cb_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state)
762 {
763    Ecore_Wl2_Input *input;
764 
765    input = data;
766    if (!input) return;
767 
768    input->display->serial = serial;
769    input->timestamp = timestamp;
770 
771    if (state == WL_POINTER_BUTTON_STATE_PRESSED)
772      {
773         if ((input->focus.pointer) &&
774             (!input->grab.window) && (!input->grab.count))
775           {
776              _ecore_wl2_input_grab(input, input->focus.pointer, button);
777              input->grab.timestamp = timestamp;
778           }
779 
780         if (input->focus.pointer)
781           _ecore_wl2_input_mouse_down_send(input, input->focus.pointer,
782                                            0, button, timestamp);
783 
784         input->grab.count++;
785      }
786    else
787      {
788         if (input->focus.pointer)
789           _ecore_wl2_input_mouse_up_send(input, input->focus.pointer,
790                                          0, button, timestamp);
791 
792         if (input->grab.count) input->grab.count--;
793         if ((input->grab.window) && (input->grab.button == button) &&
794             (!input->grab.count))
795           _ecore_wl2_input_ungrab(input);
796      }
797 }
798 
799 static void
_pointer_cb_axis(void * data,struct wl_pointer * pointer EINA_UNUSED,unsigned int timestamp,unsigned int axis,wl_fixed_t value)800 _pointer_cb_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value)
801 {
802    Ecore_Wl2_Input *input;
803 
804    input = data;
805    if (!input) return;
806 
807    input->timestamp = timestamp;
808 
809    _ecore_wl2_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value),
810                                      timestamp);
811 }
812 
813 static const struct wl_pointer_listener _pointer_listener =
814 {
815    _pointer_cb_enter,
816    _pointer_cb_leave,
817    _pointer_cb_motion,
818    _pointer_cb_button,
819    _pointer_cb_axis,
820    NULL, /* frame */
821    NULL, /* axis_source */
822    NULL, /* axis_stop */
823    NULL, /* axis_discrete */
824 };
825 
826 static void
_keyboard_cb_keymap(void * data,struct wl_keyboard * keyboard EINA_UNUSED,unsigned int format,int fd,unsigned int size)827 _keyboard_cb_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size)
828 {
829    Ecore_Wl2_Input *input;
830    Ecore_Wl2_Event_Seat_Keymap_Changed *ev;
831    char *map = NULL;
832    const char *locale;
833 
834    input = data;
835    if (!input)
836      {
837         close(fd);
838         return;
839      }
840 
841    if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
842      {
843         close(fd);
844         return;
845      }
846 
847    map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
848    if (map == MAP_FAILED)
849      {
850         close(fd);
851         return;
852      }
853 
854    /* free any existing keymap and state */
855    if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
856    if (input->xkb.state) xkb_state_unref(input->xkb.state);
857    if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
858 
859    input->xkb.keymap =
860      xkb_map_new_from_string(input->display->xkb_context, map,
861                              XKB_KEYMAP_FORMAT_TEXT_V1, 0);
862 
863    munmap(map, size);
864    close(fd);
865 
866    if (!input->xkb.keymap)
867      {
868         ERR("Failed to compile keymap");
869         return;
870      }
871 
872    input->xkb.state = xkb_state_new(input->xkb.keymap);
873    input->xkb.maskless_state = xkb_state_new(input->xkb.keymap);
874 
875    if (!input->xkb.state || !input->xkb.maskless_state)
876      {
877         ERR("Failed to create keymap state");
878         xkb_map_unref(input->xkb.keymap);
879         input->xkb.keymap = NULL;
880         return;
881      }
882 
883    if (!(locale = getenv("LC_ALL")))
884      if (!(locale = getenv("LC_CTYPE")))
885        if (!(locale = getenv("LANG")))
886          locale = "C";
887 
888    if (input->xkb.compose_table)
889      xkb_compose_table_unref(input->xkb.compose_table);
890 
891    input->xkb.compose_table =
892      xkb_compose_table_new_from_locale(input->display->xkb_context,
893                                        locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
894    if (input->xkb.compose_state)
895      xkb_compose_state_unref(input->xkb.compose_state);
896    input->xkb.compose_state = NULL;
897 
898    if (input->xkb.compose_table)
899      {
900         input->xkb.compose_state =
901           xkb_compose_state_new(input->xkb.compose_table,
902                                 XKB_COMPOSE_STATE_NO_FLAGS);
903      }
904 
905    ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
906    if (ev)
907      {
908         ev->id = input->id;
909         ev->display = input->display;
910         input->display->refs++;
911         ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYMAP_CHANGED, ev,
912                         _display_event_free, ev->display);
913      }
914 
915    input->xkb.control_mask =
916      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CTRL);
917    input->xkb.alt_mask =
918      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_ALT);
919    input->xkb.shift_mask =
920      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_SHIFT);
921    input->xkb.win_mask =
922      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_LOGO);
923    input->xkb.scroll_mask =
924      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_SCROLL);
925    input->xkb.num_mask =
926      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_LED_NAME_NUM);
927    input->xkb.caps_mask =
928      1 << xkb_map_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_CAPS);
929    input->xkb.altgr_mask =
930      1 << xkb_map_mod_get_index(input->xkb.keymap, "ISO_Level3_Shift");
931 }
932 
933 static void
_keyboard_cb_enter(void * data,struct wl_keyboard * keyboard EINA_UNUSED,unsigned int serial,struct wl_surface * surface,struct wl_array * keys EINA_UNUSED)934 _keyboard_cb_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED)
935 {
936    Ecore_Wl2_Input *input;
937    Ecore_Wl2_Window *window;
938 
939    input = data;
940    if (!input) return;
941 
942    input->display->serial = serial;
943 
944    if (!input->timestamp)
945      {
946         struct timeval tv;
947 
948         gettimeofday(&tv, NULL);
949         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
950      }
951 
952    /* find the window which this surface belongs to */
953    window = _ecore_wl2_display_window_surface_find(input->display, surface);
954    if (!window) return;
955 
956    input->focus.keyboard = window;
957    _ecore_wl2_input_focus_in_send(window, input);
958 }
959 
960 static void
_keyboard_cb_leave(void * data,struct wl_keyboard * keyboard EINA_UNUSED,unsigned int serial,struct wl_surface * surface)961 _keyboard_cb_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface)
962 {
963    Ecore_Wl2_Input *input;
964    Ecore_Wl2_Window *window;
965 
966    input = data;
967    if (!input) return;
968 
969    input->display->serial = serial;
970 
971    input->repeat.sym = 0;
972    input->repeat.key = 0;
973    input->repeat.time = 0;
974    if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
975    input->repeat.timer = NULL;
976    window = _ecore_wl2_display_window_surface_find(input->display, surface);
977    if (window)
978      {
979         if (input->focus.keyboard != window)
980           ERR("Received keyboard.leave when keyboard did not have enter");
981      }
982    input->focus.keyboard = NULL;
983    if (window)
984      _ecore_wl2_input_focus_out_send(window, input);
985 }
986 
987 static Eina_Bool
_keyboard_cb_repeat(void * data)988 _keyboard_cb_repeat(void *data)
989 {
990    Ecore_Wl2_Input *input;
991    Ecore_Wl2_Window *window;
992 
993    input = data;
994    if (!input) return ECORE_CALLBACK_RENEW;
995 
996    window = input->focus.keyboard;
997    if (!window) goto out;
998 
999    _ecore_wl2_input_key_send(input, input->focus.keyboard,
1000                              input->repeat.sym, input->repeat.sym_name,
1001                              input->repeat.key + 8,
1002                              WL_KEYBOARD_KEY_STATE_PRESSED,
1003                              input->repeat.time);
1004 
1005    if (!input->repeat.repeating)
1006      {
1007         ecore_timer_interval_set(input->repeat.timer, input->repeat.rate);
1008         input->repeat.repeating = EINA_TRUE;
1009      }
1010    return ECORE_CALLBACK_RENEW;
1011 
1012 out:
1013    input->repeat.sym = 0;
1014    input->repeat.key = 0;
1015    input->repeat.time = 0;
1016    return ECORE_CALLBACK_CANCEL;
1017 }
1018 
1019 /* from weston/clients/window.c */
1020 /* Translate symbols appropriately if a compose sequence is being entered */
1021 static xkb_keysym_t
process_key_press(xkb_keysym_t sym,Ecore_Wl2_Input * input)1022 process_key_press(xkb_keysym_t sym, Ecore_Wl2_Input *input)
1023 {
1024    if (!input->xkb.compose_state)
1025      return sym;
1026    if (sym == XKB_KEY_NoSymbol)
1027      return sym;
1028    if (xkb_compose_state_feed(input->xkb.compose_state, sym) !=
1029        XKB_COMPOSE_FEED_ACCEPTED)
1030      return sym;
1031 
1032    switch (xkb_compose_state_get_status(input->xkb.compose_state))
1033      {
1034       case XKB_COMPOSE_COMPOSING:
1035         return XKB_KEY_NoSymbol;
1036       case XKB_COMPOSE_COMPOSED:
1037         return xkb_compose_state_get_one_sym(input->xkb.compose_state);
1038       case XKB_COMPOSE_CANCELLED:
1039         return XKB_KEY_NoSymbol;
1040       case XKB_COMPOSE_NOTHING:
1041       default: break;
1042      }
1043    return sym;
1044 }
1045 
1046 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)1047 _keyboard_cb_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state)
1048 {
1049    Ecore_Wl2_Input *input;
1050    Ecore_Wl2_Window *window;
1051    unsigned int code;
1052    xkb_keysym_t sym = XKB_KEY_NoSymbol, sym_name = XKB_KEY_NoSymbol;
1053    const xkb_keysym_t *syms;
1054 
1055    input = data;
1056    if (!input) return;
1057 
1058    /* try to get the window which has keyboard focus */
1059    window = input->focus.keyboard;
1060    if (!window) return;
1061 
1062    input->display->serial = serial;
1063    input->timestamp = timestamp;
1064 
1065    /* xkb rules reflect X broken keycodes, so offset by 8 */
1066    code = keycode + 8;
1067 
1068    if (xkb_state_key_get_syms(input->xkb.state, code, &syms) == 1)
1069      sym = syms[0];
1070    if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1071      sym = process_key_press(sym, input);
1072    sym_name = xkb_state_key_get_one_sym(input->xkb.maskless_state, code);
1073 
1074    _ecore_wl2_input_key_send(input, window, sym, sym_name, code,
1075                              state, timestamp);
1076 
1077    if (!xkb_keymap_key_repeats(input->xkb.keymap, code)) return;
1078 
1079    if ((state == WL_KEYBOARD_KEY_STATE_RELEASED) &&
1080        (keycode == input->repeat.key))
1081      {
1082         input->repeat.sym = 0;
1083         input->repeat.key = 0;
1084         input->repeat.time = 0;
1085         if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1086         input->repeat.timer = NULL;
1087      }
1088    else if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1089      {
1090         /* don't setup key repeat timer if not enabled */
1091         if (!input->repeat.enabled) return;
1092 
1093         input->repeat.sym = sym;
1094         input->repeat.sym_name = sym;
1095         input->repeat.key = keycode;
1096         input->repeat.time = timestamp;
1097 
1098         /* Delete this timer if there is still one */
1099         if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1100         input->repeat.timer = NULL;
1101 
1102         if (!input->repeat.timer)
1103           {
1104              input->repeat.repeating = EINA_FALSE;
1105              input->repeat.timer =
1106                ecore_timer_add(input->repeat.delay, _keyboard_cb_repeat, input);
1107           }
1108      }
1109 }
1110 
1111 static void
_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)1112 _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)
1113 {
1114    Ecore_Wl2_Input *input;
1115    xkb_mod_mask_t mask;
1116 
1117    input = data;
1118    if (!input) return;
1119 
1120    /* skip PC style modifiers if we have no keymap */
1121    if (!input->xkb.keymap) return;
1122 
1123    xkb_state_update_mask(input->xkb.state,
1124                          depressed, latched, locked, 0, 0, group);
1125 
1126    mask =
1127      xkb_state_serialize_mods(input->xkb.state,
1128                               XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
1129 
1130    /* reset modifiers to default */
1131    input->keyboard.modifiers = 0;
1132 
1133    if (mask & input->xkb.control_mask)
1134      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CTRL;
1135    if (mask & input->xkb.alt_mask)
1136      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALT;
1137    if (mask & input->xkb.shift_mask)
1138      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
1139    if (mask & input->xkb.win_mask)
1140      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_WIN;
1141    if (mask & input->xkb.altgr_mask)
1142      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
1143    if (mask & input->xkb.scroll_mask)
1144      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_SCROLL;
1145    if (mask & input->xkb.num_mask)
1146      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_NUM;
1147    if (mask & input->xkb.caps_mask)
1148      input->keyboard.modifiers |= ECORE_EVENT_MODIFIER_CAPS;
1149 
1150 
1151    mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_LOCKED);
1152    if (mask & input->xkb.scroll_mask)
1153      input->keyboard.modifiers |= ECORE_EVENT_LOCK_SCROLL;
1154    if (mask & input->xkb.num_mask)
1155      input->keyboard.modifiers |= ECORE_EVENT_LOCK_NUM;
1156    if (mask & input->xkb.caps_mask)
1157      input->keyboard.modifiers |= ECORE_EVENT_LOCK_CAPS;
1158 }
1159 
1160 static void
_keyboard_cb_repeat_setup(void * data,struct wl_keyboard * keyboard EINA_UNUSED,int32_t rate,int32_t delay)1161 _keyboard_cb_repeat_setup(void *data, struct wl_keyboard *keyboard EINA_UNUSED, int32_t rate, int32_t delay)
1162 {
1163    Ecore_Wl2_Input *input;
1164    Ecore_Wl2_Event_Seat_Keyboard_Repeat_Changed *ev;
1165 
1166    input = data;
1167    if (!input) return;
1168 
1169    if (rate == 0)
1170      {
1171         input->repeat.enabled = EINA_FALSE;
1172         return;
1173      }
1174 
1175    input->repeat.enabled = EINA_TRUE;
1176    if (!input->repeat.changed)
1177      {
1178         input->repeat.rate = (1.0 / rate);
1179         input->repeat.delay = (delay / 1000.0);
1180      }
1181    ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed));
1182    if (ev)
1183      {
1184         ev->id = input->id;
1185         ev->display = input->display;
1186         ev->display->refs++;
1187         ecore_event_add(ECORE_WL2_EVENT_SEAT_KEYBOARD_REPEAT_CHANGED, ev,
1188                         _display_event_free, ev->display);
1189      }
1190 }
1191 
1192 static const struct wl_keyboard_listener _keyboard_listener =
1193 {
1194    _keyboard_cb_keymap,
1195    _keyboard_cb_enter,
1196    _keyboard_cb_leave,
1197    _keyboard_cb_key,
1198    _keyboard_cb_modifiers,
1199    _keyboard_cb_repeat_setup
1200 };
1201 
1202 static void
_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)1203 _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)
1204 {
1205    Ecore_Wl2_Input *input;
1206    Ecore_Wl2_Window *window;
1207 
1208    input = data;
1209    if (!input) return;
1210 
1211    /* find the window which this surface belongs to */
1212    window = _ecore_wl2_display_window_surface_find(input->display, surface);
1213    if (!window) return;
1214 
1215    input->focus.touch = window;
1216    input->timestamp = timestamp;
1217    input->grab.touch_count++;
1218 
1219    _pointer_cb_enter(data, NULL, serial, surface, x, y);
1220 
1221    if ((!input->grab.window) && (input->focus.touch) && input->grab.touch_count == 1)
1222      {
1223         _ecore_wl2_input_grab(input, input->focus.touch, BTN_LEFT);
1224         input->grab.timestamp = timestamp;
1225      }
1226 
1227    _ecore_wl2_input_mouse_down_send(input, input->focus.touch, id,
1228                                     BTN_LEFT, timestamp);
1229 }
1230 
1231 static void
_touch_cb_up(void * data,struct wl_touch * touch EINA_UNUSED,unsigned int serial,unsigned int timestamp,int id)1232 _touch_cb_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id)
1233 {
1234    Ecore_Wl2_Input *input;
1235 
1236    input = data;
1237    if (!input) return;
1238    EINA_SAFETY_ON_NULL_RETURN(input->focus.touch); //if this is happening, then we are getting up events in a invalid state
1239 
1240    input->timestamp = timestamp;
1241    input->display->serial = serial;
1242 
1243    _ecore_wl2_input_mouse_up_send(input, input->focus.touch, id,
1244                                   BTN_LEFT, timestamp);
1245 
1246    if (input->grab.count) input->grab.count--;
1247    if (input->grab.touch_count) input->grab.touch_count--;
1248    if ((input->grab.window) && (input->grab.button == BTN_LEFT) &&
1249        (!input->grab.count) && !input->grab.touch_count)
1250      _ecore_wl2_input_ungrab(input);
1251 
1252    if (input->grab.touch_count == 0) input->focus.touch = NULL;
1253 
1254 }
1255 
1256 static void
_touch_cb_motion(void * data,struct wl_touch * touch EINA_UNUSED,unsigned int timestamp,int id,wl_fixed_t x,wl_fixed_t y)1257 _touch_cb_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id, wl_fixed_t x, wl_fixed_t y)
1258 {
1259    Ecore_Wl2_Input *input;
1260 
1261    input = data;
1262    if (!input) return;
1263    if (!input->focus.touch) return;
1264 
1265    input->timestamp = timestamp;
1266    input->pointer.sx = wl_fixed_to_int(x);
1267    input->pointer.sy = wl_fixed_to_int(y);
1268 
1269    _ecore_wl2_input_mouse_move_send(input, input->focus.touch, id);
1270 }
1271 
1272 static void
_touch_cb_frame(void * data EINA_UNUSED,struct wl_touch * touch EINA_UNUSED)1273 _touch_cb_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED)
1274 {
1275 
1276 }
1277 
1278 static void
_touch_cb_cancel(void * data EINA_UNUSED,struct wl_touch * tough EINA_UNUSED)1279 _touch_cb_cancel(void *data EINA_UNUSED, struct wl_touch *tough EINA_UNUSED)
1280 {
1281 
1282 }
1283 
1284 static const struct wl_touch_listener _touch_listener =
1285 {
1286    _touch_cb_down,
1287    _touch_cb_up,
1288    _touch_cb_motion,
1289    _touch_cb_frame,
1290    _touch_cb_cancel,
1291    NULL, // XXX: FIXME: add shape
1292    NULL, // XXX: FIXME: add orientation
1293 };
1294 
1295 static void
_data_cb_offer(void * data,struct wl_data_device * data_device EINA_UNUSED,struct wl_data_offer * offer)1296 _data_cb_offer(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
1297 {
1298    Ecore_Wl2_Input *input;
1299 
1300    input = data;
1301    if (!input) return;
1302 
1303    _ecore_wl2_dnd_add(input, offer);
1304 }
1305 
1306 static void
_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)1307 _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)
1308 {
1309    Ecore_Wl2_Input *input;
1310 
1311    input = data;
1312    if (!input) return;
1313 
1314    _ecore_wl2_dnd_enter(input, offer, surface,
1315                         wl_fixed_to_int(x), wl_fixed_to_int(y), serial);
1316 }
1317 
1318 static void
_data_cb_leave(void * data,struct wl_data_device * data_device EINA_UNUSED)1319 _data_cb_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
1320 {
1321    Ecore_Wl2_Input *input;
1322 
1323    input = data;
1324    if (!input) return;
1325 
1326    _ecore_wl2_dnd_leave(input);
1327 }
1328 
1329 static void
_data_cb_motion(void * data,struct wl_data_device * data_device EINA_UNUSED,uint32_t serial,wl_fixed_t x,wl_fixed_t y)1330 _data_cb_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, uint32_t serial, wl_fixed_t x, wl_fixed_t y)
1331 {
1332    Ecore_Wl2_Input *input;
1333 
1334    input = data;
1335    if (!input) return;
1336 
1337    _ecore_wl2_dnd_motion(input, wl_fixed_to_int(x),
1338                          wl_fixed_to_int(y), serial);
1339 }
1340 
1341 static void
_data_cb_drop(void * data,struct wl_data_device * data_device EINA_UNUSED)1342 _data_cb_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
1343 {
1344    Ecore_Wl2_Input *input;
1345 
1346    input = data;
1347    if (!input) return;
1348 
1349    _ecore_wl2_dnd_drop(input);
1350 }
1351 
1352 static void
_data_cb_selection(void * data,struct wl_data_device * data_device EINA_UNUSED,struct wl_data_offer * offer)1353 _data_cb_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
1354 {
1355    Ecore_Wl2_Input *input;
1356 
1357    input = data;
1358    if (!input) return;
1359 
1360    _ecore_wl2_dnd_selection(input, offer);
1361 }
1362 
1363 static const struct wl_data_device_listener _data_listener =
1364 {
1365    _data_cb_offer,
1366    _data_cb_enter,
1367    _data_cb_leave,
1368    _data_cb_motion,
1369    _data_cb_drop,
1370    _data_cb_selection
1371 };
1372 
1373 static void
_seat_cb_capabilities(void * data,struct wl_seat * seat,enum wl_seat_capability caps)1374 _seat_cb_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
1375 {
1376    Ecore_Wl2_Event_Seat_Capabilities *ev;
1377    Ecore_Wl2_Input *input;
1378 
1379    input = data;
1380    if (!input) return;
1381 
1382    if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->wl.pointer))
1383      {
1384         input->wl.pointer = wl_seat_get_pointer(seat);
1385         wl_pointer_set_user_data(input->wl.pointer, input);
1386         wl_pointer_add_listener(input->wl.pointer, &_pointer_listener, input);
1387      }
1388    else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->wl.pointer))
1389      {
1390 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
1391         if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1392           wl_pointer_release(input->wl.pointer);
1393         else
1394 #endif
1395           wl_pointer_destroy(input->wl.pointer);
1396         input->wl.pointer = NULL;
1397      }
1398 
1399    if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->wl.keyboard))
1400      {
1401         input->wl.keyboard = wl_seat_get_keyboard(seat);
1402         wl_keyboard_set_user_data(input->wl.keyboard, input);
1403         wl_keyboard_add_listener(input->wl.keyboard, &_keyboard_listener, input);
1404      }
1405    else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->wl.keyboard))
1406      {
1407 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1408         if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1409           wl_keyboard_release(input->wl.keyboard);
1410         else
1411 #endif
1412           wl_keyboard_destroy(input->wl.keyboard);
1413         input->wl.keyboard = NULL;
1414      }
1415 
1416    if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->wl.touch))
1417      {
1418         input->wl.touch = wl_seat_get_touch(seat);
1419         wl_touch_set_user_data(input->wl.touch, input);
1420         wl_touch_add_listener(input->wl.touch, &_touch_listener, input);
1421      }
1422    else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->wl.touch))
1423      {
1424 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1425         if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1426           wl_touch_release(input->wl.touch);
1427         else
1428 #endif
1429           wl_touch_destroy(input->wl.touch);
1430         input->wl.touch = NULL;
1431      }
1432    ecore_wl2_display_flush(input->display);
1433 
1434    ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Capabilities));
1435    EINA_SAFETY_ON_NULL_RETURN(ev);
1436 
1437    ev->id = input->id;
1438    ev->pointer_enabled = !!(caps & WL_SEAT_CAPABILITY_POINTER);
1439    ev->keyboard_enabled = !!(caps & WL_SEAT_CAPABILITY_KEYBOARD);
1440    ev->touch_enabled = !!(caps & WL_SEAT_CAPABILITY_TOUCH);
1441    ev->display = input->display;
1442    ev->display->refs++;
1443 
1444    ecore_event_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED, ev,
1445                    _display_event_free, ev->display);
1446 }
1447 
1448 static void
_cb_seat_event_free(void * data EINA_UNUSED,void * event)1449 _cb_seat_event_free(void *data EINA_UNUSED, void *event)
1450 {
1451    Ecore_Wl2_Event_Seat_Name *ev;
1452 
1453    ev = event;
1454    eina_stringshare_del(ev->name);
1455    ecore_wl2_display_disconnect(ev->display);
1456    free(ev);
1457 }
1458 
1459 static void
_seat_cb_name(void * data,struct wl_seat * seat EINA_UNUSED,const char * name)1460 _seat_cb_name(void *data, struct wl_seat *seat EINA_UNUSED, const char *name)
1461 {
1462    Ecore_Wl2_Event_Seat_Name *ev;
1463    Ecore_Wl2_Input *input;
1464 
1465    input = data;
1466    eina_stringshare_replace(&input->name, name);
1467 
1468    ev = calloc(1, sizeof(Ecore_Wl2_Event_Seat_Name));
1469    EINA_SAFETY_ON_NULL_RETURN(ev);
1470 
1471    ev->id = input->id;
1472    ev->name = eina_stringshare_add(name);
1473    ev->display = input->display;
1474    ev->display->refs++;
1475 
1476    ecore_event_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED, ev,
1477                    _cb_seat_event_free, NULL);
1478 }
1479 
1480 static const struct wl_seat_listener _seat_listener =
1481 {
1482    _seat_cb_capabilities,
1483    _seat_cb_name,
1484 };
1485 
1486 static void
_ecore_wl2_input_cursor_setup(Ecore_Wl2_Input * input)1487 _ecore_wl2_input_cursor_setup(Ecore_Wl2_Input *input)
1488 {
1489    char *tmp;
1490 
1491    input->cursor.size = 32;
1492    tmp = getenv("ECORE_WL_CURSOR_SIZE");
1493    if (tmp) input->cursor.size = atoi(tmp);
1494 
1495    if (!input->cursor.name)
1496      input->cursor.name = eina_stringshare_add("left_ptr");
1497 }
1498 
1499 Eina_Bool
_ecore_wl2_input_cursor_update(void * data)1500 _ecore_wl2_input_cursor_update(void *data)
1501 {
1502    Ecore_Wl2_Input *input;
1503 
1504    input = data;
1505    if (!input) return EINA_FALSE;
1506 
1507    if (input->wl.pointer)
1508      wl_pointer_set_cursor(input->wl.pointer, input->pointer.enter_serial,
1509                            input->cursor.surface,
1510                            input->cursor.hot_x, input->cursor.hot_y);
1511    ecore_wl2_display_flush(input->display);
1512 
1513    return ECORE_CALLBACK_RENEW;
1514 }
1515 
1516 static void
_ecore_wl2_devices_free(Ecore_Wl2_Input_Devices * devices)1517 _ecore_wl2_devices_free(Ecore_Wl2_Input_Devices *devices)
1518 {
1519    if (devices->seat_dev)
1520      efl_unref(devices->seat_dev);
1521    if (devices->pointer_dev)
1522      efl_unref(devices->pointer_dev);
1523    if (devices->keyboard_dev)
1524      efl_unref(devices->keyboard_dev);
1525    if (devices->touch_dev)
1526      efl_unref(devices->touch_dev);
1527 
1528    free(devices);
1529 }
1530 
1531 static Eina_Bool
_ecore_wl2_cb_device_event(void * data,int type,void * event)1532 _ecore_wl2_cb_device_event(void *data, int type, void *event)
1533 {
1534    Ecore_Wl2_Input_Devices *devs, *devices = NULL;;
1535    Ecore_Wl2_Event_Device *ev = event;
1536    Ecore_Wl2_Input *input = data;
1537    Eina_List *l;
1538 
1539    if (input->id != ev->seat_id)
1540      return ECORE_CALLBACK_PASS_ON;
1541 
1542    EINA_LIST_FOREACH(input->devices_list, l, devs)
1543      {
1544         if (devs->window == ev->window)
1545           {
1546              devices = devs;
1547              break;
1548           }
1549      }
1550 
1551    if (type == ECORE_WL2_EVENT_DEVICE_ADDED)
1552      {
1553         if (!devices)
1554           {
1555              devices = calloc(1, sizeof(Ecore_Wl2_Input_Devices));
1556              EINA_SAFETY_ON_NULL_RETURN_VAL(devices, ECORE_CALLBACK_PASS_ON);
1557              input->devices_list =
1558                eina_list_append(input->devices_list, devices);
1559              devices->window = ev->window;
1560           }
1561 
1562         if (ev->type == ECORE_WL2_DEVICE_TYPE_POINTER)
1563           devices->pointer_dev = efl_ref(ev->dev);
1564         else if (ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD)
1565           devices->keyboard_dev = efl_ref(ev->dev);
1566         else if (ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH)
1567           devices->touch_dev = efl_ref(ev->dev);
1568         else if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
1569           devices->seat_dev = efl_ref(ev->dev);
1570 
1571         return ECORE_CALLBACK_PASS_ON;
1572      }
1573 
1574    if (!devices)
1575      return ECORE_CALLBACK_PASS_ON;
1576 
1577    if (ev->type == ECORE_WL2_DEVICE_TYPE_SEAT)
1578      {
1579         input->devices_list =
1580           eina_list_remove(input->devices_list, devices);
1581         _ecore_wl2_devices_free(devices);
1582         return ECORE_CALLBACK_PASS_ON;
1583      }
1584 
1585    if ((ev->type == ECORE_WL2_DEVICE_TYPE_POINTER) &&
1586        (devices->pointer_dev == ev->dev))
1587      {
1588         efl_unref(devices->pointer_dev);
1589         devices->pointer_dev = NULL;
1590      }
1591    else if ((ev->type == ECORE_WL2_DEVICE_TYPE_KEYBOARD) &&
1592             (devices->keyboard_dev == ev->dev))
1593      {
1594         efl_unref(devices->keyboard_dev);
1595         devices->keyboard_dev = NULL;
1596      }
1597    else if ((ev->type == ECORE_WL2_DEVICE_TYPE_TOUCH) &&
1598             (devices->touch_dev == ev->dev))
1599      {
1600         efl_unref(devices->touch_dev);
1601         devices->touch_dev = NULL;
1602      }
1603 
1604    return ECORE_CALLBACK_PASS_ON;
1605 }
1606 
1607 void
_ecore_wl2_input_add(Ecore_Wl2_Display * display,unsigned int id,unsigned int version)1608 _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int version)
1609 {
1610    Ecore_Wl2_Input *input;
1611 
1612    input = calloc(1, sizeof(Ecore_Wl2_Input));
1613    if (!input) return;
1614 
1615    input->id = id;
1616    input->display = display;
1617    input->seat_version = version;
1618    input->repeat.rate = 0.025;
1619    input->repeat.delay = 0.4;
1620    input->repeat.enabled = EINA_TRUE;
1621    input->repeat.changed = EINA_FALSE;
1622 
1623    wl_array_init(&input->data.selection.types);
1624    wl_array_init(&input->data.drag.types);
1625 
1626    /* setup cursor size and theme */
1627    _ecore_wl2_input_cursor_setup(input);
1628 
1629    input->wl.seat =
1630      wl_registry_bind(display->wl.registry, id, &wl_seat_interface, 4);
1631 
1632    display->inputs =
1633      eina_inlist_append(display->inputs, EINA_INLIST_GET(input));
1634 
1635    wl_seat_add_listener(input->wl.seat, &_seat_listener, input);
1636    wl_seat_set_user_data(input->wl.seat, input);
1637 
1638    input->dev_add_handler =
1639      ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_ADDED,
1640                              _ecore_wl2_cb_device_event, input);
1641 
1642    input->dev_remove_handler =
1643      ecore_event_handler_add(ECORE_WL2_EVENT_DEVICE_REMOVED,
1644                              _ecore_wl2_cb_device_event, input);
1645 
1646    if (!display->wl.data_device_manager) return;
1647 
1648    input->data.device =
1649      wl_data_device_manager_get_data_device(display->wl.data_device_manager,
1650                                             input->wl.seat);
1651    wl_data_device_add_listener(input->data.device, &_data_listener, input);
1652 }
1653 
1654 void
_ecore_wl2_input_del(Ecore_Wl2_Input * input)1655 _ecore_wl2_input_del(Ecore_Wl2_Input *input)
1656 {
1657    Ecore_Wl2_Input_Devices *devices;
1658    Ecore_Wl2_Display *display;
1659    Eina_Inlist *l = NULL;
1660    Ecore_Wl2_Mouse_Down_Info *info = NULL;
1661    Ecore_Wl2_Window *window;
1662 
1663    if (!input) return;
1664 
1665    display = input->display;
1666 
1667    l = _ecore_wl2_mouse_down_info_list;
1668    while (l)
1669      {
1670         info = EINA_INLIST_CONTAINER_GET(l, Ecore_Wl2_Mouse_Down_Info);
1671         l = eina_inlist_remove(l, l);
1672         free(info);
1673      }
1674    _ecore_wl2_mouse_down_info_list = NULL;
1675 
1676    if (input->repeat.timer) ecore_timer_del(input->repeat.timer);
1677 
1678    if (input->cursor.name) eina_stringshare_del(input->cursor.name);
1679 
1680    if (input->data.selection.types.data)
1681      {
1682         char **t;
1683 
1684         wl_array_for_each(t, &input->data.selection.types)
1685           free(*t);
1686 
1687         wl_array_release(&input->data.selection.types);
1688      }
1689    if (input->data.drag.types.data)
1690      {
1691         char **t;
1692 
1693         wl_array_for_each(t, &input->data.drag.types)
1694           free(*t);
1695 
1696         wl_array_release(&input->data.drag.types);
1697      }
1698 
1699    if (input->data.selection.source)
1700      wl_data_source_destroy(input->data.selection.source);
1701    if (input->data.drag.source)
1702      wl_data_source_destroy(input->data.drag.source);
1703    if (input->drag.offer) _ecore_wl2_offer_unref(input->drag.offer);
1704    if (input->selection.offer) _ecore_wl2_offer_unref(input->selection.offer);
1705    if (input->data.device) wl_data_device_destroy(input->data.device);
1706 
1707    if (input->xkb.state) xkb_state_unref(input->xkb.state);
1708    if (input->xkb.maskless_state) xkb_state_unref(input->xkb.maskless_state);
1709    if (input->xkb.keymap) xkb_map_unref(input->xkb.keymap);
1710    if (input->xkb.compose_table)
1711      xkb_compose_table_unref(input->xkb.compose_table);
1712    if (input->xkb.compose_state)
1713      xkb_compose_state_unref(input->xkb.compose_state);
1714 
1715    if (input->wl.seat) wl_seat_destroy(input->wl.seat);
1716 
1717    ecore_event_handler_del(input->dev_add_handler);
1718    ecore_event_handler_del(input->dev_remove_handler);
1719    EINA_LIST_FREE(input->devices_list, devices)
1720       _ecore_wl2_devices_free(devices);
1721 
1722    display->inputs =
1723      eina_inlist_remove(display->inputs, EINA_INLIST_GET(input));
1724 
1725    EINA_INLIST_FOREACH(display->windows, window)
1726      if (window->grab == input) window->grab = NULL;
1727 
1728    eina_stringshare_replace(&input->name, NULL);
1729    free(input);
1730 }
1731 
1732 void
_ecore_wl2_input_cursor_set(Ecore_Wl2_Input * input,const char * cursor)1733 _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor)
1734 {
1735    eina_stringshare_replace(&input->cursor.name, cursor);
1736    if (!cursor) eina_stringshare_replace(&input->cursor.name, "left_ptr");
1737 }
1738 
1739 void
_ecore_wl2_input_window_remove(Ecore_Wl2_Input * input,Ecore_Wl2_Window * window)1740 _ecore_wl2_input_window_remove(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window)
1741 {
1742    Ecore_Wl2_Input_Devices *devices;
1743    Eina_List *l, *l_next;
1744 
1745    if ((input->focus.pointer) &&
1746        (input->focus.pointer == window))
1747      input->focus.pointer = NULL;
1748    if ((input->focus.keyboard) &&
1749        (input->focus.keyboard == window))
1750      {
1751         input->focus.keyboard = NULL;
1752         ecore_timer_del(input->repeat.timer);
1753         input->repeat.timer = NULL;
1754      }
1755 
1756    EINA_LIST_FOREACH_SAFE(input->devices_list, l, l_next, devices)
1757       if (devices->window == window)
1758         {
1759            _ecore_wl2_devices_free(devices);
1760            input->devices_list = eina_list_remove_list(input->devices_list, l);
1761         }
1762 }
1763 
1764 EAPI struct wl_seat *
ecore_wl2_input_seat_get(Ecore_Wl2_Input * input)1765 ecore_wl2_input_seat_get(Ecore_Wl2_Input *input)
1766 {
1767    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
1768    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
1769    return input->wl.seat;
1770 }
1771 
1772 EAPI Ecore_Wl2_Seat_Capabilities
ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input * input)1773 ecore_wl2_input_seat_capabilities_get(Ecore_Wl2_Input *input)
1774 {
1775    Ecore_Wl2_Seat_Capabilities cap = ECORE_WL2_SEAT_CAPABILITIES_NONE;
1776 
1777    EINA_SAFETY_ON_NULL_RETURN_VAL(input, cap);
1778    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
1779    if (input->wl.keyboard)
1780      cap |= ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD;
1781    if (input->wl.pointer)
1782      cap |= ECORE_WL2_SEAT_CAPABILITIES_POINTER;
1783    if (input->wl.touch)
1784      cap |= ECORE_WL2_SEAT_CAPABILITIES_TOUCH;
1785    return cap;
1786 }
1787 
1788 EAPI Eina_Stringshare *
ecore_wl2_input_name_get(Ecore_Wl2_Input * input)1789 ecore_wl2_input_name_get(Ecore_Wl2_Input *input)
1790 {
1791    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
1792    return input->name;
1793 }
1794 
1795 EAPI unsigned int
ecore_wl2_input_seat_id_get(Ecore_Wl2_Input * input)1796 ecore_wl2_input_seat_id_get(Ecore_Wl2_Input *input)
1797 {
1798    EINA_SAFETY_ON_NULL_RETURN_VAL(input, 0);
1799    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, 0);
1800    return input->id;
1801 }
1802 
1803 EAPI Ecore_Wl2_Display *
ecore_wl2_input_display_get(const Ecore_Wl2_Input * input)1804 ecore_wl2_input_display_get(const Ecore_Wl2_Input *input)
1805 {
1806    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
1807    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
1808    return input->display;
1809 }
1810 
1811 EAPI struct xkb_keymap *
ecore_wl2_input_keymap_get(const Ecore_Wl2_Input * input)1812 ecore_wl2_input_keymap_get(const Ecore_Wl2_Input *input)
1813 {
1814    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
1815    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, NULL);
1816    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, NULL);
1817    return input->xkb.keymap;
1818 }
1819 
1820 EAPI Eina_Bool
ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input * input,double rate,double delay)1821 ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input *input, double rate, double delay)
1822 {
1823    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
1824    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
1825    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
1826    input->repeat.rate = rate;
1827    input->repeat.delay = delay;
1828    input->repeat.changed = EINA_TRUE;
1829    return input->repeat.enabled;
1830 }
1831 
1832 EAPI Eina_Bool
ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input * input,double * rate,double * delay)1833 ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay)
1834 {
1835    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
1836    EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
1837    EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE);
1838    if (rate) *rate = input->repeat.rate;
1839    if (delay) *delay = input->repeat.delay;
1840    return input->repeat.enabled;
1841 }
1842 
1843 EAPI void
ecore_wl2_input_pointer_set(Ecore_Wl2_Input * input,struct wl_surface * surface,int hot_x,int hot_y)1844 ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y)
1845 {
1846    EINA_SAFETY_ON_NULL_RETURN(input);
1847 
1848    input->cursor.surface = surface;
1849    input->cursor.hot_x = hot_x;
1850    input->cursor.hot_y = hot_y;
1851 
1852    _ecore_wl2_input_cursor_update(input);
1853 }
1854 
1855 EAPI void
ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input * input,const char * cursor)1856 ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor)
1857 {
1858    EINA_SAFETY_ON_NULL_RETURN(input);
1859    _ecore_wl2_input_cursor_set(input, cursor);
1860 }
1861 
1862 EAPI Eina_Bool
ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input * input,int * x,int * y)1863 ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int *x, int *y)
1864 {
1865    EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
1866 
1867    if (x) *x = 0;
1868    if (y) *y = 0;
1869    if (!input->wl.pointer) return EINA_FALSE;
1870    if (x) *x = input->pointer.sx;
1871    if (y) *y = input->pointer.sy;
1872    return EINA_TRUE;
1873 }
1874 
1875 EAPI Ecore_Wl2_Input *
ecore_wl2_input_default_input_get(const Ecore_Wl2_Display * ewd)1876 ecore_wl2_input_default_input_get(const Ecore_Wl2_Display *ewd)
1877 {
1878    Ecore_Wl2_Input *input;
1879 
1880    EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
1881    EINA_SAFETY_ON_NULL_RETURN_VAL(ewd->inputs, NULL);
1882 
1883    input = ecore_wl2_display_input_find_by_name(ewd, "seat0");
1884    if (!input) input = ecore_wl2_display_input_find_by_name(ewd, "default");
1885 
1886    return input;
1887 }
1888