[alt.sources] Xmon - graphically monitor a list Part03/03

ferguson@cs.rochester.edu (George Ferguson) (08/29/90)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 3)."
# Contents:  xmon.c xmon.man
# Wrapped by ferguson@cyan.cs.rochester.edu on Tue Aug 28 16:40:51 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xmon.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xmon.c'\"
else
echo shar: Extracting \"'xmon.c'\" \(11059 characters\)
sed "s/^X//" >'xmon.c' <<'END_OF_FILE'
X/*
X *	Xmon : Graphically monitor a list
X *
X *	George Ferguson, ferguson@cs.rochester.edu,  4 May 1990.
X *
X *	$Id: xmon.c,v 1.4 90/08/21 11:14:39 ferguson Exp $
X *
X */
Xstatic char *rcsid = "$Id: xmon.c,v 1.4 90/08/21 11:14:39 ferguson Exp $";
X#include <stdio.h>
X#include <ctype.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Xaw/Label.h>	
X#include <X11/Xaw/Toggle.h>	
X#include <X11/Xaw/Cardinals.h>	
X#include "app-resources.h"
Xextern WidgetClass classNameToWidgetClass();
Xextern char *getTextFromWidget();
X
X/*	-	-	-	-	-	-	-	-	*/
X/*
X * Functions defined in this file:
X */
Xstatic void initGraphics(), initWidgets();
Xstatic void quit(), update(), info(), reinit(), cd(), cmd();
Xstatic void timeoutProc();
Xstatic void syntax();
Xvoid fail();
X
X/*
X * Action binding table
X */
Xstatic XtActionsRec cmdActionsTable[] = {
X    { "xmon-update", update },
X    { "xmon-quit", quit },
X    { "xmon-info", info },
X    { "xmon-reinit", reinit },
X    { "xmon-cd", cd },
X    { "xmon-cmd", cmd },
X};
X
X/*
X * Global widget data
X */
XWidget toplevel,faceBox,infoLabel,radioGroup;
XAppResources appResources;
Xstatic XtAppContext app_con;
Xstatic XtIntervalId interval;
X
X/*
X * Global graphics data
X */
XGC gc;
X
X/*
X * Other global data
X */
Xchar *program;
X
X/*
X *	Non-widget resources obtained from resource manager
X */
Xstatic XtResource resources[] = {
X    { "addNames", "AddNames", XtRBoolean, sizeof(Boolean),
X      XtOffset(AppResources *,addNames), XtRImmediate, False },
X    { "opaqueNames", "OpaqueNames", XtRBoolean, sizeof(Boolean),
X      XtOffset(AppResources *,opaqueNames), XtRImmediate, False },
X    { "smallFont", "SmallFont", XtRFont, sizeof(Font),
X      XtOffset(AppResources *,smallFont), XtRString, SMALLFONT },
X    { "updateInterval", "UpdateInterval", XtRInt, sizeof(int),
X      XtOffset(AppResources *,updateInterval), XtRImmediate, (XtPointer)60 },
X    { "faceDirectory", "FaceDirectory", XtRString, sizeof(String),
X      XtOffset(AppResources *,faceDirectory), XtRImmediate, FACEDIR },
X    { "updateCommand", "UpdateCommand", XtRString, sizeof(String),
X      XtOffset(AppResources *,updateCommand), XtRImmediate, UPDATECOMMAND },
X    { "updateCursor", "UpdateCursor", XtRCursor, sizeof(Cursor),
X      XtOffset(AppResources *,updateCursor), XtRString, UPDATECURSOR },
X    { "nameCommand", "nameCommand", XtRString, sizeof(String),
X      XtOffset(AppResources *,nameCommand), XtRImmediate, NULL },
X    { "debug", "Debug", XtRBoolean, sizeof(Boolean),
X      XtOffset(AppResources *,debug), XtRImmediate, False },
X    { "revision", "Revision", XtRString, sizeof(String),
X      XtOffset(AppResources *,revision), XtRImmediate, "" },
X    { "widgets", "Widgets", XtRString, sizeof(String),
X      XtOffset(AppResources *,widgets), XtRImmediate, "" },
X};
X
X/*
X *	Non-widget resources settable on command line.
X */
Xstatic XrmOptionDescRec options[] = {
X    { "-addNames",	".addNames",	XrmoptionNoArg,		"True" },
X    { "-opaqueNames",	".opaqueNames",	XrmoptionNoArg,		"True" },
X    { "-smallFont",	".smallFont",	XrmoptionSepArg,	SMALLFONT },
X    { "-updateInterval",".updateInterval",XrmoptionSepArg,	"60" },
X    { "-faceDirectory",	".faceDirectory",XrmoptionSepArg,	FACEDIR },
X    { "-updateCommand",	".updateCommand",XrmoptionSepArg,	UPDATECOMMAND},
X    { "-nameCommand",	".nameCommand",	XrmoptionSepArg,	NULL},
X    { "-debug",		".debug",	XrmoptionNoArg,		"True"},
X};
X
X/*
X *	Widget and non-widget resources if the application defaults
X *	file can't be found.
X *	[ Generated automatically from Xmon.ad. ]
X */
Xstatic String fallbackResources[] = {
X#include "Xmon.ad.h"
X	NULL
X};
X
X/*	-	-	-	-	-	-	-	-	*/
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X    program = *argv;
X    initGraphics(argc,argv);
X    initWidgets();
X    initMemory();
X    XtRealizeWidget(toplevel);
X    updateFaces();
X    if (appResources.updateInterval != 0)
X	interval = XtAppAddTimeOut(app_con,appResources.updateInterval*1000,
X							timeoutProc,NULL);
X    XtAppMainLoop(app_con);
X}
X
Xstatic void
XinitGraphics(argc,argv)
Xint argc;
Xchar **argv;
X{
X    XGCValues gcvals;
X    char *rev,*strchr();
X
X    toplevel = XtAppInitialize(&app_con, "Xmon",
X			       options, XtNumber(options),
X			       &argc,argv,fallbackResources,NULL,ZERO);
X    XtGetApplicationResources(toplevel,(XtPointer)&appResources,
X                              resources,XtNumber(resources),NULL,ZERO);
X    rev = strchr(fallbackResources[0],'$');
X    if (strcmp(appResources.revision,rev) != 0) {
X	fprintf(stderr,"%s: app-defaults release not %s\n",program,rev);
X	fprintf(stderr,"%s: you may have an outdated app-defaults file\n",
X								program);
X    }
X    XtAppAddActions(app_con,cmdActionsTable,XtNumber(cmdActionsTable));
X    if (argc != 1) {
X	syntax(argc,argv);
X	XtDestroyApplicationContext(app_con);
X	exit(1);
X    }
X    gc = XDefaultGC(XtDisplay(toplevel),
X				XScreenNumberOfScreen(XtScreen(toplevel)));
X    XSetFont(XtDisplay(toplevel),gc,appResources.smallFont);
X}
X
Xstatic void
XinitWidgets()
X{
X    char name[32],class[32],parent[32];
X    char *s;
X    int i;
X    Boolean isShell;
X    WidgetClass wc;
X    Widget w;
X
X    if ((s=appResources.widgets) == NULL)
X	fail("no widgets specified!\n","");
X    while (*s) {
X        while (isspace(*s))
X            s += 1;
X	if (!*s)
X	    break;
X        i = 0;
X        while (*s && !isspace(*s))
X            class[i++] = *s++;
X        class[i] = '\0';
X        while (isspace(*s))
X            s += 1;
X        i = 0;
X        while (*s && !isspace(*s))
X            name[i++] = *s++;
X        name[i] = '\0';
X        while (isspace(*s))
X            s += 1;
X        i = 0;
X        while (*s && !isspace(*s))
X            parent[i++] = *s++;
X        parent[i] = '\0';
X	isShell = False;
X        if ((wc=classNameToWidgetClass(class,&isShell)) == NULL)
X	    fail("can't convert string \"%s\" to widgetClass\n",class);
X	if (strcmp(parent,"toplevel") == 0)
X	    w = toplevel;
X	else if ((w=XtNameToWidget(toplevel,parent)) == NULL)
X	    fail("can't convert string \"%s\" to widget\n",parent);
X	if (isShell)
X            w = XtCreatePopupShell(name,wc,w,NULL,ZERO);
X        else
X            w = XtCreateManagedWidget(name,wc,w,NULL,ZERO);
X    }
X    if ((faceBox=XtNameToWidget(toplevel,"*faceBox")) == NULL)
X	fail("didn't create widget \"faceBox\"\n","");
X    if ((infoLabel=XtNameToWidget(toplevel,"*infoLabel")) == NULL)
X	fail("didn't create widget \"infoLabel\"\n","");
X}
X
X/*	-	-	-	-	-	-	-	-	*/
X/* Action procedures */
X
X/*
X * Default action for "quit" button: destroys application.
X */
Xstatic void
Xquit(w,event,params,num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X    XtDestroyApplicationContext(app_con);
X    exit(0);
X}
X
X/*
X * Default action for all "face" buttons: sets infoLabel.
X */
Xstatic void
Xinfo(w,event,params,num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X    Arg arg[1];
X
X    if ((w=(Widget)XawToggleGetCurrent(radioGroup)) == NULL)
X	XtSetArg(arg[0],XtNlabel,"");
X    else
X	XtSetArg(arg[0],XtNlabel,getTextFromWidget(w));
X    XtSetValues(infoLabel,arg,ONE);
X}
X
X/*
X * Default action for "update" button: Sets all buttons and resets timer.
X */
Xstatic void
Xupdate(w,event,params,num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X    updateFaces();
X    if (appResources.updateInterval != NULL) {
X	XtRemoveTimeOut(interval);
X	interval = XtAppAddTimeOut(app_con,appResources.updateInterval*1000,
X							timeoutProc,NULL);
X    }
X}
X
X/*
X * Forget the bitmaps
X */
Xstatic void
Xreinit(w,event,params,num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X    if (radioGroup != NULL)
X	XawToggleUnsetCurrent(radioGroup);
X    clearBitmapCache();
X    update(w,event,params,num_params);
X}
X
X/*
X * Change directory
X */
Xstatic void
Xcd(w,event,params,num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X    char *text,dirname[256];
X    int i;
X
X    text = getTextFromWidget((Widget)XawToggleGetCurrent(radioGroup));
X    if (text == NULL)
X	return;
X    i = 0;
X    while (*text && !isspace(*text) && i < 255)
X	dirname[i++] = *text++;
X    dirname[i] = '\0';
X    if (chdir(dirname) < 0)
X	fprintf(stderr,"%s: couldn't cd to \"%s\"\n",program,dirname);
X}
X
X/*
X * General action function for user translations
X *	Only test for a selection if the fields are needed.
X */
Xstatic char buf[1024];
X
Xstatic void cmd(w,event,params,num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X    char *s,*t,*text;
X    int i,field,f,seenDollar,hadBracket;
X
X    if (*num_params < ONE)
X	return;
X    text = getTextFromWidget((Widget)XawToggleGetCurrent(radioGroup));
X    s = *params;
X    i = 0;
X    seenDollar = 0;
X    while (*s) {
X	if (*s == '$') {
X	    if (seenDollar) {
X		buf[i++] = *s;
X		seenDollar = False;
X	    } else {
X		seenDollar = True;
X	    }
X	    s += 1;
X	} else if (seenDollar && (*s == '{' || isdigit(*s))) {
X	    if (text == NULL)
X		return;
X	    field = 0;
X	    if ((hadBracket = (*s == '{')))
X		s += 1;
X	    while (*s && isdigit(*s))
X		field = field * 10 + *s++ - '0';
X	    if (hadBracket) {
X		if (*s != '}') {
X		    fprintf(stderr,"bad field in cmd: \"%s\"\n",*params);
X		    return;
X		} else
X		    s += 1;
X	    }
X	    if (field == 0) {
X		t = text;
X		while (*t)
X		    buf[i++] = *t++;
X	    } else {
X		t = text;
X		f = 1;
X		while (*t && f < field)
X		    if (isspace(*t)) {
X			while (*t && isspace(*t))
X			    t += 1;
X			f += 1;
X		    } else
X			t += 1;
X		if (*t != '\0')
X		    while (*t && !isspace(*t))
X			buf[i++] = *t++;
X	    }
X	    seenDollar = False;
X	} else {
X	    if (seenDollar) {
X		buf[i++] = '$';
X		seenDollar = False;
X	    }
X	    buf[i++] = *s++;
X	}
X    }
X    if (seenDollar)
X	buf[i++] = '$';		/* final $ if needed */
X    buf[i] = '\0';
X    if (appResources.debug)
X	printf("cmd: \"%s\"\n",buf);
X    else
X	system(buf);
X}
X
X/*	-	-	-	-	-	-	-	-	*/
X/*
X * Callback for timer: Sets all buttons and schedules next update.
X */
Xstatic void
XtimeoutProc(client_data,id)
XXtPointer client_data;
XXtIntervalId *id;
X{
X    updateFaces();
X    interval = XtAppAddTimeOut(app_con,appResources.updateInterval*1000,
X							timeoutProc,NULL);
X}
X
X/*	-	-	-	-	-	-	-	-	*/
X/*
X *	syntax() : print the usage message.
X */
Xstatic void
Xsyntax(argc,argv)
Xint argc;
Xchar **argv;
X{
X    argv += 1;
X    if (argc == 2)
X	fprintf(stderr,"%s: bad argument: %s\n",program,*argv);
X    else {
X	fprintf(stderr,"%s: bad arguments: ",program);
X	while (--argc)
X	    fprintf(stderr,"%s ",*argv++);
X	fprintf(stderr,"\n");
X    }
X    fprintf(stderr,"usage: %s\t-addNames\t\tadd labels to icons\n",program);
X    fprintf(stderr,"\t\t-opaqueNames\t\tprint labels opaquely\n");
X    fprintf(stderr,"\t\t-updateInterval N\tseconds between updates\n");
X    fprintf(stderr,"\t\t-faceDirectory dir\tlocation of icons\n");
X    fprintf(stderr,"\t\t-updateCommand cmd\tcommand to monitor\n");
X    fprintf(stderr,"\t\t-nameCommand cmd\tcommand to map names to icons\n");
X    fprintf(stderr,"\t\t-debug\t\t\tprint command instead of executing\n");
X}
X
X/*
X *	fail() : Print a message and die.
X */
Xvoid
Xfail(fmt,arg)
Xchar *fmt,*arg;
X{
X    fprintf(stderr,fmt,arg);
X    XtDestroyApplicationContext(app_con);
X    exit(1);
X}
X
END_OF_FILE
if test 11059 -ne `wc -c <'xmon.c'`; then
    echo shar: \"'xmon.c'\" unpacked with wrong size!
