diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-07-04 21:43:27 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-07-04 21:43:27 +0100 |
commit | 88cb69b10c66751f687c3745c8e9861b105de3a2 (patch) | |
tree | 3887fc1f4f4cf61b9111b62f6e85af0b72534782 /boilerplate/cairo-boilerplate-xlib.c | |
parent | 8a10ab1c04298d6c22ae8aabec5d762141a8e98f (diff) | |
download | cairo-88cb69b10c66751f687c3745c8e9861b105de3a2.tar.gz |
[boilerpate] Move target definition to backends.
By moving the backend target definition out of the massive amlagamated
block in cairo-boilerplate.c and into each of the
cairo-boilerplate-backend.c, we make it much easier to add new targets as
the information need only be entered in a single file and not scattered
across three. However, updating the target interface means trawling across
all the files -- except given that I found it difficult maintaining the
single massive array I do not see this as an increase in the maintenance
burden.
Diffstat (limited to 'boilerplate/cairo-boilerplate-xlib.c')
-rw-r--r-- | boilerplate/cairo-boilerplate-xlib.c | 207 |
1 files changed, 129 insertions, 78 deletions
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c index f40f92713..3c996cd2e 100644 --- a/boilerplate/cairo-boilerplate-xlib.c +++ b/boilerplate/cairo-boilerplate-xlib.c @@ -24,9 +24,8 @@ * Author: Carl D. Worth <cworth@cworth.org> */ -#include "cairo-boilerplate.h" +#include "cairo-boilerplate-private.h" #include "cairo-boilerplate-xlib.h" -#include "cairo-boilerplate-xlib-private.h" #include <cairo-xlib.h> #if CAIRO_HAS_XLIB_XRENDER_SURFACE @@ -36,14 +35,28 @@ #include <X11/Xutil.h> /* for XDestroyImage */ -typedef struct _xlib_target_closure -{ +typedef struct _xlib_target_closure { Display *dpy; Drawable drawable; cairo_bool_t drawable_is_pixmap; } xlib_target_closure_t; -void +static void +_cairo_boilerplate_xlib_cleanup (void *closure) +{ + xlib_target_closure_t *xtc = closure; + + if (xtc->drawable) { + if (xtc->drawable_is_pixmap) + XFreePixmap (xtc->dpy, xtc->drawable); + else + XDestroyWindow (xtc->dpy, xtc->drawable); + } + XCloseDisplay (xtc->dpy); + free (xtc); +} + +static void _cairo_boilerplate_xlib_synchronize (void *closure) { xlib_target_closure_t *xtc = closure; @@ -185,7 +198,7 @@ _cairo_boilerplate_xlib_perf_create_surface (Display *dpy, width, height); } -cairo_surface_t * +static cairo_surface_t * _cairo_boilerplate_xlib_create_surface (const char *name, cairo_content_t content, double width, @@ -228,60 +241,24 @@ _cairo_boilerplate_xlib_create_surface (const char *name, return surface; } -cairo_surface_t * -_cairo_boilerplate_xlib_reference_create_surface (const char *name, - cairo_content_t content, - double width, - double height, - double max_width, - double max_height, - cairo_boilerplate_mode_t mode, - int id, - void **closure) +cairo_status_t +cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface) { - xlib_target_closure_t *xtc; - Display *dpy; - cairo_surface_t *surface; - const char *display; - - display = getenv ("CAIRO_REFERENCE_DISPLAY"); - if (display == NULL) { - return _cairo_boilerplate_xlib_fallback_create_surface (name, content, - width, height, - max_width, - max_height, - mode, id, - closure); - } - - *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t)); - - width = ceil (width); - if (width < 1) - width = 1; - - height = ceil (height); - if (height < 1) - height = 1; + cairo_xlib_surface_t *surface = (cairo_xlib_surface_t*) abstract_surface; - xtc->dpy = dpy = XOpenDisplay (display); - if (xtc->dpy == NULL) { - free (xtc); - CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", display)); - return NULL; - } + if (cairo_surface_get_type (abstract_surface) != CAIRO_SURFACE_TYPE_XLIB) + return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; - if (mode == CAIRO_BOILERPLATE_MODE_TEST) - surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc); - else /* mode == CAIRO_BOILERPLATE_MODE_PERF */ - surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc); + surface->render_major = surface->render_minor = -1; + surface->xrender_format = NULL; - if (surface == NULL || cairo_surface_status (surface)) - _cairo_boilerplate_xlib_cleanup (xtc); + /* The content type is forced by _xrender_format_to_content() during + * non-Render surface creation, so repeat the procedure here. */ + surface->base.content = CAIRO_CONTENT_COLOR; - return surface; + return CAIRO_STATUS_SUCCESS; } -#endif + /* The xlib-fallback target differs from the xlib target in two ways: * @@ -292,7 +269,7 @@ _cairo_boilerplate_xlib_reference_create_surface (const char *name, * This provides testing of the non-Render fallback paths we have in * cairo-xlib-surface.c */ -cairo_surface_t * +static cairo_surface_t * _cairo_boilerplate_xlib_fallback_create_surface (const char *name, cairo_content_t content, double width, @@ -389,35 +366,109 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, return surface; } -void -_cairo_boilerplate_xlib_cleanup (void *closure) +static cairo_surface_t * +_cairo_boilerplate_xlib_reference_create_surface (const char *name, + cairo_content_t content, + double width, + double height, + double max_width, + double max_height, + cairo_boilerplate_mode_t mode, + int id, + void **closure) { - xlib_target_closure_t *xtc = closure; + xlib_target_closure_t *xtc; + Display *dpy; + cairo_surface_t *surface; + const char *display; - if (xtc->drawable) { - if (xtc->drawable_is_pixmap) - XFreePixmap (xtc->dpy, xtc->drawable); - else - XDestroyWindow (xtc->dpy, xtc->drawable); + display = getenv ("CAIRO_REFERENCE_DISPLAY"); + if (display == NULL) { + return _cairo_boilerplate_xlib_fallback_create_surface (name, content, + width, height, + max_width, + max_height, + mode, id, + closure); } - XCloseDisplay (xtc->dpy); - free (xtc); -} -cairo_status_t -cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t*) abstract_surface; + *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t)); - if (cairo_surface_get_type (abstract_surface) != CAIRO_SURFACE_TYPE_XLIB) - return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; + width = ceil (width); + if (width < 1) + width = 1; - surface->render_major = surface->render_minor = -1; - surface->xrender_format = NULL; + height = ceil (height); + if (height < 1) + height = 1; - /* The content type is forced by _xrender_format_to_content() during - * non-Render surface creation, so repeat the procedure here. */ - surface->base.content = CAIRO_CONTENT_COLOR; + xtc->dpy = dpy = XOpenDisplay (display); + if (xtc->dpy == NULL) { + free (xtc); + CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", display)); + return NULL; + } - return CAIRO_STATUS_SUCCESS; + if (mode == CAIRO_BOILERPLATE_MODE_TEST) + surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc); + else /* mode == CAIRO_BOILERPLATE_MODE_PERF */ + surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc); + + if (surface == NULL || cairo_surface_status (surface)) + _cairo_boilerplate_xlib_cleanup (xtc); + + return surface; } +#endif + +static const cairo_boilerplate_target_t targets[] = { +#if CAIRO_HAS_XLIB_XRENDER_SURFACE + /* Acceleration architectures may make the results differ by a + * bit, so we set the error tolerance to 1. */ + { + "xlib", "xlib", NULL, "xlib-reference", + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1, + _cairo_boilerplate_xlib_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, + { + "xlib", "xlib", NULL, "xlib-reference", + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, + _cairo_boilerplate_xlib_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, + { + "xlib-reference", "xlib", NULL, NULL, + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, + _cairo_boilerplate_xlib_reference_create_surface, + NULL, NULL, + NULL, /* get_image */ + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, +#endif +#if CAIRO_HAS_XLIB_SURFACE + /* This is a fallback surface which uses xlib fallbacks instead of + * the Render extension. */ + { + "xlib-fallback", "xlib", NULL, NULL, + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, + _cairo_boilerplate_xlib_fallback_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, +#endif +}; +CAIRO_BOILERPLATE (xlib, targets) |