/*
 * handler.c - the input handler that holds the RMB and cycles windows
 *
 * Bruno Costa - 16 Sep 89 - 16 Jan 91
 *
 */

#include <exec/types.h>
#include <devices/inputevent.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include "hold.h"

extern struct IntuitionBase *IntuitionBase;

/*
 *  input handler
 */
struct InputEvent *
__saveds __asm handler ( register __a0 struct InputEvent *head,
                         register __a1 struct handlerdata *data
                       )
{
 register struct InputEvent *ep, *old;
 int delink, prelink;
 static struct { ULONG sec, micro; int x, y; } last;

 delink = prelink = OFF;
 ep = old = head;

 while (ep != NULL)
 {
   if (ep->ie_Class == IECLASS_RAWMOUSE)
   {
     switch (ep->ie_Code)
     {
       case IECODE_RBUTTON:			/* right button down */
         if (data->hold)
           if (data->ignore)
           {
             data->ignore = OFF;
             delink = ON;
           }
           else
           {
             data->ignore = ON;
             last.x = ep->ie_X;
             last.y = ep->ie_Y;
             last.sec = ep->ie_TimeStamp.tv_secs;
             last.micro = ep->ie_TimeStamp.tv_micro;
           }
         break;

       case IECODE_RBUTTON | IECODE_UP_PREFIX:	/* right button up */
         if (data->hold && data->ignore)
         {
           if ( (abs (last.x - ep->ie_X) < DCLICKERR)	&&
                (abs (last.y - ep->ie_Y) < DCLICKERR)	&&
                DoubleClick (last.sec, last.micro,
                             ep->ie_TimeStamp.tv_secs, ep->ie_TimeStamp.tv_micro) )
             delink = ON;
           else
             data->ignore = OFF;
         }
         break;

       case IECODE_LBUTTON | IECODE_UP_PREFIX:	/* left button up */
       case IECODE_LBUTTON:			/* left button down */
         if (data->hold && data->ignore)
         {
           data->ignore = OFF;
           prelink = ON;
           data->event.ie_Class     = IECLASS_RAWMOUSE;
           data->event.ie_SubClass  = 0;
           data->event.ie_Code      = IECODE_RBUTTON | IECODE_UP_PREFIX;
           data->event.ie_Qualifier = 0;
           data->event.ie_X = 0;
           data->event.ie_Y = 0;
           data->event.ie_TimeStamp.tv_secs  = ep->ie_TimeStamp.tv_secs;
           data->event.ie_TimeStamp.tv_micro = ep->ie_TimeStamp.tv_micro - 1;
         }
         break;

       case IECODE_NOBUTTON:		/* mouse movement */
         data->count = 0;
         data->activated = FALSE;
         break;
     }
   }
   else if (data->activate)
     if (data->activated == FALSE  &&  ep->ie_Class == IECLASS_TIMER)
       if (++data->count > data->maxtime)
       {
         Signal (data->task, data->actmask);
         data->activated = TRUE;
       }

   if (delink)
   {
     delink = OFF;
     if (ep == head)
       old = ep = head = head->ie_NextEvent;
     else
       ep = old->ie_NextEvent = ep->ie_NextEvent;
   }
   else
   {
     if (prelink)
     {
       prelink = OFF;
       data->event.ie_NextEvent = ep;
       if (ep == head)
         head = &data->event;
       else
         old->ie_NextEvent = &data->event;
     }
     old = ep;
     ep = ep->ie_NextEvent;
   }
 }

 return (head);
}
