13 //#include <GL/glext.h>
14 //#include <GL/glxext.h>
15 #include <GL/glxtokens.h>
21 void (*screen_paint)(d_screen_t *sc);
22 void (*screen_root_pixmap_change)(d_screen_t *sc);
23 void (*window_show)(d_window_t *w);
24 void (*window_zombie_dead)(d_window_t *w);
25 void (*window_resize)(d_window_t *w);
26 void (*window_reshape)(d_window_t *w);
32 xcb_glx_context_t context;
33 xcb_glx_context_tag_t context_tag;
38 xcb_glx_pixmap_t glpixmap;
41 static gboolean glxrender_check_visual(d_screen_t *sc);
43 static void glxrender_paint(d_screen_t *sc);
44 static void glxrender_root_pixmap_change(d_screen_t *sc);
45 static void paint_root(d_screen_t *sc, data_t *d);
46 static void paint_window(d_window_t *window, data_t *d, window_data_t *wd,
47 gboolean opaque, int x, int y, int width,
48 int height, int bwidth);
49 static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
50 int x, int y, int width, int height, int bwidth);
51 static void glxrender_update_window_pixmap(d_window_t *w, data_t *d,
53 static void glxrender_free_window_pixmap(d_window_t *w, window_data_t *wd);
54 static void glxrender_update_root_pixmap(d_screen_t *sc, data_t *d);
56 static void glxrender_window_show(d_window_t *window);
57 static void glxrender_window_zombie_dead(d_window_t *window);
58 static void glxrender_window_resize(d_window_t *window);
59 static void glxrender_window_reshape(d_window_t *window);
62 glxrender_init(d_screen_t *sc, int id)
65 xcb_generic_error_t *err;
66 xcb_glx_make_current_cookie_t curck;
67 xcb_glx_make_current_reply_t *currep;
71 data_t *d = malloc(sizeof(data_t));
72 d->screen_paint = sc->screen_paint;
73 d->screen_root_pixmap_change = sc->screen_root_pixmap_change;
74 d->window_show = sc->window_show;
75 d->window_zombie_dead = sc->window_zombie_dead;
76 d->window_resize = sc->window_resize;
77 d->window_reshape = sc->window_reshape;
78 screen_add_plugin_data(sc, plugin_id, d);
80 sc->screen_paint = glxrender_paint;
81 sc->screen_root_pixmap_change = glxrender_root_pixmap_change;
82 sc->window_show = glxrender_window_show;
83 sc->window_zombie_dead = glxrender_window_zombie_dead;
84 sc->window_resize = glxrender_window_resize;
85 sc->window_reshape = glxrender_window_reshape;
87 d->shadowalpha = 0x3333; /* 20% */
91 if (!glxrender_check_visual(sc)) {
92 printf("unable to use the overlay window for GLX\n");
96 d->context = xcb_generate_id(sc->dpy->conn);
97 ck = xcb_glx_create_context_checked(sc->dpy->conn, d->context,
98 sc->overlay_visual, sc->num,
100 if ((err = xcb_request_check(sc->dpy->conn, ck))) {
101 printf("context creation failed\n");
102 display_error(sc->dpy, err);
107 curck = xcb_glx_make_current(sc->dpy->conn,
108 sc->overlay, d->context, XCB_NONE);
109 currep = xcb_glx_make_current_reply(sc->dpy->conn, curck, &err);
112 display_error(sc->dpy, err);
115 printf("make current failed\n");
118 d->context_tag = currep->context_tag;
121 glViewport(0, 0, sc->super.width_in_pixels, sc->super.height_in_pixels);
122 glMatrixMode(GL_PROJECTION);
124 glOrtho(0, sc->super.width_in_pixels, sc->super.height_in_pixels,
126 glMatrixMode(GL_MODELVIEW);
128 glClear(GL_COLOR_BUFFER_BIT);
129 glEnable(GL_TEXTURE_2D);
130 xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
131 glClearColor(0.4, 0.4, 0.4, 1.0);
134 glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
140 glxrender_check_visual(d_screen_t *sc)
142 xcb_glx_get_visual_configs_cookie_t ck;
143 xcb_glx_get_visual_configs_reply_t *rep;
146 ck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num);
147 rep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, ck, NULL);
152 gboolean depth, doublebuffer, rgba;
155 static int config[] = {
163 list = xcb_glx_get_visual_configs_property_list(rep);
164 len = xcb_glx_get_visual_configs_property_list_length(rep);
165 printf("got %d %d, %d\n", rep->num_visuals, rep->num_properties, len);
167 for (i = 0; i < rep->num_visuals; ++i) {
178 int s = i * rep->num_properties;
180 depth = doublebuffer = rgba = FALSE;
182 /* look for the overlay's visual */
183 if (list[s+ID] != sc->overlay_visual) continue;
185 printf("0x%x ", list[s+ID]);
186 printf("%d ", list[s+CLASS]);
187 printf("%s ", list[s+USE_GL] ? "yes" : "no");
188 printf("%d ", list[s+RED_DEPTH]);
189 printf("%d ", list[s+GREEN_DEPTH]);
190 printf("%d ", list[s+BLUE_DEPTH]);
191 printf("%d ", list[s+ALPHA_DEPTH]);
192 printf("%s ", list[s+DOUBLE_BUFFER] ? "yes" : "no");
193 printf("%d ", list[s+DEPTH_SIZE]);
196 for (j = 0; j < rep->num_properties; ++j)
197 printf("%d ", list[i*rep->num_properties+j]);
200 if (!list[s+USE_GL]) {
201 printf("overlay visual does not support GL\n");
205 if (!list[s+DOUBLE_BUFFER]) {
206 printf("overlay visual is not double buffered\n");
210 ok = TRUE; /* yippa ! */
219 glxrender_free(d_screen_t *sc)
221 data_t *d = screen_find_plugin_data(sc, plugin_id);
223 screen_remove_plugin_data(sc, plugin_id);
227 glxrender_next_timeout(struct d_screen *sc, struct timeval *tv)
235 glxrender_timeout(struct d_screen *sc, const struct timeval *now)
241 glxrender_window_free_data(d_window_t *w, window_data_t *wd)
243 glxrender_free_window_pixmap(w, wd);
244 glDeleteTextures(1, &wd->texname);
249 glxrender_window_show(d_window_t *w)
254 d = screen_find_plugin_data(w->sc, plugin_id);
259 wd = window_find_plugin_data(w, plugin_id);
261 glxrender_window_free_data(w, wd);
263 wd = malloc(sizeof(window_data_t));
264 glGenTextures(1, &wd->texname);
266 window_add_plugin_data(w, plugin_id, wd);
270 glxrender_window_zombie_dead(d_window_t *w)
275 d = screen_find_plugin_data(w->sc, plugin_id);
276 wd = window_find_plugin_data(w, plugin_id);
278 glxrender_window_free_data(w, wd);
279 window_remove_plugin_data(w, plugin_id);
283 d->window_zombie_dead(w);
287 glxrender_free_window_pixmap(d_window_t *w, window_data_t *wd)
289 /* this might cause an error, oh well */
291 // xcb_render_free_picture(w->sc->dpy->conn, wd->picture);
292 // wd->picture = XCB_NONE;
297 glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
301 px = window_get_pixmap(w);
305 glxrender_update_root_pixmap(d_screen_t *sc, data_t *d)
309 px = screen_get_root_pixmap(sc);
315 glxrender_window_resize(d_window_t *w)
320 d = screen_find_plugin_data(w->sc, plugin_id);
321 wd = window_find_plugin_data(w, plugin_id);
327 glxrender_free_window_pixmap(w, wd);
331 glxrender_window_reshape(d_window_t *w)
336 d = screen_find_plugin_data(w->sc, plugin_id);
337 wd = window_find_plugin_data(w, plugin_id);
340 d->window_reshape(w);
343 glxrender_free_window_pixmap(w, wd);
347 glxrender_root_pixmap_change(d_screen_t *sc)
351 d = screen_find_plugin_data(sc, plugin_id);
352 int a; /* XXX free things here */
353 //if (d->root_picture) {
354 // xcb_render_free_picture(sc->dpy->conn, d->root_picture);
355 // d->root_picture = XCB_NONE;
359 d->screen_root_pixmap_change(sc);
363 glxrender_paint(d_screen_t *sc)
365 data_t *d = screen_find_plugin_data(sc, plugin_id);
370 for (it = list_bottom(sc->stacking); it; it = it->prev) {
371 d_window_t *w = it->data;
373 if (!window_is_input_only(w) &&
374 (window_is_mapped(w) || window_is_zombie(w)))
376 int x, y, width, height, bwidth;
380 window_get_area(w, &x, &y, &width, &height, &bwidth);
382 if (!(x < sc->super.width_in_pixels &&
383 y < sc->super.height_in_pixels &&
384 (x + width > 0 || x + width + d->xshadowoff > 0) &&
385 (y + height > 0 || y + height + d->yshadowoff > 0)))
390 opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
392 wd = window_find_plugin_data(w, plugin_id);
394 paint_shadow(w, d, wd, x, y, width, height, bwidth);
395 paint_window(w, d, wd, opaque, x, y, width, height, bwidth);
399 xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
401 /* call the function we replaced in the chain */
406 paint_root(d_screen_t *sc, data_t *d)
408 //if (!d->root_picture)
409 glxrender_update_root_pixmap(sc, d);
413 paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque,
414 int x, int y, int width, int height, int bwidth)
417 glxrender_update_window_pixmap(w, d, wd);
419 //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
422 xcb_render_picture_t alphamap;
426 op = XCB_RENDER_PICT_OP_SRC;
430 op = XCB_RENDER_PICT_OP_OVER;
431 alphamap = wd->alpha_picture;
434 xcb_render_composite(w->sc->dpy->conn,
440 x, y, width + bwidth*2, height + bwidth *2);
446 paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
447 int x, int y, int width, int height, int bwidth)
450 xcb_render_composite(w->sc->dpy->conn,
451 XCB_RENDER_PICT_OP_OVER,
456 x+d->xshadowoff, y+d->yshadowoff,
457 width + bwidth*2, height + bwidth *2);