/* ByeMouse.c 
 *
 *    Author:  Ralph Ciper
 *   Written:  August, 1989
 * Copyright:  None, Placed in Public Domain by Author 
 *
 *   Compile:  LC -rr -b -O -v -y ByeMouse
 *      Link:  BLINK FROM ByeMouse.o TO ByeMouse SMALLCODE SMALLDATA
 *       Run:  Run <NIL: >NIL: ByeMouse
 *      
 */
 
#include <proto/exec.h>
#include <exec/memory.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/dos.h>

/*  set time limit to 300 ticks (5 secs @60hz / 6 secs @ 50hz) */
#define LIMIT 300

/*  hardware address of mouse position counter */

#define MOUSE_POS *(volatile long *)0xDFF00A

int ByeMouse(int,char *);

int ByeMouse(int argl,char *arg)
{
   struct Preferences   prefs;
   USHORT               oldptr[POINTERSIZE+4];
   USHORT              *np,*op,hold;
   long                 oldpos,newpos;
   int                  count,i;
   int                  cleared,stagnant;
   struct IntuitionBase *IntuitionBase;
   struct GfxBase       *GfxBase;
   struct DOSBase       *DOSBase;
   struct Task          *task;     
   char                  Name[29] = "ByeMouse 1.1, by Ralph Ciper";   
   BPTR                  fh;
   
   IntuitionBase = OpenLibrary("intuition.library",NULL);
   GfxBase       = OpenLibrary("graphics.library",NULL);
   DOSBase       = OpenLibrary("dos.library",NULL);

   if (argl)
   {  
      fh = Output(); 
      if (fh) Write(fh,Name,28);
   } else fh = NULL;
     
   if (argl == NULL || *arg != '*')
   {
      task = FindTask(Name);
      if (task) 
      {
         *(int *)(task->tc_SPLower+4) = TRUE;
         if (fh) Write(fh,"--Cancelled\n",12);
         return NULL;
      }  
      if (*arg == '-') 
      { 
         if (fh) Write(fh,"--Not Found\n",12);
         return NULL;
      }
   } 
     
   op = oldptr;
   for(count=0; count<POINTERSIZE+4; count++) *op++ = NULL;
 
   oldpos= MOUSE_POS;
   count = LIMIT;
   np    = NULL;
    
   cleared = FALSE;
   task = FindTask(NULL);
   *(int *)(task->tc_SPLower+4) = FALSE;

   if (fh) Write(fh,"\n",1);
   task->tc_Node.ln_Name = Name;
   while (*(int *)(task->tc_SPLower+4) == FALSE || cleared)
   {
      WaitTOF();
      newpos = MOUSE_POS;
      stagnant = (newpos==oldpos);
      if (stagnant) stagnant = ( count++ >LIMIT);
      else { oldpos = newpos; stagnant = NULL; count =  NULL; }
         
      if (*(int *)(task->tc_SPLower+4)) stagnant = FALSE;

      if ((!stagnant) ^ (!cleared))
      {
         Forbid();
         GetPrefs(&prefs,sizeof(struct Preferences));
         np = prefs.PointerMatrix;
         op = oldptr;
         for(i=0; i<POINTERSIZE+4; i++)
         {
            hold = *op;
            *op++ = *np;
            *np++ = hold;
         }
         SetPrefs(&prefs,sizeof(struct Preferences),TRUE);
         Permit();
         cleared = stagnant;
      }
   }
   task->tc_Node.ln_Name = NULL;
   return NULL;
}

