summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-01 23:12:43 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-09-01 23:12:43 +0100
commit7d1eb259f93d3f2f2e754b2b8b90cb88359b477d (patch)
treeb608289649a97f6d0088246c1e09abb9fc1ad17b
parentb8ddd66cf6e0d16383580c3c3398343f577b89fd (diff)
[xlib] Make xlib_display_t private and rename xlib_screen_info_t
The issue Joonas was trying to solve was the unwanted inclusion of the inlines via cairo-freelist-private.h. Unwittingly he included cairoint.h from cairo-xlib-private.h instead, a far more heinous crime as that causes the boilerplate to try to use the hidden, private symbols. Instead we resolve this issue by making the cairo_xlib_display_t structure private to cairo-xlib-display.c and provide functions to manipulate the abstract data type. Whilst in the vicinity, we rename cairo_xlib_screen_info_t to cairo_xlib_screen_t for consistency and cleanliness.
-rw-r--r--src/cairo-xlib-display.c126
-rw-r--r--src/cairo-xlib-private.h88
-rw-r--r--src/cairo-xlib-screen.c155
-rw-r--r--src/cairo-xlib-surface-private.h3
-rw-r--r--src/cairo-xlib-surface.c173
5 files changed, 339 insertions, 206 deletions
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index d05bfedd..0c0ce61c 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -38,8 +38,32 @@
#include "cairo-xlib-private.h"
#include "cairo-xlib-xrender-private.h"
+#include "cairo-freelist-private.h"
+
#include <X11/Xlibint.h> /* For XESetCloseDisplay */
+struct _cairo_xlib_display {
+ cairo_xlib_display_t *next;
+ cairo_reference_count_t ref_count;
+ cairo_mutex_t mutex;
+
+ Display *display;
+ cairo_xlib_screen_t *screens;
+
+ int render_major;
+ int render_minor;
+ XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_A1 + 1];
+
+ cairo_xlib_job_t *workqueue;
+ cairo_freelist_t wq_freelist;
+
+ cairo_xlib_hook_t *close_display_hooks;
+ unsigned int buggy_gradients :1;
+ unsigned int buggy_pad_reflect :1;
+ unsigned int buggy_repeat :1;
+ unsigned int closed :1;
+};
+
typedef int (*cairo_xlib_error_func_t) (Display *display,
XErrorEvent *event);
@@ -71,14 +95,14 @@ _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
static void
_cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
{
- cairo_xlib_screen_info_t *screen;
+ cairo_xlib_screen_t *screen;
cairo_xlib_hook_t *hook;
/* call all registered shutdown routines */
CAIRO_MUTEX_LOCK (display->mutex);
for (screen = display->screens; screen != NULL; screen = screen->next)
- _cairo_xlib_screen_info_close_display (screen);
+ _cairo_xlib_screen_close_display (screen);
while (TRUE) {
hook = display->close_display_hooks;
@@ -99,7 +123,7 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
static void
_cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
{
- cairo_xlib_screen_info_t *screens;
+ cairo_xlib_screen_t *screens;
CAIRO_MUTEX_LOCK (display->mutex);
screens = display->screens;
@@ -107,10 +131,10 @@ _cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
CAIRO_MUTEX_UNLOCK (display->mutex);
while (screens != NULL) {
- cairo_xlib_screen_info_t *screen = screens;
+ cairo_xlib_screen_t *screen = screens;
screens = screen->next;
- _cairo_xlib_screen_info_destroy (screen);
+ _cairo_xlib_screen_destroy (screen);
}
}
@@ -559,3 +583,95 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
return xrender_format;
}
+
+Display *
+_cairo_xlib_display_get_dpy (cairo_xlib_display_t *display)
+{
+ return display->display;
+}
+
+void
+_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
+ cairo_xlib_screen_t *screen)
+{
+ cairo_xlib_screen_t **prev;
+ cairo_xlib_screen_t *list;
+
+ CAIRO_MUTEX_LOCK (display->mutex);
+ for (prev = &display->screens; (list = *prev); prev = &list->next) {
+ if (list == screen) {
+ *prev = screen->next;
+ break;
+ }
+ }
+ CAIRO_MUTEX_UNLOCK (display->mutex);
+}
+
+cairo_status_t
+_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
+ Screen *screen,
+ cairo_xlib_screen_t **out)
+{
+ cairo_xlib_screen_t *info = NULL, **prev;
+
+ CAIRO_MUTEX_LOCK (display->mutex);
+ if (display->closed) {
+ CAIRO_MUTEX_UNLOCK (display->mutex);
+ return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+ }
+
+ for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
+ if (info->screen == screen) {
+ /*
+ * MRU the list
+ */
+ if (prev != &display->screens) {
+ *prev = info->next;
+ info->next = display->screens;
+ display->screens = info;
+ }
+ break;
+ }
+ }
+ CAIRO_MUTEX_UNLOCK (display->mutex);
+
+ *out = info;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+
+void
+_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
+ cairo_xlib_screen_t *screen)
+{
+ CAIRO_MUTEX_LOCK (display->mutex);
+ screen->next = display->screens;
+ display->screens = screen;
+ CAIRO_MUTEX_UNLOCK (display->mutex);
+}
+
+void
+_cairo_xlib_display_get_xrender_version (cairo_xlib_display_t *display,
+ int *major, int *minor)
+{
+ *major = display->render_major;
+ *minor = display->render_minor;
+}
+
+cairo_bool_t
+_cairo_xlib_display_has_repeat (cairo_xlib_display_t *display)
+{
+ return ! display->buggy_repeat;
+}
+
+cairo_bool_t
+_cairo_xlib_display_has_reflect (cairo_xlib_display_t *display)
+{
+ return ! display->buggy_pad_reflect;
+}
+
+cairo_bool_t
+_cairo_xlib_display_has_gradients (cairo_xlib_display_t *display)
+{
+ return ! display->buggy_gradients;
+}
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index b980b074..e92bb942 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -41,11 +41,13 @@
#include "cairo-xlib-xrender-private.h"
#include "cairo-compiler-private.h"
-#include "cairo-freelist-private.h"
#include "cairo-mutex-private.h"
#include "cairo-reference-count-private.h"
+#include "cairo-types-private.h"
typedef struct _cairo_xlib_display cairo_xlib_display_t;
+typedef struct _cairo_xlib_screen cairo_xlib_screen_t;
+
typedef struct _cairo_xlib_hook cairo_xlib_hook_t;
typedef struct _cairo_xlib_job cairo_xlib_job_t;
typedef void (*cairo_xlib_notify_func) (Display *, void *);
@@ -56,28 +58,6 @@ struct _cairo_xlib_hook {
void (*func) (cairo_xlib_display_t *display, void *data);
};
-struct _cairo_xlib_display {
- cairo_xlib_display_t *next;
- cairo_reference_count_t ref_count;
- cairo_mutex_t mutex;
-
- Display *display;
- cairo_xlib_screen_info_t *screens;
-
- int render_major;
- int render_minor;
- XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_A1 + 1];
-
- cairo_xlib_job_t *workqueue;
- cairo_freelist_t wq_freelist;
-
- cairo_xlib_hook_t *close_display_hooks;
- unsigned int buggy_gradients :1;
- unsigned int buggy_pad_reflect :1;
- unsigned int buggy_repeat :1;
- unsigned int closed :1;
-};
-
/* size of color cube */
#define CUBE_SIZE 6
/* size of gray ramp */
@@ -92,8 +72,8 @@ typedef struct _cairo_xlib_visual_info {
uint8_t gray8_to_pseudocolor[256];
} cairo_xlib_visual_info_t;
-struct _cairo_xlib_screen_info {
- cairo_xlib_screen_info_t *next;
+struct _cairo_xlib_screen {
+ cairo_xlib_screen_t *next;
cairo_reference_count_t ref_count;
cairo_mutex_t mutex;
@@ -115,10 +95,33 @@ _cairo_xlib_display_get (Display *display, cairo_xlib_display_t **out);
cairo_private cairo_xlib_display_t *
_cairo_xlib_display_reference (cairo_xlib_display_t *info);
+
cairo_private void
_cairo_xlib_display_destroy (cairo_xlib_display_t *info);
cairo_private void
+_cairo_xlib_display_lock (cairo_xlib_display_t *display);
+
+cairo_private void
+_cairo_xlib_display_unlock (cairo_xlib_display_t *display);
+
+cairo_private Display *
+_cairo_xlib_display_get_dpy (cairo_xlib_display_t *info);
+
+cairo_private void
+_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
+ cairo_xlib_screen_t *screen);
+
+cairo_private cairo_status_t
+_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
+ Screen *screen,
+ cairo_xlib_screen_t **out);
+
+cairo_private void
+_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
+ cairo_xlib_screen_t *screen);
+
+cairo_private void
_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
cairo_private void
@@ -136,40 +139,53 @@ _cairo_xlib_display_queue_resource (cairo_xlib_display_t *display,
cairo_private void
_cairo_xlib_display_notify (cairo_xlib_display_t *display);
+cairo_private void
+_cairo_xlib_display_get_xrender_version (cairo_xlib_display_t *display,
+ int *major, int *minor);
+
+cairo_private cairo_bool_t
+_cairo_xlib_display_has_repeat (cairo_xlib_display_t *display);
+
+cairo_private cairo_bool_t
+_cairo_xlib_display_has_reflect (cairo_xlib_display_t *display);
+
+cairo_private cairo_bool_t
+_cairo_xlib_display_has_gradients (cairo_xlib_display_t *display);
+
cairo_private XRenderPictFormat *
_cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
cairo_format_t format);
cairo_private cairo_status_t
-_cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
- Screen *screen,
- cairo_xlib_screen_info_t **out);
+_cairo_xlib_screen_get (Display *dpy,
+ Screen *screen,
+ cairo_xlib_screen_t **out);
-cairo_private cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info);
+cairo_private cairo_xlib_screen_t *
+_cairo_xlib_screen_reference (cairo_xlib_screen_t *info);
cairo_private void
-_cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info);
+_cairo_xlib_screen_destroy (cairo_xlib_screen_t *info);
cairo_private void
-_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info);
+_cairo_xlib_screen_close_display (cairo_xlib_screen_t *info);
cairo_private GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
unsigned int depth,
Drawable drawable,
unsigned int *need_reset);
cairo_private void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
unsigned int depth,
GC gc,
cairo_bool_t reset_clip);
cairo_private cairo_font_options_t *
-_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info);
+_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info);
cairo_private cairo_status_t
-_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
Visual *visual,
cairo_xlib_visual_info_t **out);
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index e491a333..38e64af3 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -144,7 +144,7 @@ get_integer_default (Display *dpy,
static void
_cairo_xlib_init_screen_font_options (Display *dpy,
- cairo_xlib_screen_info_t *info)
+ cairo_xlib_screen_t *info)
{
cairo_bool_t xft_hinting;
cairo_bool_t xft_antialias;
@@ -254,8 +254,8 @@ _cairo_xlib_init_screen_font_options (Display *dpy,
cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON);
}
-cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
+cairo_xlib_screen_t *
+_cairo_xlib_screen_reference (cairo_xlib_screen_t *info)
{
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
@@ -265,7 +265,7 @@ _cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
}
void
-_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
+_cairo_xlib_screen_close_display (cairo_xlib_screen_t *info)
{
cairo_xlib_visual_info_t **visuals;
Display *dpy;
@@ -273,7 +273,7 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
CAIRO_MUTEX_LOCK (info->mutex);
- dpy = info->display->display;
+ dpy = _cairo_xlib_display_get_dpy (info->display);
#if HAS_ATOMIC_OPS
do {
@@ -297,26 +297,16 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
}
void
-_cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
+_cairo_xlib_screen_destroy (cairo_xlib_screen_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_display_remove_screen (info->display, info);
- _cairo_xlib_screen_info_close_display (info);
+ _cairo_xlib_screen_close_display (info);
_cairo_xlib_display_destroy (info->display);
@@ -328,77 +318,68 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
}
cairo_status_t
-_cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
- Screen *screen,
- cairo_xlib_screen_info_t **out)
+_cairo_xlib_screen_get (Display *dpy,
+ Screen *screen,
+ cairo_xlib_screen_t **out)
{
- cairo_xlib_screen_info_t *info = NULL, **prev;
+ cairo_xlib_display_t *display;
+ cairo_xlib_screen_t *info;
+ cairo_status_t status;
- CAIRO_MUTEX_LOCK (display->mutex);
- if (display->closed) {
- CAIRO_MUTEX_UNLOCK (display->mutex);
- return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+ status = _cairo_xlib_display_get (dpy, &display);
+ if (likely (status == CAIRO_STATUS_SUCCESS))
+ status = _cairo_xlib_display_get_screen (display, screen, &info);
+ if (unlikely (status))
+ goto CLEANUP_DISPLAY;
+
+ if (info != NULL) {
+ *out = _cairo_xlib_screen_reference (info);
+ goto CLEANUP_DISPLAY;
}
- for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
- if (info->screen == screen) {
- /*
- * MRU the list
- */
- if (prev != &display->screens) {
- *prev = info->next;
- info->next = display->screens;
- display->screens = info;
- }
- break;
- }
+ info = malloc (sizeof (cairo_xlib_screen_t));
+ if (unlikely (info == NULL)) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto CLEANUP_DISPLAY;
}
- CAIRO_MUTEX_UNLOCK (display->mutex);
- if (info != NULL) {
- info = _cairo_xlib_screen_info_reference (info);
- } else {
- info = malloc (sizeof (cairo_xlib_screen_info_t));
- if (unlikely (info == NULL))
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
- 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;
- info->gc_depths = 0;
- memset (info->gc, 0, sizeof (info->gc));
-
- _cairo_array_init (&info->visuals,
- sizeof (cairo_xlib_visual_info_t*));
-
- if (screen) {
- Display *dpy = display->display;
- int event_base, error_base;
-
- info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
- (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
- }
+ CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
+ CAIRO_MUTEX_INIT (info->mutex);
+ info->display = display;
+ info->screen = screen;
+ info->has_render = FALSE;
+ info->has_font_options = FALSE;
+ info->gc_depths = 0;
+ memset (info->gc, 0, sizeof (info->gc));
+
+ _cairo_array_init (&info->visuals,
+ sizeof (cairo_xlib_visual_info_t*));
- /* 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);
+ if (screen) {
+ int event_base, error_base;
+
+ 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_xlib_display_add_screen (display, info);
+
*out = info;
return CAIRO_STATUS_SUCCESS;
+
+ CLEANUP_DISPLAY:
+ _cairo_xlib_display_destroy (display);
+ return status;
}
#if HAS_ATOMIC_OPS
GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
unsigned int depth,
Drawable drawable,
unsigned int *dirty)
@@ -438,12 +419,13 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
}
gcv.graphics_exposures = False;
- return XCreateGC (info->display->display, drawable,
+ return XCreateGC (_cairo_xlib_display_get_dpy (info->display),
+ drawable,
GCGraphicsExposures, &gcv);
}
void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
unsigned int depth,
GC gc,
cairo_bool_t reset_clip)
@@ -485,7 +467,7 @@ out:
}
#else
GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_t *info,
unsigned int depth,
Drawable drawable,
unsigned int *dirty)
@@ -510,7 +492,8 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
XGCValues gcv;
gcv.graphics_exposures = False;
- gc = XCreateGC (info->display->display, drawable,
+ gc = XCreateGC (_cairo_xlib_display_get_dpy (info->display),
+ drawable,
GCGraphicsExposures, &gcv);
}
@@ -518,7 +501,7 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
}
void
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_t *info,
unsigned int depth,
GC gc,
cairo_bool_t reset_clip)
@@ -557,11 +540,11 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
#endif
cairo_status_t
-_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
+_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_t *info,
Visual *visual,
cairo_xlib_visual_info_t **out)
{
- Display *dpy = info->display->display;
+ Display *dpy = _cairo_xlib_display_get_dpy (info->display);
cairo_xlib_visual_info_t **visuals, *ret = NULL;
cairo_status_t status;
int i, n_visuals;
@@ -617,19 +600,19 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
}
cairo_font_options_t *
-_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info)
+_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info)
{
if (info->has_font_options)
return &info->font_options;
CAIRO_MUTEX_LOCK (info->mutex);
if (! info->has_font_options) {
- Display *dpy = info->display->display;
-
_cairo_font_options_init_default (&info->font_options);
- if (info->screen != NULL)
- _cairo_xlib_init_screen_font_options (dpy, info);
+ if (info->screen != NULL) {
+ _cairo_xlib_init_screen_font_options (_cairo_xlib_display_get_dpy (info->display),
+ info);
+ }
info->has_font_options = TRUE;
}
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index cb97650b..b3cbe045 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -46,12 +46,11 @@ struct _cairo_xlib_surface {
Display *dpy;
cairo_xlib_display_t *display;
- cairo_xlib_screen_info_t *screen_info;
+ cairo_xlib_screen_t *screen;
cairo_xlib_hook_t close_display_hook;
GC gc;
Drawable drawable;
- Screen *screen;
cairo_bool_t owns_pixmap;
Visual *visual;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 65b8a694..b53f4dec 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -74,9 +74,8 @@ typedef int (*cairo_xlib_error_func_t) (Display *display,
XErrorEvent *event);
static cairo_surface_t *
-_cairo_xlib_surface_create_internal (Display *dpy,
+_cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
Drawable drawable,
- Screen *screen,
Visual *visual,
XRenderPictFormat *xrender_format,
int width,
@@ -249,8 +248,8 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src,
xrender_format->depth);
surface = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_internal (dpy, pix,
- src->screen, NULL,
+ _cairo_xlib_surface_create_internal (src->screen, pix,
+ NULL,
xrender_format,
width, height,
xrender_format->depth);
@@ -327,8 +326,8 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
xrender_format->depth);
surface = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_internal (src->dpy, pix,
- src->screen, src->visual,
+ _cairo_xlib_surface_create_internal (src->screen, pix,
+ src->visual,
xrender_format,
width, height,
xrender_format->depth);
@@ -382,7 +381,7 @@ _cairo_xlib_surface_finish (void *abstract_surface)
}
if (surface->gc != NULL) {
- _cairo_xlib_screen_put_gc (surface->screen_info,
+ _cairo_xlib_screen_put_gc (surface->screen,
surface->depth,
surface->gc,
surface->gc_has_clip_rects);
@@ -392,17 +391,15 @@ _cairo_xlib_surface_finish (void *abstract_surface)
if (surface->clip_rects != surface->embedded_clip_rects)
free (surface->clip_rects);
- if (surface->screen_info != NULL)
- _cairo_xlib_screen_info_destroy (surface->screen_info);
-
- if (surface->display != NULL) {
+ if (surface->dpy != NULL) {
_cairo_xlib_remove_close_display_hook (surface->display,
&surface->close_display_hook);
- _cairo_xlib_display_destroy (surface->display);
+ surface->dpy = NULL;
}
+ _cairo_xlib_screen_destroy (surface->screen);
+
cairo_region_destroy (surface->clip_region);
- surface->dpy = NULL;
return status;
}
@@ -857,7 +854,7 @@ _get_image_surface (cairo_xlib_surface_t *surface,
} else {
format = CAIRO_FORMAT_RGB24;
- status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+ status = _cairo_xlib_screen_get_visual_info (surface->screen,
surface->visual,
&visual_info);
if (unlikely (status))
@@ -984,7 +981,7 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface,
{
if (surface->gc == NULL) {
- surface->gc = _cairo_xlib_screen_get_gc (surface->screen_info,
+ surface->gc = _cairo_xlib_screen_get_gc (surface->screen,
surface->depth,
surface->drawable,
&surface->clip_dirty);
@@ -1017,7 +1014,7 @@ _cairo_xlib_surface_maybe_put_gc (cairo_xlib_surface_t *surface)
if (surface->gc_has_clip_rects)
return;
- _cairo_xlib_screen_put_gc (surface->screen_info,
+ _cairo_xlib_screen_put_gc (surface->screen,
surface->depth,
surface->gc,
FALSE);
@@ -1117,7 +1114,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
_characterize_field (surface->g_mask, &o_g_width, &o_g_shift);
_characterize_field (surface->b_mask, &o_b_width, &o_b_shift);
} else {
- status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+ status = _cairo_xlib_screen_get_visual_info (surface->screen,
surface->visual,
&visual_info);
if (unlikely (status))
@@ -1289,7 +1286,7 @@ static inline cairo_bool_t
_cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst,
cairo_xlib_surface_t *src)
{
- return dst->screen_info == src->screen_info;
+ return dst->screen == src->screen;
}
static cairo_status_t
@@ -1400,9 +1397,9 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac
other->depth);
surface = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_internal (other->dpy,
+ _cairo_xlib_surface_create_internal (other->screen,
pixmap,
- other->screen, other->visual,
+ other->visual,
other->xrender_format,
width, height,
other->depth);
@@ -2010,9 +2007,9 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_surface_t *dst,
CAIRO_FORMAT_ARGB32);
surface = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_internal (dst->dpy, None,
- dst->screen, NULL,
- format, 0, 0, 32);
+ _cairo_xlib_surface_create_internal (dst->screen, None,
+ NULL, format,
+ 0, 0, 32);
if (unlikely (surface->base.status)) {
XRenderFreePicture (dst->dpy, picture);
return surface->base.status;
@@ -2744,7 +2741,7 @@ _cairo_xlib_surface_get_font_options (void *abstract_surface,
{
cairo_xlib_surface_t *surface = abstract_surface;
- *options = *_cairo_xlib_screen_get_font_options (surface->screen_info);
+ *options = *_cairo_xlib_screen_get_font_options (surface->screen);
}
static void
@@ -2870,19 +2867,15 @@ _cairo_xlib_surface_detach_display (cairo_xlib_display_t *display, void *data)
}
static cairo_surface_t *
-_cairo_xlib_surface_create_internal (Display *dpy,
- Drawable drawable,
- Screen *screen,
- Visual *visual,
- XRenderPictFormat *xrender_format,
- int width,
- int height,
- int depth)
+_cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
+ Drawable drawable,
+ Visual *visual,
+ XRenderPictFormat *xrender_format,
+ int width,
+ int height,
+ int depth)
{
cairo_xlib_surface_t *surface;
- cairo_xlib_display_t *display;
- cairo_xlib_screen_info_t *screen_info;
- cairo_status_t status;
CAIRO_MUTEX_INITIALIZE ();
@@ -2891,14 +2884,15 @@ _cairo_xlib_surface_create_internal (Display *dpy,
/* XXX find matching visual for core/dithering fallbacks? */
} else if (visual) {
+ Screen *scr = screen->screen;
int j, k;
/* This is ugly, but we have to walk over all visuals
* for the display to find the correct depth.
*/
depth = 0;
- for (j = 0; j < screen->ndepths; j++) {
- Depth *d = &screen->depths[j];
+ for (j = 0; j < scr->ndepths; j++) {
+ Depth *d = &scr->depths[j];
for (k = 0; k < d->nvisuals; k++) {
if (&d->visuals[k] == visual) {
depth = d->depth;
@@ -2913,36 +2907,27 @@ _cairo_xlib_surface_create_internal (Display *dpy,
if (depth == 0)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
- status = _cairo_xlib_display_get (dpy, &display);
- if (unlikely (status))
- return _cairo_surface_create_in_error (status);
-
- status = _cairo_xlib_screen_info_get (display, screen, &screen_info);
- if (unlikely (status)) {
- _cairo_xlib_display_destroy (display);
- return _cairo_surface_create_in_error (status);
- }
-
surface = malloc (sizeof (cairo_xlib_surface_t));
- if (unlikely (surface == NULL)) {
- _cairo_xlib_screen_info_destroy (screen_info);
- _cairo_xlib_display_destroy (display);
+ if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
- }
+
+ surface->dpy = _cairo_xlib_display_get_dpy (screen->display);
/* initialize and hook into the CloseDisplay callback */
surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
- _cairo_xlib_add_close_display_hook (display, &surface->close_display_hook);
+ _cairo_xlib_add_close_display_hook (screen->display,
+ &surface->close_display_hook);
- surface->render_major = display->render_major;
- surface->render_minor = display->render_minor;
+ _cairo_xlib_display_get_xrender_version (screen->display,
+ &surface->render_major,
+ &surface->render_minor);
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {
if (!xrender_format) {
if (visual) {
- xrender_format = XRenderFindVisualFormat (dpy, visual);
+ xrender_format = XRenderFindVisualFormat (surface->dpy, visual);
} else if (depth == 1) {
xrender_format =
- _cairo_xlib_display_get_xrender_format (display,
+ _cairo_xlib_display_get_xrender_format (screen->display,
CAIRO_FORMAT_A1);
}
}
@@ -2959,29 +2944,27 @@ _cairo_xlib_surface_create_internal (Display *dpy,
_cairo_surface_init (&surface->base, &cairo_xlib_surface_backend,
_xrender_format_to_content (xrender_format));
- surface->dpy = dpy;
- surface->display = display;
- surface->screen_info = screen_info;
+ surface->screen = _cairo_xlib_screen_reference (screen);
+ surface->display = screen->display;
surface->gc = NULL;
surface->drawable = drawable;
- surface->screen = screen;
surface->owns_pixmap = FALSE;
surface->use_pixmap = 0;
surface->width = width;
surface->height = height;
- surface->buggy_repeat = screen_info->display->buggy_repeat;
+ surface->buggy_repeat = ! _cairo_xlib_display_has_repeat (surface->display);
if (! CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) {
/* so we can use the XTile fallback */
surface->buggy_repeat = TRUE;
}
- surface->buggy_pad_reflect = screen_info->display->buggy_pad_reflect;
+ surface->buggy_pad_reflect = ! _cairo_xlib_display_has_reflect (surface->display);
if (! CAIRO_SURFACE_RENDER_HAS_EXTENDED_REPEAT (surface))
surface->buggy_pad_reflect = TRUE;
- surface->buggy_gradients = screen_info->display->buggy_gradients;
+ surface->buggy_gradients = ! _cairo_xlib_display_has_gradients (surface->display);
if (! CAIRO_SURFACE_RENDER_HAS_GRADIENTS (surface))
surface->buggy_gradients = TRUE;
@@ -3095,13 +3078,25 @@ cairo_xlib_surface_create (Display *dpy,
int width,
int height)
{
- Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
+ Screen *scr;
+ cairo_xlib_screen_t *screen;
+ cairo_surface_t *surface;
+ cairo_status_t status;
- if (screen == NULL)
+ scr = _cairo_xlib_screen_from_visual (dpy, visual);
+ if (scr == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
- return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
- visual, NULL, width, height, 0);
+ status = _cairo_xlib_screen_get (dpy, scr, &screen);
+ if (unlikely (status))
+ return _cairo_surface_create_in_error (status);
+
+ surface = _cairo_xlib_surface_create_internal (screen, drawable,
+ visual, NULL,
+ width, height, 0);
+ _cairo_xlib_screen_destroy (screen);
+
+ return surface;
}
slim_hidden_def (cairo_xlib_surface_create);
@@ -3121,12 +3116,24 @@ slim_hidden_def (cairo_xlib_surface_create);
cairo_surface_t *
cairo_xlib_surface_create_for_bitmap (Display *dpy,
Pixmap bitmap,
- Screen *screen,
+ Screen *scr,
int width,
int height)
{
- return _cairo_xlib_surface_create_internal (dpy, bitmap, screen,
- NULL, NULL, width, height, 1);
+ cairo_xlib_screen_t *screen;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ status = _cairo_xlib_screen_get (dpy, scr, &screen);
+ if (unlikely (status))
+ return _cairo_surface_create_in_error (status);
+
+ surface = _cairo_xlib_surface_create_internal (screen, bitmap,
+ NULL, NULL,
+ width, height, 1);
+ _cairo_xlib_screen_destroy (screen);
+
+ return surface;
}
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
@@ -3153,13 +3160,25 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy,
cairo_surface_t *
cairo_xlib_surface_create_with_xrender_format (Display *dpy,
Drawable drawable,
- Screen *screen,
+ Screen *scr,
XRenderPictFormat *format,
int width,
int height)
{
- return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
- NULL, format, width, height, 0);
+ cairo_xlib_screen_t *screen;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ status = _cairo_xlib_screen_get (dpy, scr, &screen);
+ if (unlikely (status))
+ return _cairo_surface_create_in_error (status);
+
+ surface = _cairo_xlib_surface_create_internal (screen, drawable,
+ NULL, format,
+ width, height, 0);
+ _cairo_xlib_screen_destroy (screen);
+
+ return surface;
}
slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
@@ -3358,7 +3377,7 @@ cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
return NULL;
}
- return surface->screen;
+ return surface->screen->screen;
}
/**
@@ -3504,7 +3523,7 @@ _cairo_xlib_surface_remove_scaled_font (cairo_xlib_display_t *display,
Display *dpy;
int i;
- dpy = display->display;
+ dpy = _cairo_xlib_display_get_dpy (display);
for (i = 0; i < NUM_GLYPHSETS; i++) {
cairo_xlib_font_glyphset_info_t *glyphset_info;
@@ -3706,8 +3725,8 @@ _cairo_xlib_scaled_font_get_glyphset_info_for_format (cairo_scaled_font_t *scale
glyphset_info->xrender_format =
_cairo_xlib_display_get_xrender_format (display,
glyphset_info->format);
- glyphset_info->glyphset = XRenderCreateGlyphSet (display->display,
- glyphset_info->xrender_format);
+ glyphset_info->glyphset = XRenderCreateGlyphSet (_cairo_xlib_display_get_dpy (display),
+ glyphset_info->xrender_format);
}
return glyphset_info;