v03i062: xwatchwin -- watch a window on another X server, Part01/01

Dan Heller argv at island.uu.net
Fri Mar 31 17:05:10 AEST 1989


Submitted-by: George Drapeau <drapeau at jessica.stanford.edu>
Posting-number: Volume 3, Issue 62
Archive-name: xwatchwin/part01

[I generated a README from the man page.  As sent, there were *lots* of
lines that went over 80 chars (many over two or three lines), so I
reformatted much of the code by moving comments above the lines they
commented.  I tried to preserve as much of the original style of the
author as possible.  Please be aware of this when sending articles to
be posted by any newsgroup.  --argv]

#! /bin/sh
# This is a shar archive.  Extract with sh, not csh.
#George D. Drapeau			Internet: drapeau at jessica.stanford.edu
#Academic Information Resources
#Stanford University
echo x - Imakefile
cat > Imakefile << '25787!Funky!Stuff!'
#ifdef SunSharedLibs
SYS_LIBRARIES = -lX11
#else
LOCAL_LIBRARIES = $(XLIB)
#endif
SimpleProgramTarget(xwatchwin)
25787!Funky!Stuff!
echo x - Makefile
cat > Makefile << '25787!Funky!Stuff!'
# Makefile generated by imake - do not edit!
# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $
#
# The cpp used on this machine replaces all newlines and multiple tabs and
# spaces in a macro expansion with a single space.  Imake tries to compensate
# for this, but is not always successful.
#

###########################################################################
# X Window System Makefile generated from template file Imake.tmpl
# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $
#
# Do not change the body of the imake template file.  Server-specific
# parameters may be set in the appropriate .macros file; site-specific
# parameters (but shared by all servers) may be set in site.def.  If you
# make any changes, you'll need to rebuild the makefiles using
# "make World" (at best) or "make Makefile; make Makefiles" (at least) in
# the top level directory.
#
# If your C preprocessor doesn't define any unique symbols, you'll need
# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
# "make Makefile", "make Makefiles", or "make World").
#
# If you absolutely can't get imake to work, you'll need to set the
# variables at the top of each Makefile as well as the dependencies at the
# bottom (makedepend will do this automatically).
#

###########################################################################
# platform-specific configuration parameters - edit Sun.macros to change

# platform:  $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $
# operating system:  SunOS 4.0

BOOTSTRAPCFLAGS =
             AS = as
             CC = cc
            CPP = /lib/cpp
             LD = ld
           LINT = lint
        INSTALL = install
           TAGS = ctags
             RM = rm -f
             MV = mv
             LN = ln -s
         RANLIB = ranlib
RANLIBINSTFLAGS = -t
             AR = ar clq
             LS = ls
       LINTOPTS = -axz
    LINTLIBFLAG = -C
           MAKE = make
STD_CPP_DEFINES =
    STD_DEFINES =

###########################################################################
# site-specific configuration parameters - edit site.def to change

# site:  $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $

