x: Add region related helper functions
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
3f4c05720d
commit
56f7dd36f6
2
Makefile
2
Makefile
|
@ -9,7 +9,7 @@ MANDIR ?= $(PREFIX)/share/man/man1
|
||||||
APPDIR ?= $(PREFIX)/share/applications
|
APPDIR ?= $(PREFIX)/share/applications
|
||||||
ICODIR ?= $(PREFIX)/share/icons/hicolor/
|
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
|
LIBS = -lm -lrt
|
||||||
INCS =
|
INCS =
|
||||||
|
|
||||||
|
|
|
@ -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
53
src/x.c
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <xcb/xcb_renderutil.h>
|
#include <xcb/xcb_renderutil.h>
|
||||||
|
#include <xcb/xfixes.h>
|
||||||
|
#include <pixman.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "x.h"
|
#include "x.h"
|
||||||
|
@ -208,3 +210,54 @@ x_create_picture(session_t *ps, int wid, int hei,
|
||||||
|
|
||||||
return picture;
|
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
10
src/x.h
|
@ -4,8 +4,12 @@
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
#include <xcb/xcb_renderutil.h>
|
#include <xcb/xcb_renderutil.h>
|
||||||
|
|
||||||
|
#include "region.h"
|
||||||
|
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
typedef struct winprop winprop_t;
|
typedef struct winprop winprop_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a specific attribute of a window.
|
* 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,
|
x_create_picture(session_t *ps, int wid, int hei,
|
||||||
xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
|
xcb_render_pictforminfo_t *pictfmt, unsigned long valuemask,
|
||||||
const xcb_render_create_picture_value_list_t *attr);
|
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 *);
|
||||||
|
|
Loading…
Reference in New Issue