/*
 *  VSCREEN.C       Creates virtual screens that can be larger than
 *                  the actual display area of your monitor.  The virtual
 *                  screen scrolls when the mouse moves off the edge of
 *                  the display.
 *
 *                  Copyright 1988 by Davide P. Cervone, all rights reserved.
 *
 *                  You may may distibute this code as is, for non-commercial
 *                  purposes, provided that this notice remains intact and the
 *                  documentation file is distributed with it.
 *
 *                  You may not modify this code or incorporate it into your
 *                  own programs without the permission of the author.
 */

/*
 *  WARNING:  This code uses and even modifies the INTUITIONPRIVATE
 *  area of the IntuitionBase structure.  Use it at your own risk.  It is
 *  likely to break under a future release of Intuition.
 */

#define INTUITIONPRIVATE

#include <exec/types.h>
#include <exec/semaphores.h>
#include <exec/interrupts.h>
#include <exec/memory.h>
#include <devices/input.h>
#include <graphics/sprite.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <libraries/dos.h>
#ifndef MANX
   #ifdef PROTO
      #include <proto/intuition.h>
      #include <proto/exec.h>
      #include <proto/graphics.h>
      #include <proto/layers.h>
      #include <proto/dos.h>
   #endif
#endif


#define USAGE       "VSCREEN width height [screen]"
#define COPYRIGHT   "Copyright 1988 by Davide P. Cervone, all rights reserved"

#define PORTNAME    "vScreenPort"


#define INTUITION_REV   0L
#define GRAPHICS_REV    0L
#define LAYERS_REV      0L

#define ERROR_EXIT      RETURN_ERROR
#define OK_EXIT         RETURN_OK

extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
#ifndef PROTO
extern struct DOSBase *DOSBase;
#endif


/*
 *  This structure is used to pass information from the Handler to the
 *  loader.  It contins pointers to the variables that the loader will
 *  have to initialize, and to the routines that it has to call, or 
 *  SetFunction into the libraries.  A pointer to this structure is
 *  stored in the MsgPort so that the loader can find and remove the handler
 *  once it's job is done.
 */

struct vScreenInfo
{
   short MajVers,MinVers, LoadVers;     /* version of handler and loader */
   char *Program;                       /* name of the handler program */
   char *PortName;                      /* name of the public port */
   long Segment;                        /* SegList loaded by loader */
   struct Interrupt *HandlerInfo;       /* Input.Device handler */
   struct IntuitionBase **IntuitionBase;
   struct GfxBase **GfxBase;

   struct Screen **VScreen;             /* the virtual screen */
   SHORT *ScreenWidth,*ScreenHeight;    /* the new width and height */
   SHORT *OldWidth,*OldHeight;          /* old screen size */
   SHORT **RxOffset,**RyOffset;         /* pointer to RasInfo offsets */
   SHORT *RxOffset2,*RyOffset2;         /* normalized offsets */
   LONG  *LaceScreen,*LaceShift;        /* LACE screen? */
   LONG  *HiResScreen,*HiResShift;      /* HIRES screen ? */
   WORD  *OldMaxDH,*OldMaxDR,*OldMaxDW; /* old IntuitionBase MaxDisplays */
   
   /*
    *  These routines are called by the loader:
    */

   void (*SetVScreen)();
   void (*ResetVScreen)();
   void (*FixView)();
   
   /*
    *  These routines replace the Intution and Graphics library routines:
    */
   
   void (*aCloseScreen)();
   void (*aBuildSysRequest)();
   void (*aAutoRequest)();
   void (*aLoadView)();
   void (*aMoveSprite)();
   
   /*
    *  These are the addresses of the JSR or JMP instructions that
    *  need to be changed to call the old library vectors:
    */

   long *CloseScreenJmpTarget;
   long *BuildSysRequestJmpTarget;
   long *AutoRequestJmpTarget;
   long *LoadViewJmpTarget;
   long *MoveSpriteJmpTarget;
   
   /*
    *  These are the old function vectors returned by SetFunction(): 
    */
  
   long OldCloseScreen;
   long OldBuildSysRequest;
   long OldAutoRequest;
   long OldLoadView;
   long OldMoveSprite;
};


/*
 *  These macros give easy access to the vScreenInfo structure:
 */

#define VAR(x)      (*(vScreenData->x))
#define var(x)      (vScreenData->x)


/*
 *  External routine declarations:
 */

#ifndef PROTO
extern struct Window *OpenWindow();
extern struct IntuiMessage *GetMsg();
extern APTR OpenLibrary();
extern PLANEPTR AllocRaster();
extern UBYTE *AllocMem();
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
extern LONG OpenDevice();
extern struct MsgPort *FindPort();
extern long LoadSeg();
#endif
