aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/wayland/seat.c131
1 files changed, 56 insertions, 75 deletions
diff --git a/backend/wayland/seat.c b/backend/wayland/seat.c
index f6665a58..e2d5278c 100644
--- a/backend/wayland/seat.c
+++ b/backend/wayland/seat.c
@@ -21,8 +21,6 @@
#include "util/signal.h"
#include "util/time.h"
-static const struct wlr_touch_impl touch_impl;
-
static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
uint32_t format, int32_t fd, uint32_t size) {
close(fd);
@@ -119,11 +117,17 @@ void init_seat_keyboard(struct wlr_wl_seat *seat) {
&seat->wlr_keyboard.base);
}
-static void touch_coordinates_to_absolute(struct wlr_wl_input_device *device,
+static void touch_coordinates_to_absolute(struct wlr_wl_seat *seat,
wl_fixed_t x, wl_fixed_t y, double *sx, double *sy) {
- // TODO: each output needs its own touch
+ /**
+ * TODO: multi-output touch support
+ * Although the wayland backend supports multi-output pointers, the support
+ * for multi-output touch has been left on the side for simplicity reasons.
+ * If this is a feature you want/need, please open an issue on the wlroots
+ * tracker here https://gitlab.freedesktop.org/wlroots/wlroots/-/issues
+ */
struct wlr_wl_output *output, *tmp;
- wl_list_for_each_safe(output, tmp, &device->backend->outputs, link) {
+ wl_list_for_each_safe(output, tmp, &seat->backend->outputs, link) {
*sx = wl_fixed_to_double(x) / output->wlr_output.width;
*sy = wl_fixed_to_double(y) / output->wlr_output.height;
return; // Choose the first output in the list
@@ -135,56 +139,46 @@ static void touch_coordinates_to_absolute(struct wlr_wl_input_device *device,
static void touch_handle_down(void *data, struct wl_touch *wl_touch,
uint32_t serial, uint32_t time, struct wl_surface *surface,
int32_t id, wl_fixed_t x, wl_fixed_t y) {
- struct wlr_wl_input_device *device = data;
- assert(device && device->wlr_input_device.touch);
+ struct wlr_wl_seat *seat = data;
- double sx, sy;
- touch_coordinates_to_absolute(device, x, y, &sx, &sy);
struct wlr_event_touch_down event = {
- .device = &device->wlr_input_device,
+ .device = &seat->wlr_touch.base,
.time_msec = time,
.touch_id = id,
- .x = sx,
- .y = sy
};
- wlr_signal_emit_safe(&device->wlr_input_device.touch->events.down, &event);
+ touch_coordinates_to_absolute(seat, x, y, &event.x, &event.y);
+ wlr_signal_emit_safe(&seat->wlr_touch.events.down, &event);
}
static void touch_handle_up(void *data, struct wl_touch *wl_touch,
uint32_t serial, uint32_t time, int32_t id) {
- struct wlr_wl_input_device *device = data;
- assert(device && device->wlr_input_device.touch);
+ struct wlr_wl_seat *seat = data;
struct wlr_event_touch_up event = {
- .device = &device->wlr_input_device,
+ .device = &seat->wlr_touch.base,
.time_msec = time,
.touch_id = id,
};
- wlr_signal_emit_safe(&device->wlr_input_device.touch->events.up, &event);
+ wlr_signal_emit_safe(&seat->wlr_touch.events.up, &event);
}
static void touch_handle_motion(void *data, struct wl_touch *wl_touch,
uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) {
- struct wlr_wl_input_device *device = data;
- assert(device && device->wlr_input_device.touch);
+ struct wlr_wl_seat *seat = data;
+ struct wlr_input_device *device = &seat->wlr_touch.base;
- double sx, sy;
- touch_coordinates_to_absolute(device, x, y, &sx, &sy);
struct wlr_event_touch_motion event = {
- .device = &device->wlr_input_device,
+ .device = device,
.time_msec = time,
.touch_id = id,
- .x = sx,
- .y = sy
};
- wlr_signal_emit_safe(&device->wlr_input_device.touch->events.motion, &event);
+ touch_coordinates_to_absolute(seat, x, y, &event.x, &event.y);
+ wlr_signal_emit_safe(&seat->wlr_touch.events.motion, &event);
}
static void touch_handle_frame(void *data, struct wl_touch *wl_touch) {
- struct wlr_wl_input_device *device = data;
- assert(device && device->wlr_input_device.touch);
-
- wlr_signal_emit_safe(&device->wlr_input_device.touch->events.frame, NULL);
+ struct wlr_wl_seat *seat = data;
+ wlr_signal_emit_safe(&seat->wlr_touch.events.frame, NULL);
}
static void touch_handle_cancel(void *data, struct wl_touch *wl_touch) {
@@ -211,6 +205,23 @@ static const struct wl_touch_listener touch_listener = {
.orientation = touch_handle_orientation,
};
+static const struct wlr_touch_impl touch_impl = {
+ .name = "wl-touch",
+};
+
+static void init_seat_touch(struct wlr_wl_seat *seat) {
+ assert(seat->wl_touch);
+
+ char name[128] = {0};
+ snprintf(name, sizeof(name), "wayland-touch-%s", seat->name);
+
+ wlr_touch_init(&seat->wlr_touch, &touch_impl, name);
+
+ wl_touch_add_listener(seat->wl_touch, &touch_listener, seat);
+ wlr_signal_emit_safe(&seat->backend->backend.events.new_input,
+ &seat->wlr_touch.base);
+}
+
static struct wlr_wl_input_device *get_wl_input_device_from_input_device(
struct wlr_input_device *wlr_dev) {
assert(wlr_input_device_is_wl(wlr_dev));
@@ -233,8 +244,9 @@ bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl) {
void destroy_wl_seats(struct wlr_wl_backend *wl) {
struct wlr_wl_seat *seat, *tmp_seat;
wl_list_for_each_safe(seat, tmp_seat, &wl->seats, link) {
- if (seat->touch) {
- wl_touch_destroy(seat->touch);
+ if (seat->wl_touch) {
+ wl_touch_release(seat->wl_touch);
+ wlr_touch_finish(&seat->wlr_touch);
}
if (seat->wl_pointer) {
finish_seat_pointer(seat);
@@ -302,8 +314,9 @@ struct wlr_wl_input_device *create_wl_input_device(
free(dev);
return NULL;
case WLR_INPUT_DEVICE_TOUCH:
- type_name = "touch";
- break;
+ wlr_log(WLR_ERROR, "can't create touch wlr_wl_input_device");
+ free(dev);
+ return NULL;
case WLR_INPUT_DEVICE_TABLET_TOOL:
type_name = "tablet-tool";
break;
@@ -350,8 +363,7 @@ void destroy_wl_input_device(struct wlr_wl_input_device *dev) {
free(wlr_dev->tablet);
break;
case WLR_INPUT_DEVICE_TOUCH:
- wlr_touch_finish(wlr_dev->touch);
- free(wlr_dev->touch);
+ wlr_log(WLR_ERROR, "wlr_wl_input_device has no touch");
break;
default:
break;
@@ -361,29 +373,6 @@ void destroy_wl_input_device(struct wlr_wl_input_device *dev) {
free(dev);
}
-void create_wl_touch(struct wlr_wl_seat *seat) {
- assert(seat->touch);
- struct wl_touch *wl_touch = seat->touch;
- struct wlr_wl_input_device *dev =
- create_wl_input_device(seat, WLR_INPUT_DEVICE_TOUCH);
- if (!dev) {
- return;
- }
-
- struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
-
- wlr_dev->touch = calloc(1, sizeof(*wlr_dev->touch));
- if (!wlr_dev->touch) {
- wlr_log_errno(WLR_ERROR, "Allocation failed");
- destroy_wl_input_device(dev);
- return;
- }
- wlr_touch_init(wlr_dev->touch, &touch_impl, wlr_dev->name);
-
- wl_touch_add_listener(wl_touch, &touch_listener, dev);
- wlr_signal_emit_safe(&seat->backend->backend.events.new_input, wlr_dev);
-}
-
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
enum wl_seat_capability caps) {
struct wlr_wl_seat *seat = data;
@@ -419,26 +408,18 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
seat->wl_keyboard = NULL;
}
- if ((caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch == NULL) {
- wlr_log(WLR_DEBUG, "seat %p offered touch", (void *)wl_seat);
+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch == NULL) {
+ wlr_log(WLR_DEBUG, "seat '%s' offering touch", seat->name);
- seat->touch = wl_seat_get_touch(wl_seat);
- if (backend->started) {
- create_wl_touch(seat);
- }
+ seat->wl_touch = wl_seat_get_touch(wl_seat);
+ init_seat_touch(seat);
}
- if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch != NULL) {
- wlr_log(WLR_DEBUG, "seat %p dropped touch", (void *)wl_seat);
-
- struct wlr_wl_input_device *device, *tmp;
- wl_list_for_each_safe(device, tmp, &backend->devices, link) {
- if (device->wlr_input_device.type == WLR_INPUT_DEVICE_TOUCH) {
- destroy_wl_input_device(device);
- }
- }
+ if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch != NULL) {
+ wlr_log(WLR_DEBUG, "seat '%s' dropping touch", seat->name);
- wl_touch_release(seat->touch);
- seat->touch = NULL;
+ wl_touch_release(seat->wl_touch);
+ wlr_touch_finish(&seat->wlr_touch);
+ seat->wl_touch = NULL;
}
}