###########################################################################
# definitions common to all Makefiles - do not edit

          SHELL = /bin/sh

        DESTDIR = /usr/local
      USRLIBDIR = $(DESTDIR)/X11R3/lib
         BINDIR = $(DESTDIR)/X11R3/bin
         INCDIR = $(DESTDIR)/include/X11R3
         ADMDIR = $(DESTDIR)/usr/adm
         LIBDIR = $(USRLIBDIR)
     LINTLIBDIR = $(USRLIBDIR)/lint
        FONTDIR = $(LIBDIR)/fonts
       XINITDIR = $(LIBDIR)/xinit
         XDMDIR = $(LIBDIR)/xdm
         UWMDIR = $(LIBDIR)/uwm
         AWMDIR = $(LIBDIR)/awm
         TWMDIR = $(LIBDIR)/twm
        MANPATH = $(DESTDIR)/man
  MANSOURCEPATH = $(MANPATH)/man
         MANDIR = $(MANSOURCEPATH)1
      LIBMANDIR = $(MANSOURCEPATH)3
    XAPPLOADDIR = $(LIBDIR)/app-defaults

   INSTBINFLAGS = -sm 0755
   INSTUIDFLAGS = -m 4755
   INSTLIBFLAGS = -m 0664
   INSTINCFLAGS = -m 0444
   INSTMANFLAGS = -m 0444
   INSTAPPFLAGS = -m 0444
  INSTKMEMFLAGS = -g kmem -m 2755
        FCFLAGS = -t
    CDEBUGFLAGS =

        PATHSEP = /
         DEPEND = $(DEPENDSRC)/makedepend
          IMAKE = $(IMAKESRC)/imake
            RGB = $(RGBSRC)/rgb
             FC = $(BDFTOSNFSRC)/bdftosnf
      MKFONTDIR = $(MKFONTDIRSRC)/mkfontdir
      MKDIRHIER = $(SCRIPTSSRC)/mkdirhier.sh

         CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES)
      LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT
        LDFLAGS = $(CDEBUGFLAGS) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES)
            TOP = /usr/local/X
      CLIENTSRC = $(TOP)/clients
        DEMOSRC = $(TOP)/demos
         LIBSRC = $(TOP)/lib
        FONTSRC = $(TOP)/fonts
     INCLUDESRC = $(TOP)/X11
      SERVERSRC = $(TOP)/server
        UTILSRC = $(TOP)/util
     SCRIPTSSRC = $(UTILSRC)/scripts
     EXAMPLESRC = $(TOP)/examples
     CONTRIBSRC = $(TOP)/contrib
         DOCSRC = $(TOP)/doc
         RGBSRC = $(TOP)/rgb
      DEPENDSRC = $(UTILSRC)/makedepend
       IMAKESRC = $(UTILSRC)/imake
       IRULESRC = $(UTILSRC)/imake.includes
        XLIBSRC = $(LIBSRC)/X
         XMUSRC = $(LIBSRC)/Xmu
     TOOLKITSRC = $(LIBSRC)/Xt
     AWIDGETSRC = $(LIBSRC)/Xaw
     OLDXLIBSRC = $(LIBSRC)/oldX
    BDFTOSNFSRC = $(FONTSRC)/bdftosnf
   MKFONTDIRSRC = $(FONTSRC)/mkfontdir
   EXTENSIONSRC = $(TOP)/extensions
   EXTENSIONLIB = $(EXTENSIONSRC)/lib/libXext.a
           XLIB = $(XLIBSRC)/libX11.a
         XMULIB = $(XMUSRC)/libXmu.a
        OLDXLIB = $(OLDXLIBSRC)/liboldX.a
       XTOOLLIB = $(TOOLKITSRC)/libXt.a
         XAWLIB = $(AWIDGETSRC)/libXaw.a
       LINTXLIB = $(XLIBSRC)/llib-lX11.ln
        LINTXMU = $(XMUSRC)/llib-lXmu.ln
      LINTXTOOL = $(TOOLKITSRC)/llib-lXt.ln
        LINTXAW = $(AWIDGETSRC)/llib-lXaw.ln
       INCLUDES = -I$(TOP)
      MACROFILE = Sun.macros
   ICONFIGFILES = $(IRULESRC)/Imake.tmpl \
			$(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def
  IMAKE_DEFINES =
      IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
			-s Makefile $(IMAKE_DEFINES)
         RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
			.emacs_* tags TAGS make.log MakeOut

###########################################################################
# rules:  $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $

###########################################################################
# start of Imakefile

SYS_LIBRARIES = -lX11

 OBJS = xwatchwin.o
 SRCS = xwatchwin.c

 PROGRAM = xwatchwin

all:: xwatchwin

xwatchwin: $(OBJS) $(LOCAL_LIBRARIES)
	$(RM) $@
	$(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES)

relink::
	$(RM) $(PROGRAM)
	$(MAKE) $(MFLAGS) $(PROGRAM)

install:: xwatchwin
	$(INSTALL) -c $(INSTALLFLAGS) xwatchwin $(BINDIR)

install.man:: xwatchwin.man
	$(INSTALL) -c $(INSTMANFLAGS) xwatchwin.man $(MANDIR)/xwatchwin.1

depend:: $(DEPEND)

depend::
	$(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS)

$(DEPEND):
	@echo "making $@"; \
	cd $(DEPENDSRC); $(MAKE)

clean::
	$(RM) $(PROGRAM)

###########################################################################
# Imake.tmpl common rules for all Makefiles - do not edit

emptyrule::

clean::
	$(RM_CMD) \#*

Makefile:: $(IMAKE)

Makefile:: Imakefile \
	$(IRULESRC)/Imake.tmpl \
	$(IRULESRC)/Imake.rules \
	$(IRULESRC)/site.def \
	$(IRULESRC)/$(MACROFILE)
	- at if [ -f Makefile ]; then \
	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
	else exit 0; fi
	$(IMAKE_CMD) -DTOPDIR=$(TOP)

$(IMAKE):
	@echo "making $@"; \
	cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)

