Most of the x_* functions don't need session_t

Replace session_t parameter with xcb_connection_t if that's the only
thing needed.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-02-03 15:59:31 +00:00
parent ad3dc5d233
commit 17c8517abc
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
8 changed files with 175 additions and 184 deletions

View File

@ -3,8 +3,8 @@
#include <xcb/render.h>
#include <xcb/xcb_renderutil.h>
#include "backend.h"
#include "backend_common.h"
#include "backend/backend.h"
#include "backend/backend_common.h"
#include "kernel.h"
#include "common.h"
#include "log.h"
@ -21,13 +21,13 @@ solid_picture(session_t *ps, bool argb, double a, double r, double g, double b)
xcb_render_color_t col;
xcb_rectangle_t rect;
pixmap = x_create_pixmap(ps, argb ? 32 : 8, ps->root, 1, 1);
pixmap = x_create_pixmap(ps->c, argb ? 32 : 8, ps->root, 1, 1);
if (!pixmap)
return XCB_NONE;
pa.repeat = 1;
picture = x_create_picture_with_standard_and_pixmap(
ps, argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
ps->c, argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
XCB_RENDER_CP_REPEAT, &pa);
if (!picture) {
@ -194,9 +194,9 @@ bool build_shadow(session_t *ps, double opacity, const int width, const int heig
}
shadow_pixmap =
x_create_pixmap(ps, 8, ps->root, shadow_image->width, shadow_image->height);
x_create_pixmap(ps->c, 8, ps->root, shadow_image->width, shadow_image->height);
shadow_pixmap_argb =
x_create_pixmap(ps, 32, ps->root, shadow_image->width, shadow_image->height);
x_create_pixmap(ps->c, 32, ps->root, shadow_image->width, shadow_image->height);
if (!shadow_pixmap || !shadow_pixmap_argb) {
log_error("Failed to create shadow pixmaps");
@ -204,9 +204,9 @@ bool build_shadow(session_t *ps, double opacity, const int width, const int heig
}
shadow_picture = x_create_picture_with_standard_and_pixmap(
ps, XCB_PICT_STANDARD_A_8, shadow_pixmap, 0, NULL);
ps->c, XCB_PICT_STANDARD_A_8, shadow_pixmap, 0, NULL);
shadow_picture_argb = x_create_picture_with_standard_and_pixmap(
ps, XCB_PICT_STANDARD_ARGB_32, shadow_pixmap_argb, 0, NULL);
ps->c, XCB_PICT_STANDARD_ARGB_32, shadow_pixmap_argb, 0, NULL);
if (!shadow_picture || !shadow_picture_argb)
goto shadow_picture_err;

View File

