From d384f864992fbf7513446a70158135a08e704678 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 28 Oct 2008 16:33:51 +0000 Subject: [PATCH] [xlib] Propagate real status from get_screen_info(). Return the real error from _cairo_xlib_screen_info_get() in order to avoid having to create a fake NO_MEMORY error. --- src/cairo-xlib-private.h | 6 +++-- src/cairo-xlib-screen.c | 58 +++++++++++++++++++++++----------------- src/cairo-xlib-surface.c | 6 ++--- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h index cd89290ae..58edbeb5b 100644 --- a/src/cairo-xlib-private.h +++ b/src/cairo-xlib-private.h @@ -138,8 +138,10 @@ cairo_private XRenderPictFormat * _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 (cairo_xlib_display_t *display, Screen *screen); +cairo_private cairo_status_t +_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, + Screen *screen, + cairo_xlib_screen_info_t **out); 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 a864fec22..65d131c0c 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -318,15 +318,17 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info) free (info); } -cairo_xlib_screen_info_t * -_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen) +cairo_status_t +_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, + Screen *screen, + cairo_xlib_screen_info_t **out) { cairo_xlib_screen_info_t *info = NULL, **prev; CAIRO_MUTEX_LOCK (display->mutex); if (display->closed) { CAIRO_MUTEX_UNLOCK (display->mutex); - return NULL; + return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); } for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) { @@ -348,35 +350,41 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen) info = _cairo_xlib_screen_info_reference (info); } else { info = malloc (sizeof (cairo_xlib_screen_info_t)); - if (info != NULL) { - CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */ - CAIRO_MUTEX_INIT (info->mutex); - info->display = _cairo_xlib_display_reference (display); - info->screen = screen; - info->has_render = FALSE; - info->has_font_options = FALSE; - memset (info->gc, 0, sizeof (info->gc)); - info->gc_needs_clip_reset = 0; + if (info == NULL) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); - _cairo_array_init (&info->visuals, - sizeof (cairo_xlib_visual_info_t*)); + CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */ + CAIRO_MUTEX_INIT (info->mutex); + info->display = _cairo_xlib_display_reference (display); + info->screen = screen; + info->has_render = FALSE; + info->has_font_options = FALSE; + memset (info->gc, 0, sizeof (info->gc)); + info->gc_needs_clip_reset = 0; - if (screen) { - Display *dpy = display->display; - int event_base, error_base; + _cairo_array_init (&info->visuals, + sizeof (cairo_xlib_visual_info_t*)); - info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) && - (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0)); - } + if (screen) { + Display *dpy = display->display; + int event_base, error_base; - CAIRO_MUTEX_LOCK (display->mutex); - info->next = display->screens; - display->screens = info; - CAIRO_MUTEX_UNLOCK (display->mutex); + info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) && + (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0)); } + + /* Small window of opportunity for two screen infos for the same + * Screen - just wastes a little bit of memory but should not cause + * any corruption. + */ + CAIRO_MUTEX_LOCK (display->mutex); + info->next = display->screens; + display->screens = info; + CAIRO_MUTEX_UNLOCK (display->mutex); } - return info; + *out = info; + return CAIRO_STATUS_SUCCESS; } static int diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 4d7e6a813..d078dcdc0 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2545,10 +2545,10 @@ _cairo_xlib_surface_create_internal (Display *dpy, if (status) return _cairo_surface_create_in_error (status); - screen_info = _cairo_xlib_screen_info_get (display, screen); - if (screen_info == NULL) { + status = _cairo_xlib_screen_info_get (display, screen, &screen_info); + if (status) { _cairo_xlib_display_destroy (display); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + return _cairo_surface_create_in_error (status); } surface = malloc (sizeof (cairo_xlib_surface_t));