[gtk+/wip/ebassi/frame-marker: 7/12] Add GdkDrawingContext



commit 59acc669cc877a712c800554efea0769301e55e7
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon May 30 09:44:30 2016 +0100

    Add GdkDrawingContext
    
    Instead of giving out Cairo contexts, GdkWindow should provide a
    "drawing context", which can then create Cairo contexts on demand; this
    allows us to future proof the API for when we're going to use a
    different rendering pipeline, like OpenGL.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=766675

 gdk/Makefile.am                |    3 +
 gdk/gdk.h                      |    1 +
 gdk/gdkdrawingcontext.c        |  275 ++++++++++++++++++++++++++++++++++++++++
 gdk/gdkdrawingcontext.h        |   53 ++++++++
 gdk/gdkdrawingcontextprivate.h |   29 ++++
 gdk/gdkinternals.h             |    4 +
 gdk/gdkwindow.c                |   91 +++++++++++---
 gdk/gdkwindow.h                |    7 +-
 gdk/gdkwindowimpl.h            |    5 +
 gtk/gtkwidget.c                |    6 +-
 10 files changed, 453 insertions(+), 21 deletions(-)
---
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 16230cb..91da7bd 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -75,6 +75,7 @@ gdk_public_h_sources =                                \
        gdkdisplay.h                            \
        gdkdisplaymanager.h                     \
        gdkdnd.h                                \
+       gdkdrawingcontext.h                     \
        gdkevents.h                             \
        gdkframetimings.h                       \
        gdkglcontext.h                          \
@@ -116,6 +117,7 @@ gdk_private_headers =                               \
        gdkdisplaymanagerprivate.h              \
        gdkdisplayprivate.h                     \
        gdkdndprivate.h                         \
+       gdkdrawingcontextprivate.h              \
        gdkframeclockidle.h                     \
        gdkframeclockprivate.h                  \
        gdkglcontextprivate.h                   \
@@ -146,6 +148,7 @@ gdk_c_sources =                             \
        gdkdisplay.c                            \
        gdkdisplaymanager.c                     \
        gdkdnd.c                                \
+       gdkdrawingcontext.c                     \
        gdkevents.c                             \
        gdkframetimings.c                       \
        gdkgl.c                                 \
diff --git a/gdk/gdk.h b/gdk/gdk.h
index 4631c52..92bafe1 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -38,6 +38,7 @@
 #include <gdk/gdkdisplay.h>
 #include <gdk/gdkdisplaymanager.h>
 #include <gdk/gdkdnd.h>
+#include <gdk/gdkdrawingcontext.h>
 #include <gdk/gdkenumtypes.h>
 #include <gdk/gdkevents.h>
 #include <gdk/gdkframeclock.h>
