v03i047: prompting program, Part01/01

Mike Wexler mikew at wyse.wyse.com
Sat Mar 11 05:36:10 AEST 1989


Submitted-by: brachman at ubc-cs (Barry Brachman)
Posting-number: Volume 3, Issue 47
Archive-name: xprompt/part01

[I had problems with this in grab mode(default).  In -nograb mode
it seems to work. -mcw]

#! /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 1)."
# Contents:  README AUTHOR Imakefile Makefile patchlevel.h trexp.c
#   trexp.h xprompt.c xprompt.man
# Wrapped by mikew at wyse on Tue Mar  7 15:41:55 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2489 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
XXprompt provides a means by which programs can ask the user
Xfor one or more responses.  I have found it especially useful for
Xreducing the size of my twm menus.
XInstead of hardwiring alternatives into a menu, a single script is used
Xto call xprompt and then invoke the appropriate thing.
X
XFor example, I have a twm menu item:
X
X	"RLOGIN"	!"xprompt.rlogin &"
X
Xthat invokes a shell script called xprompt.rlogin:
X
X#! /bin/sh
X
Xdefaulthost=${HOME}/.xprompt.rlogin
Xreply=
X
Xif [ -r $defaulthost ]
Xthen
X	reply=`cat $defaulthost`
Xfi
X
Xreply=`xprompt -p "Hostname" -r "$reply"`
Xif [ $? = 1 ]
Xthen
X	exit 0
Xfi
Xecho "$reply" > $defaulthost
X
Xxhost "$reply" > /dev/null 2>&1
Xxterm -T "rlogin $reply" -e rlogin "$reply" &
X
Xexit 0
X
XXprompt relies on the user to set its geometry to something reasonable.
XI set the following resources in my .xresources:
X	XPrompt*cursor: left_ptr
X	XPrompt*Geometry: 800x30+300+2
X	XPrompt*Rlen: 70
X	XPrompt*borderWidth: 2
X	XPrompt*Grab: off
X	XPrompt*Warp: on
X	XPrompt*returnExit: on
X	XPrompt*textTranslations: #override \n\
X                         Ctrl<Key>W:  erase-word() \n\
X                         <Btn1Up>: select-start() \n\
X                         <Btn2Up>: insert-selection(PRIMARY,CUT_BUFFER0) \n\
X                         <Btn3Up>: next-prompt-or-finish()
X
XThis is my first X program and there's a good chance I've made a few major
XX faux pas.  Suggestions on how to clean it up will be gratefully received.
XThere are a few minor problems, perhaps my fault, perhaps the fault
Xof the text widget.  Horizontal scrolling, for example, doesn't seem
Xto work correctly.  Still, I've found the program useful and perhaps others
Xwill as well.
X
XThe program has been tested with the server running on a monochrome Sun 3/50
X(SunOS 4.0) and has been compiled with gcc 1.32 and greater.
XThe program has executed on all manner of Sun 3 and a Sun 4/260.
XIt has been written for X11R3.  I can't vouch for the Imakefile.  The
Xenclosed Makefile was not made by imake.
X
XI have a man page for trcomp() should anyone think it's a useful library
Xfunction.  Ask and I'll mail it.
X
XPlease report bugs, enhancements, suggestions, etc. to me rather than
Xposting to the net.
X
X-----
XBarry Brachman           | UUCP:    {alberta,uw-beaver,uunet}!
XDept. of Computer Science|           ubc-vision!ubc-csgrads!brachman
XUniv. of British Columbia| Internet: brachman at cs.ubc.ca
XVancouver, B.C. V6T 1W5  |           brachman%ubc.csnet at csnet-relay.arpa
X(604) 228-4327           | brachman at ubc.csnet
X
END_OF_FILE
if test 2489 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'AUTHOR' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'AUTHOR'\"
else
echo shar: Extracting \"'AUTHOR'\" \(1007 characters\)
sed "s/^X//" >'AUTHOR' <<'END_OF_FILE'
X(Message inbox:959)
XReturn-Path: uunet!ubc-cs!fs1.cs.ubc.ca!ean
XReceived:  by wyse.wyse.com (5.58/Wyse master/5-13-88)
X	id AA03268; Wed, 22 Feb 89 22:51:05 PST
XReceived: from ubc-cs.UUCP by uunet.UU.NET (5.61/1.14) with UUCP 
X	id AA10238; Wed, 22 Feb 89 21:22:05 -0500
XReceived: from relay.ubc.ca by cs.ubc.ca id AA11508; Wed, 22 Feb 89 11:09:33 pst
XReceived: from ean.ubc.ca by relay.ubc.ca (5.59/1.14)
X	id AA19385; Wed, 22 Feb 89 11:09:31 PST
XReceived: from fs1.cs.ubc.ca by ean.ubc.ca (5.59/1.14)
X	id AA28553; Wed, 22 Feb 89 11:04:51 PST
XReceived: by fs1.cs.ubc.ca.ubc.ca (4.0/SMI-4.0)
X	id AA10932; Wed, 22 Feb 89 11:04:44 PST
XDate: 22 Feb 89 11:04 -0800
XFrom: Barry Brachman <uunet!ubc-cs!brachman>
XTo: Mike Wexler <wyse!mikew>
XMessage-Id: <865*brachman at cs.ubc.ca>
XSubject: xprompt v1.0
X
XI would like to submit the enclosed program, xprompt, to comp.sources.x.
XThis replaces an earlier distribution that was posted to comp.windows.x.
X
XYou might check the Imakefile since I am unable to do so.
X
XThanks.
X
END_OF_FILE
if test 1007 -ne `wc -c <'AUTHOR'`; then
    echo shar: \"'AUTHOR'\" unpacked with wrong size!
