SDL  2.0
SDL_waylandevents.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2019 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_assert.h"
28 #include "SDL_log.h"
29 
30 #include "../../core/unix/SDL_poll.h"
31 #include "../../events/SDL_sysevents.h"
32 #include "../../events/SDL_events_c.h"
33 #include "../../events/scancodes_xfree86.h"
34 
35 #include "SDL_waylandvideo.h"
36 #include "SDL_waylandevents_c.h"
37 #include "SDL_waylandwindow.h"
38 
39 #include "SDL_waylanddyn.h"
40 
41 #include "pointer-constraints-unstable-v1-client-protocol.h"
42 #include "relative-pointer-unstable-v1-client-protocol.h"
43 #include "xdg-shell-client-protocol.h"
44 #include "xdg-shell-unstable-v6-client-protocol.h"
45 
46 #include <linux/input.h>
47 #include <sys/select.h>
48 #include <sys/mman.h>
49 #include <poll.h>
50 #include <unistd.h>
51 #include <xkbcommon/xkbcommon.h>
52 
53 struct SDL_WaylandInput {
54  SDL_VideoData *display;
55  struct wl_seat *seat;
56  struct wl_pointer *pointer;
57  struct wl_touch *touch;
58  struct wl_keyboard *keyboard;
59  SDL_WaylandDataDevice *data_device;
60  struct zwp_relative_pointer_v1 *relative_pointer;
61  SDL_WindowData *pointer_focus;
62  SDL_WindowData *keyboard_focus;
63 
64  /* Last motion location */
65  wl_fixed_t sx_w;
66  wl_fixed_t sy_w;
67 
68  double dx_frac;
69  double dy_frac;
70 
71  struct {
72  struct xkb_keymap *keymap;
73  struct xkb_state *state;
74  } xkb;
75 };
76 
77 struct SDL_WaylandTouchPoint {
79  float x;
80  float y;
81  struct wl_surface* surface;
82 
83  struct SDL_WaylandTouchPoint* prev;
84  struct SDL_WaylandTouchPoint* next;
85 };
86 
87 struct SDL_WaylandTouchPointList {
88  struct SDL_WaylandTouchPoint* head;
89  struct SDL_WaylandTouchPoint* tail;
90 };
91 
92 static struct SDL_WaylandTouchPointList touch_points = {NULL, NULL};
93 
94 static void
95 touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
96 {
97  struct SDL_WaylandTouchPoint* tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
98 
99  tp->id = id;
100  tp->x = x;
101  tp->y = y;
102  tp->surface = surface;
103 
104  if (touch_points.tail) {
105  touch_points.tail->next = tp;
106  tp->prev = touch_points.tail;
107  } else {
108  touch_points.head = tp;
109  tp->prev = NULL;
110  }
111 
112  touch_points.tail = tp;
113  tp->next = NULL;
114 }
115 
116 static void
117 touch_update(SDL_TouchID id, float x, float y)
118 {
119  struct SDL_WaylandTouchPoint* tp = touch_points.head;
120 
121  while (tp) {
122  if (tp->id == id) {
123  tp->x = x;
124  tp->y = y;
125  }
126 
127  tp = tp->next;
128  }
129 }
130 
131 static void
132 touch_del(SDL_TouchID id, float* x, float* y)
133 {
134  struct SDL_WaylandTouchPoint* tp = touch_points.head;
135 
136  while (tp) {
137  if (tp->id == id) {
138  *x = tp->x;
139  *y = tp->y;
140 
141  if (tp->prev) {
142  tp->prev->next = tp->next;
143  } else {
144  touch_points.head = tp->next;
145  }
146 
147  if (tp->next) {
148  tp->next->prev = tp->prev;
149  } else {
150  touch_points.tail = tp->prev;
151  }
152 
153  SDL_free(tp);
154  }
155 
156  tp = tp->next;
157  }
158 }
159 
160 static struct wl_surface*
161 touch_surface(SDL_TouchID id)
162 {
163  struct SDL_WaylandTouchPoint* tp = touch_points.head;
164 
165  while (tp) {
166  if (tp->id == id) {
167  return tp->surface;
168  }
169 
170  tp = tp->next;
171  }
172 
173  return NULL;
174 }
175 
176 void
178 {
180 
181  WAYLAND_wl_display_flush(d->display);
182 
183  if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_FALSE, 0)) {
184  WAYLAND_wl_display_dispatch(d->display);
185  }
186  else
187  {
188  WAYLAND_wl_display_dispatch_pending(d->display);
189  }
190 }
191 
192 static void
193 pointer_handle_enter(void *data, struct wl_pointer *pointer,
194  uint32_t serial, struct wl_surface *surface,
195  wl_fixed_t sx_w, wl_fixed_t sy_w)
196 {
197  struct SDL_WaylandInput *input = data;
199 
200  if (!surface) {
201  /* enter event for a window we've just destroyed */
202  return;
203  }
204 
205  /* This handler will be called twice in Wayland 1.4
206  * Once for the window surface which has valid user data
207  * and again for the mouse cursor surface which does not have valid user data
208  * We ignore the later
209  */
210 
211  window = (SDL_WindowData *)wl_surface_get_user_data(surface);
212 
213  if (window) {
214  input->pointer_focus = window;
215  SDL_SetMouseFocus(window->sdlwindow);
216  }
217 }
218 
219 static void
220 pointer_handle_leave(void *data, struct wl_pointer *pointer,
221  uint32_t serial, struct wl_surface *surface)
222 {
223  struct SDL_WaylandInput *input = data;
224 
225  if (input->pointer_focus) {
227  input->pointer_focus = NULL;
228  }
229 }
230 
231 static void
232 pointer_handle_motion(void *data, struct wl_pointer *pointer,
233  uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
234 {
235  struct SDL_WaylandInput *input = data;
236  SDL_WindowData *window = input->pointer_focus;
237  input->sx_w = sx_w;
238  input->sy_w = sy_w;
239  if (input->pointer_focus) {
240  const int sx = wl_fixed_to_int(sx_w);
241  const int sy = wl_fixed_to_int(sy_w);
242  SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
243  }
244 }
245 
246 static SDL_bool
247 ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
248 {
249  SDL_WindowData *window_data = input->pointer_focus;
250  SDL_Window *window = window_data->sdlwindow;
251 
252  if (window->hit_test) {
253  const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
254  const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
255 
256  static const uint32_t directions_wl[] = {
257  WL_SHELL_SURFACE_RESIZE_TOP_LEFT, WL_SHELL_SURFACE_RESIZE_TOP,
258  WL_SHELL_SURFACE_RESIZE_TOP_RIGHT, WL_SHELL_SURFACE_RESIZE_RIGHT,
259  WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, WL_SHELL_SURFACE_RESIZE_BOTTOM,
260  WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT, WL_SHELL_SURFACE_RESIZE_LEFT
261  };
262 
263  /* the names are different (ZXDG_TOPLEVEL_V6_RESIZE_EDGE_* vs
264  WL_SHELL_SURFACE_RESIZE_*), but the values are the same. */
265  const uint32_t *directions_zxdg = directions_wl;
266 
267  switch (rc) {
269  if (input->display->shell.xdg) {
270  xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial);
271  } else if (input->display->shell.zxdg) {
272  zxdg_toplevel_v6_move(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial);
273  } else {
274  wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
275  }
276  return SDL_TRUE;
277 
286  if (input->display->shell.xdg) {
287  xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
288  } else if (input->display->shell.zxdg) {
289  zxdg_toplevel_v6_resize(window_data->shell_surface.zxdg.roleobj.toplevel, input->seat, serial, directions_zxdg[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
290  } else {
291  wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions_wl[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
292  }
293  return SDL_TRUE;
294 
295  default: return SDL_FALSE;
296  }
297  }
298 
299  return SDL_FALSE;
300 }
301 
302 static void
303 pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial,
305 {
306  SDL_WindowData *window = input->pointer_focus;
307  enum wl_pointer_button_state state = state_w;
308  uint32_t sdl_button;
309 
310  if (input->pointer_focus) {
311  switch (button) {
312  case BTN_LEFT:
313  sdl_button = SDL_BUTTON_LEFT;
314  if (ProcessHitTest(input, serial)) {
315  return; /* don't pass this event on to app. */
316  }
317  break;
318  case BTN_MIDDLE:
319  sdl_button = SDL_BUTTON_MIDDLE;
320  break;
321  case BTN_RIGHT:
322  sdl_button = SDL_BUTTON_RIGHT;
323  break;
324  case BTN_SIDE:
325  sdl_button = SDL_BUTTON_X1;
326  break;
327  case BTN_EXTRA:
328  sdl_button = SDL_BUTTON_X2;
329  break;
330  default:
331  return;
332  }
333 
334  Wayland_data_device_set_serial(input->data_device, serial);
335 
336  SDL_SendMouseButton(window->sdlwindow, 0,
337  state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
338  }
339 }
340 
341 static void
342 pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
344 {
345  struct SDL_WaylandInput *input = data;
346 
347  pointer_handle_button_common(input, serial, time, button, state_w);
348 }
349 
350 static void
351 pointer_handle_axis_common(struct SDL_WaylandInput *input,
352  uint32_t time, uint32_t axis, wl_fixed_t value)
353 {
354  SDL_WindowData *window = input->pointer_focus;
355  enum wl_pointer_axis a = axis;
356  float x, y;
357 
358  if (input->pointer_focus) {
359  switch (a) {
360  case WL_POINTER_AXIS_VERTICAL_SCROLL:
361  x = 0;
362  y = 0 - (float)wl_fixed_to_double(value);
363  break;
364  case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
365  x = 0 - (float)wl_fixed_to_double(value);
366  y = 0;
367  break;
368  default:
369  return;
370  }
371 
373  }
374 }
375 
376 static void
377 pointer_handle_axis(void *data, struct wl_pointer *pointer,
378  uint32_t time, uint32_t axis, wl_fixed_t value)
379 {
380  struct SDL_WaylandInput *input = data;
381 
382  pointer_handle_axis_common(input, time, axis, value);
383 }
384 
385 static const struct wl_pointer_listener pointer_listener = {
386  pointer_handle_enter,
387  pointer_handle_leave,
388  pointer_handle_motion,
389  pointer_handle_button,
390  pointer_handle_axis,
391  NULL, /* frame */
392  NULL, /* axis_source */
393  NULL, /* axis_stop */
394  NULL, /* axis_discrete */
395 };
396 
397 static void
398 touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial,
399  unsigned int timestamp, struct wl_surface *surface,
400  int id, wl_fixed_t fx, wl_fixed_t fy)
401 {
402  SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);
403  const double dblx = wl_fixed_to_double(fx);
404  const double dbly = wl_fixed_to_double(fy);
405  const float x = dblx / window_data->sdlwindow->w;
406  const float y = dbly / window_data->sdlwindow->h;
407 
408  touch_add(id, x, y, surface);
409 
410  SDL_SendTouch(1, (SDL_FingerID)id, SDL_TRUE, x, y, 1.0f);
411 }
412 
413 static void
414 touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial,
415  unsigned int timestamp, int id)
416 {
417  float x = 0, y = 0;
418 
419  touch_del(id, &x, &y);
420  SDL_SendTouch(1, (SDL_FingerID)id, SDL_FALSE, x, y, 0.0f);
421 }
422 
423 static void
424 touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
425  int id, wl_fixed_t fx, wl_fixed_t fy)
426 {
427  SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
428  const double dblx = wl_fixed_to_double(fx);
429  const double dbly = wl_fixed_to_double(fy);
430  const float x = dblx / window_data->sdlwindow->w;
431  const float y = dbly / window_data->sdlwindow->h;
432 
433  touch_update(id, x, y);
434  SDL_SendTouchMotion(1, (SDL_FingerID)id, x, y, 1.0f);
435 }
436 
437 static void
438 touch_handler_frame(void *data, struct wl_touch *touch)
439 {
440 
441 }
442 
443 static void
444 touch_handler_cancel(void *data, struct wl_touch *touch)
445 {
446 
447 }
448 
449 static const struct wl_touch_listener touch_listener = {
450  touch_handler_down,
451  touch_handler_up,
452  touch_handler_motion,
453  touch_handler_frame,
454  touch_handler_cancel,
455  NULL, /* shape */
456  NULL, /* orientation */
457 };
458 
459 static void
460 keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
462 {
463  struct SDL_WaylandInput *input = data;
464  char *map_str;
465 
466  if (!data) {
467  close(fd);
468  return;
469  }
470 
471  if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
472  close(fd);
473  return;
474  }
475 
476  map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
477  if (map_str == MAP_FAILED) {
478  close(fd);
479  return;
480  }
481 
482  input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
483  map_str,
484  XKB_KEYMAP_FORMAT_TEXT_V1,
485  0);
486  munmap(map_str, size);
487  close(fd);
488 
489  if (!input->xkb.keymap) {
490  fprintf(stderr, "failed to compile keymap\n");
491  return;
492  }
493 
494  input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
495  if (!input->xkb.state) {
496  fprintf(stderr, "failed to create XKB state\n");
497  WAYLAND_xkb_keymap_unref(input->xkb.keymap);
498  input->xkb.keymap = NULL;
499  return;
500  }
501 }
502 
503 static void
504 keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
505  uint32_t serial, struct wl_surface *surface,
506  struct wl_array *keys)
507 {
508  struct SDL_WaylandInput *input = data;
510 
511  if (!surface) {
512  /* enter event for a window we've just destroyed */
513  return;
514  }
515 
516  window = wl_surface_get_user_data(surface);
517 
518  if (window) {
519  input->keyboard_focus = window;
520  window->keyboard_device = input;
521  SDL_SetKeyboardFocus(window->sdlwindow);
522  }
523 }
524 
525 static void
526 keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
527  uint32_t serial, struct wl_surface *surface)
528 {
530 }
531 
532 static void
533 keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
534  uint32_t serial, uint32_t time, uint32_t key,
535  uint32_t state_w)
536 {
537  struct SDL_WaylandInput *input = data;
538  SDL_WindowData *window = input->keyboard_focus;
539  enum wl_keyboard_key_state state = state_w;
540  const xkb_keysym_t *syms;
541  uint32_t scancode;
542  char text[8];
543  int size;
544 
546  scancode = xfree86_scancode_table2[key];
547 
548  // TODO when do we get WL_KEYBOARD_KEY_STATE_REPEAT?
549  if (scancode != SDL_SCANCODE_UNKNOWN)
550  SDL_SendKeyboardKey(state == WL_KEYBOARD_KEY_STATE_PRESSED ?
551  SDL_PRESSED : SDL_RELEASED, scancode);
552  }
553 
554  if (!window || window->keyboard_device != input || !input->xkb.state)
555  return;
556 
557  // TODO can this happen?
558  if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1)
559  return;
560 
561  if (state) {
562  size = WAYLAND_xkb_keysym_to_utf8(syms[0], text, sizeof text);
563 
564  if (size > 0) {
565  text[size] = 0;
566 
567  Wayland_data_device_set_serial(input->data_device, serial);
568 
570  }
571  }
572 }
573 
574 static void
575 keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
576  uint32_t serial, uint32_t mods_depressed,
577  uint32_t mods_latched, uint32_t mods_locked,
578  uint32_t group)
579 {
580  struct SDL_WaylandInput *input = data;
581 
582  WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
583  mods_locked, 0, 0, group);
584 }
585 
586 static const struct wl_keyboard_listener keyboard_listener = {
587  keyboard_handle_keymap,
588  keyboard_handle_enter,
589  keyboard_handle_leave,
590  keyboard_handle_key,
591  keyboard_handle_modifiers,
592  NULL, /* repeat_info */
593 };
594 
595 static void
596 seat_handle_capabilities(void *data, struct wl_seat *seat,
597  enum wl_seat_capability caps)
598 {
599  struct SDL_WaylandInput *input = data;
600 
601  if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
602  input->pointer = wl_seat_get_pointer(seat);
603  input->display->pointer = input->pointer;
604  wl_pointer_set_user_data(input->pointer, input);
605  wl_pointer_add_listener(input->pointer, &pointer_listener,
606  input);
607  } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
608  wl_pointer_destroy(input->pointer);
609  input->pointer = NULL;
610  input->display->pointer = NULL;
611  }
612 
613  if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
614  SDL_AddTouch(1, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch");
615  input->touch = wl_seat_get_touch(seat);
616  wl_touch_set_user_data(input->touch, input);
617  wl_touch_add_listener(input->touch, &touch_listener,
618  input);
619  } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
620  SDL_DelTouch(1);
621  wl_touch_destroy(input->touch);
622  input->touch = NULL;
623  }
624 
625  if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
626  input->keyboard = wl_seat_get_keyboard(seat);
627  wl_keyboard_set_user_data(input->keyboard, input);
628  wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
629  input);
630  } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
631  wl_keyboard_destroy(input->keyboard);
632  input->keyboard = NULL;
633  }
634 }
635 
636 static const struct wl_seat_listener seat_listener = {
637  seat_handle_capabilities,
638  NULL, /* name */
639 };
640 
641 static void
642 data_source_handle_target(void *data, struct wl_data_source *wl_data_source,
643  const char *mime_type)
644 {
645 }
646 
647 static void
648 data_source_handle_send(void *data, struct wl_data_source *wl_data_source,
649  const char *mime_type, int32_t fd)
650 {
652 }
653 
654 static void
655 data_source_handle_cancelled(void *data, struct wl_data_source *wl_data_source)
656 {
658 }
659 
660 static void
661 data_source_handle_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source)
662 {
663 }
664 
665 static void
666 data_source_handle_dnd_finished(void *data, struct wl_data_source *wl_data_source)
667 {
668 }
669 
670 static void
671 data_source_handle_action(void *data, struct wl_data_source *wl_data_source,
672  uint32_t dnd_action)
673 {
674 }
675 
676 static const struct wl_data_source_listener data_source_listener = {
677  data_source_handle_target,
678  data_source_handle_send,
679  data_source_handle_cancelled,
680  data_source_handle_dnd_drop_performed, // Version 3
681  data_source_handle_dnd_finished, // Version 3
682  data_source_handle_action, // Version 3
683 };
684 
687 {
688  SDL_WaylandDataSource *data_source = NULL;
689  SDL_VideoData *driver_data = NULL;
690  struct wl_data_source *id = NULL;
691 
692  if (_this == NULL || _this->driverdata == NULL) {
693  SDL_SetError("Video driver uninitialized");
694  } else {
695  driver_data = _this->driverdata;
696 
697  if (driver_data->data_device_manager != NULL) {
698  id = wl_data_device_manager_create_data_source(
699  driver_data->data_device_manager);
700  }
701 
702  if (id == NULL) {
703  SDL_SetError("Wayland unable to create data source");
704  } else {
705  data_source = SDL_calloc(1, sizeof *data_source);
706  if (data_source == NULL) {
707  SDL_OutOfMemory();
708  wl_data_source_destroy(id);
709  } else {
710  WAYLAND_wl_list_init(&(data_source->mimes));
711  data_source->source = id;
712  wl_data_source_set_user_data(id, data_source);
713  wl_data_source_add_listener(id, &data_source_listener,
714  data_source);
715  }
716  }
717  }
718  return data_source;
719 }
720 
721 static void
722 data_offer_handle_offer(void *data, struct wl_data_offer *wl_data_offer,
723  const char *mime_type)
724 {
725  SDL_WaylandDataOffer *offer = data;
726  Wayland_data_offer_add_mime(offer, mime_type);
727 }
728 
729 static void
730 data_offer_handle_source_actions(void *data, struct wl_data_offer *wl_data_offer,
731  uint32_t source_actions)
732 {
733 }
734 
735 static void
736 data_offer_handle_actions(void *data, struct wl_data_offer *wl_data_offer,
737  uint32_t dnd_action)
738 {
739 }
740 
741 static const struct wl_data_offer_listener data_offer_listener = {
742  data_offer_handle_offer,
743  data_offer_handle_source_actions, // Version 3
744  data_offer_handle_actions, // Version 3
745 };
746 
747 static void
748 data_device_handle_data_offer(void *data, struct wl_data_device *wl_data_device,
749  struct wl_data_offer *id)
750 {
751  SDL_WaylandDataOffer *data_offer = NULL;
752 
753  data_offer = SDL_calloc(1, sizeof *data_offer);
754  if (data_offer == NULL) {
755  SDL_OutOfMemory();
756  } else {
757  data_offer->offer = id;
758  data_offer->data_device = data;
759  WAYLAND_wl_list_init(&(data_offer->mimes));
760  wl_data_offer_set_user_data(id, data_offer);
761  wl_data_offer_add_listener(id, &data_offer_listener, data_offer);
762  }
763 }
764 
765 static void
766 data_device_handle_enter(void *data, struct wl_data_device *wl_data_device,
767  uint32_t serial, struct wl_surface *surface,
768  wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id)
769 {
770  SDL_WaylandDataDevice *data_device = data;
771  SDL_bool has_mime = SDL_FALSE;
772  uint32_t dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
773 
774  data_device->drag_serial = serial;
775 
776  if (id != NULL) {
777  data_device->drag_offer = wl_data_offer_get_user_data(id);
778 
779  /* TODO: SDL Support more mime types */
780  has_mime = Wayland_data_offer_has_mime(
781  data_device->drag_offer, FILE_MIME);
782 
783  /* If drag_mime is NULL this will decline the offer */
784  wl_data_offer_accept(id, serial,
785  (has_mime == SDL_TRUE) ? FILE_MIME : NULL);
786 
787  /* SDL only supports "copy" style drag and drop */
788  if (has_mime == SDL_TRUE) {
789  dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
790  }
791  wl_data_offer_set_actions(data_device->drag_offer->offer,
792  dnd_action, dnd_action);
793  }
794 }
795 
796 static void
797 data_device_handle_leave(void *data, struct wl_data_device *wl_data_device)
798 {
799  SDL_WaylandDataDevice *data_device = data;
800  SDL_WaylandDataOffer *offer = NULL;
801 
802  if (data_device->selection_offer != NULL) {
803  data_device->selection_offer = NULL;
805  }
806 }
807 
808 static void
809 data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
810  uint32_t time, wl_fixed_t x, wl_fixed_t y)
811 {
812 }
813 
814 static void
815 data_device_handle_drop(void *data, struct wl_data_device *wl_data_device)
816 {
817  SDL_WaylandDataDevice *data_device = data;
818  void *buffer = NULL;
819  size_t length = 0;
820 
821  const char *current_uri = NULL;
822  const char *last_char = NULL;
823  char *current_char = NULL;
824 
825  if (data_device->drag_offer != NULL) {
826  /* TODO: SDL Support more mime types */
829 
830  /* uri-list */
831  current_uri = (const char *)buffer;
832  last_char = (const char *)buffer + length;
833  for (current_char = buffer; current_char < last_char; ++current_char) {
834  if (*current_char == '\n' || *current_char == 0) {
835  if (*current_uri != 0 && *current_uri != '#') {
836  *current_char = 0;
837  SDL_SendDropFile(NULL, current_uri);
838  }
839  current_uri = (const char *)current_char + 1;
840  }
841  }
842 
843  SDL_free(buffer);
844  }
845 }
846 
847 static void
848 data_device_handle_selection(void *data, struct wl_data_device *wl_data_device,
849  struct wl_data_offer *id)
850 {
851  SDL_WaylandDataDevice *data_device = data;
852  SDL_WaylandDataOffer *offer = NULL;
853 
854  if (id != NULL) {
855  offer = wl_data_offer_get_user_data(id);
856  }
857 
858  if (data_device->selection_offer != offer) {
860  data_device->selection_offer = offer;
861  }
862 
864 }
865 
866 static const struct wl_data_device_listener data_device_listener = {
867  data_device_handle_data_offer,
868  data_device_handle_enter,
869  data_device_handle_leave,
870  data_device_handle_motion,
871  data_device_handle_drop,
872  data_device_handle_selection
873 };
874 
875 void
877 {
878  struct SDL_WaylandInput *input;
879  SDL_WaylandDataDevice *data_device = NULL;
880 
881  input = SDL_calloc(1, sizeof *input);
882  if (input == NULL)
883  return;
884 
885  input->display = d;
886  input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
887  input->sx_w = wl_fixed_from_int(0);
888  input->sy_w = wl_fixed_from_int(0);
889  d->input = input;
890 
891  if (d->data_device_manager != NULL) {
892  data_device = SDL_calloc(1, sizeof *data_device);
893  if (data_device == NULL) {
894  return;
895  }
896 
897  data_device->data_device = wl_data_device_manager_get_data_device(
898  d->data_device_manager, input->seat
899  );
900  data_device->video_data = d;
901 
902  if (data_device->data_device == NULL) {
903  SDL_free(data_device);
904  } else {
905  wl_data_device_set_user_data(data_device->data_device, data_device);
906  wl_data_device_add_listener(data_device->data_device,
907  &data_device_listener, data_device);
908  input->data_device = data_device;
909  }
910  }
911 
912  wl_seat_add_listener(input->seat, &seat_listener, input);
913  wl_seat_set_user_data(input->seat, input);
914 
915  WAYLAND_wl_display_flush(d->display);
916 }
917 
919 {
920  struct SDL_WaylandInput *input = d->input;
921 
922  if (!input)
923  return;
924 
925  if (input->data_device != NULL) {
927  if (input->data_device->selection_offer != NULL) {
928  Wayland_data_offer_destroy(input->data_device->selection_offer);
929  }
930  if (input->data_device->drag_offer != NULL) {
931  Wayland_data_offer_destroy(input->data_device->drag_offer);
932  }
933  if (input->data_device->data_device != NULL) {
934  wl_data_device_release(input->data_device->data_device);
935  }
936  SDL_free(input->data_device);
937  }
938 
939  if (input->keyboard)
940  wl_keyboard_destroy(input->keyboard);
941 
942  if (input->pointer)
943  wl_pointer_destroy(input->pointer);
944 
945  if (input->touch) {
946  SDL_DelTouch(1);
947  wl_touch_destroy(input->touch);
948  }
949 
950  if (input->seat)
951  wl_seat_destroy(input->seat);
952 
953  if (input->xkb.state)
954  WAYLAND_xkb_state_unref(input->xkb.state);
955 
956  if (input->xkb.keymap)
957  WAYLAND_xkb_keymap_unref(input->xkb.keymap);
958 
959  SDL_free(input);
960  d->input = NULL;
961 }
962 
963 SDL_WaylandDataDevice* Wayland_get_data_device(struct SDL_WaylandInput *input)
964 {
965  if (input == NULL) {
966  return NULL;
967  }
968 
969  return input->data_device;
970 }
971 
972 /* !!! FIXME: just merge these into display_handle_global(). */
974 {
975  d->relative_pointer_manager =
976  wl_registry_bind(d->registry, id,
977  &zwp_relative_pointer_manager_v1_interface, 1);
978 }
979 
981 {
982  if (d->relative_pointer_manager)
983  zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
984 }
985 
987 {
988  d->pointer_constraints =
989  wl_registry_bind(d->registry, id,
990  &zwp_pointer_constraints_v1_interface, 1);
991 }
992 
994 {
995  if (d->pointer_constraints)
996  zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
997 }
998 
999 static void
1000 relative_pointer_handle_relative_motion(void *data,
1001  struct zwp_relative_pointer_v1 *pointer,
1002  uint32_t time_hi,
1003  uint32_t time_lo,
1004  wl_fixed_t dx_w,
1005  wl_fixed_t dy_w,
1006  wl_fixed_t dx_unaccel_w,
1007  wl_fixed_t dy_unaccel_w)
1008 {
1009  struct SDL_WaylandInput *input = data;
1010  SDL_VideoData *d = input->display;
1011  SDL_WindowData *window = input->pointer_focus;
1012  double dx_unaccel;
1013  double dy_unaccel;
1014  double dx;
1015  double dy;
1016 
1017  dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
1018  dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
1019 
1020  /* Add left over fraction from last event. */
1021  dx_unaccel += input->dx_frac;
1022  dy_unaccel += input->dy_frac;
1023 
1024  input->dx_frac = modf(dx_unaccel, &dx);
1025  input->dy_frac = modf(dy_unaccel, &dy);
1026 
1027  if (input->pointer_focus && d->relative_mouse_mode) {
1028  SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
1029  }
1030 }
1031 
1032 static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
1033  relative_pointer_handle_relative_motion,
1034 };
1035 
1036 static void
1037 locked_pointer_locked(void *data,
1038  struct zwp_locked_pointer_v1 *locked_pointer)
1039 {
1040 }
1041 
1042 static void
1043 locked_pointer_unlocked(void *data,
1044  struct zwp_locked_pointer_v1 *locked_pointer)
1045 {
1046 }
1047 
1048 static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
1049  locked_pointer_locked,
1050  locked_pointer_unlocked,
1051 };
1052 
1053 static void
1054 lock_pointer_to_window(SDL_Window *window,
1055  struct SDL_WaylandInput *input)
1056 {
1057  SDL_WindowData *w = window->driverdata;
1058  SDL_VideoData *d = input->display;
1059  struct zwp_locked_pointer_v1 *locked_pointer;
1060 
1061  if (w->locked_pointer)
1062  return;
1063 
1064  locked_pointer =
1065  zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints,
1066  w->surface,
1067  input->pointer,
1068  NULL,
1069  ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
1070  zwp_locked_pointer_v1_add_listener(locked_pointer,
1071  &locked_pointer_listener,
1072  window);
1073 
1074  w->locked_pointer = locked_pointer;
1075 }
1076 
1077 int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
1078 {
1080  SDL_VideoData *d = input->display;
1081  SDL_Window *window;
1082  struct zwp_relative_pointer_v1 *relative_pointer;
1083 
1084  if (!d->relative_pointer_manager)
1085  return -1;
1086 
1087  if (!d->pointer_constraints)
1088  return -1;
1089 
1090  if (!input->pointer)
1091  return -1;
1092 
1093  if (!input->relative_pointer) {
1094  relative_pointer =
1095  zwp_relative_pointer_manager_v1_get_relative_pointer(
1096  d->relative_pointer_manager,
1097  input->pointer);
1098  zwp_relative_pointer_v1_add_listener(relative_pointer,
1099  &relative_pointer_listener,
1100  input);
1101  input->relative_pointer = relative_pointer;
1102  }
1103 
1104  for (window = vd->windows; window; window = window->next)
1105  lock_pointer_to_window(window, input);
1106 
1107  d->relative_mouse_mode = 1;
1108 
1109  return 0;
1110 }
1111 
1112 int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
1113 {
1115  SDL_VideoData *d = input->display;
1116  SDL_Window *window;
1117  SDL_WindowData *w;
1118 
1119  for (window = vd->windows; window; window = window->next) {
1120  w = window->driverdata;
1121  if (w->locked_pointer)
1122  zwp_locked_pointer_v1_destroy(w->locked_pointer);
1123  w->locked_pointer = NULL;
1124  }
1125 
1126  zwp_relative_pointer_v1_destroy(input->relative_pointer);
1127  input->relative_pointer = NULL;
1128 
1129  d->relative_mouse_mode = 0;
1130 
1131  return 0;
1132 }
1133 
1134 #endif /* SDL_VIDEO_DRIVER_WAYLAND */
1135 
1136 /* vi: set ts=4 sw=4 expandtab: */
SDL_HITTEST_DRAGGABLE
@ SDL_HITTEST_DRAGGABLE
Definition: SDL_video.h:1023
SDL_zxdg_shell_surface::toplevel
struct zxdg_toplevel_v6 * toplevel
Definition: SDL_waylandwindow.h:38
SDL_TOUCH_DEVICE_DIRECT
@ SDL_TOUCH_DEVICE_DIRECT
Definition: SDL_touch.h:47
SDL_waylandvideo.h
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
SDL_waylandevents_c.h
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:381
SDL_WaylandDataDevice::data_device
struct wl_data_device * data_device
Definition: SDL_waylanddatamanager.h:52
tail
SDL_EventEntry * tail
Definition: SDL_events.c:81
time
EGLSurface EGLnsecsANDROID time
Definition: eglext.h:518
Wayland_data_offer_receive
void * Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, size_t *length, const char *mime_type, SDL_bool null_terminate)
Wayland_get_data_device
SDL_WaylandDataDevice * Wayland_get_data_device(struct SDL_WaylandInput *input)
NULL
#define NULL
Definition: begin_code.h:167
surface
EGLSurface surface
Definition: eglext.h:248
SDL_BUTTON_RIGHT
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:284
SDL_log.h
SDL_WindowData
Definition: SDL_androidwindow.h:38
SDL_FingerID
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
FILE_MIME
#define FILE_MIME
Definition: SDL_waylanddatamanager.h:31
Wayland_display_add_input
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
SDL_TouchID
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
Wayland_data_source_destroy
void Wayland_data_source_destroy(SDL_WaylandDataSource *source)
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
SDL_WindowData::wl
struct wl_shell_surface * wl
Definition: SDL_waylandwindow.h:60
SDL_HITTEST_RESIZE_TOPLEFT
@ SDL_HITTEST_RESIZE_TOPLEFT
Definition: SDL_video.h:1024
input
GLenum GLenum GLenum input
Definition: SDL_opengl_glext.h:9374
SDL_SendTouch
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:242
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
Wayland_PumpEvents
void Wayland_PumpEvents(_THIS)
pointer
GLsizei const void * pointer
Definition: SDL_opengl_glext.h:378
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
Wayland_display_destroy_input
void Wayland_display_destroy_input(SDL_VideoData *d)
SDL_VideoData::data_device_manager
struct wl_data_device_manager * data_device_manager
Definition: SDL_waylandvideo.h:63
SDL_WaylandDataDevice::drag_serial
uint32_t drag_serial
Definition: SDL_waylanddatamanager.h:56
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:669
Wayland_data_device_clear_selection
int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *device)
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:211
SDL_SendTouchMotion
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:364
SDL_SendKeyboardKey
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:679
SDL_WaylandDataOffer::mimes
struct wl_list mimes
Definition: SDL_waylanddatamanager.h:47
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_BUTTON_X1
#define SDL_BUTTON_X1
Definition: SDL_mouse.h:285
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
SDL_SendClipboardUpdate
int SDL_SendClipboardUpdate(void)
Definition: SDL_clipboardevents.c:31
SDL_SendKeyboardText
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:789
SDL_xdg_shell_surface::roleobj
union SDL_xdg_shell_surface::@265 roleobj
SDL_Window::w
int w
Definition: SDL_sysvideo.h:80
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
SDL_HITTEST_RESIZE_BOTTOMRIGHT
@ SDL_HITTEST_RESIZE_BOTTOMRIGHT
Definition: SDL_video.h:1028
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
buffer
GLuint buffer
Definition: SDL_opengl_glext.h:533
SDL_AddTouch
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
Definition: SDL_touch.c:155
SDL_HITTEST_RESIZE_TOPRIGHT
@ SDL_HITTEST_RESIZE_TOPRIGHT
Definition: SDL_video.h:1026
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
SDL_BUTTON_LEFT
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:282
SDL_HitTestResult
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
Definition: SDL_video.h:1020
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_IOReady
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
Definition: SDL_poll.c:38
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
int32_t
signed int int32_t
Definition: SDL_config_windows.h:62
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
group
GLboolean GLuint group
Definition: SDL_opengl_glext.h:4996
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
SDL_WaylandDataDevice::drag_offer
SDL_WaylandDataOffer * drag_offer
Definition: SDL_waylanddatamanager.h:57
SDL_HITTEST_RESIZE_BOTTOM
@ SDL_HITTEST_RESIZE_BOTTOM
Definition: SDL_video.h:1029
Wayland_display_destroy_pointer_constraints
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
SDL_waylandwindow.h
SDL_SendDropFile
int SDL_SendDropFile(SDL_Window *window, const char *file)
Definition: SDL_dropevents.c:80
SDL_HITTEST_RESIZE_LEFT
@ SDL_HITTEST_RESIZE_LEFT
Definition: SDL_video.h:1031
SDL_SendMouseMotion
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:301
SDL_BUTTON_MIDDLE
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:283
head
SDL_EventEntry * head
Definition: SDL_events.c:80
SDL_assert.h
SDL_WindowData::xdg
SDL_xdg_shell_surface xdg
Definition: SDL_waylandwindow.h:58
key
GLuint64 key
Definition: gl2ext.h:2192
SDL_WaylandDataSource::mimes
struct wl_list mimes
Definition: SDL_waylanddatamanager.h:42
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
Wayland_input_unlock_pointer
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
text
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47
SDL_zxdg_shell_surface::roleobj
union SDL_zxdg_shell_surface::@264 roleobj
Wayland_data_offer_has_mime
SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
SDL_DelTouch
void SDL_DelTouch(SDL_TouchID id)
Definition: SDL_touch.c:449
axis
SDL_Texture * axis
Definition: testgamecontroller.c:67
SDL_Window::h
int h
Definition: SDL_sysvideo.h:80
Wayland_data_source_send
ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source, const char *mime_type, int fd)
Wayland_display_destroy_relative_pointer_manager
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
SDL_WaylandDataOffer::offer
struct wl_data_offer * offer
Definition: SDL_waylanddatamanager.h:46
Wayland_display_add_pointer_constraints
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
SDL_VideoDevice
Definition: SDL_sysvideo.h:148
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_WaylandDataSource::source
struct wl_data_source * source
Definition: SDL_waylanddatamanager.h:41
SDL_SCANCODE_UNKNOWN
@ SDL_SCANCODE_UNKNOWN
Definition: SDL_scancode.h:45
SDL_SendMouseWheel
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
Definition: SDL_mouse.c:611
id
GLuint id
Definition: SDL_opengl_glext.h:528
SDL_HITTEST_RESIZE_RIGHT
@ SDL_HITTEST_RESIZE_RIGHT
Definition: SDL_video.h:1027
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
Wayland_data_source_create
SDL_WaylandDataSource * Wayland_data_source_create(_THIS)
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:63
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_WaylandDataSource
Definition: SDL_waylanddatamanager.h:40
SDL_WaylandDataOffer
Definition: SDL_waylanddatamanager.h:45
SDL_Point
The structure that defines a point (integer)
Definition: SDL_rect.h:48
SDL_Window::next
SDL_Window * next
Definition: SDL_sysvideo.h:114
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
SDL_WindowData::shell_surface
union SDL_WindowData::@266 shell_surface
SDL_waylanddyn.h
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_WindowData::zxdg
SDL_zxdg_shell_surface zxdg
Definition: SDL_waylandwindow.h:59
Wayland_data_device_set_serial
int Wayland_data_device_set_serial(SDL_WaylandDataDevice *device, uint32_t serial)
xfree86_scancode_table2
static const SDL_Scancode xfree86_scancode_table2[]
Definition: scancodes_xfree86.h:183
SDL_WaylandDataDevice::selection_offer
SDL_WaylandDataOffer * selection_offer
Definition: SDL_waylanddatamanager.h:58
SDL_stdinc.h
Wayland_data_offer_add_mime
int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
Wayland_input_lock_pointer
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
SDL_xdg_shell_surface::toplevel
struct xdg_toplevel * toplevel
Definition: SDL_waylandwindow.h:47
Wayland_data_offer_destroy
void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
Wayland_display_add_relative_pointer_manager
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
SDL_MOUSEWHEEL_NORMAL
@ SDL_MOUSEWHEEL_NORMAL
Definition: SDL_mouse.h:68
SDL_GetVideoDevice
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:583
SDL_WindowData::sdlwindow
SDL_Window * sdlwindow
Definition: SDL_waylandwindow.h:54
SDL_BUTTON_X2
#define SDL_BUTTON_X2
Definition: SDL_mouse.h:286
SDL_WaylandDataDevice
Definition: SDL_waylanddatamanager.h:51
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
fd
GLuint64 GLenum GLint fd
Definition: gl2ext.h:1508
SDL_HITTEST_RESIZE_TOP
@ SDL_HITTEST_RESIZE_TOP
Definition: SDL_video.h:1025
state
struct xkb_state * state
Definition: SDL_waylandsym.h:113
button
SDL_Texture * button
Definition: testgamecontroller.c:67
SDL_HITTEST_RESIZE_BOTTOMLEFT
@ SDL_HITTEST_RESIZE_BOTTOMLEFT
Definition: SDL_video.h:1030
SDL_WaylandDataOffer::data_device
void * data_device
Definition: SDL_waylanddatamanager.h:48
SDL_SendMouseButton
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:605
SDL_WaylandDataDevice::video_data
SDL_VideoData * video_data
Definition: SDL_waylanddatamanager.h:53
SDL_VideoData
Definition: SDL_androidvideo.h:36
d
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING 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
Definition: SDL_dynapi_procs.h:117
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
SDL_VideoDevice::windows
SDL_Window * windows
Definition: SDL_sysvideo.h:317
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731