x11: Move implementation of Cairo context backends
authorBenjamin Otte <otte@redhat.com>
Sat, 14 Apr 2018 00:29:23 +0000 (02:29 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 24 Apr 2018 21:16:13 +0000 (23:16 +0200)
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
gdk/x11/gdkcairocontext-x11.h
gdk/x11/gdkdnd-x11.c
gdk/x11/gdksurface-x11.c

index ee464d8f4a7755736f2ba5c67affc0bbd4553181..41fb43ee0c0107a07496928f6f43318691b8ce81 100644 (file)
 
 #include "config.h"
 
-#include "gdkconfig.h"
-
 #include "gdkcairocontext-x11.h"
 
+#include "gdkprivate-x11.h"
+
+#include "gdkcairo.h"
+#include "gdkinternals.h"
+
+#include <X11/Xlib.h>
+
 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
index 2fb4d8d32371cd9229b5c19e2362fc1b7b45cde0..34c84bf1e86d9f8af3a30aa57afda4e5661e313a 100644 (file)
@@ -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
index 659923fb66ab0a6e2237fd8b14f29c02b487c07e..fed6f33890071ff1b0ef9e737ac41cff4c0111d6 100644 (file)
@@ -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);
index 387582f47765df73561f834206eb9f48a9e8a71a..c55589c8498d28f94b9c4de47ab8aa012055b2bb 100644 (file)
@@ -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;