v04i098: xf -- display a list of filenames, Part01/02

Dan Heller argv at island.uu.net
Thu Sep 7 19:25:28 AEST 1989


Submitted-by: garys at earth.cchem.Berkeley.EDU (Gary Shea)
Posting-number: Volume 4, Issue 98
Archive-name: xf/part01

#! /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 1 (of 2)."
# Contents:  Imakefile README Set.c Set.h SetP.h Xf.ad global.c
#   global.h xf.c xf.h xf.man
# Wrapped by garys at earth on Sat Aug  5 17:57:53 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(265 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X
X       INCLUDES = -I$(TOP) -I$(AWIDGETSRC) -I$(TOOLKITSRC)
XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
X
X           SRCS = Set.c dir.c global.c x.c xf.c
X           OBJS = Set.o dir.o global.o x.o xf.o
X
XComplexProgramTarget(xf)
XInstallAppDefaults(Xf)
X
END_OF_FILE
if test 265 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1035 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis is xf(1), an X11R3 utility for generating lists of filenames.
XIt is useful as a keyboard-replacement when selecting files to
Xdelete, copy, tar, etc..  Some examples of xf(1) usage are:
X
X403 % rm `xf /data/x11r3/stuff`
X404 % cp `xf ../xwatch` .
X405 % foreach f (`xf /usr/man/man1`)
X? troff -man $f | lpr -Plz -t
X? end
X
XXf(1) is written primarily in ANSI C, except for the Set widget
X(a corruption of the Athena List widget) which remains in the original
Xpcc dialect.  The code assumes the existence of the POSIX-standard
Xdirectory-access routines (present on many modern workstations with
Xrecent OS releases ;^), and uses the getopt(1) routine to parse
Xthe (currently few) command line arguments.  Getopt(1) and the
XPOSIX directory-access routines are available from the
Xcomp.sources.unix archives.
X
XIf you find bugs or have suggestions for improvement of the xf(1)
Xprogram, please notify me and I will make appropriate changes
Xin future releases of xf(1).
X
XGary Shea
XDep't of Chemistry, UC Berkeley
Xgarys at earth.cchem.berkeley.edu
END_OF_FILE
if test 1035 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Set.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Set.c'\"
else
echo shar: Extracting \"'Set.c'\" \(28746 characters\)
sed "s/^X//" >'Set.c' <<'END_OF_FILE'
X#if ( !defined(lint))
X  static char rcsid[] = "$Header: Set.c,v 1.3 89/07/17 07:18:56 garys Exp $";
X#endif
X
X/*  This is the Set widget, it is useful to display a set, without the
X *  overhead of having a widget for each item in the set.  It allows 
X *  the user to select an item in a set and notifies the application through
X *  a callback function.
X *
X *	Created: 	8/13/88
X *	By:		Chris D. Peterson
X *                      MIT - Project Athena
X *	Modified: 	7/17/89
X *	By:		Gary Shea
X *                      UC Berkeley, Dept. of Chemistry
X *	
X */
X
X/***********************************************************
XCopyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X
X                        All Rights Reserved
X
XPermission to use, copy, modify, and distribute this software and its 
Xdocumentation for any purpose and without fee is hereby granted, 
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in 
Xsupporting documentation, and that the names of Digital or MIT not be
Xused in advertising or publicity pertaining to distribution of the
Xsoftware without specific, written prior permission.  
X
XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
X******************************************************************/
X
X/*
X * Set.c - Set widget
X *
X */
X
X#include <X11/IntrinsicP.h>
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <ctype.h>
X#include <X11/StringDefs.h>
X#include "SetP.h"
X
X# define XTPAUSE_COUNT	100000
X
Xchar * malloc();
X
X/* 
X * Default Translation table.
X */
X
Xstatic char defaultTranslations[] =  
X   "<Btn1Down>:   Toggle() NotifyA()";
X
X/****************************************************************
X *
X * Full class record constant
X *
X ****************************************************************/
X
X/* Private Data */
X
X#define offset(field) XtOffset(SetWidget, field)
X
Xstatic XtResource resources[] = {
X    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
X	offset(set.foreground), XtRString, "XtDefaultForeground"},
X    {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
X       offset(simple.cursor), XtRString, "left_ptr"},
X    {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
X	offset(set.font),XtRString, "XtDefaultFont"},
X    {XtNset, XtCSet, XtRPointer, sizeof(XtSetReturnStruct **),
X       offset(set.set), XtRString, NULL},
X    {XtNdefaultColumns, XtCColumns, XtRInt,  sizeof(int),
X	offset(set.default_cols), XtRImmediate, (caddr_t)2},
X    {XtNlongest, XtCLongest, XtRInt,  sizeof(int),
X	offset(set.longest), XtRImmediate, (caddr_t)0},
X    {XtNnumberStrings, XtCNumberStrings, XtRInt,  sizeof(int),
X	offset(set.nitems), XtRImmediate, (caddr_t)0},
X    {XtNforceColumns, XtCColumns, XtRBoolean,  sizeof(Boolean),
X	offset(set.force_cols), XtRString, (caddr_t) "False"},
X    {XtNverticalSet, XtCBoolean, XtRBoolean,  sizeof(Boolean),
X	offset(set.vertical_cols), XtRString, (caddr_t) "False"},
X    {XtNinternalWidth, XtCWidth, XtRDimension,  sizeof(Dimension),
X	offset(set.internal_width), XtRImmediate, (caddr_t)4},
X    {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
X	offset(set.internal_height), XtRImmediate, (caddr_t)2},
X    {XtNcolumnSpacing, XtCSpacing, XtRDimension,  sizeof(Dimension),
X	offset(set.column_space), XtRImmediate, (caddr_t)6},
X    {XtNrowSpacing, XtCSpacing, XtRDimension,  sizeof(Dimension),
X	offset(set.row_space), XtRImmediate, (caddr_t)2},
X    {XtNcallbackA, XtCCallback, XtRCallback, sizeof(caddr_t),
X        offset(set.callbackA), XtRCallback, NULL},
X    {XtNcallbackB, XtCCallback, XtRCallback, sizeof(caddr_t),
X        offset(set.callbackB), XtRCallback, NULL},
X    {XtNcallbackC, XtCCallback, XtRCallback, sizeof(caddr_t),
X        offset(set.callbackC), XtRCallback, NULL},
X};
X
Xstatic void Initialize();
Xstatic void ChangeSize();
Xstatic void Resize();
Xstatic void Redisplay();
Xstatic Boolean Layout();
Xstatic XtGeometryResult PreferredGeom();
Xstatic Boolean SetValues();
Xstatic void Notify(), NotifyA(), NotifyB(), NotifyC(), Toggle(), Flash() ;
X
X/* Late additions.  Why aren't these already static? */
X
Xstatic Boolean ItemInRectangle();
Xstatic void FindCornerItems();
Xstatic void PaintItemName();
Xstatic void HighlightBackground();
X
Xstatic XtActionsRec actions[] = {
X      {"NotifyA",         NotifyA},
X      {"NotifyB",         NotifyB},
X      {"NotifyC",         NotifyC},
X      {"Toggle",          Toggle},
X      {"Flash",           Flash},
X      {NULL,NULL}
X};
X
Xstatic XtSetDataStruct		noSetSoln ;
Xstatic XtSetDataStruct		*noSetSolnPtr = &noSetSoln ;
X
XSetClassRec setClassRec = {
X  {
X/* core_class fields */	
X#define superclass		(&simpleClassRec)
X    /* superclass	  	*/	(WidgetClass) superclass,
X    /* class_name	  	*/	"Set",
X    /* widget_size	  	*/	sizeof(SetRec),
X    /* class_initialize   	*/	NULL,
X    /* class_part_initialize	*/	NULL,
X    /* class_inited       	*/	FALSE,
X    /* initialize	  	*/	Initialize,
X    /* initialize_hook		*/	NULL,
X    /* realize		  	*/	XtInheritRealize,
X    /* actions		  	*/	actions,
X    /* num_actions	  	*/	XtNumber(actions),
X    /* resources	  	*/	resources,
X    /* num_resources	  	*/	XtNumber(resources),
X    /* xrm_class	  	*/	NULLQUARK,
X    /* compress_motion	  	*/	TRUE,
X    /* compress_exposure  	*/	FALSE,
X    /* compress_enterleave	*/	TRUE,
X    /* visible_interest	  	*/	FALSE,
X    /* destroy		  	*/	NULL,
X    /* resize		  	*/	Resize,
X    /* expose		  	*/	Redisplay,
X    /* set_values	  	*/	SetValues,
X    /* set_values_hook		*/	NULL,
X    /* set_values_almost	*/	XtInheritSetValuesAlmost,
X    /* get_values_hook		*/	NULL,
X    /* accept_focus	 	*/	NULL,
X    /* version			*/	XtVersion,
X    /* callback_private   	*/	NULL,
X    /* tm_table		   	*/	defaultTranslations,
X   /* query_geometry		*/      PreferredGeom,
X  }
X};
X
XWidgetClass setWidgetClass = (WidgetClass)&setClassRec;
X
X/****************************************************************
X *
X * Private Procedures
X *
X ****************************************************************/
X
Xstatic void GetGCs(w)
XWidget w;
X{
X    XGCValues	values;
X    SetWidget lw = (SetWidget) w;    
X
X# ifdef OLD_WAY
X    values.foreground	= lw->set.foreground;
X    values.font		= lw->set.font->fid;
X
X    lw->set.normgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
X				 &values);
X
X    values.foreground	= lw->core.background_pixel;
X
X    lw->set.revgc = XtGetGC(w, (unsigned) GCForeground | GCFont,
X				 &values);
X# else
X    values.font		= lw->set.font->fid;
X    values.foreground	= lw->core.background_pixel;
X
X    lw->set.normgc = XtGetGC(w, (unsigned) GCFont | GCForeground,
X				 &values);
X
X    values.foreground	= lw->set.foreground;
X
X    lw->set.revgc = XtGetGC(w, (unsigned) GCForeground,
X				 &values);
X# endif
X
X    values.foreground = lw->set.foreground;
X    values.tile       = XtGrayPixmap(XtScreen(w));
X    values.fill_style = FillTiled;
X
X    lw->set.graygc = XtGetGC(w, (unsigned) GCForeground | GCFont |
X			      GCTile | GCFillStyle, &values);
X}
X
X/*	Function Name: ResetSet
X *	Description: Resets the new set when important things change.
X *	Arguments: w - the widget.
X *                 changex, changey - allow the height or width to change?
X *	Returns: none.
X */
X
Xstatic void
XResetSet(w, changex, changey)
XWidget w;
XBoolean changex, changey;
X{
X    SetWidget lw = (SetWidget) w;
X    int width = w->core.width;
X    int height = w->core.height;
X
X    if (lw->set.nitems == 0)	/* Get number of items. */
X        while (lw->set.set[lw->set.nitems] != NULL)
X	    lw->set.nitems++;
X
X    if (lw->set.longest == 0) { /* Get column width. */
X        int i, len, max;
X        for ( i = 0, max = 0; i < lw->set.nitems; i++) {
X	    len = XTextWidth(lw->set.font, lw->set.set[i]->string,
X			     strlen(lw->set.set[i]->string));
X	    if (len > max)
X	        max = len;
X	}
X        lw->set.col_width = max;
X    }
X    else 
X        lw->set.col_width = lw->set.longest;
X    lw->set.col_width += lw->set.column_space;
X
X    if (Layout(w, changex, changey, &width, &height))
X      ChangeSize(w, width, height);
X}
X
X/*	Function Name: ChangeSize.
X *	Description: Lays out the widget.
X *	Arguments: w - the widget to try change the size of.
X *	Returns: none.
X */
X
Xstatic void
XChangeSize(w, width, height)
XWidget w;
Xint width, height;
X{
X    int w_ret, h_ret;
X
X    (void) Layout(w, FALSE, FALSE, &width, &height);
X
X    switch ( XtMakeResizeRequest(w, width, height, &w_ret, &h_ret) ) {
X    case XtGeometryYes:
X    case XtGeometryNo:
X        break;
X    case XtGeometryAlmost:
X        if (Layout(w, FALSE, FALSE, &width, &height)) {
X            XtWarning("Size Changed when it shouldn't have...");
X	    XtWarning("when initializing the Set Widget");
X	}
X	(void) XtMakeResizeRequest(w, w_ret, h_ret, NULL, NULL);
X	break;
X    default:
X	XtWarning("Unknown geometry return in Set Widget");
X	break;
X    }
X}
X
X/*	Function Name: Initialize
X *	Description: Function that initilizes the widget instance.
X *	Arguments: junk - NOT USED.
X *                 new  - the new widget.
X *	Returns: none
X */
X
X/* ARGSUSED */
Xstatic void 
XInitialize(junk, new)
XWidget junk, new;
X{
X    SetWidget lw = (SetWidget) new;
X
X/* 
X * Initialize all private resources.
X */
X
X    GetGCs(new);
X
X    /* Set row height. */
X    lw->set.row_height = lw->set.font->max_bounds.ascent
X			+ lw->set.font->max_bounds.descent
X			+ lw->set.row_space;
X
X    ResetSet(new, (new->core.width == 0), (new->core.height == 0));
X
X/*
X * Default to the name of the widget as the entire set.
X * A static XtSetDataStruct kept around for just this purpose
X * is used.
X */
X
X    if (lw->set.set == NULL) {
X      lw->set.set = &noSetSolnPtr ;
X      noSetSolnPtr->string = lw->core.name ;
X      lw->set.nitems = 1;
X    }
X
X} /* Initialize */
X
X/*	Function Name: CvtToItem
X *	Description: Converts Xcoord to item number of item containing that
X *                   point.
X *	Arguments: w - the set widget.
X *                 xloc, yloc - x location, and y location.
X *	Returns: the item number.
X */
X
Xstatic int
XCvtToItem(w, xloc, yloc, item)
XWidget w;
Xint xloc, yloc;
Xint *item;
X{
X    int one, another;
X    SetWidget lw = (SetWidget) w;
X    int ret_val = OKAY;
X
X    if (lw->set.vertical_cols) {
X        one = lw->set.nrows * ((xloc - (int) lw->set.internal_width)
X	    / lw->set.col_width);
X        another = (yloc - (int) lw->set.internal_height) 
X	        / lw->set.row_height;
X	 /* If out of range, return minimum possible value. */
X	if (another >= lw->set.nrows) {
X	    another = lw->set.nrows - 1;
X	    ret_val = OUT_OF_RANGE;
X	}
X    }
X    else {
X        one = (lw->set.ncols * ((yloc - (int) lw->set.internal_height) 
X              / lw->set.row_height)) ;
X	/* If in right margin handle things right. */
X        another = (xloc - (int) lw->set.internal_width) / lw->set.col_width;
X	if (another >= lw->set.ncols) {
X	    another = lw->set.ncols - 1; 
X	    ret_val = OUT_OF_RANGE;
X	}
X    }  
X    if ((xloc < 0) || (yloc < 0))
X        ret_val = OUT_OF_RANGE;
X    if (one < 0) one = 0;
X    if (another < 0) another = 0;
X    *item = one + another;
X    if (*item >= lw->set.nitems) return(OUT_OF_RANGE);
X    return(ret_val);
X}
X
X/*	Function Name: FindCornerItems.
X *	Description: Find the corners of the rectangle in item space.
X *	Arguments: w - the set widget.
X *                 event - the event structure that has the rectangle it it.
X *                 ul_ret, lr_ret - the corners ** RETURNED **.
X *	Returns: none.
X */
X
Xstatic void
XFindCornerItems(w, event, ul_ret, lr_ret)
XWidget w;
XXEvent * event;
Xint *ul_ret, *lr_ret;
X{
X    int xloc, yloc;
X
X    xloc = event->xexpose.x;
X    yloc = event->xexpose.y;
X    CvtToItem(w, xloc, yloc, ul_ret);
X    xloc += event->xexpose.width;
X    yloc += event->xexpose.height;
X    CvtToItem(w, xloc, yloc, lr_ret);
X}
X
X/*	Function Name: ItemInRectangle
X *	Description: returns TRUE if the item passed is in the given rectangle.
X *	Arguments: w - the set widget.
X *                 ul, lr - corners of the rectangle in item space.
X *                 item - item to check.
X *	Returns: TRUE if the item passed is in the given rectangle.
X */
X
Xstatic Boolean
XItemInRectangle(w, ul, lr, item)
XWidget w;
Xint ul, lr, item;
X{
X    SetWidget lw = (SetWidget) w;
X    register int mod_item;
X    int things;
X    
X    if (item < ul || item > lr) 
X        return(FALSE);
X    if (lw->set.vertical_cols)
X        things = lw->set.nrows;
X    else
X        things = lw->set.ncols;
X
X    mod_item = item % things;
X    if ( (mod_item >= ul % things) && (mod_item <= lr % things ) )
X        return(TRUE);
X    return(FALSE);
X}
X
X/*	Function Name: HighlightBackground
X *	Description: paints the color of the background for the given item.
X *	Arguments: w - the widget.
X *                 x, y - ul corner of the area item occupies.
X *                 item - the item we are dealing with.
X *                 gc - the gc that is used to paint this rectangle
X *	Returns: none.
X */
X
Xstatic void
XHighlightBackground(w, x, y, item, gc)
XWidget w;
Xint x, y, item;
XGC gc;
X{
X    SetWidget lw = (SetWidget) w;
X    int hl_x, hl_y, width, height;
X
X    hl_x = x - lw->set.column_space/2;
X    width = XTextWidth(lw->set.font, lw->set.set[item]->string,
X			 strlen(lw->set.set[item]->string))
X		     + lw->set.column_space;
X    hl_y = y - lw->set.row_space/2;
X    height = lw->set.row_height + lw->set.row_space;
X
X    XFillRectangle(XtDisplay(w), XtWindow(w), gc, hl_x, hl_y, width, height);
X}
X
X/*	Function Name: PaintItemName
X *	Description: paints the name of the item in the appropriate location.
X *	Arguments: w - the set widget.
X *                 item - the item to draw.
X *	Returns: none.
X */
X
Xstatic void
XPaintItemName(w, item)
XWidget w;
Xint item;
X{
X    char * str;
X    GC gc;
X    int x, y, str_y;
X    SetWidget lw = (SetWidget) w;
X   
X    if (lw->set.vertical_cols) {
X	x = lw->set.col_width * (item / lw->set.nrows)
X	  + lw->set.internal_width;
X        y = lw->set.row_height * (item % lw->set.nrows)
X	  + lw->set.internal_height;
X    }
X    else {
X        x = lw->set.col_width * (item % lw->set.ncols)
X	  + lw->set.internal_width;
X        y = lw->set.row_height * (item / lw->set.ncols)
X	  + lw->set.internal_height;
X    }
X
X    str_y = y + lw->set.font->max_bounds.ascent;
X
X    /* Highly simplified logic for determining highliting...
X    *  hope it's not stupid.
X    */
X
X    if (lw->set.set[item]->is_lit) {
X	gc = lw->set.revgc;
X	HighlightBackground(w, x, y, item, lw->set.revgc);
X	gc = lw->set.normgc;
X    }
X    else {
X	if (XtIsSensitive(w)) 
X	    gc = lw->set.normgc;
X	else
X	    gc = lw->set.graygc;
X	HighlightBackground(w, x, y, item, lw->set.normgc);
X	gc = lw->set.revgc;
X    }
X
X    str =  lw->set.set[item]->string;	/* draw it */
X    XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str));
X}
X    
X/*	Function Name: Redisplay
X *	Description: Repaints the widget window on expose events.
X *	Arguments: w - the set widget.
X *                 event - the expose event for this repaint.
X *                 junk - NOT USED.
X *	Returns: 
X */
X
X/* ARGSUSED */
Xstatic void 
XRedisplay(w, event, junk)
XWidget w;
XXEvent *event;
XRegion junk;
X{
X    int item;			/* an item to work with. */
X    int ul_item, lr_item;       /* corners of items we need to paint. */
X    SetWidget lw = (SetWidget) w;
X
X    if (event == NULL) {	/* repaint all. */
X        ul_item = 0;
X	lr_item = lw->set.nrows * lw->set.ncols - 1;
X	XClearWindow(XtDisplay(w), XtWindow(w));
X    }
X    else
X        FindCornerItems(w, event, &ul_item, &lr_item);
X    
X    for (item = ul_item; (item <= lr_item && item < lw->set.nitems) ; item++)
X      if (ItemInRectangle(w, ul_item, lr_item, item))
X	PaintItemName(w, item);
X}
X
X/*	Function Name: PreferredGeom
X *	Description: This tells the parent what size we would like to be
X *                   given certain constraints.
X *	Arguments: w - the widget.
X *                 intended - what the parent intends to do with us.
X *                 requested - what we want to happen.
X *	Returns: none.
X */
X
Xstatic XtGeometryResult 
XPreferredGeom(w, intended, requested)
XWidget w;
XXtWidgetGeometry *intended, *requested;
X{
X    int width_req, height_req, new_width, new_height;
X    Boolean change;
X    
X    width_req = intended->request_mode & CWWidth;
X    height_req = intended->request_mode & CWHeight;
X    if (width_req)
X      new_width = intended->width;
X    else
X      new_width = w->core.width;
X
X    if (height_req)
X      new_height = intended->height;
X    else
X      new_height = w->core.height;
X
X    requested->request_mode = 0;
X    
X/*
X * We only care about our height and width.
X */
X
X    if ( !width_req && !height_req) {
X      return(XtGeometryYes);
X    }
X    
X    change = Layout(w, !width_req, !height_req, &new_width, &new_height);
X
X    requested->request_mode |= CWWidth;
X    requested->width = new_width;
X    requested->request_mode |= CWHeight;
X    requested->height = new_height;
X
X    if (change)
X        return(XtGeometryAlmost);
X    return(XtGeometryYes);
X}
X
X/*	Function Name: Resize
X *	Description: resizes the widget, by changing the number of rows and
X *                   columns.
X *	Arguments: w - the widget.
X *	Returns: none.
X */
X
Xstatic void
XResize(w)
XWidget w;
X{
X  int width, height;
X
X  width = w->core.width;
X  height = w->core.height;
X
X  if (Layout(w, FALSE, FALSE, &width, &height))
X    XtWarning(
X      "Size Changed when it shouldn't have in Resizing the Set Widget");
X}
X
X/*	Function Name: Layout
X *	Description: lays out the item in the set.
X *	Arguments: w - the widget.
X *                 xfree, yfree - TRUE if we are free to resize the widget in
X *                                this direction.
X *                 width, height - the is the current width and height that 
X *                                 we are going to layout the set widget to,
X *                                 depending on xfree and yfree of course.
X *                               
X *	Returns: TRUE if width or height have been changed.
X */
X
Xstatic Boolean
XLayout(w, xfree, yfree, width, height)
XWidget w;
XBoolean xfree, yfree;
Xint *width, *height;
X{
X    SetWidget lw = (SetWidget) w;
X    Boolean change = FALSE;
X    
X/* 
X * If force columns is set then always use number of columns specified
X * by default_cols.
X */
X
X    if (lw->set.force_cols) {
X        lw->set.ncols = lw->set.default_cols;
X	if (lw->set.ncols <= 0) lw->set.ncols = 1;
X	/* 12/3 = 4 and 10/3 = 4, but 9/3 = 3 */
X	lw->set.nrows = ( ( lw->set.nitems - 1) / lw->set.ncols) + 1 ;
X	if (xfree) {		/* If allowed resize width. */
X	    *width = lw->set.ncols * lw->set.col_width 
X	           + 2 * lw->set.internal_width;
X	    change = TRUE;
X	}
X	if (yfree) {		/* If allowed resize height. */
X	    *height = (lw->set.nrows * lw->set.row_height)
X                    + 2 * lw->set.internal_height;
X	    change = TRUE;
X	}
X	return(change);
X    }
X
X/*
X * If both width and height are free to change the use default_cols
X * to determine the number columns and set new width and height to
X * just fit the window.
X */
X
X    if (xfree && yfree) {
X        lw->set.ncols = lw->set.default_cols;
X	if (lw->set.ncols <= 0) lw->set.ncols = 1;
X	lw->set.nrows = ( ( lw->set.nitems - 1) / lw->set.ncols) + 1 ;
X        *width = lw->set.ncols * lw->set.col_width
X	       + 2 * lw->set.internal_width;
X	*height = (lw->set.nrows * lw->set.row_height)
X                + 2 * lw->set.internal_height;
X	change = TRUE;
X    }
X/* 
X * If the width is fixed then use it to determine the number of columns.
X * If the height is free to move (width still fixed) then resize the height
X * of the widget to fit the current set exactly.
X */
X    else if (!xfree) {
X        lw->set.ncols = (*width - 2 * lw->set.internal_width)
X	               / lw->set.col_width;
X	if (lw->set.ncols <= 0) lw->set.ncols = 1;
X	lw->set.nrows = ( ( lw->set.nitems - 1) / lw->set.ncols) + 1 ;
X	if ( yfree ) {
X  	    *height = (lw->set.nrows * lw->set.row_height)
X		    + 2 * lw->set.internal_height;
X	    change = TRUE;
X	}
X    }
X/* 
X * The last case is xfree and !yfree we use the height to determine
X * the number of rows and then set the width to just fit the resulting
X * number of columns.
X */
X    else if (!yfree) {		/* xfree must be TRUE. */
X        lw->set.nrows = (*height - 2 * lw->set.internal_height) 
X	               / lw->set.row_height;
X	if (lw->set.nrows <= 0) lw->set.nrows = 1;
X	lw->set.ncols = (( lw->set.nitems - 1 ) / lw->set.nrows) + 1;
X	*width = lw->set.ncols * lw->set.col_width 
X	       + 2 * lw->set.internal_width;
X	change = TRUE;
X    }      
X    return(change);
X}
X
X/*	Function Name: Notify
X *	Description: The user callback translations A,B,C each call
X *		   this routine where the callbacks are done.
X *	Arguments: w - the widget that the notify occured in.
X *                 event - event that caused this notification.
X *                 callbackName - The desired user callback.
X *	Returns: none.
X */
X
X/*	Function Name: Notify[ABC]
X *	Description: Calls Notify() with minimal info.
X *	Arguments: w - the widget that the notify occured in.
X *                 event - event that caused this notification.
X *                 params, num_params - not used.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XNotifyA(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X
X# ifdef DEBUG
X    fprintf ( stderr, "\nNotifyA:\n" ) ;
X# endif
X
X    Notify ( w, event, XtNcallbackA ) ;
X}
X
X/* ARGSUSED */
Xstatic void
XNotifyB(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X
X# ifdef DEBUG
X    fprintf ( stderr, "\nNotifyB:\n" ) ;
X# endif
X
X    Notify ( w, event, XtNcallbackB ) ;
X}
X
X/* ARGSUSED */
Xstatic void
XNotifyC(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X
X# ifdef DEBUG
X    fprintf ( stderr, "\nNotifyC:\n" ) ;
X# endif
X
X    Notify ( w, event, XtNcallbackC ) ;
X}
X
X/*	Function Name: Toggle
X *	Description: Toggle the current element.
X *	Arguments: w - the widget that the event occured in.
X *                 event - event that caused this notification.
X *                 params, num_params - not used.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XToggle(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X  SetWidget lw = ( SetWidget ) w;
X  int item;
X
X# ifdef DEBUG
X    fprintf ( stderr, "\nToggle:\n" ) ;
X# endif
X
X/* Find item and if out of range then return. */
X
X  if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
X      == OUT_OF_RANGE)
X    return;
X
X# ifdef DEBUG
X    fprintf ( stderr, "\titem=%d, is_lit=%d:\n",
X	item, lw->set.set[item]->is_lit ) ;
X# endif
X
X  XtSetToggle(w, item);	/* Toggle is_lit state of the item. */
X}
X
X/*	Function Name: Flash
X *	Description: Flash the current element.
X *	Arguments: w - the widget that the event occured in.
X *                 event - event that caused this notification.
X *                 params, num_params - not used.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XFlash(w, event, params, num_params)
XWidget w;
XXEvent * event;
XString * params;
XCardinal *num_params;
X{
X  SetWidget lw = ( SetWidget ) w;
X  int item;
X
X# ifdef DEBUG
X    fprintf ( stderr, "\nFlash:\n" ) ;
X# endif
X
X/* Find item and if out of range then return. */
X
X  if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
X      == OUT_OF_RANGE)
X    return;
X
X# ifdef DEBUG
X    fprintf ( stderr, "\titem=%d, is_lit=%d:\n",
X	item, lw->set.set[item]->is_lit ) ;
X# endif
X
X  XtSetFlash(w, item);	/* Toggle is_lit state of the item. */
X}
X
X/*	Function Name: Notify
X *	Description: The user callback translations A,B,C each call
X *		   this routine where the callbacks are done.
X *	Arguments: w - the widget that the notify occured in.
X *                 event - event that caused this notification.
X *                 callbackName - The desired user callback.
X *	Returns: none.
X */
X
X/* ARGSUSED */
Xstatic void
XNotify(w, event, callbackName)
XWidget w;
XXEvent * event;
XString * callbackName;
X{
X    SetWidget lw = ( SetWidget ) w;
X    int item, item_len;
X    XtSetReturnStruct ret_value;
X
X# ifdef DEBUG
X    fprintf ( stderr, "\nNotify:\n" ) ;
X# endif
X
X/* 
X * Find item and if out of range then return. 
X */
X
X    if ( ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
X	== OUT_OF_RANGE) )
X	    return;
X
X# ifdef DEBUG
X    fprintf ( stderr, "\titem=%d, is_lit=%d:\n",
X	item, lw->set.set[item]->is_lit ) ;
X# endif
X
X/* 
X * Call Callback function.
X */
X
X    ret_value.string = lw->set.set[item]->string;
X    ret_value.index = item;
X    
X    XtCallCallbacks( w, callbackName, (caddr_t) &ret_value);
X}
X
X/*
X * Set specified arguments into widget
X */
X
X/* ARGSUSED */
Xstatic Boolean SetValues(current, request, new)
XWidget current, request, new;
X{
X    SetWidget cl = (SetWidget) current;
X    SetWidget rl = (SetWidget) request;
X    SetWidget nl = (SetWidget) new;
X    Boolean redraw = FALSE;
X
X    if ((cl->set.foreground != rl->set.foreground) ||
X	(cl->core.background_pixel != rl->core.background_pixel) ||
X	(cl->set.font != rl->set.font) ) {
X        XtDestroyGC(cl->set.normgc);
X        XtDestroyGC(cl->set.graygc);
X	XtDestroyGC(cl->set.revgc);
X        GetGCs(new);
X        redraw = TRUE;
X    }
X
X    /* Reset row height. */
X
X    if ((cl->set.row_space != rl->set.row_space) ||
X	(cl->set.font != rl->set.font)) 
X        nl->set.row_height = nl->set.font->max_bounds.ascent
X	                    + nl->set.font->max_bounds.descent
X			    + nl->set.row_space;
X    
X    if ((cl->core.width != rl->core.width)                     ||
X	(cl->core.height != rl->core.height)                   ||
X	(cl->set.internal_width != rl->set.internal_width)   ||
X	(cl->set.internal_height != rl->set.internal_height) ||
X	(cl->set.column_space != rl->set.column_space)       ||
X	(cl->set.row_space != rl->set.row_space)             ||
X	(cl->set.default_cols != rl->set.default_cols)       ||
X	(  (cl->set.force_cols != rl->set.force_cols) &&
X	   (rl->set.force_cols != rl->set.ncols) )           ||
X	(cl->set.vertical_cols != rl->set.vertical_cols)     ||
X	(cl->set.longest != rl->set.longest)                 ||
X	(cl->set.nitems != rl->set.nitems)                   ||
X	(cl->set.font != rl->set.font)                       ||
X	(cl->set.set != rl->set.set)                        ) {
X
X      ResetSet(new, TRUE, TRUE);
X      redraw = TRUE;
X    }
X
X    if ((cl->core.sensitive != rl->core.sensitive) ||
X	(cl->core.ancestor_sensitive != rl->core.ancestor_sensitive)) {
X	redraw = TRUE;
X    }
X    
X    if (!XtIsRealized(current))
X      return(FALSE);
X      
X    return(redraw);
X}
X
X/* Exported Functions */
X
X/*	Function Name: XtSetChange.
X *	Description: Changes the set being used and shown.
X *	Arguments: w - the set widget.
X *                 set - the new set.
X *                 nitems - the number of items in the set.
X *                 longest - the length (in Pixels) of the longest element
X *                           in the set.
X *                 resize - if TRUE the the set widget will
X *                          try to resize itself.
X *	Returns: none.
X *      NOTE:      If nitems of longest are <= 0 then they will be calculated.
X *                 If nitems is <= 0 then the set needs to be NULL terminated.
X */
X
Xvoid
XXtSetChange(w, set, nitems, longest, resize_it)
XWidget w;
XXtSetDataStruct ** set;
Xint nitems, longest;
XBoolean resize_it;
X{
X    SetWidget lw = (SetWidget) w;
X
X    lw->set.set = set;
X
X    if (nitems <= 0) nitems = 0;
X    lw->set.nitems = nitems;
X    if (longest <= 0) longest = 0;
X    lw->set.longest = longest;
X
X    ResetSet(w, resize_it, resize_it);
X    if ( XtIsRealized(w) )
X      Redisplay(w, NULL, NULL);
X}
X
X/*	Function Name: XtSetHighlight
X *	Description: Toggles the given item.
X *	Arguments: w - the set widget.
X *                 item - the item to toggle.
X *	Returns: none.
X */
X
Xvoid
XXtSetToggle(w, item)
XWidget w;
Xint item;
X{
X    SetWidget lw = ( SetWidget ) w;
X
X    if (XtIsSensitive(w)) {
X	lw->set.set[item]->is_lit = ! lw->set.set[item]->is_lit ;
X	PaintItemName(w, item);
X    }
X}
X
X/*	Function Name: XtSetFlash
X *	Description: Flash the given item.
X *	Arguments: w - the set widget.
X *                 item - the item to toggle.
X *	Returns: none.
X */
X
Xvoid
XXtSetFlash(w, item)
XWidget w;
Xint item;
X{
X    SetWidget lw = ( SetWidget ) w;
X    int	      i;
X
X    if (XtIsSensitive(w)) {
X	lw->set.set[item]->is_lit = ! lw->set.set[item]->is_lit ;
X	PaintItemName(w, item);
X	for ( i = 0 ; i < XTPAUSE_COUNT ; ++i ) {
X	    ++i ; --i ;
X	}
X	lw->set.set[item]->is_lit = ! lw->set.set[item]->is_lit ;
X	PaintItemName(w, item);
X    }
X}
X
END_OF_FILE
if test 28746 -ne `wc -c <'Set.c'`; then
    echo shar: \"'Set.c'\" unpacked with wrong size!
