diff --git a/src/compton.c b/src/compton.c
index 176792f..a43e2d4 100644
--- a/src/compton.c
+++ b/src/compton.c
@@ -451,48 +451,6 @@ presum_gaussian(session_t *ps, conv *map) {
}
}
-
-/**
- * Generate a 1x1 Picture
of a particular color.
- */
-static xcb_render_picture_t
-solid_picture(session_t *ps, bool argb, double a,
- double r, double g, double b) {
- xcb_pixmap_t pixmap;
- xcb_render_picture_t picture;
- xcb_render_create_picture_value_list_t pa;
- xcb_render_color_t col;
- xcb_rectangle_t rect;
-
- pixmap = x_create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1);
- if (!pixmap) return None;
-
- pa.repeat = True;
- picture = x_create_picture_with_standard_and_pixmap(ps,
- argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
- XCB_RENDER_CP_REPEAT, &pa);
-
- if (!picture) {
- xcb_free_pixmap(ps->c, pixmap);
- return None;
- }
-
- col.alpha = a * 0xffff;
- col.red = r * 0xffff;
- col.green = g * 0xffff;
- col.blue = b * 0xffff;
-
- rect.x = 0;
- rect.y = 0;
- rect.width = 1;
- rect.height = 1;
-
- xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_SRC, picture, col, 1, &rect);
- xcb_free_pixmap(ps->c, pixmap);
-
- return picture;
-}
-
// === Error handling ===
static void
@@ -1177,9 +1135,6 @@ restack_win(session_t *ps, win *w, Window new_above) {
}
}
-static bool
-init_filters(session_t *ps);
-
static void
configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
// On root window changes
@@ -1208,7 +1163,7 @@ configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
if (ps->o.glx_reinit_on_root_change && ps->psglx) {
if (!glx_reinit(ps, bkend_use_glx(ps)))
printf_errf("(): Failed to reinitialize GLX, troubles ahead.");
- if (BKEND_GLX == ps->o.backend && !init_filters(ps))
+ if (BKEND_GLX == ps->o.backend && !glx_init_blur(ps))
printf_errf("(): Failed to initialize filters.");
}
@@ -3212,20 +3167,6 @@ swopti_handle_timeout(session_t *ps) {
return (ps->refresh_intv - offset) / 1e6;
}
-/**
- * Pregenerate alpha pictures.
- */
-static void
-init_alpha_picts(session_t *ps) {
- ps->alpha_picts = ccalloc(MAX_ALPHA+1, xcb_render_picture_t);
-
- for (int i = 0; i <= MAX_ALPHA; ++i) {
- double o = (double) i / MAX_ALPHA;
- ps->alpha_picts[i] = solid_picture(ps, false, o, 0, 0, 0);
- assert(ps->alpha_picts[i] != None);
- }
-}
-
/**
* Initialize X composite overlay window.
*/
@@ -3280,50 +3221,6 @@ init_overlay(session_t *ps) {
return ps->overlay;
}
-/**
- * Query needed X Render / OpenGL filters to check for their existence.
- */
-static bool
-init_filters(session_t *ps) {
- // Blur filter
- if (ps->o.blur_background || ps->o.blur_background_frame) {
- switch (ps->o.backend) {
- case BKEND_XRENDER:
- case BKEND_XR_GLX_HYBRID:
- {
- // Query filters
- xcb_render_query_filters_reply_t *pf = xcb_render_query_filters_reply(ps->c,
- xcb_render_query_filters(ps->c, get_tgt_window(ps)), NULL);
- if (pf) {
- xcb_str_iterator_t iter = xcb_render_query_filters_filters_iterator(pf);
- for (; iter.rem; xcb_str_next(&iter)) {
- // Convolution filter
- if (strlen(XRFILTER_CONVOLUTION) == xcb_str_name_length(iter.data)
- && !memcmp(XRFILTER_CONVOLUTION, xcb_str_name(iter.data), strlen(XRFILTER_CONVOLUTION)))
- ps->xrfilter_convolution_exists = true;
- }
- free(pf);
- }
-
- // Turn features off if any required filter is not present
- if (!ps->xrfilter_convolution_exists) {
- printf_errf("(): X Render convolution filter unsupported by your X server. Background blur is not possible.");
- return false;
- }
- break;
- }
-#ifdef CONFIG_OPENGL
- case BKEND_GLX:
- return glx_init_blur(ps);
-#endif
- default:
- assert(false);
- }
- }
-
- return true;
-}
-
/**
* Redirect all windows.
*/
@@ -3927,32 +3824,15 @@ session_init(session_t *ps_old, int argc, char **argv) {
// of OpenGL context.
init_overlay(ps);
+ // Initialize filters, must be preceded by OpenGL context creation
+ if (!init_render(ps))
+ exit(1);
+
if (ps->o.print_diagnostics) {
print_diagnostics(ps);
exit(0);
}
- // Initialize OpenGL as early as possible
- if (bkend_use_glx(ps)) {
-#ifdef CONFIG_OPENGL
- if (!glx_init(ps, true))
- exit(1);
-#else
- printf_errfq(1, "(): GLX backend support not compiled in.");
-#endif
- }
-
- // Initialize window GL shader
- if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
-#ifdef CONFIG_OPENGL
- if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str, &ps->o.glx_prog_win))
- exit(1);
-#else
- printf_errf("(): GLSL supported not compiled in, can't load shader.");
- exit(1);
-#endif
- }
-
// Initialize software optimization
if (ps->o.sw_opti)
ps->o.sw_opti = swopti_init(ps);
@@ -3963,10 +3843,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
|| ps->o.xinerama_shadow_crop))
xcb_randr_select_input(ps->c, ps->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
- // Initialize VSync
- if (!vsync_init(ps))
- exit(1);
-
cxinerama_upd_scrs(ps);
// Create registration window
@@ -3974,7 +3850,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
exit(1);
init_atoms(ps);
- init_alpha_picts(ps);
ps->gaussian_map = gaussian_kernel(ps->o.shadow_radius);
presum_gaussian(ps, ps->gaussian_map);
@@ -3993,22 +3868,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
ps->tgt_picture = ps->root_picture;
}
- // Initialize filters, must be preceded by OpenGL context creation
- if (!init_filters(ps))
- exit(1);
-
- ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
- ps->white_picture = solid_picture(ps, true, 1, 1, 1, 1);
-
- // Generates another Picture for shadows if the color is modified by
- // user
- if (!ps->o.shadow_red && !ps->o.shadow_green && !ps->o.shadow_blue) {
- ps->cshadow_picture = ps->black_picture;
- } else {
- ps->cshadow_picture = solid_picture(ps, true, 1,
- ps->o.shadow_red, ps->o.shadow_green, ps->o.shadow_blue);
- }
-
ev_io_init(&ps->xiow, x_event_callback, ConnectionNumber(ps->dpy), EV_READ);
ev_io_start(ps->loop, &ps->xiow);
ev_init(&ps->unredir_timer, tmout_unredir_callback);
diff --git a/src/render.c b/src/render.c
index 3ff4186..6703354 100644
--- a/src/render.c
+++ b/src/render.c
@@ -1087,4 +1087,163 @@ void paint_all(session_t *ps, region_t *region, const region_t *region_real,
}
}
+/**
+ * Query needed X Render / OpenGL filters to check for their existence.
+ */
+static bool xr_init_blur(session_t *ps) {
+ // Query filters
+ xcb_render_query_filters_reply_t *pf = xcb_render_query_filters_reply(
+ ps->c, xcb_render_query_filters(ps->c, get_tgt_window(ps)), NULL);
+ if (pf) {
+ xcb_str_iterator_t iter =
+ xcb_render_query_filters_filters_iterator(pf);
+ for (; iter.rem; xcb_str_next(&iter)) {
+ int len = xcb_str_name_length(iter.data);
+ char *name = xcb_str_name(iter.data);
+ // Check for the convolution filter
+ if (strlen(XRFILTER_CONVOLUTION) == len &&
+ !memcmp(XRFILTER_CONVOLUTION, name,
+ strlen(XRFILTER_CONVOLUTION)))
+ ps->xrfilter_convolution_exists = true;
+ }
+ free(pf);
+ }
+
+ // Turn features off if any required filter is not present
+ if (!ps->xrfilter_convolution_exists) {
+ printf_errf("(): Xrender convolution filter "
+ "unsupported by your X server. "
+ "Background blur is not possible.");
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Generate a 1x1 Picture
of a particular color.
+ */
+static xcb_render_picture_t
+solid_picture(session_t *ps, bool argb, double a, double r, double g, double b) {
+ xcb_pixmap_t pixmap;
+ xcb_render_picture_t picture;
+ xcb_render_create_picture_value_list_t pa;
+ xcb_render_color_t col;
+ xcb_rectangle_t rect;
+
+ pixmap = x_create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1);
+ if (!pixmap)
+ return XCB_NONE;
+
+ pa.repeat = True;
+ picture = x_create_picture_with_standard_and_pixmap(
+ ps, argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
+ XCB_RENDER_CP_REPEAT, &pa);
+
+ if (!picture) {
+ xcb_free_pixmap(ps->c, pixmap);
+ return XCB_NONE;
+ }
+
+ col.alpha = a * 0xffff;
+ col.red = r * 0xffff;
+ col.green = g * 0xffff;
+ col.blue = b * 0xffff;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = 1;
+ rect.height = 1;
+
+ xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_SRC, picture, col, 1,
+ &rect);
+ xcb_free_pixmap(ps->c, pixmap);
+
+ return picture;
+}
+
+/**
+ * Pregenerate alpha pictures.
+ */
+static bool init_alpha_picts(session_t *ps) {
+ ps->alpha_picts = ccalloc(MAX_ALPHA + 1, xcb_render_picture_t);
+
+ for (int i = 0; i <= MAX_ALPHA; ++i) {
+ double o = (double)i / MAX_ALPHA;
+ ps->alpha_picts[i] = solid_picture(ps, false, o, 0, 0, 0);
+ if (ps->alpha_picts[i] == XCB_NONE)
+ return false;
+ }
+ return true;
+}
+
+bool init_render(session_t *ps) {
+ // Initialize OpenGL as early as possible
+ if (bkend_use_glx(ps)) {
+#ifdef CONFIG_OPENGL
+ if (!glx_init(ps, true))
+ exit(1);
+#else
+ printf_errfq(1, "(): GLX backend support not compiled in.");
+#endif
+ }
+
+ // Initialize VSync
+ if (!vsync_init(ps)) {
+ return false;
+ }
+
+ // Initialize window GL shader
+ if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
+#ifdef CONFIG_OPENGL
+ if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str,
+ &ps->o.glx_prog_win))
+ return false;
+#else
+ printf_errf("(): GLSL supported not compiled in, can't load "
+ "shader.");
+ return false;
+#endif
+ }
+
+ if (!init_alpha_picts(ps)) {
+ printf_errf("(): Failed to init alpha pictures.");
+ return false;
+ }
+
+ // Blur filter
+ if (ps->o.blur_background || ps->o.blur_background_frame) {
+ bool ret;
+ if (ps->o.backend == BKEND_GLX)
+ ret = glx_init_blur(ps);
+ else
+ ret = xr_init_blur(ps);
+ if (!ret)
+ return false;
+ }
+
+ ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
+ ps->white_picture = solid_picture(ps, true, 1, 1, 1, 1);
+
+ if (ps->black_picture == XCB_NONE || ps->white_picture == XCB_NONE) {
+ printf_errf("(): Failed to create solid xrender pictures.");
+ return false;
+ }
+
+ // Generates another Picture for shadows if the color is modified by
+ // user
+ if (!ps->o.shadow_red && !ps->o.shadow_green && !ps->o.shadow_blue) {
+ ps->cshadow_picture = ps->black_picture;
+ } else {
+ ps->cshadow_picture =
+ solid_picture(ps, true, 1, ps->o.shadow_red, ps->o.shadow_green,
+ ps->o.shadow_blue);
+ if (ps->cshadow_picture == XCB_NONE) {
+ printf_errf("(): Failed to create shadow picture.");
+ return false;
+ }
+ }
+ return true;
+}
+
// vim: set ts=8 sw=8 noet :
diff --git a/src/render.h b/src/render.h
index 1709d6e..3a2d31d 100644
--- a/src/render.h
+++ b/src/render.h
@@ -30,3 +30,5 @@ paint_all(session_t *ps, region_t *region, const region_t *region_real, win * co
void free_picture(xcb_connection_t *c, xcb_render_picture_t *p);
void free_paint(session_t *ps, paint_t *ppaint);
+
+bool init_render(session_t *ps);