}
}
+/* TODO: share this function with wayland-server.c */
+static struct wl_resource *
+find_resource_for_surface(struct wl_list *list, struct wl_surface *surface)
+{
+ struct wl_resource *r;
+
+ if (!surface)
+ return NULL;
+
+ wl_list_for_each(r, list, link) {
+ if (r->client == surface->resource.client)
+ return r;
+ }
+
+ return NULL;
+}
+
+static void
+touch_set_focus(struct wlsc_input_device *device,
+ struct wl_surface *surface, uint32_t time)
+{
+ struct wl_input_device *input_device = &device->input_device;
+ struct wl_resource *resource;
+
+ if (device->touch_focus == surface)
+ return;
+
+ resource = find_resource_for_surface(&input_device->resource_list,
+ surface);
+ if (!resource) {
+ fprintf(stderr, "couldn't find resource\n");
+ return;
+ }
+
+ device->touch_focus = surface;
+ device->touch_focus_resource = resource;
+}
+
/**
* notify_touch - emulates button touches and notifies surfaces accordingly.
*
* It assumes always the correct cycle sequence until it gets here: touch_down
* → touch_update → ... → touch_update → touch_end. The driver is responsible
* for sending along such order.
+ *
*/
WL_EXPORT void
notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
int x, int y, int touch_type)
{
+ struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
+ struct wlsc_compositor *ec = wd->compositor;
+ struct wlsc_surface *es;
+ int32_t sx, sy;
+
+ switch (touch_type) {
+ case WL_INPUT_DEVICE_TOUCH_DOWN:
+ wlsc_compositor_idle_inhibit(ec);
+
+ wd->num_tp++;
+
+ /* the first finger down picks the surface, and all further go
+ * to that surface for the remainder of the touch session i.e.
+ * until all touch points are up again. */
+ if (wd->num_tp == 1) {
+ es = wlsc_compositor_pick_surface(ec, x, y, &sx, &sy);
+ touch_set_focus(wd, &es->surface, time);
+ } else {
+ es = (struct wlsc_surface *) wd->touch_focus;
+ wlsc_surface_transform(es, x, y, &sx, &sy);
+ }
+ if (wd->touch_focus_resource)
+ wl_resource_post_event(wd->touch_focus_resource,
+ touch_type, time,
+ wd->touch_focus,
+ touch_id, sx, sy);
+ break;
+ case WL_INPUT_DEVICE_TOUCH_MOTION:
+ es = (struct wlsc_surface *) wd->touch_focus;
+ wlsc_surface_transform(es, x, y, &sx, &sy);
+ if (wd->touch_focus_resource)
+ wl_resource_post_event(wd->touch_focus_resource,
+ touch_type, time, touch_id, sx, sy);
+ break;
+ case WL_INPUT_DEVICE_TOUCH_UP:
+ wlsc_compositor_idle_release(ec);
+ wd->num_tp--;
+
+ if (wd->num_tp == 0) {
+ wd->touch_focus = NULL;
+ wd->touch_focus_resource = NULL;
+ }
+ if (wd->touch_focus_resource)
+ wl_resource_post_event(wd->touch_focus_resource,
+ touch_type, time, touch_id);
+ break;
+ }
}
static void
device->hotspot_x = 16;
device->hotspot_y = 16;
device->modifier_state = 0;
+ device->num_tp = 0;
device->input_device.implicit_grab.interface = &implicit_grab_interface;