The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
/*
 * $Id: amiga.trm,v 1.15 2002/08/30 20:18:23 sfeam Exp $
 *
 */

/* GNUPLOT - amiga.trm */

/*[
 * Copyright 1991, 1992, 1993, 1998
 *
 * 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 (info-gnuplot@dartmouth.edu).
 * 
 */

#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(x, y)
unsigned int x, y;
{
    if ((x >= AMIGA_xmax) || (y >= AMIGA_ymax))
	return;

    Move(AMIGA_RastPort, x, AMIGA_VTF(y));
}


/*
 *
 */
TERM_PUBLIC void
AMIGA_vector(x, y)
unsigned int x, y;
{
    if ((x >= AMIGA_xmax) || (y >= AMIGA_ymax))
	return;

    Draw(AMIGA_RastPort, x, AMIGA_VTF(y));
}


/*
 *
 */
TERM_PUBLIC void
AMIGA_linetype(linetype)
    int linetype;
{
    if (AMIGA_window_mode != TRUE) {
	if (linetype >= 13)
	    linetype %= 13;

	if (linetype <= L_TYPE_NODRAW)
	    linetype = -2;

	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(x, y, str)
unsigned int x, 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(mode)
enum JUSTIFY mode;
{
    AMIGA_justify = mode;
    return TRUE;
}


/*
 *
 */
TERM_PUBLIC int
AMIGA_set_font(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(void)
{
    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 */