diff --git a/gdk/gdkdrawingcontext.c b/gdk/gdkdrawingcontext.c
new file mode 100644
index 0000000..caffa0c
--- /dev/null
+++ b/gdk/gdkdrawingcontext.c
@@ -0,0 +1,275 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright 2016  Endless
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gdkdrawingcontext
+ * @Title: GdkDrawingContext
+ * @Short_description: Drawing context for GDK windows
+ *
+ * #GdkDrawingContext is an object that represents the current drawing
+ * state of a #GdkWindow.
+ *
+ * It's possible to use a #GdkDrawingContext to draw on a #GdkWindow
+ * via rendering API like Cairo or OpenGL.
+ *
+ * A #GdkDrawingContext can only be created by calling gdk_window_begin_draw_frame()
+ * and will be valid until a call to gdk_window_end_draw_frame().
+ *
+ * #GdkDrawingContext is available since GDK 3.22
+ */
+
+#include "config.h"
+
+#include <cairo-gobject.h>
+
+#include "gdkdrawingcontextprivate.h"
+
+#include "gdkrectangle.h"
+#include "gdkinternals.h"
+#include "gdkintl.h"
+#include "gdkframeclockidle.h"
+#include "gdkwindowimpl.h"
+#include "gdkglcontextprivate.h"
+#include "gdk-private.h"
+
+G_DEFINE_TYPE (GdkDrawingContext, gdk_drawing_context, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+
+  PROP_WINDOW,
+  PROP_CLIP,
+
+  N_PROPS
+};
+
+static GParamSpec *obj_property[N_PROPS];
+
+static void
+gdk_drawing_context_dispose (GObject *gobject)
+{
+  GdkDrawingContext *self = GDK_DRAWING_CONTEXT (gobject);
+
+  g_clear_object (&self->window);
+  g_clear_pointer (&self->clip, cairo_region_destroy);
+  g_clear_pointer (&self->cr, cairo_destroy);
+
+  G_OBJECT_CLASS (gdk_drawing_context_parent_class)->dispose (gobject);
+}
+
+static void
+gdk_drawing_context_set_property (GObject      *gobject,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+  GdkDrawingContext *self = GDK_DRAWING_CONTEXT (gobject);
+
+  switch (prop_id)
+    {
+    case PROP_WINDOW:
+      self->window = g_value_dup_object (value);
+      break;
+
+    case PROP_CLIP:
+      self->clip = g_value_dup_boxed (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+    }
+}
+
+static void
+gdk_drawing_context_get_property (GObject    *gobject,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+  GdkDrawingContext *self = GDK_DRAWING_CONTEXT (gobject);
+
+  switch (prop_id)
+    {
+    case PROP_WINDOW:
+      g_value_set_object (value, self->window);
+      break;
+
+    case PROP_CLIP:
+      g_value_set_boxed (value, self->clip);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+    }
+}
+
+static void
+gdk_drawing_context_constructed (GObject *gobject)
+{
+  GdkDrawingContext *self = GDK_DRAWING_CONTEXT (gobject);
+
+  if (self->window == NULL)
+    {
+      g_critical ("The drawing context of type %s does not have a window "
+                  "associated to it. Drawing contexts can only be created "
+                  "using gdk_window_begin_draw_frame().",
+                  G_OBJECT_TYPE_NAME (gobject));
+    }
+
+  G_OBJECT_CLASS (gdk_drawing_context_parent_class)->constructed (gobject);
+}
+
+static void
+gdk_drawing_context_class_init (GdkDrawingContextClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->constructed = gdk_drawing_context_constructed;
+  gobject_class->set_property = gdk_drawing_context_set_property;
+  gobject_class->get_property = gdk_drawing_context_get_property;
+  gobject_class->dispose = gdk_drawing_context_dispose;
+
+  /**
+   * GdkDrawingContext:window:
+   *
+   * The #GdkWindow that created the drawing context.
+   *
+   * Since: 3.22
+   */
+  obj_property[PROP_WINDOW] =
+    g_param_spec_object ("window", "Window", "The window that created the context",
+                         GDK_TYPE_WINDOW,
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_STRINGS);
+  /**
+   * GdkDrawingContext:clip:
+   *
+   * The clip region applied to the drawing context.
+   *
+   * Since: 3.22
+   */
+  obj_property[PROP_CLIP] =
+    g_param_spec_boxed ("clip", "Clip", "The clip region of the context",
+                        CAIRO_GOBJECT_TYPE_REGION,
+                        G_PARAM_CONSTRUCT_ONLY |
+                        G_PARAM_READWRITE |
+                        G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, obj_property);
+}
+
+static void
+gdk_drawing_context_init (GdkDrawingContext *self)
+{
+}
+
+/**
+ * gdk_drawing_context_get_cairo_context:
+ * @context:
+ *
+ * Retrieves a Cairo context to be used to draw on the #GdkWindow
+ * that created the #GdkDrawingContext.
+ *
+ * The returned context is guaranteed to be valid as long as the
+ * #GdkDrawingContext is valid, that is between a call to
+ * gdk_window_begin_draw_frame() and gdk_window_end_draw_frame().
+ *
+ * Returns: (transfer none): a Cairo context to be used to draw
+ *   the contents of the #GdkWindow. The context is owned by the
+ *   #GdkDrawingContext and should not be destroyed
+ *
+ * Since: 3.22
+ */
+cairo_t *
+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_WINDOW (context->window), NULL);
+
+  if (context->cr == NULL)
+    {
+      context->cr = gdk_cairo_create (context->window);
+      gdk_cairo_region (context->cr, context->clip);
+      cairo_clip (context->cr);
+    }
+
+  return context->cr;
+}
+
+/**
+ * gdk_drawing_context_get_window:
+ * @context: a #GdkDrawingContext
+ *
+ * Retrieves the window that created the drawing @context.
+ *
+ * Returns: (transfer none): a #GdkWindow
+ *
+ * Since: 3.22
+ */
+GdkWindow *
+gdk_drawing_context_get_window (GdkDrawingContext *context)
+{
+  g_return_val_if_fail (GDK_IS_DRAWING_CONTEXT (context), NULL);
+
+  return context->window;
+}
+
+/**
+ * gdk_drawing_context_get_clip:
+ * @context: a #GdkDrawingContext
+ *
+ * Retrieves a copy of the clip region used when creating the @context.
+ *
+ * Returns: (transfer full) (nullable): a Cairo region
+ *
+ * Since: 3.22
+ */
+cairo_region_t *
+gdk_drawing_context_get_clip (GdkDrawingContext *context)
+{
+  g_return_val_if_fail (GDK_IS_DRAWING_CONTEXT (context), NULL);
+
+  if (context->clip == NULL)
+    return NULL;
+
+  return cairo_region_copy (context->clip);
+}
+
+/**
+ * gdk_drawing_context_is_valid:
+ * @context: a #GdkDrawingContext
+ *
+ * Checks whether the given #GdkDrawingContext is valid.
+ *
+ * Returns: %TRUE if the context is valid
+ *
+ * Since: 3.22
+ */
+gboolean
+gdk_drawing_context_is_valid (GdkDrawingContext *context)
+{
+  g_return_val_if_fail (GDK_IS_DRAWING_CONTEXT (context), FALSE);
+
+  if (context->window == NULL)
+    return FALSE;
+
+  if (gdk_window_get_drawing_context (context->window) != context)
+    return FALSE;
+
+  return TRUE;
+}
diff --git a/gdk/gdkdrawingcontext.h b/gdk/gdkdrawingcontext.h
new file mode 100644
index 0000000..6202648
--- /dev/null
+++ b/gdk/gdkdrawingcontext.h
@@ -0,0 +1,53 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_DRAWING_CONTEXT_H__
+#define __GDK_DRAWING_CONTEXT_H__
+
+#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdk.h> can be included directly."
+#endif
+
+#include <gdk/gdkversionmacros.h>
+#include <gdk/gdktypes.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_DRAWING_CONTEXT (gdk_drawing_context_get_type ())
+
+#define GDK_DRAWING_CONTEXT(obj)        (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_DRAWING_CONTEXT, 
GdkDrawingContext))
+#define GDK_IS_DRAWING_CONTEXT(obj)     (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_DRAWING_CONTEXT))
+
+typedef struct _GdkDrawingContext       GdkDrawingContext;
+typedef struct _GdkDrawingContextClass  GdkDrawingContextClass;
+
+GDK_AVAILABLE_IN_3_22
+GType gdk_drawing_context_get_type (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_22
+GdkWindow *     gdk_drawing_context_get_window          (GdkDrawingContext *context);
+GDK_AVAILABLE_IN_3_22
+cairo_region_t *gdk_drawing_context_get_clip            (GdkDrawingContext *context);
+
+GDK_AVAILABLE_IN_3_22
+gboolean        gdk_drawing_context_is_valid            (GdkDrawingContext *context);
+
+GDK_AVAILABLE_IN_3_22
+cairo_t *       gdk_drawing_context_get_cairo_context   (GdkDrawingContext *context);
+
+G_END_DECLS
+
+#endif /* __GDK_DRAWING_CONTEXT_H__ */
diff --git a/gdk/gdkdrawingcontextprivate.h b/gdk/gdkdrawingcontextprivate.h
new file mode 100644
index 0000000..a41cf02
--- /dev/null
+++ b/gdk/gdkdrawingcontextprivate.h
@@ -0,0 +1,29 @@
+#ifndef __GDK_DRAWING_CONTEXT_PRIVATE_H__
+#define __GDK_DRAWING_CONTEXT_PRIVATE_H__
+
+#include "gdkdrawingcontext.h"
+
+G_BEGIN_DECLS
+
+#define GDK_DRAWING_CONTEXT_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAWING_CONTEXT, 
GdkDrawingContextClass))
+#define GDK_IS_DRAWING_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAWING_CONTEXT))
+#define GDK_DRAWING_CONTEXT_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAWING_CONTEXT, 
GdkDrawingContextClass))
+
+struct _GdkDrawingContext
+{
+  GObject parent_instance;
+
+  GdkWindow *window;
+
+  cairo_region_t *clip;
+  cairo_t *cr;
+};
+
+struct _GdkDrawingContextClass
+{
+  GObjectClass parent_instance;
+};
+
+G_END_DECLS
+
+#endif /* __GDK_DRAWING_CONTEXT_PRIVATE_H__ */
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 03555d1..1e7bcb0 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -379,6 +379,8 @@ struct _GdkWindow
 
   GdkFrameClock *frame_clock; /* NULL to use from parent or default */
   GdkWindowInvalidateHandlerFunc invalidate_handler;
