/*
 *  CALC      Provides a calculator that opens on the active screen when
 *            you press a specific key sequence.  Otherwise, the program
 *            waits quitely in the background.
 *
 *              Copyright 1989 by Davide P. Cervone.
 *  You may use this code, provided this copyright notice is kept intact.
 */

#define INTUITION_PREFERENCES_H         /* don't need 'em */
#include <intuition/intuitionbase.h>
#include <devices/input.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>

#include "cHandler.h"
#include "cSetup.h"

#ifndef SWINDOWS
#define CLOSEDELAY      5
static APTR CloseTask;          /* The task that asked to close the window
                                   were the calculator is currently open */
#endif

UWORD KeyCode;                  /* The keycode to activate the calculator */
UWORD Qualifiers;               /*   and required qualifiers */


/*
 *  myHandler()
 *
 *  The input handler that looks for the keypress that brings up the
 *  calculator.  It scans the input event list for RAWKEY events that
 *  match the given keycode.  If the qualifiers match, and the active 
 *  screen is not the one containing the calculator (or the calculator
 *  is not open) then signal the calc task to open the calculator on 
 *  the active screen and removes the event from the EventList.
 */

struct InputEvent *myHandler(EventList,data)
struct InputEvent *EventList;
APTR data;
{
   struct InputEvent **EventPtr = &EventList;
   struct InputEvent *theEvent;
   
   while ((theEvent = *EventPtr) != NULL)
   {
      if (theEvent->ie_Class == IECLASS_RAWKEY &&
          theEvent->ie_Code  == KeyCode &&
         (theEvent->ie_Qualifier & Qualifiers) == Qualifiers &&
          IntuitionBase->ActiveScreen != CalcScreen)
      {
         Signal(CalcTask,CalcSMask);
         *EventPtr =   theEvent->ie_NextEvent;
      } else {
          EventPtr = &(theEvent->ie_NextEvent);
      }
   }
   return(EventList);
}


/*
 *  cCloseScreen()
 *
 *  Our replacement CloseScreen routine, called before the real CloseScreen.
 *  If the screen is the one containing the calculator and the calculator
 *  is open, and there is not already a task waiting to be signaled, then 
 *  get the current task pointer, and clear the CLOSESIGNAL.  Signal the
 *  calculator to close since the screen is about to close.  Wait for
 *  the CalcTask to signal us that the calculator is closed.  Now it is
 *  safe to close the screen.
 */

#ifndef SWINDOWS
void cCloseScreen(theScreen)
struct Screen *theScreen;
{
   extern APTR FindTask();

   if (theScreen == CalcScreen && CalcWindow && CloseTask == NULL)
   {
      CloseTask = FindTask(NULL);
      SetSignal(0L,CLOSESIGNAL);
      Signal(CalcTask,CalcCMask);
      Wait(CLOSESIGNAL);
      CloseTask = NULL;
   }
}

void SignalClosed()
{
   if (CloseTask)
   {
      Delay(CLOSEDELAY);
      Signal(CloseTask,CLOSESIGNAL);
   }
}
#endif
