<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 23, 2014 at 1:02 AM, Stanislav Vorobiov <span dir="ltr"><<a href="mailto:s.vorobiov@samsung.com" target="_blank">s.vorobiov@samsung.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">if the system doesn't have a pointer device<br>
common_surface_resize will crash on<br>
accessing seat->pointer->button_count. if the system<br>
does have a pointer device, but attempts to resize<br>
a window using touchscreen - nothing happens. here<br>
we implement separate window resizing path for<br>
seat->touch as it is done in common_surface_move<br>
---<br>
</div><div class=""> clients/window.c      |    5 +-<br>
 desktop-shell/shell.c |  153 ++++++++++++++++++++++++++++++++++++++++++++++---<br>
 shared/cairo-util.h   |    2 +-<br>
 shared/frame.c        |   20 ++++---<br>
 4 files changed, 159 insertions(+), 21 deletions(-)<br>
<br>
</div><div><div class="h5">diff --git a/clients/window.c b/clients/window.c<br>
index e770a04..185fe23 100644<br>
--- a/clients/window.c<br>
+++ b/clients/window.c<br>
@@ -2409,9 +2409,10 @@ frame_touch_down_handler(struct widget *widget, struct input *input,<br>
                         float x, float y, void *data)<br>
 {<br>
        struct window_frame *frame = data;<br>
+       enum theme_location location;<br>
<br>
-       frame_touch_down(frame->frame, input, id, x, y);<br>
-       frame_handle_status(frame, input, time, THEME_LOCATION_CLIENT_AREA);<br>
+       location = frame_touch_down(frame->frame, input, id, x, y);<br>
+       frame_handle_status(frame, input, time, location);<br>
 }<br>
<br>
 static void<br>
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c<br>
index bc4a258..23125af 100644<br>
--- a/desktop-shell/shell.c<br>
+++ b/desktop-shell/shell.c<br>
@@ -1581,6 +1581,14 @@ struct weston_resize_grab {<br>
        int32_t width, height;<br>
 };<br>
<br>
+struct weston_touch_resize_grab {<br>
+       struct shell_touch_grab base;<br>
+       int active;<br>
+       uint32_t edges;<br>
+       int32_t width, height;<br>
+       wl_fixed_t dx, dy;<br>
+};<br>
+<br>
 static void<br>
 resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,<br>
                   wl_fixed_t x, wl_fixed_t y)<br>
@@ -1668,6 +1676,84 @@ static const struct weston_pointer_grab_interface resize_grab_interface = {<br>
        resize_grab_cancel,<br>
 };<br>
