[RFC weston 1/3] compositor: implement relative motion

Philipp Brüschweiler blei42 at gmail.com
Sat Sep 1 08:50:55 PDT 2012


notify_motion() now takes both absolute and relative motion parameters
and relays this motion to the grab. The grab can then send the absolute
motion to the "normal" pointer and the relative motion to the relative
pointer.

Support for raw pointers should work analogously, but is not implemented
yet.
---
 src/compositor-wayland.c |  6 ++--
 src/compositor-x11.c     |  3 +-
 src/compositor.c         | 82 +++++++++++++++++++++++++++++++++++++++++++++---
 src/compositor.h         |  9 +++++-
 src/evdev.c              | 11 +++----
 src/shell.c              | 41 +++++++++++++++++-------
 6 Dateien geändert, 125 Zeilen hinzugefügt(+), 27 Zeilen entfernt(-)

diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 1f45def..69e82e0 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -595,9 +595,9 @@ input_handle_motion(void *data, struct wl_pointer *pointer,
 
 	check_focus(input, x, y);
 	if (input->focus)
-		notify_motion(&input->base, time,
-			      x - wl_fixed_from_int(c->border.left),
-			      y - wl_fixed_from_int(c->border.top));
+		notify_motion_absolute(&input->base, time,
+				       x - wl_fixed_from_int(c->border.left),
+				       y - wl_fixed_from_int(c->border.top));
 }
 
 static void
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index d5fa0c6..81e8340 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -821,7 +821,8 @@ x11_compositor_deliver_motion_event(struct x11_compositor *c,
 	y = wl_fixed_from_int(motion_notify->event_y);
 	x11_output_transform_coordinate(output, &x, &y);
 
-	notify_motion(&c->core_seat, weston_compositor_get_time(), x, y);
+	notify_motion_absolute(&c->core_seat, weston_compositor_get_time(),
+			       x, y);
 }
 
 static void
diff --git a/src/compositor.c b/src/compositor.c
index 9ce44d4..00c1ade 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2164,7 +2164,33 @@ clip_pointer_motion(struct weston_seat *seat, wl_fixed_t *fx, wl_fixed_t *fy)
 }
 
 WL_EXPORT void