+
+  GdkDrawingContext *drawing_context;
 };
 
 #define GDK_WINDOW_TYPE(d) ((((GdkWindow *)(d)))->window_type)
@@ -468,6 +470,8 @@ void gdk_window_get_unscaled_size (GdkWindow *window,
                                    int *unscaled_width,
                                    int *unscaled_height);
 
+GdkDrawingContext *gdk_window_get_drawing_context (GdkWindow *window);
+
 void       _gdk_window_process_updates_recurse (GdkWindow *window,
                                                 cairo_region_t *expose_region);
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index b6137f4..4724f3f 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -40,6 +40,7 @@
 #include "gdkframeclockidle.h"
 #include "gdkwindowimpl.h"
 #include "gdkglcontextprivate.h"
+#include "gdkdrawingcontextprivate.h"
 #include "gdk-private.h"
 
 #include <math.h>
@@ -3143,7 +3144,7 @@ gdk_cairo_get_window (cairo_t *cr)
  * @region: a Cairo region
  *
  * Indicates that you are beginning the process of redrawing @region
- * on @window, and provides you with a Cairo context for drawing.
+ * on @window, and provides you with a #GdkDrawingContext.
  *
  * If @window is a top level #GdkWindow, backed by a native window
  * implementation, a backing store (offscreen buffer) large enough to
