if the system doesn't have a pointer device
common_surface_resize will crash on
accessing seat->pointer->button_count. if the system
does have a pointer device, but attempts to resize
a window using touchscreen - nothing happens. here
we implement separate window resizing path for
seat->touch as it is done in common_surface_move
---
 clients/window.c      |    5 +-
 desktop-shell/shell.c |  153 ++++++++++++++++++++++++++++++++++++++++++++++---
 shared/cairo-util.h   |    2 +-
 shared/frame.c        |   10 ++--
 4 files changed, 154 insertions(+), 16 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index e770a04..185fe23 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2409,9 +2409,10 @@ frame_touch_down_handler(struct widget *widget, struct 
input *input,
                         float x, float y, void *data)
 {
        struct window_frame *frame = data;
+       enum theme_location location;
 
-       frame_touch_down(frame->frame, input, id, x, y);
-       frame_handle_status(frame, input, time, THEME_LOCATION_CLIENT_AREA);
+       location = frame_touch_down(frame->frame, input, id, x, y);
+       frame_handle_status(frame, input, time, location);
 }
 
 static void
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index bc4a258..23125af 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -1581,6 +1581,14 @@ struct weston_resize_grab {
        int32_t width, height;
 };
 
+struct weston_touch_resize_grab {
+       struct shell_touch_grab base;
+       int active;
+       uint32_t edges;
+       int32_t width, height;
+       wl_fixed_t dx, dy;
+};
+
 static void
 resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
                   wl_fixed_t x, wl_fixed_t y)
@@ -1668,6 +1676,84 @@ static const struct weston_pointer_grab_interface 
resize_grab_interface = {
        resize_grab_cancel,
 };
 
+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)
+{
+}
+
+static void
+touch_resize_grab_up(struct weston_touch_grab *grab, uint32_t time, int 
touch_id)
+{
+       struct weston_touch_resize_grab *resize =
+               (struct weston_touch_resize_grab *) container_of(
+                       grab, struct shell_touch_grab, grab);
+
+       if (touch_id == 0)
+               resize->active = 0;
+
+       if (grab->touch->num_tp == 0) {
+               shell_touch_grab_end(&resize->base);
+               free(resize);
+       }
+}
+
+static void
+touch_resize_grab_motion(struct weston_touch_grab *grab, uint32_t time,
+                      int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+       struct weston_touch_resize_grab *resize = (struct 
weston_touch_resize_grab *) grab;
+       struct weston_touch *touch = grab->touch;
+       struct shell_surface *shsurf = resize->base.shsurf;
+       int32_t width, height;
+       wl_fixed_t from_x, from_y;
+       wl_fixed_t to_x, to_y;
+
+       if (!shsurf || !resize->active)
+               return;
+
+       weston_view_from_global_fixed(shsurf->view,
+                                     resize->dx, resize->dy,
+                                     &from_x, &from_y);
+       weston_view_from_global_fixed(shsurf->view,
+                                     touch->grab_x, touch->grab_y, &to_x, 
&to_y);
+
+       width = resize->width;
+       if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
+               width += wl_fixed_to_int(from_x - to_x);
+       } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
+               width += wl_fixed_to_int(to_x - from_x);
+       }
+
+       height = resize->height;
+       if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
+               height += wl_fixed_to_int(from_y - to_y);
+       } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
+               height += wl_fixed_to_int(to_y - from_y);
+       }
+
+       shsurf->client->send_configure(shsurf->surface,
+                                      resize->edges, width, height);
+}
+
+static void
+touch_resize_grab_cancel(struct weston_touch_grab *grab)
+{
+       struct weston_touch_resize_grab *resize =
+               (struct weston_touch_resize_grab *) container_of(
+                       grab, struct shell_touch_grab, grab);
+
+       shell_touch_grab_end(&resize->base);
+       free(resize);
+}
+
+static const struct weston_touch_grab_interface touch_resize_grab_interface = {
+       touch_resize_grab_down,
+       touch_resize_grab_up,
+       touch_resize_grab_motion,
+       touch_resize_grab_cancel,
+};
+
 /*
  * Returns the bounding box of a surface and all its sub-surfaces,
  * in the surface coordinates system. */
@@ -1731,6 +1817,37 @@ surface_resize(struct shell_surface *shsurf,
        return 0;
 }
 
