xref: /csrg-svn/local/local.cmd/dis.c (revision 16671)
116475Ssam #ifndef lint
2*16671Ssam static char sccsid[] = "@(#)dis.c	1.2 (Berkeley) 07/05/84";
316475Ssam #endif
416475Ssam 
516475Ssam /*
616475Ssam **	Dis -- VDU page display program
716475Ssam **
816475Ssam **	"dis [-t<timeout>] [-c<refresh count>] [-u]"
916475Ssam **
1016475Ssam **	Bugs and comments to:	Piers Lauder
1116475Ssam **				Dept of Comp Sci
1216475Ssam **				Sydney University
1316475Ssam **	May '80.
1416475Ssam */
1516475Ssam 
1616475Ssam #include	<signal.h>
1716475Ssam #include	<setjmp.h>
1816475Ssam #include	<sgtty.h>
1916475Ssam #include	<stdio.h>
2016475Ssam 
2116475Ssam /*
2216475Ssam **	Parameters
2316475Ssam */
2416475Ssam 
2516475Ssam #define		MAXWID		132
2616475Ssam #define		MAXLEN		80
2716475Ssam 
2816475Ssam 
2916475Ssam /*
3016475Ssam **	Screen buffer
3116475Ssam */
3216475Ssam 
3316475Ssam char *		Buf;
3416475Ssam 
3516475Ssam /*
3616475Ssam **	Term Cap
3716475Ssam */
3816475Ssam 
3916475Ssam char		*CM, *CL;
4016475Ssam short		amflag;
4116475Ssam 
4216475Ssam extern short	ospeed;
4316475Ssam extern char	PC, *BC, *UP;
4416475Ssam 
4516475Ssam extern char *	tgoto();
4616475Ssam extern char *	tgetstr();
4716475Ssam 
4816475Ssam /*
4916475Ssam **	Screen macro
5016475Ssam */
5116475Ssam 
5216475Ssam #define		putcm(cp,p,c)		if(*cp++!=c){\
5316475Ssam 						if(move((--cp)-p))\
5416475Ssam 							putc(c,stdout);\
5516475Ssam 						*cp++=c;\
5616475Ssam 					}
5716475Ssam 
5816475Ssam /*
5916475Ssam **	Miscellaneous
6016475Ssam */
6116475Ssam 
6216475Ssam jmp_buf		alrmbuf;
6316475Ssam short		width;
6416475Ssam short		Width;		/* width - 1 */
6516475Ssam short		length;
6616475Ssam short		Length;		/* length - 1 */
6716475Ssam char *		name;
6816475Ssam unsigned	timeout;
6916475Ssam short		rcount;
7016475Ssam 
7116475Ssam void
7216475Ssam 		tcinit(),
7316475Ssam 		dis(),
7416475Ssam 		warn(),
7516475Ssam 		terror(),
7616475Ssam 		outc();
7716475Ssam 
7816475Ssam int		alrmcatch();
7916475Ssam 
8016475Ssam /*
8116475Ssam **	Externals
8216475Ssam */
8316475Ssam 
8416475Ssam extern char	_sobuf[];
8516475Ssam extern char *	tgetstr();
8616475Ssam extern char *	malloc();
8716475Ssam extern char *	getenv();
8816475Ssam 
8916475Ssam 
9016475Ssam 
main(argc,argv)9116475Ssam main(argc, argv)
9216475Ssam 	register int		argc;
9316475Ssam 	register char *		argv[];
9416475Ssam {
9516475Ssam 	register char *		cp;
9616475Ssam 	register unsigned	size;
9716475Ssam 
9816475Ssam 	name = *argv++;
9916475Ssam 	argc--;
10016475Ssam 
10116475Ssam 	while ( argc )
10216475Ssam 	{
10316475Ssam 		switch( argv[0][0] )
10416475Ssam 		{
10516475Ssam 		 case '-':	argv[0]++;
10616475Ssam 				continue;
10716475Ssam 		 case 't':	timeout = atoi(&argv[0][1]);
10816475Ssam 				break;
10916475Ssam 		 case 'c':	rcount = atoi(&argv[0][1]);
11016475Ssam 				break;
11116475Ssam 		 case 'u':	setbuf(stdin, NULL);
11216475Ssam 				break;
11316475Ssam 		 default:	fprintf(stderr, "%s: bad arg - %s\n", name, argv[0] );
11416475Ssam 				return 1;
11516475Ssam 		}
11616475Ssam 		argc--;
11716475Ssam 		argv++;
11816475Ssam 	}
11916475Ssam 
12016475Ssam 	setbuf(stdout, _sobuf);
12116475Ssam 	tcinit();
12216475Ssam 	size = length * width;
12316475Ssam 	if ( (Buf = malloc(size)) == (char *)0 )
12416475Ssam 	{
12516475Ssam 		fprintf(stderr, "No memory\n");
12616475Ssam 		exit(2);
12716475Ssam 	}
12816475Ssam 	bzero(Buf, size);
12916475Ssam 
13016475Ssam 	Length = length - 1;
13116475Ssam 	Width = width - 1;
13216475Ssam 	dis(size);
13316475Ssam 
13416475Ssam 	return 0;
13516475Ssam }
13616475Ssam 
13716475Ssam 
13816475Ssam 
13916475Ssam 
14016475Ssam void
dis(size)14116475Ssam dis(size)
14216475Ssam 	unsigned		size;
14316475Ssam {
14416475Ssam 	register char *		ep;
14516475Ssam 	register char *		p = Buf;
14616475Ssam 	register int		c;
14716475Ssam 	register int		line;
14816475Ssam 	/** on stack to avoid setjmp **/
14916475Ssam 	char *			cp;
15016475Ssam 	char *			lastend;
15116475Ssam 	int			rc;
15216475Ssam 
15316475Ssam 	lastend = p;
15416475Ssam 	rc = rcount;
15516475Ssam 
15616475Ssam 	do
15716475Ssam 	{
15816475Ssam 		line = 0;
15916475Ssam 		cp = p;
16016475Ssam 		ep = cp+width;
16116475Ssam 
16216475Ssam 		if ( timeout == 0 || setjmp(alrmbuf) == 0 )
16316475Ssam 		{
16416475Ssam 			if ( timeout )
16516475Ssam 			{
16616475Ssam 				signal(SIGALRM, alrmcatch);
16716475Ssam 				alarm(timeout);
16816475Ssam 			}
16916475Ssam 			while ( (c = getchar()) != EOF )
17016475Ssam 			{
17116475Ssam 				if ( rcount && !rc )
17216475Ssam 				{
17316475Ssam 					tputs(CL, 1, outc);
17416475Ssam 					bzero(p, size);
17516475Ssam 					rc = rcount;
17616475Ssam 				}
17716475Ssam 				if ( c < ' ' )
17816475Ssam 				{
17916475Ssam 					switch ( c )
18016475Ssam 					{
18116475Ssam 					 case '\f':	if ( cp != p )
18216475Ssam 								break;
18316475Ssam 							continue;
18416475Ssam 					 case '\t':	c = cp - &p[line*width] + 1;
18516475Ssam 							putcm(cp, p, ' ');
18616475Ssam 							while ( c++&7 )
18716475Ssam 								putcm(cp, p, ' ');
18816475Ssam 							continue;
18916475Ssam 					 case '\n':	while ( cp < ep )
19016475Ssam 								putcm(cp, p, ' ');
19116475Ssam 							if ( line < Length )
19216475Ssam 							{
19316475Ssam 								cp = &p[(++line)*width];
19416475Ssam 								ep = cp+width;
19516475Ssam 							}
19616475Ssam 							continue;
19716475Ssam 					 default:
19816475Ssam 							if ( cp < ep )
19916475Ssam 								putcm(cp, p, '?');
20016475Ssam 							continue;
20116475Ssam 					}
20216475Ssam 				}
20316475Ssam 				else
20416475Ssam 				{
20516475Ssam 					if ( cp < ep )
20616475Ssam 						putcm(cp, p, c);
20716475Ssam 					continue;
20816475Ssam 				}
20916475Ssam 				break;
21016475Ssam 			}
21116475Ssam 			if ( timeout )
21216475Ssam 				alarm(0);
21316475Ssam 		}
21416475Ssam 		ep = cp - 1;
21516475Ssam 		while ( cp < lastend )
21616475Ssam 			putcm(cp, p, ' ');
21716475Ssam 		lastend = ep;
21816475Ssam 		if ( (line = (ep-p)/width) < Length )
21916475Ssam 			line++;
22016475Ssam 		(void)move(line*width);
22116475Ssam 		fflush(stdout);
22216475Ssam 		if ( rcount )
22316475Ssam 			--rc;
22416475Ssam 	}
22516475Ssam 	while
22616475Ssam 		( c != EOF );
22716475Ssam }
22816475Ssam 
22916475Ssam 
23016475Ssam 
23116475Ssam 
23216475Ssam int
move(pos)23316475Ssam move(pos)
23416475Ssam 	register int	pos;
23516475Ssam {
23616475Ssam 	register int	x = pos%width;
23716475Ssam 	register int	y = pos/width;
23816475Ssam 	register int	i;
23916475Ssam 	static int	oy, ox = -1;
24016475Ssam 
24116475Ssam 	if ( oy == y )
24216475Ssam 	{
24316475Ssam 		if ( (i = x - ox) != 1 )
24416475Ssam 			if ( i <= 3 && i > 0 )
24516475Ssam 			{
24616475Ssam 				i--;
24716475Ssam 				pos -= i;
24816475Ssam 				do
24916475Ssam 					putc(Buf[pos++], stdout);
25016475Ssam 				while
25116475Ssam 					( --i > 0 );
25216475Ssam 			}
25316475Ssam 			else
25416475Ssam 				tputs(tgoto(CM, x, y), 1, outc);
25516475Ssam 	}
25616475Ssam 	else
25716475Ssam 		if ( oy == (y-1) && x == 0 )
25816475Ssam 		{
25916475Ssam 			if ( ox != Width || !amflag )
26016475Ssam 				putc('\n', stdout);
26116475Ssam 		}
26216475Ssam 		else
26316475Ssam 			tputs(tgoto(CM, x, y), oy<y?y-oy:oy-y, outc);
26416475Ssam 
26516475Ssam 	ox = x; oy = y;
26616475Ssam 	if ( y==Length && x==Width && amflag )
26716475Ssam 		return 0;
26816475Ssam 	return 1;
26916475Ssam }
27016475Ssam 
27116475Ssam 
27216475Ssam 
27316475Ssam 
27416475Ssam int
alrmcatch()27516475Ssam alrmcatch()
27616475Ssam {
27716475Ssam 	longjmp(alrmbuf, 1);
27816475Ssam }
27916475Ssam 
28016475Ssam 
28116475Ssam 
28216475Ssam 
28316475Ssam void
tcinit()28416475Ssam tcinit()
28516475Ssam {
28616475Ssam 	register char *	cp;
28716475Ssam 	struct sgttyb	gb;
28816475Ssam 	char		bp[1024];
28916475Ssam 	static char	buf[100];
29016475Ssam 	char		*area = buf;
29116475Ssam 
29216475Ssam 	if ( tgetent(bp, getenv("TERM")) != 1 )
29316475Ssam 		terror("no \"termcap\" entry");
29416475Ssam 	if ( (CL = tgetstr("cl", &area)) == (char *)0 )
29516475Ssam 		terror("not VDU");
29616475Ssam 	if ( (CM = tgetstr("cm", &area)) == (char *)0 )
29716475Ssam 		terror("no cursor addressing");
29816475Ssam 	UP = tgetstr("up", &area);
29916475Ssam 	BC = tgetstr("bc", &area);
30016475Ssam 	if ( tgetflag("am") == 1 )
30116475Ssam 		amflag++;
30216475Ssam 	if ( (cp = getenv("WIDTH")) != (char *)0 )
30316475Ssam 		width = atoi(cp);
30416475Ssam 	else
30516475Ssam 		width = tgetnum("co");
30616475Ssam 	if ( width > MAXWID )
30716475Ssam 	{
30816475Ssam 		width = MAXWID;
30916475Ssam 		warn("width truncated");
31016475Ssam 	}
31116475Ssam 	if ( (length = tgetnum("li")) > MAXLEN )
31216475Ssam 	{
31316475Ssam 		length = MAXLEN;
31416475Ssam 		warn("length truncated");
31516475Ssam 	}
31616475Ssam 	if ( (cp = tgetstr("pc", &area)) != (char *)0 )
31716475Ssam 		PC = *cp;
31816475Ssam 	gtty(1, &gb);
31916475Ssam 	ospeed = gb.sg_ospeed;
32016475Ssam 
32116475Ssam 	tputs(CL, 1, outc);
32216475Ssam 	fflush(stdout);
32316475Ssam }
32416475Ssam 
32516475Ssam 
32616475Ssam 
32716475Ssam 
32816475Ssam void
outc(c)32916475Ssam outc(c)
33016475Ssam {
33116475Ssam 	putc(c, stdout);
33216475Ssam }
33316475Ssam 
33416475Ssam 
33516475Ssam 
33616475Ssam 
33716475Ssam void
warn(s)33816475Ssam warn(s)
33916475Ssam 	char *	s;
34016475Ssam {
34116475Ssam 	fprintf(stderr, "Warning: %s\n", s);
34216475Ssam 	sleep(2);
34316475Ssam }
34416475Ssam 
34516475Ssam 
34616475Ssam 
34716475Ssam 
34816475Ssam void
terror(s)34916475Ssam terror(s)
35016475Ssam 	char *	s;
35116475Ssam {
35216475Ssam 	fprintf(stderr, "Terminal capability error - %s\n", s);
35316475Ssam 	exit(1);
35416475Ssam }
355