diff --git a/.clang-format b/.clang-format index ea447d79..d801a4db 100644 --- a/.clang-format +++ b/.clang-format @@ -23,7 +23,7 @@ PenaltyBreakAssignment: 0 PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 1 PenaltyBreakString: 5 -PenaltyExcessCharacter: 1 +PenaltyExcessCharacter: 3 PenaltyBreakFirstLessLess: 0 PenaltyBreakTemplateDeclaration: 0 BreakBeforeBinaryOperators: None diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index 2b036ccc..40cf9d2d 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -10,10 +10,10 @@ * */ -#include #include #include #include +#include #include #include #include @@ -53,20 +53,9 @@ struct _glx_data { }; struct glx_fbconfig_info * -glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt, int depth) { - assert(pictfmt); - - if (pictfmt->type != XCB_RENDER_PICT_TYPE_DIRECT) { - log_error("compton cannot handle non-DirectColor visuals. Report an " - "issue if you see this error message."); - return NULL; - } - int red_size = popcountl(pictfmt->direct.red_mask), - blue_size = popcountl(pictfmt->direct.blue_mask), - green_size = popcountl(pictfmt->direct.green_mask), - alpha_size = popcountl(pictfmt->direct.alpha_mask); - log_debug("Looking for FBConfig for RGBA%d%d%d%d, depth %d", red_size, blue_size, - green_size, alpha_size, depth); +glx_find_fbconfig(Display *dpy, int screen, struct glx_fbconfig_criteria m) { + log_debug("Looking for FBConfig for RGBA%d%d%d%d, depth %d", m.red_size, m.blue_size, + m.green_size, m.alpha_size, m.visual_depth); int ncfg; // clang-format off @@ -77,11 +66,12 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_X_RENDERABLE, true, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, GLX_DONT_CARE, - GLX_BUFFER_SIZE, red_size + green_size + blue_size + alpha_size, - GLX_RED_SIZE, red_size, - GLX_BLUE_SIZE, blue_size, - GLX_GREEN_SIZE, green_size, - GLX_ALPHA_SIZE, alpha_size, + GLX_BUFFER_SIZE, m.red_size + m.green_size + + m.blue_size + m.alpha_size, + GLX_RED_SIZE, m.red_size, + GLX_BLUE_SIZE, m.blue_size, + GLX_GREEN_SIZE, m.green_size, + GLX_ALPHA_SIZE, m.alpha_size, GLX_STENCIL_SIZE, 0, GLX_DEPTH_SIZE, 0, 0 @@ -112,7 +102,7 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt, glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_RED_SIZE, &red); glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_BLUE_SIZE, &blue); glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_GREEN_SIZE, &green); - if (red != red_size || green != green_size || blue != blue_size) { + if (red != m.red_size || green != m.green_size || blue != m.blue_size) { // Color size doesn't match, this cannot work continue; } @@ -128,7 +118,8 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt, int visual; glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_VISUAL_ID, &visual); - if (depth != -1 && x_get_visual_depth(XGetXCBConnection(dpy), visual) != depth) { + if (m.visual_depth != -1 && + x_get_visual_depth(XGetXCBConnection(dpy), visual) != m.visual_depth) { // Some driver might attach fbconfig to a GLX visual with a // different depth. // @@ -144,7 +135,7 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt, // Prefer the texture format with matching alpha, with the other one as // fallback - if (alpha_size) { + if (m.alpha_size) { texture_fmt = rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT; } else { texture_fmt = rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT; @@ -421,13 +412,8 @@ static void *glx_prepare_win(void *backend_data, session_t *ps, win *w) { goto err; } - auto pictfmt = x_get_pictform_for_visual(ps->c, w->a.visual); - if (!pictfmt) { - log_error("Window %#010x has invalid visual %#x", w->id, w->a.visual); - goto err; - } - int depth = x_get_visual_depth(ps->c, w->a.visual); - auto fbcfg = glx_find_fbconfig(ps->dpy, ps->scr, pictfmt, depth); + auto criteria = x_visual_to_fbconfig_criteria(ps->c, w->a.visual); + auto fbcfg = glx_find_fbconfig(ps->dpy, ps->scr, criteria); if (!fbcfg) { log_error("Couldn't find FBConfig with requested visual %x", w->a.visual); goto err; diff --git a/src/backend/gl/glx.h b/src/backend/gl/glx.h index a83603bd..def8042c 100644 --- a/src/backend/gl/glx.h +++ b/src/backend/gl/glx.h @@ -3,8 +3,9 @@ #pragma once #include #include -#include -#include + +#include "log.h" +#include "x.h" struct glx_fbconfig_info { GLXFBConfig cfg; @@ -13,5 +14,48 @@ struct glx_fbconfig_info { int y_inverted; }; -struct glx_fbconfig_info * -glx_find_fbconfig(Display *, int screen, xcb_render_pictforminfo_t *, int depth); +/// The search criteria for glx_find_fbconfig +struct glx_fbconfig_criteria { + /// Bit width of the red component + int red_size; + /// Bit width of the green component + int green_size; + /// Bit width of the blue component + int blue_size; + /// Bit width of the alpha component + int alpha_size; + /// The depth of X visual + int visual_depth; +}; + +struct glx_fbconfig_info *glx_find_fbconfig(Display *, int screen, struct glx_fbconfig_criteria); + +/// Generate a search criteria for fbconfig from a X visual. +/// Returns {-1, -1, -1, -1, -1} on failure +static inline struct glx_fbconfig_criteria +x_visual_to_fbconfig_criteria(xcb_connection_t *c, xcb_visualid_t visual) { + auto pictfmt = x_get_pictform_for_visual(c, visual); + auto depth = x_get_visual_depth(c, visual); + if (!pictfmt || depth == -1) { + log_error("Invalid visual %#03x", visual); + return (struct glx_fbconfig_criteria){-1, -1, -1, -1, -1}; + } + if (pictfmt->type != XCB_RENDER_PICT_TYPE_DIRECT) { + log_error("compton cannot handle non-DirectColor visuals. Report an " + "issue if you see this error message."); + return (struct glx_fbconfig_criteria){-1, -1, -1, -1, -1}; + } + + int red_size = popcountl(pictfmt->direct.red_mask), + blue_size = popcountl(pictfmt->direct.blue_mask), + green_size = popcountl(pictfmt->direct.green_mask), + alpha_size = popcountl(pictfmt->direct.alpha_mask); + + return (struct glx_fbconfig_criteria){ + .red_size = red_size, + .green_size = green_size, + .blue_size = blue_size, + .alpha_size = alpha_size, + .visual_depth = depth, + }; +} diff --git a/src/render.c b/src/render.c index 9855b323..04e39133 100644 --- a/src/render.c +++ b/src/render.c @@ -36,7 +36,7 @@ * Bind texture in paint_t if we are using GLX backend. */ static inline bool paint_bind_tex(session_t *ps, paint_t *ppaint, unsigned wid, unsigned hei, - unsigned depth, xcb_visualid_t visual, bool force) { + int depth, xcb_visualid_t visual, bool force) { #ifdef CONFIG_OPENGL // XXX This is a mess. But this will go away after the backend refactor. static thread_local struct glx_fbconfig_info *argb_fbconfig = NULL; @@ -47,16 +47,13 @@ static inline bool paint_bind_tex(session_t *ps, paint_t *ppaint, unsigned wid, if (!visual) { assert(depth == 32); if (!argb_fbconfig) { - xcb_render_pictforminfo_t tmp_pictfmt = { - .direct = - { - .red_mask = 255, - .blue_mask = 255, - .green_mask = 255, - .alpha_mask = 255, - }, - .type = XCB_RENDER_PICT_TYPE_DIRECT}; - argb_fbconfig = glx_find_fbconfig(ps->dpy, ps->scr, &tmp_pictfmt, 32); + argb_fbconfig = glx_find_fbconfig( + ps->dpy, ps->scr, + (struct glx_fbconfig_criteria){.red_size = 8, + .green_size = 8, + .blue_size = 8, + .alpha_size = 8, + .visual_depth = 32}); } if (!argb_fbconfig) { log_error("Failed to find appropriate FBConfig for 32 bit depth"); @@ -64,18 +61,18 @@ static inline bool paint_bind_tex(session_t *ps, paint_t *ppaint, unsigned wid, } fbcfg = argb_fbconfig; } else { - xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps->c, visual); - if (!depth) { - assert(visual); - depth = x_get_visual_depth(ps->c, visual); + auto m = x_visual_to_fbconfig_criteria(ps->c, visual); + if (m.visual_depth < 0) { + return false; } - if (!pictfmt) { + if (depth && depth != m.visual_depth) { + log_error("Mismatching visual depth: %d != %d", depth, m.visual_depth); return false; } if (!ppaint->fbcfg) { - ppaint->fbcfg = glx_find_fbconfig(ps->dpy, ps->scr, pictfmt, depth); + ppaint->fbcfg = glx_find_fbconfig(ps->dpy, ps->scr, m); } if (!ppaint->fbcfg) { log_error("Failed to find appropriate FBConfig for X pixmap"); @@ -109,7 +106,8 @@ static int get_buffer_age(session_t *ps) { if (bkend_use_glx(ps)) { if (ps->o.glx_swap_method == SWAPM_BUFFER_AGE) { unsigned int val; - glXQueryDrawable(ps->dpy, get_tgt_window(ps), GLX_BACK_BUFFER_AGE_EXT, &val); + glXQueryDrawable(ps->dpy, get_tgt_window(ps), + GLX_BACK_BUFFER_AGE_EXT, &val); return (int)val ?: -1; } else { return -1; @@ -174,7 +172,8 @@ void render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei, doubl int alpha_step = opacity * MAX_ALPHA; xcb_render_picture_t alpha_pict = ps->alpha_picts[alpha_step]; if (alpha_step != 0) { - int op = ((!argb && !alpha_pict) ? XCB_RENDER_PICT_OP_SRC : XCB_RENDER_PICT_OP_OVER); + int op = ((!argb && !alpha_pict) ? XCB_RENDER_PICT_OP_SRC + : XCB_RENDER_PICT_OP_OVER); xcb_render_composite(ps->c, op, pict, alpha_pict, ps->tgt_buffer.pict, x, y, 0, 0, dx, dy, wid, hei); } @@ -191,8 +190,9 @@ void render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei, doubl } } -static inline void paint_region(session_t *ps, win *w, int x, int y, int wid, int hei, double opacity, - const region_t *reg_paint, xcb_render_picture_t pict) { +static inline void +paint_region(session_t *ps, win *w, int x, int y, int wid, int hei, double opacity, + const region_t *reg_paint, xcb_render_picture_t pict) { const int dx = (w ? w->g.x : 0) + x; const int dy = (w ? w->g.y : 0) + y; const bool argb = (w && (win_has_alpha(w) || ps->o.force_win_blend)); @@ -293,8 +293,9 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) { xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, pict, XCB_NONE, newpict, 0, 0, 0, 0, 0, 0, wid, hei); - xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_DIFFERENCE, ps->white_picture, - XCB_NONE, newpict, 0, 0, 0, 0, 0, 0, wid, hei); + xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_DIFFERENCE, + ps->white_picture, XCB_NONE, newpict, 0, 0, + 0, 0, 0, 0, wid, hei); // We use an extra PictOpInReverse operation to get correct // pixel alpha. There could be a better solution. if (win_has_alpha(w)) @@ -318,7 +319,8 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) { const int r = extents.right; #define COMP_BDR(cx, cy, cwid, chei) \ - paint_region(ps, w, (cx), (cy), (cwid), (chei), w->frame_opacity *dopacity, reg_paint, pict) + paint_region(ps, w, (cx), (cy), (cwid), (chei), w->frame_opacity *dopacity, \ + reg_paint, pict) // Sanitize the margins, in case some broken WM makes // top_width + bottom_width > height in some cases. @@ -409,7 +411,8 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) { } break; #ifdef CONFIG_OPENGL case BKEND_GLX: - glx_dim_dst(ps, x, y, wid, hei, ps->psglx->z - 0.7, dim_opacity, reg_paint); + glx_dim_dst(ps, x, y, wid, hei, ps->psglx->z - 0.7, dim_opacity, + reg_paint); break; #endif default: assert(false); @@ -433,8 +436,9 @@ static bool get_root_tile(session_t *ps) { // Get the values of background attributes for (int p = 0; background_props_str[p]; p++) { - winprop_t prop = wid_get_prop( - ps, ps->root, get_atom(ps, background_props_str[p]), 1L, XCB_ATOM_PIXMAP, 32); + winprop_t prop = + wid_get_prop(ps, ps->root, get_atom(ps, background_props_str[p]), 1L, + XCB_ATOM_PIXMAP, 32); if (prop.nitems) { pixmap = *prop.p32; fill = false; @@ -649,10 +653,12 @@ static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int x, i // be applied on source picture, to get the nearby pixels outside the // window. xcb_render_set_picture_filter(ps->c, src_pict, strlen(XRFILTER_CONVOLUTION), - XRFILTER_CONVOLUTION, kwid * khei + 2, convolution_blur); - xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, src_pict, XCB_NONE, dst_pict, - (rd_from_tgt ? x : 0), (rd_from_tgt ? y : 0), 0, 0, - (rd_from_tgt ? 0 : x), (rd_from_tgt ? 0 : y), wid, hei); + XRFILTER_CONVOLUTION, kwid * khei + 2, + convolution_blur); + xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, src_pict, XCB_NONE, + dst_pict, (rd_from_tgt ? x : 0), + (rd_from_tgt ? y : 0), 0, 0, (rd_from_tgt ? 0 : x), + (rd_from_tgt ? 0 : y), wid, hei); xrfilter_reset(ps, src_pict); { @@ -719,10 +725,12 @@ static inline void win_blur_background(session_t *ps, win *w, xcb_render_picture } // Modify the factor of the center pixel - kern_src[2 + (khei / 2) * kwid + kwid / 2] = DOUBLE_TO_XFIXED(factor_center); + kern_src[2 + (khei / 2) * kwid + kwid / 2] = + DOUBLE_TO_XFIXED(factor_center); // Copy over - memcpy(kern_dst, kern_src, (kwid * khei + 2) * sizeof(xcb_render_fixed_t)); + memcpy(kern_dst, kern_src, + (kwid * khei + 2) * sizeof(xcb_render_fixed_t)); normalize_conv_kern(kwid, khei, kern_dst + 2); } @@ -773,7 +781,8 @@ static inline void resize_region(region_t *region, short mod) { int hei = y2 - y1; if (wid <= 0 || hei <= 0) continue; - newrects[nnewrects] = (pixman_box32_t){.x1 = x1, .x2 = x2, .y1 = y1, .y2 = y2}; + newrects[nnewrects] = + (pixman_box32_t){.x1 = x1, .x2 = x2, .y1 = y1, .y2 = y2}; ++nnewrects; } @@ -887,13 +896,14 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) { // Mask out the region we don't want shadow on if (pixman_region32_not_empty(&ps->shadow_exclude_reg)) - pixman_region32_subtract(®_tmp, ®_tmp, &ps->shadow_exclude_reg); + pixman_region32_subtract(®_tmp, ®_tmp, + &ps->shadow_exclude_reg); // Might be worth while to crop the region to shadow // border - pixman_region32_intersect_rect(®_tmp, ®_tmp, w->g.x + w->shadow_dx, - w->g.y + w->shadow_dy, - w->shadow_width, w->shadow_height); + pixman_region32_intersect_rect( + ®_tmp, ®_tmp, w->g.x + w->shadow_dx, + w->g.y + w->shadow_dy, w->shadow_width, w->shadow_height); // Mask out the body of the window from the shadow if // needed Doing it here instead of in make_shadow() for @@ -913,7 +923,8 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) { // eventually, so here we just check to make sure // we don't access out of bounds. pixman_region32_intersect( - ®_tmp, ®_tmp, &ps->xinerama_scr_regs[w->xinerama_scr]); + ®_tmp, ®_tmp, + &ps->xinerama_scr_regs[w->xinerama_scr]); #endif // Detect if the region is empty before painting