fi
# end of 'Set.c'
fi
if test -f 'Set.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Set.h'\"
else
echo shar: Extracting \"'Set.h'\" \(7003 characters\)
sed "s/^X//" >'Set.h' <<'END_OF_FILE'
X/*  This is the Set widget, it is useful for displaying a set without the
X *  overhead of having a widget for each item in the set.  It allows 
X *  the user to select items in a set and notifies the application through
X *  a callback function.
X *
X *	Created: 	8/13/88
X *	By:		Chris D. Peterson
X *                      MIT - Project Athena
X *	Modified: 	7/17/89
X *	By:		Gary Shea
X *                      UC Berkeley, Dept. of Chemistry
X *	
X *
X */
X
X/***********************************************************
XCopyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X
X                        All Rights Reserved
X
XPermission to use, copy, modify, and distribute this software and its 
Xdocumentation for any purpose and without fee is hereby granted, 
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in 
Xsupporting documentation, and that the names of Digital or MIT not be
Xused in advertising or publicity pertaining to distribution of the
Xsoftware without specific, written prior permission.  
X
XDIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
X******************************************************************/
X
X#ifndef _XtSet_h
X#define _XtSet_h
X
X/***********************************************************************
X *
X * Set Widget
X *
X *
X ***********************************************************************/
X
X#include <X11/Simple.h>
X
X/* Resources:
X
X Name		     Class		RepType		Default Value
X ----		     -----		-------		-------------
X background	     Background		Pixel		XtDefaultBackground
X border		     BorderColor	Pixel		XtDefaultForeground
X borderWidth	     BorderWidth	Dimension	1
X callbackA           Callback           XtCallbackList  NULL       **6
X callbackB           Callback           XtCallbackList  NULL       **6
X callbackC           Callback           XtCallbackList  NULL       **6
X columnSpacing       Spacing            Dimension       6
X cursor		     Cursor		Cursor		left_ptr
X defaultColumns      Columns            int             2          **5
X destroyCallback     Callback		Pointer		NULL 
X font		     Font		XFontStruct*	XtDefaultFont
X forceColumns        Columns            Boolean         False      **5
X foreground	     Foreground		Pixel		XtDefaultForeground
X height		     Height		Dimension	0          **1
X insensitiveBorder   Insensitive	Pixmap		Gray
X internalHeight	     Height		Dimension	2
X internalWidth	     Width		Dimension	4
X set                 Set                XtSetDataStruct**    NULL       **2
X longest             Longest            int             0          **3  **4
X mappedWhenManaged   MappedWhenManaged	Boolean		True
X numberStrings       NumberStrings      int             0          **4
X pasteBuffer         Boolean            Boolean         False
X rowSpacing          Spacing            Dimension       4
X sensitive	     Sensitive		Boolean		True
X verticalSet         Boolean            Boolean         False
X width		     Width		Dimension	0          **1
X x		     Position		Position	0
X y		     Position		Position	0
X
X **1 - If the Width or Height of the set widget is zero (0) then the value
X       is set to the minimum size necessay to fit the entire set.
X
X       If both Width and Height are zero then they are adjusted to fit the
X       entire set that is created width the number of default columns 
X       specified in the defaultColumns resource.
X
X **2 - This is an array of strings the specify elements of the set.
X       This resource must be specified. 
X       (What good is a set widget without a set??  :-)
X
X **3 - Longest is the length of the widest string in pixels.
X
X **4 - If either of these values are zero (0) then the set widget calculates
X       the correct value. 
X
X       (This allows you to make startup faster if you already have 
X        this information calculated)
X
X       NOTE: If the numberStrings value is zero the set must 
X             be NULL terminated.
X
X **5 - By setting the Set.Columns resource you can force the application to
X       have a given number of columns.	     
X        
X **6 - This returns the name and index of the item selected in an 
X       XtSetReturnStruct that is pointed to by the client_data
X       in the CallbackProc.
X
X*/
X
X#define XtCSet                  "Set"
X#define XtCSpacing              "Spacing"
X#define XtCColumns              "Columns"
X#define XtCLongest              "Longest"
X#define XtCNumberStrings        "NumberStrings"
X
X#define XtNcolumnSpacing        "columnSpacing"
X#define XtNrowSpacing           "rowSpacing"
X#define XtNverticalSet          "verticalSet"
X#define XtNforceColumns         "forceColumns"
X#define XtNnumberStrings        "numberStrings"
X#define XtNlongest              "longest"
X#define XtNdefaultColumns       "defaultColumns"
X#define XtNforeground		"foreground"
X#define XtNfont			"font"
X#define XtNset                  "set"
X#define XtNcallbackA            "callbackA"
X#define XtNcallbackB            "callbackB"
X#define XtNcallbackC            "callbackC"
X 
X/* Class record constants */
X
Xextern WidgetClass setWidgetClass;
X
Xtypedef struct _SetClassRec *SetWidgetClass;
Xtypedef struct _SetRec      *SetWidget;
X
X/* The set return structure. */
X
Xtypedef struct _XtSetReturnStruct {
X  String string;
X  int index;
X} XtSetReturnStruct;
X
X/* The set and toggle structure. */
X
Xtypedef struct _XtSetDataStruct {
X  String string;
X  int is_lit;
X} XtSetDataStruct;
X
X/******************************************************************
X *
X * Exported Functions
X *
X *****************************************************************/
X
X/*	Function Name: XtSetChange.
X *	Description: Changes the set being used and shown.
X *	Arguments: w - the set widget.
X *                 set - the new set.
X *                 nitems - the number of items in the set.
X *                 longest - the length (in Pixels) of the longest element
X *                           in the set.
X *                 resize - if TRUE the the set widget will
X *                          try to resize itself.
X *	Returns: none.
X *      NOTE:      If nitems of longest are <= 0 then they will be caluculated.
X *                 If nitems is <= 0 then the set needs to be NULL terminated.
X */
X
Xextern void XtSetChange(); /* w, set, nitems, longest, resize */
X
X/*	Function Name: XtSetToggle
X *	Description: Toggles state of the given item.
X *	Arguments: w - the set widget.
X *                 item - the item to toggle.
X *	Returns: none.
X */
X
Xextern void XtSetToggle(); /* w, item */
X
X#endif _XtSet_h
X/* DON'T ADD STUFF AFTER THIS #endif */
END_OF_FILE
if test 7003 -ne `wc -c <'Set.h'`; then
    echo shar: \"'Set.h'\" unpacked with wrong size!
