FreeRDP
uwac-input.c
1 /*
2  * Copyright © 2014-2015 David FORT <contact@hardening-consulting.com>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission. The copyright holders make no representations
11  * about the suitability of this software for any purpose. It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22 #include "uwac-priv.h"
23 #include "uwac-utils.h"
24 
25 #include <stdio.h>
26 #include <inttypes.h>
27 #include <stdlib.h>
28 #include <stdint.h>
29 #include <string.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <time.h>
33 #include <unistd.h>
34 #include <sys/mman.h>
35 #include <sys/timerfd.h>
36 #include <sys/epoll.h>
37 
38 #include "uwac-os.h"
39 #include "wayland-cursor.h"
40 #include "wayland-client-protocol.h"
41 
42 static struct wl_buffer* create_pointer_buffer(UwacSeat* seat, const void* src, size_t size)
43 {
44  struct wl_buffer* buffer = NULL;
45  int fd = 0;
46  void* data = NULL;
47  struct wl_shm_pool* pool = NULL;
48 
49  assert(seat);
50 
51  fd = uwac_create_anonymous_file(size);
52 
53  if (fd < 0)
54  return buffer;
55 
56  data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
57 
58  if (data == MAP_FAILED)
59  {
60  goto error_mmap;
61  }
62  memcpy(data, src, size);
63 
64  pool = wl_shm_create_pool(seat->display->shm, fd, size);
65 
66  if (!pool)
67  {
68  munmap(data, size);
69  goto error_mmap;
70  }
71 
72  buffer =
73  wl_shm_pool_create_buffer(pool, 0, seat->pointer_image->width, seat->pointer_image->height,
74  seat->pointer_image->width * 4, WL_SHM_FORMAT_ARGB8888);
75  wl_shm_pool_destroy(pool);
76 
77  if (munmap(data, size) < 0)
78  {
79  char buffer[256] = { 0 };
80  (void)fprintf(stderr, "%s: munmap(%p, %zu) failed with [%d] %s\n", __func__, data, size,
81  errno, uwac_strerror(errno, buffer, sizeof(buffer)));
82  }
83 
84 error_mmap:
85  close(fd);
86  return buffer;
87 }
88 
89 static void on_buffer_release(void* data, struct wl_buffer* wl_buffer)
90 {
91  (void)data;
92  wl_buffer_destroy(wl_buffer);
93 }
94 
95 static const struct wl_buffer_listener buffer_release_listener = { on_buffer_release };
96 
97 static UwacReturnCode set_cursor_image(UwacSeat* seat, uint32_t serial)
98 {
99  struct wl_buffer* buffer = NULL;
100  struct wl_cursor* cursor = NULL;
101  struct wl_cursor_image* image = NULL;
102  struct wl_surface* surface = NULL;
103  int32_t x = 0;
104  int32_t y = 0;
105 
106  if (!seat || !seat->display || !seat->default_cursor || !seat->default_cursor->images)
107  return UWAC_ERROR_INTERNAL;
108 
109  int scale = 1;
110  if (seat->pointer_focus)
111  scale = seat->pointer_focus->display->actual_scale;
112 
113  switch (seat->pointer_type)
114  {
115  case 2: /* Custom poiner */
116  image = seat->pointer_image;
117  buffer = create_pointer_buffer(seat, seat->pointer_data, seat->pointer_size);
118  if (!buffer)
119  return UWAC_ERROR_INTERNAL;
120  if (wl_buffer_add_listener(buffer, &buffer_release_listener, seat) < 0)
121  return UWAC_ERROR_INTERNAL;
122 
123  surface = seat->pointer_surface;
124  x = image->hotspot_x / scale;
125  y = image->hotspot_y / scale;
126  break;
127  case 1: /* NULL pointer */
128  break;
129  default: /* Default system pointer */
130  cursor = seat->default_cursor;
131  if (!cursor)
132  return UWAC_ERROR_INTERNAL;
133  image = cursor->images[0];
134  if (!image)
135  return UWAC_ERROR_INTERNAL;
136  x = image->hotspot_x;
137  y = image->hotspot_y;
138  buffer = wl_cursor_image_get_buffer(image);
139  if (!buffer)
140  return UWAC_ERROR_INTERNAL;
141  surface = seat->pointer_surface;
142  break;
143  }
144 
145  if (surface && buffer)
146  {
147  wl_surface_set_buffer_scale(surface, scale);
148  wl_surface_attach(surface, buffer, 0, 0);
149  wl_surface_damage(surface, 0, 0, image->width, image->height);
150  wl_surface_commit(surface);
151  }
152 
153  wl_pointer_set_cursor(seat->pointer, serial, surface, x, y);
154 
155  return UWAC_SUCCESS;
156 }
157 
158 static void keyboard_repeat_func(UwacTask* task, uint32_t events)
159 {
160  UwacSeat* input = container_of(task, UwacSeat, repeat_task);
161  assert(input);
162  UwacWindow* window = input->keyboard_focus;
163  uint64_t exp = 0;
164 
165  if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp)
166  /* If we change the timer between the fd becoming
167  * readable and getting here, there'll be nothing to
168  * read and we get EAGAIN. */
169  return;
170 
171  if (window)
172  {
173  UwacKeyEvent* key = NULL;
174 
175  key = (UwacKeyEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_KEY);
176  if (!key)
177  return;
178 
179  key->window = window;
180  key->sym = input->repeat_sym;
181  key->raw_key = input->repeat_key;
182  key->pressed = true;
183  key->repeated = true;
184  }
185 }
186 
187 static void keyboard_handle_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format,
188  int fd, uint32_t size)
189 {
190  UwacSeat* input = data;
191  struct xkb_keymap* keymap = NULL;
192  struct xkb_state* state = NULL;
193  char* map_str = NULL;
194  int mapFlags = MAP_SHARED;
195 
196  if (!data)
197  {
198  close(fd);
199  return;
200  }
201 
202  if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
203  {
204  close(fd);
205  return;
206  }
207 
208  if (input->seat_version >= 7)
209  mapFlags = MAP_PRIVATE;
210 
211  map_str = mmap(NULL, size, PROT_READ, mapFlags, fd, 0);
212  if (map_str == MAP_FAILED)
213  {
214  close(fd);
215  return;
216  }
217 
218  keymap = xkb_keymap_new_from_string(input->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
219  munmap(map_str, size);
220  close(fd);
221 
222  if (!keymap)
223  {
224  assert(uwacErrorHandler(input->display, UWAC_ERROR_INTERNAL, "failed to compile keymap\n"));
225  return;
226  }
227 
228  state = xkb_state_new(keymap);
229  if (!state)
230  {
231  assert(
232  uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY, "failed to create XKB state\n"));
233  xkb_keymap_unref(keymap);
234  return;
235  }
236 
237  xkb_keymap_unref(input->xkb.keymap);
238  xkb_state_unref(input->xkb.state);
239  input->xkb.keymap = keymap;
240  input->xkb.state = state;
241 
242  input->xkb.control_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Control");
243  input->xkb.alt_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Mod1");
244  input->xkb.shift_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Shift");
245  input->xkb.caps_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Lock");
246  input->xkb.num_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Mod2");
247 }
248 
249 static void keyboard_handle_key(void* data, struct wl_keyboard* keyboard, uint32_t serial,
250  uint32_t time, uint32_t key, uint32_t state_w);
251 
252 static void keyboard_handle_enter(void* data, struct wl_keyboard* keyboard, uint32_t serial,
253  struct wl_surface* surface, struct wl_array* keys)
254 {
255  UwacSeat* input = (UwacSeat*)data;
256  assert(input);
257 
258  UwacKeyboardEnterLeaveEvent* event = (UwacKeyboardEnterLeaveEvent*)UwacDisplayNewEvent(
259  input->display, UWAC_EVENT_KEYBOARD_ENTER);
260  if (!event)
261  return;
262 
263  event->window = input->keyboard_focus = (UwacWindow*)wl_surface_get_user_data(surface);
264  event->seat = input;
265 
266  /* we may have the keys in the `keys` array, but as this function is called only
267  * when the window gets focus, so there may be keys from other unrelated windows, eg.
268  * this was leading to problems like passing CTRL+D to freerdp from closing terminal window
269  * if it was closing very fast and the keys was still pressed by the user while the freerdp
270  * gets focus
271  *
272  * currently just ignore this, as further key presses will be handled correctly anyway
273  */
274 }
275 
276 static void keyboard_handle_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial,
277  struct wl_surface* surface)
278 {
279  struct itimerspec its = { 0 };
280  uint32_t* pressedKey = NULL;
281  size_t i = 0;
282 
283  UwacSeat* input = (UwacSeat*)data;
284  assert(input);
285 
286  its.it_interval.tv_sec = 0;
287  its.it_interval.tv_nsec = 0;
288  its.it_value.tv_sec = 0;
289  its.it_value.tv_nsec = 0;
290  (void)timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
291 
292  UwacPointerEnterLeaveEvent* event =
293  (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
294  if (!event)
295  return;
296 
297  event->window = input->keyboard_focus;
298 
299  /* we are currently loosing input focus of the main window:
300  * check if we currently have some keys pressed and release them as if we enter the window again
301  * it will be still "virtually" pressed in remote even if in reality the key has been released
302  */
303  for (pressedKey = input->pressed_keys.data, i = 0; i < input->pressed_keys.size;
304  i += sizeof(uint32_t))
305  {
306  keyboard_handle_key(data, keyboard, serial, 0, *pressedKey, WL_KEYBOARD_KEY_STATE_RELEASED);
307  pressedKey++;
308  }
309 }
310 
311 static int update_key_pressed(UwacSeat* seat, uint32_t key)
312 {
313  uint32_t* keyPtr = NULL;
314  assert(seat);
315 
316  /* check if the key is not already pressed */
317  wl_array_for_each(keyPtr, &seat->pressed_keys)
318  {
319  if (*keyPtr == key)
320  return 1;
321  }
322 
323  keyPtr = wl_array_add(&seat->pressed_keys, sizeof(uint32_t));
324  if (!keyPtr)
325  return -1;
326 
327  *keyPtr = key;
328  return 0;
329 }
330 
331 static int update_key_released(UwacSeat* seat, uint32_t key)
332 {
333  size_t toMove = 0;
334  bool found = false;
335 
336  assert(seat);
337 
338  size_t i = 0;
339  uint32_t* keyPtr = seat->pressed_keys.data;
340  for (; i < seat->pressed_keys.size; i++, keyPtr++)
341  {
342  if (*keyPtr == key)
343  {
344  found = true;
345  break;
346  }
347  }
348 
349  if (found)
350  {
351  toMove = seat->pressed_keys.size - ((i + 1) * sizeof(uint32_t));
352  if (toMove)
353  memmove(keyPtr, keyPtr + 1, toMove);
354 
355  seat->pressed_keys.size -= sizeof(uint32_t);
356  }
357  return 1;
358 }
359 
360 static void keyboard_handle_key(void* data, struct wl_keyboard* keyboard, uint32_t serial,
361  uint32_t time, uint32_t key, uint32_t state_w)
362 {
363  UwacSeat* input = (UwacSeat*)data;
364  assert(input);
365 
366  UwacWindow* window = input->keyboard_focus;
367  UwacKeyEvent* keyEvent = NULL;
368 
369  uint32_t code = 0;
370  uint32_t num_syms = 0;
371  enum wl_keyboard_key_state state = state_w;
372  const xkb_keysym_t* syms = NULL;
373  xkb_keysym_t sym = 0;
374  struct itimerspec its;
375 
376  if (state_w == WL_KEYBOARD_KEY_STATE_PRESSED)
377  update_key_pressed(input, key);
378  else
379  update_key_released(input, key);
380 
381  input->display->serial = serial;
382  code = key + 8;
383  if (!window || !input->xkb.state)
384  return;
385 
386  /* We only use input grabs for pointer events for now, so just
387  * ignore key presses if a grab is active. We expand the key
388  * event delivery mechanism to route events to widgets to
389  * properly handle key grabs. In the meantime, this prevents
390  * key event delivery while a grab is active. */
391  /*if (input->grab && input->grab_button == 0)
392  return;*/
393 
394  num_syms = xkb_state_key_get_syms(input->xkb.state, code, &syms);
395 
396  sym = XKB_KEY_NoSymbol;
397  if (num_syms == 1)
398  sym = syms[0];
399 
400  if (state == WL_KEYBOARD_KEY_STATE_RELEASED && key == input->repeat_key)
401  {
402  its.it_interval.tv_sec = 0;
403  its.it_interval.tv_nsec = 0;
404  its.it_value.tv_sec = 0;
405  its.it_value.tv_nsec = 0;
406  (void)timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
407  }
408  else if (state == WL_KEYBOARD_KEY_STATE_PRESSED &&
409  xkb_keymap_key_repeats(input->xkb.keymap, code))
410  {
411  input->repeat_sym = sym;
412  input->repeat_key = key;
413  input->repeat_time = time;
414  its.it_interval.tv_sec = input->repeat_rate_sec;
415  its.it_interval.tv_nsec = input->repeat_rate_nsec;
416  its.it_value.tv_sec = input->repeat_delay_sec;
417  its.it_value.tv_nsec = input->repeat_delay_nsec;
418  (void)timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
419  }
420 
421  keyEvent = (UwacKeyEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_KEY);
422  if (!keyEvent)
423  return;
424 
425  keyEvent->window = window;
426  keyEvent->sym = sym;
427  keyEvent->raw_key = key;
428  keyEvent->pressed = (state == WL_KEYBOARD_KEY_STATE_PRESSED);
429  keyEvent->repeated = false;
430 }
431 
432 static void keyboard_handle_modifiers(void* data, struct wl_keyboard* keyboard, uint32_t serial,
433  uint32_t mods_depressed, uint32_t mods_latched,
434  uint32_t mods_locked, uint32_t group)
435 {
436  UwacSeat* input = data;
437  assert(input);
438 
439  UwacKeyboardModifiersEvent* event = NULL;
440  xkb_mod_mask_t mask = 0;
441 
442  /* If we're not using a keymap, then we don't handle PC-style modifiers */
443  if (!input->xkb.keymap)
444  return;
445 
446  xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
447  mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_DEPRESSED |
448  XKB_STATE_MODS_LATCHED |
449  XKB_STATE_MODS_LOCKED);
450  input->modifiers = 0;
451  if (mask & input->xkb.control_mask)
452  input->modifiers |= UWAC_MOD_CONTROL_MASK;
453  if (mask & input->xkb.alt_mask)
454  input->modifiers |= UWAC_MOD_ALT_MASK;
455  if (mask & input->xkb.shift_mask)
456  input->modifiers |= UWAC_MOD_SHIFT_MASK;
457  if (mask & input->xkb.caps_mask)
458  input->modifiers |= UWAC_MOD_CAPS_MASK;
459  if (mask & input->xkb.num_mask)
460  input->modifiers |= UWAC_MOD_NUM_MASK;
461 
462  event = (UwacKeyboardModifiersEvent*)UwacDisplayNewEvent(input->display,
463  UWAC_EVENT_KEYBOARD_MODIFIERS);
464  if (!event)
465  return;
466 
467  event->modifiers = input->modifiers;
468 }
469 
470 static void set_repeat_info(UwacSeat* input, int32_t rate, int32_t delay)
471 {
472  assert(input);
473 
474  input->repeat_rate_sec = input->repeat_rate_nsec = 0;
475  input->repeat_delay_sec = input->repeat_delay_nsec = 0;
476 
477  /* a rate of zero disables any repeating, regardless of the delay's
478  * value */
479  if (rate == 0)
480  return;
481 
482  if (rate == 1)
483  input->repeat_rate_sec = 1;
484  else
485  input->repeat_rate_nsec = 1000000000 / rate;
486 
487  input->repeat_delay_sec = delay / 1000;
488  delay -= (input->repeat_delay_sec * 1000);
489  input->repeat_delay_nsec = delay * 1000 * 1000;
490 }
491 
492 static void keyboard_handle_repeat_info(void* data, struct wl_keyboard* keyboard, int32_t rate,
493  int32_t delay)
494 {
495  UwacSeat* input = data;
496  assert(input);
497 
498  set_repeat_info(input, rate, delay);
499 }
500 
501 static const struct wl_keyboard_listener keyboard_listener = {
502  keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave,
503  keyboard_handle_key, keyboard_handle_modifiers, keyboard_handle_repeat_info
504 };
505 
506 static bool touch_send_start_frame(UwacSeat* seat)
507 {
508  assert(seat);
509 
510  UwacTouchFrameBegin* ev =
511  (UwacTouchFrameBegin*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_BEGIN);
512  if (!ev)
513  return false;
514 
515  seat->touch_frame_started = true;
516  return true;
517 }
518 
519 static void touch_handle_down(void* data, struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
520  struct wl_surface* surface, int32_t id, wl_fixed_t x_w,
521  wl_fixed_t y_w)
522 {
523  UwacSeat* seat = data;
524  UwacTouchDown* tdata = NULL;
525 
526  assert(seat);
527  assert(seat->display);
528 
529  seat->display->serial = serial;
530  if (!seat->touch_frame_started && !touch_send_start_frame(seat))
531  return;
532 
533  tdata = (UwacTouchDown*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_DOWN);
534  if (!tdata)
535  return;
536 
537  tdata->seat = seat;
538  tdata->id = id;
539 
540  double sx = wl_fixed_to_double(x_w);
541  double sy = wl_fixed_to_double(y_w);
542 
543  tdata->x = (wl_fixed_t)lround(sx);
544  tdata->y = (wl_fixed_t)lround(sy);
545 
546 #if 0
547  struct widget *widget;
548  float sx = wl_fixed_to_double(x);
549  float sy = wl_fixed_to_double(y);
550 
551 
552  input->touch_focus = wl_surface_get_user_data(surface);
553  if (!input->touch_focus) {
554  DBG("Failed to find to touch focus for surface %p\n", (void*) surface);
555  return;
556  }
557 
558  if (surface != input->touch_focus->main_surface->surface) {
559  DBG("Ignoring input event from subsurface %p\n", (void*) surface);
560  input->touch_focus = NULL;
561  return;
562  }
563 
564  if (input->grab)
565  widget = input->grab;
566  else
567  widget = window_find_widget(input->touch_focus,
568  wl_fixed_to_double(x),
569  wl_fixed_to_double(y));
570  if (widget) {
571  struct touch_point *tp = xmalloc(sizeof *tp);
572  if (tp) {
573  tp->id = id;
574  tp->widget = widget;
575  tp->x = sx;
576  tp->y = sy;
577  wl_list_insert(&input->touch_point_list, &tp->link);
578 
579  if (widget->touch_down_handler)
580  (*widget->touch_down_handler)(widget, input,
581  serial, time, id,
582  sx, sy,
583  widget->user_data);
584  }
585  }
586 #endif
587 }
588 
589 static void touch_handle_up(void* data, struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
590  int32_t id)
591 {
592  UwacSeat* seat = data;
593  UwacTouchUp* tdata = NULL;
594 
595  assert(seat);
596 
597  if (!seat->touch_frame_started && !touch_send_start_frame(seat))
598  return;
599 
600  tdata = (UwacTouchUp*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_UP);
601  if (!tdata)
602  return;
603 
604  tdata->seat = seat;
605  tdata->id = id;
606 
607 #if 0
608  struct touch_point *tp, *tmp;
609 
610  if (!input->touch_focus) {
611  DBG("No touch focus found for touch up event!\n");
612  return;
613  }
614 
615  wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
616  if (tp->id != id)
617  continue;
618 
619  if (tp->widget->touch_up_handler)
620  (*tp->widget->touch_up_handler)(tp->widget, input, serial,
621  time, id,
622  tp->widget->user_data);
623 
624  wl_list_remove(&tp->link);
625  free(tp);
626 
627  return;
628  }
629 #endif
630 }
631 
632 static void touch_handle_motion(void* data, struct wl_touch* wl_touch, uint32_t time, int32_t id,
633  wl_fixed_t x_w, wl_fixed_t y_w)
634 {
635  UwacSeat* seat = data;
636  assert(seat);
637 
638  UwacTouchMotion* tdata = NULL;
639 
640  if (!seat->touch_frame_started && !touch_send_start_frame(seat))
641  return;
642 
643  tdata = (UwacTouchMotion*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_MOTION);
644  if (!tdata)
645  return;
646 
647  tdata->seat = seat;
648  tdata->id = id;
649 
650  double sx = wl_fixed_to_double(x_w);
651  double sy = wl_fixed_to_double(y_w);
652 
653  tdata->x = (wl_fixed_t)lround(sx);
654  tdata->y = (wl_fixed_t)lround(sy);
655 
656 #if 0
657  struct touch_point *tp;
658  float sx = wl_fixed_to_double(x);
659  float sy = wl_fixed_to_double(y);
660 
661  DBG("touch_handle_motion: %i %i\n", id, wl_list_length(&seat->touch_point_list));
662 
663  if (!seat->touch_focus) {
664  DBG("No touch focus found for touch motion event!\n");
665  return;
666  }
667 
668  wl_list_for_each(tp, &seat->touch_point_list, link) {
669  if (tp->id != id)
670  continue;
671 
672  tp->x = sx;
673  tp->y = sy;
674  if (tp->widget->touch_motion_handler)
675  (*tp->widget->touch_motion_handler)(tp->widget, seat, time,
676  id, sx, sy,
677  tp->widget->user_data);
678  return;
679  }
680 #endif
681 }
682 
683 static void touch_handle_frame(void* data, struct wl_touch* wl_touch)
684 {
685  UwacSeat* seat = data;
686  assert(seat);
687 
688  UwacTouchFrameEnd* ev =
689  (UwacTouchFrameEnd*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_END);
690  if (!ev)
691  return;
692 
693  ev->seat = seat;
694  seat->touch_frame_started = false;
695 }
696 
697 static void touch_handle_cancel(void* data, struct wl_touch* wl_touch)
698 {
699  UwacSeat* seat = data;
700  assert(seat);
701 
702  UwacTouchCancel* ev =
703  (UwacTouchCancel*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_CANCEL);
704  if (!ev)
705  return;
706 
707  ev->seat = seat;
708  seat->touch_frame_started = false;
709 
710 #if 0
711  struct touch_point *tp, *tmp;
712 
713  DBG("touch_handle_cancel\n");
714 
715  if (!input->touch_focus) {
716  DBG("No touch focus found for touch cancel event!\n");
717  return;
718  }
719 
720  wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
721  if (tp->widget->touch_cancel_handler)
722  (*tp->widget->touch_cancel_handler)(tp->widget, input,
723  tp->widget->user_data);
724 
725  wl_list_remove(&tp->link);
726  free(tp);
727  }
728 #endif
729 }
730 
731 static void touch_handle_shape(void* data, struct wl_touch* wl_touch, int32_t id, wl_fixed_t major,
732  wl_fixed_t minor)
733 {
734  UwacSeat* seat = data;
735  assert(seat);
736 
737  // TODO
738 }
739 
740 static void touch_handle_orientation(void* data, struct wl_touch* wl_touch, int32_t id,
741  wl_fixed_t orientation)
742 {
743  UwacSeat* seat = data;
744  assert(seat);
745 
746  // TODO
747 }
748 
749 static const struct wl_touch_listener touch_listener = {
750  touch_handle_down, touch_handle_up, touch_handle_motion, touch_handle_frame,
751  touch_handle_cancel, touch_handle_shape, touch_handle_orientation
752 };
753 
754 static void pointer_handle_enter(void* data, struct wl_pointer* pointer, uint32_t serial,
755  struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w)
756 {
757  UwacSeat* input = data;
758  UwacWindow* window = NULL;
759  UwacPointerEnterLeaveEvent* event = NULL;
760 
761  assert(input);
762 
763  double sx = wl_fixed_to_double(sx_w);
764  double sy = wl_fixed_to_double(sy_w);
765 
766  if (!surface)
767  {
768  /* enter event for a window we've just destroyed */
769  return;
770  }
771 
772  input->display->serial = serial;
773  input->display->pointer_focus_serial = serial;
774  window = wl_surface_get_user_data(surface);
775  if (window)
776  window->pointer_enter_serial = serial;
777  input->pointer_focus = window;
778  input->sx = sx;
779  input->sy = sy;
780 
781  event =
782  (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_ENTER);
783  if (!event)
784  return;
785 
786  event->seat = input;
787  event->window = window;
788  event->x = (uint32_t)lround(sx);
789  event->y = (uint32_t)lround(sy);
790 
791  /* Apply cursor theme */
792  set_cursor_image(input, serial);
793 }
794 
795 static void pointer_handle_leave(void* data, struct wl_pointer* pointer, uint32_t serial,
796  struct wl_surface* surface)
797 {
798  UwacPointerEnterLeaveEvent* event = NULL;
799  UwacWindow* window = NULL;
800  UwacSeat* input = data;
801  assert(input);
802 
803  input->display->serial = serial;
804 
805  event =
806  (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
807  if (!event)
808  return;
809 
810  window = wl_surface_get_user_data(surface);
811 
812  event->seat = input;
813  event->window = window;
814 }
815 
816 static void pointer_handle_motion(void* data, struct wl_pointer* pointer, uint32_t time,
817  wl_fixed_t sx_w, wl_fixed_t sy_w)
818 {
819  UwacPointerMotionEvent* motion_event = NULL;
820  UwacSeat* input = data;
821  assert(input);
822 
823  UwacWindow* window = input->pointer_focus;
824  if (!window || !window->display)
825  return;
826 
827  int scale = window->display->actual_scale;
828  int sx_i = wl_fixed_to_int(sx_w) * scale;
829  int sy_i = wl_fixed_to_int(sy_w) * scale;
830  double sx_d = wl_fixed_to_double(sx_w) * scale;
831  double sy_d = wl_fixed_to_double(sy_w) * scale;
832 
833  if ((sx_i < 0) || (sy_i < 0))
834  return;
835 
836  input->sx = sx_d;
837  input->sy = sy_d;
838 
839  motion_event =
840  (UwacPointerMotionEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_MOTION);
841  if (!motion_event)
842  return;
843 
844  motion_event->seat = input;
845  motion_event->window = window;
846  motion_event->x = sx_i;
847  motion_event->y = sy_i;
848 }
849 
850 static void pointer_handle_button(void* data, struct wl_pointer* pointer, uint32_t serial,
851  uint32_t time, uint32_t button, uint32_t state_w)
852 {
853  UwacPointerButtonEvent* event = NULL;
854  UwacSeat* seat = data;
855  assert(seat);
856 
857  UwacWindow* window = seat->pointer_focus;
858 
859  seat->display->serial = serial;
860 
861  event = (UwacPointerButtonEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_BUTTONS);
862  if (!event)
863  return;
864 
865  event->seat = seat;
866  event->window = window;
867  event->x = (uint32_t)lround(seat->sx);
868  event->y = (uint32_t)lround(seat->sy);
869  event->button = button;
870  event->state = (enum wl_pointer_button_state)state_w;
871 }
872 
873 static void pointer_handle_axis(void* data, struct wl_pointer* pointer, uint32_t time,
874  uint32_t axis, wl_fixed_t value)
875 {
876  UwacPointerAxisEvent* event = NULL;
877  UwacSeat* seat = data;
878  assert(seat);
879 
880  UwacWindow* window = seat->pointer_focus;
881 
882  if (!window)
883  return;
884 
885  event = (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS);
886  if (!event)
887  return;
888 
889  event->seat = seat;
890  event->window = window;
891  event->x = (uint32_t)lround(seat->sx);
892  event->y = (uint32_t)lround(seat->sy);
893  event->axis = axis;
894  event->value = value;
895 }
896 
897 static void pointer_frame(void* data, struct wl_pointer* wl_pointer)
898 {
899  UwacPointerFrameEvent* event = NULL;
900  UwacSeat* seat = data;
901  assert(seat);
902 
903  UwacWindow* window = seat->pointer_focus;
904 
905  if (!window)
906  return;
907 
908  event = (UwacPointerFrameEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_FRAME);
909  if (!event)
910  return;
911 
912  event->seat = seat;
913  event->window = window;
914 }
915 
916 static void pointer_axis_source(void* data, struct wl_pointer* wl_pointer, uint32_t axis_source)
917 {
918  UwacPointerSourceEvent* event = NULL;
919  UwacSeat* seat = data;
920  assert(seat);
921 
922  UwacWindow* window = seat->pointer_focus;
923 
924  if (!window)
925  return;
926 
927  event = (UwacPointerSourceEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_SOURCE);
928  if (!event)
929  return;
930 
931  event->seat = seat;
932  event->window = window;
933  event->axis_source = axis_source;
934 }
935 
936 static void pointer_axis_stop(void* data, struct wl_pointer* wl_pointer, uint32_t time,
937  uint32_t axis)
938 {
939  UwacSeat* seat = data;
940  assert(seat);
941 }
942 
943 static void pointer_axis_discrete(void* data, struct wl_pointer* wl_pointer, uint32_t axis,
944  int32_t discrete)
945 {
946  /*UwacSeat *seat = data;*/
947  UwacPointerAxisEvent* event = NULL;
948  UwacSeat* seat = data;
949  assert(seat);
950 
951  UwacWindow* window = seat->pointer_focus;
952 
953  if (!window)
954  return;
955 
956  event =
957  (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
958  if (!event)
959  return;
960 
961  event->seat = seat;
962  event->window = window;
963  event->x = (uint32_t)lround(seat->sx);
964  event->y = (uint32_t)lround(seat->sy);
965  event->axis = axis;
966  event->value = discrete;
967 }
968 
969 static void pointer_axis_value120(void* data, struct wl_pointer* wl_pointer, uint32_t axis,
970  int32_t value120)
971 {
972  /*UwacSeat *seat = data;*/
973  UwacPointerAxisEvent* event = NULL;
974  UwacSeat* seat = data;
975  assert(seat);
976 
977  UwacWindow* window = seat->pointer_focus;
978 
979  if (!window)
980  return;
981 
982  event =
983  (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
984  if (!event)
985  return;
986 
987  event->seat = seat;
988  event->window = window;
989  event->x = (uint32_t)lround(seat->sx);
990  event->y = (uint32_t)lround(seat->sy);
991  event->axis = axis;
992  event->value = value120 / 120;
993 }
994 
995 static const struct wl_pointer_listener pointer_listener = {
996  pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button,
997  pointer_handle_axis, pointer_frame, pointer_axis_source, pointer_axis_stop,
998  pointer_axis_discrete, pointer_axis_value120
999 };
1000 
1001 static void seat_handle_capabilities(void* data, struct wl_seat* seat, uint32_t caps)
1002 {
1003  UwacSeat* input = data;
1004  assert(input);
1005 
1006  if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer)
1007  {
1008  input->pointer = wl_seat_get_pointer(seat);
1009  wl_pointer_set_user_data(input->pointer, input);
1010  wl_pointer_add_listener(input->pointer, &pointer_listener, input);
1011 
1012  input->cursor_theme = wl_cursor_theme_load(NULL, 32, input->display->shm);
1013  if (!input->cursor_theme)
1014  {
1015  assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1016  "unable to get wayland cursor theme\n"));
1017  return;
1018  }
1019 
1020  input->default_cursor = wl_cursor_theme_get_cursor(input->cursor_theme, "left_ptr");
1021  if (!input->default_cursor)
1022  {
1023  assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1024  "unable to get wayland cursor left_ptr\n"));
1025  return;
1026  }
1027  }
1028  else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer)
1029  {
1030 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
1031  if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1032  wl_pointer_release(input->pointer);
1033  else
1034 #endif
1035  wl_pointer_destroy(input->pointer);
1036  if (input->cursor_theme)
1037  wl_cursor_theme_destroy(input->cursor_theme);
1038 
1039  input->default_cursor = NULL;
1040  input->cursor_theme = NULL;
1041  input->pointer = NULL;
1042  }
1043 
1044  if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard)
1045  {
1046  input->keyboard = wl_seat_get_keyboard(seat);
1047  wl_keyboard_set_user_data(input->keyboard, input);
1048  wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input);
1049  }
1050  else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard)
1051  {
1052 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1053  if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1054  wl_keyboard_release(input->keyboard);
1055  else
1056 #endif
1057  wl_keyboard_destroy(input->keyboard);
1058  input->keyboard = NULL;
1059  }
1060 
1061  if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch)
1062  {
1063  input->touch = wl_seat_get_touch(seat);
1064  wl_touch_set_user_data(input->touch, input);
1065  wl_touch_add_listener(input->touch, &touch_listener, input);
1066  }
1067  else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch)
1068  {
1069 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1070  if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1071  wl_touch_release(input->touch);
1072  else
1073 #endif
1074  wl_touch_destroy(input->touch);
1075  input->touch = NULL;
1076  }
1077 }
1078 
1079 static void seat_handle_name(void* data, struct wl_seat* seat, const char* name)
1080 {
1081  UwacSeat* input = data;
1082  assert(input);
1083 
1084  if (input->name)
1085  free(input->name);
1086 
1087  input->name = strdup(name);
1088  if (!input->name)
1089  assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
1090  "unable to strdup seat's name\n"));
1091 }
1092 
1093 static const struct wl_seat_listener seat_listener = { seat_handle_capabilities, seat_handle_name };
1094 
1095 UwacSeat* UwacSeatNew(UwacDisplay* d, uint32_t id, uint32_t version)
1096 {
1097  UwacSeat* ret = xzalloc(sizeof(UwacSeat));
1098  if (!ret)
1099  return NULL;
1100 
1101  ret->display = d;
1102  ret->seat_id = id;
1103  ret->seat_version = version;
1104 
1105  wl_array_init(&ret->pressed_keys);
1106  ret->xkb_context = xkb_context_new(0);
1107  if (!ret->xkb_context)
1108  {
1109  (void)fprintf(stderr, "%s: unable to allocate a xkb_context\n", __func__);
1110  goto fail;
1111  }
1112 
1113  ret->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, version);
1114  wl_seat_add_listener(ret->seat, &seat_listener, ret);
1115  wl_seat_set_user_data(ret->seat, ret);
1116 
1117  ret->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
1118  if (ret->repeat_timer_fd < 0)
1119  {
1120  (void)fprintf(stderr, "%s: error creating repeat timer\n", __func__);
1121  goto fail;
1122  }
1123  ret->repeat_task.run = keyboard_repeat_func;
1124  if (UwacDisplayWatchFd(d, ret->repeat_timer_fd, EPOLLIN, &ret->repeat_task) < 0)
1125  {
1126  (void)fprintf(stderr, "%s: error polling repeat timer\n", __func__);
1127  goto fail;
1128  }
1129 
1130  wl_list_insert(d->seats.prev, &ret->link);
1131  return ret;
1132 
1133 fail:
1134  UwacSeatDestroy(ret);
1135  return NULL;
1136 }
1137 
1138 void UwacSeatDestroy(UwacSeat* s)
1139 {
1140  if (!s)
1141  return;
1142 
1143  UwacSeatInhibitShortcuts(s, false);
1144  if (s->seat)
1145  {
1146 #ifdef WL_SEAT_RELEASE_SINCE_VERSION
1147  if (s->seat_version >= WL_SEAT_RELEASE_SINCE_VERSION)
1148  wl_seat_release(s->seat);
1149  else
1150 #endif
1151  wl_seat_destroy(s->seat);
1152  }
1153  s->seat = NULL;
1154 
1155  free(s->name);
1156  wl_array_release(&s->pressed_keys);
1157 
1158  xkb_state_unref(s->xkb.state);
1159  xkb_context_unref(s->xkb_context);
1160 
1161  if (s->pointer)
1162  {
1163 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
1164  if (s->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1165  wl_pointer_release(s->pointer);
1166  else
1167 #endif
1168  wl_pointer_destroy(s->pointer);
1169  }
1170 
1171  if (s->touch)
1172  {
1173 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1174  if (s->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1175  wl_touch_release(s->touch);
1176  else
1177 #endif
1178  wl_touch_destroy(s->touch);
1179  }
1180 
1181  if (s->keyboard)
1182  {
1183 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1184  if (s->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1185  wl_keyboard_release(s->keyboard);
1186  else
1187 #endif
1188  wl_keyboard_destroy(s->keyboard);
1189  }
1190 
1191  if (s->data_device)
1192  wl_data_device_destroy(s->data_device);
1193 
1194  if (s->data_source)
1195  wl_data_source_destroy(s->data_source);
1196 
1197  if (s->pointer_surface)
1198  wl_surface_destroy(s->pointer_surface);
1199 
1200  free(s->pointer_image);
1201  free(s->pointer_data);
1202 
1203  wl_list_remove(&s->link);
1204  free(s);
1205 }
1206 
1207 const char* UwacSeatGetName(const UwacSeat* seat)
1208 {
1209  assert(seat);
1210  return seat->name;
1211 }
1212 
1213 UwacSeatId UwacSeatGetId(const UwacSeat* seat)
1214 {
1215  assert(seat);
1216  return seat->seat_id;
1217 }
1218 
1219 UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* s, bool inhibit)
1220 {
1221  if (!s)
1222  return UWAC_ERROR_CLOSED;
1223 
1224  if (s->keyboard_inhibitor)
1225  {
1226  zwp_keyboard_shortcuts_inhibitor_v1_destroy(s->keyboard_inhibitor);
1227  s->keyboard_inhibitor = NULL;
1228  }
1229  if (inhibit && s->display && s->display->keyboard_inhibit_manager)
1230  s->keyboard_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(
1231  s->display->keyboard_inhibit_manager, s->keyboard_focus->surface, s->seat);
1232 
1233  if (inhibit && !s->keyboard_inhibitor)
1234  return UWAC_ERROR_INTERNAL;
1235  return UWAC_SUCCESS;
1236 }
1237 
1238 UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat, const void* data, size_t length, size_t width,
1239  size_t height, size_t hot_x, size_t hot_y)
1240 {
1241  if (!seat)
1242  return UWAC_ERROR_CLOSED;
1243 
1244  free(seat->pointer_image);
1245  seat->pointer_image = NULL;
1246 
1247  free(seat->pointer_data);
1248  seat->pointer_data = NULL;
1249  seat->pointer_size = 0;
1250 
1251  /* There is a cursor provided */
1252  if ((data != NULL) && (length != 0))
1253  {
1254  seat->pointer_image = xzalloc(sizeof(struct wl_cursor_image));
1255  if (!seat->pointer_image)
1256  return UWAC_ERROR_NOMEMORY;
1257  seat->pointer_image->width = width;
1258  seat->pointer_image->height = height;
1259  seat->pointer_image->hotspot_x = hot_x;
1260  seat->pointer_image->hotspot_y = hot_y;
1261 
1262  free(seat->pointer_data);
1263  seat->pointer_data = xmalloc(length);
1264  memcpy(seat->pointer_data, data, length);
1265  seat->pointer_size = length;
1266 
1267  seat->pointer_type = 2;
1268  }
1269  /* We want to use the system cursor */
1270  else if (length != 0)
1271  {
1272  seat->pointer_type = 0;
1273  }
1274  /* Hide the cursor */
1275  else
1276  {
1277  seat->pointer_type = 1;
1278  }
1279  if (seat && !seat->default_cursor)
1280  return UWAC_SUCCESS;
1281  return set_cursor_image(seat, seat->display->pointer_focus_serial);
1282 }