/* screen.c - 2.0 screen module for Display
 * based on scdemo, oscandemo, looki
 */

/*
Copyright (c) 1989, 1990 Commodore-Amiga, Inc.

Executables based on this information may be used in software
for Commodore Amiga computers. All other rights reserved.
This information is provided "as is"; no warranties are made.
All use is at your own risk, and no liability or responsibility
is assumed.
*/

#include "iffp/ilbmapp.h"

BOOL   VideoControlTags(struct ColorMap *,ULONG tags, ...);

extern struct Library *GfxBase;
extern struct Library *IntuitionBase;

struct TextAttr SafeFont = { (UBYTE *) "topaz.font", 8, 0, 0, };
UWORD  penarray[] = {~0};

/* default new window if none supplied in ilbm->nw */
struct   NewWindow      defnw = {
   0, 0,                                  /* LeftEdge and TopEdge */
   0, 0,                          	  /* Width and Height */
   -1, -1,                                /* DetailPen and BlockPen */
   VANILLAKEY|MOUSEBUTTONS,               /* IDCMP Flags with Flags below */
   BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP,
   NULL, NULL,                            /* Gadget and Image pointers */
   NULL,                                  /* Title string */
   NULL,                                  /* Screen ptr null till opened */
   NULL,                                  /* BitMap pointer */
   50, 20,                                /* MinWidth and MinHeight */
   0 , 0,                                 /* MaxWidth and MaxHeight */
   CUSTOMSCREEN                           /* Type of window */
   };


/* opendisplay - passed ILBMInfo, dimensions, modeID
 *
 *    Attempts to open correct 2.0 modeID screen and window,
 *    else an old 1.3 mode screen and window.
 *
 * Returns *window or NULL.
 */

struct Window *opendisplay(struct ILBMInfo *ilbm,
			   SHORT wide, SHORT high, SHORT deep,
			   ULONG mode)
    {
    struct NewWindow newwin, *nw;

    closedisplay(ilbm);
    if(ilbm->scr = openidscreen(ilbm, wide, high, deep, mode))
	{
	nw = &newwin;
	if(ilbm->windef) *nw = *(ilbm->windef);
	else *nw = *(&defnw);
	nw->Screen	= ilbm->scr;

	D(bug("sizes: scr= %ld x %ld  passed= %ld x %ld\n",
		ilbm->scr->Width,ilbm->scr->Height,wide,high)); 

	nw->Width	= wide;
	nw->Height	= high;
	if (!(ilbm->win = OpenWindow(nw)))
	    {
	    closedisplay(ilbm);
	    D(bug("Failed to open window."));
	    }
	else
	    {
	    if(ilbm->win->Flags & BACKDROP)
		{
		ShowTitle(ilbm->scr, FALSE);
		ilbm->TBState = FALSE;
		}
	    }
	}

    if(ilbm->scr)	/* nulled out by closedisplay if OpenWindow failed */
	{
	ilbm->vp  = &ilbm->scr->ViewPort;
	ilbm->srp = &ilbm->scr->RastPort;
	ilbm->wrp = ilbm->win->RPort;
	}
    return(ilbm->win);
    }


void closedisplay(struct ILBMInfo *ilbm)
    {
    if(ilbm)
	{
    	if (ilbm->win)	CloseWindow(ilbm->win), ilbm->win = NULL;
    	if (ilbm->scr)	CloseScreen(ilbm->scr), ilbm->scr = NULL;
    	ilbm->vp  = NULL;
    	ilbm->srp = ilbm->wrp = NULL;
	}
    }



/* openidscreen - ILBMInfo, dimensions, modeID
 *
 *    Attempts to open correct 2.0 modeID screen with centered
 *    overscan based on user's prefs,
 *    else old 1.3 mode screen.
 *
 * If ilbm->stype includes CUSTOMBITMAP, ilbm->brbitmap will be
 *   	used as the screen's bitmap.
 * If ilbm->stags is non-NULL, these tags will be added to the
 *	end of the taglist.
 *
 * Returns *screen or NULL.
 */

struct Screen *openidscreen(struct ILBMInfo *ilbm,
			    SHORT wide, SHORT high, SHORT deep,
			    ULONG mode)
    {
    struct NewScreen ns;			/* for old style OpenScreen */
    struct Rectangle spos, dclip, txto, stdo, maxo, uclip;  /* display rectangles */
    struct Rectangle *uclipp;
    struct Screen   *scr = NULL;
    LONG   error, trynew;
    ULONG  bitmaptag, passedtags;
    BOOL   vctl;

    if (trynew = ((((struct Library *)GfxBase)->lib_Version >= 36)&&
          (((struct Library *)IntuitionBase)->lib_Version >= 36)))
	{
    	/* if >= v36, see if mode is available */
	if(error = ModeNotAvailable(mode))
	    {
	    D(bug("Mode $%08lx not available, error=%ld:\n",mode,error));
	    /* if not available, try fall back mode */
	    mode = modefallback(mode,wide,high,deep);
	    error = ModeNotAvailable(mode);

	    D(bug("$%08lx ModeNotAvailable=%ld:\n",mode,error));
	    }

	if(error) trynew = FALSE;
	else trynew=((QueryOverscan(mode,&txto,OSCAN_TEXT))&&
			(QueryOverscan(mode,&stdo,OSCAN_STANDARD))&&
			    (QueryOverscan(mode,&maxo,OSCAN_MAX)));
	}

    D(bug("\nILBM: w=%ld, h=%ld, d=%ld, mode=0x%08lx\n",
		wide,high,deep,mode));	
    D(bug("OPEN: %s.\n",
        trynew	? "Is >= 2.0 and mode available, trying OpenScreenTags"
		: "Not 2.0, doing old OpenScreen"));

    if(trynew)
	{
	/* If user clip type specified and available, use it */
	if(ilbm->Video) ilbm->ucliptype = OSCAN_VIDEO;
	if((ilbm->ucliptype)&&(QueryOverscan(mode,&uclip,