fi
# end of 'Set.h'
fi
if test -f 'SetP.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'SetP.h'\"
else
echo shar: Extracting \"'SetP.h'\" \(3651 characters\)
sed "s/^X//" >'SetP.h' <<'END_OF_FILE'
X/*  This is the Set widget, it is useful to display a set, without the
X *  overhead of having a widget for each item in the set.  It allows 
X *  the user to select an item in a set and notifies the application through
X *  a callback function.
X *
X *	Created: 	8/13/88
X *	By:		Chris D. Peterson
X *                      MIT - Project Athena
X *	Modified: 	7/17/89
X *	By:		Gary Shea
X *                      UC Berkeley, Dept. of Chemistry
X *	
X * $Header: SetP.h,v 1.4 89/07/26 19:04:07 garys Rel $
X */
X
X/***********************************************************
XCopyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X
X                        All Rights Reserved
X
XPermission to use, copy, modify, and distribute this software and its 
Xdocumentation for any purpose and without fee is hereby granted, 
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in 
Xsupporting documentation, and that the names of Digital or MIT not be
Xused in advertising or publicity pertaining to distribution of the
Xsoftware without specific, written prior permission.  
X
XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
X******************************************************************/
X
X/* 
X * SetP.h - Private definitions for Set widget
X * 
X */
X
X#ifndef _XtSetP_h
X#define _XtSetP_h
X
X/***********************************************************************
X *
X * Set Widget Private Data
X *
X ***********************************************************************/
X
X#include <X11/SimpleP.h>
X#include "Set.h"
X
X#define OUT_OF_RANGE            -1
X#define OKAY                     0
X
X/* New fields for the Set widget class record */
X
Xtypedef struct {int foo;} SetClassPart;
X
X/* Full class record declaration */
Xtypedef struct _SetClassRec {
X    CoreClassPart	core_class;
X    SimpleClassPart	simple_class;
X    SetClassPart	set_class;
X} SetClassRec;
X
Xextern SetClassRec setClassRec;
X
X/* New fields for the Set widget record */
Xtypedef struct {
X    /* resources */
X    Pixel	foreground;
X    Dimension	internal_width,
X        	internal_height,
X                column_space,
X                row_space;
X    int         default_cols;
X    Boolean     force_cols,
X                paste,
X                vertical_cols;
X    int         longest;
X    int         nitems;		/* number of items in the set. */
X    XFontStruct	*font;
X    XtSetDataStruct **set;	/* The set itself. */
X    XtCallbackList  callbackA,	/* Give user some options. */
X		callbackB,
X		callbackC;
X
X    /* private state */
X
X    int         col_width,	/* width of each column. */
X                row_height,	/* height of each row. */
X                nrows,		/* number of rows in the set. */
X                ncols;		/* number of columns in the set. */
X    GC		normgc,		/* a couple o' GC's. */
X                revgc,
X                graygc;		/* used when inactive. */
X
X} SetPart;
X
X
X/****************************************************************
X *
X * Full instance record declaration
X *
X ****************************************************************/
X
Xtypedef struct _SetRec {
X    CorePart	core;
X    SimplePart	simple;
X    SetPart	set;
X} SetRec;
X
X#endif _XtSetP_h
END_OF_FILE
if test 3651 -ne `wc -c <'SetP.h'`; then
    echo shar: \"'SetP.h'\" unpacked with wrong size!
