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,©WinInfo);
/* 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),
©WinAttrs);
/* 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(¤tTime,&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(¤tTime,&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