[net.sources] DPY - 2 of 2

ejb@think.ARPA (Erik Bailey) (04/25/86)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	dpy.c
#	dpyget.c
#	dpymove.c
#	dpyplace.c
#	dpyread.c
#	dpywindow.c
#	gensubs.c
#	test1.c
#	test2.c
#	makefile
#	makefile.bsd
#	makefile.usg
#	ns32ksubs.s
#	vaxsubs.s
# This archive created: Thu Apr 24 22:41:37 1986
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'dpy.c'" '(22206 characters)'
if test -f 'dpy.c'
then
	echo shar: "will not over-write existing file 'dpy.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'dpy.c'
	Xstatic char *sccsid = "@(#)dpy.c	1.46	2/27/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X
	X
	X/*
	X * Different curses package (by David I. Bell).
	X * Modified to run under System V by Alan P.W. Hewett.
	X * These dpy module sources are in the public domain, and can be copied
	X * or used as desired, with the following restrictions:
	X * 1.	All copyright notices (and this notice) must be preserved.
	X * 2.	The dpy sources (even if modified) cannot be sold for profit.
	X * 3.	If any sources are modified, a sentence must exist by the
	X *	copyright notice of each modified source file which says that
	X *	the file has been modified.
	X */
	X
	X
	X#include <stdio.h>		/* standard I/O */
	X#include <signal.h>		/* signals */
	X#include "dpy.h"		/* window definitions */
	X
	X#define	DEL	0177		/* delete character */
	X#define	EOL	'\n'		/* end of line character */
	X#define	RET	'\r'		/* return character */
	X#define	BS	'\b'		/* backspace character */
	X#define	TAB	'\t'		/* tab character */
	X#define	SPACE	' '		/* space character */
	X#define	TRUE	1		/* true value */
	X#define	FALSE	0		/* false value */
	X#define	INTSIZ	(sizeof(int))	/* size of an integer */
	X
	Xextern	short	ospeed;		/* output speed for tputs to use */
	Xextern	char	PC;		/* pad character for tputs to use */
	Xstruct	window	window;		/* the window */
	Xstatic	int	dpytputs();	/* called by tputs to type to terminal */
	Xstatic	int	dpysputs();	/* called by tputs to save characters */
	Xint	dpystop();		/* stop routine */
	Xchar	*tgetstr();		/* return termcap string */
	Xchar	*malloc();		/* allocate memory */
	Xchar	*getenv();		/* return environment variable */
	X
	X
	X/*
	X * Initialize the window structure.  Returns nonzero on failure with a
	X * message already typed.  The ttytype argument is the terminal type string,
	X * or NULL if the TERM environment variable is to be used.  Modes is a
	X * string whose characters describe the desired state of the terminal.
	X * These are:
	X * 	+	turn on mode indicated by next character (default)
	X *	-	turn off mode indicated by next character.
	X *	c	cbreak mode (return each character as typed, without waiting
	X *		for an end of line, and leave signal processing on).
	X *	e	echoing of typed-in characters is enabled.
	X *	r	raw mode (return each character as typed, no canonical or
	X *		signal processing of any kind).
	X *	<SP>	spaces are ignored
	X * So the terminal modes before dpy runs are normally "e -c -r".
	X * A NULL modes pointer defaults the modes to "-e c".
	X */
	Xdpyinit(ttytype, modes)
	X	register char	*ttytype;	/* terminal type, or NULL for default */
	X	char	*modes;			/* terminal modes */
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*cp;		/* character pointer */
	X	register char	*sp;		/* pointer for spaces */
	X	register int	size;		/* size of character array */
	X	int on;				/* whether or not mode is on */
	X#ifdef BSD
	X	struct	ltchars	ltchars;	/* local terminal characters */
	X	struct	tchars	tchars;		/* terminal characters */
	X#endif BSD
	X
	X	wp = &window;
	X	wp->inited = FALSE;
	X	wp->output = FALSE;
	X	if (ttytype == NULL) {
	X		ttytype = getenv("TERM");
	X		if (ttytype == NULL) {
	X			fprintf(stderr, "dpyinit: TERM not defined\n");
	X			return(1);
	X		}
	X	}
	X	size = tgetent(wp->tdata, ttytype);
	X	if (size <= 0) {
	X		fprintf(stderr, size ? "dpyinit: cannot open termcap file\n"
	X			: "dpyinit: unknown terminal type %s\n", ttytype);
	X		return(1);
	X	}
	X	/*
	X	 * Collect current tty modes, and remember editing characters
	X	 */
	X	wp->c_kill = CKILL;		/* init in case stdin is not a tty */
	X	wp->c_erase = CERASE;
	X	wp->c_werase = CWERASE;
	X	wp->c_lnext = CLNEXT;
	X	wp->c_rprnt = CRPRNT;
	X	wp->c_eof = CEOF;
	X#ifdef	BSD
	X	if (ioctl(STDIN, TIOCGETP, &wp->old0ttyblk) == 0) {
	X		wp->c_erase = wp->old0ttyblk.sg_erase;
	X		wp->c_kill = wp->old0ttyblk.sg_kill;
	X	}
	X	if (ioctl(STDIN, TIOCGLTC, &ltchars) == 0) {
	X		wp->c_werase = ltchars.t_werasc;
	X		wp->c_rprnt = ltchars.t_rprntc;
	X		wp->c_lnext = ltchars.t_lnextc;
	X	}
	X	if (ioctl(STDIN, TIOCGETC, &tchars) == 0) {
	X		wp->c_eof = tchars.t_eofc;
	X	}
	X	wp->old1ttyblk.sg_ospeed = 0;
	X	ioctl(STDOUT, TIOCGETP, &wp->old1ttyblk);
	X	ospeed = wp->old1ttyblk.sg_ospeed;	/* save speed for tputs */
	X#endif	BSD
	X#ifdef	USG
	X	if (ioctl(STDIN, TCGETA, &wp->old0ttyblk) == 0) {
	X		wp->c_erase = wp->old0ttyblk.c_cc[VERASE];
	X		wp->c_kill = wp->old0ttyblk.c_cc[VKILL];
	X		wp->c_eof = wp->old0ttyblk.c_cc[VEOF];
	X	}
	X	ioctl(STDOUT, TCGETA, &wp->old1ttyblk);
	X#endif	USG
	X	/*
	X	 * Collect terminal capability strings
	X	 */
	X	wp->nrows = tgetnum("li");
	X	wp->ncols = tgetnum("co");
	X	wp->tc_am = tgetflag("am");
	X	wp->tbuf[0] = '\0';
	X	wp->tptr = wp->tbuf;
	X	(void) tgetstr("pc", &wp->tptr);
	X	PC = wp->tbuf[0];
	X	wp->tptr = wp->tbuf;
	X	wp->tc_ho = tgetstr("ho", &wp->tptr);
	X	wp->tc_hocc = wp->tptr - wp->tbuf - 1;
	X	wp->tc_ce = tgetstr("ce", &wp->tptr);
	X	wp->tc_cd = tgetstr("cd", &wp->tptr);
	X	wp->tc_cm = tgetstr("cm", &wp->tptr);
	X	if ((wp->nrows <= 0) || (wp->ncols <= 0) || (wp->tc_ce == NULL)
	X		|| (wp->tc_cd == NULL) || (wp->tc_cm == NULL)) {
	X			fprintf(stderr, "dpyinit: missing termcap entry\n");
	X			return(1);
	X	}
	X	sp = wp->tptr;			/* apply padding to clear screen */
	X	tputs(wp->tc_cd, wp->nrows, dpysputs);
	X	wp->tc_cd = sp;
	X	wp->tc_cdcc = wp->tptr - sp;
	X	sp = wp->tptr;			/* and to clear line string */
	X	tputs(wp->tc_ce, 1, dpysputs);
	X	wp->tc_ce = sp;
	X	wp->tc_cecc = wp->tptr - sp;
	X	if (wp->tc_ho == NULL) {	/* make home up string if not defined */
	X		sp = wp->tptr;
	X		tputs(tgoto(wp->tc_cm, 0, 0), 1, dpysputs);
	X		wp->tc_ho = sp;
	X		wp->tc_hocc = wp->tptr - sp;
	X	}
	X	wp->delta = (wp->ncols + INTSIZ) &~ (INTSIZ-1);	/* round up */
	X	size = wp->nrows * wp->delta;
	X	cp = malloc(2 * (size + INTSIZ));
	X	if (cp == NULL) {
	X		fprintf(stderr, "dpyinit: failed to allocate memory\n");
	X		return(1);
	X	}
	X	wp->begdata = cp;
	X	wp->enddata = cp + size;
	X	wp->begwin = cp;
	X	wp->endwin = cp + size - wp->delta;
	X	wp->begrow = cp;
	X	wp->endrow = cp + wp->ncols;
	X	wp->cp = cp;
	X	wp->screen = cp + size + INTSIZ;
	X	for (sp = cp + (2 * (size + INTSIZ)) - 1; sp >= cp; sp--) *sp = SPACE;
	X	*((int *)(cp + size)) = 0;	/* terminate end of screens */
	X	*((int *)(wp->screen + size)) = 0;
	X	wp->currow = 0;
	X	wp->curcol = 0;
	X	wp->noctrl = 0;
	X	wp->nocrlf = 0;
	X	wp->nomove = 0;
	X	wp->scroll = 0;
	X	wp->full = 0;
	X	wp->tabsize = 8;
	X	wp->begchange = wp->enddata;
	X	wp->endchange = wp->begdata;
	X	/*
	X	 * Copy old tty modes to new ones, and modify them as specified
	X	 */
	X	wp->new0ttyblk = wp->old0ttyblk;
	X	wp->new1ttyblk = wp->old1ttyblk;
	X	if (modes == (char*)NULL) modes = "-e c";
	X	on = TRUE;
	X	for (cp = modes; *cp ; cp++) {		/* scan mode string */
	X		switch (*cp) {
	X		case ' ':			/* spaces (ignored) */
	X			continue;
	X		case '+':			/* turn on next mode */
	X			on = TRUE;
	X			continue;
	X		case '-':			/* turn off next mode */
	X			on = FALSE;
	X			continue;
	X#ifdef	BSD
	X		case 'e':			/* enable echoing */
	X			if (on) {
	X				wp->new0ttyblk.sg_flags |= ECHO;
	X				wp->new1ttyblk.sg_flags |= ECHO;
	X			} else {
	X				wp->new0ttyblk.sg_flags &= ~ECHO;
	X				wp->new1ttyblk.sg_flags &= ~ECHO;
	X			}
	X			break;
	X
	X		case 'c':			/* enable character mode */
	X			if (on) {
	X				wp->new0ttyblk.sg_flags |= CBREAK;
	X				wp->new1ttyblk.sg_flags |= CBREAK;
	X			} else {
	X				wp->new0ttyblk.sg_flags &= ~CBREAK;
	X				wp->new1ttyblk.sg_flags &= ~CBREAK;
	X			}
	X			break;
	X
	X		case 'r':			/* enable raw mode */
	X			if (on) {
	X				wp->new0ttyblk.sg_flags |= RAW;
	X				wp->new1ttyblk.sg_flags |= RAW;
	X			} else {
	X				wp->new0ttyblk.sg_flags &= ~RAW;
	X				wp->new1ttyblk.sg_flags &= ~RAW;
	X			}
	X			break;
	X#endif	BSD
	X#ifdef	USG
	X		case 'e':			/* enable echoing */
	X			if (on) {
	X				wp->new0ttyblk.c_lflag |= ECHO | ECHOE | ECHOK ;
	X				wp->new1ttyblk.c_lflag |= ECHO | ECHOE | ECHOK ;
	X			} else {
	X				wp->new0ttyblk.c_lflag &= ~(ECHO|ECHOE|ECHOK) ;
	X				wp->new1ttyblk.c_lflag &= ~(ECHO|ECHOE|ECHOK) ;
	X			}
	X			break ;
	X
	X		case 'c':			/* enable character mode */
	X			if (on) {
	X				wp->new0ttyblk.c_iflag |= ISTRIP ;
	X				wp->new0ttyblk.c_lflag &= ~ICANON ;
	X				wp->new0ttyblk.c_cc[VMIN] = 1 ;
	X				wp->new0ttyblk.c_cc[VTIME] = 0 ;
	X				wp->new1ttyblk.c_iflag |= ISTRIP ;
	X				wp->new1ttyblk.c_lflag &= ~ICANON ;
	X				wp->new1ttyblk.c_cc[VMIN] = 1 ;
	X				wp->new1ttyblk.c_cc[VTIME] = 0 ;
	X			} else {
	X	    			wp->new0ttyblk.c_iflag |= (ICRNL|IUCLC) ;
	X	    			wp->new0ttyblk.c_lflag |= ICANON ;
	X	    			wp->new0ttyblk.c_cc[VEOF] =
	X					wp->old0ttyblk.c_cc[VEOF] ;
	X	    			wp->new0ttyblk.c_cc[VEOL] =
	X					wp->old0ttyblk.c_cc[VEOL] ;
	X	    			wp->new1ttyblk.c_iflag |= (ICRNL|IUCLC) ;
	X	    			wp->new1ttyblk.c_lflag |= ICANON ;
	X	    			wp->new1ttyblk.c_cc[VEOF] =
	X					wp->old1ttyblk.c_cc[VEOF] ;
	X	    			wp->new1ttyblk.c_cc[VEOL] =
	X					wp->old1ttyblk.c_cc[VEOL] ;
	X			}
	X			break ;
	X
	X		case 'r':			/* enable raw mode */
	X			if (on) {
	X	    			wp->new0ttyblk.c_iflag &=
	X					~(BRKINT|IGNPAR|ISTRIP|IXON|IXANY) ;
	X	    			wp->new0ttyblk.c_oflag &= ~OPOST ;
	X	    			wp->new0ttyblk.c_cflag =
	X					(wp->new0ttyblk.c_cflag|CS8) & ~PARENB ;
	X	    			wp->new0ttyblk.c_lflag &= ~ICANON ;
	X	    			wp->new0ttyblk.c_cc[VMIN] = 1 ;
	X	    			wp->new0ttyblk.c_cc[VTIME] = 0 ;
	X	    			wp->new1ttyblk.c_iflag &=
	X					~(BRKINT|IGNPAR|ISTRIP|IXON|IXANY) ;
	X	    			wp->new1ttyblk.c_oflag &= ~OPOST ;
	X	    			wp->new1ttyblk.c_cflag =
	X					(wp->new1ttyblk.c_cflag|CS8) & ~PARENB ;
	X	    			wp->new1ttyblk.c_lflag &= ~ICANON ;
	X	    			wp->new1ttyblk.c_cc[VMIN] = 1 ;
	X	    			wp->new1ttyblk.c_cc[VTIME] = 0 ;
	X			} else {
	X	    			wp->new0ttyblk.c_iflag |=
	X					(BRKINT|IGNPAR|ISTRIP|IXON
	X					|IXANY|ICRNL|IUCLC) ;
	X	    			wp->new0ttyblk.c_oflag |= OPOST ;
	X	    			wp->new0ttyblk.c_cflag =
	X					(wp->new0ttyblk.c_cflag & ~CSIZE) |
	X					CS7 | PARENB ;
	X	    			wp->new0ttyblk.c_lflag |= ICANON | ISIG ;
	X	    			wp->new0ttyblk.c_cc[VEOF] = CEOF ;
	X	    			wp->new0ttyblk.c_cc[VEOL] = 0 ;
	X	    			wp->new0ttyblk.c_cc[VEOL2] = 0 ;
	X	    			wp->new1ttyblk.c_iflag |=
	X					(BRKINT|IGNPAR|ISTRIP|IXON|
	X					IXANY|ICRNL|IUCLC) ;
	X	    			wp->new1ttyblk.c_oflag |= OPOST ;
	X	    			wp->new1ttyblk.c_cflag =
	X					(wp->new1ttyblk.c_cflag & ~CSIZE) |
	X					CS7 | PARENB ;
	X	    			wp->new1ttyblk.c_lflag |= ICANON | ISIG ;
	X	    			wp->new1ttyblk.c_cc[VEOF] = CEOF ;
	X	    			wp->new1ttyblk.c_cc[VEOL] = 0 ;
	X	    			wp->new1ttyblk.c_cc[VEOL2] = 0 ;
	X			}
	X			break;
	X#endif	USG
	X		default:
	X			fprintf(stderr, "dpyinit: illegal flag: %c%c\n",
	X				(on ? '+' : '-'), *cp);
	X			return(1);
	X		}
	X		on = TRUE;		/* reset mode */
	X	}
	X	/*
	X	 * Set the new modes for real
	X	 */
	X#ifdef	BSD
	X	wp->new1ttyblk.sg_flags &= ~XTABS;
	X	signal(SIGTSTP, dpystop);
	X	ioctl(STDIN, TIOCSETP, &wp->new0ttyblk);
	X	ioctl(STDOUT, TIOCSETP, &wp->new1ttyblk);
	X#endif	BSD
	X#ifdef	USG
	X	wp->new1ttyblk.c_oflag &= ~TAB3 ;
	X	ioctl(STDIN,TCSETAW,&wp->new0ttyblk) ;
	X	ioctl(STDOUT,TCSETAW,&wp->new1ttyblk) ;
	X#endif	USG	
	X	wp->inited = TRUE;
	X	return(0);
	X}
	X
	X
	X/*
	X * Terminate the window, home down to the bottom of the screen, and reset
	X * the terminal modes to their original state.
	X */
	Xdpyclose()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X
	X	wp = &window;
	X	if (wp->inited) {
	X		wp->inited = FALSE;
	X		if (wp->output) {
	X			domove(wp->nrows - 1, 0, (char *)NULL);
	X			fwrite(wp->tc_ce, 1, wp->tc_cecc, stdout);
	X			fflush(stdout);
	X		}
	X		free(wp->begdata);
	X#ifdef	BSD
	X		ioctl(STDIN, TIOCSETP, &wp->old0ttyblk);
	X		ioctl(STDOUT, TIOCSETP, &wp->old1ttyblk);
	X#endif	BSD
	X#ifdef	USG
	X		ioctl(STDIN, TCSETAW, &wp->old0ttyblk);
	X		ioctl(STDOUT, TCSETAW, &wp->old1ttyblk);
	X#endif	USG
	X	}
	X	return(0);
	X}
	X
	X
	X/*
	X * Put a given number of characters to the window at the current write location.
	X * Certain control characters have effects, others print as ^X or are ignored.
	X * Automatic wrapping to the next line is possible, and scrolling when the last
	X * line is full. Returns nonzero if the window cannot hold the whole buffer.
	X */
	Xdpywrite(buf, count)
	X	register char	*buf;		/* buffer address */
	X	int	count;			/* number of characters */
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*endbuf;	/* end of buffer to write */
	X	register char	*cp;		/* current character pointer */
	X	register int	ch;		/* character to store */
	X
	X	wp = &window;
	X	if (wp->full) return(1);
	X	cp = wp->cp;
	X	if (cp < wp->begchange) wp->begchange = cp;
	X	for (endbuf = buf + count; buf < endbuf; buf++) {
	X		ch = *buf;
	X		if (ch < ' ') {			/* control character */
	X			if (ch == EOL) {	/* new line */
	X				clear(cp, wp->endrow);
	X				if (cp >= wp->endwin) {	/* window full */
	X					wp->endchange = wp->endrow;
	X					if (wp->scroll == 0) {
	X						wp->full = 1;
	X						wp->cp = wp->begrow;
	X						return(1);
	X					}
	X					wp->cp = cp;
	X					dpyscroll();
	X					cp = wp->begrow;
	X					continue;
	X				}
	X				wp->begrow += wp->delta;
	X				wp->endrow += wp->delta;
	X				cp = wp->begrow;
	X				continue;
	X			}
	X			if (ch == TAB) {	/* tab */
	X				wp->cp = cp;
	X				do {
	X					if (dpywrite(" ", 1)) return(1);
	X				} while ((wp->cp - wp->begrow) % wp->tabsize);
	X				cp = wp->cp;
	X				continue;
	X			}
	X			if (ch == BS) {		/* backspace */
	X				if (cp > wp->begrow) cp--;
	X				continue;
	X			}
	X			if (ch == RET) {	/* return character */
	X				cp = wp->begrow;
	X				continue;
	X			}
	X			/*
	X			 * Obscure control character, show as ^X
	X			 */
	X			if (wp->noctrl) continue;
	X			wp->cp = cp;
	X			if (dpywrite("^", 1) || dpychar(ch + '@')) return(1);
	X			cp = wp->cp;
	X			continue;
	X		}
	X		if (ch == DEL) {		/* delete character */
	X			if (wp->noctrl) continue;
	X			wp->cp = cp;
	X			if (dpywrite("^?", 2)) return(1);
	X			cp = wp->cp;
	X			continue;
	X		}
	X		/*
	X		 * Normal printing character
	X		 */
	X		if (cp >= wp->endrow) {		/* end of row, see if do crlf */
	X			wp->cp = cp;
	X			if (cp > wp->endchange) wp->endchange = cp;
	X			if (wp->nocrlf) return(1);
	X			if (cp >= wp->endwin) {
	X				if (wp->scroll == 0) return(1);
	X				dpyscroll();
	X				cp = wp->begrow;
	X				*cp++ = ch;
	X				continue;
	X			}
	X			wp->begrow += wp->delta;
	X			wp->endrow += wp->delta;
	X			cp = wp->begrow;
	X		}
	X		*cp++ = ch;
	X	}
	X	wp->cp = cp;
	X	if (cp > wp->endchange) wp->endchange = cp;
	X	return(0);
	X}
	X
	X
	X/*
	X * Put a single character to the window.
	X * Returns nonzero if full.
	X */
	Xdpychar(ch)
	X	char	ch;
	X{
	X	return(dpywrite(&ch, 1));
	X}
	X
	X
	X/*
	X * Put a null-terminated string to the window.
	X * Returns nonzero if full.
	X */
	Xdpystr(str)
	X	char	*str;
	X{
	X	return(dpywrite(str, strlen(str)));
	X}
	X
	X
	X
	X/*
	X * Print a formatted string to the window.  Returns nonzero if full.
	X * This routine is a ripped off version of sprintf.  This routine is
	X * machine-dependent!!
	X */
	X#ifdef	BSD
	Xdpyprintf(fmt, args)
	X	char	*fmt;			/* format string */
	X{
	X	FILE	_strbuf;		/* file header */
	X	char	buf[5000];		/* data storage */
	X
	X	_strbuf._flag = _IOWRT+_IOSTRG;
	X	_strbuf._ptr = buf;
	X	_strbuf._cnt = 32767;
	X	_doprnt(fmt, &args, &_strbuf);
	X	return(dpywrite(buf, _strbuf._ptr - buf));
	X}
	X#endif	BSD
	X#ifdef	USG
	X
	X#include <varargs.h>
	X
	Xdpyprintf(format, va_alist)
	Xchar *format;
	Xva_dcl
	X{
	X	register int count;
	X	FILE siop;
	X	va_list ap;
	X	unsigned char	buf[5000];		/* data storage */
	X
	X	siop._cnt = sizeof(buf) ;
	X	siop._base = siop._ptr = &buf[0] ;
	X	siop._flag = _IOWRT;
	X	siop._file = _NFILE;
	X	va_start(ap);
	X	count = _doprnt(format, ap, &siop);
	X	va_end(ap);
	X	*siop._ptr = '\0'; /* plant terminating null character */
	X	return(dpywrite(buf, siop._ptr - buf));
	X}
	X#endif	USG
	X
	X
	X/* Clear to the end of the current row without changing the write location */
	Xdpyclrline()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*cp;		/* current character */
	X	register char	*endcp;		/* ending character */
	X
	X	wp = &window;
	X	if (wp->full) return;
	X	cp = wp->cp;
	X	endcp = wp->endrow;
	X	if (cp < wp->begchange) wp->begchange = cp;
	X	if (endcp > wp->endchange) wp->endchange = cp;
	X	clear(cp, endcp);
	X}
	X
	X
	X/* Clear to the end of the window without changing the write location */
	Xdpyclrwindow()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*begcp;		/* beginning character */
	X	register char	*cp;		/* current character */
	X	register char	*endcp;		/* ending character */
	X
	X	wp = &window;
	X	if (wp->full) return;
	X	begcp = wp->begrow;
	X	endcp = wp->endrow;
	X	cp = wp->cp;
	X	if (cp < wp->begchange) wp->begchange = cp;
	X	while (1) {
	X		clear(cp, endcp);
	X		if (begcp >= wp->endwin) break;
	X		begcp += wp->delta;
	X		endcp += wp->delta;
	X		cp = begcp;
	X	}
	X	if (endcp > wp->endchange) wp->endchange = endcp;
	X}
	X
	X
	X/* Set the current write position to the top left corner of the window */
	Xdpyhome()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X
	X	wp = &window;
	X	wp->endrow += wp->begwin - wp->begrow;
	X	wp->begrow = wp->begwin;
	X	wp->cp = wp->begrow;
	X	wp->full = 0;
	X}
	X
	X
	X/* Scroll the current window upwards a line to make room for more data. */
	Xdpyscroll()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*currow;	/* beginning of current row */
	X	register char	*nextrow;	/* beginning of next row */
	X	register int	cols;		/* columns in window */
	X
	X	wp = &window;
	X	cols = wp->endrow - wp->begrow;
	X	currow = wp->begwin;
	X	nextrow = currow + wp->delta;
	X	while (currow < wp->endwin) {		/* move each line up */
	X		bcopy(nextrow, currow, cols);
	X		currow += wp->delta;
	X		nextrow += wp->delta;
	X	}
	X	clear(currow, currow + cols);		/* clear last line */
	X	wp->begchange = wp->begwin;
	X	wp->endchange = wp->endwin + cols;
	X}
	X
	X
	X/*
	X * Return the row number being written to, or -1 if out of the window.
	X * The row number is relative to the beginning of the window.
	X */
	Xdpygetrow()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X
	X	wp = &window;
	X	if (wp->full) return(-1);
	X	return((wp->cp - wp->begwin) / wp->delta);
	X}
	X
	X
	X/*
	X * Return the column number being written to, or -1 if out of the window.
	X * The column number is relative to the current window.
	X */
	Xdpygetcol()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X
	X	wp = &window;
	X	if (wp->full) return(-1);
	X	if (wp->cp < wp->endrow) return(wp->cp - wp->begrow);
	X	if (wp->nocrlf) return(-1);
	X	return(0);
	X}
	X
	X
	X/* Make the screen match the data as previously written by the user */
	Xdpyupdate()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*scp;		/* screen character pointer */
	X	register char	*cp;		/* current character */
	X	register char	*spcp;		/* cp where spaces remain in row */
	X	register char	*endrow;	/* end of row */
	X	register char	*begrow;	/* beginning of row */
	X	register int	row;		/* current row number */
	X	int	diff;
	X
	X	wp = &window;
	X	if (wp->output == 0) {		/* first output, clear screen */
	X		wp->output = TRUE;
	X		fwrite(wp->tc_ho, 1, wp->tc_hocc, stdout);
	X		fwrite(wp->tc_cd, 1, wp->tc_cdcc, stdout);
	X	}
	X	cp = wp->begchange;
	X	scp = wp->screen + (cp - wp->begdata);
	X	endrow = 0;
	X	while (cp < wp->endchange) {	/* look for a difference */
	X		diff = strdif(cp, scp, wp->endchange - cp);
	X		cp += diff;
	X		scp += diff;
	X		if (cp >= wp->endchange) break;
	X		if (cp >= endrow) {
	X			row = (cp - wp->begdata) / wp->delta;
	X			begrow = wp->begdata + (row * wp->delta);
	X			endrow = begrow + wp->ncols;
	X			spcp = endrow - 1;
	X			while ((spcp >= begrow) && (*spcp == SPACE))
	X				spcp--;
	X			spcp++;
	X		}
	X		domove(row, cp - begrow, begrow);
	X		if (cp >= spcp) {		/* clear rest of line */
	X			fwrite(wp->tc_ce, 1, wp->tc_cecc, stdout);
	X			while (cp < endrow) {
	X				*scp++ = SPACE;
	X				cp++;
	X			}
	X			continue;
	X		}
	X		putchar(*cp);
	X		*scp++ = *cp++;
	X		if (++wp->curcol >= wp->ncols) {	/* fixup last column */
	X			wp->curcol--;
	X			if (wp->tc_am) {
	X				wp->currow++;
	X				wp->curcol = 0;
	X			}
	X		}
	X	}
	X	wp->begchange = wp->enddata;
	X	wp->endchange = wp->begdata;
	X	if (wp->nomove == 0) dpycursor();
	X	fflush(stdout);
	X}
	X
	X
	X/*
	X * Set the terminal cursor at the current write location.
	X * If the window is full, the cursor is placed at the front of the
	X * last line in the window.  If lines are not being wrapped and the
	X * line is full, the cursor is placed at the end of the line.
	X * Otherwise, the cursor is placed at the location being written to next.
	X */
	Xstatic
	Xdpycursor()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*cp;		/* current write location */
	X	register char	*begrow;	/* beginning of current row */
	X	register int	row;		/* row number */
	X
	X	wp = &window;
	X	cp = wp->cp;
	X	if (wp->full)
	X		cp = wp->endwin;
	X	else if (cp >= wp->endrow) {
	X		if (wp->nocrlf || (wp->begrow >= wp->endwin))
	X			cp = wp->endrow - 1;
	X		else
	X			cp = wp->begrow + wp->delta;
	X	}
	X	row = (cp - wp->begdata) / wp->delta;
	X	begrow = wp->begdata + (row * wp->delta);
	X	domove(row, cp - begrow, begrow);
	X}
	X
	X
	X/*
	X * Subroutine to move to the given location on the screen.  The third argument
	X * is a pointer to beginning of the desired row in case we find it is faster
	X * to type the intervening characters.  If NULL, we must use addressing.
	X */
	Xstatic
	Xdomove(row, col, cp)
	X	register int	row;		/* desired row */
	X	register int	col;		/* desired column */
	X	register char	*cp;		/* data on desired row */
	X{
	X	register struct	window	*wp;	/* window structure */
	X
	X	wp = &window;
	X	if (cp && (row == wp->currow) && (col >= wp->curcol)
	X		&& (col < wp->curcol + 6)) {		/* a few ahead */
	X			cp += wp->curcol;
	X			while (wp->curcol < col) {
	X				putchar(*cp);
	X				cp++;
	X				wp->curcol++;
	X			}
	X			return;
	X	}
	X	if ((col == 0) && (row == wp->currow + 1)) {	/* next row */
	X		putchar('\n');
	X		wp->currow++;
	X		wp->curcol = 0;
	X		return;
	X	}
	X	tputs(tgoto(wp->tc_cm, col, row), 1, dpytputs);	/* arbitrary */
	X	wp->currow = row;
	X	wp->curcol = col;
	X}
	X
	X
	X/* Local routine called by tputs to print a character */
	Xstatic
	Xdpytputs(ch)
	X	char	ch;
	X{
	X	putchar(ch);
	X}
	X
	X
	X/* Local routine called by tputs to save a character */
	Xstatic
	Xdpysputs(ch)
	X	char	ch;
	X{
	X	*window.tptr++ = ch;
	X}
	X
	X
	X/* Redraw the screen to fix glitches */
	Xdpyredraw()
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*cp;		/* current character */
	X	register char	*endcp;		/* ending character */
	X
	X	wp = &window;
	X	cp = wp->screen;
	X	endcp = cp + (wp->nrows * wp->delta);
	X	clear(cp, endcp);
	X	wp->currow = 0;
	X	wp->curcol = 0;
	X	wp->begchange = wp->begdata;
	X	wp->endchange = wp->enddata;
	X	fwrite(wp->tc_ho, 1, wp->tc_hocc, stdout);
	X	fwrite(wp->tc_cd, 1, wp->tc_cdcc, stdout);
	X	dpyupdate();
	X}
	X
	X
	X/*
	X * Routine called on a terminal stop signal.  Restore the original terminal
	X * state, home down to the bottom, and really stop.  If continued, restore
	X * the new terminal state and redraw the screen.
	X */
	Xdpystop()
	X{
	X#ifdef	BSD
	X	register struct	window	*wp;	/* window pointer */
	X
	X	wp = &window;
	X	if (wp->output) {
	X		domove(wp->nrows - 1, 0, (char *)NULL);
	X		fflush(stdout);
	X	}
	X	ioctl(STDIN, TIOCSETP, &wp->old0ttyblk);
	X	ioctl(STDOUT, TIOCSETP, &wp->old1ttyblk);
	X	kill(getpid(), SIGSTOP);	/* really stop */
	X	ioctl(STDIN, TIOCSETP, &wp->new0ttyblk);
	X	ioctl(STDOUT, TIOCSETP, &wp->new1ttyblk);
	X	if (wp->output) dpyredraw();
	X#endif	BSD
	X}
