Skip to content

Commit

Permalink
xlib: Fix screen device handling
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Benjamin Otte committed Apr 23, 2010
1 parent 49b52a8 commit 637564c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
33 changes: 18 additions & 15 deletions src/cairo-xlib-display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/cairo-xlib-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
23 changes: 16 additions & 7 deletions src/cairo-xlib-screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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;
}

Expand Down

0 comments on commit 637564c

Please sign in to comment.