22 #include "../../SDL_internal.h" 24 #if SDL_VIDEO_DRIVER_WAYLAND 30 #include "../../events/SDL_sysevents.h" 31 #include "../../events/SDL_events_c.h" 32 #include "../../events/scancodes_xfree86.h" 40 #include "pointer-constraints-unstable-v1-client-protocol.h" 41 #include "relative-pointer-unstable-v1-client-protocol.h" 43 #include <linux/input.h> 44 #include <sys/select.h> 48 #include <xkbcommon/xkbcommon.h> 50 struct SDL_WaylandInput {
54 struct wl_keyboard *keyboard;
55 struct zwp_relative_pointer_v1 *relative_pointer;
67 struct xkb_keymap *keymap;
68 struct xkb_state *
state;
78 pfd[0].fd = WAYLAND_wl_display_get_fd(d->
display);
79 pfd[0].events = POLLIN;
82 if (pfd[0].revents & POLLIN)
83 WAYLAND_wl_display_dispatch(d->
display);
85 WAYLAND_wl_display_dispatch_pending(d->
display);
89 pointer_handle_enter(
void *
data,
struct wl_pointer *
pointer,
90 uint32_t serial,
struct wl_surface *surface,
91 wl_fixed_t sx_w, wl_fixed_t sy_w)
110 input->pointer_focus =
window;
116 pointer_handle_leave(
void *data,
struct wl_pointer *pointer,
117 uint32_t serial,
struct wl_surface *surface)
119 struct SDL_WaylandInput *input =
data;
121 if (input->pointer_focus) {
123 input->pointer_focus =
NULL;
128 pointer_handle_motion(
void *data,
struct wl_pointer *pointer,
129 uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
131 struct SDL_WaylandInput *input =
data;
135 if (input->pointer_focus) {
136 const int sx = wl_fixed_to_int(sx_w);
137 const int sy = wl_fixed_to_int(sy_w);
143 ProcessHitTest(
struct SDL_WaylandInput *input,
uint32_t serial)
149 const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) };
151 static const uint32_t directions[] = {
152 WL_SHELL_SURFACE_RESIZE_TOP_LEFT, WL_SHELL_SURFACE_RESIZE_TOP,
153 WL_SHELL_SURFACE_RESIZE_TOP_RIGHT, WL_SHELL_SURFACE_RESIZE_RIGHT,
154 WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, WL_SHELL_SURFACE_RESIZE_BOTTOM,
155 WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT, WL_SHELL_SURFACE_RESIZE_LEFT
159 wl_shell_surface_move(window_data->
shell_surface, input->seat, serial);
181 pointer_handle_button_common(
struct SDL_WaylandInput *input,
uint32_t serial,
185 enum wl_pointer_button_state
state = state_w;
188 if (input->pointer_focus) {
192 if (ProcessHitTest(input, serial)) {
218 pointer_handle_button(
void *data,
struct wl_pointer *pointer,
uint32_t serial,
221 struct SDL_WaylandInput *input =
data;
223 pointer_handle_button_common(input, serial, time, button, state_w);
227 pointer_handle_axis_common(
struct SDL_WaylandInput *input,
231 enum wl_pointer_axis
a =
axis;
234 if (input->pointer_focus) {
236 case WL_POINTER_AXIS_VERTICAL_SCROLL:
238 y = wl_fixed_to_int(value);
240 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
241 x = wl_fixed_to_int(value);
253 pointer_handle_axis(
void *data,
struct wl_pointer *pointer,
256 struct SDL_WaylandInput *input =
data;
258 pointer_handle_axis_common(input, time, axis, value);
261 static const struct wl_pointer_listener pointer_listener = {
262 pointer_handle_enter,
263 pointer_handle_leave,
264 pointer_handle_motion,
265 pointer_handle_button,
270 keyboard_handle_keymap(
void *data,
struct wl_keyboard *keyboard,
273 struct SDL_WaylandInput *input =
data;
281 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
286 map_str = mmap(
NULL, size, PROT_READ, MAP_SHARED, fd, 0);
287 if (map_str == MAP_FAILED) {
292 input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context,
294 XKB_KEYMAP_FORMAT_TEXT_V1,
296 munmap(map_str, size);
299 if (!input->xkb.keymap) {
300 fprintf(stderr,
"failed to compile keymap\n");
304 input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
305 if (!input->xkb.state) {
306 fprintf(stderr,
"failed to create XKB state\n");
307 WAYLAND_xkb_keymap_unref(input->xkb.keymap);
308 input->xkb.keymap =
NULL;
314 keyboard_handle_enter(
void *data,
struct wl_keyboard *keyboard,
315 uint32_t serial,
struct wl_surface *surface,
316 struct wl_array *keys)
318 struct SDL_WaylandInput *input =
data;
326 window = wl_surface_get_user_data(surface);
329 input->keyboard_focus =
window;
336 keyboard_handle_leave(
void *data,
struct wl_keyboard *keyboard,
337 uint32_t serial,
struct wl_surface *surface)
343 keyboard_handle_key(
void *data,
struct wl_keyboard *keyboard,
347 struct SDL_WaylandInput *input =
data;
349 enum wl_keyboard_key_state state = state_w;
350 const xkb_keysym_t *syms;
368 if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1)
372 size = WAYLAND_xkb_keysym_to_utf8(syms[0], text,
sizeof text);
382 keyboard_handle_modifiers(
void *data,
struct wl_keyboard *keyboard,
387 struct SDL_WaylandInput *input =
data;
389 WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
390 mods_locked, 0, 0, group);
393 static const struct wl_keyboard_listener keyboard_listener = {
394 keyboard_handle_keymap,
395 keyboard_handle_enter,
396 keyboard_handle_leave,
398 keyboard_handle_modifiers,
402 seat_handle_capabilities(
void *data,
struct wl_seat *seat,
403 enum wl_seat_capability caps)
405 struct SDL_WaylandInput *input =
data;
407 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
408 input->pointer = wl_seat_get_pointer(seat);
409 input->display->pointer = input->pointer;
410 wl_pointer_set_user_data(input->pointer, input);
411 wl_pointer_add_listener(input->pointer, &pointer_listener,
413 }
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
414 wl_pointer_destroy(input->pointer);
415 input->pointer =
NULL;
418 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
419 input->keyboard = wl_seat_get_keyboard(seat);
420 wl_keyboard_set_user_data(input->keyboard, input);
421 wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
423 }
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
424 wl_keyboard_destroy(input->keyboard);
425 input->keyboard =
NULL;
429 static const struct wl_seat_listener seat_listener = {
430 seat_handle_capabilities,
436 struct SDL_WaylandInput *
input;
443 input->seat = wl_registry_bind(d->
registry,
id, &wl_seat_interface, 1);
444 input->sx_w = wl_fixed_from_int(0);
445 input->sy_w = wl_fixed_from_int(0);
448 wl_seat_add_listener(input->seat, &seat_listener, input);
449 wl_seat_set_user_data(input->seat, input);
451 WAYLAND_wl_display_flush(d->
display);
456 struct SDL_WaylandInput *input = d->
input;
462 wl_keyboard_destroy(input->keyboard);
465 wl_pointer_destroy(input->pointer);
468 wl_seat_destroy(input->seat);
470 if (input->xkb.state)
471 WAYLAND_xkb_state_unref(input->xkb.state);
473 if (input->xkb.keymap)
474 WAYLAND_xkb_keymap_unref(input->xkb.keymap);
484 &zwp_relative_pointer_manager_v1_interface, 1);
497 &zwp_pointer_constraints_v1_interface, 1);
507 relative_pointer_handle_relative_motion(
void *data,
508 struct zwp_relative_pointer_v1 *pointer,
513 wl_fixed_t dx_unaccel_w,
514 wl_fixed_t dy_unaccel_w)
516 struct SDL_WaylandInput *input =
data;
524 dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
525 dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
528 dx_unaccel += input->dx_frac;
529 dy_unaccel += input->dy_frac;
531 input->dx_frac = modf(dx_unaccel, &dx);
532 input->dy_frac = modf(dy_unaccel, &dy);
539 static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
540 relative_pointer_handle_relative_motion,
544 locked_pointer_locked(
void *data,
545 struct zwp_locked_pointer_v1 *locked_pointer)
550 locked_pointer_unlocked(
void *data,
551 struct zwp_locked_pointer_v1 *locked_pointer)
555 static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
556 locked_pointer_locked,
557 locked_pointer_unlocked,
562 struct SDL_WaylandInput *input)
566 struct zwp_locked_pointer_v1 *locked_pointer;
576 ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
577 zwp_locked_pointer_v1_add_listener(locked_pointer,
578 &locked_pointer_listener,
589 struct zwp_relative_pointer_v1 *relative_pointer;
597 if (!input->relative_pointer) {
599 zwp_relative_pointer_manager_v1_get_relative_pointer(
602 zwp_relative_pointer_v1_add_listener(relative_pointer,
603 &relative_pointer_listener,
605 input->relative_pointer = relative_pointer;
608 for (window = vd->
windows; window; window = window->
next)
609 lock_pointer_to_window(window, input);
623 for (window = vd->
windows; window; window = window->
next) {
630 zwp_relative_pointer_v1_destroy(input->relative_pointer);
631 input->relative_pointer =
NULL;
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
struct zwp_relative_pointer_manager_v1 * relative_pointer_manager
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
void SDL_SetKeyboardFocus(SDL_Window *window)
GLint GLint GLint GLint GLint x
struct wl_display * display
static SDL_Window * window
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
The structure that defines a point.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static const SDL_Scancode xfree86_scancode_table2[]
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
void SDL_SetMouseFocus(SDL_Window *window)
struct SDL_WaylandInput * input
GLsizei const void * pointer
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
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.
struct SDL_WaylandInput * keyboard_device
void * SDL_calloc(size_t nmemb, size_t size)
GLenum GLenum GLenum input
GLint GLint GLint GLint GLint GLint y
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
GLsizei const GLfloat * value
int SDL_SendKeyboardText(const char *text)
struct wl_shell_surface * shell_surface
#define SDL_BUTTON_MIDDLE
struct zwp_locked_pointer_v1 * locked_pointer
void Wayland_display_add_input(SDL_VideoData *d, uint32_t id)
static char text[MAX_TEXT_LENGTH]
void Wayland_display_destroy_input(SDL_VideoData *d)
void Wayland_PumpEvents(_THIS)
The type used to identify a window.
struct wl_registry * registry
SDL_VideoDevice * SDL_GetVideoDevice(void)
#define SDL_arraysize(array)
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction)
GLubyte GLubyte GLubyte GLubyte w
struct zwp_pointer_constraints_v1 * pointer_constraints
GLboolean GLboolean GLboolean GLboolean a
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)