/* $Id: pla_wn.c,v 1.11 1994/09/02 08:36:37 mjl Exp $
 * $Log: pla_wn.c,v $
 * Revision 1.11  1994/09/02  08:36:37  mjl
 * Fixed bug encountered when changing screen modes -- FreeRaster call was
 * given the wrong screen dimensions.
 *
 * Revision 1.10  1994/08/23  16:39:02  mjl
 * Minor fixes to work with PLplot 4.99h distribution and other cleaning up.
 *
 * Revision 1.9  1994/05/23  22:11:59  mjl
 * Minor incompatibilities with main sources fixed.
 *
 * Revision 1.8  1994/03/23  09:00:20  mjl
 * Much rearrangement and decruftifying.  Added support for cmap1, color map
 * state changes, solid polygon fills.  Screen now defaults to 16 color, and
 * palette can be set by calling program.  Added hack to capture screen
 * output into an iff file family without user intervention.
 *
 * Revision 1.7  1994/01/17  21:16:06  mjl
 * Changed virt window from 25 to 16x larger than workbench window
 * to fix problem with overflows (submitted by Wesley Ebisuzaki).
*/

/*	pla_wn.c

	PLPLOT Amiga window device driver.
*/

#include "plplotP.h"
#include "drivers.h"
#include "plamiga.h"
#include "pla_menu.h"

#include <graphics/gfxmacros.h>

/* Function prototypes */

static void   WaitForPage	(PLStream *pls);
static void   HandleEvents	(PLStream *pls);
static void   fill_polygon	(PLStream *pls);
static int    (*func)		(void);
static void   setcmap		(PLStream *pls);

/* top level declarations */
/* Keep these global since other Amiga related source files need them */

struct ReqToolsBase *ReqToolsBase;
struct Process *myproc;

PlAmigaWin PlAmigadev;
PlAmigaWin (*pla) = &PlAmigadev;

APTR oldwinptr;
static struct DrawInfo *drInfo;
static int tidy_when_done;

/* Data structure for polyline call */

static WORD polyTable[PL_MAXPOLY * 2];

/* Data structures for area fill calls */

#define MAX_VERTICES PL_MAXPOLY
#define BUFFERT_SIZE PL_MAXPOLY * 5 / 2

static struct AreaInfo areaInfo;
static struct TmpRas   tmpRas;
static UWORD buffert[ BUFFERT_SIZE ];
static PLANEPTR extra_space;
static WORD ras_width, ras_height;

/*------------------------------------------------------------------------
 *  Source machine generated by GadToolsBox V1.4
 *  which is (c) Copyright 1991,92 Jaba Development
 */

struct IntuiMessage    PlplotMsg;

struct TextAttr topaz11 = {
    (STRPTR)"topaz.font", 11, 0x00, 0x42 };

struct TextAttr topaz8 = {
    (STRPTR)"topaz.font", 8, 0x00, 0x02 };

struct ColorSpec ScreenColors[] = {
    0, 0x09, 0x09, 0x08,
    1, 0x00, 0x00, 0x00,
    2, 0x0C, 0x0C, 0x0C,
    3, 0x05, 0x06, 0x0B,
    4, 0x00, 0x00, 0x0F,
    5, 0x0F, 0x00, 0x0F,
    6, 0x00, 0x0F, 0x0F,
    7, 0x0F, 0x0F, 0x0F,
    8, 0x06, 0x02, 0x00,
    9, 0x0E, 0x05, 0x00,
    10, 0x09, 0x0F, 0x01,
    11, 0x0E, 0x0B, 0x00,
    12, 0x05, 0x05, 0x0F,
    13, 0x09, 0x02, 0x0F,
    14, 0x00, 0x0B, 0x00,
    15, 0x00, 0x03, 0x06,
    ~0, 0x00, 0x00, 0x00 };

UWORD DriPens[] = {
    0, 1, 1, 2, 1, 3, 1, 0, 2, (UWORD) ~0 };

