/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1986 The Software Distillery.  All Rights Reserved */
/* |. o.| || This program may not be distributed without the permission of   */
/* | .  | || the authors.                                                    */
/* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
/* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
/* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 * VERY loosely based on the input.device example by Rob Peck, 12/1/85
 */

#include "popcli.h"
#include "popbug.h"

/************************************************************************/
/* the handler subroutine - called through the handler stub             */
/************************************************************************/
struct InputEvent *
__asm
myhandler(
  register __a0 struct InputEvent *ev,  /* pointer to a list of events */
  register __a1 GLOBAL_DATA *gptr)      /* Everything we need to know  */
{
   register struct InputEvent          *ep, *laste;
   register struct OURMSG              *msg;

   /* run down the list of events to see if they pressed a magic button */
   for (ep = ev, laste = NULL; ep != NULL; ep = ep->ie_NextEvent)
   {
      if ((ep->ie_Class == IECLASS_RAWKEY)    &&
          (ep->ie_Qualifier & IEQUALIFIER_LCOMMAND) &&
	  (gptr->keytab[ep->ie_Code] != NULL))	/* if key is currently active */
      {
         /* we can handle this event so take it off the chain */
         if (laste == NULL)
            ev = ep->ie_NextEvent;
         else
            laste->ie_NextEvent = ep->ie_NextEvent;

         /* Send a message, so that ol'buddy will know what to do. */
         msg = (struct OURMSG *)
                       AllocMem( sizeof(struct OURMSG),
                                 (MEMF_CLEAR | MEMF_PUBLIC) );

         /* If we can't get memory, shut up because we can't run   */
         /* anything anyway.                                       */
         if (msg)
         {
            msg->msgpart.mn_Length = sizeof(struct OURMSG);
            msg->type = MSG_EXECUTE;
            msg->key = ep->ie_Code;

            PutMsg( gptr->execport, (struct Message *)msg );
         }
         else
            laste = ep;
      }
      else
         laste = ep;

      if (ep->ie_Class != IECLASS_TIMER)
         {
         gptr->noevents = 0;
         if (gptr->blankscreen != NULL)
            Signal(gptr->buddy, gptr->unblanksig);
         }
      }

   /* pass on the pointer to the event */
   return(ev);
}


struct MsgPort *MyCreatePort(gptr, name)
register GLOBAL_DATA *gptr;
char *name;
{
   register UBYTE sigbit;
   register struct MsgPort *port;

   if ((sigbit = AllocSignal(-1)) == -1)
      return((struct MsgPort *)0);

   if ((port = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),
                        MEMF_CLEAR|MEMF_PUBLIC)) == 0)
      {
      FreeSignal(sigbit);
      return((struct MsgPort *) (0));
      }
   port->mp_Node.ln_Name = name;
   port->mp_Node.ln_Pri = 0;
   port->mp_Node.ln_Type = NT_MSGPORT;
   port->mp_Flags = PA_SIGNAL;
   port->mp_SigBit = sigbit;
   port->mp_SigTask = (struct Task *)FindTask(0);
   AddPort(port);
   return(port);
}

void MyDeletePort(gptr, port)
register GLOBAL_DATA *gptr;
register struct MsgPort *port;
{
   RemPort(port);
   FreeSignal(port->mp_SigBit);
   FreeMem((char *)port,sizeof(struct MsgPort));
}

struct IOStdReq *CreateIOReq(gptr, port, size)
GLOBAL_DATA *gptr;
struct MsgPort *port;
int size;
{
   register struct IOStdReq *ioReq;

   if ((ioReq = (struct IOStdReq *)
                AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
      {
      ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE;
      ioReq->io_Message.mn_Node.ln_Pri  = 0;
      ioReq->io_Message.mn_Length       = size;
      ioReq->io_Message.mn_ReplyPort    = port;
      }
   return(ioReq);
}

void DeleteIOReq(gptr, ioReq)
GLOBAL_DATA *gptr;
register struct IOStdReq *ioReq;
{
   ioReq->io_Message.mn_Node.ln_Type = 0xff;
   ioReq->io_Device = (struct Device *) -1;
   ioReq->io_Unit = (struct Unit *) -1;

   FreeMem( (char *)ioReq, ioReq->io_Message.mn_Length);
}

/************************************************************************/
/* Queue a timer to go off in a given number of seconds                 */
/************************************************************************/
void QueueTimer(gptr, tr, seconds)
GLOBAL_DATA *gptr;
struct timerequest *tr;
ULONG seconds;
{
   tr->tr_node.io_Command = TR_ADDREQUEST;   /* add a new timer request */
   tr->tr_time.tv_secs =  seconds;        	/* seconds */
   tr->tr_time.tv_micro = 0;
   SendIO( (struct IORequest *)tr );
}