fi
# end of 'AUTHOR'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(163 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X
XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
X
X           SRCS = xprompt.c trexp.c
X           OBJS = xprompt.o trexp.o
X
XComplexProgramTarget(xprompt)
END_OF_FILE
if test 163 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(6487 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.37 88/10/08 20:08:30 jim Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space.  Imake tries to compensate
X# for this, but is not always successful.
X#
X
X###########################################################################
X# X Window System Makefile generated from template file Imake.tmpl
X# $XConsortium: Imake.tmpl,v 1.91 88/10/23 22:37:10 jim Exp $
X#
X# Do not change the body of the imake template file.  Server-specific
X# parameters may be set in the appropriate .macros file; site-specific
X# parameters (but shared by all servers) may be set in site.def.  If you
X# make any changes, you'll need to rebuild the makefiles using
X# "make World" (at best) or "make Makefile; make Makefiles" (at least) in
X# the top level directory.
X#
X# If your C preprocessor doesn't define any unique symbols, you'll need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make Makefile", "make Makefiles", or "make World").
X#
X# If you absolutely can't get imake to work, you'll need to set the
X# variables at the top of each Makefile as well as the dependencies at the
X# bottom (makedepend will do this automatically).
X#
X
X###########################################################################
X# platform-specific configuration parameters - edit Sun.macros to change
X
X# platform:  $XConsortium: Sun.macros,v 1.52 88/10/23 11:00:55 jim Exp $
X# operating system:   SunOS 3.4
X
XBOOTSTRAPCFLAGS =
X             AS = as
X             CC = cc
X            CPP = /lib/cpp
X             LD = ld
X           LINT = lint
X        INSTALL = install
X           TAGS = ctags
X             RM = rm -f
X             MV = mv
X             LN = ln -s
X         RANLIB = ranlib
XRANLIBINSTFLAGS = -t
X             AR = ar clq
X             LS = ls
X       LINTOPTS = -xz
X    LINTLIBFLAG = -C
X           MAKE = make
XSTD_CPP_DEFINES =
X    STD_DEFINES =
X
X###########################################################################
X# site-specific configuration parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.16 88/10/12 10:30:24 jim Exp $
X
X###########################################################################
X# definitions common to all Makefiles - do not edit
X
X          SHELL =  /bin/sh
X
X        DESTDIR = /global
X      USRLIBDIR = $(DESTDIR)/lib
X         BINDIR = $(DESTDIR)/bin/X11
X         INCDIR = $(DESTDIR)/include
X         ADMDIR = $(DESTDIR)/usr/adm
X         LIBDIR = $(USRLIBDIR)/X11
X     LINTLIBDIR = $(USRLIBDIR)/lint
X        FONTDIR = $(LIBDIR)/fonts
X       XINITDIR = $(LIBDIR)/xinit
X         XDMDIR = $(LIBDIR)/xdm
X         UWMDIR = $(LIBDIR)/uwm
X         AWMDIR = $(LIBDIR)/awm
X         TWMDIR = $(LIBDIR)/twm
X          DTDIR = $(LIBDIR)/dt
X        MANPATH = /usr/man
X  MANSOURCEPATH = $(MANPATH)/man
X         MANDIR = $(MANSOURCEPATH)n
X      LIBMANDIR = $(MANSOURCEPATH)n3
X    XAPPLOADDIR = $(LIBDIR)/app-defaults
X
X   INSTBINFLAGS = -m 0755
X   INSTUIDFLAGS = -m 4755
X   INSTLIBFLAGS = -m 0664
X   INSTINCFLAGS = -m 0444
X   INSTMANFLAGS = -m 0444
X   INSTAPPFLAGS = -m 0444
X  INSTKMEMFLAGS = -m 4755
X        FCFLAGS = -t
X    CDEBUGFLAGS = -O
X
X        PATHSEP = /
X         DEPEND = $(BINDIR)/makedepend
X          IMAKE = $(BINDIR)/imake
X            RGB = $(LIBDIR)/rgb
X             FC = $(BINDIR)/bdftosnf
X      MKFONTDIR = $(BINDIR)/mkfontdir
X      MKDIRHIER = $(BINDIR)/mkdirhier.sh
X
X         CFLAGS = $(CDEBUGFLAGS) $(INCLUDES) $(STD_DEFINES) $(DEFINES)
X      LINTFLAGS = $(LINTOPTS) $(INCLUDES) $(STD_DEFINES) $(DEFINES) -DLINT
X        LDFLAGS = $(CDEBUGFLAGS) -L$(USRLIBDIR) $(SYS_LIBRARIES) $(SYSAUX_LIBRARIES)
X
X       IRULESRC = $(LIBDIR)/imake.includes
X
X   EXTENSIONLIB = $(USRLIBDIR)/libext.a
X           XLIB = $(USRLIBDIR)/libX11.a
X         XMULIB = $(USRLIBDIR)/libXmu.a
X        OLDXLIB = $(USRLIBDIR)/liboldX.a
X       XTOOLLIB = $(USRLIBDIR)/libXt.a
X         XAWLIB = $(USRLIBDIR)/libXaw.a
X       LINTXLIB = $(USRLIBDIR)/lint/llib-lX11.ln
X        LINTXMU = $(USRLIBDIR)/lint/llib-lXmu.ln
X      LINTXTOOL = $(USRLIBDIR)/lint/llib-lXt.ln
X        LINTXAW = $(USRLIBDIR)/lint/llib-lXaw.ln
X       INCLUDES = -I$(INCDIR)
X      MACROFILE = Sun.macros
X   ICONFIGFILES = $(IRULESRC)/Imake.tmpl \
X			$(IRULESRC)/$(MACROFILE) $(IRULESRC)/site.def
X  IMAKE_DEFINES =
X      IMAKE_CMD = $(NEWTOP)$(IMAKE) -TImake.tmpl -I$(NEWTOP)$(IRULESRC) \
X			-s Makefile $(IMAKE_DEFINES)
X         RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a \
X			.emacs_* tags TAGS make.log MakeOut
X
X###########################################################################
X# rules:  $XConsortium: Imake.rules,v 1.71 88/10/23 22:46:34 jim Exp $
X
X###########################################################################
X# start of Imakefile
X
XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
X
X           SRCS = xprompt.c trexp.c
X           OBJS = xprompt.o trexp.o
X
X PROGRAM = xprompt
X
Xall:: xprompt
X
Xxprompt: $(OBJS) $(LOCAL_LIBRARIES)
X	$(RM) $@
X	$(CC) -o $@ $(OBJS) $(LOCAL_LIBRARIES) $(LDFLAGS) $(SYSLAST_LIBRARIES)
X
Xrelink::
X	$(RM) $(PROGRAM)
X	$(MAKE) $(MFLAGS) $(PROGRAM)
X
Xinstall:: xprompt
X	$(INSTALL) -c $(INSTALLFLAGS) xprompt $(BINDIR)
X
Xinstall.man:: xprompt.man
X	$(INSTALL) -c $(INSTMANFLAGS) xprompt.man $(MANDIR)/xprompt.n
X
Xdepend:: $(DEPEND)
X
Xdepend::
X	$(DEPEND) -s "# DO NOT DELETE" -- $(CFLAGS) -- $(SRCS)
X
X$(DEPEND):
X	@echo "making $@"; \
X	cd $(DEPENDSRC); $(MAKE)
X
Xclean::
X	$(RM) $(PROGRAM)
X
X###########################################################################
X# Imake.tmpl common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X	$(RM_CMD) \#*
X
XMakefile:: $(IMAKE)
X
XMakefile:: Imakefile \
X	$(IRULESRC)/Imake.tmpl \
X	$(IRULESRC)/Imake.rules \
X	$(IRULESRC)/site.def \
X	$(IRULESRC)/$(MACROFILE)
X	- at if [ -f Makefile ]; then \
X	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP)
X
X$(IMAKE):
X	@echo "making $@"; \
X	cd $(IMAKESRC); $(MAKE) BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS)
X
Xtags::
X	$(TAGS) -w *.[ch]
X	$(TAGS) -xw *.[ch] > TAGS
X
X###########################################################################
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X	@echo "install done"
X
Xinstall.man::
X	@echo "install.man done"
X
XMakefiles::
X
X###########################################################################
X# dependencies generated by makedepend
X
END_OF_FILE
if test 6487 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 0
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'trexp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'trexp.c'\"
else
echo shar: Extracting \"'trexp.c'\" \(4728 characters\)
sed "s/^X//" >'trexp.c' <<'END_OF_FILE'
X/* vi: set tabstop=4 : */
X
X#include <stdio.h>
X
X#include "trexp.h"
X
X#ifdef DEBUG
Xmain()
X{
X	int st;
X	char buf[BUFSIZ];
X	trexp *t;
X
X	printf("Enter the expression:\n");
X	gets(buf);
X	if ((t = trcomp(buf)) == NULL) {
X		fprintf(stderr, "Compile error.\n");
X		exit(1);
X	}
X	printf("Number in set: %d\n", trnset(t));
X	trshow(stdout, t);
X	while (1) {
X		printf("Character?\n");
X		if (gets(buf) == NULL)
X			break;
X		if (trexec(t, buf[0]))
X			printf("Yes.\n");
X		else
X			printf("No.\n");
X	}
X}
X#endif DEBUG
X
X/*
X * trcomp - compile a transliteration string
X *
X * Returns a pointer to a trexp structure if successful and NULL
X * if the control string is improperly formed.
X *
X * The macro trexec may subsequently be used with the compiled expression
X * and a single character.
X * The value is 1 if the character is in the set, 0 otherwise.
X * The value of the macro trnset, passed the pointer to the compiled
X * expression, is the number of elements specified by the expression.
X *
X * The argument to trcomp is a string specifying individual characters
X * and ranges of characters as used in the tr(1) command:
X * a) a backslash followed by 1, 2, or 3 octal digits stands for the ASCII
X *    character corresponding to the octal value.  The value is limited to
X *    8 bits.
X * b) a backslash followed by a non-octal digit character stands for the
X *    character.
X * c) other ASCII characters stand for themselves
X * d) the range of characters between two characters, <c1> and <c2>,
X *    is specified by sequence of the form <c1>-<c2> when <c1> comes before
X *    <c2> in the ASCII character set
X *
X * The space allocated by trcomp() may be released using free()
X */
X
Xstatic int next_token();
X
Xtrexp *
Xtrcomp(exp)
Xchar *exp;
X{
X	register int i, low, high;
X	char *ptr, *save;
X	trexp *t;
X	char *malloc();
X
X	if ((t = (trexp *) malloc(sizeof(trexp))) == NULL)
X		return(NULL);
X	for (i = 0; i < sizeof(trexp); i++)
X		t->exp[i] = 0;
X	t->nset = 0;
X	ptr = exp;
X	while (*ptr != '\0') {
X		if ((low = next_token(&ptr)) < 0)
X			return(NULL);
X		if (*ptr == '-') {
X			save = ptr++;
X			if ((high = next_token(&ptr)) < 0)
X				return(NULL);
X			if (low < high) {
X				for (i = low; i <= high; i++) {
X					if (!t->exp[i]) {
X						t->exp[i] = 1;
X						t->nset++;
X					}
X				}
X			}
X			else {
X				ptr = save;
X				if (!t->exp[low]) {
X					t->exp[low] = 1;
X					t->nset++;
X				}
X			}
X		}
X		else {
X			if (!t->exp[low]) {
X				t->exp[low] = 1;
X				t->nset++;
X			}
X		}
X	}
X	return(t);
X}
X
X#define isoctdigit(d)	(d >= '0' && d <= '7')
X
Xstatic int
Xnext_token(str)
Xchar **str;
X{
X	register char *p;
X	int val;
X
X	p = *str;
X	if (*p == '\\') {
X		p++;
X		if (isoctdigit(*p)) {
X			val = *p++ - '0';
X			if (isoctdigit(*p)) {
X				val = val * 8 + *p++ - '0';
X				if (isoctdigit(*p))
X					val = val * 8 + *p++ - '0';
X			}
X			*str = p;
X			return(val & 0377);
X		}
X		else {
X			if (*p == '\0')		/* Premature eos */
X				return(-1);
X			*str = p + 1;
X			return(*p & 0377);
X		}
X	}
X	*str = p + 1;
X	return(*p & 0377);
X}
X
Xvoid
Xtrshow(f, t)
XFILE *f;
Xtrexp *t;
X{
X	register int i, j, k;
X	static char *ascii_tab[] = {
X		"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
X		"BS",  "HT",  "NL",  "VT",  "NP",  "CR",  "SO",  "SI",
X		"DEL", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
X		"CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US",
X		"SP",  "!",   "\"",  "#",   "$",   "%",   "&",   "'",
X		"(",   ")",   "*",   "+",   ",",   "-",   ".",   "/",
X		"0",   "1",   "2",   "3",   "4",   "5",   "6",   "7",
X		"8",   "9",   ":",   ";",   "<",   "=",   ">",   "?",
X		"@",   "A",   "B",   "C",   "D",   "E",   "F",   "G",
X		"H",   "I",   "J",   "K",   "L",   "M",   "N",   "O",
X		"P",   "Q",   "R",   "S",   "T",   "U",   "V",   "W",
X		"X",   "Y",   "Z",   "[",   "\\",  "]",   "^",   "_",
X		"`",   "a",   "b",   "c",   "d",   "e",   "f",   "g",
X		"h",   "i",   "j",   "k",   "l",   "m",   "n",   "o",
X		"p",   "q",   "r",   "s",   "t",   "u",   "v",   "w",
X		"x",   "y",   "z",   "{",   "|",   "}",   "~",   "DEL"
X	};
X
X	for (i = 0; i < 32; i++) {
X		for (j = 0; j < 8; j++) {
X			k = i * 8 + j;
X			if (t->exp[k]) {
X				if (k > 0177)
X					fprintf(f, "|%03o    ", k, t->exp[k]);
X				else
X					fprintf(f, "|%03o %3s", k, ascii_tab[k]);
X			}
X			else
X				fprintf(f, "|       ");
X		}
X		fprintf(f, "|\n");
X	}
X}
X
X#ifdef NOTDEF
X/*
X * This is the old, non-compiling version
X */
Xstrrange(str, ch)
Xchar *str;
Xint ch;
X{
X	int low, high;
X	char *ptr, *save;
X
X	ch &= 0377;
X	ptr = str;
X	while (*ptr != '\0') {
X		if ((low = next_token(&ptr)) < 0)
X			return(-1);
X		if (ch == low)
X			return(1);
X		if (*ptr == '-') {
X			save = ptr++;
X			if ((high = next_token(&ptr)) < 0)
X				return(-1);
X			if (low < high) {
X				if (ch >= low && ch <= high)
X					return(1);
X			}
X			else
X				ptr = save;
X		}
X	}
X	return(0);
X}
X#endif NOTDEF
X
END_OF_FILE
if test 4728 -ne `wc -c <'trexp.c'`; then
    echo shar: \"'trexp.c'\" unpacked with wrong size!