fi
# end of 'SetP.h'
fi
if test -f 'Xf.ad' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Xf.ad'\"
else
echo shar: Extracting \"'Xf.ad'\" \(1276 characters\)
sed "s/^X//" >'Xf.ad' <<'END_OF_FILE'
X!
X! The Xf directory/selection application class defaults.
X!
X! First the filename prompter...
X!
X! *** The dialog.label string must be padded with
X!	blanks to get the right effect from the funky Dialog widget...
X!
XXf*dialog.label: \
XEnter Directory Name                                            *
XXf*dialog.maximumLength:	128
XXf*dialog.confirm.label:	Confirm
XXf*value.translations: #replace\n\
X    Ctrl<Key>U: beginning-of-line() kill-to-end-of-line()\n\
X    Ctrl<Key>H: delete-previous-character()\n\
X    <Key>Return: \n\
X    <Key>: insert-char()
XXf*confirm.accelerators: #override \n\
X    <Key>Return: set() notify() unset()
X!
X! The directory box...
X!
XXf*form.set.defaultColumns:	5
XXf*form.set.columnSpacing:	10
XXf*form.set.fromVert:		label
XXf*form.set.verticalSet:	on
X!
X! What the Set widget should do...
X!
XXf*form.set.translations:\
X    None <Btn1Down>:   Toggle()\n\
X    None <Btn2Down>:   Toggle()\n\
X    None <Btn2Up>:   Toggle() NotifyB()
X!
XXf*form.up.label:		Up
XXf*form.up.fromVert:		set
XXf*form.quit.label:		Quit
XXf*form.quit.fromVert:		set
XXf*form.quit.fromHoriz:		up
XXf*form.done.label:		Done
XXf*form.done.fromVert:		set
XXf*form.done.fromHoriz:		quit
XXf*form.dir_name.label:		Enter Directory Name
XXf*form.dir_name.fromVert:	set
XXf*form.dir_name.fromHoriz:	done
X!
END_OF_FILE
if test 1276 -ne `wc -c <'Xf.ad'`; then
    echo shar: \"'Xf.ad'\" unpacked with wrong size!
