[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