Port from xrender to xcb-render
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
6d54d6b055
commit
539d62ca93
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-image xcomposite xfixes xrender xext
|
PACKAGES = x11 x11-xcb xcb-renderutil xcb-render xcb-damage xcb-randr xcb-image xcomposite xfixes xext
|
||||||
LIBS = -lm -lrt
|
LIBS = -lm -lrt
|
||||||
INCS =
|
INCS =
|
||||||
|
|
||||||
|
|
23
src/common.h
23
src/common.h
|
@ -83,7 +83,6 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
#include <X11/extensions/Xrender.h>
|
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#include <X11/extensions/Xdbe.h>
|
#include <X11/extensions/Xdbe.h>
|
||||||
#ifdef CONFIG_XSYNC
|
#ifdef CONFIG_XSYNC
|
||||||
|
@ -219,6 +218,10 @@
|
||||||
// Window opacity / dim state changed
|
// Window opacity / dim state changed
|
||||||
#define WFLAG_OPCT_CHANGE 0x0004
|
#define WFLAG_OPCT_CHANGE 0x0004
|
||||||
|
|
||||||
|
// xcb-render specific macros
|
||||||
|
#define XFIXED_TO_DOUBLE(value) (((double) (value)) / 65536)
|
||||||
|
#define DOUBLE_TO_XFIXED(value) ((xcb_render_fixed_t) (((double) (value)) * 65536))
|
||||||
|
|
||||||
// === Types ===
|
// === Types ===
|
||||||
|
|
||||||
typedef uint32_t opacity_t;
|
typedef uint32_t opacity_t;
|
||||||
|
@ -489,7 +492,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Pixmap pixmap;
|
Pixmap pixmap;
|
||||||
Picture pict;
|
xcb_render_picture_t pict;
|
||||||
glx_texture_t *ptex;
|
glx_texture_t *ptex;
|
||||||
} paint_t;
|
} paint_t;
|
||||||
|
|
||||||
|
@ -685,7 +688,7 @@ typedef struct _options_t {
|
||||||
/// Background blur blacklist. A linked list of conditions.
|
/// Background blur blacklist. A linked list of conditions.
|
||||||
c2_lptr_t *blur_background_blacklist;
|
c2_lptr_t *blur_background_blacklist;
|
||||||
/// Blur convolution kernel.
|
/// Blur convolution kernel.
|
||||||
XFixed *blur_kerns[MAX_BLUR_PASS];
|
xcb_render_fixed_t *blur_kerns[MAX_BLUR_PASS];
|
||||||
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
||||||
double inactive_dim;
|
double inactive_dim;
|
||||||
/// Whether to use fixed inactive dim opacity, instead of deciding
|
/// Whether to use fixed inactive dim opacity, instead of deciding
|
||||||
|
@ -811,9 +814,9 @@ typedef struct session {
|
||||||
XserverRegion screen_reg;
|
XserverRegion screen_reg;
|
||||||
/// Picture of root window. Destination of painting in no-DBE painting
|
/// Picture of root window. Destination of painting in no-DBE painting
|
||||||
/// mode.
|
/// mode.
|
||||||
Picture root_picture;
|
xcb_render_picture_t root_picture;
|
||||||
/// A Picture acting as the painting target.
|
/// A Picture acting as the painting target.
|
||||||
Picture tgt_picture;
|
xcb_render_picture_t tgt_picture;
|
||||||
/// Temporary buffer to paint to before sending to display.
|
/// Temporary buffer to paint to before sending to display.
|
||||||
paint_t tgt_buffer;
|
paint_t tgt_buffer;
|
||||||
#ifdef CONFIG_XSYNC
|
#ifdef CONFIG_XSYNC
|
||||||
|
@ -859,7 +862,7 @@ typedef struct session {
|
||||||
/// Whether all windows are currently redirected.
|
/// Whether all windows are currently redirected.
|
||||||
bool redirected;
|
bool redirected;
|
||||||
/// Pre-generated alpha pictures.
|
/// Pre-generated alpha pictures.
|
||||||
Picture *alpha_picts;
|
xcb_render_picture_t *alpha_picts;
|
||||||
/// Whether all reg_ignore of windows should expire in this paint.
|
/// Whether all reg_ignore of windows should expire in this paint.
|
||||||
bool reg_ignore_expire;
|
bool reg_ignore_expire;
|
||||||
/// Time of last fading. In milliseconds.
|
/// Time of last fading. In milliseconds.
|
||||||
|
@ -870,7 +873,7 @@ typedef struct session {
|
||||||
/// ignore linked list.
|
/// ignore linked list.
|
||||||
ignore_t **ignore_tail;
|
ignore_t **ignore_tail;
|
||||||
// Cached blur convolution kernels.
|
// Cached blur convolution kernels.
|
||||||
XFixed *blur_kerns_cache[MAX_BLUR_PASS];
|
xcb_render_fixed_t *blur_kerns_cache[MAX_BLUR_PASS];
|
||||||
/// Reset program after next paint.
|
/// Reset program after next paint.
|
||||||
bool reset;
|
bool reset;
|
||||||
|
|
||||||
|
@ -897,11 +900,11 @@ typedef struct session {
|
||||||
|
|
||||||
// === Shadow/dimming related ===
|
// === Shadow/dimming related ===
|
||||||
/// 1x1 black Picture.
|
/// 1x1 black Picture.
|
||||||
Picture black_picture;
|
xcb_render_picture_t black_picture;
|
||||||
/// 1x1 Picture of the shadow color.
|
/// 1x1 Picture of the shadow color.
|
||||||
Picture cshadow_picture;
|
xcb_render_picture_t cshadow_picture;
|
||||||
/// 1x1 white Picture.
|
/// 1x1 white Picture.
|
||||||
Picture white_picture;
|
xcb_render_picture_t white_picture;
|
||||||
/// Gaussian map of shadow.
|
/// Gaussian map of shadow.
|
||||||
conv *gaussian_map;
|
conv *gaussian_map;
|
||||||
// for shadow precomputation
|
// for shadow precomputation
|
||||||
|
|
181
src/compton.c
181
src/compton.c
|
@ -25,8 +25,8 @@ static void
|
||||||
configure_win(session_t *ps, xcb_configure_notify_event_t *ce);
|
configure_win(session_t *ps, xcb_configure_notify_event_t *ce);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
xr_blur_dst(session_t *ps, Picture tgt_buffer,
|
xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer,
|
||||||
int x, int y, int wid, int hei, XFixed **blur_kerns,
|
int x, int y, int wid, int hei, xcb_render_fixed_t **blur_kerns,
|
||||||
XserverRegion reg_clip);
|
XserverRegion reg_clip);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -619,7 +619,7 @@ win_build_shadow(session_t *ps, win *w, double opacity) {
|
||||||
|
|
||||||
xcb_image_t *shadow_image = NULL;
|
xcb_image_t *shadow_image = NULL;
|
||||||
Pixmap shadow_pixmap = None, shadow_pixmap_argb = None;
|
Pixmap shadow_pixmap = None, shadow_pixmap_argb = None;
|
||||||
Picture shadow_picture = None, shadow_picture_argb = None;
|
xcb_render_picture_t shadow_picture = None, shadow_picture_argb = None;
|
||||||
GC gc = None;
|
GC gc = None;
|
||||||
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
|
|
||||||
|
@ -653,7 +653,7 @@ win_build_shadow(session_t *ps, win *w, double opacity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_image_put(c, shadow_pixmap, XGContextFromGC(gc), shadow_image, 0, 0, 0);
|
xcb_image_put(c, shadow_pixmap, XGContextFromGC(gc), shadow_image, 0, 0, 0);
|
||||||
XRenderComposite(ps->dpy, PictOpSrc, ps->cshadow_picture, shadow_picture,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, ps->cshadow_picture, shadow_picture,
|
||||||
shadow_picture_argb, 0, 0, 0, 0, 0, 0,
|
shadow_picture_argb, 0, 0, 0, 0, 0, 0,
|
||||||
shadow_image->width, shadow_image->height);
|
shadow_image->width, shadow_image->height);
|
||||||
|
|
||||||
|
@ -668,7 +668,7 @@ win_build_shadow(session_t *ps, win *w, double opacity) {
|
||||||
XFreeGC(ps->dpy, gc);
|
XFreeGC(ps->dpy, gc);
|
||||||
xcb_image_destroy(shadow_image);
|
xcb_image_destroy(shadow_image);
|
||||||
XFreePixmap(ps->dpy, shadow_pixmap);
|
XFreePixmap(ps->dpy, shadow_pixmap);
|
||||||
XRenderFreePicture(ps->dpy, shadow_picture);
|
xcb_render_free_picture(c, shadow_picture);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -680,9 +680,9 @@ shadow_picture_err:
|
||||||
if (shadow_pixmap_argb)
|
if (shadow_pixmap_argb)
|
||||||
XFreePixmap(ps->dpy, shadow_pixmap_argb);
|
XFreePixmap(ps->dpy, shadow_pixmap_argb);
|
||||||
if (shadow_picture)
|
if (shadow_picture)
|
||||||
XRenderFreePicture(ps->dpy, shadow_picture);
|
xcb_render_free_picture(c, shadow_picture);
|
||||||
if (shadow_picture_argb)
|
if (shadow_picture_argb)
|
||||||
XRenderFreePicture(ps->dpy, shadow_picture_argb);
|
xcb_render_free_picture(c, shadow_picture_argb);
|
||||||
if (gc)
|
if (gc)
|
||||||
XFreeGC(ps->dpy, gc);
|
XFreeGC(ps->dpy, gc);
|
||||||
|
|
||||||
|
@ -692,13 +692,15 @@ shadow_picture_err:
|
||||||
/**
|
/**
|
||||||
* Generate a 1x1 <code>Picture</code> of a particular color.
|
* Generate a 1x1 <code>Picture</code> of a particular color.
|
||||||
*/
|
*/
|
||||||
static Picture
|
static xcb_render_picture_t
|
||||||
solid_picture(session_t *ps, bool argb, double a,
|
solid_picture(session_t *ps, bool argb, double a,
|
||||||
double r, double g, double b) {
|
double r, double g, double b) {
|
||||||
Pixmap pixmap;
|
Pixmap pixmap;
|
||||||
Picture picture;
|
xcb_render_picture_t picture;
|
||||||
xcb_render_create_picture_value_list_t pa;
|
xcb_render_create_picture_value_list_t pa;
|
||||||
XRenderColor c;
|
xcb_render_color_t col;
|
||||||
|
xcb_rectangle_t rect;
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
|
|
||||||
pixmap = XCreatePixmap(ps->dpy, ps->root, 1, 1, argb ? 32 : 8);
|
pixmap = XCreatePixmap(ps->dpy, ps->root, 1, 1, argb ? 32 : 8);
|
||||||
|
|
||||||
|
@ -707,19 +709,24 @@ solid_picture(session_t *ps, bool argb, double a,
|
||||||
pa.repeat = True;
|
pa.repeat = True;
|
||||||
picture = x_create_picture_with_standard_and_pixmap(ps,
|
picture = x_create_picture_with_standard_and_pixmap(ps,
|
||||||
argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
|
argb ? XCB_PICT_STANDARD_ARGB_32 : XCB_PICT_STANDARD_A_8, pixmap,
|
||||||
CPRepeat, &pa);
|
XCB_RENDER_CP_REPEAT, &pa);
|
||||||
|
|
||||||
if (!picture) {
|
if (!picture) {
|
||||||
XFreePixmap(ps->dpy, pixmap);
|
XFreePixmap(ps->dpy, pixmap);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.alpha = a * 0xffff;
|
col.alpha = a * 0xffff;
|
||||||
c.red = r * 0xffff;
|
col.red = r * 0xffff;
|
||||||
c.green = g * 0xffff;
|
col.green = g * 0xffff;
|
||||||
c.blue = b * 0xffff;
|
col.blue = b * 0xffff;
|
||||||
|
|
||||||
XRenderFillRectangle(ps->dpy, PictOpSrc, picture, &c, 0, 0, 1, 1);
|
rect.x = 0;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.width = 1;
|
||||||
|
rect.height = 1;
|
||||||
|
|
||||||
|
xcb_render_fill_rectangles(c, XCB_RENDER_PICT_OP_SRC, picture, col, 1, &rect);
|
||||||
XFreePixmap(ps->dpy, pixmap);
|
XFreePixmap(ps->dpy, pixmap);
|
||||||
|
|
||||||
return picture;
|
return picture;
|
||||||
|
@ -858,6 +865,7 @@ get_root_tile(session_t *ps) {
|
||||||
if (ps->o.paint_on_overlay) {
|
if (ps->o.paint_on_overlay) {
|
||||||
return ps->root_picture;
|
return ps->root_picture;
|
||||||
} */
|
} */
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
|
|
||||||
assert(!ps->root_tile_paint.pixmap);
|
assert(!ps->root_tile_paint.pixmap);
|
||||||
ps->root_tile_fill = false;
|
ps->root_tile_fill = false;
|
||||||
|
@ -894,15 +902,20 @@ get_root_tile(session_t *ps) {
|
||||||
.repeat = True,
|
.repeat = True,
|
||||||
};
|
};
|
||||||
ps->root_tile_paint.pict = x_create_picture_with_visual_and_pixmap(
|
ps->root_tile_paint.pict = x_create_picture_with_visual_and_pixmap(
|
||||||
ps, ps->vis, pixmap, CPRepeat, &pa);
|
ps, ps->vis, pixmap, XCB_RENDER_CP_REPEAT, &pa);
|
||||||
|
|
||||||
// Fill pixmap if needed
|
// Fill pixmap if needed
|
||||||
if (fill) {
|
if (fill) {
|
||||||
XRenderColor c;
|
xcb_render_color_t col;
|
||||||
|
xcb_rectangle_t rect;
|
||||||
|
|
||||||
c.red = c.green = c.blue = 0x8080;
|
col.red = col.green = col.blue = 0x8080;
|
||||||
c.alpha = 0xffff;
|
col.alpha = 0xffff;
|
||||||
XRenderFillRectangle(ps->dpy, PictOpSrc, ps->root_tile_paint.pict, &c, 0, 0, 1, 1);
|
|
||||||
|
rect.x = rect.y = 0;
|
||||||
|
rect.width = rect.height = 1;
|
||||||
|
|
||||||
|
xcb_render_fill_rectangles(c, XCB_RENDER_PICT_OP_SRC, ps->root_tile_paint.pict, col, 1, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
ps->root_tile_fill = fill;
|
ps->root_tile_fill = fill;
|
||||||
|
@ -958,7 +971,7 @@ find_client_win(session_t *ps, Window w) {
|
||||||
/**
|
/**
|
||||||
* Get alpha <code>Picture</code> for an opacity in <code>double</code>.
|
* Get alpha <code>Picture</code> for an opacity in <code>double</code>.
|
||||||
*/
|
*/
|
||||||
static inline Picture
|
static inline xcb_render_picture_t
|
||||||
get_alpha_pict_d(session_t *ps, double o) {
|
get_alpha_pict_d(session_t *ps, double o) {
|
||||||
assert((round(normalize_d(o) / ps->o.alpha_step)) <= round(1.0 / ps->o.alpha_step));
|
assert((round(normalize_d(o) / ps->o.alpha_step)) <= round(1.0 / ps->o.alpha_step));
|
||||||
return ps->alpha_picts[(int) (round(normalize_d(o)
|
return ps->alpha_picts[(int) (round(normalize_d(o)
|
||||||
|
@ -969,7 +982,7 @@ get_alpha_pict_d(session_t *ps, double o) {
|
||||||
* Get alpha <code>Picture</code> for an opacity in
|
* Get alpha <code>Picture</code> for an opacity in
|
||||||
* <code>opacity_t</code>.
|
* <code>opacity_t</code>.
|
||||||
*/
|
*/
|
||||||
static inline Picture
|
static inline xcb_render_picture_t
|
||||||
get_alpha_pict_o(session_t *ps, opacity_t o) {
|
get_alpha_pict_o(session_t *ps, opacity_t o) {
|
||||||
return get_alpha_pict_d(ps, (double) o / OPAQUE);
|
return get_alpha_pict_d(ps, (double) o / OPAQUE);
|
||||||
}
|
}
|
||||||
|
@ -1234,14 +1247,15 @@ win_paint_shadow(session_t *ps, win *w,
|
||||||
* @return true if successful, false otherwise
|
* @return true if successful, false otherwise
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
xr_blur_dst(session_t *ps, Picture tgt_buffer,
|
xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer,
|
||||||
int x, int y, int wid, int hei, XFixed **blur_kerns,
|
int x, int y, int wid, int hei, xcb_render_fixed_t **blur_kerns,
|
||||||
XserverRegion reg_clip) {
|
XserverRegion reg_clip) {
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
assert(blur_kerns[0]);
|
assert(blur_kerns[0]);
|
||||||
|
|
||||||
// Directly copying from tgt_buffer to it does not work, so we create a
|
// Directly copying from tgt_buffer to it does not work, so we create a
|
||||||
// Picture in the middle.
|
// Picture in the middle.
|
||||||
Picture tmp_picture = x_create_picture(ps, wid, hei, NULL, 0, NULL);
|
xcb_render_picture_t tmp_picture = x_create_picture(ps, wid, hei, NULL, 0, NULL);
|
||||||
|
|
||||||
if (!tmp_picture) {
|
if (!tmp_picture) {
|
||||||
printf_errf("(): Failed to build intermediate Picture.");
|
printf_errf("(): Failed to build intermediate Picture.");
|
||||||
|
@ -1251,20 +1265,20 @@ xr_blur_dst(session_t *ps, Picture tgt_buffer,
|
||||||
if (reg_clip && tmp_picture)
|
if (reg_clip && tmp_picture)
|
||||||
XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_clip, 0, 0);
|
XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_clip, 0, 0);
|
||||||
|
|
||||||
Picture src_pict = tgt_buffer, dst_pict = tmp_picture;
|
xcb_render_picture_t src_pict = tgt_buffer, dst_pict = tmp_picture;
|
||||||
for (int i = 0; blur_kerns[i]; ++i) {
|
for (int i = 0; blur_kerns[i]; ++i) {
|
||||||
assert(i < MAX_BLUR_PASS - 1);
|
assert(i < MAX_BLUR_PASS - 1);
|
||||||
XFixed *convolution_blur = blur_kerns[i];
|
xcb_render_fixed_t *convolution_blur = blur_kerns[i];
|
||||||
int kwid = XFixedToDouble(convolution_blur[0]),
|
int kwid = XFIXED_TO_DOUBLE(convolution_blur[0]),
|
||||||
khei = XFixedToDouble(convolution_blur[1]);
|
khei = XFIXED_TO_DOUBLE(convolution_blur[1]);
|
||||||
bool rd_from_tgt = (tgt_buffer == src_pict);
|
bool rd_from_tgt = (tgt_buffer == src_pict);
|
||||||
|
|
||||||
// Copy from source picture to destination. The filter must
|
// Copy from source picture to destination. The filter must
|
||||||
// be applied on source picture, to get the nearby pixels outside the
|
// be applied on source picture, to get the nearby pixels outside the
|
||||||
// window.
|
// window.
|
||||||
XRenderSetPictureFilter(ps->dpy, src_pict, XRFILTER_CONVOLUTION,
|
xcb_render_set_picture_filter(c, src_pict, strlen(XRFILTER_CONVOLUTION), XRFILTER_CONVOLUTION,
|
||||||
convolution_blur, kwid * khei + 2);
|
kwid * khei + 2, convolution_blur);
|
||||||
XRenderComposite(ps->dpy, PictOpSrc, src_pict, None, dst_pict,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, src_pict, None, dst_pict,
|
||||||
(rd_from_tgt ? x: 0), (rd_from_tgt ? y: 0), 0, 0,
|
(rd_from_tgt ? x: 0), (rd_from_tgt ? y: 0), 0, 0,
|
||||||
(rd_from_tgt ? 0: x), (rd_from_tgt ? 0: y), wid, hei);
|
(rd_from_tgt ? 0: x), (rd_from_tgt ? 0: y), wid, hei);
|
||||||
xrfilter_reset(ps, src_pict);
|
xrfilter_reset(ps, src_pict);
|
||||||
|
@ -1277,7 +1291,7 @@ xr_blur_dst(session_t *ps, Picture tgt_buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_pict != tgt_buffer)
|
if (src_pict != tgt_buffer)
|
||||||
XRenderComposite(ps->dpy, PictOpSrc, src_pict, None, tgt_buffer,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, src_pict, None, tgt_buffer,
|
||||||
0, 0, 0, 0, x, y, wid, hei);
|
0, 0, 0, 0, x, y, wid, hei);
|
||||||
|
|
||||||
free_picture(ps, &tmp_picture);
|
free_picture(ps, &tmp_picture);
|
||||||
|
@ -1303,7 +1317,7 @@ xr_take_screenshot(session_t *ps) {
|
||||||
* Blur the background of a window.
|
* Blur the background of a window.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
win_blur_background(session_t *ps, win *w, xcb_render_picture_t tgt_buffer,
|
||||||
XserverRegion reg_paint, const reg_data_t *pcache_reg) {
|
XserverRegion reg_paint, const reg_data_t *pcache_reg) {
|
||||||
const int x = w->g.x;
|
const int x = w->g.x;
|
||||||
const int y = w->g.y;
|
const int y = w->g.y;
|
||||||
|
@ -1324,8 +1338,8 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
{
|
{
|
||||||
// Normalize blur kernels
|
// Normalize blur kernels
|
||||||
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
||||||
XFixed *kern_src = ps->o.blur_kerns[i];
|
xcb_render_fixed_t *kern_src = ps->o.blur_kerns[i];
|
||||||
XFixed *kern_dst = ps->blur_kerns_cache[i];
|
xcb_render_fixed_t *kern_dst = ps->blur_kerns_cache[i];
|
||||||
assert(i < MAX_BLUR_PASS);
|
assert(i < MAX_BLUR_PASS);
|
||||||
if (!kern_src) {
|
if (!kern_src) {
|
||||||
assert(!kern_dst);
|
assert(!kern_dst);
|
||||||
|
@ -1338,12 +1352,12 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
// Skip for fixed factor_center if the cache exists already
|
// Skip for fixed factor_center if the cache exists already
|
||||||
if (ps->o.blur_background_fixed && kern_dst) continue;
|
if (ps->o.blur_background_fixed && kern_dst) continue;
|
||||||
|
|
||||||
int kwid = XFixedToDouble(kern_src[0]),
|
int kwid = XFIXED_TO_DOUBLE(kern_src[0]),
|
||||||
khei = XFixedToDouble(kern_src[1]);
|
khei = XFIXED_TO_DOUBLE(kern_src[1]);
|
||||||
|
|
||||||
// Allocate cache space if needed
|
// Allocate cache space if needed
|
||||||
if (!kern_dst) {
|
if (!kern_dst) {
|
||||||
kern_dst = malloc((kwid * khei + 2) * sizeof(XFixed));
|
kern_dst = malloc((kwid * khei + 2) * sizeof(xcb_render_fixed_t));
|
||||||
if (!kern_dst) {
|
if (!kern_dst) {
|
||||||
printf_errf("(): Failed to allocate memory for blur kernel.");
|
printf_errf("(): Failed to allocate memory for blur kernel.");
|
||||||
return;
|
return;
|
||||||
|
@ -1353,10 +1367,10 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
|
|
||||||
// Modify the factor of the center pixel
|
// Modify the factor of the center pixel
|
||||||
kern_src[2 + (khei / 2) * kwid + kwid / 2] =
|
kern_src[2 + (khei / 2) * kwid + kwid / 2] =
|
||||||
XDoubleToFixed(factor_center);
|
DOUBLE_TO_XFIXED(factor_center);
|
||||||
|
|
||||||
// Copy over
|
// Copy over
|
||||||
memcpy(kern_dst, kern_src, (kwid * khei + 2) * sizeof(XFixed));
|
memcpy(kern_dst, kern_src, (kwid * khei + 2) * sizeof(xcb_render_fixed_t));
|
||||||
normalize_conv_kern(kwid, khei, kern_dst + 2);
|
normalize_conv_kern(kwid, khei, kern_dst + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1389,20 +1403,21 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
void
|
void
|
||||||
render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||||
double opacity, bool argb, bool neg,
|
double opacity, bool argb, bool neg,
|
||||||
Picture pict, glx_texture_t *ptex,
|
xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||||
XserverRegion reg_paint, const reg_data_t *pcache_reg
|
XserverRegion reg_paint, const reg_data_t *pcache_reg
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
, const glx_prog_main_t *pprogram
|
, const glx_prog_main_t *pprogram
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
switch (ps->o.backend) {
|
switch (ps->o.backend) {
|
||||||
case BKEND_XRENDER:
|
case BKEND_XRENDER:
|
||||||
case BKEND_XR_GLX_HYBRID:
|
case BKEND_XR_GLX_HYBRID:
|
||||||
{
|
{
|
||||||
Picture alpha_pict = get_alpha_pict_d(ps, opacity);
|
xcb_render_picture_t alpha_pict = get_alpha_pict_d(ps, opacity);
|
||||||
if (alpha_pict != ps->alpha_picts[0]) {
|
if (alpha_pict != ps->alpha_picts[0]) {
|
||||||
int op = ((!argb && !alpha_pict) ? PictOpSrc: PictOpOver);
|
int op = ((!argb && !alpha_pict) ? XCB_RENDER_PICT_OP_SRC: XCB_RENDER_PICT_OP_OVER);
|
||||||
XRenderComposite(ps->dpy, op, pict, alpha_pict,
|
xcb_render_composite(c, op, pict, alpha_pict,
|
||||||
ps->tgt_buffer.pict, x, y, 0, 0, dx, dy, wid, hei);
|
ps->tgt_buffer.pict, x, y, 0, 0, dx, dy, wid, hei);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1425,6 +1440,7 @@ render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||||
static inline void
|
static inline void
|
||||||
win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
||||||
const reg_data_t *pcache_reg) {
|
const reg_data_t *pcache_reg) {
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
glx_mark(ps, w->id, true);
|
glx_mark(ps, w->id, true);
|
||||||
|
|
||||||
// Fetch Pixmap
|
// Fetch Pixmap
|
||||||
|
@ -1447,7 +1463,7 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
||||||
};
|
};
|
||||||
|
|
||||||
w->paint.pict = x_create_picture_with_pictfmt_and_pixmap(ps, w->pictfmt,
|
w->paint.pict = x_create_picture_with_pictfmt_and_pixmap(ps, w->pictfmt,
|
||||||
draw, CPSubwindowMode, &pa);
|
draw, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1474,11 +1490,11 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
||||||
const int wid = w->widthb;
|
const int wid = w->widthb;
|
||||||
const int hei = w->heightb;
|
const int hei = w->heightb;
|
||||||
|
|
||||||
Picture pict = w->paint.pict;
|
xcb_render_picture_t pict = w->paint.pict;
|
||||||
|
|
||||||
// Invert window color, if required
|
// Invert window color, if required
|
||||||
if (bkend_use_xrender(ps) && w->invert_color) {
|
if (bkend_use_xrender(ps) && w->invert_color) {
|
||||||
Picture newpict = x_create_picture(ps, wid, hei, w->pictfmt, 0, NULL);
|
xcb_render_picture_t newpict = x_create_picture(ps, wid, hei, w->pictfmt, 0, NULL);
|
||||||
if (newpict) {
|
if (newpict) {
|
||||||
// Apply clipping region to save some CPU
|
// Apply clipping region to save some CPU
|
||||||
if (reg_paint) {
|
if (reg_paint) {
|
||||||
|
@ -1488,14 +1504,14 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
||||||
free_region(ps, ®);
|
free_region(ps, ®);
|
||||||
}
|
}
|
||||||
|
|
||||||
XRenderComposite(ps->dpy, PictOpSrc, pict, None,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, pict, None,
|
||||||
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||||
XRenderComposite(ps->dpy, PictOpDifference, ps->white_picture, None,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_DIFFERENCE, ps->white_picture, None,
|
||||||
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||||
// We use an extra PictOpInReverse operation to get correct pixel
|
// We use an extra PictOpInReverse operation to get correct pixel
|
||||||
// alpha. There could be a better solution.
|
// alpha. There could be a better solution.
|
||||||
if (WMODE_ARGB == w->mode)
|
if (WMODE_ARGB == w->mode)
|
||||||
XRenderComposite(ps->dpy, PictOpInReverse, pict, None,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_IN_REVERSE, pict, None,
|
||||||
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||||
pict = newpict;
|
pict = newpict;
|
||||||
}
|
}
|
||||||
|
@ -1576,19 +1592,19 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
||||||
unsigned short cval = 0xffff * dim_opacity;
|
unsigned short cval = 0xffff * dim_opacity;
|
||||||
|
|
||||||
// Premultiply color
|
// Premultiply color
|
||||||
XRenderColor color = {
|
xcb_render_color_t color = {
|
||||||
.red = 0, .green = 0, .blue = 0, .alpha = cval,
|
.red = 0, .green = 0, .blue = 0, .alpha = cval,
|
||||||
};
|
};
|
||||||
|
|
||||||
XRectangle rect = {
|
xcb_rectangle_t rect = {
|
||||||
.x = x,
|
.x = x,
|
||||||
.y = y,
|
.y = y,
|
||||||
.width = wid,
|
.width = wid,
|
||||||
.height = hei,
|
.height = hei,
|
||||||
};
|
};
|
||||||
|
|
||||||
XRenderFillRectangles(ps->dpy, PictOpOver, ps->tgt_buffer.pict,
|
xcb_render_fill_rectangles(c, XCB_RENDER_PICT_OP_OVER, ps->tgt_buffer.pict,
|
||||||
&color, &rect, 1);
|
color, 1, &rect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
|
@ -1654,6 +1670,7 @@ is_region_empty(const session_t *ps, XserverRegion region,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t) {
|
paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t) {
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
if (!region_real)
|
if (!region_real)
|
||||||
region_real = region;
|
region_real = region;
|
||||||
|
|
||||||
|
@ -1709,7 +1726,7 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
|
||||||
#ifdef MONITOR_REPAINT
|
#ifdef MONITOR_REPAINT
|
||||||
switch (ps->o.backend) {
|
switch (ps->o.backend) {
|
||||||
case BKEND_XRENDER:
|
case BKEND_XRENDER:
|
||||||
XRenderComposite(ps->dpy, PictOpSrc, ps->black_picture, None,
|
xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, ps->black_picture, None,
|
||||||
ps->tgt_picture, 0, 0, 0, 0, 0, 0,
|
ps->tgt_picture, 0, 0, 0, 0, 0, 0,
|
||||||
ps->root_width, ps->root_height);
|
ps->root_width, ps->root_height);
|
||||||
break;
|
break;
|
||||||
|
@ -1889,8 +1906,8 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
|
||||||
}
|
}
|
||||||
// No-DBE painting mode
|
// No-DBE painting mode
|
||||||
else if (ps->tgt_buffer.pict != ps->tgt_picture) {
|
else if (ps->tgt_buffer.pict != ps->tgt_picture) {
|
||||||
XRenderComposite(
|
xcb_render_composite(
|
||||||
ps->dpy, PictOpSrc, ps->tgt_buffer.pict, None,
|
c, XCB_RENDER_PICT_OP_SRC, ps->tgt_buffer.pict, None,
|
||||||
ps->tgt_picture, 0, 0, 0, 0,
|
ps->tgt_picture, 0, 0, 0, 0,
|
||||||
0, 0, ps->root_width, ps->root_height);
|
0, 0, ps->root_width, ps->root_height);
|
||||||
}
|
}
|
||||||
|
@ -2512,11 +2529,11 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
|
||||||
|
|
||||||
o = ev->error_code - ps->render_error;
|
o = ev->error_code - ps->render_error;
|
||||||
switch (o) {
|
switch (o) {
|
||||||
CASESTRRET2(BadPictFormat);
|
CASESTRRET2(XCB_RENDER_PICT_FORMAT);
|
||||||
CASESTRRET2(BadPicture);
|
CASESTRRET2(XCB_RENDER_PICTURE);
|
||||||
CASESTRRET2(BadPictOp);
|
CASESTRRET2(XCB_RENDER_PICT_OP);
|
||||||
CASESTRRET2(BadGlyphSet);
|
CASESTRRET2(XCB_RENDER_GLYPH_SET);
|
||||||
CASESTRRET2(BadGlyph);
|
CASESTRRET2(XCB_RENDER_GLYPH);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
|
@ -4234,14 +4251,14 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
|
||||||
// Convolution filter parameter (box blur)
|
// Convolution filter parameter (box blur)
|
||||||
// gaussian or binomial filters are definitely superior, yet looks
|
// gaussian or binomial filters are definitely superior, yet looks
|
||||||
// like they aren't supported as of xorg-server-1.13.0
|
// like they aren't supported as of xorg-server-1.13.0
|
||||||
static const XFixed convolution_blur[] = {
|
static const xcb_render_fixed_t convolution_blur[] = {
|
||||||
// Must convert to XFixed with XDoubleToFixed()
|
// Must convert to XFixed with DOUBLE_TO_XFIXED()
|
||||||
// Matrix size
|
// Matrix size
|
||||||
XDoubleToFixed(3), XDoubleToFixed(3),
|
DOUBLE_TO_XFIXED(3), DOUBLE_TO_XFIXED(3),
|
||||||
// Matrix
|
// Matrix
|
||||||
XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1),
|
DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1),
|
||||||
XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1),
|
DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1),
|
||||||
XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1),
|
DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1),
|
||||||
};
|
};
|
||||||
ps->o.blur_kerns[0] = malloc(sizeof(convolution_blur));
|
ps->o.blur_kerns[0] = malloc(sizeof(convolution_blur));
|
||||||
if (!ps->o.blur_kerns[0]) {
|
if (!ps->o.blur_kerns[0]) {
|
||||||
|
@ -4639,7 +4656,7 @@ init_alpha_picts(session_t *ps) {
|
||||||
int i;
|
int i;
|
||||||
int num = round(1.0 / ps->o.alpha_step) + 1;
|
int num = round(1.0 / ps->o.alpha_step) + 1;
|
||||||
|
|
||||||
ps->alpha_picts = malloc(sizeof(Picture) * num);
|
ps->alpha_picts = malloc(sizeof(xcb_render_picture_t) * num);
|
||||||
|
|
||||||
for (i = 0; i < num; ++i) {
|
for (i = 0; i < num; ++i) {
|
||||||
double o = i * ps->o.alpha_step;
|
double o = i * ps->o.alpha_step;
|
||||||
|
@ -4709,6 +4726,7 @@ init_overlay(session_t *ps) {
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
init_filters(session_t *ps) {
|
init_filters(session_t *ps) {
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
// Blur filter
|
// Blur filter
|
||||||
if (ps->o.blur_background || ps->o.blur_background_frame) {
|
if (ps->o.blur_background || ps->o.blur_background_frame) {
|
||||||
switch (ps->o.backend) {
|
switch (ps->o.backend) {
|
||||||
|
@ -4716,15 +4734,17 @@ init_filters(session_t *ps) {
|
||||||
case BKEND_XR_GLX_HYBRID:
|
case BKEND_XR_GLX_HYBRID:
|
||||||
{
|
{
|
||||||
// Query filters
|
// Query filters
|
||||||
XFilters *pf = XRenderQueryFilters(ps->dpy, get_tgt_window(ps));
|
xcb_render_query_filters_reply_t *pf = xcb_render_query_filters_reply(c,
|
||||||
|
xcb_render_query_filters(c, get_tgt_window(ps)), NULL);
|
||||||
if (pf) {
|
if (pf) {
|
||||||
for (int i = 0; i < pf->nfilter; ++i) {
|
xcb_str_iterator_t iter = xcb_render_query_filters_filters_iterator(pf);
|
||||||
|
for (; iter.rem; xcb_str_next(&iter)) {
|
||||||
// Convolution filter
|
// Convolution filter
|
||||||
if (!strcmp(pf->filter[i], XRFILTER_CONVOLUTION))
|
if (!strcmp(xcb_str_name(iter.data), XRFILTER_CONVOLUTION))
|
||||||
ps->xrfilter_convolution_exists = true;
|
ps->xrfilter_convolution_exists = true;
|
||||||
}
|
}
|
||||||
|
free(pf);
|
||||||
}
|
}
|
||||||
cxfree(pf);
|
|
||||||
|
|
||||||
// Turn features off if any required filter is not present
|
// Turn features off if any required filter is not present
|
||||||
if (!ps->xrfilter_convolution_exists) {
|
if (!ps->xrfilter_convolution_exists) {
|
||||||
|
@ -5326,14 +5346,17 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
ps->root_width = DisplayWidth(ps->dpy, ps->scr);
|
ps->root_width = DisplayWidth(ps->dpy, ps->scr);
|
||||||
ps->root_height = DisplayHeight(ps->dpy, ps->scr);
|
ps->root_height = DisplayHeight(ps->dpy, ps->scr);
|
||||||
|
|
||||||
|
xcb_prefetch_extension_data(c, &xcb_render_id);
|
||||||
xcb_prefetch_extension_data(c, &xcb_damage_id);
|
xcb_prefetch_extension_data(c, &xcb_damage_id);
|
||||||
xcb_prefetch_extension_data(c, &xcb_randr_id);
|
xcb_prefetch_extension_data(c, &xcb_randr_id);
|
||||||
|
|
||||||
if (!XRenderQueryExtension(ps->dpy,
|
ext_info = xcb_get_extension_data(c, &xcb_render_id);
|
||||||
&ps->render_event, &ps->render_error)) {
|
if (!ext_info || !ext_info->present) {
|
||||||
fprintf(stderr, "No render extension\n");
|
fprintf(stderr, "No render extension\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
ps->render_event = ext_info->first_event;
|
||||||
|
ps->render_error = ext_info->first_error;
|
||||||
|
|
||||||
if (!XQueryExtension(ps->dpy, COMPOSITE_NAME, &ps->composite_opcode,
|
if (!XQueryExtension(ps->dpy, COMPOSITE_NAME, &ps->composite_opcode,
|
||||||
&ps->composite_event, &ps->composite_error)) {
|
&ps->composite_event, &ps->composite_error)) {
|
||||||
|
@ -5525,10 +5548,10 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
};
|
};
|
||||||
|
|
||||||
ps->root_picture = x_create_picture_with_visual_and_pixmap(ps,
|
ps->root_picture = x_create_picture_with_visual_and_pixmap(ps,
|
||||||
ps->vis, ps->root, CPSubwindowMode, &pa);
|
ps->vis, ps->root, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
|
||||||
if (ps->o.paint_on_overlay) {
|
if (ps->o.paint_on_overlay) {
|
||||||
ps->tgt_picture = x_create_picture_with_visual_and_pixmap(ps,
|
ps->tgt_picture = x_create_picture_with_visual_and_pixmap(ps,
|
||||||
ps->vis, ps->overlay, CPSubwindowMode, &pa);
|
ps->vis, ps->overlay, XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
|
||||||
} else
|
} else
|
||||||
ps->tgt_picture = ps->root_picture;
|
ps->tgt_picture = ps->root_picture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ void map_win(session_t *ps, Window id);
|
||||||
void
|
void
|
||||||
render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||||
double opacity, bool argb, bool neg,
|
double opacity, bool argb, bool neg,
|
||||||
Picture pict, glx_texture_t *ptex,
|
xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||||
XserverRegion reg_paint, const reg_data_t *pcache_reg
|
XserverRegion reg_paint, const reg_data_t *pcache_reg
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
, const glx_prog_main_t *pprogram
|
, const glx_prog_main_t *pprogram
|
||||||
|
@ -63,8 +63,11 @@ render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||||
* Reset filter on a <code>Picture</code>.
|
* Reset filter on a <code>Picture</code>.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
xrfilter_reset(session_t *ps, Picture p) {
|
xrfilter_reset(session_t *ps, xcb_render_picture_t p) {
|
||||||
XRenderSetPictureFilter(ps->dpy, p, "Nearest", NULL, 0);
|
#define FILTER "Nearest"
|
||||||
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
|
xcb_render_set_picture_filter(c, p, strlen(FILTER), FILTER, 0, NULL);
|
||||||
|
#undef FILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,9 +149,10 @@ rect_to_reg(session_t *ps, const XRectangle *src) {
|
||||||
* Destroy a <code>Picture</code>.
|
* Destroy a <code>Picture</code>.
|
||||||
*/
|
*/
|
||||||
inline static void
|
inline static void
|
||||||
free_picture(session_t *ps, Picture *p) {
|
free_picture(session_t *ps, xcb_render_picture_t *p) {
|
||||||
if (*p) {
|
if (*p) {
|
||||||
XRenderFreePicture(ps->dpy, *p);
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
|
xcb_render_free_picture(c, *p);
|
||||||
*p = None;
|
*p = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +498,7 @@ find_win_all(session_t *ps, const Window wid) {
|
||||||
static inline void
|
static inline void
|
||||||
win_render(session_t *ps, win *w, int x, int y, int wid, int hei,
|
win_render(session_t *ps, win *w, int x, int y, int wid, int hei,
|
||||||
double opacity, XserverRegion reg_paint, const reg_data_t *pcache_reg,
|
double opacity, XserverRegion reg_paint, const reg_data_t *pcache_reg,
|
||||||
Picture pict) {
|
xcb_render_picture_t pict) {
|
||||||
const int dx = (w ? w->g.x: 0) + x;
|
const int dx = (w ? w->g.x: 0) + x;
|
||||||
const int dy = (w ? w->g.y: 0) + y;
|
const int dy = (w ? w->g.y: 0) + y;
|
||||||
const bool argb = (w && (WMODE_ARGB == w->mode || ps->o.force_win_blend));
|
const bool argb = (w && (WMODE_ARGB == w->mode || ps->o.force_win_blend));
|
||||||
|
@ -526,13 +530,13 @@ set_tgt_clip(session_t *ps, XserverRegion reg, const reg_data_t *pcache_reg) {
|
||||||
* Normalize a convolution kernel.
|
* Normalize a convolution kernel.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
normalize_conv_kern(int wid, int hei, XFixed *kern) {
|
normalize_conv_kern(int wid, int hei, xcb_render_fixed_t *kern) {
|
||||||
double sum = 0.0;
|
double sum = 0.0;
|
||||||
for (int i = 0; i < wid * hei; ++i)
|
for (int i = 0; i < wid * hei; ++i)
|
||||||
sum += XFixedToDouble(kern[i]);
|
sum += XFIXED_TO_DOUBLE(kern[i]);
|
||||||
double factor = 1.0 / sum;
|
double factor = 1.0 / sum;
|
||||||
for (int i = 0; i < wid * hei; ++i)
|
for (int i = 0; i < wid * hei; ++i)
|
||||||
kern[i] = XDoubleToFixed(XFixedToDouble(kern[i]) * factor);
|
kern[i] = DOUBLE_TO_XFIXED(XFIXED_TO_DOUBLE(kern[i]) * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
18
src/config.c
18
src/config.c
|
@ -49,11 +49,11 @@ parse_matrix_readnum(const char *src, double *dest) {
|
||||||
/**
|
/**
|
||||||
* Parse a matrix.
|
* Parse a matrix.
|
||||||
*/
|
*/
|
||||||
XFixed *
|
xcb_render_fixed_t *
|
||||||
parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
int wid = 0, hei = 0;
|
int wid = 0, hei = 0;
|
||||||
const char *pc = NULL;
|
const char *pc = NULL;
|
||||||
XFixed *matrix = NULL;
|
xcb_render_fixed_t *matrix = NULL;
|
||||||
|
|
||||||
// Get matrix width and height
|
// Get matrix width and height
|
||||||
{
|
{
|
||||||
|
@ -82,7 +82,7 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
"rendering, and/or consume lots of memory");
|
"rendering, and/or consume lots of memory");
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
matrix = calloc(wid * hei + 2, sizeof(XFixed));
|
matrix = calloc(wid * hei + 2, sizeof(xcb_render_fixed_t));
|
||||||
if (!matrix) {
|
if (!matrix) {
|
||||||
printf_errf("(): Failed to allocate memory for matrix.");
|
printf_errf("(): Failed to allocate memory for matrix.");
|
||||||
goto parse_matrix_err;
|
goto parse_matrix_err;
|
||||||
|
@ -95,7 +95,7 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
for (int i = 0; i < wid * hei; ++i) {
|
for (int i = 0; i < wid * hei; ++i) {
|
||||||
// Ignore the center element
|
// Ignore the center element
|
||||||
if (i == skip) {
|
if (i == skip) {
|
||||||
matrix[2 + i] = XDoubleToFixed(0);
|
matrix[2 + i] = DOUBLE_TO_XFIXED(0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double val = 0;
|
double val = 0;
|
||||||
|
@ -103,7 +103,7 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
goto parse_matrix_err;
|
goto parse_matrix_err;
|
||||||
src = pc;
|
src = pc;
|
||||||
if (val < 0) hasneg = true;
|
if (val < 0) hasneg = true;
|
||||||
matrix[2 + i] = XDoubleToFixed(val);
|
matrix[2 + i] = DOUBLE_TO_XFIXED(val);
|
||||||
}
|
}
|
||||||
if (BKEND_XRENDER == ps->o.backend && hasneg)
|
if (BKEND_XRENDER == ps->o.backend && hasneg)
|
||||||
printf_errf("(): A convolution kernel with negative values "
|
printf_errf("(): A convolution kernel with negative values "
|
||||||
|
@ -134,8 +134,8 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in width and height
|
// Fill in width and height
|
||||||
matrix[0] = XDoubleToFixed(wid);
|
matrix[0] = DOUBLE_TO_XFIXED(wid);
|
||||||
matrix[1] = XDoubleToFixed(hei);
|
matrix[1] = DOUBLE_TO_XFIXED(hei);
|
||||||
|
|
||||||
return matrix;
|
return matrix;
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ parse_matrix_err:
|
||||||
/**
|
/**
|
||||||
* Parse a convolution kernel.
|
* Parse a convolution kernel.
|
||||||
*/
|
*/
|
||||||
XFixed *
|
xcb_render_fixed_t *
|
||||||
parse_conv_kern(session_t *ps, const char *src, const char **endptr) {
|
parse_conv_kern(session_t *ps, const char *src, const char **endptr) {
|
||||||
return parse_matrix(ps, src, endptr);
|
return parse_matrix(ps, src, endptr);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ parse_conv_kern(session_t *ps, const char *src, const char **endptr) {
|
||||||
* Parse a list of convolution kernels.
|
* Parse a list of convolution kernels.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
parse_conv_kern_lst(session_t *ps, const char *src, XFixed **dest, int max) {
|
parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, int max) {
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *kern_str;
|
const char *kern_str;
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
bool parse_long(const char *, long *);
|
bool parse_long(const char *, long *);
|
||||||
const char *parse_matrix_readnum(const char *, double *);
|
const char *parse_matrix_readnum(const char *, double *);
|
||||||
XFixed *parse_matrix(session_t *, const char *, const char **);
|
xcb_render_fixed_t *parse_matrix(session_t *, const char *, const char **);
|
||||||
XFixed *parse_conv_kern(session_t *, const char *, const char **);
|
xcb_render_fixed_t *parse_conv_kern(session_t *, const char *, const char **);
|
||||||
bool parse_conv_kern_lst(session_t *, const char *, XFixed **, int);
|
bool parse_conv_kern_lst(session_t *, const char *, xcb_render_fixed_t **, int);
|
||||||
bool parse_geometry(session_t *, const char *, geometry_t *);
|
bool parse_geometry(session_t *, const char *, geometry_t *);
|
||||||
bool parse_rule_opacity(session_t *, const char *);
|
bool parse_rule_opacity(session_t *, const char *);
|
||||||
|
|
||||||
|
|
10
src/opengl.c
10
src/opengl.c
|
@ -434,7 +434,7 @@ glx_init_blur(session_t *ps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAX_BLUR_PASS && ps->o.blur_kerns[i]; ++i) {
|
for (int i = 0; i < MAX_BLUR_PASS && ps->o.blur_kerns[i]; ++i) {
|
||||||
XFixed *kern = ps->o.blur_kerns[i];
|
xcb_render_fixed_t *kern = ps->o.blur_kerns[i];
|
||||||
if (!kern)
|
if (!kern)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ glx_init_blur(session_t *ps) {
|
||||||
|
|
||||||
// Build shader
|
// Build shader
|
||||||
{
|
{
|
||||||
int wid = XFixedToDouble(kern[0]), hei = XFixedToDouble(kern[1]);
|
int wid = XFIXED_TO_DOUBLE(kern[0]), hei = XFIXED_TO_DOUBLE(kern[1]);
|
||||||
int nele = wid * hei - 1;
|
int nele = wid * hei - 1;
|
||||||
unsigned int len = strlen(FRAG_SHADER_BLUR_PREFIX) +
|
unsigned int len = strlen(FRAG_SHADER_BLUR_PREFIX) +
|
||||||
strlen(sampler_type) +
|
strlen(sampler_type) +
|
||||||
|
@ -466,7 +466,7 @@ glx_init_blur(session_t *ps) {
|
||||||
for (int k = 0; k < wid; ++k) {
|
for (int k = 0; k < wid; ++k) {
|
||||||
if (hei / 2 == j && wid / 2 == k)
|
if (hei / 2 == j && wid / 2 == k)
|
||||||
continue;
|
continue;
|
||||||
double val = XFixedToDouble(kern[2 + j * wid + k]);
|
double val = XFIXED_TO_DOUBLE(kern[2 + j * wid + k]);
|
||||||
if (0.0 == val)
|
if (0.0 == val)
|
||||||
continue;
|
continue;
|
||||||
sum += val;
|
sum += val;
|
||||||
|
@ -1187,8 +1187,8 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
|
||||||
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
||||||
XFixed *kern = ps->o.blur_kerns[i];
|
XFixed *kern = ps->o.blur_kerns[i];
|
||||||
if (!kern) break;
|
if (!kern) break;
|
||||||
inc_x += XFixedToDouble(kern[0]) / 2;
|
inc_x += XFIXED_TO_DOUBLE(kern[0]) / 2;
|
||||||
inc_y += XFixedToDouble(kern[1]) / 2;
|
inc_y += XFIXED_TO_DOUBLE(kern[1]) / 2;
|
||||||
}
|
}
|
||||||
inc_x = min_i(ps->o.resize_damage, inc_x);
|
inc_x = min_i(ps->o.resize_damage, inc_x);
|
||||||
inc_y = min_i(ps->o.resize_damage, inc_y);
|
inc_y = min_i(ps->o.resize_damage, inc_y);
|
||||||
|
|
|
@ -282,7 +282,7 @@ bool wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def,
|
||||||
void win_determine_mode(session_t *ps, win *w) {
|
void win_determine_mode(session_t *ps, win *w) {
|
||||||
winmode_t mode = WMODE_SOLID;
|
winmode_t mode = WMODE_SOLID;
|
||||||
|
|
||||||
if (w->pictfmt && w->pictfmt->type == PictTypeDirect &&
|
if (w->pictfmt && w->pictfmt->type == XCB_RENDER_PICT_TYPE_DIRECT &&
|
||||||
w->pictfmt->direct.alpha_mask) {
|
w->pictfmt->direct.alpha_mask) {
|
||||||
mode = WMODE_ARGB;
|
mode = WMODE_ARGB;
|
||||||
} else if (w->opacity != OPAQUE) {
|
} else if (w->opacity != OPAQUE) {
|
||||||
|
|
Loading…
Reference in New Issue