fi
# end of 'Xf.ad'
fi
if test -f 'global.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'global.c'\"
else
echo shar: Extracting \"'global.c'\" \(1107 characters\)
sed "s/^X//" >'global.c' <<'END_OF_FILE'
X/* 
X * global.c --
X *
X *	Global-variable declarations for the xf utility.
X *
X * Copyright 1989 Regents of the University of California
X * Permission to use, copy, modify, and distribute this
X * software and its documentation for any purpose and without
X * fee is hereby granted, provided that the above copyright
X * notice appear in all copies.  The University of California
X * makes no representations about the suitability of this
X * software for any purpose.  It is provided "as is" without
X * express or implied warranty.
X *
X * Author: Gary Shea, UC Berkeley, Dept. of Chemistry
X */
X
Xstatic char rcsid[] = "$Header: global.c,v 1.2 89/07/17 07:19:25 garys Exp $";
X
X# include "xf.h"
X
X/* The debugging file pointer. */
X
XFILE		*pErrFp ;
X
X/* Directory display mode options -- pretty limited for now. */
X
Xint		ls_mode_a = FALSE ;
X
X/* The DirTree globals are the root of the tree and the
X*  current-working-directory node.
X*/
X
XDirTree		*dirRootPtr = NULL ;
XDirTree		*cwdPtr = NULL ;
X
X/* Some X things.  These must be accesible everywhere. */
X
XXtAppContext	appContext ;
XDisplay		*display;
XWidget		topLevelW ;
X
X
END_OF_FILE
if test 1107 -ne `wc -c <'global.c'`; then
    echo shar: \"'global.c'\" unpacked with wrong size!
