mirror of https://github.com/encounter/SDL.git
Fixed bug 3644 - Wayland touch event support
Moritz Bitsch Attached is a small patch which enables multitouch events on Wayland.
This commit is contained in:
parent
a78c20ae19
commit
834ab350e5
|
@ -52,6 +52,7 @@ struct SDL_WaylandInput {
|
||||||
SDL_VideoData *display;
|
SDL_VideoData *display;
|
||||||
struct wl_seat *seat;
|
struct wl_seat *seat;
|
||||||
struct wl_pointer *pointer;
|
struct wl_pointer *pointer;
|
||||||
|
struct wl_touch *touch;
|
||||||
struct wl_keyboard *keyboard;
|
struct wl_keyboard *keyboard;
|
||||||
SDL_WaylandDataDevice *data_device;
|
SDL_WaylandDataDevice *data_device;
|
||||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||||
|
@ -71,6 +72,105 @@ struct SDL_WaylandInput {
|
||||||
} xkb;
|
} xkb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SDL_WaylandTouchPoint {
|
||||||
|
SDL_TouchID id;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
struct wl_surface* surface;
|
||||||
|
|
||||||
|
struct SDL_WaylandTouchPoint* prev;
|
||||||
|
struct SDL_WaylandTouchPoint* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SDL_WaylandTouchPointList {
|
||||||
|
struct SDL_WaylandTouchPoint* head;
|
||||||
|
struct SDL_WaylandTouchPoint* tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct SDL_WaylandTouchPointList touch_points = {NULL, NULL};
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
|
||||||
|
{
|
||||||
|
struct SDL_WaylandTouchPoint* tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
|
||||||
|
|
||||||
|
tp->id = id;
|
||||||
|
tp->x = x;
|
||||||
|
tp->y = y;
|
||||||
|
tp->surface = surface;
|
||||||
|
|
||||||
|
if (touch_points.tail) {
|
||||||
|
touch_points.tail->next = tp;
|
||||||
|
tp->prev = touch_points.tail;
|
||||||
|
} else {
|
||||||
|
touch_points.head = tp;
|
||||||
|
tp->prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
touch_points.tail = tp;
|
||||||
|
tp->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_update(SDL_TouchID id, float x, float y)
|
||||||
|
{
|
||||||
|
struct SDL_WaylandTouchPoint* tp = touch_points.head;
|
||||||
|
|
||||||
|
while (tp) {
|
||||||
|
if (tp->id == id) {
|
||||||
|
tp->x = x;
|
||||||
|
tp->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_del(SDL_TouchID id, float* x, float* y)
|
||||||
|
{
|
||||||
|
struct SDL_WaylandTouchPoint* tp = touch_points.head;
|
||||||
|
|
||||||
|
while (tp) {
|
||||||
|
if (tp->id == id) {
|
||||||
|
*x = tp->x;
|
||||||
|
*y = tp->y;
|
||||||
|
|
||||||
|
if (tp->prev) {
|
||||||
|
tp->prev->next = tp->next;
|
||||||
|
} else {
|
||||||
|
touch_points.head = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp->next) {
|
||||||
|
tp->next->prev = tp->prev;
|
||||||
|
} else {
|
||||||
|
touch_points.tail = tp->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_surface*
|
||||||
|
touch_surface(SDL_TouchID id)
|
||||||
|
{
|
||||||
|
struct SDL_WaylandTouchPoint* tp = touch_points.head;
|
||||||
|
|
||||||
|
while (tp) {
|
||||||
|
if (tp->id == id) {
|
||||||
|
return tp->surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
tp = tp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Wayland_PumpEvents(_THIS)
|
Wayland_PumpEvents(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -268,6 +368,69 @@ static const struct wl_pointer_listener pointer_listener = {
|
||||||
pointer_handle_axis,
|
pointer_handle_axis,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial,
|
||||||
|
unsigned int timestamp, struct wl_surface *surface,
|
||||||
|
int id, wl_fixed_t fx, wl_fixed_t fy)
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
SDL_WindowData* window;
|
||||||
|
|
||||||
|
window = (SDL_WindowData *)wl_surface_get_user_data(surface);
|
||||||
|
|
||||||
|
x = wl_fixed_to_double(fx) / window->sdlwindow->w;
|
||||||
|
y = wl_fixed_to_double(fy) / window->sdlwindow->h;
|
||||||
|
|
||||||
|
touch_add(id, x, y, surface);
|
||||||
|
SDL_SendTouch(1, (SDL_FingerID)id, SDL_TRUE, x, y, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_handler_up(void *data, struct wl_touch *touch, unsigned int serial,
|
||||||
|
unsigned int timestamp, int id)
|
||||||
|
{
|
||||||
|
float x = 0, y = 0;
|
||||||
|
|
||||||
|
touch_del(id, &x, &y);
|
||||||
|
SDL_SendTouch(1, (SDL_FingerID)id, SDL_FALSE, x, y, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
|
||||||
|
int id, wl_fixed_t fx, wl_fixed_t fy)
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
SDL_WindowData* window;
|
||||||
|
|
||||||
|
window = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
|
||||||
|
|
||||||
|
x = wl_fixed_to_double(fx) / window->sdlwindow->w;
|
||||||
|
y = wl_fixed_to_double(fy) / window->sdlwindow->h;
|
||||||
|
|
||||||
|
touch_update(id, x, y);
|
||||||
|
SDL_SendTouchMotion(1, (SDL_FingerID)id, x, y, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_handler_frame(void *data, struct wl_touch *touch)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
touch_handler_cancel(void *data, struct wl_touch *touch)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_touch_listener touch_listener = {
|
||||||
|
touch_handler_down,
|
||||||
|
touch_handler_up,
|
||||||
|
touch_handler_motion,
|
||||||
|
touch_handler_frame,
|
||||||
|
touch_handler_cancel
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
||||||
uint32_t format, int fd, uint32_t size)
|
uint32_t format, int fd, uint32_t size)
|
||||||
|
@ -420,6 +583,18 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||||
input->pointer = NULL;
|
input->pointer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
|
||||||
|
SDL_AddTouch(1, "wayland_touch");
|
||||||
|
input->touch = wl_seat_get_touch(seat);
|
||||||
|
wl_touch_set_user_data(input->touch, input);
|
||||||
|
wl_touch_add_listener(input->touch, &touch_listener,
|
||||||
|
input);
|
||||||
|
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
|
||||||
|
SDL_DelTouch(1);
|
||||||
|
wl_touch_destroy(input->touch);
|
||||||
|
input->touch = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
|
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
|
||||||
input->keyboard = wl_seat_get_keyboard(seat);
|
input->keyboard = wl_seat_get_keyboard(seat);
|
||||||
wl_keyboard_set_user_data(input->keyboard, input);
|
wl_keyboard_set_user_data(input->keyboard, input);
|
||||||
|
@ -739,6 +914,11 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
||||||
if (input->pointer)
|
if (input->pointer)
|
||||||
wl_pointer_destroy(input->pointer);
|
wl_pointer_destroy(input->pointer);
|
||||||
|
|
||||||
|
if (input->touch) {
|
||||||
|
SDL_DelTouch(1);
|
||||||
|
wl_touch_destroy(input->touch);
|
||||||
|
}
|
||||||
|
|
||||||
if (input->seat)
|
if (input->seat)
|
||||||
wl_seat_destroy(input->seat);
|
wl_seat_destroy(input->seat);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue