Annotation of OpenXM_contrib/gnuplot/term/unixpc.trm, Revision 1.1.1.1
1.1 maekawa 1: /*
2: * $Id: unixpc.trm,v 1.14 1998/04/14 00:18:12 drd Exp $
3: *
4: */
5:
6: /* GNUPLOT - unixpc.trm */
7:
8: /*[
9: * Copyright 1990 - 1993, 1998
10: *
11: * Permission to use, copy, and distribute this software and its
12: * documentation for any purpose with or without fee is hereby granted,
13: * provided that the above copyright notice appear in all copies and
14: * that both that copyright notice and this permission notice appear
15: * in supporting documentation.
16: *
17: * Permission to modify the software is granted, but not the right to
18: * distribute the complete modified source code. Modifications are to
19: * be distributed as patches to the released version. Permission to
20: * distribute binaries produced by compiling modified sources is granted,
21: * provided you
22: * 1. distribute the corresponding source modifications from the
23: * released version in the form of a patch file along with the binaries,
24: * 2. add special version identification to distinguish your version
25: * in addition to the base release version number,
26: * 3. provide your name and address as the primary contact for the
27: * support of your modified version, and
28: * 4. retain our contact information in regard to use of the base
29: * software.
30: * Permission to distribute the released version of the source code along
31: * with corresponding source modifications in the form of a patch file is
32: * granted with same provisions 2 through 4 for binary distributions.
33: *
34: * This software is provided "as is" without express or implied warranty
35: * to the extent permitted by applicable law.
36: ]*/
37:
38: /*
39: * This file is included by ../term.c.
40: *
41: * This terminal driver supports:
42: * Unix PC's (ATT 3b1)
43: *
44: * AUTHORS
45: * John Campbell
46: *
47: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
48: *
49: */
50:
51: /*
52: >From: John Campbell (...!arizona!naucse!jdc)
53:
54: I originally ported gnuplot to the ATT 3b1 (ATT7300) on 12/4/88, and then
55: added the minimal code needed to bring it up to 2.0 level on 1/28/90. The
56: 3b1, as I view it, is a 720x300 bitmapped, monochrome display (often people
57: don't use the top 12 scan lines and thus the effective size is 720x288). I
58: tried to maximize the size of the graph area, by using these top 12 lines
59: (normally reserved) and set up a signal handler to restore them upon exit,
60: abort, etc.
61:
62: Line styles were "fudged" (they do not know the aspect ratio). The same
63: line style may look different depending upon the slope of the curve. Due to
64: this only 4 line styles were implemented. While more line types are possible,
65: the current styles were chosen as distinguishable.
66:
67: The 3b1 has 4 "special" rows at the bottom that I could not use in graphics
68: mode. It has been suggested that we use these lines for command prompting.
69: Others have requested that we have a graphics window and a command window.
70: My experience with gnuplot only includes relatively dumb graphics devices--
71: hence gnuplot "looks and feels" normal to me the way I implemented it.
72: I welcome either of these changes from someone else, however.
73: */
74:
75: /*
76: * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
77: */
78:
79: #include "driver.h"
80:
81: #ifdef TERM_REGISTER
82: register_term(unixpc)
83: #endif
84:
85: #ifdef TERM_PROTO
86: TERM_PUBLIC void uPC_init __PROTO((void));
87: TERM_PUBLIC void uPC_graphics __PROTO((void));
88: TERM_PUBLIC void uPC_text __PROTO((void));
89: TERM_PUBLIC void uPC_linetype __PROTO((int linetype));
90: TERM_PUBLIC void uPC_move __PROTO((unsigned int x, unsigned int y));
91: TERM_PUBLIC void uPC_vector __PROTO((unsigned int x, unsigned int y));
92: TERM_PUBLIC void uPC_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
93: TERM_PUBLIC int uPC_text_angle __PROTO((int ang));
94: TERM_PUBLIC void uPC_reset __PROTO((void));
95: #define uPC_XMAX 720
96: #define uPC_YMAX 300
97: #define uPC_VCHAR FNT5X9_VCHAR
98: #define uPC_HCHAR FNT5X9_HCHAR
99: #define uPC_VTIC uPC_VCHAR/2 /* Was 8 */
100: #define uPC_HTIC uPC_HCHAR /* Was 12 */
101: #endif /* TERM_PROTO */
102:
103: #ifndef TERM_PROTO_ONLY
104: #ifdef TERM_BODY
105: void uPC_fixwind __PROTO((int signo));
106: void uPC_putc __PROTO((unsigned int x, unsigned int y, int c, int angle));
107: void uPC_plot_word __PROTO((unsigned short *a, unsigned short b));
108: #include <sys/window.h> /* Started with tam.h--too much trouble. */
109: #include <sys/signal.h>
110: #include <errno.h>
111:
112: #define uPC_HIGH_BIT (0x8000)
113:
114: typedef unsigned short Scr_type;
115: typedef unsigned char Scr_kluge;
116:
117:
118: #define uPC_XSIZE 45 /* Short ints. */
119: #define uPC_YSIZE uPC_YMAX
120:
121: Scr_type uPC_display[uPC_YSIZE][uPC_XSIZE];
122: int uPC_width = 2 * uPC_XSIZE;
123: int uPC_sx = 0, uPC_sy = 0;
124: int uPC_cur_linetype = 0;
125: int uPC_angle = 0;
126: unsigned short uPC_raster_count = 0;
127: static Scr_type lookup[] =
128: {
129: 0x0001, 0x0002, 0x0004, 0x0008,
130: 0x0010, 0x0020, 0x0040, 0x0080,
131: 0x0100, 0x0200, 0x0400, 0x0800,
132: 0x1000, 0x2000, 0x4000, 0x8000,
133: };
134:
135: #define uPC_XLAST (uPC_XMAX - 1)
136: #define uPC_YLAST (uPC_YMAX - 1)
137:
138:
139: static struct urdata uPC_ur = { (unsigned short *) uPC_display,
140: 2 * uPC_XSIZE, 0, 0, 0, 0, 0, 0,
141: uPC_XMAX, uPC_YMAX, SRCSRC, DSTOR, 0
142: };
143:
144: #define IfErrOut(e1,e2,s1,s2) if (e1 e2) {\
145: fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2);\
146: uPC_fixwind(0);\
147: exit(-1);}
148:
149: TERM_PUBLIC void uPC_init()
150: {
151: /* This routine will ioctl to change 0 size */
152: int i;
153: struct uwdata uw;
154: int uPC_fixwind();
155: short gw;
156:
157: /* Check that we are on the bitmapped window. */
158: if (iswind() != 0) {
159: fputs("Sorry--must run from the bitmapped terminal\n", stderr);
160: exit(-1);
161: }
162: for (i = 1; i <= 16; i++) {
163: if (i != SIGINT && i != SIGFPE) /* Two are caught in plot.c */
164: signal(i, uPC_fixwind);
165: }
166:
167: /* Increase the screen size */
168: uw.uw_x = 0;
169: uw.uw_y = 0; /* Leave room for top status line. */
170: uw.uw_width = uPC_XMAX; /* 720 */
171: uw.uw_height = uPC_YMAX; /* 288 normal--we clobber 12 (top row) */
172: uw.uw_uflags = 1; /* Creates with no border */
173:
174: IfErrOut(ioctl(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
175: }
176:
177:
178: TERM_PUBLIC void uPC_graphics()
179: {
180: /* This routine will clear the uPC_display buffer and window. */
181: register Scr_type *j;
182: register int i;
183:
184: j = (Scr_type *) uPC_display;
185: i = uPC_YSIZE * uPC_XSIZE + 1;
186:
187: while (--i)
188: *j++ = 0;
189: /* Position the cursor to the bottom of the screen so when we come back to
190: * text mode we are just below the graph.
191: */
192: fputs("\033[25;1H", stdout);
193:
194: uPC_ur.ur_dstop = DSTSRC; /* replace (clear screen). */
195: IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
196: "ioctl failed", "WIOCRASTOP");
197: uPC_ur.ur_dstop = DSTOR; /* Or in (show text) */
198: }
199:
200:
201: TERM_PUBLIC void uPC_text()
202: {
203: /* This routine will flush the display. */
204:
205: IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
206: "ioctl failed", "WIOCRASTOP");
207: }
208:
209:
210: TERM_PUBLIC void uPC_linetype(linetype)
211: int linetype;
212: {
213: /* This routine records the current linetype. */
214: if (uPC_cur_linetype != linetype) {
215: uPC_raster_count = 0;
216: uPC_cur_linetype = linetype;
217: }
218: }
219:
220:
221: TERM_PUBLIC void uPC_move(x, y)
222: unsigned int x, y;
223: {
224: /* This routine just records x and y in uPC_sx, uPC_sy */
225: uPC_sx = x;
226: uPC_sy = y;
227: }
228:
229:
230: /* Was just (*(a)|=(b)) */
231: #define uPC_PLOT(a,b) (uPC_cur_linetype != 0 ? uPC_plot_word (a,b) :\
232: (*(a)|=(b)))
233:
234: void uPC_plot_word(a, b)
235: Scr_type *a, b;
236: /*
237: Weak attempt to make line styles. The real problem is the aspect
238: ratio. This routine is called only when a bit is to be turned on in
239: a horizontal word. A better line style routine would know something
240: about the slope of the line around the current point (in order to
241: change weighting).
242:
243: This yields 3 working linetypes plus a usable axis line type.
244: */
245: {
246: /* Various line types */
247: switch (uPC_cur_linetype) {
248: case -1:
249: /* Distinguish between horizontal and vertical axis. */
250: if (uPC_sx > uPC_XMAX / 8 && uPC_sx < 7 * uPC_XMAX / 8) {
251: /* Fuzzy tolerance because we don't know exactly where the y axis is */
252: if (++uPC_raster_count % 2 == 0)
253: *(a) |= b;
254: } else {
255: /* Due to aspect ratio, take every other y pixel and every third x. */
256: *(a) |= (b & 0x9999);
257: }
258: break;
259: case 1:
260: case 5:
261: /* Make a | |----| |----| type of line. */
262: if ((1 << uPC_raster_count) & 0xF0F0)
263: *(a) |= b;
264: if (++uPC_raster_count > 15)
265: uPC_raster_count = 0;
266: break;
267: case 2:
268: case 6:
269: /* Make a |----|----|----|--- | | type of line. */
270: if ((1 << uPC_raster_count) & 0x0EFFF)
271: *(a) |= b;
272: if (++uPC_raster_count > 19)
273: uPC_raster_count = 0;
274: break;
275: case 3:
276: case 7:
277: /* Make a | - | - | - | - | type of line. */
278: if ((1 << uPC_raster_count) & 0x4444)
279: *(a) |= b;
280: if (++uPC_raster_count > 15)
281: uPC_raster_count = 0;
282: break;
283: case 4:
284: case 8:
285: default:
286: *(a) |= b;
287: break;
288: }
289: }
290:
291: TERM_PUBLIC void uPC_vector(x, y)
292: unsigned int x, y;
293: {
294: /* This routine calls line with x,y */
295: int x1 = uPC_sx, y1 = uPC_sy, x2 = x, y2 = y;
296: register int c, e, dx, dy, width;
297: register Scr_type mask, *a;
298:
299: /* Record new sx, sy for next call to the vector routine. */
300: uPC_sx = x2;
301: uPC_sy = y2;
302:
303: a = &uPC_display[(uPC_YSIZE - 1) - y1][x1 >> 4];
304: mask = lookup[x1 & 0x0f];
305: width = uPC_width;
306:
307: if ((dx = x2 - x1) > 0) {
308: if ((dy = y2 - y1) > 0) {
309: if (dx > dy) { /* dx > 0, dy > 0, dx > dy */
310: dy <<= 1;
311: e = dy - dx;
312: c = dx + 2;
313: dx <<= 1;
314:
315: while (--c) {
316: uPC_PLOT(a, mask);
317: if (e >= 0) {
318: (Scr_kluge *) a -= width;
319: e -= dx;
320: }
321: if (mask & uPC_HIGH_BIT) {
322: mask = 1;
323: a++;
324: } else
325: mask <<= 1;
326: e += dy;
327: }
328: } else { /* dx > 0, dy > 0, dx <= dy */
329: dx <<= 1;
330: e = dx - dy;
331: c = dy + 2;
332: dy <<= 1;
333:
334: while (--c) {
335: uPC_PLOT(a, mask);
336: if (e >= 0) {
337: if (mask & uPC_HIGH_BIT) {
338: mask = 1;
339: a++;
340: } else
341: mask <<= 1;
342: e -= dy;
343: }
344: (Scr_kluge *) a -= width;
345: e += dx;
346: }
347: }
348: } else {
349: dy = -dy;
350: if (dx > dy) { /* dx > 0, dy <= 0, dx > dy */
351: dy <<= 1;
352: e = dy - dx;
353: c = dx + 2;
354: dx <<= 1;
355:
356: while (--c) {
357: uPC_PLOT(a, mask);
358: if (e >= 0) {
359: (Scr_kluge *) a += width;
360: e -= dx;
361: }
362: if (mask & uPC_HIGH_BIT) {
363: mask = 1;
364: a++;
365: } else
366: mask <<= 1;
367: e += dy;
368: }
369: } else { /* dx > 0, dy <= 0, dx <= dy */
370: dx <<= 1;
371: e = dx - dy;
372: c = dy + 2;
373: dy <<= 1;
374:
375: while (--c) {
376: uPC_PLOT(a, mask);
377: if (e >= 0) {
378: if (mask & uPC_HIGH_BIT) {
379: mask = 1;
380: a++;
381: } else
382: mask <<= 1;
383: e -= dy;
384: }
385: (Scr_kluge *) a += width;
386: e += dx;
387: }
388: }
389: }
390: } else {
391: dx = -dx;
392: if ((dy = y2 - y1) > 0) {
393: if (dx > dy) { /* dx <= 0, dy > 0, dx > dy */
394: dy <<= 1;
395: e = dy - dx;
396: c = dx + 2;
397: dx <<= 1;
398:
399: while (--c) {
400: uPC_PLOT(a, mask);
401: if (e >= 0) {
402: (Scr_kluge *) a -= width;
403: e -= dx;
404: }
405: if (mask & 1) {
406: mask = uPC_HIGH_BIT;
407: a--;
408: } else
409: mask >>= 1;
410: e += dy;
411: }
412: } else { /* dx <= 0, dy > 0, dx <= dy */
413: dx <<= 1;
414: e = dx - dy;
415: c = dy + 2;
416: dy <<= 1;
417:
418: while (--c) {
419: uPC_PLOT(a, mask);
420: if (e >= 0) {
421: if (mask & 1) {
422: mask = uPC_HIGH_BIT;
423: a--;
424: } else
425: mask >>= 1;
426: e -= dy;
427: }
428: (Scr_kluge *) a -= width;
429: e += dx;
430: }
431: }
432: } else {
433: dy = -dy;
434: if (dx > dy) { /* dx <= 0, dy <= 0, dx > dy */
435: dy <<= 1;
436: e = dy - dx;
437: c = dx + 2;
438: dx <<= 1;
439:
440: while (--c) {
441: uPC_PLOT(a, mask);
442: if (e >= 0) {
443: (Scr_kluge *) a += width;
444: e -= dx;
445: }
446: if (mask & 1) {
447: mask = uPC_HIGH_BIT;
448: a--;
449: } else
450: mask >>= 1;
451: e += dy;
452: }
453: } else { /* dx <= 0, dy <= 0, dx <= dy */
454: dx <<= 1;
455: e = dx - dy;
456: c = dy + 2;
457: dy <<= 1;
458:
459: while (--c) {
460: uPC_PLOT(a, mask);
461: if (e >= 0) {
462: if (mask & 1) {
463: mask = uPC_HIGH_BIT;
464: a--;
465: } else
466: mask >>= 1;
467: e -= dy;
468: }
469: (Scr_kluge *) a += width;
470: e += dx;
471: }
472: }
473: }
474: }
475: }
476:
477:
478: #ifdef uPC_NOT_USED
479: /* Added by Russell Lang, eln272v@monu1.cc.monash.oz
480: This placement to the nearest character cell worked, and I'm leaving
481: it here so the calculations involved won't be lost! (jdc)
482: */
483: TERM_PUBLIC void uPC_put_text(x, y, str)
484: unsigned int x, y;
485: char str[];
486: {
487: /* This routine puts the text at the cursor location nearest
488: to (x,y). Obviously the exact postion would look better */
489:
490: /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
491: printf("\033[%d;%dH%s\033[25;1H",
492: (int) (24 - (y - uPC_VCHAR / 2) * 25 / uPC_YMAX),
493: (int) (x * 80 / uPC_XMAX), str);
494: fflush(stdout);
495: }
496:
497: #endif
498:
499:
500: TERM_PUBLIC void uPC_put_text(x, y, str)
501: unsigned int x, y;
502: char str[];
503: {
504: if (uPC_angle == 1)
505: x += uPC_VCHAR / 2;
506: else
507: y -= uPC_VCHAR / 2;
508:
509: switch (uPC_angle) {
510: case 0:
511: for (; *str; ++str, x += uPC_HCHAR)
512: uPC_putc(x, y, *str, uPC_angle);
513: break;
514: case 1:
515: for (; *str; ++str, y += uPC_HCHAR)
516: uPC_putc(x, y, *str, uPC_angle);
517: break;
518: }
519: }
520:
521:
522: void uPC_putc(x, y, c, angle)
523: unsigned int x, y;
524: int c, angle;
525: /*
526: Put a character at an x,y location in the bit map (using the fnt5x9
527: array. This is mostly just copied from the bitmap.c driver.
528: */
529: {
530: int i, j, k;
531: register Scr_type mask, *a;
532: char_row fc;
533: unsigned int pixelon;
534:
535: i = c - ' ';
536: for (j = 0; j < FNT5X9_VBITS; j++) {
537: fc = fnt5x9[i][j];
538: for (k = 0; k < FNT5X9_HBITS; k++) {
539: pixelon = ((unsigned int) (fc)) >> k & 1;
540: if (pixelon) {
541: switch (angle) {
542: case 0:
543: mask = lookup[x + k + 1 & 0x0f];
544: a = &uPC_display[(uPC_YSIZE - 1) - (y + j)][(x + k + 1) >> 4];
545: break;
546: case 1:
547: mask = lookup[x - j & 0x0f];
548: a = &uPC_display[(uPC_YSIZE - 1) - (y + k + 1)][(x - j) >> 4];
549: break;
550: }
551: *(a) |= (mask); /* see uPC_PLOT macro */
552: }
553: }
554: }
555: }
556:
557:
558: TERM_PUBLIC int uPC_text_angle(ang)
559: int ang;
560: {
561: uPC_angle = ang;
562: return TRUE;
563: }
564:
565:
566: TERM_PUBLIC void uPC_reset()
567: {
568: /* Reset window to normal size. */
569: uPC_fixwind(0);
570: }
571:
572:
573:
574: void uPC_fixwind(signo)
575: int signo;
576: {
577: static struct uwdata wreset =
578: {0, 12, 720, 288, 0x1};
579: struct utdata ut;
580:
581: /* Reset the window to the right size. */
582: ioctl(1, WIOCSETD, &wreset); /* 0, not wncur here! */
583:
584: /* Scroll the screen once. (avoids typing over the same line) */
585: putc('\n', stderr);
586:
587: if (signo) {
588: if (signo == SIGILL || signo == SIGTRAP || signo == SIGPWR)
589: signal(signo, SIG_DFL);
590: kill(0, signo); /* Redo the signal (as if we never trapped it). */
591: }
592: }
593: #endif /* TERM_BODY */
594:
595: #ifdef TERM_TABLE
596:
597: TERM_TABLE_START(unixpc_driver)
598: "unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
599: uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR,
600: uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset,
601: uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
602: uPC_linetype, uPC_put_text, uPC_text_angle,
603: null_justify_text, line_and_point, do_arrow, set_font_null
604: TERM_TABLE_END(unixpc_driver)
605:
606: #undef LAST_TERM
607: #define LAST_TERM unixpc_driver
608:
609: #endif /* TERM_TABLE */
610: #endif /* TERM_PROTO_ONLY */
611:
612: #ifdef TERM_HELP
613: START_HELP(unixpc)
614: "1 unixpc",
615: "?commands set terminal unixpc",
616: "?set terminal unixpc",
617: "?set term unixpc",
618: "?terminal unixpc",
619: "?term unixpc",
620: "?unixpc",
621: " The `unixpc` terminal driver supports AT&T 3b1 and AT&T 7300 Unix PC. It has",
622: " no options."
623: END_HELP(unixpc)
624: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>