home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xdpyinfo / xdpyinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-20  |  12.3 KB  |  420 lines

  1. /*
  2.  * $XConsortium: xdpyinfo.c,v 1.21 91/03/20 12:00:38 gildea Exp $
  3.  * 
  4.  * xdpyinfo - print information about X display connecton
  5.  *
  6.  * Copyright 1988 by the Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided 
  10.  * that the above copyright notice appear in all copies and that both that 
  11.  * copyright notice and this permission notice appear in supporting 
  12.  * documentation, and that the name of M.I.T. not be used in advertising
  13.  * or publicity pertaining to distribution of the software without specific, 
  14.  * written prior permission. M.I.T. makes no representations about the 
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * Author:  Jim Fulton, MIT X Consortium
  19.  */
  20.  
  21. #include <X11/Xlib.h>
  22. #include <X11/Xutil.h>
  23. #include <X11/extensions/multibuf.h>
  24. #include <X11/Xos.h>
  25. #include <stdio.h>
  26.  
  27. char *ProgramName;
  28.  
  29.  
  30. static void usage ()
  31. {
  32.     fprintf (stderr, "usage:  %s [-display displayname]\n",
  33.          ProgramName);
  34.     exit (1);
  35. }
  36.  
  37. main (argc, argv)
  38.     int argc;
  39.     char *argv[];
  40. {
  41.     Display *dpy;            /* X connection */
  42.     char *displayname = NULL;        /* server to contact */
  43.     int i;                /* temp variable:  iterator */
  44.     Bool multibuf = False;
  45.     int mbuf_event_base, mbuf_error_base;
  46.  
  47.     ProgramName = argv[0];
  48.  
  49.     for (i = 1; i < argc; i++) {
  50.     char *arg = argv[i];
  51.  
  52.     if (arg[0] == '-') {
  53.         switch (arg[1]) {
  54.           case 'd':
  55.         if (++i >= argc) usage ();
  56.         displayname = argv[i];
  57.         continue;
  58.           default:
  59.         usage ();
  60.         }
  61.     } else
  62.       usage ();
  63.     }
  64.  
  65.     dpy = XOpenDisplay (displayname);
  66.     if (!dpy) {
  67.     fprintf (stderr, "%s:  unable to open display \"%s\".\n",
  68.          ProgramName, XDisplayName (displayname));
  69.     exit (1);
  70.     }
  71.  
  72.     if (XmbufQueryExtension (dpy, &mbuf_event_base, &mbuf_error_base))
  73.       multibuf = True;
  74.  
  75.     print_display_info (dpy);
  76.     for (i = 0; i < ScreenCount (dpy); i++) {
  77.     print_screen_info (dpy, i);
  78.     if (multibuf)
  79.         print_multibuf_info (dpy, i);
  80.     }
  81.  
  82.     XCloseDisplay (dpy);
  83.     exit (0);
  84. }
  85.  
  86. print_display_info (dpy)
  87.     Display *dpy;
  88. {
  89.     char dummybuf[40];
  90.     char *cp;
  91.     int minkeycode, maxkeycode;
  92.     int i, n;
  93.     XPixmapFormatValues *pmf;
  94.     Window focuswin;
  95.     int focusrevert;
  96.  
  97.     printf ("name of display:    %s\n", DisplayString (dpy));
  98.     printf ("version number:    %d.%d\n",
  99.         ProtocolVersion (dpy), ProtocolRevision (dpy));
  100.     printf ("vendor string:    %s\n", ServerVendor (dpy));
  101.     printf ("vendor release number:    %d\n", VendorRelease (dpy));
  102.     printf ("maximum request size:  %ld bytes\n", XMaxRequestSize (dpy) * 4);
  103.     printf ("motion buffer size:  %d\n", XDisplayMotionBufferSize (dpy));
  104.  
  105.     switch (BitmapBitOrder (dpy)) {
  106.       case LSBFirst:    cp = "LSBFirst"; break;
  107.       case MSBFirst:    cp = "MSBFirst"; break;
  108.       default:    
  109.     sprintf (dummybuf, "unknown order %d", BitmapBitOrder (dpy));
  110.     cp = dummybuf;
  111.     break;
  112.     }
  113.     printf ("bitmap unit, bit order, padding:    %d, %s, %d\n",
  114.         BitmapUnit (dpy), cp, BitmapPad (dpy));
  115.  
  116.     switch (ImageByteOrder (dpy)) {
  117.       case LSBFirst:    cp = "LSBFirst"; break;
  118.       case MSBFirst:    cp = "MSBFirst"; break;
  119.       default:    
  120.     sprintf (dummybuf, "unknown order %d", ImageByteOrder (dpy));
  121.     cp = dummybuf;
  122.     break;
  123.     }
  124.     printf ("image byte order:    %s\n", cp);
  125.  
  126.     pmf = XListPixmapFormats (dpy, &n);
  127.     printf ("number of supported pixmap formats:    %d\n", n);
  128.     if (pmf) {
  129.     printf ("supported pixmap formats:\n");
  130.     for (i = 0; i < n; i++) {
  131.         printf ("    depth %d, bits_per_pixel %d, scanline_pad %d\n",
  132.             pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad);
  133.     }
  134.     XFree ((char *) pmf);
  135.     }
  136.  
  137.  
  138.     /*
  139.      * when we get interfaces to the PixmapFormat stuff, insert code here
  140.      */
  141.  
  142.     XDisplayKeycodes (dpy, &minkeycode, &maxkeycode);
  143.     printf ("keycode range:    minimum %d, maximum %d\n",
  144.         minkeycode, maxkeycode);
  145.  
  146.     XGetInputFocus (dpy, &focuswin, &focusrevert);
  147.     printf ("focus:  ");
  148.     switch (focuswin) {
  149.       case PointerRoot:
  150.     printf ("PointerRoot\n");
  151.     break;
  152.       case None:
  153.     printf ("None\n");
  154.     break;
  155.       default:
  156.     printf("window 0x%lx, revert to ", focuswin);
  157.     switch (focusrevert) {
  158.       case RevertToParent:
  159.         printf ("Parent\n");
  160.         break;
  161.       case RevertToNone:
  162.         printf ("None\n");
  163.         break;
  164.       case RevertToPointerRoot:
  165.         printf ("PointerRoot\n");
  166.         break;
  167.       default:            /* should not happen */
  168.         printf ("%d\n", focusrevert);
  169.         break;
  170.     }
  171.     break;
  172.     }
  173.  
  174.     print_extension_info (dpy);
  175.  
  176.     printf ("default screen number:    %d\n", DefaultScreen (dpy));
  177.     printf ("number of screens:    %d\n", ScreenCount (dpy));
  178.  
  179.     return;
  180. }
  181.  
  182. print_extension_info (dpy)
  183.     Display *dpy;
  184. {
  185.     int n = 0;
  186.     char **extlist = XListExtensions (dpy, &n);
  187.  
  188.     printf ("number of extensions:    %d\n", n);
  189.  
  190.     if (extlist) {
  191.     register int i;
  192.  
  193.     for (i = 0; i < n; i++) {
  194.         printf ("    %s\n", extlist[i]);
  195.     }
  196.     XFreeExtensionList (extlist);
  197.     }
  198.     return;
  199. }
  200.  
  201. print_screen_info (dpy, scr)
  202.     Display *dpy;
  203.     int scr;
  204. {
  205.     Screen *s = ScreenOfDisplay (dpy, scr);  /* opaque structure */
  206.     XVisualInfo viproto;        /* fill in for getting info */
  207.     XVisualInfo *vip;            /* retured info */
  208.     int nvi;                /* number of elements returned */
  209.     int i;                /* temp variable: iterator */
  210.     char eventbuf[80];            /* want 79 chars per line + nul */
  211.     static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED";
  212.     double xres, yres;
  213.     int ndepths = 0, *depths = NULL;
  214.  
  215.  
  216.     /*
  217.      * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
  218.      *
  219.      *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
  220.      *         = N pixels / (M inch / 25.4)
  221.      *         = N * 25.4 pixels / M inch
  222.      */
  223.  
  224.     xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) / 
  225.         ((double) DisplayWidthMM(dpy,scr)));
  226.     yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) / 
  227.         ((double) DisplayHeightMM(dpy,scr)));
  228.  
  229.     printf ("\n");
  230.     printf ("screen #%d:\n", scr);
  231.     printf ("  dimensions:    %dx%d pixels (%dx%d millimeters)\n",
  232.         DisplayWidth (dpy, scr), DisplayHeight (dpy, scr),
  233.         DisplayWidthMM(dpy, scr), DisplayHeightMM (dpy, scr));
  234.     printf ("  resolution:    %dx%d dots per inch\n", 
  235.         (int) (xres + 0.5), (int) (yres + 0.5));
  236.     depths = XListDepths (dpy, scr, &ndepths);
  237.     if (!depths) ndepths = 0;
  238.     printf ("  depths (%d):    ", ndepths);
  239.     for (i = 0; i < ndepths; i++) {
  240.     printf ("%d", depths[i]);
  241.     if (i < ndepths - 1) { 
  242.         putchar (',');
  243.         putchar (' ');
  244.     }
  245.     }
  246.     putchar ('\n');
  247.     if (depths) XFree ((char *) depths);
  248.     printf ("  root window id:    0x%lx\n", RootWindow (dpy, scr));
  249.     printf ("  depth of root window:    %d plane%s\n",
  250.         DisplayPlanes (dpy, scr),
  251.         DisplayPlanes (dpy, scr) == 1 ? "" : "s");
  252.     printf ("  number of colormaps:    minimum %d, maximum %d\n",
  253.         MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
  254.     printf ("  default colormap:    0x%lx\n", DefaultColormap (dpy, scr));
  255.     printf ("  default number of colormap cells:    %d\n",
  256.         DisplayCells (dpy, scr));
  257.     printf ("  preallocated pixels:    black %d, white %d\n",
  258.         BlackPixel (dpy, scr), WhitePixel (dpy, scr));
  259.     printf ("  options:    backing-store %s, save-unders %s\n",
  260.         (DoesBackingStore (s) == NotUseful) ? no :
  261.         ((DoesBackingStore (s) == Always) ? yes : when),
  262.         DoesSaveUnders (s) ? yes : no);
  263.     printf ("  current input event mask:    0x%lx\n", EventMaskOfScreen (s));
  264.     (void) print_event_mask (eventbuf, 79, 4, EventMaskOfScreen (s));
  265.               
  266.  
  267.     nvi = 0;
  268.     viproto.screen = scr;
  269.     vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
  270.     printf ("  number of visuals:    %d\n", nvi);
  271.     printf ("  default visual id:  0x%lx\n", 
  272.         XVisualIDFromVisual (DefaultVisual (dpy, scr)));
  273.     for (i = 0; i < nvi; i++) {
  274.     print_visual_info (vip+i);
  275.     }
  276.     if (vip) XFree ((char *) vip);
  277.  
  278.     return;
  279. }
  280.  
  281.  
  282. print_multibuf_info(dpy, scr)
  283.     Display *dpy;
  284.     int scr;
  285. {
  286.     int j;            /* temp variable: iterator */
  287.     int nmono, nstereo;        /* count */
  288.     XmbufBufferInfo *mono_info = NULL, *stereo_info = NULL; /* arrays */
  289.     static char *fmt = 
  290.     "    visual id, max buffers, depth:    0x%lx, %d, %d\n";
  291.  
  292.     if (!XmbufGetScreenInfo (dpy, RootWindow(dpy, scr), &nmono, &mono_info,
  293.                  &nstereo, &stereo_info)) {
  294.     fprintf (stderr,
  295.          "%s:  unable to get multibuffer info for screen %d\n",
  296.          ProgramName, scr);
  297.     } else {
  298.     printf ("  number of mono multibuffer types:    %d\n", nmono);
  299.     for (j = 0; j < nmono; j++) {
  300.         printf (fmt, mono_info[j].visualid, mono_info[j].max_buffers,
  301.             mono_info[j].depth);
  302.     }
  303.     printf ("  number of stereo multibuffer types:    %d\n", nstereo);
  304.     for (j = 0; j < nstereo; j++) {
  305.         printf (fmt, stereo_info[j].visualid,
  306.             stereo_info[j].max_buffers, stereo_info[j].depth);
  307.     }
  308.     if (mono_info) XFree ((char *) mono_info);
  309.     if (stereo_info) XFree ((char *) stereo_info);
  310.     }
  311. }
  312.  
  313.  
  314. print_visual_info (vip)
  315.     XVisualInfo *vip;
  316. {
  317.     char errorbuf[40];            /* for sprintfing into */
  318.     char *class = NULL;            /* for printing */
  319.  
  320.     switch (vip->class) {
  321.       case StaticGray:    class = "StaticGray"; break;
  322.       case GrayScale:    class = "GrayScale"; break;
  323.       case StaticColor:    class = "StaticColor"; break;
  324.       case PseudoColor:    class = "PseudoColor"; break;
  325.       case TrueColor:    class = "TrueColor"; break;
  326.       case DirectColor:    class = "DirectColor"; break;
  327.       default:    
  328.     sprintf (errorbuf, "unknown class %d", vip->class);
  329.     class = errorbuf;
  330.     break;
  331.     }
  332.  
  333.     printf ("  visual:\n");
  334.     printf ("    visual id:    0x%lx\n", vip->visualid);
  335.     printf ("    class:    %s\n", class);
  336.     printf ("    depth:    %d plane%s\n", vip->depth, 
  337.         vip->depth == 1 ? "" : "s");
  338.     printf ("    size of colormap:    %d entries\n", vip->colormap_size);
  339.     printf ("    red, green, blue masks:    0x%lx, 0x%lx, 0x%lx\n",
  340.         vip->red_mask, vip->green_mask, vip->blue_mask);
  341.     printf ("    significant bits in color specification:    %d bits\n",
  342.         vip->bits_per_rgb);
  343.  
  344.     return;
  345. }
  346.  
  347. /*
  348.  * The following routine prints out an event mask, wrapping events at nice
  349.  * boundaries.
  350.  */
  351.  
  352. #define MASK_NAME_WIDTH 25
  353.  
  354. static struct _event_table {
  355.     char *name;
  356.     long value;
  357. } event_table[] = {
  358.     { "KeyPressMask             ", KeyPressMask },
  359.     { "KeyReleaseMask           ", KeyReleaseMask },
  360.     { "ButtonPressMask          ", ButtonPressMask },
  361.     { "ButtonReleaseMask        ", ButtonReleaseMask },
  362.     { "EnterWindowMask          ", EnterWindowMask },
  363.     { "LeaveWindowMask          ", LeaveWindowMask },
  364.     { "PointerMotionMask        ", PointerMotionMask },
  365.     { "PointerMotionHintMask    ", PointerMotionHintMask },
  366.     { "Button1MotionMask        ", Button1MotionMask },
  367.     { "Button2MotionMask        ", Button2MotionMask },
  368.     { "Button3MotionMask        ", Button3MotionMask },
  369.     { "Button4MotionMask        ", Button4MotionMask },
  370.     { "Button5MotionMask        ", Button5MotionMask },
  371.     { "ButtonMotionMask         ", ButtonMotionMask },
  372.     { "KeymapStateMask          ", KeymapStateMask },
  373.     { "ExposureMask             ", ExposureMask },
  374.     { "VisibilityChangeMask     ", VisibilityChangeMask },
  375.     { "StructureNotifyMask      ", StructureNotifyMask },
  376.     { "ResizeRedirectMask       ", ResizeRedirectMask },
  377.     { "SubstructureNotifyMask   ", SubstructureNotifyMask },
  378.     { "SubstructureRedirectMask ", SubstructureRedirectMask },
  379.     { "FocusChangeMask          ", FocusChangeMask },
  380.     { "PropertyChangeMask       ", PropertyChangeMask },
  381.     { "ColormapChangeMask       ", ColormapChangeMask },
  382.     { "OwnerGrabButtonMask      ", OwnerGrabButtonMask },
  383.     { NULL, 0 }};
  384.  
  385. int print_event_mask (buf, lastcol, indent, mask)
  386.     char *buf;                /* string to write into */
  387.     int lastcol;            /* strlen(buf)+1 */
  388.     int indent;                /* amount by which to indent */
  389.     long mask;                /* event mask */
  390. {
  391.     struct _event_table *etp;
  392.     int len;
  393.     int bitsfound = 0;
  394.  
  395.     buf[0] = buf[lastcol] = '\0';    /* just in case */
  396.  
  397. #define INDENT() { register int i; len = indent; \
  398.            for (i = 0; i < indent; i++) buf[i] = ' '; }
  399.  
  400.     INDENT ();
  401.  
  402.     for (etp = event_table; etp->name; etp++) {
  403.     if (mask & etp->value) {
  404.         if (len + MASK_NAME_WIDTH > lastcol) {
  405.         puts (buf);
  406.         INDENT ();
  407.         }
  408.         strcpy (buf+len, etp->name);
  409.         len += MASK_NAME_WIDTH;
  410.         bitsfound++;
  411.     }
  412.     }
  413.  
  414.     if (bitsfound) puts (buf);
  415.  
  416. #undef INDENT
  417.  
  418.     return (bitsfound);
  419. }
  420.