/*
 *  File:		offscreen.c
 *  Function:	offscreen graphics routines
 *  Author:		Paul Elseth
 *				Copyright (c) 1991, Paul Elseth
 *
 *	Change History:
 *
 *		12/04/91	PBE		created
 */

#ifndef __OFFSCREEN__
#include "offscreen.h"
#endif
#ifndef	__MEMORY__
#include <memory.h>
#endif
#ifndef	__orca__
#include <orca.h>
#endif
#ifndef	__MEMUTILS__
#include "memutils.h"
#endif
#ifndef	__OPTIONS__
#include "options.h"
#endif

#pragma noroot


/*
 *	AddPixelMap()
 *		Add a pixel map to the offscreen grafport.
 *		Assumes that the current port is set to the new grafport.
 */
static
short AddPixelMap(unsigned short width, unsigned short hite)
{
	LocInfo	locInfo;
    Ptr		pixImagePtr;
	short	err;
	
    locInfo.portSCB = GetMasterSCB();

    locInfo.boundsRect.h1 = 0;
	locInfo.boundsRect.h2 = width;
	locInfo.boundsRect.v1 = 0;
	locInfo.boundsRect.v2 = hite;

    locInfo.width = ((width / 4) + 7) & 0xfff8;

	err = GetNewPtr((long) locInfo.width * hite, &pixImagePtr);
	if (err == 0) {
		locInfo.ptrToPixImage = pixImagePtr;

		SetPortLoc(&locInfo);

		SetPortRect(&locInfo.boundsRect);

		ClipRect(&locInfo.boundsRect);
        SetVisRgn(GetClipHandle());

		EraseRect(&locInfo.boundsRect);
		}

	return err;
}


/*
 *	CreateOffPort()
 *		Create an offscreen grafPort.
 */
short CreateOffPort(short width, short hite, GrafPort ***pMapH)
{
	GrafPort	*oPort, **portH;
    short		err;

    oPort = GetPort();

    portH = *pMapH = 0;

/* get memory for the cacheing port: */
	err = GetNewHandle(sizeof(GrafPort), (Handle *) &portH);
    if (err == 0) {
		HLock((Handle) portH);

		OpenPort(*portH);
		err = toolerror();
	    if (err == 0) {
		    err = AddPixelMap(width, hite);
            if (err == 0) {
				HUnlock((Handle) portH);
				*pMapH = portH;
				}
			}
        }

	if (err != 0 && portH != nil)
	    DisposeIfHandle((Handle) portH);

	return err;
}


/*
 *	AdjustOffPort()
 *		Adjust the size of the offscreen grafPort pixelmap.
 *      Simply disposes of the current pixelmap and creates a new one.
 */
short AdjustOffPort(GrafPort **pMapH, short width, short hite)
{
	GrafPort	*oPort, *pMapP;
	LocInfo		locInfo;
	short		err;

	oPort = GetPort();

/* switch to the offscreen port: */
	HLock((Handle) pMapH);
	pMapP = *pMapH;
	SetPort(pMapP);

/* dispose of current pixelmap: */
	DisposeIfPtr((Ptr) pMapP->portInfo.ptrToPixImage);

/* create new pixel map: */
	err = AddPixelMap(width, hite);

    SetPort(oPort);
	HUnlock((Handle) pMapH);

    return err;
}


/*
 *	DisposeOffscreen()
 *	    Dispose of an offscreen pixelmap.
 */
short DisposeOffscreen(GrafPort **pMapH)
{
	DisposeIfPtr((**pMapH).portInfo.ptrToPixImage);

	ClosePort(*pMapH);

    DisposeIfHandle((Handle) pMapH);
}
