home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / hacking / internet / xwatch.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1992-08-29  |  23.8 KB  |  673 lines

  1. #! /bin/sh
  2. # This is a shar archive.  Extract with sh, not csh.
  3. #George D. Drapeau                      Internet: drapeau@jessica.stanford.edu
  4. #Academic Information Resources
  5. #Stanford University
  6. echo x - Imakefile
  7. cat > Imakefile << '25787!Funky!Stuff!'
  8. #ifdef SunSharedLibs
  9. SYS_LIBRARIES = -lX11
  10. #else
  11. LOCAL_LIBRARIES = $(XLIB)
  12. #endif
  13. SimpleProgramTarget(xwatchwin)
  14. 25787!Funky!Stuff!
  15. echo x - Makefile
  16. cat > Makefile << '25787!Funky!Stuff!'
  17. # Makefile generated by imake - do not edit!
  18. # $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $
  19. #
  20. # The cpp used on this machine replaces all newlines and multiple tabs and
  21. # spaces in a macro expansion with a single space.  Imake tries to compensate
  22. # for this, but is not always successful.
  23. #
  24.  
  25. ###########################################################################
  26. # X Window System Makefile generated from template file Imake.tmpl
  27. # $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $
  28. #
  29. # Do not change the body of the imake template file.  Server-specific
  30. # parameters may be set in the appropriate .macros file; site-specific
  31. # parameters (but shared by all servers) may be set in site.def.  If you
  32. # make any changes, you'll need to rebuild the makefiles using
  33. # "make World" (at best) or "make Makefile; make Makefiles" (at least) in
  34. # the top level directory.
  35. #
  36. # If your C preprocessor doesn't define any unique symbols, you'll need
  37. # to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
  38. # "make Makefile", "make Makefiles", or "make World").
  39. #
  40. # If you absolutely can't get imake to work, you'll need to set the
  41. # variables at the top of each Makefile as well as the dependencies at the
  42. # bottom (makedepend will do this automatically).
  43. #
  44.  
  45. ###########################################################################
  46. # platform-specific configuration parameters - edit Sun.macros to change
  47.  
  48. # platform:  $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $
  49. # operating system:  SunOS 4.0
  50.  
  51. BOOTSTRAPCFLAGS =
  52.          AS = as
  53.          CC = cc
  54.         CPP = /lib/cpp
  55.          LD = ld
  56.        LINT = lint
  57.     INSTALL = install
  58.        TAGS = ctags
  59.          RM = rm -f
  60.          MV = mv
  61.          LN = ln -s
  62.      RANLIB = ranlib
  63. RANLIBINSTFLAGS = -t
  64.          AR = ar clq
  65.          LS = ls
  66.        LINTOPTS = -axz
  67.     LINTLIBFLAG = -C
  68.        MAKE = make
  69. STD_CPP_DEFINES =
  70.     STD_DEFINES =
  71.  
  72. ###########################################################################
  73. # site-specific configuration parameters - edit site.def to change
  74.  
  75. # site:  $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $
  76.  
  77. ###########################################################################
  78. # definitions common to all Makefiles - do not edit
  79.  
  80.       SHELL = /bin/sh
  81.  
  82.     DESTDIR = /usr/local
  83.       USRLIBDIR = $(DESTDIR)/X11R3/lib
  84.      BINDIR = $(DESTDIR)/X11R3/bin
  85.      INCDIR = $(DESTDIR)/include/X11R3
  86.      ADMDIR = $(DESTDIR)/usr/adm
  87.      LIBDIR = $(USRLIBDIR)
  88.      LINTLIBDIR = $(USRLIBDIR)/lint
  89.     FONTDIR = $(LIBDIR)/fonts
  90.        XINITDIR = $(LIBDIR)/xinit
  91.      XDMDIR = $(LIBDIR)/xdm
  92.      UWMDIR = $(LIBDIR)/uwm
  93.      AWMDIR = $(LIBDIR)/awm
  94.      TWMDIR = $(LIBDIR)/twm
  95.     MANPATH = $(DESTDIR)/man
  96.   MANSOURCEPATH = $(MANPATH)/man
  97.      MANDIR = $(MANSOURCEPATH)1
  98.       LIBMANDIR = $(MANSOURCEPATH)3
  99.     XAPPLOADDIR = $(LIBDIR)/app-defaults
  100.  
  101.    INSTBINFLAGS = -sm 0755
  102.    INSTUIDFLAGS = -m 4755
  103.    INSTLIBFLAGS = -m 0664
  104.    INSTINCFLAGS = -m 0444
  105.    INSTMANFLAGS = -m 0444
  106.    INSTAPPFLAGS = -m 0444
  107.   INSTKMEMFLAGS = -g kmem -m 2755
  108.     FCFLAGS = -t
  109.     CDEBUGFLAGS =
  110.  
  111.     PATHSEP = /
  112.      DEPEND = $(DEPENDSRC)/makedepend
  113.       IMAKE = $(IMAKESRC)/imake
  114.         RGB = $(RGBSRC)/rgb
  115.          FC = $(BDFTOSNFSRC)/bdftosnf
  116.       MKFONTDIR = $(MKFONTDIRSRC)/mkfontdir
  117.       MKDIRHIER = $(SCRIPTSSRC)/mkdirhier.sh
  118.  
  119.      CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES)
  120.       LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT
  121.     LDFLAGS = $(CDEBUGFLAGS) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES)
  122.         TOP = /usr/local/X
  123.       CLIENTSRC = $(TOP)/clients
  124.     DEMOSRC = $(TOP)/demos
  125.      LIBSRC = $(TOP)/lib
  126.     FONTSRC = $(TOP)/fonts
  127.      INCLUDESRC = $(TOP)/X11
  128.       SERVERSRC = $(TOP)/server
  129.     UTILSRC = $(TOP)/util
  130.      SCRIPTSSRC = $(UTILSRC)/scripts
  131.      EXAMPLESRC = $(TOP)/examples
  132.      CONTRIBSRC = $(TOP)/contrib
  133.      DOCSRC = $(TOP)/doc
  134.      RGBSRC = $(TOP)/rgb
  135.       DEPENDSRC = $(UTILSRC)/makedepend
  136.        IMAKESRC = $(UTILSRC)/imake
  137.        IRULESRC = $(UTILSRC)/imake.includes
  138.     XLIBSRC = $(LIBSRC)/X
  139.      XMUSRC = $(LIBSRC)/Xmu
  140.      TOOLKITSRC = $(LIBSRC)/Xt
  141.      AWIDGETSRC = $(LIBSRC)/Xaw
  142.      OLDXLIBSRC = $(LIBSRC)/oldX
  143.     BDFTOSNFSRC = $(FONTSRC)/bdftosnf
  144.    MKFONTDIRSRC = $(FONTSRC)/mkfontdir
  145.    EXTENSIONSRC = $(TOP)/extensions
  146.    EXTENSIONLIB = $(EXTENSIONSRC)/lib/libXext.a
  147.        XLIB = $(XLIBSRC)/libX11.a
  148.      XMULIB = $(XMUSRC)/libXmu.a
  149.     OLDXLIB = $(OLDXLIBSRC)/liboldX.a
  150.        XTOOLLIB = $(TOOLKITSRC)/libXt.a
  151.      XAWLIB = $(AWIDGETSRC)/libXaw.a
  152.        LINTXLIB = $(XLIBSRC)/llib-lX11.ln
  153.     LINTXMU = $(XMUSRC)/llib-lXmu.ln
  154.       LINTXTOOL = $(TOOLKITSRC)/llib-lXt.ln
  155.     LINTXAW = $(AWIDGETSRC)/llib-lXaw.ln
  156.        INCLUDES = -I$(TOP)
  157.       MACROFILE = Sun.macros
  158.    ICONFIGFILES = $(IRULESRC)/Imake.tmpl \
  159.             $(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def
  160.   IMAKE_DEFINES =
  161.       IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
  162.             -s Makefile $(IMAKE_DEFINES)
  163.      RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
  164.             .emacs_* tags TAGS make.log MakeOut
  165.  
  166. ###########################################################################
  167. # rules:  $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $
  168.  
  169. ###########################################################################
  170. # start of Imakefile
  171.  
  172. SYS_LIBRARIES = -lX11
  173.  
  174.  OBJS = xwatchwin.o
  175.  SRCS = xwatchwin.c
  176.  
  177.  PROGRAM = xwatchwin
  178.  
  179. all:: xwatchwin
  180.  
  181. xwatchwin: $(OBJS) $(LOCAL_LIBRARIES)
  182.     $(RM) $@
  183.     $(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES)
  184.  
  185. relink::
  186.     $(RM) $(PROGRAM)
  187.     $(MAKE) $(MFLAGS) $(PROGRAM)
  188.  
  189. install:: xwatchwin
  190.     $(INSTALL) -c $(INSTALLFLAGS) xwatchwin $(BINDIR)
  191.  
  192. install.man:: xwatchwin.man
  193.     $(INSTALL) -c $(INSTMANFLAGS) xwatchwin.man $(MANDIR)/xwatchwin.1
  194.  
  195. depend:: $(DEPEND)
  196.  
  197. depend::
  198.     $(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS)
  199.  
  200. $(DEPEND):
  201.     @echo "making $@"; \
  202.     cd $(DEPENDSRC); $(MAKE)
  203.  
  204. clean::
  205.     $(RM) $(PROGRAM)
  206.  
  207. ###########################################################################
  208. # Imake.tmpl common rules for all Makefiles - do not edit
  209.  
  210. emptyrule::
  211.  
  212. clean::
  213.     $(RM_CMD) \#*
  214.  
  215. Makefile:: $(IMAKE)
  216.  
  217. Makefile:: Imakefile \
  218.     $(IRULESRC)/Imake.tmpl \
  219.     $(IRULESRC)/Imake.rules \
  220.     $(IRULESRC)/site.def \
  221.     $(IRULESRC)/$(MACROFILE)
  222.     -@if [ -f Makefile ]; then \
  223.     echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
  224.     $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
  225.     else exit 0; fi
  226.     $(IMAKE_CMD) -DTOPDIR=$(TOP)
  227.  
  228. $(IMAKE):
  229.     @echo "making $@"; \
  230.     cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)
  231.  
  232. tags::
  233.     $(TAGS) -w *.[ch]
  234.     $(TAGS) -xw *.[ch] > TAGS
  235.  
  236. ###########################################################################
  237. # empty rules for directories that do not have SUBDIRS - do not edit
  238.  
  239. install::
  240.     @echo "install done"
  241.  
  242. install.man::
  243.     @echo "install.man done"
  244.  
  245. Makefiles::
  246.  
  247. ###########################################################################
  248. # dependencies generated by makedepend
  249.  
  250. 25787!Funky!Stuff!
  251. echo x - xwatchwin.c
  252. cat > xwatchwin.c << '25787!Funky!Stuff!'
  253. #include <stdio.h>
  254. #include <ctype.h>
  255. #include <sys/time.h>
  256. #include <X11/Xlib.h>
  257. #include <X11/Xutil.h>
  258.  
  259. #define STRINGLENGTH    256
  260. #define SLEEPTIME       0    /* Sleep for this many seconds before redrawing */
  261.  
  262. char    **Argv;
  263. int     Argc;
  264. Display *dpy;
  265.  
  266.  
  267. main(argc,argv)
  268.      int        argc;
  269.      char       **argv;
  270. {
  271.   Window        watchWin,GetWindowByName();
  272.   int           i,strPos,optIndex;
  273.   char          displayName[64],xWatchName[STRINGLENGTH];
  274.   char          *optstring;
  275.   extern char   *optarg;
  276.   extern int    optind,opterr;
  277.   int           windowID,windowIDSet,updateTime,updateTimeSet;
  278.   
  279.  
  280.   if (argc < 3)                     /* Did user enter enough arguments? */
  281.     {                               /* Nope, print an error message and exit. */
  282.       printf("Usage:\t%s HostName [-u UpdateTime] [-w windowID] [WindowName]\n",
  283.       argv[0]);
  284.       exit(1);
  285.     }
  286.  
  287.   /* Initialize var to update every SLEEPTIME seconds. */
  288.   updateTime = SLEEPTIME;
  289.   updateTimeSet = 0;
  290.   windowIDSet = 0;
  291.   optind = 2;       /* Skip over first, obligatory argument (hostname) */
  292.   while ((optIndex = getopt(argc,argv,"u:w:")) != -1) /* Get user's arguments */
  293.     switch (optIndex)
  294.       {
  295.       case 'u':         /* User wants to update every 'optarg' seconds. */
  296.     updateTime = atoi(optarg);
  297.     updateTimeSet = 1;    /* Set flag saying user specified this option. */
  298.     break;
  299.       case 'w':   /* User wants to specify window by id instead of by name */
  300.     sscanf(&optarg[2],"%lx",&windowID);
  301.     windowIDSet = 1;    /* Set flag saying user specified this option. */
  302.     break;
  303.       }                     /* end switch (optIndex) */
  304.  
  305.   Argv = argv;
  306.   Argc = argc;
  307.   sprintf(displayName,"%s:0.0",argv[1]);    /* Set the X display name. */
  308.   if (!windowIDSet)        /* Did user specify window to watch by number? */
  309.     for (i=2, bzero(xWatchName, STRINGLENGTH); i < argc; i++)
  310.     /* No, parse rest of arguments as window name to watch */
  311.       {
  312.     if (!strcmp(argv[i],"-u"))         /* Don't parse optional arguments */
  313.       {
  314.         i++;                   /* Skip over argument to '-u' switch. */
  315.         continue;
  316.       }
  317.     /* Get current length of xWatchName string */
  318.     strPos = strlen(xWatchName);
  319.     /* Copy another argument to the end of the string */
  320.     strcpy(&xWatchName[strPos],argv[i]);
  321.       }
  322.  
  323.   /* Attempt to open a connection with the remote X server */
  324.   if ((dpy = XOpenDisplay(displayName)) == NULL)
  325.     {
  326.       /* Couldn't open the display for some reason, so... */
  327.       fprintf(stderr,"%s: Could not open Display %s\n", argv[0],displayName);
  328.       exit(1);      /* ...report the error and exit with an error code */
  329.     }
  330.  
  331.   if (!windowIDSet)         /* Did user specify a window to watch by id? */
  332.     /* No, get window id from window name. */
  333.     watchWin = GetWindowByName(XDefaultRootWindow(dpy),xWatchName);
  334.   else watchWin = windowID; /* Yes, use user-specified window id. */
  335.   if (watchWin)    /* Did the user find the window s/he was looking for? */
  336.     /* Yes, periodically show the contents of that window  */
  337.     WatchWindow(watchWin,updateTime);
  338.   else  /* No, report that the window was not found, and exit. */
  339.     {
  340.       printf("Could not find the window you specified.\n");
  341.       exit(1);
  342.     }
  343.   
  344. }       /* end function main */
  345.  
  346.  
  347.  
  348.  
  349. /* Takes two strings, removes spaces from the second,... */
  350. /* ...and compares them..  Returns 1 if equal, 0 if not. */
  351. WinNamesEqual(str1,str2)
  352.      char       *str1,*str2;
  353. {
  354.   char  tempStr[STRINGLENGTH],*tempStrPtr;
  355.   int   index;
  356.   
  357.   bzero(tempStr,STRINGLENGTH);  /* Clear the contents of the string, if any */
  358.   /* Go through each character in the second string. */
  359.   for (tempStrPtr=tempStr; *str2; str2++)
  360.     {
  361.       if (!isspace(*str2))    /* Is this character a space?  */
  362.     *tempStrPtr++ = *str2;  /* No, copy this character to a temp string. */
  363.     }
  364.   if (!strcmp(str1,tempStr))    /* Are the two resulting string equal? */
  365.     return(1);                  /* Yes, return 1 */
  366.   else
  367.     return(0);                  /* No, return 0 */
  368. }                               /* end function WinNamesEqual */
  369.  
  370.  
  371. WatchWindow(win,updateTime)
  372.      Window     win;
  373.      int        updateTime;
  374. {
  375.   Display               *dpy2;
  376.   Window                copyWin;
  377.   GC                    gc;
  378.   XWindowAttributes     copyWinInfo,newWinInfo;
  379.   XSetWindowAttributes  copyWinAttrs;
  380.   XWMHints              wmHints;
  381.   XSizeHints            sizeHints;
  382.   XImage                *image;
  383.   struct timeval        currentTime;
  384.   struct timezone       zone;
  385.   long                  timeInSecs;
  386.   Bool                  srcWinUnmapped;
  387.   
  388.   /* Get the window attributes of the window we're watching */
  389.   XGetWindowAttributes(dpy,win,©WinInfo);
  390.   /* Is the original window in a state to be watched?  */
  391.   if (copyWinInfo.map_state != IsViewable)
  392.     {  /* Nope, tell the user of the problem and exit. */
  393.       printf("The window you wish to look at is not in a state to be viewed\n");
  394.       printf("(perhaps it is iconified or not mapped)\n");
  395.       exit(1);
  396.     }
  397.   /* Attempt to open a connection with the local X server */
  398.   if ((dpy2 = XOpenDisplay(NULL)) == NULL)
  399.     {
  400.       /* Couldn't open the display for some reason, so... */
  401.       fprintf(stderr,"%s: Could not open Display.\n", Argv[0]);
  402.       exit(1); /* ...report the error and exit with an error code */
  403.     }
  404.   /* Set a couple more attributes */
  405.   copyWinAttrs.colormap = XDefaultColormap(dpy2,XDefaultScreen(dpy2));
  406.   copyWinAttrs.bit_gravity = copyWinInfo.bit_gravity;
  407.   /* Check for different depths b/w source & dest displays */
  408.   if (copyWinInfo.depth != XDefaultDepth(dpy2,XDefaultScreen(dpy2)))
  409.     {
  410.       puts("Sorry, the original and copied windows contain incompatible");
  411.       puts("information (i.e., they don't use the same number of bits per pixel.");
  412.       exit(1);
  413.     }
  414.   /* Create a copy of the window we're watching */
  415.   copyWin = XCreateWindow(dpy2,XDefaultRootWindow(dpy2),
  416.               copyWinInfo.x,copyWinInfo.y,
  417.               copyWinInfo.width,copyWinInfo.height,
  418.               copyWinInfo.border_width,
  419.               copyWinInfo.depth,
  420.               CopyFromParent,
  421.               XDefaultVisual(dpy2,XDefaultScreen(dpy2)),
  422.               (CWColormap|CWBitGravity),
  423.               ©WinAttrs);
  424.   /* Get size hints for window being watched */
  425.   XGetNormalHints(dpy,win,&sizeHints);
  426.   /* Set standard window properties for my window */
  427.   XSetStandardProperties(dpy2,copyWin,"XWatchWin","XWatchWin",
  428.              None,Argv,Argc,&sizeHints);
  429.   /* Get window mgr hints for the window being watched */
  430.   XGetWMHints(dpy,win,&wmHints);
  431.   /* Tell the X server about my window manager hints */
  432.   XSetWMHints(dpy2,copyWin,&wmHints);
  433.   gc = XDefaultGC(dpy2,0); /* Get a default graphics context */
  434.   /* Only interested in exposures and button presses */
  435.   XSelectInput(dpy2,copyWin,(ExposureMask|ButtonPressMask));
  436.   /* Put the window up on the display */
  437.   XMapWindow(dpy2,copyWin);
  438.   XSelectInput(dpy,win, /* Only interested if the source window is... */
  439.            /* ...iconified or if it's mapped/unmapped */
  440.            (VisibilityChangeMask|StructureNotifyMask));
  441.   /* Store an image of the original window in an XImage */
  442.   image = XGetImage(dpy,(Drawable)win,
  443.             0,0,
  444.             copyWinInfo.width,copyWinInfo.height,
  445.             AllPlanes,XYPixmap);
  446.   gettimeofday(¤tTime,&zone); /* Get the current time. */
  447.   timeInSecs = currentTime.tv_sec; /* Save the current time in seconds */
  448.   /* Set variable saying it's okay to watch the src window. */
  449.   srcWinUnmapped = 0;
  450.   while (1) /* Enter an infinite event loop */
  451.     {
  452.       XEvent    event;
  453.  
  454.       /* Check if the source window was turned into an... */
  455.       if (XCheckWindowEvent(dpy,win,
  456.                 (VisibilityChangeMask|StructureNotifyMask),
  457.                 &event))
  458.     { /* ...icon or back into a window */
  459.       /* Get the window attributes of the window we're watching */
  460.       XGetWindowAttributes(dpy,win,&newWinInfo);
  461.       /* Is the original window in a state to be watched?  */
  462.       if (newWinInfo.map_state != IsViewable)
  463.         {
  464.           /* Let program know that the src window is unwatchable. */
  465.           srcWinUnmapped = 1;
  466.           printf("The window you are watching just became 'invisible'..\n");
  467.           printf("I will wait until it is 'visible' again...\n");
  468.           continue;
  469.         }
  470.       else
  471.         /* Let program know that src window is watchable again. */
  472.         srcWinUnmapped = 0;
  473.     } /* end if(XCheckWindowEvent... */
  474.  
  475.       /* Look for window events, but don't sit around... */
  476.       if (XCheckWindowEvent(dpy2,copyWin,
  477.                 (ExposureMask|ButtonPressMask),
  478.                 /* ...waiting for one (i.e., don't block) */
  479.                 &event))
  480.     switch (event.type)
  481.       {
  482.       case ButtonPress:
  483.         XDestroyImage(image);/* Free memory resources used by the image */
  484.         exit(0);            /* Get outtahere */
  485.         break;
  486.       case Expose:
  487.         /* Put the original window's image into the... */
  488.         XPutImage(dpy2,(Drawable)copyWin,
  489.               gc,image,0,0,0,0, /* ...copy of the window. */
  490.               copyWinInfo.width,copyWinInfo.height);
  491.         break;
  492.       }                             /* end switch (event.type) */
  493.       gettimeofday(¤tTime,&zone); /* Get the current time. */
  494.       /* Have 'updateTime' seconds passed? */
  495.       if (currentTime.tv_sec > (timeInSecs + updateTime))
  496.     { /* Yes, update the local copy of the window. */
  497.       if (srcWinUnmapped)/* Is the source window watchable? */
  498.         continue;   /* No, go through the event loop again. */
  499.       else  /* Yes, it's watchable, so get a new copy of the window. */
  500.         {
  501.           XDestroyImage(image);/* Free memory resources used by the image */
  502.           /* Store an image of the original window in an XImage */
  503.           image = XGetImage(dpy,(Drawable)win,
  504.                 0,0,
  505.                 copyWinInfo.width,copyWinInfo.height,
  506.                 AllPlanes,XYPixmap);
  507.         } /* end else XDestroyImage... */
  508.       /* Put the original window's image into the... */
  509.       XPutImage(dpy2,(Drawable)copyWin,
  510.             gc,image,0,0,0,0, /* ...copy of the window. */
  511.             copyWinInfo.width,copyWinInfo.height);
  512.       timeInSecs = currentTime.tv_sec;/* Update the current time */
  513.     }                               /* end if currentTime... */
  514.     }                                   /* end while(1) */
  515. }                                       /* end function WatchWindow */
  516.  
  517.  
  518. /* Given the name of a window and the top of a ... */
  519. /* ...window tree, this function will try to find... */
  520. /* the Window ID corresponding to the window name... */
  521. /* ...given as argument. */
  522. Window GetWindowByName(window,windowName)
  523.      Window     window;
  524.      char       *windowName;
  525. {
  526.   Window        rootWin,parentWin,wID;
  527.   Window        *childWinList;
  528.   int           numChildren,i;
  529.   char          *childWinName;
  530.  
  531.   /* Get information about windows that are children... */
  532.   XQueryTree(dpy,window,
  533.          &rootWin,&parentWin,&childWinList, /* ...of 'window'. */
  534.          &numChildren);
  535.   for (i=0;i<numChildren;i++) /* Look at each child of 'window' */
  536.     {
  537.       /* Get the name of that window */
  538.       XFetchName(dpy,childWinList[i],&childWinName);
  539.       if (childWinName != NULL) /* Is there a name attached to this window? */
  540.     {
  541.       /* Is this the window the user is looking for? */
  542.       if (WinNamesEqual(windowName,childWinName))
  543.         {
  544.           XFree(childWinList);/* Free up space taken by list of windows */
  545.           XFree(childWinName);/* Return space taken by this window's name */
  546.           /* Yes, return the Window ID of this window */
  547.           return(childWinList[i]);
  548.         }
  549.       XFree(childWinName);/* Return space taken by this window's name */
  550.     }               /* end if childWinName... */
  551.     }                   /* end for i=0... */
  552.   /* If this section of code is reached, then no match was found at this
  553.    * level of the tree
  554.    */
  555.   for (i=0;i<numChildren;i++) /* Recurse on the children of this window */
  556.     {
  557.       wID = GetWindowByName(childWinList[i],windowName);
  558.       if (wID)          /* Was a match found in this window's children? */
  559.     {
  560.       XFree(childWinList); /* Free up space taken by list of windows */
  561.       return(wID);  /* Return the ID of the window that matched */
  562.     }
  563.     }                   /* end for i=0... */
  564.   /* If this section of code is reached, then no match was found below
  565.    * this level of the tree
  566.    */
  567.   XFree(childWinList); /* Free up space taken by list of windows */
  568.   return((Window)0); /* No match was found, return 0. */
  569. }               /* end function GetWindowByName */
  570. 25787!Funky!Stuff!
  571. echo x - xwatchwin.man
  572. cat > xwatchwin.man << '25787!Funky!Stuff!'
  573. .TH xwatchwin 1 "17 March 1989" "X Version 11"
  574. .SH NAME
  575. xwatchwin - watch a window on another X server
  576. .SH SYNOPSIS
  577. .B "xwatchwin"
  578. hostname
  579. [\-u \fIupdatetime\fP] [\-w \fIwindowID\fP] [window name]
  580. .SH DESCRIPTION
  581. .PP
  582. \fIxwatchwin\fP allows you to peek at a window on another X server.
  583. To use it, you must specify the name of the machine you want to watch, then
  584. the name of the window on that machine.  \fIXwatchwin\fP will attempt to
  585. connect with the X server \fIhostname\fP:0.0, and if successful, will try
  586. to retrieve a copy of the window in which you specified interest.
  587.  
  588. You may specify the window you want to watch either by name or by its
  589. window id, usually a hexidecimal number.  Usually specifying the
  590. window by name is simpler, although not all windows have names
  591. associated with them; in that case you must use the window id option.
  592.  
  593. If the window you want to watch is not in a viewable state,
  594. \fIxwatchwin\fP will tell you so and exit.  If while you are watching a
  595. window it becomes 'unviewable', \fIxwatchwin\fP will print a message to
  596. stdout and wait until the window becomes 'viewable' again.
  597.  
  598. \fIxwatchwin\fP was written as an aid to a class for people learning to
  599. use X.  The idea is that the instructor would type into an xterm
  600. window on his/her display and the students would use \fIxwatchwin\fP to
  601. see what the instructor typed.  The students could then type the same
  602. thing in their own terminal windows.  I hope that others will find
  603. equally (if not more) constructive uses.
  604.  
  605. .SH OPTIONS
  606. .TP 8
  607. .B \-u \fIupdatetime\fP
  608. This option specifies how often (in seconds) you want to get a new copy
  609. of the window you're watching.  It is in effect a 'sample rate'.  By default,
  610. \fIxwatchwin\fP updates your copy of the window as often as it can.  The time
  611. it takes to actually do the update is dependent on the speed of the X server
  612. on both machines, the speed of the intervening network, and other factors.
  613. .TP 8
  614. .B \-w \fIwindowID\fP
  615. This option specifies the window you want to watch by number, for example,
  616. "0x50000b".  Use the xlswins(1) command to get a list of window id's and
  617. possibly their names on the remote server.  
  618.  
  619. You must specify a window to watch either by name or by id.  Specifying
  620. a window to watch by name is usually easier if you know what you're looking for.
  621. .SH EXAMPLES
  622. If there is an X server on the remote machine "crow" and if on that server
  623. there is a window called "X Terminal Emulator", you can watch that window
  624. by typing
  625.  
  626. xwatchwin crow X Terminal Emulator
  627.  
  628. If there is a window on "crow" that has no name but has a window id of
  629. "0x50000b", you can watch it by typing
  630.  
  631. xwatchwin crow -w 0x50000b
  632.  
  633. If you want to get new copies of a window only every 30 seconds, you can
  634. do so by typing
  635.  
  636. xwatchwin crow -u 30 -w 0x50000b
  637. .SH "SEE ALSO"
  638. xlswins(1), xwininfo(1), xdpyinfo(1),
  639. .SH BUGS
  640. \fIxwatchwin\fP doesn't support the \-display option.  You must set the
  641. display on which the \fIxwatchwin\fP window is created by changing your
  642. DISPLAY environment variable.
  643.  
  644. If the window you're watching is unmapped (made 'invisible')
  645. while \fIxwatchwin\fP
  646. is getting a new copy of that window, the program will crash.  The smaller
  647. your update interval, the more likely you are to experience this bug (although
  648. it hasn't happened all that often to me).
  649.  
  650. Parsing arguments is messy and not as forgiving as it should be.
  651.  
  652. The event loop is a mess.
  653.  
  654. \fIxwatchwin\fP cannot deal with two displays with different depths.
  655. For example, if the window you're watching is an 8-bit color window and
  656. your display only supports 2-bit color, \fIxwatchwin\fP will not be able
  657. to display the window.  To understand the issues involved in fixing
  658. this, see the paper by David's Lemke and Rosenthal, "\fIVisualizing X11
  659. Clients\fP".
  660. .SH COPYRIGHT
  661. Copyright 1989, George D. Drapeau
  662. .SH AUTHOR
  663. George D. Drapeau
  664. .PP
  665. Stanford University
  666. .br
  667. Academic Information Resources / Systems Development
  668. .br
  669. Internet: drapeau@jessica.stanford.edu
  670. .br
  671. UUCP: labrea!drapeau@jessica
  672. 25787!Funky!Stuff!
  673.