glxCreatePixmap is failing for some reason. if that works, then probably glx renderi...
[dana/dcompmgr.git] / glxrender.c
1 #include "efence.h"
2
3 #include "render.h"
4 #include "screen.h"
5 #include "window.h"
6 #include "display.h"
7 #include "list.h"
8 #include <stdio.h>
9 #include <string.h>
10 #include <assert.h>
11 #include <stdlib.h>
12
13 #include <xcb/glx.h>
14 //#include <GL/glext.h>
15 //#include <GL/glxext.h>
16 #include <GL/glxtokens.h>
17 #include <GL/gl.h>
18
19 #define MAX_DEPTH 32
20
21 static int plugin_id;
22
23 typedef struct {
24     void (*screen_paint)(d_screen_t *sc);
25     void (*screen_root_pixmap_change)(d_screen_t *sc);
26     void (*window_show)(d_window_t *w);
27     void (*window_zombie_dead)(d_window_t *w);
28     void (*window_resize)(d_window_t *w);
29     void (*window_reshape)(d_window_t *w);
30
31     uint16_t shadowalpha;
32     int xshadowoff;
33     int yshadowoff;
34
35     uint32_t fbconfig[MAX_DEPTH + 1];
36
37     xcb_glx_context_t context;
38     xcb_glx_context_tag_t context_tag;
39 } data_t;
40
41 typedef struct {
42     GLuint texname;
43     xcb_glx_pixmap_t glpixmap;
44 } window_data_t;
45
46 static uint32_t glxrender_visual_info(uint32_t *props, int vis, int numprops,
47                                       uint32_t name);
48 static gboolean glxrender_check_visual(d_screen_t *sc);
49 static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d);
50
51 static void glxrender_paint(d_screen_t *sc);
52 static void glxrender_root_pixmap_change(d_screen_t *sc);
53 static void paint_root(d_screen_t *sc, data_t *d);
54 static void paint_window(d_window_t *window, data_t *d, window_data_t *wd,
55                          gboolean opaque, int x, int y, int width,
56                          int height, int bwidth);
57 static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
58                          int x, int y, int width, int height, int bwidth);
59 static void glxrender_update_window_pixmap(d_window_t *w, data_t *d,
60                                            window_data_t *wd);
61 static void glxrender_free_window_pixmap(d_window_t *w, data_t *d,
62                                          window_data_t *wd);
63 static void glxrender_update_root_pixmap(d_screen_t *sc, data_t *d);
64
65 static void glxrender_window_show(d_window_t *window);
66 static void glxrender_window_zombie_dead(d_window_t *window);
67 static void glxrender_window_resize(d_window_t *window);
68 static void glxrender_window_reshape(d_window_t *window);
69
70 void
71 glxrender_init(d_screen_t *sc, int id)
72 {
73     xcb_void_cookie_t ck;
74     xcb_generic_error_t *err;
75     xcb_glx_make_current_cookie_t curck;
76     xcb_glx_make_current_reply_t *currep;
77
78     plugin_id = id;
79
80     data_t *d = malloc(sizeof(data_t));
81     d->screen_paint = sc->screen_paint;
82     d->screen_root_pixmap_change = sc->screen_root_pixmap_change;
83     d->window_show = sc->window_show;
84     d->window_zombie_dead = sc->window_zombie_dead;
85     d->window_resize = sc->window_resize;
86     d->window_reshape = sc->window_reshape;
87     screen_add_plugin_data(sc, plugin_id, d);
88
89     sc->screen_paint = glxrender_paint;
90     sc->screen_root_pixmap_change = glxrender_root_pixmap_change;
91     sc->window_show = glxrender_window_show;
92     sc->window_zombie_dead = glxrender_window_zombie_dead;
93     sc->window_resize = glxrender_window_resize;
94     sc->window_reshape = glxrender_window_reshape;
95
96     d->shadowalpha = 0x3333; /* 20% */
97     d->xshadowoff = 2;
98     d->yshadowoff = 2;
99
100     if (!glxrender_check_visual(sc)) {
101         printf("unable to use the overlay window for GLX\n");
102         exit(1);
103     }
104
105     if (!(glxrender_find_fb_config(sc, d))) {
106         printf("unable to find FB configs\n");
107         exit(1);
108     }
109
110     d->context = xcb_generate_id(sc->dpy->conn);
111     ck = xcb_glx_create_context_checked(sc->dpy->conn, d->context,
112                                         sc->overlay_visual, sc->num,
113                                         XCB_NONE, TRUE);
114     if ((err = xcb_request_check(sc->dpy->conn, ck))) {
115         printf("context creation failed\n");
116         display_error(sc->dpy, err);
117         free(err);
118         exit(1);
119     }
120
121     curck = xcb_glx_make_current(sc->dpy->conn,
122                                  sc->overlay, d->context, XCB_NONE);
123     currep = xcb_glx_make_current_reply(sc->dpy->conn, curck, &err);
124     if (!currep) {
125         if (err) {
126             display_error(sc->dpy, err);
127             free(err);
128         }
129         printf("make current failed\n");
130         exit(1);
131     }
132     d->context_tag = currep->context_tag;
133     free(currep);
134
135     glViewport(0, 0, sc->super->width_in_pixels, sc->super->height_in_pixels);
136     glMatrixMode(GL_PROJECTION);
137     glLoadIdentity();
138     glOrtho(0, sc->super->width_in_pixels, sc->super->height_in_pixels,
139             0.0, -1.0, 100.0);
140     glMatrixMode(GL_MODELVIEW);
141     glLoadIdentity();
142     glClear(GL_COLOR_BUFFER_BIT);
143     glEnable(GL_TEXTURE_2D);
144     xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
145     glClearColor(0.4, 0.4, 0.4, 1.0);
146
147 /*
148   glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);                          
149   glEnable(GL_BLEND);
150 */
151 }
152
153 static uint32_t
154 glxrender_visual_info(uint32_t *props, int vis, int numprops, uint32_t name)
155 {
156     int s;
157
158     assert(numprops > 14);
159
160     /*
161     for (s = vis * numprops; s < vis*numprops + numprops; ++s)
162         printf("%x ", props[s]);
163     printf("\n");
164     */
165
166     s = vis * numprops;
167     switch (name) {
168     case GLX_VISUAL_ID:     return props[s+0];  /* id number */
169     case GLX_X_VISUAL_TYPE: return props[s+1];  /* XCB_CLASS_TRUE_COLOR etc */
170     case GLX_USE_GL:        return props[s+2];  /* boolean */
171     case GLX_RED_SIZE:      return props[s+3];  /* number */
172     case GLX_GREEN_SIZE:    return props[s+4];  /* number */
173     case GLX_BLUE_SIZE:     return props[s+5];  /* number */
174     case GLX_ALPHA_SIZE:    return props[s+6];  /* number */
175     case GLX_DOUBLEBUFFER:  return props[s+11]; /* boolean */
176     case GLX_DEPTH_SIZE:    return props[s+14]; /* number */
177     case GLX_STENCIL_SIZE:  return props[s+15]; /* number */
178     default: assert(0);
179     }
180 }
181
182 static gboolean
183 glxrender_check_visual(d_screen_t *sc)
184 {
185     xcb_glx_get_visual_configs_cookie_t ck;
186     xcb_glx_get_visual_configs_reply_t *rep;
187     gboolean ok = FALSE;
188
189     ck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num);
190     rep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, ck, NULL);
191     if (rep) {
192         uint32_t *props;
193         unsigned int i, nprops;
194
195 /*
196         static int config[] = {
197             GLX_DEPTH_SIZE, 1,
198             GLX_DOUBLEBUFFER,
199             GLX_RGBA,
200             XCB_NONE
201         };
202 */
203
204         props = xcb_glx_get_visual_configs_property_list(rep);
205         nprops = rep->num_properties;
206
207         for (i = 0; i < rep->num_visuals; ++i) {
208             /* look for the overlay's visual */
209             if (glxrender_visual_info(props, i, nprops, GLX_VISUAL_ID) !=
210                 sc->overlay_visual)
211             {
212                 continue;
213             }
214
215             if (!glxrender_visual_info(props, i, nprops, GLX_USE_GL)) {
216                 printf("overlay visual does not support GL\n");
217                 break;
218             }
219
220             if (!glxrender_visual_info(props, i, nprops, GLX_DOUBLEBUFFER)) {
221                 printf("overlay visual is not double buffered\n");
222                 break;
223             }
224
225             ok = TRUE; /* yippa ! */
226         }
227
228         free(rep);
229     }
230     return ok;
231 }
232
233 static uint32_t
234 glxrender_fbconfig_info(uint32_t *props, int con, int numprops, uint32_t name)
235 {
236     int i;
237
238     for (i = 0; i < numprops; ++i) {
239         if (props[i*2 + con*numprops*2] == name)
240             return props[i*2 + con*numprops*2 + 1];
241     }
242     return 0;
243 }
244
245 static gboolean
246 glxrender_find_fb_config(d_screen_t *sc, data_t *d)
247 {
248     xcb_glx_get_visual_configs_cookie_t vck;
249     xcb_glx_get_visual_configs_reply_t *vrep;
250     xcb_glx_get_fb_configs_cookie_t fbck;
251     xcb_glx_get_fb_configs_reply_t *fbrep;
252     xcb_depth_iterator_t depth_it;
253     unsigned int i, nvprops, nfbprops;
254     uint32_t *vprops, *fbprops;
255     uint32_t db, stencil, depthsize;
256
257     vck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num);
258     vrep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, vck, NULL);
259     if (!vrep) return FALSE;
260
261     fbck = xcb_glx_get_fb_configs(sc->dpy->conn, sc->num);
262     fbrep = xcb_glx_get_fb_configs_reply(sc->dpy->conn, fbck, NULL);
263     if (!fbrep) return FALSE;
264
265     vprops = xcb_glx_get_visual_configs_property_list(vrep);
266     nvprops = vrep->num_properties;
267     fbprops = xcb_glx_get_fb_configs_property_list(fbrep);
268     nfbprops = fbrep->num_properties;
269
270     memset(d->fbconfig, 0, (MAX_DEPTH + 1) * sizeof(d->fbconfig[0]));
271
272     db = 32767;
273     stencil = 32767;
274     depthsize = 32767;
275     depth_it = xcb_screen_allowed_depths_iterator(sc->super);
276     for (; depth_it.rem; xcb_depth_next(&depth_it)) {
277         uint32_t vid;
278         int j;
279         unsigned int k;
280         xcb_visualtype_t *visuals;
281         int nvisuals;
282
283         vid = 0;
284         if (depth_it.data->depth > MAX_DEPTH) continue;
285
286         printf("looking for depth %d\n", depth_it.data->depth);
287
288         visuals = xcb_depth_visuals(depth_it.data);
289         nvisuals = xcb_depth_visuals_length(depth_it.data);
290
291         /* pick the nicest visual for the depth */
292         for (j = 0; j < nvisuals; ++j) {
293             uint32_t val;
294
295             /* find the visual's properties */
296             for (k = 0; k < vrep->num_visuals; ++k)
297                 if (glxrender_visual_info(vprops, k, nvprops, GLX_VISUAL_ID)
298                     == visuals[j].visual_id)
299                 {
300                     break;
301                 }
302             if (k == vrep->num_visuals) continue;
303
304             val = glxrender_visual_info(vprops, k, nvprops, GLX_USE_GL);
305             if (!val) continue;
306
307             val = glxrender_visual_info(vprops, k, nvprops, GLX_DOUBLEBUFFER);
308             if (!val > db) continue;
309             db = val;
310
311             val = glxrender_visual_info(vprops, k, nvprops, GLX_STENCIL_SIZE);
312             if (!val > stencil) continue;
313             stencil = val;
314
315             val = glxrender_visual_info(vprops, k, nvprops, GLX_DEPTH_SIZE);
316             if (!val > depthsize) continue;
317             depthsize = val;
318
319             /* try this visual */
320             vid = visuals[j].visual_id;
321
322             /* look for an fbconfig for this visual */
323             for (k = 0; k < fbrep->num_FB_configs; ++k) {
324                 uint32_t val;
325
326                 //printf("root visual 0x%x\n", sc->super.root_visual);
327                 //printf("overlay visual 0x%x\n", sc->overlay_visual);
328
329                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
330                                               GLX_VISUAL_ID);
331                 //printf("x visual 0x%x\n", val);
332                 if (val != vid) continue;
333
334                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
335                                               GLX_DOUBLEBUFFER);
336                 printf("dbl buffer %s\n", val ? "yes" : "no");
337                 if (val) continue;
338
339                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
340                                               GLX_DEPTH_SIZE);
341                 printf("depth size %d\n", val);
342
343                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
344                                               GLX_RED_SIZE);
345                 printf("red size %d\n", val);
346                 if (!val) continue;
347
348                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
349                                               GLX_GREEN_SIZE);
350                 printf("green size %d\n", val);
351                 if (!val) continue;
352
353                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
354                                               GLX_BLUE_SIZE);
355                 printf("blue size %d\n", val);
356                 if (!val) continue;
357
358                 val = glxrender_fbconfig_info(fbprops, k, nfbprops,
359                                               GLX_ALPHA_SIZE);
360                 printf("alpha size %d\n", val);
361                 //if (depth_it.data->depth == 32 && !val) continue;
362
363                 val = glxrender_fbconfig_info(fbprops, j, nfbprops,
364                                               GLX_RENDER_TYPE);
365                 printf("rgba bit %s\n", val & GLX_RGBA_BIT ? "yes" : "no");
366                 if (!(val & GLX_RGBA_BIT)) continue;
367
368                 val = glxrender_fbconfig_info(fbprops, j, nfbprops,
369                                               GLX_CONFIG_CAVEAT);
370                 printf("caveat 0x%x\n", val);
371
372                 val = glxrender_fbconfig_info(fbprops, j, nfbprops,
373                                               GLX_BIND_TO_TEXTURE_RGBA_EXT);
374                 printf("bind ext %s\n", val ? "yes" : "no");
375                 if (!val) continue;
376
377                 d->fbconfig[depth_it.data->depth] =
378                     glxrender_fbconfig_info(fbprops, i, nfbprops,
379                                             GLX_FBCONFIG_ID);
380                 break;
381             }
382
383             if (d->fbconfig[depth_it.data->depth])
384                 printf("found visual 0x%x fbconfig 0x%x for depth %d\n",
385                        vid, d->fbconfig[depth_it.data->depth],
386                        depth_it.data->depth);
387         }
388     }
389
390     free(vrep);
391     free(fbrep);
392     return TRUE;
393 }
394
395 void
396 glxrender_free(d_screen_t *sc)
397 {
398     data_t *d = screen_find_plugin_data(sc, plugin_id);
399     free(d);
400     screen_remove_plugin_data(sc, plugin_id);
401 }
402
403 int
404 glxrender_next_timeout(struct d_screen *sc, struct timeval *tv)
405 {
406     (void)sc;
407     (void)tv;
408     return FALSE;
409 }
410
411 void
412 glxrender_timeout(struct d_screen *sc, const struct timeval *now)
413 {
414     (void)sc; (void)now;
415 }
416
417 void
418 glxrender_window_free_data(d_window_t *w, data_t *d, window_data_t *wd)
419 {
420     glxrender_free_window_pixmap(w, d, wd);
421     glDeleteTextures(1, &wd->texname);
422     free(wd);
423 }
424
425 static void
426 glxrender_window_show(d_window_t *w)
427 {
428     data_t *d;
429     window_data_t *wd;
430
431     d = screen_find_plugin_data(w->sc, plugin_id);
432
433     /* pass it on */
434     d->window_show(w);
435
436     wd = window_find_plugin_data(w, plugin_id);
437     if (wd)
438         glxrender_window_free_data(w, d, wd);
439    
440     wd = malloc(sizeof(window_data_t));
441     glGenTextures(1, &wd->texname);
442     wd->glpixmap = XCB_NONE;
443
444     window_add_plugin_data(w, plugin_id, wd);
445 }
446
447 static void
448 glxrender_window_zombie_dead(d_window_t *w)
449 {
450     data_t *d;
451     window_data_t *wd;
452
453     d = screen_find_plugin_data(w->sc, plugin_id);
454     wd = window_find_plugin_data(w, plugin_id);
455     if (wd) {
456         glxrender_window_free_data(w, d, wd);
457         window_remove_plugin_data(w, plugin_id);
458     }
459
460     /* pass it on */
461     d->window_zombie_dead(w);
462 }
463
464 static void
465 glxrender_free_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
466 {
467     /* this might cause an error, oh well */
468     if (wd->glpixmap) {
469         glBindTexture(GL_TEXTURE_2D, wd->texname);
470
471         {
472             /*
473               ReleaseTexImageEXT
474               1           CARD8           opcode (X assigned)
475               1           16              GLX opcode (glXVendorPrivate)
476               2           5               request length
477               4           1331            vendor specific opcode
478               4           CARD32          context tag
479               4           GLX_DRAWABLE    drawable
480               4           INT32           buffer
481             */
482             unsigned int len = (2 + 0) * sizeof(uint32_t);
483             uint32_t data[] = {
484                 wd->glpixmap,
485                 GLX_FRONT_LEFT_EXT
486             };
487             xcb_glx_vendor_private(w->sc->dpy->conn,
488                                    1331,
489                                    d->context_tag,
490                                    len, (uint8_t*)data);
491         }
492
493         glBindTexture(GL_TEXTURE_2D, 0);
494
495         xcb_glx_destroy_glx_pixmap(w->sc->dpy->conn, wd->glpixmap);
496         wd->glpixmap = XCB_NONE;
497     }
498 }
499
500 static void
501 glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
502 {
503     xcb_pixmap_t px;
504     uint8_t depth;
505
506     static const uint32_t attrs[] = {
507         GLX_TEXTURE_FORMAT_EXT,
508         GLX_TEXTURE_FORMAT_RGBA_EXT,
509     };
510
511     px = window_get_pixmap(w);
512     depth = window_get_depth(w);
513     if (px && d->fbconfig[depth]) {
514         wd->glpixmap = xcb_generate_id(w->sc->dpy->conn);
515         printf("creating pixmap fbcon 0x%x\n", d->fbconfig[depth]);
516         xcb_glx_create_pixmap(w->sc->dpy->conn, w->sc->num, d->fbconfig[depth],
517                               px, wd->glpixmap, 2, attrs);
518
519         glBindTexture(GL_TEXTURE_2D, wd->texname);
520
521         if (0) {
522             /*
523               BindTexImageEXT
524               1           CARD8                   opcode (X assigned)
525               1           16                      GLX opcode (glXVendorPrivate)
526               2           6+n                     request length
527               4           1330                    vendor specific opcode
528               4           CARD32                  context tag
529               4           GLX_DRAWABLE            drawable
530               4           INT32                   buffer
531               4           CARD32                  num_attributes
532               4*n         LISTofATTRIBUTE_PAIR    attribute, value pairs.
533             */
534             unsigned int len = (4 + 0) * sizeof(uint32_t);
535             uint32_t data[] = {
536                 wd->glpixmap,
537                 GLX_FRONT_LEFT_EXT,
538                 0,
539                 NULL
540             };
541             xcb_glx_vendor_private(w->sc->dpy->conn,
542                                    1330,
543                                    d->context_tag,
544                                    len, (uint8_t*)data);
545         }
546
547         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
548         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
549
550         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
551         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
552         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
553
554         glBindTexture(GL_TEXTURE_2D, 0);
555     }
556 }
557
558 static void
559 glxrender_update_root_pixmap(d_screen_t *sc, data_t *d)
560 {
561     xcb_pixmap_t px;
562
563     px = screen_get_root_pixmap(sc);
564     if (px) {
565     }
566 }
567
568 static void
569 glxrender_window_resize(d_window_t *w)
570 {
571     data_t *d;
572     window_data_t *wd;
573
574     d = screen_find_plugin_data(w->sc, plugin_id);
575     wd = window_find_plugin_data(w, plugin_id);
576
577     /* pass it on */
578     d->window_resize(w);
579
580     assert(wd != NULL);
581     glxrender_free_window_pixmap(w, d, wd);
582 }
583
584 static void
585 glxrender_window_reshape(d_window_t *w)
586 {
587     data_t *d;
588     window_data_t *wd;
589
590     d = screen_find_plugin_data(w->sc, plugin_id);
591     wd = window_find_plugin_data(w, plugin_id);
592
593     /* pass it on */
594     d->window_reshape(w);
595
596     assert(wd != NULL);
597     glxrender_free_window_pixmap(w, d, wd);
598 }
599
600 static void
601 glxrender_root_pixmap_change(d_screen_t *sc)
602 {
603     data_t *d;
604
605     d = screen_find_plugin_data(sc, plugin_id);
606     int a; /* XXX free things here */
607     //if (d->root_picture) {
608     //    xcb_render_free_picture(sc->dpy->conn, d->root_picture);
609     //    d->root_picture = XCB_NONE;
610     //}
611
612     /* pass it on */
613     d->screen_root_pixmap_change(sc);
614 }
615
616 static void
617 glxrender_paint(d_screen_t *sc)
618 {
619     data_t *d = screen_find_plugin_data(sc, plugin_id);
620     d_list_it_t *it;
621
622     //printf("painting\n");
623
624     paint_root(sc, d);
625
626     for (it = list_bottom(sc->stacking); it; it = it->prev) {
627         d_window_t *w = it->data;
628
629         if (!window_is_input_only(w) &&
630             (window_is_mapped(w) || window_is_zombie(w)))
631         {
632             int x, y, width, height, bwidth;
633             gboolean opaque;
634             window_data_t *wd;
635
636             window_get_area(w, &x, &y, &width, &height, &bwidth);
637
638             if (!(x < sc->super->width_in_pixels &&
639                   y < sc->super->height_in_pixels &&
640                   (x + width > 0 || x + width + d->xshadowoff > 0) &&
641                   (y + height > 0 || y + height + d->yshadowoff > 0)))
642             {
643                 continue;
644             }
645
646             opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
647
648             wd = window_find_plugin_data(w, plugin_id);
649
650             paint_shadow(w, d, wd, x, y, width, height, bwidth);
651             paint_window(w, d, wd, opaque, x, y, width, height, bwidth);
652         }
653     }
654
655     xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
656
657     /* call the function we replaced in the chain */
658     d->screen_paint(sc);
659 }
660
661 static void
662 paint_root(d_screen_t *sc, data_t *d)
663 {
664     //if (!d->root_picture)
665     glxrender_update_root_pixmap(sc, d);
666
667     glClear(GL_COLOR_BUFFER_BIT);
668 }
669
670 static void
671 paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque,
672              int x, int y, int width, int height, int bwidth)
673 {
674     if (!wd->glpixmap)
675         glxrender_update_window_pixmap(w, d, wd);
676
677     glBindTexture(GL_TEXTURE_2D, wd->texname);
678     glBegin(GL_QUADS);
679     glColor3f(1.0, 1.0, 1.0);
680     glVertex2i(x, y);
681     glTexCoord2f(1, 0);
682     glVertex2i(x + width + bwidth, y);
683     glTexCoord2f(1, 1);
684     glVertex2i(x + width + bwidth,
685                y + height + bwidth);
686     glTexCoord2f(0, 1);
687     glVertex2i(x, y + height + bwidth);
688     glTexCoord2f(0, 0);
689     glEnd();
690 }
691
692 static void
693 paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
694              int x, int y, int width, int height, int bwidth)
695 {
696 /*
697     xcb_render_composite(w->sc->dpy->conn,
698                          XCB_RENDER_PICT_OP_OVER,
699                          wd->shadow_picture,
700                          wd->picture,
701                          d->overlay_buffer,
702                          0, 0, 0, 0,
703                          x+d->xshadowoff, y+d->yshadowoff,
704                          width + bwidth*2, height + bwidth *2);
705 */
706 }