
 /* SV_SuperVisor.c
    - SuperVising (global exit) Functions for SVO-Support -
    (c) 1990-94 by Andreas R. Kleinert
    Last changes : 07.05.1994
 */

#include "svobject.h"

#include <proto/superview.h>


struct SVObjectHandle * __saveds __asm SVO_AllocHandle( register __a1 APTR future_a1);
void __saveds __asm SVO_FreeHandle( register __a1 struct SVObjectHandle *SVObjectHandle_a1);
void __saveds __asm SVO_CloseDisplay( register __a1 struct SVObjectHandle *SVObjectHandle_a1);
void __saveds __asm SVO_FreeResources( register __a1 struct SVObjectHandle *SVObjectHandle_a1);

/* *************************************************** */
/* *						     * */
/* * SVO_AllocHandle : Alloc SVObjectHandle and more * */
/* *						     * */
/* *************************************************** */

struct SVObjectHandle * __saveds __asm SVO_AllocHandle( register __a1 APTR future_a1)
{
 APTR future = future_a1;

 struct SuperViewBase *SuperViewBase = N;
 struct SVDriverBase  *SVDriverBase  = N;

 struct SVObjectHandle *handle;
 struct SVD_DriverNode *entry;
 char open_name [256];

 handle = (APTR) AllocVec(sizeof(struct SVObjectHandle), (MEMF_CLEAR|MEMF_PUBLIC));
 if(handle)
  {
   handle->ah_Type      = SV_SUBTYPE_NONE;
   handle->ah_WriteMode = SV_SUBTYPE_NONE;
   handle->ah_Medium    = AKO_MEDIUM_DISK; /* default */

   SuperViewBase = (APTR) OpenLibrary("superview.library", 2);
   if(SuperViewBase)
    {
     if(LibVer(SuperViewBase) > 2)
      {
       if(!SVL_GetGlobalDriver(&entry, N))
        {
         strcpy(open_name, "LIBS:svdrivers/");
         strcat(open_name, entry->svd_FileName);

         if(SVDriverBase = (APTR) OpenLibrary(open_name, SVD_VERSION))
          {
           if(handle->ah_SVDriverHandle = SVD_AllocHandle(N))
            {
             handle->ah_DriverBase   = SVDriverBase;
             handle->ah_SVDriver     = entry;
            }else CloseLibrary((APTR) SVDriverBase);
          }
        }

       CloseLibrary(SuperViewBase);
      }
    }
  }

 return(handle);
}

/* *************************************************** */
/* *						     * */
/* * SVO_FreeHandle : Free SVObjectHandle and more   * */
/* *						     * */
/* *************************************************** */

void __saveds __asm SVO_FreeHandle( register __a1 struct SVObjectHandle *SVObjectHandle_a1)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;
 struct SVDriverBase *SVDriverBase = N;

 SVO_CloseDisplay(SVObjectHandle);
 SVO_FreeResources(SVObjectHandle);

 SVDriverBase = SVObjectHandle->ah_DriverBase;
 if(SVDriverBase)
  {
   if(SVObjectHandle->ah_SVDriverHandle) SVD_FreeHandle(SVObjectHandle->ah_SVDriverHandle);

   CloseLibrary((APTR) SVDriverBase);

   SVObjectHandle->ah_DriverBase   = N;
   SVObjectHandle->ah_SVDriverHandle = N;
  }

 FreeVec(SVObjectHandle);
}

/* *************************************************** */
/* *						     * */
/* * SVO_CloseDisplay : Close Display, ...           * */
/* *						     * */
/* *************************************************** */

void __saveds __asm SVO_CloseDisplay( register __a1 struct SVObjectHandle *SVObjectHandle_a1)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;
 struct SVDriverBase *SVDriverBase = N;
 APTR msg;

 if(SVObjectHandle->ah_Screen)
  {
   if(SVObjectHandle->ah_Window)
    {
     while( msg = GetMsg(SVObjectHandle->ah_Window->UserPort) ) ReplyMsg(msg);

     CloseWindow(SVObjectHandle->ah_Window);
    }

   CloseScreen(SVObjectHandle->ah_Screen);

   SVObjectHandle->ah_Window = N;
   SVObjectHandle->ah_Screen = N;
  }

 SVDriverBase = SVObjectHandle->ah_DriverBase;
 if(SVDriverBase) if(SVObjectHandle->ah_SVDriverHandle) SVD_CloseDisplay(SVObjectHandle->ah_SVDriverHandle);
}

/* *************************************************** */
/* *						     * */
/* * SVO_FreeResources : Free Memory and more        * */
/* *						     * */
/* *************************************************** */

void __saveds __asm SVO_FreeResources( register __a1 struct SVObjectHandle *SVObjectHandle_a1)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;
 struct SVDriverBase *SVDriverBase = N;

 if(!SVObjectHandle) return;

 if(SVObjectHandle->ah_filehandle_source)  Close(SVObjectHandle->ah_filehandle_source);
 if(SVObjectHandle->ah_filehandle_source2) Close(SVObjectHandle->ah_filehandle_source2);
 if(SVObjectHandle->ah_filehandle_dest)    Close(SVObjectHandle->ah_filehandle_dest);
 if(SVObjectHandle->ah_filehandle_dest2)   Close(SVObjectHandle->ah_filehandle_dest2);
 if(SVObjectHandle->ah_ramhandle)          SVSUP_FreeMemList(SVObjectHandle->ah_ramhandle);

 if(SVObjectHandle->ah_SVOHeader)
  {
   FreeVec(SVObjectHandle->ah_SVOHeader);

   if(SVObjectHandle->ah_XpkBuffer) FreeMem(SVObjectHandle->ah_XpkBuffer, SVObjectHandle->ah_XpkBufferSize);
  }

 SVDriverBase = SVObjectHandle->ah_DriverBase;
 if(SVDriverBase) if(SVObjectHandle->ah_SVDriverHandle) SVD_FreeResources(SVObjectHandle->ah_SVDriverHandle);

 if(SVObjectHandle->ah_SV_GfxBuffer)
  {
   /* Here, inside SVO.svobject, we cannot use AllocVec()/FreeVec() for
      the GfxBuffers, because Xpk-Library's Buffers are all allocated via
      AllocMem(). Otherwise we'll get "GURU : memory header not located".
   */

   if(SVObjectHandle->ah_SV_GfxBuffer->svgfx_Buffer) FreeMem(SVObjectHandle->ah_SV_GfxBuffer->svgfx_Buffer, SVObjectHandle->ah_SV_GfxBuffer->svgfx_BufferSize);

   FreeVec(SVObjectHandle->ah_SV_GfxBuffer);
  }

 SVObjectHandle->ah_filehandle_source  = N;
 SVObjectHandle->ah_filehandle_source2 = N;
 SVObjectHandle->ah_filehandle_dest    = N;
 SVObjectHandle->ah_filehandle_dest2   = N;
 SVObjectHandle->ah_ramhandle          = N;
 SVObjectHandle->ah_SVOHeader          = N;
 SVObjectHandle->ah_XpkBuffer          = N;
 SVObjectHandle->ah_SV_GfxBuffer       = N;
}
