/* LinkUnTmpRas.c  -- allocate, initialize and link a TmpRas structure
 *                    into the given RastPort.  AllocRaster's a
 *                    temporary raster area using the given size.
 *                    Also a function to unlink and free the TmpRas and
 *                    Raster.
 *   Written for Manx 3.4a
 *
 * Copyright  1988, Patrick White.
 *    Anybody can use this code in any commercial or non-commercial program.
 * It may not be sold alone or as part of a code toolbox (without prior
 * arrangments with me).
 *
 * altercation history
 * 7/7/88       written
 * 7/8/88       made teh sucker more reasonable to use
 */
#include        <exec/types.h>
#include        <functions.h>
#include        <exec/memory.h>
#include        <intuition/intuition.h>
#include        <graphics/gfx.h>
#include        <graphics/gfxbase.h>
#include        <graphics/rastport.h>
extern  struct  GfxBase  *GfxBase;
/*-----------------------------------------*/
/* allocate, init, then link into the RastPort, a TmpRas structure and
 * related Raster.
 *
 * return codes from ret_code
 *       0 == all ok.. worked perfectly
 *      -1 == GfxBase not opened
 *      -2 == can't allocate raster
 *      -3 == can't allocate TmpRas structure
 */
struct  TmpRas  *
InitLinkTR( rport, width, height, ret_code )
struct  RastPort  *rport;       /* RastPort to attach TmpRas to */
LONG    width;                  /* max width of window or screen */
LONG    height;                 /* max height of window or screen */
LONG    *ret_code;              /* return code to indicate errors */
{
   register struct TmpRas *ret_ptr;  /* storage for TmpRas ptr to return */
   register BYTE   *ras_ptr;         /* ptr to the alloced raster */
   register struct TmpRas *tras;     /* ptr to alloced TmpRas structure */
   /* check if GfxBase is set (graphics library opened yet) */
   if (NULL == GfxBase)  {
      *ret_code = -1L;
      return  NULL;
      }
   /* allocate a Raster */
   if (NULL == (ras_ptr = AllocRaster( width, height )))  {
      *ret_code = -2L;
      return  NULL;
      }
   /* alloacte a TmpRas structure */
   if (NULL == (tras = AllocMem( (LONG) sizeof(struct TmpRas), MEMF_PUBLIC
                | MEMF_CHIP | MEMF_CLEAR )))  {
      /* free alloc'd raster */
      FreeRaster( ras_ptr, width, height );
      *ret_code = -3L;
      return  NULL;
      }
   /* init the TmpRas struct */
   InitTmpRas( tras, ras_ptr, (LONG) RASSIZE( width, height ) );
   /* forbid so nobody tries to use this rast port while I'm screwing
    * with it */
   Forbid();
   /* save current TmpRas ptr in RastPort */
   ret_ptr = rport->TmpRas;
   /* link it into the RastPort */
   rport->TmpRas = tras;
   /* Ok.. I'm done here.. th rest of teh world can do it's thing now */
   Permit();

   /* return saved ptr */
   *ret_code = 0L;
   return  ret_ptr;
}
/*---------------------------------------*/
/* unlink and free the TmpRas and raster in a rasterport -- ASSUMES THAT
 * THE RASTER IS FULL SCREEN AND THAT BOTH WERE ALLOCATED BY THE ABOVE
 * FUNCTION.  If this is not the case, expect a visit from the GURU
 * Also assumes that the screen sizes now were what they were when the
 *  raster was allocated -- will free teh wrong amount of memory if this
 *  is not the case.
 * return codes
 *       0 == everything ok
 *      -1 == GfxBase no longer open -- nothing done
 *      -2 == TmpRas ptr was NULL
 */
LONG
UnlinkFreeTR( rport, width, height )
struct  RastPort  *rport;      /* RastPort to unlink and free TmpRas from */
LONG    width;                  /* max width of window or screen */
LONG    height;                 /* max height of window or screen */
{
   register  struct  TmpRas  *tr;  /* pointer to TmpRas struct to free */
   register  int     ret_code;     /* return code */
   /* check if GfxBase still open */
   if (NULL == GfxBase)
      return  -1L;
   /* forbid everybody so they don't try to use the rast port while I'm
    * mucking with it */
   Forbid();
   /* get the pointer in the RastPort */
   tr = rport->TmpRas;
   /* set the pointer in the RastPort to NULL */
   rport->TmpRas = NULL;
   /* permit the world to do it's thing again */
   Permit();

   /* free TmpRas and associated raster */
   if (0 != (ret_code = FreeTmpRas( tr, width, height )))
      return -2L;
   /* all ok -- return 0 */
   return  0L;
}
/*---------------------------------------*/
/* free a TmpRas structure alloacted by InitLinkTR()
 * return codes:
 *    0 == all ok
 *   -2 == null tmpras ptr
 */
LONG
FreeTmpRas( tmpras, width, height )
struct  TmpRas  *tmpras;        /* ptr to TmpRas struct to free */
LONG    width;                  /* width of raster to free */
LONG    height;                 /* height of raster to free */
{
   /* check if there was a TmpRas structure there */
   if (NULL == tmpras)
      return  -2L;
   /* free the raster */
   if (NULL != tmpras->RasPtr)
      FreeRaster( tmpras->RasPtr, width, height );
   /* free the TmpRas structure itself */
   FreeMem( tmpras, (LONG) sizeof(struct TmpRas) );
   /* all ok -- return 0 */
   return  0L;
}
