diff --git a/gdk/gdksubsurface.c b/gdk/gdksubsurface.c index 13776a0bfa..5f0a26f62e 100644 --- a/gdk/gdksubsurface.c +++ b/gdk/gdksubsurface.c @@ -113,6 +113,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface, GdkTexture *texture, const graphene_rect_t *source, const graphene_rect_t *dest, + GdkTextureTransform transform, gboolean above, GdkSubsurface *sibling) { @@ -155,7 +156,7 @@ gdk_subsurface_attach (GdkSubsurface *subsurface, } } - return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, source, dest, above, sibling); + return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, source, dest, transform, above, sibling); } void @@ -203,3 +204,12 @@ gdk_subsurface_is_above_parent (GdkSubsurface *subsurface) return subsurface->above_parent; } + +GdkTextureTransform +gdk_subsurface_get_transform (GdkSubsurface *subsurface) +{ + g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), GDK_TEXTURE_TRANSFORM_NORMAL); + + return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_transform (subsurface); +} + diff --git a/gdk/gdksubsurfaceprivate.h b/gdk/gdksubsurfaceprivate.h index 2ffe394e5b..ea36af1bf5 100644 --- a/gdk/gdksubsurfaceprivate.h +++ b/gdk/gdksubsurfaceprivate.h @@ -47,6 +47,16 @@ struct _GdkSubsurface GdkSubsurface *sibling_below; }; +typedef enum { + GDK_TEXTURE_TRANSFORM_NORMAL, + GDK_TEXTURE_TRANSFORM_90, + GDK_TEXTURE_TRANSFORM_180, + GDK_TEXTURE_TRANSFORM_270, + GDK_TEXTURE_TRANSFORM_FLIPPED, + GDK_TEXTURE_TRANSFORM_FLIPPED_90, + GDK_TEXTURE_TRANSFORM_FLIPPED_180, + GDK_TEXTURE_TRANSFORM_FLIPPED_270, +} GdkTextureTransform; struct _GdkSubsurfaceClass { @@ -56,6 +66,7 @@ struct _GdkSubsurfaceClass GdkTexture *texture, const graphene_rect_t *source, const graphene_rect_t *dest, + GdkTextureTransform transform, gboolean above, GdkSubsurface *sibling); void (* detach) (GdkSubsurface *subsurface); @@ -64,15 +75,19 @@ struct _GdkSubsurfaceClass graphene_rect_t *source); void (* get_dest) (GdkSubsurface *subsurface, graphene_rect_t *dest); + GdkTextureTransform + (* get_transform) (GdkSubsurface *subsurface); }; GType gdk_subsurface_get_type (void) G_GNUC_CONST; GdkSurface * gdk_subsurface_get_parent (GdkSubsurface *subsurface); + gboolean gdk_subsurface_attach (GdkSubsurface *subsurface, GdkTexture *texture, const graphene_rect_t *source, const graphene_rect_t *dest, + GdkTextureTransform transform, gboolean above, GdkSubsurface *sibling); void gdk_subsurface_detach (GdkSubsurface *subsurface); @@ -82,6 +97,8 @@ void gdk_subsurface_get_source (GdkSubsurface *subsurfac void gdk_subsurface_get_dest (GdkSubsurface *subsurface, graphene_rect_t *dest); gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface); +GdkTextureTransform + gdk_subsurface_get_transform (GdkSubsurface *subsurface); G_END_DECLS diff --git a/gdk/wayland/gdksubsurface-wayland-private.h b/gdk/wayland/gdksubsurface-wayland-private.h index 42f357e89f..fb5c98a85a 100644 --- a/gdk/wayland/gdksubsurface-wayland-private.h +++ b/gdk/wayland/gdksubsurface-wayland-private.h @@ -2,6 +2,7 @@ #include "gdksubsurfaceprivate.h" +#include "wayland-client-protocol.h" typedef struct _GdkWaylandSubsurface GdkWaylandSubsurface; typedef struct _GdkWaylandSubsurfaceClass GdkWaylandSubsurfaceClass; @@ -23,6 +24,7 @@ struct _GdkWaylandSubsurface GdkTexture *texture; cairo_rectangle_int_t dest; graphene_rect_t source; + enum wl_output_transform transform; struct wl_region *opaque_region; diff --git a/gdk/wayland/gdksubsurface-wayland.c b/gdk/wayland/gdksubsurface-wayland.c index 588974812d..3e72234e85 100644 --- a/gdk/wayland/gdksubsurface-wayland.c +++ b/gdk/wayland/gdksubsurface-wayland.c @@ -149,11 +149,24 @@ get_wl_buffer (GdkWaylandSubsurface *self, return buffer; } +static inline enum wl_output_transform +gdk_texture_transform_to_wl (GdkTextureTransform transform) +{ + return (enum wl_output_transform) transform; +} + +static inline GdkTextureTransform +wl_output_transform_to_gdk (enum wl_output_transform transform) +{ + return (GdkTextureTransform) transform; +} + static gboolean gdk_wayland_subsurface_attach (GdkSubsurface *sub, GdkTexture *texture, const graphene_rect_t *source, const graphene_rect_t *dest, + GdkTextureTransform transform, gboolean above, GdkSubsurface *sibling) { @@ -188,6 +201,8 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub, self->source.size.width = source->size.width; self->source.size.height = source->size.height; + self->transform = gdk_texture_transform_to_wl (transform); + scale = gdk_fractional_scale_to_double (&parent->scale); device_rect.origin.x = dest->origin.x * scale; @@ -302,6 +317,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub, if (result) { + wl_surface_set_buffer_transform (self->surface, self->transform); wl_subsurface_set_position (self->subsurface, self->dest.x, self->dest.y); wp_viewport_set_destination (self->viewport, self->dest.width, self->dest.height); wp_viewport_set_source (self->viewport, @@ -406,6 +422,14 @@ gdk_wayland_subsurface_get_source (GdkSubsurface *sub, source->size.height = self->source.size.height; } +static GdkTextureTransform +gdk_wayland_subsurface_get_transform (GdkSubsurface *sub) +{ + GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub); + + return wl_output_transform_to_gdk (self->transform); +} + static void gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class) { @@ -419,6 +443,7 @@ gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class) subsurface_class->get_texture = gdk_wayland_subsurface_get_texture; subsurface_class->get_source = gdk_wayland_subsurface_get_source; subsurface_class->get_dest = gdk_wayland_subsurface_get_dest; + subsurface_class->get_transform = gdk_wayland_subsurface_get_transform; }; static void diff --git a/gsk/gskoffload.c b/gsk/gskoffload.c index f4fc9558e7..3c3410faad 100644 --- a/gsk/gskoffload.c +++ b/gsk/gskoffload.c @@ -653,12 +653,14 @@ gsk_offload_new (GdkSurface *surface, info->texture, &info->source, &info->dest, + GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL); else info->is_offloaded = gdk_subsurface_attach (info->subsurface, info->texture, &info->source, &info->dest, + GDK_TEXTURE_TRANSFORM_NORMAL, info->place_above != NULL, info->place_above); } diff --git a/testsuite/gdk/subsurface.c b/testsuite/gdk/subsurface.c index a0a0d8251e..37657e8049 100644 --- a/testsuite/gdk/subsurface.c +++ b/testsuite/gdk/subsurface.c @@ -42,9 +42,9 @@ test_subsurface_stacking (void) texture = gdk_texture_new_from_resource ("/org/gtk/libgtk/icons/16x16/actions/media-eject.png"); - gdk_subsurface_attach (sub0, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), TRUE, NULL); - gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), TRUE, NULL); - gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), TRUE, NULL); + gdk_subsurface_attach (sub0, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL); + gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL); + gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, NULL); g_assert_true (surface->subsurfaces_above == sub2); g_assert_true (sub2->sibling_below == NULL); @@ -67,7 +67,7 @@ test_subsurface_stacking (void) g_assert_true (sub0->sibling_above == NULL); g_assert_true (sub0->above_parent); - gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), FALSE, NULL); + gdk_subsurface_attach (sub2, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, FALSE, NULL); g_assert_true (surface->subsurfaces_above == sub0); g_assert_true (sub0->sibling_below == NULL); @@ -79,7 +79,7 @@ test_subsurface_stacking (void) g_assert_true (sub2->sibling_above == NULL); g_assert_false (sub2->above_parent); - gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), TRUE, sub2); + gdk_subsurface_attach (sub1, texture, &TEXTURE_RECT (texture), &GRAPHENE_RECT_INIT (0, 0, 10, 10), GDK_TEXTURE_TRANSFORM_NORMAL, TRUE, sub2); g_assert_true (surface->subsurfaces_below == sub1); g_assert_true (sub1->sibling_above == NULL);