TIVI-2250: Fix crasher bug when using a system witout a mouse
[platform/upstream/ecore.git] / src / lib / ecore_wayland / ecore_wl_input.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 /**
6  * NB: Events that receive a 'serial' instead of timestamp
7  * 
8  * input_device_attach (for pointer image)
9  * input_device_button_event (button press/release)
10  * input_device_key_press
11  * input_device_pointer_enter
12  * input_device_pointer_leave
13  * input_device_keyboard_enter
14  * input_device_keyboard_leave
15  * input_device_touch_down
16  * input_device_touch_up
17  * 
18  **/
19
20 #include "ecore_wl_private.h"
21 #include <sys/mman.h>
22 #include <sys/timerfd.h>
23
24 /* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... 
25  *        What about other OSs ?? */
26 #ifdef __linux__
27 # include <linux/input.h>
28 #else
29 # define BTN_LEFT 0x110
30 # define BTN_RIGHT 0x111
31 # define BTN_MIDDLE 0x112
32 # define BTN_SIDE 0x113
33 # define BTN_EXTRA 0x114
34 # define BTN_FORWARD 0x115
35 # define BTN_BACK 0x116
36 #endif
37
38 #define MOD_SHIFT_MASK 0x01
39 #define MOD_ALT_MASK 0x02
40 #define MOD_CONTROL_MASK 0x04
41
42 Ecore_Wl_Dnd *glb_dnd = NULL;
43
44 /* local function prototypes */
45 static void _ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps);
46
47 static void _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy);
48 static void _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, struct wl_surface *surface);
49 static void _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy);
50 static void _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state);
51 static void _ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int timestamp, unsigned int axis, wl_fixed_t value);
52 static void _ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp __UNUSED__);
53 static void _ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int format, int fd, unsigned int size);
54 static void _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface, struct wl_array *keys __UNUSED__);
55 static void _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface);
56 static void _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int key, unsigned int state);
57 static void _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial __UNUSED__, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group);
58 static Eina_Bool _ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler __UNUSED__);
59 static void _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y);
60 static void _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, int id __UNUSED__);
61 static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch __UNUSED__, unsigned int timestamp, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y);
62 static void _ecore_wl_input_cb_touch_frame(void *data __UNUSED__, struct wl_touch *touch __UNUSED__);
63 static void _ecore_wl_input_cb_touch_cancel(void *data __UNUSED__, struct wl_touch *touch __UNUSED__);
64 static void _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer);
65 static void _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer);
66 static void _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device);
67 static void _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y);
68 static void _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device);
69 static void _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer);
70
71 static void _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp);
72 static void _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp);
73 static void _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp);
74 static void _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input __UNUSED__, Ecore_Wl_Window *win, unsigned int timestamp);
75 static void _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input __UNUSED__, Ecore_Wl_Window *win, unsigned int timestamp);
76 static void _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button, unsigned int timestamp);
77 static void _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button, unsigned int timestamp);
78 static void _ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int value, unsigned int timestamp);
79
80 /* static int _ecore_wl_input_keysym_to_string(unsigned int symbol, char *buffer, int len); */
81
82 /* wayland interfaces */
83 static const struct wl_pointer_listener pointer_listener = 
84 {
85    _ecore_wl_input_cb_pointer_enter,
86    _ecore_wl_input_cb_pointer_leave,
87    _ecore_wl_input_cb_pointer_motion,
88    _ecore_wl_input_cb_pointer_button,
89    _ecore_wl_input_cb_pointer_axis,
90 };
91
92 static const struct wl_keyboard_listener keyboard_listener = 
93 {
94    _ecore_wl_input_cb_keyboard_keymap,
95    _ecore_wl_input_cb_keyboard_enter,
96    _ecore_wl_input_cb_keyboard_leave,
97    _ecore_wl_input_cb_keyboard_key,
98    _ecore_wl_input_cb_keyboard_modifiers,
99 };
100
101 static const struct wl_touch_listener touch_listener = 
102 {
103    _ecore_wl_input_cb_touch_down,
104    _ecore_wl_input_cb_touch_up,
105    _ecore_wl_input_cb_touch_motion,
106    _ecore_wl_input_cb_touch_frame,
107    _ecore_wl_input_cb_touch_cancel
108 };
109
110 static const struct wl_seat_listener _ecore_wl_seat_listener = 
111 {
112    _ecore_wl_input_seat_handle_capabilities,
113 };
114
115 static const struct wl_data_device_listener _ecore_wl_data_listener = 
116 {
117    _ecore_wl_input_cb_data_offer,
118    _ecore_wl_input_cb_data_enter,
119    _ecore_wl_input_cb_data_leave,
120    _ecore_wl_input_cb_data_motion,
121    _ecore_wl_input_cb_data_drop,
122    _ecore_wl_input_cb_data_selection
123 };
124
125 static const struct wl_callback_listener _ecore_wl_pointer_surface_listener = 
126 {
127    _ecore_wl_input_cb_pointer_frame
128 };
129
130 /* local variables */
131 static int _pointer_x, _pointer_y;
132
133 EAPI void 
134 ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button)
135 {
136    LOGFN(__FILE__, __LINE__, __FUNCTION__);
137
138    if (!input) return;
139    input->grab = win;
140    input->grab_button = button;
141 }
142
143 EAPI void 
144 ecore_wl_input_ungrab(Ecore_Wl_Input *input)
145 {
146    LOGFN(__FILE__, __LINE__, __FUNCTION__);
147
148    if (!input) return;
149    input->grab = NULL;
150    input->grab_button = 0;
151 }
152
153 /* NB: This function should be called just before shell move and shell resize
154  * functions. Those requests will trigger a mouse/touch implicit grab on the
155  * compositor that will prevent the respective mouse/touch up events being
156  * released after the end of the operation. This function checks if such grab
157  * is in place for those windows and, if so, emit the respective mouse up
158  * event. It's a workaround to the fact that wayland doesn't inform the
159  * application about this move or resize grab being finished.
160  */
161 void
162 _ecore_wl_input_grab_release(Ecore_Wl_Input *input, Ecore_Wl_Window *win)
163 {
164    LOGFN(__FILE__, __LINE__, __FUNCTION__);
165
166    if (!input) return;
167    if (input->grab != win) return;
168
169    _ecore_wl_input_mouse_up_send(input, input->grab,
170                                  input->grab_button, input->grab_timestamp);
171    ecore_wl_input_ungrab(input);
172 }
173
174 EAPI void
175 ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_surface *surface, int hot_x, int hot_y)
176 {
177    LOGFN(__FILE__, __LINE__, __FUNCTION__);
178
179    if (input)
180      wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, 
181                            surface, hot_x, hot_y);
182 }
183
184 EAPI void
185 ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name)
186 {
187    struct wl_cursor_image *cursor_image;
188    struct wl_buffer *buffer;
189    struct wl_cursor *cursor;
190
191    LOGFN(__FILE__, __LINE__, __FUNCTION__);
192
193    if (!input) return;
194
195    eina_stringshare_replace(&input->cursor_name, cursor_name);
196
197    /* No cursor. Set to default Left Pointer */
198    if (!cursor_name) 
199      eina_stringshare_replace(&input->cursor_name, "left_ptr");
200
201    /* try to get this cursor from the theme */
202    if (!(cursor = ecore_wl_cursor_get(input->cursor_name)))
203      {
204         /* if the theme does not have this cursor, default to left pointer */
205         if (!(cursor = ecore_wl_cursor_get("left_ptr")))
206           return;
207      }
208
209    if ((!cursor->images) || (!cursor->images[0]))
210      {
211         ecore_wl_input_pointer_set(input, NULL, 0, 0);
212         return;
213      }
214
215    cursor_image = cursor->images[0];
216    if ((buffer = wl_cursor_image_get_buffer(cursor_image)))
217      {
218         ecore_wl_input_pointer_set(input, input->cursor_surface, 
219                                    cursor_image->hotspot_x, 
220                                    cursor_image->hotspot_y);
221         wl_surface_attach(input->cursor_surface, buffer, 0, 0);
222         wl_surface_damage(input->cursor_surface, 0, 0, 
223                           cursor_image->width, cursor_image->height);
224         wl_surface_commit(input->cursor_surface);
225
226         if (!input->cursor_frame_cb)
227           _ecore_wl_input_cb_pointer_frame(input, NULL, 0);
228      }
229 }
230
231 EAPI void
232 ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input)
233 {
234    LOGFN(__FILE__, __LINE__, __FUNCTION__);
235
236    if (!input) return;
237
238    /* Restore to default wayland cursor */
239    ecore_wl_input_cursor_from_name_set(input, "left_ptr");
240 }
241
242 /* local functions */
243 void 
244 _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id)
245 {
246    Ecore_Wl_Input *input;
247
248    LOGFN(__FILE__, __LINE__, __FUNCTION__);
249
250    if (!(input = malloc(sizeof(Ecore_Wl_Input)))) return;
251
252    memset(input, 0, sizeof(Ecore_Wl_Input));
253
254    input->display = ewd;
255    input->pointer_focus = NULL;
256    input->keyboard_focus = NULL;
257
258    input->seat = 
259      wl_registry_bind(ewd->wl.registry, id, &wl_seat_interface, 1);
260    wl_list_insert(ewd->inputs.prev, &input->link);
261
262    wl_seat_add_listener(input->seat, 
263                         &_ecore_wl_seat_listener, input);
264    wl_seat_set_user_data(input->seat, input);
265
266    input->data_device = 
267      wl_data_device_manager_get_data_device(ewd->wl.data_device_manager, 
268                                             input->seat);
269    wl_data_device_add_listener(input->data_device, 
270                                &_ecore_wl_data_listener, input);
271    input->cursor_surface = 
272      wl_compositor_create_surface(_ecore_wl_disp->wl.compositor);
273
274    input->repeat.timerfd = 
275      timerfd_create(CLOCK_MONOTONIC, (TFD_CLOEXEC | TFD_NONBLOCK));
276
277    input->repeat.hdlr = 
278      ecore_main_fd_handler_add(input->repeat.timerfd, ECORE_FD_READ, 
279                                _ecore_wl_input_cb_keyboard_repeat, input, 
280                                NULL, NULL);
281
282    ewd->input = input;
283
284    /* create Ecore_Wl_Dnd */
285    if (!glb_dnd)
286      if (!(glb_dnd = calloc(1, sizeof(Ecore_Wl_Dnd)))) return;
287    glb_dnd->ewd = ewd;
288    glb_dnd->input = input;
289    input->dnd = glb_dnd;
290    wl_array_init(&glb_dnd->types_offered);
291 }
292
293 void 
294 _ecore_wl_input_del(Ecore_Wl_Input *input)
295 {
296    if (!input) return;
297
298    if (input->cursor_name) eina_stringshare_del(input->cursor_name);
299    input->cursor_name = NULL;
300
301    if (input->keyboard_focus)
302      {
303         Ecore_Wl_Window *win = NULL;
304
305         if ((win = input->keyboard_focus))
306           win->keyboard_device = NULL;
307
308         input->keyboard_focus = NULL;
309      }
310
311    if (input->drag_source) _ecore_wl_dnd_del(input->drag_source);
312    input->drag_source = NULL;
313
314    if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
315    input->selection_source = NULL;
316
317    if (input->data_device) wl_data_device_destroy(input->data_device);
318
319    if (input->xkb.state)
320      xkb_state_unref(input->xkb.state);
321    if (input->xkb.keymap)
322      xkb_map_unref(input->xkb.keymap);
323
324    if (input->cursor_surface)
325      wl_surface_destroy(input->cursor_surface);
326
327    wl_list_remove(&input->link);
328    if (input->seat) wl_seat_destroy(input->seat);
329
330    if (input->repeat.hdlr) ecore_main_fd_handler_del(input->repeat.hdlr);
331    input->repeat.hdlr = NULL;
332
333    if (input->repeat.timerfd) close(input->repeat.timerfd);
334    input->repeat.timerfd = 0;
335
336    free(input);
337 }
338
339 void 
340 _ecore_wl_input_pointer_xy_get(int *x, int *y)
341 {
342    if (x) *x = _pointer_x;
343    if (y) *y = _pointer_y;
344 }
345
346 static void 
347 _ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
348 {
349    Ecore_Wl_Input *input;
350
351    if (!(input = data)) return;
352
353    if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->pointer))
354      {
355         input->pointer = wl_seat_get_pointer(seat);
356         wl_pointer_set_user_data(input->pointer, input);
357         wl_pointer_add_listener(input->pointer, &pointer_listener, input);
358      }
359    else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->pointer))
360      {
361         wl_pointer_destroy(input->pointer);
362         input->pointer = NULL;
363      }
364
365    if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->keyboard))
366      {
367         input->keyboard = wl_seat_get_keyboard(seat);
368         wl_keyboard_set_user_data(input->keyboard, input);
369         wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input);
370      }
371    else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->keyboard))
372      {
373         wl_keyboard_destroy(input->keyboard);
374         input->keyboard = NULL;
375      }
376
377    if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->touch))
378      {
379         input->touch = wl_seat_get_touch(seat);
380         wl_touch_set_user_data(input->touch, input);
381         wl_touch_add_listener(input->touch, &touch_listener, input);
382      }
383    else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->touch))
384      {
385         wl_touch_destroy(input->touch);
386         input->touch = NULL;
387      }
388 }
389
390
391 static void 
392 _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy)
393 {
394    Ecore_Wl_Input *input;
395
396    /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
397
398    if (!(input = data)) return;
399
400    _pointer_x = input->sx = wl_fixed_to_int(sx);
401    _pointer_y = input->sy = wl_fixed_to_int(sy);
402
403    input->timestamp = timestamp;
404
405    if (input->pointer_focus)
406      _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp);
407
408    ecore_wl_input_cursor_from_name_set(input, input->cursor_name);
409 }
410
411 static void 
412 _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state)
413 {
414    Ecore_Wl_Input *input;
415
416    LOGFN(__FILE__, __LINE__, __FUNCTION__);
417
418    if (!(input = data)) return;
419
420    input->timestamp = timestamp;
421    input->display->serial = serial;
422
423 //   _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp);
424
425    if (state)
426      {
427         if ((input->pointer_focus) && (!input->grab) && (state))
428           {
429              ecore_wl_input_grab(input, input->pointer_focus, button);
430              input->grab_timestamp = timestamp;
431           }
432
433         _ecore_wl_input_mouse_down_send(input, input->pointer_focus, 
434                                         button, timestamp);
435      }
436    else
437      {
438         _ecore_wl_input_mouse_up_send(input, input->pointer_focus, 
439                                       button, timestamp);
440         if ((input->grab) && (input->grab_button == button) && (!state))
441           ecore_wl_input_ungrab(input);
442      }
443
444 //   _ecore_wl_input_mouse_move_send(input, timestamp);
445 }
446
447 static void 
448 _ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int timestamp, unsigned int axis, wl_fixed_t value)
449 {
450    Ecore_Wl_Input *input;
451
452    LOGFN(__FILE__, __LINE__, __FUNCTION__);
453
454    if (!(input = data)) return;
455    _ecore_wl_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value), 
456                                     timestamp);
457 }
458
459 static void 
460 _ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp __UNUSED__)
461 {
462    Ecore_Wl_Input *input;
463
464    LOGFN(__FILE__, __LINE__, __FUNCTION__);
465
466    if (!(input = data)) return;
467
468    if (callback)
469      {
470         if (callback != input->cursor_frame_cb) return;
471         wl_callback_destroy(callback);
472         input->cursor_frame_cb = NULL;
473      }
474
475    if (!input->cursor_name)
476      {
477         ecore_wl_input_pointer_set(input, NULL, 0, 0);
478         return;
479      }
480
481    if (!input->cursor_frame_cb)
482      {
483         input->cursor_frame_cb = wl_surface_frame(input->cursor_surface);
484         wl_callback_add_listener(input->cursor_frame_cb, 
485                                  &_ecore_wl_pointer_surface_listener, input);
486      }
487 }
488
489 static void 
490 _ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int format, int fd, unsigned int size)
491 {
492    Ecore_Wl_Input *input;
493    char *map = NULL;
494
495    LOGFN(__FILE__, __LINE__, __FUNCTION__);
496
497    if (!(input = data))
498      {
499         close(fd);
500         return;
501      }
502
503    if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
504      {
505         close(fd);
506         return;
507      }
508
509    map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
510    if (map == MAP_FAILED)
511      {
512         close(fd);
513         return;
514      }
515
516    input->xkb.keymap = 
517      xkb_map_new_from_string(input->display->xkb.context, map, 
518                              XKB_KEYMAP_FORMAT_TEXT_V1, 0);
519
520    munmap(map, size);
521    close(fd);
522
523    if (!(input->xkb.keymap)) return;
524    if (!(input->xkb.state = xkb_state_new(input->xkb.keymap)))
525      {
526         xkb_map_unref(input->xkb.keymap);
527         input->xkb.keymap = NULL;
528         return;
529      }
530
531    input->xkb.control_mask = 
532      1 << xkb_map_mod_get_index(input->xkb.keymap, "Control");
533    input->xkb.alt_mask = 
534      1 << xkb_map_mod_get_index(input->xkb.keymap, "Mod1");
535    input->xkb.shift_mask = 
536      1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift");
537 }
538
539 static void 
540 _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state)
541 {
542    Ecore_Wl_Input *input;
543    Ecore_Wl_Window *win;
544    unsigned int code, num;
545    const xkb_keysym_t *syms;
546    xkb_keysym_t sym = XKB_KEY_NoSymbol;
547    xkb_mod_mask_t mask;
548    char string[32], key[32], keyname[32];// compose[32];
549    Ecore_Event_Key *e;
550    struct itimerspec ts;
551    int len = 0;
552
553    LOGFN(__FILE__, __LINE__, __FUNCTION__);
554
555    if (!(input = data)) return;
556    input->display->serial = serial;
557
558    /* xkb rules reflect X broken keycodes, so offset by 8 */
559    code = keycode + 8;
560
561    win = input->keyboard_focus;
562    if ((!win) || (win->keyboard_device != input) || (!input->xkb.state)) 
563      return;
564
565    mask = xkb_state_serialize_mods(input->xkb.state, 
566                                    XKB_STATE_DEPRESSED | XKB_STATE_LATCHED);
567
568    input->modifiers = 0;
569
570    /* The Ecore_Event_Modifiers don't quite match the X mask bits */
571    if (mask & input->xkb.control_mask)
572      input->modifiers |= MOD_CONTROL_MASK;
573    if (mask & input->xkb.alt_mask)
574      input->modifiers |= MOD_ALT_MASK;
575    if (mask & input->xkb.shift_mask)
576      input->modifiers |= MOD_SHIFT_MASK;
577
578    num = xkb_key_get_syms(input->xkb.state, code, &syms);
579    if (num == 1) sym = syms[0];
580
581    memset(key, 0, sizeof(key));
582    xkb_keysym_get_name(sym, key, sizeof(key));
583
584    memset(keyname, 0, sizeof(keyname));
585    xkb_keysym_get_name(sym, keyname, sizeof(keyname));
586    if (keyname[0] == '\0')
587      snprintf(keyname, sizeof(keyname), "Keycode-%i", code);
588
589    memset(string, 0, sizeof(string));
590    if (xkb_keysym_to_utf8(sym, string, 32) <= 0)
591      {
592         /* FIXME: NB: We may need to add more checks here for other 
593          * non-printable characters */
594         if ((sym == XKB_KEY_Tab) || (sym == XKB_KEY_ISO_Left_Tab)) 
595           string[len++] = '\t';
596      }
597
598    /* FIXME: NB: Start hacking on compose key support */
599    /* memset(compose, 0, sizeof(compose)); */
600    /* if (sym == XKB_KEY_Multi_key) */
601    /*   { */
602    /*      if (xkb_keysym_to_utf8(sym, compose, 32) <= 0) */
603    /*        compose[0] = '\0'; */
604    /*   } */
605
606    e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
607               ((string[0] != '\0') ? strlen(string) : 0) + 3);
608    if (!e) return;
609
610    e->keyname = (char *)(e + 1);
611    e->key = e->keyname + strlen(keyname) + 1;
612    e->string = strlen(string) ? e->key + strlen(key) + 1 : NULL;
613    e->compose = e->string;
614
615    strcpy((char *)e->keyname, keyname);
616    strcpy((char *)e->key, key);
617    if (strlen(string)) strcpy((char *)e->string, string);
618
619    e->window = win->id;
620    e->event_window = win->id;
621    e->timestamp = timestamp;
622    e->modifiers = input->modifiers;
623
624    if (state)
625      ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
626    else
627      ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
628
629    if ((!state) && (keycode == input->repeat.key))
630      {
631         input->repeat.sym = 0;
632         input->repeat.key = 0;
633         input->repeat.time = 0;
634
635         ts.it_interval.tv_sec = 0;
636         ts.it_interval.tv_nsec = 0;
637         ts.it_value.tv_sec = 0;
638         ts.it_value.tv_nsec = 0;
639
640         timerfd_settime(input->repeat.timerfd, 0, &ts, NULL);
641      }
642    else if ((state) && 
643             ((!input->repeat.key) || 
644                 ((keycode) && (keycode != input->repeat.key))))
645      {
646         input->repeat.sym = sym;
647         input->repeat.key = keycode;
648         input->repeat.time = timestamp;
649
650         /* interval after expires */
651         ts.it_interval.tv_sec = 0;
652         ts.it_interval.tv_nsec = 35 * 1000 * 1000;
653
654         /* initial expiration */
655         ts.it_value.tv_sec = 0;
656         ts.it_value.tv_nsec = 500 * 1000 * 1000;
657
658         timerfd_settime(input->repeat.timerfd, 0, &ts, NULL);
659      }
660 }
661
662 static void 
663 _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial __UNUSED__, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group)
664 {
665    Ecore_Wl_Input *input;
666
667    LOGFN(__FILE__, __LINE__, __FUNCTION__);
668
669    if (!(input = data)) return;
670    xkb_state_update_mask(input->xkb.state, depressed, latched, 
671                          locked, 0, 0, group);
672 }
673
674 static Eina_Bool 
675 _ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler __UNUSED__)
676 {
677    Ecore_Wl_Input *input;
678    Ecore_Wl_Window *win = NULL;
679    unsigned long long int xp;
680
681    LOGFN(__FILE__, __LINE__, __FUNCTION__);
682
683    if (!(input = data)) return ECORE_CALLBACK_RENEW;
684
685    /* Trap for EAGAIN */
686    if (read(input->repeat.timerfd, &xp, sizeof(xp)) != sizeof(xp))
687      return ECORE_CALLBACK_RENEW;
688
689    if ((win = input->keyboard_focus))
690      _ecore_wl_input_cb_keyboard_key(input, NULL, input->display->serial, 
691                                      input->repeat.time, 
692                                      input->repeat.key, EINA_TRUE);
693
694    return ECORE_CALLBACK_RENEW;
695 }
696
697 static void 
698 _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy)
699 {
700    Ecore_Wl_Input *input;
701    Ecore_Wl_Window *win = NULL;
702
703    LOGFN(__FILE__, __LINE__, __FUNCTION__);
704
705    if (!surface) return;
706    if (!(input = data)) return;
707
708    if (!input->timestamp)
709      {
710         struct timeval tv;
711
712         gettimeofday(&tv, NULL);
713         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
714      }
715
716    input->sx = wl_fixed_to_double(sx);
717    input->sy = wl_fixed_to_double(sy);
718    input->display->serial = serial;
719    input->pointer_enter_serial = serial;
720
721    /* The cursor on the surface is undefined until we set it */
722    if (input->pointer)
723      ecore_wl_input_cursor_from_name_set(input, "left_ptr");
724
725    if ((win = wl_surface_get_user_data(surface)))
726      {
727         win->pointer_device = input;
728         input->pointer_focus = win;
729
730         _ecore_wl_input_mouse_in_send(input, win, input->timestamp);
731      }
732 }
733
734 static void 
735 _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer __UNUSED__, unsigned int serial, struct wl_surface *surface)
736 {
737    Ecore_Wl_Input *input;
738    Ecore_Wl_Window *win;
739
740    LOGFN(__FILE__, __LINE__, __FUNCTION__);
741
742    if (!surface) return;
743    if (!(input = data)) return;
744
745    input->display->serial = serial;
746
747    if (!surface) return;
748    if (!(win = wl_surface_get_user_data(surface))) return;
749
750    win->pointer_device = NULL;
751    input->pointer_focus = NULL;
752
753    /* _ecore_wl_input_mouse_move_send(input, win, input->timestamp); */
754    _ecore_wl_input_mouse_out_send(input, win, input->timestamp);
755
756    if (input->grab)
757      {
758         /* move or resize started */
759
760         /* printf("Pointer Leave WITH a Grab\n"); */
761      }
762 }
763
764 static void 
765 _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface, struct wl_array *keys __UNUSED__)
766 {
767    Ecore_Wl_Input *input;
768    Ecore_Wl_Window *win = NULL;
769
770    LOGFN(__FILE__, __LINE__, __FUNCTION__);
771
772    if (!surface) return;
773    if (!(input = data)) return;
774
775    if (!input->timestamp)
776      {
777         struct timeval tv;
778
779         gettimeofday(&tv, NULL);
780         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
781      }
782
783    input->display->serial = serial;
784
785    if (!(win = wl_surface_get_user_data(surface))) return;
786
787    win->keyboard_device = input;
788    input->keyboard_focus = win;
789
790    _ecore_wl_input_focus_in_send(input, win, input->timestamp);
791 }
792
793 static void 
794 _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard __UNUSED__, unsigned int serial, struct wl_surface *surface)
795 {
796    Ecore_Wl_Input *input;
797    Ecore_Wl_Window *win;
798
799    LOGFN(__FILE__, __LINE__, __FUNCTION__);
800
801    if (!surface) return;
802    if (!(input = data)) return;
803
804    if (input->repeat.timerfd)
805      {
806         struct itimerspec ts;
807         
808         ts.it_interval.tv_sec = 0;
809         ts.it_interval.tv_nsec = 0;
810         ts.it_value.tv_sec = 0;
811         ts.it_value.tv_nsec = 0;
812
813         timerfd_settime(input->repeat.timerfd, 0, &ts, NULL);
814      }
815
816    if (!input->timestamp)
817      {
818         struct timeval tv;
819
820         gettimeofday(&tv, NULL);
821         input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000);
822      }
823
824    input->display->serial = serial;
825
826    if (!surface) return;
827    if (!(win = wl_surface_get_user_data(surface))) return;
828
829    win->keyboard_device = NULL;
830    _ecore_wl_input_focus_out_send(input, win, input->timestamp);
831
832    input->keyboard_focus = NULL;
833 }
834
835 static void 
836 _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y)
837 {
838    Ecore_Wl_Input *input;
839
840    LOGFN(__FILE__, __LINE__, __FUNCTION__);
841
842    if (!surface) return;
843    if (!(input = data)) return;
844
845    /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
846     * This needs to be tested with an actual touch device */
847    /* input->timestamp = timestamp; */
848    input->display->serial = serial;
849    input->sx = wl_fixed_to_int(x);
850    input->sy = wl_fixed_to_int(y);
851    _ecore_wl_input_cb_pointer_enter(data, NULL, serial, surface, x, y);
852    if ((input->pointer_focus) && (!input->grab))
853      {
854         ecore_wl_input_grab(input, input->pointer_focus, BTN_LEFT);
855         input->grab_timestamp = timestamp;
856      }
857
858    _ecore_wl_input_mouse_down_send(input, input->pointer_focus, BTN_LEFT, timestamp);
859 }
860
861 static void 
862 _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch __UNUSED__, unsigned int serial, unsigned int timestamp, int id __UNUSED__)
863 {
864    Ecore_Wl_Input *input;
865
866    LOGFN(__FILE__, __LINE__, __FUNCTION__);
867
868    if (!(input = data)) return;
869
870    /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
871     * This needs to be tested with an actual touch device */
872    /* input->timestamp = timestamp; */
873    input->display->serial = serial;
874    _ecore_wl_input_mouse_up_send(input, input->pointer_focus, BTN_LEFT, timestamp);
875    if ((input->grab) && (input->grab_button == BTN_LEFT))
876      ecore_wl_input_ungrab(input);
877 }
878
879 static void 
880 _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch __UNUSED__, unsigned int timestamp, int id __UNUSED__, wl_fixed_t x, wl_fixed_t y)
881 {
882    Ecore_Wl_Input *input;
883
884    LOGFN(__FILE__, __LINE__, __FUNCTION__);
885
886    if (!(input = data)) return;
887
888    /* FIXME: NB: Not sure yet if input->timestamp should be set here. 
889     * This needs to be tested with an actual touch device */
890    /* input->timestamp = timestamp; */
891    input->sx = wl_fixed_to_int(x);
892    input->sy = wl_fixed_to_int(y);
893
894    _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp);
895 }
896
897 static void 
898 _ecore_wl_input_cb_touch_frame(void *data __UNUSED__, struct wl_touch *touch __UNUSED__)
899 {
900    LOGFN(__FILE__, __LINE__, __FUNCTION__);
901 }
902
903 static void 
904 _ecore_wl_input_cb_touch_cancel(void *data __UNUSED__, struct wl_touch *touch __UNUSED__)
905 {
906    LOGFN(__FILE__, __LINE__, __FUNCTION__);
907 }
908
909 static void 
910 _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer)
911 {
912    LOGFN(__FILE__, __LINE__, __FUNCTION__);
913
914    _ecore_wl_dnd_add(data, data_device, offer);
915 }
916
917 static void 
918 _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer)
919 {
920    LOGFN(__FILE__, __LINE__, __FUNCTION__);
921
922    if (!surface) return;
923
924    _ecore_wl_dnd_enter(data, data_device, timestamp, surface, x, y, offer);
925 }
926
927 static void 
928 _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device)
929 {
930    LOGFN(__FILE__, __LINE__, __FUNCTION__);
931
932    _ecore_wl_dnd_leave(data, data_device);
933 }
934
935 static void 
936 _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y)
937 {
938    LOGFN(__FILE__, __LINE__, __FUNCTION__);
939
940    _ecore_wl_dnd_motion(data, data_device, timestamp, x, y);
941 }
942
943 static void 
944 _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device)
945 {
946    LOGFN(__FILE__, __LINE__, __FUNCTION__);
947
948    _ecore_wl_dnd_drop(data, data_device);
949 }
950
951 static void 
952 _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer)
953 {
954    LOGFN(__FILE__, __LINE__, __FUNCTION__);
955
956    _ecore_wl_dnd_selection(data, data_device, offer);
957 }
958
959 static void 
960 _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp)
961 {
962    Ecore_Event_Mouse_Move *ev;
963
964    LOGFN(__FILE__, __LINE__, __FUNCTION__);
965
966    if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
967
968    ev->timestamp = timestamp;
969    ev->x = input->sx;
970    ev->y = input->sy;
971    /* ev->root.x = input->sx; */
972    /* ev->root.y = input->sy; */
973    ev->modifiers = input->modifiers;
974    ev->multi.device = 0;
975    ev->multi.radius = 1;
976    ev->multi.radius_x = 1;
977    ev->multi.radius_y = 1;
978    ev->multi.pressure = 1.0;
979    ev->multi.angle = 0.0;
980    ev->multi.x = input->sx;
981    ev->multi.y = input->sy;
982
983    if (win)
984      {
985         ev->window = win->id;
986         ev->event_window = win->id;
987      }
988
989    ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
990 }
991
992 static void 
993 _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp)
994 {
995    Ecore_Wl_Event_Mouse_In *ev;
996
997    LOGFN(__FILE__, __LINE__, __FUNCTION__);
998
999    if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return;
1000
1001    ev->x = input->sx;
1002    ev->y = input->sy;
1003    /* ev->root.x = input->sx; */
1004    /* ev->root.y = input->sy; */
1005    ev->modifiers = input->modifiers;
1006    ev->timestamp = timestamp;
1007
1008    if (win)
1009      {
1010         ev->window = win->id;
1011         ev->event_window = win->id;
1012      }
1013
1014    ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
1015 }
1016
1017 static void 
1018 _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp)
1019 {
1020    Ecore_Wl_Event_Mouse_Out *ev;
1021
1022    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1023
1024    if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return;
1025
1026    ev->x = input->sx;
1027    ev->y = input->sy;
1028    /* ev->root.x = input->sx; */
1029    /* ev->root.y = input->sy; */
1030    ev->modifiers = input->modifiers;
1031    ev->timestamp = timestamp;
1032
1033    if (win)
1034      {
1035         ev->window = win->id;
1036         ev->event_window = win->id;
1037      }
1038
1039    ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL);
1040 }
1041
1042 static void 
1043 _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input __UNUSED__, Ecore_Wl_Window *win, unsigned int timestamp)
1044 {
1045    Ecore_Wl_Event_Focus_In *ev;
1046
1047    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1048
1049    if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return;
1050    ev->timestamp = timestamp;
1051    if (win) ev->win = win->id;
1052    ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL);
1053 }
1054
1055 static void 
1056 _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input __UNUSED__, Ecore_Wl_Window *win, unsigned int timestamp)
1057 {
1058    Ecore_Wl_Event_Focus_Out *ev;
1059
1060    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1061
1062    if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return;
1063    ev->timestamp = timestamp;
1064    if (win) ev->win = win->id;
1065    ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL);
1066 }
1067
1068 static void 
1069 _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button, unsigned int timestamp)
1070 {
1071    Ecore_Event_Mouse_Button *ev;
1072
1073    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1074
1075    if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
1076
1077    if (button == BTN_LEFT)
1078      ev->buttons = 1;
1079    else if (button == BTN_MIDDLE)
1080      ev->buttons = 2;
1081    else if (button == BTN_RIGHT)
1082      ev->buttons = 3;
1083    else
1084      ev->buttons = button;
1085
1086    ev->timestamp = timestamp;
1087    ev->x = input->sx;
1088    ev->y = input->sy;
1089    /* ev->root.x = input->sx; */
1090    /* ev->root.y = input->sy; */
1091    ev->modifiers = input->modifiers;
1092
1093    /* FIXME: Need to get these from wayland somehow */
1094    ev->double_click = 0;
1095    ev->triple_click = 0;
1096
1097    ev->multi.device = 0;
1098    ev->multi.radius = 1;
1099    ev->multi.radius_x = 1;
1100    ev->multi.radius_y = 1;
1101    ev->multi.pressure = 1.0;
1102    ev->multi.angle = 0.0;
1103    ev->multi.x = input->sx;
1104    ev->multi.y = input->sy;
1105
1106    if (win)
1107      {
1108         ev->window = win->id;
1109         ev->event_window = win->id;
1110      }
1111
1112    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
1113 }
1114
1115 static void 
1116 _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button, unsigned int timestamp)
1117 {
1118    Ecore_Event_Mouse_Button *ev;
1119
1120    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1121
1122    if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
1123
1124    if (button == BTN_LEFT)
1125      ev->buttons = 1;
1126    else if (button == BTN_MIDDLE)
1127      ev->buttons = 2;
1128    else if (button == BTN_RIGHT)
1129      ev->buttons = 3;
1130    else
1131      ev->buttons = button;
1132
1133    ev->timestamp = timestamp;
1134    ev->x = input->sx;
1135    ev->y = input->sy;
1136    /* ev->root.x = input->sx; */
1137    /* ev->root.y = input->sy; */
1138    ev->modifiers = input->modifiers;
1139
1140    /* FIXME: Need to get these from wayland somehow */
1141    ev->double_click = 0;
1142    ev->triple_click = 0;
1143
1144    ev->multi.device = 0;
1145    ev->multi.radius = 1;
1146    ev->multi.radius_x = 1;
1147    ev->multi.radius_y = 1;
1148    ev->multi.pressure = 1.0;
1149    ev->multi.angle = 0.0;
1150    ev->multi.x = input->sx;
1151    ev->multi.y = input->sy;
1152
1153    if (win)
1154      {
1155         ev->window = win->id;
1156         ev->event_window = win->id;
1157      }
1158
1159    ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
1160 }
1161
1162 static void 
1163 _ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int value, unsigned int timestamp)
1164 {
1165    Ecore_Event_Mouse_Wheel *ev;
1166
1167    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1168
1169    if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return;
1170
1171    ev->timestamp = timestamp;
1172    ev->modifiers = input->modifiers;
1173    ev->x = input->sx;
1174    ev->y = input->sy;
1175    /* ev->root.x = input->sx; */
1176    /* ev->root.y = input->sy; */
1177
1178    if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
1179      {
1180         ev->direction = 0;
1181         ev->z = value;
1182      }
1183    else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
1184      {
1185         ev->direction = 1;
1186         ev->z = value;
1187      }
1188
1189    if (input->grab)
1190      {
1191         ev->window = input->grab->id;
1192         ev->event_window = input->grab->id;
1193      }
1194    else if (input->pointer_focus)
1195      {
1196         ev->window = input->pointer_focus->id;
1197         ev->event_window = input->pointer_focus->id;
1198      }
1199
1200    ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
1201 }
1202
1203 void
1204 _ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source)
1205 {
1206    wl_data_device_set_selection(input->data_device, source, input->display->serial);
1207 }