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);
21 void (*window_reshape)(d_window_t *w);
23 xcb_render_pictformat_t root_format;
24 xcb_render_query_pict_formats_reply_t *pict_formats;
25 xcb_render_picture_t overlay_picture;
26 xcb_render_picture_t overlay_buffer;
27 xcb_render_picture_t root_picture;
28 xcb_render_picture_t solid_bg;
32 xcb_render_picture_t picture;
35 static void render_paint(d_screen_t *sc);
36 static void render_root_pixmap_changed(d_screen_t *sc);
37 static void paint_root(d_screen_t *sc, data_t *d);
38 static void paint_window(d_window_t *window, data_t *d);
39 static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd);
40 static void render_update_root_picture(d_screen_t *sc, data_t *d);
41 static void render_free_picture(d_window_t *w, window_data_t *wd);
42 static xcb_render_pictformat_t find_visual_format(data_t *d,
43 xcb_visualid_t visual);
44 static xcb_render_picture_t solid_picture(d_screen_t *sc,
48 static void render_window_show(d_window_t *window);
49 static void render_window_hide(d_window_t *window);
50 static void render_window_resize(d_window_t *window);
51 static void render_window_reshape(d_window_t *window);
54 render_init(d_screen_t *sc, int id)
56 xcb_render_query_pict_formats_cookie_t ck;
61 data_t *d = malloc(sizeof(data_t));
62 d->screen_paint = sc->screen_paint;
63 d->screen_root_pixmap_changed = sc->screen_root_pixmap_changed;
64 d->window_show = sc->window_show;
65 d->window_hide = sc->window_hide;
66 d->window_resize = sc->window_resize;
67 d->window_reshape = sc->window_reshape;
68 screen_add_plugin_data(sc, plugin_id, d);
70 sc->screen_paint = render_paint;
71 sc->screen_root_pixmap_changed = render_root_pixmap_changed;
72 sc->window_show = render_window_show;
73 sc->window_hide = render_window_hide;
74 sc->window_resize = render_window_resize;
75 sc->window_reshape = render_window_reshape;
77 ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn);
78 d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
81 d->root_format = find_visual_format(d, sc->super.root_visual);
82 d->root_picture = XCB_NONE;
84 d->overlay_picture = xcb_generate_id(sc->dpy->conn);
85 xcb_render_create_picture(sc->dpy->conn,
86 d->overlay_picture, sc->overlay, d->root_format,
89 /* make the double buffer */
90 px = xcb_generate_id(sc->dpy->conn);
91 xcb_create_pixmap(sc->dpy->conn, sc->super.root_depth, px,
92 sc->super.root, sc->super.width_in_pixels,
93 sc->super.height_in_pixels);
94 d->overlay_buffer = xcb_generate_id(sc->dpy->conn);
95 xcb_render_create_picture(sc->dpy->conn, d->overlay_buffer, px,
96 d->root_format, 0, 0);
97 xcb_free_pixmap(sc->dpy->conn, px);
99 d->solid_bg = solid_picture(sc, 1.0, 0.0, 0.0, 0.0);
103 render_free(d_screen_t *sc)
105 data_t *d = screen_find_plugin_data(sc, plugin_id);
106 free(d->pict_formats);
107 xcb_render_free_picture(sc->dpy->conn, d->solid_bg);
109 xcb_render_free_picture(sc->dpy->conn, d->root_picture);
110 xcb_render_free_picture(sc->dpy->conn, d->overlay_picture);
111 xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer);
113 screen_remove_plugin_data(sc, plugin_id);
117 render_window_free(d_window_t *w, window_data_t *wd)
119 render_free_picture(w, wd);
124 render_window_show(d_window_t *w)
129 d = screen_find_plugin_data(w->sc, plugin_id);
134 wd = window_find_plugin_data(w, plugin_id);
136 render_window_free(w, wd);
138 wd = malloc(sizeof(window_data_t));
139 wd->picture = XCB_NONE;
140 window_add_plugin_data(w, plugin_id, wd);
146 render_window_hide(d_window_t *w)
151 d = screen_find_plugin_data(w->sc, plugin_id);
152 wd = window_find_plugin_data(w, plugin_id);
154 render_window_free(w, wd);
155 window_remove_plugin_data(w, plugin_id);
162 static xcb_render_picture_t
163 solid_picture(d_screen_t *sc, double a, double r, double g, double b)
165 xcb_render_picture_t picture;
166 xcb_render_color_t c;
168 picture = xcb_generate_id (sc->dpy->conn);
170 c.alpha = a * 0xffff;
171 c.red = a * r * 0xffff;
172 c.green = a * g * 0xffff;
173 c.blue = a * b * 0xffff;
175 xcb_render_create_solid_fill (sc->dpy->conn, picture, c);
179 static xcb_render_pictformat_t
180 find_visual_format(data_t *d, xcb_visualid_t visual)
182 xcb_render_pictscreen_iterator_t si;
183 xcb_render_pictdepth_iterator_t di;
184 xcb_render_pictvisual_iterator_t vi;
186 if (!visual) return XCB_NONE;
188 /* go through all the screens */
189 si = xcb_render_query_pict_formats_screens_iterator(d->pict_formats);
190 for (; si.rem; xcb_render_pictscreen_next(&si)) {
191 di = xcb_render_pictscreen_depths_iterator(si.data);
192 for (; di.rem; xcb_render_pictdepth_next(&di)) {
193 vi = xcb_render_pictdepth_visuals_iterator(di.data);
194 for (; vi.rem; xcb_render_pictvisual_next(&vi)) {
195 if (vi.data->visual == visual)
196 return vi.data->format;
204 render_free_picture(d_window_t *w, window_data_t *wd)
206 /* this might cause an error, oh well */
208 xcb_render_free_picture(w->sc->dpy->conn, wd->picture);
209 wd->picture = XCB_NONE;
214 render_update_root_picture(d_screen_t *sc, data_t *d)
218 px = screen_get_root_pixmap(sc);
220 d->root_picture = xcb_generate_id(sc->dpy->conn);
221 xcb_render_create_picture_checked(sc->dpy->conn,
223 d->root_format, 0, NULL);
228 render_update_picture(d_window_t *w, data_t *d, window_data_t *wd)
232 px = window_get_pixmap(w);
233 //printf("got pixmap 0x%x\n", px);
235 xcb_render_pictformat_t format;
236 const uint32_t vals = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS;
238 render_free_picture(w, wd);
240 wd->picture = xcb_generate_id(w->sc->dpy->conn);
241 format = find_visual_format(d, window_get_visual(w));
242 /* we don't need to check this. if it fails, we'll just be drawing
243 an invalid picture and creating some X errors but that's no big
245 xcb_render_create_picture(w->sc->dpy->conn,
246 wd->picture, px, format,
247 XCB_RENDER_CP_SUBWINDOW_MODE,
250 xcb_xfixes_set_picture_clip_region(w->sc->dpy->conn,
252 window_get_region(w),
259 render_window_reshape(d_window_t *w)
264 d = screen_find_plugin_data(w->sc, plugin_id);
265 wd = window_find_plugin_data(w, plugin_id);
267 /* pass it on, and let the window update it's region before we query
269 d->window_reshape(w);
272 xcb_xfixes_set_picture_clip_region(w->sc->dpy->conn,
274 window_get_region(w),
279 render_window_resize(d_window_t *w)
284 d = screen_find_plugin_data(w->sc, plugin_id);
285 wd = window_find_plugin_data(w, plugin_id);
291 render_free_picture(w, wd);
295 render_root_pixmap_changed(d_screen_t *sc)
299 d = screen_find_plugin_data(sc, plugin_id);
300 if (d->root_picture) {
301 xcb_render_free_picture(sc->dpy->conn, d->root_picture);
302 d->root_picture = XCB_NONE;
306 d->screen_root_pixmap_changed(sc);
310 render_paint(d_screen_t *sc)
312 data_t *d = screen_find_plugin_data(sc, plugin_id);
315 //printf("-- painting --\n");
318 for (it = list_bottom(sc->stacking); it; it = it->prev) {
319 d_window_t *w = it->data;
320 if (!window_is_input_only(w) && window_is_mapped(w))
325 /* copy the double buffer to the overlay window */
326 xcb_render_composite(sc->dpy->conn,
327 XCB_RENDER_PICT_OP_SRC,
333 sc->super.width_in_pixels,
334 sc->super.height_in_pixels);
336 /* call the function we replaced in the chain */
341 paint_root(d_screen_t *sc, data_t *d)
343 xcb_render_picture_t src;
346 if (!d->root_picture)
347 render_update_root_picture(sc, d);
349 if (d->root_picture) {
350 src = d->root_picture;
351 op = XCB_RENDER_PICT_OP_SRC;
355 op = XCB_RENDER_PICT_OP_CLEAR;
357 xcb_render_composite(sc->dpy->conn,
364 sc->super.width_in_pixels,
365 sc->super.height_in_pixels);
369 paint_window(d_window_t *w, data_t *d)
373 wd = window_find_plugin_data(w, plugin_id);
376 render_update_picture(w, d, wd);
378 //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
380 int x, y, width, height, bwidth;
383 window_get_area(w, &x, &y, &width, &height, &bwidth);
384 op = (window_is_argb(w) ?
385 XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC);
387 xcb_render_composite(w->sc->dpy->conn,
393 x, y, width + bwidth*2, height + bwidth *2);