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 >
C/C++ Source or Header  |  1992-06-26  |  11KB  |  598 lines

  1. #include <intuition/intuitionbase.h>
  2. #include <libraries/commodities.h>
  3. #include <exec/execbase.h>
  4. #include <exec/memory.h>
  5. #include <dos/dos.h>
  6.  
  7. #include <clib/commodities_protos.h>
  8. #include <clib/intuition_protos.h>
  9. #include <clib/exec_protos.h>
  10. #include <clib/alib_protos.h>
  11.  
  12. #define SIG_BREAK    SIGBREAKF_CTRL_C
  13. #define SIG_NOTICE    SIGBREAKF_CTRL_D
  14. #define SIG_ON        SIGBREAKF_CTRL_E
  15. #define SIG_OFF        SIGBREAKF_CTRL_F
  16.  
  17. #define NUM_PATCHES    (sizeof(PatchTable) / sizeof(struct PatchInfo))
  18.  
  19. #define JMP_ABS        0x4EF9
  20.  
  21. struct Wedge
  22. {
  23.     UWORD    Command;
  24.     APTR    Address;
  25.     UWORD    Pad;
  26. };
  27.  
  28. struct PatchInfo
  29. {
  30.     APTR         NewRoutine;
  31.     LONG         Offset;
  32.     ULONG        *Destination;
  33. };
  34.  
  35. struct WindowNode
  36. {
  37.     struct MinNode     Node;
  38.     struct Window    *Window;
  39.     UWORD        *Pointer;
  40.     BYTE         Height,
  41.              Width;
  42.     BYTE         XOffset,
  43.              YOffset;
  44.     BYTE         Off;
  45. };
  46.  
  47. extern ULONG __far         LVOClearPointer,
  48.                  LVOSetPointer,
  49.                  LVOOpenWindow,
  50.                  LVOOpenWindowTagList,
  51.                  LVOCloseWindow;
  52.  
  53. extern VOID __stdargs         StackOldSetPointer(struct Window *Window,UWORD *Pointer,WORD Height,WORD Width,WORD XOffset,WORD YOffset);
  54. extern VOID              NewSetPointer(VOID);
  55.  
  56. APTR                 OldSetPointer;
  57.  
  58. VOID            (* __asm OldClearPointer)(register __a0 struct Window *,register __a6 struct IntuitionBase *);
  59. struct Window *        (* __asm OldOpenWindowTagList)(register __a0 struct NewWindow *,register __a1 struct TagItem *,register __a6 struct IntuitionBase *);
  60. struct Window *        (* __asm OldOpenWindow)(register __a0 struct NewWindow *,register __a6 struct IntuitionBase *);
  61. VOID            (* __asm OldCloseWindow)(register __a0 struct Window *,register __a6 struct IntuitionBase *);
  62.  
  63. LONG __saveds             Main(VOID);
  64. VOID __regargs             UpdateNode(struct WindowNode *Node,struct Window *Window);
  65. struct WindowNode * __regargs     NewNode(struct Window *Window);
  66.  
  67. VOID __saveds __stdargs         BlankerAction(CxMsg *CxMessage,CxObj *CxObject);
  68. VOID                 ShutdownCx(VOID);
  69. BYTE                 SetupCx(VOID);
  70. VOID                 TurnOff(VOID);
  71. VOID                 TurnOn(VOID);
  72.  
  73. VOID __stdargs __saveds         StackNewSetPointer(struct Window *Window,UWORD *Pointer,WORD Height,WORD Width,WORD XOffset,WORD YOffset);
  74.  
  75. VOID __asm __saveds         NewClearPointer(register __a0 struct Window *Window);
  76. struct Window * __asm __saveds     NewOpenWindowTagList(register __a0 struct NewWindow *NewWindow,register __a1 struct TagItem *TagList);
  77. struct Window * __asm __saveds     NewOpenWindow(register __a0 struct NewWindow *NewWindow);
  78. VOID __asm __saveds         NewCloseWindow(register __a0 struct Window *Window);
  79.  
  80. struct ExecBase        *SysBase;
  81. struct IntuitionBase    *IntuitionBase;
  82. struct Library        *CxBase;
  83.  
  84. struct Process        *MainProcess;
  85.  
  86. struct SignalSemaphore     WindowSemaphore;
  87. struct List         WindowList;
  88.  
  89. ULONG             UseCount    = 0,
  90.              BlankCount    = 0;
  91. BYTE             AllOff        = FALSE;
  92.  
  93. struct MsgPort        *CxPort;
  94. CxObj            *Broker;
  95.  
  96. struct NewBroker NewBroker =
  97. {
  98.     NB_VERSION,
  99.     "MouseBlanker",
  100.     "Mouse Pointer Blanker v1.0",
  101.     "Mouse Pointer Blanker",
  102.     NBU_UNIQUE,
  103.     NULL,
  104.     0,NULL,0
  105. };
  106.  
  107. struct PatchInfo PatchTable[] =
  108. {
  109.     NewClearPointer,    (LONG)&LVOClearPointer,        (ULONG *)&OldClearPointer,
  110.     NewSetPointer,        (LONG)&LVOSetPointer,        (ULONG *)&OldSetPointer,
  111.     NewOpenWindowTagList,    (LONG)&LVOOpenWindowTagList,    (ULONG *)&OldOpenWindowTagList,
  112.     NewOpenWindow,        (LONG)&LVOOpenWindow,        (ULONG *)&OldOpenWindow,
  113.     NewCloseWindow,        (LONG)&LVOCloseWindow,        (ULONG *)&OldCloseWindow
  114. };
  115.  
  116. UWORD __chip BlankSprite[(2 + 1) * 2] =
  117. {
  118.     0x0000,0x0000,
  119.  
  120.     0x0000,0x0000,
  121.  
  122.     0x0000,0x0000
  123. };
  124.  
  125. LONG __saveds
  126. Main()
  127. {
  128.     LONG Result = RETURN_FAIL;
  129.  
  130.     SysBase = *(struct ExecBase **)4;
  131.  
  132.     MainProcess = (struct Process *)SysBase -> ThisTask;
  133.  
  134.     if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  135.     {
  136.         if(CxBase = OpenLibrary("commodities.library",37))
  137.         {
  138.             if(SetupCx())
  139.             {
  140.                 struct Wedge *WedgeTable;
  141.  
  142.                 if(WedgeTable = (struct Wedge *)AllocMem(sizeof(struct Wedge) * NUM_PATCHES,MEMF_ANY|MEMF_CLEAR))
  143.                 {
  144.                     struct WindowNode    *Node,
  145.                                 *Next;
  146.                     ULONG             IntuiLock,
  147.                                  SignalSet;
  148.                     struct Screen        *Screen;
  149.                     struct Window        *Window;
  150.                     BYTE             Terminated = FALSE;
  151.                     WORD             i;
  152.  
  153.                     Result = RETURN_OK;
  154.  
  155.                     InitSemaphore(&WindowSemaphore);
  156.  
  157.                     NewList(&WindowList);
  158.  
  159.                     IntuiLock = LockIBase(NULL);
  160.  
  161.                     Screen = IntuitionBase -> FirstScreen;
  162.  
  163.                     while(Screen)
  164.                     {
  165.                         Window = Screen -> FirstWindow;
  166.  
  167.                         while(Window)
  168.                         {
  169.                             NewNode(Window);
  170.  
  171.                             Window = Window -> NextWindow;
  172.                         }
  173.  
  174.                         Screen = Screen -> NextScreen;
  175.                     }
  176.  
  177.                     Forbid();
  178.  
  179.                     UnlockIBase(IntuiLock);
  180.  
  181.                     for(i = 0 ; i < NUM_PATCHES ; i++)
  182.                     {
  183.                         WedgeTable[i] . Command    = JMP_ABS;
  184.                         WedgeTable[i] . Address    = PatchTable[i] . NewRoutine;
  185.  
  186.                         *PatchTable[i] . Destination = (ULONG)SetFunction((struct Library *)IntuitionBase,PatchTable[i] . Offset,(APTR)&WedgeTable[i]);
  187.                     }
  188.  
  189.                     CacheClearU();
  190.  
  191.                     Permit();
  192.  
  193.                     while(!Terminated)
  194.                     {
  195.                         SignalSet = Wait(SIG_BREAK | SIG_ON | SIG_OFF);
  196.  
  197.                         if(SignalSet & SIG_BREAK)
  198.                             Terminated = TRUE;
  199.  
  200.                         if(SignalSet & SIG_ON)
  201.                             TurnOn();
  202.  
  203.                         if(SignalSet & SIG_OFF)
  204.                             TurnOff();
  205.                     }
  206.  
  207.                     Forbid();
  208.  
  209.                     for(i = 0 ; i < NUM_PATCHES ; i++)
  210.                         WedgeTable[i] . Address    = (APTR)*PatchTable[i] . Destination;
  211.  
  212.                     CacheClearU();
  213.  
  214.                     SetSignal(0,SIG_NOTICE);
  215.  
  216.                     Permit();
  217.  
  218.                     while(UseCount > 0)
  219.                         Wait(SIG_NOTICE);
  220.  
  221.                     TurnOn();
  222.  
  223.                     ObtainSemaphore(&WindowSemaphore);
  224.  
  225.                     Node = (struct WindowNode *)WindowList . lh_Head;
  226.  
  227.                     while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
  228.                     {
  229.                         Remove((struct Node *)Node);
  230.  
  231.                         FreeVec(Node);
  232.  
  233.                         Node = Next;
  234.                     }
  235.  
  236.                     ReleaseSemaphore(&WindowSemaphore);
  237.                 }
  238.  
  239.                 ShutdownCx();
  240.                     }
  241.         }
  242.  
  243.         CloseLibrary((struct Library *)IntuitionBase);
  244.     }
  245.  
  246.     return(Result);
  247. }
  248.  
  249. VOID __regargs
  250. UpdateNode(struct WindowNode *Node,struct Window *Window)
  251. {
  252.     Node -> Pointer    = Window -> Pointer;
  253.     Node -> Height    = Window -> PtrHeight;
  254.     Node -> Width    = Window -> PtrWidth;
  255.     Node -> XOffset    = Window -> XOffset;
  256.     Node -> YOffset    = Window -> YOffset;
  257. }
  258.  
  259. struct WindowNode * __regargs
  260. NewNode(struct Window *Window)
  261. {
  262.     struct WindowNode *Node;
  263.  
  264.     if(Node = (struct WindowNode *)AllocVec(sizeof(struct WindowNode),MEMF_PUBLIC | MEMF_CLEAR))
  265.     {
  266.         Node -> Window = Window;
  267.  
  268.         UpdateNode(Node,Window);
  269.  
  270.         AddTail(&WindowList,(struct Node *)Node);
  271.     }
  272.  
  273.     return(Node);
  274. }
  275.  
  276. struct WindowNode * __regargs
  277. FindWindow(struct Window *Window)
  278. {
  279.     struct WindowNode    *Node,
  280.                 *Next;
  281.  
  282.     Node = (struct WindowNode *)WindowList . lh_Head;
  283.  
  284.     while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
  285.     {
  286.         if(Window == Node -> Window)
  287.             return(Node);
  288.  
  289.         Node = Next;
  290.     }
  291.  
  292.     return(NULL);
  293. }
  294.  
  295. VOID __saveds __stdargs
  296. BlankerAction(CxMsg *CxMessage,CxObj *CxObject)
  297. {
  298.     struct InputEvent *Event = (struct InputEvent *)CxMsgData(CxMessage);
  299.  
  300.     switch(Event -> ie_Class)
  301.     {
  302.         case IECLASS_TIMER:    if(BlankCount++ >= 50)
  303.                     {
  304.                         BlankCount = 0;
  305.  
  306.                         Signal(MainProcess,SIG_OFF);
  307.                     }
  308.  
  309.                     break;
  310.  
  311.         case IECLASS_RAWKEY:    if(!(Event -> ie_Code & IECODE_UP_PREFIX))
  312.                         Signal(MainProcess,SIG_OFF);
  313.  
  314.                     break;
  315.  
  316.         case IECLASS_NEWPOINTERPOS:
  317.         case IECLASS_POINTERPOS:
  318.         case IECLASS_RAWMOUSE:    Signal(MainProcess,SIG_ON);
  319.                     break;
  320.  
  321.         default:        break;
  322.     }
  323. }
  324.  
  325. VOID
  326. ShutdownCx()
  327. {
  328.     if(CxPort)
  329.     {
  330.         struct Message *Message;
  331.  
  332.         if(Broker)
  333.             DeleteCxObjAll(Broker);
  334.  
  335.         RemPort(CxPort);
  336.  
  337.         while(Message = GetMsg(CxPort))
  338.             ReplyMsg(Message);
  339.  
  340.         DeleteMsgPort(CxPort);
  341.  
  342.         CxPort = NULL;
  343.         Broker = NULL;
  344.     }
  345. }
  346.  
  347. BYTE
  348. SetupCx()
  349. {
  350.     ShutdownCx();
  351.  
  352.     if(CxPort = CreateMsgPort())
  353.     {
  354.         CxPort -> mp_Node . ln_Name = NewBroker . nb_Name;
  355.  
  356.         AddPort(CxPort);
  357.  
  358.         NewBroker . nb_Port = CxPort;
  359.         NewBroker . nb_Pri  = 0;
  360.  
  361.         if(Broker = CxBroker(&NewBroker,NULL))
  362.         {
  363.             CxObj *ObjectList;
  364.  
  365.             ObjectList = CxCustom(BlankerAction,NULL);
  366.  
  367.             if(!CxObjError(ObjectList))
  368.             {
  369.                 AttachCxObj(Broker,ObjectList);
  370.  
  371.                 if(!CxObjError(Broker))
  372.                 {
  373.                     ActivateCxObj(Broker,TRUE);
  374.  
  375.                     return(TRUE);
  376.                 }
  377.             }
  378.         }
  379.     }
  380.  
  381.     ShutdownCx();
  382.  
  383.     return(FALSE);
  384. }
  385.  
  386. VOID
  387. TurnOff()
  388. {
  389.     ObtainSemaphore(&WindowSemaphore);
  390.  
  391.     if(!AllOff)
  392.     {
  393.         struct WindowNode    *Node,
  394.                     *Next;
  395.  
  396.         Node = (struct WindowNode *)WindowList . lh_Head;
  397.  
  398.         while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
  399.         {
  400.             if(!Node -> Off)
  401.             {
  402.                 UpdateNode(Node,Node -> Window);
  403.  
  404.                 StackOldSetPointer(Node -> Window,BlankSprite,1,16,0,0);
  405.  
  406.                 Node -> Off = TRUE;
  407.             }
  408.  
  409.             Node = Next;
  410.         }
  411.  
  412.         AllOff = TRUE;
  413.     }
  414.  
  415.     ReleaseSemaphore(&WindowSemaphore);
  416. }
  417.  
  418. VOID
  419. TurnOn()
  420. {
  421.     struct WindowNode    *Node,
  422.                 *Next;
  423.  
  424.     ObtainSemaphore(&WindowSemaphore);
  425.  
  426.     AllOff = FALSE;
  427.  
  428.     BlankCount = 0;
  429.  
  430.     Node = (struct WindowNode *)WindowList . lh_Head;
  431.  
  432.     while(Next = (struct WindowNode *)Node -> Node . mln_Succ)
  433.     {
  434.         if(Node -> Off)
  435.         {
  436.             if(Node -> Pointer)
  437.                 StackOldSetPointer(Node -> Window,Node -> Pointer,Node -> Height,Node -> Width,Node -> XOffset,Node -> YOffset);
  438.             else
  439.                 OldClearPointer(Node -> Window,IntuitionBase);
  440.  
  441.             Node -> Off = FALSE;
  442.         }
  443.  
  444.         Node = Next;
  445.     }
  446.  
  447.     ReleaseSemaphore(&WindowSemaphore);
  448. }
  449.  
  450. VOID __asm __saveds
  451. NewClearPointer(register __a0 struct Window *Window)
  452. {
  453.     struct WindowNode *Node;
  454.  
  455.     ObtainSemaphore(&WindowSemaphore);
  456.  
  457.     UseCount++;
  458.  
  459.     if(Node = FindWindow(Window))
  460.     {
  461.         if(!AllOff)
  462.         {
  463.             OldClearPointer(Window,IntuitionBase);
  464.  
  465.             Node -> Off = FALSE;
  466.         }
  467.         else
  468.             Node -> Off = TRUE;
  469.  
  470.         Node -> Pointer = NULL;
  471.     }
  472.     else
  473.         OldClearPointer(Window,IntuitionBase);
  474.  
  475.     UseCount--;
  476.  
  477.     Signal(MainProcess,SIG_NOTICE);
  478.  
  479.     ReleaseSemaphore(&WindowSemaphore);
  480. }
  481.  
  482. VOID __stdargs __saveds
  483. StackNewSetPointer(struct Window *Window,UWORD *Pointer,WORD Height,WORD Width,WORD XOffset,WORD YOffset)
  484. {
  485.     struct WindowNode *Node;
  486.  
  487.     ObtainSemaphore(&WindowSemaphore);
  488.  
  489.     UseCount++;
  490.  
  491.     if(Node = FindWindow(Window))
  492.     {
  493.         if(!AllOff)
  494.         {
  495.             StackOldSetPointer(Window,Pointer,Height,Width,XOffset,YOffset);
  496.  
  497.             Node -> Off = FALSE;
  498.         }
  499.         else
  500.             Node -> Off = TRUE;
  501.  
  502.         Node -> Pointer    = Pointer;
  503.         Node -> Height    = Height;
  504.         Node -> Width    = Width;
  505.         Node -> XOffset    = XOffset;
  506.         Node -> YOffset    = YOffset;
  507.     }
  508.     else
  509.         StackOldSetPointer(Window,Pointer,Height,Width,XOffset,YOffset);
  510.  
  511.     UseCount--;
  512.  
  513.     Signal(MainProcess,SIG_NOTICE);
  514.  
  515.     ReleaseSemaphore(&WindowSemaphore);
  516. }
  517.  
  518. struct Window * __asm __saveds
  519. NewOpenWindowTagList(register __a0 struct NewWindow *NewWindow,register __a1 struct TagItem *TagList)
  520. {
  521.     struct Window    *Window;
  522.     ULONG         Signals;
  523.  
  524.     ObtainSemaphore(&WindowSemaphore);
  525.  
  526.     UseCount++;
  527.  
  528.     if(Window = OldOpenWindowTagList(NewWindow,TagList,IntuitionBase))
  529.     {
  530.         NewNode(Window);
  531.  
  532.         Signals = SIG_NOTICE | SIG_ON;
  533.     }
  534.     else
  535.         Signals = SIG_NOTICE;
  536.  
  537.     UseCount--;
  538.  
  539.     Signal(MainProcess,Signals);
  540.  
  541.     ReleaseSemaphore(&WindowSemaphore);
  542.  
  543.     return(Window);
  544. }
  545.  
  546. struct Window * __asm __saveds
  547. NewOpenWindow(register __a0 struct NewWindow *NewWindow)
  548. {
  549.     struct Window    *Window;
  550.     ULONG         Signals;
  551.  
  552.     ObtainSemaphore(&WindowSemaphore);
  553.  
  554.     UseCount++;
  555.  
  556.     if(Window = OldOpenWindow(NewWindow,IntuitionBase))
  557.     {
  558.         NewNode(Window);
  559.  
  560.         Signals = SIG_NOTICE | SIG_ON;
  561.     }
  562.     else
  563.         Signals = SIG_NOTICE;
  564.  
  565.     UseCount--;
  566.  
  567.     Signal(MainProcess,Signals);
  568.  
  569.     ReleaseSemaphore(&WindowSemaphore);
  570.  
  571.     return(Window);
  572. }
  573.  
  574. VOID __asm __saveds
  575. NewCloseWindow(register __a0 struct Window *Window)
  576. {
  577.     struct WindowNode *Node;
  578.  
  579.     ObtainSemaphore(&WindowSemaphore);
  580.  
  581.     UseCount++;
  582.  
  583.     if(Node = FindWindow(Window))
  584.     {
  585.         Remove((struct Node *)Node);
  586.  
  587.         FreeVec(Node);
  588.     }
  589.  
  590.     OldCloseWindow(Window,IntuitionBase);
  591.  
  592.     UseCount--;
  593.  
  594.     Signal(MainProcess,SIG_NOTICE);
  595.  
  596.     ReleaseSemaphore(&WindowSemaphore);
  597. }
  598.