Skip to content

Commit

Permalink
Merge pull request chjj#73 from yshui/x-helpers
Browse files Browse the repository at this point in the history
Some new x helper functions
  • Loading branch information
yshui authored Dec 21, 2018
2 parents f8c86d5 + 6c00d46 commit 699d40f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 5 deletions.
7 changes: 4 additions & 3 deletions src/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
// Invert window color, if required
if (bkend_use_xrender(ps) && w->invert_color) {
xcb_render_picture_t newpict =
x_create_picture(ps, wid, hei, w->pictfmt, 0, NULL);
x_create_picture_with_pictfmt(ps, wid, hei, w->pictfmt, 0, NULL);
if (newpict) {
// Apply clipping region to save some CPU
if (reg_paint) {
Expand Down Expand Up @@ -684,7 +684,8 @@ xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int x, int y, int wi

// Directly copying from tgt_buffer to it does not work, so we create a
// Picture in the middle.
xcb_render_picture_t tmp_picture = x_create_picture(ps, wid, hei, NULL, 0, NULL);
xcb_render_picture_t tmp_picture =
x_create_picture_with_pictfmt(ps, wid, hei, NULL, 0, NULL);

if (!tmp_picture) {
log_error("Failed to build intermediate Picture.");
Expand Down Expand Up @@ -991,7 +992,7 @@ void paint_all(session_t *ps, region_t *region, const region_t *region_real, win
// Then we create a new picture, and copy content to it
xcb_render_pictforminfo_t *pictfmt =
x_get_pictform_for_visual(ps, ps->vis);
xcb_render_picture_t new_pict = x_create_picture(
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,
ps->tgt_buffer.pict, None, new_pict, 0, 0, 0,
Expand Down
59 changes: 58 additions & 1 deletion src/x.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ x_create_picture_with_standard_and_pixmap(
* Create an picture.
*/
xcb_render_picture_t
x_create_picture(session_t *ps, int wid, int hei,
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)
{
Expand All @@ -214,6 +214,15 @@ x_create_picture(session_t *ps, int wid, int hei,
return picture;
}

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)
{
xcb_render_pictforminfo_t *pictfmt = x_get_pictform_for_visual(ps, 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) {
xcb_generic_error_t *e = NULL;
xcb_xfixes_fetch_region_reply_t *xr = xcb_xfixes_fetch_region_reply(ps->c,
Expand Down Expand Up @@ -263,6 +272,19 @@ 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) {
xcb_render_change_picture_value_list_t v = {
.clipmask = None
};
xcb_generic_error_t *e =
xcb_request_check(ps->c, xcb_render_change_picture(ps->c, pict,
XCB_RENDER_CP_CLIP_MASK, &v));
if (e)
log_error("failed to clear clip region");
free(e);
return;
}

/**
* X11 error handler function.
*
Expand Down Expand Up @@ -390,3 +412,38 @@ x_validate_pixmap(session_t *ps, xcb_pixmap_t pxmap) {
return XGetGeometry(ps->dpy, pxmap, &rroot, &rx, &ry,
&rwid, &rhei, &rborder, &rdepth) && rwid && rhei;
}
/// Names of root window properties that could point to a pixmap of
/// background.
static const char *background_props_str[] = {
"_XROOTPMAP_ID",
"_XSETROOT_ID",
0,
};

xcb_pixmap_t x_get_root_back_pixmap(session_t *ps) {
xcb_pixmap_t pixmap = XCB_NONE;

// Get the values of background attributes
for (int p = 0; background_props_str[p]; p++) {
xcb_atom_t prop_atom = get_atom(ps, background_props_str[p]);
winprop_t prop =
wid_get_prop(ps, ps->root, prop_atom, 1, XCB_ATOM_PIXMAP, 32);
if (prop.nitems) {
pixmap = *prop.p32;
free_winprop(&prop);
break;
}
free_winprop(&prop);
}

return pixmap;
}

bool x_atom_is_background_prop(session_t *ps, xcb_atom_t atom) {
for (int p = 0; background_props_str[p]; p++) {
xcb_atom_t prop_atom = get_atom(ps, background_props_str[p]);
if (prop_atom == atom)
return true;
}
return false;
}
15 changes: 14 additions & 1 deletion src/x.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,23 @@ attr_nonnull(1);
* Create an picture.
*/
xcb_render_picture_t
x_create_picture(session_t *ps, int wid, int hei,
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_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);

/// 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);

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_clear_picture_clip_region(session_t *ps, xcb_render_picture_t pict);

/**
* X11 error handler function.
*
Expand Down Expand Up @@ -154,3 +161,9 @@ free_winprop(winprop_t *pprop) {
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);

/// Return true if the atom refers to a property name that is used for the
/// root window background pixmap
bool x_atom_is_background_prop(session_t *ps, xcb_atom_t atom);

0 comments on commit 699d40f

Please sign in to comment.