[PATCH] shell: support zooming without a pointer device

Stanislav Vorobiov s.vorobiov at samsung.com
Mon May 5 08:29:24 PDT 2014


if the system doesn't have a pointer device
do_zoom will crash on accessing seat->pointer->x.
here we implement zoom support on systems with
a touchscreen, touchscreen's last touch point is
simply used instead of pointer's current position
---
 desktop-shell/shell.c |   22 ++++++++++++++++++++--
 src/compositor.h      |    1 +
 src/input.c           |    3 +++
 src/zoom.c            |   40 ++++++++++++++++++++++++++++++++--------
 4 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 2aab283..c7760f7 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -1375,6 +1375,7 @@ static void
 touch_move_grab_down(struct weston_touch_grab *grab, uint32_t time,
 		     int touch_id, wl_fixed_t sx, wl_fixed_t sy)
 {
+	wl_signal_emit(&grab->touch->motion_signal, grab->touch);
 }
 
 static void
@@ -1403,6 +1404,8 @@ touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
 	int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx);
 	int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy);
 
+	wl_signal_emit(&grab->touch->motion_signal, grab->touch);
+
 	if (!shsurf || !move->active)
 		return;
 
@@ -1715,6 +1718,7 @@ static void
 touch_resize_grab_down(struct weston_touch_grab *grab, uint32_t time,
 		     int touch_id, wl_fixed_t sx, wl_fixed_t sy)
 {
+	wl_signal_emit(&grab->touch->motion_signal, grab->touch);
 }
 
 static void
@@ -1744,6 +1748,8 @@ touch_resize_grab_motion(struct weston_touch_grab *grab, uint32_t time,
 	wl_fixed_t from_x, from_y;
 	wl_fixed_t to_x, to_y;
 
+	wl_signal_emit(&grab->touch->motion_signal, grab->touch);
+
 	if (!shsurf || !resize->active)
 		return;
 
@@ -4376,11 +4382,23 @@ do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
 	struct weston_compositor *compositor = ws->compositor;
 	struct weston_output *output;
 	float increment;
+	double x, y;
+
+	if (seat->pointer) {
+		x = wl_fixed_to_double(seat->pointer->x);
+		y = wl_fixed_to_double(seat->pointer->y);
+	} else if (seat->touch) {
+		x = wl_fixed_to_double(seat->touch->grab_x);
+		y = wl_fixed_to_double(seat->touch->grab_y);
+	} else {
+		x = wl_fixed_to_double(0);
+		y = wl_fixed_to_double(0);
+	}
 
 	wl_list_for_each(output, &compositor->output_list, link) {
 		if (pixman_region32_contains_point(&output->region,
-						   wl_fixed_to_double(seat->pointer->x),
-						   wl_fixed_to_double(seat->pointer->y),
+						   x,
+						   y,
 						   NULL)) {
 			if (key == KEY_PAGEUP)
 				increment = output->zoom.increment;
diff --git a/src/compositor.h b/src/compositor.h
index 057f8be..f2f1bf4 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -347,6 +347,7 @@ struct weston_touch {
 	struct wl_listener focus_resource_listener;
 	uint32_t focus_serial;
 	struct wl_signal focus_signal;
+	struct wl_signal motion_signal;
 
 	uint32_t num_tp;
 
diff --git a/src/input.c b/src/input.c
index 2c799f4..616b6e6 100644
--- a/src/input.c
+++ b/src/input.c
@@ -278,6 +278,8 @@ default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
 	struct wl_resource *resource;
 	struct wl_list *resource_list;
 
+	wl_signal_emit(&touch->motion_signal, touch);
+
 	resource_list = &touch->focus_resource_list;
 
 	wl_resource_for_each(resource, resource_list) {
@@ -583,6 +585,7 @@ weston_touch_create(void)
 	touch->default_grab.touch = touch;
 	touch->grab = &touch->default_grab;
 	wl_signal_init(&touch->focus_signal);
+	wl_signal_init(&touch->motion_signal);
 
 	return touch;
 }
diff --git a/src/zoom.c b/src/zoom.c
index 622c0d7..8c8b18a 100644
--- a/src/zoom.c
+++ b/src/zoom.c
@@ -86,8 +86,16 @@ weston_zoom_frame_xy(struct weston_animation *animation,
 
 	if (weston_spring_done(&output->zoom.spring_xy)) {
 		output->zoom.spring_xy.current = output->zoom.spring_xy.target;
-		output->zoom.current.x = seat->pointer->x;
-		output->zoom.current.y = seat->pointer->y;
+		if (seat->pointer) {
+			output->zoom.current.x = seat->pointer->x;
+			output->zoom.current.y = seat->pointer->y;
+		} else if (seat->touch) {
+			output->zoom.current.x = seat->touch->grab_x;
+			output->zoom.current.y = seat->touch->grab_y;
+		} else {
+			output->zoom.current.x = 0;
+			output->zoom.current.y = 0;
+		}
 		wl_list_remove(&animation->link);
 		wl_list_init(&animation->link);
 	}
@@ -220,14 +228,24 @@ WL_EXPORT void
 weston_output_update_zoom(struct weston_output *output)
 {
 	struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
-	wl_fixed_t x = seat->pointer->x;
-	wl_fixed_t y = seat->pointer->y;
+	wl_fixed_t x, y;
+
+	if (seat->pointer) {
+		x = seat->pointer->x;
+		y = seat->pointer->y;
+	} else if (seat->touch) {
+		x = seat->touch->grab_x;
+		y = seat->touch->grab_y;
+	} else {
+		x = 0;
+		y = 0;
+	}
 
 	zoom_area_center_from_pointer(output, &x, &y);
 
 	if (wl_list_empty(&output->zoom.animation_xy.link)) {
-		output->zoom.current.x = seat->pointer->x;
-		output->zoom.current.y = seat->pointer->y;
+		output->zoom.current.x = x;
+		output->zoom.current.y = y;
 	} else {
 		output->zoom.to.x = x;
 		output->zoom.to.y = y;
@@ -258,8 +276,14 @@ weston_output_activate_zoom(struct weston_output *output)
 
 	output->zoom.active = 1;
 	output->disable_planes++;
-	wl_signal_add(&seat->pointer->motion_signal,
-		      &output->zoom.motion_listener);
+	wl_list_init(&output->zoom.motion_listener.link);
+	if (seat->pointer) {
+		wl_signal_add(&seat->pointer->motion_signal,
+			      &output->zoom.motion_listener);
+	} else if (seat->touch) {
+		wl_signal_add(&seat->touch->motion_signal,
+			      &output->zoom.motion_listener);
+	}
 }
 
 WL_EXPORT void
-- 
1.7.9.5



More information about the wayland-devel mailing list