diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-27 17:52:11 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-27 17:53:30 +0100 |
commit | dd0866cdc878a0be438a117051ccc64f12f81970 (patch) | |
tree | 67300bea21b93db50aa15691a74a38e4fdccd742 | |
parent | 2dc42af9422a15f902934a53c074e4194991a9e4 (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.c | 107 |
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. */ { |