home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_progs
/
fract
/
fracblnk.lha
/
MouseBlanker.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-26
|
11KB
|
598 lines
#include <intuition/intuitionbase.h>
#include <libraries/commodities.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <clib/commodities_protos.h>
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#define SIG_BREAK SIGBREAKF_CTRL_C
#define SIG_NOTICE SIGBREAKF_CTRL_D
#define SIG_ON SIGBREAKF_CTRL_E
#define SIG_OFF SIGBREAKF_CTRL_F
#define NUM_PATCHES (sizeof(PatchTable) / sizeof(struct PatchInfo))
#define JMP_ABS 0x4EF9
struct Wedge
{
UWORD Command;
APTR Address;
UWORD Pad;
};
struct PatchInfo
{
APTR NewRoutine;
LONG Offset;
ULONG *Destination;
};
struct WindowNode
{
struct MinNode Node;
struct Window *Window;
UWORD *Pointer;
BYTE Height,
Width;
BYTE XOffset,
YOffset;
BYTE Off;
};
extern ULONG __far LVOClearPointer,
LVOSetPointer,
LVOOpenWindow,
LVOOpenWindowTagList,
LVOCloseWindow;
extern VOID __stdargs StackOldSetPointer(struct Window *Window,UWORD *Pointer,WORD Height,WORD Width,WORD XOffset,WORD YOffset);
extern VOID NewSetPointer(VOID);
APTR OldSetPointer;
VOID (* __asm OldClearPointer)(register __a0 struct Window *,register __a6 struct IntuitionBase *);
struct Window * (* __asm OldOpenWindowTagList)(register __a0 struct NewWindow *,register __a1 struct TagItem *,register __a6 struct IntuitionBase *);
struct Window * (* __asm OldOpenWindow)(register __a0 struct NewWindow *,register __a6 struct IntuitionBase *);
VOID (* __asm OldCloseWindow)(register __a0 struct Window *,register __a6 struct IntuitionBase *);
LONG __saveds Main(VOID);
VOID __regargs UpdateNode(struct WindowNode *Node,struct Window *Window);
struct WindowNode * __regargs NewNode(struct Window *Window);
VOID __saveds __stdargs BlankerAction(CxMsg *CxMessage,CxObj *CxObject);
VOID ShutdownCx(VOID);
BYTE SetupCx(VOID);
VOID TurnOff(VOID);
VOID TurnOn(VOID);
VOID __stdargs __saveds StackNewSetPointer(struct Window *Window,UWORD *Pointer,WORD Height,WORD Width,WORD XOffset,WORD YOffset);
VOID __asm __saveds NewClearPointer(register __a0 struct Window *Window);
struct Window * __asm __saveds NewOpenWindowTagList(register __a0 struct NewWindow *NewWindow,register __a1 struct TagItem *TagList);
struct Window * __asm __saveds NewOpenWindow(register __a0 struct NewWindow *NewWindow);
VOID __asm __saveds NewCloseWindow(register __a0 struct Window *Window);
struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase;
struct Library *CxBase;
struct Process *MainProcess;
struct SignalSemaphore WindowSemaphore;
struct List WindowList;
ULONG UseCount = 0,
BlankCount = 0;
BYTE AllOff = FALSE;
struct MsgPort *CxPort;
CxObj *Broker;
struct NewBroker NewBroker =
{
NB_VERSION,
"MouseBlanker",
"Mouse Pointer Blanker v1.0",
"Mouse Pointer Blanker",
NBU_UNIQUE,
NULL,
0,NULL,0
};
struct PatchInfo PatchTable[] =
{
NewClearPointer, (LONG)&LVOClearPointer, (ULONG *)&OldClearPointer,
NewSetPointer, (LONG)&LVOSetPointer, (ULONG *)&OldSetPointer,
NewOpenWindowTagList, (LONG)&LVOOpenWindowTagList, (ULONG *)&OldOpenWindowTagList,
NewOpenWindow, (LONG)&LVOOpenWindow, (ULONG *)&OldOpenWindow,
NewCloseWindow, (LONG)&LVOCloseWindow, (ULONG *)&OldCloseWindow
};
UWORD __chip BlankSprite[(2 + 1) * 2] =
{
0x0000,0x0000,
0x0000,0x0000,
0x0000,0x0000
};
LONG __saveds
Main()
{
LONG Result = RETURN_FAIL;
SysBase = *(struct ExecBase **)4;
MainProcess = (struct Process *)SysBase -> ThisTask;
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
{
if(CxBase = OpenLibrary("commodities.library",37))
{
if(SetupCx())
{
struct Wedge *WedgeTable;
if(WedgeTable = (struct Wedge *)AllocMem(sizeof(struct Wedge) * NUM_PATCHES,MEMF_ANY|MEMF_CLEAR))
{
struct WindowNode *Node,
*Next;
ULONG IntuiLock,
SignalSet;
struct Screen *Screen;
struct Window *Window;
BYTE Terminated = FALSE;
WORD i;
Result = RETURN_OK;
InitSemaphore(&WindowSemaphore);
NewList(&WindowList);
IntuiLock = LockIBase(NULL);
Screen = IntuitionBase -> FirstScreen;
while(Screen)
{
Window = Screen -> FirstWindow;
while(Window)
{
NewNode(Window);
Window = Window -> NextWindow;
}
Screen = Screen -> NextScreen;
}
Forbid();
UnlockIBase(IntuiLock);
for(i = 0 ; i < NUM_PATCHES ; i++)
{
WedgeTable[i] . Command = JMP_ABS;
WedgeTable[i] . Address = PatchTable[i] . NewRoutine;
*PatchTable[i] . Destination = (ULONG)SetFunction((struct Library *)IntuitionBase,PatchTable[i] . Offset,(APTR)&WedgeTable[i]);
}
CacheClearU();
Permit();
while(!Terminated)
{
SignalSet = Wait(SIG_BREAK | SIG_ON | SIG_OFF);
if(SignalSet & SIG_BREAK)
Terminated = TRUE;
if(SignalSet & SIG_ON)
TurnOn();
if(SignalSet & SIG_OFF)
TurnOff();
}
Forbid();
for(i = 0 ; i < NUM_PATCHES ; i++)
WedgeTable[i] . Address = (APTR)*PatchTable[i] . Destination;
CacheClearU();
SetSignal(0,SIG_NOTICE);
Permit();
while(UseCount > 0)
Wait(SIG_NOTICE);
TurnOn();
ObtainSemaphore(&WindowSemaphore);
Node = (struct WindowNode *)WindowList . lh_Head;
while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
{
Remove((struct Node *)Node);
FreeVec(Node);
Node = Next;
}
ReleaseSemaphore(&WindowSemaphore);
}
ShutdownCx();
}
}
CloseLibrary((struct Library *)IntuitionBase);
}
return(Result);
}
VOID __regargs
UpdateNode(struct WindowNode *Node,struct Window *Window)
{
Node -> Pointer = Window -> Pointer;
Node -> Height = Window -> PtrHeight;
Node -> Width = Window -> PtrWidth;
Node -> XOffset = Window -> XOffset;
Node -> YOffset = Window -> YOffset;
}
struct WindowNode * __regargs
NewNode(struct Window *Window)
{
struct WindowNode *Node;
if(Node = (struct WindowNode *)AllocVec(sizeof(struct WindowNode),MEMF_PUBLIC | MEMF_CLEAR))
{
Node -> Window = Window;
UpdateNode(Node,Window);
AddTail(&WindowList,(struct Node *)Node);
}
return(Node);
}
struct WindowNode * __regargs
FindWindow(struct Window *Window)
{
struct WindowNode *Node,
*Next;
Node = (struct WindowNode *)WindowList . lh_Head;
while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
{
if(Window == Node -> Window)
return(Node);
Node = Next;
}
return(NULL);
}
VOID __saveds __stdargs
BlankerAction(CxMsg *CxMessage,CxObj *CxObject)
{
struct InputEvent *Event = (struct InputEvent *)CxMsgData(CxMessage);
switch(Event -> ie_Class)
{
case IECLASS_TIMER: if(BlankCount++ >= 50)
{
BlankCount = 0;
Signal(MainProcess,SIG_OFF);
}
break;
case IECLASS_RAWKEY: if(!(Event -> ie_Code & IECODE_UP_PREFIX))
Signal(MainProcess,SIG_OFF);
break;
case IECLASS_NEWPOINTERPOS:
case IECLASS_POINTERPOS:
case IECLASS_RAWMOUSE: Signal(MainProcess,SIG_ON);
break;
default: break;
}
}
VOID
ShutdownCx()
{
if(CxPort)
{
struct Message *Message;
if(Broker)
DeleteCxObjAll(Broker);
RemPort(CxPort);
while(Message = GetMsg(CxPort))
ReplyMsg(Message);
DeleteMsgPort(CxPort);
CxPort = NULL;
Broker = NULL;
}
}
BYTE
SetupCx()
{
ShutdownCx();
if(CxPort = CreateMsgPort())
{
CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
AddPort(CxPort);
NewBroker . nb_Port = CxPort;
NewBroker . nb_Pri = 0;
if(Broker = CxBroker(&NewBroker,NULL))
{
CxObj *ObjectList;
ObjectList = CxCustom(BlankerAction,NULL);
if(!CxObjError(ObjectList))
{
AttachCxObj(Broker,ObjectList);
if(!CxObjError(Broker))
{
ActivateCxObj(Broker,TRUE);
return(TRUE);
}
}
}
}
ShutdownCx();
return(FALSE);
}
VOID
TurnOff()
{
ObtainSemaphore(&WindowSemaphore);
if(!AllOff)
{
struct WindowNode *Node,
*Next;
Node = (struct WindowNode *)WindowList . lh_Head;
while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
{
if(!Node -> Off)
{
UpdateNode(Node,Node -> Window);
StackOldSetPointer(Node -> Window,BlankSprite,1,16,0,0);
Node -> Off = TRUE;
}
Node = Next;
}
AllOff = TRUE;
}
ReleaseSemaphore(&WindowSemaphore);
}
VOID
TurnOn()
{
struct WindowNode *Node,
*Next;
ObtainSemaphore(&WindowSemaphore);
AllOff = FALSE;
BlankCount = 0;
Node = (struct WindowNode *)WindowList . lh_Head;
while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
{
if(Node -> Off)
{
if(Node -> Pointer)
StackOldSetPointer(Node -> Window,Node -> Pointer,Node -> Height,Node -> Width,Node -> XOffset,Node -> YOffset);
else
OldClearPointer(Node -> Window,IntuitionBase);
Node -> Off = FALSE;
}
Node = Next;
}
ReleaseSemaphore(&WindowSemaphore);
}
VOID __asm __saveds
NewClearPointer(register __a0 struct Window *Window)
{
struct WindowNode *Node;
ObtainSemaphore(&WindowSemaphore);
UseCount++;
if(Node = FindWindow(Window))
{
if(!AllOff)
{
OldClearPointer(Window,IntuitionBase);
Node -> Off = FALSE;
}
else
Node -> Off = TRUE;
Node -> Pointer = NULL;
}
else
OldClearPointer(Window,IntuitionBase);
UseCount--;
Signal(MainProcess,SIG_NOTICE);
ReleaseSemaphore(&WindowSemaphore);
}
VOID __stdargs __saveds
StackNewSetPointer(struct Window *Window,UWORD *Pointer,WORD Height,WORD Width,WORD XOffset,WORD YOffset)
{
struct WindowNode *Node;
ObtainSemaphore(&WindowSemaphore);
UseCount++;
if(Node = FindWindow(Window))
{
if(!AllOff)
{
StackOldSetPointer(Window,Pointer,Height,Width,XOffset,YOffset);
Node -> Off = FALSE;
}
else
Node -> Off = TRUE;
Node -> Pointer = Pointer;
Node -> Height = Height;
Node -> Width = Width;
Node -> XOffset = XOffset;
Node -> YOffset = YOffset;
}
else
StackOldSetPointer(Window,Pointer,Height,Width,XOffset,YOffset);
UseCount--;
Signal(MainProcess,SIG_NOTICE);
ReleaseSemaphore(&WindowSemaphore);
}
struct Window * __asm __saveds
NewOpenWindowTagList(register __a0 struct NewWindow *NewWindow,register __a1 struct TagItem *TagList)
{
struct Window *Window;
ULONG Signals;
ObtainSemaphore(&WindowSemaphore);
UseCount++;
if(Window = OldOpenWindowTagList(NewWindow,TagList,IntuitionBase))
{
NewNode(Window);
Signals = SIG_NOTICE | SIG_ON;
}
else
Signals = SIG_NOTICE;
UseCount--;
Signal(MainProcess,Signals);
ReleaseSemaphore(&WindowSemaphore);
return(Window);
}
struct Window * __asm __saveds
NewOpenWindow(register __a0 struct NewWindow *NewWindow)
{
struct Window *Window;
ULONG Signals;
ObtainSemaphore(&WindowSemaphore);
UseCount++;
if(Window = OldOpenWindow(NewWindow,IntuitionBase))
{
NewNode(Window);
Signals = SIG_NOTICE | SIG_ON;
}
else
Signals = SIG_NOTICE;
UseCount--;
Signal(MainProcess,Signals);
ReleaseSemaphore(&WindowSemaphore);
return(Window);
}
VOID __asm __saveds
NewCloseWindow(register __a0 struct Window *Window)
{
struct WindowNode *Node;
ObtainSemaphore(&WindowSemaphore);
UseCount++;
if(Node = FindWindow(Window))
{
Remove((struct Node *)Node);
FreeVec(Node);
}
OldCloseWindow(Window,IntuitionBase);
UseCount--;
Signal(MainProcess,SIG_NOTICE);
ReleaseSemaphore(&WindowSemaphore);
}