11 #include <xcb/render.h>
16 void (*screen_paint)(d_screen_t *sc);
17 void (*screen_root_pixmap_changed)(d_screen_t *sc);
18 void (*window_show)(d_window_t *w);
19 void (*window_hide)(d_window_t *w);
20 void (*window_resize)(d_window_t *w);
22 xcb_render_pictformat_t root_format;
23 xcb_render_query_pict_formats_reply_t *pict_formats;
24 xcb_render_picture_t overlay_picture;
25 xcb_render_picture_t overlay_buffer;
26 xcb_render_picture_t root_picture;
27 xcb_render_picture_t solid_bg;
31 xcb_render_picture_t picture;
34 static void render_paint(d_screen_t *sc);
35 static void render_root_pixmap_changed(d_screen_t *sc);
36 static void paint_root(d_screen_t *sc, data_t *d);
37 static void paint_window(d_window_t *window, data_t *d);
38 static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd);
39 static void render_update_root_picture(d_screen_t *sc, data_t *d);
40 static void render_free_picture(d_window_t *w, window_data_t *wd);
41 static xcb_render_pictformat_t find_visual_format(data_t *d,
42 xcb_visualid_t visual);
43 static xcb_render_picture_t solid_picture(d_screen_t *sc,
47 static void render_window_show(d_window_t *window);
48 static void render_window_hide(d_window_t *window);
49 static void render_window_resize(d_window_t *window);
52 render_init(d_screen_t *sc, int id)
54 xcb_render_query_pict_formats_cookie_t ck;
59 data_t *d = malloc(sizeof(data_t));
60 d->screen_paint = sc->screen_paint;
61 d->screen_root_pixmap_changed = sc->screen_root_pixmap_changed;
62 d->window_show = sc->window_show;
63 d->window_hide = sc->window_hide;
64 d->window_resize = sc->window_resize;
65 screen_add_plugin_data(sc, plugin_id, d);
67 sc->screen_paint = render_paint;
68 sc->screen_root_pixmap_changed = render_root_pixmap_changed;
69 sc->window_show = render_window_show;
70 sc->window_hide = render_window_hide;
71 sc->window_resize = render_window_resize;
73 ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn);
74 d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
77 d->root_format = find_visual_format(d, sc->super.root_visual);
78 d->root_picture = XCB_NONE;
80 d->overlay_picture = xcb_generate_id(sc->dpy->conn);
81 xcb_render_create_picture(sc->dpy->conn,
82 d->overlay_picture, sc->overlay, d->root_format,
85 /* make the double buffer */
86 px = xcb_generate_id(sc->dpy->conn);
87 xcb_create_pixmap(sc->dpy->conn, sc->super.root_depth, px,
88 sc->super.root, sc->super.width_in_pixels,
89 sc->super.height_in_pixels);
90 d->overlay_buffer = xcb_generate_id(sc->dpy->conn);
91 xcb_render_create_picture(sc->dpy->conn, d->overlay_buffer, px,
92 d->root_format, 0, 0);
93 xcb_free_pixmap(sc->dpy->conn, px);
95 d->solid_bg = solid_picture(sc, 1.0, 0.0, 0.0, 0.0);
99 render_free(d_screen_t *sc)
101 data_t *d = screen_find_plugin_data(sc, plugin_id);
102 free(d->pict_formats);
103 xcb_render_free_picture(sc->dpy->conn, d->solid_bg);
105 xcb_render_free_picture(sc->dpy->conn, d->root_picture);
106 xcb_render_free_picture(sc->dpy->conn, d->overlay_picture);
107 xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer);
109 screen_remove_plugin_data(sc, plugin_id);
113 render_window_free(d_window_t *w, window_data_t *wd)
115 render_free_picture(w, wd);
120 render_window_show(d_window_t *w)
125 d = screen_find_plugin_data(w->sc, plugin_id);
130 wd = window_find_plugin_data(w, plugin_id);
132 render_window_free(w, wd);
134 wd = malloc(sizeof(window_data_t));
135 wd->picture = XCB_NONE;
136 window_add_plugin_data(w, plugin_id, wd);
142 render_window_hide(d_window_t *w)
147 d = screen_find_plugin_data(w->sc, plugin_id);
148 wd = window_find_plugin_data(w, plugin_id);
150 render_window_free(w, wd);
151 window_remove_plugin_data(w, plugin_id);
158 static xcb_render_picture_t
159 solid_picture(d_screen_t *sc, double a, double r, double g, double b)
161 xcb_render_picture_t picture;
162 xcb_render_color_t c;
164 picture = xcb_generate_id (sc->dpy->conn);
166 c.alpha = a * 0xffff;
167 c.red = a * r * 0xffff;
168 c.green = a * g * 0xffff;
169 c.blue = a * b * 0xffff;
171 xcb_render_create_solid_fill (sc->dpy->conn, picture, c);
175 static xcb_render_pictformat_t
176 find_visual_format(data_t *d, xcb_visualid_t visual)
178 xcb_render_pictscreen_iterator_t si;
179 xcb_render_pictdepth_iterator_t di;
180 xcb_render_pictvisual_iterator_t vi;
182 if (!visual) return XCB_NONE;
184 /* go through all the screens */
185 si = xcb_render_query_pict_formats_screens_iterator(d->pict_formats);
186 for (; si.rem; xcb_render_pictscreen_next(&si)) {
187 di = xcb_render_pictscreen_depths_iterator(si.data);
188 for (; di.rem; xcb_render_pictdepth_next(&di)) {
189 vi = xcb_render_pictdepth_visuals_iterator(di.data);
190 for (; vi.rem; xcb_render_pictvisual_next(&vi)) {
191 if (vi.data->visual == visual)
192 return vi.data->format;
200 render_free_picture(d_window_t *w, window_data_t *wd)
202 /* this might cause an error, oh well */
204 xcb_render_free_picture(w->sc->dpy->conn, wd->picture);
205 wd->picture = XCB_NONE;
210 render_update_root_picture(d_screen_t *sc, data_t *d)
214 px = screen_get_root_pixmap(sc);
216 d->root_picture = xcb_generate_id(sc->dpy->conn);
217 xcb_render_create_picture_checked(sc->dpy->conn,
219 d->root_format, 0, NULL);
224 render_update_picture(d_window_t *w, data_t *d, window_data_t *wd)
228 px = window_get_pixmap(w);
229 //printf("got pixmap 0x%x\n", px);
231 xcb_render_pictformat_t format;
232 const uint32_t vals = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS;
234 render_free_picture(w, wd);
236 wd->picture = xcb_generate_id(w->sc->dpy->conn);
237 format = find_visual_format(d, window_get_visual(w));
238 /* we don't need to check this. if it fails, we'll just be drawing
239 an invalid picture and creating some X errors but that's no big
241 xcb_render_create_picture(w->sc->dpy->conn,
242 wd->picture, px, format,
243 XCB_RENDER_CP_SUBWINDOW_MODE,
249 render_window_resize(d_window_t *w)
254 d = screen_find_plugin_data(w->sc, plugin_id);
255 wd = window_find_plugin_data(w, plugin_id);
257 render_free_picture(w, wd);
264 render_root_pixmap_changed(d_screen_t *sc)
268 d = screen_find_plugin_data(sc, plugin_id);
269 if (d->root_picture) {
270 xcb_render_free_picture(sc->dpy->conn, d->root_picture);
271 d->root_picture = XCB_NONE;
275 d->screen_root_pixmap_changed(sc);
279 render_paint(d_screen_t *sc)
281 data_t *d = screen_find_plugin_data(sc, plugin_id);
284 //printf("-- painting --\n");
287 for (it = list_bottom(sc->stacking); it; it = it->prev) {
288 d_window_t *w = it->data;
289 if (!window_is_input_only(w) && window_is_mapped(w))
294 /* copy the double buffer to the overlay window */
295 xcb_render_composite(sc->dpy->conn,
296 XCB_RENDER_PICT_OP_SRC,
302 sc->super.width_in_pixels,
303 sc->super.height_in_pixels);
305 /* call the function we replaced in the chain */
310 paint_root(d_screen_t *sc, data_t *d)
312 xcb_render_picture_t src;
315 if (!d->root_picture)
316 render_update_root_picture(sc, d);
318 if (d->root_picture) {
319 src = d->root_picture;
320 op = XCB_RENDER_PICT_OP_SRC;
324 op = XCB_RENDER_PICT_OP_CLEAR;
326 xcb_render_composite(sc->dpy->conn,
333 sc->super.width_in_pixels,
334 sc->super.height_in_pixels);
338 paint_window(d_window_t *w, data_t *d)
342 wd = window_find_plugin_data(w, plugin_id);
345 render_update_picture(w, d, wd);
347 //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
349 int x, y, width, height, bwidth;
352 window_get_area(w, &x, &y, &width, &height, &bwidth);
353 op = (window_is_argb(w) ?
354 XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC);
355 xcb_render_composite(w->sc->dpy->conn,
361 x, y, width + bwidth*2, height + bwidth *2);