<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Apr 22, 2014 at 12:55 PM, 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 | 10 ++--<br>
4 files changed, 154 insertions(+), 16 deletions(-)<br>
<br>
</div><div class="">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>
</div><div class=""> static void<br>
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c<br>
</div>index bc4a258..23125af 100644<br>
<div><div class="h5">--- 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>
</div></div>@@ -1731,6 +1817,37 @@ surface_resize(struct shell_surface *shsurf,<br>
<div><div class="h5"> 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>
</div></div>+ shsurf->resize_edges = edges;<br>
<div class="">+ 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>
</div>@@ -1743,17 +1860,35 @@ common_surface_resize(struct wl_resource *resource,<br>
<div class=""> 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>
</div>+ goto out;<br>
+<br>
+ surface = weston_surface_get_main_surface(seat->pointer->focus->surface);<br>
<div class="">+ if (surface != shsurf->surface)<br>
</div>+ goto out;<br>
<div class="">+<br>
+ if (surface_resize(shsurf, seat, edges) < 0)<br>
+ wl_resource_post_no_memory(resource);<br>
<br>
</div><div class="">- surface = weston_surface_get_main_surface(seat->pointer->focus->surface);<br>
- if (surface != shsurf->surface)<br>
</div> return;<br>
+ }<br>
+<br>
+out:<br>
+ if (seat->touch) {<br>
<div class="">+ if (seat->touch->grab_serial != serial ||<br>
+ seat->touch->focus == NULL)<br>
+ return;<br>
<br>
</div><div class="">- if (surface_resize(shsurf, seat, edges) < 0)<br>
- wl_resource_post_no_memory(resource);<br>
</div>+ surface = weston_surface_get_main_surface(seat->touch->focus->surface);<br>
<div class="">+ if (surface != shsurf->surface)<br>
+ return;<br>
</div><div class="">+<br>
+ if (surface_touch_resize(shsurf, seat, edges) < 0)<br>
+ wl_resource_post_no_memory(resource);<br>
+ }<br>
}<br>
<br>
static void<br>
</div>@@ -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>
<div class="">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>index 35e6b65..4c910b1 100644<br>
<div class="">--- a/shared/frame.c<br>
+++ b/shared/frame.c<br>
@@ -782,20 +782,20 @@ frame_pointer_button(struct frame *frame, void *data,<br>
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>
+ return location;<br>
<br>
if (touch && button) {<br>
touch->button = button;<br>
frame_button_press(touch->button);<br>
- return;<br>
</div>+ return THEME_LOCATION_TITLEBAR;<br>
<div class="im HOEnZb"> }<br></div></blockquote><div><br></div><div>Yes, this is a bit better. I'd still rather call theme_get_location before this and just return that value. However, the end result should be the same.<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"><div class="im HOEnZb">
<br>
location = theme_get_location(frame->theme, x, y,<br>
@@ -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>