#include #include #include #include extern const char *__progname; #include "findvis.h" static void get_config(Display *disp, XVisualInfo *vi, int attr, int *valp) { int e; e = glXGetConfig(disp,vi,attr,valp); switch (e) { case GLX_NO_EXTENSION: fprintf(stderr,"%s: no GLX extension support\n",__progname); exit(1); break; case GLX_BAD_SCREEN: fprintf(stderr,"%s: visual %#x is on nonexistent screen?\n",__progname,(unsigned int)vi->visualid); exit(1); break; case GLX_BAD_ATTRIBUTE: fprintf(stderr,"%s: bad attribute %d\n",__progname,attr); exit(1); break; case GLX_BAD_VISUAL: fprintf(stderr,"%s: non-GL visual\n",__progname); exit(1); break; case 0: break; default: fprintf(stderr,"%s: strange error %d from glXGetConfig\n",__progname,e); exit(1); break; } } XVisualInfo *find_visual(Display *disp) { typedef struct vstat VSTAT; struct vstat { int inx; int rsize; int gsize; int bsize; int asize; int dsize; int arsize; int agsize; int absize; int aasize; } ; XVisualInfo *viv; int nvi; int i; int value; VSTAT vs; VSTAT bvs; viv = XGetVisualInfo(disp,0,0,&nvi); if (nvi < 1) { fprintf(stderr,"%s: no visuals?!\n",__progname); exit(1); } bvs.inx = -1; for (i=nvi-1;i>=0;i--) { get_config(disp,viv+i,GLX_USE_GL,&value); switch (value) { case True: break; case False: continue; break; default: fprintf(stderr,"%s: strange value %d from GLX_USE_GL on %#x\n", __progname,value,(unsigned int)viv[i].visualid); exit(1); break; } get_config(disp,viv+i,GLX_LEVEL,&value); if (value != 0) continue; get_config(disp,viv+i,GLX_RGBA,&value); if (value != True) continue; vs.inx = i; get_config(disp,viv+i,GLX_RED_SIZE,&vs.rsize); get_config(disp,viv+i,GLX_GREEN_SIZE,&vs.gsize); get_config(disp,viv+i,GLX_BLUE_SIZE,&vs.bsize); get_config(disp,viv+i,GLX_ALPHA_SIZE,&vs.asize); get_config(disp,viv+i,GLX_DEPTH_SIZE,&vs.dsize); get_config(disp,viv+i,GLX_ACCUM_RED_SIZE,&vs.arsize); get_config(disp,viv+i,GLX_ACCUM_GREEN_SIZE,&vs.agsize); get_config(disp,viv+i,GLX_ACCUM_BLUE_SIZE,&vs.absize); get_config(disp,viv+i,GLX_ACCUM_ALPHA_SIZE,&vs.aasize); if ( (vs.rsize < 4) || (vs.gsize < 4) || (vs.bsize < 4) || (vs.asize < 4) || (vs.dsize < 8) || (vs.arsize < 4) || (vs.agsize < 4) || (vs.absize < 4) || (vs.aasize < 4) ) continue; if ( (bvs.inx < 0) || ( (vs.rsize >= bvs.rsize) && (vs.gsize >= bvs.gsize) && (vs.bsize >= bvs.bsize) && (vs.asize >= bvs.asize) && (vs.dsize >= bvs.dsize) && (vs.arsize >= bvs.arsize) && (vs.agsize >= bvs.agsize) && (vs.absize >= bvs.absize) && (vs.aasize >= bvs.aasize) && ( vs.rsize+vs.gsize+vs.bsize+vs.asize >= bvs.rsize+bvs.gsize+bvs.bsize+bvs.asize ) && ( vs.arsize+vs.agsize+vs.absize+vs.aasize >= bvs.arsize+bvs.agsize+bvs.absize+bvs.aasize ) ) ) { bvs = vs; } } if (bvs.inx < 0) { fprintf(stderr,"%s: can't find a suitable visual\n",__progname); exit(1); } return(viv+bvs.inx); }