typedef struct {
void (*screen_paint)(d_screen_t *sc);
+ void (*screen_root_pixmap_changed)(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);
+ xcb_render_pictformat_t root_format;
xcb_render_query_pict_formats_reply_t *pict_formats;
xcb_render_picture_t overlay_picture;
xcb_render_picture_t overlay_buffer;
+ xcb_render_picture_t root_picture;
xcb_render_picture_t solid_bg;
} data_t;
typedef struct {
xcb_render_picture_t picture;
- gboolean waiting_picture;
- xcb_void_cookie_t ck_picture;
} window_data_t;
-static void render_screen_paint(d_screen_t *sc);
+static void render_paint(d_screen_t *sc);
+static void render_root_pixmap_changed(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);
-static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
- gboolean children);
+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);
static xcb_render_pictformat_t find_visual_format(data_t *d,
xcb_visualid_t visual);
render_init(d_screen_t *sc, int id)
{
xcb_render_query_pict_formats_cookie_t ck;
- xcb_render_pictformat_t format;
xcb_pixmap_t px;
plugin_id = 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->window_show = sc->window_show;
d->window_hide = sc->window_hide;
d->window_resize = sc->window_resize;
screen_add_plugin_data(sc, plugin_id, d);
- sc->screen_paint = render_screen_paint;
+ sc->screen_paint = render_paint;
+ sc->screen_root_pixmap_changed = render_root_pixmap_changed;
sc->window_show = render_window_show;
sc->window_hide = render_window_hide;
sc->window_resize = render_window_resize;
d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
NULL);
- format = find_visual_format(d, sc->super.root_visual);
+ d->root_format = find_visual_format(d, sc->super.root_visual);
+ d->root_picture = XCB_NONE;
d->overlay_picture = xcb_generate_id(sc->dpy->conn);
xcb_render_create_picture(sc->dpy->conn,
- d->overlay_picture, sc->overlay, format,
+ d->overlay_picture, sc->overlay, d->root_format,
0, NULL);
/* make the double buffer */
sc->super.height_in_pixels);
d->overlay_buffer = xcb_generate_id(sc->dpy->conn);
xcb_render_create_picture(sc->dpy->conn, d->overlay_buffer, px,
- format, 0, 0);
+ d->root_format, 0, 0);
xcb_free_pixmap(sc->dpy->conn, px);
d->solid_bg = solid_picture(sc, 1.0, 0.0, 0.0, 0.0);
data_t *d = screen_find_plugin_data(sc, plugin_id);
free(d->pict_formats);
xcb_render_free_picture(sc->dpy->conn, d->solid_bg);
+ if (d->root_picture)
+ xcb_render_free_picture(sc->dpy->conn, d->root_picture);
xcb_render_free_picture(sc->dpy->conn, d->overlay_picture);
xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer);
free(d);
wd = malloc(sizeof(window_data_t));
wd->picture = XCB_NONE;
- wd->waiting_picture = FALSE;
window_add_plugin_data(w, plugin_id, wd);
window_ref(w);
d->window_hide(w);
}
-static
-xcb_render_picture_t solid_picture(d_screen_t *sc,
- double a, double r,
- double g, double b)
+static xcb_render_picture_t
+solid_picture(d_screen_t *sc, double a, double r, double g, double b)
{
xcb_render_picture_t picture;
xcb_render_color_t c;
return XCB_NONE;
}
-static xcb_render_picture_t
-render_get_picture(d_window_t *w, window_data_t *wd)
+static void
+render_free_picture(d_window_t *w, window_data_t *wd)
{
- if (wd->waiting_picture) {
- xcb_generic_error_t *err;
- //printf("** checking create picture 0x%x\n", w->id);
- err = xcb_request_check(w->sc->dpy->conn, wd->ck_picture);
- if (err) {
- wd->picture = XCB_NONE;
- printf("error creating picture for window 0x%x\n", w->id);
- free(err);
- }
- wd->waiting_picture = FALSE;
+ /* this might cause an error, oh well */
+ if (wd->picture) {
+ xcb_render_free_picture(w->sc->dpy->conn, wd->picture);
+ wd->picture = XCB_NONE;
}
- //printf("returning picture 0x%x for window 0x%x\n", wd->picture, w->id);
- return wd->picture;
}
static void
-render_free_picture(d_window_t *w, window_data_t *wd)
+render_update_root_picture(d_screen_t *sc, data_t *d)
{
- xcb_render_picture_t pict;
+ xcb_pixmap_t px;
- pict = render_get_picture(w, wd);
- if (pict) xcb_render_free_picture(w->sc->dpy->conn, pict);
- wd->picture = XCB_NONE;
+ 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);
+ }
}
static void
-render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
- gboolean children)
+render_update_picture(d_window_t *w, data_t *d, window_data_t *wd)
{
xcb_pixmap_t px;
//printf("got pixmap 0x%x\n", px);
if (px) {
xcb_render_pictformat_t format;
- const uint32_t vals = (children ?
- XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS :
- XCB_SUBWINDOW_MODE_CLIP_BY_CHILDREN);
+ const uint32_t vals = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS;
render_free_picture(w, wd);
wd->picture = xcb_generate_id(w->sc->dpy->conn);
format = find_visual_format(d, window_get_visual(w));
- wd->ck_picture =
- xcb_render_create_picture_checked(w->sc->dpy->conn,
- wd->picture, px, format,
- XCB_RENDER_CP_SUBWINDOW_MODE,
- &vals);
- wd->waiting_picture = TRUE;
+ /* we don't need to check this. if it fails, we'll just be drawing
+ an invalid picture and creating some X errors but that's no big
+ deal really */
+ xcb_render_create_picture(w->sc->dpy->conn,
+ wd->picture, px, format,
+ XCB_RENDER_CP_SUBWINDOW_MODE,
+ &vals);
}
}
}
static void
-render_screen_paint(d_screen_t *sc)
+render_root_pixmap_changed(d_screen_t *sc)
+{
+ data_t *d;
+
+ d = screen_find_plugin_data(sc, plugin_id);
+ if (d->root_picture) {
+ xcb_render_free_picture(sc->dpy->conn, d->root_picture);
+ d->root_picture = XCB_NONE;
+ }
+
+ /* pass it on */
+ d->screen_root_pixmap_changed(sc);
+}
+
+static void
+render_paint(d_screen_t *sc)
{
data_t *d = screen_find_plugin_data(sc, plugin_id);
d_list_it_t *it;
static void
paint_root(d_screen_t *sc, data_t *d)
{
+ xcb_render_picture_t src;
+ int op;
+
+ if (!d->root_picture)
+ render_update_root_picture(sc, d);
+
+ if (d->root_picture) {
+ src = d->root_picture;
+ op = XCB_RENDER_PICT_OP_SRC;
+ }
+ else {
+ src = d->solid_bg;
+ op = XCB_RENDER_PICT_OP_CLEAR;
+ }
xcb_render_composite(sc->dpy->conn,
- XCB_RENDER_PICT_OP_CLEAR,
- d->solid_bg,
+ op,
+ src,
XCB_NONE,
d->overlay_buffer,
0, 0, 0, 0,
paint_window(d_window_t *w, data_t *d)
{
window_data_t *wd;
- xcb_render_picture_t pict;
int x, y, width, height, bwidth;
wd = window_find_plugin_data(w, plugin_id);
if (!wd->picture)
- render_update_picture(w, d, wd, TRUE);
- pict = render_get_picture(w, wd);
+ render_update_picture(w, d, wd);
//printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
- if (pict) {
+ if (wd->picture) {
window_get_area(w, &x, &y, &width, &height, &bwidth);
xcb_render_composite(w->sc->dpy->conn,
//XCB_RENDER_PICT_OP_SRC, /* - for solid */
XCB_RENDER_PICT_OP_OVER, /* - for argb */
- pict,
+ wd->picture,
XCB_NONE,
d->overlay_buffer,
0, 0, 0, 0,