+static int
+surface_touch_resize(struct shell_surface *shsurf,
+              struct weston_seat *seat, uint32_t edges)
+{
+       struct weston_touch_resize_grab *resize;
+
+       if (shsurf->state.fullscreen || shsurf->state.maximized)
+               return 0;
+
+       if (edges == 0 || edges > 15 ||
+           (edges & 3) == 3 || (edges & 12) == 12)
+               return 0;
+
+       resize = malloc(sizeof *resize);
+       if (!resize)
+               return -1;
+
+       resize->active = 1;
+       resize->edges = edges;
+       surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,
+                                       &resize->width, &resize->height);
+       resize->dx = seat->touch->grab_x;
+       resize->dy = seat->touch->grab_y;
+
+       shsurf->resize_edges = edges;
+       shell_touch_grab_start(&resize->base, &touch_resize_grab_interface, 
shsurf,
+                        seat->touch);
+
+       return 0;
+}
+
 static void
 common_surface_resize(struct wl_resource *resource,
                      struct wl_resource *seat_resource, uint32_t serial,
@@ -1743,17 +1860,35 @@ common_surface_resize(struct wl_resource *resource,
        if (shsurf->state.fullscreen)
                return;
 
-       if (seat->pointer->button_count == 0 ||
-           seat->pointer->grab_serial != serial ||
-           seat->pointer->focus == NULL)
-               return;
+       if (seat->pointer) {
+               if (seat->pointer->button_count == 0 ||
+                   seat->pointer->grab_serial != serial ||
+                   seat->pointer->focus == NULL)
+                       goto out;
+
+               surface = 
weston_surface_get_main_surface(seat->pointer->focus->surface);
+               if (surface != shsurf->surface)
+                       goto out;
+
+               if (surface_resize(shsurf, seat, edges) < 0)
+                       wl_resource_post_no_memory(resource);
 
-       surface = 
weston_surface_get_main_surface(seat->pointer->focus->surface);
-       if (surface != shsurf->surface)
                return;
+       }
+
+out:
+       if (seat->touch) {
+               if (seat->touch->grab_serial != serial ||
+                   seat->touch->focus == NULL)
+                       return;
 
-       if (surface_resize(shsurf, seat, edges) < 0)
-               wl_resource_post_no_memory(resource);
+               surface = 
weston_surface_get_main_surface(seat->touch->focus->surface);
+               if (surface != shsurf->surface)
+                       return;
+
+               if (surface_touch_resize(shsurf, seat, edges) < 0)
+                       wl_resource_post_no_memory(resource);
+       }
 }
 
 static void
@@ -1877,7 +2012,7 @@ xdg_ping_timeout_handler(void *data)
                        continue;
                if (seat->pointer->focus->surface->resource == NULL)
                        continue;
-               
+
                shsurf = get_shell_surface(seat->pointer->focus->surface);
                if (shsurf &&
                    wl_resource_get_client(shsurf->resource) == sc->client)
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 4493b0d..9643023 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -204,7 +204,7 @@ enum theme_location
 frame_pointer_button(struct frame *frame, void *pointer,
                     uint32_t button, enum frame_button_state state);
 
-void
+enum theme_location
 frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y);
 
 void
diff --git a/shared/frame.c b/shared/frame.c
index 35e6b65..4c910b1 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -782,20 +782,20 @@ frame_pointer_button(struct frame *frame, void *data,
        return location;
 }
 
-void
+enum theme_location
 frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)
 {
        struct frame_touch *touch = frame_touch_get(frame, data);
        struct frame_button *button = frame_find_button(frame, x, y);
-       enum theme_location location;
+       enum theme_location location = THEME_LOCATION_EXTERIOR;
 
        if (id > 0)
-               return;
+               return location;
 
        if (touch && button) {
                touch->button = button;
                frame_button_press(touch->button);
-               return;
+               return THEME_LOCATION_TITLEBAR;
        }
 
        location = theme_get_location(frame->theme, x, y,
@@ -820,6 +820,8 @@ frame_touch_down(struct frame *frame, void *data, int32_t 
id, int x, int y)
        default:
                break;
        }
+
+       return location;
 }
 
 void
-- 
1.7.9.5

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to