+
+static const struct ds_touch_interface touch_iface;
+
+static struct ds_wl_touch *
+get_wl_touch_from_touch(struct ds_touch *ds_touch)
+{
+ assert(ds_touch->iface == &touch_iface);
+ return (struct ds_wl_touch *)ds_touch;
+}
+
+static void
+touch_iface_destroy(struct ds_touch *ds_touch)
+{
+ struct ds_wl_touch *touch;
+
+ touch = get_wl_touch_from_touch(ds_touch);
+
+ wl_touch_release(touch->wl_touch);
+
+ free(touch);
+}
+
+static const struct ds_touch_interface touch_iface = {
+ .destroy = touch_iface_destroy,
+};
+
+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 fixed_x, wl_fixed_t fixed_y)
+{
+ struct ds_wl_seat *seat = data;
+
+ ds_dbg("wl_touch: down");
+
+ struct ds_event_touch_down event = {
+ .device = seat->touch_dev,
+ .id = id,
+ .x = fixed_x,
+ .y = fixed_y,
+ };
+
+ wl_signal_emit(&seat->touch_dev->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 ds_wl_seat *seat = data;
+
+ ds_dbg("wl_touch: up");
+
+ struct ds_event_touch_up event = {
+ .device = seat->touch_dev,
+ .id = id,
+ };
+
+ wl_signal_emit(&seat->touch_dev->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 fixed_x, wl_fixed_t fixed_y)
+{
+ ds_dbg("wl_touch: motion");
+}
+
+static void
+touch_handle_frame(void *data, struct wl_touch *wl_touch)
+{
+ ds_dbg("wl_touch: frame");
+}
+
+static void
+touch_handle_cancel(void *data, struct wl_touch *wl_touch)
+{
+ ds_dbg("wl_touch: cancel");
+}
+
+static const struct wl_touch_listener wl_touch_listener = {
+ .down = touch_handle_down,
+ .up = touch_handle_up,
+ .motion = touch_handle_motion,
+ .frame = touch_handle_frame,
+ .cancel = touch_handle_cancel,
+};
+
+static struct ds_touch *
+create_wl_touch(struct ds_wl_seat *seat)
+{
+ struct ds_wl_touch *touch;
+
+ touch = calloc(1, sizeof *touch);
+ if (!touch) {
+ ds_err("Could not allocate memory");
+ return NULL;
+ }
+
+ ds_touch_init(&touch->base, &touch_iface);
+
+ touch->wl_touch = wl_seat_get_touch(seat->wl_seat);
+ wl_touch_add_listener(touch->wl_touch, &wl_touch_listener, seat);
+
+ return &touch->base;
+}