SHAR_EOF
if test 22206 -ne "`wc -c < 'dpy.c'`"
then
	echo shar: "error transmitting 'dpy.c'" '(should have been 22206 characters)'
fi
fi
echo shar: "extracting 'dpyget.c'" '(1117 characters)'
if test -f 'dpyget.c'
then
	echo shar: "will not over-write existing file 'dpyget.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'dpyget.c'
	X#ifdef SCCS
	Xstatic char *sccsid = "@(#)dpyget.c	1.1	1/28/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X#endif
	X
	X#include "dpy.h"
	X
	X/* Return the character which is at the specified location in the current
	X * window.  The character returned is the one in our internal screen image,
	X * not what is actually on the screen (these will be identical if dpyupdate
	X * was just called).  Returns negative if the coordinates are illegal.
	X */
	Xdpyget(row, col)
	X	register int	row;		/* row to get character from */
	X	register int	col;		/* column to get character from */
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*cp;		/* character pointer */
	X	register int	winrows;	/* number of rows in window */
	X	register int	wincols;	/* number of columns in window */
	X
	X	wp = &window;
	X	winrows = ((wp->endwin - wp->begwin) / wp->delta) + 1;
	X	wincols = wp->endrow - wp->begrow;
	X	if (row < 0) row += winrows;
	X	if (col < 0) col += wincols;
	X	if (((unsigned)row >= winrows) || ((unsigned)col >= wincols)) {
	X		return(-1);		/* out of window */
	X	}
	X	cp = wp->begwin + (row * wp->delta) + col;
	X	return(*cp & 0xff);
	X}
