From 9dff55540fc2f984c25f7cc8d6c14c3f071d2b03 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 29 Sep 2018 11:46:29 +0200 Subject: [PATCH] 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 }