fi
# end of 'global.c'
fi
if test -f 'global.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'global.h'\"
else
echo shar: Extracting \"'global.h'\" \(903 characters\)
sed "s/^X//" >'global.h' <<'END_OF_FILE'
X/*
X * global.h --
X *
X *	Declarations of variables global to the xf program.
X *
X * Copyright 1989 Regents of the University of California
X * Permission to use, copy, modify, and distribute this
X * software and its documentation for any purpose and without
X * fee is hereby granted, provided that the above copyright
X * notice appear in all copies.  The University of California
X * makes no representations about the suitability of this
X * software for any purpose.  It is provided "as is" without
X * express or implied warranty.
X *
X * Author: Gary Shea (garys at earth.cchem.berkeley.edu)
X *
X * $Header: global.h,v 1.2 89/07/17 07:22:38 garys Exp $
X */
X
X#ifndef _global_h
X#define _global_h
X
Xextern FILE		*pErrFp ;
Xextern int		ls_mode_a ;
Xextern DirTree		*dirRootPtr ;
Xextern DirTree		*cwdPtr ;
Xextern XtAppContext	appContext ;
Xextern Display		*display ;
Xextern Widget		topLevelW ;
X
X
X#endif /* _global_h */
X
END_OF_FILE
if test 903 -ne `wc -c <'global.h'`; then
    echo shar: \"'global.h'\" unpacked with wrong size!
