x: Add region related helper functions

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2018-09-29 23:36:53 +01:00
parent 3f4c05720d
commit 56f7dd36f6
4 changed files with 89 additions and 1 deletions

View File

@ -9,7 +9,7 @@ MANDIR ?= $(PREFIX)/share/man/man1
APPDIR ?= $(PREFIX)/share/applications
ICODIR ?= $(PREFIX)/share/icons/hicolor/
PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-shape xcb-image xcb-xfixes xfixes xext
PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-composite xcb-shape xcb-image xcb-xfixes xfixes xext pixman-1
LIBS = -lm -lrt
INCS =

25
src/region.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <pixman.h>
#include <stdio.h>
#include "utils.h"
typedef struct pixman_region32 pixman_region32_t;
typedef struct pixman_box32 pixman_box32_t;
typedef pixman_region32_t region_t;
typedef pixman_box32_t rect_t;
RC_TYPE(region_t, rc_region, pixman_region32_init, pixman_region32_fini, static inline)
/// copy a region_t
static inline void
copy_region_(region_t *dst, const region_t *p) {
pixman_region32_copy(dst, (region_t *)p);
}
static inline void
dump_region_(const region_t *x) {
int nrects;
const rect_t *rects = pixman_region32_rectangles((region_t *)x, &nrects);
fprintf(stderr, "nrects: %d\n", nrects);
for (int i = 0; i < nrects; i++)
fprintf(stderr, "(%d, %d) - (%d, %d)\n", rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
}

53
src/x.c
View File

@ -2,6 +2,8 @@
#include <X11/Xlib.h>
#include <xcb/xcb_renderutil.h>
#include <xcb/xfixes.h>
#include <pixman.h>
#include "common.h"
#include "x.h"
@ -208,3 +210,54 @@ x_create_picture(session_t *ps, int wid, int hei,
return picture;
}
bool x_fetch_region(session_t *ps, XserverRegion r, pixman_region32_t *res) {
xcb_generic_error_t *e = NULL;
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
xcb_xfixes_fetch_region_reply_t *xr = xcb_xfixes_fetch_region_reply(c,
xcb_xfixes_fetch_region(c, r), &e);
if (!xr) {
printf_errf("(): failed to fetch rectangles");
return false;
}
int nrect = xcb_xfixes_fetch_region_rectangles_length(xr);
pixman_box32_t *b = calloc(nrect, sizeof *b);
xcb_rectangle_t *xrect = xcb_xfixes_fetch_region_rectangles(xr);
for (int i = 0; i < nrect; i++) {
b[i] = (pixman_box32_t) {
.x1 = xrect[i].x,
.y1 = xrect[i].y,
.x2 = xrect[i].x + xrect[i].width,
.y2 = xrect[i].y + xrect[i].height
};
}
bool ret = pixman_region32_init_rects(res, b, nrect);
free(b);
free(xr);
return ret;
}
void x_set_picture_clip_region(session_t *ps, 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);
xcb_rectangle_t *xrects = calloc(nrects, sizeof *xrects);
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,
};
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
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));
if (e)
printf_errf("(): failed to set clip region");
free(e);
free(xrects);
return;
}

10
src/x.h
View File

@ -4,8 +4,12 @@
#include <xcb/xcb.h>
#include <xcb/render.h>
#include <xcb/xcb_renderutil.h>
#include "region.h"
typedef struct session session_t;
typedef struct winprop winprop_t;
/**
* Get a specific attribute of a window.
*
@ -66,3 +70,9 @@ xcb_render_picture_t
x_create_picture(session_t *ps, int wid, int hei,
xcb_render_pictforminfo_t *pictfmt, 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, XserverRegion 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 *);