/*----------------------------------------------------------------------*\
 * Utility macros/functions
\*----------------------------------------------------------------------*/

#define ami_cmd(code) \
if (code) { fprintf(stderr, \
	    "Error in %s at line %d\n", \
	    __FILE__, __LINE__); \
	    return; }

static void myputs (char *str)
{
    Write (Output(), str, strlen(str));
}

static PLINT
xscale(PLINT x)
{
    return (PLINT) (pla->xoffset + x * pla->xscale);
}

static PLINT
yscale(PLINT y)
{
    return (PLINT) (pla->yoffset + pla->cur_height - y * pla->yscale);
}

static void 
setpen(PLINT color)
{
    SetAPen(pla->WRPort, color);
}

static void 
PLMove(PLINT x, PLINT y)
{
    Move(pla->WRPort, xscale(x), yscale(y));
}

static void 
PLDraw(PLINT x, PLINT y)
{
    Draw(pla->WRPort, xscale(x), yscale(y));
}

/*----------------------------------------------------------------------*\
 * Initialization of Menus follows.
\*----------------------------------------------------------------------*/

struct NewMenu PlplotNewMenu[] = {

/********* Project menu *********/

    NM_TITLE, (STRPTR)"Project", NULL, 0, NULL, NULL,

/* Open */

    NM_ITEM, (STRPTR)"Open", (STRPTR)"O", NM_ITEMDISABLED, 0L,
    (APTR)plamiga_Open,

/* Save */

    NM_ITEM, (STRPTR)"Save", (STRPTR)"S", NM_ITEMDISABLED, 0L,
    (APTR)plamiga_Save,

/* Save As */

    NM_ITEM, (STRPTR)"Save As", (STRPTR)"A", 0, NULL, NULL,
    NM_SUB, (STRPTR)"ILBM (IFF)", NULL, 0, 0L,
    (APTR)plamiga_SaveAs_ILBM,

/* Print */

    NM_ITEM, (STRPTR)"Print", (STRPTR)"P", 0, NULL, NULL,
    NM_SUB, (STRPTR)"Bitmap", NULL, 0, 0L,
    (APTR)plamiga_Print_Bitmap,
    NM_SUB, (STRPTR)"Full page (landscape)", NULL, 0, 0L,
    (APTR)plamiga_Print_landscape,
    NM_SUB, (STRPTR)"Full page (portrait)", NULL, 0, 0L,
    (APTR)plamiga_Print_portrait,

/* About */

    NM_ITEM, (STRPTR)"About...", NULL, NM_ITEMDISABLED, 0L,
    (APTR)plamiga_About,

/* Quit */

    NM_ITEM, (STRPTR)"Quit", (STRPTR)"Q", 0, 0L,
    (APTR)plamiga_Quit,

/********* Settings menu *********/

    NM_TITLE, (STRPTR)"Settings", NULL, 0, NULL, NULL,

/* Bring up ScreenMode requester */

    NM_ITEM, (STRPTR)"Screen Mode", NULL, 0, 0L,
    (APTR)plamiga_Screenmode,

/* Bring up palette requester */

    NM_ITEM, (STRPTR)"Palette", (STRPTR)"U", 0, 0L,
    (APTR)plamiga_Palette0,

/* Bring up cmap 1 modifier (not ready yet) */
/*
    NM_ITEM, (STRPTR)"Palette 1", NULL, NM_ITEMDISABLED, 0L,
    (APTR)plamiga_Palette1,
*/
    NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,

/* Load config file */

    NM_ITEM, (STRPTR)"Load Settings", NULL, 0, 0L,
    (APTR)plamiga_LoadConfig,

/* Save config file */

    NM_ITEM, (STRPTR)"Save Settings", NULL, 0, 0L,
    (APTR)plamiga_SaveConfigAs,
    NM_ITEM, (STRPTR)"Save Settings As...", NULL, 0, 0L,
    (APTR)plamiga_SaveConfig,

/********* User menu *********/

