home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / utilities / xglinfo / xglinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  27.1 KB  |  964 lines

  1. /*
  2.  * 
  3.  *           Copyright (c) Digital Equipment Corporation, 1993
  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.  * $Log: xglinfo.c,v $
  27.  * Revision 1.1.2.3  1993/06/18  15:02:52  John_Dennis
  28.  *     change copyright token to free copyright token
  29.  *     [1993/06/18  14:59:33  John_Dennis]
  30.  *
  31.  * Revision 1.1.2.2  1993/06/16  20:33:39  John_Dennis
  32.  *     various lint clean ups, nicer formatting, etc.
  33.  *     [1993/06/16  20:13:42  John_Dennis]
  34.  * 
  35.  *     Initial Version by John Dennis
  36.  *     [1993/06/15  20:07:25  John_Dennis]
  37.  * 
  38.  * $EndLog$
  39.  */
  40. /*****************************************************************************/
  41. /******************************** Documentation ******************************/
  42. /*****************************************************************************/
  43.  
  44. /*
  45.  * See man page for full documentation.
  46.  *
  47.  * Written by John Dennis, Digital Equipment Corporation.
  48.  * jdennis@mlo.dec.com
  49.  *
  50.  * With thanks and credit to Jim Fulton who wrote the original version of
  51.  * xdpyinfo while at MIT which served as a starting point for this code.
  52.  */
  53.  
  54. /*****************************************************************************/
  55. /******************************* Include Files *******************************/
  56. /*****************************************************************************/
  57.  
  58. #include <stdio.h>
  59. #include <string.h>
  60. #include <stdlib.h>
  61. #include <X11/Xlib.h>
  62. #include <X11/Xutil.h>
  63. #include <GL/gl.h>
  64. #include <GL/glx.h>
  65. #include "global.h"
  66.  
  67. /*****************************************************************************/
  68. /****************************** Internal Defines *****************************/
  69. /*****************************************************************************/
  70.  
  71. #define GL_GET_CONFIG(_config, _pValue)                                      \
  72. {                                                                            \
  73.   switch (result = glXGetConfig(dpy, visual, _config, (_pValue))) {          \
  74.   case Success:                                                              \
  75.     break;                                                                   \
  76.   case GLX_NO_EXTENSION:                                                     \
  77.     printf("ERROR glXGetConfig %s return GLX_NO_EXTENSION, visuaID 0x%lx\n", \
  78.           "_config", visual->visualid);                                      \
  79.     break;                                                                   \
  80.   case GLX_BAD_SCREEN:                                                       \
  81.     printf("ERROR glXGetConfig %s return GLX_BAD_SCREEN, visuaID 0x%lx\n",   \
  82.           "_config", visual->visualid);                                      \
  83.     break;                                                                   \
  84.   case GLX_BAD_ATTRIBUTE:                                                    \
  85.     printf("ERROR glXGetConfig %s return GLX_BAD_ATTRIBUTE, visuaID 0x%lx\n",\
  86.           "_config", visual->visualid);                                      \
  87.     break;                                                                   \
  88.   case GLX_BAD_VISUAL:                                                       \
  89.     printf("ERROR glXGetConfig %s return GLX_BAD_VISUAL, visuaID 0x%lx\n",   \
  90.           "_config", visual->visualid);                                      \
  91.     break;                                                                   \
  92.   default:                                                                   \
  93.     printf("ERROR glXGetConfig %s return unknown error %d, visuaID 0x%lx\n", \
  94.           "_config", result, visual->visualid);                              \
  95.     break;                                                                   \
  96.   }                                                                          \
  97. }
  98.  
  99. /*****************************************************************************/
  100. /************************** Internal Type Definitions ************************/
  101. /*****************************************************************************/
  102.  
  103. typedef struct GLXVisualInfo {
  104.   int useGL;                   /* support GLX rendering */
  105.   int bufferSize;               /* depth of the color buffer */
  106.   int level;                   /* level in plane stacking */
  107.   int rgba;                   /* true if RGBA mode */
  108.   int doubleBuffer;               /* double buffering supported */
  109.   int stereo;                   /* stereo buffering supported */
  110.   int auxBuffers;               /* number of aux buffers */
  111.   int redSize;                   /* number of red component bits */
  112.   int greenSize;               /* number of green component bits */
  113.   int blueSize;                   /* number of blue component bits */
  114.   int alphaSize;               /* number of alpha component bits */
  115.   int depthSize;               /* number of depth bits */
  116.   int stencilSize;               /* number of stencil bits */
  117.   int accumRedSize;               /* number of red accum bits */
  118.   int accumGreenSize;               /* number of green accum bits */
  119.   int accumBlueSize;               /* number of blue accum bits */
  120.   int accumAlphaSize;               /* number of alpha accum bits */
  121. } GLXVisualInfo;
  122.  
  123. /*****************************************************************************/
  124. /**********************  External Function Declarations  *********************/
  125. /*****************************************************************************/
  126.  
  127. /*****************************************************************************/
  128. /**********************  Internal Function Declarations  *********************/
  129. /*****************************************************************************/
  130.  
  131. static void
  132. Usage(
  133.   void
  134. );
  135.  
  136. static void
  137. ProcessArgs(
  138.          int argc   ,
  139.          char       *argv[]
  140. );
  141.  
  142. void
  143. PrintEventMask (
  144.     int indent,                /* amount by which to indent */
  145.     unsigned long mask                /* event mask */
  146. );
  147.  
  148. void
  149. PrintExtensionInfo(
  150.   Display    *dpy,
  151.   int         fieldNameLen,
  152.   int          indent
  153. );
  154.  
  155. void
  156. PrintPixmapFormats(
  157.   Display    *dpy,
  158.   int         fieldNameLen,
  159.   int          indent
  160. );
  161.  
  162. void
  163. PrintWindowFocus(
  164.   Display    *dpy,
  165.   int         fieldNameLen
  166. );
  167.  
  168. void
  169. PrintDisplayInfo(
  170.   Display    *dpy,
  171.   int         fieldNameLen
  172. );
  173.  
  174. int
  175. GetGLVisualInfo (
  176.     Display    *dpy,
  177.     XVisualInfo *visual,
  178.     GLXVisualInfo *glVisual
  179. );
  180.  
  181. int
  182. PrintCookedVisualInfo (
  183.     Display    *dpy,
  184.     XVisualInfo *visual,
  185.     int indent
  186. );
  187.  
  188. int
  189. PrintRawVisualInfo (
  190.     Display    *dpy,
  191.     XVisualInfo *visual,
  192.     int indent
  193. );
  194.  
  195. void
  196. PrintScreenInfo(
  197.   Display    *dpy,
  198.   int         scr,
  199.   int         fieldNameLen,
  200.   int          indent
  201. );
  202.  
  203. void
  204. PrintScreenVisualInfo(
  205.   Display    *dpy,
  206.   int         scr,
  207.   int         fieldNameLen,
  208.   int          indent
  209. );
  210.  
  211. /*****************************************************************************/
  212. /*************************  External Global Variables  ***********************/
  213. /*****************************************************************************/
  214.  
  215. char       *ProgramName;
  216.  
  217. /*****************************************************************************/
  218. /*************************  Internal Global Variables  ***********************/
  219. /*****************************************************************************/
  220.  
  221. static char       *displayname = NULL;    /* server to contact */
  222. static int         printDisplayInfo = GL_TRUE;
  223. static int         printScreenInfo = GL_TRUE;
  224. static int         printVisualInfo = GL_TRUE;
  225. static int         printCookedVisualInfo = GL_TRUE;
  226. static int         printRawVisualInfo = GL_FALSE;
  227.  
  228. static int        pageWidth = 80;
  229. static GLint       glErrorBase, glEventBase;
  230. static GLint       glMajorVersion, glMinorVersion;
  231. static Bool        dpyHasGL = GL_FALSE;
  232.  
  233. /*****************************************************************************/
  234. /***************************  Internal Functions  ****************************/
  235. /*****************************************************************************/
  236.  
  237. static void
  238. Usage(
  239.   void
  240. )
  241. {
  242.   fprintf(stderr, "usage:  %s [-display displayname]\n\n",
  243.       ProgramName);
  244.   fprintf(stderr, "  the following options take a '+' or '-' switch\n");
  245.   fprintf(stderr, "  a '+' turns the option on, a '-' turns the option off\n\n");
  246.   fprintf(stderr, "  [+-printDisplayInfo] [+-printScreenInfo] [+-printVisualInfo]\n");
  247.   fprintf(stderr, "  [+-printCookedVisualInfo] [+-printRawVisualInfo]\n");
  248.   exit(1);
  249. }
  250.  
  251. static void
  252. ProcessArgs(
  253.          int argc   ,
  254.          char       *argv[]
  255. )
  256. {
  257.   int         i;
  258.     char       *arg;
  259.   char        switchChar;
  260.  
  261.   ProgramName = argv[0];
  262.  
  263.   for (i = 1; i < argc; i++) {
  264.     arg = argv[i];
  265.     switchChar = arg[0];
  266.  
  267.     if (switchChar == '-' || switchChar == '+') {
  268.       arg++;
  269.       if (strcmp(arg, "display") == 0) {
  270.     if (switchChar == '-') {
  271.       if (++i >= argc) goto missing;
  272.       displayname = argv[i];
  273.     }
  274.     else goto unknown;
  275.       }
  276.       else if (strcmp(arg, "printDisplayInfo") == 0) {
  277.     if (switchChar == '+')
  278.       printDisplayInfo = GL_TRUE;
  279.     else
  280.       printDisplayInfo = GL_FALSE;
  281.       }
  282.       else if (strcmp(arg, "printScreenInfo") == 0) {
  283.     if (switchChar == '+')
  284.       printScreenInfo = GL_TRUE;
  285.     else
  286.       printScreenInfo = GL_FALSE;
  287.       }
  288.       else if (strcmp(arg, "printVisualInfo") == 0) {
  289.     if (switchChar == '+')
  290.       printVisualInfo = GL_TRUE;
  291.     else
  292.       printVisualInfo = GL_FALSE;
  293.       }
  294.       else if (strcmp(arg, "printRawVisualInfo") == 0) {
  295.     if (switchChar == '+')
  296.       printRawVisualInfo = GL_TRUE;
  297.     else
  298.       printRawVisualInfo = GL_FALSE;
  299.       }
  300.       else if (strcmp(arg, "printCookedVisualInfo") == 0) {
  301.     if (switchChar == '+')
  302.       printCookedVisualInfo = GL_TRUE;
  303.     else
  304.       printCookedVisualInfo = GL_FALSE;
  305.       }
  306.       else goto unknown;
  307.     }
  308.     else {
  309.       goto unknown;
  310.     }
  311.   }
  312.   return;
  313.  
  314.   unknown:
  315.       fprintf(stderr, "unknown arg: %s\n", argv[i]);
  316.       Usage();
  317.     
  318.   missing:
  319.       fprintf(stderr, "missing arg for: %s\n", argv[i]);
  320.       Usage();
  321. }
  322.  
  323. void
  324. PrintEventMask (
  325.     int indent,                /* amount by which to indent */
  326.     unsigned long mask                /* event mask */
  327. )
  328. {
  329.   char buf[1024];
  330.     int i, pad;
  331.     int nameWidth = 21;
  332.     unsigned long bit;
  333.     int len = indent;
  334.     int nameLen;
  335.     int bitsfound = 0;
  336.     char *name;
  337.  
  338.     for (i = 0; i < indent; i++) buf[i] = ' ';
  339.  
  340.     for (bit = 1; mask; bit <<= 1) {
  341.       if (bit & mask) {
  342.     mask ^= bit;               /* clear bit from mask */
  343.     name = EventMaskName((long)bit);
  344.     nameLen = strlen(name);
  345.     if (nameLen >= nameWidth) nameLen = nameWidth - 1; /* -1 for pad */
  346.     pad = nameWidth - nameLen;
  347.     if (len + nameLen > pageWidth) {
  348.       puts (buf);
  349.       len = indent;
  350.     }
  351.     strncpy(buf+len, name, nameLen);
  352.     len += nameLen;
  353.     if (len + pad > pageWidth) {
  354.       buf[len] = 0;
  355.       puts (buf);
  356.       len = indent;
  357.     }
  358.     else {
  359.       for (i = 0; i < pad; i++) buf[len++] = ' ';
  360.     }
  361.     buf[len] = 0;
  362.     bitsfound++;
  363.       }
  364.     }
  365.  
  366.     if (bitsfound) puts (buf);
  367. }
  368.  
  369. void
  370. PrintExtensionInfo(
  371.   Display    *dpy,
  372.   int         fieldNameLen,
  373.   int          indent
  374. )
  375. {
  376.   int         n = 0;
  377.   int         len, lineLen;
  378.   char      **extlist = XListExtensions(dpy, &n);
  379.  
  380.  
  381.   printf("%*s%d total\n",
  382.      fieldNameLen, "Server Extensions:",
  383.      n);
  384.   if (extlist) {
  385.     register int i;
  386.  
  387.     printf("%*s", indent, "");
  388.     lineLen = indent;
  389.     for (i = 0; i < n; i++) {
  390.       len = strlen(extlist[i]);
  391.       len += 2;                   /* for ", " */
  392.       if ((lineLen + len) >= pageWidth) {
  393.     printf("\n%*s", indent, "");
  394.     lineLen = indent;
  395.       }
  396.       printf("%s, ", extlist[i]);
  397.       lineLen += len;
  398.     }
  399.     if (lineLen > indent) printf("\n");
  400.     XFreeExtensionList(extlist);
  401.   }
  402. }
  403.  
  404. void
  405. PrintPixmapFormats(
  406.   Display    *dpy,
  407.   int         fieldNameLen,
  408.   int          indent
  409. )
  410. {
  411.   int i, n;
  412.   XPixmapFormatValues *pmf;
  413.  
  414.   pmf = XListPixmapFormats(dpy, &n);
  415.   printf("%*s%d total\n",
  416.      fieldNameLen, "pixmap formats:",
  417.      n);
  418.   if (pmf) {
  419.     for (i = 0; i < n; i++) {
  420.       printf("%*sdepth %2d, bits_per_pixel %2d, scanline_pad %2d\n",
  421.          indent, "",
  422.          pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad);
  423.     }
  424.     XFree((char *) pmf);
  425.   }
  426. }
  427.  
  428. void
  429. PrintWindowFocus(
  430.   Display    *dpy,
  431.   int         fieldNameLen
  432. )
  433. {
  434.   Window      focusWin;
  435.   int         focusRevert;
  436.  
  437.   XGetInputFocus(dpy, &focusWin, &focusRevert);
  438.   switch (focusWin) {
  439.   case PointerRoot:
  440.   case None:
  441.     printf("%*s%s\n",
  442.        fieldNameLen, "focus:",
  443.        WindowFocusName(focusWin));
  444.     break;
  445.   default:
  446.     printf("%*s0x%lx, revert to %s\n",
  447.        fieldNameLen, "focus window:",
  448.        focusWin, WindowFocusRevertName(focusRevert));
  449.     break;
  450.   }
  451. }
  452.  
  453. void
  454. PrintDisplayInfo(
  455.   Display    *dpy,
  456.   int         fieldNameLen
  457. )
  458. {
  459.   char       *cp;
  460.   int         minkeycode, maxkeycode;
  461.   char        title[256];
  462.   int         i;
  463.   int         titleLen, fillLen;
  464.  
  465.   sprintf(title, " Display %s ", DisplayString(dpy));
  466.   titleLen = strlen(title);
  467.   fillLen = (pageWidth - titleLen) / 2;
  468.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  469.   printf("%s", title);
  470.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  471.   printf("\n");  
  472.  
  473.   printf("%*s%s\n",
  474.      fieldNameLen, "name of display:",
  475.      DisplayString(dpy));
  476.   printf("%*s%d.%d\n",
  477.      fieldNameLen, "version number:",
  478.      ProtocolVersion(dpy), ProtocolRevision(dpy));
  479.   printf("%*s%s\n",
  480.      fieldNameLen, "vendor string:",
  481.      ServerVendor(dpy));
  482.   printf("%*s%d\n",
  483.      fieldNameLen, "vendor release:",
  484.      VendorRelease(dpy));
  485.   printf("%*s%ld bytes\n",
  486.      fieldNameLen, "max request size:",
  487.      XMaxRequestSize(dpy) * 4);
  488.   printf("%*s%d\n",
  489.      fieldNameLen, "motion buffer size:",
  490.      XDisplayMotionBufferSize(dpy));
  491.  
  492.   cp = ByteOrderName(BitmapBitOrder(dpy));
  493.   printf("%*sunit = %d, bit order = %s, padding = %d\n",
  494.      fieldNameLen, "bitmap:",
  495.      BitmapUnit(dpy), cp, BitmapPad(dpy));
  496.  
  497.   cp = ByteOrderName(ImageByteOrder(dpy));
  498.   printf("%*s%s\n",
  499.      fieldNameLen, "image byte order:",
  500.      cp);
  501.  
  502.   XDisplayKeycodes(dpy, &minkeycode, &maxkeycode);
  503.   printf("%*sminimum %d, maximum %d\n",
  504.      fieldNameLen, "keycode range:",
  505.      minkeycode, maxkeycode);
  506.  
  507.   PrintWindowFocus(dpy, fieldNameLen);
  508.  
  509.   printf("%*s%d\n",
  510.      fieldNameLen, "default screen num:",
  511.      DefaultScreen(dpy));
  512.   printf("%*s%d\n",
  513.      fieldNameLen, "number of screens:",
  514.      ScreenCount(dpy));
  515.  
  516.  
  517.   PrintPixmapFormats(dpy, fieldNameLen,
  518.              fieldNameLen > 0 ? fieldNameLen : -fieldNameLen);
  519.   PrintExtensionInfo(dpy, fieldNameLen,
  520.              fieldNameLen > 0 ? fieldNameLen : -fieldNameLen);
  521.  
  522.   printf("%*s",
  523.      fieldNameLen, "GLX Extension:");
  524.   if (dpyHasGL) {
  525.     printf("error base = %d, event base = %d, ",
  526.        glErrorBase, glEventBase);
  527.     if (glXQueryVersion(dpy, &glMajorVersion, &glMinorVersion)) {
  528.       printf("Version %d.%d\n",
  529.          glMajorVersion, glMinorVersion);
  530.     }
  531.     else {
  532.       printf("glXQueryVersion returned error\n");
  533.       exit(1);
  534.     }
  535.   }
  536.   else {
  537.     printf("NONE\n");
  538.   }
  539. }
  540.  
  541. int
  542. GetGLVisualInfo (
  543.     Display    *dpy,
  544.     XVisualInfo *visual,
  545.     GLXVisualInfo *glVisual
  546. )
  547. {
  548.   int result;
  549.  
  550.   if (!dpyHasGL) {
  551.     glVisual->useGL = GL_FALSE;
  552.     return(0);
  553.   }
  554.  
  555.   GL_GET_CONFIG(GLX_USE_GL, &glVisual->useGL);
  556.  
  557.   if (!glVisual->useGL) return(0);
  558.  
  559.   GL_GET_CONFIG(GLX_BUFFER_SIZE, &glVisual->bufferSize);
  560.   GL_GET_CONFIG(GLX_LEVEL, &glVisual->level);
  561.   GL_GET_CONFIG(GLX_RGBA, &glVisual->rgba);
  562.   GL_GET_CONFIG(GLX_DOUBLEBUFFER, &glVisual->doubleBuffer);
  563.   GL_GET_CONFIG(GLX_STEREO, &glVisual->stereo);
  564.   GL_GET_CONFIG(GLX_AUX_BUFFERS, &glVisual->auxBuffers);
  565.   GL_GET_CONFIG(GLX_RED_SIZE, &glVisual->redSize);
  566.   GL_GET_CONFIG(GLX_GREEN_SIZE, &glVisual->greenSize);
  567.   GL_GET_CONFIG(GLX_BLUE_SIZE, &glVisual->blueSize);
  568.   GL_GET_CONFIG(GLX_ALPHA_SIZE, &glVisual->alphaSize);
  569.   GL_GET_CONFIG(GLX_DEPTH_SIZE, &glVisual->depthSize);
  570.   GL_GET_CONFIG(GLX_STENCIL_SIZE, &glVisual->stencilSize);
  571.   GL_GET_CONFIG(GLX_ACCUM_RED_SIZE, &glVisual->accumRedSize);
  572.   GL_GET_CONFIG(GLX_ACCUM_GREEN_SIZE, &glVisual->accumGreenSize);
  573.   GL_GET_CONFIG(GLX_ACCUM_BLUE_SIZE, &glVisual->accumBlueSize);
  574.   GL_GET_CONFIG(GLX_ACCUM_ALPHA_SIZE, &glVisual->accumAlphaSize);
  575.  
  576.   return(1);
  577. }
  578.  
  579. int
  580. PrintCookedVisualInfo (
  581.     Display    *dpy,
  582.     XVisualInfo *visual,
  583.     int indent
  584. )
  585. {
  586.   int result;
  587.   int hasRGB, hasAlpha, hasDepth, hasStencil, hasAccum, hasAuxBuffers;
  588.   GLXVisualInfo glVisualInfo;
  589.   GLXVisualInfo *gl = &glVisualInfo;
  590.   int listEmpty;
  591.  
  592.   printf ("%s visual: ID = 0x%lx (hex) %d (decimal) screen = %d\n",
  593.       VisualClassName(visual->class) , visual->visualid, visual->visualid,
  594.       visual->screen);
  595.  
  596.   if (result = GetGLVisualInfo(dpy, visual, gl)) {
  597.  
  598.     hasRGB = ((gl->redSize != 0)   ||
  599.           (gl->greenSize != 0) ||
  600.           (gl->blueSize != 0));
  601.     hasAlpha = (gl->alphaSize != 0);
  602.     hasDepth = (gl->depthSize != 0);
  603.     hasStencil = (gl->stencilSize != 0);
  604.     hasAccum = ((gl->accumRedSize != 0)   ||
  605.         (gl->accumGreenSize != 0) ||
  606.         (gl->accumBlueSize != 0)  ||
  607.         (gl->accumAlphaSize != 0));
  608.     hasAuxBuffers = (gl->auxBuffers != 0);
  609.  
  610.  
  611.     printf("%*s", indent, "");
  612.     if (gl->level < 0) {
  613.       printf("UNDERLAY(%d) ", -gl->level);
  614.     }
  615.     if (gl->level > 0) {
  616.       printf("OVERLAY(%d) ", gl->level);
  617.     }
  618.     if (gl->doubleBuffer)
  619.       printf("DOUBLE buffered ");
  620.     else
  621.       printf("SINGLE buffered ");
  622.  
  623.     if (gl->stereo)
  624.       printf("STEREO ");
  625.     else
  626.       printf("MONO ");
  627.  
  628.     /*
  629.      * RGBA visual
  630.      */
  631.     if (gl->rgba) {               /* rgba visual */
  632.       printf("RGB visual ");
  633.  
  634.       listEmpty = GL_TRUE;
  635.       if (hasAlpha || hasDepth || hasStencil || hasAccum || hasAuxBuffers) {
  636.     printf("with (");
  637.     if (hasAlpha) {
  638.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  639.       printf("Alpha");
  640.     }
  641.     if (hasDepth) {
  642.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  643.       printf("Z");
  644.     }
  645.     if (hasStencil) {
  646.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  647.       printf("Stencil");
  648.     }
  649.     if (hasAccum) {
  650.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  651.       printf("Accum");
  652.     }
  653.     if (hasAuxBuffers) {
  654.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  655.       printf("%d Aux Buffers");
  656.     }
  657.     printf(")\n");
  658.       }
  659.  
  660.       printf("%*s", indent, "");
  661.       printf("GL Sizes: RGBA=(%d,%d,%d,%d), ",
  662.          gl->redSize, gl->greenSize, gl->blueSize, gl->alphaSize);
  663.       if (hasDepth)
  664.     printf("Z=%d, ", gl->depthSize);
  665.       if (hasStencil)
  666.     printf("Stencil=%d, ", gl->stencilSize);
  667.       if (hasAccum)
  668.     printf("Accum=(%d,%d,%d,%d)",
  669.            gl->accumRedSize, gl->accumGreenSize, gl->accumBlueSize,
  670.            gl->accumAlphaSize);
  671.       printf("\n");
  672.  
  673.       /*
  674.        * Do some simple sanity checks on rgba visual.
  675.        */
  676.       if (!hasRGB)
  677.     printf("%*sERROR: RGBA visual, but RGB have zero size\n",
  678.            indent, "");
  679.       if (hasAlpha && hasAccum && gl->accumAlphaSize == 0)
  680.     printf("%*sERROR: RGBA visual with Alpha and Accum, but Accum Alpha size is zero\n",
  681.            indent, "");
  682.     }                       /* end rgba visual */
  683.     /*
  684.      * COLOR INDEX visual
  685.      */
  686.     else {                   /* color index visual */
  687.       printf("COLOR INDEX visual ");
  688.  
  689.       listEmpty = GL_TRUE;
  690.       if (hasDepth || hasStencil || hasAuxBuffers) {
  691.     printf("with (");
  692.     if (hasDepth) {
  693.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  694.       printf("Z");
  695.     }
  696.     if (hasStencil) {
  697.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  698.       printf("Stencil");
  699.     }
  700.     if (hasAuxBuffers) {
  701.       if (listEmpty) listEmpty = GL_FALSE; else printf(" ");
  702.       printf("%d Aux Buffers");
  703.     }
  704.     printf(")\n");
  705.       }
  706.  
  707.       printf("%*s", indent, "");
  708.       printf("GL Sizes: ColorIndex=%d, ", gl->bufferSize);
  709.       if (hasDepth)
  710.     printf("Z=%d, ", gl->depthSize);
  711.       if (hasStencil)
  712.     printf("Stencil=%d", gl->stencilSize);
  713.       printf("\n");
  714.  
  715.       /*
  716.        * Do some simple sanity checks on color index visual.
  717.        */
  718.       if (hasRGB)
  719.     printf("%*sERROR: CI visual, but RGB has non-zero sizes (%d,%d,%d)\n",
  720.            indent, "", gl->redSize, gl->greenSize, gl->blueSize);
  721.       if (hasAlpha)
  722.     printf("%*sERROR: CI visual, but Alpha has non-zero size = %d\n",
  723.            indent, "", gl->alphaSize);
  724.       if (hasAccum)
  725.     printf("%*sERROR: CI visual, but Accum has non-zero sizes (%d,%d,%d,%d)\n",
  726.            indent, "", gl->accumRedSize, gl->accumGreenSize,
  727.            gl->accumBlueSize, gl->accumAlphaSize);
  728.     }                       /* end color index visual */
  729.   }
  730.   else {
  731.     printf("%*s", indent, "");
  732.     printf("GL NOT SUPPORTED\n");
  733.   }
  734.  
  735.   printf("%*sCore X: ", indent, "");
  736.   printf ("depth=%d, ", visual->depth);
  737.   printf ("colormapSize=%d ", visual->colormap_size);
  738.  
  739.   if ((visual->class == TrueColor) || (visual->class == DirectColor)) {
  740.     printf ("RGB: masks=(0x%lx,0x%lx,0x%lx) ",
  741.         visual->red_mask, visual->green_mask, visual->blue_mask);
  742.     printf ("bits=%d",
  743.         visual->bits_per_rgb);
  744.   }
  745.   printf("\n");
  746. }
  747.  
  748. int
  749. PrintRawVisualInfo (
  750.     Display    *dpy,
  751.     XVisualInfo *visual,
  752.     int indent
  753. )
  754. {
  755.   int result;
  756.   GLXVisualInfo glVisualInfo;
  757.   GLXVisualInfo *gl = &glVisualInfo;
  758.  
  759.   printf ("%s visual: ID = 0x%lx (hex) %d (decimal) screen = %d\n",
  760.       VisualClassName(visual->class) , visual->visualid, visual->visualid,
  761.       visual->screen);
  762.   
  763.   if (result = GetGLVisualInfo(dpy, visual, gl)) {
  764.  
  765.     printf("%*s", indent, "");
  766.     printf("useGL=%d, level=%d, doubleBuffer=%d, rgba=%d, stereo=%d\n",
  767.        gl->useGL, gl->level, gl->doubleBuffer, gl->rgba, gl->stereo);
  768.  
  769.     printf("%*s", indent, "");
  770.     printf("bufferSize=%d, number aux buffers=%d\n",
  771.        gl->bufferSize, gl->auxBuffers);
  772.  
  773.     printf("%*s", indent, "");
  774.     printf("sizes: RGBA=(%d,%d,%d,%d), Z=%d, STENCIL=%d, ACCUM=(%d,%d,%d,%d)\n",
  775.        gl->redSize, gl->greenSize, gl->blueSize, gl->alphaSize,
  776.        gl->depthSize, gl->stencilSize, 
  777.        gl->accumRedSize, gl->accumGreenSize,
  778.        gl->accumBlueSize, gl->accumAlphaSize);
  779.  
  780.   }
  781.   else {
  782.     printf("%*s", indent, "");
  783.     printf("GL NOT SUPPORTED\n");
  784.   }
  785.  
  786.   printf("%*sCore X: ", indent, "");
  787.   printf ("depth=%d, ", visual->depth);
  788.   printf ("colormapSize=%d ", visual->colormap_size);
  789.   printf ("RGB: masks=(0x%lx,0x%lx,0x%lx) ",
  790.       visual->red_mask, visual->green_mask, visual->blue_mask);
  791.   printf ("bits=%d",
  792.       visual->bits_per_rgb);
  793.   printf("\n");
  794. }
  795.  
  796. void
  797. PrintScreenInfo(
  798.   Display    *dpy,
  799.   int         scr,
  800.   int         fieldNameLen,
  801.   int          indent
  802. )
  803. {
  804.   Screen     *s = ScreenOfDisplay(dpy, scr);    /* opaque structure */
  805.   int         i;        /* temp variable: iterator */
  806.   static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED";
  807.   double      xres, yres;
  808.   int         ndepths = 0, *depths = NULL;
  809.   char        title[256];
  810.   int         titleLen, fillLen;
  811.  
  812.   sprintf(title, " Screen %d ", scr);
  813.   titleLen = strlen(title);
  814.   fillLen = (pageWidth - titleLen) / 2;
  815.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  816.   printf("%s", title);
  817.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  818.   printf("\n");  
  819.  
  820.   /*
  821.    * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
  822.    * 
  823.    * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) = N pixels /
  824.    * (M inch / 25.4) = N * 25.4 pixels / M inch
  825.    */
  826.  
  827.   xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
  828.       ((double) DisplayWidthMM(dpy, scr)));
  829.   yres = ((((double) DisplayHeight(dpy, scr)) * 25.4) /
  830.       ((double) DisplayHeightMM(dpy, scr)));
  831.  
  832.   printf("%*s%d\n",
  833.      fieldNameLen, "screen:",
  834.      scr);
  835.   printf("%*s%dx%d pixels (%dx%d millimeters)\n",
  836.          fieldNameLen, "dimensions:",
  837.      DisplayWidth(dpy, scr), DisplayHeight(dpy, scr),
  838.      DisplayWidthMM(dpy, scr), DisplayHeightMM(dpy, scr));
  839.  
  840.   printf("%*s%dx%d dots per inch\n",
  841.      fieldNameLen, "resolution:",
  842.      (int) (xres + 0.5), (int) (yres + 0.5));
  843.   depths = XListDepths(dpy, scr, &ndepths);
  844.   if (!depths)
  845.     ndepths = 0;
  846.   printf("%*s(%d total):       ",
  847.      fieldNameLen, "depths:", ndepths);
  848.   for (i = 0; i < ndepths; i++) {
  849.     printf("%d", depths[i]);
  850.     if (i < ndepths - 1) {
  851.       putchar(',');
  852.       putchar(' ');
  853.     }
  854.   }
  855.   putchar('\n');
  856.   if (depths)
  857.     XFree((char *) depths);
  858.   printf("%*s0x%lx\n",
  859.      fieldNameLen, "root window id:", RootWindow(dpy, scr));
  860.   printf("%*s%d plane%s\n",
  861.      fieldNameLen, "depth of root window:",
  862.      DisplayPlanes(dpy, scr),
  863.      DisplayPlanes(dpy, scr) == 1 ? "" : "s");
  864.   printf("%*sminimum %d, maximum %d\n",
  865.      fieldNameLen, "number colormaps:",
  866.      MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
  867.   printf("%*s0x%lx, number colormap cells %d\n",
  868.      fieldNameLen, "default colormap:",
  869.      DefaultColormap(dpy, scr), DisplayCells(dpy, scr));
  870.   printf("%*sblack 0x%lx, white 0x%lx\n",
  871.      fieldNameLen, "preallocated pixels:",  
  872.      BlackPixel(dpy, scr), WhitePixel(dpy, scr));
  873.   printf("%*sbacking-store %s, save-unders %s\n",
  874.      fieldNameLen, "options:",
  875.      (DoesBackingStore(s) == NotUseful) ? no :
  876.      ((DoesBackingStore(s) == Always) ? yes : when),
  877.      DoesSaveUnders(s) ? yes : no);
  878.   printf("%*s0x%lx\n",
  879.      fieldNameLen, "input event mask:", EventMaskOfScreen(s));
  880.   PrintEventMask(fieldNameLen > 0 ? fieldNameLen : -fieldNameLen,
  881.          EventMaskOfScreen(s));
  882.  
  883.  
  884.   return;
  885. }
  886.  
  887. void
  888. PrintScreenVisualInfo(
  889.   Display    *dpy,
  890.   int         scr,
  891.   int         fieldNameLen,
  892.   int          indent
  893. )
  894. {
  895.   XVisualInfo visualTemplate;        /* fill in for getting info */
  896.   XVisualInfo *visuals;        /* retured info */
  897.   int         nVisuals;        /* number of elements returned */
  898.   int         i;
  899.   char        title[256];
  900.   int         titleLen, fillLen;
  901.  
  902.   nVisuals = 0;
  903.   visualTemplate.screen = scr;
  904.   visuals = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate, &nVisuals);
  905.  
  906.   sprintf(title, " %d Visuals for Screen %d (default = 0x%lx) ",
  907.       nVisuals, scr, XVisualIDFromVisual(DefaultVisual(dpy, scr)));
  908.   titleLen = strlen(title);
  909.   fillLen = (pageWidth - titleLen) / 2;
  910.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  911.   printf("%s", title);
  912.   for (i = 0; i < fillLen; i++) printf("%c", '=');
  913.   printf("\n");  
  914.  
  915.   for (i = 0; i < nVisuals; i++) {
  916.     if (printCookedVisualInfo)
  917.       PrintCookedVisualInfo (dpy, &visuals[i], indent);
  918.     if (printRawVisualInfo)
  919.       PrintRawVisualInfo (dpy, &visuals[i], indent);
  920.     printf("\n");
  921.   }
  922.   if (visuals)
  923.     XFree((char *) visuals);
  924.  
  925. }
  926.  
  927. /*****************************************************************************/
  928. /****************************  Exported Functions  ***************************/
  929. /*****************************************************************************/
  930.  
  931. int
  932. main(
  933.       int argc,
  934.       char *argv[]
  935. )
  936. {
  937.   Display    *dpy;        /* X connection */
  938.   int         screenNum;
  939.   int         fieldNameLen = -24;
  940.   int         indent = 2;
  941.  
  942.   ProcessArgs(argc, argv);
  943.  
  944.   dpy = XOpenDisplay(displayname);
  945.   if (!dpy) {
  946.     fprintf(stderr, "%s:  unable to open display \"%s\".\n",
  947.         ProgramName, XDisplayName(displayname));
  948.     exit(1);
  949.   }
  950.  
  951.   dpyHasGL = glXQueryExtension(dpy, &glErrorBase, &glEventBase);
  952.  
  953.   if (printDisplayInfo) PrintDisplayInfo(dpy, fieldNameLen);
  954.  
  955.   for (screenNum = 0; screenNum < ScreenCount(dpy); screenNum++) {
  956.     if (printScreenInfo)
  957.       PrintScreenInfo(dpy, screenNum, fieldNameLen, indent);
  958.     if (printRawVisualInfo || printCookedVisualInfo)
  959.       PrintScreenVisualInfo(dpy, screenNum, fieldNameLen, indent);
  960.   }
  961.  
  962.   return(XCloseDisplay(dpy));
  963. }
  964.