-notify_motion(struct weston_seat *seat, uint32_t time, wl_fixed_t x, wl_fixed_t y)
+notify_motion_absolute(struct weston_seat *seat, uint32_t time,
+		       wl_fixed_t x, wl_fixed_t y)
+{
+	struct wl_pointer *pointer = seat->seat.pointer;
+
+	wl_fixed_t dx = x - pointer->x;
+	wl_fixed_t dy = y - pointer->y;
+
+	notify_motion(seat, time, x, y, dx, dy);
+}
+
+WL_EXPORT void
+notify_motion_relative(struct weston_seat *seat, uint32_t time,
+		       wl_fixed_t dx, wl_fixed_t dy)
+{
+	struct wl_pointer *pointer = seat->seat.pointer;
+
+	wl_fixed_t x = dx + pointer->x;
+	wl_fixed_t y = dy + pointer->y;
+
+	notify_motion(seat, time, x, y, dx, dy);
+}
+
+WL_EXPORT void
+notify_motion(struct weston_seat *seat, uint32_t time,
+	      wl_fixed_t x, wl_fixed_t y,
+	      wl_fixed_t dx, wl_fixed_t dy)
 {
 	const struct wl_pointer_grab_interface *interface;
 	struct weston_compositor *ec = seat->compositor;
@@ -2192,8 +2218,11 @@ notify_motion(struct weston_seat *seat, uint32_t time, wl_fixed_t x, wl_fixed_t
 
 	weston_device_repick(seat);
 	interface = pointer->grab->interface;
+	/* FIXME dx and dy would have to be transformed relative to the
+	 * target surface. */
 	interface->motion(pointer->grab, time,
-			  pointer->grab->x, pointer->grab->y);
+			  pointer->grab->x, pointer->grab->y,
+			  dx, dy);
 
 	if (seat->sprite) {
 		weston_surface_set_position(seat->sprite,
@@ -2274,9 +2303,13 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
 	else
 		return;
 
-	if (pointer->focus_resource)
-		wl_pointer_send_axis(pointer->focus_resource, time, axis,
+	if (pointer->abs.focus_resource)
+		wl_pointer_send_axis(pointer->abs.focus_resource, time, axis,
 				     value);
+
+	if (pointer->rel.focus_resource)
+		wl_relative_pointer_send_axis(pointer->rel.focus_resource,
+					      time, axis, value);
 }
 
 WL_EXPORT void
@@ -2712,6 +2745,10 @@ static const struct wl_pointer_interface pointer_interface = {
 	pointer_set_cursor
 };
 
+static const struct wl_relative_pointer_interface relative_pointer_interface = {
+	pointer_set_cursor
+};
+
 static void
 handle_drag_surface_destroy(struct wl_listener *listener, void *data)
 {
@@ -2741,7 +2778,41 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
 
         cr = wl_client_add_object(client, &wl_pointer_interface,
 				  &pointer_interface, id, seat);
-	wl_list_insert(&seat->seat.pointer->resource_list, &cr->link);
+	wl_list_insert(&seat->seat.pointer->abs.resource_list, &cr->link);
+	cr->destroy = unbind_resource;
+
+	if (seat->seat.pointer->focus &&
+	    seat->seat.pointer->focus->resource.client == client) {
+		struct weston_surface *surface;
+		wl_fixed_t sx, sy;
+
+		surface = (struct weston_surface *) seat->seat.pointer->focus;
+		weston_surface_from_global_fixed(surface,
+						 seat->seat.pointer->x,
+						 seat->seat.pointer->y,
+						 &sx,
+						 &sy);
+		wl_pointer_set_focus(seat->seat.pointer,
+				     seat->seat.pointer->focus,
+				     sx,
+				     sy);
+	}
+}
+
+static void
+seat_get_relative_pointer(struct wl_client *client,
+			  struct wl_resource *resource,
+			  uint32_t id)
+{
+	struct weston_seat *seat = resource->data;
+	struct wl_resource *cr;
+
+	if (!seat->seat.pointer)
+		return;
+
+        cr = wl_client_add_object(client, &wl_relative_pointer_interface,
+				  &relative_pointer_interface, id, seat);
+	wl_list_insert(&seat->seat.pointer->rel.resource_list, &cr->link);
 	cr->destroy = unbind_resource;
 
 	if (seat->seat.pointer->focus &&
@@ -2805,6 +2876,7 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
 
 static const struct wl_seat_interface seat_interface = {
 	seat_get_pointer,
+	seat_get_relative_pointer,
 	seat_get_keyboard,
 	seat_get_touch,
 };
diff --git a/src/compositor.h b/src/compositor.h
index 96a0477..696f00d 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -505,8 +505,15 @@ weston_surface_draw(struct weston_surface *es,
 		    struct weston_output *output, pixman_region32_t *damage);
 
 void
+notify_motion_absolute(struct weston_seat *seat, uint32_t time,
+		       wl_fixed_t x, wl_fixed_t y);
+void
+notify_motion_relative(struct weston_seat *seat, uint32_t time,
+		       wl_fixed_t dx, wl_fixed_t dy);
+void
 notify_motion(struct weston_seat *seat, uint32_t time,
-	      wl_fixed_t x, wl_fixed_t y);
+	      wl_fixed_t x, wl_fixed_t y,
+	      wl_fixed_t dx, wl_fixed_t dy);
 void
 notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
 	      enum wl_pointer_button_state state);
diff --git a/src/evdev.c b/src/evdev.c
index 8848736..64eb4c0 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -217,9 +217,8 @@ evdev_flush_motion(struct evdev_device *device, uint32_t time)
 		return;
 
 	if (device->pending_events & EVDEV_RELATIVE_MOTION) {
-		notify_motion(master, time,
-			      master->seat.pointer->x + device->rel.dx,
-			      master->seat.pointer->y + device->rel.dy);
+		notify_motion_relative(master, time,
+				       device->rel.dx, device->rel.dy);
 		device->pending_events &= ~EVDEV_RELATIVE_MOTION;
 		device->rel.dx = 0;
 		device->rel.dy = 0;
@@ -248,9 +247,9 @@ evdev_flush_motion(struct evdev_device *device, uint32_t time)
 		device->pending_events &= ~EVDEV_ABSOLUTE_MT_UP;
 	}
 	if (device->pending_events & EVDEV_ABSOLUTE_MOTION) {
-		notify_motion(master, time,
-			      wl_fixed_from_int(device->abs.x),
-			      wl_fixed_from_int(device->abs.y));
+		notify_motion_absolute(master, time,
+				       wl_fixed_from_int(device->abs.x),
+				       wl_fixed_from_int(device->abs.y));
 		device->pending_events &= ~EVDEV_ABSOLUTE_MOTION;
 	}
 }
diff --git a/src/shell.c b/src/shell.c
index 06d8684..8dd22f8 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -986,7 +986,8 @@ noop_grab_focus(struct wl_pointer_grab *grab,
 
 static void
 move_grab_motion(struct wl_pointer_grab *grab,
-		 uint32_t time, wl_fixed_t x, wl_fixed_t y)
+		 uint32_t time, wl_fixed_t x, wl_fixed_t y,
+		 wl_fixed_t relx, wl_fixed_t rely)
 {
 	struct weston_move_grab *move = (struct weston_move_grab *) grab;
 	struct wl_pointer *pointer = grab->pointer;
@@ -1078,7 +1079,8 @@ struct weston_resize_grab {
 
 static void
 resize_grab_motion(struct wl_pointer_grab *grab,
-		   uint32_t time, wl_fixed_t x, wl_fixed_t y)
+		   uint32_t time, wl_fixed_t x, wl_fixed_t y,
+		   wl_fixed_t dx, wl_fixed_t dy)
 {
 	struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
 	struct wl_pointer *pointer = grab->pointer;
@@ -1210,7 +1212,8 @@ busy_cursor_grab_focus(struct wl_pointer_grab *base,
 
 static void
 busy_cursor_grab_motion(struct wl_pointer_grab *grab,
-			uint32_t time, int32_t x, int32_t y)
+			uint32_t time, wl_fixed_t x, wl_fixed_t y,
+			wl_fixed_t dx, wl_fixed_t dy)
 {
 }
 
@@ -1793,34 +1796,49 @@ popup_grab_focus(struct wl_pointer_grab *grab,
 
 static void
 popup_grab_motion(struct wl_pointer_grab *grab,
-		  uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
+		  uint32_t time, wl_fixed_t sx, wl_fixed_t sy,
+		  wl_fixed_t dx, wl_fixed_t dy)
 {
 	struct wl_resource *resource;
 
-	resource = grab->pointer->focus_resource;
+	resource = grab->pointer->abs.focus_resource;
 	if (resource)
 		wl_pointer_send_motion(resource, time, sx, sy);
+
+	resource = grab->pointer->rel.focus_resource;
+	if (resource)
+		wl_relative_pointer_send_motion(resource, time, dx, dy);
 }
 
 static void
 popup_grab_button(struct wl_pointer_grab *grab,
 		  uint32_t time, uint32_t button, uint32_t state_w)
 {
-	struct wl_resource *resource;
+	struct wl_resource *resource, *rel_resource;
 	struct shell_surface *shsurf =
 		container_of(grab, struct shell_surface, popup.grab);
 	struct wl_display *display;
 	enum wl_pointer_button_state state = state_w;
 	uint32_t serial;
 
-	resource = grab->pointer->focus_resource;
+	resource = grab->pointer->abs.focus_resource;
+	rel_resource = grab->pointer->rel.focus_resource;
 	if (resource) {
 		display = wl_client_get_display(resource->client);
 		serial = wl_display_get_serial(display);
 		wl_pointer_send_button(resource, serial, time, button, state);
-	} else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
-		   (shsurf->popup.initial_up ||
-		    time - shsurf->popup.seat->pointer->grab_time > 500)) {
+	}
+	if (rel_resource) {
+		display = wl_client_get_display(rel_resource->client);
+		serial = wl_display_get_serial(display);
+		wl_relative_pointer_send_button(rel_resource, serial, time,
+						button, state);
+	}
+
+	if (!resource && !rel_resource &&
+	    state == WL_POINTER_BUTTON_STATE_RELEASED &&
+	    (shsurf->popup.initial_up ||
+	     time - shsurf->popup.seat->pointer->grab_time > 500)) {
 		wl_shell_surface_send_popup_done(&shsurf->resource);
 		wl_pointer_end_grab(grab->pointer);
 		shsurf->popup.grab.pointer = NULL;
@@ -2451,7 +2469,8 @@ terminate_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
 
 static void
 rotate_grab_motion(struct wl_pointer_grab *grab,
-		   uint32_t time, wl_fixed_t x, wl_fixed_t y)
+		   uint32_t time, wl_fixed_t x, wl_fixed_t y,
+		   wl_fixed_t relx, wl_fixed_t rely)
 {
 	struct rotate_grab *rotate =
 		container_of(grab, struct rotate_grab, base.grab);
-- 
1.7.12



More information about the wayland-devel mailing list