fi
# end of 'trexp.c'
fi
if test -f 'trexp.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'trexp.h'\"
else
echo shar: Extracting \"'trexp.h'\" \(182 characters\)
sed "s/^X//" >'trexp.h' <<'END_OF_FILE'
X
X/* trexp.h */
X
X#define trexec(t, ch)		(t->exp[ch & 0377])
X#define trnset(t)			(t->nset)
X
Xtypedef struct trexp {
X	char exp[256];
X	int nset;
X} trexp;
X
Xtrexp *trcomp();
Xvoid trshow();
END_OF_FILE
if test 182 -ne `wc -c <'trexp.h'`; then
    echo shar: \"'trexp.h'\" unpacked with wrong size!
fi
# end of 'trexp.h'
fi
if test -f 'xprompt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xprompt.c'\"
else
echo shar: Extracting \"'xprompt.c'\" \(18704 characters\)
sed "s/^X//" >'xprompt.c' <<'END_OF_FILE'
X/* vi: set tabstop=4 : */
X
X/*
X * xprompt - prompt the user for one or more replies
X *
X * Written for X11R3
X * 24-Jan-89 bjb
X *
X * Copyright (C) 1989 Barry Brachman and The University of British Columbia
X *
X * Permission is given to freely copy and distribute this software provided:
X *
X *	1) You do not sell it,
X *	2) You do not use it for commercial advantage, and
X *	3) This notice accompanies the distribution
X *
X * Barry Brachman           | UUCP:    {alberta,uw-beaver,uunet}!
X * Dept. of Computer Science|           ubc-vision!ubc-csgrads!brachman
X * Univ. of British Columbia| Internet: brachman at cs.ubc.ca
X * Vancouver, B.C. V6T 1W5  |           brachman%ubc.csnet at csnet-relay.arpa
X * (604) 228-4327           | brachman at ubc.csnet
X */
X
X#include <X11/Xos.h>
X#include <sys/stat.h>
X#include <ctype.h>
X#include <stdio.h>
X#include <X11/Xatom.h>
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/Box.h>
X#include <X11/Shell.h>
X#include <X11/AsciiText.h>
X#include <X11/TextP.h>
X#include <X11/Cardinals.h>
X#include <X11/Xutil.h>
X#include <X11/Xlib.h>
X
X#include "trexp.h"
X
X#ifndef lint
Xstatic char *version = "xprompt v1.0 brachman at cs.ubc.ca 14-Feb-89";
X#endif lint
X
Xstatic XrmOptionDescRec table[] = {
X    {"-grab",   "Grab",                XrmoptionNoArg,  (caddr_t) "on"},
X    {"-ibw",    "insideborderWidth",   XrmoptionSepArg, NULL},
X    {"-nograb", "Grab",                XrmoptionNoArg,  (caddr_t) "off"},
X    {"-nowarp", "Warp",                XrmoptionNoArg,  (caddr_t) "off"},
X	{"-nre",    "returnExit",          XrmoptionNoArg,  (caddr_t) "off"},
X	{"-p",      "",                    XrmoptionSkipLine, NULL},
X    {"-pfn",    "promptFont",          XrmoptionSepArg, NULL},
X	{"-re",     "returnExit",          XrmoptionNoArg,  (caddr_t) "on"},
X    {"-rfn",    "replyFont",           XrmoptionSepArg, NULL},
X    {"-rlen",   "Rlen",                XrmoptionSepArg, NULL},
X    {"-tf",     "textTranslationFile", XrmoptionSepArg, NULL},
X    {"-w",      "wordChars",           XrmoptionSepArg, NULL},
X    {"-warp",   "Warp",                XrmoptionNoArg, (caddr_t) "on"},
X};
X
Xtypedef struct {
X    int rlen;				/* maximum reply length */
X    Boolean grab;			/* If TRUE, grab the keyboard */
X	Boolean warp;			/* If TRUE, warp to reply window */
X	Boolean return_exit;	/* If TRUE, exit on <return> if single prompt */
X	char *texttranslations;
X	char *texttranslationfile;
X	char *wordchars;
X    char *geometry;
X    int borderwidth;
X    int insideborderwidth;
X    XFontStruct *font;
X    XFontStruct *pfont;
X    XFontStruct *rfont;
X} app_resourceRec, *app_res;
X
Xstatic app_resourceRec app_resources;
X
Xstatic XtResource resources[] = {
X{"rlen",  "Rlen", XtRInt, sizeof(int),
X   XtOffset(app_res, rlen), XtRImmediate, (caddr_t) 80},
X{"grab",  "Grab", XtRBoolean, sizeof(Boolean),
X   XtOffset(app_res, grab), XtRImmediate, (caddr_t) TRUE },
X{"insideborderwidth", "insideborderWidth", XtRInt, sizeof(int),
X   XtOffset(app_res, insideborderwidth), XtRImmediate, (caddr_t) 1},
X{"replyfont", "replyFont", XtRFontStruct, sizeof(XFontStruct *),
X   XtOffset(app_res, rfont), XtRString, NULL},
X{"promptfont", "promptFont", XtRFontStruct, sizeof(XFontStruct *),
X   XtOffset(app_res, pfont), XtRString, NULL},
X{"returnexit", "returnExit", XtRBoolean, sizeof(Boolean),
X   XtOffset(app_res, return_exit), XtRImmediate, (caddr_t) FALSE},
X{"texttranslationfile", "textTranslationFile", XtRString, sizeof(caddr_t),
X   XtOffset(app_res, texttranslationfile), XtRString, NULL},
X{"texttranslations", "textTranslations", XtRString, sizeof(caddr_t),
X   XtOffset(app_res, texttranslations), XtRString, NULL},
X{"wordchars", "wordChars", XtRString, sizeof(caddr_t),
X   XtOffset(app_res, wordchars), XtRString, "a-zA-Z0-9"},
X{"warp",  "Warp", XtRBoolean, sizeof(Boolean),
X   XtOffset(app_res, warp), XtRImmediate, (caddr_t) FALSE },
X
X{XtNgeometry,  "Geometry", XtRString, sizeof(caddr_t),
X   XtOffset(app_res, geometry), XtRString, (caddr_t) "500x150+500+400"},
X{XtNborderWidth, "borderWidth", XtRInt, sizeof(int),
X   XtOffset(app_res, borderwidth), XtRImmediate, (caddr_t) 1},
X{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
X   XtOffset(app_res, font), XtRString, (caddr_t) XtDefaultFont},
X};
X
Xstatic char xprompt_TextTranslations[] =
X"\
XCtrl<Key>C:		    abort() \n\
XCtrl<Key>D:		    finish-prompt() \n\
XCtrl<Key>J:         next-prompt() \n\
XCtrl<Key>M:         next-prompt() \n\
X<Key>Down:		    next-prompt() \n\
X<Key>Up:		    previous-prompt() \n\
X<Key>Linefeed:	    next-prompt() \n\
X<Key>Return:	    next-prompt-or-finish() \n\
XCtrl<Key>U:         erase-line() \n\
X<Btn1Up>:           finish-prompt() \n\
X<Btn2Up>:           finish-prompt() \n\
X<Btn3Up>:           finish-prompt() \n\
X<Btn1Down>:         ignore() \n\
X<Btn2Down>:         ignore() \n\
X<Btn3Down>:         ignore() \n\
X<Btn1Motion>:       ignore() \n\
X<Btn2Motion>:       ignore() \n\
X<Btn3Motion>:       ignore() \n\
X<VisibilityNotify>: visibility-event() \n\
X";
X
Xstatic struct promptargs {
X	char *prompt;
X	char *reply;
X    Boolean seenprompt;
X	struct promptargs *next;
X	struct promptargs *prev;
X} *promptargs, *npa, *npa_prev;
Xstatic int cpromptarg, npromptargs, nprompts_seen;
X
Xstatic char *promptbuf, *replybuf;
Xstatic Widget toplevel, box, popup, reply_w, prompt_w;
Xstatic Widget complete_top_w, complete_w;
Xstatic Window orig_win;
Xstatic int orig_x, orig_y;
Xstatic int reply_x, reply_y;
Xstatic int bb_width, bb_height;
Xstatic int visible;
X
Xstatic trexp *word_tr;
Xstatic void changeprompt(), unparsegeometry(), unwarp();
Xstatic int get_user_text_translations();
X
Xchar *malloc();
X
Xnull_cursor()
X{}
X
X/*ARGSUSED*/
Xstatic void
XEraseLine(ctx, event, args, nargs)
XTextWidget ctx;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X	replybuf[0] = '\0';
X	XtTextSetLastPos(reply_w, 0);
X	XtTextSetInsertionPoint(reply_w, 0);
X	XtTextDisplay(reply_w);
X}
X
X/*ARGSUSED*/
Xstatic void
XEraseWord(ctx, event, args, nargs)
XTextWidget ctx;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X	register int endpos, pos, startpos;
X
X	startpos = pos = XtTextGetInsertionPoint(reply_w);
X
X	/* Skip any leading "non-word" characters */
X	while (replybuf[pos] != '\0' && !trexec(word_tr, replybuf[pos]))
X		pos++;
X	/* Skip any "word" characters */
X	while (trexec(word_tr, replybuf[pos]))
X		pos++;
X
X	endpos = pos;
X	pos = startpos;
X	while (replybuf[endpos] != '\0')
X		replybuf[pos++] = replybuf[endpos++];
X	replybuf[pos] = '\0';
X
X	XtTextSetLastPos(reply_w, pos);
X	XtTextSetInsertionPoint(reply_w, startpos);
X	XtTextDisplay(reply_w);
X}
X
X/*ARGSUSED*/
Xstatic void
XFinishPrompt(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X	int i;
X
X	strcpy(npa->reply, replybuf);
X	for (i = 0, npa = promptargs; i < npromptargs; npa = npa->next, i++)
X		printf("%s\n", npa->reply);
X	unwarp();
X	XtDestroyWidget(toplevel);
X	exit(0);
X}
X
X/*ARGSUSED*/
Xstatic void
XPreviousPrompt(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X	npa_prev = npa;
X	npa = npa->prev;
X	if (--cpromptarg == 0)
X		cpromptarg = npromptargs;
X	changeprompt();
X}
X
X/*ARGSUSED*/
Xstatic void
XNextPrompt(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X	if (npromptargs > 1) {
X		npa_prev = npa;
X		npa = npa->next;
X		if (++cpromptarg > npromptargs)
X			cpromptarg = 1;
X		changeprompt();
X	}
X}
X
X/*ARGSUSED*/
Xstatic void
XNextPromptOrFinish(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X	if (nprompts_seen == npromptargs && app_resources.return_exit) {
X		FinishPrompt(w, event, args, nargs);
X		/*NOTREACHED*/
X	}
X	NextPrompt(w, event, args, nargs);
X}
X
X/*ARGSUSED*/
Xstatic void
Xchangeprompt()
X{
X	int replylen, promptlen;
X
X	if (npromptargs > 1)
X		sprintf(promptbuf, "%s[%d/%d]:", npa->prompt, cpromptarg, npromptargs);
X	else
X		sprintf(promptbuf, "%s:", npa->prompt);
X	strcpy(npa_prev->reply, replybuf);
X	strcpy(replybuf, npa->reply);
X	if (npa->seenprompt == FALSE) {
X		npa->seenprompt = TRUE;
X		nprompts_seen++;
X	}
X
X	replylen = strlen(replybuf);
X	promptlen = strlen(promptbuf);
X	XtTextSetLastPos(reply_w, replylen);
X	XtTextSetLastPos(prompt_w, promptlen);
X
X	XtTextSetInsertionPoint(reply_w, replylen);
X	XtTextSetInsertionPoint(prompt_w, promptlen);
X
X	XtTextDisplay(reply_w);
X	XtTextDisplay(prompt_w);
X}
X
X/*ARGSUSED*/
Xstatic void
XAbort(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X	unwarp();
X    XtDestroyWidget(toplevel);
X    exit(1);
X}
X
X/*ARGSUSED*/
Xstatic void
XIgnore(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X}
X
X/*ARGSUSED*/
Xstatic void
XVisibilityEvent(w, event, args, nargs)
XWidget w;
XXEvent event;
XString *args;
XCardinal *nargs;
X{
X
X	visible = 1;
X}
X
Xstatic XtActionsRec xprompt_actions[] = {
X  {"erase-line",		    EraseLine },
X  {"erase-word",            EraseWord },
X  {"next-prompt",		    NextPrompt },
X  {"previous-prompt",	    PreviousPrompt },
X  {"finish-prompt",		    FinishPrompt },
X  {"next-prompt-or-finish", NextPromptOrFinish },
X  {"abort",				    Abort },
X  {"ignore",                Ignore },
X  {"visibility-event",      VisibilityEvent },
X};
X
Xstatic
XSyntax(call)
Xchar *call;
X{
X
X    fprintf(stderr, "Usage: %s [flags] [xtoolkitargs] -p prompt [-r reply] \
X[-p prompt [-r reply]] ...\n", call);
X    fprintf(stderr, "where <flags> is one or more of:\n");
Xfprintf(stderr, "-rlen #     (Maximum length of user's reply: default 80)\n");
Xfprintf(stderr, "-ibw #      (Border width of inside window: default 1)\n");
Xfprintf(stderr, "-grab       (Grab keyboard: default)\n");
Xfprintf(stderr, "-nograb     (Don't grab keyboard)\n");
Xfprintf(stderr, "-re         (Return key will exit if there's one prompt)\n");
Xfprintf(stderr, "-nre        (Return key won't exit: default)\n");
Xfprintf(stderr, "-pfn <font> (Prompt font)\n");
Xfprintf(stderr, "-rfn <font> (Reply font)\n");
Xfprintf(stderr, "-tf <file>  (Translation file to override defaults)\n");
Xfprintf(stderr, "-w <str>    (Characters making up a word\n");
Xfprintf(stderr, "-warp       (Warp cursor to reply window)\n");
Xfprintf(stderr, "-nowarp     (Don't warp cursor)\n");
X    exit(1);
X}
X
Xvoid unparsegeometry();
X
Xmain(argc, argv)
Xunsigned int argc;
Xchar **argv;
X{
X    register int i, j;
X	int len, maxpromptlen;
X	TextWidget ctx;
X    Arg arg[10];
X    int geom_mask, geom_x, geom_y, geom_width, geom_height;
X    char geom_str[100];
X	XtTranslations t;
X    XFontStruct *font;
X
X    toplevel = XtInitialize(argv[0], "XPrompt", table, XtNumber(table),
X		&argc, argv);
X
X    XtGetApplicationResources(toplevel, &app_resources, resources,
X                  XtNumber(resources), NULL, 0);
X
X    j = 0;
X	promptargs = NULL;
X	maxpromptlen = 0;
X    for (i = 1; i < argc; i++) {
X		if (i == argc - 1 || strcmp(argv[i], "-p"))
X			Syntax(argv[0]);
X		if (promptargs) {
X			npa->next =
X				(struct promptargs *) malloc(sizeof(struct promptargs));
X			npa->next->prev = npa;
X			npa = npa->next;
X			npa->next = NULL;
X		}
X		else {
X			promptargs = npa =
X				(struct promptargs *) malloc(sizeof(struct promptargs));
X			npa->prev = npa->next = NULL;
X		}
X		npa->prompt = argv[++i];
X		if ((len = strlen(npa->prompt)) > maxpromptlen)
X			maxpromptlen = len;
X		if ((npa->reply = (char *) malloc(app_resources.rlen + 1)) == NULL) {
X			fprintf(stderr, "Can't alloc reply buffer\n");
X			exit(1);
X		}
X		npa->reply[0] = '\0';
X		if (argv[i+1] && !strcmp(argv[i+1], "-r")) {
X			if (++i == argc - 1)
X				Syntax(argv[0]);
X			if (strlen(argv[++i]) > app_resources.rlen) {
X				fprintf(stderr, "xprompt: default reply is too long\n");
X				exit(1);
X			}
X			strcpy(npa->reply, argv[i]);
X		}
X		npa->seenprompt = FALSE;
X		j++;
X	}
X	if ((npromptargs = j) == 0)
X		Syntax(argv[0]);
X	promptargs->prev = npa;
X	npa->next = promptargs;
X	npa = promptargs;
X	cpromptarg = 1;
X	replybuf = (char *) malloc(app_resources.rlen + 1);
X	if (npromptargs > 1) {
X		maxpromptlen += 5;
X		if (npromptargs < 10)
X			maxpromptlen += 2;
X		else if (npromptargs < 100)
X			maxpromptlen += 4;
X		else
X			maxpromptlen += 10;		/* yuk */
X	}
X	else
X		maxpromptlen += 2;
X	promptbuf = (char *) malloc(maxpromptlen);
X
X    if (app_resources.pfont == NULL)
X		app_resources.pfont = app_resources.font;
X    if (app_resources.rfont == NULL)
X		app_resources.rfont = app_resources.font;
X
X    XtAddActions(xprompt_actions, XtNumber(xprompt_actions));
X
X	if ((word_tr = trcomp(app_resources.wordchars)) == NULL) {
X		fprintf(stderr, "xprompt: Parse of word chars failed.\n");
X		exit(1);
X	}
X	
X    geom_x = 500;
X    geom_y = 400;
X    geom_width = 800;
X    geom_height = 30;
X    geom_mask =
X		XParseGeometry(app_resources.geometry, &geom_x, &geom_y, &geom_width,
X			&geom_height);
X    unparsegeometry(geom_str, geom_mask, geom_width, geom_height, geom_x, 
X		    geom_y);
X    XtSetArg(arg[0], XtNgeometry, geom_str);
X    XtSetArg(arg[1], XtNborderWidth, app_resources.borderwidth);
X	/*    popup = XtCreatePopupShell("popup", overrideShellWidgetClass,
X		  toplevel, arg, 2); */
X	popup = XtCreatePopupShell("xprompt", topLevelShellWidgetClass,
X							   toplevel, arg, 2);
X
X	box =
X		XtCreateManagedWidget("box", boxWidgetClass, popup, NULL, ZERO);
X
X    font = app_resources.pfont;
X    bb_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
X    bb_height = font->max_bounds.ascent + font->max_bounds.descent;
X	if (npromptargs > 1)
X		sprintf(promptbuf, "%s[1/%d]:", promptargs->prompt, npromptargs);
X	else
X		sprintf(promptbuf, "%s:", promptargs->prompt);
X	promptargs->seenprompt = TRUE;
X	nprompts_seen = 1;
X    XtSetArg(arg[0], XtNstring, promptbuf);
X	XtSetArg(arg[1], XtNlength, maxpromptlen);
X    XtSetArg(arg[2], XtNborderWidth, 0);
X    XtSetArg(arg[3], XtNfont, app_resources.pfont);
X	XtSetArg(arg[4], XtNeditType, XttextRead);
X	XtSetArg(arg[5], XtNwidth, bb_width * maxpromptlen);
X	XtSetArg(arg[6], XtNsensitive, False);
X	prompt_w =
X		XtCreateManagedWidget("text", asciiStringWidgetClass, box, arg, 7);
X	/*
X	 * The following kludge is used because I couldn't find any obvious
X	 * way to turn off the cursor in the prompt window
X	 * I suppose one could define a null cursor and use that...
X	 */
X	ctx = (TextWidget) prompt_w;
X	ctx->text.sink->InsertCursor = null_cursor;
X
X    font = app_resources.rfont;
X    bb_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
X    bb_height = font->max_bounds.ascent + font->max_bounds.descent;
X	strcpy(replybuf, promptargs->reply);
X    XtSetArg(arg[0], XtNtextOptions, editable | scrollOnOverflow);
X    XtSetArg(arg[1], XtNheight, bb_height + 6);
X    XtSetArg(arg[2], XtNstring, replybuf);
X    XtSetArg(arg[3], XtNlength, app_resources.rlen);
X    XtSetArg(arg[4], XtNeditType, XttextEdit);
X    XtSetArg(arg[5], XtNborderWidth, app_resources.insideborderwidth);
X    XtSetArg(arg[6], XtNwidth, app_resources.rlen * bb_width);
X    XtSetArg(arg[7], XtNinsertPosition, strlen(promptargs->reply));
X    XtSetArg(arg[8], XtNfont, app_resources.rfont);
X	reply_w =
X		XtCreateManagedWidget("reply", asciiStringWidgetClass, box, arg, 9);
X
X	t = XtParseTranslationTable(xprompt_TextTranslations);
X	XtOverrideTranslations(reply_w, t);
X	if (app_resources.texttranslations != NULL) {
X		t = XtParseTranslationTable(app_resources.texttranslations);
X		if (t == NULL) {
X			fprintf(stderr, "xprompt: error parsing translation table.\n");
X			exit(1);
X		}
X		XtOverrideTranslations(reply_w, t);
X	}
X	if (app_resources.texttranslationfile != NULL
X		&& get_user_text_translations(app_resources.texttranslationfile) < 0)
X		exit(1);
X
X	visible = 0;
X    XtPopup(popup, XtGrabNonexclusive);
X
X	/*
X	 * Handle the grab and/or warp, if necessary
X	 */
X    if (app_resources.grab) {
X	    XGrabKeyboard(XtDisplay(reply_w), XtWindow(reply_w), False,
X			GrabModeAsync, GrabModeAsync, CurrentTime);
X	    XSetInputFocus(XtDisplay(reply_w), XtWindow(reply_w),
X		        RevertToPointerRoot, CurrentTime);
X    }
X
X	if (app_resources.warp) {
X		XWindowAttributes reply_w_attr;
X		XEvent event;
X		long em;
X
X		if (XGetWindowAttributes(XtDisplay(reply_w), XtWindow(reply_w),
X								 &reply_w_attr) == 0)
X			app_resources.warp = FALSE;
X		else {
X			Window root_return, child_return;
X			int root_x_return, root_y_return;
X			int win_x_return, win_y_return;
X			unsigned int mask_return;
X
X			orig_x = -1;
X			orig_y = -1;
X			/*
X			 * Find out where the cursor is so that it can be put back
X			 * before the program exits.
X			 */
X			if (XQueryPointer(XtDisplay(popup), XtWindow(popup),
X							  &root_return, &child_return,
X							  &root_x_return, &root_y_return,
X							  &win_x_return, &win_y_return,
X							  &mask_return) != 0) {
X				orig_win = root_return;
X				orig_x = root_x_return;
X				orig_y = root_y_return;
X			}
X			reply_x = reply_w_attr.width - reply_w_attr.width / 10;
X			reply_y = reply_w_attr.height / 2;
X
X			/*
X			 * The following weirdness waits for the windows to become visible
X			 * before warping the cursor.
X			 * This is necessary to avoid the case where a window manager
X			 * repositions things *after* the warp has occurred.
X			 * Suggestions on the Right Thing welcome.
X			 */
X			if (!visible) {
X				em = VisibilityChangeMask;
X				XSelectInput(XtDisplay(popup), XtWindow(popup), em);
X				while (1) {
X					bzero(&event, sizeof(event));
X					XNextEvent(XtDisplay(popup), &event);
X					if (event.type == VisibilityNotify)
X						break;
X				}
X				em = reply_w_attr.all_event_masks;
X				XSelectInput(XtDisplay(popup), XtWindow(popup), em);
X			}
X			XWarpPointer(XtDisplay(reply_w), None, XtWindow(reply_w),
X						 0, 0, 0, 0, reply_x, reply_y);
X		}
X	}
X
X    XtMainLoop();
X}
X
Xstatic int
Xget_user_text_translations(file)
Xchar *file;
X{
X	char *p;
X	FILE *fp;
X	struct stat statb;
X	XtTranslations t;
X
X	if ((fp = fopen(file, "r")) == NULL) {
X		fprintf(stderr, "xprompt: Can't open translation file '%s'.\n", file); 
X		return(-1);
X	}
X	if (fstat(fileno(fp), &statb) < 0) {
X		fprintf(stderr, "xprompt: Can't stat translation file '%s'.\n", file);
X		fclose(fp);
X		return(-1);
X	}
X	if (statb.st_size == 0) {
X		fclose(fp);
X		return(0);
X	}
X	if ((p = (char *) malloc((unsigned) statb.st_size)) == NULL) {
X		fprintf(stderr, "xprompt: Can't malloc translation table.\n");
X		fclose(fp);
X		return(-1);
X	}
X	if (fread(p, statb.st_size, 1, fp) == 0) {
X		fprintf(stderr, "xprompt: error reading translation table.\n");
X		free(p);
X		fclose(fp);
X		return(-1);
X	}
X	fclose(fp);
X	if ((t = XtParseTranslationTable(p)) == NULL) {
X		fprintf(stderr, "xprompt: error parsing translation table.\n");
X		free(p);
X		return(-1);
X	}
X	XtOverrideTranslations(reply_w, t);
X	free(p);
X	return(0);
X}
X
Xstatic void
Xunwarp()
X{
X
X	if (app_resources.warp && orig_x != -1 && orig_y != -1) {
X		XWarpPointer(XtDisplay(reply_w), None, orig_win,
X					 0, 0, 0, 0, orig_x, orig_y);
X		XFlush(XtDisplay(reply_w));
X	}
X}
X
Xstatic void
Xunparsegeometry(buf, mask, w, h, x, y)
Xchar *buf;
Xint mask, w, h, x, y;
X{
X
X	sprintf(buf, "%dx%d%c%d%c%d",
X			w, h,
X			mask & XNegative ? '-' : '+', x,
X			mask & YNegative ? '-' : '+', y);
X}
END_OF_FILE
if test 18704 -ne `wc -c <'xprompt.c'`; then
    echo shar: \"'xprompt.c'\" unpacked with wrong size!
