Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / atariaes.trm
diff --git a/term/atariaes.trm b/term/atariaes.trm
new file mode 100644 (file)
index 0000000..a5dfb21
--- /dev/null
@@ -0,0 +1,787 @@
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: atariaes.trm,v 1.19 2006/07/21 02:35:45 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - atari.trm */
+
+/*[
+ * Copyright 1992, 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:
+ *   Atari Screens working with the normal VDI
+ *     (this should include TT and big screens)
+ *
+ * AUTHORS
+ *  Alexander Lehmann
+ *  HE Koechling
+ *
+ * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
+ *
+ * ATARI-related comments please to alexlehm@iti.informatik.th-darmstadt.de
+ *
+ */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(atari)
+#endif
+
+#ifdef TERM_PROTO
+
+/* function-prototypes */
+TERM_PUBLIC void ATARI_options __PROTO((void));
+TERM_PUBLIC void ATARI_init __PROTO((void));
+TERM_PUBLIC void ATARI_reset __PROTO((void));
+TERM_PUBLIC void ATARI_graphics __PROTO((void));
+TERM_PUBLIC void ATARI_text __PROTO((void));
+TERM_PUBLIC void ATARI_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void ATARI_vector __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void ATARI_linetype __PROTO((int lt));
+TERM_PUBLIC void ATARI_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
+TERM_PUBLIC int ATARI_text_angle __PROTO((int ang));
+TERM_PUBLIC int ATARI_justify_text __PROTO((enum JUSTIFY mode));
+TERM_PUBLIC void ATARI_point __PROTO((unsigned int x, unsigned int y, int number));
+
+/* default to hi-res */
+#define ATARI_XMAX 640
+#define ATARI_YMAX 400
+#define ATARI_VCHAR 16
+#define ATARI_HCHAR 8
+#define ATARI_HTIC (ATARI_XMAX/100)
+#define ATARI_VTIC ATARI_HTIC
+
+#endif /* TERM_PROTO */
+
+#ifndef TERM_PROTO_ONLY
+#ifdef TERM_BODY
+
+#ifdef __PUREC__
+/* why did they have to change these names ??? */
+# include <aes.h>
+# include <vdi.h>
+# include <tos.h>
+#else /* !__PUREC__ i.e. __GNUC__, maybe others */
+# include <aesbind.h>
+# include <vdibind.h>
+# include <osbind.h>
+extern short _global[];
+#endif
+
+#include <ctype.h>
+
+static void open_window __PROTO((void));
+static void close_window __PROTO((void));
+static void text_mode __PROTO((void));
+static void mouse_mode __PROTO((void));
+static void application_exit __PROTO((void));
+void application_init __PROTO((void));
+static int intersect __PROTO((int *x1, int *y1, int *w1, int *h1, int x2, int y2, int w2, int h2));
+static void walk_rects __PROTO((void (*draw) (int, int, int, int), int x1, int y1, int w1, int h1));
+static void clear __PROTO((int x, int y, int w, int h));
+static void process_message __PROTO((int *msg));
+long poll_events __PROTO((int waitkey));
+static void f_line __PROTO((int x, int y, int w, int h));
+static void flush_line __PROTO((void));
+static void put_text __PROTO((int x, int y, int w, int h));
+
+static int multi_aes;
+static int window_id = -1;
+static int vdi_handle = -1;
+static int win_xpos, win_ypos;
+static int win_xsize, win_ysize;
+
+#define ATARI_yc(y) (ATARI_maxycoord-(y))
+static int ATARI_linetypes[] =
+{
+    0xffff, 0x1111,
+    0xffff, 0x5555, 0x3333, 0x7777,
+    0x3f3f, 0x0f0f, 0x5f5f, 0xe4e4, 0x55f5
+};
+
+#define ATARI_LINETYPES_MAX     (sizeof(ATARI_linetypes)/sizeof(int))
+
+static int ATARI_lt;
+static int ATARI_maxycoord;
+static int ATARI_rotation;
+static int ATARI_numcolors;
+static int pxy[128];           /* Maximum of 64 pixels per v_pline */
+static int pxy_index;
+static int ATARI_colors[16];
+static int ATARI_savecolors[16][3];
+static int ATARI_numpalette;
+
+#define ATARI_c_height_default 6       /* well, well ...               */
+
+static int ATARI_c_height = ATARI_c_height_default;
+
+static int cursor_is_on = FALSE;
+static int put_text_x;
+static int put_text_y;
+static char *put_text_str;
+
+/* don't change this without changing process_message() below */
+#define WINTYPE (NAME|CLOSER|FULLER|MOVER|SIZER)
+
+static void
+open_window()
+{
+    int x, y, w, h;
+
+    if (window_id == -1) {
+       wind_calc(WC_BORDER, WINTYPE, win_xpos, win_ypos,
+                 win_xsize, win_ysize, &x, &y, &w, &h);
+       window_id = wind_create(WINTYPE, x, y, w, h);
+
+       if (window_id < 0) {
+           window_id = -1;
+           int_error(NO_CARET, "Can't create window");
+       }
+       wind_set(window_id, WF_NAME, "gnuplot output");
+       wind_open(window_id, x, y, w, h);
+    }
+}
+
+static void
+close_window()
+{
+    if (window_id != -1) {
+       wind_close(window_id);
+       wind_delete(window_id);
+       window_id = -1;
+    }
+}
+
+static void
+text_mode()
+{
+    if (!multi_aes) {
+       if (!cursor_is_on) {
+           cursor_is_on = TRUE;
+           graf_mouse(M_OFF, NULL);
+           fputs("\033e", stderr);
+       }
+       fputs("\033E", stderr);
+    }
+}
+
+static void
+mouse_mode()
+{
+    if (!multi_aes) {
+       if (cursor_is_on) {
+           cursor_is_on = FALSE;
+           graf_mouse(M_ON, NULL);
+           fputs("\033f", stderr);
+       }
+    }
+}
+
+static void
+application_exit()
+{
+    close_window();
+
+    if (vdi_handle != -1) {
+       v_clsvwk(vdi_handle);
+    }
+    mouse_mode();
+}
+
+void
+application_init()
+{
+    if (aesid < 0) {
+       if ((aesid = appl_init()) < 0)
+           int_error(NO_CARET, "APPL_INIT failed !");
+    }
+#ifdef __PUREC__
+    multi_aes = _GemParBlk.global[1] == -1;
+#else
+    /* tested with gcc only */
+    multi_aes = _global[1] == -1;
+#endif
+
+    if (!multi_aes)
+       graf_mouse(ARROW, NULL);
+    else
+       menu_register(aesid, "  Terminal: atari");
+
+    text_mode();
+    atexit(application_exit);
+}
+
+static int
+intersect(int *x1, int *y1, int *w1, int *h1, int x2, int y2, int w2, int h2)
+{
+    if (*x1 > x2) {
+       w2 -= *x1 - x2;
+       x2 = *x1;
+    } else {
+       (*w1) -= x2 - *x1;
+       *x1 = x2;
+    }
+    if (*y1 > y2) {
+       h2 -= *y1 - y2;
+       y2 = *y1;
+    } else {
+       (*h1) -= y2 - *y1;
+       *y1 = y2;
+    }
+    if (*w1 > w2) {
+       *w1 = w2;
+    } else {
+       w2 = *w1;
+    }
+    if (*h1 > h2) {
+       *h1 = h2;
+    } else {
+       h2 = *h1;
+    }
+
+    return (*w1) > 0 && (*h1) > 0;
+}
+
+static void
+walk_rects(void (*draw) (int, int, int, int), int x1, int y1, int w1, int h1)
+{
+    int x, y, w, h;
+    int pxy[4];
+
+    wind_update(BEG_UPDATE);
+    graf_mouse(M_OFF, NULL);
+
+    wind_get(window_id, WF_FIRSTXYWH, &x, &y, &w, &h);
+    while (w > 0 && h > 0) {
+       if (intersect(&x, &y, &w, &h, x1, y1, w1, h1)) {
+           pxy[0] = x;
+           pxy[1] = y;
+           pxy[2] = x + w - 1;
+           pxy[3] = y + h - 1;
+           vs_clip(vdi_handle, 1, pxy);
+           (*draw) (x, y, w, h);
+       }
+       wind_get(window_id, WF_NEXTXYWH, &x, &y, &w, &h);
+    }
+    vs_clip(vdi_handle, 0, pxy);
+    graf_mouse(M_ON, NULL);
+    wind_update(END_UPDATE);
+}
+
+static void
+clear(int x, int y, int w, int h)
+{
+    static MFDB mfdb = { NULL };
+    int pxy[8];
+
+    pxy[0] = pxy[4] = x;
+    pxy[1] = pxy[5] = y;
+    pxy[2] = pxy[6] = x + w - 1;
+    pxy[3] = pxy[7] = y + h - 1;
+
+    vro_cpyfm(vdi_handle, ALL_WHITE /*0 */ , pxy, &mfdb, &mfdb);
+}
+
+static void
+process_message(int *msg)
+{
+    static int is_fulled = FALSE;
+    static int small_xpos, small_ypos, small_xsize, small_ysize;
+    int x, y, w, h;
+
+    if (window_id == -1 || msg[3] != window_id)
+       return;
+
+    switch (msg[0]) {
+    case WM_REDRAW:
+       walk_rects(clear, msg[4], msg[5], msg[6], msg[7]);
+       break;
+
+    case WM_CLOSED:
+       close_window();
+       break;
+
+    case WM_TOPPED:
+       wind_set(window_id, WF_TOP, window_id);
+       break;
+
+    case WM_MOVED:
+    case WM_SIZED:
+       is_fulled = 0;
+       wind_calc(WC_WORK, WINTYPE, msg[4], msg[5], msg[6], msg[7],
+                 &win_xpos, &win_ypos, &win_xsize, &win_ysize);
+       wind_set(window_id, WF_CURRXYWH, msg[4], msg[5], msg[6], msg[7]);
+       break;
+
+    case WM_FULLED:
+       if (!is_fulled) {
+           is_fulled = TRUE;
+           small_xpos = win_xpos;
+           small_ypos = win_ypos;
+           small_xsize = win_xsize;
+           small_ysize = win_ysize;
+
+           wind_get(0, WF_WORKXYWH, &x, &y, &w, &h);
+           wind_calc(WC_WORK, WINTYPE, x, y, w, h, &win_xpos, &win_ypos,
+                     &win_xsize, &win_ysize);
+       } else {
+           is_fulled = FALSE;
+           win_xpos = small_xpos;
+           win_ypos = small_ypos;
+           win_xsize = small_xsize;
+           win_ysize = small_ysize;
+       }
+       wind_calc(WC_BORDER, WINTYPE, win_xpos, win_ypos, win_xsize,
+                 win_ysize, &x, &y, &w, &h);
+       wind_set(window_id, WF_CURRXYWH, x, y, w, h);
+       break;
+    }
+}
+
+long
+poll_events(int waitkey)
+{
+    int msg[8];
+    int dummy;
+    int which;
+    int key = 0;
+    /* 1/10th second when waiting for key, poll otherwise */
+    unsigned long time = (waitkey ? 100L : 1L);
+
+    do {
+       which = evnt_multi(
+                             (waitkey ? (MU_MESAG | MU_KEYBD | MU_TIMER) : (MU_MESAG | MU_TIMER)),
+                             0, 0, 0,
+                             0, 0, 0, 0, 0,
+                             0, 0, 0, 0, 0,
+                             msg,
+#ifdef __PUREC__
+                             time, 0,
+#else
+                             time,
+#endif
+                             &dummy, &dummy, &dummy, &dummy, &key, &dummy);
+
+       if (which & MU_MESAG) {
+           process_message(msg);
+       }
+    } while (which & MU_MESAG);
+
+    if (which & MU_KEYBD) {
+       return ((Kbshift(-1) & 7) << 24) | ((long) (key & 0xff00) << 8) | (key & 0xff);
+    } else {
+       return 0;
+    }
+}
+
+static void
+f_line(int x, int y, int w, int h)
+{
+    v_pline(vdi_handle, pxy_index, pxy);
+}
+
+static void
+flush_line()
+{
+    int line_type;
+    int color_index;
+    int i;
+
+    if (pxy_index >= 2) {
+       if (ATARI_numcolors == 2) {     /* Monochrome */
+           color_index = 1;
+           line_type = ATARI_lt;
+           if (line_type >= 0)
+               line_type %= (ATARI_LINETYPES_MAX - 2);
+       } else {                /* Color */
+           if (ATARI_lt < 0) {
+               color_index = 1;
+               line_type = ATARI_lt;
+           } else {
+               color_index = 2 + ATARI_lt % (ATARI_numcolors - 2);
+               line_type = (ATARI_lt / (ATARI_numcolors - 2)) % (ATARI_LINETYPES_MAX - 2);
+           }
+       }
+
+       vswr_mode(vdi_handle, MD_TRANS);
+       vsl_color(vdi_handle, color_index);
+
+       vsl_type(vdi_handle, 7);
+       vsl_udsty(vdi_handle, ATARI_linetypes[line_type + 2]);
+       walk_rects(f_line, win_xpos, win_ypos, win_xsize, win_ysize);
+    }
+    if (pxy_index >= 1) {
+       pxy[0] = pxy[2 * (pxy_index - 1)];
+       pxy[1] = pxy[2 * (pxy_index - 1) + 1];
+       pxy_index = 1;
+    }
+}
+
+static void
+put_text(int x, int y, int w, int h)
+{
+    v_gtext(vdi_handle, put_text_x, put_text_y, put_text_str);
+}
+
+TERM_PUBLIC void
+ATARI_options()
+{
+#define ATARIHEXERROR "palette values 3 hex digits, please"
+#define ATARIHEIGHTERROR "expecting a character height"
+    char opt[6];               /* maximum: 'fff'\0 */
+    int i;
+    char *tok_end;
+
+    term_options[0] = NUL;
+    ATARI_c_height = ATARI_c_height_default;
+
+    for (i = 0; i < 17; i++) {
+       if (END_OF_COMMAND)
+           break;
+       if (token[c_token].length > 5) {
+           ATARI_numpalette = 0;
+           ATARI_c_height = ATARI_c_height_default;
+           term_options[0] = NUL;
+           int_error(c_token, ATARIHEXERROR);
+       }
+       capture(opt, c_token, c_token, 6);
+       if (!i) {
+           ATARI_c_height = strtoul(opt, &tok_end, 10);
+           if (*tok_end != NUL) {
+               ATARI_numpalette = 0;
+               ATARI_c_height = ATARI_c_height_default;
+               term_options[0] = NUL;
+               int_error(c_token, ATARIHEIGHTERROR);
+           }
+           if (ATARI_c_height > 999)
+               ATARI_c_height = 999;   /* avoid opt length overflow */
+           sprintf(opt, "%d ", ATARI_c_height);
+       } else {
+           if (*opt == '"' || *opt == '\'') {
+               opt[strlen(opt) - 1] = NUL;
+               strcpy(opt, opt + 1);
+           }
+           ATARI_colors[i - 1] = strtoul(opt, &tok_end, 16);
+           if (*tok_end != NUL) {
+               ATARI_numpalette = 0;
+               ATARI_c_height = ATARI_c_height_default;
+               term_options[0] = NUL;
+               int_error(c_token, ATARIHEXERROR);
+           }
+           sprintf(opt, "%X ", ATARI_colors[i - 1]);
+
+           /* do we need to quote? */
+           if (isdigit((unsigned char) *opt) && strpbrk(opt, "ABCDEF")) {
+               sprintf(opt, "\"%X\" ", ATARI_colors[i - 1]);
+           }
+       }
+       strcat(term_options, opt);
+       c_token++;
+    }
+    ATARI_numpalette = (i == 0 ? 0 : i - 1);
+    /* printf("Number of linetypes:%d\n", ATARI_LINETYPES_MAX); */
+}
+
+TERM_PUBLIC void
+ATARI_init()
+{
+    int work_in[11];
+    int work_out[57];
+    int i;
+    int hchar, wchar, dummy;
+    int rgb[3];
+    int num_save;
+    char *colors, *tok_end;
+    int x, y, w, h;
+    static int have_win_size = 0;
+
+    application_init();
+
+    if (ATARI_numpalette == 0 && (colors = getenv("GNUCOLORS")) && *colors) {
+       for (i = 0; i < 17; i++) {
+           if (!i) {
+               ATARI_c_height = strtoul(colors, &tok_end, 10);
+               if (colors == tok_end) {
+                   i = 0;
+                   ATARI_c_height = ATARI_c_height_default;
+                   break;
+               }
+           } else {
+               if (*colors == '\0')
+                   break;
+               ATARI_colors[i] = strtoul(colors, &tok_end, 16);
+               if (colors == tok_end || (unsigned) ATARI_colors[i] > 0xfff) {
+                   i = 0;
+                   break;
+               }
+           }
+           colors = tok_end;
+
+           while (*colors == ' ')
+               colors++;
+       }
+       ATARI_numpalette = (i == 0 ? 0 : i - 1);
+    }
+    vdi_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
+
+    if (!vdi_handle)
+       int_error(NO_CARET, "Fatal error opening virtual workstation");
+
+    for (i = 0; i < 10; work_in[i++] = 1);
+    work_in[10] = 2;           /* use raster coordinates */
+    v_opnvwk(work_in, &vdi_handle, work_out);
+
+    if (!vdi_handle)
+       int_error(NO_CARET, "Fatal error opening virtual workstation");
+
+    if (!have_win_size) {
+       wind_get(0, WF_WORKXYWH, &x, &y, &w, &h);
+       wind_calc(WC_WORK, WINTYPE, x, y, w, h, &win_xpos, &win_ypos,
+                 &win_xsize, &win_ysize);
+       have_win_size = 1;
+    }
+    term->xmax = win_xsize;
+    term->ymax = win_ysize;
+
+    vst_height(vdi_handle, ATARI_c_height, &dummy, &dummy, &wchar, &hchar);
+
+    term->h_char = wchar;
+    term->v_char = hchar;      /* hchar stands for height this time */
+    term->h_tic = win_xsize / 100;
+    term->v_tic = term->h_tic;
+
+    ATARI_maxycoord = win_ysize - 1;
+    ATARI_numcolors = work_out[13];
+
+    for (i = 0; i < ATARI_numpalette; i++) {
+       vq_color(vdi_handle, i, 1, ATARI_savecolors[i]);
+
+       rgb[0] = 1000 * (ATARI_colors[i] >> 8);
+       rgb[0] /= 15;
+       rgb[1] = 1000 * ((ATARI_colors[i] >> 4) & 15);
+       rgb[1] /= 15;
+       rgb[2] = 1000 * (ATARI_colors[i] & 15);
+       rgb[2] /= 15;
+       vs_color(vdi_handle, i, rgb);
+    }
+    pxy_index = 0;
+}
+
+TERM_PUBLIC void
+ATARI_reset()
+{
+    int i;
+
+    close_window();
+    if (vdi_handle != -1) {
+       for (i = 0; i < ATARI_numpalette; i++) {
+           vs_color(vdi_handle, i, ATARI_savecolors[i]);
+       }
+       v_clsvwk(vdi_handle);
+       vdi_handle = -1;
+    }
+}
+
+TERM_PUBLIC void
+ATARI_graphics()
+{
+    ATARI_maxycoord = win_ysize - 1;
+
+    term->xmax = win_xsize;
+    term->ymax = win_ysize;
+
+    mouse_mode();
+    open_window();
+    poll_events(0);
+    walk_rects(clear, win_xpos, win_ypos, win_xsize, win_ysize);
+
+    pxy_index = 0;
+}
+
+TERM_PUBLIC void
+ATARI_text()
+{
+    flush_line();
+    if (!multi_aes) {
+       while (window_id != -1 && !poll_events(1));
+       close_window();
+    }
+    text_mode();
+}
+
+TERM_PUBLIC void
+ATARI_move(unsigned int x, unsigned int y)
+{
+    flush_line();
+
+    pxy[0] = x + win_xpos;
+    pxy[1] = ATARI_yc(y) + win_ypos;
+    pxy_index = 1;
+}
+
+TERM_PUBLIC void
+ATARI_vector(unsigned int x, unsigned int y)
+{
+    pxy[2 * pxy_index] = x + win_xpos;
+    pxy[2 * pxy_index + 1] = ATARI_yc(y) + win_ypos;
+    pxy_index++;
+
+    if (pxy_index == 64) {     /* we're all full */
+       flush_line();
+    }
+}
+
+TERM_PUBLIC void
+ATARI_linetype(int lt)
+{
+    flush_line();
+
+    ATARI_lt = lt;
+}
+
+TERM_PUBLIC void
+ATARI_put_text(unsigned int x, unsigned int y, const char *str)
+{
+    int vchar = term->v_char;
+    int dummy;
+
+    if (!strlen(str))
+       return;
+
+    if (x < 0)
+       x = 0;
+    if (y < 0)
+       y = 0;
+
+    /* align text left and to middle of char height */
+    vst_alignment(vdi_handle, 0, 5, &dummy, &dummy);
+    vst_rotation(vdi_handle, (ATARI_rotation ? 900 : 0));
+    if (ATARI_rotation) {
+       put_text_x = x - vchar / 2 + 1 + win_xpos;
+       put_text_y = ATARI_yc(y) - 1 + win_ypos;
+       put_text_str = str;
+    } else {
+       put_text_x = x + 1 + win_xpos;
+       put_text_y = ATARI_yc(y) - vchar / 2 + 1 + win_ypos;
+       put_text_str = str;
+    }
+    walk_rects(put_text, win_xpos, win_ypos, win_xsize, win_ysize);
+}
+
+TERM_PUBLIC int
+ATARI_text_angle(int ang)
+{
+    ATARI_rotation = ang;
+
+    return TRUE;
+}
+
+TERM_PUBLIC int
+ATARI_justify_text(enum JUSTIFY mode)
+{
+    return FALSE;
+}
+
+TERM_PUBLIC void
+ATARI_point(unsigned int x, unsigned int y, int number)
+{
+    int old_linetype;
+
+    if (ATARI_numcolors == 2) {
+       line_and_point(x, y, number);   /* monochrome */
+    } else {
+       /* we map colors that exceed our limit to dotted lines, but we can't do
+          that with the markers (sortof a generalized line_and_point) */
+       old_linetype = ATARI_lt;
+       if (ATARI_lt > ATARI_numcolors - 2)
+           ATARI_linetype(ATARI_lt % (ATARI_numcolors - 2));   /* same color, but no dots */
+       do_point(x, y, number);
+       ATARI_linetype(old_linetype);
+    }
+}
+
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(atari_driver)
+    "atari", "Atari AES-Terminal",
+    ATARI_XMAX, ATARI_YMAX, ATARI_VCHAR, ATARI_HCHAR,
+    ATARI_VTIC, ATARI_HTIC, ATARI_options, ATARI_init, ATARI_reset,
+    ATARI_text, null_scale, ATARI_graphics, ATARI_move, ATARI_vector,
+    ATARI_linetype, ATARI_put_text, ATARI_text_angle,
+    ATARI_justify_text, ATARI_point, do_arrow, set_font_null,
+    0, TERM_CAN_MULTIPLOT, 0, 0
+TERM_TABLE_END(atari_driver)
+
+#undef LAST_TERM
+#define LAST_TERM atari_driver
+
+#endif /* TERM_TABLE */
+
+#endif /* TERM_PROTO_ONLY */
+
+#ifdef TERM_HELP
+START_HELP(atari)
+"1 atari ST (via AES)",
+"?commands set terminal atari",
+"?set terminal atari",
+"?set term atari",
+"?terminal atari",
+"?term atari",
+"?atari",
+" The `atari` terminal has options to set the character size and the screen",
+" colors.",
+"",
+" Syntax:",
+"       set terminal atari {<fontsize>} {<col0> <col1> ... <col15>}",
+"",
+" The character size must appear if any colors are to be specified.  Each of",
+" the (up to 16) colors is given as a three-digit hex number, where the digits",
+" represent RED, GREEN and BLUE (in that order).  The range of 0--15 is scaled",
+" to whatever color range the screen actually has.  On a normal ST screen, odd",
+" and even intensities are the same.",
+"",
+" Examples:",
+"       set terminal atari 4    # use small (6x6) font",
+"       set terminal atari 6 0  # set monochrome screen to white on black",
+"       set terminal atari 13 0 fff f00 f0 f ff f0f",
+"                  # set first seven colors to black, white, red, green,",
+"                  # blue, cyan, and purple and use large font (8x16).",
+"",
+" Additionally, if an environment variable GNUCOLORS exists, its contents are",
+" interpreted as an options string, but an explicit terminal option takes",
+" precedence."
+END_HELP(atari)
+#endif /* TERM_HELP */