8 #include <xcb/render.h>
10 #define PLUGIN_NAME "render"
13 void (*screen_paint)(d_screen_t *sc);
14 void (*window_show)(d_window_t *w);
15 void (*window_hide)(d_window_t *w);
16 void (*window_reconfigure)(d_window_t *w);
18 xcb_render_query_pict_formats_reply_t *pict_formats;
19 xcb_render_picture_t overlay_picture;
20 xcb_render_picture_t overlay_buffer;
21 xcb_render_picture_t solid_bg;
25 xcb_render_picture_t picture;
26 xcb_void_cookie_t ck_picture;
29 static void render_screen_paint(d_screen_t *sc);
30 static void paint_root(d_screen_t *sc, data_t *d);
31 static void paint_window(d_window_t *window);
32 static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
34 static void render_free_picture(d_window_t *w, window_data_t *wd);
35 static xcb_render_pictformat_t find_visual_format(data_t *d,
36 xcb_visualid_t visual);
37 static xcb_render_picture_t solid_picture(d_screen_t *sc,
41 static void render_window_show(d_window_t *window);
42 static void render_window_hide(d_window_t *window);
43 static void render_window_reconfigure(d_window_t *window);
46 render_init(d_screen_t *sc)
48 xcb_render_query_pict_formats_cookie_t ck;
49 xcb_render_pictformat_t format;
52 data_t *d = malloc(sizeof(data_t));
53 d->screen_paint = sc->screen_paint;
54 d->window_show = sc->window_show;
55 d->window_hide = sc->window_hide;
56 d->window_reconfigure = sc->window_reconfigure;
57 screen_add_plugin_data(sc, PLUGIN_NAME, d);
59 sc->screen_paint = render_screen_paint;
60 sc->window_show = render_window_show;
61 sc->window_hide = render_window_hide;
62 sc->window_reconfigure = render_window_reconfigure;
64 ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn);
65 d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
68 format = find_visual_format(d, sc->super.root_visual);
70 d->overlay_picture = xcb_generate_id(sc->dpy->conn);
71 xcb_render_create_picture(sc->dpy->conn,
72 d->overlay_picture, sc->overlay, format,
75 /* make the double buffer */
76 px = xcb_generate_id(sc->dpy->conn);
77 xcb_create_pixmap(sc->dpy->conn, sc->super.root_depth, px,
78 sc->super.root, sc->super.width_in_pixels,
79 sc->super.height_in_pixels);
80 d->overlay_buffer = xcb_generate_id(sc->dpy->conn);
81 xcb_render_create_picture(sc->dpy->conn, d->overlay_buffer, px,
83 xcb_free_pixmap(sc->dpy->conn, px);
85 d->solid_bg = solid_picture(sc, 1.0, 0.0, 0.0, 0.0);
89 render_free(d_screen_t *sc)
91 data_t *d = screen_find_plugin_data(sc, PLUGIN_NAME);
92 free(d->pict_formats);
93 xcb_render_free_picture(sc->dpy->conn, d->solid_bg);
94 xcb_render_free_picture(sc->dpy->conn, d->overlay_picture);
95 xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer);
100 render_window_free(d_window_t *w, window_data_t *wd)
102 render_free_picture(w, wd);
107 render_window_show(d_window_t *w)
112 d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
117 wd = window_find_plugin_data(w, PLUGIN_NAME);
119 render_window_free(w, wd);
121 wd = malloc(sizeof(window_data_t));
122 wd->picture = XCB_NONE;
123 wd->ck_picture.sequence = 0;
124 window_add_plugin_data(w, PLUGIN_NAME, wd);
130 render_window_hide(d_window_t *w)
135 d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
136 wd = window_find_plugin_data(w, PLUGIN_NAME);
138 render_window_free(w, wd);
139 window_remove_plugin_data(w, PLUGIN_NAME);
149 xcb_render_picture_t solid_picture(d_screen_t *sc,
153 xcb_render_picture_t picture;
154 xcb_render_color_t c;
156 picture = xcb_generate_id (sc->dpy->conn);
158 c.alpha = a * 0xffff;
159 c.red = a * r * 0xffff;
160 c.green = a * g * 0xffff;
161 c.blue = a * b * 0xffff;
163 xcb_render_create_solid_fill (sc->dpy->conn, picture, c);
167 static xcb_render_pictformat_t
168 find_visual_format(data_t *d, xcb_visualid_t visual)
170 xcb_render_pictscreen_iterator_t si;
171 xcb_render_pictdepth_iterator_t di;
172 xcb_render_pictvisual_iterator_t vi;
174 if (!visual) return XCB_NONE;
176 /* go through all the screens */
177 si = xcb_render_query_pict_formats_screens_iterator(d->pict_formats);
178 for (; si.rem; xcb_render_pictscreen_next(&si)) {
179 di = xcb_render_pictscreen_depths_iterator(si.data);
180 for (; di.rem; xcb_render_pictdepth_next(&di)) {
181 vi = xcb_render_pictdepth_visuals_iterator(di.data);
182 for (; vi.rem; xcb_render_pictvisual_next(&vi)) {
183 if (vi.data->visual == visual)
184 return vi.data->format;
191 static xcb_render_picture_t
192 render_get_picture(d_window_t *w, window_data_t *wd)
194 if (wd->ck_picture.sequence) {
195 xcb_generic_error_t *err;
196 //printf("** checking create picture 0x%x\n", w->id);
197 err = xcb_request_check(w->sc->dpy->conn, wd->ck_picture);
199 wd->picture = XCB_NONE;
200 printf("error creating picture for window 0x%x\n", w->id);
203 wd->ck_picture.sequence = 0;
205 //printf("returning picture 0x%x for window 0x%x\n", wd->picture, w->id);
210 render_free_picture(d_window_t *w, window_data_t *wd)
212 xcb_render_picture_t pict;
214 pict = render_get_picture(w, wd);
215 if (pict) xcb_render_free_picture(w->sc->dpy->conn, pict);
216 wd->picture = XCB_NONE;
220 render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
225 px = window_get_pixmap(w);
226 //printf("got pixmap 0x%x\n", px);
228 xcb_render_pictformat_t format;
229 const uint32_t vals = (children ?
230 XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS :
231 XCB_SUBWINDOW_MODE_CLIP_BY_CHILDREN);
233 render_free_picture(w, wd);
235 wd->picture = xcb_generate_id(w->sc->dpy->conn);
236 format = find_visual_format(d, window_get_visual(w));
238 xcb_render_create_picture_checked(w->sc->dpy->conn,
239 wd->picture, px, format,
240 XCB_RENDER_CP_SUBWINDOW_MODE,
246 render_window_reconfigure(d_window_t *w)
251 d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
252 wd = window_find_plugin_data(w, PLUGIN_NAME);
253 render_free_picture(w, wd);
260 render_screen_paint(d_screen_t *sc)
262 data_t *d = screen_find_plugin_data(sc, PLUGIN_NAME);
265 //printf("-- painting --\n");
268 for (it = list_bottom(sc->stacking); it; it = it->prev) {
269 d_window_t *w = it->data;
270 if (!window_is_input_only(w) && window_is_mapped(w))
275 /* copy the double buffer to the overlay window */
276 xcb_render_composite(sc->dpy->conn,
277 XCB_RENDER_PICT_OP_SRC,
283 sc->super.width_in_pixels,
284 sc->super.height_in_pixels);
286 /* call the function we replaced in the chain */
291 paint_root(d_screen_t *sc, data_t *d)
293 xcb_render_composite(sc->dpy->conn,
294 XCB_RENDER_PICT_OP_CLEAR,
300 sc->super.width_in_pixels,
301 sc->super.height_in_pixels);
305 paint_window(d_window_t *w)
309 xcb_render_picture_t pict;
310 int x, y, width, height, bwidth;
312 d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
313 wd = window_find_plugin_data(w, PLUGIN_NAME);
316 render_update_picture(w, d, wd, TRUE);
317 pict = render_get_picture(w, wd);
319 //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
320 window_get_area(w, &x, &y, &width, &height, &bwidth);
321 xcb_render_composite(w->sc->dpy->conn,
322 //XCB_RENDER_PICT_OP_SRC, /* - for solid */
323 XCB_RENDER_PICT_OP_OVER, /* - for argb */
328 x, y, width + bwidth*2, height + bwidth *2);