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" 44 #include <linux/input.h> 45 #include <sys/select.h> 49 #include <xkbcommon/xkbcommon.h> 51 struct SDL_WaylandInput {
55 struct wl_touch *touch;
56 struct wl_keyboard *keyboard;
58 struct zwp_relative_pointer_v1 *relative_pointer;
70 struct xkb_keymap *keymap;
71 struct xkb_state *
state;
75 struct SDL_WaylandTouchPoint {
81 struct SDL_WaylandTouchPoint* prev;
82 struct SDL_WaylandTouchPoint* next;
85 struct SDL_WaylandTouchPointList {
86 struct SDL_WaylandTouchPoint*
head;
87 struct SDL_WaylandTouchPoint*
tail;
90 static struct SDL_WaylandTouchPointList touch_points = {
NULL,
NULL};
95 struct SDL_WaylandTouchPoint* tp =
SDL_malloc(
sizeof(
struct SDL_WaylandTouchPoint));
102 if (touch_points.tail) {
103 touch_points.tail->next = tp;
104 tp->prev = touch_points.tail;
106 touch_points.head = tp;
110 touch_points.tail = tp;
117 struct SDL_WaylandTouchPoint* tp = touch_points.head;
132 struct SDL_WaylandTouchPoint* tp = touch_points.head;
140 tp->prev->next = tp->next;
142 touch_points.head = tp->next;
146 tp->next->prev = tp->prev;
148 touch_points.tail = tp->prev;
158 static struct wl_surface*
161 struct SDL_WaylandTouchPoint* tp = touch_points.head;
180 WAYLAND_wl_display_dispatch(d->
display);
184 WAYLAND_wl_display_dispatch_pending(d->
display);
189 pointer_handle_enter(
void *
data,
struct wl_pointer *
pointer,
190 uint32_t serial,
struct wl_surface *surface,
191 wl_fixed_t sx_w, wl_fixed_t sy_w)
210 input->pointer_focus =
window;
216 pointer_handle_leave(
void *data,
struct wl_pointer *pointer,
217 uint32_t serial,
struct wl_surface *surface)
219 struct SDL_WaylandInput *input =
data;
221 if (input->pointer_focus) {
223 input->pointer_focus =
NULL;
228 pointer_handle_motion(
void *data,
struct wl_pointer *pointer,
231 struct SDL_WaylandInput *input =
data;
235 if (input->pointer_focus) {
236 const int sx = wl_fixed_to_int(sx_w);
237 const int sy = wl_fixed_to_int(sy_w);
243 ProcessHitTest(
struct SDL_WaylandInput *input,
uint32_t serial)
249 const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
251 static const uint32_t directions[] = {
281 pointer_handle_button_common(
struct SDL_WaylandInput *input,
uint32_t serial,
288 if (input->pointer_focus) {
292 if (ProcessHitTest(input, serial)) {
320 pointer_handle_button(
void *data,
struct wl_pointer *pointer,
uint32_t serial,
323 struct SDL_WaylandInput *input =
data;
325 pointer_handle_button_common(input, serial, time, button, state_w);
329 pointer_handle_axis_common(
struct SDL_WaylandInput *input,
336 if (input->pointer_focus) {
340 y = (float)wl_fixed_to_double(value);
343 x = (float)wl_fixed_to_double(value);
355 pointer_handle_axis(
void *data,
struct wl_pointer *pointer,
358 struct SDL_WaylandInput *input =
data;
360 pointer_handle_axis_common(input, time, axis, value);
364 pointer_handle_enter,
365 pointer_handle_leave,
366 pointer_handle_motion,
367 pointer_handle_button,
376 touch_handler_down(
void *data,
struct wl_touch *touch,
unsigned int serial,
377 unsigned int timestamp,
struct wl_surface *surface,
378 int id, wl_fixed_t fx, wl_fixed_t fy)
385 x = wl_fixed_to_double(fx) / window->
sdlwindow->
w;
386 y = wl_fixed_to_double(fy) / window->
sdlwindow->
h;
388 touch_add(
id, x, y, surface);
393 touch_handler_up(
void *data,
struct wl_touch *touch,
unsigned int serial,
394 unsigned int timestamp,
int id)
398 touch_del(
id, &x, &y);
403 touch_handler_motion(
void *data,
struct wl_touch *touch,
unsigned int timestamp,
404 int id, wl_fixed_t fx, wl_fixed_t fy)
411 x = wl_fixed_to_double(fx) / window->
sdlwindow->
w;
412 y = wl_fixed_to_double(fy) / window->
sdlwindow->
h;
414 touch_update(
id, x, y);
419 touch_handler_frame(
void *data,
struct wl_touch *touch)
425 touch_handler_cancel(
void *data,
struct wl_touch *touch)
433 touch_handler_motion,
435 touch_handler_cancel,
441 keyboard_handle_keymap(
void *data,
struct wl_keyboard *keyboard,
444 struct SDL_WaylandInput *input =
data;
457 map_str = mmap(
NULL, size, PROT_READ, MAP_SHARED, fd, 0);
458 if (map_str == MAP_FAILED) {
463 input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
465 XKB_KEYMAP_FORMAT_TEXT_V1,
467 munmap(map_str, size);
470 if (!input->xkb.keymap) {
471 fprintf(stderr,
"failed to compile keymap\n");
475 input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
476 if (!input->xkb.state) {
477 fprintf(stderr,
"failed to create XKB state\n");
478 WAYLAND_xkb_keymap_unref(input->xkb.keymap);
479 input->xkb.keymap =
NULL;
485 keyboard_handle_enter(
void *data,
struct wl_keyboard *keyboard,
486 uint32_t serial,
struct wl_surface *surface,
487 struct wl_array *keys)
489 struct SDL_WaylandInput *input =
data;
500 input->keyboard_focus =
window;
507 keyboard_handle_leave(
void *data,
struct wl_keyboard *keyboard,
508 uint32_t serial,
struct wl_surface *surface)
514 keyboard_handle_key(
void *data,
struct wl_keyboard *keyboard,
518 struct SDL_WaylandInput *input =
data;
521 const xkb_keysym_t *syms;
539 if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1)
543 size = WAYLAND_xkb_keysym_to_utf8(syms[0], text,
sizeof text);
556 keyboard_handle_modifiers(
void *data,
struct wl_keyboard *keyboard,
561 struct SDL_WaylandInput *input =
data;
563 WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
564 mods_locked, 0, 0, group);
568 keyboard_handle_keymap,
569 keyboard_handle_enter,
570 keyboard_handle_leave,
572 keyboard_handle_modifiers,
577 seat_handle_capabilities(
void *data,
struct wl_seat *seat,
580 struct SDL_WaylandInput *input =
data;
584 input->display->pointer = input->pointer;
588 }
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
590 input->pointer =
NULL;
599 }
else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
610 }
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
612 input->keyboard =
NULL;
617 seat_handle_capabilities,
622 data_source_handle_target(
void *data,
struct wl_data_source *wl_data_source,
623 const char *mime_type)
628 data_source_handle_send(
void *data,
struct wl_data_source *wl_data_source,
629 const char *mime_type,
int32_t fd)
635 data_source_handle_cancelled(
void *data,
struct wl_data_source *wl_data_source)
641 data_source_handle_dnd_drop_performed(
void *data,
struct wl_data_source *wl_data_source)
646 data_source_handle_dnd_finished(
void *data,
struct wl_data_source *wl_data_source)
651 data_source_handle_action(
void *data,
struct wl_data_source *wl_data_source,
657 data_source_handle_target,
658 data_source_handle_send,
659 data_source_handle_cancelled,
660 data_source_handle_dnd_drop_performed,
661 data_source_handle_dnd_finished,
662 data_source_handle_action,
670 struct wl_data_source *
id =
NULL;
685 data_source =
SDL_calloc(1,
sizeof *data_source);
686 if (data_source ==
NULL) {
690 WAYLAND_wl_list_init(&(data_source->
mimes));
702 data_offer_handle_offer(
void *data,
struct wl_data_offer *wl_data_offer,
703 const char *mime_type)
710 data_offer_handle_source_actions(
void *data,
struct wl_data_offer *wl_data_offer,
716 data_offer_handle_actions(
void *data,
struct wl_data_offer *wl_data_offer,
722 data_offer_handle_offer,
723 data_offer_handle_source_actions,
724 data_offer_handle_actions,
728 data_device_handle_data_offer(
void *data,
struct wl_data_device *wl_data_device,
729 struct wl_data_offer *
id)
733 data_offer =
SDL_calloc(1,
sizeof *data_offer);
734 if (data_offer ==
NULL) {
739 WAYLAND_wl_list_init(&(data_offer->
mimes));
746 data_device_handle_enter(
void *data,
struct wl_data_device *wl_data_device,
747 uint32_t serial,
struct wl_surface *surface,
748 wl_fixed_t x, wl_fixed_t y,
struct wl_data_offer *
id)
772 dnd_action, dnd_action);
777 data_device_handle_leave(
void *data,
struct wl_data_device *wl_data_device)
789 data_device_handle_motion(
void *data,
struct wl_data_device *wl_data_device,
790 uint32_t time, wl_fixed_t x, wl_fixed_t y)
795 data_device_handle_drop(
void *data,
struct wl_data_device *wl_data_device)
801 const char *current_uri =
NULL;
802 const char *last_char =
NULL;
803 char *current_char =
NULL;
811 current_uri = (
const char *)buffer;
812 last_char = (
const char *)buffer + length;
813 for (current_char = buffer; current_char < last_char; ++current_char) {
814 if (*current_char ==
'\n' || *current_char == 0) {
815 if (*current_uri != 0 && *current_uri !=
'#') {
819 current_uri = (
const char *)current_char + 1;
828 data_device_handle_selection(
void *data,
struct wl_data_device *wl_data_device,
829 struct wl_data_offer *
id)
847 data_device_handle_data_offer,
848 data_device_handle_enter,
849 data_device_handle_leave,
850 data_device_handle_motion,
851 data_device_handle_drop,
852 data_device_handle_selection
858 struct SDL_WaylandInput *
input;
867 input->sx_w = wl_fixed_from_int(0);
868 input->sy_w = wl_fixed_from_int(0);
872 data_device =
SDL_calloc(1,
sizeof *data_device);
873 if (data_device ==
NULL) {
887 &data_device_listener, data_device);
888 input->data_device = data_device;
895 WAYLAND_wl_display_flush(d->
display);
900 struct SDL_WaylandInput *input = d->
input;
905 if (input->data_device !=
NULL) {
907 if (input->data_device->selection_offer !=
NULL) {
910 if (input->data_device->drag_offer !=
NULL) {
913 if (input->data_device->data_device !=
NULL) {
933 if (input->xkb.state)
934 WAYLAND_xkb_state_unref(input->xkb.state);
936 if (input->xkb.keymap)
937 WAYLAND_xkb_keymap_unref(input->xkb.keymap);
949 return input->data_device;
979 relative_pointer_handle_relative_motion(
void *data,
980 struct zwp_relative_pointer_v1 *pointer,
985 wl_fixed_t dx_unaccel_w,
986 wl_fixed_t dy_unaccel_w)
988 struct SDL_WaylandInput *input =
data;
996 dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
997 dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
1000 dx_unaccel += input->dx_frac;
1001 dy_unaccel += input->dy_frac;
1003 input->dx_frac = modf(dx_unaccel, &dx);
1004 input->dy_frac = modf(dy_unaccel, &dy);
1012 relative_pointer_handle_relative_motion,
1016 locked_pointer_locked(
void *data,
1017 struct zwp_locked_pointer_v1 *locked_pointer)
1022 locked_pointer_unlocked(
void *data,
1023 struct zwp_locked_pointer_v1 *locked_pointer)
1028 locked_pointer_locked,
1029 locked_pointer_unlocked,
1034 struct SDL_WaylandInput *input)
1038 struct zwp_locked_pointer_v1 *locked_pointer;
1050 &locked_pointer_listener,
1061 struct zwp_relative_pointer_v1 *relative_pointer;
1069 if (!input->relative_pointer) {
1075 &relative_pointer_listener,
1077 input->relative_pointer = relative_pointer;
1080 for (window = vd->
windows; window; window = window->
next)
1081 lock_pointer_to_window(window, input);
1095 for (window = vd->
windows; window; window = window->
next) {
1103 input->relative_pointer =
NULL;
static struct wl_data_source * wl_data_device_manager_create_data_source(struct wl_data_device_manager *wl_data_device_manager)
ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source, const char *mime_type, int fd)
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
struct zwp_relative_pointer_manager_v1 * relative_pointer_manager
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
void SDL_SetKeyboardFocus(SDL_Window *window)
EGLSurface EGLnsecsANDROID time
SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
GLint GLint GLint GLint GLint x
static void wl_pointer_destroy(struct wl_pointer *wl_pointer)
int SDL_SendDropFile(SDL_Window *window, const char *file)
struct wl_display * display
const struct wl_interface zwp_relative_pointer_manager_v1_interface
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
The structure that defines a point.
static void * wl_registry_bind(struct wl_registry *wl_registry, uint32_t name, const struct wl_interface *interface, uint32_t version)
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
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 void wl_data_offer_set_user_data(struct wl_data_offer *wl_data_offer, void *user_data)
static int wl_data_source_add_listener(struct wl_data_source *wl_data_source, const struct wl_data_source_listener *listener, void *data)
static const SDL_Scancode xfree86_scancode_table2[]
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
void SDL_SetMouseFocus(SDL_Window *window)
struct wl_data_source * source
struct SDL_WaylandInput * input
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 wl_seat_destroy(struct wl_seat *wl_seat)
static struct wl_touch * wl_seat_get_touch(struct wl_seat *wl_seat)
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
static SDL_VideoDevice * _this
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
static void wl_data_offer_accept(struct wl_data_offer *wl_data_offer, uint32_t serial, const char *mime_type)
struct SDL_WaylandInput * keyboard_device
void(* offer)(void *data, struct wl_data_offer *wl_data_offer, const char *mime_type)
void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer)
const struct wl_interface zwp_pointer_constraints_v1_interface
struct wl_data_device_manager * data_device_manager
GLenum GLenum GLenum input
static void * wl_data_offer_get_user_data(struct wl_data_offer *wl_data_offer)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
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
static void zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
void Wayland_data_source_destroy(SDL_WaylandDataSource *source)
int SDL_SendClipboardUpdate(void)
int SDL_SendKeyboardText(const char *text)
int Wayland_data_device_set_serial(SDL_WaylandDataDevice *device, uint32_t serial)
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)
struct wl_shell_surface * shell_surface
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
void SDL_DelTouch(SDL_TouchID id)
SDL_WaylandDataSource * Wayland_data_source_create(_THIS)
#define SDL_BUTTON_MIDDLE
GLint GLint GLint GLint GLint GLint y
static void wl_seat_set_user_data(struct wl_seat *wl_seat, void *user_data)
static void zwp_relative_pointer_manager_v1_destroy(struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1)
static struct wl_pointer * wl_seat_get_pointer(struct wl_seat *wl_seat)
static int wl_touch_add_listener(struct wl_touch *wl_touch, const struct wl_touch_listener *listener, void *data)
GLsizei const void * pointer
static void wl_touch_set_user_data(struct wl_touch *wl_touch, void *user_data)
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_pointer_add_listener(struct wl_pointer *wl_pointer, const struct wl_pointer_listener *listener, void *data)
static int wl_data_offer_add_listener(struct wl_data_offer *wl_data_offer, const struct wl_data_offer_listener *listener, void *data)
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer, const char *mime_type)
static int wl_seat_add_listener(struct wl_seat *wl_seat, const struct wl_seat_listener *listener, void *data)
struct zwp_locked_pointer_v1 * locked_pointer
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
static void * wl_surface_get_user_data(struct wl_surface *wl_surface)
SDL_WaylandDataDevice * Wayland_get_data_device(struct SDL_WaylandInput *input)
SDL_VideoData * video_data
static void wl_data_device_release(struct wl_data_device *wl_data_device)
static void zwp_relative_pointer_v1_destroy(struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1)
#define SDL_OutOfMemory()
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)
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
static void wl_data_device_set_user_data(struct wl_data_device *wl_data_device, void *user_data)
struct wl_data_device * data_device
static int wl_keyboard_add_listener(struct wl_keyboard *wl_keyboard, const struct wl_keyboard_listener *listener, void *data)
static void zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
static char text[MAX_TEXT_LENGTH]
SDL_WaylandDataOffer * selection_offer
static int wl_data_device_add_listener(struct wl_data_device *wl_data_device, const struct wl_data_device_listener *listener, void *data)
void Wayland_display_destroy_input(SDL_VideoData *d)
void Wayland_PumpEvents(_THIS)
EGLSurface EGLNativeWindowType * window
The type used to identify a window.
static void wl_keyboard_destroy(struct wl_keyboard *wl_keyboard)
struct wl_registry * registry
struct wl_data_offer * offer
static void wl_data_source_destroy(struct wl_data_source *wl_data_source)
SDL_VideoDevice * SDL_GetVideoDevice(void)
const struct wl_interface wl_seat_interface
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)
#define SDL_arraysize(array)
int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *device)
static void wl_data_source_set_user_data(struct wl_data_source *wl_data_source, void *user_data)
static void wl_pointer_set_user_data(struct wl_pointer *wl_pointer, void *user_data)
static void wl_keyboard_set_user_data(struct wl_keyboard *wl_keyboard, void *user_data)
GLuint GLsizei GLsizei * length
struct zwp_pointer_constraints_v1 * pointer_constraints
GLboolean GLboolean GLboolean GLboolean a
void * Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, size_t *length, const char *mime_type, SDL_bool null_terminate)
static void wl_shell_surface_move(struct wl_shell_surface *wl_shell_surface, struct wl_seat *seat, uint32_t serial)
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
SDL_WaylandDataOffer * drag_offer
static struct wl_keyboard * wl_seat_get_keyboard(struct wl_seat *wl_seat)
static void wl_touch_destroy(struct wl_touch *wl_touch)