1 #ifndef lint
2 static char sccsid[] = "@(#)dis.c 1.2 (Berkeley) 07/05/84";
3 #endif
4
5 /*
6 ** Dis -- VDU page display program
7 **
8 ** "dis [-t<timeout>] [-c<refresh count>] [-u]"
9 **
10 ** Bugs and comments to: Piers Lauder
11 ** Dept of Comp Sci
12 ** Sydney University
13 ** May '80.
14 */
15
16 #include <signal.h>
17 #include <setjmp.h>
18 #include <sgtty.h>
19 #include <stdio.h>
20
21 /*
22 ** Parameters
23 */
24
25 #define MAXWID 132
26 #define MAXLEN 80
27
28
29 /*
30 ** Screen buffer
31 */
32
33 char * Buf;
34
35 /*
36 ** Term Cap
37 */
38
39 char *CM, *CL;
40 short amflag;
41
42 extern short ospeed;
43 extern char PC, *BC, *UP;
44
45 extern char * tgoto();
46 extern char * tgetstr();
47
48 /*
49 ** Screen macro
50 */
51
52 #define putcm(cp,p,c) if(*cp++!=c){\
53 if(move((--cp)-p))\
54 putc(c,stdout);\
55 *cp++=c;\
56 }
57
58 /*
59 ** Miscellaneous
60 */
61
62 jmp_buf alrmbuf;
63 short width;
64 short Width; /* width - 1 */
65 short length;
66 short Length; /* length - 1 */
67 char * name;
68 unsigned timeout;
69 short rcount;
70
71 void
72 tcinit(),
73 dis(),
74 warn(),
75 terror(),
76 outc();
77
78 int alrmcatch();
79
80 /*
81 ** Externals
82 */
83
84 extern char _sobuf[];
85 extern char * tgetstr();
86 extern char * malloc();
87 extern char * getenv();
88
89
90
main(argc,argv)91 main(argc, argv)
92 register int argc;
93 register char * argv[];
94 {
95 register char * cp;
96 register unsigned size;
97
98 name = *argv++;
99 argc--;
100
101 while ( argc )
102 {
103 switch( argv[0][0] )
104 {
105 case '-': argv[0]++;
106 continue;
107 case 't': timeout = atoi(&argv[0][1]);
108 break;
109 case 'c': rcount = atoi(&argv[0][1]);
110 break;
111 case 'u': setbuf(stdin, NULL);
112 break;
113 default: fprintf(stderr, "%s: bad arg - %s\n", name, argv[0] );
114 return 1;
115 }
116 argc--;
117 argv++;
118 }
119
120 setbuf(stdout, _sobuf);
121 tcinit();
122 size = length * width;
123 if ( (Buf = malloc(size)) == (char *)0 )
124 {
125 fprintf(stderr, "No memory\n");
126 exit(2);
127 }
128 bzero(Buf, size);
129
130 Length = length - 1;
131 Width = width - 1;
132 dis(size);
133
134 return 0;
135 }
136
137
138
139
140 void
dis(size)141 dis(size)
142 unsigned size;
143 {
144 register char * ep;
145 register char * p = Buf;
146 register int c;
147 register int line;
148 /** on stack to avoid setjmp **/
149 char * cp;
150 char * lastend;
151 int rc;
152
153 lastend = p;
154 rc = rcount;
155
156 do
157 {
158 line = 0;
159 cp = p;
160 ep = cp+width;
161
162 if ( timeout == 0 || setjmp(alrmbuf) == 0 )
163 {
164 if ( timeout )
165 {
166 signal(SIGALRM, alrmcatch);
167 alarm(timeout);
168 }
169 while ( (c = getchar()) != EOF )
170 {
171 if ( rcount && !rc )
172 {
173 tputs(CL, 1, outc);
174 bzero(p, size);
175 rc = rcount;
176 }
177 if ( c < ' ' )
178 {
179 switch ( c )
180 {
181 case '\f': if ( cp != p )
182 break;
183 continue;
184 case '\t': c = cp - &p[line*width] + 1;
185 putcm(cp, p, ' ');
186 while ( c++&7 )
187 putcm(cp, p, ' ');
188 continue;
189 case '\n': while ( cp < ep )
190 putcm(cp, p, ' ');
191 if ( line < Length )
192 {
193 cp = &p[(++line)*width];
194 ep = cp+width;
195 }
196 continue;
197 default:
198 if ( cp < ep )
199 putcm(cp, p, '?');
200 continue;
201 }
202 }
203 else
204 {
205 if ( cp < ep )
206 putcm(cp, p, c);
207 continue;
208 }
209 break;
210 }
211 if ( timeout )
212 alarm(0);
213 }
214 ep = cp - 1;
215 while ( cp < lastend )
216 putcm(cp, p, ' ');
217 lastend = ep;
218 if ( (line = (ep-p)/width) < Length )
219 line++;
220 (void)move(line*width);
221 fflush(stdout);
222 if ( rcount )
223 --rc;
224 }
225 while
226 ( c != EOF );
227 }
228
229
230
231
232 int
move(pos)233 move(pos)
234 register int pos;
235 {
236 register int x = pos%width;
237 register int y = pos/width;
238 register int i;
239 static int oy, ox = -1;
240
241 if ( oy == y )
242 {
243 if ( (i = x - ox) != 1 )
244 if ( i <= 3 && i > 0 )
245 {
246 i--;
247 pos -= i;
248 do
249 putc(Buf[pos++], stdout);
250 while
251 ( --i > 0 );
252 }
253 else
254 tputs(tgoto(CM, x, y), 1, outc);
255 }
256 else
257 if ( oy == (y-1) && x == 0 )
258 {
259 if ( ox != Width || !amflag )
260 putc('\n', stdout);
261 }
262 else
263 tputs(tgoto(CM, x, y), oy<y?y-oy:oy-y, outc);
264
265 ox = x; oy = y;
266 if ( y==Length && x==Width && amflag )
267 return 0;
268 return 1;
269 }
270
271
272
273
274 int
alrmcatch()275 alrmcatch()
276 {
277 longjmp(alrmbuf, 1);
278 }
279
280
281
282
283 void
tcinit()284 tcinit()
285 {
286 register char * cp;
287 struct sgttyb gb;
288 char bp[1024];
289 static char buf[100];
290 char *area = buf;
291
292 if ( tgetent(bp, getenv("TERM")) != 1 )
293 terror("no \"termcap\" entry");
294 if ( (CL = tgetstr("cl", &area)) == (char *)0 )
295 terror("not VDU");
296 if ( (CM = tgetstr("cm", &area)) == (char *)0 )
297 terror("no cursor addressing");
298 UP = tgetstr("up", &area);
299 BC = tgetstr("bc", &area);
300 if ( tgetflag("am") == 1 )
301 amflag++;
302 if ( (cp = getenv("WIDTH")) != (char *)0 )
303 width = atoi(cp);
304 else
305 width = tgetnum("co");
306 if ( width > MAXWID )
307 {
308 width = MAXWID;
309 warn("width truncated");
310 }
311 if ( (length = tgetnum("li")) > MAXLEN )
312 {
313 length = MAXLEN;
314 warn("length truncated");
315 }
316 if ( (cp = tgetstr("pc", &area)) != (char *)0 )
317 PC = *cp;
318 gtty(1, &gb);
319 ospeed = gb.sg_ospeed;
320
321 tputs(CL, 1, outc);
322 fflush(stdout);
323 }
324
325
326
327
328 void
outc(c)329 outc(c)
330 {
331 putc(c, stdout);
332 }
333
334
335
336
337 void
warn(s)338 warn(s)
339 char * s;
340 {
341 fprintf(stderr, "Warning: %s\n", s);
342 sleep(2);
343 }
344
345
346
347
348 void
terror(s)349 terror(s)
350 char * s;
351 {
352 fprintf(stderr, "Terminal capability error - %s\n", s);
353 exit(1);
354 }
355