#include <exec/types.h>

#ifndef DEBUG
#include <proto/exec.h>
#endif

typedef  LONG   (*PFL)();

extern   struct   ExecBase       *SysBase;
extern   struct   IntuitionBase  *IntuitionBase;
extern   LONG     OWentry_point(), CWentry_point(), MIentry_point(), PMentry_point();
extern   VOID     MyOpenWindow(), MyCloseWindow(), MyPutMsg();

struct   RomHook
   {
   struct Library *hk_Base;
   LONG            hk_SysFunc;
   PFL             hk_MyFunc;
   PFL             hk_Entry;
   LONG            hk_LVO;
   };

#define  NEWHOOKS 4
struct   RomHook  Hook[NEWHOOKS] =
   {
      { NULL, 0, (PFL)MyOpenWindow,  (PFL)OWentry_point, -204 },
      { NULL, 0, (PFL)MyCloseWindow, (PFL)CWentry_point,  -72 },
      { NULL, 0, NULL,               (PFL)MIentry_point, -150 },
      { NULL, 0, (PFL)MyPutMsg,      (PFL)PMentry_point, -366 },
   };


/* The SetHooks() and CleanHooks() functions set the parameters for     */
/* the SetFunction() calls and execute those. By doing so, the          */
/* libraries (namely Exec and Intuition) vector tables are patched so   */
/* that calls to the specified functions go trough our code before or   */
/* after doing their normal stuff.                                      */
/* We must save the old pointers to restore them when exiting.          */
/*                                                                      */
/* This is derived from DropShadow's hooks.                             */

VOID
SetHooks()
{
   register USHORT   h;

   Forbid();
   for(h=0; h<NEWHOOKS; h++)
      {
      if (h<3) Hook[h].hk_Base = (struct Library *)IntuitionBase;
      else     Hook[h].hk_Base = (struct Library *)SysBase;
      Hook[h].hk_SysFunc = SetFunction(Hook[h].hk_Base,Hook[h].hk_LVO,Hook[h].hk_Entry);
      }
   Permit();
}

VOID
ClearHooks()
{
   register USHORT   h;

   Forbid();
   for(h=0; h<NEWHOOKS; h++)
      SetFunction(Hook[h].hk_Base, Hook[h].hk_LVO, Hook[h].hk_SysFunc);
   Permit();
}

