xref: /onnv-gate/usr/src/cmd/tplot/vplot.c (revision 335:d26e4323ca82)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include <stdio.h>
34 #include <signal.h>
35 #include <values.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <sgtty.h>
40 #include <stdlib.h>
41 
42 #define	NB	88
43 #define	BSIZ	512
44 #define	mapx(x)	((1536*((x)-botx)/del)+centx)
45 #define	mapy(y)	((1536*(del-(y)+boty)/del)-centy)
46 #define	SOLID -1
47 #define	DOTTED 014
48 #define	SHORTDASHED 034
49 #define	DOTDASHED 054
50 #define	LONGDASHED 074
51 #define	SETSTATE	(('v'<<8)+1)
52 #define	NEG_MASK  (MAXINT<<(2*BITS(char)))
53 #define	MAXCHAR   ((char)~((char)(1<<BITS(char)-1)))
54 #define	BUILDINT(ubyte, lbyte)  \
55 	ubyte > MAXCHAR \
56 	? (ubyte << BITS(char))|lbyte|NEG_MASK \
57 	: (ubyte << BITS(char))|lbyte
58 
59 int	linmod	= SOLID;
60 int	again;
61 int	done1;
62 extern char	chrtab[][16];
63 short	plotcom[] = { 0200, 0, 0, 0 };
64 short	eotcom[] = { 0210, 0, 0, 0 };
65 char	blocks	[NB][BSIZ];
66 short	obuf[264];
67 int	lastx;
68 int	lasty;
69 double	topx	= 1536;
70 double	topy	= 1536;
71 double	botx	= 0;
72 double	boty	= 0;
73 int	centx;
74 int	centy;
75 double	delx	= 1536;
76 double	dely	= 1536;
77 double	del	= 1536;
78 int	bflag;
79 int	fflag;
80 char	*banname;
81 FILE	*vpstr;
82 
83 struct	buf {
84 	int	bno;
85 	char	*block;
86 };
87 struct	buf	bufs[NB];
88 
89 int	in, out;
90 char picname[] = "/var/tmp/rasterXXXXXX";
91 char *picture;
92 
93 void	getpict(void);
94 void	plotch(int);
95 void	putpict(void);
96 void	line(int, int, int, int);
97 void	point(int, int);
98 void	getblk(int);
99 void	onintr(void);
100 
101 int
main(int argc,char ** argv)102 main(int argc, char **argv)
103 {
104 	int i;
105 	int c;
106 	char *fname;
107 
108 	while ((c = getopt(argc, argv, "e:b:")) != EOF)
109 	switch (c) {
110 		case 'b':
111 			bflag++;
112 			banname = optarg;
113 			break;
114 
115 		case 'e':
116 			fname = optarg;
117 			fflag++;
118 			break;
119 
120 		case '?':
121 			fprintf(stderr,
122 			    "usage: vplot [ -f raster ] [ file ]\n");
123 			exit(1);
124 	}
125 	if (fflag) {
126 		if ((in = open(fname, O_RDONLY)) < 0) {
127 			fprintf(stderr, "vplot: cannot open %s\n", fname);
128 			exit(1);
129 		}
130 		putpict();
131 		exit(0);
132 	}
133 	if (optind < argc)
134 		if (freopen(argv[optind], "r", stdin) == NULL) {
135 			fprintf(stderr,
136 			    "vplot: cannot open %s\n", argv[optind]);
137 			exit(1);
138 		}
139 	signal(SIGTERM, (void (*)(int))onintr);
140 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
141 		signal(SIGINT, (void (*)(int))onintr);
142 	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
143 		signal(SIGHUP, (void (*)(int))onintr);
144 another:
145 	for (i = 0; i < NB; i++) {
146 		bufs[i].bno = -1;
147 		bufs[i].block = blocks[i];
148 	}
149 
150 	if ((picture = mktemp(picname)) == NULL) {
151 		fprintf(stderr, "vplot: cannot create unique tmp. file name\n");
152 		exit(1);
153 	}
154 
155 	if ((out = open(picture, (O_WRONLY|O_CREAT|O_TRUNC|O_EXCL),
156 	    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH))) == -1) {
157 		fprintf(stderr, "vplot: cannot open %s\n", picture);
158 		exit(1);
159 	}
160 
161 	zseek(out, 32*32);
162 	write(out, blocks[0], BSIZ);
163 /*
164  * delete following code when filsys deals properly with
165  * holes in files
166  */
167 	for (i = 0; i < 512; i++)
168 		blocks[0][i] = 0;
169 	zseek(out, 0);
170 	for (i = 0; i < 32*32; i++)
171 		write(out, blocks[0], 512);
172 	getpict();
173 	for (i = 0; i < NB; i++)
174 		if (bufs[i].bno != -1) {
175 			zseek(out, bufs[i].bno);
176 			write(out, bufs[i].block, BSIZ);
177 		}
178 	putpict();
179 	if (again) {
180 		close(out);
181 		goto another;
182 	}
183 	unlink(picture);
184 	return (0);
185 }
186 
187 void
getpict(void)188 getpict(void)
189 {
190 	int x1, y1;
191 
192 	again = 0;
193 	for (;;)
194 	switch (x1 = getc(stdin)) {
195 	case 's':
196 		botx = getw(stdin);
197 		boty = getw(stdin);
198 		topx = getw(stdin);
199 		topy = getw(stdin);
200 		delx = topx-botx;
201 		dely = topy-boty;
202 		if (dely/delx > 1536./2048.)
203 			del = dely;
204 		else
205 			del = delx * (1566./2048.);
206 		centx = 0;
207 		centx = (2048 - mapx(topx)) / 2;
208 		centy = 0;
209 		centy = mapy(topy) / 2;
210 		continue;
211 
212 	case 'l':
213 		done1 |= 01;
214 		x1 = mapx(getw(stdin));
215 		y1 = mapy(getw(stdin));
216 		lastx = mapx(getw(stdin));
217 		lasty = mapy(getw(stdin));
218 		line(x1, y1, lastx, lasty);
219 		continue;
220 
221 	case 'm':
222 		lastx = mapx(getw(stdin));
223 		lasty = mapy(getw(stdin));
224 		continue;
225 
226 	case 't':
227 		done1 |= 01;
228 		while ((x1 = getc(stdin)) != '\n')
229 			plotch(x1);
230 		continue;
231 
232 	case 'e':
233 		if (done1) {
234 			again++;
235 			return;
236 		}
237 		continue;
238 
239 	case 'p':
240 		done1 |= 01;
241 		lastx = mapx(getw(stdin));
242 		lasty = mapy(getw(stdin));
243 		point(lastx, lasty);
244 		point(lastx+1, lasty);
245 		point(lastx, lasty+1);
246 		point(lastx+1, lasty+1);
247 		continue;
248 
249 	case 'n':
250 		done1 |= 01;
251 		x1 = mapx(getw(stdin));
252 		y1 = mapy(getw(stdin));
253 		line(lastx, lasty, x1, y1);
254 		lastx = x1;
255 		lasty = y1;
256 		continue;
257 
258 	case 'f':
259 		getw(stdin);
260 		getc(stdin);
261 		switch (getc(stdin)) {
262 		case 't':
263 			linmod = DOTTED;
264 			break;
265 		default:
266 		case 'i':
267 			linmod = SOLID;
268 			break;
269 		case 'g':
270 			linmod = LONGDASHED;
271 			break;
272 		case 'r':
273 			linmod = SHORTDASHED;
274 			break;
275 		case 'd':
276 			linmod = DOTDASHED;
277 			break;
278 		}
279 		while ((x1 = getc(stdin)) != '\n')
280 			if (x1 == -1)
281 				return;
282 		continue;
283 
284 	case 'd':
285 		getw(stdin);
286 		getw(stdin);
287 		getw(stdin);
288 		x1 = getw(stdin);
289 		while (--x1 >= 0)
290 			getw(stdin);
291 		continue;
292 
293 	case -1:
294 		return;
295 
296 	default:
297 		printf("Botch\n");
298 		return;
299 	}
300 }
301 
302 void
plotch(int c)303 plotch(int c)
304 {
305 	int j;
306 	char *cp;
307 	int i;
308 
309 	if (c < ' ' || c > 0177)
310 		return;
311 	cp = chrtab[c-' '];
312 	for (i = -16; i < 16; i += 2) {
313 		c = *cp++;
314 		for (j = 7; j >= 0; --j)
315 			if ((c>>j)&1) {
316 				point(lastx+6-j*2, lasty+i);
317 				point(lastx+7-j*2, lasty+i);
318 				point(lastx+6-j*2, lasty+i+1);
319 				point(lastx+7-j*2, lasty+i+1);
320 			}
321 	}
322 	lastx += 16;
323 }
324 
325 int	f; /* versatec file number */
326 
327 void
putpict(void)328 putpict(void)
329 {
330 	int x;
331 	short *ip, *op;
332 	int y;
333 
334 	if (f == 0) {
335 		f = open("/dev/vp", O_WRONLY);
336 		if (f < 0) {
337 			fprintf(stderr, "Cannot open vp\n");
338 			unlink(picture);
339 			exit(1);
340 		}
341 		vpstr = fdopen(f, "w");
342 		if (bflag)  {
343 			banner(vpstr, banname);
344 			fflush(vpstr);
345 		}
346 		ioctl(f, TIOCSETP, plotcom);
347 	}
348 	op = obuf;
349 	lseek(in, 0L, 0);
350 	for (y = 0; y < 2048; y++) {
351 		if ((y&077) == 0)
352 			read(in, blocks[0], 32*BSIZ);
353 		for (x = 0; x < 32; x++)  {
354 			ip = (short *)&blocks[x][(y&077)<<3];
355 			*op++ = *ip++;
356 			*op++ = *ip++;
357 			*op++ = *ip++;
358 			*op++ = *ip++;
359 		}
360 		*op++ = 0;
361 		*op++ = 0;
362 		*op++ = 0;
363 		*op++ = 0;
364 		if (y&1) {
365 			write(f, (char *)obuf, sizeof (obuf));
366 			op = obuf;
367 		}
368 	}
369 }
370 
371 void
line(int x0,int y0,int x1,int y1)372 line(int x0, int y0, int x1, int y1)
373 {
374 	int dx, dy;
375 	int xinc, yinc;
376 	int res1;
377 	int res2;
378 	int slope;
379 
380 	xinc = 1;
381 	yinc = 1;
382 	if ((dx = x1-x0) < 0) {
383 		xinc = -1;
384 		dx = -dx;
385 	}
386 	if ((dy = y1-y0) < 0) {
387 		yinc = -1;
388 		dy = -dy;
389 	}
390 	slope = xinc*yinc;
391 	res1 = 0;
392 	res2 = 0;
393 	if (dx >= dy)
394 	while (x0 != x1) {
395 	if ((x0 + slope*y0) & linmod)
396 	if (((x0>>6) + ((y0&~077)>>1)) == bufs[0].bno)
397 		bufs[0].block[((y0&077)<<3)+((x0>>3)&07)] |= 1 << (7-(x0&07));
398 	else
399 		point(x0, y0);
400 		if (res1 > res2) {
401 			res2 += dx - res1;
402 			res1 = 0;
403 			y0 += yinc;
404 		}
405 		res1 += dy;
406 		x0 += xinc;
407 	} else while (y0 != y1) {
408 	if ((x0 + slope * y0) & linmod)
409 		if (((x0 >> 6) + ((y0 & ~077) >> 1)) == bufs[0].bno)
410 			bufs[0].block[((y0 & 077) << 3)+((x0 >> 3) & 07)]
411 			    |= 1 << (7 - (x0& 07));
412 	else
413 		point(x0, y0);
414 		if (res1 > res2) {
415 			res2 += dy - res1;
416 			res1 = 0;
417 			x0 += xinc;
418 		}
419 		res1 += dx;
420 		y0 += yinc;
421 	}
422 	if ((x1+slope*y1)&linmod)
423 	if (((x1>>6) + ((y1&~077)>>1)) == bufs[0].bno)
424 		bufs[0].block[((y1&077)<<3)+((x1>>3)&07)] |= 1 << (7-(x1&07));
425 	else
426 		point(x1, y1);
427 }
428 
429 void
point(int x,int y)430 point(int x, int y)
431 {
432 	int bno;
433 
434 	bno = ((x&03700)>>6) + ((y&03700)>>1);
435 	if (bno != bufs[0].bno) {
436 		if (bno < 0 || bno >= 1024)
437 			return;
438 		getblk(bno);
439 	}
440 	bufs[0].block[((y&077)<<3)+((x>>3)&07)] |= 1 << (7-(x&07));
441 }
442 
443 void
getblk(int b)444 getblk(int b)
445 {
446 	struct buf *bp1, *bp2;
447 	char *tp;
448 
449 loop:
450 	for (bp1 = bufs; bp1 < &bufs[NB]; bp1++) {
451 		if (bp1->bno == b || bp1->bno == -1) {
452 			tp = bp1->block;
453 			for (bp2 = bp1; bp2 > bufs; --bp2) {
454 				bp2->bno = (bp2-1)->bno;
455 				bp2->block = (bp2-1)->block;
456 			}
457 			bufs[0].bno = b;
458 			bufs[0].block = tp;
459 			return;
460 		}
461 	}
462 	zseek(out, bufs[NB-1].bno);
463 	write(out, bufs[NB-1].block, BSIZ);
464 	zseek(in, b);
465 	read(in, bufs[NB-1].block, BSIZ);
466 	bufs[NB-1].bno = b;
467 	goto loop;
468 }
469 
470 void
onintr(void)471 onintr(void)
472 {
473 	unlink(picture);
474 	exit(1);
475 }
476 
477 
478 int
zseek(int a,int b)479 zseek(int a, int b)
480 {
481 	return (lseek(a, (long)b*512, 0));
482 }
483