From 03e6cefe73e4a3865a41e853f28e0e700d37a948 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 14 Apr 2018 02:29:23 +0200 Subject: [PATCH] x11: Move implementation of Cairo context backends Also, don't implement SurfaceClass.ref_cairo_surface() anymore. This means calls to it will crash now. But as they only happen in the generic GdkCairoContext implementation, we shouldn't be affected by that. Plus, once all backends have been ported, that call is going away anyway. --- gdk/x11/gdkcairocontext-x11.c | 97 ++++++++++++++++++++++++++++++++++- gdk/x11/gdkcairocontext-x11.h | 3 ++ gdk/x11/gdkdnd-x11.c | 6 ++- gdk/x11/gdksurface-x11.c | 39 -------------- 4 files changed, 102 insertions(+), 43 deletions(-) diff --git a/gdk/x11/gdkcairocontext-x11.c b/gdk/x11/gdkcairocontext-x11.c index ee464d8f4a..41fb43ee0c 100644 --- a/gdk/x11/gdkcairocontext-x11.c +++ b/gdk/x11/gdkcairocontext-x11.c @@ -20,15 +20,108 @@ #include "config.h" -#include "gdkconfig.h" - #include "gdkcairocontext-x11.h" +#include "gdkprivate-x11.h" + +#include "gdkcairo.h" +#include "gdkinternals.h" + +#include + G_DEFINE_TYPE (GdkX11CairoContext, gdk_x11_cairo_context, GDK_TYPE_CAIRO_CONTEXT) +static cairo_surface_t * +create_cairo_surface_for_surface (GdkSurface *surface) +{ + GdkDisplay *display; + cairo_surface_t *cairo_surface; + Visual *visual; + int scale; + + display = gdk_surface_get_display (surface); + scale = gdk_surface_get_scale_factor (surface); + + visual = gdk_x11_display_get_window_visual (GDK_X11_DISPLAY (display)); + cairo_surface = cairo_xlib_surface_create (gdk_x11_display_get_xdisplay (display), + GDK_SURFACE_XID (surface), + visual, + gdk_surface_get_width (surface) * scale, + gdk_surface_get_height (surface) * scale); + cairo_surface_set_device_scale (cairo_surface, scale, scale); + + return cairo_surface; +} + +static void +gdk_x11_cairo_context_begin_frame (GdkDrawContext *draw_context, + cairo_region_t *region) +{ + GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (draw_context); + GdkRectangle clip_box; + GdkSurface *surface; + double sx, sy; + + surface = gdk_draw_context_get_surface (draw_context); + cairo_region_get_extents (region, &clip_box); + + self->window_surface = create_cairo_surface_for_surface (surface); + self->paint_surface = gdk_surface_create_similar_surface (surface, + cairo_surface_get_content (self->window_surface), + MAX (clip_box.width, 1), + MAX (clip_box.height, 1)); + + sx = sy = 1; + cairo_surface_get_device_scale (self->paint_surface, &sx, &sy); + cairo_surface_set_device_offset (self->paint_surface, -clip_box.x*sx, -clip_box.y*sy); +} + +static void +gdk_x11_cairo_context_end_frame (GdkDrawContext *draw_context, + cairo_region_t *painted, + cairo_region_t *damage) +{ + GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (draw_context); + cairo_t *cr; + + cr = cairo_create (self->window_surface); + + cairo_set_source_surface (cr, self->paint_surface, 0, 0); + gdk_cairo_region (cr, painted); + cairo_clip (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + + cairo_destroy (cr); + + cairo_surface_flush (self->window_surface); + + g_clear_pointer (&self->paint_surface, cairo_surface_destroy); + g_clear_pointer (&self->window_surface, cairo_surface_destroy); +} + +static cairo_t * +gdk_x11_cairo_context_cairo_create (GdkCairoContext *context) +{ + GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (context); + + if (self->paint_surface == NULL) + return NULL; + + return cairo_create (self->paint_surface); +} + static void gdk_x11_cairo_context_class_init (GdkX11CairoContextClass *klass) { + GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass); + GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass); + + draw_context_class->begin_frame = gdk_x11_cairo_context_begin_frame; + draw_context_class->end_frame = gdk_x11_cairo_context_end_frame; + + cairo_context_class->cairo_create = gdk_x11_cairo_context_cairo_create; } static void diff --git a/gdk/x11/gdkcairocontext-x11.h b/gdk/x11/gdkcairocontext-x11.h index 2fb4d8d323..34c84bf1e8 100644 --- a/gdk/x11/gdkcairocontext-x11.h +++ b/gdk/x11/gdkcairocontext-x11.h @@ -40,6 +40,9 @@ typedef struct _GdkX11CairoContextClass GdkX11CairoContextClass; struct _GdkX11CairoContext { GdkCairoContext parent_instance; + + cairo_surface_t *window_surface; + cairo_surface_t *paint_surface; }; struct _GdkX11CairoContextClass diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index 659923fb66..fed6f33890 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -2746,9 +2746,11 @@ gdk_x11_drag_context_drop_done (GdkDragContext *context, { GdkX11DragContext *x11_context = GDK_X11_DRAG_CONTEXT (context); GdkDragAnim *anim; +/* cairo_surface_t *win_surface; cairo_surface_t *surface; cairo_t *cr; +*/ guint id; gdk_x11_drag_context_release_selection (context); @@ -2762,6 +2764,7 @@ gdk_x11_drag_context_drop_done (GdkDragContext *context, return; } +/* win_surface = _gdk_surface_ref_cairo_surface (x11_context->drag_surface); surface = gdk_surface_create_similar_surface (x11_context->drag_surface, cairo_surface_get_content (win_surface), @@ -2773,14 +2776,13 @@ gdk_x11_drag_context_drop_done (GdkDragContext *context, cairo_destroy (cr); cairo_surface_destroy (win_surface); -/* pattern = cairo_pattern_create_for_surface (surface); gdk_surface_set_background_pattern (x11_context->drag_surface, pattern); cairo_pattern_destroy (pattern); -*/ cairo_surface_destroy (surface); +*/ anim = g_slice_new0 (GdkDragAnim); anim->context = g_object_ref (x11_context); diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c index 387582f477..c55589c849 100644 --- a/gdk/x11/gdksurface-x11.c +++ b/gdk/x11/gdksurface-x11.c @@ -467,44 +467,6 @@ gdk_x11_surface_end_frame (GdkSurface *surface) * X11 specific implementations of generic functions * *****************************************************/ -static cairo_surface_t * -gdk_x11_create_cairo_surface (GdkSurfaceImplX11 *impl, - int width, - int height) -{ - Visual *visual; - - visual = gdk_x11_display_get_window_visual (GDK_X11_DISPLAY (gdk_surface_get_display (impl->wrapper))); - return cairo_xlib_surface_create (GDK_SURFACE_XDISPLAY (impl->wrapper), - GDK_SURFACE_IMPL_X11 (impl)->xid, - visual, - width, height); -} - -static cairo_surface_t * -gdk_x11_ref_cairo_surface (GdkSurface *surface) -{ - GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl); - - if (GDK_SURFACE_DESTROYED (surface)) - return NULL; - - if (!impl->cairo_surface) - { - impl->cairo_surface = gdk_x11_create_cairo_surface (impl, - gdk_surface_get_width (surface) * impl->surface_scale, - gdk_surface_get_height (surface) * impl->surface_scale); - cairo_surface_set_device_scale (impl->cairo_surface, impl->surface_scale, impl->surface_scale); - - if (SURFACE_IS_TOPLEVEL (surface) && impl->toplevel->in_frame) - hook_surface_changed (surface); - } - - cairo_surface_reference (impl->cairo_surface); - - return impl->cairo_surface; -} - static void gdk_surface_impl_x11_finalize (GObject *object) { @@ -4858,7 +4820,6 @@ gdk_surface_impl_x11_class_init (GdkSurfaceImplX11Class *klass) object_class->finalize = gdk_surface_impl_x11_finalize; - impl_class->ref_cairo_surface = gdk_x11_ref_cairo_surface; impl_class->show = gdk_surface_x11_show; impl_class->hide = gdk_surface_x11_hide; impl_class->withdraw = gdk_surface_x11_withdraw; -- 2.30.2