<br>
+static void<br>
+touch_resize_grab_down(struct weston_touch_grab *grab, uint32_t time,<br>
+                    int touch_id, wl_fixed_t sx, wl_fixed_t sy)<br>
+{<br>
+}<br>
+<br>
+static void<br>
+touch_resize_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)<br>
+{<br>
+       struct weston_touch_resize_grab *resize =<br>
+               (struct weston_touch_resize_grab *) container_of(<br>
+                       grab, struct shell_touch_grab, grab);<br>
+<br>
+       if (touch_id == 0)<br>
+               resize->active = 0;<br>
+<br>
+       if (grab->touch->num_tp == 0) {<br>
+               shell_touch_grab_end(&resize->base);<br>
+               free(resize);<br>
+       }<br>
+}<br>
+<br>
+static void<br>
+touch_resize_grab_motion(struct weston_touch_grab *grab, uint32_t time,<br>
+                      int touch_id, wl_fixed_t sx, wl_fixed_t sy)<br>
+{<br>
+       struct weston_touch_resize_grab *resize = (struct weston_touch_resize_grab *) grab;<br>
+       struct weston_touch *touch = grab->touch;<br>
+       struct shell_surface *shsurf = resize->base.shsurf;<br>
+       int32_t width, height;<br>
+       wl_fixed_t from_x, from_y;<br>
+       wl_fixed_t to_x, to_y;<br>
+<br>
+       if (!shsurf || !resize->active)<br>
+               return;<br>
+<br>
+       weston_view_from_global_fixed(shsurf->view,<br>
+                                     resize->dx, resize->dy,<br>
+                                     &from_x, &from_y);<br>
+       weston_view_from_global_fixed(shsurf->view,<br>
+                                     touch->grab_x, touch->grab_y, &to_x, &to_y);<br>
+<br>
+       width = resize->width;<br>
+       if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {<br>
+               width += wl_fixed_to_int(from_x - to_x);<br>
+       } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {<br>
+               width += wl_fixed_to_int(to_x - from_x);<br>
+       }<br>
+<br>
+       height = resize->height;<br>
+       if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {<br>
+               height += wl_fixed_to_int(from_y - to_y);<br>
+       } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {<br>
+               height += wl_fixed_to_int(to_y - from_y);<br>
+       }<br>
+<br>
+       shsurf->client->send_configure(shsurf->surface,<br>
+                                      resize->edges, width, height);<br>
+}<br>
+<br>
+static void<br>
+touch_resize_grab_cancel(struct weston_touch_grab *grab)<br>
+{<br>
+       struct weston_touch_resize_grab *resize =<br>
+               (struct weston_touch_resize_grab *) container_of(<br>
+                       grab, struct shell_touch_grab, grab);<br>
+<br>
+       shell_touch_grab_end(&resize->base);<br>
+       free(resize);<br>
+}<br>
+<br>
+static const struct weston_touch_grab_interface touch_resize_grab_interface = {<br>
+       touch_resize_grab_down,<br>
+       touch_resize_grab_up,<br>
+       touch_resize_grab_motion,<br>
+       touch_resize_grab_cancel,<br>
+};<br>
+<br>
 /*<br>
  * Returns the bounding box of a surface and all its sub-surfaces,<br>
  * in the surface coordinates system. */<br>
@@ -1731,6 +1817,37 @@ surface_resize(struct shell_surface *shsurf,<br>
        return 0;<br>
 }<br>
<br>
+static int<br>
+surface_touch_resize(struct shell_surface *shsurf,<br>
+              struct weston_seat *seat, uint32_t edges)<br>
+{<br>
+       struct weston_touch_resize_grab *resize;<br>
+<br>
+       if (shsurf->state.fullscreen || shsurf->state.maximized)<br>
+               return 0;<br>
+<br>
+       if (edges == 0 || edges > 15 ||<br>
+           (edges & 3) == 3 || (edges & 12) == 12)<br>
+               return 0;<br>
+<br>
+       resize = malloc(sizeof *resize);<br>
+       if (!resize)<br>
+               return -1;<br>
+<br>
+       resize->active = 1;<br>
+       resize->edges = edges;<br>
+       surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,<br>
+                                       &resize->width, &resize->height);<br>
+       resize->dx = seat->touch->grab_x;<br>
+       resize->dy = seat->touch->grab_y;<br>
+<br>
+       shsurf->resize_edges = edges;<br>
+       shell_touch_grab_start(&resize->base, &touch_resize_grab_interface, shsurf,<br>
+                        seat->touch);<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
 static void<br>
 common_surface_resize(struct wl_resource *resource,<br>
                      struct wl_resource *seat_resource, uint32_t serial,<br>
@@ -1743,17 +1860,35 @@ common_surface_resize(struct wl_resource *resource,<br>
        if (shsurf->state.fullscreen)<br>
                return;<br>
<br>
-       if (seat->pointer->button_count == 0 ||<br>
-           seat->pointer->grab_serial != serial ||<br>
-           seat->pointer->focus == NULL)<br>
-               return;<br>
+       if (seat->pointer) {<br>
+               if (seat->pointer->button_count == 0 ||<br>
+                   seat->pointer->grab_serial != serial ||<br>
+                   seat->pointer->focus == NULL)<br>
+                       goto out;<br>
+<br>
+               surface = weston_surface_get_main_surface(seat->pointer->focus->surface);<br>
+               if (surface != shsurf->surface)<br>
+                       goto out;<br>
+<br>
+               if (surface_resize(shsurf, seat, edges) < 0)<br>
+                       wl_resource_post_no_memory(resource);<br>
<br>
-       surface = weston_surface_get_main_surface(seat->pointer->focus->surface);<br>
-       if (surface != shsurf->surface)<br>
                return;<br>
+       }<br>
+<br>
+out:<br>
+       if (seat->touch) {<br>
+               if (seat->touch->grab_serial != serial ||<br>
+                   seat->touch->focus == NULL)<br>
+                       return;<br>
<br>
-       if (surface_resize(shsurf, seat, edges) < 0)<br>
-               wl_resource_post_no_memory(resource);<br>
+               surface = weston_surface_get_main_surface(seat->touch->focus->surface);<br>
+               if (surface != shsurf->surface)<br>
+                       return;<br>
+<br>
+               if (surface_touch_resize(shsurf, seat, edges) < 0)<br>
+                       wl_resource_post_no_memory(resource);<br>
+       }<br>
 }<br>
<br>
 static void<br>
@@ -1877,7 +2012,7 @@ xdg_ping_timeout_handler(void *data)<br>
                        continue;<br>
                if (seat->pointer->focus->surface->resource == NULL)<br>
                        continue;<br>
-<br>
+<br>
                shsurf = get_shell_surface(seat->pointer->focus->surface);<br>
                if (shsurf &&<br>
                    wl_resource_get_client(shsurf->resource) == sc->client)<br>
diff --git a/shared/cairo-util.h b/shared/cairo-util.h<br>
index 4493b0d..9643023 100644<br>
--- a/shared/cairo-util.h<br>
+++ b/shared/cairo-util.h<br>
@@ -204,7 +204,7 @@ enum theme_location<br>
 frame_pointer_button(struct frame *frame, void *pointer,<br>
                     uint32_t button, enum frame_button_state state);<br>
<br>
-void<br>
+enum theme_location<br>
 frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y);<br>
