Eliminate implicit conversions

Use explicit conversions everywhere. Adding bounds check assertions when
necessary.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui
2019-03-30 09:07:21 +00:00
parent 532a90d573
commit 0037b7e5fb
35 changed files with 786 additions and 671 deletions

View File

@ -39,8 +39,8 @@ region_t get_damage(session_t *ps, bool all_damage) {
pixman_region32_copy(&region, &ps->screen_reg);
} else {
for (int i = 0; i < buffer_age; i++) {
const int curr = ((ps->damage - ps->damage_ring) + i) % ps->ndamage;
log_trace("damage index: %d, damage ring offset: %d", i, curr);
auto curr = ((ps->damage - ps->damage_ring) + i) % ps->ndamage;
log_trace("damage index: %d, damage ring offset: %ld", i, curr);
dump_region(&ps->damage_ring[curr]);
pixman_region32_union(&region, &region, &ps->damage_ring[curr]);
}

View File

@ -38,10 +38,10 @@ xcb_render_picture_t solid_picture(xcb_connection_t *c, xcb_drawable_t d, bool a
return XCB_NONE;
}
col.alpha = a * 0xffff;
col.red = r * 0xffff;
col.green = g * 0xffff;
col.blue = b * 0xffff;
col.alpha = (uint16_t)(a * 0xffff);
col.red = (uint16_t)(r * 0xffff);
col.green = (uint16_t)(g * 0xffff);
col.blue = (uint16_t)(b * 0xffff);
rect.x = 0;
rect.y = 0;
@ -74,21 +74,22 @@ make_shadow(xcb_connection_t *c, const conv *kernel, double opacity, int width,
assert(shadow_sum);
// We only support square kernels for shadow
assert(kernel->w == kernel->h);
int d = kernel->w, r = d / 2;
int d = kernel->w;
int 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);
ximage = xcb_image_create_native(c, to_u16_checked(swidth), to_u16_checked(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;
long sstride = ximage->stride;
// If the window body is smaller than the kernel, we do convolution directly
if (width < r * 2 && height < r * 2) {
@ -96,13 +97,14 @@ make_shadow(xcb_connection_t *c, const conv *kernel, double opacity, int width,
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;
data[y * sstride + x] = (uint8_t)(sum * 255.0);
}
}
return ximage;
}
if (height < r * 2) {
// Implies width >= r * 2
// If the window height is smaller than the kernel, we divide
// the window like this:
// -r r width-r width+r
@ -114,14 +116,15 @@ make_shadow(xcb_connection_t *c, const conv *kernel, double opacity, int width,
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;
data[y * sstride + x] = (uint8_t)sum;
data[y * sstride + swidth - x - 1] = (uint8_t)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);
memset(&data[y * sstride + r * 2], (uint8_t)sum,
(size_t)(width - 2 * r));
}
return ximage;
}
@ -132,49 +135,52 @@ make_shadow(xcb_connection_t *c, const conv *kernel, double opacity, int width,
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;
data[y * sstride + x] = (uint8_t)sum;
data[(sheight - y - 1) * sstride + x] = (uint8_t)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;
data[y * sstride + x] = (uint8_t)sum;
}
}
return ximage;
}
// Implies: width >= r * 2 && height >= r * 2
// Fill part 3
for (int y = r; y < height + r; y++) {
memset(data + sstride * y + r, 255 * opacity, width);
memset(data + sstride * y + r, (uint8_t)(255 * opacity), (size_t)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;
data[y * sstride + x] = (uint8_t)tmpsum;
data[(sheight - y - 1) * sstride + x] = (uint8_t)tmpsum;
data[(sheight - y - 1) * sstride + (swidth - x - 1)] = (uint8_t)tmpsum;
data[y * sstride + (swidth - x - 1)] = (uint8_t)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);
memset(&data[y * sstride + r * 2], (uint8_t)tmpsum, (size_t)(width - r * 2));
memset(&data[(sheight - y - 1) * sstride + r * 2], (uint8_t)tmpsum,
(size_t)(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;
data[y * sstride + x] = (uint8_t)tmpsum;
data[y * sstride + (swidth - x - 1)] = (uint8_t)tmpsum;
}
}
@ -256,8 +262,9 @@ shadow_picture_err:
return false;
}
void *default_backend_render_shadow(backend_t *backend_data, int width, int height,
const conv *kernel, double r, double g, double b, double a) {
void *
default_backend_render_shadow(backend_t *backend_data, int width, int height,
const conv *kernel, double r, double g, double b, double a) {
xcb_pixmap_t shadow_pixel = solid_picture(backend_data->c, backend_data->root,
true, 1, r, g, b),
shadow = XCB_NONE;

View File

@ -12,16 +12,17 @@
typedef struct session session_t;
typedef struct win win;
typedef struct conv conv;
typedef struct backend_base backend_t;
bool build_shadow(xcb_connection_t *, xcb_drawable_t, double opacity, const int width,
const int height, const conv *kernel, xcb_render_picture_t shadow_pixel,
bool build_shadow(xcb_connection_t *, xcb_drawable_t, double opacity, int width,
int height, const conv *kernel, xcb_render_picture_t shadow_pixel,
xcb_pixmap_t *pixmap, xcb_render_picture_t *pict);
xcb_render_picture_t solid_picture(xcb_connection_t *, xcb_drawable_t, bool argb,
double a, double r, double g, double b);
xcb_image_t *
make_shadow(xcb_connection_t *c, const conv *kernel, double opacity, int width, int height);
xcb_image_t *make_shadow(xcb_connection_t *c, const conv *kernel, double opacity,
int width, int height);
/// The default implementation of `is_win_transparent`, it simply looks at win::mode. So
/// this is not suitable for backends that alter the content of windows
@ -31,5 +32,6 @@ bool default_is_win_transparent(void *, win *, void *);
/// caveat as `default_is_win_transparent` applies.
bool default_is_frame_transparent(void *, win *, void *);
void *default_backend_render_shadow(backend_t *backend_data, int width, int height,
const conv *kernel, double r, double g, double b, double a);
void *
default_backend_render_shadow(backend_t *backend_data, int width, int height,
const conv *kernel, double r, double g, double b, double a);

View File

@ -119,14 +119,16 @@ GLuint gl_create_program_from_str(const char *vert_shader_str, const char *frag_
{
GLuint shaders[2];
unsigned int count = 0;
if (vert_shader)
int count = 0;
if (vert_shader) {
shaders[count++] = vert_shader;
if (frag_shader)
}
if (frag_shader) {
shaders[count++] = frag_shader;
assert(count <= sizeof(shaders) / sizeof(shaders[0]));
if (count)
}
if (count) {
prog = gl_create_program(shaders, count);
}
}
if (vert_shader)
@ -185,7 +187,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
if (gd->win_shader.prog) {
glUseProgram(gd->win_shader.prog);
if (gd->win_shader.unifm_opacity >= 0) {
glUniform1f(gd->win_shader.unifm_opacity, ptex->opacity);
glUniform1f(gd->win_shader.unifm_opacity, (float)ptex->opacity);
}
if (gd->win_shader.unifm_invert_color >= 0) {
glUniform1i(gd->win_shader.unifm_invert_color, ptex->color_inverted);
@ -194,7 +196,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
glUniform1i(gd->win_shader.unifm_tex, 0);
}
if (gd->win_shader.unifm_dim >= 0) {
glUniform1f(gd->win_shader.unifm_dim, ptex->dim);
glUniform1f(gd->win_shader.unifm_dim, (float)ptex->dim);
}
}
@ -224,23 +226,23 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
// Calculate texture coordinates
// (texture_x1, texture_y1), texture coord for the _bottom left_ corner
GLfloat texture_x1 = crect.x1 - dst_x;
GLfloat texture_y1 = crect.y2 - dst_y2;
GLfloat texture_x2 = texture_x1 + crect.x2 - crect.x1;
GLfloat texture_y2 = texture_y1 + crect.y1 - crect.y2;
auto texture_x1 = (GLfloat)(crect.x1 - dst_x);
auto texture_y1 = (GLfloat)(crect.y2 - dst_y2);
auto texture_x2 = texture_x1 + (GLfloat)(crect.x2 - crect.x1);
auto texture_y2 = texture_y1 + (GLfloat)(crect.y1 - crect.y2);
// X pixmaps might be Y inverted, invert the texture coordinates
if (ptex->y_inverted) {
texture_y1 = ptex->height - texture_y1;
texture_y2 = ptex->height - texture_y2;
texture_y1 = (GLfloat)ptex->height - texture_y1;
texture_y2 = (GLfloat)ptex->height - texture_y2;
}
// GL_TEXTURE_2D coordinates are normalized
// TODO use texelFetch
texture_x1 /= ptex->width;
texture_y1 /= ptex->height;
texture_x2 /= ptex->width;
texture_y2 /= ptex->height;
texture_x1 /= (GLfloat)ptex->width;
texture_y1 /= (GLfloat)ptex->height;
texture_x2 /= (GLfloat)ptex->width;
texture_y2 /= (GLfloat)ptex->height;
// Vertex coordinates
GLint vx1 = crect.x1;
@ -333,11 +335,11 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
// last pass, draw directly into the back buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
glUniform1f(p->unifm_opacity, opacity);
glUniform1f(p->unifm_opacity, (float)opacity);
}
glUniform1f(p->unifm_offset_x, 1.0 / gd->width);
glUniform1f(p->unifm_offset_y, 1.0 / gd->height);
glUniform1f(p->unifm_offset_x, 1.0f / (GLfloat)gd->width);
glUniform1f(p->unifm_offset_y, 1.0f / (GLfloat)gd->height);
// XXX use multiple draw calls is probably going to be slow than
// just simply blur the whole area.
@ -354,29 +356,29 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
crect.y2 = gd->height - crect.y2;
// Texture coordinates
GLfloat texture_x1 = (crect.x1 - extent->x1);
GLfloat texture_y1 = (crect.y2 - dst_y);
GLfloat texture_x2 = texture_x1 + (crect.x2 - crect.x1);
GLfloat texture_y2 = texture_y1 + (crect.y1 - crect.y2);
auto texture_x1 = (GLfloat)(crect.x1 - extent->x1);
auto texture_y1 = (GLfloat)(crect.y2 - dst_y);
auto texture_x2 = texture_x1 + (GLfloat)(crect.x2 - crect.x1);
auto texture_y2 = texture_y1 + (GLfloat)(crect.y1 - crect.y2);
texture_x1 /= gd->width;
texture_x2 /= gd->width;
texture_y1 /= gd->height;
texture_y2 /= gd->height;
texture_x1 /= (GLfloat)gd->width;
texture_x2 /= (GLfloat)gd->width;
texture_y1 /= (GLfloat)gd->height;
texture_y2 /= (GLfloat)gd->height;
// Vertex coordinates
// For passes before the last one, we are drawing into a buffer,
// so (dx, dy) from source maps to (0, 0)
GLfloat vx1 = crect.x1 - extent->x1;
GLfloat vy1 = crect.y2 - dst_y;
GLint vx1 = crect.x1 - extent->x1;
GLint vy1 = crect.y2 - dst_y;
if (i == gd->npasses - 1) {
// For last pass, we are drawing back to source, so we
// don't need to map
vx1 = crect.x1;
vy1 = crect.y2;
}
GLfloat vx2 = vx1 + (crect.x2 - crect.x1);
GLfloat vy2 = vy1 + (crect.y1 - crect.y2);
GLint vx2 = vx1 + (crect.x2 - crect.x1);
GLint vy2 = vy1 + (crect.y1 - crect.y2);
GLfloat texture_x[] = {texture_x1, texture_x2, texture_x2, texture_x1};
GLfloat texture_y[] = {texture_y1, texture_y1, texture_y2, texture_y2};
@ -406,7 +408,7 @@ end:
return ret;
}
static GLuint glGetUniformLocationChecked(GLuint p, const char *name) {
static GLint glGetUniformLocationChecked(GLuint p, const char *name) {
auto ret = glGetUniformLocation(p, name);
if (ret < 0) {
log_error("Failed to get location of uniform '%s'. compton might not "
@ -470,13 +472,13 @@ void gl_fill(backend_t *base, double r, double g, double b, double a, const regi
int nrects;
const rect_t *rect = pixman_region32_rectangles((region_t *)clip, &nrects);
struct gl_data *gd = (void *)base;
glColor4f(r, g, b, a);
glColor4d(r, g, b, a);
glBegin(GL_QUADS);
for (int i = 0; i < nrects; i++) {
glVertex2f(rect[i].x1, gd->height - rect[i].y2);
glVertex2f(rect[i].x2, gd->height - rect[i].y2);
glVertex2f(rect[i].x2, gd->height - rect[i].y1);
glVertex2f(rect[i].x1, gd->height - rect[i].y1);
glVertex2i(rect[i].x1, gd->height - rect[i].y2);
glVertex2i(rect[i].x2, gd->height - rect[i].y2);
glVertex2i(rect[i].x2, gd->height - rect[i].y1);
glVertex2i(rect[i].x1, gd->height - rect[i].y1);
}
glEnd();
}
@ -524,7 +526,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
// Build shader
int width = kern->w, height = kern->h;
int nele = width * height - 1;
size_t body_len = (strlen(shader_add) + 42) * nele;
size_t body_len = (strlen(shader_add) + 42) * (uint)nele;
char *shader_body = ccalloc(body_len, char);
char *pc = shader_body;
@ -541,7 +543,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
continue;
}
sum += val;
pc += snprintf(pc, body_len - (pc - shader_body),
pc += snprintf(pc, body_len - (ulong)(pc - shader_body),
FRAG_SHADER_BLUR_ADD, val, k - width / 2,
j - height / 2);
assert(pc < shader_body + body_len);
@ -553,9 +555,10 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
strlen(shader_body) + 10 /* sum */ +
1 /* null terminator */;
char *shader_str = ccalloc(shader_len, char);
size_t real_shader_len = snprintf(
auto real_shader_len = snprintf(
shader_str, shader_len, FRAG_SHADER_BLUR, extension, shader_body, sum);
assert(real_shader_len < shader_len);
assert(real_shader_len >= 0);
assert((size_t)real_shader_len < shader_len);
free(shader_body);
// Build program

View File

@ -162,7 +162,7 @@ static inline bool gl_has_extension(const char *ext) {
}
for (int i = 0; i < nexts; i++) {
const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, i);
const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, (GLuint)i);
if (strcmp(ext, exti) == 0)
return true;
}

View File

@ -44,7 +44,7 @@ struct _glx_data {
struct gl_data gl;
Display *display;
int screen;
int target_win;
xcb_window_t target_win;
int glx_event;
int glx_error;
GLXContext ctx;
@ -70,7 +70,7 @@ struct glx_fbconfig_info *glx_find_fbconfig(Display *dpy, int screen, struct xvi
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_X_RENDERABLE, true,
GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, GLX_DONT_CARE,
GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, (GLint)GLX_DONT_CARE,
GLX_BUFFER_SIZE, m.red_size + m.green_size +
m.blue_size + m.alpha_size,
GLX_RED_SIZE, m.red_size,
@ -117,7 +117,8 @@ struct glx_fbconfig_info *glx_find_fbconfig(Display *dpy, int screen, struct xvi
int visual;
glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_VISUAL_ID, &visual);
if (m.visual_depth != -1 &&
x_get_visual_depth(XGetXCBConnection(dpy), visual) != m.visual_depth) {
x_get_visual_depth(XGetXCBConnection(dpy), (xcb_visualid_t)visual) !=
m.visual_depth) {
// Some driver might attach fbconfig to a GLX visual with a
// different depth.
//
@ -347,6 +348,11 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
return false;
}
if (fmt.visual_depth < 0) {
log_error("Pixmap %#010x with invalid depth %d", pixmap, fmt.visual_depth);
return false;
}
auto r = xcb_get_geometry_reply(base->c, xcb_get_geometry(base->c, pixmap), NULL);
if (!r) {
log_error("Invalid pixmap %#010x", pixmap);
@ -400,7 +406,7 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
// Create texture
wd->texture.texture = gl_new_texture(GL_TEXTURE_2D);
wd->texture.opacity = 1;
wd->texture.depth = fmt.visual_depth;
wd->texture.depth = (unsigned int)fmt.visual_depth;
wd->texture.color_inverted = false;
wd->texture.dim = 0;
wd->texture.has_alpha = fmt.alpha_size != 0;
@ -475,7 +481,7 @@ static inline bool glx_has_extension(Display *dpy, int screen, const char *ext)
return false;
}
long inlen = strlen(ext);
auto inlen = strlen(ext);
const char *curr = glx_exts;
bool match = false;
while (curr && !match) {
@ -483,9 +489,9 @@ static inline bool glx_has_extension(Display *dpy, int screen, const char *ext)
if (!end) {
// Last extension string
match = strcmp(ext, curr) == 0;
} else if (end - curr == inlen) {
} else if (curr + inlen == end) {
// Length match, do match string
match = strncmp(ext, curr, end - curr) == 0;
match = strncmp(ext, curr, (unsigned long)(end - curr)) == 0;
}
curr = end ? end + 1 : NULL;
}

View File

@ -64,7 +64,7 @@ typedef struct _xrender_data {
/// Blur kernels converted to X format
xcb_render_fixed_t *x_blur_kern[MAX_BLUR_PASS];
/// Number of elements in each blur kernel
size_t x_blur_kern_size[MAX_BLUR_PASS];
int x_blur_kern_size[MAX_BLUR_PASS];
xcb_special_event_t *present_event;
} xrender_data;
@ -75,9 +75,9 @@ struct _xrender_image_data {
xcb_pixmap_t pixmap;
// A Picture links to the Pixmap
xcb_render_picture_t pict;
long width, height;
int width, height;
// The effective size of the image
long ewidth, eheight;
int ewidth, eheight;
bool has_alpha;
double opacity;
xcb_visualid_t visual;
@ -89,7 +89,7 @@ static void compose(backend_t *base, void *img_data, int dst_x, int dst_y,
const region_t *reg_paint, const region_t *reg_visible) {
struct _xrender_data *xd = (void *)base;
struct _xrender_image_data *img = img_data;
int op = (img->has_alpha ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC);
uint8_t op = (img->has_alpha ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC);
auto alpha_pict = xd->alpha_pict[(int)(img->opacity * 255.0)];
region_t reg;
pixman_region32_init(&reg);
@ -101,7 +101,8 @@ static void compose(backend_t *base, void *img_data, int dst_x, int dst_y,
x_set_picture_clip_region(base->c, xd->back[xd->curr_back], 0, 0, &reg);
xcb_render_composite(base->c, op, img->pict, alpha_pict, xd->back[xd->curr_back],
0, 0, 0, 0, dst_x, dst_y, img->ewidth, img->eheight);
0, 0, 0, 0, to_i16_checked(dst_x), to_i16_checked(dst_y),
to_u16_checked(img->ewidth), to_u16_checked(img->eheight));
pixman_region32_fini(&reg);
}
@ -113,13 +114,15 @@ fill(backend_t *base, double r, double g, double b, double a, const region_t *cl
// color is in X fixed point representation
xcb_render_fill_rectangles(
base->c, XCB_RENDER_PICT_OP_OVER, xd->back[xd->curr_back],
(xcb_render_color_t){
.red = r * 0xffff, .green = g * 0xffff, .blue = b * 0xffff, .alpha = a * 0xffff},
(xcb_render_color_t){.red = (uint16_t)(r * 0xffff),
.green = (uint16_t)(g * 0xffff),
.blue = (uint16_t)(b * 0xffff),
.alpha = (uint16_t)(a * 0xffff)},
1,
(xcb_rectangle_t[]){{.x = extent->x1,
.y = extent->y1,
.width = extent->x2 - extent->x1,
.height = extent->y2 - extent->y1}});
(xcb_rectangle_t[]){{.x = to_i16_checked(extent->x1),
.y = to_i16_checked(extent->y1),
.width = to_u16_checked(extent->x2 - extent->x1),
.height = to_u16_checked(extent->y2 - extent->y1)}});
}
static bool blur(backend_t *backend_data, double opacity, const region_t *reg_blur,
@ -135,9 +138,10 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
}
const pixman_box32_t *extent = pixman_region32_extents(&reg_op);
const int height = extent->y2 - extent->y1;
const int width = extent->x2 - extent->x1;
int src_x = extent->x1, src_y = extent->y1;
const auto height = to_u16_checked(extent->y2 - extent->y1);
const auto width = to_u16_checked(extent->x2 - extent->x1);
auto src_x = to_i16_checked(extent->x1);
auto src_y = to_i16_checked(extent->y1);
static const char *filter0 = "Nearest"; // The "null" filter
static const char *filter = "convolution";
@ -183,8 +187,9 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
// be applied on source picture, to get the nearby pixels outside the
// window.
// TODO cache converted blur_kerns
xcb_render_set_picture_filter(c, src_pict, strlen(filter), filter,
xd->x_blur_kern_size[i], xd->x_blur_kern[i]);
xcb_render_set_picture_filter(
c, src_pict, to_u16_checked(strlen(filter)), filter,
to_u32_checked(xd->x_blur_kern_size[i]), xd->x_blur_kern[i]);
if (xd->x_blur_kern[i + 1] || i == 0) {
// This is not the last pass, or this is the first pass
@ -199,7 +204,8 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
}
// reset filter
xcb_render_set_picture_filter(c, src_pict, strlen(filter0), filter0, 0, NULL);
xcb_render_set_picture_filter(
c, src_pict, to_u16_checked(strlen(filter0)), filter0, 0, NULL);
src_pict = tmp_picture[current];
dst_pict = tmp_picture[!current];
@ -211,8 +217,9 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
// There is only 1 pass
if (i == 1) {
xcb_render_composite(c, XCB_RENDER_PICT_OP_OVER, src_pict, alpha_pict,
xd->back[xd->curr_back], 0, 0, 0, 0, extent->x1,
extent->y1, width, height);
xd->back[xd->curr_back], 0, 0, 0, 0,
to_i16_checked(extent->x1),
to_i16_checked(extent->y1), width, height);
}
xcb_render_free_picture(c, tmp_picture[0]);
@ -232,7 +239,7 @@ bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool
}
auto img = ccalloc(1, struct _xrender_image_data);
img->depth = fmt.visual_depth;
img->depth = (uint8_t)fmt.visual_depth;
img->width = img->ewidth = r->width;
img->height = img->eheight = r->height;
img->pixmap = pixmap;
@ -328,7 +335,8 @@ static void present(backend_t *base) {
// but that will require a different backend API
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_SRC,
xd->back[xd->curr_back], XCB_NONE, xd->target, 0, 0,
0, 0, 0, 0, xd->target_width, xd->target_height);
0, 0, 0, 0, to_u16_checked(xd->target_width),
to_u16_checked(xd->target_height));
xd->buffer_age[xd->curr_back] = 1;
}
}
@ -358,6 +366,8 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
pixman_region32_init(&reg);
const auto tmpw = to_u16_checked(img->width);
const auto tmph = to_u16_checked(img->height);
switch (op) {
case IMAGE_OP_INVERT_COLOR_ALL:
x_set_picture_clip_region(base->c, img->pict, 0, 0, reg_visible);
@ -366,36 +376,35 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
x_create_picture_with_visual(base->c, base->root, img->width,
img->height, img->visual, 0, NULL);
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_SRC, img->pict,
XCB_NONE, tmp_pict, 0, 0, 0, 0, 0, 0,
img->width, img->height);
XCB_NONE, tmp_pict, 0, 0, 0, 0, 0, 0, tmpw, tmph);
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_DIFFERENCE,
xd->white_pixel, XCB_NONE, tmp_pict, 0, 0, 0,
0, 0, 0, img->width, img->height);
0, 0, 0, tmpw, tmph);
// We use an extra PictOpInReverse operation to get correct pixel
// alpha. There could be a better solution.
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_IN_REVERSE,
tmp_pict, XCB_NONE, img->pict, 0, 0, 0, 0, 0,
0, img->width, img->height);
0, tmpw, tmph);
xcb_render_free_picture(base->c, tmp_pict);
} else {
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_DIFFERENCE,
xd->white_pixel, XCB_NONE, img->pict, 0, 0,
0, 0, 0, 0, img->width, img->height);
0, 0, 0, 0, tmpw, tmph);
}
break;
case IMAGE_OP_DIM_ALL:
x_set_picture_clip_region(base->c, img->pict, 0, 0, reg_visible);
xcb_render_color_t color = {
.red = 0, .green = 0, .blue = 0, .alpha = 0xffff * dargs[0]};
.red = 0, .green = 0, .blue = 0, .alpha = (uint16_t)(0xffff * dargs[0])};
// Dim the actually content of window
xcb_rectangle_t rect = {
.x = 0,
.y = 0,
.width = img->width,
.height = img->height,
.width = tmpw,
.height = tmph,
};
xcb_render_fill_rectangles(base->c, XCB_RENDER_PICT_OP_OVER, img->pict,
@ -415,7 +424,7 @@ static bool image_op(backend_t *base, enum image_operations op, void *image,
auto alpha_pict = xd->alpha_pict[(int)(dargs[0] * 255)];
x_set_picture_clip_region(base->c, img->pict, 0, 0, &reg);
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_IN, img->pict, XCB_NONE,
alpha_pict, 0, 0, 0, 0, 0, 0, img->width, img->height);
alpha_pict, 0, 0, 0, 0, 0, 0, tmpw, tmph);
img->has_alpha = true;
break;
case IMAGE_OP_RESIZE_TILE:
@ -454,10 +463,11 @@ static void *copy(backend_t *base, const void *image, const region_t *reg) {
return NULL;
}
auto alpha_pict =
xcb_render_picture_t alpha_pict =
img->opacity == 1 ? XCB_NONE : xd->alpha_pict[(int)(img->opacity * 255)];
xcb_render_composite(base->c, XCB_RENDER_PICT_OP_SRC, img->pict, alpha_pict,
new_img->pict, 0, 0, 0, 0, 0, 0, img->width, img->height);
new_img->pict, 0, 0, 0, 0, 0, 0, to_u16_checked(img->width),
to_u16_checked(img->height));
return new_img;
}
@ -526,7 +536,8 @@ backend_t *backend_xrender_init(session_t *ps) {
int pixmap_needed = xd->vsync ? 2 : 1;
for (int i = 0; i < pixmap_needed; i++) {
xd->back_pixmap[i] = x_create_pixmap(ps->c, pictfmt->depth, ps->root,
ps->root_width, ps->root_height);
to_u16_checked(ps->root_width),
to_u16_checked(ps->root_height));
xd->back[i] = x_create_picture_with_pictfmt_and_pixmap(
ps->c, pictfmt, xd->back_pixmap[i], 0, NULL);
xd->buffer_age[i] = -1;