tags::
	$(TAGS) -w *.[ch]
	$(TAGS) -xw *.[ch] > TAGS

###########################################################################
# empty rules for directories that do not have SUBDIRS - do not edit

install::
	@echo "install done"

install.man::
	@echo "install.man done"

Makefiles::

###########################################################################
# dependencies generated by makedepend

25787!Funky!Stuff!
echo x - xwatchwin.c
cat > xwatchwin.c << '25787!Funky!Stuff!'
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#define STRINGLENGTH	256
#define SLEEPTIME	0    /* Sleep for this many seconds before redrawing */

char	**Argv;
int	Argc;
Display	*dpy;


main(argc,argv)
     int	argc;
     char	**argv;
{
  Window	watchWin,GetWindowByName();
  int		i,strPos,optIndex;
  char		displayName[64],xWatchName[STRINGLENGTH];
  char		*optstring;
  extern char	*optarg;
  extern int	optind,opterr;
  int		windowID,windowIDSet,updateTime,updateTimeSet;
  

  if (argc < 3)			    /* Did user enter enough arguments? */
    {				    /* Nope, print an error message and exit. */
      printf("Usage:\t%s HostName [-u UpdateTime] [-w windowID] [WindowName]\n",
	  argv[0]);
      exit(1);
    }

  /* Initialize var to update every SLEEPTIME seconds. */
  updateTime = SLEEPTIME;
  updateTimeSet = 0;
  windowIDSet = 0;
  optind = 2;	    /* Skip over first, obligatory argument (hostname) */
  while ((optIndex = getopt(argc,argv,"u:w:")) != -1) /* Get user's arguments */
    switch (optIndex)
      {
      case 'u':		/* User wants to update every 'optarg' seconds. */
	updateTime = atoi(optarg);
	updateTimeSet = 1;    /* Set flag saying user specified this option. */
	break;
      case 'w':   /* User wants to specify window by id instead of by name */
	sscanf(&optarg[2],"%lx",&windowID);
	windowIDSet = 1;    /* Set flag saying user specified this option. */
	break;
      }			    /* end switch (optIndex) */

  Argv = argv;
  Argc = argc;
  sprintf(displayName,"%s:0.0",argv[1]);    /* Set the X display name. */
  if (!windowIDSet)	   /* Did user specify window to watch by number? */
    for (i=2, bzero(xWatchName, STRINGLENGTH); i < argc; i++)
    /* No, parse rest of arguments as window name to watch */
      {
	if (!strcmp(argv[i],"-u"))	   /* Don't parse optional arguments */
	  {
	    i++;		   /* Skip over argument to '-u' switch. */
	    continue;
	  }
	/* Get current length of xWatchName string */
	strPos = strlen(xWatchName);
	/* Copy another argument to the end of the string */
	strcpy(&xWatchName[strPos],argv[i]);
      }

  /* Attempt to open a connection with the remote X server */
  if ((dpy = XOpenDisplay(displayName)) == NULL)
    {
      /* Couldn't open the display for some reason, so... */
      fprintf(stderr,"%s: Could not open Display %s\n", argv[0],displayName);
      exit(1);	    /* ...report the error and exit with an error code */
    }

  if (!windowIDSet)	    /* Did user specify a window to watch by id? */
    /* No, get window id from window name. */
    watchWin = GetWindowByName(XDefaultRootWindow(dpy),xWatchName);
  else watchWin = windowID; /* Yes, use user-specified window id. */
  if (watchWin)	   /* Did the user find the window s/he was looking for? */
    /* Yes, periodically show the contents of that window  */
    WatchWindow(watchWin,updateTime);
  else	/* No, report that the window was not found, and exit. */
    {
      printf("Could not find the window you specified.\n");
      exit(1);
    }
  
}	/* end function main */