SHAR_EOF
if test 1117 -ne "`wc -c < 'dpyget.c'`"
then
	echo shar: "error transmitting 'dpyget.c'" '(should have been 1117 characters)'
fi
fi
echo shar: "extracting 'dpymove.c'" '(1069 characters)'
if test -f 'dpymove.c'
then
	echo shar: "will not over-write existing file 'dpymove.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'dpymove.c'
	X#ifdef SCCS
	Xstatic char *sccsid = "@(#)dpymove.c	1.3	1/17/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X#endif
	X
	X#include "dpy.h"
	X
	X/* Set the current write location to the given row and column.
	X * The position given is relative to the current window.
	X * Negative numbers indicate backwards from last row or column.
	X * Returns nonzero if arguments are out of bounds.
	X */
	Xdpymove(row, col)
	X	register int	row;		/* desired row number */
	X	register int	col;		/* desired column number */
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register int	winrows;	/* number of rows in window */
	X	register int	wincols;	/* number of columns in window */
	X
	X	wp = &window;
	X	winrows = ((wp->endwin - wp->begwin) / wp->delta) + 1;
	X	wincols = wp->endrow - wp->begrow;
	X	if (row < 0) row += winrows;
	X	if (col < 0) col += wincols;
	X	if (((unsigned)row >= winrows) || ((unsigned)col >= wincols)) {
	X		return(1);		/* out of window */
	X	}
	X	wp->begrow = wp->begwin + (row * wp->delta);
	X	wp->endrow = wp->begrow + wincols;
	X	wp->cp = wp->begrow + col;
	X	wp->full = 0;
	X	return(0);
	X}
