Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / amiga.trm
diff --git a/term/amiga.trm b/term/amiga.trm
new file mode 100644 (file)
index 0000000..5b77306
--- /dev/null
@@ -0,0 +1,832 @@
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: amiga.trm,v 1.20 2006/07/21 02:35:45 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - amiga.trm */
+
+/*[
+ * Copyright 1991, 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:
+ *   Amiga Custom Screen
+ *
+ * AUTHORS
+ *   Carsten Steger
+ *
+ *   Pat R. Empleo      Slightly modified for Aztec C v5.2a (beta); sort of
+ *   08/27/91           supports overscan; for large WB 2.0 virtual screens,
+ *                      we limit the plot size so we don't have to scroll
+ *                      around (not fun).
+ *
+ *   Carsten Steger     Modified to support Kickstart 2.0.
+ *   09/11/91           Opens a text overscan screen when used with WB 2.0.
+ *                      Discerns between NTSC and PAL Amigas when used with
+ *                      WB 1.3 and lower.
+ *
+ *   Pat R. Empleo      Defined some 2.0 stuff in order to get Aztec C to
+ *   09/20/91           work with Carsten's new code (see above).  When
+ *                      KS/WB 2.0 support gets implemented in Aztec C, this
+ *                      kludge will get deleted!
+ *                      (Aztec C release 5.2 beta)
+ *
+ *   Carsten Steger     Converted to new terminal layout.
+ *   10/01/95
+ *
+ *   Lars Hecking       Add code from George Coulouris <glc5@cornell.edu> to
+ *   06/20/97           implement window option, requires AmigaOS 3.0+.
+ *                      General cleanup, better readability.
+ *
+ *   Lars Hecking       Replace static arrays for AMIGA_FontName and temporary
+ *   06/21/97           arrays with AllocMem()'d memory.
+ *
+ * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
+ *
+ */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(amiga)
+#endif
+
+#ifdef TERM_PROTO
+
+#define AMIGA_XMAX 640
+#define AMIGA_YMAX 512
+
+#define AMIGA_VCHAR 12
+#define AMIGA_HCHAR 8
+#define AMIGA_VTIC  5
+#define AMIGA_HTIC  5
+
+TERM_PUBLIC void AMIGA_reset __PROTO((void));
+TERM_PUBLIC void AMIGA_init __PROTO((void));
+TERM_PUBLIC void AMIGA_options __PROTO((void));
+TERM_PUBLIC void AMIGA_text __PROTO((void));
+TERM_PUBLIC void AMIGA_graphics __PROTO((void));
+TERM_PUBLIC void AMIGA_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void AMIGA_vector __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void AMIGA_linetype __PROTO((int linetype));
+TERM_PUBLIC void AMIGA_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
+TERM_PUBLIC int AMIGA_justify_text __PROTO((enum JUSTIFY mode));
+TERM_PUBLIC int AMIGA_set_font __PROTO((const char *font));
+TERM_PUBLIC void AMIGA_suspend __PROTO((void));
+TERM_PUBLIC void AMIGA_resume __PROTO((void));
+
+#define GOT_AMIGA_PROTO
+
+#endif /* TERM_PROTO */
+
+
+#ifndef TERM_PROTO_ONLY
+#ifdef TERM_BODY
+
+#ifdef AMIGA_AC_5
+#include <intuition/intuitionbase.h>
+#include <intuition/screens.h>
+#include <graphics/text.h>
+#include <graphics/gfxbase.h>
+#else
+/* You will have to use the Kickstart 2.0 header files for this to compile */
+#include <exec/types.h>
+#include <dos/dos.h>
+#include <intuition/intuitionbase.h>
+#include <graphics/gfxbase.h>
+#include <proto/intuition.h>
+#include <proto/graphics.h>
+#include <proto/exec.h>
+#include <proto/diskfont.h>
+#endif /* !AMIGA_AC_5 */
+
+#ifdef HAVE_ATEXIT
+void AMIGA_exit(void);
+# define ATEXIT(x) (atexit(x) != 0)
+# ifdef AMIGA_SC_6_1
+/* #  define ATEXIT(x) (onexit(x) == 0) */
+#  define RAWCON(x) rawcon(x)
+# else
+#  define RAWCON(x)            /* nought */
+# endif                                /* SAS */
+#else
+# define ATEXIT(x) 0
+#endif /* HAVE_ATEXIT */
+
+#ifndef RETURN_FAIL
+# define RETURN_FAIL 20
+#endif
+
+#define LIB_VERSION(LibBase)    ((LibBase)->LibNode.lib_Version)
+
+#define AMIGA_ERROR(string,rc)  {fprintf (stderr,"%s\n",string);\
+                                AMIGA_reset (); exit (rc);}
+
+/* from plot.c */
+extern TBOOLEAN interactive;
+
+/* The origin is in the upper left hand corner, so we have to translate */
+/* and flip the coordinates: */
+#define AMIGA_VTF(y) (AMIGA_ymax-1-(y))
+
+
+/* Libraries */
+struct IntuitionBase *IntuitionBase;
+struct GfxBase *GfxBase;
+struct Library *DiskfontBase;
+
+
+/* Name of font, size in pts */
+static char *AMIGA_FontName = NULL;
+static int AMIGA_FontNameLen = 0;
+static int AMIGA_FontSize = 8;
+static char AMIGA_default_font[MAX_ID_LEN+1] = {'\0'};
+#define AMIGA_DEFAULTFONT "topaz"
+
+/* Font stuff */
+static struct TextAttr AMIGA_Font =
+{
+    "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT
+};
+static struct TextFont *AMIGA_TextFont;
+
+
+/* Screen stuff */
+static struct NewScreen AMIGA_NewScreen =
+{
+    0, 0, AMIGA_XMAX, AMIGA_YMAX, 4, 15, 0, HIRES | LACE,
+    CUSTOMSCREEN | SCREENBEHIND | SCREENQUIET, NULL, NULL, NULL, NULL
+};
+static struct Screen *AMIGA_Screen;
+static struct TagItem AMIGA_ScrTagList[] =
+{
+    { SA_Overscan, OSCAN_TEXT },
+    { TAG_DONE, 0 }
+};
+
+
+/* Window stuff */
+/* FALSE: plot to screen; TRUE: plot to window */
+static TBOOLEAN AMIGA_window_mode = FALSE;
+
+#define AMIGA_WIN_XMAX 512
+#define AMIGA_WIN_YMAX 320
+
+static struct Window *AMIGA_Window;
+static struct TagItem AMIGA_WinTagList[] =
+{
+    { WA_InnerWidth, AMIGA_WIN_XMAX },
+    { WA_InnerHeight, AMIGA_WIN_YMAX },
+    { WA_Title, (ULONG) "gnuplot" },
+    { WA_DragBar, TRUE },
+    { WA_DepthGadget, TRUE },
+    { WA_WBenchWindow, TRUE },
+    { WA_SmartRefresh, TRUE },
+    { WA_GimmeZeroZero, TRUE },
+    { WA_AutoAdjust, TRUE },
+    { TAG_DONE, 0 }
+};
+
+/*
+ * This  is the palette.  Values are stored as 0xrrggbb, where rr, gg, and, bb
+ * are big-endian 8-bit intensities for red, green, and blue, respectively.
+ */
+static unsigned int palette[] =
+{
+    0xffffff,                  /* white */
+    0x000000,                  /* black */
+    0xff0000,                  /* red */
+    0x00ff00,                  /* green */
+    0x0000ff,                  /* blue */
+    0x00ffff,                  /* cyan */
+    0xff00ff,                  /* magenta */
+    0xffff00,                  /* yellow */
+    0x7f007f,                  /* purple */
+    0xff7f00,                  /* orange */
+};
+
+#define PALETTE_SIZE (sizeof (palette) / sizeof (unsigned int))
+
+/* This is the color look-up table, indexed in the same order as
+ * the above palette. The values stored in this table are pen numbers;
+ * e.g clut[2] is the pen which represents the color "red".
+ */
+static unsigned int clut[PALETTE_SIZE];
+
+
+/* Colors */
+static UWORD AMIGA_Colors[] =
+{
+    0x000, 0xfff, 0xbbb, 0x0f0, 0xf00, 0x00f, 0x3ca, 0xf0f,
+    0x94d, 0x0ff, 0x82f, 0xff0, 0x0af, 0xc5e, 0xfa2, 0xf44
+};
+
+
+/* Misc */
+static int AMIGA_slinetype;
+static enum JUSTIFY AMIGA_justify = LEFT;
+static unsigned int AMIGA_ymax, AMIGA_xmax;
+static WORD AMIGA_cwd, AMIGA_cht, AMIGA_bsl, AMIGA_vadj;
+/* Common RastPort */
+static struct RastPort *AMIGA_RastPort;
+
+
+enum AMIGA_id { AMI_SCREEN, AMI_WINDOW, AMI_OTHER };
+
+static struct gen_table AMIGA_opts[] =
+{
+    {"scr$een", AMI_SCREEN },
+    {"win$dow", AMI_WINDOW },
+    { NULL, AMI_OTHER }
+};
+
+
+/*
+ * Scan terminal options
+ */
+TERM_PUBLIC void
+AMIGA_options()
+{
+
+    while (!END_OF_COMMAND) {
+       switch(lookup_table(&AMIGA_opts[0],c_token)) {
+       case AMI_SCREEN:
+           AMIGA_window_mode = FALSE;
+           c_token++;
+           break;
+       case AMI_WINDOW:
+           AMIGA_window_mode = TRUE;
+           c_token++;
+           break;
+       case AMI_OTHER:
+       default:
+           /* Font name */
+           if (isstring(c_token)) {
+               if (AMIGA_FontName != NULL) {
+                   FreeMem(AMIGA_FontName,AMIGA_FontNameLen);
+                   AMIGA_FontName = NULL;
+                   AMIGA_FontNameLen = 0;
+               }
+
+               AMIGA_FontNameLen = token_len(c_token);
+
+               AMIGA_FontName = AllocMem(AMIGA_FontNameLen,0);
+               if (AMIGA_FontName == NULL)
+                   AMIGA_ERROR("No memory for font name", RETURN_FAIL);
+               quote_str(AMIGA_FontName, c_token, AMIGA_FontNameLen);
+               c_token++;
+           } else {
+               /* Font size */
+               struct value a;
+               AMIGA_FontSize = (int) real(const_express(&a));
+           }
+
+           break;
+       }
+    }
+
+    if (AMIGA_FontName == NULL && AMIGA_FontSize != 0) {
+       AMIGA_FontNameLen = strlen(AMIGA_DEFAULTFONT) + 1;
+       AMIGA_FontName = AllocMem(AMIGA_FontNameLen,0);
+       if (AMIGA_FontName == NULL)
+           AMIGA_ERROR("No memory for font name", RETURN_FAIL);
+       strcpy(AMIGA_FontName, AMIGA_DEFAULTFONT);
+    }
+    if (AMIGA_FontName != NULL && AMIGA_FontSize == 0)
+       AMIGA_FontSize = 8;
+
+    if (AMIGA_FontName != NULL && AMIGA_FontSize != 0) {
+       sprintf(AMIGA_default_font, "%s,%d", AMIGA_FontName, AMIGA_FontSize);
+       sprintf(term_options, "%s \"%s\" %d", \
+               (AMIGA_window_mode != TRUE ? "screen" : "window"), \
+               AMIGA_FontName, AMIGA_FontSize);
+    } else
+       sprintf(term_options, "%s", (AMIGA_window_mode != TRUE ? "screen" : "window"));
+}
+
+
+/*
+ * Close open font, screen and libraries.
+ */
+TERM_PUBLIC void
+AMIGA_reset()
+{
+    if (AMIGA_window_mode == TRUE) {
+       int i = 0;
+
+       /* Free the pens */
+       while (i < PALETTE_SIZE) {
+           if (clut[i] != -1)
+               ReleasePen(AMIGA_Window->WScreen->ViewPort.ColorMap, clut[i]);
+
+           i++;
+       }
+
+       /* Close the window */
+       if (AMIGA_Window != NULL)
+           CloseWindow(AMIGA_Window);
+
+       AMIGA_Window = NULL;
+       AMIGA_window_mode = FALSE;
+    }
+    if (AMIGA_TextFont != NULL)
+       CloseFont(AMIGA_TextFont);
+
+    if (DiskfontBase != NULL)
+       CloseLibrary(DiskfontBase);
+
+    if (AMIGA_Screen != NULL)
+       CloseScreen(AMIGA_Screen);
+
+    if (IntuitionBase != NULL)
+       CloseLibrary((struct Library *) IntuitionBase);
+
+    if (GfxBase != NULL)
+       CloseLibrary((struct Library *) GfxBase);
+
+    if (AMIGA_FontName != NULL)
+       FreeMem(AMIGA_FontName,AMIGA_FontNameLen);
+
+    AMIGA_FontName = NULL;
+    AMIGA_FontNameLen = 0;
+    AMIGA_TextFont = NULL;
+    DiskfontBase = NULL;
+    AMIGA_Screen = NULL;
+    IntuitionBase = NULL;
+    GfxBase = NULL;
+
+    AMIGA_RastPort = NULL;
+}
+
+
+/*
+ * Init terminal.
+ */
+TERM_PUBLIC void
+AMIGA_init()
+{
+
+    /* Install exit trap in case of abnormal termination (see below). */
+    if (ATEXIT(AMIGA_exit))
+       AMIGA_ERROR("Couldn't set exit trap", RETURN_FAIL);
+
+    /* Open needed libraries */
+    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
+    if (GfxBase == NULL)
+       AMIGA_ERROR("No Graphics-Library", RETURN_FAIL);
+
+    IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
+    if (IntuitionBase == NULL)
+       AMIGA_ERROR("No Intuition-Library", RETURN_FAIL);
+
+    if (AMIGA_window_mode == TRUE) {
+       int i = 0;
+
+       /* Initialize the clut */
+       while (i < PALETTE_SIZE)
+           clut[i++] = -1;
+    }
+    if (LIB_VERSION(IntuitionBase) <= 34) {
+       /* We compute the vertical resolution for those poor NTSC-souls   :-)   */
+       if (GfxBase->DisplayFlags & PAL)
+           AMIGA_ymax = 512;
+       else
+           AMIGA_ymax = 400;
+
+       AMIGA_xmax = 640;
+       AMIGA_NewScreen.Width = AMIGA_xmax;
+       AMIGA_NewScreen.Height = AMIGA_ymax;
+
+       AMIGA_Screen = OpenScreen(&AMIGA_NewScreen);
+
+       if (AMIGA_Screen == NULL)
+           AMIGA_ERROR("No Screen", RETURN_FAIL);
+
+       AMIGA_RastPort = &AMIGA_Screen->RastPort;
+
+    } else {                   /* Intuition version > 34 */
+       /* Kickstart 2.0 support */
+       AMIGA_NewScreen.Width = STDSCREENWIDTH;
+       AMIGA_NewScreen.Height = STDSCREENHEIGHT;
+
+       if (AMIGA_window_mode != TRUE) {
+
+           AMIGA_Screen = OpenScreenTagList(&AMIGA_NewScreen, AMIGA_ScrTagList);
+
+           if (AMIGA_Screen == NULL)
+               AMIGA_ERROR("No Screen", RETURN_FAIL);
+
+           AMIGA_RastPort = &AMIGA_Screen->RastPort;
+
+           AMIGA_xmax = AMIGA_Screen->Width;
+           AMIGA_ymax = AMIGA_Screen->Height;
+       } else if (LIB_VERSION(GfxBase) >= 39) { /* AMIGA_window_mode == TRUE */
+           /* Open the plot window */
+
+           AMIGA_Window = (struct Window *)OpenWindowTagList(NULL, AMIGA_WinTagList);
+
+           /* Don't do this: fall back to screen */
+           if (AMIGA_Window == NULL)
+               AMIGA_ERROR("Could not open plot window", RETURN_FAIL);
+
+           AMIGA_RastPort = AMIGA_Window->RPort;
+
+           AMIGA_xmax = AMIGA_WIN_XMAX;
+           AMIGA_ymax = AMIGA_WIN_YMAX;
+
+       }                       /* Gfx version >= 39 */
+    }                          /* Intuition version <= 34 */
+
+    term->xmax = AMIGA_xmax;
+    term->ymax = AMIGA_ymax;
+
+    if (AMIGA_window_mode != TRUE) {
+       char *name =  NULL;
+/*     assert(AMIGA_FontName != NULL); */
+       /* should even do for ridiculously large FontSize :) */
+       name = AllocMem(AMIGA_FontNameLen + 1 + INT_STR_LEN + 1,0);
+       if (name == NULL)
+           AMIGA_ERROR("No memory for font name", RETURN_FAIL);
+       sprintf(name, "%s,%d", AMIGA_FontName, AMIGA_FontSize);
+       AMIGA_set_font(name);
+       FreeMem(name,AMIGA_FontNameLen + INT_STR_LEN + 2);
+
+       LoadRGB4(&AMIGA_Screen->ViewPort, AMIGA_Colors, 16);
+       RemakeDisplay();
+       AMIGA_slinetype = 1;
+       SetAPen(&AMIGA_Screen->RastPort, AMIGA_slinetype);
+    } else {
+       int i, r, g, b;
+
+       AMIGA_bsl = AMIGA_Window->RPort->TxBaseline;    /* Reference line */
+       AMIGA_cht = AMIGA_Window->RPort->TxHeight;      /* Height of characters */
+
+       /* Allocate pens */
+       for (i = 0; i < PALETTE_SIZE; i++) {
+           r = (palette[i] << 8) & 0xFF000000;
+           g = (palette[i] << 16) & 0xFF000000;
+           b = (palette[i] << 24) & 0xFF000000;
+           clut[i] = ObtainBestPenA(AMIGA_Window->WScreen->ViewPort.ColorMap, r, g, b, NULL);
+       }
+
+    }
+
+    SetDrMd(AMIGA_RastPort, JAM1);
+
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_text()
+{
+    if (AMIGA_window_mode != TRUE) {
+       if (interactive == TRUE) {
+           FILE *fp;
+
+           if ((fp = fopen("*", "r")) != NULL) {
+               int c = getc(fp);
+
+               ungetc(c, stdin);
+               fclose(fp);
+           }
+           ScreenToBack(AMIGA_Screen);
+       }
+    }
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_graphics()
+{
+
+    SetRast(AMIGA_RastPort, 0);
+
+    if (AMIGA_window_mode == TRUE) {
+       /* clear the window */
+       SetAPen(AMIGA_Window->RPort, clut[0]);
+       RectFill(AMIGA_Window->RPort, 0, 0, 640, 400);
+       AMIGA_slinetype = clut[1];
+    }
+    SetAPen(AMIGA_RastPort, AMIGA_slinetype);
+    AMIGA_resume();
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_move(unsigned int x, unsigned int y)
+{
+    if ((x >= AMIGA_xmax) || (y >= AMIGA_ymax))
+       return;
+
+    Move(AMIGA_RastPort, x, AMIGA_VTF(y));
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_vector(unsigned int x, unsigned int y)
+{
+    if ((x >= AMIGA_xmax) || (y >= AMIGA_ymax))
+       return;
+
+    Draw(AMIGA_RastPort, x, AMIGA_VTF(y));
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_linetype(int linetype)
+{
+    if (AMIGA_window_mode != TRUE) {
+       if (linetype >= 13)
+           linetype %= 13;
+
+       if (linetype < -3)
+           linetype = LT_BLACK;
+
+       AMIGA_slinetype = linetype + 3;
+    } else {
+       if (linetype >= 0)
+           linetype = (linetype % 9) + 1;
+
+       if (linetype < 0)
+           linetype = 1;
+
+       AMIGA_slinetype = clut[linetype];
+    }
+    SetAPen(AMIGA_RastPort, AMIGA_slinetype);
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_put_text(unsigned int x, unsigned int y, const char *str)
+{
+    LONG len, tx_len;
+    WORD x_min, x_max, y_min, y_max;
+
+    len = strlen(str);
+
+    tx_len = TextLength(AMIGA_RastPort, str, len);
+
+    switch (AMIGA_justify) {
+    case LEFT:
+       x_min = x;
+       x_max = x + tx_len;
+       break;
+    case CENTRE:
+       x_min = x - tx_len / 2;
+       x_max = x + tx_len - tx_len / 2;        /* avoid roundoff errors ! */
+       break;
+    default:                   /* does this make sense ?? */
+    case RIGHT:
+       x_min = x - tx_len;
+       x_max = x;
+       break;
+    }
+
+    y_min = AMIGA_VTF(y) - AMIGA_vadj;
+    y_max = y_min + AMIGA_cht;
+
+    /* Check if character-string lies completely within the screen: */
+    /* What about clipping? */
+    if ((x_max >= AMIGA_xmax) || (y_min < 0) || (y_max >= AMIGA_ymax))
+       return;
+
+    Move(AMIGA_RastPort, x_min, y_min + AMIGA_bsl);
+    Text(AMIGA_RastPort, str, len);
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC int
+AMIGA_justify_text(enum JUSTIFY mode)
+{
+    AMIGA_justify = mode;
+    return TRUE;
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC int
+AMIGA_set_font(const char *font)
+{
+    static char test_str[] =
+    " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+    static WORD test_len, test_pxl;
+
+    /* Disable for window mode */
+    if (AMIGA_window_mode != TRUE) {
+       char *name = NULL;
+       int size, sep, namelen;
+
+       /* Allow caller to pass "" to indicate default font */
+       if (!font || !(*font))
+           font = AMIGA_default_font;
+
+       sep = strcspn(font, ",");
+       namelen = strlen(font) + strlen(".font") + 1;
+       name = AllocMem(namelen,0);
+       if (name == NULL)
+           AMIGA_ERROR("No memory for font name", RETURN_FAIL);
+       strcpy(name,font);
+       name[sep] = NUL;
+       size = AMIGA_FontSize;
+       if (font[sep] == ',')
+           sscanf(&(font[sep + 1]), "%d", &size);
+
+       if (name != NULL && strcmp(name, "") != 0) {
+           strcat(name, ".font");
+
+           /* Avoid opening "diskfont.library" if a built-in font is desired */
+           if ((strcmp("topaz.font", name) == 0) &&
+               ((size == TOPAZ_EIGHTY) || (size == TOPAZ_SIXTY))) {
+               AMIGA_Font.ta_Name = name;
+               AMIGA_Font.ta_YSize = size;
+               AMIGA_Font.ta_Style = FS_NORMAL;
+               AMIGA_Font.ta_Flags = FPF_ROMFONT;
+               AMIGA_TextFont = OpenFont(&AMIGA_Font);
+
+               if (AMIGA_TextFont != NULL)
+                   SetFont(&AMIGA_Screen->RastPort, AMIGA_TextFont);
+
+           } else {
+               DiskfontBase = OpenLibrary("diskfont.library", 0);
+
+               if (DiskfontBase != NULL) {
+                   AMIGA_Font.ta_Name = name;
+                   AMIGA_Font.ta_YSize = size;
+                   AMIGA_Font.ta_Style = FS_NORMAL;
+                   AMIGA_Font.ta_Flags = FPF_ROMFONT | FPF_DISKFONT;
+                   AMIGA_TextFont = OpenDiskFont(&AMIGA_Font);
+
+                   if (AMIGA_TextFont != NULL)
+                       SetFont(&AMIGA_Screen->RastPort, AMIGA_TextFont);
+               }
+           }
+       }
+       /* Width of characters: This works better for proportional fonts than */
+       /* AMIGA_Screen->RastPort.TxWidth + AMIGA_Screen->RastPort.TxSpacing */
+       test_len = strlen(test_str);
+       test_pxl = TextLength(&AMIGA_Screen->RastPort, test_str, test_len);
+
+       AMIGA_cwd = test_pxl / test_len;
+       AMIGA_cht = AMIGA_Screen->RastPort.TxHeight;    /* Height of characters */
+       AMIGA_bsl = AMIGA_Screen->RastPort.TxBaseline;  /* Reference line */
+
+       /* Amount by which characters have to be shifted upwards to be */
+       /* vertically justified: */
+       AMIGA_vadj = AMIGA_bsl / 2;
+       term->v_char = AMIGA_cht + 4;   /* So lines won't be too close */
+       term->h_char = AMIGA_cwd;
+
+       FreeMem(name,namelen);
+    }                          /* !window_mode */
+    return TRUE;
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_suspend()
+{
+    if (AMIGA_window_mode != TRUE) {
+       if (interactive == TRUE) {
+           FILE *fp;
+
+           if ((fp = fopen("*", "r")) != NULL) {
+               int c = getc(fp);
+
+               ungetc(c, stdin);
+               fclose(fp);
+           }
+           ScreenToBack(AMIGA_Screen);
+       }
+    }
+}
+
+
+/*
+ *
+ */
+TERM_PUBLIC void
+AMIGA_resume()
+{
+    if (AMIGA_window_mode != TRUE)
+       ScreenToFront(AMIGA_Screen);
+    else
+       WindowToFront(AMIGA_Window);
+}
+
+
+#ifdef HAVE_ATEXIT
+/* This function is mainly included if the program terminates abnormally
+ * and the screen and libraries are still open. It closes down all opened
+ * libraries and screens. This happens e.g. when loading "bivariat.demo"
+ * and the stack is smaller than 120000 bytes.
+ */
+void
+AMIGA_exit()
+{
+    AMIGA_reset();
+    RAWCON(0);
+}
+
+#endif /* HAVE_ATEXIT */
+
+
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(amiga_driver)
+    "amiga", "Amiga Custom Screen/Window [screen window]",
+    AMIGA_XMAX, AMIGA_YMAX, AMIGA_VCHAR, AMIGA_HCHAR,
+    AMIGA_VTIC, AMIGA_HTIC, AMIGA_options, AMIGA_init, AMIGA_reset,
+    AMIGA_text, null_scale, AMIGA_graphics, AMIGA_move, AMIGA_vector,
+    AMIGA_linetype, AMIGA_put_text, null_text_angle,
+    AMIGA_justify_text, do_point, do_arrow, AMIGA_set_font,
+    0,                         /* pointsize */
+    TERM_CAN_MULTIPLOT, AMIGA_suspend, AMIGA_resume
+TERM_TABLE_END(amiga_driver)
+
+#undef LAST_TERM
+#define LAST_TERM amiga_driver
+
+#endif /* TERM_TABLE */
+#endif /* TERM_PROTO_ONLY */
+
+
+#ifdef TERM_HELP
+START_HELP(amiga)
+"1 amiga",
+"?commands set terminal amiga",
+"?set terminal amiga",
+"?set term amiga",
+"?terminal amiga",
+"?term amiga",
+"?amiga",
+" The `amiga` terminal, for Commodore Amiga computers, allows the user to",
+" plot either to a screen (default), or, if Kickstart 3.0 or higher is",
+" installed, to a window on the current public screen. The font and its size",
+" can also be selected.",
+"",
+" Syntax:",
+"       set terminal amiga {screen | window} {\"<fontname>\"} {<fontsize>}",
+"",
+" The default font is 8-point \"topaz\".",
+"",
+" The screen option uses a virtual screen, so it is possible that the graph",
+" will be larger than the screen."
+END_HELP(amiga)
+#endif /* TERM_HELP */