<br>
 void<br>
diff --git a/shared/frame.c b/shared/frame.c<br>
</div></div>index 35e6b65..833117c 100644<br>
--- a/shared/frame.c<br>
+++ b/shared/frame.c<br>
@@ -782,27 +782,27 @@ frame_pointer_button(struct frame *frame, void *data,<br>
<div class="">        return location;<br>
 }<br>
<br>
-void<br>
+enum theme_location<br>
 frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)<br>
 {<br>
        struct frame_touch *touch = frame_touch_get(frame, data);<br>
        struct frame_button *button = frame_find_button(frame, x, y);<br>
-       enum theme_location location;<br>
+       enum theme_location location = THEME_LOCATION_EXTERIOR;<br>
<br>
        if (id > 0)<br>
-               return;<br>
</div>-<br>
-       if (touch && button) {<br>
-               touch->button = button;<br>
-               frame_button_press(touch->button);<br>
-               return;<br>
-       }<br>
+               return location;<br>
<div class=""><br>
        location = theme_get_location(frame->theme, x, y,<br>
</div>                                      frame->width, frame->height,<br>
                                      frame->flags & FRAME_FLAG_MAXIMIZED ?<br>
                                      THEME_FRAME_MAXIMIZED : 0);<br>
<br>
+       if (touch && button) {<br>
+               touch->button = button;<br>
+               frame_button_press(touch->button);<br>
+               return location;<br>
+       }<br></blockquote><div><br></div><div>Yeah, this is much better.  frame.c bits look good to me!<br></div><div>--Jason Ekstrand<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
        switch (location) {<br>
        case THEME_LOCATION_TITLEBAR:<br>
                frame->status |= FRAME_STATUS_MOVE;<br>
<div class="im HOEnZb">@@ -820,6 +820,8 @@ frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y)<br>
        default:<br>
                break;<br>
        }<br>
+<br>
+       return location;<br>
 }<br>
<br>
 void<br>
</div><div class="HOEnZb"><div class="h5">--<br>
1.7.9.5<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</div></div></blockquote></div><br></div></div>