diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 31765a70..42d8a6ee 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -1811,6 +1811,18 @@ void weston_view_to_global_float(struct weston_view *view, float sx, float sy, float *x, float *y); +struct weston_coord_global __attribute__ ((warn_unused_result)) +weston_coord_surface_to_global(const struct weston_view *view, + struct weston_coord_surface coord); + +struct weston_coord_surface __attribute__ ((warn_unused_result)) +weston_coord_global_to_surface(const struct weston_view *view, + struct weston_coord_global coord); + +struct weston_coord_buffer __attribute__ ((warn_unused_result)) +weston_coord_surface_to_buffer(const struct weston_surface *surface, + struct weston_coord_surface coord); + void weston_view_from_global(struct weston_view *view, int32_t x, int32_t y, int32_t *vx, int32_t *vy); diff --git a/include/libweston/matrix.h b/include/libweston/matrix.h index ffa5b755..842d9688 100644 --- a/include/libweston/matrix.h +++ b/include/libweston/matrix.h @@ -27,6 +27,7 @@ #ifndef WESTON_MATRIX_H #define WESTON_MATRIX_H +#include #include #include @@ -51,6 +52,28 @@ struct weston_vector { float f[4]; }; +/** Arbitrary coordinates in any space */ +struct weston_coord { + double x; + double y; +}; + +/** Coordinates in some weston_buffer (physical pixels) */ +struct weston_coord_buffer { + struct weston_coord c; +}; + +/** Coordinates in the global compositor space (logical pixels) */ +struct weston_coord_global { + struct weston_coord c; +}; + +/** surface-local coordinates on a specific surface */ +struct weston_coord_surface { + struct weston_coord c; + const struct weston_surface *coordinate_space_id; +}; + void weston_matrix_init(struct weston_matrix *matrix); void @@ -66,6 +89,10 @@ void weston_matrix_transform(const struct weston_matrix *matrix, struct weston_vector *v); +struct weston_coord +weston_matrix_transform_coord(const struct weston_matrix *matrix, + struct weston_coord coord); + int weston_matrix_invert(struct weston_matrix *inverse, const struct weston_matrix *matrix); @@ -83,6 +110,62 @@ weston_matrix_init_transform(struct weston_matrix *matrix, int x, int y, int width, int height, int scale); +static inline struct weston_coord __attribute__ ((warn_unused_result)) +weston_coord_from_fixed(wl_fixed_t x, wl_fixed_t y) +{ + struct weston_coord out; + + out.x = wl_fixed_to_double(x); + out.y = wl_fixed_to_double(y); + return out; +} + +static inline struct weston_coord __attribute__ ((warn_unused_result)) +weston_coord(double x, double y) +{ + return (struct weston_coord){ .x = x, .y = y }; +} + +static inline struct weston_coord_surface __attribute__ ((warn_unused_result)) +weston_coord_surface(double x, double y, const struct weston_surface *surface) +{ + struct weston_coord_surface out; + + assert(surface); + + out.c = weston_coord(x, y); + out.coordinate_space_id = surface; + + return out; +} + +static inline struct weston_coord_surface __attribute__ ((warn_unused_result)) +weston_coord_surface_from_fixed(wl_fixed_t x, wl_fixed_t y, + const struct weston_surface *surface) +{ + struct weston_coord_surface out; + + assert(surface); + + out.c.x = wl_fixed_to_double(x); + out.c.y = wl_fixed_to_double(y); + out.coordinate_space_id = surface; + + return out; +} + +static inline struct weston_coord __attribute__ ((warn_unused_result)) +weston_coord_add(struct weston_coord a, struct weston_coord b) +{ + return weston_coord(a.x + b.x, a.y + b.y); +} + +static inline struct weston_coord __attribute__ ((warn_unused_result)) +weston_coord_sub(struct weston_coord a, struct weston_coord b) +{ + return weston_coord(a.x - b.x, a.y - b.y); +} + #ifdef __cplusplus } #endif diff --git a/libweston/backend.h b/libweston/backend.h index a3afb32f..3f8caff0 100644 --- a/libweston/backend.h +++ b/libweston/backend.h @@ -165,6 +165,11 @@ int weston_output_mode_set_native(struct weston_output *output, struct weston_mode *mode, int32_t scale); + +struct weston_coord_global +weston_coord_global_from_output_point(double x, double y, + const struct weston_output *output); + void weston_output_transform_coordinate(struct weston_output *output, double device_x, double device_y, diff --git a/libweston/compositor.c b/libweston/compositor.c index 46d62ef0..4c1a9928 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -678,6 +678,46 @@ weston_view_to_global_float(struct weston_view *view, *y = v.f[1] / v.f[3]; } +WL_EXPORT struct weston_coord_global +weston_coord_surface_to_global(const struct weston_view *view, + struct weston_coord_surface coord) +{ + struct weston_coord_global out; + + assert(!view->transform.dirty); + assert(view->surface == coord.coordinate_space_id); + + out.c = weston_matrix_transform_coord(&view->transform.matrix, + coord.c); + return out; +} + +WL_EXPORT struct weston_coord_surface +weston_coord_global_to_surface(const struct weston_view *view, + struct weston_coord_global coord) +{ + struct weston_coord_surface out; + + assert(!view->transform.dirty); + out.c = weston_matrix_transform_coord(&view->transform.inverse, + coord.c); + out.coordinate_space_id = view->surface; + return out; +} + +WL_EXPORT struct weston_coord_buffer +weston_coord_surface_to_buffer(const struct weston_surface *surface, + struct weston_coord_surface coord) +{ + struct weston_coord_buffer tmp; + + assert(surface == coord.coordinate_space_id); + + tmp.c = weston_matrix_transform_coord(&surface->surface_to_buffer_matrix, + coord.c); + return tmp; +} + WL_EXPORT pixman_box32_t weston_matrix_transform_rect(struct weston_matrix *matrix, pixman_box32_t rect) @@ -6421,6 +6461,32 @@ weston_compositor_add_output(struct weston_compositor *compositor, weston_view_geometry_dirty(view); } +/** Create a weston_coord_global from a point and a weston_output + * + * \param x x coordinate on the output + * \param y y coordinate on the output + * \param output the weston_output object + * \return coordinate in global space corresponding to x, y on the output + * + * Transforms coordinates from the device coordinate space (physical pixel + * units) to the global coordinate space (logical pixel units). This takes + * into account output transform and scale. + * + * \ingroup output + * \internal + */ +WL_EXPORT struct weston_coord_global +weston_coord_global_from_output_point(double x, double y, + const struct weston_output *output) +{ + struct weston_coord c; + struct weston_coord_global tmp; + + c = weston_coord(x, y); + tmp.c = weston_matrix_transform_coord(&output->inverse_matrix, c); + return tmp; +} + /** Transform device coordinates into global coordinates * * \param output the weston_output object diff --git a/shared/matrix.c b/shared/matrix.c index f41abe76..472f299a 100644 --- a/shared/matrix.c +++ b/shared/matrix.c @@ -126,6 +126,22 @@ weston_matrix_transform(const struct weston_matrix *matrix, *v = t; } +WL_EXPORT struct weston_coord +weston_matrix_transform_coord(const struct weston_matrix *matrix, + struct weston_coord c) +{ + struct weston_coord out; + struct weston_vector t = { { c.x, c.y, 0.0, 1.0 } }; + + weston_matrix_transform(matrix, &t); + + assert(fabsf(t.f[3]) > 1e-6); + + out.x = t.f[0] / t.f[3]; + out.y = t.f[1] / t.f[3]; + return out; +} + static inline void swap_rows(double *a, double *b) {