+static uint32_t
+glxrender_fbconfig_info(uint32_t *props, int con, int numprops, uint32_t name)
+{
+ int i;
+
+ for (i = 0; i < numprops; ++i) {
+ if (props[i*2 + con*numprops*2] == name)
+ return props[i*2 + con*numprops*2 + 1];
+ }
+ return 0;
+}
+
+static gboolean
+glxrender_find_fb_config(d_screen_t *sc, data_t *d)
+{
+ xcb_glx_get_visual_configs_cookie_t vck;
+ xcb_glx_get_visual_configs_reply_t *vrep;
+ xcb_glx_get_fb_configs_cookie_t fbck;
+ xcb_glx_get_fb_configs_reply_t *fbrep;
+ xcb_depth_iterator_t depth_it;
+ uint32_t fbcon = FALSE;
+ unsigned int i, nvprops, nfbprops;
+ uint32_t *vprops, *fbprops;
+ uint32_t db, stencil, depthsize;
+
+ vck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num);
+ vrep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, vck, NULL);
+ if (!vrep) return FALSE;
+
+ fbck = xcb_glx_get_fb_configs(sc->dpy->conn, sc->num);
+ fbrep = xcb_glx_get_fb_configs_reply(sc->dpy->conn, fbck, NULL);
+ if (!fbrep) return FALSE;
+
+ vprops = xcb_glx_get_visual_configs_property_list(vrep);
+ nvprops = vrep->num_properties;
+ fbprops = xcb_glx_get_fb_configs_property_list(fbrep);
+ nfbprops = fbrep->num_properties;
+
+ for (i = 0; i <= MAX_DEPTH; ++i)
+ d->fbconfig[i] = 0;
+
+ db = 32767;
+ stencil = 32767;
+ depthsize = 32767;
+ depth_it = xcb_screen_allowed_depths_iterator(&sc->super);
+ for (; depth_it.rem; xcb_depth_next(&depth_it)) {
+ uint32_t vid;
+ int j;
+ unsigned int k;
+ xcb_visualtype_t *visuals;
+ int nvisuals;
+
+ vid = 0;
+ if (depth_it.data->depth > MAX_DEPTH) continue;
+
+ visuals = xcb_depth_visuals(depth_it.data);
+ nvisuals = xcb_depth_visuals_length(depth_it.data);
+
+ /* pick the nicest visual for the depth */
+ for (j = 0; j < nvisuals; ++j) {
+ uint32_t val;
+
+ /* find the visual's properties */
+ for (k = 0; k < vrep->num_visuals; ++k)
+ if (glxrender_visual_info(vprops, k, nvprops, GLX_VISUAL_ID)
+ == visuals[j].visual_id)
+ {
+ break;
+ }
+ if (k == vrep->num_visuals) continue;
+
+ val = glxrender_visual_info(vprops, k, nvprops, GLX_USE_GL);
+ if (!val) continue;
+
+ val = glxrender_visual_info(vprops, k, nvprops, GLX_DOUBLEBUFFER);
+ if (!val > db) continue;
+ db = val;
+
+ val = glxrender_visual_info(vprops, k, nvprops, GLX_STENCIL_SIZE);
+ if (!val > stencil) continue;
+ stencil = val;
+
+ val = glxrender_visual_info(vprops, k, nvprops, GLX_DEPTH_SIZE);
+ if (!val > depthsize) continue;
+ depthsize = val;
+
+ /* use this visual */
+ vid = visuals[j].visual_id;
+ }
+
+ if (!vid) continue;
+
+ printf("found visual for depth %d\n", i);
+
+ for (k = 0; k < fbrep->num_FB_configs; ++k) {
+ uint32_t val;
+
+ printf("root visual 0x%x\n", sc->super.root_visual);
+ printf("overlay visual 0x%x\n", sc->overlay_visual);
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_VISUAL_ID);
+ printf("x visual 0x%x\n", val);
+ if (val != vid) continue;
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_DOUBLEBUFFER);
+ printf("dbl buffer %s\n", val ? "yes" : "no");
+ if (db) continue;
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_DEPTH_SIZE);
+ printf("depth size %d\n", val);
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_RED_SIZE);
+ printf("red size %d\n", val);
+ if (!val) continue;
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_GREEN_SIZE);
+ printf("green size %d\n", val);
+ if (!val) continue;
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_BLUE_SIZE);
+ printf("blue size %d\n", val);
+ if (!val) continue;
+
+ val = glxrender_fbconfig_info(fbprops, k, nfbprops,
+ GLX_ALPHA_SIZE);
+ printf("alpha size %d\n", val);
+ if (!val) continue;
+
+ val = glxrender_fbconfig_info(fbprops, j, nfbprops,
+ GLX_RENDER_TYPE);
+ printf("rgba bit %s\n", val & GLX_RGBA_BIT ? "yes" : "no");
+ if (!(val & GLX_RGBA_BIT)) continue;
+
+ val = glxrender_fbconfig_info(fbprops, j, nfbprops,
+ GLX_CONFIG_CAVEAT);
+ printf("caveat 0x%x\n", val);
+
+ val = glxrender_fbconfig_info(fbprops, j, nfbprops,
+ GLX_BIND_TO_TEXTURE_RGBA_EXT);
+ printf("bind ext %s\n", val ? "yes" : "no");
+ if (!val) continue;
+
+ d->fbconfig[depth_it.data->depth] =
+ glxrender_fbconfig_info(fbprops, i, nfbprops, GLX_FBCONFIG_ID);
+ break;
+ }
+ }
+
+ free(vrep);
+ free(fbrep);
+ return TRUE;
+}
+