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