SHAR_EOF
if test 1069 -ne "`wc -c < 'dpymove.c'`"
then
	echo shar: "error transmitting 'dpymove.c'" '(should have been 1069 characters)'
fi
fi
echo shar: "extracting 'dpyplace.c'" '(1297 characters)'
if test -f 'dpyplace.c'
then
	echo shar: "will not over-write existing file 'dpyplace.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'dpyplace.c'
	X#ifdef SCCS
	Xstatic char *sccsid = "@(#)dpyplace.c	1.5	1/28/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X#endif
	X
	X#include "dpy.h"
	X
	X/* Place a single character to the window at a particular location.
	X * The change will not be seen until a call to dpyupdate.
	X * The current write location is unaffected.
	X * Returns nonzero if coordinates are illegal.
	X * The coordinates are relative to the current window.
	X */
	Xdpyplace(row, col, ch)
	X	register int	row;		/* row to place character at */
	X	register int	col;		/* column to place character at */
	X	char	ch;			/* character to be placed */
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register char	*cp;		/* character pointer */
	X	register int	winrows;	/* number of rows in window */
	X	register int	wincols;	/* number of columns in window */
	X
	X	wp = &window;
	X	winrows = ((wp->endwin - wp->begwin) / wp->delta) + 1;
	X	wincols = wp->endrow - wp->begrow;
	X	if (row < 0) row += winrows;
	X	if (col < 0) col += wincols;
	X	if (((unsigned)row >= winrows) || ((unsigned)col >= wincols)) {
	X		return(1);		/* out of window */
	X	}
	X	cp = wp->begwin + (row * wp->delta) + col;
	X	if (*cp != ch) {		/* do only if char needs changing */
	X		if (cp < wp->begchange) wp->begchange = cp;
	X		*cp++ = ch;
	X		if (cp > wp->endchange) wp->endchange = cp;
	X	}
	X	return(0);
	X}
