home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / tools / xglinfo / xglinfo.c.z / xglinfo.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  38.9 KB  |  1,396 lines

  1. /*
  2.  * 
  3.  *           Copyright (c) Digital Equipment Corporation, 1995
  4.  * 
  5.  *                          All Rights Reserved
  6.  * 
  7.  * Permission to use, copy, modify, and distribute  this software and its
  8.  * documentation for any  purpose   and without fee  is  hereby  granted,
  9.  * provided that the above copyright notice appear in all copies and that
  10.  * both  that  copyright  notice  and  this  permission notice appear  in
  11.  * supporting documentation, and that the name of Digital  not be used in
  12.  * advertising or publicity  pertaining to distribution  of the  software
  13.  * without specific, written prior permission.
  14.  * 
  15.  * DIGITAL DISCLAIMS   ALL  WARRANTIES WITH   REGARD   TO  THIS SOFTWARE,
  16.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  17.  * EVENT   SHALL  DIGITAL  BE   LIABLE  FOR  ANY SPECIAL,   INDIRECT   OR
  18.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  19.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION  OF CONTRACT, NEGLIGENCE OR
  20.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21.  * PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  */
  24. /*
  25.  * HISTORY
  26.  */
  27. /*****************************************************************************/
  28. /******************************** Documentation ******************************/
  29. /*****************************************************************************/
  30.  
  31. /*
  32.  * See man page for full documentation.
  33.  *
  34.  * Written by John Dennis, Digital Equipment Corporation.
  35.  * jdennis@mlo.dec.com
  36.  *
  37.  * With thanks and credit to Jim Fulton who wrote the original version of
  38.  * xdpyinfo while at MIT which served as a starting point for this code.
  39.  */
  40.  
  41. /*****************************************************************************/
  42. /******************************* Include Files *******************************/
  43. /*****************************************************************************/
  44.  
  45. #include <stdio.h>
  46. #include <string.h>
  47. #include <stdlib.h>
  48. #include <X11/Xlib.h>
  49. #include <X11/Xutil.h>
  50. #include <GL/gl.h>
  51. #include <GL/glx.h>
  52. #include <GL/glu.h>
  53. #include "global.h"
  54.  
  55.  
  56. /*****************************************************************************/
  57. /****************************** Internal Defines *****************************/
  58. /*****************************************************************************/
  59.  
  60. #define GL_GET_CONFIG(_config, _pValue)                                      \
  61. {                                                                            \
  62.   switch (result = glXGetConfig(dpy, visual, _config, (_pValue))) {          \
  63.   case Success:                                                              \
  64.     break;                                                                   \
  65.   case GLX_NO_EXTENSION:                                                     \
  66.     printf("ERROR glXGetConfig %s return GLX_NO_EXTENSION, visuaID 0x%lx\n", \
  67.           "_config", visual->visualid);                                      \
  68.     break;                                                                   \
  69.   case GLX_BAD_SCREEN:                                                       \
  70.     printf("ERROR glXGetConfig %s return GLX_BAD_SCREEN, visuaID 0x%lx\n",   \
  71.           "_config", visual->visualid);                                      \
  72.     break;                                                                   \
  73.   case GLX_BAD_ATTRIBUTE:                                                    \
  74.     printf("ERROR glXGetConfig %s return GLX_BAD_ATTRIBUTE, visuaID 0x%lx\n",\
  75.           "_config", visual->visualid);                                      \
  76.     break;                                                                   \
  77.   case GLX_BAD_VISUAL:                                                       \
  78.     printf("ERROR glXGetConfig %s return GLX_BAD_VISUAL, visuaID 0x%lx\n",   \
  79.           "_config", visual->visualid);                                      \
  80.     break;                                                                   \
  81.   default:                                                                   \
  82.     printf("ERROR glXGetConfig %s return unknown error %d, visuaID 0x%lx\n", \
  83.           "_config", result, visual->visualid);                              \
  84.     break;                                                                   \
  85.   }                                                                          \
  86. }
  87.  
  88. /*****************************************************************************/
  89. /************************** Internal Type Definitions ************************/
  90. /*****************************************************************************/
  91.  
  92. typedef struct GLXVisualInfo {
  93.   int useGL;                   /* support GLX rendering */
  94.   int bufferSize;               /* depth of the color buffer */
  95.   int level;                   /* level in plane stacking */
  96.   int rgba;                   /* true if RGBA mode */
  97.   int doubleBuffer;               /* double buffering supported */
  98.   int stereo;                   /* stereo buffering supported */
  99.   int auxBuffers;               /* number of aux buffers */
  100.   int redSize;                   /* number of red component bits */
  101.   int greenSize;               /* number of green component bits */
  102.   int blueSize;                   /* number of blue component bits */
  103.   int alphaSize;               /* number of alpha component bits */
  104.   int depthSize;               /* number of depth bits */
  105.   int stencilSize;               /* number of stencil bits */
  106.   int accumRedSize;               /* number of red accum bits */
  107.   int accumGreenSize;               /* number of green accum bits */
  108.   int accumBlueSize;               /* number of blue accum bits */
  109.   int accumAlphaSize;               /* number of alpha accum bits */
  110.   int xVisualType;
  111.   int transparentPixel;               /* None or Pixel */
  112.   int transparentIndex;               /* transparent index value */
  113.   int transparentRedValue;           /* transparent color value */
  114.   int transparentGreenValue;
  115.   int transparentBlueValue;
  116.   int transparentAlphaValue;
  117.   int visualCaveats;               /* None or Slow */
  118. } GLXVisualInfo;
  119.  
  120. typedef enum 
  121. {
  122.   VID_NONE = 0,
  123.   VID_RGB  = 1,
  124.   VID_RGBA = 2,
  125.   VID_CI   = 4,
  126.   VID_ALL  = 7
  127. } VidTypes;
  128.  
  129. /*****************************************************************************/
  130. /**********************  External Function Declarations  *********************/
  131. /*****************************************************************************/
  132.  
  133. /*****************************************************************************/
  134. /**********************  Internal Function Declarations  *********************/
  135. /*****************************************************************************/
  136.  
  137. static void
  138. Usage(
  139.   void
  140. );
  141.  
  142. static void
  143. ProcessArgs(
  144.          int argc   ,
  145.          char       *argv[]
  146. );
  147.  
  148. void
  149. PrintEventMask (
  150.     int indent,                /* amount by which to indent */
  151.     unsigned long mask                /* event mask */
  152. );
  153.  
  154. void
  155. PrintExtensionInfo(
  156.   Display    *dpy,
  157.   int         fieldNameLen,
  158.   int          indent
  159. );
  160.  
  161. void
  162. PrintPixmapFormats(
  163.   Display    *dpy,
  164.   int         fieldNameLen,
  165.   int          indent
  166. );
  167.  
  168. void
  169. PrintWindowFocus(
  170.   Display    *dpy,
  171.   int         fieldNameLen
  172. );
  173.  
  174. void
  175. PrintDisplayInfo(
  176.   Display    *dpy,
  177.   int         fieldNameLen
  178. );
  179.  
  180. int
  181. GetGLVisualInfo (
  182.     Display    *dpy,
  183.     XVisualInfo *visual,
  184.     GLXVisualInfo *glVisual
  185. );
  186.  
  187. void
  188. PrintCookedVisualInfo (
  189.     Display    *dpy,
  190.     XVisualInfo *visual,
  191.     int indent
  192. );
  193.  
  194. void
  195. PrintRawVisualInfo (
  196.     Display    *dpy,
  197.     XVisualInfo *visual,
  198.     int indent
  199. );
  200.  
  201. int
  202. PrintVisualIDs (
  203.     Display    *dpy,
  204.     XVisualInfo *visual
  205. );
  206.  
  207. void
  208. PrintScreenInfo(
  209.   Display    *dpy,
  210.   int         scr,
  211.   int         fieldNameLen,
  212.   int          indent
  213. );
  214.  
  215. void
  216. PrintScreenVisualInfo(
  217.   Display    *dpy,
  218.   int         scr,
  219.   int         fieldNameLen,
  220.   int          indent
  221. );
  222.  
  223. static void
  224. PrintIndentedStringWithBlanks(
  225.   const char    * head,
  226.   const char    * string,
  227.   int            fieldNameLen,
  228.   int        indent
  229. );
  230.  
  231. static int
  232. ProcessScreen(
  233.   Display *dpy,
  234.   int screenNum,
  235.   int fieldNameLen,
  236.   int indent
  237. );
  238.  
  239. /*****************************************************************************/
  240. /*************************  External Global Variables  ***********************/
  241. /*****************************************************************************/
  242.  
  243. char       *ProgramName;
  244.  
  245. /*****************************************************************************/
  246. /*************************  Internal Global Variables  ***********************/
  247. /*****************************************************************************/
  248.  
  249. static char       *displayname = NULL;    /* server to contact */
  250. static int         printDisplayInfo = GL_TRUE;
  251. static int         printScreenInfo = GL_TRUE;
  252. static int         printVisualInfo = GL_TRUE;
  253. static int         printCookedVisualInfo = GL_TRUE;
  254. static int         printRawVisualInfo = GL_FALSE;
  255. static int         printSpecficScreen = GL_FALSE;
  256. static int         specficScreenNum = 0;
  257. static VidTypes    printVids = VID_NONE;
  258.  
  259. static int         pageWidth = 80;
  260. static int         glErrorBase, glEventBase;
  261. static int         glXMajorVersion, glXMinorVersion;
  262. static const char  *glXExtensionString = "";
  263. static int         glXVisRating = GL_FALSE;
  264. static int         glXVisInfo = GL_FALSE;
  265.  
  266. static Bool        dpyHasGL = GL_FALSE;
  267.  
  268. /*****************************************************************************/
  269. /***************************  Internal Functions  ****************************/
  270. /*****************************************************************************/
  271.  
  272. static void
  273. Usage(
  274.   void
  275. )
  276. {
  277.   fprintf(stderr, "usage:  %s [-help] [-display displayname] [-vid rgb | rgba | ci | all ] [-screen n]\n\n",
  278.       ProgramName);
  279.   fprintf(stderr, "  the following options take a '+' or '-' switch\n");
  280.   fprintf(stderr, "  a '+' turns the option on, a '-' turns the option off\n\n");
  281.   fprintf(stderr, "  [+-printDisplayInfo] [+-printScreenInfo] [+-printVisualInfo]\n");
  282.   fprintf(stderr, "  [+-printCookedVisualInfo]");
  283.   fprintf(stderr, "\n");
  284.   exit(1);
  285. }
  286.  
  287. static void
  288. ProcessArgs(
  289.          int argc   ,
  290.          char       *argv[]
  291. )
  292. {
  293.   int         i;
  294.     char       *arg;
  295.   char        switchChar;
  296.  
  297.   ProgramName = argv[0];
  298.  
  299.   for (i = 1; i < argc; i++) {
  300.     arg = argv[i];
  301.     switchChar = arg[0];
  302.  
  303.     if (switchChar == '-' || switchChar == '+') {
  304.       arg++;
  305.       if (strcmp(arg, "display") == 0) {
  306.     if (switchChar == '-') {
  307.       if (++i >= argc) goto missing;
  308.       displayname = argv[i];
  309.     }
  310.     else goto unknown;
  311.       }
  312.       else if (strcmp(arg, "screen") == 0) {
  313.     if (switchChar == '-') {
  314.       if (++i >= argc) goto missing;
  315.       if (sscanf(argv[i], "%d", &specficScreenNum) != 1) goto unknown;
  316.           printSpecficScreen = GL_TRUE;
  317.     }
  318.     else goto unknown;
  319.       }
  320.       else if (strcmp(arg, "printDisplayInfo") == 0
  321.         || strcmp(arg, "printdisplayinfo") == 0) {
  322.     if (switchChar == '+')
  323.       printDisplayInfo = GL_TRUE;
  324.     else
  325.       printDisplayInfo = GL_FALSE;
  326.       }
  327.       else if (strcmp(arg, "printScreenInfo") == 0
  328.         || strcmp(arg, "printscreeninfo") == 0) {
  329.     if (switchChar == '+')
  330.       printScreenInfo = GL_TRUE;
  331.     else
  332.       printScreenInfo = GL_FALSE;
  333.       }
  334.       else if (strcmp(arg, "printVisualInfo") == 0
  335.         || strcmp(arg, "printvisualinfo") == 0) {
  336.     if (switchChar == '+')
  337.       printVisualInfo = GL_TRUE;
  338.     else
  339.       printVisualInfo = GL_FALSE;
  340.       }
  341.       else if (strcmp(arg, "printCookedVisualInfo") == 0
  342.         || strcmp(arg, "printcookedvisualinfo") == 0) {
  343.     if (switchChar == '+')
  344.       printCookedVisualInfo = GL_TRUE;
  345.     else
  346.       printCookedVisualInfo = GL_FALSE;
  347.       }
  348.       else if (strcmp(arg, "vid") == 0) {
  349.     if (switchChar == '-') {
  350.       if (++i >= argc) goto missing;
  351.           if (strcmp(argv[i], "rgb") == 0 || strcmp(argv[i], "RGB") == 0) {
  352.             printVids = VID_RGB;
  353.           }
  354.           else if (strcmp(argv[i], "rgba") == 0 || strcmp(argv[i], "RGBA") == 0) {
  355.             printVids = VID_RGBA;
  356.           }
  357.           else if (strcmp(argv[i], "ci") == 0 || strcmp(argv[i], "CI") == 0) {
  358.             printVids = VID_CI;
  359.           }
  360.           else if (strcmp(argv[i], "all") == 0 || strcmp(argv[i], "ALL") == 0) {
  361.             printVids = VID_ALL;
  362.           }
  363.           else {
  364.             goto unknown;
  365.           }
  366.           printDisplayInfo = GL_FALSE;
  367.           printScreenInfo = GL_FALSE;
  368.           printVisualInfo = GL_TRUE;
  369.           printCookedVisualInfo = GL_FALSE;
  370.         }
  371.     else
  372.           goto unknown;
  373.       }
  374.       else if (strcmp(arg, "help") == 0
  375.         || strcmp(arg, "?") == 0) {
  376.         Usage();
  377.       }
  378.       else goto unknown;
  379.     }
  380.     else {
  381.       goto unknown;
  382.     }
  383.   }
  384.   return;
  385.  
  386.   unknown:
  387.       fprintf(stderr, "unknown arg: %s\n", argv[i]);
  388.       Usage();
  389.     
  390.   missing:
  391.       fprintf(stderr, "missing arg for: %s\n", argv[i]);
  392.       Usage();
  393. }
  394.  
  395. void
  396. PrintEventMask (
  397.     int indent,                /* amount by which to indent */
  398.     unsigned long mask                /* event mask */
  399. )
  400. {
  401.   char buf[1024];
  402.     int i, pad;
  403.     int nameWidth = 21;
  404.     unsigned long bit;
  405.     int len = indent;
  406.     int nameLen;
  407.     int bitsfound = 0;
  408.     char *name;
  409.  
  410.     for (i = 0; i < indent; i++) buf[i] = ' ';
  411.  
  412.     for (bit = 1; mask; bit <<= 1) {
  413.       if (bit & mask) {
  414.     mask ^= bit;               /* clear bit from mask */
  415.     name = EventMaskName((long)bit);
  416.     nameLen = strlen(name);
  417.     if (nameLen >= nameWidth) nameLen = nameWidth - 1; /* -1 for pad */
  418.     pad = nameWidth - nameLen;
  419.     if (len + nameLen > pageWidth) {
  420.       puts (buf);
  421.       len = indent;
  422.     }
  423.     strncpy(buf+len, name, nameLen);
  424.     len += nameLen;
  425.     if (len + pad > pageWidth) {
  426.       buf[len] = 0;
  427.       puts (buf);
  428.       len = indent;
  429.     }
  430.     else {
  431.       for (i = 0; i < pad; i++) buf[len++] = ' ';
  432.     }
  433.     buf[len] = 0;
  434.     bitsfound++;
  435.       }
  436.     }
  437.  
  438.     if (bitsfound) puts (buf);
  439. }
  440.  
  441. void
  442. PrintExtensionInfo(
  443.   Display    *dpy,
  444.   int         fieldNameLen,
  445.   int          indent
  446. )
  447. {
  448.   int         n = 0;
  449.   int         len, lineLen;
  450.   char      **extlist = XListExtensions(dpy, &n);
  451.  
  452.  
  453.   printf("%*s%d total\n",
  454.      fieldNameLen, "Server Extensions:",
  455.      n);
  456.   if (extlist) {
  457.     register int i;
  458.  
  459.     printf("%*s", indent, "");
  460.     lineLen = indent;
  461.     for (i = 0; i < n; i++) {
  462.       len = strlen(extlist[i]);
  463.       len += 2;                   /* for ", " */
  464.       if ((lineLen + len) >= pageWidth) {
  465.     printf("\n%*s", indent, "");
  466.     lineLen = indent;
  467.       }
  468.       printf("%s, ", extlist[i]);
  469.       lineLen += len;
  470.     }
  471.     if (lineLen > indent) printf("\n");
  472.     XFreeExtensionList(extlist);
  473.   }
  474. }
  475.  
  476. void
  477. PrintPixmapFormats(
  478.   Display    *dpy,
  479.   int         fieldNameLen,
  480.   int          indent
  481. )
  482. {
  483.   int i, n;
  484.   XPixmapFormatValues *pmf;
  485.  
  486.   pmf = XListPixmapFormats(dpy, &n);
  487.   printf("%*s%d total\n",
  488.      fieldNameLen, "pixmap formats:",
  489.      n);
  490.   if (pmf) {
  491.     for (i = 0; i < n; i++) {
  492.       printf("%*sdepth %2d, bits_per_pixel %2d, scanline_pad %2d\n",
  493.          indent, "",
  494.          pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad);
  495.     }
  496.     XFree((char *) pmf);
  497.   }
  498. }
  499.  
  500. void
  501. PrintWindowFocus(
  502.   Display    *dpy,
  503.   int         fieldNameLen
  504. )
  505. {
  506.   Window      focusWin;
  507.   int         focusRevert;
  508.  
  509.   XGetInputFocus(dpy, &focusWin, &focusRevert);
  510.   switch (focusWin) {
  511.   case PointerRoot:
  512.   case None:
  513.     printf("%*s%s\n",
  514.        fieldNameLen, "focus:",
  515.        WindowFocusName(focusWin));
  516.     break;
  517.   default:
  518.     printf("%*s0x%lx, revert to %s\n",
  519.        fieldNameLen, "focus window:",
  520.        focusWin, WindowFocusRevertName(focusRevert));
  521.     break;
  522.   }
  523. }
  524.  
  525. void
  526. PrintDisplayInfo(
  527.   Display    *dpy,
  528.   int         fieldNameLen
  529. )
  530. {
  531.   char       *cp;
  532.   const char *ccp;
  533.   int         minkeycode, maxkeycode;
  534.   char        title[256];
  535.   int         i;
  536.   int         titleLen, fillLen;
  537.   int          indent;
  538.  
  539.   if (fieldNameLen < 0) indent = -fieldNameLen;
  540.   else indent = fieldNameLen;
  541.   
  542.   sprintf(title, " Display %s ", DisplayString(dpy));
  543.   titleLen = strlen(title);
  544.   fillLen = (pageWidth - titleLen) / 2;
  545.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  546.   printf("%s", title);
  547.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  548.   printf("\n");  
  549.  
  550.   printf("%*s%s\n",
  551.      fieldNameLen, "name of display:",
  552.      DisplayString(dpy));
  553.   printf("%*s%d.%d\n",
  554.      fieldNameLen, "version number:",
  555.      ProtocolVersion(dpy), ProtocolRevision(dpy));
  556.   printf("%*s%s\n",
  557.      fieldNameLen, "vendor string:",
  558.      ServerVendor(dpy));
  559.   printf("%*s%d\n",
  560.      fieldNameLen, "vendor release:",
  561.      VendorRelease(dpy));
  562.   printf("%*s%ld bytes\n",
  563.      fieldNameLen, "max request size:",
  564.      XMaxRequestSize(dpy) * 4);
  565.   printf("%*s%d\n",
  566.      fieldNameLen, "motion buffer size:",
  567.      XDisplayMotionBufferSize(dpy));
  568.  
  569.   cp = ByteOrderName(BitmapBitOrder(dpy));
  570.   printf("%*sunit = %d, bit order = %s, padding = %d\n",
  571.      fieldNameLen, "bitmap:",
  572.      BitmapUnit(dpy), cp, BitmapPad(dpy));
  573.  
  574.   cp = ByteOrderName(ImageByteOrder(dpy));
  575.   printf("%*s%s\n",
  576.      fieldNameLen, "image byte order:",
  577.      cp);
  578.  
  579.   XDisplayKeycodes(dpy, &minkeycode, &maxkeycode);
  580.   printf("%*sminimum %d, maximum %d\n",
  581.      fieldNameLen, "keycode range:",
  582.      minkeycode, maxkeycode);
  583.  
  584.   PrintWindowFocus(dpy, fieldNameLen);
  585.  
  586.   printf("%*s%d\n",
  587.      fieldNameLen, "default screen num:",
  588.      DefaultScreen(dpy));
  589.   printf("%*s%d\n",
  590.      fieldNameLen, "number of screens:",
  591.      ScreenCount(dpy));
  592.  
  593.  
  594.   PrintPixmapFormats(dpy, fieldNameLen, indent);
  595.   PrintExtensionInfo(dpy, fieldNameLen, indent);
  596.  
  597.   printf("%*s",
  598.      fieldNameLen, "GLX Extension:");
  599.   if (dpyHasGL) {
  600.     printf("error base = %d, event base = %d, ",
  601.        glErrorBase, glEventBase);
  602.     if (glXQueryVersion(dpy, &glXMajorVersion, &glXMinorVersion)) {
  603.       printf("Version %d.%d\n",
  604.          glXMajorVersion, glXMinorVersion);
  605.     }
  606.     else {
  607.       printf("glXQueryVersion returned error\n");
  608.       exit(1);
  609.     }
  610.   }
  611.   else {
  612.     printf("NONE\n");
  613.   }
  614. #if defined(GLX_VERSION_1_1)
  615.   ccp = glXGetClientString (dpy, GLX_VENDOR);
  616.   if (ccp) {
  617.     printf ("%*sVendor = %s\n", fieldNameLen, "GLX Library:", ccp);
  618.   }
  619.   else {
  620.     printf ("%*sNo Vendor string\n", fieldNameLen, "GLX Library:");
  621.   }
  622.   ccp = glXGetClientString (dpy, GLX_VERSION);
  623.   if (ccp) {
  624.     printf ("%*sVersion = %s\n", indent, "", ccp);
  625.   }
  626.   else {
  627.     printf ("%*sNo Version string\n", indent, "");
  628.   }
  629.   ccp = glXGetClientString (dpy, GLX_EXTENSIONS);
  630.   PrintIndentedStringWithBlanks ("Extensions = ", ccp,
  631.     fieldNameLen, 2);
  632. #endif
  633. #if defined (GLU_VERSION_1_1)
  634.   ccp = (const char *) gluGetString (GLU_VERSION);
  635.   if (ccp) {
  636.     printf ("%*sVersion = %s\n", fieldNameLen, "GLU Library:", ccp);
  637.   }
  638.   else {
  639.     printf ("%*sNo Version string\n", fieldNameLen, "GLU Library:");
  640.   }
  641.   ccp = (const char *) gluGetString (GLU_EXTENSIONS);
  642.   PrintIndentedStringWithBlanks ("Extensions = ", ccp,
  643.     fieldNameLen, 2);
  644. #endif
  645. }
  646.  
  647. static int 
  648. QueryExtension(
  649.     char *extName
  650. )
  651. {
  652.     /*
  653.     ** Search for extName in the extensions string.  Use of strstr()
  654.     ** is not sufficient because extension names can be prefixes of
  655.     ** other extension names.  Could use strtok() but the constant
  656.     ** string returned by glXGetString can be in read-only memory.
  657.     */
  658.     char *p = (char *)glXExtensionString;
  659.     char *end;
  660.     int extNameLen;
  661.  
  662.     extNameLen = strlen(extName);
  663.  
  664.     end = p + strlen(p);
  665.  
  666.     while (p < end) {
  667.         int n = strcspn(p, " ");
  668.         if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
  669.             return GL_TRUE;
  670.         }
  671.         p += (n + 1);
  672.     }
  673.     return GL_FALSE;
  674. }
  675.  
  676. int
  677. GetGLVisualInfo (
  678.     Display    *dpy,
  679.     XVisualInfo *visual,
  680.     GLXVisualInfo *glVisual
  681. )
  682. {
  683.   int result;
  684.  
  685.   if (!dpyHasGL) {
  686.     glVisual->useGL = GL_FALSE;
  687.     return(0);
  688.   }
  689.  
  690.   GL_GET_CONFIG(GLX_USE_GL, &glVisual->useGL);
  691.  
  692.   if (!glVisual->useGL) return(0);
  693.  
  694.   GL_GET_CONFIG(GLX_BUFFER_SIZE, &glVisual->bufferSize);
  695.   GL_GET_CONFIG(GLX_LEVEL, &glVisual->level);
  696.   GL_GET_CONFIG(GLX_RGBA, &glVisual->rgba);
  697.   GL_GET_CONFIG(GLX_DOUBLEBUFFER, &glVisual->doubleBuffer);
  698.   GL_GET_CONFIG(GLX_STEREO, &glVisual->stereo);
  699.   GL_GET_CONFIG(GLX_AUX_BUFFERS, &glVisual->auxBuffers);
  700.   GL_GET_CONFIG(GLX_RED_SIZE, &glVisual->redSize);
  701.   GL_GET_CONFIG(GLX_GREEN_SIZE, &glVisual->greenSize);
  702.   GL_GET_CONFIG(GLX_BLUE_SIZE, &glVisual->blueSize);
  703.   GL_GET_CONFIG(GLX_ALPHA_SIZE, &glVisual->alphaSize);
  704.   GL_GET_CONFIG(GLX_DEPTH_SIZE, &glVisual->depthSize);
  705.   GL_GET_CONFIG(GLX_STENCIL_SIZE, &glVisual->stencilSize);
  706.   GL_GET_CONFIG(GLX_ACCUM_RED_SIZE, &glVisual->accumRedSize);
  707.   GL_GET_CONFIG(GLX_ACCUM_GREEN_SIZE, &glVisual->accumGreenSize);
  708.   GL_GET_CONFIG(GLX_ACCUM_BLUE_SIZE, &glVisual->accumBlueSize);
  709.   GL_GET_CONFIG(GLX_ACCUM_ALPHA_SIZE, &glVisual->accumAlphaSize);
  710.  
  711. #ifdef GLX_VERSION_1_1
  712.     if (glXMinorVersion > 0 || glXMajorVersion > 1)
  713.       glXExtensionString = glXQueryExtensionsString(dpy, visual->screen);
  714.  
  715. #ifdef GLX_EXT_visual_rating
  716.   if ( QueryExtension("GLX_EXT_visual_rating") ) {
  717.       GL_GET_CONFIG(GLX_VISUAL_CAVEAT_EXT, &glVisual->visualCaveats);
  718.       glXVisRating = GL_TRUE;
  719.   }
  720. #endif
  721.  
  722. #ifdef GLX_EXT_visual_info
  723.   if ( QueryExtension("GLX_EXT_visual_info") ) {
  724.       GL_GET_CONFIG(GLX_X_VISUAL_TYPE_EXT, &glVisual->xVisualType);
  725.       GL_GET_CONFIG(GLX_TRANSPARENT_TYPE_EXT, &glVisual->transparentPixel);
  726.       GL_GET_CONFIG(GLX_TRANSPARENT_INDEX_EXT, &glVisual->transparentIndex);
  727.       GL_GET_CONFIG(GLX_TRANSPARENT_RED_VALUE_EXT, &glVisual->transparentRedValue);
  728.       GL_GET_CONFIG(GLX_TRANSPARENT_GREEN_VALUE_EXT, &glVisual->transparentGreenValue);
  729.       GL_GET_CONFIG(GLX_TRANSPARENT_BLUE_VALUE_EXT, &glVisual->transparentBlueValue);
  730.       GL_GET_CONFIG(GLX_TRANSPARENT_ALPHA_VALUE_EXT, &glVisual->transparentAlphaValue);
  731.       glXVisInfo = GL_TRUE;
  732.   }
  733. #endif
  734. #endif
  735.  
  736.   return(1);
  737. }
  738.  
  739.  
  740. void
  741. PrintCookedVisualInfo (
  742.     Display    *dpy,
  743.     XVisualInfo *visual,
  744.     int indent
  745. )
  746. {
  747.   int result;
  748.   int hasRGB, hasAlpha, hasDepth, hasStencil, hasAccum, hasAuxBuffers;
  749.   GLXVisualInfo glVisualInfo;
  750.   GLXVisualInfo *gl = &glVisualInfo;
  751.   int listEmpty;
  752.  
  753.   printf ("%s visual: ID = 0x%lx (hex) %d (decimal) screen = %d\n",
  754.       VisualClassName(visual->class) , visual->visualid, visual->visualid,
  755.       visual->screen);
  756.  
  757.   if (result = GetGLVisualInfo(dpy, visual, gl)) {
  758.  
  759.     hasRGB = ((gl->redSize != 0)   ||
  760.           (gl->greenSize != 0) ||
  761.           (gl->blueSize != 0));
  762.     hasAlpha = (gl->alphaSize != 0);
  763.     hasDepth = (gl->depthSize != 0);
  764.     hasStencil = (gl->stencilSize != 0);
  765.     hasAccum = ((gl->accumRedSize != 0)   ||
  766.         (gl->accumGreenSize != 0) ||
  767.         (gl->accumBlueSize != 0)  ||
  768.         (gl->accumAlphaSize != 0));
  769.     hasAuxBuffers = (gl->auxBuffers != 0);
  770.  
  771.  
  772.     printf("%*s", indent, "");
  773.     if (gl->level < 0) {
  774.       printf("UNDERLAY(%d) ", -gl->level);
  775.     }
  776.     if (gl->level > 0) {
  777.       printf("OVERLAY(%d) ", gl->level);
  778.     }
  779.     if (gl->doubleBuffer)
  780.       printf("DOUBLE buffered ");
  781.     else
  782.       printf("SINGLE buffered ");
  783.  
  784.     if (gl->stereo)
  785.       printf("STEREO ");
  786.     else
  787.       printf("MONO ");
  788.  
  789.     /*
  790.      * RGBA visual
  791.      */
  792.     if (gl->rgba) {               /* rgba visual */
  793.       printf("RGB visual ");
  794.  
  795.       listEmpty = GL_TRUE;
  796.       if (hasAlpha || hasDepth || hasStencil || hasAccum || hasAuxBuffers) {
  797.     printf("with (");
  798.     if (hasAlpha) {
  799.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  800.       printf("Alpha");
  801.     }
  802.     if (hasDepth) {
  803.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  804.       printf("Z");
  805.     }
  806.     if (hasStencil) {
  807.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  808.       printf("Stencil");
  809.     }
  810.     if (hasAccum) {
  811.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  812.       printf("Accum");
  813.     }
  814.     if (hasAuxBuffers) {
  815.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  816.       printf("%d Aux Buffers", gl->auxBuffers);
  817.     }
  818.     printf(")\n");
  819.       }
  820.  
  821.       printf("%*s", indent, "");
  822.       printf("GL Sizes: RGBA=(%d,%d,%d,%d), ",
  823.          gl->redSize, gl->greenSize, gl->blueSize, gl->alphaSize);
  824.       if (hasDepth)
  825.     printf("Z=%d, ", gl->depthSize);
  826.       if (hasStencil)
  827.     printf("Stencil=%d, ", gl->stencilSize);
  828.       if (hasAccum)
  829.     printf("Accum=(%d,%d,%d,%d)",
  830.            gl->accumRedSize, gl->accumGreenSize, gl->accumBlueSize,
  831.            gl->accumAlphaSize);
  832.       printf("\n");
  833.  
  834.       /*
  835.        * Do some simple sanity checks on rgba visual.
  836.        */
  837.       if (!hasRGB)
  838.     printf("ERROR: RGBA visual, but RGB have zero size\n");
  839.       if (hasAlpha && hasAccum && gl->accumAlphaSize == 0)
  840.     printf("ERROR: RGBA visual with Alpha and Accum, but Accum Alpha size is zero\n");
  841.       if (!hasAlpha && hasAccum && gl->accumAlphaSize != 0)
  842.     printf("ERROR: RGBA visual without Alpha and with Accum, but Accum Alpha size is not zero\n");
  843.     }                       /* end rgba visual */
  844.     /*
  845.      * COLOR INDEX visual
  846.      */
  847.     else {                   /* color index visual */
  848.       printf("COLOR INDEX visual ");
  849.  
  850.       listEmpty = GL_TRUE;
  851.       if (hasDepth || hasStencil || hasAuxBuffers) {
  852.     printf("with (");
  853.     if (hasDepth) {
  854.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  855.       printf("Z");
  856.     }
  857.     if (hasStencil) {
  858.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  859.       printf("Stencil");
  860.     }
  861.     if (hasAuxBuffers) {
  862.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  863.       printf("%d Aux Buffers");
  864.     }
  865.     printf(")\n");
  866.       }
  867.  
  868.       printf("%*s", indent, "");
  869.       printf("GL Sizes: ColorIndex=%d, ", gl->bufferSize);
  870.       if (hasDepth)
  871.     printf("Z=%d, ", gl->depthSize);
  872.       if (hasStencil)
  873.     printf("Stencil=%d", gl->stencilSize);
  874.       printf("\n");
  875.  
  876.       /*
  877.        * Do some simple sanity checks on color index visual.
  878.        */
  879.       if (hasRGB)
  880.     printf("ERROR: CI visual, but RGB has non-zero sizes (%d,%d,%d)\n",
  881.            gl->redSize, gl->greenSize, gl->blueSize);
  882.       if (hasAlpha)
  883.     printf("ERROR: CI visual, but Alpha has non-zero size = %d\n",
  884.            gl->alphaSize);
  885.       if (hasAccum)
  886.     printf("ERROR: CI visual, but Accum has non-zero sizes (%d,%d,%d,%d)\n",
  887.            gl->accumRedSize, gl->accumGreenSize,
  888.            gl->accumBlueSize, gl->accumAlphaSize);
  889.     }                       /* end color index visual */
  890.  
  891.     if (glXVisRating || glXVisInfo) {
  892.       printf("%*s", indent, "");
  893.       printf("Extensions: ");
  894.     }
  895. #ifdef GLX_EXT_visual_rating
  896.     if (glXVisRating) {
  897.       if (gl->visualCaveats == GLX_NONE_EXT)
  898.         printf("Caveats=None");
  899.       else if (gl->visualCaveats == GLX_SLOW_VISUAL_EXT)
  900.         printf("Caveats=Slow");
  901.       else
  902.         printf("\nERROR: Unrecognized token for GLX_VISUAL_CAVEATS attribute\n");
  903.     }
  904. #endif
  905.  
  906. #ifdef GLX_EXT_visual_info
  907.     if (glXVisInfo) {
  908.       if (glXVisRating) printf(", ");
  909.       if (gl->transparentPixel == GLX_NONE_EXT) {
  910.         printf("OPAQUE ");
  911.       }
  912.       else if (gl->transparentPixel == GLX_TRANSPARENT_RGB_EXT) {
  913.         printf("TRANSPARENT PIXEL, ");
  914.         printf("color value=(%d,%d,%d,%d)", gl->transparentRedValue,
  915.            gl->transparentGreenValue, gl->transparentBlueValue, 
  916.            gl->transparentAlphaValue);
  917.       }
  918.       else if (gl->transparentPixel == GLX_TRANSPARENT_INDEX_EXT) {
  919.         printf("TRANSPARENT PIXEL, ");
  920.         printf("index value=%d", gl->transparentIndex);
  921.       }
  922.       else
  923.         printf("\nERROR: Unrecognized token for GLX_TRANSPARENT_PIXEL attribute\n");
  924.     }
  925. #endif
  926.     if (glXVisRating || glXVisInfo)
  927.       printf("\n");
  928.     }
  929.   else {
  930.     printf("%*s", indent, "");
  931.     printf("GL NOT SUPPORTED\n");
  932.   }
  933.  
  934.   printf("%*sCore X: ", indent, "");
  935.   printf ("depth=%d, ", visual->depth);
  936.   printf ("colormapSize=%d ", visual->colormap_size);
  937.  
  938.   if ((visual->class == TrueColor) || (visual->class == DirectColor)) {
  939.     printf ("RGB: masks=(0x%lx,0x%lx,0x%lx) ",
  940.         visual->red_mask, visual->green_mask, visual->blue_mask);
  941.     printf ("bits=%d",
  942.           visual->bits_per_rgb);
  943.   }
  944.   printf("\n");
  945. }
  946.  
  947. void
  948. PrintRawVisualInfo (
  949.     Display    *dpy,
  950.     XVisualInfo *visual,
  951.     int indent
  952. )
  953. {
  954.   int result;
  955.   GLXVisualInfo glVisualInfo;
  956.   GLXVisualInfo *gl = &glVisualInfo;
  957.  
  958.   printf ("%s visual: ID = 0x%lx (hex) %d (decimal) screen = %d\n",
  959.       VisualClassName(visual->class) , visual->visualid, visual->visualid,
  960.       visual->screen);
  961.   
  962.   if (result = GetGLVisualInfo(dpy, visual, gl)) {
  963.  
  964.     printf("%*s", indent, "");
  965.     printf("useGL=%d, level=%d, doubleBuffer=%d, rgba=%d, stereo=%d\n",
  966.        gl->useGL, gl->level, gl->doubleBuffer, gl->rgba, gl->stereo);
  967.  
  968.     printf("%*s", indent, "");
  969.     printf("bufferSize=%d, number aux buffers=%d\n",
  970.        gl->bufferSize, gl->auxBuffers);
  971.  
  972.     printf("%*s", indent, "");
  973.     printf("sizes: RGBA=(%d,%d,%d,%d), Z=%d, STENCIL=%d, ACCUM=(%d,%d,%d,%d)\n",
  974.        gl->redSize, gl->greenSize, gl->blueSize, gl->alphaSize,
  975.        gl->depthSize, gl->stencilSize, 
  976.        gl->accumRedSize, gl->accumGreenSize,
  977.        gl->accumBlueSize, gl->accumAlphaSize);
  978.  
  979.  
  980.     printf("%*s", indent, "");
  981.     printf("Extensions: ");
  982. #ifdef GLX_EXT_visual_rating
  983.     if (glXVisRating) {
  984.       if (gl->visualCaveats == GLX_NONE_EXT)
  985.         printf("visualCaveats=NONE, ");
  986.       else if (gl->visualCaveats == GLX_SLOW_VISUAL_EXT)
  987.         printf("visualCaveats=SLOW_VISUAL, ");
  988.       else
  989.         printf("\nERROR: Unrecognized token for GLX_VISUAL_CAVEATS attribute\n");
  990.     } 
  991.     else
  992.         printf("EXT_visual_rating not supported, ");
  993. #else
  994.     printf("EXT_visual_rating not supported, ");
  995. #endif
  996.  
  997. #ifdef GLX_EXT_visual_info
  998.     if (glXVisInfo) {
  999.       if (glXVisRating) printf(", ");
  1000.       if (gl->transparentPixel == GLX_NONE_EXT) {
  1001.         printf("transparentPixel=NONE");
  1002.       }
  1003.       else if (gl->transparentPixel == GLX_TRANSPARENT_RGB_EXT) {
  1004.         printf("transparentPixel=PIXEL, ");
  1005.         printf("color value=(%d,%d,%d,%d)", gl->transparentRedValue,
  1006.                gl->transparentGreenValue, gl->transparentBlueValue, 
  1007.                gl->transparentAlphaValue);
  1008.       }
  1009.       else if (gl->transparentPixel == GLX_TRANSPARENT_INDEX_EXT) {
  1010.         printf("transparentPixel=PIXEL, ");
  1011.         printf("index value=%d", gl->transparentIndex);
  1012.       }
  1013.       else
  1014.         printf("\nERROR: Unrecognized token for GLX_TRANSPARENT_PIXEL attribute\n");
  1015.     }
  1016.     else
  1017.         printf("EXT_visual_info not supported ");
  1018. #else
  1019.     printf("EXT_visual_info not supported ");
  1020. #endif
  1021.     printf("\n");
  1022.  
  1023.   }
  1024.   else {
  1025.     printf("%*s", indent, "");
  1026.     printf("GL NOT SUPPORTED\n");
  1027.   }
  1028.  
  1029.   printf("%*sCore X: ", indent, "");
  1030.   printf ("depth=%d, ", visual->depth);
  1031.   printf ("colormapSize=%d ", visual->colormap_size);
  1032.   printf ("RGB: masks=(0x%lx,0x%lx,0x%lx) ",
  1033.       visual->red_mask, visual->green_mask, visual->blue_mask);
  1034.   printf ("bits=%d",
  1035.       visual->bits_per_rgb);
  1036.   printf("\n");
  1037. }
  1038.  
  1039. int
  1040. PrintVisualIDs (
  1041.     Display    *dpy,
  1042.     XVisualInfo *visual
  1043. )
  1044. {
  1045.   GLXVisualInfo glVisualInfo;
  1046.   GLXVisualInfo *gl = &glVisualInfo;
  1047.  
  1048.   if (!GetGLVisualInfo(dpy, visual, gl)) return(0);
  1049.   switch(printVids) {
  1050.   case VID_NONE:
  1051.     return(0);
  1052.   case VID_RGB:
  1053.     if (!gl->rgba || gl->alphaSize != 0) return(0);
  1054.     break;
  1055.   case VID_RGBA:
  1056.     if (!gl->rgba || gl->alphaSize == 0) return(0);
  1057.     break;
  1058.   case VID_CI:
  1059.     if (gl->rgba) return(0);
  1060.     break;
  1061.   case VID_ALL:
  1062.     break;
  1063.   default:
  1064.     return(0);
  1065.   }
  1066.   
  1067.   printf ("%d\n", visual->visualid);
  1068. }
  1069.  
  1070. static void PrintIndentedStringWithBlanks(
  1071.     const char    * head,
  1072.     const char    * string,
  1073.     int            fieldNameLen,
  1074.     int        indent
  1075. )
  1076. {
  1077.     int            indentPos;
  1078.     const char        *cp;
  1079.     const char        *ncp;
  1080.     int            leftOnLine;
  1081.     
  1082.     if (fieldNameLen < 0) indentPos = -fieldNameLen;
  1083.     else indentPos = fieldNameLen;
  1084.     leftOnLine = pageWidth - indentPos - strlen (head);
  1085.  
  1086.     printf ("%*s%s", fieldNameLen, "", head);    /* first line */
  1087.     
  1088.     indentPos += indent;
  1089.  
  1090.     cp = string;
  1091.     
  1092.     if (cp == NULL)
  1093.     {
  1094.     printf ("(no string)\n");
  1095.     return;
  1096.     }
  1097.     if (*cp == 0)
  1098.     {
  1099.     printf ("(none)\n");
  1100.     return;
  1101.     }
  1102.  
  1103.     while (1)
  1104.     {
  1105.     if (strlen(cp) <= leftOnLine)
  1106.     {
  1107.         printf ("%s\n", cp);
  1108.         return;        /* all done */
  1109.     }
  1110.  
  1111.     /* we must find a space at which to break the line */
  1112.     ncp = cp + leftOnLine;    /* last possible char */
  1113.     while (ncp > cp && *ncp != ' ') ncp--;
  1114.     if (ncp == cp)
  1115.     {
  1116.         /* very long extension name; print it on one line */
  1117.         ncp = cp + leftOnLine;
  1118.         while (*ncp != 0 && *ncp != ' ') ncp++;
  1119.     }
  1120.  
  1121.     /* print from cp to ncp */
  1122.     printf ("%.*s\n", ncp - cp, cp);
  1123.     cp = ncp;
  1124.  
  1125.     /* skip to next non-blank */
  1126.     while (*cp == ' ') cp++;
  1127.  
  1128.     if (*cp == 0) return; /* all done */
  1129.  
  1130.     printf ("%*s", indentPos, "");
  1131.     leftOnLine = pageWidth - indentPos;
  1132.     }
  1133.  
  1134. }
  1135. void
  1136. PrintScreenInfo(
  1137.   Display    *dpy,
  1138.   int         scr,
  1139.   int         fieldNameLen,
  1140.   int          indent
  1141. )
  1142. {
  1143.   Screen     *s = ScreenOfDisplay(dpy, scr);    /* opaque structure */
  1144.   int         i;        /* temp variable: iterator */
  1145.   static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED";
  1146.   double      xres, yres;
  1147.   int         ndepths = 0, *depths = NULL;
  1148.   char        title[256];
  1149.   int         titleLen, fillLen;
  1150.   XVisualInfo    * vi;
  1151.   GLXContext    ctx;
  1152.   int        attrib_list[] = {0};
  1153.   Window    w;
  1154.   XSetWindowAttributes    wattribs;
  1155.   char          *cp;
  1156.   const char          *ccp;
  1157.  
  1158.   sprintf(title, " Screen %d ", scr);
  1159.   titleLen = strlen(title);
  1160.   fillLen = (pageWidth - titleLen) / 2;
  1161.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  1162.   printf("%s", title);
  1163.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  1164.   printf("\n");  
  1165.  
  1166.   /*
  1167.    * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
  1168.    * 
  1169.    * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) = N pixels /
  1170.    * (M inch / 25.4) = N * 25.4 pixels / M inch
  1171.    */
  1172.  
  1173.   xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
  1174.       ((double) DisplayWidthMM(dpy, scr)));
  1175.   yres = ((((double) DisplayHeight(dpy, scr)) * 25.4) /
  1176.       ((double) DisplayHeightMM(dpy, scr)));
  1177.  
  1178.   printf("%*s%d\n",
  1179.      fieldNameLen, "screen:",
  1180.      scr);
  1181.   printf("%*s%dx%d pixels (%dx%d millimeters)\n",
  1182.          fieldNameLen, "dimensions:",
  1183.      DisplayWidth(dpy, scr), DisplayHeight(dpy, scr),
  1184.      DisplayWidthMM(dpy, scr), DisplayHeightMM(dpy, scr));
  1185.  
  1186.   printf("%*s%dx%d dots per inch\n",
  1187.      fieldNameLen, "resolution:",
  1188.      (int) (xres + 0.5), (int) (yres + 0.5));
  1189.   depths = XListDepths(dpy, scr, &ndepths);
  1190.   if (!depths)
  1191.     ndepths = 0;
  1192.   printf("%*s(%d total):       ",
  1193.      fieldNameLen, "depths:", ndepths);
  1194.   for (i = 0; i < ndepths; i++) {
  1195.     printf("%d", depths[i]);
  1196.     if (i < ndepths - 1) {
  1197.       putchar(',');
  1198.       putchar(' ');
  1199.     }
  1200.   }
  1201.   putchar('\n');
  1202.   if (depths)
  1203.     XFree((char *) depths);
  1204.   printf("%*s0x%lx\n",
  1205.      fieldNameLen, "root window id:", RootWindow(dpy, scr));
  1206.   printf("%*s%d plane%s\n",
  1207.      fieldNameLen, "depth of root window:",
  1208.      DisplayPlanes(dpy, scr),
  1209.      DisplayPlanes(dpy, scr) == 1 ? "" : "s");
  1210.   printf("%*s0x%lx\n",
  1211.      fieldNameLen, "default visual id:",
  1212.      XVisualIDFromVisual (DefaultVisual (dpy, scr)));
  1213.   printf("%*sminimum %d, maximum %d\n",
  1214.      fieldNameLen, "number colormaps:",
  1215.      MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
  1216.   printf("%*s0x%lx, number colormap cells %d\n",
  1217.      fieldNameLen, "default colormap:",
  1218.      DefaultColormap(dpy, scr), DisplayCells(dpy, scr));
  1219.   printf("%*sblack 0x%lx, white 0x%lx\n",
  1220.      fieldNameLen, "preallocated pixels:",  
  1221.      BlackPixel(dpy, scr), WhitePixel(dpy, scr));
  1222.   printf("%*sbacking-store %s, save-unders %s\n",
  1223.      fieldNameLen, "options:",
  1224.      (DoesBackingStore(s) == NotUseful) ? no :
  1225.      ((DoesBackingStore(s) == Always) ? yes : when),
  1226.      DoesSaveUnders(s) ? yes : no);
  1227.   printf("%*s0x%lx\n",
  1228.      fieldNameLen, "input event mask:", EventMaskOfScreen(s));
  1229.   PrintEventMask(fieldNameLen > 0 ? fieldNameLen : -fieldNameLen,
  1230.          EventMaskOfScreen(s));
  1231.  
  1232.     if (dpyHasGL)
  1233.     {
  1234.     vi = glXChooseVisual (dpy, scr, attrib_list);
  1235.     if (vi == NULL)
  1236.     {
  1237.         printf ("Error: could not find visual for OpenGL\n");
  1238.         return;        
  1239.     }
  1240.     ctx = glXCreateContext (dpy, vi, NULL, False);
  1241.     wattribs.colormap = XCreateColormap (dpy, 
  1242.         RootWindow(dpy, scr), vi->visual, AllocNone);
  1243.  
  1244. #if defined(GLX_VERSION_1_1)
  1245.         ccp = glXQueryServerString (dpy, scr, GLX_VENDOR);
  1246.         if (ccp == NULL) ccp = "NOT AVAILABLE";
  1247.         printf ("%*sVendor = %s\n", fieldNameLen, "GLX Server:", ccp);
  1248.         ccp = glXQueryServerString (dpy, scr, GLX_VERSION);
  1249.         if (ccp == NULL) ccp = "NOT AVAILABLE";
  1250.         printf ("%*sVersion = %s\n", fieldNameLen, "", ccp);
  1251.         ccp = glXQueryServerString (dpy, scr, GLX_EXTENSIONS);
  1252.         if (ccp == NULL) ccp = "NOT AVAILABLE";
  1253.         PrintIndentedStringWithBlanks ("Extensions = ", ccp, fieldNameLen,
  1254.                                        indent);
  1255.         ccp = glXQueryExtensionsString (dpy, scr);
  1256.         PrintIndentedStringWithBlanks ("Useable Extensions = ", ccp, fieldNameLen,
  1257.                                        indent);
  1258. #endif
  1259.  
  1260.     w = XCreateWindow (dpy, RootWindow(dpy, scr),
  1261.         0, 0, 1, 1, 0, vi->depth,
  1262.         InputOutput, vi->visual, 
  1263.         CWBackPixel | CWBorderPixel | CWColormap, 
  1264.         &wattribs);
  1265.     glXMakeCurrent (dpy, w, ctx);
  1266.     cp = (char *) glGetString (GL_VENDOR);
  1267.     printf ("%*sVendor = %s\n", fieldNameLen, "GL Extension:", cp);
  1268.     cp = (char *) glGetString (GL_RENDERER);
  1269.     printf ("%*sRenderer = %s\n", fieldNameLen, "", cp);
  1270.     cp = (char *) glGetString (GL_VERSION);
  1271.     printf ("%*sVersion = %s\n", fieldNameLen, "", cp);
  1272.     cp = (char *) glGetString (GL_EXTENSIONS);
  1273.     PrintIndentedStringWithBlanks ("Extensions = ", cp, fieldNameLen,
  1274.         indent);
  1275.     }
  1276.  
  1277.   return;
  1278. }
  1279.  
  1280. void
  1281. PrintScreenVisualInfo(
  1282.   Display    *dpy,
  1283.   int         scr,
  1284.   int         fieldNameLen,
  1285.   int          indent
  1286. )
  1287. {
  1288.   XVisualInfo visualTemplate;        /* fill in for getting info */
  1289.   XVisualInfo *visuals;        /* retured info */
  1290.   int         nVisuals;        /* number of elements returned */
  1291.   int         i;
  1292.   char        title[256];
  1293.   int         titleLen, fillLen;
  1294.  
  1295.   nVisuals = 0;
  1296.   visualTemplate.screen = scr;
  1297.   visuals = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate, &nVisuals);
  1298.  
  1299.   if (printVids == VID_NONE) {
  1300.     sprintf(title, " %d Visuals for Screen %d (default = 0x%lx) ",
  1301.             nVisuals, scr, XVisualIDFromVisual(DefaultVisual(dpy, scr)));
  1302.     titleLen = strlen(title);
  1303.     fillLen = (pageWidth - titleLen) / 2;
  1304.     for (i = 0; i < fillLen; i++) printf("%c", '=');
  1305.     printf("%s", title);
  1306.     for (i = 0; i < fillLen; i++) printf("%c", '=');
  1307.     printf("\n");  
  1308.   }
  1309.  
  1310.   for (i = 0; i < nVisuals; i++) {
  1311.     if (printVids != VID_NONE) {
  1312.       PrintVisualIDs (dpy, &visuals[i]);
  1313.     }
  1314.     else {
  1315.       if (printCookedVisualInfo)
  1316.         PrintCookedVisualInfo (dpy, &visuals[i], indent);
  1317.       else
  1318.         PrintRawVisualInfo (dpy, &visuals[i], indent);
  1319.       printf("\n");
  1320.     }
  1321.   }
  1322.   
  1323.   if (visuals)
  1324.     XFree((char *) visuals);
  1325.  
  1326. }
  1327.  
  1328. int
  1329. ProcessScreen(
  1330.   Display *dpy,
  1331.   int screenNum,
  1332.   int fieldNameLen,
  1333.   int indent
  1334. )
  1335. {
  1336.   if (screenNum >= ScreenCount(dpy)) {
  1337.     fprintf(stderr, "%s: screen %d does not exist on display \"%s\".\nscreen count = %d\n",
  1338.         ProgramName, screenNum, XDisplayName(displayname),
  1339.             ScreenCount(dpy));
  1340.     exit(1);
  1341.   }
  1342.   
  1343.   if (printScreenInfo)
  1344.     PrintScreenInfo(dpy, screenNum, fieldNameLen, indent);
  1345.   if (printVisualInfo)
  1346.     PrintScreenVisualInfo(dpy, screenNum, fieldNameLen, indent);
  1347. }
  1348.  
  1349. /*****************************************************************************/
  1350. /****************************  Exported Functions  ***************************/
  1351. /*****************************************************************************/
  1352.  
  1353. int
  1354. main(
  1355.       int argc,
  1356.       char *argv[]
  1357. )
  1358. {
  1359.   Display    *dpy;        /* X connection */
  1360.   int         screenNum;
  1361.   int         fieldNameLen = -24;
  1362.   int         indent = 2;
  1363.  
  1364.   ProcessArgs(argc, argv);
  1365.  
  1366.   dpy = XOpenDisplay(displayname);
  1367.   if (!dpy) {
  1368.     fprintf(stderr, "%s:  unable to open display \"%s\".\n",
  1369.         ProgramName, XDisplayName(displayname));
  1370.     exit(1);
  1371.   }
  1372.  
  1373.   dpyHasGL = glXQueryExtension(dpy, &glErrorBase, &glEventBase);
  1374.  
  1375.  
  1376.   if (printSpecficScreen) {
  1377.     if (screenNum >= ScreenCount(dpy)) {
  1378.       fprintf(stderr, "%s: screen %d does not exist on display \"%s\".\nscreen count = %d\n",
  1379.               ProgramName, screenNum, XDisplayName(displayname),
  1380.               ScreenCount(dpy));
  1381.       exit(1);
  1382.     }
  1383.   
  1384.     if (printDisplayInfo) PrintDisplayInfo(dpy, fieldNameLen);
  1385.     ProcessScreen(dpy, specficScreenNum, fieldNameLen, indent);
  1386.   }
  1387.   else {
  1388.     if (printDisplayInfo) PrintDisplayInfo(dpy, fieldNameLen);
  1389.     for (screenNum = 0; screenNum < ScreenCount(dpy); screenNum++) {
  1390.       ProcessScreen(dpy, screenNum, fieldNameLen, indent);
  1391.     }
  1392.   }
  1393.   
  1394.   return(XCloseDisplay(dpy));
  1395. }
  1396.