@@ -3170,40 +3171,60 @@ gdk_cairo_get_window (cairo_t *cr)
  * code in GTK does not need to call gdk_window_begin_draw_frame()
  * explicitly.
  *
- * Returns: (transfer none): a Cairo context that should be used to
- *   draw the contents of the window; the returned context is owned
- *   by GDK and should not be destroyed directly
+ * Returns: (transfer none): a #GdkDrawingContext context that should be
+ *   used to draw the contents of the window; the returned context is owned
+ *   by GDK.
  *
  * Since: 3.22
  */
-cairo_t *
+GdkDrawingContext *
 gdk_window_begin_draw_frame (GdkWindow            *window,
                              const cairo_region_t *region)
 {
-  cairo_t *retval;
+  GdkDrawingContext *context;
+  GdkWindowImplClass *impl_class;
 
   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
 
+  if (window->drawing_context != NULL)
+    {
+      g_critical ("The window %p already has a drawing context. You cannot "
+                  "call gdk_window_begin_draw_frame() without calling "
+                  "gdk_window_end_draw_frame() first.", window);
+      return NULL;
+    }
+
   if (gdk_window_has_native (window) && gdk_window_is_toplevel (window))
     gdk_window_begin_paint_internal (window, region);
 
-  retval = gdk_cairo_create (window);
+  impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
+  if (impl_class->create_draw_context != NULL)
+    {
+      context = impl_class->create_draw_context (window, region);
+    }
+  else
+    {
+      context = g_object_new (GDK_TYPE_DRAWING_CONTEXT,
+                              "window", window,
+                              "clip", region,
+                              NULL);
+    }
 
-  gdk_cairo_region (retval, region);
-  cairo_clip (retval);
+  /* Do not take a reference, to avoid creating cycles */
+  window->drawing_context = context;
 
-  return retval;
+  return context;
 }
 
 /**
  * gdk_window_end_draw_frame:
  * @window: a #GdkWindow
- * @cr: the Cairo context created by gdk_window_begin_draw_frame()
+ * @context: the #GdkDrawingContext created by gdk_window_begin_draw_frame()
  *
  * Indicates that the drawing of the contents of @window started with
  * gdk_window_begin_frame() has been completed.
  *
- * This function will take care of destroying the Cairo context.
+ * This function will take care of destroying the #GdkDrawingContext.
  *
  * It is an error to call this function without a matching
  * gdk_window_begin_frame() first.
@@ -3211,14 +3232,52 @@ gdk_window_begin_draw_frame (GdkWindow            *window,
  * Since: 3.22
  */
 void
