Source/EventHandler.cp

/*
    File:       EventHandler.cp
 
    Contains:   xxx put contents here xxx
 
    Version:    xxx put version here xxx
 
    Copyright:  © 1999 by Apple Computer, Inc., all rights reserved.
 
    File Ownership:
 
        DRI:                xxx put dri here xxx
 
        Other Contact:      xxx put other contact here xxx
 
        Technology:         xxx put technology here xxx
 
    Writers:
 
        (BWS)   Brent Schorsch
 
    Change History (most recent first):
 
       <SP1>      7/1/99    BWS     first checked in
*/
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    Includes
 
#include <DiskInit.h>
#include <Menus.h>
#include <ToolUtils.h>
#include <Windows.h>
 
#include "AppleEventHandler.h"
#include "EventHandler.h"
#include "MainWindow.h"
#include "MenuHandler.h"
#include "ShellWindow.h"
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    Private Definitions
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    Private Types
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    Private Variables
 
static SInt16   gSleepTime;
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    Private Functions
 
static void EventDispatch(const EventRecord *inEvent);
static Boolean DefaultMouseDown(const EventRecord *inEvent);
static Boolean DefaultKeyDown(const EventRecord *inEvent);
static Boolean DoDiskEvent(const EventRecord *inEvent);
static void DoSuspend(void);
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    Public Variables
 
Boolean             gDone = false;
EventHandlerSet     gEventHandlers;
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    EventInit
 