SHAR_EOF
if test 1297 -ne "`wc -c < 'dpyplace.c'`"
then
	echo shar: "error transmitting 'dpyplace.c'" '(should have been 1297 characters)'
fi
fi
echo shar: "extracting 'dpyread.c'" '(3564 characters)'
if test -f 'dpyread.c'
then
	echo shar: "will not over-write existing file 'dpyread.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'dpyread.c'
	X#ifdef SCCS
	Xstatic char *sccsid = "@(#)dpyread.c	1.13	2/16/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X#endif
	X
	X#include "dpy.h"		/* window definitions */
	X
	Xstatic int readline();		/* default read routine */
	X
	X/* Read some input while possibly showing it in the current window.
	X * If the prompt string is NULL, then editing is performed without
	X * any windowing activity (useful when reading commands from scripts).
	X * Otherwise, the prompt is shown in the window along with any input.
	X * The given routine is called for each character, with an argument
	X * which is the previous character (or -1 on the first call).
	X * The routine returns the next input character, or -1 to stop reading.
	X * A null routine defaults to one which reads until an end of line.
	X * Scrolling of the window is automatically performed when necessary.
	X * Editing of the input is handled.  If the buffer fills up, the user
	X * is warned with beeps and further input is ignored.
	X * Returns number of bytes of data read.
	X */
	Xdpyread(prompt, routine, buf, count)
	X	register char	*prompt;	/* prompt string (if any) */
	X	int	(*routine)();		/* routine to call to get character */
	X	register char	*buf;		/* address of the storage buffer */
	X	int	count;			/* maximum number of bytes allowed */
	X{
	X	register struct	window	*wp;	/* window pointer */
	X	register int	ch;		/* character which was read */
	X	register char	*bp;		/* current buffer pointer location */
	X	char	*endbp;			/* end of buffer */
	X	char	redraw;			/* need to redisplay input */
	X	char	oldscroll;		/* old scrolling flag */
	X	int	promptlen;		/* length of prompt string */
	X
	X	wp = &window;
	X	promptlen = 0;
	X	if (prompt) promptlen = strlen(prompt);
	X	if ((int)routine == 0) routine = readline;
	X	bp = buf;
	X	endbp = bp + count - 1;
	X	redraw = 1;
	X	ch = -1;
	X	oldscroll = wp->scroll;
	X	wp->scroll = 1;
	X	while (1) {
	X		if (prompt && redraw) {		/* recompute window data */
	X			redraw = 0;
	X			dpyhome();
	X			dpywrite(prompt, promptlen);
	X			dpywrite(buf, bp - buf);
	X			dpyclrwindow();
	X		}
	X		if (prompt) dpyupdate();
	X		ch = routine(ch);
	X		if (ch < 0) {				/* end of file */
	X			wp->scroll = oldscroll;
	X			return(bp - buf);
	X		}
	X		if (ch == wp->c_lnext) {		/* literal input */
	X			ch = routine(ch);
	X			if (ch < 0) {
	X				wp->scroll = oldscroll;
	X				return(bp - buf);
	X			}
	X			if (bp >= endbp) {		/* buffer is full */
	X				write(STDERR, "\07", 1);
	X				continue;
	X			}
	X			*bp = ch;
	X			if (prompt) dpywrite(bp, 1);
	X			bp++;
	X			continue;
	X		}
	X		if (ch == wp->c_eof) {			/* end of file */
	X			wp->scroll = oldscroll;
	X			return(bp - buf);
	X		}
	X		if (ch == wp->c_erase) {		/* character erase */
	X			if (bp <= buf) continue;
	X			bp--;
	X			redraw = 1;
	X			continue;
	X		}
	X		if (ch == wp->c_werase) {		/* word erase */
	X			if (bp <= buf) continue;
	X			while ((bp > buf) && ((bp[-1] == '\n')
	X				|| (bp[-1] == ' ') || (bp[-1] == '\t'))) bp--;
	X			while ((bp > buf) && (bp[-1] != '\n')
	X				&& (bp[-1] != ' ') && (bp[-1] != '\t')) bp--;
	X			redraw = 1;
	X			continue;
	X		}
	X		if (ch == wp->c_kill) {			/* line erase */
	X			if (bp <= buf) continue;
	X			if (bp[-1] == '\n') bp--;
	X			while ((bp > buf) && (bp[-1] != '\n')) bp--;
	X			redraw = 1;
	X			continue;
	X		}
	X		if (ch == wp->c_rprnt) {		/* retype line */
	X			if (prompt) dpyredraw();
	X			continue;
	X		}
	X		if (bp >= endbp) {			/* buffer is full */
	X			write(STDERR, "\07", 1);
	X			continue;
	X		}
	X		*bp = ch;				/* normal character */
	X		if (prompt) dpywrite(bp, 1);
	X		bp++;
	X	}
	X}
	X
	X
	X/* Local routine to read until end of line character is reached */
	Xstatic
	Xreadline(ch)
	X{
	X	if ((ch == '\n') || (read(STDIN, &ch, 1) < 1)) return(-1);
	X	return(ch & 0xff);
	X}