-gdk_window_end_draw_frame (GdkWindow *window,
-                           cairo_t   *cr)
+gdk_window_end_draw_frame (GdkWindow         *window,
+                           GdkDrawingContext *context)
 {
+  GdkWindowImplClass *impl_class;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context));
+
+  if (window->drawing_context == NULL)
+    {
+      g_critical ("The window %p has no drawing context. You must call "
+                  "gdk_window_begin_draw_frame() before calling "
+                  "gdk_window_end_draw_frame().", window);
+      return;
+    }
+
   if (gdk_window_has_native (window) && gdk_window_is_toplevel (window))
     gdk_window_end_paint_internal (window);
 
-  gdk_cairo_set_window (cr, NULL);
-  cairo_destroy (cr);
+  impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
+  if (impl_class->destroy_draw_context != NULL)
+    impl_class->destroy_draw_context (window, context);
+  else
+    g_object_unref (context);
+
+  window->drawing_context = NULL;
+}
+
+/*< private >
+ * gdk_window_get_drawing_context:
+ * @window: a #GdkWindow
+ *
+ * Retrieves the #GdkDrawingContext associated to @window by
+ * gdk_window_begin_draw_frame().
+ *
+ * Returns: (transfer none) (nullable): a #GdkDrawingContext, if any is set
+ */
+GdkDrawingContext *
+gdk_window_get_drawing_context (GdkWindow *window)
+{
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return NULL;
+
+  return window->drawing_context;
 }
 
 /**
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 8f38cf3..463cd4f 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -31,6 +31,7 @@
 
 #include <gdk/gdkversionmacros.h>
 #include <gdk/gdktypes.h>
+#include <gdk/gdkdrawingcontext.h>
 #include <gdk/gdkevents.h>
 #include <gdk/gdkframeclock.h>
 
@@ -706,11 +707,11 @@ GDK_AVAILABLE_IN_ALL
 void         gdk_window_end_paint          (GdkWindow          *window);
 
 GDK_AVAILABLE_IN_3_22
-cairo_t *     gdk_window_begin_draw_frame  (GdkWindow            *window,
-                                            const cairo_region_t *region);
+GdkDrawingContext *gdk_window_begin_draw_frame  (GdkWindow            *window,
+                                                 const cairo_region_t *region);
 GDK_AVAILABLE_IN_3_22
 void          gdk_window_end_draw_frame    (GdkWindow            *window,
-                                            cairo_t              *cr);
+                                            GdkDrawingContext    *context);
 
 GDK_DEPRECATED_IN_3_14
 void         gdk_window_flush             (GdkWindow          *window);
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index f074343..4ccdc67 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -303,6 +303,11 @@ struct _GdkWindowImplClass
                                            GError        **error);
   void         (*invalidate_for_new_frame)(GdkWindow      *window,
                                            cairo_region_t *update_area);
+
+  GdkDrawingContext *(* create_draw_context)  (GdkWindow            *window,
+                                               const cairo_region_t *region);
+  void               (* destroy_draw_context) (GdkWindow            *window,
+                                               GdkDrawingContext    *context);
 };
 
 /* Interface Functions */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 2751a4d..158e656 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -17441,6 +17441,7 @@ gtk_widget_render (GtkWidget            *widget,
                    const cairo_region_t *region)
 {
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+  GdkDrawingContext *context;
   gboolean do_clip;
   cairo_t *cr;
   int x, y;
@@ -17452,12 +17453,13 @@ gtk_widget_render (GtkWidget            *widget,
         return;
     }
 
-  cr = gdk_window_begin_draw_frame (window, region);
+  context = gdk_window_begin_draw_frame (window, region);
+  cr = gdk_drawing_context_get_cairo_context (context);
 
   do_clip = _gtk_widget_get_translation_to_window (widget, window, &x, &y);
   cairo_translate (cr, -x, -y);
 
   gtk_widget_draw_internal (widget, cr, do_clip);
 
-  gdk_window_end_draw_frame (window, cr);
+  gdk_window_end_draw_frame (window, context);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]