compositor: Send out touch events accordingly
authorTiago Vignatti <tiago.vignatti@intel.com>
Wed, 21 Dec 2011 17:34:10 +0000 (19:34 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 22 Dec 2011 16:13:05 +0000 (11:13 -0500)
Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
compositor/compositor.c
compositor/compositor.h

index 384f79e..95f3a76 100644 (file)
@@ -1437,17 +1437,103 @@ notify_keyboard_focus(struct wl_input_device *device,
        }
 }
 
+/* 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
@@ -1536,6 +1622,7 @@ wlsc_input_device_init(struct wlsc_input_device *device,
        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;
 
index 3ac1d74..0501cca 100644 (file)
@@ -114,6 +114,10 @@ struct wlsc_input_device {
        struct wlsc_data_source *selection_data_source;
        struct wl_listener selection_data_source_listener;
        struct wl_grab grab;
+
+       uint32_t num_tp;
+       struct wl_surface *touch_focus;
+       struct wl_resource *touch_focus_resource;
 };
 
 enum wlsc_visual {