@ -10,7 +10,7 @@
#include <xcb/composite.h>
#include "backend/backend.h"
#include "backend_common.h"
#include "backend/backend_common.h"
#include "common.h"
#include "config.h"
#include "log.h"
@ -135,7 +135,7 @@ static void compose(void *backend_data, session_t *ps, win *w, void *win_data, i
// Detect if the region is empty before painting
if (pixman_region32_not_empty(&reg_tmp)) {
x_set_picture_clip_region(ps, xd->back, 0, 0, &reg_tmp);
x_set_picture_clip_region(ps->c, xd->back, 0, 0, &reg_tmp);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_OVER,
wd->shadow_pict, alpha_pict, xd->back, 0, 0, 0,
0, dst_x + w->shadow_dx, dst_y + w->shadow_dy,
@ -147,9 +147,9 @@ static void compose(void *backend_data, session_t *ps, win *w, void *win_data, i
// Clip region of rendered_pict might be set during rendering, clear it to make
// sure we get everything into the buffer
x_clear_picture_clip_region(ps, wd->rendered_pict);
x_clear_picture_clip_region(ps->c, wd->rendered_pict);
x_set_picture_clip_region(ps, xd->back, 0, 0, reg_paint);
x_set_picture_clip_region(ps->c, xd->back, 0, 0, reg_paint);
xcb_render_composite(ps->c, op, wd->rendered_pict, alpha_pict, xd->back, 0, 0, 0,
0, dst_x, dst_y, w->widthb, w->heightb);
}
@ -184,8 +184,8 @@ static bool blur(void *backend_data, session_t *ps, double opacity, const region
return false;
}
x_set_picture_clip_region(ps, tmp_picture[0], 0, 0, &clip);
x_set_picture_clip_region(ps, tmp_picture[1], 0, 0, &clip);
x_set_picture_clip_region(ps->c, tmp_picture[0], 0, 0, &clip);
x_set_picture_clip_region(ps->c, tmp_picture[1], 0, 0, &clip);
// The multipass blur implemented here is not correct, but this is what old
// compton did anyway. XXX
@ -269,14 +269,14 @@ render_win(void *backend_data, session_t *ps, win *w, void *win_data, const regi
}
// Copy the content of the window over to the buffer
x_clear_picture_clip_region(ps, wd->buffer);
x_clear_picture_clip_region(ps->c, wd->buffer);
wd->rendered_pict = wd->buffer;
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, wd->pict, XCB_NONE,
wd->rendered_pict, 0, 0, 0, 0, 0, 0, w->widthb, w->heightb);
if (w->invert_color) {
// Handle invert color
x_set_picture_clip_region(ps, wd->rendered_pict, 0, 0, &reg_paint_local);
x_set_picture_clip_region(ps->c, wd->rendered_pict, 0, 0, &reg_paint_local);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_DIFFERENCE, xd->white_pixel, XCB_NONE,
wd->rendered_pict, 0, 0, 0, 0, 0, 0, w->widthb, w->heightb);
@ -302,7 +302,7 @@ render_win(void *backend_data, session_t *ps, win *w, void *win_data, const regi
// Draw the frame with frame opacity
xcb_render_picture_t alpha_pict =
xd->alpha_pict[(int)(w->frame_opacity * dopacity * 255)];
x_set_picture_clip_region(ps, wd->rendered_pict, 0, 0, &frame_reg);
x_set_picture_clip_region(ps->c, wd->rendered_pict, 0, 0, &frame_reg);
// Step 2: multiply alpha value
// XXX test
@ -328,7 +328,7 @@ render_win(void *backend_data, session_t *ps, win *w, void *win_data, const regi
.height = w->heightb,
};
x_clear_picture_clip_region(ps, wd->rendered_pict);
x_clear_picture_clip_region(ps->c, wd->rendered_pict);
xcb_render_fill_rectangles(ps->c, XCB_RENDER_PICT_OP_OVER,
wd->rendered_pict, color, 1, &rect);
}
@ -350,7 +350,7 @@ static void *prepare_win(void *backend_data, session_t *ps, win *w) {
draw = w->id;
log_trace("%s %x", w->name, wd->pixmap);
wd->pict = x_create_picture_with_pictfmt_and_pixmap(ps, w->pictfmt, draw, 0, NULL);
wd->pict = x_create_picture_with_pictfmt_and_pixmap(ps->c, w->pictfmt, draw, 0, NULL);
wd->buffer = XCB_NONE;
// XXX delay allocating shadow pict until compose() will dramatical
@ -395,33 +395,33 @@ static void *init(session_t *ps) {
if (ps->overlay != XCB_NONE) {
xd->target =
x_create_picture_with_visual_and_pixmap(ps, ps->vis, ps->overlay, 0, NULL);
x_create_picture_with_visual_and_pixmap(ps->c, ps->vis, ps->overlay, 0, NULL);
xd->target_win = ps->overlay;
} else {
xcb_render_create_picture_value_list_t pa = {
.subwindowmode = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS,
};
xd->target = x_create_picture_with_visual_and_pixmap(
ps, ps->vis, ps->root, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
ps->c, ps->vis, ps->root, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
xd->target_win = ps->root;
}
auto pictfmt = x_get_pictform_for_visual(ps, ps->vis);
auto pictfmt = x_get_pictform_for_visual(ps->c, ps->vis);
if (!pictfmt) {
log_fatal("Default visual is invalid");
abort();
}
xd->back_pixmap =
x_create_pixmap(ps, pictfmt->depth, ps->root, ps->root_width, ps->root_height);
xd->back = x_create_picture_with_pictfmt_and_pixmap(ps, pictfmt, xd->back_pixmap, 0, NULL);
x_create_pixmap(ps->c, pictfmt->depth, ps->root, ps->root_width, ps->root_height);
xd->back = x_create_picture_with_pictfmt_and_pixmap(ps->c, pictfmt, xd->back_pixmap, 0, NULL);
xcb_pixmap_t root_pixmap = x_get_root_back_pixmap(ps);
if (root_pixmap == XCB_NONE) {
xd->root_pict = solid_picture(ps, false, 1, 0.5, 0.5, 0.5);
} else {
xd->root_pict =
x_create_picture_with_visual_and_pixmap(ps, ps->vis, root_pixmap, 0, NULL);
x_create_picture_with_visual_and_pixmap(ps->c, ps->vis, root_pixmap, 0, NULL);
}
if (ps->present_exists) {
@ -462,7 +462,7 @@ static void prepare(void *backend_data, session_t *ps, const region_t *reg_paint
// Paint the root pixmap (i.e. wallpaper)
// Limit the paint area
x_set_picture_clip_region(ps, xd->back, 0, 0, reg_paint);
x_set_picture_clip_region(ps->c, xd->back, 0, 0, reg_paint);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC, xd->root_pict, XCB_NONE,
xd->back, 0, 0, 0, 0, 0, 0, ps->root_width, ps->root_height);
@ -481,7 +481,7 @@ static void present(void *backend_data, session_t *ps) {
} else {
// compose() sets clip region, so clear it first to make
// sure we update the whole screen.
x_clear_picture_clip_region(ps, xd->back);
x_clear_picture_clip_region(ps->c, xd->back);
// TODO buffer-age-like optimization might be possible here.
// but that will require a different backend API

View File

@ -777,7 +777,7 @@ repair_win(session_t *ps, win *w) {
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, tmp, &parts);
x_fetch_region(ps->c, tmp, &parts);
xcb_xfixes_destroy_region(ps->c, tmp);
}
@ -1247,7 +1247,7 @@ xerror(Display attr_unused *dpy, XErrorEvent *ev) {
* XCB error handler function.
*/
void
ev_xcb_error(session_t attr_unused *ps, xcb_generic_error_t *err) {
ev_xcb_error(session_t *ps, xcb_generic_error_t *err) {
if (!should_ignore(ps, err->sequence))
x_print_error(err->sequence, err->major_code, err->minor_code, err->error_code);
}
@ -2947,10 +2947,10 @@ session_init(session_t *ps_old, int argc, char **argv) {
.subwindowmode = IncludeInferiors,
};
ps->root_picture = x_create_picture_with_visual_and_pixmap(ps,
ps->root_picture = x_create_picture_with_visual_and_pixmap(ps->c,
ps->vis, ps->root, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
if (ps->overlay != XCB_NONE) {
ps->tgt_picture = x_create_picture_with_visual_and_pixmap(ps,
ps->tgt_picture = x_create_picture_with_visual_and_pixmap(ps->c,
ps->vis, ps->overlay, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
} else
ps->tgt_picture = ps->root_picture;

View File

@ -154,7 +154,7 @@ dump_drawable(session_t *ps, xcb_drawable_t drawable) {
static inline void
win_validate_pixmap(session_t *ps, win *w) {
// Destroy pixmap and picture, if invalid
if (!x_validate_pixmap(ps, w->paint.pixmap))
if (!x_validate_pixmap(ps->c, w->paint.pixmap))
free_paint(ps, &w->paint);
}

View File

@ -95,7 +95,7 @@ static inline void attr_nonnull(1, 2) set_tgt_clip(session_t *ps, region_t *reg)
switch (ps->o.backend) {
case BKEND_XRENDER:
case BKEND_XR_GLX_HYBRID:
x_set_picture_clip_region(ps, ps->tgt_buffer.pict, 0, 0, reg);
x_set_picture_clip_region(ps->c, ps->tgt_buffer.pict, 0, 0, reg);
break;
#ifdef CONFIG_OPENGL
case BKEND_GLX: glx_set_clip(ps, reg); break;
@ -212,7 +212,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
};
w->paint.pict = x_create_picture_with_pictfmt_and_pixmap(
ps, w->pictfmt, draw, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
ps->c, w->pictfmt, draw, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
}
// GLX: Build texture
@ -406,12 +406,12 @@ static bool get_root_tile(session_t *ps) {
}
// Make sure the pixmap we got is valid
if (pixmap && !x_validate_pixmap(ps, pixmap))
if (pixmap && !x_validate_pixmap(ps->c, pixmap))
pixmap = XCB_NONE;
// Create a pixmap if there isn't any
if (!pixmap) {
pixmap = x_create_pixmap(ps, ps->depth, ps->root, 1, 1);
pixmap = x_create_pixmap(ps->c, ps->depth, ps->root, 1, 1);
if (pixmap == XCB_NONE) {
log_error("Failed to create pixmaps for root tile.");
return false;
@ -424,7 +424,7 @@ static bool get_root_tile(session_t *ps) {
.repeat = true,
};
ps->root_tile_paint.pict = x_create_picture_with_visual_and_pixmap(
ps, ps->vis, pixmap, XCB_RENDER_CP_REPEAT, &pa);
ps->c, ps->vis, pixmap, XCB_RENDER_CP_REPEAT, &pa);
// Fill pixmap if needed
if (fill) {
@ -484,9 +484,9 @@ static bool win_build_shadow(session_t *ps, win *w, double opacity) {
return XCB_NONE;
}
shadow_pixmap = x_create_pixmap(ps, 8, ps->root, shadow_image->width, shadow_image->height);
shadow_pixmap = x_create_pixmap(ps->c, 8, ps->root, shadow_image->width, shadow_image->height);
shadow_pixmap_argb =
x_create_pixmap(ps, 32, ps->root, shadow_image->width, shadow_image->height);
x_create_pixmap(ps->c, 32, ps->root, shadow_image->width, shadow_image->height);
if (!shadow_pixmap || !shadow_pixmap_argb) {
log_error("failed to create shadow pixmaps");
@ -494,9 +494,9 @@ static bool win_build_shadow(session_t *ps, win *w, double opacity) {
}
shadow_picture = x_create_picture_with_standard_and_pixmap(
ps, XCB_PICT_STANDARD_A_8, shadow_pixmap, 0, NULL);
ps->c, XCB_PICT_STANDARD_A_8, shadow_pixmap, 0, NULL);
shadow_picture_argb = x_create_picture_with_standard_and_pixmap(
ps, XCB_PICT_STANDARD_ARGB_32, shadow_pixmap_argb, 0, NULL);
ps->c, XCB_PICT_STANDARD_ARGB_32, shadow_pixmap_argb, 0, NULL);
if (!shadow_picture || !shadow_picture_argb)
goto shadow_picture_err;
@ -596,7 +596,7 @@ static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int x, i
}
if (reg_clip && tmp_picture)
x_set_picture_clip_region(ps, tmp_picture, 0, 0, reg_clip);
x_set_picture_clip_region(ps->c, tmp_picture, 0, 0, reg_clip);
xcb_render_picture_t src_pict = tgt_buffer, dst_pict = tmp_picture;
for (int i = 0; blur_kerns[i]; ++i) {
@ -749,7 +749,7 @@ static inline void resize_region(region_t *region, short mod) {
/// region_real = the damage region
void paint_all(session_t *ps, win *const t, bool ignore_damage) {
if (ps->o.xrender_sync_fence) {
if (!x_fence_sync(ps, ps->sync_fence)) {
if (ps->xsync_exists && !x_fence_sync(ps->c, ps->sync_fence)) {
log_error("x_fence_sync failed, xrender-sync-fence will be "
"disabled from now on.");
xcb_sync_destroy_fence(ps->c, ps->sync_fence);
@ -789,7 +789,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
if (!ps->tgt_buffer.pixmap) {
free_paint(ps, &ps->tgt_buffer);
ps->tgt_buffer.pixmap = x_create_pixmap(
ps, ps->depth, ps->root, ps->root_width, ps->root_height);
ps->c, 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");
@ -799,11 +799,11 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
if (BKEND_GLX != ps->o.backend)
ps->tgt_buffer.pict = x_create_picture_with_visual_and_pixmap(
ps, ps->vis, ps->tgt_buffer.pixmap, 0, 0);
ps->c, ps->vis, ps->tgt_buffer.pixmap, 0, 0);
}
if (BKEND_XRENDER == ps->o.backend) {
x_set_picture_clip_region(ps, ps->tgt_picture, 0, 0, &region);
x_set_picture_clip_region(ps->c, ps->tgt_picture, 0, 0, &region);
}
#ifdef CONFIG_OPENGL
@ -947,7 +947,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
// it's for debug only, we don't really care
// First we create a new picture, and copy content from the buffer to it
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps, ps->vis);
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps->c, ps->vis);
xcb_render_picture_t new_pict = x_create_picture_with_pictfmt(
ps, ps->root_width, ps->root_height, pictfmt, 0, NULL);
xcb_render_composite(ps->c, XCB_RENDER_PICT_OP_SRC,
@ -955,15 +955,15 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
0, 0, 0, 0, ps->root_width, ps->root_height);
// Next, we set the region of paint and highlight it
x_set_picture_clip_region(ps, new_pict, 0, 0, &region);
x_set_picture_clip_region(ps->c, new_pict, 0, 0, &region);
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);
// Finally, clear clip regions of new_pict and the screen, and put
// the whole thing on screen
x_set_picture_clip_region(ps, new_pict, 0, 0, &ps->screen_reg);
x_set_picture_clip_region(ps, ps->tgt_picture, 0, 0, &ps->screen_reg);
x_set_picture_clip_region(ps->c, new_pict, 0, 0, &ps->screen_reg);
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);

View File

@ -881,7 +881,7 @@ bool add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
free(new);
return false;
}
new->pictfmt = x_get_pictform_for_visual(ps, new->a.visual);
new->pictfmt = x_get_pictform_for_visual(ps->c, new->a.visual);
}
calc_win_size(ps, new);

108
src/x.c
View File

@ -129,8 +129,8 @@ static inline void x_get_server_pictfmts(xcb_connection_t *c) {
}
}
xcb_render_pictforminfo_t *x_get_pictform_for_visual(session_t *ps, xcb_visualid_t visual) {
x_get_server_pictfmts(ps->c);
xcb_render_pictforminfo_t *x_get_pictform_for_visual(xcb_connection_t *c, xcb_visualid_t visual) {
x_get_server_pictfmts(c);
xcb_render_pictvisual_t *pv = xcb_render_util_find_visual_format(g_pictfmts, visual);
for(xcb_render_pictforminfo_iterator_t i =
@ -145,7 +145,7 @@ xcb_render_pictforminfo_t *x_get_pictform_for_visual(session_t *ps, xcb_visualid
xcb_render_picture_t
x_create_picture_with_pictfmt_and_pixmap(
session_t *ps, xcb_render_pictforminfo_t * pictfmt,
xcb_connection_t *c, xcb_render_pictforminfo_t * pictfmt,
xcb_pixmap_t pixmap, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr)
{
@ -158,9 +158,9 @@ x_create_picture_with_pictfmt_and_pixmap(
}
}
xcb_render_picture_t tmp_picture = xcb_generate_id(ps->c);
xcb_render_picture_t tmp_picture = xcb_generate_id(c);
xcb_generic_error_t *e =
xcb_request_check(ps->c, xcb_render_create_picture_checked(ps->c, tmp_picture,
xcb_request_check(c, xcb_render_create_picture_checked(c, tmp_picture,
pixmap, pictfmt->id, valuemask, buf));
free(buf);
if (e) {
@ -172,26 +172,26 @@ x_create_picture_with_pictfmt_and_pixmap(
xcb_render_picture_t
x_create_picture_with_visual_and_pixmap(
session_t *ps, xcb_visualid_t visual,
xcb_connection_t *c, xcb_visualid_t visual,
xcb_pixmap_t pixmap, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr)
{
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps, visual);
return x_create_picture_with_pictfmt_and_pixmap(ps, pictfmt, pixmap, valuemask, attr);
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);
}
xcb_render_picture_t
x_create_picture_with_standard_and_pixmap(
session_t *ps, xcb_pict_standard_t standard,
xcb_connection_t *c, xcb_pict_standard_t standard,
xcb_pixmap_t pixmap, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr)
{
x_get_server_pictfmts(ps->c);
x_get_server_pictfmts(c);
xcb_render_pictforminfo_t *pictfmt =
xcb_render_util_find_standard_format(g_pictfmts, standard);
assert(pictfmt);
return x_create_picture_with_pictfmt_and_pixmap(ps, pictfmt, pixmap, valuemask, attr);
return x_create_picture_with_pictfmt_and_pixmap(c, pictfmt, pixmap, valuemask, attr);
}
/**
@ -203,7 +203,7 @@ x_create_picture_with_pictfmt(session_t *ps, int wid, int hei,
const xcb_render_create_picture_value_list_t *attr)
{
if (!pictfmt)
pictfmt = x_get_pictform_for_visual(ps, ps->vis);
pictfmt = x_get_pictform_for_visual(ps->c, ps->vis);
if (!pictfmt) {
log_fatal("Default visual is invalid");
@ -212,12 +212,12 @@ x_create_picture_with_pictfmt(session_t *ps, int wid, int hei,
int depth = pictfmt->depth;
xcb_pixmap_t tmp_pixmap = x_create_pixmap(ps, depth, ps->root, wid, hei);
xcb_pixmap_t tmp_pixmap = x_create_pixmap(ps->c, depth, ps->root, wid, hei);
if (!tmp_pixmap)
return XCB_NONE;
xcb_render_picture_t picture =
x_create_picture_with_pictfmt_and_pixmap(ps, pictfmt, tmp_pixmap, valuemask, attr);
x_create_picture_with_pictfmt_and_pixmap(ps->c, pictfmt, tmp_pixmap, valuemask, attr);
xcb_free_pixmap(ps->c, tmp_pixmap);
@ -229,14 +229,14 @@ x_create_picture_with_visual(session_t *ps, int w, int h,
xcb_visualid_t visual, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr)
{
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps, visual);
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps->c, visual);
return x_create_picture_with_pictfmt(ps, w, h, pictfmt, valuemask, attr);
}
bool x_fetch_region(session_t *ps, xcb_xfixes_region_t r, pixman_region32_t *res) {
bool x_fetch_region(xcb_connection_t *c, xcb_xfixes_region_t r, pixman_region32_t *res) {
xcb_generic_error_t *e = NULL;
xcb_xfixes_fetch_region_reply_t *xr = xcb_xfixes_fetch_region_reply(ps->c,
xcb_xfixes_fetch_region(ps->c, r), &e);
xcb_xfixes_fetch_region_reply_t *xr = xcb_xfixes_fetch_region_reply(c,
xcb_xfixes_fetch_region(c, r), &e);
if (!xr) {
log_error("Failed to fetch rectangles");
return false;
@ -259,7 +259,7 @@ bool x_fetch_region(session_t *ps, xcb_xfixes_region_t r, pixman_region32_t *res
return ret;
}
void x_set_picture_clip_region(session_t *ps, xcb_render_picture_t pict,
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) {
int nrects;
const rect_t *rects = pixman_region32_rectangles((region_t *)reg, &nrects);
@ -273,7 +273,7 @@ void x_set_picture_clip_region(session_t *ps, xcb_render_picture_t pict,
};
xcb_generic_error_t *e =
xcb_request_check(ps->c, xcb_render_set_picture_clip_rectangles_checked(ps->c, pict,
xcb_request_check(c, xcb_render_set_picture_clip_rectangles_checked(c, pict,
clip_x_origin, clip_y_origin, nrects, xrects));
if (e)
log_error("Failed to set clip region");
@ -282,12 +282,12 @@ void x_set_picture_clip_region(session_t *ps, xcb_render_picture_t pict,
return;
}
void x_clear_picture_clip_region(session_t *ps, xcb_render_picture_t pict) {
void x_clear_picture_clip_region(xcb_connection_t *c, xcb_render_picture_t pict) {
xcb_render_change_picture_value_list_t v = {
.clipmask = XCB_NONE
};
xcb_generic_error_t *e =
xcb_request_check(ps->c, xcb_render_change_picture(ps->c, pict,
xcb_request_check(c, xcb_render_change_picture(c, pict,
XCB_RENDER_CP_CLIP_MASK, &v));
if (e)
log_error("failed to clear clip region");
@ -395,15 +395,15 @@ x_print_error(unsigned long serial, uint8_t major, uint8_t minor, uint8_t error_
* Create a pixmap and check that creation succeeded.
*/
xcb_pixmap_t
x_create_pixmap(session_t *ps, uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height) {
xcb_pixmap_t pix = xcb_generate_id(ps->c);
xcb_void_cookie_t cookie = xcb_create_pixmap_checked(ps->c, depth, pix, drawable, width, height);
xcb_generic_error_t *err = xcb_request_check(ps->c, cookie);
x_create_pixmap(xcb_connection_t *c, uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t 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_generic_error_t *err = xcb_request_check(c, cookie);
if (err == NULL)
return pix;
log_error("Failed to create pixmap:");
ev_xcb_error(ps, err);
x_print_error(err->sequence, err->major_code, err->minor_code, err->error_code);
free(err);
return XCB_NONE;
}
@ -415,12 +415,12 @@ x_create_pixmap(session_t *ps, uint8_t depth, xcb_drawable_t drawable, uint16_t
* are better ways.
*/
bool
x_validate_pixmap(session_t *ps, xcb_pixmap_t pixmap) {
if (pixmap == XCB_NONE) {
return false;
}
x_validate_pixmap(xcb_connection_t *c, xcb_pixmap_t pixmap) {
if (pixmap == XCB_NONE) {
return false;
}
auto r = xcb_get_geometry_reply(ps->c, xcb_get_geometry(ps->c, pixmap), NULL);
auto r = xcb_get_geometry_reply(c, xcb_get_geometry(c, pixmap), NULL);
if (!r) {
return false;
}
@ -469,32 +469,30 @@ bool x_atom_is_background_prop(session_t *ps, xcb_atom_t atom) {
* Synchronizes a X Render drawable to ensure all pending painting requests
* are completed.
*/
bool x_fence_sync(session_t *ps, xcb_sync_fence_t f) {
if (ps->xsync_exists) {
// TODO(richardgv): If everybody just follows the rules stated in X Sync
// prototype, we need only one fence per screen, but let's stay a bit
// cautious right now
bool x_fence_sync(xcb_connection_t *c, xcb_sync_fence_t f) {
// TODO(richardgv): If everybody just follows the rules stated in X Sync
// prototype, we need only one fence per screen, but let's stay a bit
// cautious right now
auto e = xcb_request_check(ps->c, xcb_sync_trigger_fence_checked(ps->c, f));
if (e) {
log_error("Failed to trigger the fence.");
free(e);
return false;
}
auto e = xcb_request_check(c, xcb_sync_trigger_fence_checked(c, f));
if (e) {
log_error("Failed to trigger the fence.");
free(e);
return false;
}
e = xcb_request_check(ps->c, xcb_sync_await_fence_checked(ps->c, 1, &f));
if (e) {
log_error("Failed to await on a fence.");
free(e);
return false;
}
e = xcb_request_check(c, xcb_sync_await_fence_checked(c, 1, &f));
if (e) {
log_error("Failed to await on a fence.");
free(e);
return false;
}
e = xcb_request_check(ps->c, xcb_sync_reset_fence_checked(ps->c, f));
if (e) {
log_error("Failed to reset the fence.");
free(e);
return false;
}
e = xcb_request_check(c, xcb_sync_reset_fence_checked(c, f));
if (e) {
log_error("Failed to reset the fence.");
free(e);
return false;
}
return true;
}

149
src/x.h
View File

@ -1,14 +1,14 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/render.h>
#include <xcb/sync.h>
#include <xcb/xfixes.h>
#include <xcb/xcb.h>
#include <xcb/xcb_renderutil.h>
#include <xcb/xfixes.h>
#include "compiler.h"
#include "region.h"
@ -17,30 +17,32 @@ typedef struct session session_t;
/// Structure representing Window property value.
typedef struct winprop {
union {
void *ptr;
int8_t *p8;
int16_t *p16;
int32_t *p32;
uint32_t *c32; // 32bit cardinal
};
unsigned long nitems;
xcb_atom_t type;
int format;
union {
void *ptr;
int8_t *p8;
int16_t *p16;
int32_t *p32;
uint32_t *c32; // 32bit cardinal
};
unsigned long nitems;
xcb_atom_t type;
int format;
xcb_get_property_reply_t *r;
xcb_get_property_reply_t *r;
} winprop_t;
#define XCB_SYNCED_VOID(func, c, ...) xcb_request_check(c, func##_checked(c, __VA_ARGS__));
#define XCB_SYNCED(func, c, ...) ({ \
xcb_generic_error_t *e = NULL; \
__auto_type r = func##_reply(c, func(c, __VA_ARGS__), &e); \
if (e) { \
x_print_error(e->sequence, e->major_code, e->minor_code, e->error_code); \
free(e); \
} \
r; \
})
#define XCB_SYNCED_VOID(func, c, ...) \
xcb_request_check(c, func##_checked(c, __VA_ARGS__));
#define XCB_SYNCED(func, c, ...) \
({ \
xcb_generic_error_t *e = NULL; \
__auto_type r = func##_reply(c, func(c, __VA_ARGS__), &e); \
if (e) { \
x_print_error(e->sequence, e->major_code, e->minor_code, e->error_code); \
free(e); \
} \
r; \
})
/**
* Send a request to X server and get the reply to make sure all previous
@ -49,9 +51,8 @@ typedef struct winprop {
* xcb_get_input_focus is used here because it is the same request used by
* libX11
*/
static inline void
x_sync(xcb_connection_t *c) {
free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL));
static inline void x_sync(xcb_connection_t *c) {
free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL));
}
/**
@ -69,17 +70,15 @@ x_sync(xcb_connection_t *c) {
* @return a <code>winprop_t</code> structure containing the attribute
* 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);
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);
/**
* 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) {
return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat);
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) {
return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat);
}
/**
@ -87,83 +86,77 @@ wid_get_prop(const session_t *ps, xcb_window_t wid, xcb_atom_t atom, long length
*
* @return the value if successful, 0 otherwise
*/
xcb_window_t
wid_get_prop_window(session_t *ps, xcb_window_t wid, xcb_atom_t aprop);
xcb_window_t wid_get_prop_window(session_t *ps, xcb_window_t wid, xcb_atom_t aprop);
/**
* Get the value of a text property of a window.
*/
bool wid_get_text_prop(session_t *ps, xcb_window_t wid, xcb_atom_t prop,
char ***pstrlst, int *pnstr);
bool wid_get_text_prop(session_t *ps, xcb_window_t wid, xcb_atom_t prop, char ***pstrlst, int *pnstr);
xcb_render_pictforminfo_t *x_get_pictform_for_visual(session_t *, xcb_visualid_t);
xcb_render_pictforminfo_t *x_get_pictform_for_visual(xcb_connection_t *, xcb_visualid_t);
xcb_render_picture_t x_create_picture_with_pictfmt_and_pixmap(
session_t *ps, xcb_render_pictforminfo_t *pictfmt,
xcb_pixmap_t pixmap, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1, 2);
xcb_render_picture_t
x_create_picture_with_pictfmt_and_pixmap(xcb_connection_t *, xcb_render_pictforminfo_t *pictfmt,
xcb_pixmap_t pixmap, unsigned long 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(
session_t *ps, xcb_visualid_t visual,
xcb_pixmap_t pixmap, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1);
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,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1);
xcb_render_picture_t x_create_picture_with_standard_and_pixmap(
session_t *ps, xcb_pict_standard_t standard,
xcb_pixmap_t pixmap, unsigned long 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,
const xcb_render_create_picture_value_list_t *attr)
attr_nonnull(1);
/**
* Create an picture.
*/
xcb_render_picture_t
x_create_picture_with_pictfmt(session_t *ps, int wid, int hei,
xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr);
xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr);
xcb_render_picture_t
x_create_picture_with_visual(session_t *ps, int w, int h,
xcb_visualid_t visual, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr);
x_create_picture_with_visual(session_t *ps, int w, int h, xcb_visualid_t visual, unsigned long valuemask,
const xcb_render_create_picture_value_list_t *attr);
/// Fetch a X region and store it in a pixman region
bool x_fetch_region(session_t *ps, xcb_xfixes_region_t r, region_t *res);
bool x_fetch_region(xcb_connection_t *, xcb_xfixes_region_t r, region_t *res);
void x_set_picture_clip_region(session_t *ps, 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,
int clip_x_origin, int clip_y_origin, const region_t *);
void x_clear_picture_clip_region(session_t *ps, xcb_render_picture_t pict);
void x_clear_picture_clip_region(xcb_connection_t *, xcb_render_picture_t pict);
/**
* X11 error handler function.
*
* 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, uint8_t minor, uint8_t error_code);
xcb_pixmap_t
x_create_pixmap(session_t *ps, uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height);
xcb_pixmap_t x_create_pixmap(xcb_connection_t *, uint8_t depth, xcb_drawable_t drawable,
uint16_t width, uint16_t height);
bool
x_validate_pixmap(session_t *ps, xcb_pixmap_t pxmap);
bool x_validate_pixmap(xcb_connection_t *, xcb_pixmap_t pxmap);
/**
* Free a <code>winprop_t</code>.
*
* @param pprop pointer to the <code>winprop_t</code> to free.
*/
static inline void
free_winprop(winprop_t *pprop) {
// Empty the whole structure to avoid possible issues
if (pprop->r)
free(pprop->r);
pprop->ptr = NULL;
pprop->r = NULL;
pprop->nitems = 0;
static inline void free_winprop(winprop_t *pprop) {
// Empty the whole structure to avoid possible issues
if (pprop->r)
free(pprop->r);
pprop->ptr = NULL;
pprop->r = NULL;
pprop->nitems = 0;
}
/// Get the back pixmap of the root window
xcb_pixmap_t x_get_root_back_pixmap(session_t *ps);
@ -172,4 +165,4 @@ xcb_pixmap_t x_get_root_back_pixmap(session_t *ps);
/// root window background pixmap
bool x_atom_is_background_prop(session_t *ps, xcb_atom_t atom);
bool x_fence_sync(session_t *, xcb_sync_fence_t);
bool x_fence_sync(xcb_connection_t *, xcb_sync_fence_t);