add support for 'recursive' xlib surfaces (ala IncludeInferiors) --- commit 653f9a101eea6a37bd2c17d17f634c8bfb546c55 tree c5b4c2425aa3bb076bcc75ded098d67ece148ddb parent 5aaf584bf44d762af5e486f21a037eb0cc6e1197 author Ryan Lortie Sat, 17 Mar 2007 22:51:56 -0400 committer Ryan Lortie Sat, 17 Mar 2007 22:51:56 -0400 src/cairo-xlib-surface.c | 101 +++++++++++++++++++++++++++++++++++++++++++++- src/cairo-xlib.h | 7 +++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 49bdaae..9960923 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -121,6 +121,7 @@ struct _cairo_xlib_surface { int depth; Picture dst_picture, src_picture; + int recursive; cairo_bool_t have_clip_rects; XRectangle *clip_rects; @@ -689,10 +690,21 @@ static void _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface) { if (!surface->src_picture) + { + XRenderPictureAttributes pa; + int mask = 0; + + if (surface->recursive) + { + pa.subwindow_mode = IncludeInferiors; + mask |= CPSubwindowMode; + } + surface->src_picture = XRenderCreatePicture (surface->dpy, surface->drawable, surface->xrender_format, - 0, NULL); + mask, &pa); + } } static void @@ -719,10 +731,19 @@ static void _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface) { if (!surface->dst_picture) { + XRenderPictureAttributes pa; + int mask = 0; + + if (surface->recursive) + { + pa.subwindow_mode = IncludeInferiors; + mask |= CPSubwindowMode; + } + surface->dst_picture = XRenderCreatePicture (surface->dpy, surface->drawable, surface->xrender_format, - 0, NULL); + mask, &pa); _cairo_xlib_surface_set_picture_clip_rects (surface); } @@ -2053,6 +2074,7 @@ cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface, surface->width = width; surface->height = height; } + /** * cairo_xlib_surface_set_drawable: * @surface: a #cairo_surface_t for the XLib backend @@ -2101,6 +2123,57 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, } /** + * cairo_xlib_surface_set_recursive: + * @surface: a #cairo_surface_t for the XLib backend + * @recursive: if child windows should be included in draw ops + * + * Sets the surface as recursive or not. + * + * For destinations of draws this means that child windows + * that would normally clip the draw are simply drawn over + * top of. + * + * For sources of draws this means that child windows that + * would normally clip the content of the parent window have + * their image data include as part of that content. + * + * This flag corresponds to the XRender IncludeInferiors + * attribute. + * + * Since: 1.4 + **/ +void +cairo_xlib_surface_set_recursive (cairo_surface_t *abstract_surface, + int recursive) +{ + cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface; + + if (! _cairo_surface_is_xlib (abstract_surface)) { + _cairo_surface_set_error (abstract_surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); + return; + } + + /* XXX: and what about this case? */ + if (surface->owns_pixmap) + return; + + recursive = recursive != 0; + + if (surface->recursive != recursive) { + if (surface->dst_picture) + XRenderFreePicture (surface->dpy, surface->dst_picture); + + if (surface->src_picture) + XRenderFreePicture (surface->dpy, surface->src_picture); + + surface->dst_picture = None; + surface->src_picture = None; + + surface->recursive = recursive; + } +} + +/** * cairo_xlib_surface_get_display: * @surface: a #cairo_xlib_surface_t * @@ -2147,6 +2220,30 @@ cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface) } /** + * cairo_xlib_surface_get_recursive: + * @surface: a #cairo_xlib_surface_t + * + * Returns if the surface is "recursive" or not. See + * cairo_xlib_surface_set_recursive(). + * + * Return value: 1 if the surface is recursive. + * + * Since: 1.4 + **/ +int +cairo_xlib_surface_get_recursive (cairo_surface_t *abstract_surface) +{ + cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; + + if (! _cairo_surface_is_xlib (abstract_surface)) { + _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); + return 0; + } + + return surface->recursive; +} + +/** * cairo_xlib_surface_get_screen: * @surface: a #cairo_xlib_surface_t * diff --git a/src/cairo-xlib.h b/src/cairo-xlib.h index ad92b39..b240947 100644 --- a/src/cairo-xlib.h +++ b/src/cairo-xlib.h @@ -70,12 +70,19 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *surface, int width, int height); +cairo_public void +cairo_xlib_surface_set_recursive (cairo_surface_t *surface, + int recursive); + cairo_public Display * cairo_xlib_surface_get_display (cairo_surface_t *surface); cairo_public Drawable cairo_xlib_surface_get_drawable (cairo_surface_t *surface); +cairo_public int +cairo_xlib_surface_get_recursive (cairo_surface_t *surface); + cairo_public Screen * cairo_xlib_surface_get_screen (cairo_surface_t *surface);