/usr/bin/gnuplot symlinks packageing problems were fixed gor gnuplot-x11
[gnuplot] / term / unixpc.trm
1 /* Hello, Emacs, this is -*-C-*-
2  * $Id: unixpc.trm,v 1.14 2006/07/21 02:35:48 sfeam Exp $
3  *
4  */
5
6 /* GNUPLOT - unixpc.trm */
7
8 /*[
9  * Copyright 1990 - 1993, 1998, 2004
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 (gnuplot-info@lists.sourceforge.net).
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, const 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 = {
140     (unsigned short *) uPC_display,
141     2 * uPC_XSIZE, 0, 0, 0, 0, 0, 0,
142     uPC_XMAX, uPC_YMAX, SRCSRC, DSTOR, 0
143 };
144
145 #define IfErrOut(e1,e2,s1,s2) if (e1 e2) {                              \
146     fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2);        \
147     uPC_fixwind(0);                                                     \
148     exit(-1);                                                           \
149 }
150
151 TERM_PUBLIC void
152 uPC_init()
153 {
154     /* This routine will ioctl to change 0 size */
155     int i;
156     struct uwdata uw;
157     int uPC_fixwind();
158     short gw;
159
160     /* Check that we are on the bitmapped window. */
161     if (iswind() != 0) {
162         fputs("Sorry--must run from the bitmapped terminal\n", stderr);
163         exit(-1);
164     }
165     for (i = 1; i <= 16; i++) {
166         if (i != SIGINT && i != SIGFPE)         /* Two are caught in plot.c */
167             signal(i, uPC_fixwind);
168     }
169
170 /* Increase the screen size */
171     uw.uw_x = 0;
172     uw.uw_y = 0;                /* Leave room for top status line. */
173     uw.uw_width = uPC_XMAX;     /* 720 */
174     uw.uw_height = uPC_YMAX;    /* 288 normal--we clobber 12 (top row) */
175     uw.uw_uflags = 1;           /* Creates with no border */
176
177     IfErrOut(ioctl(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
178 }
179
180
181 TERM_PUBLIC void
182 uPC_graphics()
183 {
184 /* This routine will clear the uPC_display buffer and window. */
185     register Scr_type *j;
186     register int i;
187
188     j = (Scr_type *) uPC_display;
189     i = uPC_YSIZE * uPC_XSIZE + 1;
190
191     while (--i)
192         *j++ = 0;
193    /* Position the cursor to the bottom of the screen so when we come back to
194     * text mode we are just below the graph.
195     */
196     fputs("\033[25;1H", stdout);
197
198     uPC_ur.ur_dstop = DSTSRC;   /* replace (clear screen). */
199     IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
200              "ioctl failed", "WIOCRASTOP");
201     uPC_ur.ur_dstop = DSTOR;    /* Or in (show text) */
202 }
203
204
205 TERM_PUBLIC void
206 uPC_text()
207 {
208 /* This routine will flush the display. */
209
210     IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
211              "ioctl failed", "WIOCRASTOP");
212 }
213
214
215 TERM_PUBLIC void
216 uPC_linetype(int linetype)
217 {
218 /* This routine records the current linetype. */
219     if (uPC_cur_linetype != linetype) {
220         uPC_raster_count = 0;
221         uPC_cur_linetype = linetype;
222     }
223 }
224
225
226 TERM_PUBLIC void
227 uPC_move(unsigned int x, unsigned int y)
228 {
229 /* This routine just records x and y in uPC_sx, uPC_sy */
230     uPC_sx = x;
231     uPC_sy = y;
232 }
233
234
235 /* Was just (*(a)|=(b)) */
236 #define uPC_PLOT(a,b)   (uPC_cur_linetype != 0 ? uPC_plot_word (a,b) :\
237                                 (*(a)|=(b)))
238
239 /*
240    Weak attempt to make line styles.  The real problem is the aspect
241    ratio.  This routine is called only when a bit is to be turned on in
242    a horizontal word.  A better line style routine would know something
243    about the slope of the line around the current point (in order to
244    change weighting).
245
246    This yields 3 working linetypes plus a usable axis line type.
247 */
248 void
249 uPC_plot_word(Scr_type *a, Scr_type b)
250 {
251     /* Various line types */
252     switch (uPC_cur_linetype) {
253     case LT_AXIS:
254         /* Distinguish between horizontal and vertical axis. */
255         if (uPC_sx > uPC_XMAX / 8 && uPC_sx < 7 * uPC_XMAX / 8) {
256             /* Fuzzy tolerance because we don't know exactly where the y axis is */
257             if (++uPC_raster_count % 2 == 0)
258                 *(a) |= b;
259         } else {
260             /* Due to aspect ratio, take every other y pixel and every third x. */
261             *(a) |= (b & 0x9999);
262         }
263         break;
264     case 1:
265     case 5:
266         /* Make a |    |----|    |----| type of line. */
267         if ((1 << uPC_raster_count) & 0xF0F0)
268             *(a) |= b;
269         if (++uPC_raster_count > 15)
270             uPC_raster_count = 0;
271         break;
272     case 2:
273     case 6:
274         /* Make a |----|----|----|--- |    | type of line. */
275         if ((1 << uPC_raster_count) & 0x0EFFF)
276             *(a) |= b;
277         if (++uPC_raster_count > 19)
278             uPC_raster_count = 0;
279         break;
280     case 3:
281     case 7:
282         /* Make a | -  | -  | -  | -  | type of line. */
283         if ((1 << uPC_raster_count) & 0x4444)
284             *(a) |= b;
285         if (++uPC_raster_count > 15)
286             uPC_raster_count = 0;
287         break;
288     case 4:
289     case 8:
290     default:
291         *(a) |= b;
292         break;
293     }
294 }
295
296 TERM_PUBLIC void
297 uPC_vector(unsigned int x, unsigned int y)
298 {
299 /* This routine calls line with x,y */
300     int x1 = uPC_sx, y1 = uPC_sy, x2 = x, y2 = y;
301     register int c, e, dx, dy, width;
302     register Scr_type mask, *a;
303
304 /* Record new sx, sy for next call to the vector routine. */
305     uPC_sx = x2;
306     uPC_sy = y2;
307
308     a = &uPC_display[(uPC_YSIZE - 1) - y1][x1 >> 4];
309     mask = lookup[x1 & 0x0f];
310     width = uPC_width;
311
312     if ((dx = x2 - x1) > 0) {
313         if ((dy = y2 - y1) > 0) {
314             if (dx > dy) {      /* dx > 0, dy > 0, dx > dy */
315                 dy <<= 1;
316                 e = dy - dx;
317                 c = dx + 2;
318                 dx <<= 1;
319
320                 while (--c) {
321                     uPC_PLOT(a, mask);
322                     if (e >= 0) {
323                         (Scr_kluge *) a -= width;
324                         e -= dx;
325                     }
326                     if (mask & uPC_HIGH_BIT) {
327                         mask = 1;
328                         a++;
329                     } else
330                         mask <<= 1;
331                     e += dy;
332                 }
333             } else {            /* dx > 0, dy > 0, dx <= dy */
334                 dx <<= 1;
335                 e = dx - dy;
336                 c = dy + 2;
337                 dy <<= 1;
338
339                 while (--c) {
340                     uPC_PLOT(a, mask);
341                     if (e >= 0) {
342                         if (mask & uPC_HIGH_BIT) {
343                             mask = 1;
344                             a++;
345                         } else
346                             mask <<= 1;
347                         e -= dy;
348                     }
349                     (Scr_kluge *) a -= width;
350                     e += dx;
351                 }
352             }
353         } else {
354             dy = -dy;
355             if (dx > dy) {      /* dx > 0, dy <= 0, dx > dy */
356                 dy <<= 1;
357                 e = dy - dx;
358                 c = dx + 2;
359                 dx <<= 1;
360
361                 while (--c) {
362                     uPC_PLOT(a, mask);
363                     if (e >= 0) {
364                         (Scr_kluge *) a += width;
365                         e -= dx;
366                     }
367                     if (mask & uPC_HIGH_BIT) {
368                         mask = 1;
369                         a++;
370                     } else
371                         mask <<= 1;
372                     e += dy;
373                 }
374             } else {            /* dx > 0, dy <= 0, dx <= dy */
375                 dx <<= 1;
376                 e = dx - dy;
377                 c = dy + 2;
378                 dy <<= 1;
379
380                 while (--c) {
381                     uPC_PLOT(a, mask);
382                     if (e >= 0) {
383                         if (mask & uPC_HIGH_BIT) {
384                             mask = 1;
385                             a++;
386                         } else
387                             mask <<= 1;
388                         e -= dy;
389                     }
390                     (Scr_kluge *) a += width;
391                     e += dx;
392                 }
393             }
394         }
395     } else {
396         dx = -dx;
397         if ((dy = y2 - y1) > 0) {
398             if (dx > dy) {      /* dx <= 0, dy > 0, dx > dy */
399                 dy <<= 1;
400                 e = dy - dx;
401                 c = dx + 2;
402                 dx <<= 1;
403
404                 while (--c) {
405                     uPC_PLOT(a, mask);
406                     if (e >= 0) {
407                         (Scr_kluge *) a -= width;
408                         e -= dx;
409                     }
410                     if (mask & 1) {
411                         mask = uPC_HIGH_BIT;
412                         a--;
413                     } else
414                         mask >>= 1;
415                     e += dy;
416                 }
417             } else {            /* dx <= 0, dy > 0, dx <= dy */
418                 dx <<= 1;
419                 e = dx - dy;
420                 c = dy + 2;
421                 dy <<= 1;
422
423                 while (--c) {
424                     uPC_PLOT(a, mask);
425                     if (e >= 0) {
426                         if (mask & 1) {
427                             mask = uPC_HIGH_BIT;
428                             a--;
429                         } else
430                             mask >>= 1;
431                         e -= dy;
432                     }
433                     (Scr_kluge *) a -= width;
434                     e += dx;
435                 }
436             }
437         } else {
438             dy = -dy;
439             if (dx > dy) {      /* dx <= 0, dy <= 0, dx > dy */
440                 dy <<= 1;
441                 e = dy - dx;
442                 c = dx + 2;
443                 dx <<= 1;
444
445                 while (--c) {
446                     uPC_PLOT(a, mask);
447                     if (e >= 0) {
448                         (Scr_kluge *) a += width;
449                         e -= dx;
450                     }
451                     if (mask & 1) {
452                         mask = uPC_HIGH_BIT;
453                         a--;
454                     } else
455                         mask >>= 1;
456                     e += dy;
457                 }
458             } else {            /* dx <= 0, dy <= 0, dx <= dy */
459                 dx <<= 1;
460                 e = dx - dy;
461                 c = dy + 2;
462                 dy <<= 1;
463
464                 while (--c) {
465                     uPC_PLOT(a, mask);
466                     if (e >= 0) {
467                         if (mask & 1) {
468                             mask = uPC_HIGH_BIT;
469                             a--;
470                         } else
471                             mask >>= 1;
472                         e -= dy;
473                     }
474                     (Scr_kluge *) a += width;
475                     e += dx;
476                 }
477             }
478         }
479     }
480 }
481
482
483 #ifdef uPC_NOT_USED
484
485 /* Added by Russell Lang, eln272v@monu1.cc.monash.oz
486    This placement to the nearest character cell worked, and I'm leaving
487    it here so the calculations involved won't be lost!  (jdc)
488 */
489 TERM_PUBLIC void
490 uPC_put_text(unsigned int x, unsigned int y, const char str[])
491 {
492     /* This routine puts the text at the cursor location nearest
493        to (x,y).  Obviously the exact postion would look better */
494
495     /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
496     printf("\033[%d;%dH%s\033[25;1H",
497            (int) (24 - (y - uPC_VCHAR / 2) * 25 / uPC_YMAX),
498            (int) (x * 80 / uPC_XMAX), str);
499     fflush(stdout);
500 }
501
502 #endif
503
504
505 TERM_PUBLIC void
506 uPC_put_text(unsigned int x, unsigned int y, const char str[])
507 {
508     if (uPC_angle == 1)
509         x += uPC_VCHAR / 2;
510     else
511         y -= uPC_VCHAR / 2;
512
513     switch (uPC_angle) {
514     case 0:
515         for (; *str; ++str, x += uPC_HCHAR)
516             uPC_putc(x, y, *str, uPC_angle);
517         break;
518     case 1:
519         for (; *str; ++str, y += uPC_HCHAR)
520             uPC_putc(x, y, *str, uPC_angle);
521         break;
522     }
523 }
524
525
526 /*
527    Put a character at an x,y location in the bit map (using the fnt5x9
528    array.  This is mostly just copied from the bitmap.c driver.
529 */
530 void
531 uPC_putc(unsigned int x, unsigned int y, int c, int angle)
532 {
533     int i, j, k;
534     register Scr_type mask, *a;
535     char_row fc;
536     unsigned int pixelon;
537
538     i = c - ' ';
539     for (j = 0; j < FNT5X9_VBITS; j++) {
540         fc = fnt5x9[i][j];
541         for (k = 0; k < FNT5X9_HBITS; k++) {
542             pixelon = ((unsigned int) (fc)) >> k & 1;
543             if (pixelon) {
544                 switch (angle) {
545                 case 0:
546                     mask = lookup[x + k + 1 & 0x0f];
547                     a = &uPC_display[(uPC_YSIZE - 1) - (y + j)][(x + k + 1) >> 4];
548                     break;
549                 case 1:
550                     mask = lookup[x - j & 0x0f];
551                     a = &uPC_display[(uPC_YSIZE - 1) - (y + k + 1)][(x - j) >> 4];
552                     break;
553                 }
554                 *(a) |= (mask); /* see uPC_PLOT macro */
555             }
556         }
557     }
558 }
559
560
561 TERM_PUBLIC int
562 uPC_text_angle(int ang)
563 {
564     uPC_angle = (ang ? 1 : 0);
565     return TRUE;
566 }
567
568
569 TERM_PUBLIC void
570 uPC_reset()
571 {
572     /* Reset window to normal size. */
573     uPC_fixwind(0);
574 }
575
576
577
578 void
579 uPC_fixwind(int signo)
580 {
581     static struct uwdata wreset =
582     {0, 12, 720, 288, 0x1};
583     struct utdata ut;
584
585 /* Reset the window to the right size. */
586     ioctl(1, WIOCSETD, &wreset);        /* 0, not wncur here! */
587
588 /* Scroll the screen once. (avoids typing over the same line) */
589     putc('\n', stderr);
590
591     if (signo) {
592         if (signo == SIGILL || signo == SIGTRAP || signo == SIGPWR)
593             signal(signo, SIG_DFL);
594         kill(0, signo);         /* Redo the signal (as if we never trapped it). */
595     }
596 }
597 #endif /* TERM_BODY */
598
599 #ifdef TERM_TABLE
600
601 TERM_TABLE_START(unixpc_driver)
602     "unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
603     uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR,
604     uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset,
605     uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
606     uPC_linetype, uPC_put_text, uPC_text_angle,
607     null_justify_text, line_and_point, do_arrow, set_font_null
608 TERM_TABLE_END(unixpc_driver)
609
610 #undef LAST_TERM
611 #define LAST_TERM unixpc_driver
612
613 #endif /* TERM_TABLE */
614 #endif /* TERM_PROTO_ONLY */
615
616 #ifdef TERM_HELP
617 START_HELP(unixpc)
618 "1 unixpc",
619 "?commands set terminal unixpc",
620 "?set terminal unixpc",
621 "?set term unixpc",
622 "?terminal unixpc",
623 "?term unixpc",
624 "?unixpc",
625 " The `unixpc` terminal driver supports AT&T 3b1 and AT&T 7300 Unix PC.  It has",
626 " no options."
627 END_HELP(unixpc)
628 #endif /* TERM_HELP */