diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt
index a6bcd8b82a..2cc4563ce8 100644
--- a/docs/reference/gdk/gdk4-sections.txt
+++ b/docs/reference/gdk/gdk4-sections.txt
@@ -1201,6 +1201,14 @@ GDK_DRAWING_CONTEXT
GDK_IS_DRAWING_CONTEXT
+
+gdkcairocontext
+GdkCairoContext
+
+
+gdk_cairo_context_get_type
+
+
gdkvulkancontext
GdkVulkanContext
diff --git a/gdk/gdk.h b/gdk/gdk.h
index 921e93690d..8311ef23bd 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/gdk/gdkcairocontext.c b/gdk/gdkcairocontext.c
new file mode 100644
index 0000000000..281ef501e2
--- /dev/null
+++ b/gdk/gdkcairocontext.c
@@ -0,0 +1,102 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * gdkcairocontext.c: Cairo wrappers
+ *
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see .
+ */
+
+#include "config.h"
+
+#include "gdkcairocontext.h"
+
+#include "gdkcairocontextprivate.h"
+
+#include "gdkdisplayprivate.h"
+#include "gdkinternals.h"
+#include "gdkintl.h"
+
+/**
+ * SECTION:gdkcairocontext
+ * @Title: GdkCairoContext
+ * @Short_description: Cairo draw context
+ *
+ * #GdkCairoContext is an object representing the platform-specific
+ * draw context.
+ *
+ * #GdkCairoContexts are created for a #GdkDisplay using
+ * gdk_surface_create_cairo_context(), and the context can then be used
+ * to draw on that #GdkSurface.
+ */
+
+/**
+ * GdkCairoContext:
+ *
+ * The GdkCairoContext struct contains only private fields and should not
+ * be accessed directly.
+ */
+
+typedef struct _GdkCairoContextPrivate GdkCairoContextPrivate;
+
+struct _GdkCairoContextPrivate {
+ gpointer unused;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GdkCairoContext, gdk_cairo_context, GDK_TYPE_DRAW_CONTEXT,
+ G_ADD_PRIVATE (GdkCairoContext))
+
+void
+gdk_surface_begin_paint_internal (GdkSurface *surface,
+ const cairo_region_t *region);
+
+static void
+gdk_cairo_context_begin_frame (GdkDrawContext *draw_context,
+ cairo_region_t *region)
+{
+ gdk_surface_begin_paint_internal (gdk_draw_context_get_surface (draw_context),
+ region);
+}
+
+void
+gdk_surface_end_paint_internal (GdkSurface *surface);
+
+static void
+gdk_cairo_context_end_frame (GdkDrawContext *draw_context,
+ cairo_region_t *painted,
+ cairo_region_t *damage)
+{
+ gdk_surface_end_paint_internal (gdk_draw_context_get_surface (draw_context));
+}
+
+static void
+gdk_cairo_context_surface_resized (GdkDrawContext *draw_context)
+{
+}
+
+static void
+gdk_cairo_context_class_init (GdkCairoContextClass *klass)
+{
+ GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
+
+ draw_context_class->begin_frame = gdk_cairo_context_begin_frame;
+ draw_context_class->end_frame = gdk_cairo_context_end_frame;
+ draw_context_class->surface_resized = gdk_cairo_context_surface_resized;
+}
+
+static void
+gdk_cairo_context_init (GdkCairoContext *self)
+{
+}
+
diff --git a/gdk/gdkcairocontext.h b/gdk/gdkcairocontext.h
new file mode 100644
index 0000000000..0d2948a262
--- /dev/null
+++ b/gdk/gdkcairocontext.h
@@ -0,0 +1,47 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * gdkcairocontext.h: specific Cairo wrappers
+ *
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see .
+ */
+
+#ifndef __GDK_CAIRO_CONTEXT__
+#define __GDK_CAIRO_CONTEXT__
+
+#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include
+#include
+
+#include
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_CAIRO_CONTEXT (gdk_cairo_context_get_type ())
+#define GDK_CAIRO_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CAIRO_CONTEXT, GdkCairoContext))
+#define GDK_IS_CAIRO_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CAIRO_CONTEXT))
+
+#define GDK_CAIRO_ERROR (gdk_cairo_error_quark ())
+
+GDK_AVAILABLE_IN_ALL
+GType gdk_cairo_context_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __GDK_CAIRO_CONTEXT__ */
diff --git a/gdk/gdkcairocontextprivate.h b/gdk/gdkcairocontextprivate.h
new file mode 100644
index 0000000000..66cc3223eb
--- /dev/null
+++ b/gdk/gdkcairocontextprivate.h
@@ -0,0 +1,50 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * gdkcairocontextprivate.h: specific Cairo wrappers
+ *
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see .
+ */
+
+#ifndef __GDK_CAIRO_CONTEXT_PRIVATE__
+#define __GDK_CAIRO_CONTEXT_PRIVATE__
+
+#include "gdkcairocontext.h"
+
+#include "gdkdrawcontextprivate.h"
+
+#include
+
+G_BEGIN_DECLS
+
+#define GDK_CAIRO_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CAIRO_CONTEXT, GdkCairoContextClass))
+#define GDK_IS_CAIRO_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CAIRO_CONTEXT))
+#define GDK_CAIRO_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CAIRO_CONTEXT, GdkCairoContextClass))
+
+typedef struct _GdkCairoContextClass GdkCairoContextClass;
+
+struct _GdkCairoContext
+{
+ GdkDrawContext parent_instance;
+};
+
+struct _GdkCairoContextClass
+{
+ GdkDrawContextClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GDK__CAIRO_CONTEXT_PRIVATE__ */
diff --git a/gdk/gdkdrawingcontext.c b/gdk/gdkdrawingcontext.c
index 57740eeb34..70569ba9cf 100644
--- a/gdk/gdkdrawingcontext.c
+++ b/gdk/gdkdrawingcontext.c
@@ -232,7 +232,7 @@ gdk_drawing_context_get_cairo_context (GdkDrawingContext *context)
g_return_val_if_fail (GDK_IS_DRAWING_CONTEXT (context), NULL);
g_return_val_if_fail (GDK_IS_SURFACE (priv->surface), NULL);
- if (priv->paint_context != NULL)
+ if (!GDK_IS_CAIRO_CONTEXT (priv->paint_context))
return NULL;
if (priv->cr == NULL)
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index ed769e215e..a818fb2d7d 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1496,7 +1496,7 @@ gdk_surface_get_paint_gl_context (GdkSurface *surface,
* %NULL on error
**/
GdkGLContext *
-gdk_surface_create_gl_context (GdkSurface *surface,
+gdk_surface_create_gl_context (GdkSurface *surface,
GError **error)
{
GdkGLContext *paint_context;
@@ -1509,9 +1509,17 @@ gdk_surface_create_gl_context (GdkSurface *surface,
return NULL;
return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->create_gl_context (surface->impl_surface,
- FALSE,
- paint_context,
- error);
+ FALSE,
+ paint_context,
+ error);
+}
+
+GdkCairoContext *
+gdk_surface_create_cairo_context (GdkSurface *surface)
+{
+ return g_object_new (GDK_TYPE_CAIRO_CONTEXT,
+ "surface", surface,
+ NULL);
}
/**
@@ -1558,7 +1566,10 @@ gdk_surface_create_vulkan_context (GdkSurface *surface,
NULL);
}
-static void
+void
+gdk_surface_begin_paint_internal (GdkSurface *surface,
+ const cairo_region_t *region);
+void
gdk_surface_begin_paint_internal (GdkSurface *surface,
const cairo_region_t *region)
{
@@ -1609,7 +1620,9 @@ gdk_surface_begin_paint_internal (GdkSurface *surface,
gdk_surface_clear_backing_region (surface);
}
-static void
+void
+gdk_surface_end_paint_internal (GdkSurface *surface);
+void
gdk_surface_end_paint_internal (GdkSurface *surface)
{
GdkSurfaceImplClass *impl_class;
@@ -1688,7 +1701,7 @@ gdk_surface_end_paint_internal (GdkSurface *surface)
* by GDK.
*/
GdkDrawingContext *
-gdk_surface_begin_draw_frame (GdkSurface *surface,
+gdk_surface_begin_draw_frame (GdkSurface *surface,
GdkDrawContext *draw_context,
const cairo_region_t *region)
{
@@ -1698,12 +1711,9 @@ gdk_surface_begin_draw_frame (GdkSurface *surface,
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
g_return_val_if_fail (gdk_surface_has_native (surface), NULL);
g_return_val_if_fail (gdk_surface_is_toplevel (surface), NULL);
+ g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (draw_context), NULL);
+ g_return_val_if_fail (gdk_draw_context_get_surface (draw_context) == surface, NULL);
g_return_val_if_fail (region != NULL, NULL);
- if (draw_context != NULL)
- {
- g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (draw_context), NULL);
- g_return_val_if_fail (gdk_draw_context_get_surface (draw_context) == surface, NULL);
- }
if (GDK_SURFACE_DESTROYED (surface))
return NULL;
@@ -1718,10 +1728,7 @@ gdk_surface_begin_draw_frame (GdkSurface *surface,
real_region = cairo_region_copy (region);
- if (draw_context)
- gdk_draw_context_begin_frame (draw_context, real_region);
- else
- gdk_surface_begin_paint_internal (surface, real_region);
+ gdk_draw_context_begin_frame (draw_context, real_region);
context = g_object_new (GDK_TYPE_DRAWING_CONTEXT,
"surface", surface,
@@ -1784,7 +1791,6 @@ gdk_surface_end_draw_frame (GdkSurface *surface,
}
else
{
- gdk_surface_end_paint_internal (surface);
}
surface->drawing_context = NULL;
diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h
index e333608a99..3775f20d5d 100644
--- a/gdk/gdksurface.h
+++ b/gdk/gdksurface.h
@@ -843,11 +843,13 @@ gboolean gdk_surface_show_window_menu (GdkSurface *surface,
GdkEvent *event);
GDK_AVAILABLE_IN_ALL
-GdkGLContext * gdk_surface_create_gl_context (GdkSurface *surface,
+GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface);
+GDK_AVAILABLE_IN_ALL
+GdkGLContext * gdk_surface_create_gl_context (GdkSurface *surface,
GError **error);
GDK_AVAILABLE_IN_ALL
GdkVulkanContext *
- gdk_surface_create_vulkan_context(GdkSurface *surface,
+ gdk_surface_create_vulkan_context(GdkSurface *surface,
GError **error);
G_END_DECLS
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index d4e3623309..f2081c1536 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -136,6 +136,7 @@ typedef struct _GdkSnapshot GdkSnapshot;
typedef struct _GdkDrawingContext GdkDrawingContext;
typedef struct _GdkDrawContext GdkDrawContext;
+typedef struct _GdkCairoContext GdkCairoContext;
typedef struct _GdkGLContext GdkGLContext;
typedef struct _GdkVulkanContext GdkVulkanContext;
diff --git a/gdk/meson.build b/gdk/meson.build
index d801d7592a..0f22b2fe39 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -2,6 +2,7 @@ gdk_public_sources = files([
'gdk.c',
'gdkapplaunchcontext.c',
'gdkcairo.c',
+ 'gdkcairocontext.c',
'gdkclipboard.c',
'gdkcontentdeserializer.c',
'gdkcontentformats.c',
@@ -51,6 +52,7 @@ gdk_public_headers = files([
'gdk.h',
'gdkapplaunchcontext.h',
'gdkcairo.h',
+ 'gdkcairocontext.h',
'gdkclipboard.h',
'gdkcontentdeserializer.h',
'gdkcontentformats.h',
diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c
index 5cf3d7822d..f5871e49a8 100644
--- a/gsk/gskcairorenderer.c
+++ b/gsk/gskcairorenderer.c
@@ -18,6 +18,8 @@ struct _GskCairoRenderer
{
GskRenderer parent_instance;
+ GdkCairoContext *cairo_context;
+
#ifdef G_ENABLE_DEBUG
ProfileTimers profile_timers;
#endif
@@ -32,16 +34,22 @@ G_DEFINE_TYPE (GskCairoRenderer, gsk_cairo_renderer, GSK_TYPE_RENDERER)
static gboolean
gsk_cairo_renderer_realize (GskRenderer *renderer,
- GdkSurface *surface,
+ GdkSurface *surface,
GError **error)
{
+ GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
+
+ self->cairo_context = gdk_surface_create_cairo_context (surface);
+
return TRUE;
}
static void
gsk_cairo_renderer_unrealize (GskRenderer *renderer)
{
+ GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
+ g_clear_object (&self->cairo_context);
}
static void
@@ -99,11 +107,14 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
GskRenderNode *root,
const cairo_region_t *region)
{
+ GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
GdkSurface *surface = gsk_renderer_get_surface (renderer);
GdkDrawingContext *context;
cairo_t *cr;
- context = gdk_surface_begin_draw_frame (surface, NULL, region);
+ context = gdk_surface_begin_draw_frame (surface,
+ GDK_DRAW_CONTEXT (self->cairo_context),
+ region);
cr = gdk_drawing_context_get_cairo_context (context);
g_return_if_fail (cr != NULL);