Ping On 04/23/2014 05:41 PM, Jason Ekstrand wrote: > > > > On Wed, Apr 23, 2014 at 1:02 AM, Stanislav Vorobiov <[email protected] > <mailto:[email protected]>> wrote: > > 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 | 20 ++++--- > 4 files changed, 159 insertions(+), 21 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..833117c 100644 > --- a/shared/frame.c > +++ b/shared/frame.c > @@ -782,27 +782,27 @@ 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; > - > - if (touch && button) { > - touch->button = button; > - frame_button_press(touch->button); > - return; > - } > + return location; > > location = theme_get_location(frame->theme, x, y, > frame->width, frame->height, > frame->flags & FRAME_FLAG_MAXIMIZED > ? > THEME_FRAME_MAXIMIZED : 0); > > + if (touch && button) { > + touch->button = button; > + frame_button_press(touch->button); > + return location; > + } > > > Yeah, this is much better. frame.c bits look good to me! > --Jason Ekstrand > > > + > switch (location) { > case THEME_LOCATION_TITLEBAR: > frame->status |= FRAME_STATUS_MOVE; > @@ -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 > [email protected] > <mailto:[email protected]> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel > >
_______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
