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;
83 } pointer_curr_axis_info;
86 struct SDL_WaylandTouchPoint {
92 struct SDL_WaylandTouchPoint* prev;
93 struct SDL_WaylandTouchPoint* next;
96 struct SDL_WaylandTouchPointList {
97 struct SDL_WaylandTouchPoint*
head;
98 struct SDL_WaylandTouchPoint*
tail;
101 static struct SDL_WaylandTouchPointList touch_points = {
NULL,
NULL};
106 struct SDL_WaylandTouchPoint* tp =
SDL_malloc(
sizeof(
struct SDL_WaylandTouchPoint));
113 if (touch_points.tail) {
114 touch_points.tail->next = tp;
115 tp->prev = touch_points.tail;
117 touch_points.head = tp;
121 touch_points.tail = tp;
128 struct SDL_WaylandTouchPoint* tp = touch_points.head;
143 struct SDL_WaylandTouchPoint* tp = touch_points.head;
152 tp->prev->next = tp->next;
154 touch_points.head = tp->next;
158 tp->next->prev = tp->prev;
160 touch_points.tail = tp->prev;
164 struct SDL_WaylandTouchPoint *next = tp->next;
174 static struct wl_surface*
177 struct SDL_WaylandTouchPoint* tp = touch_points.head;
196 WAYLAND_wl_display_flush(
d->display);
199 err = WAYLAND_wl_display_dispatch(
d->display);
201 err = WAYLAND_wl_display_dispatch_pending(
d->display);
203 if (err == -1 && !
d->display_disconnected) {
207 d->display_disconnected = 1;
215 pointer_handle_enter(
void *
data,
struct wl_pointer *
pointer,
217 wl_fixed_t sx_w, wl_fixed_t sy_w)
242 pointer_handle_leave(
void *
data,
struct wl_pointer *
pointer,
247 if (
input->pointer_focus) {
254 pointer_handle_motion(
void *
data,
struct wl_pointer *
pointer,
261 if (
input->pointer_focus) {
262 const int sx = wl_fixed_to_int(sx_w);
263 const int sy = wl_fixed_to_int(sy_w);
269 ProcessHitTest(
struct SDL_WaylandInput *
input,
uint32_t serial)
278 static const uint32_t directions_wl[] = {
287 const uint32_t *directions_zxdg = directions_wl;
291 if (
input->display->shell.xdg) {
293 }
else if (
input->display->shell.zxdg) {
308 if (
input->display->shell.xdg) {
310 }
else if (
input->display->shell.zxdg) {
325 pointer_handle_button_common(
struct SDL_WaylandInput *
input,
uint32_t serial,
332 if (
input->pointer_focus) {
336 if (ProcessHitTest(
input, serial)) {
373 pointer_handle_axis_common_v1(
struct SDL_WaylandInput *
input,
380 if (
input->pointer_focus) {
384 y = 0 - (float)wl_fixed_to_double(
value);
387 x = 0 - (float)wl_fixed_to_double(
value);
399 pointer_handle_axis_common(
struct SDL_WaylandInput *
input,
SDL_bool discrete,
404 if (
input->pointer_focus) {
411 }
else if(
input->pointer_curr_axis_info.is_y_discrete) {
416 input->pointer_curr_axis_info.y = 0 - (float)wl_fixed_to_double(
value);
423 }
else if(
input->pointer_curr_axis_info.is_x_discrete) {
428 input->pointer_curr_axis_info.x = 0 - (float)wl_fixed_to_double(
value);
435 pointer_handle_axis(
void *
data,
struct wl_pointer *
pointer,
447 pointer_handle_frame(
void *
data,
struct wl_pointer *
pointer)
451 float x =
input->pointer_curr_axis_info.x,
y =
input->pointer_curr_axis_info.y;
454 memset(&
input->pointer_curr_axis_info, 0,
sizeof input->pointer_curr_axis_info);
456 if(
x == 0.0
f &&
y == 0.0
f)
463 pointer_handle_axis_source(
void *
data,
struct wl_pointer *
pointer,
470 pointer_handle_axis_stop(
void *
data,
struct wl_pointer *
pointer,
477 pointer_handle_axis_discrete(
void *
data,
struct wl_pointer *
pointer,
487 pointer_handle_enter,
488 pointer_handle_leave,
489 pointer_handle_motion,
490 pointer_handle_button,
492 pointer_handle_frame,
493 pointer_handle_axis_source,
494 pointer_handle_axis_stop,
495 pointer_handle_axis_discrete,
499 touch_handler_down(
void *
data,
struct wl_touch *touch,
unsigned int serial,
500 unsigned int timestamp,
struct wl_surface *
surface,
501 int id, wl_fixed_t fx, wl_fixed_t fy)
504 const double dblx = wl_fixed_to_double(fx);
505 const double dbly = wl_fixed_to_double(fy);
515 touch_handler_up(
void *
data,
struct wl_touch *touch,
unsigned int serial,
516 unsigned int timestamp,
int id)
533 touch_handler_motion(
void *
data,
struct wl_touch *touch,
unsigned int timestamp,
534 int id, wl_fixed_t fx, wl_fixed_t fy)
537 const double dblx = wl_fixed_to_double(fx);
538 const double dbly = wl_fixed_to_double(fy);
542 touch_update(
id,
x,
y);
547 touch_handler_frame(
void *
data,
struct wl_touch *touch)
553 touch_handler_cancel(
void *
data,
struct wl_touch *touch)
561 touch_handler_motion,
563 touch_handler_cancel,
569 keyboard_handle_keymap(
void *
data,
struct wl_keyboard *keyboard,
585 map_str = mmap(
NULL,
size, PROT_READ, MAP_SHARED,
fd, 0);
586 if (map_str == MAP_FAILED) {
591 input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(
input->display->xkb_context,
593 XKB_KEYMAP_FORMAT_TEXT_V1,
595 munmap(map_str,
size);
598 if (!
input->xkb.keymap) {
599 fprintf(stderr,
"failed to compile keymap\n");
603 input->xkb.state = WAYLAND_xkb_state_new(
input->xkb.keymap);
604 if (!
input->xkb.state) {
605 fprintf(stderr,
"failed to create XKB state\n");
606 WAYLAND_xkb_keymap_unref(
input->xkb.keymap);
613 keyboard_handle_enter(
void *
data,
struct wl_keyboard *keyboard,
615 struct wl_array *keys)
635 keyboard_handle_leave(
void *
data,
struct wl_keyboard *keyboard,
642 keyboard_handle_key(
void *
data,
struct wl_keyboard *keyboard,
649 const xkb_keysym_t *syms;
667 if (WAYLAND_xkb_state_key_get_syms(
input->xkb.state,
key + 8, &syms) != 1)
671 size = WAYLAND_xkb_keysym_to_utf8(syms[0],
text,
sizeof text);
684 keyboard_handle_modifiers(
void *
data,
struct wl_keyboard *keyboard,
691 WAYLAND_xkb_state_update_mask(
input->xkb.state, mods_depressed, mods_latched,
692 mods_locked, 0, 0,
group);
696 keyboard_handle_repeat_info(
void *
data,
struct wl_keyboard *wl_keyboard,
703 keyboard_handle_keymap,
704 keyboard_handle_enter,
705 keyboard_handle_leave,
707 keyboard_handle_modifiers,
708 keyboard_handle_repeat_info,
712 seat_handle_capabilities(
void *
data,
struct wl_seat *seat,
719 memset(&
input->pointer_curr_axis_info, 0,
sizeof input->pointer_curr_axis_info);
754 seat_handle_name(
void *
data,
struct wl_seat *wl_seat,
const char *
name)
760 seat_handle_capabilities,
765 data_source_handle_target(
void *
data,
struct wl_data_source *wl_data_source,
766 const char *mime_type)
771 data_source_handle_send(
void *
data,
struct wl_data_source *wl_data_source,
778 data_source_handle_cancelled(
void *
data,
struct wl_data_source *wl_data_source)
784 data_source_handle_dnd_drop_performed(
void *
data,
struct wl_data_source *wl_data_source)
789 data_source_handle_dnd_finished(
void *
data,
struct wl_data_source *wl_data_source)
794 data_source_handle_action(
void *
data,
struct wl_data_source *wl_data_source,
800 data_source_handle_target,
801 data_source_handle_send,
802 data_source_handle_cancelled,
803 data_source_handle_dnd_drop_performed,
804 data_source_handle_dnd_finished,
805 data_source_handle_action,
813 struct wl_data_source *
id =
NULL;
828 data_source =
SDL_calloc(1,
sizeof *data_source);
829 if (data_source ==
NULL) {
833 WAYLAND_wl_list_init(&(data_source->
mimes));
845 data_offer_handle_offer(
void *
data,
struct wl_data_offer *wl_data_offer,
846 const char *mime_type)
853 data_offer_handle_source_actions(
void *
data,
struct wl_data_offer *wl_data_offer,
859 data_offer_handle_actions(
void *
data,
struct wl_data_offer *wl_data_offer,
865 data_offer_handle_offer,
866 data_offer_handle_source_actions,
867 data_offer_handle_actions,
871 data_device_handle_data_offer(
void *
data,
struct wl_data_device *wl_data_device,
872 struct wl_data_offer *
id)
876 data_offer =
SDL_calloc(1,
sizeof *data_offer);
877 if (data_offer ==
NULL) {
882 WAYLAND_wl_list_init(&(data_offer->
mimes));
889 data_device_handle_enter(
void *
data,
struct wl_data_device *wl_data_device,
891 wl_fixed_t
x, wl_fixed_t
y,
struct wl_data_offer *
id)
916 dnd_action, dnd_action);
922 data_device_handle_leave(
void *
data,
struct wl_data_device *wl_data_device)
934 data_device_handle_motion(
void *
data,
struct wl_data_device *wl_data_device,
940 data_device_handle_drop(
void *
data,
struct wl_data_device *wl_data_device)
946 const char *current_uri =
NULL;
947 const char *last_char =
NULL;
948 char *current_char =
NULL;
956 current_uri = (
const char *)
buffer;
958 for (current_char =
buffer; current_char < last_char; ++current_char) {
959 if (*current_char ==
'\n' || *current_char == 0) {
960 if (*current_uri != 0 && *current_uri !=
'#') {
964 current_uri = (
const char *)current_char + 1;
973 data_device_handle_selection(
void *
data,
struct wl_data_device *wl_data_device,
974 struct wl_data_offer *
id)
992 data_device_handle_data_offer,
993 data_device_handle_enter,
994 data_device_handle_leave,
995 data_device_handle_motion,
996 data_device_handle_drop,
997 data_device_handle_selection
1003 struct SDL_WaylandInput *
input;
1015 input->sx_w = wl_fixed_from_int(0);
1016 input->sy_w = wl_fixed_from_int(0);
1019 if (
d->data_device_manager !=
NULL) {
1020 data_device =
SDL_calloc(1,
sizeof *data_device);
1021 if (data_device ==
NULL) {
1026 d->data_device_manager,
input->seat
1035 &data_device_listener, data_device);
1036 input->data_device = data_device;
1043 WAYLAND_wl_display_flush(
d->display);
1048 struct SDL_WaylandInput *
input =
d->input;
1055 if (
input->data_device->selection_offer !=
NULL) {
1058 if (
input->data_device->drag_offer !=
NULL) {
1061 if (
input->data_device->data_device !=
NULL) {
1067 if (
input->keyboard)
1081 if (
input->xkb.state)
1082 WAYLAND_xkb_state_unref(
input->xkb.state);
1084 if (
input->xkb.keymap)
1085 WAYLAND_xkb_keymap_unref(
input->xkb.keymap);
1097 return input->data_device;
1103 d->relative_pointer_manager =
1110 if (
d->relative_pointer_manager)
1116 d->pointer_constraints =
1123 if (
d->pointer_constraints)
1128 relative_pointer_handle_relative_motion(
void *
data,
1129 struct zwp_relative_pointer_v1 *
pointer,
1134 wl_fixed_t dx_unaccel_w,
1135 wl_fixed_t dy_unaccel_w)
1145 dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
1146 dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
1149 dx_unaccel +=
input->dx_frac;
1150 dy_unaccel +=
input->dy_frac;
1152 input->dx_frac = modf(dx_unaccel, &dx);
1153 input->dy_frac = modf(dy_unaccel, &dy);
1155 if (
input->pointer_focus &&
d->relative_mouse_mode) {
1161 relative_pointer_handle_relative_motion,
1165 locked_pointer_locked(
void *
data,
1166 struct zwp_locked_pointer_v1 *locked_pointer)
1171 locked_pointer_unlocked(
void *
data,
1172 struct zwp_locked_pointer_v1 *locked_pointer)
1177 locked_pointer_locked,
1178 locked_pointer_unlocked,
1183 struct SDL_WaylandInput *
input)
1187 struct zwp_locked_pointer_v1 *locked_pointer;
1189 if (
w->locked_pointer)
1199 &locked_pointer_listener,
1202 w->locked_pointer = locked_pointer;
1210 struct zwp_relative_pointer_v1 *relative_pointer;
1212 if (!
d->relative_pointer_manager)
1215 if (!
d->pointer_constraints)
1218 if (!
input->pointer)
1221 if (!
input->relative_pointer) {
1224 d->relative_pointer_manager,
1227 &relative_pointer_listener,
1229 input->relative_pointer = relative_pointer;
1235 d->relative_mouse_mode = 1;
1249 if (
w->locked_pointer)
1251 w->locked_pointer =
NULL;
1257 d->relative_mouse_mode = 0;