SDL  2.0
SDL_waylandevents.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #include "../../SDL_internal.h"
23 
24 #if SDL_VIDEO_DRIVER_WAYLAND
25 
26 #include "SDL_stdinc.h"
27 #include "SDL_timer.h"
28 
29 #include "../../core/unix/SDL_poll.h"
30 #include "../../events/SDL_sysevents.h"
31 #include "../../events/SDL_events_c.h"
32 #include "../../events/scancodes_xfree86.h"
33 
34 #include "SDL_waylandvideo.h"
35 #include "SDL_waylandevents_c.h"
36 #include "SDL_waylandwindow.h"
37 
38 #include "SDL_waylanddyn.h"
39 
44 
45 #ifdef SDL_INPUT_LINUXEV
46 #include <linux/input.h>
47 #else
48 #define BTN_LEFT (0x110)
49 #define BTN_RIGHT (0x111)
50 #define BTN_MIDDLE (0x112)
51 #define BTN_SIDE (0x113)
52 #define BTN_EXTRA (0x114)
53 #endif
54 #include <sys/select.h>
55 #include <sys/mman.h>
56 #include <poll.h>
57 #include <unistd.h>
58 #include <xkbcommon/xkbcommon.h>
59 
60 typedef struct {
61  // repeat_rate in range of [1, 1000]
62  int32_t repeat_rate;
63  int32_t repeat_delay;
65 
66  SDL_bool is_key_down;
67  uint32_t next_repeat_ms;
68  uint32_t scancode;
69  char text[8];
70 } SDL_WaylandKeyboardRepeat;
71 
72 struct SDL_WaylandInput {
73  SDL_VideoData *display;
74  struct wl_seat *seat;
75  struct wl_pointer *pointer;
76  struct wl_touch *touch;
77  struct wl_keyboard *keyboard;
78  SDL_WaylandDataDevice *data_device;
79  struct zwp_relative_pointer_v1 *relative_pointer;
80  struct zwp_confined_pointer_v1 *confined_pointer;
81  SDL_Window *confined_pointer_window;
82  SDL_WindowData *pointer_focus;
83  SDL_WindowData *keyboard_focus;
84 
85  /* Last motion location */
86  wl_fixed_t sx_w;
87  wl_fixed_t sy_w;
88 
89  double dx_frac;
90  double dy_frac;
91 
92  struct {
93  struct xkb_keymap *keymap;
94  struct xkb_state *state;
95  } xkb;
96 
97  /* information about axis events on current frame */
98  struct {
99  SDL_bool is_x_discrete;
100  float x;
101 
102  SDL_bool is_y_discrete;
103  float y;
104  } pointer_curr_axis_info;
105 
106  SDL_WaylandKeyboardRepeat keyboard_repeat;
107 };
108 
109 struct SDL_WaylandTouchPoint {
110  SDL_TouchID id;
111  float x;
112  float y;
113  struct wl_surface* surface;
114 
115  struct SDL_WaylandTouchPoint* prev;
116  struct SDL_WaylandTouchPoint* next;
117 };
118 
119 struct SDL_WaylandTouchPointList {
120  struct SDL_WaylandTouchPoint* head;
121  struct SDL_WaylandTouchPoint* tail;
122 };
123 
124 static struct SDL_WaylandTouchPointList touch_points = {NULL, NULL};
125 
126 static void
127 touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
128 {
129  struct SDL_WaylandTouchPoint* tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
130 
131  tp->id = id;
132  tp->x = x;
133  tp->y = y;
134  tp->surface = surface;
135 
136  if (touch_points.tail) {
137  touch_points.tail->next = tp;
138  tp->prev = touch_points.tail;
139  } else {
140  touch_points.head = tp;
141  tp->prev = NULL;
142  }
143 
144  touch_points.tail = tp;
145  tp->next = NULL;
146 }
147 
148 static void
149 touch_update(SDL_TouchID id, float x, float y)
150 {
151  struct SDL_WaylandTouchPoint* tp = touch_points.head;
152 
153  while (tp) {
154  if (tp->id == id) {
155  tp->x = x;
156  tp->y = y;
157  }
158 
159  tp = tp->next;
160  }
161 }
162 
163 static void
164 touch_del(SDL_TouchID id, float* x, float* y, struct wl_surface **surface)
165 {
166  struct SDL_WaylandTouchPoint* tp = touch_points.head;
167 
168  while (tp) {
169  if (tp->id == id) {
170  *x = tp->x;
171  *y = tp->y;
172  *surface = tp->surface;
173 
174  if (tp->prev) {
175  tp->prev->next = tp->next;
176  } else {
177  touch_points.head = tp->next;
178  }
179 
180  if (tp->next) {
181  tp->next->prev = tp->prev;
182  } else {
183  touch_points.tail = tp->prev;
184  }
185 
186  {
187  struct SDL_WaylandTouchPoint *next = tp->next;
188  SDL_free(tp);
189  tp = next;
190  }
191  } else {
192  tp = tp->next;
193  }
194  }
195 }
196 
197 static struct wl_surface*
198 touch_surface(SDL_TouchID id)
199 {
200  struct SDL_WaylandTouchPoint* tp = touch_points.head;
201 
202  while (tp) {
203  if (tp->id == id) {
204  return tp->surface;
205  }
206 
207  tp = tp->next;
208  }
209 
210  return NULL;
211 }
212 
213 /* Returns the time till next repeat, or 0 if no key is down. */
214 static void
215 keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t now)
216 {
217  if (!repeat_info->is_key_down || !repeat_info->is_initialized) {
218  return;
219  }
220  while (repeat_info->next_repeat_ms <= now) {
221  if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
222  SDL_SendKeyboardKey(SDL_PRESSED, repeat_info->scancode);
223  }
224  if (repeat_info->text[0]) {
225  SDL_SendKeyboardText(repeat_info->text);
226  }
227  repeat_info->next_repeat_ms += 1000 / repeat_info->repeat_rate;
228  }
229 }
230 
231 static void
232 keyboard_repeat_clear(SDL_WaylandKeyboardRepeat* repeat_info) {
233  if (!repeat_info->is_initialized) {
234  return;
235  }
236  repeat_info->is_key_down = SDL_FALSE;
237 }
238 
239 static void
240 keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info,
241  uint32_t scancode, SDL_bool has_text, char text[8]) {
242  if (!repeat_info->is_initialized) {
243  return;
244  }
245  repeat_info->is_key_down = SDL_TRUE;
246  repeat_info->next_repeat_ms = SDL_GetTicks() + repeat_info->repeat_delay;
247  repeat_info->scancode = scancode;
248  if (has_text) {
249  memcpy(repeat_info->text, text, 8);
250  } else {
251  repeat_info->text[0] = '\0';
252  }
253 }
254 
255 void
257 {
259  struct SDL_WaylandInput *input = d->input;
260  int err;
261 
262  WAYLAND_wl_display_flush(d->display);
263 
264  if (input) {
265  uint32_t now = SDL_GetTicks();
266  keyboard_repeat_handle(&input->keyboard_repeat, now);
267  }
268 
269  if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_FALSE, 0)) {
270  err = WAYLAND_wl_display_dispatch(d->display);
271  } else {
272  err = WAYLAND_wl_display_dispatch_pending(d->display);
273  }
274  if (err == -1 && !d->display_disconnected) {
275  /* Something has failed with the Wayland connection -- for example,
276  * the compositor may have shut down and closed its end of the socket,
277  * or there is a library-specific error. No recovery is possible. */
278  d->display_disconnected = 1;
279  /* Only send a single quit message, as application shutdown might call
280  * SDL_PumpEvents */
281  SDL_SendQuit();
282  }
283 }
284 
285 static void
286 pointer_handle_motion(void *data, struct wl_pointer *pointer,
287  uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
288 {
289  struct SDL_WaylandInput *input = data;
290  SDL_WindowData *window = input->pointer_focus;
291  input->sx_w = sx_w;
292  input->sy_w = sy_w;
293  if (input->pointer_focus) {
294  const int sx = wl_fixed_to_int(sx_w);
295  const int sy = wl_fixed_to_int(sy_w);
296  SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
297  }
298 }
299 
300 static void
301 pointer_handle_enter(void *data, struct wl_pointer *pointer,
302  uint32_t serial, struct wl_surface *surface,
303  wl_fixed_t sx_w, wl_fixed_t sy_w)
304 {
305  struct SDL_WaylandInput *input = data;
307 
308  if (!surface) {
309  /* enter event for a window we've just destroyed */
310  return;
311  }
312 
313  /* This handler will be called twice in Wayland 1.4
314  * Once for the window surface which has valid user data
315  * and again for the mouse cursor surface which does not have valid user data
316  * We ignore the later
317  */
318 
320 
321  if (window) {
322  input->pointer_focus = window;
323  SDL_SetMouseFocus(window->sdlwindow);
324  /* In the case of e.g. a pointer confine warp, we may receive an enter
325  * event with no following motion event, but with the new coordinates
326  * as part of the enter event. */
327  pointer_handle_motion(data, pointer, serial, sx_w, sy_w);
328  }
329 }
330 
331 static void
332 pointer_handle_leave(void *data, struct wl_pointer *pointer,
333  uint32_t serial, struct wl_surface *surface)
334 {
335  struct SDL_WaylandInput *input = data;
336 
337  if (input->pointer_focus) {
339  input->pointer_focus = NULL;
340  }
341 }
342 
343 static SDL_bool
344 ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
345 {
346  SDL_WindowData *window_data = input->pointer_focus;
347  SDL_Window *window = window_data->sdlwindow;
348 
349  if (window->hit_test) {
350  const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
351  const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
352 
353  static const uint32_t directions_wl[] = {
358  };
359 
360  /* the names are different (ZXDG_TOPLEVEL_V6_RESIZE_EDGE_* vs
361  WL_SHELL_SURFACE_RESIZE_*), but the values are the same. */
362  const uint32_t *directions_zxdg = directions_wl;
363 
364  switch (rc) {
366  if (input->display->shell.xdg) {
367  xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial);
368  } else if (input->display->shell.zxdg) {
369  zxdg_toplevel_v6_move(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial);
370  } else {
371  wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
372  }
373  return SDL_TRUE;
374 
383  if (input->display->shell.xdg) {
384  xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
385  } else if (input->display->shell.zxdg) {
386  zxdg_toplevel_v6_resize(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
387  } else {
388  wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions_wl[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
389  }
390  return SDL_TRUE;
391 
392  default: return SDL_FALSE;
393  }
394  }
395 
396  return SDL_FALSE;
397 }
398 
399 static void
400 pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial,
402 {
403  SDL_WindowData *window = input->pointer_focus;
404  enum wl_pointer_button_state state = state_w;
405  uint32_t sdl_button;
406 
407  if (input->pointer_focus) {
408  switch (button) {
409  case BTN_LEFT:
410  sdl_button = SDL_BUTTON_LEFT;
411  if (ProcessHitTest(input, serial)) {
412  return; /* don't pass this event on to app. */
413  }
414  break;
415  case BTN_MIDDLE:
416  sdl_button = SDL_BUTTON_MIDDLE;
417  break;
418  case BTN_RIGHT:
419  sdl_button = SDL_BUTTON_RIGHT;
420  break;
421  case BTN_SIDE:
422  sdl_button = SDL_BUTTON_X1;
423  break;
424  case BTN_EXTRA:
425  sdl_button = SDL_BUTTON_X2;
426  break;
427  default:
428  return;
429  }
430 
431  Wayland_data_device_set_serial(input->data_device, serial);
432 
433  SDL_SendMouseButton(window->sdlwindow, 0,
434  state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
435  }
436 }
437 
438 static void
439 pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
441 {
442  struct SDL_WaylandInput *input = data;
443 
444  pointer_handle_button_common(input, serial, time, button, state_w);
445 }
446 
447 static void
448 pointer_handle_axis_common_v1(struct SDL_WaylandInput *input,
449  uint32_t time, uint32_t axis, wl_fixed_t value)
450 {
451  SDL_WindowData *window = input->pointer_focus;
452  enum wl_pointer_axis a = axis;
453  float x, y;
454 
455  if (input->pointer_focus) {
456  switch (a) {
458  x = 0;
459  y = 0 - (float)wl_fixed_to_double(value);
460  break;
462  x = 0 - (float)wl_fixed_to_double(value);
463  y = 0;
464  break;
465  default:
466  return;
467  }
468 
470  }
471 }
472 
473 static void
474 pointer_handle_axis_common(struct SDL_WaylandInput *input, SDL_bool discrete,
475  uint32_t axis, wl_fixed_t value)
476 {
477  enum wl_pointer_axis a = axis;
478 
479  if (input->pointer_focus) {
480  switch (a) {
482  if (discrete) {
483  /* this is a discrete axis event so we process it and flag
484  * to ignore future continuous axis events in this frame */
485  input->pointer_curr_axis_info.is_y_discrete = SDL_TRUE;
486  } else if(input->pointer_curr_axis_info.is_y_discrete) {
487  /* this is a continuous axis event and we have already
488  * processed a discrete axis event before so we ignore it */
489  break;
490  }
491  input->pointer_curr_axis_info.y = 0 - (float)wl_fixed_to_double(value);
492  break;
494  if (discrete) {
495  /* this is a discrete axis event so we process it and flag
496  * to ignore future continuous axis events in this frame */
497  input->pointer_curr_axis_info.is_x_discrete = SDL_TRUE;
498  } else if(input->pointer_curr_axis_info.is_x_discrete) {
499  /* this is a continuous axis event and we have already
500  * processed a discrete axis event before so we ignore it */
501  break;
502  }
503  input->pointer_curr_axis_info.x = 0 - (float)wl_fixed_to_double(value);
504  break;
505  }
506  }
507 }
508 
509 static void
510 pointer_handle_axis(void *data, struct wl_pointer *pointer,
511  uint32_t time, uint32_t axis, wl_fixed_t value)
512 {
513  struct SDL_WaylandInput *input = data;
514 
515  if(wl_seat_get_version(input->seat) >= 5)
516  pointer_handle_axis_common(input, SDL_FALSE, axis, value);
517  else
518  pointer_handle_axis_common_v1(input, time, axis, value);
519 }
520 
521 static void
522 pointer_handle_frame(void *data, struct wl_pointer *pointer)
523 {
524  struct SDL_WaylandInput *input = data;
525  SDL_WindowData *window = input->pointer_focus;
526  float x = input->pointer_curr_axis_info.x, y = input->pointer_curr_axis_info.y;
527 
528  /* clear pointer_curr_axis_info for next frame */
529  memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
530 
531  if(x == 0.0f && y == 0.0f)
532  return;
533  else
535 }
536 
537 static void
538 pointer_handle_axis_source(void *data, struct wl_pointer *pointer,
539  uint32_t axis_source)
540 {
541  /* unimplemented */
542 }
543 
544 static void
545 pointer_handle_axis_stop(void *data, struct wl_pointer *pointer,
547 {
548  /* unimplemented */
549 }
550 
551 static void
552 pointer_handle_axis_discrete(void *data, struct wl_pointer *pointer,
553  uint32_t axis, int32_t discrete)
554 {
555  struct SDL_WaylandInput *input = data;
556 
557  pointer_handle_axis_common(input, SDL_TRUE, axis, wl_fixed_from_int(discrete));
558 }
559 
560 
561 static const struct wl_pointer_listener pointer_listener = {
562  pointer_handle_enter,
563  pointer_handle_leave,
564  pointer_handle_motion,
565  pointer_handle_button,
566  pointer_handle_axis,
567  pointer_handle_frame, // Version 5
568  pointer_handle_axis_source, // Version 5
569  pointer_handle_axis_stop, // Version 5
570  pointer_handle_axis_discrete, // Version 5
571 };
572 
573 static void
574 touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial,
575  unsigned int timestamp, struct wl_surface *surface,
576  int id, wl_fixed_t fx, wl_fixed_t fy)
577 {
579  const double dblx = wl_fixed_to_double(fx);
580  const double dbly = wl_fixed_to_double(fy);
581  const float x = dblx / window_data->sdlwindow->w;
582  const float y = dbly / window_data->sdlwindow->h;
583 
584  touch_add(id, x, y, surface);
585 
586  SDL_SendTouch(1, (SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
587 }
588 
589 static void
590 touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial,
591  unsigned int timestamp, int id)
592 {
593  float x = 0, y = 0;
594  struct wl_surface *surface = NULL;
596 
597  touch_del(id, &x, &y, &surface);
598 
599  if (surface) {
601  window = window_data->sdlwindow;
602  }
603 
604  SDL_SendTouch(1, (SDL_FingerID)id, window, SDL_FALSE, x, y, 0.0f);
605 }
606 
607 static void
608 touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
609  int id, wl_fixed_t fx, wl_fixed_t fy)
610 {
611  SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
612  const double dblx = wl_fixed_to_double(fx);
613  const double dbly = wl_fixed_to_double(fy);
614  const float x = dblx / window_data->sdlwindow->w;
615  const float y = dbly / window_data->sdlwindow->h;
616 
617  touch_update(id, x, y);
618  SDL_SendTouchMotion(1, (SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f);
619 }
620 
621 static void
622 touch_handler_frame(void *data, struct wl_touch *touch)
623 {
624 
625 }
626 
627 static void
628 touch_handler_cancel(void *data, struct wl_touch *touch)
629 {
630 
631 }
632 
633 static const struct wl_touch_listener touch_listener = {
634  touch_handler_down,
635  touch_handler_up,
636  touch_handler_motion,
637  touch_handler_frame,
638  touch_handler_cancel,
639  NULL, /* shape */
640  NULL, /* orientation */
641 };
642 
643 static void
644 keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
646 {
647  struct SDL_WaylandInput *input = data;
648  char *map_str;
649 
650  if (!data) {
651  close(fd);
652  return;
653  }
654 
656  close(fd);
657  return;
658  }
659 
660  map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
661  if (map_str == MAP_FAILED) {
662  close(fd);
663  return;
664  }
665 
666  input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
667  map_str,
668  XKB_KEYMAP_FORMAT_TEXT_V1,
669  0);
670  munmap(map_str, size);
671  close(fd);
672 
673  if (!input->xkb.keymap) {
674  fprintf(stderr, "failed to compile keymap\n");
675  return;
676  }
677 
678  input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
679  if (!input->xkb.state) {
680  fprintf(stderr, "failed to create XKB state\n");
681  WAYLAND_xkb_keymap_unref(input->xkb.keymap);
682  input->xkb.keymap = NULL;
683  return;
684  }
685 }
686 
687 static void
688 keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
689  uint32_t serial, struct wl_surface *surface,
690  struct wl_array *keys)
691 {
692  struct SDL_WaylandInput *input = data;
694 
695  if (!surface) {
696  /* enter event for a window we've just destroyed */
697  return;
698  }
699 
701 
702  if (window) {
703  input->keyboard_focus = window;
704  window->keyboard_device = input;
705  SDL_SetKeyboardFocus(window->sdlwindow);
706  }
707 }
708 
709 static void
710 keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
711  uint32_t serial, struct wl_surface *surface)
712 {
714 }
715 
716 static SDL_bool
717 keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key)
718 {
719  SDL_WindowData *window = input->keyboard_focus;
720  const xkb_keysym_t *syms;
721 
722  if (!window || window->keyboard_device != input || !input->xkb.state) {
723  return SDL_FALSE;
724  }
725 
726  // TODO can this happen?
727  if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1) {
728  return SDL_FALSE;
729  }
730 
731  return WAYLAND_xkb_keysym_to_utf8(syms[0], text, 8) > 0;
732 }
733 
734 static void
735 keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
736  uint32_t serial, uint32_t time, uint32_t key,
737  uint32_t state_w)
738 {
739  struct SDL_WaylandInput *input = data;
740  enum wl_keyboard_key_state state = state_w;
741  uint32_t scancode = SDL_SCANCODE_UNKNOWN;
742  char text[8];
743 
745  scancode = xfree86_scancode_table2[key];
746 
747  if (scancode != SDL_SCANCODE_UNKNOWN) {
749  SDL_PRESSED : SDL_RELEASED, scancode);
750  }
751  }
752 
754  SDL_bool has_text = keyboard_input_get_text(text, input, key);
755  if (has_text) {
756  Wayland_data_device_set_serial(input->data_device, serial);
758  }
759  keyboard_repeat_set(&input->keyboard_repeat, scancode, has_text, text);
760  } else {
761  keyboard_repeat_clear(&input->keyboard_repeat);
762  }
763 }
764 
765 static void
766 keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
767  uint32_t serial, uint32_t mods_depressed,
768  uint32_t mods_latched, uint32_t mods_locked,
769  uint32_t group)
770 {
771  struct SDL_WaylandInput *input = data;
772 
773  WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
774  mods_locked, 0, 0, group);
775 }
776 
777 static void
778 keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
779  int32_t rate, int32_t delay)
780 {
781  struct SDL_WaylandInput *input = data;
782  input->keyboard_repeat.repeat_rate = SDL_max(0, SDL_min(rate, 1000));
783  input->keyboard_repeat.repeat_delay = delay;
784  input->keyboard_repeat.is_initialized = SDL_TRUE;
785 }
786 
787 static const struct wl_keyboard_listener keyboard_listener = {
788  keyboard_handle_keymap,
789  keyboard_handle_enter,
790  keyboard_handle_leave,
791  keyboard_handle_key,
792  keyboard_handle_modifiers,
793  keyboard_handle_repeat_info, // Version 4
794 };
795 
796 static void
797 seat_handle_capabilities(void *data, struct wl_seat *seat,
798  enum wl_seat_capability caps)
799 {
800  struct SDL_WaylandInput *input = data;
801 
802  if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
803  input->pointer = wl_seat_get_pointer(seat);
804  memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
805  input->display->pointer = input->pointer;
807  wl_pointer_add_listener(input->pointer, &pointer_listener,
808  input);
809  } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
810  wl_pointer_destroy(input->pointer);
811  input->pointer = NULL;
812  input->display->pointer = NULL;
813  }
814 
815  if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
816  SDL_AddTouch(1, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch");
817  input->touch = wl_seat_get_touch(seat);
819  wl_touch_add_listener(input->touch, &touch_listener,
820  input);
821  } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
822  SDL_DelTouch(1);
823  wl_touch_destroy(input->touch);
824  input->touch = NULL;
825  }
826 
827  if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
828  input->keyboard = wl_seat_get_keyboard(seat);
830  wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
831  input);
832  } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
833  wl_keyboard_destroy(input->keyboard);
834  input->keyboard = NULL;
835  }
836 }
837 
838 static void
839 seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name)
840 {
841  /* unimplemented */
842 }
843 
844 static const struct wl_seat_listener seat_listener = {
845  seat_handle_capabilities,
846  seat_handle_name, // Version 2
847 };
848 
849 static void
850 data_source_handle_target(void *data, struct wl_data_source *wl_data_source,
851  const char *mime_type)
852 {
853 }
854 
855 static void
856 data_source_handle_send(void *data, struct wl_data_source *wl_data_source,
857  const char *mime_type, int32_t fd)
858 {
860 }
861 
862 static void
863 data_source_handle_cancelled(void *data, struct wl_data_source *wl_data_source)
864 {
866 }
867 
868 static void
869 data_source_handle_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source)
870 {
871 }
872 
873 static void
874 data_source_handle_dnd_finished(void *data, struct wl_data_source *wl_data_source)
875 {
876 }
877 
878 static void
879 data_source_handle_action(void *data, struct wl_data_source *wl_data_source,
880  uint32_t dnd_action)
881 {
882 }
883 
884 static const struct wl_data_source_listener data_source_listener = {
885  data_source_handle_target,
886  data_source_handle_send,
887  data_source_handle_cancelled,
888  data_source_handle_dnd_drop_performed, // Version 3
889  data_source_handle_dnd_finished, // Version 3
890  data_source_handle_action, // Version 3
891 };
892 
895 {
896  SDL_WaylandDataSource *data_source = NULL;
897  SDL_VideoData *driver_data = NULL;
898  struct wl_data_source *id = NULL;
899 
900  if (_this == NULL || _this->driverdata == NULL) {
901  SDL_SetError("Video driver uninitialized");
902  } else {
903  driver_data = _this->driverdata;
904 
905  if (driver_data->data_device_manager != NULL) {
907  driver_data->data_device_manager);
908  }
909 
910  if (id == NULL) {
911  SDL_SetError("Wayland unable to create data source");
912  } else {
913  data_source = SDL_calloc(1, sizeof *data_source);
914  if (data_source == NULL) {
915  SDL_OutOfMemory();
917  } else {
918  WAYLAND_wl_list_init(&(data_source->mimes));
919  data_source->source = id;
920  wl_data_source_set_user_data(id, data_source);
921  wl_data_source_add_listener(id, &data_source_listener,
922  data_source);
923  }
924  }
925  }
926  return data_source;
927 }
928 
929 static void
930 data_offer_handle_offer(void *data, struct wl_data_offer *wl_data_offer,
931  const char *mime_type)
932 {
933  SDL_WaylandDataOffer *offer = data;
934  Wayland_data_offer_add_mime(offer, mime_type);
935 }
936 
937 static void
938 data_offer_handle_source_actions(void *data, struct wl_data_offer *wl_data_offer,
939  uint32_t source_actions)
940 {
941 }
942 
943 static void
944 data_offer_handle_actions(void *data, struct wl_data_offer *wl_data_offer,
945  uint32_t dnd_action)
946 {
947 }
948 
949 static const struct wl_data_offer_listener data_offer_listener = {
950  data_offer_handle_offer,
951  data_offer_handle_source_actions, // Version 3
952  data_offer_handle_actions, // Version 3
953 };
954 
955 static void
956 data_device_handle_data_offer(void *data, struct wl_data_device *wl_data_device,
957  struct wl_data_offer *id)
958 {
959  SDL_WaylandDataOffer *data_offer = NULL;
960 
961  data_offer = SDL_calloc(1, sizeof *data_offer);
962  if (data_offer == NULL) {
963  SDL_OutOfMemory();
964  } else {
965  data_offer->offer = id;
966  data_offer->data_device = data;
967  WAYLAND_wl_list_init(&(data_offer->mimes));
968  wl_data_offer_set_user_data(id, data_offer);
969  wl_data_offer_add_listener(id, &data_offer_listener, data_offer);
970  }
971 }
972 
973 static void
974 data_device_handle_enter(void *data, struct wl_data_device *wl_data_device,
975  uint32_t serial, struct wl_surface *surface,
976  wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id)
977 {
978  SDL_WaylandDataDevice *data_device = data;
979  SDL_bool has_mime = SDL_FALSE;
981 
982  data_device->drag_serial = serial;
983 
984  if (id != NULL) {
985  data_device->drag_offer = wl_data_offer_get_user_data(id);
986 
987  /* TODO: SDL Support more mime types */
988  has_mime = Wayland_data_offer_has_mime(
989  data_device->drag_offer, FILE_MIME);
990 
991  /* If drag_mime is NULL this will decline the offer */
992  wl_data_offer_accept(id, serial,
993  (has_mime == SDL_TRUE) ? FILE_MIME : NULL);
994 
995  /* SDL only supports "copy" style drag and drop */
996  if (has_mime == SDL_TRUE) {
998  }
999  if (wl_data_offer_get_version(data_device->drag_offer->offer) >= 3) {
1001  dnd_action, dnd_action);
1002  }
1003  }
1004 }
1005 
1006 static void
1007 data_device_handle_leave(void *data, struct wl_data_device *wl_data_device)
1008 {
1009  SDL_WaylandDataDevice *data_device = data;
1011 
1012  if (data_device->selection_offer != NULL) {
1013  data_device->selection_offer = NULL;
1015  }
1016 }
1017 
1018 static void
1019 data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
1020  uint32_t time, wl_fixed_t x, wl_fixed_t y)
1021 {
1022 }
1023 
1024 static void
1025 data_device_handle_drop(void *data, struct wl_data_device *wl_data_device)
1026 {
1027  SDL_WaylandDataDevice *data_device = data;
1028  void *buffer = NULL;
1029  size_t length = 0;
1030 
1031  const char *current_uri = NULL;
1032  const char *last_char = NULL;
1033  char *current_char = NULL;
1034 
1035  if (data_device->drag_offer != NULL) {
1036  /* TODO: SDL Support more mime types */
1039 
1040  /* uri-list */
1041  current_uri = (const char *)buffer;
1042  last_char = (const char *)buffer + length;
1043  for (current_char = buffer; current_char < last_char; ++current_char) {
1044  if (*current_char == '\n' || *current_char == 0) {
1045  if (*current_uri != 0 && *current_uri != '#') {
1046  *current_char = 0;
1047  SDL_SendDropFile(NULL, current_uri);
1048  }
1049  current_uri = (const char *)current_char + 1;
1050  }
1051  }
1052 
1053  SDL_free(buffer);
1054  }
1055 }
1056 
1057 static void
1058 data_device_handle_selection(void *data, struct wl_data_device *wl_data_device,
1059  struct wl_data_offer *id)
1060 {
1061  SDL_WaylandDataDevice *data_device = data;
1063 
1064  if (id != NULL) {
1066  }
1067 
1068  if (data_device->selection_offer != offer) {
1070  data_device->selection_offer = offer;
1071  }
1072 
1074 }
1075 
1076 static const struct wl_data_device_listener data_device_listener = {
1077  data_device_handle_data_offer,
1078  data_device_handle_enter,
1079  data_device_handle_leave,
1080  data_device_handle_motion,
1081  data_device_handle_drop,
1082  data_device_handle_selection
1083 };
1084 
1085 void
1087 {
1088  struct SDL_WaylandInput *input;
1089  SDL_WaylandDataDevice *data_device = NULL;
1090 
1091  input = SDL_calloc(1, sizeof *input);
1092  if (input == NULL)
1093  return;
1094 
1095  input->display = d;
1096  input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, SDL_min(5, version));
1097  input->sx_w = wl_fixed_from_int(0);
1098  input->sy_w = wl_fixed_from_int(0);
1099  d->input = input;
1100 
1101  if (d->data_device_manager != NULL) {
1102  data_device = SDL_calloc(1, sizeof *data_device);
1103  if (data_device == NULL) {
1104  return;
1105  }
1106 
1108  d->data_device_manager, input->seat
1109  );
1110  data_device->video_data = d;
1111 
1112  if (data_device->data_device == NULL) {
1113  SDL_free(data_device);
1114  } else {
1115  wl_data_device_set_user_data(data_device->data_device, data_device);
1117  &data_device_listener, data_device);
1118  input->data_device = data_device;
1119  }
1120  }
1121 
1122  wl_seat_add_listener(input->seat, &seat_listener, input);
1124 
1125  WAYLAND_wl_display_flush(d->display);
1126 }
1127 
1129 {
1130  struct SDL_WaylandInput *input = d->input;
1131 
1132  if (!input)
1133  return;
1134 
1135  if (input->data_device != NULL) {
1137  if (input->data_device->selection_offer != NULL) {
1138  Wayland_data_offer_destroy(input->data_device->selection_offer);
1139  }
1140  if (input->data_device->drag_offer != NULL) {
1141  Wayland_data_offer_destroy(input->data_device->drag_offer);
1142  }
1143  if (input->data_device->data_device != NULL) {
1144  wl_data_device_release(input->data_device->data_device);
1145  }
1146  SDL_free(input->data_device);
1147  }
1148 
1149  if (input->keyboard)
1150  wl_keyboard_destroy(input->keyboard);
1151 
1152  if (input->pointer)
1153  wl_pointer_destroy(input->pointer);
1154 
1155  if (input->touch) {
1156  SDL_DelTouch(1);
1157  wl_touch_destroy(input->touch);
1158  }
1159 
1160  if (input->seat)
1161  wl_seat_destroy(input->seat);
1162 
1163  if (input->xkb.state)
1164  WAYLAND_xkb_state_unref(input->xkb.state);
1165 
1166  if (input->xkb.keymap)
1167  WAYLAND_xkb_keymap_unref(input->xkb.keymap);
1168 
1169  SDL_free(input);
1170  d->input = NULL;
1171 }
1172 
1173 SDL_WaylandDataDevice* Wayland_get_data_device(struct SDL_WaylandInput *input)
1174 {
1175  if (input == NULL) {
1176  return NULL;
1177  }
1178 
1179  return input->data_device;
1180 }
1181 
1182 /* !!! FIXME: just merge these into display_handle_global(). */
1184 {
1185  d->relative_pointer_manager =
1186  wl_registry_bind(d->registry, id,
1188 }
1189 
1191 {
1192  if (d->relative_pointer_manager)
1193  zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
1194 }
1195 
1197 {
1198  d->pointer_constraints =
1199  wl_registry_bind(d->registry, id,
1201 }
1202 
1204 {
1205  if (d->pointer_constraints)
1206  zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
1207 }
1208 
1209 static void
1210 relative_pointer_handle_relative_motion(void *data,
1211  struct zwp_relative_pointer_v1 *pointer,
1212  uint32_t time_hi,
1213  uint32_t time_lo,
1214  wl_fixed_t dx_w,
1215  wl_fixed_t dy_w,
1216  wl_fixed_t dx_unaccel_w,
1217  wl_fixed_t dy_unaccel_w)
1218 {
1219  struct SDL_WaylandInput *input = data;
1220  SDL_VideoData *d = input->display;
1221  SDL_WindowData *window = input->pointer_focus;
1222  double dx_unaccel;
1223  double dy_unaccel;
1224  double dx;
1225  double dy;
1226 
1227  dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
1228  dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
1229 
1230  /* Add left over fraction from last event. */
1231  dx_unaccel += input->dx_frac;
1232  dy_unaccel += input->dy_frac;
1233 
1234  input->dx_frac = modf(dx_unaccel, &dx);
1235  input->dy_frac = modf(dy_unaccel, &dy);
1236 
1237  if (input->pointer_focus && d->relative_mouse_mode) {
1238  SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
1239  }
1240 }
1241 
1242 static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
1243  relative_pointer_handle_relative_motion,
1244 };
1245 
1246 static void
1247 locked_pointer_locked(void *data,
1248  struct zwp_locked_pointer_v1 *locked_pointer)
1249 {
1250 }
1251 
1252 static void
1253 locked_pointer_unlocked(void *data,
1254  struct zwp_locked_pointer_v1 *locked_pointer)
1255 {
1256 }
1257 
1258 static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
1259  locked_pointer_locked,
1260  locked_pointer_unlocked,
1261 };
1262 
1263 static void
1264 lock_pointer_to_window(SDL_Window *window,
1265  struct SDL_WaylandInput *input)
1266 {
1267  SDL_WindowData *w = window->driverdata;
1268  SDL_VideoData *d = input->display;
1269  struct zwp_locked_pointer_v1 *locked_pointer;
1270 
1271  if (w->locked_pointer)
1272  return;
1273 
1274  locked_pointer =
1275  zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints,
1276  w->surface,
1277  input->pointer,
1278  NULL,
1280  zwp_locked_pointer_v1_add_listener(locked_pointer,
1281  &locked_pointer_listener,
1282  window);
1283 
1284  w->locked_pointer = locked_pointer;
1285 }
1286 
1287 static void pointer_confine_destroy(struct SDL_WaylandInput *input)
1288 {
1289  if (input->confined_pointer) {
1290  zwp_confined_pointer_v1_destroy(input->confined_pointer);
1291  input->confined_pointer = NULL;
1292  }
1293 }
1294 
1295 int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
1296 {
1298  SDL_VideoData *d = input->display;
1299  SDL_Window *window;
1300  struct zwp_relative_pointer_v1 *relative_pointer;
1301 
1302  if (!d->relative_pointer_manager)
1303  return -1;
1304 
1305  if (!d->pointer_constraints)
1306  return -1;
1307 
1308  if (!input->pointer)
1309  return -1;
1310 
1311  /* If we have a pointer confine active, we must destroy it here because
1312  * creating a locked pointer otherwise would be a protocol error. */
1313  pointer_confine_destroy(input);
1314 
1315  if (!input->relative_pointer) {
1316  relative_pointer =
1318  d->relative_pointer_manager,
1319  input->pointer);
1320  zwp_relative_pointer_v1_add_listener(relative_pointer,
1321  &relative_pointer_listener,
1322  input);
1323  input->relative_pointer = relative_pointer;
1324  }
1325 
1326  for (window = vd->windows; window; window = window->next)
1327  lock_pointer_to_window(window, input);
1328 
1329  d->relative_mouse_mode = 1;
1330 
1331  return 0;
1332 }
1333 
1334 int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
1335 {
1337  SDL_VideoData *d = input->display;
1338  SDL_Window *window;
1339  SDL_WindowData *w;
1340 
1341  for (window = vd->windows; window; window = window->next) {
1342  w = window->driverdata;
1343  if (w->locked_pointer)
1344  zwp_locked_pointer_v1_destroy(w->locked_pointer);
1345  w->locked_pointer = NULL;
1346  }
1347 
1348  zwp_relative_pointer_v1_destroy(input->relative_pointer);
1349  input->relative_pointer = NULL;
1350 
1351  d->relative_mouse_mode = 0;
1352 
1353  if (input->confined_pointer_window)
1354  Wayland_input_confine_pointer(input->confined_pointer_window, input);
1355 
1356  return 0;
1357 }
1358 
1359 static void
1360 confined_pointer_confined(void *data,
1361  struct zwp_confined_pointer_v1 *confined_pointer)
1362 {
1363 }
1364 
1365 static void
1366 confined_pointer_unconfined(void *data,
1367  struct zwp_confined_pointer_v1 *confined_pointer)
1368 {
1369 }
1370 
1371 static const struct zwp_confined_pointer_v1_listener confined_pointer_listener = {
1372  confined_pointer_confined,
1373  confined_pointer_unconfined,
1374 };
1375 
1376 int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input)
1377 {
1378  SDL_WindowData *w = window->driverdata;
1379  SDL_VideoData *d = input->display;
1380  struct zwp_confined_pointer_v1 *confined_pointer;
1381 
1382  if (!d->pointer_constraints)
1383  return -1;
1384 
1385  if (!input->pointer)
1386  return -1;
1387 
1388  /* A confine may already be active, in which case we should destroy it and
1389  * create a new one. */
1390  if (input->confined_pointer)
1392 
1393  input->confined_pointer_window = window;
1394 
1395  /* We cannot create a confine if the pointer is already locked. Defer until
1396  * the pointer is unlocked. */
1397  if (d->relative_mouse_mode)
1398  return 0;
1399 
1400  confined_pointer =
1401  zwp_pointer_constraints_v1_confine_pointer(d->pointer_constraints,
1402  w->surface,
1403  input->pointer,
1404  NULL,
1406  zwp_confined_pointer_v1_add_listener(confined_pointer,
1407  &confined_pointer_listener,
1408  window);
1409 
1410  input->confined_pointer = confined_pointer;
1411  return 0;
1412 }
1413 
1414 int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input)
1415 {
1416  pointer_confine_destroy(input);
1417  input->confined_pointer_window = NULL;
1418  return 0;
1419 }
1420 
1421 #endif /* SDL_VIDEO_DRIVER_WAYLAND */
1422 
1423 /* vi: set ts=4 sw=4 expandtab: */
#define _THIS
int SDL_SendClipboardUpdate(void)
unsigned int uint32_t
signed int int32_t
int SDL_SendDropFile(SDL_Window *window, const char *file)
#define SDL_SetError
#define SDL_malloc
#define SDL_free
#define SDL_calloc
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
SDL_EventEntry * head
Definition: SDL_events.c:87
SDL_EventEntry * tail
Definition: SDL_events.c:88
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_PRESSED
Definition: SDL_events.h:50
int SDL_SendQuit(void)
Definition: SDL_quit.c:201
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:634
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:848
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:806
#define memcpy
Definition: SDL_malloc.c:630
#define memset
Definition: SDL_malloc.c:627
#define is_initialized(M)
Definition: SDL_malloc.c:2146
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:599
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:208
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
Definition: SDL_mouse.c:605
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:298
#define SDL_BUTTON_X1
Definition: SDL_mouse.h:285
#define SDL_BUTTON_X2
Definition: SDL_mouse.h:286
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:283
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:284
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:282
@ SDL_MOUSEWHEEL_NORMAL
Definition: SDL_mouse.h:68
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLsizei const void * pointer
GLuint id
GLboolean GLboolean GLboolean GLboolean a
GLuint buffer
GLuint const GLchar * name
GLboolean GLuint group
GLsizeiptr size
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
GLenum GLenum GLenum input
GLubyte GLubyte GLubyte GLubyte w
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
Definition: SDL_poll.c:37
@ SDL_SCANCODE_UNKNOWN
Definition: SDL_scancode.h:45
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
#define SDL_min(x, y)
Definition: SDL_stdinc.h:412
#define SDL_max(x, y)
Definition: SDL_stdinc.h:413
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:587
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:241
void SDL_DelTouch(SDL_TouchID id)
Definition: SDL_touch.c:440
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
Definition: SDL_touch.c:154
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure)
Definition: SDL_touch.c:355
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
@ SDL_TOUCH_DEVICE_DIRECT
Definition: SDL_touch.h:47
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
static SDL_VideoDevice * _this
Definition: SDL_video.c:126
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
Definition: SDL_video.h:1027
@ SDL_HITTEST_DRAGGABLE
Definition: SDL_video.h:1029
@ SDL_HITTEST_RESIZE_LEFT
Definition: SDL_video.h:1037
@ SDL_HITTEST_RESIZE_TOP
Definition: SDL_video.h:1031
@ SDL_HITTEST_RESIZE_TOPRIGHT
Definition: SDL_video.h:1032
@ SDL_HITTEST_RESIZE_BOTTOM
Definition: SDL_video.h:1035
@ SDL_HITTEST_RESIZE_BOTTOMRIGHT
Definition: SDL_video.h:1034
@ SDL_HITTEST_RESIZE_BOTTOMLEFT
Definition: SDL_video.h:1036
@ SDL_HITTEST_RESIZE_RIGHT
Definition: SDL_video.h:1033
@ SDL_HITTEST_RESIZE_TOPLEFT
Definition: SDL_video.h:1030
void * Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, size_t *length, const char *mime_type, SDL_bool null_terminate)
void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source, const char *mime_type, int fd)
int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *device)
int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
void Wayland_data_source_destroy(SDL_WaylandDataSource *source)
SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
#define FILE_MIME
SDL_WaylandDataSource * Wayland_data_source_create(_THIS)
int Wayland_data_device_set_serial(SDL_WaylandDataDevice *device, uint32_t serial)
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
void Wayland_display_destroy_input(SDL_VideoData *d)
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version)
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input)
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
SDL_WaylandDataDevice * Wayland_get_data_device(struct SDL_WaylandInput *input)
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input)
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
void Wayland_PumpEvents(_THIS)
struct xkb_state * state
#define NULL
Definition: begin_code.h:163
EGLSurface surface
Definition: eglext.h:248
EGLSurface EGLnsecsANDROID time
Definition: eglext.h:518
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
GLuint64 key
Definition: gl2ext.h:2192
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
static struct wl_data_device * wl_data_device_manager_get_data_device(struct wl_data_device_manager *wl_data_device_manager, struct wl_seat *seat)
static struct wl_data_source * wl_data_device_manager_create_data_source(struct wl_data_device_manager *wl_data_device_manager)
@ WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY
@ WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE
static void wl_data_device_release(struct wl_data_device *wl_data_device)
static int wl_data_device_add_listener(struct wl_data_device *wl_data_device, const struct wl_data_device_listener *listener, void *data)
static void wl_data_device_set_user_data(struct wl_data_device *wl_data_device, void *user_data)
static void wl_data_offer_set_user_data(struct wl_data_offer *wl_data_offer, void *user_data)
static int wl_data_offer_add_listener(struct wl_data_offer *wl_data_offer, const struct wl_data_offer_listener *listener, void *data)
static void wl_data_offer_accept(struct wl_data_offer *wl_data_offer, uint32_t serial, const char *mime_type)
static void * wl_data_offer_get_user_data(struct wl_data_offer *wl_data_offer)
static void wl_data_offer_set_actions(struct wl_data_offer *wl_data_offer, uint32_t dnd_actions, uint32_t preferred_action)
static int wl_data_source_add_listener(struct wl_data_source *wl_data_source, const struct wl_data_source_listener *listener, void *data)
static void wl_data_source_set_user_data(struct wl_data_source *wl_data_source, void *user_data)
static void wl_data_source_destroy(struct wl_data_source *wl_data_source)
static void wl_keyboard_set_user_data(struct wl_keyboard *wl_keyboard, void *user_data)
static void wl_keyboard_destroy(struct wl_keyboard *wl_keyboard)
static int wl_keyboard_add_listener(struct wl_keyboard *wl_keyboard, const struct wl_keyboard_listener *listener, void *data)
@ WL_KEYBOARD_KEY_STATE_PRESSED
@ WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1
static int wl_pointer_add_listener(struct wl_pointer *wl_pointer, const struct wl_pointer_listener *listener, void *data)
static void wl_pointer_set_user_data(struct wl_pointer *wl_pointer, void *user_data)
static void wl_pointer_destroy(struct wl_pointer *wl_pointer)
@ WL_POINTER_AXIS_VERTICAL_SCROLL
@ WL_POINTER_AXIS_HORIZONTAL_SCROLL
static void * wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version)
static struct wl_touch * wl_seat_get_touch(struct wl_seat *wl_seat)
static int wl_seat_add_listener(struct wl_seat *wl_seat, const struct wl_seat_listener *listener, void *data)
static void wl_seat_destroy(struct wl_seat *wl_seat)
static struct wl_pointer * wl_seat_get_pointer(struct wl_seat *wl_seat)
static void wl_seat_set_user_data(struct wl_seat *wl_seat, void *user_data)
static struct wl_keyboard * wl_seat_get_keyboard(struct wl_seat *wl_seat)
@ WL_SEAT_CAPABILITY_KEYBOARD
@ WL_SEAT_CAPABILITY_POINTER
@ WL_SEAT_CAPABILITY_TOUCH
static void wl_shell_surface_move(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial)
@ WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT
@ WL_SHELL_SURFACE_RESIZE_BOTTOM
@ WL_SHELL_SURFACE_RESIZE_LEFT
@ WL_SHELL_SURFACE_RESIZE_TOP
@ WL_SHELL_SURFACE_RESIZE_RIGHT
@ WL_SHELL_SURFACE_RESIZE_TOP_RIGHT
@ WL_SHELL_SURFACE_RESIZE_TOP_LEFT
@ WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT
static void * wl_surface_get_user_data(struct wl_surface *wl_surface)
static void wl_touch_destroy(struct wl_touch *wl_touch)
static int wl_touch_add_listener(struct wl_touch *wl_touch, const struct wl_touch_listener *listener, void *data)
static void wl_touch_set_user_data(struct wl_touch *wl_touch, void *user_data)
static void xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges)
static void xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial)
static void zwp_confined_pointer_v1_destroy(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
static int zwp_confined_pointer_v1_add_listener(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, const struct zwp_confined_pointer_v1_listener *listener, void *data)
static int zwp_locked_pointer_v1_add_listener(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, const struct zwp_locked_pointer_v1_listener *listener, void *data)
static void zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
static struct zwp_locked_pointer_v1 * zwp_pointer_constraints_v1_lock_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
static struct zwp_confined_pointer_v1 * zwp_pointer_constraints_v1_confine_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
static void zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
static struct zwp_relative_pointer_v1 * zwp_relative_pointer_manager_v1_get_relative_pointer(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1, struct wl_pointer *pointer)
static void zwp_relative_pointer_manager_v1_destroy(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1)
static void zwp_relative_pointer_v1_destroy(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1)
static int zwp_relative_pointer_v1_add_listener(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, const struct zwp_relative_pointer_v1_listener *listener, void *data)
static void zxdg_toplevel_v6_resize(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, struct wl_seat *seat, uint32_t serial, uint32_t edges)
static void zxdg_toplevel_v6_move(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, struct wl_seat *seat, uint32_t serial)
const struct wl_interface zwp_pointer_constraints_v1_interface
const struct wl_interface zwp_relative_pointer_manager_v1_interface
static const SDL_Scancode xfree86_scancode_table2[]
The structure that defines a point (integer)
Definition: SDL_rect.h:49
struct wl_data_device_manager * data_device_manager
SDL_Window * windows
Definition: SDL_sysvideo.h:327
SDL_WaylandDataOffer * drag_offer
SDL_WaylandDataOffer * selection_offer
struct wl_data_device * data_device
struct wl_data_offer * offer
struct wl_data_source * source
SDL_Window * sdlwindow
SDL_xdg_shell_surface xdg
struct wl_shell_surface * wl
union SDL_WindowData::@445 shell_surface
SDL_zxdg_shell_surface zxdg
The type used to identify a window.
Definition: SDL_sysvideo.h:75
SDL_Window * next
Definition: SDL_sysvideo.h:115
struct xdg_toplevel * toplevel
union SDL_xdg_shell_surface::@444 roleobj
struct zxdg_toplevel_v6 * toplevel
union SDL_zxdg_shell_surface::@443 roleobj
void(* offer)(void *data, struct wl_data_offer *wl_data_offer, const char *mime_type)
SDL_Texture * button
SDL_Texture * axis
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
const struct wl_interface wl_seat_interface
static uint32_t wl_seat_get_version(struct wl_seat *wl_seat)
static uint32_t wl_data_offer_get_version(struct wl_data_offer *wl_data_offer)