void _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info) { cairo_xlib_screen_info_t **prev; cairo_xlib_screen_info_t *list; assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); if (! _cairo_reference_count_dec_and_test (&info->ref_count)) return; CAIRO_MUTEX_LOCK (info->display->mutex); for (prev = &info->display->screens; (list = *prev); prev = &list->next) { if (list == info) { *prev = info->next; break; } } CAIRO_MUTEX_UNLOCK (info->display->mutex); _cairo_xlib_screen_info_close_display (info); _cairo_xlib_display_destroy (info->display); _cairo_array_fini (&info->visuals); CAIRO_MUTEX_FINI (info->mutex); free (info); }
cairo_bool_t _cairo_xlib_add_close_display_hook (Display *dpy, void (*func) (Display *, void *), void *data, const void *key) { 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->key = key; hook->next = display->close_display_hooks; display->close_display_hooks = hook; ret = TRUE; } } CAIRO_MUTEX_UNLOCK (display->mutex); _cairo_xlib_display_destroy (display); return ret; }
void _cairo_xlib_remove_close_display_hooks (Display *dpy, const void *key) { 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->key == key) { *prev = hook->next; _cairo_freelist_free (&display->hook_freelist, hook); } else prev = &hook->next; } *prev = NULL; CAIRO_MUTEX_UNLOCK (display->mutex); _cairo_xlib_display_destroy (display); }
static int _cairo_xlib_close_display (Display *dpy, XExtCodes *codes) { cairo_xlib_display_t *display, **prev, *next; cairo_xlib_error_func_t old_handler; CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); for (display = _cairo_xlib_display_list; display; display = display->next) if (display->display == dpy) break; CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); if (display == NULL) return 0; /* protect the notifies from triggering XErrors */ XSync (dpy, False); old_handler = XSetErrorHandler (_noop_error_handler); _cairo_xlib_display_notify (display); _cairo_xlib_call_close_display_hooks (display); _cairo_xlib_display_discard_screens (display); /* catch any that arrived before marking the display as closed */ _cairo_xlib_display_notify (display); XSync (dpy, False); XSetErrorHandler (old_handler); /* * Unhook from the global list */ CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); prev = &_cairo_xlib_display_list; for (display = _cairo_xlib_display_list; display; display = next) { next = display->next; if (display->display == dpy) { *prev = next; break; } else prev = &display->next; } CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); assert (display != NULL); _cairo_xlib_display_destroy (display); /* Return value in accordance with requirements of * XESetCloseDisplay */ return 0; }