From a0c1c8c1c85aee0810c42b8721e3aad0fc95032a Mon Sep 17 00:00:00 2001 From: Thiago Melo Date: Thu, 25 May 2023 19:15:39 +0200 Subject: [PATCH] Fix Bug#63589. --- src/xterm.c | 37 +++++++++++++++++++++++++++++++++++++ src/xterm.h | 6 ++++++ 2 files changed, 43 insertions(+) diff --git a/src/xterm.c b/src/xterm.c index e981a36..d35b35c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5806,10 +5806,15 @@ x_begin_cr_clip (struct frame *f, GC gc) cairo_surface_t *surface; #ifdef USE_CAIRO_XCB_SURFACE if (FRAME_DISPLAY_INFO (f)->xcb_visual) + { surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection, (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f), FRAME_DISPLAY_INFO (f)->xcb_visual, width, height); + if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) + eassert (FRAME_DISPLAY_INFO (f)->cairo_device + == cairo_surface_get_device (surface)); + } else #endif surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), @@ -30504,6 +30509,27 @@ #define NUM_ARGV 10 unblock_input (); +#ifdef USE_CAIRO_XCB_SURFACE + /* Store reference to the cairo device for this display, to ensure + that it is destroyed before closing connection (Bug#63589). + For that, we create a drawable, an XCB surface for that drawable, + and then we get the device reference from there. */ + Pixmap drawable; + cairo_surface_t *surface; + + drawable = XCreatePixmap (dpyinfo->display, dpyinfo->root_window, + 1, 1, dpyinfo->n_planes); + surface = cairo_xcb_surface_create (dpyinfo->xcb_connection, drawable, + dpyinfo->xcb_visual, 1, 1); + + if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) + { + dpyinfo->cairo_device = cairo_device_reference (cairo_surface_get_device (surface)); + cairo_surface_destroy (surface); + } + XFreePixmap (dpyinfo->display, drawable); +#endif + #if defined HAVE_XFIXES && defined USE_XCB SAFE_FREE (); #endif @@ -30783,6 +30809,17 @@ x_delete_terminal (struct terminal *terminal) xim_close_dpy (dpyinfo); #endif +#ifdef USE_CAIRO_XCB_SURFACE + /* Ensure that the cairo device is destroyed before closing + connection (Bug#63589). */ + if (dpyinfo->cairo_device) + { + cairo_device_finish (dpyinfo->cairo_device); + cairo_device_destroy (dpyinfo->cairo_device); + dpyinfo->cairo_device = NULL; + } +#endif + /* Normally, the display is available... */ if (dpyinfo->display) { diff --git a/src/xterm.h b/src/xterm.h index 8834346..4793908 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -884,6 +884,12 @@ #define X_INVALID_WINDOW 0xffffffff server_time_monotonic_p will be true). */ int_fast64_t server_time_offset; #endif +#if defined USE_XCB && defined USE_CAIRO_XCB + /* Cairo device associated with cairo surfaces in this display. + Required for proper cleanup before closing display connection + in cairo-xcb builds. */ + cairo_device_t *cairo_device; +#endif }; #ifdef HAVE_X_I18N -- 2.39.2