On Thu, 18 Apr 2013 13:18:05 +0100
Rob Bradford <[email protected]> wrote:

> From: Rob Bradford <[email protected]>
> 
> Implement a basic implementation for returning the visible area in response 
> to a
> probe_area request.
> 
> v2: Return an object that the event is fired on rather than firing on the
> surface (review from Kristian)
> v3: Use weston_surface_{to,from}_global (review from Pekka Paalanen)
> v4: Take into consideration the output position (review from Pekka)
> ---
>  src/shell.c | 83 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 82 insertions(+), 1 deletion(-)
> 
> diff --git a/src/shell.c b/src/shell.c
> index 9d0ae02..dab54ed 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -2073,6 +2073,86 @@ shell_surface_set_popup(struct wl_client *client,
>       shsurf->popup.y = y;
>  }
>  
> +
> +static void
> +shell_surface_probe_area(struct wl_client *client,
> +                      struct wl_resource *resource,
> +                      int x,
> +                      int y,
> +                      int w,
> +                      int h,
> +                      uint32_t result_id)
> +{
> +     struct wl_resource result;
> +     struct shell_surface *shsurf = resource->data;
> +     struct {
> +             struct {
> +                     float x;
> +                     float y;
> +             } tl, br; /* tl = top left, br = bottom right */
> +     } orig, new;
> +
> +     float new_x, new_y, new_w, new_h;
> +
> +     struct weston_output *output = shsurf->surface->output;
> +
> +     /* orig and new are in global co-ordinates */
> +     weston_surface_to_global_float(shsurf->surface,
> +                                    x, y,
> +                                    &orig.tl.x, &orig.tl.y);
> +     weston_surface_to_global_float(shsurf->surface,
> +                                    x + w, y + h,
> +                                    &orig.br.x, &orig.br.y);

If you wanted this to work also on transformed surfaces, I think you
would need to transform all four corners, and then operate on the
bounding box. When returning the result, account for the boundingbox's
effect on the coordinates.

But IIRC I said the last time, that that can be left for later, right?

> +
> +     new = orig;
> +
> +     /* Clamp the top left so it is inside the output dimensions */
> +     if (orig.tl.x < output->x)
> +       new.tl.x = output->x;
> +     if (orig.tl.y < output->y)
> +       new.tl.y = output->y;
> +     if (orig.tl.x > output->x + output->width)
> +       new.tl.x = output->x + output->width;
> +     if (orig.tl.y > output->y + output->height)
> +       new.tl.y = output->y + output->height;
> +
> +     /* Clamp the bottom right so it is inside the output dimensions */
> +     if (orig.br.x < output->x)
> +       new.br.x = output->x;
> +     if (orig.br.y < output->y)
> +       new.br.y = output->y;
> +     if (orig.br.x > output->x + output->width)
> +       new.br.x = output->x + output->width;
> +     if (orig.br.y > output->y + output->height)
> +       new.br.y = output->y + output->height;
> +
> +     /* Translate back into relative co-ordinates */
> +     weston_surface_from_global_float(shsurf->surface,
> +                                      new.tl.x, new.tl.y,
> +                                      &new_x, &new_y);

This one takes care of the distance from the edge, ok.

> +
> +     /* and relative size */
> +     new_w = new.br.x - ceilf(new.tl.x);
> +     new_h = new.br.y - ceilf(new.tl.y);

I think that is computing the w,h in the global coordinate system, when
it should be computed in the surface-local coordinate system. Would
probably fail also on a scaled surface, no need for rotation.

> +
> +     memset(&result, 0, sizeof(result));
> +
> +     result.object.interface = &wl_probe_result_interface;
> +     result.object.id = result_id;
> +     result.destroy = NULL;
> +     result.client = client;
> +     result.data = NULL;
> +
> +     wl_client_add_resource(client, &result);
> +
> +     wl_resource_post_event(&result,
> +                            WL_PROBE_RESULT_VISIBLE_AREA,
> +                            (int)ceilf(new_x), (int)ceilf(new_y),
> +                            (int)floorf(new_w), (int)floorf(new_h));
> +
> +     wl_resource_destroy(&result);
> +}
> +
>  static const struct wl_shell_surface_interface shell_surface_implementation 
> = {
>       shell_surface_pong,
>       shell_surface_move,
> @@ -2083,7 +2163,8 @@ static const struct wl_shell_surface_interface 
> shell_surface_implementation = {
>       shell_surface_set_popup,
>       shell_surface_set_maximized,
>       shell_surface_set_title,
> -     shell_surface_set_class
> +     shell_surface_set_class,
> +     shell_surface_probe_area
>  };
>  
>  static void


The transform caveats notwithstanding, looks mergable :-)

Thanks,
pq
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to