fi
# end of 'global.h'
fi
if test -f 'xf.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xf.c'\"
else
echo shar: Extracting \"'xf.c'\" \(5308 characters\)
sed "s/^X//" >'xf.c' <<'END_OF_FILE'
X/* 
X * xf.c --
X *
X *	A visual aid for selecting filenames
X *	from anywhere in the file system and outputting them
X *	on the standard output.  This file contains the
X *	main() and error-message routines.
X *
X * Copyright 1989 Regents of the University of California
X * Permission to use, copy, modify, and distribute this
X * software and its documentation for any purpose and without
X * fee is hereby granted, provided that the above copyright
X * notice appear in all copies.  The University of California
X * makes no representations about the suitability of this
X * software for any purpose.  It is provided "as is" without
X * express or implied warranty.
X *
X * Author: Gary Shea, UC Berkeley, Dept. of Chemistry
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: xf.c,v 1.3 89/07/18 00:05:17 garys Exp $";
X#endif /* not lint */
X
X#include "xf.h"
X
X#define XF_APP_CLASS	"Xf"
X
X#ifdef ERRFILE
X#define ErrorFileName	"dt.err"
X#endif
X
X/* Local functions. */
X
Xstatic void	format( void ) ;
X
X
X/*
X *----------------------------------------------------------------------
X *
X * main --
X *
X *	Initialize the X interface, the directory tree, build and
X *	display the initial directory box, handle any command-line-
X *	specified directories, then loop forever.
X *
X *----------------------------------------------------------------------
X */
X
Xmain( int argc, char **argv )
X{
X    char	errLine[ ERRLINE_LEN ] ;
X    char	*pLocName = argv[0] ;
X
X    char	c ;
X    int		getoptError = 0 ;
X
X    extern int	optind ;
X    extern char	*optarg ;
X
X    extern Widget	BuildDirBox( DirTree *dirPtr ) ;
X
X
X#ifdef ERRFILE
X    /* Open the error file. */
X
X    if ( ( pErrFp = fopen( ErrorFileName, "w" )) == (FILE *)0 )
X    {
X	sprintf( errLine, "Can't open error file <%s>", ErrorFileName ) ;
X	FatalError( pLocName, errLine ) ;
X    }
X#endif
X
X    /* Get X set up. */
X
X    XtToolkitInitialize() ;
X    appContext = XtCreateApplicationContext() ;
X
X    if ( ( display = XtOpenDisplay( appContext,
X	NULL, NULL, XF_APP_CLASS, NULL, 0, &argc, argv ) ) == NULL )
X    {
X	fprintf( stderr, "Unable to open display\n" );
X	exit( 1 ) ;
X    }
X
X    /* Yeah, it does seem a little pointless right now,
X    *  but it's bound to grow...
X    */
X
X    while ( ( c = getopt ( argc, argv, "a" )) != EOF )
X    {
X	switch ( c )
X	{
X	case 'a' : ls_mode_a = TRUE ; break ;
X	case '?' : ++getoptError ; break ;
X	}
X    }
X
X    if ( getoptError ) format () ;
X
X    topLevelW = XtAppCreateShell ( NULL, XF_APP_CLASS,
X	applicationShellWidgetClass, display, NULL, 0 ) ;
X
X#ifdef DEBUG
X    XSynchronize ( display, True ) ;
X#endif
X
X    /* Initialize the directory tree to know where we are now,
X    *  and that the current directory is where to root relative
X    *  filenames.
X    */
X
X    DirTree_CWD() ;
X
X#ifdef DEBUG
X    fprintf( pErrFp, "Survived DirTree_CWD\n" );
X#endif
X
X    /* If the user specified any directories on the command line,
X    *  handle them now.
X    */
X
X     if ( optind < argc )
X     {
X	int	ok = FALSE ;
X
X	for ( ; optind < argc ; ++optind )
X	{
X	    DirTree		*dtPtr ;
X    
X	    /* Extend the directory tree if necessary... */
X    
X	    if ( ( dtPtr = DirTree_Find ( argv[ optind ] ) ) == NULL )
X		continue ;
X    
X	    /* Display the directory box for the directory. */
X	
X	    if ( ! dtPtr->isDisplayed ) BuildDirBox ( dtPtr ) ;
X	    ok = TRUE ;
X	}
X
X	if ( !ok ) exit( 1 ) ;
X    }
X    else
X	BuildDirBox ( cwdPtr ) ;
X
X    /* Loop it up. */
X
X    XtAppMainLoop ( appContext ) ;
X}
X
X
X/*
X *----------------------------------------------------------------------
X *
X * OSFatalError, UserError, UserFatalError,
X *		FatalError, InternalError, Warning --
X *
X *	Global error-message routines.
X *
X * Results:
X *	None.
X *
X * Side effects:
X *	FatalError, InternalError, UserFatalError, OSFatalError
X *	exit the program.  All spew some output to the stderr.
X *
X *----------------------------------------------------------------------
X */
X
Xvoid
XOSFatalError( char *routineName, char *message )
X{
X    char	errLine[ ERRLINE_LEN ] ;
X
X    sprintf ( errLine,
X	"fatal error: %s: %s\nos" ) ;
X    perror ( errLine ) ;
X
X    exit( 1 ) ;
X}
X
Xvoid
XUserError( char *message )
X{
X    fprintf( stderr, "%s\n", message ) ;
X}
X
Xvoid
XUserFatalError( char *message )
X{
X    UserError ( message ) ;
X    exit ( 1 ) ;
X}
X
Xvoid
XFatalError( char *routineName, char *message )
X{
X    fprintf( stderr,
X	"fatal error: %s: %s\n",
X	routineName,
X	message ) ;
X    exit( 1 ) ;
X}
X
Xvoid
XInternalError( char *routineName, char *message )
X{
X    fprintf( stderr,
X	"internal error: %s: %s\n",
X	routineName,
X	message ) ;
X    exit( 1 ) ;
X}
X
Xvoid
XWarning( char *routineName, char *message )
X{
X    fprintf( stderr,
X	"warning: %s: %s\n",
X	routineName,
X	message ) ;
X}
X
X
X/*
X *----------------------------------------------------------------------
X *
X * format --
X *
X *	Display the calling conventions (such as they are)
X *	of the xf program.
X *
X * Results:
X *	None.
X *
X * Side effects:
X *	The program exits after output to stderr.
X *
X *  Arguments:
X *	None.
X *
X *----------------------------------------------------------------------
X */
X
Xvoid
Xformat( void )
X{
X    char	errLine[ ERRLINE_LEN ] ;
X    char	*pLocName = "format()" ;
X
X#ifdef DEBUG
X    fprintf ( pErrFp, "\n%s:\n", pLocName ) ;
X#endif
X
X    fprintf ( stderr, "format: xf [options] [name...]\n" ) ;
X    fprintf ( stderr, "options: -a    Display files beginning with '.'\n'" ) ;
X}
X
END_OF_FILE
if test 5308 -ne `wc -c <'xf.c'`; then
    echo shar: \"'xf.c'\" unpacked with wrong size!
fi
# end of 'xf.c'
fi
if test -f 'xf.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xf.h'\"
else
echo shar: Extracting \"'xf.h'\" \(2992 characters\)
sed "s/^X//" >'xf.h' <<'END_OF_FILE'
X/*
X * xf.h --
X *
X *	Declarations of use to the xf file-utility tool.
X *
X * Copyright 1989 Regents of the University of California
X * Permission to use, copy, modify, and distribute this
X * software and its documentation for any purpose and without
X * fee is hereby granted, provided that the above copyright
X * notice appear in all copies.  The University of California
X * makes no representations about the suitability of this
X * software for any purpose.  It is provided "as is" without
X * express or implied warranty.
X *
X * Author: Gary Shea, UC Berkeley, Dept. of Chemistry
X *
X * $Header: xf.h,v 1.2 89/07/17 07:22:42 garys Exp $
X */
X
X#ifndef _xf_h
X#define _xf_h
X
X/* Generally useful includes. */
X
X# include <stdio.h>
X# include <sys/param.h>
X# include <sys/types.h>
X# include <sys/stat.h>
X# include <dirent.h>
X# include <errno.h>
X# include <X11/Xlib.h>
X# include <X11/Intrinsic.h>
X# include <X11/StringDefs.h>
X# include <X11/Shell.h>
X# include <X11/List.h>
X# include <X11/Form.h>
X# include <X11/Label.h>
X# include <X11/Dialog.h>
X# include <X11/Command.h>
X# include <X11/cursorfont.h>
X# include <X11/Xutil.h>
X# include "Set.h"
X# include "dir.h"
X# include "global.h"
X
X/* data structures */
X
X/* Typing "struct dirent" gets tedious, so here's a typedef: */
X
Xtypedef struct dirent DirEnt ;
X
X/* procedures */
X
Xvoid	OSFatalError( char *routineName, char *message ) ;
Xvoid	UserError( char *message ) ;
Xvoid	UserFatalError( char *message ) ;
Xvoid	FatalError( char *routineName, char *message ) ;
Xvoid	InternalError( char *routineName, char *message ) ;
Xvoid	Warning( char *routineName, char *message ) ;
X
X/* System call declarations... */
X
Xchar	*malloc( unsigned n ) ;
Xchar	*strcpy( char *dest, char *src ) ;
Xchar	*getwd( char *pathname ) ;	/* pathname[ MAXPATHLEN ] */
X
X/* Generally useful, non-program-specific definitions... */
X
X# ifndef FALSE
X# define FALSE 0
X# define TRUE (!FALSE)
X# endif
X
X# ifndef ERRLINE_LEN
X# define ERRLINE_LEN	300
X# endif
X
X/* Some macros... */
X
X# define StrSave( strPtr ) \
X    (strcpy( malloc(strlen((strPtr))+1), (strPtr) ))
X
X/* 
X *  From Mark Moraes xlife(1).
X *
X *  This is a simple way to maintain a dynamically allocated array that
X *  grows in chunks. Essentially, obj is a a pointer to the object
X *  (starts off as NULL), and count is the number of elements in it.
X *  size is the currently allocated size, and incr is the size to
X *  increase it by if count == size. type is the type of the object - it
X *  callocs size*sizeof(type) elements for it, and casts this to (type
X *  *). Type is the reason this is a macro and not a procedure.
X *  basically you call this before you store something in obj[count].
X *  Great for adding things at the end of lists.
X */
X
X#define TestAndGrow(obj, count, size, incr, type)\
X	if((count) == (size) || (obj) == NULL) { \
X		size += (incr);	\
X		if ((obj) == NULL) \
X			obj = (type *) XtCalloc(size, sizeof(type));\
X		else \
X			obj = (type *) XtRealloc((char *) obj, \
X			 (size)*sizeof(type));\
X	} else
X
X
X#endif /* _xf_h */
X
END_OF_FILE
if test 2992 -ne `wc -c <'xf.h'`; then
    echo shar: \"'xf.h'\" unpacked with wrong size!
