[cairo-commit] 4 commits - src/cairoint.h src/cairo-user-font.c src/cairo-xlib-display.c src/cairo-xlib-private.h src/cairo-xlib-screen.c src/cairo-xlib-surface.c src/cairo-xlib-surface-private.h test/cairo-test.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Sep 2 03:22:19 PDT 2008
src/cairo-user-font.c | 10 ++-
src/cairo-xlib-display.c | 105 ++++++++++++++-------------------------
src/cairo-xlib-private.h | 19 ++++---
src/cairo-xlib-screen.c | 14 +----
src/cairo-xlib-surface-private.h | 2
src/cairo-xlib-surface.c | 76 +++++++++++++++++++---------
src/cairoint.h | 10 +++
test/cairo-test.c | 5 +
8 files changed, 133 insertions(+), 108 deletions(-)
New commits:
commit 7b2e8035f253e4667ebdb285d7b49aaece88f3b3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 2 10:54:13 2008 +0100
[cairo-test] Fixup a few memleaks on failure.
Free the test image before jumping to UNWIND_CAIRO.
diff --git a/test/cairo-test.c b/test/cairo-test.c
index c0e59bf..6c04f8c 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -689,6 +689,7 @@ cairo_test_for_target (cairo_test_context_t *ctx,
if (cairo_surface_status (test_image)) {
cairo_test_log (ctx, "Error: Failed to extract image: %s\n",
cairo_status_to_string (cairo_surface_status (test_image)));
+ cairo_surface_destroy (test_image);
ret = CAIRO_TEST_FAILURE;
goto UNWIND_CAIRO;
}
@@ -713,6 +714,7 @@ cairo_test_for_target (cairo_test_context_t *ctx,
if (cairo_test_files_equal (test_filename, pass_filename)) {
/* identical output as last known PASS */
cairo_test_log (ctx, "Vector surface matches last pass.\n");
+ cairo_surface_destroy (test_image);
ret = CAIRO_TEST_SUCCESS;
goto UNWIND_CAIRO;
}
@@ -720,6 +722,7 @@ cairo_test_for_target (cairo_test_context_t *ctx,
/* identical output as last known FAIL, fail */
cairo_test_log (ctx, "Vector surface matches last fail.\n");
have_result = TRUE; /* presume these were kept around as well */
+ cairo_surface_destroy (test_image);
ret = CAIRO_TEST_FAILURE;
goto UNWIND_CAIRO;
}
@@ -728,6 +731,7 @@ cairo_test_for_target (cairo_test_context_t *ctx,
if (ref_name == NULL) {
cairo_test_log (ctx, "Error: Cannot find reference image for %s\n",
base_name);
+ cairo_surface_destroy (test_image);
ret = CAIRO_TEST_FAILURE;
goto UNWIND_CAIRO;
}
@@ -776,6 +780,7 @@ cairo_test_for_target (cairo_test_context_t *ctx,
cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
ref_name,
cairo_status_to_string (cairo_surface_status (ref_image)));
+ cairo_surface_destroy (ref_image);
cairo_surface_destroy (test_image);
ret = CAIRO_TEST_FAILURE;
goto UNWIND_CAIRO;
commit a5d33bcbb43cd1738e45b803c1aa968aff55e7ab
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 2 10:28:17 2008 +0100
[xlib] Keep a pointer to the cairo_xlib_display_t on the surface.
Cleanup the code somewhat by passing cairo_xlib_display_t around
internally as opposed to a Display and then having to lookup the
corresponding cairo_xlib_display_t each time.
[To get a cairo_xlib_display_t from a Display is a list traversal under
mutex (though the element we're looking for is most likely at the start),
but to get the Display is just a lockless pointer dereference.]
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index ff2e08e..5e6dba1 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -90,7 +90,7 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
_cairo_xlib_remove_close_display_hook_internal (display, hook);
CAIRO_MUTEX_UNLOCK (display->mutex);
- hook->func (display->display, hook);
+ hook->func (display, hook);
CAIRO_MUTEX_LOCK (display->mutex);
}
display->closed = TRUE;
@@ -317,15 +317,10 @@ UNLOCK:
return display;
}
-cairo_bool_t
-_cairo_xlib_add_close_display_hook (Display *dpy, cairo_xlib_hook_t *hook)
+void
+_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display,
+ cairo_xlib_hook_t *hook)
{
- cairo_xlib_display_t *display;
-
- display = _cairo_xlib_display_get (dpy);
- if (display == NULL)
- return FALSE;
-
CAIRO_MUTEX_LOCK (display->mutex);
hook->prev = NULL;
hook->next = display->close_display_hooks;
@@ -333,10 +328,6 @@ _cairo_xlib_add_close_display_hook (Display *dpy, cairo_xlib_hook_t *hook)
hook->next->prev = hook;
display->close_display_hooks = hook;
CAIRO_MUTEX_UNLOCK (display->mutex);
-
- _cairo_xlib_display_destroy (display);
-
- return TRUE;
}
/* display->mutex must be held */
@@ -357,20 +348,12 @@ _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
}
void
-_cairo_xlib_remove_close_display_hook (Display *dpy,
- cairo_xlib_hook_t *hook)
+_cairo_xlib_remove_close_display_hook (cairo_xlib_display_t *display,
+ cairo_xlib_hook_t *hook)
{
- cairo_xlib_display_t *display;
-
- display = _cairo_xlib_display_get (dpy);
- if (display == NULL)
- return;
-
CAIRO_MUTEX_LOCK (display->mutex);
_cairo_xlib_remove_close_display_hook_internal (display, hook);
CAIRO_MUTEX_UNLOCK (display->mutex);
-
- _cairo_xlib_display_destroy (display);
}
cairo_status_t
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index e962278..e381e58 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -53,7 +53,7 @@ typedef void (*cairo_xlib_notify_resource_func) (Display *, XID);
struct _cairo_xlib_hook {
cairo_xlib_hook_t *prev, *next; /* private */
- void (*func) (Display *display, void *data);
+ void (*func) (cairo_xlib_display_t *display, void *data);
};
struct _cairo_xlib_display {
@@ -113,11 +113,11 @@ _cairo_xlib_display_reference (cairo_xlib_display_t *info);
cairo_private void
_cairo_xlib_display_destroy (cairo_xlib_display_t *info);
-cairo_private cairo_bool_t
-_cairo_xlib_add_close_display_hook (Display *display, cairo_xlib_hook_t *hook);
+cairo_private void
+_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
cairo_private void
-_cairo_xlib_remove_close_display_hook (Display *display, cairo_xlib_hook_t *hook);
+_cairo_xlib_remove_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
cairo_private cairo_status_t
_cairo_xlib_display_queue_work (cairo_xlib_display_t *display,
@@ -136,7 +136,7 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
cairo_format_t format);
cairo_private cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_get (Display *display, Screen *screen);
+_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen);
cairo_private cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info);
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 83015a2..4a26eee 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -346,19 +346,14 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
}
cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
+_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
{
- cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *info = NULL, **prev;
- display = _cairo_xlib_display_get (dpy);
- if (display == NULL)
- return NULL;
-
CAIRO_MUTEX_LOCK (display->mutex);
if (display->closed) {
CAIRO_MUTEX_UNLOCK (display->mutex);
- goto DONE;
+ return NULL;
}
for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
@@ -394,7 +389,9 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
sizeof (cairo_xlib_visual_info_t*));
if (screen) {
+ Display *dpy = display->display;
int event_base, error_base;
+
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
_cairo_xlib_init_screen_font_options (dpy, info);
@@ -407,9 +404,6 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
}
}
-DONE:
- _cairo_xlib_display_destroy (display);
-
return info;
}
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index a16e8e4..e06fd97 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -45,6 +45,7 @@ struct _cairo_xlib_surface {
cairo_surface_t base;
Display *dpy;
+ cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *screen_info;
cairo_xlib_hook_t close_display_hook;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index e9ff65d..d6f4109 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -320,12 +320,14 @@ _cairo_xlib_surface_finish (void *abstract_surface)
if (surface->screen_info != NULL)
_cairo_xlib_screen_info_destroy (surface->screen_info);
- if (surface->dpy != NULL) {
- _cairo_xlib_remove_close_display_hook (surface->dpy,
+ if (surface->display != NULL) {
+ _cairo_xlib_remove_close_display_hook (surface->display,
&surface->close_display_hook);
- surface->dpy = NULL;
+ _cairo_xlib_display_destroy (surface->display);
}
+ surface->dpy = NULL;
+
return status;
}
@@ -2381,12 +2383,14 @@ _cairo_surface_is_xlib (cairo_surface_t *surface)
/* callback from CloseDisplay */
static void
-_cairo_xlib_surface_detach_display (Display *dpy, void *data)
+_cairo_xlib_surface_detach_display (cairo_xlib_display_t *display, void *data)
{
cairo_xlib_surface_t *surface = cairo_container_of (data,
cairo_xlib_surface_t,
close_display_hook);
+ Display *dpy;
+ dpy = surface->dpy;
surface->dpy = NULL;
if (surface->dst_picture != None) {
@@ -2422,6 +2426,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
int depth)
{
cairo_xlib_surface_t *surface;
+ cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *screen_info;
CAIRO_MUTEX_INITIALIZE ();
@@ -2453,25 +2458,26 @@ _cairo_xlib_surface_create_internal (Display *dpy,
if (depth == 0)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
- screen_info = _cairo_xlib_screen_info_get (dpy, screen);
- if (screen_info == NULL)
+ display = _cairo_xlib_display_get (dpy);
+ if (display == NULL)
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+
+ screen_info = _cairo_xlib_screen_info_get (display, screen);
+ if (screen_info == NULL) {
+ _cairo_xlib_display_destroy (display);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ }
surface = malloc (sizeof (cairo_xlib_surface_t));
if (surface == NULL) {
_cairo_xlib_screen_info_destroy (screen_info);
+ _cairo_xlib_display_destroy (display);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
/* initialize and hook into the CloseDisplay callback */
surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
- if (! _cairo_xlib_add_close_display_hook (dpy,
- &surface->close_display_hook))
- {
- free (surface);
- _cairo_xlib_screen_info_destroy (screen_info);
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
+ _cairo_xlib_add_close_display_hook (display, &surface->close_display_hook);
if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
surface->render_major = -1;
@@ -2493,6 +2499,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
_xrender_format_to_content (xrender_format));
surface->dpy = dpy;
+ surface->display = display;
surface->screen_info = screen_info;
surface->gc = NULL;
@@ -3000,8 +3007,8 @@ typedef struct _cairo_xlib_surface_font_private {
/* callback from CloseDisplay */
static void
-_cairo_xlib_surface_remove_scaled_font (Display *dpy,
- void *data)
+_cairo_xlib_surface_remove_scaled_font (cairo_xlib_display_t *display,
+ void *data)
{
cairo_xlib_surface_font_private_t *font_private;
cairo_scaled_font_t *scaled_font;
@@ -3019,8 +3026,10 @@ _cairo_xlib_surface_remove_scaled_font (Display *dpy,
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
if (font_private != NULL) {
+ Display *dpy;
int i;
+ dpy = display->display;
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info;
@@ -3049,19 +3058,19 @@ _cairo_xlib_surface_font_init (Display *dpy,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font_private->scaled_font = scaled_font;
+ font_private->display = _cairo_xlib_display_get (dpy);
+ if (font_private->display == NULL) {
+ free (font_private);
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
/* initialize and hook into the CloseDisplay callback */
font_private->close_display_hook.func =
_cairo_xlib_surface_remove_scaled_font;
- if (! _cairo_xlib_add_close_display_hook (dpy,
- &font_private->close_display_hook))
- {
- free (font_private);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
+ _cairo_xlib_add_close_display_hook (font_private->display,
+ &font_private->close_display_hook);
- font_private->display = _cairo_xlib_display_get (dpy);
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info = &font_private->glyphset_info[i];
switch (i) {
@@ -3092,7 +3101,7 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
int i;
display = font_private->display;
- _cairo_xlib_remove_close_display_hook (display->display,
+ _cairo_xlib_remove_close_display_hook (display,
&font_private->close_display_hook);
for (i = 0; i < NUM_GLYPHSETS; i++) {
commit 939b836bfa95df759aca96936bb9a6d89d3130b8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 2 10:08:04 2008 +0100
[xlib] Use an embedded doubly-linked list for the close display hooks.
Kill the allocation and linear search of the close display list on remove,
by embedding a list node into the parent structure.
Original patch by Karl Tomlinson <karlt+ at karlt.net>, Mozilla Corporation.
https://bugzilla.mozilla.org/show_bug.cgi?id=453199#c5
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 895258d..ff2e08e 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -29,6 +29,8 @@
*
* The Initial Developer of the Original Code is Chris Wilson.
*
+ * Contributor(s):
+ * Karl Tomlinson <karlt+ at karlt.net>, Mozilla Corporation
*/
#include "cairoint.h"
@@ -65,10 +67,14 @@ struct _cairo_xlib_job {
static cairo_xlib_display_t *_cairo_xlib_display_list;
static void
+_cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
+ cairo_xlib_hook_t *hook);
+
+static void
_cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
{
cairo_xlib_screen_info_t *screen;
- cairo_xlib_hook_t *hooks, *list;
+ cairo_xlib_hook_t *hook;
/* call all registered shutdown routines */
CAIRO_MUTEX_LOCK (display->mutex);
@@ -76,28 +82,16 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
for (screen = display->screens; screen != NULL; screen = screen->next)
_cairo_xlib_screen_info_close_display (screen);
- hooks = display->close_display_hooks;
- while (hooks != NULL) {
- display->close_display_hooks = NULL;
- CAIRO_MUTEX_UNLOCK (display->mutex);
-
- list = hooks;
- do {
- cairo_xlib_hook_t *hook = list;
- list = hook->next;
+ while (TRUE) {
+ hook = display->close_display_hooks;
+ if (hook == NULL)
+ break;
- hook->func (display->display, hook->data);
- } while (list != NULL);
+ _cairo_xlib_remove_close_display_hook_internal (display, hook);
+ CAIRO_MUTEX_UNLOCK (display->mutex);
+ hook->func (display->display, hook);
CAIRO_MUTEX_LOCK (display->mutex);
- do {
- cairo_xlib_hook_t *hook = hooks;
- hooks = hook->next;
-
- _cairo_freelist_free (&display->hook_freelist, hook);
- } while (hooks != NULL);
-
- hooks = display->close_display_hooks;
}
display->closed = TRUE;
@@ -151,7 +145,6 @@ _cairo_xlib_display_destroy (cairo_xlib_display_t *display)
_cairo_freelist_free (&display->wq_freelist, job);
}
_cairo_freelist_fini (&display->wq_freelist);
- _cairo_freelist_fini (&display->hook_freelist);
CAIRO_MUTEX_FINI (display->mutex);
@@ -277,7 +270,6 @@ _cairo_xlib_display_get (Display *dpy)
XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
_cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t));
- _cairo_freelist_init (&display->hook_freelist, sizeof (cairo_xlib_hook_t));
CAIRO_REFERENCE_COUNT_INIT (&display->ref_count, 2); /* add one for the CloseDisplay */
CAIRO_MUTEX_INIT (display->mutex);
@@ -326,56 +318,56 @@ UNLOCK:
}
cairo_bool_t
-_cairo_xlib_add_close_display_hook (Display *dpy, void (*func) (Display *, void *), void *data)
+_cairo_xlib_add_close_display_hook (Display *dpy, cairo_xlib_hook_t *hook)
{
cairo_xlib_display_t *display;
- cairo_xlib_hook_t *hook;
- cairo_bool_t ret = FALSE;
display = _cairo_xlib_display_get (dpy);
if (display == NULL)
return FALSE;
CAIRO_MUTEX_LOCK (display->mutex);
- if (display->closed == FALSE) {
- hook = _cairo_freelist_alloc (&display->hook_freelist);
- if (hook != NULL) {
- hook->func = func;
- hook->data = data;
-
- hook->next = display->close_display_hooks;
- display->close_display_hooks = hook;
- ret = TRUE;
- }
- }
+ hook->prev = NULL;
+ hook->next = display->close_display_hooks;
+ if (hook->next != NULL)
+ hook->next->prev = hook;
+ display->close_display_hooks = hook;
CAIRO_MUTEX_UNLOCK (display->mutex);
_cairo_xlib_display_destroy (display);
- return ret;
+ return TRUE;
+}
+
+/* display->mutex must be held */
+static void
+_cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
+ cairo_xlib_hook_t *hook)
+{
+ if (display->close_display_hooks == hook)
+ display->close_display_hooks = hook->next;
+ else if (hook->prev != NULL)
+ hook->prev->next = hook->next;
+
+ if (hook->next != NULL)
+ hook->next->prev = hook->prev;
+
+ hook->prev = NULL;
+ hook->next = NULL;
}
void
-_cairo_xlib_remove_close_display_hooks (Display *dpy, const void *data)
+_cairo_xlib_remove_close_display_hook (Display *dpy,
+ cairo_xlib_hook_t *hook)
{
cairo_xlib_display_t *display;
- cairo_xlib_hook_t *hook, *next, **prev;
display = _cairo_xlib_display_get (dpy);
if (display == NULL)
return;
CAIRO_MUTEX_LOCK (display->mutex);
- prev = &display->close_display_hooks;
- for (hook = display->close_display_hooks; hook != NULL; hook = next) {
- next = hook->next;
- if (hook->data == data) {
- *prev = hook->next;
- _cairo_freelist_free (&display->hook_freelist, hook);
- break;
- }
- prev = &hook->next;
- }
+ _cairo_xlib_remove_close_display_hook_internal (display, hook);
CAIRO_MUTEX_UNLOCK (display->mutex);
_cairo_xlib_display_destroy (display);
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 61ce889..e962278 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -28,6 +28,10 @@
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributors(s):
+ * Chris Wilson <chris at chris-wilson.co.uk>
+ * Karl Tomlinson <karlt+ at karlt.net>, Mozilla Corporation
*/
#ifndef CAIRO_XLIB_PRIVATE_H
@@ -48,9 +52,8 @@ typedef void (*cairo_xlib_notify_func) (Display *, void *);
typedef void (*cairo_xlib_notify_resource_func) (Display *, XID);
struct _cairo_xlib_hook {
- cairo_xlib_hook_t *next;
+ cairo_xlib_hook_t *prev, *next; /* private */
void (*func) (Display *display, void *data);
- void *data;
};
struct _cairo_xlib_display {
@@ -66,7 +69,6 @@ struct _cairo_xlib_display {
cairo_xlib_job_t *workqueue;
cairo_freelist_t wq_freelist;
- cairo_freelist_t hook_freelist;
cairo_xlib_hook_t *close_display_hooks;
unsigned int buggy_repeat :1;
unsigned int closed :1;
@@ -112,9 +114,10 @@ cairo_private void
_cairo_xlib_display_destroy (cairo_xlib_display_t *info);
cairo_private cairo_bool_t
-_cairo_xlib_add_close_display_hook (Display *display, void (*func) (Display *, void *), void *data);
+_cairo_xlib_add_close_display_hook (Display *display, cairo_xlib_hook_t *hook);
+
cairo_private void
-_cairo_xlib_remove_close_display_hooks (Display *display, const void *data);
+_cairo_xlib_remove_close_display_hook (Display *display, cairo_xlib_hook_t *hook);
cairo_private cairo_status_t
_cairo_xlib_display_queue_work (cairo_xlib_display_t *display,
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index d5df19c..a16e8e4 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -46,6 +46,7 @@ struct _cairo_xlib_surface {
Display *dpy;
cairo_xlib_screen_info_t *screen_info;
+ cairo_xlib_hook_t close_display_hook;
GC gc;
Drawable drawable;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index e7116f3..e9ff65d 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -35,6 +35,8 @@
* Contributor(s):
* Carl D. Worth <cworth at cworth.org>
* Behdad Esfahbod <behdad at behdad.org>
+ * Chris Wilson <chris at chris-wilson.co.uk>
+ * Karl Tomlinson <karlt+ at karlt.net>, Mozilla Corporation
*/
#include "cairoint.h"
@@ -319,7 +321,8 @@ _cairo_xlib_surface_finish (void *abstract_surface)
_cairo_xlib_screen_info_destroy (surface->screen_info);
if (surface->dpy != NULL) {
- _cairo_xlib_remove_close_display_hooks (surface->dpy, surface);
+ _cairo_xlib_remove_close_display_hook (surface->dpy,
+ &surface->close_display_hook);
surface->dpy = NULL;
}
@@ -2376,10 +2379,13 @@ _cairo_surface_is_xlib (cairo_surface_t *surface)
return surface->backend == &cairo_xlib_surface_backend;
}
+/* callback from CloseDisplay */
static void
_cairo_xlib_surface_detach_display (Display *dpy, void *data)
{
- cairo_xlib_surface_t *surface = data;
+ cairo_xlib_surface_t *surface = cairo_container_of (data,
+ cairo_xlib_surface_t,
+ close_display_hook);
surface->dpy = NULL;
@@ -2457,8 +2463,10 @@ _cairo_xlib_surface_create_internal (Display *dpy,
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
+ /* initialize and hook into the CloseDisplay callback */
+ surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
if (! _cairo_xlib_add_close_display_hook (dpy,
- _cairo_xlib_surface_detach_display, surface))
+ &surface->close_display_hook))
{
free (surface);
_cairo_xlib_screen_info_destroy (screen_info);
@@ -2984,16 +2992,24 @@ typedef struct _cairo_xlib_font_glyphset_info {
} cairo_xlib_font_glyphset_info_t;
typedef struct _cairo_xlib_surface_font_private {
+ cairo_scaled_font_t *scaled_font;
+ cairo_xlib_hook_t close_display_hook;
cairo_xlib_display_t *display;
cairo_xlib_font_glyphset_info_t glyphset_info[NUM_GLYPHSETS];
} cairo_xlib_surface_font_private_t;
+/* callback from CloseDisplay */
static void
_cairo_xlib_surface_remove_scaled_font (Display *dpy,
void *data)
{
- cairo_scaled_font_t *scaled_font = data;
cairo_xlib_surface_font_private_t *font_private;
+ cairo_scaled_font_t *scaled_font;
+
+ font_private = cairo_container_of (data,
+ cairo_xlib_surface_font_private_t,
+ close_display_hook);
+ scaled_font = font_private->scaled_font;
CAIRO_MUTEX_LOCK (scaled_font->mutex);
font_private = scaled_font->surface_private;
@@ -3032,9 +3048,13 @@ _cairo_xlib_surface_font_init (Display *dpy,
if (font_private == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ font_private->scaled_font = scaled_font;
+
+ /* initialize and hook into the CloseDisplay callback */
+ font_private->close_display_hook.func =
+ _cairo_xlib_surface_remove_scaled_font;
if (! _cairo_xlib_add_close_display_hook (dpy,
- _cairo_xlib_surface_remove_scaled_font,
- scaled_font))
+ &font_private->close_display_hook))
{
free (font_private);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3072,7 +3092,8 @@ _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
int i;
display = font_private->display;
- _cairo_xlib_remove_close_display_hooks (display->display, scaled_font);
+ _cairo_xlib_remove_close_display_hook (display->display,
+ &font_private->close_display_hook);
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info;
diff --git a/src/cairoint.h b/src/cairoint.h
index e4c3369..6986546 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -119,6 +119,16 @@ _cairo_win32_tmpfile (void);
*/
#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_SLANT
+#ifdef __GNUC__
+#define cairo_container_of(ptr, type, member) ({ \
+ const typeof(((type *) 0)->member) *mptr__ = (ptr); \
+ (type *) ((char *) mptr__ - offsetof (type, member)); \
+})
+#else
+#define cairo_container_of(ptr, type, member) \
+ (type *)((char *) (ptr) - (char *) &((type *)0)->member)
+#endif
+
/* Size in bytes of buffer to use off the stack per functions.
* Mostly used by text functions. For larger allocations, they'll
commit 38f779afcb84d48a1a146eec11a6db5c484d3578
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 2 09:12:44 2008 +0100
[user-font] Propagate status return.
An error return possible went unpropagated - fix that. Also whilst in the
vicinity avoid the non-constant initialisation of the local variable
before the antiquated compilers moan.
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index ebac53b..f49943b 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -147,8 +147,11 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
cairo_box_t bbox;
double x1, y1, x2, y2;
double x_scale, y_scale;
- cairo_surface_t *null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface));
- cairo_surface_t *analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
+ cairo_surface_t *null_surface;
+ cairo_surface_t *analysis_surface;
+
+ null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface));
+ analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
cairo_surface_destroy (null_surface);
_cairo_analysis_surface_set_ctm (analysis_surface, &scaled_font->extent_scale);
@@ -156,6 +159,9 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
cairo_surface_destroy (analysis_surface);
+ if (status)
+ return status;
+
_cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2);
x_scale = scaled_font->extent_x_scale;
More information about the cairo-commit
mailing list