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