From 11204e7a4442a426dd82c5ba0b0994f20e7e7d57 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 28 Sep 2018 18:38:33 +0200 Subject: [PATCH 01/12] Port usage of XCompositeNameWindowPixmap to xcb Signed-off-by: Uli Schlachter --- Makefile | 2 +- src/common.h | 5 +++-- src/compton.c | 3 ++- src/xrescheck.h | 10 +++++----- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 57475e1..9a09c3c 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ MANDIR ?= $(PREFIX)/share/man/man1 APPDIR ?= $(PREFIX)/share/applications ICODIR ?= $(PREFIX)/share/icons/hicolor/ -PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-image xcomposite xfixes xext +PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-image xcomposite xfixes xext LIBS = -lm -lrt INCS = diff --git a/src/common.h b/src/common.h index d2496a0..d0266ba 100644 --- a/src/common.h +++ b/src/common.h @@ -82,7 +82,7 @@ #include #include #include -#include +#include /* FIXME remove this once done porting to xcb-composite */ #include #include #ifdef CONFIG_XSYNC @@ -93,6 +93,7 @@ #include #endif +#include #include #include #include @@ -596,7 +597,7 @@ typedef struct _options_t { Window benchmark_wid; /// A list of conditions of windows not to paint. c2_lptr_t *paint_blacklist; - /// Whether to avoid using XCompositeNameWindowPixmap(), for debugging. + /// Whether to avoid using xcb_composite_name_window_pixmap(), for debugging. bool no_name_pixmap; /// Whether to work under synchronized mode for debugging. bool synchronize; diff --git a/src/compton.c b/src/compton.c index 04eab3e..56069a2 100644 --- a/src/compton.c +++ b/src/compton.c @@ -1446,7 +1446,8 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint, // Fetch Pixmap if (!w->paint.pixmap && ps->has_name_pixmap) { set_ignore_next(ps); - w->paint.pixmap = XCompositeNameWindowPixmap(ps->dpy, w->id); + w->paint.pixmap = xcb_generate_id(c); + xcb_composite_name_window_pixmap(c, w->id, w->paint.pixmap); if (w->paint.pixmap) free_fence(ps, &w->fence); } diff --git a/src/xrescheck.h b/src/xrescheck.h index 48f254b..67aea3f 100644 --- a/src/xrescheck.h +++ b/src/xrescheck.h @@ -48,16 +48,16 @@ XCreatePixmap_(Display *dpy, Drawable drawable, #define XCreatePixmap(dpy, drawable, width, height, depth) \ XCreatePixmap_(dpy, drawable, width, height, depth, M_POS_DATA) -static inline Pixmap -XCompositeNameWindowPixmap_(Display *dpy, Window window, M_POS_DATA_PARAMS) { - Pixmap ret = XCompositeNameWindowPixmap(dpy, window); +static inline xcb_pixmap_t +xcb_composite_name_window_pixmap_(xcb_connection_t *c, xcb_window_t window, xcb_pixmap_t pixmap, M_POS_DATA_PARAMS) { + xcb_pixmap_t ret = xcb_composite_name_window_pixmap(c, window, pixmap); if (ret) xrc_add_xid_(ret, "PixmapC", M_POS_DATA_PASSTHROUGH); return ret; } -#define XCompositeNameWindowPixmap(dpy, window) \ - XCompositeNameWindowPixmap_(dpy, window, M_POS_DATA) +#define xcb_composite_name_window_pixmap(dpy, window, pixmap) \ + xcb_composite_name_window_pixmap_(dpy, window, pixmap, M_POS_DATA) static inline void XFreePixmap_(Display *dpy, Pixmap pixmap, M_POS_DATA_PARAMS) { From 79089b0652cdf234c62535650751d58be37c40b4 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 28 Sep 2018 18:41:24 +0200 Subject: [PATCH 02/12] Port XCompositeUnredirect{Subw,W}indows to xcb Signed-off-by: Uli Schlachter --- src/compton.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compton.c b/src/compton.c index 56069a2..52f0c1d 100644 --- a/src/compton.c +++ b/src/compton.c @@ -3680,6 +3680,7 @@ static bool register_cm(session_t *ps) { assert(!ps->reg_win); + xcb_connection_t *c = XGetXCBConnection(ps->dpy); ps->reg_win = XCreateSimpleWindow(ps->dpy, ps->root, 0, 0, 1, 1, 0, None, None); @@ -3690,7 +3691,7 @@ register_cm(session_t *ps) { // Unredirect the window if it's redirected, just in case if (ps->redirected) - XCompositeUnredirectWindow(ps->dpy, ps->reg_win, CompositeRedirectManual); + xcb_composite_unredirect_window(c, ps->reg_win, CompositeRedirectManual); { XClassHint *h = XAllocClassHint(); @@ -4788,9 +4789,9 @@ redir_start(session_t *ps) { /* // Unredirect GL context window as this may have an effect on VSync: // < http://dri.freedesktop.org/wiki/CompositeSwap > - XCompositeUnredirectWindow(ps->dpy, ps->reg_win, CompositeRedirectManual); + xcb_composite_unredirect_window(c, ps->reg_win, CompositeRedirectManual); if (ps->o.paint_on_overlay && ps->overlay) { - XCompositeUnredirectWindow(ps->dpy, ps->overlay, + xcb_composite_unredirect_window(c, ps->overlay, CompositeRedirectManual); } */ @@ -4954,6 +4955,7 @@ timeout_reset(session_t *ps, timeout_t *ptmout) { static void redir_stop(session_t *ps) { if (ps->redirected) { + xcb_connection_t *c = XGetXCBConnection(ps->dpy); #ifdef DEBUG_REDIR print_timestamp(ps); printf_dbgf("(): Screen unredirected.\n"); @@ -4964,7 +4966,7 @@ redir_stop(session_t *ps) { for (win *w = ps->list; w; w = w->next) free_wpaint(ps, w); - XCompositeUnredirectSubwindows(ps->dpy, ps->root, CompositeRedirectManual); + xcb_composite_unredirect_subwindows(c, ps->root, CompositeRedirectManual); // Unmap overlay window if (ps->overlay) XUnmapWindow(ps->dpy, ps->overlay); From 8064eaaa3785eebad1c20746e8cf010d557fff4a Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 28 Sep 2018 18:44:51 +0200 Subject: [PATCH 03/12] Replace more usage of XComposite with xcb Signed-off-by: Uli Schlachter --- src/compton.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/compton.c b/src/compton.c index 52f0c1d..98e92f3 100644 --- a/src/compton.c +++ b/src/compton.c @@ -4690,7 +4690,16 @@ init_dbe(session_t *ps) { */ static bool init_overlay(session_t *ps) { - ps->overlay = XCompositeGetOverlayWindow(ps->dpy, ps->root); + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + xcb_composite_get_overlay_window_reply_t *reply = + xcb_composite_get_overlay_window_reply(c, + xcb_composite_get_overlay_window(c, ps->root), NULL); + if (reply) { + ps->overlay = reply->overlay_win; + free(reply); + } else { + ps->overlay = XCB_NONE; + } if (ps->overlay) { // Set window region of the overlay window, code stolen from // compiz-0.8.8 @@ -4779,12 +4788,14 @@ redir_start(session_t *ps) { printf_dbgf("(): Screen redirected.\n"); #endif + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + // Map overlay window. Done firstly according to this: // https://bugzilla.gnome.org/show_bug.cgi?id=597014 if (ps->overlay) XMapWindow(ps->dpy, ps->overlay); - XCompositeRedirectSubwindows(ps->dpy, ps->root, CompositeRedirectManual); + xcb_composite_redirect_subwindows(c, ps->root, CompositeRedirectManual); /* // Unredirect GL context window as this may have an effect on VSync: @@ -5650,6 +5661,7 @@ session_init(session_t *ps_old, int argc, char **argv) { */ static void session_destroy(session_t *ps) { + xcb_connection_t *c = XGetXCBConnection(ps->dpy); redir_stop(ps); // Stop listening to events on root window @@ -5793,7 +5805,7 @@ session_destroy(session_t *ps) { // Release overlay window if (ps->overlay) { - XCompositeReleaseOverlayWindow(ps->dpy, ps->overlay); + xcb_composite_release_overlay_window(c, ps->overlay); ps->overlay = None; } From 2f49f6f03dc906ba3fd2f435a0e211977381ac70 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 28 Sep 2018 19:13:53 +0200 Subject: [PATCH 04/12] Switch XComposite initialisation to XCB Signed-off-by: Uli Schlachter --- Makefile | 2 +- src/compton.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9a09c3c..62a4d1e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ MANDIR ?= $(PREFIX)/share/man/man1 APPDIR ?= $(PREFIX)/share/applications ICODIR ?= $(PREFIX)/share/icons/hicolor/ -PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-image xcomposite xfixes xext +PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-image xfixes xext LIBS = -lm -lrt INCS = diff --git a/src/compton.c b/src/compton.c index 98e92f3..399d60a 100644 --- a/src/compton.c +++ b/src/compton.c @@ -5362,6 +5362,7 @@ session_init(session_t *ps_old, int argc, char **argv) { ps->root_height = DisplayHeight(ps->dpy, ps->scr); xcb_prefetch_extension_data(c, &xcb_render_id); + xcb_prefetch_extension_data(c, &xcb_composite_id); xcb_prefetch_extension_data(c, &xcb_damage_id); xcb_prefetch_extension_data(c, &xcb_randr_id); @@ -5373,21 +5374,26 @@ session_init(session_t *ps_old, int argc, char **argv) { ps->render_event = ext_info->first_event; ps->render_error = ext_info->first_error; - if (!XQueryExtension(ps->dpy, COMPOSITE_NAME, &ps->composite_opcode, - &ps->composite_event, &ps->composite_error)) { + ext_info = xcb_get_extension_data(c, &xcb_composite_id); + if (!ext_info || !ext_info->present) { fprintf(stderr, "No composite extension\n"); exit(1); } + ps->composite_opcode = ext_info->major_opcode; + ps->composite_event = ext_info->first_event; + ps->composite_error = ext_info->first_error; { - int composite_major = 0, composite_minor = 0; - - XCompositeQueryVersion(ps->dpy, &composite_major, &composite_minor); + xcb_composite_query_version_reply_t *reply = + xcb_composite_query_version_reply(c, + xcb_composite_query_version(c, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION), + NULL); if (!ps->o.no_name_pixmap - && (composite_major > 0 || composite_minor >= 2)) { + && reply && (reply->major_version > 0 || reply->minor_version >= 2)) { ps->has_name_pixmap = true; } + free(reply); } ext_info = xcb_get_extension_data(c, &xcb_damage_id); From 3ed73b1f8e71605f083a96d715137aeeaca060f8 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 10:41:14 +0200 Subject: [PATCH 05/12] Replace last definitions from Xcomposite.h with xcb Note that this adds an include for Xfixes.h, because that header is still needed and was previously included through Xcomposite.h. Signed-off-by: Uli Schlachter --- src/common.h | 5 +---- src/compton.c | 12 ++++++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/common.h b/src/common.h index d0266ba..c5ae484 100644 --- a/src/common.h +++ b/src/common.h @@ -82,7 +82,7 @@ #include #include #include -#include /* FIXME remove this once done porting to xcb-composite */ +#include #include #include #ifdef CONFIG_XSYNC @@ -172,9 +172,6 @@ #endif // === Constants === -#if !(COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2) -#error libXcomposite version unsupported -#endif /// @brief Length of generic buffers. #define BUF_LEN 80 diff --git a/src/compton.c b/src/compton.c index 399d60a..80705f5 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2510,7 +2510,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { } if (ev->request_code == ps->composite_opcode - && ev->minor_code == X_CompositeRedirectSubwindows) { + && ev->minor_code == XCB_COMPOSITE_REDIRECT_SUBWINDOWS) { fprintf(stderr, "Another composite manager is already running " "(and does not handle _NET_WM_CM_Sn correctly)\n"); exit(1); @@ -3691,7 +3691,7 @@ register_cm(session_t *ps) { // Unredirect the window if it's redirected, just in case if (ps->redirected) - xcb_composite_unredirect_window(c, ps->reg_win, CompositeRedirectManual); + xcb_composite_unredirect_window(c, ps->reg_win, XCB_COMPOSITE_REDIRECT_MANUAL); { XClassHint *h = XAllocClassHint(); @@ -4795,15 +4795,15 @@ redir_start(session_t *ps) { if (ps->overlay) XMapWindow(ps->dpy, ps->overlay); - xcb_composite_redirect_subwindows(c, ps->root, CompositeRedirectManual); + xcb_composite_redirect_subwindows(c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL); /* // Unredirect GL context window as this may have an effect on VSync: // < http://dri.freedesktop.org/wiki/CompositeSwap > - xcb_composite_unredirect_window(c, ps->reg_win, CompositeRedirectManual); + xcb_composite_unredirect_window(c, ps->reg_win, XCB_COMPOSITE_REDIRECT_MANUAL); if (ps->o.paint_on_overlay && ps->overlay) { xcb_composite_unredirect_window(c, ps->overlay, - CompositeRedirectManual); + XCB_COMPOSITE_REDIRECT_MANUAL); } */ // Must call XSync() here @@ -4977,7 +4977,7 @@ redir_stop(session_t *ps) { for (win *w = ps->list; w; w = w->next) free_wpaint(ps, w); - xcb_composite_unredirect_subwindows(c, ps->root, CompositeRedirectManual); + xcb_composite_unredirect_subwindows(c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL); // Unmap overlay window if (ps->overlay) XUnmapWindow(ps->dpy, ps->overlay); From 00ae9718ee81b9e43131eb4ed7018182dfbd93f8 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 11:11:43 +0200 Subject: [PATCH 06/12] Handle asyncronous X11 errors Errors for requests sent via Xlib that expect a reply are handled via XSetErrorHandler(), which sets up a callback function that Xlib calls. Errors for requests that do not expect a reply or for errors caused via unchecked XCB requests show up as events of type 0 in the event handling function. Before this commit, errors were ignored here. This commit changes the code so that the errors are printed instead. Signed-off-by: Uli Schlachter --- src/compton.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/compton.c b/src/compton.c index 80705f5..59593bf 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2496,21 +2496,21 @@ root_damaged(session_t *ps) { } /** - * Xlib error handler function. + * X11 error handler function. */ -static int -xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { +static void +xerror_common(unsigned long serial, uint8_t major, uint8_t minor, uint8_t error_code) { session_t * const ps = ps_g; int o = 0; const char *name = "Unknown"; - if (should_ignore(ps, ev->serial)) { - return 0; + if (should_ignore(ps, serial)) { + return; } - if (ev->request_code == ps->composite_opcode - && ev->minor_code == XCB_COMPOSITE_REDIRECT_SUBWINDOWS) { + if (major == ps->composite_opcode + && minor == XCB_COMPOSITE_REDIRECT_SUBWINDOWS) { fprintf(stderr, "Another composite manager is already running " "(and does not handle _NET_WM_CM_Sn correctly)\n"); exit(1); @@ -2518,17 +2518,17 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { #define CASESTRRET2(s) case s: name = #s; break - o = ev->error_code - ps->xfixes_error; + o = error_code - ps->xfixes_error; switch (o) { CASESTRRET2(BadRegion); } - o = ev->error_code - ps->damage_error; + o = error_code - ps->damage_error; switch (o) { CASESTRRET2(XCB_DAMAGE_BAD_DAMAGE); } - o = ev->error_code - ps->render_error; + o = error_code - ps->render_error; switch (o) { CASESTRRET2(XCB_RENDER_PICT_FORMAT); CASESTRRET2(XCB_RENDER_PICTURE); @@ -2539,7 +2539,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { #ifdef CONFIG_OPENGL if (ps->glx_exists) { - o = ev->error_code - ps->glx_error; + o = error_code - ps->glx_error; switch (o) { CASESTRRET2(GLX_BAD_SCREEN); CASESTRRET2(GLX_BAD_ATTRIBUTE); @@ -2554,7 +2554,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { #ifdef CONFIG_XSYNC if (ps->xsync_exists) { - o = ev->error_code - ps->xsync_error; + o = error_code - ps->xsync_error; switch (o) { CASESTRRET2(XSyncBadCounter); CASESTRRET2(XSyncBadAlarm); @@ -2563,7 +2563,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { } #endif - switch (ev->error_code) { + switch (error_code) { CASESTRRET2(BadAccess); CASESTRRET2(BadAlloc); CASESTRRET2(BadAtom); @@ -2588,17 +2588,32 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { print_timestamp(ps); { char buf[BUF_LEN] = ""; - XGetErrorText(ps->dpy, ev->error_code, buf, BUF_LEN); + XGetErrorText(ps->dpy, error_code, buf, BUF_LEN); printf("error %4d %-12s request %4d minor %4d serial %6lu: \"%s\"\n", - ev->error_code, name, ev->request_code, - ev->minor_code, ev->serial, buf); + error_code, name, major, + minor, serial, buf); } // print_backtrace(); +} +/** + * Xlib error handler function. + */ +static int +xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { + xerror_common(ev->serial, ev->request_code, ev->minor_code, ev->error_code); return 0; } +/** + * XCB error handler function. + */ +inline static void +ev_xcb_error(session_t __attribute__((unused)) *ps, xcb_generic_error_t *err) { + xerror_common(err->sequence, err->major_code, err->minor_code, err->error_code); +} + static void expose_root(session_t *ps, XRectangle *rects, int nrects) { free_all_damage_last(ps); @@ -3268,6 +3283,9 @@ ev_handle(session_t *ps, xcb_generic_event_t *ev) { case SelectionClear: ev_selection_clear(ps, (xcb_selection_clear_event_t *)ev); break; + case 0: + ev_xcb_error(ps, (xcb_generic_error_t *)ev); + break; default: if (ps->shape_exists && ev->response_type == ps->shape_event) { ev_shape_notify(ps, (xcb_shape_notify_event_t *) ev); From aa8cb217c845c8ee3b16ea63c72878d462e69992 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 11:18:09 +0200 Subject: [PATCH 07/12] Fix xcb error ignoring The existing mechanism with set_ignore_next() is (IMHO) ugly and also does not work with XCB requests. This commit adds a new function set_ignore_cookie() and fixes callers that were converted to XCB to use this new function instead. Signed-off-by: Uli Schlachter --- src/common.h | 8 ++++++++ src/compton.c | 12 ++++++------ src/compton.h | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/common.h b/src/common.h index c5ae484..68c103a 100644 --- a/src/common.h +++ b/src/common.h @@ -1995,6 +1995,14 @@ set_ignore_next(session_t *ps) { set_ignore(ps, NextRequest(ps->dpy)); } +/** + * Ignore X errors caused by given X request. + */ +static inline void +set_ignore_cookie(session_t *ps, xcb_void_cookie_t cookie) { + set_ignore(ps, cookie.sequence); +} + /** * Check if a window is a fullscreen window. * diff --git a/src/compton.c b/src/compton.c index 59593bf..f8ec4a9 100644 --- a/src/compton.c +++ b/src/compton.c @@ -1445,9 +1445,9 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint, // Fetch Pixmap if (!w->paint.pixmap && ps->has_name_pixmap) { - set_ignore_next(ps); w->paint.pixmap = xcb_generate_id(c); - xcb_composite_name_window_pixmap(c, w->id, w->paint.pixmap); + set_ignore_cookie(ps, + xcb_composite_name_window_pixmap(c, w->id, w->paint.pixmap)); if (w->paint.pixmap) free_fence(ps, &w->fence); } @@ -1997,12 +1997,12 @@ repair_win(session_t *ps, win *w) { if (!w->ever_damaged) { parts = win_extents(ps, w); - set_ignore_next(ps); - xcb_damage_subtract(c, w->damage, XCB_NONE, XCB_NONE); + set_ignore_cookie(ps, + xcb_damage_subtract(c, w->damage, XCB_NONE, XCB_NONE)); } else { parts = XFixesCreateRegion(ps->dpy, 0, 0); - set_ignore_next(ps); - xcb_damage_subtract(c, w->damage, XCB_NONE, parts); + set_ignore_cookie(ps, + xcb_damage_subtract(c, w->damage, XCB_NONE, parts)); XFixesTranslateRegion(ps->dpy, parts, w->g.x + w->g.border_width, w->g.y + w->g.border_width); diff --git a/src/compton.h b/src/compton.h index e7c67c0..cc7d753 100644 --- a/src/compton.h +++ b/src/compton.h @@ -164,8 +164,8 @@ inline static void free_damage(session_t *ps, xcb_damage_damage_t *p) { if (*p) { // BadDamage will be thrown if the window is destroyed - set_ignore_next(ps); - xcb_damage_destroy(XGetXCBConnection(ps->dpy), *p); + set_ignore_cookie(ps, + xcb_damage_destroy(XGetXCBConnection(ps->dpy), *p)); *p = None; } } From 83a48534194b60bc91a63144997dc5c25f22b38d Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 11:29:51 +0200 Subject: [PATCH 08/12] Convert use of SHAPE extension to XCB Signed-off-by: Uli Schlachter --- Makefile | 2 +- src/common.h | 2 +- src/compton.c | 15 ++++++++++----- src/compton.h | 6 ++++-- src/win.c | 14 ++++++++------ 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 62a4d1e..1dc8d2c 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ MANDIR ?= $(PREFIX)/share/man/man1 APPDIR ?= $(PREFIX)/share/applications ICODIR ?= $(PREFIX)/share/icons/hicolor/ -PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-image xfixes xext +PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-shape xcb-image xfixes xext LIBS = -lm -lrt INCS = diff --git a/src/common.h b/src/common.h index 68c103a..8b21ad1 100644 --- a/src/common.h +++ b/src/common.h @@ -83,7 +83,6 @@ #include #include #include -#include #include #ifdef CONFIG_XSYNC #include @@ -97,6 +96,7 @@ #include #include #include +#include // Workarounds for missing definitions in very old versions of X headers, // thanks to consolers for reporting diff --git a/src/compton.c b/src/compton.c index f8ec4a9..35a619d 100644 --- a/src/compton.c +++ b/src/compton.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -2027,6 +2026,8 @@ repair_win(session_t *ps, win *w) { void map_win(session_t *ps, Window id) { + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + // Unmap overlay window if it got mapped but we are currently not // in redirected state. if (ps->overlay && id == ps->overlay && !ps->redirected) { @@ -2058,7 +2059,7 @@ map_win(session_t *ps, Window id) { // Notify compton when the shape of a window changes if (ps->shape_exists) { - XShapeSelectInput(ps->dpy, id, ShapeNotifyMask); + xcb_shape_select_input(c, id, 1); } // Make sure the XSelectInput() requests are sent @@ -4722,8 +4723,8 @@ init_overlay(session_t *ps) { // Set window region of the overlay window, code stolen from // compiz-0.8.8 XserverRegion region = XFixesCreateRegion(ps->dpy, NULL, 0); - XFixesSetWindowShapeRegion(ps->dpy, ps->overlay, ShapeBounding, 0, 0, 0); - XFixesSetWindowShapeRegion(ps->dpy, ps->overlay, ShapeInput, 0, 0, region); + XFixesSetWindowShapeRegion(ps->dpy, ps->overlay, XCB_SHAPE_SK_BOUNDING, 0, 0, 0); + XFixesSetWindowShapeRegion(ps->dpy, ps->overlay, XCB_SHAPE_SK_INPUT, 0, 0, region); XFixesDestroyRegion(ps->dpy, region); // Listen to Expose events on the overlay @@ -5382,6 +5383,7 @@ session_init(session_t *ps_old, int argc, char **argv) { xcb_prefetch_extension_data(c, &xcb_render_id); xcb_prefetch_extension_data(c, &xcb_composite_id); xcb_prefetch_extension_data(c, &xcb_damage_id); + xcb_prefetch_extension_data(c, &xcb_shape_id); xcb_prefetch_extension_data(c, &xcb_randr_id); ext_info = xcb_get_extension_data(c, &xcb_render_id); @@ -5454,7 +5456,10 @@ session_init(session_t *ps_old, int argc, char **argv) { get_cfg(ps, argc, argv, false); // Query X Shape - if (XShapeQueryExtension(ps->dpy, &ps->shape_event, &ps->shape_error)) { + ext_info = xcb_get_extension_data(c, &xcb_shape_id); + if (ext_info && ext_info->present) { + ps->shape_event = ext_info->first_event; + ps->shape_error = ext_info->first_error; ps->shape_exists = true; } diff --git a/src/compton.h b/src/compton.h index cc7d753..37628bd 100644 --- a/src/compton.h +++ b/src/compton.h @@ -355,6 +355,8 @@ check_fade_fin(session_t *ps, win *w) { */ static inline void win_ev_stop(session_t *ps, win *w) { + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + // Will get BadWindow if the window is destroyed set_ignore_next(ps); XSelectInput(ps->dpy, w->id, 0); @@ -365,8 +367,8 @@ win_ev_stop(session_t *ps, win *w) { } if (ps->shape_exists) { - set_ignore_next(ps); - XShapeSelectInput(ps->dpy, w->id, 0); + set_ignore_cookie(ps, + xcb_shape_select_input(c, w->id, 0)); } } diff --git a/src/win.c b/src/win.c index 179c71b..af7ac92 100644 --- a/src/win.c +++ b/src/win.c @@ -231,13 +231,15 @@ int win_get_role(session_t *ps, win *w) { */ static inline bool win_bounding_shaped(const session_t *ps, Window wid) { if (ps->shape_exists) { - Bool bounding_shaped = False, clip_shaped = False; - int x_bounding, y_bounding, x_clip, y_clip; - unsigned int w_bounding, h_bounding, w_clip, h_clip; + xcb_shape_query_extents_reply_t *reply; + Bool bounding_shaped; + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + + reply = xcb_shape_query_extents_reply(c, + xcb_shape_query_extents(c, wid), NULL); + bounding_shaped = reply && reply->bounding_shaped; + free(reply); - XShapeQueryExtents(ps->dpy, wid, &bounding_shaped, - &x_bounding, &y_bounding, &w_bounding, &h_bounding, - &clip_shaped, &x_clip, &y_clip, &w_clip, &h_clip); return bounding_shaped; } From 9dff55540fc2f984c25f7cc8d6c14c3f071d2b03 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 11:46:29 +0200 Subject: [PATCH 09/12] Convert Xinerama usage to xcb Signed-off-by: Uli Schlachter --- Makefile | 2 +- src/common.h | 10 +++++----- src/compton.c | 31 +++++++++++++++++++------------ src/compton.h | 13 ++++++++++--- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 1dc8d2c..e90212c 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ endif # Enables support for --xinerama-shadow-crop ifeq "$(NO_XINERAMA)" "" CFG += -DCONFIG_XINERAMA - PACKAGES += xinerama + PACKAGES += xcb-xinerama endif # ==== libconfig ==== diff --git a/src/common.h b/src/common.h index 8b21ad1..dad6a7e 100644 --- a/src/common.h +++ b/src/common.h @@ -88,16 +88,16 @@ #include #endif -#ifdef CONFIG_XINERAMA -#include -#endif - #include #include #include #include #include +#ifdef CONFIG_XINERAMA +#include +#endif + // Workarounds for missing definitions in very old versions of X headers, // thanks to consolers for reporting #ifndef PictOpDifference @@ -977,7 +977,7 @@ typedef struct session { /// Whether X Xinerama extension exists. bool xinerama_exists; /// Xinerama screen info. - XineramaScreenInfo *xinerama_scrs; + xcb_xinerama_query_screens_reply_t *xinerama_scrs; /// Xinerama screen regions. XserverRegion *xinerama_scr_regs; /// Number of Xinerama screens. diff --git a/src/compton.c b/src/compton.c index 35a619d..5ffaba0 100644 --- a/src/compton.c +++ b/src/compton.c @@ -5110,21 +5110,28 @@ cxinerama_upd_scrs(session_t *ps) { if (!ps->o.xinerama_shadow_crop || !ps->xinerama_exists) return; - if (!XineramaIsActive(ps->dpy)) return; - - ps->xinerama_scrs = XineramaQueryScreens(ps->dpy, &ps->xinerama_nscrs); - - // Just in case the shit hits the fan... - if (!ps->xinerama_nscrs) { - cxfree(ps->xinerama_scrs); - ps->xinerama_scrs = NULL; + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + xcb_xinerama_is_active_reply_t *active = + xcb_xinerama_is_active_reply(c, + xcb_xinerama_is_active(c), NULL); + if (!active || !active->state) { + free(active); return; } + free(active); + + ps->xinerama_scrs = xcb_xinerama_query_screens_reply(c, + xcb_xinerama_query_screens(c), NULL); + if (!ps->xinerama_scrs) + return; + + xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs); + ps->xinerama_nscrs = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs); ps->xinerama_scr_regs = allocchk(malloc(sizeof(XserverRegion *) * ps->xinerama_nscrs)); for (int i = 0; i < ps->xinerama_nscrs; ++i) { - const XineramaScreenInfo * const s = &ps->xinerama_scrs[i]; + const xcb_xinerama_screen_info_t * const s = &scrs[i]; XRectangle r = { .x = s->x_org, .y = s->y_org, .width = s->width, .height = s->height }; ps->xinerama_scr_regs[i] = XFixesCreateRegion(ps->dpy, &r, 1); @@ -5385,6 +5392,7 @@ session_init(session_t *ps_old, int argc, char **argv) { xcb_prefetch_extension_data(c, &xcb_damage_id); xcb_prefetch_extension_data(c, &xcb_shape_id); xcb_prefetch_extension_data(c, &xcb_randr_id); + xcb_prefetch_extension_data(c, &xcb_xinerama_id); ext_info = xcb_get_extension_data(c, &xcb_render_id); if (!ext_info || !ext_info->present) { @@ -5515,9 +5523,8 @@ session_init(session_t *ps_old, int argc, char **argv) { // Query X Xinerama extension if (ps->o.xinerama_shadow_crop) { #ifdef CONFIG_XINERAMA - int xinerama_event = 0, xinerama_error = 0; - if (XineramaQueryExtension(ps->dpy, &xinerama_event, &xinerama_error)) - ps->xinerama_exists = true; + ext_info = xcb_get_extension_data(c, &xcb_xinerama_id); + ps->xinerama_exists = ext_info && ext_info->present; #else printf_errf("(): Xinerama support not compiled in."); #endif diff --git a/src/compton.h b/src/compton.h index 37628bd..bb755c6 100644 --- a/src/compton.h +++ b/src/compton.h @@ -650,14 +650,21 @@ static inline void cxinerama_win_upd_scr(session_t *ps, win *w) { #ifdef CONFIG_XINERAMA w->xinerama_scr = -1; - for (XineramaScreenInfo *s = ps->xinerama_scrs; - s < ps->xinerama_scrs + ps->xinerama_nscrs; ++s) + + if (!ps->xinerama_scrs) + return; + + xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs); + int length = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs); + for (int i = 0; i < length; i++) { + xcb_xinerama_screen_info_t *s = &scrs[i]; if (s->x_org <= w->g.x && s->y_org <= w->g.y && s->x_org + s->width >= w->g.x + w->widthb && s->y_org + s->height >= w->g.y + w->heightb) { - w->xinerama_scr = s - ps->xinerama_scrs; + w->xinerama_scr = i; return; } + } #endif } From ea9942b87eab63623c0219bed082c2cdcc83576e Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 11:53:30 +0200 Subject: [PATCH 10/12] Replace use of XFreePixmap with XCB Signed-off-by: Uli Schlachter --- src/common.h | 3 ++- src/compton.c | 10 +++++----- src/xrescheck.h | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/common.h b/src/common.h index dad6a7e..04c2279 100644 --- a/src/common.h +++ b/src/common.h @@ -2525,7 +2525,8 @@ wintype_arr_enable(bool arr[]) { static inline void free_pixmap(session_t *ps, Pixmap *p) { if (*p) { - XFreePixmap(ps->dpy, *p); + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + xcb_free_pixmap(c, *p); *p = None; } } diff --git a/src/compton.c b/src/compton.c index 5ffaba0..a1af16c 100644 --- a/src/compton.c +++ b/src/compton.c @@ -666,7 +666,7 @@ win_build_shadow(session_t *ps, win *w, double opacity) { XFreeGC(ps->dpy, gc); xcb_image_destroy(shadow_image); - XFreePixmap(ps->dpy, shadow_pixmap); + xcb_free_pixmap(c, shadow_pixmap); xcb_render_free_picture(c, shadow_picture); return true; @@ -675,9 +675,9 @@ shadow_picture_err: if (shadow_image) xcb_image_destroy(shadow_image); if (shadow_pixmap) - XFreePixmap(ps->dpy, shadow_pixmap); + xcb_free_pixmap(c, shadow_pixmap); if (shadow_pixmap_argb) - XFreePixmap(ps->dpy, shadow_pixmap_argb); + xcb_free_pixmap(c, shadow_pixmap_argb); if (shadow_picture) xcb_render_free_picture(c, shadow_picture); if (shadow_picture_argb) @@ -711,7 +711,7 @@ solid_picture(session_t *ps, bool argb, double a, XCB_RENDER_CP_REPEAT, &pa); if (!picture) { - XFreePixmap(ps->dpy, pixmap); + xcb_free_pixmap(c, pixmap); return None; } @@ -726,7 +726,7 @@ solid_picture(session_t *ps, bool argb, double a, rect.height = 1; xcb_render_fill_rectangles(c, XCB_RENDER_PICT_OP_SRC, picture, col, 1, &rect); - XFreePixmap(ps->dpy, pixmap); + xcb_free_pixmap(c, pixmap); return picture; } diff --git a/src/xrescheck.h b/src/xrescheck.h index 67aea3f..ce4bd60 100644 --- a/src/xrescheck.h +++ b/src/xrescheck.h @@ -60,11 +60,11 @@ xcb_composite_name_window_pixmap_(xcb_connection_t *c, xcb_window_t window, xcb_ xcb_composite_name_window_pixmap_(dpy, window, pixmap, M_POS_DATA) static inline void -XFreePixmap_(Display *dpy, Pixmap pixmap, M_POS_DATA_PARAMS) { - XFreePixmap(dpy, pixmap); +xcb_free_pixmap_(xcb_connection_t *c, Pixmap pixmap, M_POS_DATA_PARAMS) { + xcb_free_pixmap(c, pixmap); xrc_delete_xid_(pixmap, M_POS_DATA_PASSTHROUGH); } -#define XFreePixmap(dpy, pixmap) XFreePixmap_(dpy, pixmap, M_POS_DATA); +#define xcb_free_pixmap(c, pixmap) xcb_free_pixmap_(c, pixmap, M_POS_DATA); #endif From 529306e65f88539f03d23f066b45d17a87909475 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 12:00:18 +0200 Subject: [PATCH 11/12] Convert usage of XCreatePixmap to xcb Signed-off-by: Uli Schlachter --- src/compton.c | 20 +++++++++++--------- src/x.c | 4 +++- src/xrescheck.h | 17 +++++++---------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/compton.c b/src/compton.c index a1af16c..45dfc29 100644 --- a/src/compton.c +++ b/src/compton.c @@ -628,10 +628,10 @@ win_build_shadow(session_t *ps, win *w, double opacity) { return None; } - shadow_pixmap = XCreatePixmap(ps->dpy, ps->root, - shadow_image->width, shadow_image->height, 8); - shadow_pixmap_argb = XCreatePixmap(ps->dpy, ps->root, - shadow_image->width, shadow_image->height, 32); + shadow_pixmap = xcb_generate_id(c); + shadow_pixmap_argb = xcb_generate_id(c); + xcb_create_pixmap(c, 8, shadow_pixmap, ps->root, shadow_image->width, shadow_image->height); + xcb_create_pixmap(c, 32, shadow_pixmap_argb, ps->root, shadow_image->width, shadow_image->height); if (!shadow_pixmap || !shadow_pixmap_argb) { printf_errf("(): failed to create shadow pixmaps"); @@ -701,9 +701,9 @@ solid_picture(session_t *ps, bool argb, double a, xcb_rectangle_t rect; xcb_connection_t *c = XGetXCBConnection(ps->dpy); - pixmap = XCreatePixmap(ps->dpy, ps->root, 1, 1, argb ? 32 : 8); - + pixmap = xcb_generate_id(c); if (!pixmap) return None; + xcb_create_pixmap(c, argb ? 32 : 8, pixmap, ps->root, 1, 1); pa.repeat = True; picture = x_create_picture_with_standard_and_pixmap(ps, @@ -892,7 +892,8 @@ get_root_tile(session_t *ps) { // Create a pixmap if there isn't any if (!pixmap) { - pixmap = XCreatePixmap(ps->dpy, ps->root, 1, 1, ps->depth); + pixmap = xcb_generate_id(c); + xcb_create_pixmap(c, ps->depth, pixmap, ps->root, 1, 1); fill = true; } @@ -1709,8 +1710,9 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t else { if (!ps->tgt_buffer.pixmap) { free_paint(ps, &ps->tgt_buffer); - ps->tgt_buffer.pixmap = XCreatePixmap(ps->dpy, ps->root, - ps->root_width, ps->root_height, ps->depth); + ps->tgt_buffer.pixmap = xcb_generate_id(c); + xcb_create_pixmap(c, ps->depth, ps->tgt_buffer.pixmap, + ps->root, ps->root_width, ps->root_height); } if (BKEND_GLX != ps->o.backend) diff --git a/src/x.c b/src/x.c index d6d5009..cb9c149 100644 --- a/src/x.c +++ b/src/x.c @@ -193,9 +193,11 @@ x_create_picture(session_t *ps, int wid, int hei, int depth = pictfmt->depth; - Pixmap tmp_pixmap = XCreatePixmap(ps->dpy, ps->root, wid, hei, depth); + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + Pixmap tmp_pixmap = xcb_generate_id(c); if (!tmp_pixmap) return None; + xcb_create_pixmap(c, depth, tmp_pixmap, ps->root, wid, hei); xcb_render_picture_t picture = x_create_picture_with_pictfmt_and_pixmap(ps, pictfmt, tmp_pixmap, valuemask, attr); diff --git a/src/xrescheck.h b/src/xrescheck.h index ce4bd60..55c9781 100644 --- a/src/xrescheck.h +++ b/src/xrescheck.h @@ -35,18 +35,15 @@ xrc_clear_xid(void); // Pixmap -static inline Pixmap -XCreatePixmap_(Display *dpy, Drawable drawable, - unsigned int width, unsigned int height, unsigned int depth, - M_POS_DATA_PARAMS) { - Pixmap ret = XCreatePixmap(dpy, drawable, width, height, depth); - if (ret) - xrc_add_xid_(ret, "Pixmap", M_POS_DATA_PASSTHROUGH); - return ret; +static inline void +xcb_create_pixmap_(xcb_connection_t *c, uint8_t depth, xcb_pixmap_t pixmap, + xcb_drawable_t drawable, uint16_t width, uint16_t height, M_POS_DATA_PARAMS) { + xcb_create_pixmap(c, depth, pixmap, drawable, width, height); + xrc_add_xid_(pixmap, "Pixmap", M_POS_DATA_PASSTHROUGH); } -#define XCreatePixmap(dpy, drawable, width, height, depth) \ - XCreatePixmap_(dpy, drawable, width, height, depth, M_POS_DATA) +#define xcb_create_pixmap(c, depth, pixmap, drawable, width, height) \ + xcb_create_pixmap_(c, depth, pixmap, drawable, width, height, M_POS_DATA) static inline xcb_pixmap_t xcb_composite_name_window_pixmap_(xcb_connection_t *c, xcb_window_t window, xcb_pixmap_t pixmap, M_POS_DATA_PARAMS) { From 884867654044a324d84fdc011e4c701385baf78b Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sun, 30 Sep 2018 09:31:22 +0200 Subject: [PATCH 12/12] Add a function that allocates a pixmap and checks success Signed-off-by: Uli Schlachter --- src/common.h | 22 ++++++++++++++++++++++ src/compton.c | 26 ++++++++++++++------------ src/x.c | 4 +--- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/common.h b/src/common.h index 04c2279..6f1c6c8 100644 --- a/src/common.h +++ b/src/common.h @@ -1251,6 +1251,9 @@ extern session_t *ps_g; static inline void print_timestamp(session_t *ps); +void +ev_xcb_error(session_t *ps, xcb_generic_error_t *err); + #ifdef DEBUG_BACKTRACE #include @@ -2530,3 +2533,22 @@ free_pixmap(session_t *ps, Pixmap *p) { *p = None; } } + +/** + * Create a pixmap and check that creation succeeded. + */ +static inline xcb_pixmap_t +create_pixmap(session_t *ps, uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height) +{ + xcb_connection_t *c = XGetXCBConnection(ps->dpy); + xcb_pixmap_t pix = xcb_generate_id(c); + xcb_void_cookie_t cookie = xcb_create_pixmap_checked(c, depth, pix, drawable, width, height); + xcb_generic_error_t *err = xcb_request_check(c, cookie); + if (err == NULL) + return pix; + + printf_err("Failed to create pixmap:"); + ev_xcb_error(ps, err); + free(err); + return XCB_NONE; +} diff --git a/src/compton.c b/src/compton.c index a8fdefe..be62eb5 100644 --- a/src/compton.c +++ b/src/compton.c @@ -628,10 +628,8 @@ win_build_shadow(session_t *ps, win *w, double opacity) { return None; } - shadow_pixmap = xcb_generate_id(c); - shadow_pixmap_argb = xcb_generate_id(c); - xcb_create_pixmap(c, 8, shadow_pixmap, ps->root, shadow_image->width, shadow_image->height); - xcb_create_pixmap(c, 32, shadow_pixmap_argb, ps->root, shadow_image->width, shadow_image->height); + shadow_pixmap = create_pixmap(ps, 8, ps->root, shadow_image->width, shadow_image->height); + shadow_pixmap_argb = create_pixmap(ps, 32, ps->root, shadow_image->width, shadow_image->height); if (!shadow_pixmap || !shadow_pixmap_argb) { printf_errf("(): failed to create shadow pixmaps"); @@ -701,9 +699,8 @@ solid_picture(session_t *ps, bool argb, double a, xcb_rectangle_t rect; xcb_connection_t *c = XGetXCBConnection(ps->dpy); - pixmap = xcb_generate_id(c); + pixmap = create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1); if (!pixmap) return None; - xcb_create_pixmap(c, argb ? 32 : 8, pixmap, ps->root, 1, 1); pa.repeat = True; picture = x_create_picture_with_standard_and_pixmap(ps, @@ -892,8 +889,11 @@ get_root_tile(session_t *ps) { // Create a pixmap if there isn't any if (!pixmap) { - pixmap = xcb_generate_id(c); - xcb_create_pixmap(c, ps->depth, pixmap, ps->root, 1, 1); + pixmap = create_pixmap(ps, ps->depth, ps->root, 1, 1); + if (pixmap == XCB_NONE) { + fprintf(stderr, "Failed to create some pixmap\n"); + exit(1); + } fill = true; } @@ -1710,9 +1710,11 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t else { if (!ps->tgt_buffer.pixmap) { free_paint(ps, &ps->tgt_buffer); - ps->tgt_buffer.pixmap = xcb_generate_id(c); - xcb_create_pixmap(c, ps->depth, ps->tgt_buffer.pixmap, - ps->root, ps->root_width, ps->root_height); + ps->tgt_buffer.pixmap = create_pixmap(ps, ps->depth, ps->root, ps->root_width, ps->root_height); + if (ps->tgt_buffer.pixmap == XCB_NONE) { + fprintf(stderr, "Failed to allocate a screen-sized pixmap\n"); + exit(1); + } } if (BKEND_GLX != ps->o.backend) @@ -2612,7 +2614,7 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { /** * XCB error handler function. */ -inline static void +void ev_xcb_error(session_t __attribute__((unused)) *ps, xcb_generic_error_t *err) { xerror_common(err->sequence, err->major_code, err->minor_code, err->error_code); } diff --git a/src/x.c b/src/x.c index cb9c149..0b8cd30 100644 --- a/src/x.c +++ b/src/x.c @@ -193,11 +193,9 @@ x_create_picture(session_t *ps, int wid, int hei, int depth = pictfmt->depth; - xcb_connection_t *c = XGetXCBConnection(ps->dpy); - Pixmap tmp_pixmap = xcb_generate_id(c); + Pixmap tmp_pixmap = create_pixmap(ps, depth, ps->root, wid, hei); if (!tmp_pixmap) return None; - xcb_create_pixmap(c, depth, tmp_pixmap, ps->root, wid, hei); xcb_render_picture_t picture = x_create_picture_with_pictfmt_and_pixmap(ps, pictfmt, tmp_pixmap, valuemask, attr);