SHAR_EOF
if test 3564 -ne "`wc -c < 'dpyread.c'`"
then
	echo shar: "error transmitting 'dpyread.c'" '(should have been 3564 characters)'
fi
fi
echo shar: "extracting 'dpywindow.c'" '(1170 characters)'
if test -f 'dpywindow.c'
then
	echo shar: "will not over-write existing file 'dpywindow.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'dpywindow.c'
	X#ifdef SCCS
	Xstatic char *sccsid = "@(#)dpywindow.c	1.3	1/17/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X#endif
	X
	X#include "dpy.h"
	X
	X/* Set the row and column boundaries of the current window.
	X * Negative numbers indicate backwards from last row or column.
	X * The write location is set to the top left of the window.
	X * Returns nonzero if arguments are out of bounds.
	X */
	Xdpywindow(minrow, maxrow, mincol, maxcol)
	X	register int	minrow, maxrow;		/* range of rows */
	X	register int	mincol, maxcol;		/* range of columns */
	X{
	X	register struct	window	*wp;		/* window pointer */
	X
	X	wp = &window;
	X	if (minrow < 0) minrow += wp->nrows;
	X	if (maxrow < 0) maxrow += wp->nrows;
	X	if (mincol < 0) mincol += wp->ncols;
	X	if (maxcol < 0) maxcol += wp->ncols;
	X	if (((unsigned) minrow > maxrow)
	X		|| ((unsigned) maxrow >= wp->nrows)
	X		|| ((unsigned) mincol > maxcol)
	X		|| (maxcol >= wp->ncols)) {
	X			return(1);		/* illegal */
	X	}
	X	wp->begwin = wp->begdata + (minrow * wp->delta) + mincol;
	X	wp->endwin = wp->begwin + ((maxrow - minrow) * wp->delta);
	X	wp->begrow = wp->begwin;
	X	wp->endrow = wp->begrow + (maxcol - mincol + 1);
	X	wp->cp = wp->begrow;
	X	wp->full = 0;
	X	return(0);
	X}
SHAR_EOF
if test 1170 -ne "`wc -c < 'dpywindow.c'`"
then
	echo shar: "error transmitting 'dpywindow.c'" '(should have been 1170 characters)'
fi
fi
echo shar: "extracting 'gensubs.c'" '(1183 characters)'
if test -f 'gensubs.c'
then
	echo shar: "will not over-write existing file 'gensubs.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'gensubs.c'
	X#ifdef SCCS
	Xstatic char *sccsid = "@(#)gensubs.c	1.3	1/17/85";
	Xstatic char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
	X#endif
	X
	X/*
	X * Generic subroutines usable on any machine.  These subroutines should
	X * be replaced by assembly-level routines if possible, to make dpy run
	X * as fast as possible.
	X */
	X
	X
	X/*
	X * Compare two strings of a given length, and return the number of leading
	X * bytes which are identical, or the length if the strings are identical.
	X * Nulls are not treated specially.  Examples:
	X *	strdif("hi mom", "hi pop", 6) returns 3.
	X *	strdif("aaaa1", "aaaa2", 2) returns 2.
	X */
	Xstrdif(s1, s2, len)
	X	register char	*s1;		/* first string */
	X	register char	*s2;		/* second string */
	X{
	X	register char	*end;		/* ending character */
	X	char	*beg;			/* beginning character */
	X
	X	beg = s1;
	X	end = s1 + len;
	X	while ((s1 < end) && (*s1 == *s2)) {
	X		s1++;
	X		s2++;
	X	}
	X	return(s1 - beg);
	X}
	X
	X
	X
	X/*
	X * Clear a number of bytes to spaces, from the original character location
	X * up to but not including the ending location.
	X */
	Xclear(beg, end)
	X	register char	*beg;		/* beginning of string to clear */
	X	register char	*end;		/* end of string to clear */
	X{
	X	while (beg < end) *beg++ = ' ';
	X}
SHAR_EOF
if test 1183 -ne "`wc -c < 'gensubs.c'`"
then
	echo shar: "error transmitting 'gensubs.c'" '(should have been 1183 characters)'
