diff --git a/.circleci/config.yml b/.circleci/config.yml
index 1c859f72..dcd8f587 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -3,6 +3,8 @@ executors:
docker:
- image: yshui/comptonci
working_directory: "/tmp/workspace"
+ environment:
+ UBSAN_OPTIONS: "halt_on_error=1"
version: 2.1
commands:
diff --git a/meson.build b/meson.build
index 2251f40b..6fe5e1b0 100644
--- a/meson.build
+++ b/meson.build
@@ -46,8 +46,8 @@ endif
add_global_arguments('-D_GNU_SOURCE', language: 'c')
-warns = [ 'all', 'extra', 'no-unused-parameter', 'nonnull', 'shadow',
- 'implicit-fallthrough', 'no-unknown-warning-option', 'no-missing-braces' ]
+warns = [ 'all', 'extra', 'no-unused-parameter', 'nonnull', 'shadow', 'no-type-limits',
+ 'implicit-fallthrough', 'no-unknown-warning-option', 'no-missing-braces', 'conversion' ]
foreach w : warns
if cc.has_argument('-W'+w)
add_global_arguments('-W'+w, language: 'c')
diff --git a/src/backend/backend.c b/src/backend/backend.c
index a2e612ac..ceba1704 100644
--- a/src/backend/backend.c
+++ b/src/backend/backend.c
@@ -39,8 +39,8 @@ region_t get_damage(session_t *ps, bool all_damage) {
pixman_region32_copy(®ion, &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(®ion, ®ion, &ps->damage_ring[curr]);
}
diff --git a/src/backend/backend_common.c b/src/backend/backend_common.c
index 644dbe9d..5d7b7b1b 100644
--- a/src/backend/backend_common.c
+++ b/src/backend/backend_common.c
@@ -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;
diff --git a/src/backend/backend_common.h b/src/backend/backend_common.h
index d0e9136e..40fdf488 100644
--- a/src/backend/backend_common.h
+++ b/src/backend/backend_common.h
@@ -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);
diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c
index 6e8b788e..8cc91c89 100644
--- a/src/backend/gl/gl_common.c
+++ b/src/backend/gl/gl_common.c
@@ -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
diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h
index 03ad3535..2ada4dba 100644
--- a/src/backend/gl/gl_common.h
+++ b/src/backend/gl/gl_common.h
@@ -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;
}
diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c
index 782fb4b9..ebcc73ca 100644
--- a/src/backend/gl/glx.c
+++ b/src/backend/gl/glx.c
@@ -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;
}
diff --git a/src/backend/xrender.c b/src/backend/xrender.c
index 4b67aec6..193f26d3 100644
--- a/src/backend/xrender.c
+++ b/src/backend/xrender.c
@@ -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(®);
@@ -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, ®);
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(®);
}
@@ -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(®_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(®);
+ 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, ®);
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;
diff --git a/src/c2.c b/src/c2.c
index fae0d26d..b51acf01 100644
--- a/src/c2.c
+++ b/src/c2.c
@@ -106,8 +106,8 @@ struct _c2_l {
xcb_atom_t tgtatom;
bool tgt_onframe;
int index;
- enum { C2_L_PUNDEFINED,
- C2_L_PID,
+ enum { C2_L_PUNDEFINED = -1,
+ C2_L_PID = 0,
C2_L_PX,
C2_L_PY,
C2_L_PX2,
@@ -554,17 +554,19 @@ static int c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
}
// Copy target name out
- unsigned tgtlen = 0;
+ int tgtlen = 0;
for (; pattern[offset] && (isalnum(pattern[offset]) || '_' == pattern[offset]);
++offset) {
++tgtlen;
}
- if (!tgtlen)
+ if (!tgtlen) {
c2_error("Empty target.");
- pleaf->tgt = strndup(&pattern[offset - tgtlen], tgtlen);
+ }
+ pleaf->tgt = strndup(&pattern[offset - tgtlen], (size_t)tgtlen);
// Check for predefined targets
- for (unsigned i = 1; i < sizeof(C2_PREDEFS) / sizeof(C2_PREDEFS[0]); ++i) {
+ static const int npredefs = (int)(sizeof(C2_PREDEFS) / sizeof(C2_PREDEFS[0]));
+ for (int i = 0; i < npredefs; ++i) {
if (!strcmp(C2_PREDEFS[i].name, pleaf->tgt)) {
pleaf->predef = i;
pleaf->type = C2_PREDEFS[i].type;
@@ -573,25 +575,6 @@ static int c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
}
}
- // Alias for predefined targets
- if (!pleaf->predef) {
-#define TGTFILL(pdefid) \
- (pleaf->predef = pdefid, pleaf->type = C2_PREDEFS[pdefid].type, \
- pleaf->format = C2_PREDEFS[pdefid].format)
-
- // if (!strcmp("WM_NAME", tgt) || !strcmp("_NET_WM_NAME", tgt))
- // TGTFILL(C2_L_PNAME);
-#undef TGTFILL
-
- // Alias for custom properties
-#define TGTFILL(target, type, format) \
- (pleaf->target = strdup(target), pleaf->type = type, pleaf->format = format)
-
- // if (!strcmp("SOME_ALIAS"))
- // TGTFILL("ALIAS_TEXT", C2_L_TSTRING, 32);
-#undef TGTFILL
- }
-
C2H_SKIP_SPACES();
// Parse target-on-frame flag
@@ -607,27 +590,29 @@ static int c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
C2H_SKIP_SPACES();
- int index = -1;
+ long index = -1;
char *endptr = NULL;
index = strtol(pattern + offset, &endptr, 0);
- if (!endptr || pattern + offset == endptr)
+ if (!endptr || pattern + offset == endptr) {
c2_error("No index number found after bracket.");
-
- if (index < 0)
+ }
+ if (index < 0) {
c2_error("Index number invalid.");
-
- if (pleaf->predef)
+ }
+ if (pleaf->predef != C2_L_PUNDEFINED) {
c2_error("Predefined targets can't have index.");
+ }
- pleaf->index = index;
- offset = endptr - pattern;
+ pleaf->index = to_int_checked(index);
+ offset = to_int_checked(endptr - pattern);
C2H_SKIP_SPACES();
- if (']' != pattern[offset])
+ if (pattern[offset] != ']') {
c2_error("Index end marker not found.");
+ }
++offset;
@@ -641,44 +626,43 @@ static int c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
// Look for format
bool hasformat = false;
- int format = 0;
+ long format = 0;
{
char *endptr = NULL;
format = strtol(pattern + offset, &endptr, 0);
assert(endptr);
- if ((hasformat = (endptr && endptr != pattern + offset)))
- offset = endptr - pattern;
+ if ((hasformat = (endptr && endptr != pattern + offset))) {
+ offset = to_int_checked(endptr - pattern);
+ }
C2H_SKIP_SPACES();
}
// Look for type
enum c2_l_type type = C2_L_TUNDEFINED;
- {
- switch (pattern[offset]) {
- case 'w': type = C2_L_TWINDOW; break;
- case 'd': type = C2_L_TDRAWABLE; break;
- case 'c': type = C2_L_TCARDINAL; break;
- case 's': type = C2_L_TSTRING; break;
- case 'a': type = C2_L_TATOM; break;
- default: c2_error("Invalid type character.");
- }
-
- if (type) {
- if (pleaf->predef) {
- log_warn("Type specified for a default target "
- "will be ignored.");
- } else {
- if (pleaf->type && type != pleaf->type)
- log_warn("Default type overridden on "
- "target.");
- pleaf->type = type;
- }
- }
-
- offset++;
- C2H_SKIP_SPACES();
+ switch (pattern[offset]) {
+ case 'w': type = C2_L_TWINDOW; break;
+ case 'd': type = C2_L_TDRAWABLE; break;
+ case 'c': type = C2_L_TCARDINAL; break;
+ case 's': type = C2_L_TSTRING; break;
+ case 'a': type = C2_L_TATOM; break;
+ default: c2_error("Invalid type character.");
}
+ if (type) {
+ if (pleaf->predef != C2_L_PUNDEFINED) {
+ log_warn("Type specified for a default target "
+ "will be ignored.");
+ } else {
+ if (pleaf->type && type != pleaf->type)
+ log_warn("Default type overridden on "
+ "target.");
+ pleaf->type = type;
+ }
+ }
+
+ offset++;
+ C2H_SKIP_SPACES();
+
// Default format
if (!pleaf->format) {
switch (pleaf->type) {
@@ -692,20 +676,20 @@ static int c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
// Write format
if (hasformat) {
- if (pleaf->predef)
- log_warn("Format \"%d\" specified on a default target "
+ if (pleaf->predef != C2_L_PUNDEFINED) {
+ log_warn("Format \"%ld\" specified on a default target "
"will be ignored.",
format);
- else if (C2_L_TSTRING == pleaf->type)
- log_warn("Format \"%d\" specified on a string target "
+ } else if (pleaf->type == C2_L_TSTRING) {
+ log_warn("Format \"%ld\" specified on a string target "
"will be ignored.",
format);
- else {
+ } else {
if (pleaf->format && pleaf->format != format)
log_warn("Default format %d overridden on "
"target.",
pleaf->format);
- pleaf->format = format;
+ pleaf->format = to_int_checked(format);
}
}
}
@@ -798,52 +782,51 @@ static int c2_parse_pattern(const char *pattern, int offset, c2_ptr_t *presult)
c2_l_t *const pleaf = presult->l;
// Exists operator cannot have pattern
- if (!pleaf->op)
+ if (!pleaf->op) {
return offset;
+ }
C2H_SKIP_SPACES();
char *endptr = NULL;
- // Check for boolean patterns
if (!strcmp_wd("true", &pattern[offset])) {
pleaf->ptntype = C2_L_PTINT;
pleaf->ptnint = true;
- offset += strlen("true");
+ offset += 4; // length of "true";
} else if (!strcmp_wd("false", &pattern[offset])) {
pleaf->ptntype = C2_L_PTINT;
pleaf->ptnint = false;
- offset += strlen("false");
- }
- // Check for integer patterns
- else if (pleaf->ptnint = strtol(pattern + offset, &endptr, 0),
- pattern + offset != endptr) {
+ offset += 5; // length of "false";
+ } else if (pleaf->ptnint = strtol(pattern + offset, &endptr, 0),
+ pattern + offset != endptr) {
pleaf->ptntype = C2_L_PTINT;
- offset = endptr - pattern;
+ offset = to_int_checked(endptr - pattern);
// Make sure we are stopping at the end of a word
- if (isalnum(pattern[offset]))
+ if (isalnum(pattern[offset])) {
c2_error("Trailing characters after a numeric pattern.");
- }
- // Check for string patterns
- else {
+ }
+ } else {
+ // Parse string patterns
bool raw = false;
char delim = '\0';
// String flags
- if ('r' == tolower(pattern[offset])) {
+ if (tolower(pattern[offset]) == 'r') {
raw = true;
++offset;
C2H_SKIP_SPACES();
}
// Check for delimiters
- if ('\"' == pattern[offset] || '\'' == pattern[offset]) {
+ if (pattern[offset] == '\"' || pattern[offset] == '\'') {
pleaf->ptntype = C2_L_PTSTRING;
delim = pattern[offset];
++offset;
}
- if (C2_L_PTSTRING != pleaf->ptntype)
+ if (pleaf->ptntype != C2_L_PTSTRING) {
c2_error("Invalid pattern type.");
+ }
// Parse the string now
// We can't determine the length of the pattern, so we use the length
@@ -876,8 +859,7 @@ static int c2_parse_pattern(const char *pattern, int offset, c2_ptr_t *presult)
if (pstr != &tstr[2] || val <= 0)
c2_error("Invalid octal/hex escape "
"sequence.");
- assert(val < 256 && val >= 0);
- *(ptptnstr++) = val;
+ *(ptptnstr++) = to_char_checked(val);
offset += 2;
break;
}
@@ -929,10 +911,10 @@ fail:
* Parse a condition with legacy syntax.
*/
static int c2_parse_legacy(const char *pattern, int offset, c2_ptr_t *presult) {
- unsigned plen = strlen(pattern + offset);
-
- if (plen < 4 || ':' != pattern[offset + 1] || !strchr(pattern + offset + 2, ':'))
+ if (strlen(pattern + offset) < 4 || pattern[offset + 1] != ':' ||
+ !strchr(pattern + offset + 2, ':')) {
c2_error("Legacy parser: Invalid format.");
+ }
// Allocate memory for new leaf
auto pleaf = cmalloc(c2_l_t);
@@ -1000,7 +982,7 @@ static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
}
// Get target atom if it's not a predefined one
- if (!pleaf->predef) {
+ if (pleaf->predef == C2_L_PUNDEFINED) {
pleaf->tgtatom = get_atom(ps, pleaf->tgt);
if (!pleaf->tgtatom) {
log_error("Failed to get atom for target \"%s\".", pleaf->tgt);
@@ -1027,20 +1009,18 @@ static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
// Enable specific tracking options in compton if needed by the condition
// TODO: Add track_leader
- if (pleaf->predef) {
- switch (pleaf->predef) {
- case C2_L_PFOCUSED: ps->o.track_focus = true; break;
- // case C2_L_PROUNDED: ps->o.detect_rounded_corners = true; break;
- case C2_L_PNAME:
- case C2_L_PCLASSG:
- case C2_L_PCLASSI:
- case C2_L_PROLE: ps->o.track_wdata = true; break;
- default: break;
- }
+ switch (pleaf->predef) {
+ case C2_L_PFOCUSED: ps->o.track_focus = true; break;
+ // case C2_L_PROUNDED: ps->o.detect_rounded_corners = true; break;
+ case C2_L_PNAME:
+ case C2_L_PCLASSG:
+ case C2_L_PCLASSI:
+ case C2_L_PROLE: ps->o.track_wdata = true; break;
+ default: break;
}
// Warn about lower case characters in target name
- if (!pleaf->predef) {
+ if (pleaf->predef == C2_L_PUNDEFINED) {
for (const char *pc = pleaf->tgt; *pc; ++pc) {
if (islower(*pc)) {
log_warn("Lowercase character in target name \"%s\".",
@@ -1160,10 +1140,11 @@ c2_lptr_t *c2_free_lptr(c2_lptr_t *lp) {
* Get a string representation of a rule target.
*/
static const char *c2h_dump_str_tgt(const c2_l_t *pleaf) {
- if (pleaf->predef)
+ if (pleaf->predef != C2_L_PUNDEFINED) {
return C2_PREDEFS[pleaf->predef].name;
- else
+ } else {
return pleaf->tgt;
+ }
}
/**
@@ -1298,8 +1279,9 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
const xcb_window_t wid = (pleaf->tgt_onframe ? w->client_win : w->id);
// Return if wid is missing
- if (!pleaf->predef && !wid)
+ if (pleaf->predef == C2_L_PUNDEFINED && !wid) {
return;
+ }
const int idx = (pleaf->index < 0 ? 0 : pleaf->index);
@@ -1310,7 +1292,7 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
// Get the value
// A predefined target
- if (pleaf->predef) {
+ if (pleaf->predef != C2_L_PUNDEFINED) {
*perr = false;
switch (pleaf->predef) {
case C2_L_PID: tgt = wid; break;
@@ -1355,7 +1337,9 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
// Do comparison
switch (pleaf->op) {
- case C2_L_OEXISTS: *pres = (pleaf->predef ? tgt : true); break;
+ case C2_L_OEXISTS:
+ *pres = (pleaf->predef != C2_L_PUNDEFINED ? tgt : true);
+ break;
case C2_L_OEQ: *pres = (tgt == pleaf->ptnint); break;
case C2_L_OGT: *pres = (tgt > pleaf->ptnint); break;
case C2_L_OGTEQ: *pres = (tgt >= pleaf->ptnint); break;
@@ -1373,7 +1357,7 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
char *tgt_free = NULL;
// A predefined target
- if (pleaf->predef) {
+ if (pleaf->predef != C2_L_PUNDEFINED) {
switch (pleaf->predef) {
case C2_L_PWINDOWTYPE: tgt = WINTYPES[w->window_type]; break;
case C2_L_PNAME: tgt = w->name; break;
@@ -1382,20 +1366,19 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
case C2_L_PROLE: tgt = w->role; break;
default: assert(0); break;
}
- }
- // If it's an atom type property, convert atom to string
- else if (C2_L_TATOM == pleaf->type) {
+ } else if (pleaf->type == C2_L_TATOM) {
+ // An atom type property, convert it to string
winprop_t prop =
wid_get_prop_adv(ps, wid, pleaf->tgtatom, idx, 1L,
c2_get_atom_type(pleaf), pleaf->format);
- xcb_atom_t atom = winprop_get_int(prop);
+ xcb_atom_t atom = (xcb_atom_t)winprop_get_int(prop);
if (atom) {
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(
ps->c, xcb_get_atom_name(ps->c, atom), NULL);
if (reply) {
- tgt_free =
- strndup(xcb_get_atom_name_name(reply),
- xcb_get_atom_name_name_length(reply));
+ tgt_free = strndup(
+ xcb_get_atom_name_name(reply),
+ (size_t)xcb_get_atom_name_name_length(reply));
free(reply);
}
}
@@ -1403,9 +1386,8 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
tgt = tgt_free;
}
free_winprop(&prop);
- }
- // Otherwise, just fetch the string list
- else {
+ } else {
+ // Not an atom type, just fetch the string list
char **strlst = NULL;
int nstr;
if (wid_get_text_prop(ps, wid, pleaf->tgtatom, &strlst, &nstr) &&
@@ -1456,8 +1438,10 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
} break;
case C2_L_MPCRE:
#ifdef CONFIG_REGEX_PCRE
- *pres = (pcre_exec(pleaf->regex_pcre, pleaf->regex_pcre_extra,
- tgt, strlen(tgt), 0, 0, NULL, 0) >= 0);
+ assert(strlen(tgt) <= INT_MAX);
+ *pres =
+ (pcre_exec(pleaf->regex_pcre, pleaf->regex_pcre_extra,
+ tgt, (int)strlen(tgt), 0, 0, NULL, 0) >= 0);
#else
assert(0);
#endif
diff --git a/src/common.h b/src/common.h
index 997f6379..407d0bb9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -186,8 +186,8 @@ struct _glx_texture {
GLXPixmap glpixmap;
xcb_pixmap_t pixmap;
GLenum target;
- unsigned width;
- unsigned height;
+ int width;
+ int height;
bool y_inverted;
};
@@ -366,7 +366,7 @@ typedef struct session {
/// Pre-generated alpha pictures.
xcb_render_picture_t *alpha_picts;
/// Time of last fading. In milliseconds.
- unsigned long fade_time;
+ long fade_time;
/// Head pointer of the error ignore linked list.
ignore_t *ignore_head;
/// Pointer to the next
member of tail element of the error
@@ -416,7 +416,7 @@ typedef struct session {
// === Software-optimization-related ===
/// Currently used refresh rate.
- short refresh_rate;
+ int refresh_rate;
/// Interval between refresh in nanoseconds.
long refresh_intv;
/// Nanosecond offset of the first painting.
@@ -566,20 +566,20 @@ static inline int timeval_ms_cmp(struct timeval *ptv, unsigned long ms) {
// We use those if statement instead of a - expression because of possible
// truncation problem from long to int.
- {
- long sec = ms / MS_PER_SEC;
- if (ptv->tv_sec > sec)
- return 1;
- if (ptv->tv_sec < sec)
- return -1;
+ auto sec = (long)(ms / MS_PER_SEC);
+ if (ptv->tv_sec > sec) {
+ return 1;
+ }
+ if (ptv->tv_sec < sec) {
+ return -1;
}
- {
- long usec = ms % MS_PER_SEC * (US_PER_SEC / MS_PER_SEC);
- if (ptv->tv_usec > usec)
- return 1;
- if (ptv->tv_usec < usec)
- return -1;
+ auto usec = (long)(ms % MS_PER_SEC * (US_PER_SEC / MS_PER_SEC));
+ if (ptv->tv_usec > usec) {
+ return 1;
+ }
+ if (ptv->tv_usec < usec) {
+ return -1;
}
return 0;
@@ -712,7 +712,8 @@ _Noreturn static inline void die(const char *msg) {
*/
static inline xcb_atom_t get_atom(session_t *ps, const char *atom_name) {
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(
- ps->c, xcb_intern_atom(ps->c, 0, strlen(atom_name), atom_name), NULL);
+ ps->c,
+ xcb_intern_atom(ps->c, 0, to_u16_checked(strlen(atom_name)), atom_name), NULL);
xcb_atom_t atom = XCB_NONE;
if (reply) {
diff --git a/src/compiler.h b/src/compiler.h
index b44562b2..e26736fb 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -95,3 +95,6 @@
#else
# define thread_local _Pragma("GCC error \"No thread local storage support\"") __error__
#endif
+
+typedef unsigned long ulong;
+typedef unsigned int uint;
diff --git a/src/compton.c b/src/compton.c
index 3565284d..a4e3ce3a 100644
--- a/src/compton.c
+++ b/src/compton.c
@@ -108,10 +108,10 @@ static inline void free_xinerama_info(session_t *ps) {
/**
* Get current system clock in milliseconds.
*/
-static inline uint64_t get_time_ms(void) {
+static inline int64_t get_time_ms(void) {
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
- return tp.tv_sec * ((uint64_t)1000ul) + tp.tv_nsec / 1000000;
+ return (int64_t)tp.tv_sec * 1000 + (int64_t)tp.tv_nsec / 1000000;
}
// XXX Move to x.c
@@ -202,11 +202,11 @@ static double fade_timeout(session_t *ps) {
if (ps->o.fade_delta + ps->fade_time < now)
return 0;
- int diff = ps->o.fade_delta + ps->fade_time - now;
+ auto diff = ps->o.fade_delta + ps->fade_time - now;
- diff = normalize_i_range(diff, 0, ps->o.fade_delta * 2);
+ diff = clamp(diff, 0, ps->o.fade_delta * 2);
- return diff / 1000.0;
+ return (double)diff / 1000.0;
}
/**
@@ -215,7 +215,7 @@ static double fade_timeout(session_t *ps) {
* @param steps steps of fading
* @return whether we are still in fading mode
*/
-static bool run_fade(session_t *ps, win **_w, unsigned steps) {
+static bool run_fade(session_t *ps, win **_w, long steps) {
win *w = *_w;
if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) {
// We are not fading
@@ -237,11 +237,11 @@ static bool run_fade(session_t *ps, win **_w, unsigned steps) {
if (steps) {
if (w->opacity < w->opacity_tgt) {
- w->opacity = normalize_d_range(
- w->opacity + ps->o.fade_in_step * steps, 0.0, w->opacity_tgt);
+ w->opacity = clamp(w->opacity + ps->o.fade_in_step * (double)steps,
+ 0.0, w->opacity_tgt);
} else {
- w->opacity = normalize_d_range(
- w->opacity - ps->o.fade_out_step * steps, w->opacity_tgt, 1);
+ w->opacity = clamp(w->opacity - ps->o.fade_out_step * (double)steps,
+ w->opacity_tgt, 1);
}
}
@@ -277,8 +277,8 @@ static int should_ignore(session_t *ps, unsigned long sequence) {
/**
* Determine the event mask for a window.
*/
-long determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) {
- long evmask = 0;
+uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) {
+ uint32_t evmask = 0;
win *w = NULL;
// Check if it's a mapped frame window
@@ -292,7 +292,7 @@ long determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) {
// Check if it's a mapped client window
if (WIN_EVMODE_CLIENT == mode ||
((w = find_toplevel(ps, wid)) && w->a.map_state == XCB_MAP_STATE_VIEWABLE)) {
- if (ps->o.frame_opacity || ps->o.track_wdata || ps->track_atom_lst ||
+ if (ps->o.frame_opacity > 0 || ps->o.track_wdata || ps->track_atom_lst ||
ps->o.detect_client_opacity)
evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE;
}
@@ -412,7 +412,7 @@ static void handle_root_flags(session_t *ps) {
"temporarily disabled");
}
}
- ps->root_flags &= ~ROOT_FLAGS_SCREEN_CHANGE;
+ ps->root_flags &= ~(uint64_t)ROOT_FLAGS_SCREEN_CHANGE;
}
}
@@ -423,7 +423,7 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
*fade_running = false;
// Fading step calculation
- unsigned long steps = 0L;
+ long steps = 0L;
auto now = get_time_ms();
if (ps->fade_time) {
assert(now >= ps->fade_time);
@@ -616,8 +616,9 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
if (!ps->o.unredir_if_possible_delay || ps->tmout_unredir_hit)
redir_stop(ps);
else if (!ev_is_active(&ps->unredir_timer)) {
- ev_timer_set(&ps->unredir_timer,
- ps->o.unredir_if_possible_delay / 1000.0, 0);
+ ev_timer_set(
+ &ps->unredir_timer,
+ (double)ps->o.unredir_if_possible_delay / 1000.0, 0);
ev_timer_start(ps->loop, &ps->unredir_timer);
}
}
@@ -1066,11 +1067,14 @@ void update_ewmh_active_win(session_t *ps) {
static bool register_cm(session_t *ps) {
assert(!ps->reg_win);
- ps->reg_win =
- XCreateSimpleWindow(ps->dpy, ps->root, 0, 0, 1, 1, 0, XCB_NONE, XCB_NONE);
+ ps->reg_win = xcb_generate_id(ps->c);
+ auto e = xcb_request_check(
+ ps->c, xcb_create_window_checked(ps->c, XCB_COPY_FROM_PARENT, ps->reg_win, ps->root,
+ 0, 0, 1, 1, 0, XCB_NONE, ps->vis, 0, NULL));
- if (!ps->reg_win) {
+ if (e) {
log_fatal("Failed to create window.");
+ free(e);
return false;
}
@@ -1092,7 +1096,7 @@ static bool register_cm(session_t *ps) {
// Set _NET_WM_PID
{
- uint32_t pid = getpid();
+ auto pid = getpid();
xcb_change_property(ps->c, XCB_PROP_MODE_REPLACE, ps->reg_win,
get_atom(ps, "_NET_WM_PID"), XCB_ATOM_CARDINAL, 32, 1,
&pid);
@@ -1108,7 +1112,7 @@ static bool register_cm(session_t *ps) {
if (!ps->o.no_x_selection) {
unsigned len = strlen(REGISTER_PROP) + 2;
int s = ps->scr;
- Atom atom;
+ xcb_atom_t atom;
while (s >= 10) {
++len;
@@ -1260,7 +1264,7 @@ static double swopti_handle_timeout(session_t *ps) {
return 0;
// Add an offset so we wait until the next refresh after timeout
- return (ps->refresh_intv - offset) / 1e6;
+ return (double)(ps->refresh_intv - offset) / 1e6;
}
/**
@@ -1768,10 +1772,13 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
XSetErrorHandler(xerror);
ps->scr = DefaultScreen(ps->dpy);
- ps->root = RootWindow(ps->dpy, ps->scr);
- ps->vis = XVisualIDFromVisual(DefaultVisual(ps->dpy, ps->scr));
- ps->depth = DefaultDepth(ps->dpy, ps->scr);
+ auto screen = x_screen_of_display(ps->c, ps->scr);
+ ps->vis = screen->root_visual;
+ ps->depth = screen->root_depth;
+ ps->root = screen->root;
+ ps->root_width = screen->width_in_pixels;
+ ps->root_height = screen->height_in_pixels;
// Start listening to events on root earlier to catch all possible
// root geometry changes
@@ -1786,9 +1793,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
free(e);
}
- ps->root_width = DisplayWidth(ps->dpy, ps->scr);
- ps->root_height = DisplayHeight(ps->dpy, ps->scr);
-
xcb_prefetch_extension_data(ps->c, &xcb_render_id);
xcb_prefetch_extension_data(ps->c, &xcb_composite_id);
xcb_prefetch_extension_data(ps->c, &xcb_damage_id);
diff --git a/src/compton.h b/src/compton.h
index 1e3e26aa..a6c47599 100644
--- a/src/compton.h
+++ b/src/compton.h
@@ -38,7 +38,7 @@ enum root_flags {
void add_damage(session_t *ps, const region_t *damage);
-long determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode);
+uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode);
xcb_window_t find_client_win(session_t *ps, xcb_window_t w);
diff --git a/src/config.c b/src/config.c
index fac6795c..89c70d91 100644
--- a/src/config.c
+++ b/src/config.c
@@ -3,6 +3,7 @@
// Copyright (c) 2013 Richard Grenville
#include
+#include
#include
#include
#include
@@ -42,6 +43,22 @@ bool parse_long(const char *s, long *dest) {
return true;
}
+/**
+ * Parse an int number.
+ */
+bool parse_int(const char *s, int *dest) {
+ long val;
+ if (!parse_long(s, &val)) {
+ return false;
+ }
+ if (val > INT_MAX || val < INT_MIN) {
+ log_error("Number exceeded int limits: %ld", val);
+ return false;
+ }
+ *dest = (int)val;
+ return true;
+}
+
/**
* Parse a floating-point number in from a string,
* also strips the trailing space and comma after the number.
@@ -82,11 +99,11 @@ conv *parse_blur_kern(const char *src, const char **endptr, bool *hasneg) {
if (src == (pc = parse_readnum(src, &val)))
goto err1;
src = pc;
- width = val;
+ width = (int)val;
if (src == (pc = parse_readnum(src, &val)))
goto err1;
src = pc;
- height = val;
+ height = (int)val;
// Validate matrix width and height
if (width <= 0 || height <= 0) {
@@ -102,7 +119,7 @@ conv *parse_blur_kern(const char *src, const char **endptr, bool *hasneg) {
"rendering, and/or consume lots of memory");
// Allocate memory
- conv *matrix = cvalloc(sizeof(conv) + width * height * sizeof(double));
+ conv *matrix = cvalloc(sizeof(conv) + (size_t)(width * height) * sizeof(double));
// Read elements
int skip = height / 2 * width + width / 2;
@@ -276,70 +293,76 @@ bool parse_blur_kern_lst(const char *src, conv **dest, int max, bool *hasneg) {
*/
bool parse_geometry(session_t *ps, const char *src, region_t *dest) {
pixman_region32_clear(dest);
- if (!src)
+ if (!src) {
return true;
- if (!ps->root_width || !ps->root_height)
+ }
+ if (!ps->root_width || !ps->root_height) {
return true;
+ }
- geometry_t geom = {.wid = ps->root_width, .hei = ps->root_height, .x = 0, .y = 0};
+ long x = 0, y = 0;
+ long width = ps->root_width, height = ps->root_height;
long val = 0L;
char *endptr = NULL;
src = skip_space(src);
- if (!*src)
+ if (!*src) {
goto parse_geometry_end;
+ }
// Parse width
// Must be base 10, because "0x0..." may appear
- if (!('+' == *src || '-' == *src)) {
+ if (*src != '+' && *src != '-') {
val = strtol(src, &endptr, 10);
assert(endptr);
if (src != endptr) {
- geom.wid = val;
- if (geom.wid < 0) {
+ if (val < 0) {
log_error("Invalid width: %s", src);
return false;
}
+ width = val;
src = endptr;
}
src = skip_space(src);
}
// Parse height
- if ('x' == *src) {
+ if (*src == 'x') {
++src;
val = strtol(src, &endptr, 10);
assert(endptr);
if (src != endptr) {
- geom.hei = val;
- if (geom.hei < 0) {
+ if (val < 0) {
log_error("Invalid height: %s", src);
return false;
}
+ height = val;
src = endptr;
}
src = skip_space(src);
}
// Parse x
- if ('+' == *src || '-' == *src) {
+ if (*src == '+' || *src == '-') {
val = strtol(src, &endptr, 10);
if (endptr && src != endptr) {
- geom.x = val;
- if (*src == '-')
- geom.x += ps->root_width - geom.wid;
+ x = val;
+ if (*src == '-') {
+ x += ps->root_width - width;
+ }
src = endptr;
}
src = skip_space(src);
}
// Parse y
- if ('+' == *src || '-' == *src) {
+ if (*src == '+' || *src == '-') {
val = strtol(src, &endptr, 10);
if (endptr && src != endptr) {
- geom.y = val;
- if (*src == '-')
- geom.y += ps->root_height - geom.hei;
+ y = val;
+ if (*src == '-') {
+ y += ps->root_height - height;
+ }
src = endptr;
}
src = skip_space(src);
@@ -351,7 +374,16 @@ bool parse_geometry(session_t *ps, const char *src, region_t *dest) {
}
parse_geometry_end:
- pixman_region32_union_rect(dest, dest, geom.x, geom.y, geom.wid, geom.hei);
+ if (x < INT_MIN || x > INT_MAX || y < INT_MIN || y > INT_MAX) {
+ log_error("Geometry coordinates exceeded limits: %s", src);
+ return false;
+ }
+ if (width > UINT_MAX || height > UINT_MAX) {
+ // less than 0 is checked for earlier
+ log_error("Geometry size exceeded limits: %s", src);
+ return false;
+ }
+ pixman_region32_union_rect(dest, dest, (int)x, (int)y, (uint)width, (uint)height);
return true;
}
diff --git a/src/config.h b/src/config.h
index 4c88ad0b..685bfd9e 100644
--- a/src/config.h
+++ b/src/config.h
@@ -97,7 +97,7 @@ typedef struct options_t {
/// when determining if a window could be unredirected.
c2_lptr_t *unredir_if_possible_blacklist;
/// Delay before unredirecting screen, in milliseconds.
- unsigned long unredir_if_possible_delay;
+ long unredir_if_possible_delay;
/// Forced redirection setting through D-Bus.
switch_t redirected_force;
/// Whether to stop painting. Controlled through D-Bus.
@@ -155,7 +155,7 @@ typedef struct options_t {
/// How much to fade out in a single fading step.
double fade_out_step;
/// Fading time delta. In milliseconds.
- unsigned long fade_delta;
+ int fade_delta;
/// Whether to disable fading on window open/close.
bool no_fading_openclose;
/// Whether to disable fading on ARGB managed destroyed windows.
@@ -227,10 +227,11 @@ typedef struct options_t {
extern const char *const BACKEND_STRS[NUM_BKEND + 1];
-attr_warn_unused_result bool parse_long(const char *, long *);
-attr_warn_unused_result bool parse_blur_kern_lst(const char *, conv **, int, bool *hasneg);
-attr_warn_unused_result bool parse_geometry(session_t *, const char *, region_t *);
-attr_warn_unused_result bool parse_rule_opacity(c2_lptr_t **, const char *);
+bool must_use parse_long(const char *, long *);
+bool must_use parse_int(const char *, int *);
+bool must_use parse_blur_kern_lst(const char *, conv **, int, bool *hasneg);
+bool must_use parse_geometry(session_t *, const char *, region_t *);
+bool must_use parse_rule_opacity(c2_lptr_t **, const char *);
/**
* Add a pattern to a condition linked list.
diff --git a/src/config_libconfig.c b/src/config_libconfig.c
index 5cbcba7d..ed836357 100644
--- a/src/config_libconfig.c
+++ b/src/config_libconfig.c
@@ -295,7 +295,12 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
// --detect-client-opacity
lcfg_lookup_bool(&cfg, "detect-client-opacity", &opt->detect_client_opacity);
// --refresh-rate
- config_lookup_int(&cfg, "refresh-rate", &opt->refresh_rate);
+ if (config_lookup_int(&cfg, "refresh-rate", &opt->refresh_rate)) {
+ if (opt->refresh_rate < 0) {
+ log_warn("Invalid refresh rate %d, fallback to 0", opt->refresh_rate);
+ opt->refresh_rate = 0;
+ }
+ }
// --vsync
if (config_lookup_string(&cfg, "vsync", &sval)) {
opt->vsync = parse_vsync(sval);
@@ -337,8 +342,13 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
// --unredir-if-possible
lcfg_lookup_bool(&cfg, "unredir-if-possible", &opt->unredir_if_possible);
// --unredir-if-possible-delay
- if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival))
- opt->unredir_if_possible_delay = ival;
+ if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival)) {
+ if (ival < 0) {
+ log_warn("Invalid unredir-if-possible-delay %d", ival);
+ } else {
+ opt->unredir_if_possible_delay = ival;
+ }
+ }
// --inactive-dim-fixed
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &opt->inactive_dim_fixed);
// --detect-transient
diff --git a/src/dbus.c b/src/dbus.c
index 2cdf4659..dc54b3e4 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -41,9 +41,9 @@ typedef uint32_t cdbus_window_t;
#define CDBUS_TYPE_WINDOW DBUS_TYPE_UINT32
#define CDBUS_TYPE_WINDOW_STR DBUS_TYPE_UINT32_AS_STRING
-typedef uint16_t cdbus_enum_t;
-#define CDBUS_TYPE_ENUM DBUS_TYPE_UINT16
-#define CDBUS_TYPE_ENUM_STR DBUS_TYPE_UINT16_AS_STRING
+typedef uint32_t cdbus_enum_t;
+#define CDBUS_TYPE_ENUM DBUS_TYPE_UINT32
+#define CDBUS_TYPE_ENUM_STR DBUS_TYPE_UINT32_AS_STRING
#define CDBUS_SERVICE_NAME "com.github.chjj.compton"
#define CDBUS_INTERFACE_NAME CDBUS_SERVICE_NAME
@@ -610,6 +610,14 @@ static inline bool cdbus_reply_int32(session_t *ps, DBusMessage *srcmsg, int32_t
return cdbus_reply(ps, srcmsg, cdbus_apdarg_int32, &val);
}
+/**
+ * Send a reply with an int32 argument, cast from a long.
+ */
+static inline bool cdbus_reply_int32l(session_t *ps, DBusMessage *srcmsg, long val) {
+ int32_t tmp = (int32_t)val;
+ return cdbus_reply(ps, srcmsg, cdbus_apdarg_int32, &tmp);
+}
+
/**
* Send a reply with an uint32 argument.
*/
@@ -786,12 +794,12 @@ static bool cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
cdbus_m_win_get_do(class_general, cdbus_reply_string);
cdbus_m_win_get_do(role, cdbus_reply_string);
- cdbus_m_win_get_do(opacity, cdbus_reply_uint32);
- cdbus_m_win_get_do(opacity_tgt, cdbus_reply_uint32);
+ cdbus_m_win_get_do(opacity, cdbus_reply_double);
+ cdbus_m_win_get_do(opacity_tgt, cdbus_reply_double);
cdbus_m_win_get_do(has_opacity_prop, cdbus_reply_bool);
cdbus_m_win_get_do(opacity_prop, cdbus_reply_uint32);
cdbus_m_win_get_do(opacity_is_set, cdbus_reply_bool);
- cdbus_m_win_get_do(opacity_set, cdbus_reply_uint32);
+ cdbus_m_win_get_do(opacity_set, cdbus_reply_double);
cdbus_m_win_get_do(frame_opacity, cdbus_reply_double);
if (!strcmp("left_width", target)) {
@@ -986,7 +994,7 @@ static bool cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
return true;
}
cdbus_m_opts_get_do(unredir_if_possible, cdbus_reply_bool);
- cdbus_m_opts_get_do(unredir_if_possible_delay, cdbus_reply_int32);
+ cdbus_m_opts_get_do(unredir_if_possible_delay, cdbus_reply_int32l);
cdbus_m_opts_get_do(redirected_force, cdbus_reply_enum);
cdbus_m_opts_get_do(stoppaint_force, cdbus_reply_enum);
cdbus_m_opts_get_do(logpath, cdbus_reply_string);
@@ -1010,8 +1018,8 @@ static bool cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
cdbus_m_opts_get_do(xinerama_shadow_crop, cdbus_reply_bool);
cdbus_m_opts_get_do(fade_delta, cdbus_reply_int32);
- cdbus_m_opts_get_do(fade_in_step, cdbus_reply_int32);
- cdbus_m_opts_get_do(fade_out_step, cdbus_reply_int32);
+ cdbus_m_opts_get_do(fade_in_step, cdbus_reply_double);
+ cdbus_m_opts_get_do(fade_out_step, cdbus_reply_double);
cdbus_m_opts_get_do(no_fading_openclose, cdbus_reply_bool);
cdbus_m_opts_get_do(blur_background, cdbus_reply_bool);
@@ -1066,10 +1074,14 @@ static bool cdbus_process_opts_set(session_t *ps, DBusMessage *msg) {
// fade_delta
if (!strcmp("fade_delta", target)) {
- int32_t val = 0.0;
- if (!cdbus_msg_get_arg(msg, 1, DBUS_TYPE_INT32, &val))
+ int32_t val = 0;
+ if (!cdbus_msg_get_arg(msg, 1, DBUS_TYPE_INT32, &val)) {
return false;
- ps->o.fade_delta = max_i(val, 1);
+ }
+ if (val <= 0) {
+ return false;
+ }
+ ps->o.fade_delta = max2(val, 1);
goto cdbus_process_opts_set_success;
}
diff --git a/src/event.c b/src/event.c
index 417377d1..a196ea47 100644
--- a/src/event.c
+++ b/src/event.c
@@ -4,8 +4,8 @@
#include
#include
-#include "compiler.h"
#include "common.h"
+#include "compiler.h"
#include "compton.h"
#include "event.h"
#include "utils.h"
@@ -93,7 +93,7 @@ static inline xcb_window_t attr_pure ev_window(session_t *ps, xcb_generic_event_
}
}
-static inline const char * ev_name(session_t *ps, xcb_generic_event_t *ev) {
+static inline const char *ev_name(session_t *ps, xcb_generic_event_t *ev) {
static char buf[128];
switch (ev->response_type & 0x7f) {
CASESTRRET(FocusIn);
@@ -363,7 +363,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
}
// If frame extents property changes
- if (ps->o.frame_opacity && ev->atom == ps->atom_frame_extents) {
+ if (ps->o.frame_opacity > 0 && ev->atom == ps->atom_frame_extents) {
win *w = find_toplevel(ps, ev->window);
if (w) {
win_update_frame_extents(ps, w, ev->window);
@@ -441,10 +441,10 @@ static inline void repair_win(session_t *ps, win *w) {
xcb_xfixes_region_t tmp = xcb_generate_id(ps->c);
xcb_xfixes_create_region(ps->c, tmp, 0, NULL);
set_ignore_cookie(ps, xcb_damage_subtract(ps->c, w->damage, XCB_NONE, tmp));
- xcb_xfixes_translate_region(ps->c, tmp, w->g.x + w->g.border_width,
- w->g.y + w->g.border_width);
x_fetch_region(ps->c, tmp, &parts);
xcb_xfixes_destroy_region(ps->c, tmp);
+ pixman_region32_translate(&parts, w->g.x + w->g.border_width,
+ w->g.y + w->g.border_width);
}
w->ever_damaged = true;
diff --git a/src/kernel.c b/src/kernel.c
index 07d810c7..5b1e997a 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -14,20 +14,10 @@ double sum_kernel(const conv *map, int x, int y, int width, int height) {
double ret = 0;
// Compute sum of values which are "in range"
- int xstart = x, xend = width + x;
- if (xstart < 0) {
- xstart = 0;
- }
- if (xend > map->w) {
- xend = map->w;
- }
- int ystart = y, yend = height + y;
- if (ystart < 0) {
- ystart = 0;
- }
- if (yend > map->h) {
- yend = map->h;
- }
+ int xstart = normalize_i_range(x, 0, map->w),
+ xend = normalize_i_range(width + x, 0, map->w);
+ int ystart = normalize_i_range(y, 0, map->h),
+ yend = normalize_i_range(height + y, 0, map->h);
assert(yend >= ystart && xend >= xstart);
int d = map->w;
@@ -70,11 +60,11 @@ static double attr_const gaussian(double r, double x, double y) {
conv *gaussian_kernel(double r) {
conv *c;
- int size = r * 2 + 1;
+ int size = (int)r * 2 + 1;
int center = size / 2;
double t;
- c = cvalloc(sizeof(conv) + size * size * sizeof(double));
+ c = cvalloc(sizeof(conv) + (size_t)(size * size) * sizeof(double));
c->w = c->h = size;
c->rsum = NULL;
t = 0.0;
diff --git a/src/log.c b/src/log.c
index 7a707212..7071d4c6 100644
--- a/src/log.c
+++ b/src/log.c
@@ -150,11 +150,13 @@ attr_printf(4, 5) void log_printf(struct log *l, int level, const char *func,
va_list args;
va_start(args, fmt);
- size_t blen = vasprintf(&buf, fmt, args);
+ int blen = vasprintf(&buf, fmt, args);
va_end(args);
- if (!buf)
+ if (blen < 0 || !buf) {
+ free(buf);
return;
+ }
struct timespec ts;
timespec_get(&ts, TIME_UTC);
@@ -163,9 +165,10 @@ attr_printf(4, 5) void log_printf(struct log *l, int level, const char *func,
strftime(time_buf, sizeof time_buf, "%x %T", tm);
char *time = NULL;
- size_t tlen = asprintf(&time, "%s.%03ld", time_buf, ts.tv_nsec / 1000000);
- if (!time) {
+ int tlen = asprintf(&time, "%s.%03ld", time_buf, ts.tv_nsec / 1000000);
+ if (tlen < 0 || !time) {
free(buf);
+ free(time);
return;
}
@@ -190,7 +193,7 @@ attr_printf(4, 5) void log_printf(struct log *l, int level, const char *func,
head->ops->writev(
head,
(struct iovec[]){{.iov_base = "[ ", .iov_len = 2},
- {.iov_base = time, .iov_len = tlen},
+ {.iov_base = time, .iov_len = (size_t)tlen},
{.iov_base = " ", .iov_len = 1},
{.iov_base = (void *)func, .iov_len = flen},
{.iov_base = " ", .iov_len = 1},
@@ -198,7 +201,7 @@ attr_printf(4, 5) void log_printf(struct log *l, int level, const char *func,
{.iov_base = (void *)log_level_str, .iov_len = llen},
{.iov_base = (void *)s, .iov_len = slen},
{.iov_base = " ] ", .iov_len = 3},
- {.iov_base = buf, .iov_len = blen},
+ {.iov_base = buf, .iov_len = (size_t)blen},
{.iov_base = "\n", .iov_len = 1}},
11);
head = head->next;
@@ -329,12 +332,12 @@ struct log_target *stderr_logger_new(void) {
/// such as apitrace
struct gl_string_marker_logger {
struct log_target tgt;
- void (*gl_string_marker)(GLsizei len, const char *);
+ PFNGLSTRINGMARKERGREMEDYPROC gl_string_marker;
};
void gl_string_marker_logger_write(struct log_target *tgt, const char *str, size_t len) {
auto g = (struct gl_string_marker_logger *)tgt;
- g->gl_string_marker(len, str);
+ g->gl_string_marker((GLsizei)len, str);
}
static const struct log_ops gl_string_marker_logger_ops = {
diff --git a/src/opengl.c b/src/opengl.c
index b29ba72c..65f339d0 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -323,45 +323,42 @@ bool glx_init_blur(session_t *ps) {
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
// Build shader
- {
- int width = kern->w, height = kern->h;
- int nele = width * height - 1;
- unsigned int len =
- strlen(FRAG_SHADER_BLUR_PREFIX) +
- strlen(sampler_type) + strlen(extension) +
- (strlen(shader_add) + strlen(texture_func) + 42) * nele +
- strlen(FRAG_SHADER_BLUR_SUFFIX) +
- strlen(texture_func) + 12 + 1;
- char *shader_str = ccalloc(len, char);
- char *pc = shader_str;
- sprintf(pc, FRAG_SHADER_BLUR_PREFIX, extension, sampler_type);
- pc += strlen(pc);
- assert(strlen(shader_str) < len);
+ int width = kern->w, height = kern->h;
+ int nele = width * height - 1;
+ assert(nele >= 0);
+ auto len =
+ strlen(FRAG_SHADER_BLUR_PREFIX) + strlen(sampler_type) +
+ strlen(extension) +
+ (strlen(shader_add) + strlen(texture_func) + 42) * (uint)nele +
+ strlen(FRAG_SHADER_BLUR_SUFFIX) + strlen(texture_func) + 12 + 1;
+ char *shader_str = ccalloc(len, char);
+ char *pc = shader_str;
+ sprintf(pc, FRAG_SHADER_BLUR_PREFIX, extension, sampler_type);
+ pc += strlen(pc);
+ assert(strlen(shader_str) < len);
- double sum = 0.0;
- for (int j = 0; j < height; ++j) {
- for (int k = 0; k < width; ++k) {
- if (height / 2 == j && width / 2 == k)
- continue;
- double val = kern->data[j * width + k];
- if (val == 0) {
- continue;
- }
- sum += val;
- sprintf(pc, shader_add, val, texture_func,
- k - width / 2, j - height / 2);
- pc += strlen(pc);
- assert(strlen(shader_str) < len);
+ double sum = 0.0;
+ for (int j = 0; j < height; ++j) {
+ for (int k = 0; k < width; ++k) {
+ if (height / 2 == j && width / 2 == k)
+ continue;
+ double val = kern->data[j * width + k];
+ if (val == 0) {
+ continue;
}
+ sum += val;
+ sprintf(pc, shader_add, val, texture_func,
+ k - width / 2, j - height / 2);
+ pc += strlen(pc);
+ assert(strlen(shader_str) < len);
}
-
- sprintf(pc, FRAG_SHADER_BLUR_SUFFIX, texture_func, sum);
- assert(strlen(shader_str) < len);
- ppass->frag_shader =
- gl_create_shader(GL_FRAGMENT_SHADER, shader_str);
- free(shader_str);
}
+ sprintf(pc, FRAG_SHADER_BLUR_SUFFIX, texture_func, sum);
+ assert(strlen(shader_str) < len);
+ ppass->frag_shader = gl_create_shader(GL_FRAGMENT_SHADER, shader_str);
+ free(shader_str);
+
if (!ppass->frag_shader) {
log_error("Failed to create fragment shader %d.", i);
free(extension);
@@ -443,8 +440,8 @@ bool glx_load_prog_main(session_t *ps, const char *vshader_str, const char *fsha
/**
* Bind a X pixmap to an OpenGL texture.
*/
-bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap, unsigned width,
- unsigned height, bool repeat, const struct glx_fbconfig_info *fbcfg) {
+bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap, int width,
+ int height, bool repeat, const struct glx_fbconfig_info *fbcfg) {
if (ps->o.backend != BKEND_GLX && ps->o.backend != BKEND_XR_GLX_HYBRID)
return true;
@@ -480,25 +477,27 @@ bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap,
}
// Create GLX pixmap
- unsigned depth = 0;
+ int depth = 0;
if (!ptex->glpixmap) {
need_release = false;
// Retrieve pixmap parameters, if they aren't provided
- if (!(width && height)) {
- Window rroot = None;
- int rx = 0, ry = 0;
- unsigned rbdwid = 0;
- if (!XGetGeometry(ps->dpy, pixmap, &rroot, &rx, &ry, &width,
- &height, &rbdwid, &depth)) {
+ if (!width || !height) {
+ auto r = xcb_get_geometry_reply(
+ ps->c, xcb_get_geometry(ps->c, pixmap), NULL);
+ if (!r) {
log_error("Failed to query info of pixmap %#010x.", pixmap);
return false;
}
- if (depth > OPENGL_MAX_DEPTH) {
+ if (r->depth > OPENGL_MAX_DEPTH) {
log_error("Requested depth %d higher than %d.", depth,
OPENGL_MAX_DEPTH);
return false;
}
+ depth = r->depth;
+ width = r->width;
+ height = r->height;
+ free(r);
}
// Determine texture target, copied from compiz
@@ -522,7 +521,7 @@ bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap,
GLX_TEXTURE_FORMAT_EXT,
fbcfg->texture_fmt,
GLX_TEXTURE_TARGET_EXT,
- tex_tgt,
+ (GLint)tex_tgt,
0,
};
@@ -636,7 +635,8 @@ void glx_set_clip(session_t *ps, const region_t *reg) {
region_t reg_new; \
int nrects; \
const rect_t *rects; \
- pixman_region32_init_rect(®_new, dx, dy, width, height); \
+ assert(width >= 0 && height >= 0); \
+ pixman_region32_init_rect(®_new, dx, dy, (uint)width, (uint)height); \
pixman_region32_intersect(®_new, ®_new, (region_t *)reg_tgt); \
rects = pixman_region32_rectangles(®_new, &nrects); \
glBegin(GL_QUADS); \
@@ -704,13 +704,13 @@ bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
inc_x += XFIXED_TO_DOUBLE(kern[0]) / 2;
inc_y += XFIXED_TO_DOUBLE(kern[1]) / 2;
}
- inc_x = min_i(ps->o.resize_damage, inc_x);
- inc_y = min_i(ps->o.resize_damage, inc_y);
+ inc_x = min2(ps->o.resize_damage, inc_x);
+ inc_y = min2(ps->o.resize_damage, inc_y);
- mdx = max_i(dx - inc_x, 0);
- mdy = max_i(dy - inc_y, 0);
- int mdx2 = min_i(dx + width + inc_x, ps->root_width),
- mdy2 = min_i(dy + height + inc_y, ps->root_height);
+ mdx = max2(dx - inc_x, 0);
+ mdy = max2(dy - inc_y, 0);
+ int mdx2 = min2(dx + width + inc_x, ps->root_width),
+ mdy2 = min2(dy + height + inc_y, ps->root_height);
mwidth = mdx2 - mdx;
mheight = mdy2 - mdy;
}
@@ -763,9 +763,9 @@ bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
// Texture scaling factor
GLfloat texfac_x = 1.0f, texfac_y = 1.0f;
- if (GL_TEXTURE_2D == tex_tgt) {
- texfac_x /= mwidth;
- texfac_y /= mheight;
+ if (tex_tgt == GL_TEXTURE_2D) {
+ texfac_x /= (GLfloat)mwidth;
+ texfac_y /= (GLfloat)mheight;
}
// Paint it back
@@ -816,39 +816,37 @@ bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
if (ppass->unifm_factor_center >= 0)
glUniform1f(ppass->unifm_factor_center, factor_center);
- {
- P_PAINTREG_START(crect) {
- const GLfloat rx = (crect.x1 - mdx) * texfac_x;
- const GLfloat ry = (mheight - (crect.y1 - mdy)) * texfac_y;
- const GLfloat rxe = rx + (crect.x2 - crect.x1) * texfac_x;
- const GLfloat rye = ry - (crect.y2 - crect.y1) * texfac_y;
- GLfloat rdx = crect.x1 - mdx;
- GLfloat rdy = mheight - crect.y1 + mdy;
- if (last_pass) {
- rdx = crect.x1;
- rdy = ps->root_height - crect.y1;
- }
- GLfloat rdxe = rdx + (crect.x2 - crect.x1);
- GLfloat rdye = rdy - (crect.y2 - crect.y1);
-
- // log_trace("%f, %f, %f, %f -> %f, %f, %f, %f", rx, ry,
- // rxe, rye, rdx,
- // rdy, rdxe, rdye);
-
- glTexCoord2f(rx, ry);
- glVertex3f(rdx, rdy, z);
-
- glTexCoord2f(rxe, ry);
- glVertex3f(rdxe, rdy, z);
-
- glTexCoord2f(rxe, rye);
- glVertex3f(rdxe, rdye, z);
-
- glTexCoord2f(rx, rye);
- glVertex3f(rdx, rdye, z);
+ P_PAINTREG_START(crect) {
+ auto rx = (GLfloat)(crect.x1 - mdx) * texfac_x;
+ auto ry = (GLfloat)(mheight - (crect.y1 - mdy)) * texfac_y;
+ auto rxe = rx + (GLfloat)(crect.x2 - crect.x1) * texfac_x;
+ auto rye = ry - (GLfloat)(crect.y2 - crect.y1) * texfac_y;
+ auto rdx = (GLfloat)(crect.x1 - mdx);
+ auto rdy = (GLfloat)(mheight - crect.y1 + mdy);
+ if (last_pass) {
+ rdx = (GLfloat)crect.x1;
+ rdy = (GLfloat)(ps->root_height - crect.y1);
}
- P_PAINTREG_END();
+ auto rdxe = rdx + (GLfloat)(crect.x2 - crect.x1);
+ auto rdye = rdy - (GLfloat)(crect.y2 - crect.y1);
+
+ // log_trace("%f, %f, %f, %f -> %f, %f, %f, %f", rx, ry,
+ // rxe, rye, rdx,
+ // rdy, rdxe, rdye);
+
+ glTexCoord2f(rx, ry);
+ glVertex3f(rdx, rdy, z);
+
+ glTexCoord2f(rxe, ry);
+ glVertex3f(rdxe, rdy, z);
+
+ glTexCoord2f(rxe, rye);
+ glVertex3f(rdxe, rdye, z);
+
+ glTexCoord2f(rx, rye);
+ glVertex3f(rdx, rdye, z);
}
+ P_PAINTREG_END();
glUseProgram(0);
@@ -880,7 +878,7 @@ glx_blur_dst_end:
return ret;
}
-bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z,
+bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, int z,
GLfloat factor, const region_t *reg_tgt) {
// It's possible to dim in glx_render(), but it would be over-complicated
// considering all those mess in color negation and modulation
@@ -888,21 +886,19 @@ bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z,
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.0f, 0.0f, 0.0f, factor);
- {
- P_PAINTREG_START(crect) {
- // XXX what does all of these variables mean?
- GLint rdx = crect.x1;
- GLint rdy = ps->root_height - crect.y1;
- GLint rdxe = rdx + (crect.x2 - crect.x1);
- GLint rdye = rdy - (crect.y2 - crect.y1);
+ P_PAINTREG_START(crect) {
+ // XXX what does all of these variables mean?
+ GLint rdx = crect.x1;
+ GLint rdy = ps->root_height - crect.y1;
+ GLint rdxe = rdx + (crect.x2 - crect.x1);
+ GLint rdye = rdy - (crect.y2 - crect.y1);
- glVertex3i(rdx, rdy, z);
- glVertex3i(rdxe, rdy, z);
- glVertex3i(rdxe, rdye, z);
- glVertex3i(rdx, rdye, z);
- }
- P_PAINTREG_END();
+ glVertex3i(rdx, rdy, z);
+ glVertex3i(rdxe, rdy, z);
+ glVertex3i(rdxe, rdye, z);
+ glVertex3i(rdx, rdye, z);
}
+ P_PAINTREG_END();
glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
glDisable(GL_BLEND);
@@ -941,7 +937,7 @@ bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx,
// This is all weird, but X Render is using premultiplied ARGB format, and
// we need to use those things to correct it. Thanks to derhass for help.
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(opacity, opacity, opacity, opacity);
+ glColor4d(opacity, opacity, opacity, opacity);
}
if (!has_prog) {
@@ -1023,7 +1019,7 @@ bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx,
assert(pprogram->prog);
glUseProgram(pprogram->prog);
if (pprogram->unifm_opacity >= 0)
- glUniform1f(pprogram->unifm_opacity, opacity);
+ glUniform1f(pprogram->unifm_opacity, (float)opacity);
if (pprogram->unifm_invert_color >= 0)
glUniform1i(pprogram->unifm_invert_color, neg);
if (pprogram->unifm_tex >= 0)
@@ -1045,17 +1041,17 @@ bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx,
{
P_PAINTREG_START(crect) {
// XXX explain these variables
- GLfloat rx = (double)(crect.x1 - dx + x);
- GLfloat ry = (double)(crect.y1 - dy + y);
- GLfloat rxe = rx + (double)(crect.x2 - crect.x1);
- GLfloat rye = ry + (double)(crect.y2 - crect.y1);
+ auto rx = (GLfloat)(crect.x1 - dx + x);
+ auto ry = (GLfloat)(crect.y1 - dy + y);
+ auto rxe = rx + (GLfloat)(crect.x2 - crect.x1);
+ auto rye = ry + (GLfloat)(crect.y2 - crect.y1);
// Rectangle textures have [0-w] [0-h] while 2D texture has [0-1]
// [0-1] Thanks to amonakov for pointing out!
if (GL_TEXTURE_2D == ptex->target) {
- rx = rx / ptex->width;
- ry = ry / ptex->height;
- rxe = rxe / ptex->width;
- rye = rye / ptex->height;
+ rx = rx / (GLfloat)ptex->width;
+ ry = ry / (GLfloat)ptex->height;
+ rxe = rxe / (GLfloat)ptex->width;
+ rye = rye / (GLfloat)ptex->height;
}
GLint rdx = crect.x1;
GLint rdy = ps->root_height - crect.y1;
@@ -1065,8 +1061,8 @@ bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx,
// Invert Y if needed, this may not work as expected, though. I
// don't have such a FBConfig to test with.
if (!ptex->y_inverted) {
- ry = 1.0 - ry;
- rye = 1.0 - rye;
+ ry = 1.0f - ry;
+ rye = 1.0f - rye;
}
// log_trace("Rect %d: %f, %f, %f, %f -> %d, %d, %d, %d", ri, rx,
diff --git a/src/opengl.h b/src/opengl.h
index d01294c6..8c746d35 100644
--- a/src/opengl.h
+++ b/src/opengl.h
@@ -26,7 +26,7 @@
#include
#include
-bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z,
+bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, int z,
GLfloat factor, const region_t *reg_tgt);
bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx, int dy,
@@ -46,8 +46,8 @@ bool glx_load_prog_main(session_t *ps, const char *vshader_str, const char *fsha
glx_prog_main_t *pprogram);
#endif
-bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap, unsigned width,
- unsigned height, bool repeat, const struct glx_fbconfig_info *);
+bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap, int width,
+ int height, bool repeat, const struct glx_fbconfig_info *);
void glx_release_pixmap(session_t *ps, glx_texture_t *ptex);
diff --git a/src/options.c b/src/options.c
index bf84e802..d9969ef9 100644
--- a/src/options.c
+++ b/src/options.c
@@ -483,7 +483,6 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
"open a bug report.";
optind = 1;
while (-1 != (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
- long val = 0;
switch (o) {
#define P_CASEBOOL(idx, option) \
case idx: \
@@ -491,9 +490,15 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
break
#define P_CASELONG(idx, option) \
case idx: \
- if (!parse_long(optarg, &val)) \
+ if (!parse_long(optarg, &opt->option)) { \
exit(1); \
- opt->option = val; \
+ } \
+ break
+#define P_CASEINT(idx, option) \
+ case idx: \
+ if (!parse_int(optarg, &opt->option)) { \
+ exit(1); \
+ } \
break
// clang-format off
@@ -511,7 +516,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
case 320:
// These options are handled by get_early_config()
break;
- P_CASELONG('D', fade_delta);
+ P_CASEINT('D', fade_delta);
case 'I': opt->fade_in_step = normalize_d(atof(optarg)); break;
case 'O': opt->fade_out_step = normalize_d(atof(optarg)); break;
case 'c': shadow_enable = true; break;
@@ -535,12 +540,12 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
case 'F':
fading_enable = true;
break;
- P_CASELONG('r', shadow_radius);
+ P_CASEINT('r', shadow_radius);
case 'o':
opt->shadow_opacity = atof(optarg);
break;
- P_CASELONG('l', shadow_offset_x);
- P_CASELONG('t', shadow_offset_y);
+ P_CASEINT('l', shadow_offset_x);
+ P_CASEINT('t', shadow_offset_y);
case 'i':
opt->inactive_opacity = normalize_d(atof(optarg));
break;
@@ -587,7 +592,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
P_CASEBOOL(266, shadow_ignore_shaped);
P_CASEBOOL(267, detect_rounded_corners);
P_CASEBOOL(268, detect_client_opacity);
- P_CASELONG(269, refresh_rate);
+ P_CASEINT(269, refresh_rate);
case 270:
if (optarg) {
opt->vsync = parse_vsync(optarg);
@@ -656,10 +661,10 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
log_error("--glx-copy-from-front %s", deprecation_message);
exit(1);
break;
- P_CASELONG(293, benchmark);
+ P_CASEINT(293, benchmark);
case 294:
// --benchmark-wid
- opt->benchmark_wid = strtol(optarg, NULL, 0);
+ opt->benchmark_wid = (xcb_window_t)strtol(optarg, NULL, 0);
break;
case 295:
log_error("--glx-use-copysubbuffermesa %s", deprecation_message);
@@ -706,7 +711,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
MAX_BLUR_PASS, &conv_kern_hasneg))
exit(1);
break;
- P_CASELONG(302, resize_damage);
+ P_CASEINT(302, resize_damage);
case 303:
// --glx-use-gpushader4
log_warn("--glx-use-gpushader4 is deprecated since v6."
@@ -782,8 +787,8 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
}
// Range checking and option assignments
- opt->fade_delta = max_i(opt->fade_delta, 1);
- opt->shadow_radius = max_i(opt->shadow_radius, 0);
+ opt->fade_delta = max2(opt->fade_delta, 1);
+ opt->shadow_radius = max2(opt->shadow_radius, 0);
opt->shadow_red = normalize_d(opt->shadow_red);
opt->shadow_green = normalize_d(opt->shadow_green);
opt->shadow_blue = normalize_d(opt->shadow_blue);
@@ -802,7 +807,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
// Other variables determined by options
// Determine whether we need to track focus changes
- if (opt->inactive_opacity != opt->active_opacity || opt->inactive_dim) {
+ if (opt->inactive_opacity != opt->active_opacity || opt->inactive_dim > 0) {
opt->track_focus = true;
}
diff --git a/src/region.h b/src/region.h
index cb972d7d..a056c80b 100644
--- a/src/region.h
+++ b/src/region.h
@@ -42,7 +42,8 @@ static inline rect_t from_x_rect(const xcb_rectangle_t *rect) {
/// Returning an array that needs to be freed
static inline rect_t *from_x_rects(int nrects, const xcb_rectangle_t *rects) {
rect_t *ret = ccalloc(nrects, rect_t);
- for (int i = 0; i < nrects; i++)
+ for (int i = 0; i < nrects; i++) {
ret[i] = from_x_rect(rects + i);
+ }
return ret;
}
diff --git a/src/render.c b/src/render.c
index 337c931e..5ddbd686 100644
--- a/src/render.c
+++ b/src/render.c
@@ -34,9 +34,8 @@
/**
* 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, bool repeat,
- int depth, xcb_visualid_t visual, bool force) {
+static inline bool paint_bind_tex(session_t *ps, paint_t *ppaint, int wid, int hei,
+ bool repeat, 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;
@@ -174,13 +173,15 @@ void render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei, doubl
switch (ps->o.backend) {
case BKEND_XRENDER:
case BKEND_XR_GLX_HYBRID: {
- int alpha_step = opacity * MAX_ALPHA;
+ auto alpha_step = (int)(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);
- xcb_render_composite(ps->c, op, pict, alpha_pict, ps->tgt_buffer.pict,
- x, y, 0, 0, dx, dy, wid, hei);
+ uint8_t 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,
+ to_i16_checked(x), to_i16_checked(y), 0, 0, to_i16_checked(dx),
+ to_i16_checked(dy), to_u16_checked(wid), to_u16_checked(hei));
}
break;
}
@@ -279,8 +280,8 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
const int x = w->g.x;
const int y = w->g.y;
- const int wid = w->widthb;
- const int hei = w->heightb;
+ const uint16_t wid = to_u16_checked(w->widthb);
+ const uint16_t hei = to_u16_checked(w->heightb);
xcb_render_picture_t pict = w->paint.pict;
@@ -320,10 +321,10 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
} else {
// Painting parameters
const margin_t extents = win_calc_frame_extents(w);
- const int t = extents.top;
- const int l = extents.left;
- const int b = extents.bottom;
- const int r = extents.right;
+ const auto t = (int)extents.top;
+ const auto l = (int)extents.left;
+ const auto b = (int)extents.bottom;
+ const auto r = (int)extents.right;
#define COMP_BDR(cx, cy, cwid, chei) \
paint_region(ps, w, (cx), (cy), (cwid), (chei), w->frame_opacity * w->opacity, \
@@ -337,7 +338,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
int body_height = hei;
// ctop = checked top
// Make sure top margin is smaller than height
- int ctop = min_i(body_height, t);
+ int ctop = min2(body_height, t);
if (ctop > 0)
COMP_BDR(0, 0, wid, ctop);
@@ -348,7 +349,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
// bottom
// cbot = checked bottom
// Make sure bottom margin is not too large
- int cbot = min_i(body_height, b);
+ int cbot = min2(body_height, b);
if (cbot > 0)
COMP_BDR(0, hei - cbot, wid, cbot);
@@ -359,7 +360,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
// left
int body_width = wid;
- int cleft = min_i(body_width, l);
+ int cleft = min2(body_width, l);
if (cleft > 0)
COMP_BDR(0, ctop, cleft, body_height);
@@ -368,7 +369,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
break;
// right
- int cright = min_i(body_width, r);
+ int cright = min2(body_width, r);
if (cright > 0)
COMP_BDR(wid - cright, ctop, cright, body_height);
@@ -396,7 +397,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
switch (ps->o.backend) {
case BKEND_XRENDER:
case BKEND_XR_GLX_HYBRID: {
- unsigned short cval = 0xffff * dim_opacity;
+ auto cval = (uint16_t)(0xffff * dim_opacity);
// Premultiply color
xcb_render_color_t color = {
@@ -407,8 +408,8 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
};
xcb_rectangle_t rect = {
- .x = x,
- .y = y,
+ .x = to_i16_checked(x),
+ .y = to_i16_checked(y),
.width = wid,
.height = hei,
};
@@ -418,8 +419,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, (int)(ps->psglx->z - 0.7),
+ (float)dim_opacity, reg_paint);
break;
#endif
default: assert(false);
@@ -447,7 +448,7 @@ static bool get_root_tile(session_t *ps) {
// Create a pixmap if there isn't any
if (!pixmap) {
- pixmap = x_create_pixmap(ps->c, ps->depth, ps->root, 1, 1);
+ pixmap = x_create_pixmap(ps->c, (uint8_t)ps->depth, ps->root, 1, 1);
if (pixmap == XCB_NONE) {
log_error("Failed to create pixmaps for root tile.");
return false;
@@ -605,8 +606,9 @@ static inline void win_paint_shadow(session_t *ps, win *w, region_t *reg_paint)
*
* @return true if successful, false otherwise
*/
-static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int x, int y, int wid,
- int hei, xcb_render_fixed_t **blur_kerns, const region_t *reg_clip) {
+static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int16_t x,
+ int16_t y, uint16_t wid, uint16_t hei,
+ xcb_render_fixed_t **blur_kerns, const region_t *reg_clip) {
assert(blur_kerns[0]);
// Directly copying from tgt_buffer to it does not work, so we create a
@@ -627,16 +629,16 @@ static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int x, i
assert(i < MAX_BLUR_PASS - 1);
xcb_render_fixed_t *convolution_blur = blur_kerns[i];
// `x / 65536.0` converts from X fixed point to double
- int kwid = ((double)convolution_blur[0]) / 65536.0,
- khei = ((double)convolution_blur[1]) / 65536.0;
+ int kwid = (int)((double)convolution_blur[0] / 65536.0),
+ khei = (int)((double)convolution_blur[1] / 65536.0);
bool rd_from_tgt = (tgt_buffer == src_pict);
// Copy from source picture to destination. The filter must
// 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_set_picture_filter(
+ ps->c, src_pict, strlen(XRFILTER_CONVOLUTION), XRFILTER_CONVOLUTION,
+ (uint32_t)(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),
@@ -664,10 +666,10 @@ static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int x, i
*/
static inline void win_blur_background(session_t *ps, win *w, xcb_render_picture_t tgt_buffer,
const region_t *reg_paint) {
- const int x = w->g.x;
- const int y = w->g.y;
- const int wid = w->widthb;
- const int hei = w->heightb;
+ const int16_t x = w->g.x;
+ const int16_t y = w->g.y;
+ const auto wid = to_u16_checked(w->widthb);
+ const auto hei = to_u16_checked(w->heightb);
double factor_center = 1.0;
// Adjust blur strength according to window opacity, to make it appear
@@ -702,7 +704,7 @@ static inline void win_blur_background(session_t *ps, win *w, xcb_render_picture
// If kern_dst is allocated, it's always allocated to the right
// size
- size_t size = kern_dst ? kern_src->w * kern_src->h + 2 : 0;
+ size_t size = kern_dst ? (size_t)(kern_src->w * kern_src->h + 2) : 0;
x_picture_filter_from_conv(kern_src, factor_center, &kern_dst, &size);
ps->blur_kerns_cache[i] = kern_dst;
}
@@ -726,8 +728,8 @@ static inline void win_blur_background(session_t *ps, win *w, xcb_render_picture
#ifdef CONFIG_OPENGL
case BKEND_GLX:
// TODO: Handle frame opacity
- glx_blur_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5, factor_center,
- reg_paint, &w->glx_blur_cache);
+ glx_blur_dst(ps, x, y, wid, hei, (float)ps->psglx->z - 0.5f,
+ (float)factor_center, reg_paint, &w->glx_blur_cache);
break;
#endif
default: assert(0);
@@ -786,7 +788,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
pixman_region32_copy(®ion, &ps->screen_reg);
} else {
for (int i = 0; i < get_buffer_age(ps); i++) {
- const int curr = ((ps->damage - ps->damage_ring) + i) % ps->ndamage;
+ auto curr = ((ps->damage - ps->damage_ring) + i) % ps->ndamage;
pixman_region32_union(®ion, ®ion, &ps->damage_ring[curr]);
}
}
@@ -800,7 +802,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
#endif
if (ps->o.resize_damage > 0) {
- resize_region(®ion, ps->o.resize_damage);
+ resize_region(®ion, (short)ps->o.resize_damage);
}
// Remove the damaged area out of screen
@@ -809,8 +811,9 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
if (!paint_isvalid(ps, &ps->tgt_buffer)) {
if (!ps->tgt_buffer.pixmap) {
free_paint(ps, &ps->tgt_buffer);
- ps->tgt_buffer.pixmap = x_create_pixmap(
- ps->c, ps->depth, ps->root, ps->root_width, ps->root_height);
+ ps->tgt_buffer.pixmap =
+ x_create_pixmap(ps->c, (uint8_t)ps->depth, ps->root,
+ ps->root_width, ps->root_height);
if (ps->tgt_buffer.pixmap == XCB_NONE) {
log_fatal("Failed to allocate a screen-sized pixmap for"
"painting");
@@ -874,9 +877,10 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
// Might be worth while to crop the region to shadow
// border
+ assert(w->shadow_width >= 0 && w->shadow_height >= 0);
pixman_region32_intersect_rect(
- ®_tmp, ®_tmp, w->g.x + w->shadow_dx,
- w->g.y + w->shadow_dy, w->shadow_width, w->shadow_height);
+ ®_tmp, ®_tmp, w->g.x + w->shadow_dx, w->g.y + w->shadow_dy,
+ (uint)w->shadow_width, (uint)w->shadow_height);
// Mask out the body of the window from the shadow if
// needed Doing it here instead of in make_shadow() for
@@ -958,6 +962,8 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
ps->vsync_wait(ps);
}
+ auto rwidth = to_u16_checked(ps->root_width);
+ auto rheight = to_u16_checked(ps->root_height);
switch (ps->o.backend) {
case BKEND_XRENDER:
if (ps->o.monitor_repaint) {
@@ -969,16 +975,16 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
// to it
auto pictfmt = x_get_pictform_for_visual(ps->c, ps->vis);
xcb_render_picture_t new_pict = x_create_picture_with_pictfmt(
- ps->c, ps->root, ps->root_width, ps->root_height, pictfmt, 0, NULL);
+ ps->c, ps->root, rwidth, rheight, pictfmt, 0, NULL);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC,
- ps->tgt_buffer.pict, XCB_NONE, new_pict, 0, 0,
- 0, 0, 0, 0, ps->root_width, ps->root_height);
+ ps->tgt_buffer.pict, XCB_NONE, new_pict, 0,
+ 0, 0, 0, 0, 0, rwidth, rheight);
// Next, we set the region of paint and highlight it
x_set_picture_clip_region(ps->c, new_pict, 0, 0, ®ion);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_OVER, ps->white_picture,
- ps->alpha_picts[MAX_ALPHA / 2], new_pict, 0, 0,
- 0, 0, 0, 0, ps->root_width, ps->root_height);
+ ps->alpha_picts[MAX_ALPHA / 2], new_pict, 0,
+ 0, 0, 0, 0, 0, rwidth, rheight);
// Finally, clear clip regions of new_pict and the screen, and put
// the whole thing on screen
@@ -986,12 +992,12 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
x_set_picture_clip_region(ps->c, ps->tgt_picture, 0, 0, &ps->screen_reg);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, new_pict,
XCB_NONE, ps->tgt_picture, 0, 0, 0, 0, 0, 0,
- ps->root_width, ps->root_height);
+ rwidth, rheight);
xcb_render_free_picture(ps->c, new_pict);
} else
- xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, ps->tgt_buffer.pict,
- XCB_NONE, ps->tgt_picture, 0, 0, 0, 0, 0, 0,
- ps->root_width, ps->root_height);
+ xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC,
+ ps->tgt_buffer.pict, XCB_NONE, ps->tgt_picture,
+ 0, 0, 0, 0, 0, 0, rwidth, rheight);
break;
#ifdef CONFIG_OPENGL
case BKEND_XR_GLX_HYBRID:
@@ -1151,7 +1157,7 @@ bool init_render(session_t *ps) {
// 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) {
+ if (ps->o.shadow_red == 0 && ps->o.shadow_green == 0 && ps->o.shadow_blue == 0) {
ps->cshadow_picture = ps->black_picture;
} else {
ps->cshadow_picture = solid_picture(ps->c, ps->root, true, 1, ps->o.shadow_red,
diff --git a/src/render.h b/src/render.h
index c05845de..430e670d 100644
--- a/src/render.h
+++ b/src/render.h
@@ -2,9 +2,9 @@
// Copyright (c) Yuxuan Shui
#pragma once
-#include
-#include
#include
+#include
+#include
#ifdef CONFIG_OPENGL
#include "backend/gl/glx.h"
#endif
@@ -16,24 +16,20 @@ typedef struct win win;
typedef struct session session_t;
typedef struct paint {
- xcb_pixmap_t pixmap;
- xcb_render_picture_t pict;
- glx_texture_t *ptex;
+ xcb_pixmap_t pixmap;
+ xcb_render_picture_t pict;
+ glx_texture_t *ptex;
#ifdef CONFIG_OPENGL
- struct glx_fbconfig_info *fbcfg;
+ struct glx_fbconfig_info *fbcfg;
#endif
} paint_t;
-void
-render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
- double opacity, bool argb, bool neg,
- xcb_render_picture_t pict, glx_texture_t *ptex,
- const region_t *reg_paint, const glx_prog_main_t *pprogram);
-void
-paint_one(session_t *ps, win *w, const region_t *reg_paint);
+void render(session_t *ps, int x, int y, int dx, int dy, int w, int h, double opacity,
+ bool argb, bool neg, xcb_render_picture_t pict, glx_texture_t *ptex,
+ const region_t *reg_paint, const glx_prog_main_t *pprogram);
+void paint_one(session_t *ps, win *w, const region_t *reg_paint);
-void
-paint_all(session_t *ps, win * const t, bool ignore_damage);
+void paint_all(session_t *ps, win *const t, bool ignore_damage);
void free_picture(xcb_connection_t *c, xcb_render_picture_t *p);
diff --git a/src/string_utils.h b/src/string_utils.h
index 8f40bb12..d49158d2 100644
--- a/src/string_utils.h
+++ b/src/string_utils.h
@@ -4,6 +4,8 @@
#include
#include
+#include "compiler.h"
+
#define mstrncmp(s1, s2) strncmp((s1), (s2), strlen(s1))
char *mstrjoin(const char *src1, const char *src2);
@@ -26,7 +28,7 @@ static inline int uitostr(unsigned int n, char *buf) {
int pos = ret;
while (pos--) {
- buf[pos] = n % 10 + '0';
+ buf[pos] = (char)(n % 10 + '0');
n /= 10;
}
return ret;
diff --git a/src/types.h b/src/types.h
index eb749f66..f446833f 100644
--- a/src/types.h
+++ b/src/types.h
@@ -14,14 +14,6 @@ typedef enum {
UNSET
} switch_t;
-/// Structure representing a X geometry.
-typedef struct {
- int wid;
- int hei;
- int x;
- int y;
-} geometry_t;
-
/// A structure representing margins around a rectangle.
typedef struct {
unsigned int top;
diff --git a/src/utils.c b/src/utils.c
index d7e6b6f0..d863c363 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -22,7 +22,7 @@ void report_allocation_failure(const char *func, const char *file, unsigned int
{.iov_base = "at ", .iov_len = 3},
{.iov_base = (void *)file, .iov_len = strlen(file)},
{.iov_base = ":", .iov_len = 1},
- {.iov_base = buf, .iov_len = llen},
+ {.iov_base = buf, .iov_len = (size_t)llen},
{.iov_base = (void *)msg2, .iov_len = sizeof(msg2) - 1},
};
diff --git a/src/utils.h b/src/utils.h
index 45f39116..1b29c472 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -3,6 +3,7 @@
#pragma once
#include
#include
+#include
#include
#include
#include
@@ -27,7 +28,7 @@ __attribute__((optimize("-fno-fast-math")))
#endif
static inline bool
safe_isnan(double a) {
- return isnan(a);
+ return __builtin_isnan(a);
}
#define CASESTRRET(s) \
@@ -42,13 +43,51 @@ safe_isnan(double a) {
} while (0)
/// Same as assert, but evaluates the expression even in release builds
-#define CHECK(expr) \
+#define CHECK(expr) \
do { \
__auto_type __tmp = (expr); \
assert(__tmp); \
(void)__tmp; \
} while (0)
+// Some macros for checked cast
+
+#define to_int_checked(val) \
+ ({ \
+ auto tmp = (val); \
+ assert(tmp >= INT_MIN && tmp <= INT_MAX); \
+ (int)tmp; \
+ })
+
+#define to_char_checked(val) \
+ ({ \
+ auto tmp = (val); \
+ assert(tmp >= CHAR_MIN && tmp <= CHAR_MAX); \
+ (char)tmp; \
+ })
+
+#define to_u16_checked(val) \
+ ({ \
+ auto tmp = (val); \
+ assert(tmp >= 0 && tmp <= UINT16_MAX); \
+ (uint16_t) tmp; \
+ })
+
+#define to_i16_checked(val) \
+ ({ \
+ auto tmp = (val); \
+ assert(tmp >= INT16_MIN && tmp <= INT16_MAX); \
+ (int16_t) tmp; \
+ })
+
+#define to_u32_checked(val) \
+ ({ \
+ auto tmp = (val); \
+ int64_t max = UINT32_MAX; /* silence clang tautological comparison \
+ warning*/ \
+ assert(tmp >= 0 && tmp <= max); \
+ (uint32_t) tmp; \
+ })
/**
* Normalize an int value to a specific range.
*
@@ -65,33 +104,11 @@ static inline int attr_const normalize_i_range(int i, int min, int max) {
return i;
}
-/**
- * Select the larger integer of two.
- */
-static inline int attr_const max_i(int a, int b) {
- return (a > b ? a : b);
-}
+#define min2(a, b) ((a) > (b) ? (b) : (a))
+#define max2(a, b) ((a) > (b) ? (a) : (b))
-/**
- * Select the smaller integer of two.
- */
-static inline int attr_const min_i(int a, int b) {
- return (a > b ? b : a);
-}
-
-/**
- * Select the larger long integer of two.
- */
-static inline long attr_const max_l(long a, long b) {
- return (a > b ? a : b);
-}
-
-/**
- * Select the smaller long integer of two.
- */
-static inline long attr_const min_l(long a, long b) {
- return (a > b ? b : a);
-}
+/// clamp `val` into interval [min, max]
+#define clamp(val, min, max) max2(min2(val, max), min)
static inline int attr_const popcountl(unsigned long a) {
return __builtin_popcountl(a);
@@ -147,11 +164,20 @@ allocchk_(const char *func_name, const char *file, unsigned int line, void *ptr)
#define cvalloc(size) allocchk(malloc(size))
/// @brief Wrapper of calloc().
-#define ccalloc(nmemb, type) ((type *)allocchk(calloc((nmemb), sizeof(type))))
+#define ccalloc(nmemb, type) \
+ ({ \
+ auto tmp = (nmemb); \
+ assert(tmp >= 0); \
+ ((type *)allocchk(calloc((size_t)tmp, sizeof(type)))); \
+ })
/// @brief Wrapper of ealloc().
-#define crealloc(ptr, nmemb) \
- ((__typeof__(ptr))allocchk(realloc((ptr), (nmemb) * sizeof(*(ptr)))))
+#define crealloc(ptr, nmemb) \
+ ({ \
+ auto tmp = (nmemb); \
+ assert(tmp >= 0); \
+ ((__typeof__(ptr))allocchk(realloc((ptr), (size_t)tmp * sizeof(*(ptr))))); \
+ })
/// RC_TYPE generates a reference counted type from `type`
///
diff --git a/src/vsync.c b/src/vsync.c
index fba4ebf8..d5a5b8fb 100644
--- a/src/vsync.c
+++ b/src/vsync.c
@@ -38,7 +38,7 @@ static int vsync_drm_wait(session_t *ps) {
do {
ret = ioctl(ps->drm_fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
- vbl.request.type &= ~_DRM_VBLANK_RELATIVE;
+ vbl.request.type &= ~(uint)_DRM_VBLANK_RELATIVE;
} while (ret && errno == EINTR);
if (ret)
@@ -90,9 +90,9 @@ static bool vsync_opengl_oml_init(session_t *ps) {
return glxext.has_GLX_OML_sync_control;
}
-static inline bool vsync_opengl_swc_swap_interval(session_t *ps, unsigned int interval) {
+static inline bool vsync_opengl_swc_swap_interval(session_t *ps, int interval) {
if (glxext.has_GLX_MESA_swap_control)
- return glXSwapIntervalMESA(interval) == 0;
+ return glXSwapIntervalMESA((uint)interval) == 0;
else if (glxext.has_GLX_SGI_swap_control)
return glXSwapIntervalSGI(interval) == 0;
else if (glxext.has_GLX_EXT_swap_control) {
diff --git a/src/win.c b/src/win.c
index 14f55a89..c6eab854 100644
--- a/src/win.c
+++ b/src/win.c
@@ -110,8 +110,9 @@ static inline bool group_is_focused(session_t *ps, xcb_window_t leader) {
* Get a rectangular region a window occupies, excluding shadow.
*/
static void win_get_region_local(const win *w, region_t *res) {
+ assert(w->widthb >= 0 && w->heightb >= 0);
pixman_region32_fini(res);
- pixman_region32_init_rect(res, 0, 0, w->widthb, w->heightb);
+ pixman_region32_init_rect(res, 0, 0, (uint)w->widthb, (uint)w->heightb);
}
/**
@@ -120,14 +121,15 @@ static void win_get_region_local(const win *w, region_t *res) {
void win_get_region_noframe_local(const win *w, region_t *res) {
const margin_t extents = win_calc_frame_extents(w);
- int x = extents.left;
- int y = extents.top;
- int width = max_i(w->g.width - extents.left - extents.right, 0);
- int height = max_i(w->g.height - extents.top - extents.bottom, 0);
+ int x = (int)extents.left;
+ int y = (int)extents.top;
+ int width = max2(w->g.width - (int)(extents.left + extents.right), 0);
+ int height = max2(w->g.height - (int)(extents.top + extents.bottom), 0);
pixman_region32_fini(res);
- if (width > 0 && height > 0)
- pixman_region32_init_rect(res, x, y, width, height);
+ if (width > 0 && height > 0) {
+ pixman_region32_init_rect(res, x, y, (uint)width, (uint)height);
+ }
}
gen_by_val(win_get_region_noframe_local);
@@ -139,13 +141,13 @@ void win_get_region_frame_local(const win *w, region_t *res) {
res,
(rect_t[]){
// top
- {.x1 = 0, .y1 = 0, .x2 = w->g.width, .y2 = extents.top},
+ {.x1 = 0, .y1 = 0, .x2 = w->g.width, .y2 = (int)extents.top},
// bottom
- {.x1 = 0, .y1 = w->g.height - extents.bottom, .x2 = w->g.width, .y2 = w->g.height},
+ {.x1 = 0, .y1 = (int)(w->g.height - extents.bottom), .x2 = w->g.width, .y2 = w->g.height},
// left
- {.x1 = 0, .y1 = 0, .x2 = extents.left, .y2 = w->g.height},
+ {.x1 = 0, .y1 = 0, .x2 = (int)extents.left, .y2 = w->g.height},
// right
- {.x1 = w->g.width - extents.right, .y1 = 0, .x2 = w->g.width, .y2 = w->g.height},
+ {.x1 = (int)(w->g.width - extents.right), .y1 = 0, .x2 = w->g.width, .y2 = w->g.height},
},
4);
@@ -208,8 +210,9 @@ _win_bind_image(session_t *ps, win *w, void **win_image, void **shadow_image) {
}
if (w->shadow) {
*shadow_image = ps->backend_data->ops->render_shadow(
- ps->backend_data, w->widthb, w->heightb, ps->gaussian_map, ps->o.shadow_red,
- ps->o.shadow_green, ps->o.shadow_blue, ps->o.shadow_opacity);
+ ps->backend_data, w->widthb, w->heightb, ps->gaussian_map,
+ ps->o.shadow_red, ps->o.shadow_green, ps->o.shadow_blue,
+ ps->o.shadow_opacity);
if (!*shadow_image) {
log_error("Failed to bind shadow image");
ps->backend_data->ops->release_image(ps->backend_data, *win_image);
@@ -249,10 +252,10 @@ static bool attr_pure win_has_rounded_corners(const win *w) {
// Determine the minimum width/height of a rectangle that could mark
// a window as having rounded corners
- unsigned short minwidth =
- max_i(w->widthb * (1 - ROUNDED_PERCENT), w->widthb - ROUNDED_PIXELS);
- unsigned short minheight =
- max_i(w->heightb * (1 - ROUNDED_PERCENT), w->heightb - ROUNDED_PIXELS);
+ auto minwidth =
+ (uint16_t)max2(w->widthb * (1 - ROUNDED_PERCENT), w->widthb - ROUNDED_PIXELS);
+ auto minheight =
+ (uint16_t)max2(w->heightb * (1 - ROUNDED_PERCENT), w->heightb - ROUNDED_PIXELS);
// Get the rectangles in the bounding region
int nrects = 0;
@@ -461,7 +464,7 @@ bool win_should_dim(session_t *ps, const win *w) {
return false;
}
- if (ps->o.inactive_dim && !(w->focused)) {
+ if (ps->o.inactive_dim > 0 && !(w->focused)) {
return true;
} else {
return false;
@@ -644,7 +647,7 @@ void win_update_opacity_rule(session_t *ps, win *w) {
if (!is_set)
wid_rm_opacity_prop(ps, w->id);
else
- wid_set_opacity_prop(ps, w->id, opacity * OPAQUE);
+ wid_set_opacity_prop(ps, w->id, (opacity_t)(opacity * OPAQUE));
}
/**
@@ -1241,12 +1244,14 @@ void win_set_focused(session_t *ps, win *w, bool focused) {
*/
void win_extents(const win *w, region_t *res) {
pixman_region32_clear(res);
- pixman_region32_union_rect(res, res, w->g.x, w->g.y, w->widthb, w->heightb);
+ pixman_region32_union_rect(res, res, w->g.x, w->g.y, (uint)w->widthb, (uint)w->heightb);
- if (w->shadow)
+ if (w->shadow) {
+ assert(w->shadow_width >= 0 && w->shadow_height >= 0);
pixman_region32_union_rect(res, res, w->g.x + w->shadow_dx,
- w->g.y + w->shadow_dy, w->shadow_width,
- w->shadow_height);
+ w->g.y + w->shadow_dy, (uint)w->shadow_width,
+ (uint)w->shadow_height);
+ }
}
gen_by_val(win_extents);
diff --git a/src/win.h b/src/win.h
index cdab3e60..e0e253d9 100644
--- a/src/win.h
+++ b/src/win.h
@@ -425,10 +425,10 @@ static inline region_t win_get_bounding_shape_global_by_val(win *w) {
*/
static inline margin_t attr_pure win_calc_frame_extents(const win *w) {
margin_t result = w->frame_extents;
- result.top = max_i(result.top, w->g.border_width);
- result.left = max_i(result.left, w->g.border_width);
- result.bottom = max_i(result.bottom, w->g.border_width);
- result.right = max_i(result.right, w->g.border_width);
+ result.top = max2(result.top, w->g.border_width);
+ result.left = max2(result.left, w->g.border_width);
+ result.bottom = max2(result.bottom, w->g.border_width);
+ result.right = max2(result.right, w->g.border_width);
return result;
}
diff --git a/src/x.c b/src/x.c
index 857dd543..7e79262a 100644
--- a/src/x.c
+++ b/src/x.c
@@ -38,18 +38,21 @@
* and number of items. A blank one on failure.
*/
winprop_t wid_get_prop_adv(const session_t *ps, xcb_window_t w, xcb_atom_t atom,
- long offset, long length, xcb_atom_t rtype, int rformat) {
+ int offset, int length, xcb_atom_t rtype, int rformat) {
xcb_get_property_reply_t *r = xcb_get_property_reply(
- ps->c, xcb_get_property(ps->c, 0, w, atom, rtype, offset, length), NULL);
+ ps->c,
+ xcb_get_property(ps->c, 0, w, atom, rtype, to_u32_checked(offset),
+ to_u32_checked(length)),
+ NULL);
if (r && xcb_get_property_value_length(r) &&
(rtype == XCB_GET_PROPERTY_TYPE_ANY || r->type == rtype) &&
(!rformat || r->format == rformat) &&
(r->format == 8 || r->format == 16 || r->format == 32)) {
- int len = xcb_get_property_value_length(r);
+ auto len = xcb_get_property_value_length(r);
return (winprop_t){
.ptr = xcb_get_property_value(r),
- .nitems = len / (r->format / 8),
+ .nitems = (ulong)(len / (r->format / 8)),
.type = r->type,
.format = r->format,
.r = r,
@@ -73,7 +76,7 @@ xcb_window_t wid_get_prop_window(session_t *ps, xcb_window_t wid, xcb_atom_t apr
// Return it
if (prop.nitems) {
- p = *prop.p32;
+ p = (xcb_window_t)*prop.p32;
}
free_winprop(&prop);
@@ -182,7 +185,7 @@ int x_get_visual_depth(xcb_connection_t *c, xcb_visualid_t visual) {
xcb_render_picture_t
x_create_picture_with_pictfmt_and_pixmap(xcb_connection_t *c,
const xcb_render_pictforminfo_t *pictfmt,
- xcb_pixmap_t pixmap, unsigned long valuemask,
+ xcb_pixmap_t pixmap, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr) {
void *buf = NULL;
if (attr) {
@@ -208,7 +211,7 @@ x_create_picture_with_pictfmt_and_pixmap(xcb_connection_t *c,
xcb_render_picture_t
x_create_picture_with_visual_and_pixmap(xcb_connection_t *c, xcb_visualid_t visual,
- xcb_pixmap_t pixmap, unsigned long valuemask,
+ xcb_pixmap_t pixmap, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr) {
const xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(c, visual);
return x_create_picture_with_pictfmt_and_pixmap(c, pictfmt, pixmap, valuemask, attr);
@@ -216,7 +219,7 @@ x_create_picture_with_visual_and_pixmap(xcb_connection_t *c, xcb_visualid_t visu
xcb_render_picture_t
x_create_picture_with_standard_and_pixmap(xcb_connection_t *c, xcb_pict_standard_t standard,
- xcb_pixmap_t pixmap, unsigned long valuemask,
+ xcb_pixmap_t pixmap, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr) {
x_get_server_pictfmts(c);
@@ -229,12 +232,12 @@ x_create_picture_with_standard_and_pixmap(xcb_connection_t *c, xcb_pict_standard
* Create an picture.
*/
xcb_render_picture_t
-x_create_picture_with_pictfmt(xcb_connection_t *c, xcb_drawable_t d, int wid, int hei,
- const xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
+x_create_picture_with_pictfmt(xcb_connection_t *c, xcb_drawable_t d, int w, int h,
+ const xcb_render_pictforminfo_t *pictfmt, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr) {
- int depth = pictfmt->depth;
+ uint8_t depth = pictfmt->depth;
- xcb_pixmap_t tmp_pixmap = x_create_pixmap(c, depth, d, wid, hei);
+ xcb_pixmap_t tmp_pixmap = x_create_pixmap(c, depth, d, w, h);
if (!tmp_pixmap)
return XCB_NONE;
@@ -248,7 +251,7 @@ x_create_picture_with_pictfmt(xcb_connection_t *c, xcb_drawable_t d, int wid, in
xcb_render_picture_t
x_create_picture_with_visual(xcb_connection_t *c, xcb_drawable_t d, int w, int h,
- xcb_visualid_t visual, unsigned long valuemask,
+ xcb_visualid_t visual, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr) {
auto pictfmt = x_get_pictform_for_visual(c, visual);
return x_create_picture_with_pictfmt(c, d, w, h, pictfmt, valuemask, attr);
@@ -279,21 +282,22 @@ bool x_fetch_region(xcb_connection_t *c, xcb_xfixes_region_t r, pixman_region32_
}
void x_set_picture_clip_region(xcb_connection_t *c, xcb_render_picture_t pict,
- int clip_x_origin, int clip_y_origin, const region_t *reg) {
+ int16_t clip_x_origin, int16_t clip_y_origin,
+ const region_t *reg) {
int nrects;
const rect_t *rects = pixman_region32_rectangles((region_t *)reg, &nrects);
auto xrects = ccalloc(nrects, xcb_rectangle_t);
for (int i = 0; i < nrects; i++)
xrects[i] = (xcb_rectangle_t){
- .x = rects[i].x1,
- .y = rects[i].y1,
- .width = rects[i].x2 - rects[i].x1,
- .height = rects[i].y2 - rects[i].y1,
+ .x = to_i16_checked(rects[i].x1),
+ .y = to_i16_checked(rects[i].y1),
+ .width = to_u16_checked(rects[i].x2 - rects[i].x1),
+ .height = to_u16_checked(rects[i].y2 - rects[i].y1),
};
- xcb_generic_error_t *e =
- xcb_request_check(c, xcb_render_set_picture_clip_rectangles_checked(
- c, pict, clip_x_origin, clip_y_origin, nrects, xrects));
+ xcb_generic_error_t *e = xcb_request_check(
+ c, xcb_render_set_picture_clip_rectangles_checked(
+ c, pict, clip_x_origin, clip_y_origin, to_u32_checked(nrects), xrects));
if (e)
log_error("Failed to set clip region");
free(e);
@@ -321,7 +325,7 @@ enum { XSyncBadCounter = 0,
*
* XXX consider making this error to string
*/
-void x_print_error(unsigned long serial, uint8_t major, uint8_t minor, uint8_t error_code) {
+void x_print_error(unsigned long serial, uint8_t major, uint16_t minor, uint8_t error_code) {
session_t *const ps = ps_g;
int o = 0;
@@ -405,10 +409,10 @@ void x_print_error(unsigned long serial, uint8_t major, uint8_t minor, uint8_t e
* Create a pixmap and check that creation succeeded.
*/
xcb_pixmap_t x_create_pixmap(xcb_connection_t *c, uint8_t depth, xcb_drawable_t drawable,
- uint16_t width, uint16_t height) {
+ int width, int height) {
xcb_pixmap_t pix = xcb_generate_id(c);
- xcb_void_cookie_t cookie =
- xcb_create_pixmap_checked(c, depth, pix, drawable, width, height);
+ xcb_void_cookie_t cookie = xcb_create_pixmap_checked(
+ c, depth, pix, drawable, to_u16_checked(width), to_u16_checked(height));
xcb_generic_error_t *err = xcb_request_check(c, cookie);
if (err == NULL)
return pix;
@@ -456,7 +460,7 @@ xcb_pixmap_t x_get_root_back_pixmap(session_t *ps) {
winprop_t prop =
wid_get_prop(ps, ps->root, prop_atom, 1, XCB_ATOM_PIXMAP, 32);
if (prop.nitems) {
- pixmap = *prop.p32;
+ pixmap = (xcb_pixmap_t)*prop.p32;
free_winprop(&prop);
break;
}
@@ -523,10 +527,10 @@ bool x_fence_sync(xcb_connection_t *c, xcb_sync_fence_t f) {
* @param[inout] size size of the array pointed to by `ret`, in number of elements
* @return number of elements filled into `*ret`
*/
-size_t x_picture_filter_from_conv(const conv *kernel, double center,
- xcb_render_fixed_t **ret, size_t *size) {
+int x_picture_filter_from_conv(const conv *kernel, double center,
+ xcb_render_fixed_t **ret, size_t *size) {
if (*size < (size_t)(kernel->w * kernel->h + 2)) {
- *size = kernel->w * kernel->h + 2;
+ *size = (size_t)(kernel->w * kernel->h + 2);
*ret = crealloc(*ret, *size);
}
auto buf = *ret;
@@ -550,18 +554,18 @@ size_t x_picture_filter_from_conv(const conv *kernel, double center,
}
/// Generate a search criteria for fbconfig from a X visual.
-/// Returns {-1, -1, -1, -1, -1, -1} on failure
+/// Returns {-1, -1, -1, -1, -1, 0} on failure
struct xvisual_info x_get_visual_info(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 xvisual_info){-1, -1, -1, -1, -1, -1};
+ return (struct xvisual_info){-1, -1, -1, -1, -1, 0};
}
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 xvisual_info){-1, -1, -1, -1, -1, -1};
+ return (struct xvisual_info){-1, -1, -1, -1, -1, 0};
}
int red_size = popcountl(pictfmt->direct.red_mask),
@@ -578,3 +582,14 @@ struct xvisual_info x_get_visual_info(xcb_connection_t *c, xcb_visualid_t visual
.visual = visual,
};
}
+
+xcb_screen_t *x_screen_of_display(xcb_connection_t *c, int screen) {
+ xcb_screen_iterator_t iter;
+
+ iter = xcb_setup_roots_iterator(xcb_get_setup(c));
+ for (; iter.rem; --screen, xcb_screen_next(&iter))
+ if (screen == 0)
+ return iter.data;
+
+ return NULL;
+}
diff --git a/src/x.h b/src/x.h
index 2797e814..275bc56d 100644
--- a/src/x.h
+++ b/src/x.h
@@ -88,13 +88,13 @@ static inline void x_sync(xcb_connection_t *c) {
* and number of items. A blank one on failure.
*/
winprop_t wid_get_prop_adv(const session_t *ps, xcb_window_t w, xcb_atom_t atom,
- long offset, long length, xcb_atom_t rtype, int rformat);
+ int offset, int length, xcb_atom_t rtype, int rformat);
/**
* Wrapper of wid_get_prop_adv().
*/
static inline winprop_t wid_get_prop(const session_t *ps, xcb_window_t wid, xcb_atom_t atom,
- long length, xcb_atom_t rtype, int rformat) {
+ int length, xcb_atom_t rtype, int rformat) {
return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat);
}
@@ -118,19 +118,19 @@ int x_get_visual_depth(xcb_connection_t *, xcb_visualid_t);
xcb_render_picture_t
x_create_picture_with_pictfmt_and_pixmap(xcb_connection_t *,
const xcb_render_pictforminfo_t *pictfmt,
- xcb_pixmap_t pixmap, unsigned long valuemask,
+ xcb_pixmap_t pixmap, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1, 2);
xcb_render_picture_t
x_create_picture_with_visual_and_pixmap(xcb_connection_t *, xcb_visualid_t visual,
- xcb_pixmap_t pixmap, unsigned long valuemask,
+ xcb_pixmap_t pixmap, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1);
xcb_render_picture_t
x_create_picture_with_standard_and_pixmap(xcb_connection_t *, xcb_pict_standard_t standard,
- xcb_pixmap_t pixmap, unsigned long valuemask,
+ xcb_pixmap_t pixmap, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1);
@@ -138,22 +138,22 @@ x_create_picture_with_standard_and_pixmap(xcb_connection_t *, xcb_pict_standard_
* Create an picture.
*/
xcb_render_picture_t
-x_create_picture_with_pictfmt(xcb_connection_t *, xcb_drawable_t, int wid, int hei,
- const xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
+x_create_picture_with_pictfmt(xcb_connection_t *, xcb_drawable_t, int w, int h,
+ const xcb_render_pictforminfo_t *pictfmt, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1, 5);
xcb_render_picture_t
x_create_picture_with_visual(xcb_connection_t *, xcb_drawable_t, int w, int h,
- xcb_visualid_t visual, unsigned long valuemask,
+ xcb_visualid_t visual, uint32_t valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1);
/// Fetch a X region and store it in a pixman region
bool x_fetch_region(xcb_connection_t *, xcb_xfixes_region_t r, region_t *res);
-void x_set_picture_clip_region(xcb_connection_t *, xcb_render_picture_t,
- int clip_x_origin, int clip_y_origin, const region_t *);
+void x_set_picture_clip_region(xcb_connection_t *, xcb_render_picture_t, int16_t clip_x_origin,
+ int16_t clip_y_origin, const region_t *);
void x_clear_picture_clip_region(xcb_connection_t *, xcb_render_picture_t pict);
@@ -162,10 +162,10 @@ void x_clear_picture_clip_region(xcb_connection_t *, xcb_render_picture_t pict);
*
* XXX consider making this error to string
*/
-void x_print_error(unsigned long serial, uint8_t major, uint8_t minor, uint8_t error_code);
+void x_print_error(unsigned long serial, uint8_t major, uint16_t minor, uint8_t error_code);
xcb_pixmap_t x_create_pixmap(xcb_connection_t *, uint8_t depth, xcb_drawable_t drawable,
- uint16_t width, uint16_t height);
+ int width, int height);
bool x_validate_pixmap(xcb_connection_t *, xcb_pixmap_t pxmap);
@@ -202,11 +202,13 @@ bool x_fence_sync(xcb_connection_t *, xcb_sync_fence_t);
* will be allocated, and `*ret` will be updated.
* @param[inout] size size of the array pointed to by `ret`.
*/
-size_t x_picture_filter_from_conv(const conv *kernel, double center,
- xcb_render_fixed_t **ret, size_t *size);
+int x_picture_filter_from_conv(const conv *kernel, double center,
+ xcb_render_fixed_t **ret, size_t *size);
/// Generate a search criteria for fbconfig from a X visual.
/// Returns {-1, -1, -1, -1, -1, -1} on failure
struct xvisual_info x_get_visual_info(xcb_connection_t *c, xcb_visualid_t visual);
xcb_visualid_t x_get_visual_for_standard(xcb_connection_t *c, xcb_pict_standard_t std);
+
+xcb_screen_t *x_screen_of_display(xcb_connection_t *c, int screen);