fi
# end of 'xf.h'
fi
if test -f 'xf.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xf.man'\"
else
echo shar: Extracting \"'xf.man'\" \(6956 characters\)
sed "s/^X//" >'xf.man' <<'END_OF_FILE'
X.\" $Header: xf.man,v 1.3 89/07/31 00:21:41 garys Rel $
X.TH XF 1X "17 July 1988" "X Version 11"
X.SH NAME
X\fIxf\fR \- X window filename tool
X.SH SYNOPSIS
X.B xf
X[-a] [\fIdirectory_name\fR ...]
X.SH DESCRIPTION
XThe
X.I xf
Xprogram is a visual tool for generating a collection of filenames
Xfrom a variety of directories,
Xtypically as the command-line input to a program like rm(1) or
Xchmod(1).
X
X.I Xf
Xhas two different window types, a directory window and a
Xdialog window.
X
XThe directory window is labeled with a directory name, and
Xthe directory's files are displayed in a matrix
X(the \fISet\fR widget);
Xany number of entries may
Xbe highlighted by calling the \fISet\fR widget's
XToggle() translation function (bound to None<Btn1Down> by default).
XNote that this is different from the Athena List widget (from which
X\fISet\fR was derived).  Highlighting a \fISet\fR widget entry has nothing
Xto do with the Xt selection mechanism, no selection is exported
Xfrom \fIxf\fR.
XThe directory window has four buttons:
X"Up" which opens a directory window on the next higher
Xdirectory; "Done" which causes the set of all highlighted file
Xnames in all current \fIxf\fR windows to appear on the stdout,
Xand the program to exit; "Quit" which does so with no output;
Xand "Enter Filename" which causes a dialog widget to be opened.
X
XThe Dialog widget allows entry of an absolute or relative (to
Xthe directory from which \fIxf\fR was called) pathname, and
Xcauses a directory window to be opened in the specified directory.
XIt has only one button, "Confirm" which is pressed when the
Xtyped in filename is correct.  Typing Return within the prompt
Xwindow has the same effect as pressing the "Confirm" button.
XThe default behavior of the Text child of the Dialog widget
Xis determined by the app-defaults file (see below).
X.SH OPTIONS
X.I Xf
Xaccepts all of the standard X Toolkit command line options along with the 
Xadditional options listed below:
X.TP 8
X.B \-a
XFile names that begin with '.' will not be suppressed.
XThis is reminiscent of ls(1).
X.PP
XThe following standard X Toolkit command line arguments are commonly used with 
X.I xf:
X.TP 8
X.B \-bg \fIcolor\fP
XThis option specifies the color to use for the background of the window.  
XThe default is \fIwhite\fP.
X.TP 8
X.B \-bd \fIcolor\fP
XThis option specifies the color to use for the border of the window.
XThe default is \fIblack\fP.
X.TP 8
X.B \-bw \fInumber\fP
XThis option specifies the width in pixels of the border surrounding the window.
X.TP 8
X.B \-fg \fIcolor\fP
XThis option specifies the color to use for displaying text.  The default is 
X\fIblack\fP.
X.TP 8
X.B \-fn \fIfont\fP
XThis option specifies the font to be used for displaying normal text.  The
Xdefault is \fI6x10\fP.
X.TP 8
X.B \-rv
XThis option indicates that reverse video should be simulated by swapping
Xthe foreground and background colors.
X.TP 8
X.B \-display \fIhost\fP:\fIdisplay\fP
XThis option specifies the X server to contact.
X.TP 8
X.B \-xrm \fIresourcestring\fP
XThis option specifies a resource string to be used.
X.SH X DEFAULTS
XThe \fIxf\fR directory window is based upon the 
X.I Set
Xwidget, a variant of the List widget (from the Athena widget set).
XThe directory window consists of a Form widget ("form") containing
Xa Label widget ("label"),
Xa \fISet\fR widget ("set"),
Xand four Command widgets ("up", "quit", "done", "dir_name").
XThe dialog window is a Dialog widget
X("dialog") with a child Command widget ("confirm").
X.I Xf
Xunderstands all of the core and relevant Athena
Xresource names and classes for both of its window types.
XThe \fISet\fR widget recognizes the following additional names and classes:
X.PP
X.TP 8
X.B columnSpacing (\fPclass\fB Spacing)
XSpecifies the space between columns in the \fISet\fR widget.
XThe default is 6 in the \fISet\fR widget, 10 in \fIxf\fR.
X.TP 8
X.B rowSpacing (\fPclass\fB Spacing)
XSpecifies the space between rows in the \fISet\fR widget.
XThe default is 4 in the \fISet\fR widget, 4 in \fIxf\fR.
X.TP 8
X.B defaultColumns (\fPclass\fB Columns)
XSpecifies the number of columns the contents of the
X\fISet\fR widget will be displayed in.
X.TP 8
X.B forceColumns (\fPclass\fB Boolean)
XForce the \fISet\fR widget to use exactly defaultColumns columns.
X.PP
XThe default resources for \fIxf\fR are:
X.EX
X!
X! The Xf directory/selection application class defaults.
X!
X! First the filename prompter...
X!
X! *** The dialog.label string must be padded with
X!	blanks to get the right effect from the funky Dialog widget...
X!
XXf*dialog.label: \\
XEnter Directory Name                                            *
XXf*dialog.maximumLength:	128
XXf*dialog.confirm.label:	Confirm
XXf*value.translations: #replace\\n\\
X    Ctrl<Key>U: beginning-of-line() kill-to-end-of-line()\\n\\
X    Ctrl<Key>H: delete-previous-character()\\n\\
X    <Key>Return: \\n\\
X    <Key>: insert-char()
XXf*confirm.accelerators: #override \\n\\
X    <Key>Return: set() notify() unset()
X!
X! The directory box...
X!
XXf*form.set.defaultColumns:	5
XXf*form.set.columnSpacing:	10
XXf*form.set.fromVert:		label
XXf*form.set.verticalSet:	on
X!
X! What the Set widget should do...
X!
XXf*form.set.translations:\\
X    None <Btn1Down>:   Toggle()\\n\\
X    None <Btn2Down>:   Toggle()\\n\\
X    None <Btn2Up>:   Toggle() NotifyB()
X!
XXf*form.up.label:		Up
XXf*form.up.fromVert:		set
XXf*form.quit.label:		Quit
XXf*form.quit.fromVert:		set
XXf*form.quit.fromHoriz:		up
XXf*form.done.label:		Done
XXf*form.done.fromVert:		set
XXf*form.done.fromHoriz:		quit
XXf*form.dir_name.label:		Enter Directory Name
XXf*form.dir_name.fromVert:	set
XXf*form.dir_name.fromHoriz:	done
X!
X.EE
X.SH X TRANSLATIONS
XThe \fISet\fR widget supports the following translation functions
X.TP 8
X.B Toggle()
XToggles the foreground and background colors on the
Xentry in the \fISet\fR widget element which was clicked on.
X.TP 8
X.B NotifyA(), NotifyB(), NotifyC()
XDifferent callbacks may be bound to each of these functions,
Xthey have no other side effects.
X.I Xf
Xuses NotifyB() to open the subdirectory which was clicked on.
XAn error is printed if the clicked-on entry was not a subdirectory.
X.PP
XThe default translations are set in the resource defaults
Xdescribed above.
X.SH "SEE ALSO"
Xls(1), X(1), xrdb(1), Athena List, Command, Label, and Dialog widgets
X.SH BUGS
X.I Xf
Xuses the Dialog widget, which is not very good at dialogs,
Xalthough the use of accelerators helps.
X.PP
X.I Xf
Xshould support some kind of selection mechanism.
X.br
XThere are undoubtedly countless others.
X.SH COPYRIGHT
XCopyright 1989 Regents of the University of California.
XPermission to use, copy, modify, and distribute this
Xsoftware and its documentation for any purpose and without
Xfee is hereby granted, provided that the above copyright
Xnotice appear in all copies.  The University of California
Xmakes no representations about the suitability of this
Xsoftware for any purpose.  It is provided "as is" without
Xexpress or implied warranty.
X.PP
XSome parts of \fIxf\fR are copyright MIT, 1988.
X.SH AUTHORS
XGary Shea (UC Berkeley)
X.br
XChris D. Peterson (MIT-Athena)
X
X
END_OF_FILE
if test 6956 -ne `wc -c <'xf.man'`; then
    echo shar: \"'xf.man'\" unpacked with wrong size!
fi
# end of 'xf.man'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both 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
gary



More information about the Comp.sources.x mailing list