    NM_TITLE, (STRPTR)"User", NULL, 0, NULL, NULL,
    NM_ITEM, (STRPTR)"DUMMY", NULL, NM_ITEMDISABLED, 0L,
    (APTR)plamiga_DUMMY,

/* This is the end */

    NM_END, NULL, NULL, 0, 0L, NULL };

/*----------------------------------------------------------------------*\
 * plD_init_amiwn()
 *
 * Initialize device.
\*----------------------------------------------------------------------*/

void
plD_init_amiwn(PLStream *pls)
{
    PLDev *dev;
    PLFLT Initdpmx, Initdpmy;
    struct Screen *wb_screen;
    
    pls->termin = 1;		/* is an interactive terminal */
    pls->icol0 = 1;
    pls->width = 1;
    pls->bytecnt = 0;
    pls->page = 0;
    pls->plbuf_write = 1;
    pls->dev_fill0 = 1;
    tidy_when_done = 0;

    if (!pls->colorset)
        pls->color = 1;

/* Open the required libraries. */

    pla_OpenLibs();
    tidy_when_done = 1;

/* Check for hack mode */

    if (pls->hack) {
	if (pls->FileName == NULL)
	    plP_sfnam(pls, "foo.iff");

	plFamInit(pls);
	plP_getmember(pls);
	fprintf(stderr, "Sending screen output to an IFF file family.\n");
	fprintf(stderr, "First file: %s\n", pls->FileName);
    }

/* Save old window pointer */

    myproc = (struct Process *) FindTask (NULL);
    oldwinptr = myproc->pr_WindowPtr;

/*
 * Set up default screen & window parameters.  Take the default screen
 * parameters from Workbench -- the user can always change it and save the
 * configuration.
 */

    pla->scr_displayID	= INVALID_ID;
    wb_screen = LockPubScreen("Workbench");

    if (wb_screen != NULL) {
	pla->scr_displayID = GetVPModeID(&(wb_screen->ViewPort));
	if (pla->scr_displayID != INVALID_ID) {
	    pla->scr_left	= wb_screen->LeftEdge;
	    pla->scr_top	= wb_screen->TopEdge;
	    pla->scr_width	= wb_screen->Width;
	    pla->scr_height	= wb_screen->Height;
	}
	UnlockPubScreen(NULL, wb_screen);
    }

/* This is the fallback in case Workbench can't be found */

    if (pla->scr_displayID == INVALID_ID) {
	pla->scr_left		= 0;
	pla->scr_top		= 0;
	pla->scr_width		= 640;
	pla->scr_height		= 400;
	pla->scr_displayID	= NTSC_MONITOR_ID | HIRESLACE_KEY;
    }

    pla->scr_depth	= 4;
    pla->maxcolors	= pow(2., (double) pla->scr_depth);
    pla->scr_type	= CUSTOMSCREEN;

    pla_SetFont();

/* Initialize display */

    pla_InitDisplay();

/* Virtual screen is 16 times the actual one. */

    pla->init_width = pla->cur_width * 16;
    pla->init_height = pla->cur_height * 16;

/* Set up initial plotting scale factors */

    pla->xscale = (double) pla->cur_width / pla->init_width;
    pla->yscale = (double) pla->cur_height / pla->init_height;

/* Allocate and initialize device-specific data */

    dev = plAllocDev(pls);

    dev->xold = UNDEFINED;
    dev->yold = UNDEFINED;
    dev->xmin = 0;
    dev->xmax = pla->init_width - 1;
    dev->ymin = 0;
    dev->ymax = pla->init_height - 1;

/* For borderless window, only the menubar width needs to be accounted for in */
/* the offsets.  If the screen resolution changes later, tough!  Too late */
/* to do anything about it. */

    pla->xoffset = 8;
    pla->yoffset = pla->screen->BarHeight + 2;

    Initdpmx = GfxBase->NormalDPMX;
    Initdpmy = GfxBase->NormalDPMY;
    if (pla->screen->ViewPort.Modes & HIRES)
	Initdpmx *= 2.;
    if (pla->screen->ViewPort.Modes & LACE)
	Initdpmy *= 2.;

    plP_setpxl((PLFLT) (Initdpmx / 40.), (PLFLT) (Initdpmy / 40.));
    plP_setphy(0, (pla->init_width - 1), 0, (pla->init_height - 1));
}

