Some new x helper functions

They should be useful for the refactored backends.

Renamed x_create_picture to x_create_picture_with_pictfmt.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2018-12-21 23:44:42 +00:00
parent f8c86d51b3
commit 6c00d46d7a
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
3 changed files with 76 additions and 5 deletions

View File

@ -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) {
@ -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.");
@ -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,

59
src/x.c
View File

@ -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)
{
@ -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,
@ -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.
*
@ -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
src/x.h
View File

@ -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.
*
@ -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);