diff --git a/src/backend/backend_common.c b/src/backend/backend_common.c index 221f350..9500308 100644 --- a/src/backend/backend_common.c +++ b/src/backend/backend_common.c @@ -46,9 +46,8 @@ solid_picture(session_t *ps, bool argb, double a, double r, double g, double b) return picture; } -static xcb_image_t * -make_shadow(xcb_connection_t *c, const conv *kernel, const double *shadow_sum, - double opacity, int width, int height) { +xcb_image_t *make_shadow(xcb_connection_t *c, const conv *kernel, + const double *shadow_sum, double opacity, int width, int height) { /* * We classify shadows into 4 kinds of regions * r = shadow radius diff --git a/src/backend/backend_common.h b/src/backend/backend_common.h index 850e60b..e769108 100644 --- a/src/backend/backend_common.h +++ b/src/backend/backend_common.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #include @@ -8,6 +8,7 @@ typedef struct session session_t; typedef struct win win; +typedef struct conv conv; bool build_shadow(session_t *ps, double opacity, const int width, const int height, xcb_render_picture_t shadow_pixel, xcb_pixmap_t *pixmap, @@ -17,3 +18,6 @@ xcb_render_picture_t solid_picture(session_t *ps, bool argb, double a, double r, double g, double b); void paint_all_new(session_t *ps, region_t *region, win *const t); + +xcb_image_t *make_shadow(xcb_connection_t *c, const conv *kernel, + const double *shadow_sum, double opacity, int width, int height); diff --git a/src/backend/meson.build b/src/backend/meson.build index 177fe92..8fa0715 100644 --- a/src/backend/meson.build +++ b/src/backend/meson.build @@ -1,7 +1,7 @@ # enable xrender - +srcs += [ files('backend_common.c') ] if get_option('new_backends') - srcs += [ files('xrender.c', 'backend.c', 'backend_common.c') ] + srcs += [ files('xrender.c', 'backend.c') ] # enable opengl if get_option('opengl') diff --git a/src/render.c b/src/render.c index 9935161..c107c2f 100644 --- a/src/render.c +++ b/src/render.c @@ -13,6 +13,7 @@ #include "vsync.h" #include "win.h" +#include "backend/backend_common.h" #include "render.h" #ifdef CONFIG_OPENGL @@ -436,130 +437,6 @@ static void paint_root(session_t *ps, const region_t *reg_paint) { ps->root_tile_paint.pict); } -static xcb_image_t * -make_shadow(xcb_connection_t *c, const conv *kernel, const double *shadow_sum, - double opacity, int width, int height) { - /* - * We classify shadows into 4 kinds of regions - * r = shadow radius - * (0, 0) is the top left of the window itself - * -r r width-r width+r - * -r +-----+---------+-----+ - * | 1 | 2 | 1 | - * r +-----+---------+-----+ - * | 2 | 3 | 2 | - * height-r +-----+---------+-----+ - * | 1 | 2 | 1 | - * height+r +-----+---------+-----+ - */ - xcb_image_t *ximage; - int d = kernel->size, r = d / 2; - int swidth = width + r * 2, sheight = height + r * 2; - - assert(d % 2 == 1); - assert(d > 0); - - ximage = xcb_image_create_native(c, swidth, sheight, XCB_IMAGE_FORMAT_Z_PIXMAP, 8, - 0, 0, NULL); - if (!ximage) { - log_error("failed to create an X image"); - return 0; - } - - unsigned char *data = ximage->data; - uint32_t sstride = ximage->stride; - - // If the window body is smaller than the kernel, we do convolution directly - if (width < r * 2 && height < r * 2) { - for (int y = 0; y < sheight; y++) { - for (int x = 0; x < swidth; x++) { - double sum = sum_kernel_normalized( - kernel, d - x - 1, d - y - 1, width, height); - data[y * sstride + x] = sum * 255.0; - } - } - return ximage; - } - - if (height < r * 2) { - // If the window height is smaller than the kernel, we divide - // the window like this: - // -r r width-r width+r - // +------+-------------+------+ - // | | | | - // +------+-------------+------+ - for (int y = 0; y < sheight; y++) { - for (int x = 0; x < r * 2; x++) { - double sum = sum_kernel_normalized(kernel, d - x - 1, - d - y - 1, d, height) * - 255.0; - data[y * sstride + x] = sum; - data[y * sstride + swidth - x - 1] = sum; - } - } - for (int y = 0; y < sheight; y++) { - double sum = - sum_kernel_normalized(kernel, 0, d - y - 1, d, height) * 255.0; - memset(&data[y * sstride + r * 2], sum, width - 2 * r); - } - return ximage; - } - if (width < r * 2) { - // Similarly, for width smaller than kernel - for (int y = 0; y < r * 2; y++) { - for (int x = 0; x < swidth; x++) { - double sum = sum_kernel_normalized(kernel, d - x - 1, - d - y - 1, width, d) * - 255.0; - data[y * sstride + x] = sum; - data[(sheight - y - 1) * sstride + x] = sum; - } - } - for (int x = 0; x < swidth; x++) { - double sum = - sum_kernel_normalized(kernel, d - x - 1, 0, width, d) * 255.0; - for (int y = r * 2; y < height; y++) { - data[y * sstride + x] = sum; - } - } - return ximage; - } - - // Fill part 3 - for (int y = r; y < height + r; y++) { - memset(data + sstride * y + r, 255, width); - } - - // Part 1 - for (int y = 0; y < r * 2; y++) { - for (int x = 0; x < r * 2; x++) { - double tmpsum = shadow_sum[y * d + x] * opacity * 255.0; - data[y * sstride + x] = tmpsum; - data[(sheight - y - 1) * sstride + x] = tmpsum; - data[(sheight - y - 1) * sstride + (swidth - x - 1)] = tmpsum; - data[y * sstride + (swidth - x - 1)] = tmpsum; - } - } - - // Part 2, top/bottom - for (int y = 0; y < r * 2; y++) { - double tmpsum = shadow_sum[d * y + d - 1] * opacity * 255.0; - memset(&data[y * sstride + r * 2], tmpsum, width - r * 2); - memset(&data[(sheight - y - 1) * sstride + r * 2], tmpsum, width - r * 2); - } - - // Part 2, left/right - for (int x = 0; x < r * 2; x++) { - double tmpsum = shadow_sum[d * (d - 1) + x] * opacity * 255.0; - for (int y = r * 2; y < height; y++) { - data[y * sstride + x] = tmpsum; - data[y * sstride + (swidth - x - 1)] = tmpsum; - } - } - - return ximage; -} - /** * Generate shadow Picture for a window. */ @@ -1116,47 +993,6 @@ static bool xr_init_blur(session_t *ps) { 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. */