/* Takes two strings, removes spaces from the second,... */
/* ...and compares them..  Returns 1 if equal, 0 if not. */
WinNamesEqual(str1,str2)
     char	*str1,*str2;
{
  char	tempStr[STRINGLENGTH],*tempStrPtr;
  int	index;
  
  bzero(tempStr,STRINGLENGTH);	/* Clear the contents of the string, if any */
  /* Go through each character in the second string. */
  for (tempStrPtr=tempStr; *str2; str2++)
    {
      if (!isspace(*str2))    /* Is this character a space?  */
	*tempStrPtr++ = *str2;	/* No, copy this character to a temp string. */
    }
  if (!strcmp(str1,tempStr))	/* Are the two resulting string equal? */
    return(1);			/* Yes, return 1 */
  else
    return(0);			/* No, return 0 */
}				/* end function WinNamesEqual */


WatchWindow(win,updateTime)
     Window	win;
     int	updateTime;
{
  Display		*dpy2;
  Window		copyWin;
  GC			gc;
  XWindowAttributes	copyWinInfo,newWinInfo;
  XSetWindowAttributes	copyWinAttrs;
  XWMHints		wmHints;
  XSizeHints		sizeHints;
  XImage		*image;
  struct timeval	currentTime;
  struct timezone	zone;
  long			timeInSecs;
  Bool			srcWinUnmapped;
  
  /* Get the window attributes of the window we're watching */
  XGetWindowAttributes(dpy,win,&copyWinInfo);
  /* Is the original window in a state to be watched?  */
  if (copyWinInfo.map_state != IsViewable)
    {  /* Nope, tell the user of the problem and exit. */
      printf("The window you wish to look at is not in a state to be viewed\n");
      printf("(perhaps it is iconified or not mapped)\n");
      exit(1);
    }
  /* Attempt to open a connection with the local X server */
  if ((dpy2 = XOpenDisplay(NULL)) == NULL)
    {
	  /* Couldn't open the display for some reason, so... */
      fprintf(stderr,"%s: Could not open Display.\n", Argv[0]);
      exit(1); /* ...report the error and exit with an error code */
    }
  /* Set a couple more attributes */
  copyWinAttrs.colormap = XDefaultColormap(dpy2,XDefaultScreen(dpy2));
  copyWinAttrs.bit_gravity = copyWinInfo.bit_gravity;
  /* Check for different depths b/w source & dest displays */
  if (copyWinInfo.depth != XDefaultDepth(dpy2,XDefaultScreen(dpy2)))
    {
      puts("Sorry, the original and copied windows contain incompatible");
      puts("information (i.e., they don't use the same number of bits per pixel.");
      exit(1);
    }
  /* Create a copy of the window we're watching */
  copyWin = XCreateWindow(dpy2,XDefaultRootWindow(dpy2),
			  copyWinInfo.x,copyWinInfo.y,
			  copyWinInfo.width,copyWinInfo.height,
			  copyWinInfo.border_width,
			  copyWinInfo.depth,
			  CopyFromParent,
			  XDefaultVisual(dpy2,XDefaultScreen(dpy2)),
			  (CWColormap|CWBitGravity),
			  &copyWinAttrs);
  /* Get size hints for window being watched */
  XGetNormalHints(dpy,win,&sizeHints);
  /* Set standard window properties for my window */
  XSetStandardProperties(dpy2,copyWin,"XWatchWin","XWatchWin",
			 None,Argv,Argc,&sizeHints);
  /* Get window mgr hints for the window being watched */
  XGetWMHints(dpy,win,&wmHints);
  /* Tell the X server about my window manager hints */
  XSetWMHints(dpy2,copyWin,&wmHints);
  gc = XDefaultGC(dpy2,0); /* Get a default graphics context */
  /* Only interested in exposures and button presses */
  XSelectInput(dpy2,copyWin,(ExposureMask|ButtonPressMask));
  /* Put the window up on the display */
  XMapWindow(dpy2,copyWin);
  XSelectInput(dpy,win, /* Only interested if the source window is... */
	       /* ...iconified or if it's mapped/unmapped */
	       (VisibilityChangeMask|StructureNotifyMask));
  /* Store an image of the original window in an XImage */
  image = XGetImage(dpy,(Drawable)win,
		    0,0,
		    copyWinInfo.width,copyWinInfo.height,
		    AllPlanes,XYPixmap);
  gettimeofday(&currentTime,&zone); /* Get the current time. */
  timeInSecs = currentTime.tv_sec; /* Save the current time in seconds */
  /* Set variable saying it's okay to watch the src window. */
  srcWinUnmapped = 0;
  while (1) /* Enter an infinite event loop */
    {
      XEvent	event;

      /* Check if the source window was turned into an... */
      if (XCheckWindowEvent(dpy,win,
			    (VisibilityChangeMask|StructureNotifyMask),
			    &event))
	{ /* ...icon or back into a window */
	  /* Get the window attributes of the window we're watching */
	  XGetWindowAttributes(dpy,win,&newWinInfo);
	  /* Is the original window in a state to be watched?  */
	  if (newWinInfo.map_state != IsViewable)
	    {
	      /* Let program know that the src window is unwatchable. */
	      srcWinUnmapped = 1;
	      printf("The window you are watching just became 'invisible'..\n");
	      printf("I will wait until it is 'visible' again...\n");
	      continue;
	    }
	  else
	    /* Let program know that src window is watchable again. */
	    srcWinUnmapped = 0;
	} /* end if(XCheckWindowEvent... */

      /* Look for window events, but don't sit around... */
      if (XCheckWindowEvent(dpy2,copyWin,
			    (ExposureMask|ButtonPressMask),
			    /* ...waiting for one (i.e., don't block) */
			    &event))
	switch (event.type)
	  {
	  case ButtonPress:
	    XDestroyImage(image);/* Free memory resources used by the image */
	    exit(0);		/* Get outtahere */
	    break;
	  case Expose:
	    /* Put the original window's image into the... */
	    XPutImage(dpy2,(Drawable)copyWin,
		      gc,image,0,0,0,0,	/* ...copy of the window. */
		      copyWinInfo.width,copyWinInfo.height);
	    break;
	  }				/* end switch (event.type) */
      gettimeofday(&currentTime,&zone);	/* Get the current time. */
      /* Have 'updateTime' seconds passed? */
      if (currentTime.tv_sec > (timeInSecs + updateTime))
	{ /* Yes, update the local copy of the window. */
	  if (srcWinUnmapped)/* Is the source window watchable? */
	    continue;	/* No, go through the event loop again. */
	  else	/* Yes, it's watchable, so get a new copy of the window. */
	    {
	      XDestroyImage(image);/* Free memory resources used by the image */
	      /* Store an image of the original window in an XImage */
	      image = XGetImage(dpy,(Drawable)win,
				0,0,
				copyWinInfo.width,copyWinInfo.height,
				AllPlanes,XYPixmap);
	    } /* end else XDestroyImage... */
	  /* Put the original window's image into the... */
	  XPutImage(dpy2,(Drawable)copyWin,
		    gc,image,0,0,0,0, /* ...copy of the window. */
		    copyWinInfo.width,copyWinInfo.height);
	  timeInSecs = currentTime.tv_sec;/* Update the current time */
	}				/* end if currentTime... */
    }					/* end while(1) */
}					/* end function WatchWindow */


