[gtk+/gtk-2-24] win32: always recreate the cairo surface if requested to do so
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-2-24] win32: always recreate the cairo surface if requested to do so
- Date: Tue, 30 Jul 2013 04:11:30 +0000 (UTC)
commit 4ecbef0791d420c014ecca911cd2a1cc18122e9a
Author: Aleksander Morgado <aleksander lanedo com>
Date: Fri Mar 15 10:56:27 2013 +0100
win32: always recreate the cairo surface if requested to do so
When _gdk_windowing_create_cairo_surface() gets called, we should always create
a fully new cairo surface, instead of just referencing the available one, which
may already be finished (i.e. in CAIRO_STATUS_SURFACE_FINISHED state).
A new user_data key is added to the surface to explicitly release the acquired
DC when the surface is destroyed, independent to the user_data key added to
clear the impl->user_data pointer.
https://bugzilla.gnome.org/show_bug.cgi?id=695636
gdk/win32/gdkdrawable-win32.c | 44 ++++++++++++++++++++++++++++++----------
1 files changed, 33 insertions(+), 11 deletions(-)
---
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index 14d9f45..3fce570 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -144,6 +144,7 @@ static GdkVisual* gdk_win32_get_visual (GdkDrawable *drawable);
static void gdk_drawable_impl_win32_finalize (GObject *object);
static const cairo_user_data_key_t gdk_win32_cairo_key;
+static const cairo_user_data_key_t gdk_win32_cairo_hdc_key;
G_DEFINE_TYPE (GdkDrawableImplWin32, _gdk_drawable_impl_win32, GDK_TYPE_DRAWABLE)
@@ -1926,13 +1927,33 @@ _gdk_win32_drawable_release_dc (GdkDrawable *drawable)
}
}
+static void
+gdk_win32_cairo_surface_release_hdc (void *data)
+{
+ _gdk_win32_drawable_release_dc (GDK_DRAWABLE (data));
+}
+
cairo_surface_t *
_gdk_windowing_create_cairo_surface (GdkDrawable *drawable,
gint width,
gint height)
{
- /* width and height are determined from the DC */
- return gdk_win32_ref_cairo_surface (drawable);
+ cairo_surface_t *surface;
+ HDC hdc;
+
+ hdc = _gdk_win32_drawable_acquire_dc (drawable);
+ if (!hdc)
+ return NULL;
+
+ surface = cairo_win32_surface_create (hdc);
+
+ /* Whenever the cairo surface is destroyed, we need to release the
+ * HDC that was acquired */
+ cairo_surface_set_user_data (surface, &gdk_win32_cairo_hdc_key,
+ drawable,
+ gdk_win32_cairo_surface_release_hdc);
+
+ return surface;
}
static void
@@ -1940,7 +1961,6 @@ gdk_win32_cairo_surface_destroy (void *data)
{
GdkDrawableImplWin32 *impl = data;
- _gdk_win32_drawable_release_dc (GDK_DRAWABLE (impl));
impl->cairo_surface = NULL;
}
@@ -1955,14 +1975,14 @@ gdk_win32_ref_cairo_surface (GdkDrawable *drawable)
if (!impl->cairo_surface)
{
- HDC hdc = _gdk_win32_drawable_acquire_dc (drawable);
- if (!hdc)
- return NULL;
-
- impl->cairo_surface = cairo_win32_surface_create (hdc);
+ /* width and height are determined from the DC */
+ impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, 0, 0);
+ /* Whenever the cairo surface is destroyed, we need to clear the
+ * pointer that we had stored here */
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
- drawable, gdk_win32_cairo_surface_destroy);
+ drawable,
+ gdk_win32_cairo_surface_destroy);
}
else
cairo_surface_reference (impl->cairo_surface);
@@ -2041,9 +2061,11 @@ _gdk_win32_drawable_finish (GdkDrawable *drawable)
if (impl->cairo_surface)
{
cairo_surface_finish (impl->cairo_surface);
+ cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_hdc_key, NULL, NULL);
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key, NULL, NULL);
}
- g_assert (impl->hdc_count == 0);
+ /* impl->hdc_count doesn't have to be 0 here; as there may still be surfaces
+ * created with gdk_windowing_create_cairo_surface() out there, which are not
+ * managed internally by the drawable */
}
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]