diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c index 8a1ec7b..6478a89 100644 --- a/src/cairo-xlib-render-compositor.c +++ b/src/cairo-xlib-render-compositor.c @@ -55,6 +55,16 @@ #include "cairo-traps-private.h" #include "cairo-tristrip-private.h" +typedef int (*cairo_xlib_error_func_t) (Display *display, + XErrorEvent *event); + +static int +_noop_error_handler (Display *display, + XErrorEvent *event) +{ + return False; /* return value is ignored */ +} + static cairo_int_status_t check_composite (const cairo_composite_rectangles_t *extents) { @@ -395,6 +405,7 @@ copy_boxes (void *_dst, GC gc; Drawable d; int i, j; + cairo_xlib_error_func_t old_handler; if (! _cairo_xlib_surface_same_screen (dst, src)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -431,10 +442,12 @@ copy_boxes (void *_dst, int y1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.y); int x2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.x); int y2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.y); + old_handler = XSetErrorHandler (_noop_error_handler); XCopyArea (dst->dpy, d, dst->drawable, gc, x1 + dx, y1 + dy, x2 - x1, y2 - y1, x1, y1); + XSetErrorHandler (old_handler); } else { /* We can only have a single control for subwindow_mode on the * GC. If we have a Window destination, we need to set ClipByChildren, @@ -453,10 +465,12 @@ copy_boxes (void *_dst, int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); + old_handler = XSetErrorHandler (_noop_error_handler); XCopyArea (dst->dpy, d, dst->drawable, gc, x1 + dx, y1 + dy, x2 - x1, y2 - y1, x1, y1); + XSetErrorHandler (old_handler); } } } else { @@ -488,10 +502,12 @@ copy_boxes (void *_dst, XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted); + old_handler = XSetErrorHandler (_noop_error_handler); XCopyArea (dst->dpy, d, dst->drawable, gc, extents->x + dx, extents->y + dy, extents->width, extents->height, extents->x, extents->y); + XSetErrorHandler (old_handler); XSetClipMask (dst->dpy, gc, None); diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index 57beeaa..68506be 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -65,6 +65,16 @@ #include "cairo-fontconfig-private.h" +typedef int (*cairo_xlib_error_func_t) (Display *display, + XErrorEvent *event); + +static int +_noop_error_handler (Display *display, + XErrorEvent *event) +{ + return False; /* return value is ignored */ +} + static int parse_boolean (const char *v) { @@ -375,12 +385,15 @@ _cairo_xlib_screen_get_gc (cairo_xlib_display_t *display, if (gc == NULL) { XGCValues gcv; + cairo_xlib_error_func_t old_handler; gcv.graphics_exposures = False; gcv.fill_style = FillTiled; + old_handler = XSetErrorHandler (_noop_error_handler); gc = XCreateGC (display->display, drawable, GCGraphicsExposures | GCFillStyle, &gcv); + XSetErrorHandler (old_handler); } return gc; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 029a542..f545021 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -840,13 +840,15 @@ _get_image_surface (cairo_xlib_surface_t *surface, * retry, but to keep things simple, we just create a * temporary pixmap */ + cairo_xlib_error_func_t old_handler; Pixmap pixmap; GC gc; status = _cairo_xlib_surface_get_gc (display, surface, &gc); if (unlikely (status)) - goto BAIL; + goto BAIL2; + old_handler = XSetErrorHandler (_noop_error_handler); pixmap = XCreatePixmap (display->display, surface->drawable, extents->width, extents->height, @@ -873,12 +875,13 @@ _get_image_surface (cairo_xlib_surface_t *surface, XFreePixmap (display->display, pixmap); } + XSetErrorHandler (old_handler); _cairo_xlib_surface_put_gc (display, surface, gc); if (ximage == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; + goto BAIL2; } } @@ -1005,15 +1008,17 @@ _get_image_surface (cairo_xlib_surface_t *surface, } BAIL: + if (unlikely (status)) + cairo_surface_destroy (&image->base); + + BAIL2: if (ximage) XDestroyImage (ximage); cairo_device_release (&display->base); - if (unlikely (status)) { - cairo_surface_destroy (&image->base); + if (unlikely (status)) return _cairo_surface_create_in_error (status); - } return &image->base; }