10 #include <xcb/render.h>
15 void (*screen_paint)(d_screen_t *sc);
16 void (*window_show)(d_window_t *w);
17 void (*window_hide)(d_window_t *w);
18 void (*window_resize)(d_window_t *w);
20 xcb_render_query_pict_formats_reply_t *pict_formats;
21 xcb_render_picture_t overlay_picture;
22 xcb_render_picture_t overlay_buffer;
23 xcb_render_picture_t solid_bg;
27 xcb_render_picture_t picture;
28 gboolean waiting_picture;
29 xcb_void_cookie_t ck_picture;
32 static void render_screen_paint(d_screen_t *sc);
33 static void paint_root(d_screen_t *sc, data_t *d);
34 static void paint_window(d_window_t *window, data_t *d);
35 static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
37 static void render_free_picture(d_window_t *w, window_data_t *wd);
38 static xcb_render_pictformat_t find_visual_format(data_t *d,
39 xcb_visualid_t visual);
40 static xcb_render_picture_t solid_picture(d_screen_t *sc,
44 static void render_window_show(d_window_t *window);
45 static void render_window_hide(d_window_t *window);
46 static void render_window_resize(d_window_t *window);
49 render_init(d_screen_t *sc, int id)
51 xcb_render_query_pict_formats_cookie_t ck;
52 xcb_render_pictformat_t format;
57 data_t *d = malloc(sizeof(data_t));
58 d->screen_paint = sc->screen_paint;
59 d->window_show = sc->window_show;
60 d->window_hide = sc->window_hide;
61 d->window_resize = sc->window_resize;
62 screen_add_plugin_data(sc, plugin_id, d);
64 sc->screen_paint = render_screen_paint;
65 sc->window_show = render_window_show;
66 sc->window_hide = render_window_hide;
67 sc->window_resize = render_window_resize;
69 ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn);
70 d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
73 format = find_visual_format(d, sc->super.root_visual);
75 d->overlay_picture = xcb_generate_id(sc->dpy->conn);
76 xcb_render_create_picture(sc->dpy->conn,
77 d->overlay_picture, sc->overlay, format,
80 /* make the double buffer */
81 px = xcb_generate_id(sc->dpy->conn);
82 xcb_create_pixmap(sc->dpy->conn, sc->super.root_depth, px,
83 sc->super.root, sc->super.width_in_pixels,
84 sc->super.height_in_pixels);
85 d->overlay_buffer = xcb_generate_id(sc->dpy->conn);
86 xcb_render_create_picture(sc->dpy->conn, d->overlay_buffer, px,
88 xcb_free_pixmap(sc->dpy->conn, px);
90 d->solid_bg = solid_picture(sc, 1.0, 0.0, 0.0, 0.0);
94 render_free(d_screen_t *sc)
96 data_t *d = screen_find_plugin_data(sc, plugin_id);
97 free(d->pict_formats);
98 xcb_render_free_picture(sc->dpy->conn, d->solid_bg);
99 xcb_render_free_picture(sc->dpy->conn, d->overlay_picture);
100 xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer);
102 screen_remove_plugin_data(sc, plugin_id);
106 render_window_free(d_window_t *w, window_data_t *wd)
108 render_free_picture(w, wd);
113 render_window_show(d_window_t *w)
118 d = screen_find_plugin_data(w->sc, plugin_id);
123 wd = window_find_plugin_data(w, plugin_id);
125 render_window_free(w, wd);
127 wd = malloc(sizeof(window_data_t));
128 wd->picture = XCB_NONE;
129 wd->waiting_picture = FALSE;
130 window_add_plugin_data(w, plugin_id, wd);
136 render_window_hide(d_window_t *w)
141 d = screen_find_plugin_data(w->sc, plugin_id);
142 wd = window_find_plugin_data(w, plugin_id);
144 render_window_free(w, wd);
145 window_remove_plugin_data(w, plugin_id);
155 xcb_render_picture_t solid_picture(d_screen_t *sc,
159 xcb_render_picture_t picture;
160 xcb_render_color_t c;
162 picture = xcb_generate_id (sc->dpy->conn);
164 c.alpha = a * 0xffff;
165 c.red = a * r * 0xffff;
166 c.green = a * g * 0xffff;
167 c.blue = a * b * 0xffff;
169 xcb_render_create_solid_fill (sc->dpy->conn, picture, c);
173 static xcb_render_pictformat_t
174 find_visual_format(data_t *d, xcb_visualid_t visual)
176 xcb_render_pictscreen_iterator_t si;
177 xcb_render_pictdepth_iterator_t di;
178 xcb_render_pictvisual_iterator_t vi;
180 if (!visual) return XCB_NONE;
182 /* go through all the screens */
183 si = xcb_render_query_pict_formats_screens_iterator(d->pict_formats);
184 for (; si.rem; xcb_render_pictscreen_next(&si)) {
185 di = xcb_render_pictscreen_depths_iterator(si.data);
186 for (; di.rem; xcb_render_pictdepth_next(&di)) {
187 vi = xcb_render_pictdepth_visuals_iterator(di.data);
188 for (; vi.rem; xcb_render_pictvisual_next(&vi)) {
189 if (vi.data->visual == visual)
190 return vi.data->format;
197 static xcb_render_picture_t
198 render_get_picture(d_window_t *w, window_data_t *wd)
200 if (wd->waiting_picture) {
201 xcb_generic_error_t *err;
202 //printf("** checking create picture 0x%x\n", w->id);
203 err = xcb_request_check(w->sc->dpy->conn, wd->ck_picture);
205 wd->picture = XCB_NONE;
206 printf("error creating picture for window 0x%x\n", w->id);
209 wd->waiting_picture = FALSE;
211 //printf("returning picture 0x%x for window 0x%x\n", wd->picture, w->id);
216 render_free_picture(d_window_t *w, window_data_t *wd)
218 xcb_render_picture_t pict;
220 pict = render_get_picture(w, wd);
221 if (pict) xcb_render_free_picture(w->sc->dpy->conn, pict);
222 wd->picture = XCB_NONE;
226 render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
231 px = window_get_pixmap(w);
232 //printf("got pixmap 0x%x\n", px);
234 xcb_render_pictformat_t format;
235 const uint32_t vals = (children ?
236 XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS :
237 XCB_SUBWINDOW_MODE_CLIP_BY_CHILDREN);
239 render_free_picture(w, wd);
241 wd->picture = xcb_generate_id(w->sc->dpy->conn);
242 format = find_visual_format(d, window_get_visual(w));
244 xcb_render_create_picture_checked(w->sc->dpy->conn,
245 wd->picture, px, format,
246 XCB_RENDER_CP_SUBWINDOW_MODE,
248 wd->waiting_picture = TRUE;
253 render_window_resize(d_window_t *w)
258 d = screen_find_plugin_data(w->sc, plugin_id);
259 wd = window_find_plugin_data(w, plugin_id);
260 render_free_picture(w, wd);
267 render_screen_paint(d_screen_t *sc)
269 data_t *d = screen_find_plugin_data(sc, plugin_id);
272 //printf("-- painting --\n");
275 for (it = list_bottom(sc->stacking); it; it = it->prev) {
276 d_window_t *w = it->data;
277 if (!window_is_input_only(w) && window_is_mapped(w))
282 /* copy the double buffer to the overlay window */
283 xcb_render_composite(sc->dpy->conn,
284 XCB_RENDER_PICT_OP_SRC,
290 sc->super.width_in_pixels,
291 sc->super.height_in_pixels);
293 /* call the function we replaced in the chain */
298 paint_root(d_screen_t *sc, data_t *d)
300 xcb_render_composite(sc->dpy->conn,
301 XCB_RENDER_PICT_OP_CLEAR,
307 sc->super.width_in_pixels,
308 sc->super.height_in_pixels);
312 paint_window(d_window_t *w, data_t *d)
315 xcb_render_picture_t pict;
316 int x, y, width, height, bwidth;
318 wd = window_find_plugin_data(w, plugin_id);
321 render_update_picture(w, d, wd, TRUE);
322 pict = render_get_picture(w, wd);
324 //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
325 window_get_area(w, &x, &y, &width, &height, &bwidth);
326 xcb_render_composite(w->sc->dpy->conn,
327 //XCB_RENDER_PICT_OP_SRC, /* - for solid */
328 XCB_RENDER_PICT_OP_OVER, /* - for argb */
333 x, y, width + bwidth*2, height + bwidth *2);