Go to the documentation of this file.
22 #include "../../SDL_internal.h"
24 #if SDL_VIDEO_DRIVER_WAYLAND
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"
46 #include <linux/input.h>
47 #include <sys/select.h>
51 #include <xkbcommon/xkbcommon.h>
53 struct SDL_WaylandInput {
57 struct wl_touch *touch;
58 struct wl_keyboard *keyboard;
60 struct zwp_relative_pointer_v1 *relative_pointer;
72 struct xkb_keymap *keymap;
73 struct xkb_state *
state;
77 struct SDL_WaylandTouchPoint {
83 struct SDL_WaylandTouchPoint* prev;
84 struct SDL_WaylandTouchPoint* next;
87 struct SDL_WaylandTouchPointList {
88 struct SDL_WaylandTouchPoint*
head;
89 struct SDL_WaylandTouchPoint*
tail;
92 static struct SDL_WaylandTouchPointList touch_points = {
NULL,
NULL};
97 struct SDL_WaylandTouchPoint* tp =
SDL_malloc(
sizeof(
struct SDL_WaylandTouchPoint));
104 if (touch_points.tail) {
105 touch_points.tail->next = tp;
106 tp->prev = touch_points.tail;
108 touch_points.head = tp;
112 touch_points.tail = tp;
119 struct SDL_WaylandTouchPoint* tp = touch_points.head;
134 struct SDL_WaylandTouchPoint* tp = touch_points.head;
142 tp->prev->next = tp->next;
144 touch_points.head = tp->next;
148 tp->next->prev = tp->prev;
150 touch_points.tail = tp->prev;
160 static struct wl_surface*
163 struct SDL_WaylandTouchPoint* tp = touch_points.head;
181 WAYLAND_wl_display_flush(
d->display);
184 WAYLAND_wl_display_dispatch(
d->display);
188 WAYLAND_wl_display_dispatch_pending(
d->display);
193 pointer_handle_enter(
void *
data,
struct wl_pointer *
pointer,
195 wl_fixed_t sx_w, wl_fixed_t sy_w)
220 pointer_handle_leave(
void *
data,
struct wl_pointer *
pointer,
225 if (
input->pointer_focus) {
232 pointer_handle_motion(
void *
data,
struct wl_pointer *
pointer,
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);
247 ProcessHitTest(
struct SDL_WaylandInput *
input,
uint32_t serial)
256 static const uint32_t directions_wl[] = {
265 const uint32_t *directions_zxdg = directions_wl;
269 if (
input->display->shell.xdg) {
271 }
else if (
input->display->shell.zxdg) {
286 if (
input->display->shell.xdg) {
288 }
else if (
input->display->shell.zxdg) {
303 pointer_handle_button_common(
struct SDL_WaylandInput *
input,
uint32_t serial,
310 if (
input->pointer_focus) {
314 if (ProcessHitTest(
input, serial)) {
351 pointer_handle_axis_common(
struct SDL_WaylandInput *
input,
358 if (
input->pointer_focus) {
362 y = 0 - (float)wl_fixed_to_double(
value);
365 x = 0 - (float)wl_fixed_to_double(
value);
377 pointer_handle_axis(
void *
data,
struct wl_pointer *
pointer,
386 pointer_handle_enter,
387 pointer_handle_leave,
388 pointer_handle_motion,
389 pointer_handle_button,
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)
407 x = wl_fixed_to_double(fx) /
window->sdlwindow->w;
408 y = wl_fixed_to_double(fy) /
window->sdlwindow->h;
415 touch_handler_up(
void *
data,
struct wl_touch *touch,
unsigned int serial,
416 unsigned int timestamp,
int id)
420 touch_del(
id, &
x, &
y);
425 touch_handler_motion(
void *
data,
struct wl_touch *touch,
unsigned int timestamp,
426 int id, wl_fixed_t fx, wl_fixed_t fy)
433 x = wl_fixed_to_double(fx) /
window->sdlwindow->w;
434 y = wl_fixed_to_double(fy) /
window->sdlwindow->h;
436 touch_update(
id,
x,
y);
441 touch_handler_frame(
void *
data,
struct wl_touch *touch)
447 touch_handler_cancel(
void *
data,
struct wl_touch *touch)
455 touch_handler_motion,
457 touch_handler_cancel,
463 keyboard_handle_keymap(
void *
data,
struct wl_keyboard *keyboard,
479 map_str = mmap(
NULL,
size, PROT_READ, MAP_SHARED,
fd, 0);
480 if (map_str == MAP_FAILED) {
485 input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(
input->display->xkb_context,
487 XKB_KEYMAP_FORMAT_TEXT_V1,
489 munmap(map_str,
size);
492 if (!
input->xkb.keymap) {
493 fprintf(stderr,
"failed to compile keymap\n");
497 input->xkb.state = WAYLAND_xkb_state_new(
input->xkb.keymap);
498 if (!
input->xkb.state) {
499 fprintf(stderr,
"failed to create XKB state\n");
500 WAYLAND_xkb_keymap_unref(
input->xkb.keymap);
507 keyboard_handle_enter(
void *
data,
struct wl_keyboard *keyboard,
509 struct wl_array *keys)
529 keyboard_handle_leave(
void *
data,
struct wl_keyboard *keyboard,
536 keyboard_handle_key(
void *
data,
struct wl_keyboard *keyboard,
543 const xkb_keysym_t *syms;
561 if (WAYLAND_xkb_state_key_get_syms(
input->xkb.state,
key + 8, &syms) != 1)
565 size = WAYLAND_xkb_keysym_to_utf8(syms[0],
text,
sizeof text);
578 keyboard_handle_modifiers(
void *
data,
struct wl_keyboard *keyboard,
585 WAYLAND_xkb_state_update_mask(
input->xkb.state, mods_depressed, mods_latched,
586 mods_locked, 0, 0,
group);
590 keyboard_handle_keymap,
591 keyboard_handle_enter,
592 keyboard_handle_leave,
594 keyboard_handle_modifiers,
599 seat_handle_capabilities(
void *
data,
struct wl_seat *seat,
640 seat_handle_capabilities,
645 data_source_handle_target(
void *
data,
struct wl_data_source *wl_data_source,
646 const char *mime_type)
651 data_source_handle_send(
void *
data,
struct wl_data_source *wl_data_source,
658 data_source_handle_cancelled(
void *
data,
struct wl_data_source *wl_data_source)
664 data_source_handle_dnd_drop_performed(
void *
data,
struct wl_data_source *wl_data_source)
669 data_source_handle_dnd_finished(
void *
data,
struct wl_data_source *wl_data_source)
674 data_source_handle_action(
void *
data,
struct wl_data_source *wl_data_source,
680 data_source_handle_target,
681 data_source_handle_send,
682 data_source_handle_cancelled,
683 data_source_handle_dnd_drop_performed,
684 data_source_handle_dnd_finished,
685 data_source_handle_action,
693 struct wl_data_source *
id =
NULL;
708 data_source =
SDL_calloc(1,
sizeof *data_source);
709 if (data_source ==
NULL) {
713 WAYLAND_wl_list_init(&(data_source->
mimes));
725 data_offer_handle_offer(
void *
data,
struct wl_data_offer *wl_data_offer,
726 const char *mime_type)
733 data_offer_handle_source_actions(
void *
data,
struct wl_data_offer *wl_data_offer,
739 data_offer_handle_actions(
void *
data,
struct wl_data_offer *wl_data_offer,
745 data_offer_handle_offer,
746 data_offer_handle_source_actions,
747 data_offer_handle_actions,
751 data_device_handle_data_offer(
void *
data,
struct wl_data_device *wl_data_device,
752 struct wl_data_offer *
id)
756 data_offer =
SDL_calloc(1,
sizeof *data_offer);
757 if (data_offer ==
NULL) {
762 WAYLAND_wl_list_init(&(data_offer->
mimes));
769 data_device_handle_enter(
void *
data,
struct wl_data_device *wl_data_device,
771 wl_fixed_t
x, wl_fixed_t
y,
struct wl_data_offer *
id)
795 dnd_action, dnd_action);
800 data_device_handle_leave(
void *
data,
struct wl_data_device *wl_data_device)
812 data_device_handle_motion(
void *
data,
struct wl_data_device *wl_data_device,
818 data_device_handle_drop(
void *
data,
struct wl_data_device *wl_data_device)
824 const char *current_uri =
NULL;
825 const char *last_char =
NULL;
826 char *current_char =
NULL;
834 current_uri = (
const char *)
buffer;
836 for (current_char =
buffer; current_char < last_char; ++current_char) {
837 if (*current_char ==
'\n' || *current_char == 0) {
838 if (*current_uri != 0 && *current_uri !=
'#') {
842 current_uri = (
const char *)current_char + 1;
851 data_device_handle_selection(
void *
data,
struct wl_data_device *wl_data_device,
852 struct wl_data_offer *
id)
870 data_device_handle_data_offer,
871 data_device_handle_enter,
872 data_device_handle_leave,
873 data_device_handle_motion,
874 data_device_handle_drop,
875 data_device_handle_selection
881 struct SDL_WaylandInput *
input;
890 input->sx_w = wl_fixed_from_int(0);
891 input->sy_w = wl_fixed_from_int(0);
894 if (
d->data_device_manager !=
NULL) {
895 data_device =
SDL_calloc(1,
sizeof *data_device);
896 if (data_device ==
NULL) {
901 d->data_device_manager,
input->seat
910 &data_device_listener, data_device);
911 input->data_device = data_device;
918 WAYLAND_wl_display_flush(
d->display);
923 struct SDL_WaylandInput *
input =
d->input;
930 if (
input->data_device->selection_offer !=
NULL) {
933 if (
input->data_device->drag_offer !=
NULL) {
936 if (
input->data_device->data_device !=
NULL) {
956 if (
input->xkb.state)
957 WAYLAND_xkb_state_unref(
input->xkb.state);
959 if (
input->xkb.keymap)
960 WAYLAND_xkb_keymap_unref(
input->xkb.keymap);
972 return input->data_device;
978 d->relative_pointer_manager =
985 if (
d->relative_pointer_manager)
991 d->pointer_constraints =
998 if (
d->pointer_constraints)
1003 relative_pointer_handle_relative_motion(
void *
data,
1004 struct zwp_relative_pointer_v1 *
pointer,
1009 wl_fixed_t dx_unaccel_w,
1010 wl_fixed_t dy_unaccel_w)
1020 dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
1021 dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
1024 dx_unaccel +=
input->dx_frac;
1025 dy_unaccel +=
input->dy_frac;
1027 input->dx_frac = modf(dx_unaccel, &dx);
1028 input->dy_frac = modf(dy_unaccel, &dy);
1030 if (
input->pointer_focus &&
d->relative_mouse_mode) {
1036 relative_pointer_handle_relative_motion,
1040 locked_pointer_locked(
void *
data,
1041 struct zwp_locked_pointer_v1 *locked_pointer)
1046 locked_pointer_unlocked(
void *
data,
1047 struct zwp_locked_pointer_v1 *locked_pointer)
1052 locked_pointer_locked,
1053 locked_pointer_unlocked,
1058 struct SDL_WaylandInput *
input)
1062 struct zwp_locked_pointer_v1 *locked_pointer;
1064 if (
w->locked_pointer)
1074 &locked_pointer_listener,
1077 w->locked_pointer = locked_pointer;
1085 struct zwp_relative_pointer_v1 *relative_pointer;
1087 if (!
d->relative_pointer_manager)
1090 if (!
d->pointer_constraints)
1093 if (!
input->relative_pointer) {
1096 d->relative_pointer_manager,
1099 &relative_pointer_listener,
1101 input->relative_pointer = relative_pointer;
1107 d->relative_mouse_mode = 1;
1121 if (
w->locked_pointer)
1123 w->locked_pointer =
NULL;
1129 d->relative_mouse_mode = 0;
static void * wl_data_offer_get_user_data(struct wl_data_offer *wl_data_offer)
struct zxdg_toplevel_v6 * toplevel
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)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
@ WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1
static void wl_seat_destroy(struct wl_seat *wl_seat)
struct wl_data_device * data_device
static struct wl_keyboard * wl_seat_get_keyboard(struct wl_seat *wl_seat)
@ WL_SHELL_SURFACE_RESIZE_TOP_RIGHT
EGLSurface EGLnsecsANDROID time
void * Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, size_t *length, const char *mime_type, SDL_bool null_terminate)
static void zxdg_toplevel_v6_resize(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, struct wl_seat *seat, uint32_t serial, uint32_t edges)
SDL_WaylandDataDevice * Wayland_get_data_device(struct SDL_WaylandInput *input)
@ WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT
@ WL_SEAT_CAPABILITY_KEYBOARD
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 zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
union SDL_xdg_shell_surface::@37 roleobj
static void wl_touch_set_user_data(struct wl_touch *wl_touch, void *user_data)
@ WL_SHELL_SURFACE_RESIZE_LEFT
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
static void * wl_surface_get_user_data(struct wl_surface *wl_surface)
@ WL_KEYBOARD_KEY_STATE_PRESSED
void Wayland_data_source_destroy(SDL_WaylandDataSource *source)
static void wl_seat_set_user_data(struct wl_seat *wl_seat, void *user_data)
void SDL_SetKeyboardFocus(SDL_Window *window)
struct wl_shell_surface * wl
static void zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
static void zwp_relative_pointer_v1_destroy(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1)
@ SDL_HITTEST_RESIZE_TOPLEFT
GLenum GLenum GLenum input
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
GLboolean GLboolean GLboolean GLboolean a
void Wayland_PumpEvents(_THIS)
GLsizei const void * pointer
void Wayland_display_destroy_input(SDL_VideoData *d)
@ WL_SHELL_SURFACE_RESIZE_BOTTOM
struct wl_data_device_manager * data_device_manager
GLuint GLsizei GLsizei * length
int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *device)
void SDL_SetMouseFocus(SDL_Window *window)
static void wl_pointer_destroy(struct wl_pointer *wl_pointer)
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
The type used to identify a window.
int SDL_SendClipboardUpdate(void)
static void * wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version)
static int wl_data_device_add_listener(struct wl_data_device *wl_data_device, const struct wl_data_device_listener *listener, void *data)
int SDL_SendKeyboardText(const char *text)
static void wl_data_device_set_user_data(struct wl_data_device *wl_data_device, void *user_data)
static void xdg_toplevel_move(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial)
static void zwp_relative_pointer_manager_v1_destroy(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1)
@ SDL_HITTEST_RESIZE_BOTTOMRIGHT
@ WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE
static void wl_data_source_set_user_data(struct wl_data_source *wl_data_source, void *user_data)
@ SDL_HITTEST_RESIZE_TOPRIGHT
static SDL_VideoDevice * _this
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)
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
GLint GLint GLint GLint GLint x
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
EGLSurface EGLNativeWindowType * window
static void wl_shell_surface_move(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial)
@ WL_SHELL_SURFACE_RESIZE_RIGHT
@ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT
static struct wl_pointer * wl_seat_get_pointer(struct wl_seat *wl_seat)
SDL_WaylandDataOffer * drag_offer
@ SDL_HITTEST_RESIZE_BOTTOM
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
static void wl_pointer_set_user_data(struct wl_pointer *wl_pointer, void *user_data)
int SDL_SendDropFile(SDL_Window *window, const char *file)
@ SDL_HITTEST_RESIZE_LEFT
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
static void wl_data_device_release(struct wl_data_device *wl_data_device)
#define SDL_BUTTON_MIDDLE
@ WL_SEAT_CAPABILITY_TOUCH
SDL_xdg_shell_surface xdg
static int wl_touch_add_listener(struct wl_touch *wl_touch, const struct wl_touch_listener *listener, void *data)
@ WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT
@ WL_POINTER_AXIS_VERTICAL_SCROLL
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)
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
static char text[MAX_TEXT_LENGTH]
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
static void wl_touch_destroy(struct wl_touch *wl_touch)
static void wl_data_offer_accept(struct wl_data_offer *wl_data_offer, uint32_t serial, const char *mime_type)
static void wl_keyboard_destroy(struct wl_keyboard *wl_keyboard)
void SDL_DelTouch(SDL_TouchID id)
const struct wl_interface zwp_pointer_constraints_v1_interface
static int wl_pointer_add_listener(struct wl_pointer *wl_pointer, const struct wl_pointer_listener *listener, void *data)
ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source, const char *mime_type, int fd)
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
struct wl_data_offer * offer
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
#define SDL_OutOfMemory()
GLint GLint GLint GLint GLint GLint y
struct wl_data_source * source
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
@ SDL_HITTEST_RESIZE_RIGHT
#define SDL_arraysize(array)
static int wl_seat_add_listener(struct wl_seat *wl_seat, const struct wl_seat_listener *listener, void *data)
SDL_WaylandDataSource * Wayland_data_source_create(_THIS)
static void wl_data_source_destroy(struct wl_data_source *wl_data_source)
static void xdg_toplevel_resize(struct xdg_toplevel *xdg_toplevel, struct wl_seat *seat, uint32_t serial, uint32_t edges)
@ WL_POINTER_AXIS_HORIZONTAL_SCROLL
static void wl_keyboard_set_user_data(struct wl_keyboard *wl_keyboard, void *user_data)
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)
void(* offer)(void *data, struct wl_data_offer *wl_data_offer, const char *mime_type)
The structure that defines a point.
static int wl_keyboard_add_listener(struct wl_keyboard *wl_keyboard, const struct wl_keyboard_listener *listener, void *data)
GLsizei const GLfloat * value
static struct wl_touch * wl_seat_get_touch(struct wl_seat *wl_seat)
union SDL_WindowData::@38 shell_surface
SDL_zxdg_shell_surface zxdg
int Wayland_data_device_set_serial(SDL_WaylandDataDevice *device, uint32_t serial)
static const SDL_Scancode xfree86_scancode_table2[]
SDL_WaylandDataOffer * selection_offer
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 struct wl_data_source * wl_data_device_manager_create_data_source(struct wl_data_device_manager *wl_data_device_manager)
@ WL_SEAT_CAPABILITY_POINTER
int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
struct xdg_toplevel * toplevel
void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
@ WL_SHELL_SURFACE_RESIZE_TOP_LEFT
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
static void wl_data_offer_set_actions(struct wl_data_offer *wl_data_offer, uint32_t dnd_actions, uint32_t preferred_action)
SDL_VideoDevice * SDL_GetVideoDevice(void)
union SDL_zxdg_shell_surface::@36 roleobj
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)
@ WL_SHELL_SURFACE_RESIZE_TOP
static void zxdg_toplevel_v6_move(struct zxdg_toplevel_v6 *zxdg_toplevel_v6, struct wl_seat *seat, uint32_t serial)
@ WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY
const struct wl_interface wl_seat_interface
@ SDL_HITTEST_RESIZE_BOTTOMLEFT
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
const struct wl_interface zwp_relative_pointer_manager_v1_interface
SDL_VideoData * video_data
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
GLubyte GLubyte GLubyte GLubyte w