/* Given the name of a window and the top of a ... */
/* ...window tree, this function will try to find... */
/* the Window ID corresponding to the window name... */
/* ...given as argument. */
Window GetWindowByName(window,windowName)
     Window	window;
     char	*windowName;
{
  Window	rootWin,parentWin,wID;
  Window	*childWinList;
  int		numChildren,i;
  char		*childWinName;

  /* Get information about windows that are children... */
  XQueryTree(dpy,window,
	     &rootWin,&parentWin,&childWinList,	/* ...of 'window'. */
	     &numChildren);
  for (i=0;i<numChildren;i++) /* Look at each child of 'window' */
    {
      /* Get the name of that window */
      XFetchName(dpy,childWinList[i],&childWinName);
      if (childWinName != NULL) /* Is there a name attached to this window? */
	{
	  /* Is this the window the user is looking for? */
	  if (WinNamesEqual(windowName,childWinName))
	    {
	      XFree(childWinList);/* Free up space taken by list of windows */
	      XFree(childWinName);/* Return space taken by this window's name */
	      /* Yes, return the Window ID of this window */
	      return(childWinList[i]);
	    }
	  XFree(childWinName);/* Return space taken by this window's name */
	}		/* end if childWinName... */
    }			/* end for i=0... */
  /* If this section of code is reached, then no match was found at this
   * level of the tree
   */
  for (i=0;i<numChildren;i++) /* Recurse on the children of this window */
    {
      wID = GetWindowByName(childWinList[i],windowName);
      if (wID)		/* Was a match found in this window's children? */
	{
	  XFree(childWinList); /* Free up space taken by list of windows */
	  return(wID);	/* Return the ID of the window that matched */
	}
    }			/* end for i=0... */
  /* If this section of code is reached, then no match was found below
   * this level of the tree
   */
  XFree(childWinList); /* Free up space taken by list of windows */
  return((Window)0); /* No match was found, return 0. */
}		/* end function GetWindowByName */
25787!Funky!Stuff!
echo x - xwatchwin.man
cat > xwatchwin.man << '25787!Funky!Stuff!'
.TH xwatchwin 1 "17 March 1989" "X Version 11"
.SH NAME
xwatchwin - watch a window on another X server
.SH SYNOPSIS
.B "xwatchwin"
hostname
[\-u \fIupdatetime\fP] [\-w \fIwindowID\fP] [window name]
.SH DESCRIPTION
.PP
\fIxwatchwin\fP allows you to peek at a window on another X server.
To use it, you must specify the name of the machine you want to watch, then
the name of the window on that machine.  \fIXwatchwin\fP will attempt to
connect with the X server \fIhostname\fP:0.0, and if successful, will try
to retrieve a copy of the window in which you specified interest.

