[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.
This commit is contained in:
Chris Wilson 2008-10-28 16:33:51 +00:00
parent e25b106e9c
commit d384f86499
3 changed files with 40 additions and 30 deletions

View file

@ -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);

View file

@ -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

View file

@ -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));