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