fi
fi
echo shar: "extracting 'test1.c'" '(553 characters)'
if test -f 'test1.c'
then
	echo shar: "will not over-write existing file 'test1.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'test1.c'
	X/*
	X * Example program.  Randomly fill up the screen with numbers until
	X * it all turns to asterisks.
	X */
	X
	X#ifdef USG
	X#define	random	rand
	X#endif USG
	X
	Xmain()
	X{
	X	register int row, col, ch;
	X	register int rows, cols;
	X
	X	if (dpyinit((char *)0, "e")) exit(1);
	X	dpymove(-1, -1);
	X	rows = dpygetrow() + 1;
	X	cols = dpygetcol() + 1;
	X	dpyhome();
	X	while (1) {
	X		dpyupdate();
	X		row = random() % rows;
	X		col = random() % cols;
	X		ch = dpyget(row, col);
	X		if (ch == ' ') ch = '1';
	X		else if (ch == '9') ch = '*';
	X		else if (ch != '*') ch++;
	X		dpyplace(row, col, ch);
	X	}
	X}
SHAR_EOF
if test 553 -ne "`wc -c < 'test1.c'`"
then
	echo shar: "error transmitting 'test1.c'" '(should have been 553 characters)'
fi
fi
echo shar: "extracting 'test2.c'" '(1446 characters)'
if test -f 'test2.c'
then
	echo shar: "will not over-write existing file 'test2.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'test2.c'
	X/*
	X * Example program.  Split the screen into three windows, input using the
	X * top window until an escape is typed, and show it in the bottom window.
	X * The middle window is just a border.  Continue until a ^E is typed.
	X */
	X
	X#include <signal.h>
	X
	X#define	BOARDER	10		/* row for boarder window */
	X#define	BUFSIZE	1000		/* maximum chars which can be input */
	X#define	ESC	'\033'		/* escape character */
	X#define	QUIT	'\005'		/* quit character (^E) */
	X
	Xint	grabchar();		/* routine to read tty chars */
	Xint	quit();			/* interrupt routine */
	X
	Xmain()
	X{
	X	register int	i;		/* character count */
	X	char	buf[BUFSIZE];		/* input buffer */
	X
	X	signal(SIGINT, quit);
	X	if (dpyinit((char *)0, "-ec"))
	X		exit(1);
	X	dpywindow(BOARDER, BOARDER, 0, -1);
	X	while (dpywrite("-----", 5) == 0) ;
	X	while (1) {
	X		dpywindow(0, BOARDER - 1, 0, -1);
	X		i = dpyread("Input: ", grabchar, buf, sizeof(buf));
	X		if ((i > 0) && (buf[i-1] == QUIT)) break;
	X		dpywindow(BOARDER + 1, -1, 0, -1);
	X		dpyprintf("Read %d chars:\n", i);
	X		dpywrite(buf, i);
	X		dpyclrwindow();
	X		dpyupdate();
	X	}
	X	dpyclose();
	X}
	X
	X
	X/*
	X * Read next char from tty, quitting on an end of file or escape character.
	X * The escape character is removed from the buffer, but the end of file
	X * character is kept.
	X */
	Xgrabchar(oldch)
	X{
	X	unsigned char	newch;
	X
	X	if ((oldch == QUIT) || (read(0, &newch, 1) != 1) || (newch == ESC))
	X		return(-1);
	X	return(newch);
	X}
	X
	X
	X/*
	X * Here on an interrupt.
	X */
	Xquit()
	X{
	X	dpyclose();
	X	exit(0);
	X}
SHAR_EOF
if test 1446 -ne "`wc -c < 'test2.c'`"
then
	echo shar: "error transmitting 'test2.c'" '(should have been 1446 characters)'
fi
fi
echo shar: "extracting 'makefile'" '(1270 characters)'
if test -f 'makefile'
then
	echo shar: "will not over-write existing file 'makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'makefile'
	X# @(#)makefile.bsd	1.6	2/27/85
	X# Makefile for BSD systems
	X
	X.SUFFIXES: .c .o .s
	X
	XCFLAGS = -O -DBSD
	XCC = cc
	XAS = as
	XRANLIB = ranlib
	XLIBDIR = /usr/lib
	X
	XCFILES = dpy.c dpymove.c dpyplace.c dpyget.c dpyread.c dpywindow.c
	XOFILES = dpy.o dpymove.o dpyplace.o dpyget.o dpyread.o dpywindow.o
	XSOURCES = ${CFILES} dpy.h vaxsubs.s ns32ksubs.s gensubs.c
	X
	X# Machine dependent assembly routines.  Define MACHINEFILES appropriately
	X# to select the target machine.  Gensubs is a portable version of the
	X# subroutines applicable to any machine (but slower than the assembly ones).
	X
	XGENFILES = gensubs.o		# generic subroutines
	XNS32KFILES= ns32ksubs.o		# National Semiconductor 32032 subroutines
	XVAXFILES = vaxsubs.o		# VAX subroutines
	XMACHINEFILES = ${VAXFILES}	# subroutines to be used
	X
	X
	Xlibdpy.a: ${OFILES} ${MACHINEFILES}
	X	ar rc libdpy.a ${OFILES} ${MACHINEFILES}
	X	${RANLIB} libdpy.a
	X
	Xsources: ${SOURCES}
	X
	X${SOURCES}:
	X	sccs get $@
	X
	X${OFILES}: dpy.h
	X
	Xinstall: libdpy.a
	X	cp libdpy.a ${LIBDIR}
	X	${RANLIB} ${LIBDIR}/libdpy.a
	X	chmod 644 ${LIBDIR}/libdpy.a
	X
	Xtest1:	test1.o libdpy.a
	X	${CC} -o test1 test1.o libdpy.a -ltermlib
	X
	Xtest2:	test2.o libdpy.a
	X	${CC} -o test2 test2.o libdpy.a -ltermlib
	X
	Xclean:
	X	rm -f *.o libdpy.a test1 test2
	X
	X.s.o:
	X	${AS} -o $*.o $*.s
	X
	X.c.o:
	X	${CC} -c ${CFLAGS} $*.c
SHAR_EOF
if test 1270 -ne "`wc -c < 'makefile'`"
then
	echo shar: "error transmitting 'makefile'" '(should have been 1270 characters)'
fi
fi
echo shar: "extracting 'makefile.bsd'" '(1270 characters)'
if test -f 'makefile.bsd'
then
	echo shar: "will not over-write existing file 'makefile.bsd'"
else
sed 's/^	X//' << \SHAR_EOF > 'makefile.bsd'
	X# @(#)makefile.bsd	1.6	2/27/85
	X# Makefile for BSD systems
	X
	X.SUFFIXES: .c .o .s
	X
	XCFLAGS = -O -DBSD
	XCC = cc
	XAS = as
	XRANLIB = ranlib
	XLIBDIR = /usr/lib
	X
	XCFILES = dpy.c dpymove.c dpyplace.c dpyget.c dpyread.c dpywindow.c
	XOFILES = dpy.o dpymove.o dpyplace.o dpyget.o dpyread.o dpywindow.o
	XSOURCES = ${CFILES} dpy.h vaxsubs.s ns32ksubs.s gensubs.c
	X
	X# Machine dependent assembly routines.  Define MACHINEFILES appropriately
	X# to select the target machine.  Gensubs is a portable version of the
	X# subroutines applicable to any machine (but slower than the assembly ones).
	X
	XGENFILES = gensubs.o		# generic subroutines
	XNS32KFILES= ns32ksubs.o		# National Semiconductor 32032 subroutines
	XVAXFILES = vaxsubs.o		# VAX subroutines
	XMACHINEFILES = ${VAXFILES}	# subroutines to be used
	X
	X
	Xlibdpy.a: ${OFILES} ${MACHINEFILES}
	X	ar rc libdpy.a ${OFILES} ${MACHINEFILES}
	X	${RANLIB} libdpy.a
	X
	Xsources: ${SOURCES}
	X
	X${SOURCES}:
	X	sccs get $@
	X
	X${OFILES}: dpy.h
	X
	Xinstall: libdpy.a
	X	cp libdpy.a ${LIBDIR}
	X	${RANLIB} ${LIBDIR}/libdpy.a
	X	chmod 644 ${LIBDIR}/libdpy.a
	X
	Xtest1:	test1.o libdpy.a
	X	${CC} -o test1 test1.o libdpy.a -ltermlib
	X
	Xtest2:	test2.o libdpy.a
	X	${CC} -o test2 test2.o libdpy.a -ltermlib
	X
	Xclean:
	X	rm -f *.o libdpy.a test1 test2
	X
	X.s.o:
	X	${AS} -o $*.o $*.s
	X
	X.c.o:
	X	${CC} -c ${CFLAGS} $*.c
