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