summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-04-23 22:10:32 +0200
committerBenjamin Otte <otte@redhat.com>2010-04-23 22:18:54 +0200
commit637564c562de21c17c36d192d3ab1b3fe069754b (patch)
tree3d9c0e9846cfbd9fe29014c06ea33c683d265d3e
parent49b52a8946cbd5f785f71069313e4a204358887b (diff)
xlib: Fix screen device handling
Add a _cairo_xlib_device_create() function that could easily be exported as a replacement for _cairo_xlib_display_get(). This function returns a cairo_device_t instead of a cairo_xlib_display_t because the display isn't acquired.
-rw-r--r--src/cairo-xlib-display.c33
-rw-r--r--src/cairo-xlib-private.h4
-rw-r--r--src/cairo-xlib-screen.c23
3 files changed, 36 insertions, 24 deletions
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index b0a58280..6dd62cc6 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -254,15 +254,22 @@ static const cairo_device_backend_t _cairo_xlib_device_backend = {
_cairo_xlib_display_destroy,
};
-cairo_status_t
-_cairo_xlib_display_get (Display *dpy,
- cairo_xlib_display_t **out)
+/**
+ * cairo_xlib_device_create:
+ * @dpy: the display to create the device for
+ *
+ * Gets the device belonging to @dpy, or creates it if it doesn't exist yet.
+ *
+ * Returns: the device belonging to @dpy
+ **/
+cairo_device_t *
+_cairo_xlib_device_create (Display *dpy)
{
cairo_xlib_display_t *display;
cairo_xlib_display_t **prev;
+ cairo_device_t *device;
XExtCodes *codes;
const char *env;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
/* There is an apparent deadlock between this mutex and the
* mutex for the display, but it's actually safe. For the
@@ -284,18 +291,14 @@ _cairo_xlib_display_get (Display *dpy,
display->next = _cairo_xlib_display_list;
_cairo_xlib_display_list = display;
}
- break;
+ device = cairo_device_reference (&display->base);
+ goto UNLOCK;
}
}
- if (display != NULL) {
- cairo_device_reference (&display->base);
- goto UNLOCK;
- }
-
display = malloc (sizeof (cairo_xlib_display_t));
if (unlikely (display == NULL)) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
goto UNLOCK;
}
@@ -326,9 +329,8 @@ _cairo_xlib_display_get (Display *dpy,
codes = XAddExtension (dpy);
if (unlikely (codes == NULL)) {
- status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
free (display);
- display = NULL;
goto UNLOCK;
}
@@ -433,10 +435,11 @@ _cairo_xlib_display_get (Display *dpy,
display->next = _cairo_xlib_display_list;
_cairo_xlib_display_list = display;
+ device = &display->base;
+
UNLOCK:
CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
- *out = display;
- return status;
+ return device;
}
void
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 550520da..d8acf9a9 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -112,8 +112,8 @@ struct _cairo_xlib_screen {
cairo_array_t visuals;
};
-cairo_private cairo_status_t
-_cairo_xlib_display_get (Display *display, cairo_xlib_display_t **out);
+cairo_private cairo_device_t *
+_cairo_xlib_device_create (Display *display);
cairo_private void
_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 2831acac..810e484b 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -307,7 +307,6 @@ _cairo_xlib_screen_destroy (cairo_xlib_screen_t *info)
cairo_device_release (&display->base);
}
- cairo_device_destroy (info->device);
_cairo_array_fini (&info->visuals);
@@ -320,12 +319,20 @@ _cairo_xlib_screen_get (Display *dpy,
cairo_xlib_screen_t **out)
{
cairo_xlib_display_t *display;
+ cairo_device_t *device;
cairo_xlib_screen_t *info;
cairo_status_t status;
- status = _cairo_xlib_display_get (dpy, &display);
- if (likely (status == CAIRO_STATUS_SUCCESS))
- status = _cairo_xlib_display_get_screen (display, screen, &info);
+ device = _cairo_xlib_device_create (dpy);
+ status = device->status;
+ if (unlikely (status))
+ goto CLEANUP_DEVICE;
+
+ status = _cairo_xlib_display_acquire (device, &display);
+ if (unlikely (status))
+ goto CLEANUP_DEVICE;
+
+ status = _cairo_xlib_display_get_screen (display, screen, &info);
if (unlikely (status))
goto CLEANUP_DISPLAY;
@@ -341,7 +348,7 @@ _cairo_xlib_screen_get (Display *dpy,
}
CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
- info->device = &display->base;
+ info->device = device;
info->screen = screen;
info->has_render = FALSE;
info->has_font_options = FALSE;
@@ -366,10 +373,12 @@ _cairo_xlib_screen_get (Display *dpy,
_cairo_xlib_display_add_screen (display, info);
*out = info;
- return CAIRO_STATUS_SUCCESS;
CLEANUP_DISPLAY:
- cairo_device_destroy ((cairo_device_t *) display);
+ cairo_device_release (&display->base);
+
+ CLEANUP_DEVICE:
+ cairo_device_destroy (device);
return status;
}