fi
# end of 'xprompt.c'
fi
if test -f 'xprompt.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xprompt.man'\"
else
echo shar: Extracting \"'xprompt.man'\" \(6556 characters\)
sed "s/^X//" >'xprompt.man' <<'END_OF_FILE'
X.TH XPROMPT 1 "29 January 1989"
X.SH NAME
Xxprompt \- prompt a user for input
X.SH SYNOPSIS
X.B xprompt
X[ X toolkit options ] [-rlen number] [-ibw number]
X.ti +8
X[-grab] [-nograb] [-pfn fontname] [-rfn fontname]
X.ti +8
X[-re] [-nre] [-tf filename] [-w wordchars]
X.ti +8
X[-warp] [-nowarp]
X.ti +8
X-p prompt [-r reply] [-p prompt [-r reply]] ...
X.SH DESCRIPTION
X.I Xprompt
Xpops up a window containing a prompt and an optional default reply.
XIf more than one prompt argument is given, the cursor-down key and the return
Xkey select the next prompt and the cursor-up key selects the previous
Xprompt.
XThe program exits normally by typing <ctrl> D or
Xpressing any mouse button inside the reply area of the window.
XThe replies are printed to stdout, one per line.
XMost standard editing characters
X(e.g., Delete, Backspace, <ctrl> U, cursor movement)
Xare available.
XThese default key bindings may be changed.
X.PP
X.I Xprompt
Xcan be aborted by typing <ctrl> C.
XIn this case, no output is generated and an exit code of
X1 is returned by the program.
X.PP
XThe default is to position the window in the middle of the screen
Xand to grab keyboard input so that the cursor need not be positioned
Xinside the text area.
X.SH OPTIONS
XThe following command line flags are recognized:
X.TP 8
X.BI \-rlen " number"
XSpecifies the maximum length of the reply.
XThe default is 80 characters.
X.TP 8
X.BI \-ibw " number"
XSpecifies the border width for the box bounding the text area.
XThe default is 1.
X.TP 8
X.B \-nograb
XThe cursor must be in the text portion of the window for
Xinput to be accepted.
X.TP 8
X.B \-grab
XThe cursor may be anywhere but
Xinput is directed to the text area.
X.TP 8
X.BI \-r " reply"
XInsert
X.I reply
Xinto the text area as the default reply.
X.TP 8
X.BI \-pfn " fontname"
XSpecifies the font to be used for the prompt string.
X.TP 8
X.BI \-rfn " fontname"
XSpecifies the font to be used for the reply string.
X.TP 8
X.BI \-re
XAfter all prompts have been seen, the return key causes the program to
Xexit normally (i.e., it becomes a synonym for <ctrl> D).
X.TP 8
X.BI \-nre
XThe return key will not terminate the program.
XThis is the default.
X.TP 8
X.BI \-tf " filename"
XSpecifies a file containing text translations, one per line,
Xto override the defaults.
X.I Xprompt
Xrecognizes the following functions in addition to those predefined:
X.RS 8
X.TP 4
X.BI abort()
XThe program terminates and returns an exit status of 1.
XThe default binding is Ctrl<Key>C.
X.TP 4
X.BI erase-line()
XErases the entire reply.
XThe default binding is Ctrl<Key>U.
X.TP 4
X.BI erase-word()
XBy default, a word is considered to consist of one or more alphanumeric
Xcharacters.
XNon-word characters following the cursor are deleted, then word characters
Xare deleted up until the next non-word character or the end of line.
XThere is no default binding.
X.TP 4
X.BI finish-prompt()
XAll replies are printed and the program terminates with an exit status
Xof 0.
XThe default bindings are Ctrl<Key>D, <Btn1Down>, <Btn2Down>, and <Btn3Down>.
X.TP 4
X.BI next-prompt()
XThe next prompt is displayed.
XThe list of prompts is circular, so the first prompt is displayed after
Xthe last.
XThe default bindings are Ctrl<Key>J, Ctrl<Key>M, <Key>Down, and <Key>Linefeed.
X.TP 4
X.BI next-prompt-or-finish()
XIf all prompts have been seen and returnExit is TRUE, finish-prompt()
Xwill be called otherwise next-prompt() will be called.
XThe default binding is <Key>Return.
X.TP 4
X.BI previous-prompt()
XThe previous prompt is displayed.
XThe last prompt is considered to be previous to the first.
XThe default binding is <Key>Up.
X.RE
XThe resource
X.B textTranslations
Xmay also be used to specify translations.
X.TP 8
X.BI \-w " wordchars"
XThe string
X.B wordchars
Xspecifies the characters that make up a word for the purpose
Xof the erase-word() function.
XThe string is in a format similar to that used by the
X.IR tar (1)
Xcommand:
X.RS 8
X.TP 4
X.BI a)
XA backslash followed by 1, 2, or 3 octal digits stands for the ASCII
Xcharacter corresponding to the octal value.  The value is limited to
X8 bits.
X.TP 4
X.BI b)
XA backslash followed by a non-octal digit character stands for the
Xcharacter.
X.TP 4
X.BI c)
XOther ASCII characters stand for themselves.
X.TP 4
X.BI d)
XThe range of characters between two characters, <c1> and <c2>,
Xis specified by a sequence of the form <c1>-<c2> when <c1> comes before
X<c2> in the ASCII character set.
X.RE
XThe default is "a-zA-Z0-9".
X.TP 8
X.B \-warp
XWarp the cursor into the text area and return it to its original position
Xbefore exiting.
X.TP 8
X.B \-nowarp
XDon't warp the cursor.
XThis is the default.
X.SH X DEFAULTS
XThe standard X toolkit options and resources are accepted.
XFor example, the default font can be changed by the standard
X.I -fn fontname
Xflag or by the resource
X.IR XPrompt*Font.
XIn addition, the following resources are understood:
X.TP 8
X.B "Rlen (\fPclass\fB Integer)"
XSpecifies the maximum length of the reply.
X.TP 8
X.B "insideborderWidth (\fPclass\fB BorderWidth)"
XSpecifies the border width for the box bounding the text area.
X.TP 8
X.B "Grab (\fPclass\fB Boolean)"
XSpecifies whether keyboard input should be focussed on the text area
Xregardless of where the cursor is.
X.TP 8
X.B "replyFont (\fPclass\fB Font)"
XThe font to use for the reply string, overriding
XXPrompt*Font.
X.TP 8
X.B "promptFont (\fPclass\fB Font)"
XThe font to use for the prompt string, overriding
XXPrompt*Font.
X.TP 8
X.B "returnExit (\fPclass\fB Boolean)"
XSpecifies whether the return key should allow normal termination if
Xall prompts have been seen.
X.TP 8
X.B "textTranslations (\fPclass\fB String)"
XText widget translations.
X.TP 8
X.B "textTranslationFile (\fPclass\fB String)"
XThe name of a file containing text widget translations.
X.TP 8
X.B "Warp (\fPclass\fB Boolean)"
XWarp the cursor into the text area.
X.TP 8
X.B "wordChars (\fPclass\fB String)
XThe set of character that make up a word for the purpose of
Xthe erase-word() function.
X.SH NOTE
XIf
X.I xprompt
Xis invoked from a Bourne shell script,
Xthe following hack can be used to quickly grab multi-reply output:
X.sp 2
X.in +4
Xreply=`xprompt -p "Prompt1" -p "Prompt2" -p "Prompt3"`
X.br
XIFS="
X.br
X"
X.br
Xset $reply
X.br
Xecho "First reply is: $1"
X.br
Xecho "Second reply is: $2"
X.br
Xecho "Third reply is: $3"
X.in -4
X.SH EXIT STATUS
XOn normal completion 0 is returned.
XIf the program is aborted, 1 is returned.
X.SH SEE ALSO
Xtar(1)
X.SH AUTHOR
X.nf
XBarry Brachman
Xbrachman at cs.ubc.ca
XDept. of Computer Science
XUniversity of British Columbia
X
XValuable suggestions by Rick Morrison and Bob Mende.
X.SH BUGS
XThe reply is limited to a single line.
XThe user is responsible for ensuring that a proper window size
Xis chosen.
X
END_OF_FILE
if test 6556 -ne `wc -c <'xprompt.man'`; then
    echo shar: \"'xprompt.man'\" unpacked with wrong size!
fi
# end of 'xprompt.man'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    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
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x



More information about the Comp.sources.x mailing list