typedef struct {
void (*screen_paint)(d_screen_t *sc);
- void (*screen_root_pixmap_changed)(d_screen_t *sc);
+ void (*screen_root_pixmap_change)(d_screen_t *sc);
void (*window_show)(d_window_t *w);
void (*window_hide)(d_window_t *w);
void (*window_resize)(d_window_t *w);
+ void (*window_opacity_change)(d_window_t *w);
xcb_render_pictformat_t root_format;
xcb_render_pictformat_t argb32_format;
xcb_xfixes_region_t paint_region;
xcb_xfixes_region_t shadow_region;
- double shadowalpha;
+ uint16_t shadowalpha;
int xshadowoff;
int yshadowoff;
} data_t;
} window_data_t;
static void render_paint(d_screen_t *sc);
-static void render_root_pixmap_changed(d_screen_t *sc);
+static void render_root_pixmap_change(d_screen_t *sc);
static void paint_root(d_screen_t *sc, data_t *d);
static void paint_window(d_window_t *window, data_t *d, window_data_t *wd,
- gboolean opaque);
-static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd);
+ gboolean opaque, int x, int y, int width,
+ int height, int bwidth);
+static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
+ int x, int y, int width, int height, int bwidth);
+static void render_update_shadow_picture(d_window_t *w, data_t *d,
+ window_data_t *wd);
static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd);
static void render_update_root_picture(d_screen_t *sc, data_t *d);
static void render_free_picture(d_window_t *w, window_data_t *wd);
xcb_visualid_t visual);
static xcb_render_pictformat_t find_argb32_format(data_t *d);
static xcb_render_picture_t solid_picture(data_t *d, d_screen_t *sc,
- double a, double r,
- double g, double b);
+ uint16_t a, uint16_t r,
+ uint16_t g, uint16_t b);
static void render_window_show(d_window_t *window);
static void render_window_hide(d_window_t *window);
static void render_window_resize(d_window_t *window);
+static void render_window_opacity_change(d_window_t *w);
void
render_init(d_screen_t *sc, int id)
data_t *d = malloc(sizeof(data_t));
d->screen_paint = sc->screen_paint;
- d->screen_root_pixmap_changed = sc->screen_root_pixmap_changed;
+ d->screen_root_pixmap_change = sc->screen_root_pixmap_change;
d->window_show = sc->window_show;
d->window_hide = sc->window_hide;
d->window_resize = sc->window_resize;
+ d->window_opacity_change = sc->window_opacity_change;
screen_add_plugin_data(sc, plugin_id, d);
sc->screen_paint = render_paint;
- sc->screen_root_pixmap_changed = render_root_pixmap_changed;
+ sc->screen_root_pixmap_change = render_root_pixmap_change;
sc->window_show = render_window_show;
sc->window_hide = render_window_hide;
sc->window_resize = render_window_resize;
+ sc->window_opacity_change = render_window_opacity_change;
ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn);
d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
d->root_format, 0, 0);
xcb_free_pixmap(sc->dpy->conn, px);
- d->solid_bg = solid_picture(d, sc, 1.0, 0.0, 0.0, 0.0);
+ d->solid_bg = solid_picture(d, sc, 0xffff, 0x6060, 02020, 0x3030);
d->all_region = xcb_generate_id(sc->dpy->conn);
d->paint_region = xcb_generate_id(sc->dpy->conn);
xcb_xfixes_create_region(sc->dpy->conn, d->paint_region, 1, &rect);
xcb_xfixes_create_region(sc->dpy->conn, d->shadow_region, 1, &rect);
- d->shadowalpha = 0.2;
+ d->shadowalpha = 0x3333; /* 20% */
d->xshadowoff = 2;
d->yshadowoff = 2;
}
wd = malloc(sizeof(window_data_t));
wd->picture = XCB_NONE;
- wd->shadow_picture = solid_picture(d, w->sc, d->shadowalpha,
- 0.0, 0.0, 0.0);
wd->paint_clip = xcb_generate_id(w->sc->dpy->conn);
rect.x = rect.y = 0;
rect.width = rect.height = 1;
xcb_xfixes_create_region(w->sc->dpy->conn, wd->paint_clip, 1, &rect);
+ render_update_shadow_picture(w, d, wd);
+
window_add_plugin_data(w, plugin_id, wd);
window_ref(w);
}
static xcb_render_picture_t
-solid_picture(data_t *d, d_screen_t *sc,
- double a, double r, double g, double b)
+solid_picture(data_t *d, d_screen_t *sc, uint16_t a, uint16_t r,
+ uint16_t g, uint16_t b)
{
xcb_pixmap_t pixmap;
xcb_render_picture_t picture;
xcb_render_create_picture(sc->dpy->conn, picture, pixmap, d->argb32_format,
XCB_RENDER_CP_REPEAT, &vals);
- c.alpha = a * 0xffff;
- c.red = r * 0xffff;
- c.green = g * 0xffff;
- c.blue = b * 0xffff;
+ c.alpha = a;
+ c.red = r;
+ c.green = g;
+ c.blue = b;
xcb_render_fill_rectangles(sc->dpy->conn, XCB_RENDER_PICT_OP_SRC,
picture, c, 1, &rect);
}
static void
+render_update_shadow_picture(d_window_t *w, data_t *d, window_data_t *wd)
+{
+ if (wd->shadow_picture)
+ xcb_render_free_picture(w->sc->dpy->conn, wd->shadow_picture);
+ wd->shadow_picture = solid_picture(d, w->sc,
+ d->shadowalpha *
+ window_get_opacity(w) / 0xffff,
+ 0, 0, 0);
+}
+
+static void
render_update_root_picture(d_screen_t *sc, data_t *d)
{
xcb_pixmap_t px;
px = screen_get_root_pixmap(sc);
if (px) {
d->root_picture = xcb_generate_id(sc->dpy->conn);
- xcb_render_create_picture_checked(sc->dpy->conn,
- d->root_picture, px,
- d->root_format, 0, NULL);
+ xcb_render_create_picture(sc->dpy->conn,
+ d->root_picture, px,
+ d->root_format, 0, NULL);
}
}
}
static void
-render_root_pixmap_changed(d_screen_t *sc)
+render_window_opacity_change(d_window_t *w)
+{
+ data_t *d;
+ window_data_t *wd;
+
+ d = screen_find_plugin_data(w->sc, plugin_id);
+ wd = window_find_plugin_data(w, plugin_id);
+
+ /* pass it on */
+ d->window_opacity_change(w);
+
+ assert(wd != NULL);
+ render_update_shadow_picture(w, d, wd);
+}
+
+static void
+render_root_pixmap_change(d_screen_t *sc)
{
data_t *d;
}
/* pass it on */
- d->screen_root_pixmap_changed(sc);
+ d->screen_root_pixmap_change(sc);
}
static void
//printf("-- painting --\n");
for (it = list_top(sc->stacking); it; it = it->next) {
d_window_t *w = it->data;
+ int x, y, width, height, bwidth;
- if (!window_is_input_only(w) && window_is_mapped(w)) {
- gboolean opaque = !window_is_argb(w);
+ window_get_area(w, &x, &y, &width, &height, &bwidth);
+
+ if (!window_is_input_only(w) && window_is_mapped(w) &&
+ x < sc->super.width_in_pixels &&
+ y < sc->super.height_in_pixels &&
+ x + width > 0 && y + height > 0)
+ {
+ gboolean opaque = !(window_is_argb(w) ||
+ window_get_opacity(w) < 0xffff);
window_data_t *wd;
wd = window_find_plugin_data(w, plugin_id);
if (opaque) {
-
- paint_window(w, d, wd, opaque);
+ paint_window(w, d, wd, opaque, x, y, width, height, bwidth);
/* remove this window from the paint region, as nothing is
above it, so nothing should draw to this space again */
for (it = list_bottom(sc->stacking); it; it = it->prev) {
d_window_t *w = it->data;
+ int x, y, width, height, bwidth;
- if (!window_is_input_only(w) && window_is_mapped(w)) {
+ window_get_area(w, &x, &y, &width, &height, &bwidth);
+
+ if (!window_is_input_only(w) && window_is_mapped(w) &&
+ x < sc->super.width_in_pixels &&
+ y < sc->super.height_in_pixels &&
+ (x + width > 0 || x + width + d->xshadowoff > 0) &&
+ (y + height > 0 || y + height + d->yshadowoff > 0))
+ {
window_data_t *wd;
- gboolean opaque = !window_is_argb(w);
+ gboolean opaque = !(window_is_argb(w) ||
+ window_get_opacity(w) < 0xffff);
wd = window_find_plugin_data(w, plugin_id);
d->overlay_buffer,
d->shadow_region,
0, 0);
- paint_shadow(w, d, wd);
+ paint_shadow(w, d, wd, x, y, width, height, bwidth);
if (!opaque) {
/* use the clip region of the highest opaque window seen so
d->overlay_buffer,
wd->paint_clip,
0, 0);
- paint_window(w, d, wd, opaque);
+ paint_window(w, d, wd, opaque, x, y, width, height, bwidth);
}
}
}
src = d->solid_bg;
op = XCB_RENDER_PICT_OP_CLEAR;
}
+
xcb_render_composite(sc->dpy->conn,
op,
src,
}
static void
-paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque)
+paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque,
+ int x, int y, int width, int height, int bwidth)
{
+ xcb_render_picture_t alphamap;
+
if (!wd->picture)
render_update_picture(w, d, wd);
//printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
if (wd->picture) {
- int x, y, width, height, bwidth;
int op;
- window_get_area(w, &x, &y, &width, &height, &bwidth);
op = !opaque ?
XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC;
+ if (opaque)
+ alphamap = XCB_NONE;
+ else
+ alphamap = solid_picture(d, w->sc, window_get_opacity(w), 0, 0, 0);
+
xcb_render_composite(w->sc->dpy->conn,
op,
wd->picture,
- XCB_NONE,
+ alphamap,
d->overlay_buffer,
0, 0, 0, 0,
x, y, width + bwidth*2, height + bwidth *2);
}
static void
-paint_shadow(d_window_t *w, data_t *d, window_data_t *wd)
+paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
+ int x, int y, int width, int height, int bwidth)
{
- int x, y, width, height, bwidth;
-
- window_get_area(w, &x, &y, &width, &height, &bwidth);
xcb_render_composite(w->sc->dpy->conn,
XCB_RENDER_PICT_OP_OVER,
wd->shadow_picture,