/*----------------------------------------------------------------------*\
 * plD_line_amiwn()
 *
 * Draw a line in the current color from (x1,y1) to (x2,y2).
\*----------------------------------------------------------------------*/

void 
plD_line_amiwn(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
{
    PLDev *dev = (PLDev *) pls->dev;
    int x1=x1a, y1=y1a, x2=x2a, y2=y2a;
    static long count = 0, max_count = 10;

    if ( (++count/max_count)*max_count == count) {
	count = 0;
	HandleEvents(pls);      /* Check for events */
    }

    if (x1 == dev->xold && y1 == dev->yold) {
	PLDraw(x2, y2);
    }
    else {
	PLMove(x1, y1);
	PLDraw(x2, y2);
    }
    dev->xold = x2;
    dev->yold = y2;
}

/*----------------------------------------------------------------------*\
 * plD_polyline_amiwn()
 *
 * Draw a polyline in the current color.
\*----------------------------------------------------------------------*/

void 
plD_polyline_amiwn (PLStream *pls, short *xa, short *ya, PLINT npts)
{
    PLDev *dev = (PLDev *) pls->dev;
    PLINT i, j;
    static long count = 0, max_count = 5;

    if ( (++count/max_count)*max_count == count) {
	count = 0;
	HandleEvents(pls);      /* Check for events */
    }

    for (i=0, j=0; i<npts; i++) {
	polyTable[j++] = xscale(xa[i]);
	polyTable[j++] = yscale(ya[i]);
    }

    Move(pla->WRPort, polyTable[0], polyTable[1]);
    PolyDraw(pla->WRPort, npts, polyTable);

    dev->xold = UNDEFINED;
    dev->yold = UNDEFINED;
}

/*----------------------------------------------------------------------*\
 * plD_eop_amiwn()
 *
 * End of page. 
\*----------------------------------------------------------------------*/

void 
plD_eop_amiwn(PLStream *pls)
{
    if (pls->hack) {
	if (plamiga_saveiff(pls->FileName)) {
	    fprintf(stderr, "Unable to save file %s, aborting.\n");
	    plexit("");
	}
	pls->member += pls->finc;
	plP_getmember(pls);
    }
    else {
/*    DisplayBeep(pla->screen);*/
	WaitForPage(pls);
    }
}

/*----------------------------------------------------------------------*\
 * plD_bop_amiwn()
 *
 * Set up for the next page.  
 * Advance to next family file if necessary (file output).
\*----------------------------------------------------------------------*/

void 
plD_bop_amiwn(PLStream *pls)
{
    PLDev *dev = (PLDev *) pls->dev;

    setpen(0);
    RectFill(pla->WRPort, pla->xoffset, pla->yoffset,
	     pla->cur_width + pla->xoffset, pla->cur_height + pla->yoffset);
    setpen(pls->icol0);

    dev->xold = UNDEFINED;
    dev->yold = UNDEFINED;
    pls->page++;
}

/*----------------------------------------------------------------------*\
 * plD_tidy_amiwn()
 *
 * Close graphics file or otherwise clean up.
\*----------------------------------------------------------------------*/

void 
plD_tidy_amiwn(PLStream *pls)
{
    if (tidy_when_done) {
	myproc->pr_WindowPtr = oldwinptr;

	pla_CloseWindow();
	pla_CloseScreen();
	pla_CloseLibs();
    }
}

/*----------------------------------------------------------------------*\
 * plD_state_amiwn()
 *
 * Handle change in PLStream state (color, pen width, fill attribute, etc).
\*----------------------------------------------------------------------*/

void 
plD_state_amiwn(PLStream *pls, PLINT op)
{
    HandleEvents(pls);	/* Check for intuition messages */

    switch (op) {

    case PLSTATE_WIDTH:
	break;

/* Set color map 0 index. */
/* Color 0 is the background. */

    case PLSTATE_COLOR0:{
	int icol0 = pls->icol0 % pla->maxcolors;
	setpen(icol0);
	break;
    }

/* Set color map 1 index. */

    case PLSTATE_COLOR1:{
	int icol1, ncol1;
	if ((ncol1 = MIN(pla->maxcolors - pls->ncol0, pls->ncol1)) < 1)
	    break;

	icol1 = pls->ncol0 + (pls->icol1 * (ncol1-1)) / (pls->ncol1-1);
	setpen(icol1);
	break;
    }

/* Set entire color map */

    case PLSTATE_CMAP0:
    case PLSTATE_CMAP1:
	setcmap(pls);
	break;
    }
}

/*----------------------------------------------------------------------*\
 * plD_esc_amiwn()
 *
 * Escape function.
\*----------------------------------------------------------------------*/

void 
plD_esc_amiwn(PLStream *pls, PLINT op, char *ptr)
{
    HandleEvents(pls);	/* Check for intuition messages */
    switch (op) {
      case PLESC_FILL:
	fill_polygon(pls);
	break;
    }
}

/*----------------------------------------------------------------------*\
 * fill_polygon()
 *
 * Fill polygon described in points pls->dev_x[] and pls->dev_y[].
 * Only solid color fill supported.
\*----------------------------------------------------------------------*/

static void
fill_polygon(PLStream *pls)
{
    int i;

    if ( AreaMove(pla->WRPort,
		  xscale(pls->dev_x[0]), yscale(pls->dev_y[0])) ) {
	fprintf(stderr, "Error in %s at line %d\n", __FILE__, __LINE__);
	goto end;
    }

    for (i = 1; i < pls->dev_npts; i++) {
	if ( AreaDraw(pla->WRPort,
		      xscale(pls->dev_x[i]), yscale(pls->dev_y[i])) ) {
	    fprintf(stderr, "Error in %s at line %d\n", __FILE__, __LINE__);
	    goto end;
	}
    }

 end:
    ami_cmd( AreaEnd(pla->WRPort) );
}

/*----------------------------------------------------------------------*\
 * setcmap()
 *
 * Sets up color palette.
\*----------------------------------------------------------------------*/

static void
setcmap(PLStream *pls)
{
    int i, ncol1 = MIN(pla->maxcolors - pls->ncol0, pls->ncol1);
    PLColor cmap1col;

/* Initialize cmap 0 colors */

    for (i = 0; i < pls->ncol0; i++) 
	SetRGB4(pla->VPort, i,
		pls->cmap0[i].r>>4, pls->cmap0[i].g>>4, pls->cmap0[i].b>>4);

/* Initialize any remaining slots for cmap1 */

    for (i = 0; i < ncol1; i++) {
	plcol_interp(pls, &cmap1col, i, ncol1);
	SetRGB4(pla->VPort, i + pls->ncol0,
		cmap1col.r>>4, cmap1col.g>>4, cmap1col.b>>4);
    }
}

/*----------------------------------------------------------------------*\
 * pla_InitDisplay()
 *
 * Initialize display and other associated parameters.
\*----------------------------------------------------------------------*/

void 
pla_InitDisplay(void)
{
/* Open screen & window */

    if (pla_OpenScreen())
	exit(1);

    if (pla_OpenWindow())
	exit(1);

/* Change the window pointer for requesters */

    myproc->pr_WindowPtr = pla->window;

/* Initialize amiga display state data structure */

    pla->SRPort = &(pla->screen->RastPort);
    pla->WRPort = pla->window->RPort;
    pla->VPort = &(pla->screen->ViewPort);
    pla->CMap = pla->VPort->ColorMap;

/* Drawing info */

    setcmap(plsc);
    setpen(1);
/*
    drInfo = GetScreenDrawInfo(pla->screen);
*/
/* Inane initialization for area fills. */
/* Get some space for the vertices and initialize the AreaInfo ptr: */

    InitArea( &areaInfo, buffert, MAX_VERTICES );
    pla->WRPort->AreaInfo = &areaInfo;

/* Initialize the TmpRas structure: */

    pla->WRPort->TmpRas = (struct TmpRas *)
	InitTmpRas( &tmpRas, extra_space, 
		   RASSIZE( ras_width, ras_height ) );

    BNDRYOFF(pla->WRPort);

/* Current window size. */

    pla->cur_width = pla->window->Width -
	pla->window->BorderLeft - pla->window->BorderRight - 16;

    pla->cur_height = pla->window->Height -
	pla->window->BorderTop - pla->window->BorderBottom - 16;
}

/*----------------------------------------------------------------------*\
 * pla_SetFont()
 *
 * Set up font for menus, screen bar.  May eventually be user-settable.
 * For now, just select between topaz 8 and topaz 11 on the basis of number
 * of lines in the display.
\*----------------------------------------------------------------------*/

void
pla_SetFont(void)
{
    if (pla->scr_height >= 350)
	pla->font = &topaz11;
    else
	pla->font = &topaz8;
}

/*----------------------------------------------------------------------*\
 * pla_OpenScreen()
\*----------------------------------------------------------------------*/

int pla_OpenScreen(void)
{
    if ( ! (pla->screen =
	    OpenScreenTags(NULL,
			   SA_Pens,		DriPens,
			   SA_Depth,		pla->scr_depth,
			   SA_Left,		pla->scr_left,
			   SA_Top,		pla->scr_top,
			   SA_Width,		pla->scr_width,
			   SA_Height,		pla->scr_height,
			   SA_Colors,		&ScreenColors[0],
			   SA_Font,		pla->font,
			   SA_Type,		pla->scr_type,
			   SA_DisplayID,	pla->scr_displayID,
			   SA_AutoScroll,	1,
			   SA_Overscan,		OSCAN_STANDARD,
			   SA_ShowTitle,	0,
			   TAG_DONE)))
	return(1L);

    if ( ! (pla->visual = GetVisualInfo(pla->screen, TAG_DONE)))
	return(2L);

/* Allocate some space that is needed to build up area fill objects */

    ras_width = pla->scr_width;
    ras_height = pla->scr_height;
    extra_space = (PLANEPTR) AllocRaster( ras_width, ras_height );
    if( extra_space == NULL )
	plexit( "Could NOT allocate enough memory for the temp raster!" );

    return(0L);
}

/*----------------------------------------------------------------------*\
 * pla_CloseScreen()
\*----------------------------------------------------------------------*/

void pla_CloseScreen(void)
{
    if (extra_space) {
	FreeRaster( extra_space, ras_width, ras_height );
	extra_space = NULL;
    }

    if (pla->visual) {
	FreeVisualInfo(pla->visual);
	pla->visual = NULL;
    }

    if (pla->screen) {
	CloseScreen(pla->screen);
	pla->screen = NULL;
    }
}

/*----------------------------------------------------------------------*\
 * pla_OpenWindow()
\*----------------------------------------------------------------------*/

int pla_OpenWindow(void)
{
    if ( ! (pla->menus = CreateMenus(PlplotNewMenu, GTMN_FrontPen, 0L, TAG_DONE)))
	return(3L);

    LayoutMenus(pla->menus, pla->visual, GTMN_TextAttr, pla->font, TAG_DONE);

    if ( ! (pla->window =
	    OpenWindowTags(NULL,
			   WA_Left,		pla->scr_left,
			   WA_Top,		pla->scr_top,
			   WA_Width,		pla->scr_width,
			   WA_Height,		pla->scr_height,
			   WA_IDCMP,		IDCMP_MENUPICK |
			   			IDCMP_VANILLAKEY | 
						IDCMP_REFRESHWINDOW,	
			   WA_Flags,		WFLG_SMART_REFRESH |
			   			WFLG_BACKDROP |
						WFLG_BORDERLESS |
			   			WFLG_ACTIVATE,
			   WA_ScreenTitle,	"Plplot 5.0",
			   WA_CustomScreen,	pla->screen,
			   TAG_DONE)))
	return(4L);

    SetMenuStrip(pla->window, pla->menus);
    GT_RefreshWindow(pla->window, NULL);

    return(0L);
}

/*----------------------------------------------------------------------*\
 * pla_CloseWindow()
\*----------------------------------------------------------------------*/

void pla_CloseWindow(void)
{
    if (pla->menus) {
	ClearMenuStrip(pla->window);
	FreeMenus(pla->menus);
	pla->menus = NULL;
    }

    if (pla->window) {
	CloseWindow(pla->window);
	pla->window = NULL;
    }
}

/*----------------------------------------------------------------------*\
 * WaitForPage()
 *
 * This routine waits for the user to advance the plot, while handling
 * all other events.
\*----------------------------------------------------------------------*/

static void
WaitForPage(PLStream *pls)
{
    if (pls->nopause)
	return;

    while (!pla->exit_eventloop) {
	Wait(1L << pla->window->UserPort->mp_SigBit);
	HandleEvents(pls);
    }
    pla->exit_eventloop = FALSE;
}


/*----------------------------------------------------------------------*\
 * HandleEvents()
 *
 * Just a front-end to HandlePlplotIDCMP() to make sure the stream
 * pointer is saved where the event-handling code can access it.
\*----------------------------------------------------------------------*/

static void
HandleEvents(PLStream *pls)
{
    HandlePlplotIDCMP();
}

/*----------------------------------------------------------------------*\
 * HandlePlplotIDCMP
 *
 * Responds to all events that PLPLOT cares about.
\*----------------------------------------------------------------------*/

int HandlePlplotIDCMP(void)
{
    struct IntuiMessage	*m;
    struct MenuItem	*n;
    BOOL		running = TRUE;

    while(m = GT_GetIMsg(pla->window->UserPort)) {

	CopyMem((char *) m, (char *) &PlplotMsg,
		(long)sizeof(struct IntuiMessage));

	GT_ReplyIMsg(m);

	switch (PlplotMsg.Class) {

	case	IDCMP_REFRESHWINDOW:
	    GT_BeginRefresh(pla->window);
	    GT_EndRefresh(pla->window, TRUE);
	    break;

	case	IDCMP_VANILLAKEY:
	    running = plamiga_KEY();
	    break;

	case	IDCMP_MENUPICK:
	    while(PlplotMsg.Code != MENUNULL) {
		n = ItemAddress(pla->menus, PlplotMsg.Code);
		func = (void *)(GTMENUITEM_USERDATA(n));
		running = func();
		if (pla->restart) {
		    pla->restart = 0;
		    return (running);
		}
		PlplotMsg.Code = n->NextSelect;
	    }
	    break;
	}
    }
    return(running);
}

/*----------------------------------------------------------------------*\
 * Libraries
\*----------------------------------------------------------------------*/

void 
pla_OpenLibs(void)
{
    if (IntuitionBase =
	(struct IntuitionBase *) OpenLibrary("intuition.library", 0L)) {

	if (GfxBase =
	    (struct GfxBase *) OpenLibrary("graphics.library", 0L)) {

	    if (ReqToolsBase =
		(struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME,
						     REQTOOLSVERSION))

		return;		/* All libraries successfully opened */
	    else
		myputs ("You need reqtools.library V38 or higher!\n"
			"Please install it in your Libs: drirectory.\n");

	    CloseLibrary((struct Library *) GfxBase);
	}
	else
	    puts("\nError opening Graphics library.");

	CloseLibrary((struct Library *) IntuitionBase);
    }
    else
	puts("\nError opening Intuition library.");

    plexit("Initialization failure");
}

void 
pla_CloseLibs(void)
{
    CloseLibrary((struct Library *) GfxBase);
    CloseLibrary((struct Library *) IntuitionBase);
    CloseLibrary((struct Library *) ReqToolsBase);
}

