home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xwininfo / xwininfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-11  |  26.6 KB  |  1,005 lines

  1. /* Copyright 1987, Massachusetts Institute of Technology */
  2.  
  3. /*
  4.  * xwininfo.c    - MIT Project Athena, X Window system window
  5.  *          information utility.
  6.  *
  7.  * $XConsortium: xwininfo.c,v 1.52 91/05/11 22:32:49 gildea Exp $
  8.  *
  9.  *    This program will report all relevant information
  10.  *    about a specific window.
  11.  *
  12.  *  Author:    Mark Lillibridge, MIT Project Athena
  13.  *        16-Jun-87
  14.  */
  15.  
  16. #include <X11/Xlib.h>
  17. #include <X11/Xutil.h>
  18. #include <X11/Xatom.h>
  19. #include <X11/Xos.h>
  20. #include <X11/extensions/shape.h>
  21. #include <X11/Xmu/WinUtil.h>
  22. #include <stdio.h>
  23.  
  24. /* Include routines to handle parsing defaults */
  25. #include "dsimple.h"
  26.  
  27. static char *window_id_format = "0x%lx";
  28.  
  29. /*
  30.  * Report the syntax for calling xwininfo:
  31.  */
  32. usage()
  33. {
  34.     fprintf (stderr,
  35.     "usage:  %s [-options ...]\n\n", program_name);
  36.     fprintf (stderr,
  37.     "where options include:\n");
  38.     fprintf (stderr,
  39.     "    -help                print this message\n");
  40.     fprintf (stderr,
  41.     "    -display host:dpy    X server to contact\n");
  42.     fprintf (stderr,
  43.     "    -root                use the root window\n");
  44.     fprintf (stderr,
  45.     "    -id windowid         use the window with the specified id\n");
  46.     fprintf (stderr,
  47.     "    -name windowname     use the window with the specified name\n");
  48.     fprintf (stderr,
  49.     "    -int                 print window id in decimal\n");
  50.     fprintf (stderr,
  51.     "    -children            print parent and child identifiers\n");
  52.     fprintf (stderr,
  53.     "    -tree                print children identifiers recursively\n");
  54.     fprintf (stderr,
  55.     "    -stats               print window geometry [DEFAULT]\n");
  56.     fprintf (stderr,
  57.     "    -bits                print window pixel information\n");
  58.     fprintf (stderr,
  59.     "    -events              print events selected for on window\n");
  60.     fprintf (stderr,
  61.     "    -size                print size hints\n");
  62.     fprintf (stderr,
  63.     "    -wm                  print window manager hints\n");
  64.     fprintf (stderr,
  65.     "    -shape               print shape extents\n");
  66.     fprintf (stderr,
  67.     "    -frame               don't ignore window manager frames\n");
  68.     fprintf (stderr,
  69.     "    -english             print sizes in english units\n");
  70.     fprintf (stderr,
  71.     "    -metric              print sizes in metric units\n");
  72.     fprintf (stderr,
  73.     "    -all                 -tree, -stats, -bits, -events, -wm, -size, -shape\n");
  74.     fprintf (stderr,
  75.     "\n");
  76.     exit (1);
  77. }
  78.  
  79. /*
  80.  * pixel to inch, metric converter.
  81.  * Hacked in by Mark W. Eichin <eichin@athena> [eichin:19880619.1509EST]
  82.  *
  83.  * Simply put: replace the old numbers with string print calls.
  84.  * Returning a local string is ok, since we only ever get called to
  85.  * print one x and one y, so as long as they don't collide, they're
  86.  * fine. This is not meant to be a general purpose routine.
  87.  *
  88.  */
  89.  
  90. #define getdsp(var,fn) var = fn(dpy, DefaultScreen(dpy))
  91. int xp=0, xmm=0;
  92. int yp=0, ymm=0;
  93. int bp=0, bmm=0;
  94. int english = 0, metric = 0;
  95.  
  96. void scale_init()
  97. {
  98.   getdsp(yp,  DisplayHeight);
  99.   getdsp(ymm, DisplayHeightMM);
  100.   getdsp(xp,  DisplayWidth);
  101.   getdsp(xmm, DisplayWidthMM);
  102.   bp  = xp  + yp;
  103.   bmm = xmm + ymm;
  104. }
  105.  
  106. double drem();
  107.  
  108. #define MILE (5280*12)
  109. #define YARD (3*12)
  110. #define FOOT (12)
  111.  
  112. char *nscale(n, np, nmm, nbuf)
  113.      int n, np, nmm;
  114.      char *nbuf;
  115. {
  116.   sprintf(nbuf, "%d", n);
  117.   if(metric||english) {
  118.     sprintf(nbuf+strlen(nbuf), " (");
  119.   }
  120.   if(metric) {
  121.     sprintf(nbuf+strlen(nbuf),"%.2f mm%s", ((float) n)*nmm/np, english?"; ":"");
  122.   }
  123.   if(english) {
  124.     float in;
  125.     int mi, yar, ft, inr;
  126.     in = ((float) n)*(nmm/25.4)/np;
  127.     inr = (int)in;
  128.     if(inr>=MILE) {
  129.       mi = inr/MILE;
  130.       inr %= MILE;
  131.       sprintf(nbuf+strlen(nbuf), "%d %s(?!?), ",
  132.           mi, (mi==1)?"mile":"miles");
  133.     }
  134.     if(inr>=YARD) {
  135.       yar = inr/YARD;
  136.       inr %= YARD;
  137.       sprintf(nbuf+strlen(nbuf), "%d %s, ",
  138.           yar, (yar==1)?"yard":"yards");
  139.     }
  140.     if(inr>=FOOT) {
  141.       ft = inr/FOOT;
  142.       inr  %= FOOT;
  143.       sprintf(nbuf+strlen(nbuf), "%d %s, ",
  144.           ft, (ft==1)?"foot":"feet");
  145.     }
  146.     sprintf(nbuf+strlen(nbuf), "%.2f inches", in);
  147.   }
  148.   if (english || metric) strcat (nbuf, ")");
  149.   return(nbuf);
  150. }      
  151.   
  152. char xbuf[BUFSIZ];
  153. char *xscale(x)
  154.      int x;
  155. {
  156.   if(!xp) {
  157.     scale_init();
  158.   }
  159.   return(nscale(x, xp, xmm, xbuf));
  160. }
  161.  
  162. char ybuf[BUFSIZ];
  163. char *yscale(y)
  164.      int y;
  165. {
  166.   if(!yp) {
  167.     scale_init();
  168.   }
  169.   return(nscale(y, yp, ymm, ybuf));
  170. }
  171.  
  172. char bbuf[BUFSIZ];
  173. char *bscale(b)
  174.      int b;
  175. {
  176.   if(!bp) {
  177.     scale_init();
  178.   }
  179.   return(nscale(b, bp, bmm, bbuf));
  180. }
  181.  
  182. /* end of pixel to inch, metric converter */
  183.  
  184. /* This handler is enabled when we are checking
  185.    to see if the -id the user specified is valid. */
  186.  
  187. /* ARGSUSED */
  188. bad_window_handler(disp, err)
  189.     Display *disp;
  190.     XErrorEvent *err;
  191. {
  192.     char badid[20];
  193.  
  194.     sprintf(badid, window_id_format, err->resourceid);
  195.     Fatal_Error("No such window with id %s.", badid);
  196.     exit (1);
  197. }
  198.  
  199.  
  200. main(argc, argv)
  201.      int argc;
  202.      char **argv;
  203. {
  204.   register int i;
  205.   int tree = 0, stats = 0, bits = 0, events = 0, wm = 0, size  = 0, shape = 0;
  206.   int frame = 0, children = 0;
  207.   Window window;
  208.  
  209.   INIT_NAME;
  210.  
  211.   /* Open display, handle command line arguments */
  212.   Setup_Display_And_Screen(&argc, argv);
  213.  
  214.   /* Get window selected on command line, if any */
  215.   window = Select_Window_Args(&argc, argv);
  216.  
  217.   /* Handle our command line arguments */
  218.   for (i = 1; i < argc; i++) {
  219.     if (!strcmp(argv[i], "-help"))
  220.       usage();
  221.     if (!strcmp(argv[i], "-int")) {
  222.       window_id_format = "%ld";
  223.       continue;
  224.     }
  225.     if (!strcmp(argv[i], "-children")) {
  226.       children = 1;
  227.       continue;
  228.     }
  229.     if (!strcmp(argv[i], "-tree")) {
  230.       tree = 1;
  231.       continue;
  232.     }
  233.     if (!strcmp(argv[i], "-stats")) {
  234.       stats = 1;
  235.       continue;
  236.     }
  237.     if (!strcmp(argv[i], "-bits")) {
  238.       bits = 1;
  239.       continue;
  240.     }
  241.     if (!strcmp(argv[i], "-events")) {
  242.       events = 1;
  243.       continue;
  244.     }
  245.     if (!strcmp(argv[i], "-wm")) {
  246.       wm = 1;
  247.       continue;
  248.     }
  249.     if (!strcmp(argv[i], "-frame")) {
  250.       frame = 1;
  251.       continue;
  252.     }
  253.     if (!strcmp(argv[i], "-size")) {
  254.       size = 1;
  255.       continue;
  256.     }
  257.     if (!strcmp(argv[i], "-shape")) {
  258.       shape = 1;
  259.       continue;
  260.     }
  261.     if (!strcmp(argv[i], "-english")) {
  262.       english = 1;
  263.       continue;
  264.     }
  265.     if (!strcmp(argv[i], "-metric")) {
  266.       metric = 1;
  267.       continue;
  268.     }
  269.     if (!strcmp(argv[i], "-all")) {
  270.       tree = stats = bits = events = wm = size = shape = 1;
  271.       continue;
  272.     }
  273.     usage();
  274.   }
  275.  
  276.   /* If no window selected on command line, let user pick one the hard way */
  277.   if (!window) {
  278.       printf("\n");
  279.       printf("xwininfo: Please select the window about which you\n");
  280.       printf("          would like information by clicking the\n");
  281.       printf("          mouse in that window.\n");
  282.       window = Select_Window(dpy);
  283.       if (window && !frame) {
  284.           Window root;
  285.           int dummyi;
  286.           unsigned int dummy;
  287.  
  288.           if (XGetGeometry (dpy, window, &root, &dummyi, &dummyi,
  289.                 &dummy, &dummy, &dummy, &dummy) &&
  290.           window != root)
  291.             window = XmuClientWindow (dpy, window);
  292.       }
  293.   }
  294.  
  295.   /*
  296.    * Do the actual displaying as per parameters
  297.    */
  298.   if (!(children || tree || bits || events || wm || size))
  299.     stats = 1;
  300.  
  301.   /*
  302.    * make sure that the window is valid
  303.    */
  304.   {
  305.     Window root;
  306.     int x, y;
  307.     unsigned width, height, bw, depth;
  308.     int (*old_handler)();
  309.  
  310.     old_handler = XSetErrorHandler(bad_window_handler);
  311.     XGetGeometry (dpy, window, &root, &x, &y, &width, &height, &bw, &depth);
  312.     XSync (dpy, False);
  313.     (void) XSetErrorHandler(old_handler);
  314.   }
  315.  
  316.   printf("\nxwininfo: Window id: ");
  317.   Display_Window_Id(window, True);
  318.   if (children || tree)
  319.     Display_Tree_Info(window, tree);
  320.   if (stats)
  321.     Display_Stats_Info(window);
  322.   if (bits)
  323.     Display_Bits_Info(window);
  324.   if (events)
  325.     Display_Events_Info(window);
  326.   if (wm)
  327.     Display_WM_Info(window);
  328.   if (size)
  329.     Display_Size_Hints(window);
  330.   if (shape)
  331.     Display_Window_Shape(window);
  332.   printf("\n");
  333.   exit(0);
  334. }
  335.  
  336.  
  337. /*
  338.  * Lookup: lookup a code in a table.
  339.  */
  340. typedef struct {
  341.     long code;
  342.     char *name;
  343. } binding;
  344.  
  345. static char _lookup_buffer[100];
  346.  
  347. char *Lookup(code, table)
  348.     int code;
  349.     binding *table;
  350. {
  351.     char *name;
  352.  
  353.     sprintf(_lookup_buffer, "unknown (code = %ld. = 0x%lx)", code, code);
  354.     name = _lookup_buffer;
  355.  
  356.     while (table->name) {
  357.         if (table->code == code) {
  358.             name = table->name;
  359.             break;
  360.         }
  361.         table++;
  362.     }
  363.  
  364.     return(name);
  365. }
  366.  
  367.  
  368. /*
  369.  * Routine to display a window id in dec/hex with name if window has one
  370.  */
  371.  
  372. Display_Window_Id(window, newline_wanted)
  373.     Window window;
  374.     Bool newline_wanted;
  375. {
  376.     char *win_name;
  377.     
  378.     printf(window_id_format, window);         /* print id # in hex/dec */
  379.  
  380.     if (!window) {
  381.     printf(" (none)");
  382.     } else {
  383.     if (window == RootWindow(dpy, screen)) {
  384.         printf(" (the root window)");
  385.     }
  386.     if (!XFetchName(dpy, window, &win_name)) { /* Get window name if any */
  387.         printf(" (has no name)");
  388.     } else if (win_name) {
  389.         printf(" \"%s\"", win_name);
  390.         XFree(win_name);
  391.     } else
  392.         printf(" (has no name)");
  393.     }
  394.  
  395.     if (newline_wanted)
  396.     printf("\n");
  397.  
  398.     return;
  399. }
  400.  
  401.  
  402. /*
  403.  * Display Stats on window
  404.  */
  405. static binding _window_classes[] = {
  406.     { InputOutput, "InputOutput" },
  407.     { InputOnly, "InputOnly" },
  408.         { 0, 0 } };
  409.  
  410. static binding _map_states[] = {
  411.     { IsUnmapped, "IsUnMapped" },
  412.     { IsUnviewable, "IsUnviewable" },
  413.     { IsViewable, "IsViewable" },
  414.     { 0, 0 } };
  415.  
  416. static binding _backing_store_states[] = {
  417.     { NotUseful, "NotUseful" },
  418.     { WhenMapped, "WhenMapped" },
  419.     { Always, "Always" },
  420.     { 0, 0 } };
  421.  
  422. static binding _bit_gravity_states[] = {
  423.     { ForgetGravity, "ForgetGravity" },
  424.     { NorthWestGravity, "NorthWestGravity" },
  425.     { NorthGravity, "NorthGravity" },
  426.     { NorthEastGravity, "NorthEastGravity" },
  427.     { WestGravity, "WestGravity" },
  428.     { CenterGravity, "CenterGravity" },
  429.     { EastGravity, "EastGravity" },
  430.     { SouthWestGravity, "SouthWestGravity" },
  431.     { SouthGravity, "SouthGravity" },
  432.     { SouthEastGravity, "SouthEastGravity" },
  433.     { StaticGravity, "StaticGravity" },
  434.     { 0, 0 }};
  435.  
  436. static binding _window_gravity_states[] = {
  437.     { UnmapGravity, "UnmapGravity" },
  438.     { NorthWestGravity, "NorthWestGravity" },
  439.     { NorthGravity, "NorthGravity" },
  440.     { NorthEastGravity, "NorthEastGravity" },
  441.     { WestGravity, "WestGravity" },
  442.     { CenterGravity, "CenterGravity" },
  443.     { EastGravity, "EastGravity" },
  444.     { SouthWestGravity, "SouthWestGravity" },
  445.     { SouthGravity, "SouthGravity" },
  446.     { SouthEastGravity, "SouthEastGravity" },
  447.     { StaticGravity, "StaticGravity" },
  448.     { 0, 0 }};
  449.  
  450. static binding _visual_classes[] = {
  451.     { StaticGray, "StaticGray" },
  452.     { GrayScale, "GrayScale" },
  453.     { StaticColor, "StaticColor" },
  454.     { PseudoColor, "PseudoColor" },
  455.     { TrueColor, "TrueColor" },
  456.     { DirectColor, "DirectColor" },
  457.     { 0, 0 }};
  458.  
  459. Display_Stats_Info(window)
  460.      Window window;
  461. {
  462.   XWindowAttributes win_attributes;
  463.   XVisualInfo vistemplate, *vinfo;
  464.   XSizeHints hints;
  465.   int dw = DisplayWidth (dpy, screen), dh = DisplayHeight (dpy, screen);
  466.   int rx, ry, xright, ybelow;
  467.   int showright = 0, showbelow = 0;
  468.   Status status;
  469.   Window wmframe;
  470.   int junk;
  471.   long longjunk;
  472.   Window junkwin;
  473.  
  474.   if (!XGetWindowAttributes(dpy, window, &win_attributes))
  475.     Fatal_Error("Can't get window attributes.");
  476.   vistemplate.visualid = XVisualIDFromVisual(win_attributes.visual);
  477.   vinfo = XGetVisualInfo(dpy, VisualIDMask, &vistemplate, &junk);
  478.  
  479.   (void) XTranslateCoordinates (dpy, window, win_attributes.root, 
  480.                 -win_attributes.border_width,
  481.                 -win_attributes.border_width,
  482.                 &rx, &ry, &junkwin);
  483.                 
  484.   xright = (dw - rx - win_attributes.border_width * 2 -
  485.         win_attributes.width);
  486.   ybelow = (dh - ry - win_attributes.border_width * 2 -
  487.         win_attributes.height);
  488.  
  489.   printf("\n");
  490.   printf("  Absolute upper-left X:  %s\n", xscale(rx));
  491.   printf("  Absolute upper-left Y:  %s\n", yscale(ry));
  492.   printf("  Relative upper-left X:  %s\n", xscale(win_attributes.x));
  493.   printf("  Relative upper-left Y:  %s\n", yscale(win_attributes.y));
  494.   printf("  Width: %s\n", xscale(win_attributes.width));
  495.   printf("  Height: %s\n", yscale(win_attributes.height));
  496.   printf("  Depth: %d\n", win_attributes.depth);
  497.   printf("  Visual Class: %s\n", Lookup(vinfo->class, _visual_classes));
  498.   printf("  Border width: %s\n", bscale(win_attributes.border_width));
  499.   printf("  Class: %s\n",
  500.        Lookup(win_attributes.class, _window_classes));
  501.   printf("  Colormap: 0x%lx (%sinstalled)\n", 
  502.      win_attributes.colormap, win_attributes.map_installed ? "" : "not ");
  503.   printf("  Bit Gravity State: %s\n",
  504.        Lookup(win_attributes.bit_gravity, _bit_gravity_states));
  505.   printf("  Window Gravity State: %s\n",
  506.        Lookup(win_attributes.win_gravity, _window_gravity_states));
  507.   printf("  Backing Store State: %s\n",
  508.        Lookup(win_attributes.backing_store, _backing_store_states));
  509.   printf("  Save Under State: %s\n",
  510.        win_attributes.save_under ? "yes" : "no");
  511.   printf("  Map State: %s\n",
  512.      Lookup(win_attributes.map_state, _map_states));
  513.   printf("  Override Redirect State: %s\n",
  514.        win_attributes.override_redirect ? "yes" : "no");
  515.   printf("  Corners:  +%d+%d  -%d+%d  -%d-%d  +%d-%d\n",
  516.      rx, ry, xright, ry, xright, ybelow, rx, ybelow);
  517.  
  518.   /*
  519.    * compute geometry string that would recreate window
  520.    */
  521.   printf("  -geometry ");
  522.  
  523.   /* compute size in appropriate units */
  524.   status = XGetWMNormalHints(dpy, window, &hints, &longjunk);
  525.   if (status  &&  hints.flags & PResizeInc  &&
  526.               hints.width_inc != 0  &&  hints.height_inc != 0) {
  527.       if (hints.flags & (PBaseSize|PMinSize)) {
  528.       if (hints.flags & PBaseSize) {
  529.           win_attributes.width -= hints.base_width;
  530.           win_attributes.height -= hints.base_height;
  531.       } else {
  532.           /* ICCCM says MinSize is default for BaseSize */
  533.           win_attributes.width -= hints.min_width;
  534.           win_attributes.height -= hints.min_height;
  535.       }
  536.       }
  537.       printf("%dx%d", win_attributes.width/hints.width_inc,
  538.          win_attributes.height/hints.height_inc);
  539.   } else
  540.       printf("%dx%d", win_attributes.width, win_attributes.height);
  541.  
  542.   if (!(hints.flags&PWinGravity))
  543.       hints.win_gravity = NorthWestGravity; /* per ICCCM */
  544.   /* find our window manager frame, if any */
  545.   wmframe = window;
  546.   while (True) {
  547.       Window root, parent;
  548.       Window *childlist;
  549.       unsigned int ujunk;
  550.  
  551.       status = XQueryTree(dpy, wmframe, &root, &parent, &childlist, &ujunk);
  552.       if (parent == root || !parent || !status)
  553.       break;
  554.       wmframe = parent;
  555.       if (status && childlist)
  556.       XFree((char *)childlist);
  557.   }
  558.   if (wmframe != window) {
  559.       /* WM reparented, so find edges of the frame */
  560.       /* Only works for ICCCM-compliant WMs, and then only if the
  561.          window has corner gravity.  We would need to know the original width
  562.      of the window to correctly handle the other gravities. */
  563.  
  564.       XWindowAttributes frame_attr;
  565.  
  566.       if (!XGetWindowAttributes(dpy, wmframe, &frame_attr))
  567.       Fatal_Error("Can't get frame attributes.");
  568.       switch (hints.win_gravity) {
  569.     case NorthWestGravity: case SouthWestGravity:
  570.     case NorthEastGravity: case SouthEastGravity:
  571.     case WestGravity:
  572.       rx = frame_attr.x;
  573.       }
  574.       switch (hints.win_gravity) {
  575.     case NorthWestGravity: case SouthWestGravity:
  576.     case NorthEastGravity: case SouthEastGravity:
  577.     case EastGravity:
  578.       xright = dw - frame_attr.x - frame_attr.width -
  579.           2*frame_attr.border_width;
  580.       }
  581.       switch (hints.win_gravity) {
  582.     case NorthWestGravity: case SouthWestGravity:
  583.     case NorthEastGravity: case SouthEastGravity:
  584.     case NorthGravity:
  585.       ry = frame_attr.y;
  586.       }
  587.       switch (hints.win_gravity) {
  588.     case NorthWestGravity: case SouthWestGravity:
  589.     case NorthEastGravity: case SouthEastGravity:
  590.     case SouthGravity:
  591.       ybelow = dh - frame_attr.y - frame_attr.height -
  592.           2*frame_attr.border_width;
  593.       }
  594.   }
  595.   /* If edge gravity, offer a corner on that edge (because the application
  596.      programmer cares about that edge), otherwise offer upper left unless
  597.      some other corner is close to an edge of the screen.
  598.      (For corner gravity, assume gravity was set by XWMGeometry.
  599.      For CenterGravity, it doesn't matter.) */
  600.   if (hints.win_gravity == EastGravity  ||
  601.       (abs(xright) <= 100  &&  abs(xright) < abs(rx)
  602.         &&  hints.win_gravity != WestGravity))
  603.       showright = 1;
  604.   if (hints.win_gravity == SouthGravity  ||
  605.       (abs(ybelow) <= 100  &&  abs(ybelow) < abs(ry)
  606.         &&  hints.win_gravity != NorthGravity))
  607.       showbelow = 1;
  608.   
  609.   if (showright)
  610.       printf("-%d", xright);
  611.   else
  612.       printf("+%d", rx);
  613.   if (showbelow)
  614.       printf("-%d", ybelow);
  615.   else
  616.       printf("+%d", ry);
  617.   printf("\n");
  618. }
  619.  
  620.  
  621. /*
  622.  * Display bits info:
  623.  */
  624. static binding _gravities[] = {
  625.     { UnmapGravity, "UnMapGravity" },      /* WARNING: both of these have*/
  626.     { ForgetGravity, "ForgetGravity" },    /* the same value - see code */
  627.     { NorthWestGravity, "NorthWestGravity" },
  628.     { NorthGravity, "NorthGravity" },
  629.     { NorthEastGravity, "NorthEastGravity" },
  630.     { WestGravity, "WestGravity" },
  631.     { CenterGravity, "CenterGravity" },
  632.     { EastGravity, "EastGravity" },
  633.     { SouthWestGravity, "SouthWestGravity" },
  634.     { SouthGravity, "SouthGravity" },
  635.     { SouthEastGravity, "SouthEastGravity" },
  636.     { StaticGravity, "StaticGravity" },
  637.     { 0, 0 } };
  638.  
  639. static binding _backing_store_hint[] = {
  640.     { NotUseful, "NotUseful" },
  641.     { WhenMapped, "WhenMapped" },
  642.     { Always, "Always" },
  643.     { 0, 0 } };
  644.  
  645. static binding _bool[] = {
  646.     { 0, "No" },
  647.     { 1, "Yes" },
  648.     { 0, 0 } };
  649.  
  650. Display_Bits_Info(window)
  651.      Window window;
  652. {
  653.   XWindowAttributes win_attributes;
  654.  
  655.   if (!XGetWindowAttributes(dpy, window, &win_attributes))
  656.     Fatal_Error("Can't get window attributes.");
  657.  
  658.   printf("\n");
  659.   printf("  Bit gravity: %s\n",
  660.      Lookup(win_attributes.bit_gravity, _gravities+1));
  661.   printf("  Window gravity: %s\n",
  662.      Lookup(win_attributes.win_gravity, _gravities));
  663.   printf("  Backing-store hint: %s\n",
  664.      Lookup(win_attributes.backing_store, _backing_store_hint));
  665.   printf("  Backing-planes to be preserved: 0x%x\n",
  666.      win_attributes.backing_planes);
  667.   printf("  Backing pixel: %d\n", win_attributes.backing_pixel);
  668.   printf("  Save-unders: %s\n",
  669.      Lookup(win_attributes.save_under, _bool));
  670. }
  671.  
  672.  
  673. /*
  674.  * Routine to display all events in an event mask
  675.  */
  676. static binding _event_mask_names[] = {
  677.     { KeyPressMask, "KeyPress" },
  678.     { KeyReleaseMask, "KeyRelease" },
  679.     { ButtonPressMask, "ButtonPress" },
  680.     { ButtonReleaseMask, "ButtonRelease" },
  681.     { EnterWindowMask, "EnterWindow" },
  682.     { LeaveWindowMask, "LeaveWindow" },
  683.     { PointerMotionMask, "PointerMotion" },
  684.     { PointerMotionHintMask, "PointerMotionHint" },
  685.     { Button1MotionMask, "Button1Motion" },
  686.     { Button2MotionMask, "Button2Motion" },
  687.     { Button3MotionMask, "Button3Motion" },
  688.     { Button4MotionMask, "Button4Motion" },
  689.     { Button5MotionMask, "Button5Motion" },
  690.     { ButtonMotionMask, "ButtonMotion" },
  691.     { KeymapStateMask, "KeymapState" },
  692.     { ExposureMask, "Exposure" },
  693.     { VisibilityChangeMask, "VisibilityChange" },
  694.     { StructureNotifyMask, "StructureNotify" },
  695.     { ResizeRedirectMask, "ResizeRedirect" },
  696.     { SubstructureNotifyMask, "SubstructureNotify" },
  697.     { SubstructureRedirectMask, "SubstructureRedirect" },
  698.     { FocusChangeMask, "FocusChange" },
  699.     { PropertyChangeMask, "PropertyChange" },
  700.     { ColormapChangeMask, "ColormapChange" },
  701.     { OwnerGrabButtonMask, "OwnerGrabButton" },
  702.     { 0, 0 } };
  703.  
  704. Display_Event_Mask(mask)
  705.      long mask;
  706. {
  707.   long bit, bit_mask;
  708.  
  709.   for (bit=0, bit_mask=1; bit<sizeof(long)*8; bit++, bit_mask <<= 1)
  710.     if (mask & bit_mask)
  711.       printf("      %s\n",
  712.          Lookup(bit_mask, _event_mask_names));
  713. }
  714.  
  715.  
  716. /*
  717.  * Display info on events
  718.  */
  719. Display_Events_Info(window)
  720.      Window window;
  721. {
  722.   XWindowAttributes win_attributes;
  723.  
  724.   if (!XGetWindowAttributes(dpy, window, &win_attributes))
  725.     Fatal_Error("Can't get window attributes.");
  726.  
  727.   printf("\n");
  728.   printf("  Someone wants these events:\n");
  729.   Display_Event_Mask(win_attributes.all_event_masks);
  730.  
  731.   printf("  Do not propagate these events:\n");
  732.   Display_Event_Mask(win_attributes.do_not_propagate_mask);
  733.  
  734.   printf("  Override redirection?: %s\n",
  735.      Lookup(win_attributes.override_redirect, _bool));
  736. }
  737.  
  738.  
  739.   /* left out visual stuff */
  740.   /* left out colormap */
  741.   /* left out map_installed */
  742.  
  743.  
  744. /*
  745.  * Display root, parent, and (recursively) children information
  746.  */
  747. Display_Tree_Info(window, recurse)
  748.      Window window;
  749.      int recurse;        /* true if should show children's children */
  750. {
  751.     display_tree_info_1(window, recurse, 0);
  752. }
  753.  
  754. display_tree_info_1(window, recurse, level)
  755.      Window window;
  756.      int recurse;
  757.      int level;            /* recursion level */
  758. {
  759.   int i, j;
  760.   int rel_x, rel_y, abs_x, abs_y;
  761.   unsigned int width, height, border, depth;
  762.   Window root_win, parent_win;
  763.   unsigned int num_children;
  764.   Window *child_list;
  765.   XClassHint classhint;
  766.  
  767.   if (!XQueryTree(dpy, window, &root_win, &parent_win, &child_list,
  768.           &num_children))
  769.     Fatal_Error("Can't query window tree.");
  770.  
  771.   if (level == 0) {
  772.     printf("\n");
  773.     printf("  Root window id: ");
  774.     Display_Window_Id(root_win, True);
  775.     printf("  Parent window id: ");
  776.     Display_Window_Id(parent_win, True);
  777.   }
  778.  
  779.   if (level == 0  ||  num_children > 0) {
  780.     printf("     ");
  781.     for (j=0; j<level; j++) printf("   ");
  782.     printf("%d child%s%s\n", num_children, num_children == 1 ? "" : "ren",
  783.        num_children ? ":" : ".");
  784.   }
  785.  
  786.   for (i = (int)num_children - 1; i >= 0; i--) {
  787.     printf("     ");
  788.     for (j=0; j<level; j++) printf("   ");
  789.     Display_Window_Id(child_list[i], False);
  790.     printf(": (");
  791.     if(XGetClassHint(dpy, child_list[i], &classhint)) {
  792.     if(classhint.res_name) {
  793.         printf("\"%s\" ", classhint.res_name);
  794.         XFree(classhint.res_name);
  795.     } else
  796.         printf("(none) ");
  797.     if(classhint.res_class) {
  798.         printf("\"%s\") ", classhint.res_class);
  799.         XFree(classhint.res_class);
  800.     } else
  801.         printf("(none)) ");
  802.     } else
  803.     printf(") ");
  804.  
  805.     if (XGetGeometry(dpy, child_list[i], &root_win,
  806.              &rel_x, &rel_y, &width, &height, &border, &depth)) {
  807.     Window child;
  808.  
  809.     printf (" %ux%u+%d+%d", width, height, rel_x, rel_y);
  810.     if (XTranslateCoordinates (dpy, child_list[i], root_win,
  811.                    0 ,0, &abs_x, &abs_y, &child)) {
  812.         printf ("  +%d+%d", abs_x - border, abs_y - border);
  813.     }
  814.     }
  815.     printf("\n");
  816.     
  817.     if (recurse)
  818.     display_tree_info_1(child_list[i], 1, level+1);
  819.   }
  820.  
  821.   if (child_list) XFree((char *)child_list);
  822. }
  823.  
  824.  
  825. /*
  826.  * Display a set of size hints
  827.  */
  828. Display_Hints(hints)
  829.      XSizeHints *hints;
  830. {
  831.     long flags;
  832.  
  833.     flags = hints->flags;
  834.     
  835.     if (flags & USPosition)
  836.       printf("      User supplied location: %s, %s\n",
  837.          xscale(hints->x), yscale(hints->y));
  838.  
  839.     if (flags & PPosition)
  840.       printf("      Program supplied location: %s, %s\n",
  841.          xscale(hints->x), yscale(hints->y));
  842.  
  843.     if (flags & USSize) {
  844.       printf("      User supplied size: %s by %s\n",
  845.          xscale(hints->width), yscale(hints->height));
  846.     }
  847.  
  848.     if (flags & PSize)
  849.       printf("      Program supplied size: %s by %s\n",
  850.          xscale(hints->width), yscale(hints->height));
  851.  
  852.     if (flags & PMinSize)
  853.       printf("      Program supplied minimum size: %s by %s\n",
  854.          xscale(hints->min_width), yscale(hints->min_height));
  855.  
  856.     if (flags & PMaxSize)
  857.       printf("      Program supplied maximum size: %s by %s\n",
  858.          xscale(hints->max_width), yscale(hints->max_height));
  859.  
  860.     if (flags & PBaseSize) {
  861.       printf("      Program supplied base size: %s by %s\n",
  862.          xscale(hints->base_width), yscale(hints->base_height));
  863.     }
  864.  
  865.     if (flags & PResizeInc) {
  866.       printf("      Program supplied x resize increment: %s\n",
  867.          xscale(hints->width_inc));
  868.       printf("      Program supplied y resize increment: %s\n",
  869.          yscale(hints->height_inc));
  870.       if (hints->width_inc != 0 && hints->height_inc != 0) {
  871.           if (flags & USSize)
  872.           printf("      User supplied size in resize increments:  %s by %s\n",
  873.              (xscale(hints->width / hints->width_inc)), 
  874.              (yscale(hints->height / hints->height_inc)));
  875.           if (flags & PSize)
  876.           printf("      Program supplied size in resize increments:  %s by %s\n",
  877.              (xscale(hints->width / hints->width_inc)), 
  878.              (yscale(hints->height / hints->height_inc)));
  879.           if (flags & PMinSize)
  880.           printf("      Program supplied minimum size in resize increments: %s by %s\n",
  881.              xscale(hints->min_width / hints->width_inc), yscale(hints->min_height / hints->height_inc));
  882.           if (flags & PBaseSize)
  883.           printf("      Program supplied base size in resize increments:  %s by %s\n",
  884.              (xscale(hints->base_width / hints->width_inc)), 
  885.              (yscale(hints->base_height / hints->height_inc)));
  886.       }
  887.         }
  888.  
  889.     if (flags & PAspect) {
  890.       printf("      Program supplied min aspect ratio: %s/%s\n",
  891.          xscale(hints->min_aspect.x), yscale(hints->min_aspect.y));
  892.       printf("      Program supplied max aspect ratio: %s/%s\n",
  893.          xscale(hints->max_aspect.x), yscale(hints->max_aspect.y));
  894.         }
  895.  
  896.     if (flags & PWinGravity) {
  897.       printf("      Program supplied window gravity: %s\n",
  898.          Lookup(hints->win_gravity, _gravities));
  899.     }
  900. }
  901.  
  902.  
  903. /*
  904.  * Display Size Hints info
  905.  */
  906. Display_Size_Hints(window)
  907.      Window window;
  908. {
  909.     XSizeHints *hints = XAllocSizeHints();
  910.     long supplied;
  911.  
  912.     printf("\n");
  913.     if (!XGetWMNormalHints(dpy, window, hints, &supplied))
  914.         printf("  No normal window size hints defined\n");
  915.     else {
  916.         printf("  Normal window size hints:\n");
  917.         hints->flags &= supplied;
  918.         Display_Hints(hints);
  919.     }
  920.  
  921.     if (!XGetWMSizeHints(dpy, window, hints, &supplied, XA_WM_ZOOM_HINTS))
  922.         printf("  No zoom window size hints defined\n");
  923.     else {
  924.         printf("  Zoom window size hints:\n");
  925.         hints->flags &= supplied;
  926.         Display_Hints(hints);
  927.     }
  928.     XFree((char *)hints);
  929. }
  930.  
  931.  
  932. Display_Window_Shape (window)
  933.     Window  window;
  934. {
  935.     Bool    ws, bs;
  936.     int        xws, yws, xbs, ybs;
  937.     unsigned int wws, hws, wbs, hbs;
  938.  
  939.     if (!XShapeQueryExtension (dpy, &bs, &ws))
  940.     return;
  941.  
  942.     printf("\n");
  943.     XShapeQueryExtents (dpy, window, &ws, &xws, &yws, &wws, &hws,
  944.                      &bs, &xbs, &ybs, &wbs, &hbs);
  945.     if (!ws)
  946.       printf("  No window shape defined\n");
  947.     else {
  948.       printf("  Window shape extents:  %sx%s",
  949.          xscale(wws), yscale(hws));
  950.       printf("+%s+%s\n", xscale(xws), yscale(yws));
  951.     }
  952.     if (!bs)
  953.       printf("  No border shape defined\n");
  954.     else {
  955.       printf("  Border shape extents:  %sx%s",
  956.          xscale(wbs), yscale(hbs));
  957.       printf("+%s+%s\n", xscale(xbs), yscale(ybs));
  958.     }
  959. }
  960.  
  961. /*
  962.  * Display Window Manager Info
  963.  */
  964. static binding _state_hints[] = {
  965.     { DontCareState, "Don't Care State" },
  966.     { NormalState, "Normal State" },
  967.     { ZoomState, "Zoomed State" },
  968.     { IconicState, "Iconic State" },
  969.     { InactiveState, "Inactive State" },
  970.     { 0, 0 } };
  971.  
  972. Display_WM_Info(window)
  973.      Window window;
  974. {
  975.         XWMHints *wmhints;
  976.     long flags;
  977.  
  978.     wmhints = XGetWMHints(dpy, window);
  979.     printf("\n");
  980.     if (!wmhints) {
  981.         printf("  No window manager hints defined\n");
  982.         return;
  983.     }
  984.     flags = wmhints->flags;
  985.  
  986.     printf("  Window manager hints:\n");
  987.  
  988.     if (flags & InputHint)
  989.       printf("      Client accepts input or input focus: %s\n",
  990.          Lookup(wmhints->input, _bool));
  991.  
  992.     if (flags & IconWindowHint) {
  993.         printf("      Icon window id: ");
  994.         Display_Window_Id(wmhints->icon_window, True);
  995.     }
  996.  
  997.     if (flags & IconPositionHint)
  998.       printf("      Initial icon position: %s, %s\n",
  999.          xscale(wmhints->icon_x), yscale(wmhints->icon_y));
  1000.  
  1001.     if (flags & StateHint)
  1002.       printf("      Initial state is %s\n",
  1003.          Lookup(wmhints->initial_state, _state_hints));
  1004. }
  1005.