#include <GL/glxtokens.h>
#include <GL/gl.h>
+#define MAX_DEPTH 32
+
static int plugin_id;
typedef struct {
int xshadowoff;
int yshadowoff;
+ uint32_t fbconfig[MAX_DEPTH + 1];
+
xcb_glx_context_t context;
xcb_glx_context_tag_t context_tag;
} data_t;
xcb_glx_pixmap_t glpixmap;
} window_data_t;
+static uint32_t glxrender_visual_info(uint32_t *props, int vis, int numprops,
+ uint32_t name);
static gboolean glxrender_check_visual(d_screen_t *sc);
+static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d);
static void glxrender_paint(d_screen_t *sc);
static void glxrender_root_pixmap_change(d_screen_t *sc);
exit(1);
}
+ if (!(glxrender_find_fb_config(sc, d))) {
+ printf("unable to find FB configs\n");
+ exit(1);
+ }
+
d->context = xcb_generate_id(sc->dpy->conn);
ck = xcb_glx_create_context_checked(sc->dpy->conn, d->context,
sc->overlay_visual, sc->num,
*/
}
+static uint32_t
+glxrender_visual_info(uint32_t *props, int vis, int numprops, uint32_t name)
+{
+ int s;
+
+ assert(numprops > 14);
+
+ /*
+ for (s = vis * numprops; s < vis*numprops + numprops; ++s)
+ printf("%x ", props[s]);
+ printf("\n");
+ */
+
+ s = vis * numprops;
+ switch (name) {
+ case GLX_VISUAL_ID: return props[s+0]; /* id number */
+ case GLX_X_VISUAL_TYPE: return props[s+1]; /* XCB_CLASS_TRUE_COLOR etc */
+ case GLX_USE_GL: return props[s+2]; /* boolean */
+ case GLX_RED_SIZE: return props[s+3]; /* number */
+ case GLX_GREEN_SIZE: return props[s+4]; /* number */
+ case GLX_BLUE_SIZE: return props[s+5]; /* number */
+ case GLX_ALPHA_SIZE: return props[s+6]; /* number */
+ case GLX_DOUBLEBUFFER: return props[s+11]; /* boolean */
+ case GLX_DEPTH_SIZE: return props[s+14]; /* number */
+ case GLX_STENCIL_SIZE: return props[s+15]; /* number */
+ default: assert(0);
+ }
+}
+
static gboolean
glxrender_check_visual(d_screen_t *sc)
{
ck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num);
rep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, ck, NULL);
if (rep) {
- uint32_t *list;
- unsigned int i, j;
- int len;
- gboolean depth, doublebuffer, rgba;
+ uint32_t *props;
+ unsigned int i, nprops;
/*
static int config[] = {
};
*/
- list = xcb_glx_get_visual_configs_property_list(rep);
- len = xcb_glx_get_visual_configs_property_list_length(rep);
- printf("got %d %d, %d\n", rep->num_visuals, rep->num_properties, len);
+ props = xcb_glx_get_visual_configs_property_list(rep);
+ nprops = rep->num_properties;
for (i = 0; i < rep->num_visuals; ++i) {
- const int
- ID = 0,
- CLASS = 1,
- USE_GL = 2,
- RED_DEPTH = 3,
- BLUE_DEPTH = 4,
- GREEN_DEPTH = 5,
- ALPHA_DEPTH = 6,
- DOUBLE_BUFFER = 11,
- DEPTH_SIZE = 14;
- int s = i * rep->num_properties;
-
- depth = doublebuffer = rgba = FALSE;
-
/* look for the overlay's visual */
- if (list[s+ID] != sc->overlay_visual) continue;
-
- printf("0x%x ", list[s+ID]);
- printf("%d ", list[s+CLASS]);
- printf("%s ", list[s+USE_GL] ? "yes" : "no");
- printf("%d ", list[s+RED_DEPTH]);
- printf("%d ", list[s+GREEN_DEPTH]);
- printf("%d ", list[s+BLUE_DEPTH]);
- printf("%d ", list[s+ALPHA_DEPTH]);
- printf("%s ", list[s+DOUBLE_BUFFER] ? "yes" : "no");
- printf("%d ", list[s+DEPTH_SIZE]);
-
- printf("\n");
- for (j = 0; j < rep->num_properties; ++j)
- printf("%d ", list[i*rep->num_properties+j]);
- printf("\n");
-
- if (!list[s+USE_GL]) {
+ if (glxrender_visual_info(props, i, nprops, GLX_VISUAL_ID) !=
+ sc->overlay_visual)
+ {
+ continue;
+ }
+
+ if (!glxrender_visual_info(props, i, nprops, GLX_USE_GL)) {
printf("overlay visual does not support GL\n");
break;
}
- if (!list[s+DOUBLE_BUFFER]) {
+ if (!glxrender_visual_info(props, i, nprops, GLX_DOUBLEBUFFER)) {
printf("overlay visual is not double buffered\n");
break;
}
return ok;
}
+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;
+}
+
void
glxrender_free(d_screen_t *sc)
{