REPORTING for DBell - DPY (Part 2 of 3)

Landon Noll chongo at nsc.UUCP
Fri Apr 12 20:00:56 AEST 1985


In net.sources:
  I am reposting DBell's DPY sources in response to all the folks who
  needed them for his LIFE and WAR progs.  DBell is no longer on the
  net (in fact in a few days he will no longer be in this hemisphere)
  otherwise he would have done this himself.

In net.sources.games:
  I am reposting DBell's LIFE sources complete with the changes for the
  new DPY.  Both LIFE and WAR (which was posted by DBell not long ago)
  require the use of DPY so be sure and GRAB IT FROM net.sources NOW!!!

#---Cut here and place in it's own directory, then feed to Bourne shell---
# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
# This archive contains:
#   dpy.c (22206 chars)
#   dpyget.c (1117 chars)
#   dpymove.c (1069 chars)
#   dpyplace.c (1297 chars)
#   dpyread.c (3564 chars)
#   dpywindow.c (1170 chars)
#   gensubs.c (1183 chars)
#   vaxsubs.s (332 chars)
#   ns32ksubs.s (812 chars)
#
echo x - dpy.c
sed -e 's/^X//' > "dpy.c" << '//E*O*F 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}
//E*O*F dpy.c//
echo x - dpyget.c
sed -e 's/^X//' > "dpyget.c" << '//E*O*F 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}
//E*O*F dpyget.c//
echo x - dpymove.c
sed -e 's/^X//' > "dpymove.c" << '//E*O*F 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}
//E*O*F dpymove.c//
echo x - dpyplace.c
sed -e 's/^X//' > "dpyplace.c" << '//E*O*F 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}
//E*O*F dpyplace.c//
echo x - dpyread.c
sed -e 's/^X//' > "dpyread.c" << '//E*O*F 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}
//E*O*F dpyread.c//
echo x - dpywindow.c
sed -e 's/^X//' > "dpywindow.c" << '//E*O*F 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}
//E*O*F dpywindow.c//
echo x - gensubs.c
sed -e 's/^X//' > "gensubs.c" << '//E*O*F 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}
//E*O*F gensubs.c//
echo x - vaxsubs.s
sed -e 's/^X//' > "vaxsubs.s" << '//E*O*F 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
//E*O*F vaxsubs.s//
echo x - ns32ksubs.s
sed -e 's/^X//' > "ns32ksubs.s" << '//E*O*F 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
//E*O*F ns32ksubs.s//
echo done
-- 
no comment is a comment.



More information about the Comp.sources.unix mailing list