Eliminate implicit conversions
Use explicit conversions everywhere. Adding bounds check assertions when necessary. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
@ -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]);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user