Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / dumb.trm
diff --git a/term/dumb.trm b/term/dumb.trm
new file mode 100644 (file)
index 0000000..6e7eeeb
--- /dev/null
@@ -0,0 +1,593 @@
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: dumb.trm,v 1.26.2.1 2008/08/16 18:11:53 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - dumb.trm */
+
+/*[
+ * Copyright 1991 - 1993, 1998, 2004   Thomas Williams, Colin Kelley
+ *
+ * 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:
+ *   DUMB terminals
+ *
+ * AUTHORS
+ *   Francois Pinard, 91-04-03
+ *           INTERNET: pinard@iro.umontreal.ca
+ *
+ *   Ethan A Merritt Nov 2003
+ *     Added support for enhanced text mode.
+ *     Yes, this is frivolous, but it serves as an example for
+ *     adding enhanced text to other terminals.  You can disable
+ *     it by adding a line
+ *     #define NO_DUMB_ENHANCED_SUPPORT
+ *
+ * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
+ *
+ */
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(dumb_driver)
+#endif
+
+#ifdef TERM_PROTO
+TERM_PUBLIC void DUMB_options __PROTO((void));
+TERM_PUBLIC void DUMB_init __PROTO((void));
+TERM_PUBLIC void DUMB_graphics __PROTO((void));
+TERM_PUBLIC void DUMB_text __PROTO((void));
+TERM_PUBLIC void DUMB_reset __PROTO((void));
+TERM_PUBLIC void DUMB_linetype __PROTO((int linetype));
+TERM_PUBLIC void DUMB_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void DUMB_point __PROTO((unsigned int x, unsigned int y,
+                                    int point));
+TERM_PUBLIC void DUMB_vector __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void DUMB_put_text __PROTO((unsigned int x, unsigned int y,
+                                       const char *str));
+TERM_PUBLIC void DUMB_arrow __PROTO((unsigned int sx, unsigned int sy,
+                                    unsigned int ex, unsigned int ey,
+                                    int head));
+
+#ifndef NO_DUMB_ENHANCED_SUPPORT
+/* To support "set term dumb enhanced" (don't ask why!) */
+TERM_PUBLIC void ENHdumb_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
+TERM_PUBLIC void ENHdumb_OPEN __PROTO((char * fontname, double fontsize,
+                                   double base, TBOOLEAN widthflag, TBOOLEAN showflag,
+                                   int overprint));
+TERM_PUBLIC void ENHdumb_FLUSH __PROTO((void));
+#else
+#define ENHdumb_put_text NULL
+#endif
+
+
+#define DUMB_XMAX 79
+#define DUMB_YMAX 24
+
+#endif /* TERM_PROTO */
+
+#ifdef TERM_BODY
+
+#define DUMB_AXIS_CONST '\1'
+#define DUMB_BORDER_CONST '\2'
+
+/* matrix of characters */
+static char *dumb_matrix = NULL;
+/* matrix of priority at each position */
+static char *dumb_priority = NULL;
+/* current character used to draw */
+static char dumb_pen;
+/* current X position */
+static int dumb_x;
+/* current Y position */
+static int dumb_y;
+static int dumb_xmax = DUMB_XMAX;
+static int dumb_ymax = DUMB_YMAX;
+static int dumb_feed = 1;
+
+#define DUMB_PIXEL(x,y) dumb_matrix[dumb_xmax*(y)+(x)]
+
+static void dumb_set_pixel __PROTO((int x, int y, int v, int p));
+
+enum DUMB_id { DUMB_FEED, DUMB_NOFEED, DUMB_ENH, DUMB_NOENH, DUMB_SIZE, DUMB_OTHER };
+
+static struct gen_table DUMB_opts[] =
+{
+    { "f$eed", DUMB_FEED },
+    { "nof$eed", DUMB_NOFEED },
+    { "enh$anced", DUMB_ENH },
+    { "noe$nhanced", DUMB_NOENH },
+    { "size", DUMB_SIZE },
+    { NULL, DUMB_OTHER }
+};
+
+TERM_PUBLIC void
+DUMB_options()
+{
+    int x, y;
+    struct value a;
+
+    while (!END_OF_COMMAND) {
+       switch(lookup_table(&DUMB_opts[0],c_token)) {
+       case DUMB_FEED:
+           c_token++;
+           dumb_feed = 1;
+           break;
+       case DUMB_NOFEED:
+           c_token++;
+           dumb_feed = 0;
+           break;
+#ifndef NO_DUMB_ENHANCED_SUPPORT
+       case DUMB_ENH:
+           c_token++;
+           term->put_text = ENHdumb_put_text;
+           term->flags |= TERM_ENHANCED_TEXT;
+           break;
+       case DUMB_NOENH:
+           c_token++;
+           term->put_text = DUMB_put_text;
+           term->flags &= ~TERM_ENHANCED_TEXT;
+           break;
+#endif
+       case DUMB_SIZE:
+           c_token++;
+           /* Fall through */
+
+       case DUMB_OTHER:
+       default:
+           x = (int) real(const_express(&a));
+           if (!END_OF_COMMAND) {
+               if (equals(c_token,","))
+                   c_token++;
+               y = (int) real(const_express(&a));
+               dumb_xmax = term->xmax = x;
+               dumb_ymax = term->ymax = y;
+           }
+           break;
+       }
+    }
+
+    sprintf(term_options, "%sfeed %s %d %d",
+           dumb_feed ? "" : "no",
+           term->put_text == ENHdumb_put_text ? "enhanced" : "",
+           dumb_xmax, dumb_ymax);
+}
+
+
+static void
+dumb_set_pixel(int x, int y, int v, int p)
+{
+    if ((unsigned) x <= dumb_xmax &&   /* ie x>=0 && x<=dumb_xmax */
+       (unsigned) y <= dumb_ymax &&
+       p > dumb_priority[dumb_xmax * y + x]) {
+       dumb_matrix[dumb_xmax * y + x] = v;
+       dumb_priority[dumb_xmax * y + x] = p;
+    }
+}
+
+
+TERM_PUBLIC void
+DUMB_init()
+{
+    if (dumb_matrix)
+       free(dumb_matrix);
+
+    dumb_matrix = gp_alloc((dumb_xmax+1) * (dumb_ymax+1) * 2, "dumb terminal");
+
+    dumb_priority = dumb_matrix + dumb_xmax * dumb_ymax;
+}
+
+
+TERM_PUBLIC void
+DUMB_graphics()
+{
+    int i;
+    char *pm = dumb_matrix, *pp = dumb_priority;
+
+    for (i = dumb_xmax * dumb_ymax; i > 0; i--) {
+       *pm++ = ' ';
+       *pp++ = 0;
+    }
+}
+
+
+TERM_PUBLIC void
+DUMB_text()
+{
+    int x, y, l;
+
+    putc('\f', gpoutfile);
+    for (y = dumb_ymax - 1; y >= 0; y--) {
+       for (l = dumb_xmax; l > 0 && DUMB_PIXEL(l - 1, y) == ' '; l--);
+       for (x = 0; x < l; x++)
+           putc(DUMB_PIXEL(x, y), gpoutfile);
+       if (dumb_feed || y > 0)
+           putc('\n', gpoutfile);
+    }
+    fflush(gpoutfile);
+}
+
+
+TERM_PUBLIC void
+DUMB_reset()
+{
+    if (dumb_matrix)
+       free(dumb_matrix);
+    dumb_matrix = NULL;
+}
+
+
+TERM_PUBLIC void
+DUMB_linetype(int linetype)
+{
+    static char pen_type[7] = { '*', '#', '$', '%', '@', '&', '=' };
+
+    if (linetype == LT_BLACK)
+       dumb_pen = DUMB_BORDER_CONST;
+    else if (linetype == LT_AXIS)
+       dumb_pen = DUMB_AXIS_CONST;
+    else if (linetype <= LT_NODRAW)
+       dumb_pen = ' ';
+    else {
+       linetype = linetype % 7;
+       dumb_pen = pen_type[linetype];
+    }
+}
+
+
+TERM_PUBLIC void
+DUMB_move(unsigned int x, unsigned int y)
+{
+    dumb_x = x;
+    dumb_y = y;
+}
+
+
+TERM_PUBLIC void
+DUMB_point(unsigned int x, unsigned int y, int point)
+{
+    dumb_set_pixel(x, y, point == -1 ? '.' : point % 26 + 'A', 4);
+}
+
+
+TERM_PUBLIC void
+DUMB_vector(unsigned int arg_x, unsigned int arg_y)
+{
+    int x = arg_x;             /* we need signed int, since
+                                * unsigned-signed=unsigned and */
+    int y = arg_y;             /* abs and cast to double wouldn't work */
+    char pen, pen1;
+    int priority;
+    int delta;
+
+    if (ABS(y - dumb_y) > ABS(x - dumb_x)) {
+       switch (dumb_pen) {
+       case DUMB_AXIS_CONST:
+           pen = ':';
+           pen1 = '+';
+           priority = 1;
+           break;
+
+       case DUMB_BORDER_CONST:
+           pen = '|';
+           pen1 = '+';
+           priority = 2;
+           break;
+
+       default:
+           pen = dumb_pen;
+           pen1 = dumb_pen;
+           priority = 3;
+           break;
+       }
+       dumb_set_pixel(dumb_x, dumb_y, pen1, priority);
+       for (delta = 1; delta < ABS(y - dumb_y); delta++) {
+           dumb_set_pixel(dumb_x  + (int) ((double) (x - dumb_x) *
+                                           delta / ABS(y - dumb_y) + 0.5),
+                          dumb_y + delta * sign(y - dumb_y), pen, priority);
+       }
+       dumb_set_pixel(x, y, pen1, priority);
+    } else if (ABS(x - dumb_x) > ABS(y - dumb_y)) {
+       switch (dumb_pen) {
+       case DUMB_AXIS_CONST:
+           pen = '.';
+           pen1 = '+';
+           priority = 1;
+           break;
+
+       case DUMB_BORDER_CONST:
+           pen = '-';
+           pen1 = '+';
+           priority = 2;
+           break;
+
+       default:
+           pen = dumb_pen;
+           pen1 = dumb_pen;
+           priority = 3;
+           break;
+       }
+       dumb_set_pixel(dumb_x, dumb_y, pen1, priority);
+       for (delta = 1; delta < ABS(x - dumb_x); delta++)
+           dumb_set_pixel(dumb_x + delta * sign(x - dumb_x),
+                          dumb_y +
+                          (int) ((double) (y - dumb_y) * delta / ABS(x - dumb_x)
+                                 + 0.5),
+                          pen, priority);
+       dumb_set_pixel(x, y, pen1, priority);
+    } else {
+       switch (dumb_pen) {
+       case DUMB_AXIS_CONST:   /* zero length axis */
+           pen = '+';
+           priority = 1;
+           break;
+
+       case DUMB_BORDER_CONST: /* zero length border */
+           pen = '+';
+           priority = 2;
+           break;
+
+       default:
+           pen = dumb_pen;
+           priority = 3;
+           break;
+       }
+       for (delta = 0; delta <= ABS(x - dumb_x); delta++)
+           dumb_set_pixel(dumb_x + delta * sign(x - dumb_x),
+                          dumb_y + delta * sign(y - dumb_y),
+                          pen, priority);
+    }
+    dumb_x = x;
+    dumb_y = y;
+}
+
+
+TERM_PUBLIC void
+DUMB_put_text(unsigned int x, unsigned int y, const char *str)
+{
+    int length;
+
+    length = strlen(str);
+    if (x + length > dumb_xmax)
+       x = GPMAX(0, dumb_xmax - length);
+
+    for (; x < dumb_xmax && *str; x++, str++)
+       dumb_set_pixel(x, y, *str, 5);
+}
+
+
+TERM_PUBLIC void
+DUMB_arrow(
+    unsigned int sx, unsigned int sy,
+    unsigned int ex, unsigned int ey,
+    int head)          /* ignored */
+{
+    char saved_pen;
+    char saved_x;
+    char saved_y;
+
+    (void) head;               /* dummy usage avoid compiler warnings */
+    saved_pen = dumb_pen;
+    saved_x = dumb_x;
+    saved_y = dumb_y;
+
+    dumb_pen = '>';
+    dumb_x = sx;
+    dumb_y = sy;
+    DUMB_vector(ex, ey);
+
+    dumb_pen = saved_pen;
+    dumb_x = saved_x;
+    dumb_y = saved_y;
+}
+
+
+#ifndef NO_DUMB_ENHANCED_SUPPORT
+/*
+ * The code from here on serves as an example of how to
+ * add enhanced text mode support to even a dumb driver.
+ */
+
+static TBOOLEAN ENHdumb_opened_string;
+static TBOOLEAN ENHdumb_show = TRUE;
+static int ENHdumb_overprint = 0;
+static TBOOLEAN ENHdumb_widthflag = TRUE;
+static unsigned int ENHdumb_xsave, ENHdumb_ysave;
+#define ENHdumb_fontsize 1
+#define ENHdumb_font ""
+static double ENHdumb_base;
+
+TERM_PUBLIC void
+ENHdumb_OPEN(
+    char *fontname,
+    double fontsize, double base,
+    TBOOLEAN widthflag, TBOOLEAN showflag,
+    int overprint)
+{
+    /* There are two special cases:
+     * overprint = 3 means save current position
+     * overprint = 4 means restore saved position
+     */
+    if (overprint == 3) {
+       ENHdumb_xsave = dumb_x;
+       ENHdumb_ysave = dumb_y;
+       return;
+    } else if (overprint == 4) {
+       DUMB_move(ENHdumb_xsave, ENHdumb_ysave);
+       return;
+    }
+
+
+    if (!ENHdumb_opened_string) {
+       ENHdumb_opened_string = TRUE;
+       /* Start new text fragment */
+           enhanced_cur_text = &enhanced_text[0];
+       /* Scale fractional font height to vertical units of display */
+           ENHdumb_base = base * 2;
+       /* Keep track of whether we are supposed to show this string */
+           ENHdumb_show = showflag;
+       /* 0/1/2  no overprint / 1st pass / 2nd pass */
+           ENHdumb_overprint = overprint;
+       /* widthflag FALSE means do not update text position after printing */
+           ENHdumb_widthflag = widthflag;
+       /* Many drivers will need to do something about font selection here */
+           /* but dumb is dumb */
+    }
+}
+
+TERM_PUBLIC void
+ENHdumb_FLUSH()
+{
+    char *str = enhanced_text; /* The fragment to print */
+    int x = dumb_x;            /* The current position  */
+    int len;
+
+    if (ENHdumb_opened_string) {
+       *enhanced_cur_text = '\0';
+       len = strlen(str);
+
+       /* print the string fragment, perhaps invisibly */
+       /* NB: base expresses offset from current y pos */
+       for (; x < dumb_xmax && *str; x++, str++)
+           if (ENHdumb_show)
+               dumb_set_pixel(x, dumb_y+ENHdumb_base, *str, 5);
+
+       if (!ENHdumb_widthflag)
+           /* don't update position */
+           ;
+       else if (ENHdumb_overprint == 1)
+           /* First pass of overprint, leave position in center of fragment */
+           dumb_x += len / 2;
+       else
+           /* Normal case is to update position to end of fragment */
+           dumb_x += len;
+
+       ENHdumb_opened_string = FALSE;
+    }
+}
+
+TERM_PUBLIC void
+ENHdumb_put_text(unsigned int x, unsigned int y, const char *str)
+{
+    /* If no enhanced text processing is needed, we can use the plain  */
+    /* vanilla put_text() routine instead of this fancy recursive one. */
+    if (ignore_enhanced_text || !strpbrk(str, "{}^_@&~")) {
+       DUMB_put_text(x,y,str);
+       return;
+    }
+
+    /* Set up global variables needed by enhanced_recursion() */
+    enhanced_fontscale = 1.0;
+    ENHdumb_opened_string = FALSE;
+    strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
+
+    DUMB_move(x,y);
+
+    /* Set the recursion going. We say to keep going until a
+     * closing brace, but we don't really expect to find one.
+     * If the return value is not the nul-terminator of the
+     * string, that can only mean that we did find an unmatched
+     * closing brace in the string. We increment past it (else
+     * we get stuck in an infinite loop) and try again.
+     */
+    while (*(str = enhanced_recursion((char *)str, TRUE,
+                       ENHdumb_font, ENHdumb_fontsize,
+                       0.0, TRUE, TRUE, 0))) {
+       (term->enhanced_flush)();
+
+       /* I think we can only get here if *str == '}' */
+           enh_err_check(str);
+
+       if (!*++str)
+           break; /* end of string */
+
+       /* else carry on and process the rest of the string */
+    }
+}
+#endif /* NO_DUMB_ENHANCED_SUPPORT */
+
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+TERM_TABLE_START(dumb_driver)
+    "dumb", "ascii art for anything that prints text",
+    DUMB_XMAX, DUMB_YMAX, 1, 1,
+    1, 1, DUMB_options, DUMB_init, DUMB_reset,
+    DUMB_text, null_scale, DUMB_graphics, DUMB_move, DUMB_vector,
+    DUMB_linetype, DUMB_put_text, null_text_angle,
+    null_justify_text, DUMB_point, DUMB_arrow, set_font_null,
+    0,                         /* pointsize */
+    TERM_CAN_MULTIPLOT,
+    NULL, NULL, NULL, NULL
+#ifdef USE_MOUSE
+    , NULL, NULL, NULL, NULL, NULL
+#endif
+    , NULL, NULL, NULL, NULL
+#ifdef WITH_IMAGE
+    , NULL
+#endif
+#ifndef NO_DUMB_ENHANCED_SUPPORT
+    , ENHdumb_OPEN, ENHdumb_FLUSH, do_enh_writec
+#endif /* NO_DUMB_ENHANCED_SUPPORT */
+TERM_TABLE_END(dumb_driver)
+
+#undef LAST_TERM
+#define LAST_TERM dumb_driver
+
+#endif /* TERM_TABLE */
+
+#ifdef TERM_HELP
+START_HELP(dumb)
+"1 dumb",
+"?commands set terminal dumb",
+"?set terminal dumb",
+"?set term dumb",
+"?terminal dumb",
+"?term dumb",
+"?dumb",
+" The `dumb` terminal driver has an optional size specification and trailing",
+" linefeed control.",
+"",
+" Syntax:",
+"       set terminal dumb {[no]feed} {<xsize> <ysize>}",
+#ifndef NO_DUMB_ENHANCED_SUPPORT
+"                         {[no]enhanced}",
+#endif
+"",
+" where <xsize> and <ysize> set the size of the dumb terminals. Default is",
+" 79 by 24. The last newline is printed only if `feed` is enabled.",
+"",
+" Examples:",
+"       set term dumb nofeed",
+"       set term dumb 79 49 # VGA screen---why would anyone do that?"
+END_HELP(dumb)
+#endif /* TERM_HELP */