summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-27 17:52:11 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-27 17:53:30 +0100
commitdd0866cdc878a0be438a117051ccc64f12f81970 (patch)
tree67300bea21b93db50aa15691a74a38e4fdccd742
parent2dc42af9422a15f902934a53c074e4194991a9e4 (diff)
boilerplate: Exercise RENDER capable windows.
Ensure that the drivers actually work when rendering to a normal window.
-rw-r--r--boilerplate/cairo-boilerplate-xlib.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index 83280e99..17de2ad8 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -241,6 +241,101 @@ _cairo_boilerplate_xlib_create_surface (const char *name,
return surface;
}
+static cairo_surface_t *
+_cairo_boilerplate_xlib_window_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;
+ Display *dpy;
+ Screen *scr;
+ int screen, x, y;
+ XSetWindowAttributes attr;
+ cairo_surface_t *surface;
+
+ /* We're not yet bothering to support perf mode for the
+ * xlib-fallback surface. */
+ if (mode == CAIRO_BOILERPLATE_MODE_PERF)
+ return NULL;
+
+ /* We also don't support drawing with destination-alpha in the
+ * xlib-fallback surface. */
+ if (content == CAIRO_CONTENT_COLOR_ALPHA)
+ return NULL;
+
+ *closure = xtc = xmalloc (sizeof (xlib_target_closure_t));
+
+ width = ceil (width);
+ if (width < 1)
+ width = 1;
+
+ height = ceil (height);
+ if (height < 1)
+ height = 1;
+
+ xtc->dpy = dpy = XOpenDisplay (NULL);
+ if (xtc->dpy == NULL) {
+ CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", XDisplayName(0)));
+ free (xtc);
+ return NULL;
+ }
+
+ /* This kills performance, but it makes debugging much
+ * easier. That's why we have it here only after explicitly not
+ * supporting PERF mode.*/
+ XSynchronize (dpy, 1);
+
+ screen = DefaultScreen (dpy);
+ if (! _cairo_boilerplate_xlib_check_screen_size (dpy, screen,
+ width, height)) {
+ CAIRO_BOILERPLATE_DEBUG (("Surface is larger than the Screen.\n"));
+ XCloseDisplay (dpy);
+ free (xtc);
+ return NULL;
+ }
+
+ /* tile the windows so threads do not overlap */
+ scr = XScreenOfDisplay (dpy, screen);
+ x = y = 0;
+ if (id-- > 1) do {
+ x += max_width;
+ if (x + max_width > WidthOfScreen (scr)) {
+ x = 0;
+ y += max_height;
+ if (y + max_height > HeightOfScreen (scr)) {
+ XCloseDisplay (dpy);
+ free (xtc);
+ return NULL;
+ }
+ }
+ } while (--id);
+
+ attr.override_redirect = True;
+ xtc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy),
+ x, y,
+ width, height, 0,
+ DefaultDepth (dpy, screen),
+ InputOutput,
+ DefaultVisual (dpy, screen),
+ CWOverrideRedirect, &attr);
+ XMapWindow (dpy, xtc->drawable);
+ xtc->drawable_is_pixmap = FALSE;
+
+ surface = cairo_xlib_surface_create (dpy, xtc->drawable,
+ DefaultVisual (dpy, screen),
+ width, height);
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_xlib_cleanup (xtc);
+
+ return surface;
+}
+
cairo_status_t
cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface)
{
@@ -416,6 +511,18 @@ static const cairo_boilerplate_target_t targets[] = {
},
#endif
#if CAIRO_HAS_XLIB_SURFACE
+ {
+ "xlib-window", "xlib", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xlib_surface_create",
+ _cairo_boilerplate_xlib_window_create_surface,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xlib_cleanup,
+ _cairo_boilerplate_xlib_synchronize,
+ FALSE, FALSE, FALSE
+ },
/* This is a fallback surface which uses xlib fallbacks instead of
* the Render extension. */
{