You may specify the window you want to watch either by name or by its
window id, usually a hexidecimal number.  Usually specifying the
window by name is simpler, although not all windows have names
associated with them; in that case you must use the window id option.

If the window you want to watch is not in a viewable state,
\fIxwatchwin\fP will tell you so and exit.  If while you are watching a
window it becomes 'unviewable', \fIxwatchwin\fP will print a message to
stdout and wait until the window becomes 'viewable' again.

\fIxwatchwin\fP was written as an aid to a class for people learning to
use X.  The idea is that the instructor would type into an xterm
window on his/her display and the students would use \fIxwatchwin\fP to
see what the instructor typed.  The students could then type the same
thing in their own terminal windows.  I hope that others will find
equally (if not more) constructive uses.

.SH OPTIONS
.TP 8
.B \-u \fIupdatetime\fP
This option specifies how often (in seconds) you want to get a new copy
of the window you're watching.  It is in effect a 'sample rate'.  By default,
\fIxwatchwin\fP updates your copy of the window as often as it can.  The time
it takes to actually do the update is dependent on the speed of the X server
on both machines, the speed of the intervening network, and other factors.
.TP 8
.B \-w \fIwindowID\fP
This option specifies the window you want to watch by number, for example,
"0x50000b".  Use the xlswins(1) command to get a list of window id's and
possibly their names on the remote server.  

You must specify a window to watch either by name or by id.  Specifying
a window to watch by name is usually easier if you know what you're looking for.
.SH EXAMPLES
If there is an X server on the remote machine "crow" and if on that server
there is a window called "X Terminal Emulator", you can watch that window
by typing

xwatchwin crow X Terminal Emulator

If there is a window on "crow" that has no name but has a window id of
"0x50000b", you can watch it by typing

xwatchwin crow -w 0x50000b

If you want to get new copies of a window only every 30 seconds, you can
do so by typing

xwatchwin crow -u 30 -w 0x50000b
.SH "SEE ALSO"
xlswins(1), xwininfo(1), xdpyinfo(1),
.SH BUGS
\fIxwatchwin\fP doesn't support the \-display option.  You must set the
display on which the \fIxwatchwin\fP window is created by changing your
DISPLAY environment variable.

If the window you're watching is unmapped (made 'invisible')
while \fIxwatchwin\fP
is getting a new copy of that window, the program will crash.  The smaller
your update interval, the more likely you are to experience this bug (although
it hasn't happened all that often to me).

Parsing arguments is messy and not as forgiving as it should be.

The event loop is a mess.

\fIxwatchwin\fP cannot deal with two displays with different depths.
For example, if the window you're watching is an 8-bit color window and
your display only supports 2-bit color, \fIxwatchwin\fP will not be able
to display the window.  To understand the issues involved in fixing
this, see the paper by David's Lemke and Rosenthal, "\fIVisualizing X11
Clients\fP".
.SH COPYRIGHT
Copyright 1989, George D. Drapeau
.SH AUTHOR
George D. Drapeau
.PP
Stanford University
.br
Academic Information Resources / Systems Development
.br
Internet: drapeau at jessica.stanford.edu
.br
UUCP: labrea!drapeau at jessica
25787!Funky!Stuff!



More information about the Comp.sources.x mailing list