short
EventInit(void)
{
SInt16      modifiers = 0;
EventRecord dummy;
 
    EventAvail(everyEvent, &dummy);
    modifiers |= dummy.modifiers;
    EventAvail(everyEvent, &dummy);
    modifiers |= dummy.modifiers;
    EventAvail(everyEvent, &dummy);
    modifiers |= dummy.modifiers;
 
    RegisterEventHandlers(nil, nil, nil, nil, nil);
    gEventHandlers.diskHandler = DoDiskEvent;
 
    gSleepTime = 32767;
    
    AppleEventsRegisterQuitFlag(&gDone);
 
    new MainWindow;
 
    return (modifiers);
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    EventLoop
 
void
EventLoop(void)
{
EventRecord theEvent;
 
    while (false == gDone)
    {
        WaitNextEvent(everyEvent, &theEvent, gSleepTime, nil);
        EventDispatch(&theEvent);
    }
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    EventDispatch
 
static void
EventDispatch(const EventRecord *inEvent)
{
WindowPtr   theWindow;
 
    switch (inEvent->what)
    {
        case nullEvent:
            //¥ Run any idle tasks
            if (gEventHandlers.idleHandler)
                (*gEventHandlers.idleHandler)(inEvent);
 
            theWindow = FrontWindow();
            if (nil != theWindow)
            {
                if (userKind == GetWindowKind(theWindow))
                {
                ShellWindow *myWindow;
                
                    myWindow = (ShellWindow *) GetWRefCon(theWindow);
                    if (nil != myWindow)
                        myWindow->Idle();
                }
            }
            break;
 
        case mouseDown:
            if (gEventHandlers.clickHandler != nil)
                if ((*gEventHandlers.clickHandler)(inEvent))
                {
                    break;
                }
 
            DefaultMouseDown(inEvent);
            break;
 
        case keyDown:
            if (gEventHandlers.keyHandler != nil)
                if ((*gEventHandlers.keyHandler)(inEvent))
                {
                    break;
                }
 
            DefaultKeyDown(inEvent);
            break;
 
        case autoKey:
            if (gEventHandlers.autoKeyHandler != nil)
                if ((*gEventHandlers.autoKeyHandler)(inEvent))
                {
                    break;
                }
 
            DefaultKeyDown(inEvent);
            break;
 
        case activateEvt:
        {
        WindowPtr   theWindow;
        
            theWindow = (WindowPtr) inEvent->message;
            if (userKind == GetWindowKind(theWindow))
            {
            ShellWindow *myWindow;
            
                myWindow = (ShellWindow *) GetWRefCon(theWindow);
                
                if (nil != myWindow)
                    myWindow->Activate((inEvent->modifiers & activeFlag) ? true : false);
            }
        }
        break;
 
        case updateEvt:
        {
        WindowPtr   theWindow;
        
            theWindow = (WindowPtr) inEvent->message;
            if (userKind == GetWindowKind(theWindow))
            {
            ShellWindow *myWindow;
            
                myWindow = (ShellWindow *) GetWRefCon(theWindow);
                if (nil != myWindow)
                    myWindow->Update();
            }
        }
        break;
 
        case diskEvt:
            if (gEventHandlers.diskHandler != nil)
                (*gEventHandlers.diskHandler)(inEvent);
            break;
 
        case osEvt:
            if (inEvent->message & 0x01000000)      //¥ Suspend/resume event
            {
                ShellWindow * myWindow = nil;
                
                theWindow = FrontWindow();
                if (nil != theWindow)
                {
                    if (userKind == GetWindowKind(theWindow))
                    {
                        myWindow = (ShellWindow *) GetWRefCon(theWindow);
                    }
                }
 
 
                if (inEvent->message & 0x00000001)  //¥ Resume
                {
                    if (nil != myWindow)
                        myWindow->Resume();
                }
                else
                {
                    if (nil != myWindow)
                        myWindow->Suspend();
                    //DoSuspend();                  //¥ Suspend
                }
            }
            break;
 
        case kHighLevelEvent:
            AEProcessAppleEvent(inEvent);
            break;
    }
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    DefaultMouseDown
 
static Boolean
DefaultMouseDown(const EventRecord *inEvent)
{
SInt16              whatPart;
SInt32              menuResult;
WindowPtr           whichWindow;
ShellWindow         *myWindow = nil;
 
    whatPart = FindWindow(inEvent->where, &whichWindow);
    
    if (userKind == GetWindowKind(whichWindow))
        myWindow = (ShellWindow *) GetWRefCon(whichWindow);
 
    switch (whatPart)
    {
        case inDrag:
            if (nil != myWindow)
                myWindow->Drag(inEvent->where, inEvent->modifiers);
            break;
            
        case inGoAway:
            if (TrackGoAway(whichWindow, inEvent->where))
            {
                if (nil != myWindow)
                {
                    myWindow->Close();
                    delete myWindow;
                    gDone = true;
                }
            }
            break;
 
        case inZoomIn:
        case inZoomOut:
            if (TrackBox(whichWindow, inEvent->where, whatPart))
            {
                if (nil != myWindow)
                    myWindow->Zoom(whatPart);
            }
            break;
            
        case inGrow:
            if (nil != myWindow)
                myWindow->Grow(inEvent->where);
            break;
 
        case inContent:
            if (nil != myWindow)
                myWindow->Click(inEvent->where, inEvent->modifiers);
            break;
 
        case inMenuBar:
            MenuPrepForSelect();
            menuResult = MenuSelect(inEvent->where);
 
            if (HiWord(menuResult) != 0)
                MenuDispatch(menuResult, inEvent->modifiers);
            break;
 
        case inSysWindow:
            SystemClick(inEvent, whichWindow);
            break;
    }
 
    return (true);
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    DefaultKeyDown
 
static Boolean
DefaultKeyDown(const EventRecord *inEvent)
{
SInt8               theKey;
SInt8               theCode;
SInt32              menuResult;
WindowPtr           whichWindow;
ShellWindow         *myWindow = nil;
 
    whichWindow = FrontWindow();
 
    if (userKind == GetWindowKind(whichWindow))
        myWindow = (ShellWindow *) GetWRefCon(whichWindow);
        
    theKey = inEvent->message & charCodeMask;
    theCode = (inEvent->message & keyCodeMask) >> 8;
 
    if ((inEvent->modifiers & cmdKey) != 0)
    {
        MenuPrepForSelect();
        
        menuResult = MenuKey(theKey);
        if (HiWord(menuResult) != 0)
            if (MenuDispatch(menuResult, inEvent->modifiers))
                return (true);
    }
 
    if (nil != myWindow)
        return (myWindow->Key(theKey, theCode, inEvent->modifiers));
    
    return (false);
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    DoDiskEvent
 
static Boolean
DoDiskEvent(const EventRecord *inEvent)
{
Point   thePoint;
SInt16  value;
 
    if (inEvent->message & 0xFFFF0000)      //¥ Error mounting disk
    {
        SetPt(&thePoint, 100, 100);
        value = DIBadMount(thePoint, inEvent->message);
    }
 
    return (true);
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    RegisterEventHandlers
 
void
RegisterEventHandlers(
    EventHandlerProc inKeyDown,
    EventHandlerProc inAutoKey,
    EventHandlerProc inMouseDown,
    EventHandlerProc inUpdate,
    EventHandlerProc inIdle)
{
    gEventHandlers.keyHandler = inKeyDown;
    gEventHandlers.autoKeyHandler = inAutoKey;
    gEventHandlers.clickHandler = inMouseDown;
    gEventHandlers.updateHandler = inUpdate;
    gEventHandlers.idleHandler = inIdle;
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    ModifyEventHandlers
 
void
ModifyEventHandlers(
    EventHandlerProc inKeyDown,
    EventHandlerProc inAutoKey,
    EventHandlerProc inMouseDown,
    EventHandlerProc inUpdate,
    EventHandlerProc inIdle)
{
    if (inKeyDown)
        gEventHandlers.keyHandler = inKeyDown;
 
    if (inAutoKey)
        gEventHandlers.autoKeyHandler = inAutoKey;
 
    if (inMouseDown)
        gEventHandlers.clickHandler = inMouseDown;
 
    if (inUpdate)
        gEventHandlers.updateHandler = inUpdate;
 
    if (inIdle)
        gEventHandlers.idleHandler = inIdle;
}
 
//¥ ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ    DoSuspend
 
static void
DoSuspend(void)
{
EventRecord theEvent;
 
    while (true)
    {
        //¥ Only check for resume and update events.  While doing so, give TONS of time to other apps
        if (WaitNextEvent(osMask, &theEvent, 32767, nil))
            if (theEvent.message & 0x01000000)      //¥ Suspend/resume event
                if (theEvent.message & 0x00000001)  //¥ Resume
                    break;
    }
}