[PATCH 2/6] compositor: emulates button touches and notifies surfaces accordingly

Tiago Vignatti vignatti at freedesktop.org
Fri Dec 16 07:59:38 PST 2011


From: Tiago Vignatti <tiago.vignatti at intel.com>

Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
 compositor/compositor.c |   97 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/compositor/compositor.c b/compositor/compositor.c
index 2c461d8..f9b4575 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -1178,6 +1178,48 @@ idle_handler(void *data)
 	return 1;
 }
 
+static void
+wlsc_output_get_constrains(struct wlsc_compositor *ec, int *x, int *y)
+{
+	struct wlsc_output *output;
+	int x_valid = 0, y_valid = 0;
+	int min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN;
+
+	wl_list_for_each(output, &ec->output_list, link) {
+		if (output->x <= *x && *x <= output->x +
+		    output->current->width)
+			x_valid = 1;
+
+		if (output->y <= *y && *y <= output->y +
+		    output->current->height)
+			y_valid = 1;
+
+		/* FIXME: calculate this only on output addition/deletion */
+		if (output->x < min_x)
+			min_x = output->x;
+		if (output->y < min_y)
+			min_y = output->y;
+
+		if (output->x + output->current->width > max_x)
+			max_x = output->x + output->current->width;
+		if (output->y + output->current->height > max_y)
+			max_y = output->y + output->current->height;
+	}
+
+	if (!x_valid) {
+		if (*x < min_x)
+			*x = min_x;
+		else if (*x >= max_x)
+			*x = max_x;
+	}
+	if (!y_valid) {
+		if (*y < min_y)
+			*y = min_y;
+		else  if (*y >= max_y)
+			*y = max_y;
+	}
+}
+
 WL_EXPORT void
 notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
 {
@@ -1499,11 +1541,66 @@ notify_keyboard_focus(struct wl_input_device *device,
  * 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.
+ *
+ * TODO: We'll have to keep touchpoint information for detect simple gestures
+ * on indirect devices.
  */
 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;
+
+	wlsc_compositor_activity(ec);
+
+	if (touch_type == WL_INPUT_DEVICE_TOUCH_DOWN) {
+		/* TODO: should TOUCH_DOWN send x and y? The driver is not
+		 * sending yet; Qt wants it, and XI 2.2 implements in such way
+		 * where the driver queues the events instead accumulate, so
+		 * it's slightly easier I guess. */
+		es = pick_surface(device, &sx, &sy);
+		wl_input_device_set_pointer_focus(device, &es->surface, time,
+				0, 0, sx, sy);
+
+		/* TODO: we will want to send touch_id information and do the
+		 * grab according the finger so multiple clients can work
+		 * accordingly. Anyway, for now just emulates a button touch */
+		notify_button(device, time, BTN_LEFT, 1);
+		if (device->grab)
+			wl_resource_post_event(device->pointer_focus_resource,
+					touch_type, time, touch_id,
+					0, 0);
+	} else if (touch_type == WL_INPUT_DEVICE_TOUCH_MOTION) {
+		/* TODO: at this point a wheel movement, scroll or any gesture
+		 * has to be identified, sent to the surface and any grab will
+		 * be ignored (?). We want this kinda of global gesture
+		 * probably only for pointer devices, i.e. touchpad, trackpad,
+		 * etc. For now we could just detect if tp > 1 and device ==
+		 * indirect ts, and return. */
+
+		/* TODO: we can avoid one screen constrains calculation here
+		 * if we move the code out from notify_motion.. */
+		notify_motion(device, time, x, y);
+
+		if (!device->grab) {
+			wlsc_output_get_constrains(ec, &x, &y);
+			es = pick_surface(device, &sx, &sy);
+			wl_input_device_set_pointer_focus(device,
+					&es->surface, time,
+					x, y, sx, sy);
+		}
+		if (device->pointer_focus_resource)
+			wl_resource_post_event(device->pointer_focus_resource,
+					touch_type, time, touch_id,
+					device->x, device->y);
+	} else if (touch_type == WL_INPUT_DEVICE_TOUCH_UP) {
+		notify_button(device, time, BTN_LEFT, 0);
+		wl_resource_post_event(device->pointer_focus_resource,
+				touch_type, time, touch_id);
+	}
 }
 
 static void
-- 
1.7.5.4



More information about the wayland-devel mailing list