Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / unixpc.trm
diff --git a/term/unixpc.trm b/term/unixpc.trm
new file mode 100644 (file)
index 0000000..bce0e6f
--- /dev/null
@@ -0,0 +1,628 @@
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: unixpc.trm,v 1.14 2006/07/21 02:35:48 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - unixpc.trm */
+
+/*[
+ * Copyright 1990 - 1993, 1998, 2004
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+/*
+ * This file is included by ../term.c.
+ *
+ * This terminal driver supports:
+ *  Unix PC's (ATT 3b1)
+ *
+ * AUTHORS
+ *    John Campbell
+ *
+ * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
+ *
+ */
+
+/*
+>From: John Campbell (...!arizona!naucse!jdc)
+
+I originally ported gnuplot to the ATT 3b1 (ATT7300) on 12/4/88, and then
+added the minimal code needed to bring it up to 2.0 level on 1/28/90.  The
+3b1, as I view it, is a 720x300 bitmapped, monochrome display (often people
+don't use the top 12 scan lines and thus the effective size is 720x288).  I
+tried to maximize the size of the graph area, by using these top 12 lines
+(normally reserved) and set up a signal handler to restore them upon exit,
+abort, etc.
+
+Line styles were "fudged" (they do not know the aspect ratio).  The same
+line style may look different depending upon the slope of the curve.  Due to
+this only 4 line styles were implemented.  While more line types are possible,
+the current styles were chosen as distinguishable.
+
+The 3b1 has 4 "special" rows at the bottom that I could not use in graphics
+mode.  It has been suggested that we use these lines for command prompting.
+Others have requested that we have a graphics window and a command window.
+My experience with gnuplot only includes relatively dumb graphics devices--
+hence gnuplot "looks and feels" normal to me the way I implemented it.
+I welcome either of these changes from someone else, however.
+*/
+
+/*
+ * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
+ */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(unixpc)
+#endif
+
+#ifdef TERM_PROTO
+TERM_PUBLIC void uPC_init __PROTO((void));
+TERM_PUBLIC void uPC_graphics __PROTO((void));
+TERM_PUBLIC void uPC_text __PROTO((void));
+TERM_PUBLIC void uPC_linetype __PROTO((int linetype));
+TERM_PUBLIC void uPC_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void uPC_vector __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void uPC_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
+TERM_PUBLIC int uPC_text_angle __PROTO((int ang));
+TERM_PUBLIC void uPC_reset __PROTO((void));
+#define uPC_XMAX 720
+#define uPC_YMAX 300
+#define uPC_VCHAR FNT5X9_VCHAR
+#define uPC_HCHAR FNT5X9_HCHAR
+#define uPC_VTIC  uPC_VCHAR/2  /* Was 8  */
+#define uPC_HTIC  uPC_HCHAR    /* Was 12 */
+#endif /* TERM_PROTO */
+
+#ifndef TERM_PROTO_ONLY
+#ifdef TERM_BODY
+void uPC_fixwind __PROTO((int signo));
+void uPC_putc __PROTO((unsigned int x, unsigned int y, int c, int angle));
+void uPC_plot_word __PROTO((unsigned short *a, unsigned short b));
+#include <sys/window.h>                /* Started with tam.h--too much trouble. */
+#include <sys/signal.h>
+#include <errno.h>
+
+#define uPC_HIGH_BIT    (0x8000)
+
+typedef unsigned short Scr_type;
+typedef unsigned char Scr_kluge;
+
+
+#define uPC_XSIZE       45     /* Short ints. */
+#define uPC_YSIZE uPC_YMAX
+
+Scr_type uPC_display[uPC_YSIZE][uPC_XSIZE];
+int uPC_width = 2 * uPC_XSIZE;
+int uPC_sx = 0, uPC_sy = 0;
+int uPC_cur_linetype = 0;
+int uPC_angle = 0;
+unsigned short uPC_raster_count = 0;
+static Scr_type lookup[] =
+{
+    0x0001, 0x0002, 0x0004, 0x0008,
+    0x0010, 0x0020, 0x0040, 0x0080,
+    0x0100, 0x0200, 0x0400, 0x0800,
+    0x1000, 0x2000, 0x4000, 0x8000,
+};
+
+#define uPC_XLAST (uPC_XMAX - 1)
+#define uPC_YLAST (uPC_YMAX - 1)
+
+
+static struct urdata uPC_ur = {
+    (unsigned short *) uPC_display,
+    2 * uPC_XSIZE, 0, 0, 0, 0, 0, 0,
+    uPC_XMAX, uPC_YMAX, SRCSRC, DSTOR, 0
+};
+
+#define IfErrOut(e1,e2,s1,s2) if (e1 e2) {                             \
+    fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2);       \
+    uPC_fixwind(0);                                                    \
+    exit(-1);                                                          \
+}
+
+TERM_PUBLIC void
+uPC_init()
+{
+    /* This routine will ioctl to change 0 size */
+    int i;
+    struct uwdata uw;
+    int uPC_fixwind();
+    short gw;
+
+    /* Check that we are on the bitmapped window. */
+    if (iswind() != 0) {
+       fputs("Sorry--must run from the bitmapped terminal\n", stderr);
+       exit(-1);
+    }
+    for (i = 1; i <= 16; i++) {
+       if (i != SIGINT && i != SIGFPE)         /* Two are caught in plot.c */
+           signal(i, uPC_fixwind);
+    }
+
+/* Increase the screen size */
+    uw.uw_x = 0;
+    uw.uw_y = 0;               /* Leave room for top status line. */
+    uw.uw_width = uPC_XMAX;    /* 720 */
+    uw.uw_height = uPC_YMAX;   /* 288 normal--we clobber 12 (top row) */
+    uw.uw_uflags = 1;          /* Creates with no border */
+
+    IfErrOut(ioctl(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
+}
+
+
+TERM_PUBLIC void
+uPC_graphics()
+{
+/* This routine will clear the uPC_display buffer and window. */
+    register Scr_type *j;
+    register int i;
+
+    j = (Scr_type *) uPC_display;
+    i = uPC_YSIZE * uPC_XSIZE + 1;
+
+    while (--i)
+       *j++ = 0;
+   /* Position the cursor to the bottom of the screen so when we come back to
+    * text mode we are just below the graph.
+    */
+    fputs("\033[25;1H", stdout);
+
+    uPC_ur.ur_dstop = DSTSRC;  /* replace (clear screen). */
+    IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
+            "ioctl failed", "WIOCRASTOP");
+    uPC_ur.ur_dstop = DSTOR;   /* Or in (show text) */
+}
+
+
+TERM_PUBLIC void
+uPC_text()
+{
+/* This routine will flush the display. */
+
+    IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
+            "ioctl failed", "WIOCRASTOP");
+}
+
+
+TERM_PUBLIC void
+uPC_linetype(int linetype)
+{
+/* This routine records the current linetype. */
+    if (uPC_cur_linetype != linetype) {
+       uPC_raster_count = 0;
+       uPC_cur_linetype = linetype;
+    }
+}
+
+
+TERM_PUBLIC void
+uPC_move(unsigned int x, unsigned int y)
+{
+/* This routine just records x and y in uPC_sx, uPC_sy */
+    uPC_sx = x;
+    uPC_sy = y;
+}
+
+
+/* Was just (*(a)|=(b)) */
+#define uPC_PLOT(a,b)   (uPC_cur_linetype != 0 ? uPC_plot_word (a,b) :\
+                                (*(a)|=(b)))
+
+/*
+   Weak attempt to make line styles.  The real problem is the aspect
+   ratio.  This routine is called only when a bit is to be turned on in
+   a horizontal word.  A better line style routine would know something
+   about the slope of the line around the current point (in order to
+   change weighting).
+
+   This yields 3 working linetypes plus a usable axis line type.
+*/
+void
+uPC_plot_word(Scr_type *a, Scr_type b)
+{
+    /* Various line types */
+    switch (uPC_cur_linetype) {
+    case LT_AXIS:
+       /* Distinguish between horizontal and vertical axis. */
+       if (uPC_sx > uPC_XMAX / 8 && uPC_sx < 7 * uPC_XMAX / 8) {
+           /* Fuzzy tolerance because we don't know exactly where the y axis is */
+           if (++uPC_raster_count % 2 == 0)
+               *(a) |= b;
+       } else {
+           /* Due to aspect ratio, take every other y pixel and every third x. */
+           *(a) |= (b & 0x9999);
+       }
+       break;
+    case 1:
+    case 5:
+       /* Make a |    |----|    |----| type of line. */
+       if ((1 << uPC_raster_count) & 0xF0F0)
+           *(a) |= b;
+       if (++uPC_raster_count > 15)
+           uPC_raster_count = 0;
+       break;
+    case 2:
+    case 6:
+       /* Make a |----|----|----|--- |    | type of line. */
+       if ((1 << uPC_raster_count) & 0x0EFFF)
+           *(a) |= b;
+       if (++uPC_raster_count > 19)
+           uPC_raster_count = 0;
+       break;
+    case 3:
+    case 7:
+       /* Make a | -  | -  | -  | -  | type of line. */
+       if ((1 << uPC_raster_count) & 0x4444)
+           *(a) |= b;
+       if (++uPC_raster_count > 15)
+           uPC_raster_count = 0;
+       break;
+    case 4:
+    case 8:
+    default:
+       *(a) |= b;
+       break;
+    }
+}
+
+TERM_PUBLIC void
+uPC_vector(unsigned int x, unsigned int y)
+{
+/* This routine calls line with x,y */
+    int x1 = uPC_sx, y1 = uPC_sy, x2 = x, y2 = y;
+    register int c, e, dx, dy, width;
+    register Scr_type mask, *a;
+
+/* Record new sx, sy for next call to the vector routine. */
+    uPC_sx = x2;
+    uPC_sy = y2;
+
+    a = &uPC_display[(uPC_YSIZE - 1) - y1][x1 >> 4];
+    mask = lookup[x1 & 0x0f];
+    width = uPC_width;
+
+    if ((dx = x2 - x1) > 0) {
+       if ((dy = y2 - y1) > 0) {
+           if (dx > dy) {      /* dx > 0, dy > 0, dx > dy */
+               dy <<= 1;
+               e = dy - dx;
+               c = dx + 2;
+               dx <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       (Scr_kluge *) a -= width;
+                       e -= dx;
+                   }
+                   if (mask & uPC_HIGH_BIT) {
+                       mask = 1;
+                       a++;
+                   } else
+                       mask <<= 1;
+                   e += dy;
+               }
+           } else {            /* dx > 0, dy > 0, dx <= dy */
+               dx <<= 1;
+               e = dx - dy;
+               c = dy + 2;
+               dy <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       if (mask & uPC_HIGH_BIT) {
+                           mask = 1;
+                           a++;
+                       } else
+                           mask <<= 1;
+                       e -= dy;
+                   }
+                   (Scr_kluge *) a -= width;
+                   e += dx;
+               }
+           }
+       } else {
+           dy = -dy;
+           if (dx > dy) {      /* dx > 0, dy <= 0, dx > dy */
+               dy <<= 1;
+               e = dy - dx;
+               c = dx + 2;
+               dx <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       (Scr_kluge *) a += width;
+                       e -= dx;
+                   }
+                   if (mask & uPC_HIGH_BIT) {
+                       mask = 1;
+                       a++;
+                   } else
+                       mask <<= 1;
+                   e += dy;
+               }
+           } else {            /* dx > 0, dy <= 0, dx <= dy */
+               dx <<= 1;
+               e = dx - dy;
+               c = dy + 2;
+               dy <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       if (mask & uPC_HIGH_BIT) {
+                           mask = 1;
+                           a++;
+                       } else
+                           mask <<= 1;
+                       e -= dy;
+                   }
+                   (Scr_kluge *) a += width;
+                   e += dx;
+               }
+           }
+       }
+    } else {
+       dx = -dx;
+       if ((dy = y2 - y1) > 0) {
+           if (dx > dy) {      /* dx <= 0, dy > 0, dx > dy */
+               dy <<= 1;
+               e = dy - dx;
+               c = dx + 2;
+               dx <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       (Scr_kluge *) a -= width;
+                       e -= dx;
+                   }
+                   if (mask & 1) {
+                       mask = uPC_HIGH_BIT;
+                       a--;
+                   } else
+                       mask >>= 1;
+                   e += dy;
+               }
+           } else {            /* dx <= 0, dy > 0, dx <= dy */
+               dx <<= 1;
+               e = dx - dy;
+               c = dy + 2;
+               dy <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       if (mask & 1) {
+                           mask = uPC_HIGH_BIT;
+                           a--;
+                       } else
+                           mask >>= 1;
+                       e -= dy;
+                   }
+                   (Scr_kluge *) a -= width;
+                   e += dx;
+               }
+           }
+       } else {
+           dy = -dy;
+           if (dx > dy) {      /* dx <= 0, dy <= 0, dx > dy */
+               dy <<= 1;
+               e = dy - dx;
+               c = dx + 2;
+               dx <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       (Scr_kluge *) a += width;
+                       e -= dx;
+                   }
+                   if (mask & 1) {
+                       mask = uPC_HIGH_BIT;
+                       a--;
+                   } else
+                       mask >>= 1;
+                   e += dy;
+               }
+           } else {            /* dx <= 0, dy <= 0, dx <= dy */
+               dx <<= 1;
+               e = dx - dy;
+               c = dy + 2;
+               dy <<= 1;
+
+               while (--c) {
+                   uPC_PLOT(a, mask);
+                   if (e >= 0) {
+                       if (mask & 1) {
+                           mask = uPC_HIGH_BIT;
+                           a--;
+                       } else
+                           mask >>= 1;
+                       e -= dy;
+                   }
+                   (Scr_kluge *) a += width;
+                   e += dx;
+               }
+           }
+       }
+    }
+}
+
+
+#ifdef uPC_NOT_USED
+
+/* Added by Russell Lang, eln272v@monu1.cc.monash.oz
+   This placement to the nearest character cell worked, and I'm leaving
+   it here so the calculations involved won't be lost!  (jdc)
+*/
+TERM_PUBLIC void
+uPC_put_text(unsigned int x, unsigned int y, const char str[])
+{
+    /* This routine puts the text at the cursor location nearest
+       to (x,y).  Obviously the exact postion would look better */
+
+    /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
+    printf("\033[%d;%dH%s\033[25;1H",
+          (int) (24 - (y - uPC_VCHAR / 2) * 25 / uPC_YMAX),
+          (int) (x * 80 / uPC_XMAX), str);
+    fflush(stdout);
+}
+
+#endif
+
+
+TERM_PUBLIC void
+uPC_put_text(unsigned int x, unsigned int y, const char str[])
+{
+    if (uPC_angle == 1)
+       x += uPC_VCHAR / 2;
+    else
+       y -= uPC_VCHAR / 2;
+
+    switch (uPC_angle) {
+    case 0:
+       for (; *str; ++str, x += uPC_HCHAR)
+           uPC_putc(x, y, *str, uPC_angle);
+       break;
+    case 1:
+       for (; *str; ++str, y += uPC_HCHAR)
+           uPC_putc(x, y, *str, uPC_angle);
+       break;
+    }
+}
+
+
+/*
+   Put a character at an x,y location in the bit map (using the fnt5x9
+   array.  This is mostly just copied from the bitmap.c driver.
+*/
+void
+uPC_putc(unsigned int x, unsigned int y, int c, int angle)
+{
+    int i, j, k;
+    register Scr_type mask, *a;
+    char_row fc;
+    unsigned int pixelon;
+
+    i = c - ' ';
+    for (j = 0; j < FNT5X9_VBITS; j++) {
+       fc = fnt5x9[i][j];
+       for (k = 0; k < FNT5X9_HBITS; k++) {
+           pixelon = ((unsigned int) (fc)) >> k & 1;
+           if (pixelon) {
+               switch (angle) {
+               case 0:
+                   mask = lookup[x + k + 1 & 0x0f];
+                   a = &uPC_display[(uPC_YSIZE - 1) - (y + j)][(x + k + 1) >> 4];
+                   break;
+               case 1:
+                   mask = lookup[x - j & 0x0f];
+                   a = &uPC_display[(uPC_YSIZE - 1) - (y + k + 1)][(x - j) >> 4];
+                   break;
+               }
+               *(a) |= (mask); /* see uPC_PLOT macro */
+           }
+       }
+    }
+}
+
+
+TERM_PUBLIC int
+uPC_text_angle(int ang)
+{
+    uPC_angle = (ang ? 1 : 0);
+    return TRUE;
+}
+
+
+TERM_PUBLIC void
+uPC_reset()
+{
+    /* Reset window to normal size. */
+    uPC_fixwind(0);
+}
+
+
+
+void
+uPC_fixwind(int signo)
+{
+    static struct uwdata wreset =
+    {0, 12, 720, 288, 0x1};
+    struct utdata ut;
+
+/* Reset the window to the right size. */
+    ioctl(1, WIOCSETD, &wreset);       /* 0, not wncur here! */
+
+/* Scroll the screen once. (avoids typing over the same line) */
+    putc('\n', stderr);
+
+    if (signo) {
+       if (signo == SIGILL || signo == SIGTRAP || signo == SIGPWR)
+           signal(signo, SIG_DFL);
+       kill(0, signo);         /* Redo the signal (as if we never trapped it). */
+    }
+}
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(unixpc_driver)
+    "unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
+    uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR,
+    uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset,
+    uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
+    uPC_linetype, uPC_put_text, uPC_text_angle,
+    null_justify_text, line_and_point, do_arrow, set_font_null
+TERM_TABLE_END(unixpc_driver)
+
+#undef LAST_TERM
+#define LAST_TERM unixpc_driver
+
+#endif /* TERM_TABLE */
+#endif /* TERM_PROTO_ONLY */
+
+#ifdef TERM_HELP
+START_HELP(unixpc)
+"1 unixpc",
+"?commands set terminal unixpc",
+"?set terminal unixpc",
+"?set term unixpc",
+"?terminal unixpc",
+"?term unixpc",
+"?unixpc",
+" The `unixpc` terminal driver supports AT&T 3b1 and AT&T 7300 Unix PC.  It has",
+" no options."
+END_HELP(unixpc)
+#endif /* TERM_HELP */