/* This patch is a quite ugly way to solve the problem
** that occurs when Intuition tries to draw something
** in a screen which has it's layers locked.
** The problem is solved by disabling dangerous functions.
** Some functions remain because they require more work.
** An example of this is OpenWindow(), since OpenWindow()
** can't be as easily ignored as the functions that ARE
** patched here. OpenWindow() would require some sort of
** semaphore locking and waiting - and so we're back where
** we started.
*/

typedef VOID (*FPTR)();

IMPORT struct IntuitionBase *IntuitionBase;
#define LVOWindowToBack   -0x0132L
#define LVOWindowToFront  -0x0138L
#define LVOActivateWindow -0x01c2L

VOID myActivateWindow(), myWindowToFront(), myWindowToBack();

LONG oldActivateWindow, oldWindowToFront, oldWindowToBack;

STATIC WORD patched = 0;

VOID SafePatch()
{
    if (!patched) {
        Forbid();     /* I don't expect interrupts to do much intuition */
        oldActivateWindow = (LONG)SetFunction((struct Library *)IntuitionBase,
          LVOActivateWindow, (FPTR)myActivateWindow);
        oldWindowToFront = (LONG)SetFunction((struct Library *)IntuitionBase,
          LVOWindowToFront, (FPTR)myWindowToFront);
        oldWindowToBack =  (LONG)SetFunction((struct Library *)IntuitionBase,
          LVOWindowToBack, (FPTR)myWindowToBack);
        Permit();
        patched = 1;
    }
}

VOID SafeRestore()
{
    if (patched) {
        Forbid();
        (VOID)SetFunction((struct Library *)IntuitionBase,
          LVOActivateWindow, (FPTR)oldActivateWindow);
        (VOID)SetFunction((struct Library *)IntuitionBase,
          LVOWindowToFront, (FPTR)oldWindowToFront);
        (VOID)SetFunction((struct Library *)IntuitionBase,
          LVOWindowToBack, (FPTR)oldWindowToBack);
        Permit();
        patched = 0;
    }
}