fi
# end of 'xmon.c'
fi
if test -f 'xmon.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xmon.man'\"
else
echo shar: Extracting \"'xmon.man'\" \(10663 characters\)
sed "s/^X//" >'xmon.man' <<'END_OF_FILE'
X.\"
X.\"	Xmon : Graphically monitor a list
X.\"
X.\"	George Ferguson, ferguson@cs.rochester.edu,  4 May 1990.
X.\"
X.\"	$Id: xmon.man,v 1.2 90/08/21 11:11:25 ferguson Exp $
X.\"
X.TH XMON 1 "7/8/90"
X.ds ]W U of Rochester
X.SH NAME
Xxmon, xru, xrf, xls, xfrom \- graphical list monitors for users, hosts, files, or mail
X.sp
X.SH SYNOPSIS
X.B xmon
X[ X Toolkit options ]
X[ -addNames ]
X[ -opaqueNames ]
X.br
X\ \ \ \ \ [ -smallFont font ]
X[ -faceDirectory dir ]
X.br
X\ \ \ \ \ [ -updateInterval N ]
X[ -updateCommand cmd ]
X.br
X\ \ \ \ \ [ -debug ]
X.br
X.B xru
X\- display who's on the system
X.br
X.B xrf
X\- display free machines on the network
X.br
X.B xls
X\- display the contents of a directory
X.br
X.B xfrom
X\- display whom mail is from
X.sp
X.SH DESCRIPTION
X.PP
XXmon is a tool which graphically monitors a list of names. That is, it
Xperiodically runs a command and interprets the command's output as a list
Xof items to display iconically. It provides a fully-customizable
Xwidget interface, custom creation and mapping of widgets at run-time, and
Xhooks for arbitrary action bindings. Appropriate defaults are provided for
Xthe uninterested user
X.PP
XSeveral programs have been built on top of xmon using the customizations
Xdescribed below. These are
X.BR xru ,
X.BR xrf ,
X.B xls
Xand
X.BR xfrom .
X.sp
X.SH OPTIONS
X.PP
XThe following non-widget resources can be set on the command line as well
Xas in a resource file.
X.IP "\fB-addNames\fP
XAlways add user's name to their icon. The default is to only add names for
Xusers without icons, since they share the same default icon.
X.IP "\fB-opaqueNames\fP
XDraw names opaquely, ie. so that the background of the icon does not show
Xthrough. This is the default, for readability.
X.IP "\fB-smallFont\fP font"
XSpecify the font used for drawing names on icons. It defaults to 8-point
XCourier.
X.IP "\fB-faceDirectory\fP dir"
XSpecify where to look for face icons. See below under FILES for the
Xdefault.
X.IP "\fB-updateInterval\fP secs"
XSpecify how long to wait between updates. Default is 60 seconds. A value of 0
X(zero) means no automatic updating.
X.IP "\fB-updateCommand\fP cmd"
XSpecify the command to run to do updates. This had better have the username
X(or whatever you want the icons indexed by) in the first field, one item
Xper line.
X.IP "\fB-nameCommand\fP cmd"
XSpecify the command to run to map user names to icon names. This should be
Xa program which reads user names one per line from stdin and outputs the
Xcorresponding icon namee to stdout followed by newline. It should exit
Xwhen EOF is reached on stdin.
X.IP "\fB-debug\fP
XCommands invoked via the xmon-cmd() action are simply printed to stdout, rather
Xthan executed by the shell. In addition, the updateCommand and nameCommand
X(if there is one) are printed before being invoked.
XThis useful for debugging custom application
Xdefaults files.
X.sp
X.SH "REGISTERING YOUR FACE ICON"
X.PP
XCreate a 32x32 icon with the bitmap editor by doing
X
X.nf
X	% bitmap /u/ferguson/lib/images/\fBmyname\fP 32x32
X.fi
X
X(where
X.B myname
Xis your name) and save it with the "Write Output" button. For programs such
Xas xrf, faces must be created by the xmon administrator to represent
Xnon-user icons.
X.sp
X.SH "DERIVED TOOLS"
X.PP
XAs mentioned above, several programs have been built using xmon to monitor
Xdifferent lists; these will be described below. All the applications are of
Xclass
X.B Xmon
Xand so use the default application-defaults file. You can invoke the
Xmore specific defaults by either (a) invoking xmon through an approriately
Xnamed symbolic link (e.g. xru), or (b) by using the
X.B -name
Xtoolkit option (e.g. xmon -name xru).
X.SH Xru
X.PP
XThis tool continually monitors the output of an rwho(1)-style program
Xcalled ru(1) (a shell script, ru-awk, is provided for use in place of ru if
Xyour site lacks it). The default buttons invoke talk(1) or finger(1) on the
Xselected username, or w(1) on the machine corresponding to the selected
Xuser.
XBy default the keys T, F, and W do the same when typed in a faceButton.
XIn all cases the output is to an xterm window.
XThe default updateInterval for xru is 60 seconds and addNames is False.
X.SH Xrf
X.PP
XThis tool displays "idle" machines on the network using ruptime(1)-style
Xinformation from either rf(1) or a script which mimics its behaviour (rf-awk).
XThe default buttons invoke rlogin(1), finger(1), or w(1) on the selected
Xmachine in an xterm window. By default the display is only updated when
Xthe Update button is clicked (updateInterval is 0) and addNames is True.
X.SH Xls
X.PP
XThis tool provides a graphical filesystem browser by using the output
Xof ls(1). The Ls-lg and File buttons pop up small xterms with additional
Xinformation about the selected file; the Cd button changes the current
Xdirectory to the selected one and displays the new files.
XClicking the middle mouse button on
Xa face "launches" that file: if it's a directory then a new xls is opened
Xin that directory; if it's an executable file then it is executed;
Xotherwise the file is paged in an xterm. Users can customize this
Xbehaviour by modifying the default script "xls-cmd" (see FILES)
Xand changing the program called by xmon-cmd() in the translations
Xresources (see CUSTOMIZING). Updates are manual as for xrf.
X.PP
XThis tool illustrates the use of the
X.B nameCommand
Xresource to map user names to icon names. If this resource is non-empty
Xthen that command is started for each update. It should read user names
Xone per line from stdin and output the corresponding icon name to stdout
X(followed by newline).
XIt should exit after EOF on stdin. The default nameCommand is a script
X(name2icon)
Xwhich maps certain types of files (e.g. directories, executables, C code)
Xto special icons, and all other files to a default icon. This can be
Xcustomized by copying and changing the script (see FILES).
X.SH Xfrom
X.PP
XThis tool monitors your mailbox and displays whom mail is from using
Xsed(1) on your system mailbox (by default). The default buttons provide
Xeither an xterm with Mail(1) running in it, or an xterm with Mail
Xinvoked to send to the selected user. Updates are every 2 minutes by
Xdefault and addNames is False.
X.sp
X.SH "CUSTOMIZING XMON"
X.PP
XXmon and the tools built on it have default resources built in.
XIf you wish to customize the
Xtool, take a copy of the default application defaults file (see
XFILES) and modify it. Then, before invoking xmon, set the environment variable
X.B XAPPLRESDIR
Xto the directory containing your private copy. Alternatively, you can place
Xentries in your .Xdefaults file or provide them with the -xrm toolkit
Xoption.
X.SH "Widget hierarchy"
X.PP
XXmon uses standard Athena widgets which can be customized as usual and
Xin addition xmon allows you to explicitly specify the desired widget
Xhierarchy. The resource entry
X.B widgets
Xshould be a string consisting of triples specifying the widget class,
Xwidget name, and parent widget name of each widget desired. They will be
Xcreated as listed in the resource, so arbitrary relationships can be set
Xup. Each widget's properties can then be set using other resource entries
Xspecific to that widget.
X.PP
XThe default widget hierarchy provides some buttons across the top, a label
Xfor displaying information, and a viewport with a box inside it for
Xdisplaying the faces. The resource entry to specify this looks like:
X
X.nf
X.na
XXmon.widgets: \e
X        Form            form            toplevel \en\e
X        Command         quitbutton      form \en\e
X        Label           infoLabel       form \en\e
X        Viewport        view            form \en\e
X        Box             faceBox         form.view
X.ad
X.fi
X
X.PP
XYou must create at least the widgets
X.B infoLabel
Xand
X.B faceBox
X(with those names) since they are used by the action procedures. Note also
Xthat parent widget names should be given in a form acceptable to
XXtNameToWidget(3X).
X.sp
X.SH "Translation Actions"
X.PP
XThe following action procedures are registered for xmon and can be bound
Xto widget events using the
X.B translations
Xresource (see the Xt manual, Appendix C).
X.IP \fBxmon-quit()\fP
XDestroy the tool and exit with status 0.
X.IP \fBxmon-update()\fP
XExecute the updateCommand and refresh the faces.
X.IP \fBxmon-reinit()\fP
XXmon caches the bitmaps used for the faces to avoid having to call
XXReadBitmapFromFile(3X) many times on each update. This action causes xmon
Xto forget the cached bitmaps and reread them, and also refreshes the faces
Xto reflect the new bitmaps.
X.IP \fBxmon-info()\fP
XThis is the default action for clicking on a "face".
XIt places the text associated with the currently selected face
X(ie. the line of output from the updateCommand)
Xin the infoLabel, or clears the infoLabel if no face is selected.
XWhen customizing this, make sure appropriate calls to
X.B set()
Xor
X.B toggle()
X(see the Athena widgets manual) are placed before the call to xmon-info()
Xto ensure that the right info is obtained.
X.IP \fBxmon-cd()\fP
XChanges directory to the filename given by the first word of the text
Xassociated with the currently selected face. This action is used by xls
Xto change directory without forking a new copy of itself (since xmon-cmd()
Xactions are executed in a subshell, this must be built-in).
X.IP \fBxmon-cmd()\fP
XThis command is a hook for translations, particularly for face command buttons.
XThis action should be passed a single string, use double-quotes
Xto escape spaces. Any instances of "$<num>" or "${<num>}", where
X"<num>" is a sequence of digits, is replaced with the corresponding
Xfield from the face's text (ie. the text that would appear in
Xthe "infoLabel" if xmon-info() was executed when that face was selected).
XTo escape such a sequence, use two dollar signs.
XThe resulting string is then passed to sh(1) for execution. Make sure that
Xthe command is explicitly backgrounded (ie. ends with ampersand "&") if
Xyou don't want xmon to block while the command is being executed.
X.sp
X.SH ENVIRONMENT
X.PP
XXAPPLRESDIR	- Directory containing xmon resource file
X.sp
X.SH FILES
X.PP
X.nf
X.na
X/u/ferguson/lib/app-defaults/Xmon	- default xmon resource file
X/u/ferguson/lib/images/<username>	- xmon face icons
X/u/ferguson/lib/xmon/xls-cmd		- "launch" files for xls
X/u/ferguson/lib/xmon/name2icon	- map filenames to icon names
X/u/ferguson/lib/xmon/ru-awk		- list users
X/u/ferguson/lib/xmon/rf-awk		- list free machines
X.ad
X.fi
X.sp
X.SH BUGS
X.PP
XResizing the application bigger can result in some faces reappearing.
XThis is due to the XToolkit remapping widgets which were unmapped when
Xthe number of faces to display dropped. Invoking xmon-update() clears
Xthem up.
X.sp
X.SH "SEE ALSO"
X.PP
XX(1),
Xru(1),
Xrwho(1),
Xrf(1),
Xruptime(1),
Xls(1),
Xsed(1),
XMail(1).
X.sp
X.SH AUTHOR
X.PP
XGeorge Ferguson, University of Rochester
X.br
X(ferguson@cs.rochester.edu)
END_OF_FILE
if test 10663 -ne `wc -c <'xmon.man'`; then
    echo shar: \"'xmon.man'\" unpacked with wrong size!
fi
# end of 'xmon.man'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
George Ferguson			ARPA: ferguson@cs.rochester.edu
University of Rochester		UUCP: {decvax,rutgers}!rochester!ferguson
Rochester  NY  14627		VOX:  (716) 275-2527