SHAR_EOF
if test 1270 -ne "`wc -c < 'makefile.bsd'`"
then
	echo shar: "error transmitting 'makefile.bsd'" '(should have been 1270 characters)'
fi
fi
echo shar: "extracting 'makefile.usg'" '(1816 characters)'
if test -f 'makefile.usg'
then
	echo shar: "will not over-write existing file 'makefile.usg'"
else
sed 's/^	X//' << \SHAR_EOF > 'makefile.usg'
	X# @(#)makefile.usg	1.5	2/27/85
	X# Makefile for USG systems
	X
	X.SUFFIXES: .c .o .s
	X
	XCC = cc
	XOFLAG = -O
	XDFLAG =
	XSYSTEM = -DUSG
	XCFLAGS = $(OFLAG) $(DFLAG) $(SYSTEM)
	XAS = as
	XLIBDIR = /usr/lib
	XLIB = libdpy.a
	X
	XCFILES = dpy.c dpymove.c dpyplace.c dpyget.c dpyread.c dpywindow.c
	XOFILES = dpy.o dpymove.o dpyplace.o dpyget.o dpyread.o dpywindow.o
	X
	XLIBOBJS =	$(LIB)(dpy.o) \
	X		$(LIB)(dpymove.o) \
	X		$(LIB)(dpyplace.o) \
	X		$(LIB)(dpyget.o) \
	X		$(LIB)(dpyread.o) \
	X		$(LIB)(dpywindow.o)
	X
	XSOURCES = dpy.h ${CFILES} vaxsubs.s ns32ksubs.s gensubs.c
	X
	X# Machine dependent assembly routines.  Define MACHINEFILES appropriately
	X# to select the target machine.  Gensubs is a portable version of the
	X# subroutines applicable to any machine (but slower than the assembly ones).
	X
	XGENFILES = gensubs.o		# generic subroutines
	XNS32KFILES = ns32ksubs.o	# National Semiconductor 32032 subroutines
	XVAXFILES = vaxsubs.o		# VAX subroutines
	XMACHINEFILES = ${VAXFILES}	# subroutines to be used
	X
	X
	Xlibdpy.a: ${LIBOBJS} $(MACHINEFILES)
	X	$(MAKE) -$(MAKEFLAGS) -f dpy.mk.usg $? OFLAG=$(OFLAG) \
	X		DFLAG=$(DFLAG) SYSTEM=$(SYSTEM)
	X	ar rv libdpy.a $?
	X	/bin/rm $?
	X
	X$(LIB)(vaxsubs.o) vaxsubs.o : vaxsubs.s
	X
	X$(LIB)(gensubs.o) gensubs.o : gensubs.s
	X
	X$(LIB)(ns32ksubs.o) ns32ksubs.o : ns32ksubs.s
	X
	Xsources: ${SOURCES}
	X
	X$(LIBOBJS) ${OFILES}: dpy.h
	X
	Xinstall: libdpy.a
	X	cp libdpy.a ${LIBDIR}
	X	chmod 644 ${LIBDIR}/libdpy.a
	X
	Xtest1:	test1.o libdpy.a
	X	$(CC) test1.o $(LDFLAGS) -o test1 libdpy.a -lcurses
	X
	Xtest2:	test2.o libdpy.a
	X	$(CC) test2.o $(LDFLAGS) -o test2 libdpy.a -lcurses
	X
	Xprint:	${SOURCES} makefile
	X	pr -w120 -n ${SOURCES} makefile >dpy.lst
	X	@echo dpy.lst finished
	X
	Xclean:
	X	rm -f *.o libdpy.a test1 test2
	X
	XPRECIOUS:	libdpy.a
	X
	X.c.a:
	X	@echo $*.c
	X
	X.s.a:
	X	@echo $*.s
	X
	X.s.o:
	X	${AS} -o $*.o $*.s
	X
	X.c.o:
	X	${CC} -c ${CFLAGS} $*.c
	X
	X.s~.s:
	X	$(GET) $(GFLAGS) -p $< > $*.s
SHAR_EOF
if test 1816 -ne "`wc -c < 'makefile.usg'`"
then
	echo shar: "error transmitting 'makefile.usg'" '(should have been 1816 characters)'
fi
fi
echo shar: "extracting 'ns32ksubs.s'" '(812 characters)'
if test -f 'ns32ksubs.s'
then
	echo shar: "will not over-write existing file 'ns32ksubs.s'"
else
sed 's/^	X//' << \SHAR_EOF > 'ns32ksubs.s'
	X; @(#)m16subs.s	1.4	1/28/85
	X; @(#)Copyright (C) 1985 by D Bell
	X;
	X;machine dependent subroutines for the National 32032 microprocessor.
	X;strdif - return number of bytes until two strings differ or count is reached.
	X;clear	- from first address up till last address, make memory spaces.
	X
	X	.program
	X
	X_strdif::
	X	movd	16(sp),r0	;byte count
	X	movd	8(sp),r1	;first string
	X	movd	12(sp),r2	;second string
	X	cmpsb			;compare bytes
	X	subd	8(sp),r1	;get length of search
	X	movd	r1,r0		;make return value
	X	rxp	0		;return
	X
	X
	X_clear::
	X	movd	12(sp),r0	;ending address
	X	movd	8(sp),r1	;beginning address
	X	subd	r1,r0		;compute byte count
	X	cmpqd	0,r0		;see if any to do
	X	bge	done		;nope
	X	addqd	-1,r0		;fix count
	X	addr	1(r1),r2	;destination address
	X	movb	32,0(r1)	;start with a blank
	X	movsb			;fill rest too
	Xdone:	rxp	0		;return
	X
	X	.endseg
SHAR_EOF
if test 812 -ne "`wc -c < 'ns32ksubs.s'`"
then
	echo shar: "error transmitting 'ns32ksubs.s'" '(should have been 812 characters)'
fi
fi
echo shar: "extracting 'vaxsubs.s'" '(332 characters)'
if test -f 'vaxsubs.s'
then
	echo shar: "will not over-write existing file 'vaxsubs.s'"
else
sed 's/^	X//' << \SHAR_EOF > 'vaxsubs.s'
	X# @(#)vaxsubs.s	1.5	1/17/85
	X# @(#)Copyright (C) 1985 by D Bell
	X
	X
	X	.text
	X	.globl	_strdif
	X	.globl	_clear
	X
	X_strdif:
	X	.word	0x0
	X	cmpc3	12(ap),*4(ap),*8(ap)	#compare the strings
	X	subl3	4(ap),r1,r0		#return difference
	X	ret
	X
	X_clear:
	X	.word	0x0
	X	subl3	4(ap),8(ap),r0		#number of bytes to fill
	X	movc5	$0,0,$32,r0,*4(ap)	#fill the bytes
	X	ret
SHAR_EOF
if test 332 -ne "`wc -c < 'vaxsubs.s'`"
then
	echo shar: "error transmitting 'vaxsubs.s'" '(should have been 332 characters)'
fi
fi
exit 0
#	End of shell archive
-- 

Erik Bailey        -- 7 Oak Knoll                 (USENET courtesy of
ihnp4!think!ejb       Arlington, MA  02174        Thinking Machines Corp.
ejb@think.com         (617) 643-0732              Cambridge, MA)

	   It takes thought to make a program that thinks.
	   But it takes work to make a program that works.