Source/EventLoop.c

/*
    9-30-92  ¥ Brigham Stevens
    --------------------------
    This file contains all the code needed to handle dispatching events.
    Any files that need to access the globals should include the EventLoop.h file.
    
    This is a very basic event loop that does not take into account any
    real "document" type of windows.  It just does the minimum default Mac type
    behavior for windows and menus.  Many parts of the code could be changed
    to include a case on window type, and then dispatch to a handler for that type
    of window.
*/
 
#include "EventLoop.h"
 
/* These Globals are here in case any other tasks need access to the latest key presssed */
/* I use this for games */
 
Boolean     Done = false;               /* true when Quit is selected */
Boolean     KeyPressed = false;         /* true most recent event is a keyDown event */
char        KeyValue = 0;               /* the ascii code of the most recent key down */
 
Boolean     WNE_available = false;      /* Does WNE exist on this mac?? */
Boolean     BackgroundFlag = false;     /* true if we are in the background */
 
void DoCloseWindow(register EventRecord *evt, register WindowPtr theWindow)
{
    if(TrackGoAway(theWindow,evt->where)) {
        CloseWindow(theWindow);
    }
}
 
void DoClickInContent(register EventRecord *evt, register WindowPtr theWindow)
{
    int             part;
    ControlHandle   ctlh;
    Point           pt;
    GrafPtr         saveport;
    Rect            frame;
    
    if(theWindow!=FrontWindow()) {
        SelectWindow(theWindow);
    } else {
        GetPort(&saveport);
        SetPort(theWindow);
        pt = evt->where;
        GlobalToLocal(&pt);
        if(part = FindControl(pt,theWindow,&ctlh)) {
            /* TrackControl Goes Here */
        }
        SetPort(saveport);
    }
}
 
 
 
 
void DoDragWindow(register EventRecord *evt, register WindowPtr theWindow)
{
    DragWindow(theWindow,evt->where,&screenBits.bounds);
}
 
 
void DoGrowWindow(register EventRecord *evt, register WindowPtr theWindow)
{
    long    newSize;
    int     newHeight,newWidth;
    Rect    growLimitSizes;
    
    SetPort(theWindow);
    InvalRect(&theWindow->portRect);
    
    growLimitSizes.top = 20;            /* min height */
    growLimitSizes.bottom = 32767;      /* max height */
    growLimitSizes.left = 20;           /* min width */
    growLimitSizes.right = 32767;       /* max width */
    
    newSize = GrowWindow(theWindow,evt->where,&growLimitSizes);
    newHeight = HiWord(newSize);
    newWidth = LoWord(newSize);
    SizeWindow(theWindow,newWidth,newHeight,TRUE);
}
 
DoZoom(register EventRecord *evt, register WindowPtr theWindow, int part)
{
    GrafPtr savePort;
    
    GetPort(&savePort);
    SetPort(theWindow);
    
    if(TrackBox(theWindow,evt->where,part)) {
        ZoomWindow(theWindow,part,true);
    }
    
    SetPort(savePort);
}
 
 
 
void DoMenu(register long msel)
{
    int item,menu;
    item = LoWord(msel);
    menu = HiWord(msel);
    MenuDispatch(menu, item);
    HiliteMenu(0);                      /* remove menu title hiliting */
}
 
void DoKey(register EventRecord *evt)
{
    char        c;
    
    c = (char)evt->message & charCodeMask;
    
    if((evt->modifiers & cmdKey)== FALSE) {
        KeyPressed = true;
        KeyValue = c;
    } else {
        DoMenu(MenuKey(evt->message & charCodeMask));   
    }
}
 
void DrawClippedGrowIcon(WindowPtr theWindow)
/*
    Clip out the lines that appear
    on the sides of a window with a grow icon.
*/
{
    Rect        clip;
    RgnHandle   oldClip;
    
    oldClip = NewRgn();
    GetClip(oldClip);
    clip = theWindow->portRect;
    clip.left = clip.right - 15;
    clip.top = clip.bottom - 15;
 
    ClipRect(&clip);
    
    DrawGrowIcon(theWindow);
    SetClip(oldClip);
}
 
void DoUpdate(register EventRecord *evt)
{
    WindowPtr   updateWindow;
    GrafPtr     savePort;
    
    
    GetPort(&savePort);                     /* save current port */
    
    updateWindow=(WindowPtr)evt->message;   /* get windowPtr from event msg */
    SetPort(updateWindow);
    BeginUpdate(updateWindow);                      
    EraseRect(&updateWindow->portRect);     /* erase content region */
 
    DrawImage(updateWindow);                /* sample routine to draw contents */
    
    DrawControls(updateWindow);             /* draw any controls in the window */
    DrawClippedGrowIcon(updateWindow);
    EndUpdate(updateWindow);
        
    SetPort(savePort);
}
 
 
void ActivateWindow(register WindowRecord   *newFrontWindow)
{
    /* This window is now active.  Controls should be enabled, etc. */
}
 
void DeactivateWindow(register WindowRecord *newBehindWindow)
{
    /* 
        do anyting necessary to deactivate your windows here.
        controls should be dimmed, etc.
    */
}
 
void DoActivate(register EventRecord *evt)
{
    if(evt->modifiers & activeFlag)
        ActivateWindow((WindowRecord *)evt->message);
    else
        DeactivateWindow((WindowRecord *)evt->message);
}
 
void DoMFinder(register EventRecord *evt)
{
    if( (evt->message >> 24) == suspendResumeMessage)
        BackgroundFlag = !(evt->message & resumeFlag);
}
 
void DoClick(register EventRecord *evt)
{
    WindowPtr   theWindow;
    
    switch(FindWindow(evt->where, &theWindow)) {
        case inDesk:        break;
        case inMenuBar:     DoMenu(MenuSelect(evt->where));
                            break;
        case inSysWindow:   SystemClick(evt,theWindow);
                            break;
        case inContent:     DoClickInContent(evt,theWindow);
                            break;
        case inDrag:        DoDragWindow(evt,theWindow);
                            break;
        case inGrow:        DoGrowWindow(evt,theWindow);
                            break;
        case inGoAway:      DoCloseWindow(evt,theWindow);
                            break;
        case inZoomIn:      DoZoom(evt,theWindow,inZoomIn);
                            break;
        case inZoomOut:     DoZoom(evt,theWindow,inZoomOut);
                            break;
        default:            break;
    }
}
 
 
void MainEvent(void)
{
    EventRecord event;
    Boolean     eventOccured;
    
    KeyPressed = false;             /* set to false every time through  */
    
    if(WNE_available)
        eventOccured = WaitNextEvent(everyEvent,&event,10,nil);
    else {
        SystemTask();
        eventOccured = GetNextEvent(everyEvent, &event);
    }
 
    if(eventOccured) {
        switch(event.what) {
            case nullEvent:                                     break;
            case mouseDown:         DoClick(&event);            break;
            case mouseUp:                                       break;
            case keyDown:           DoKey(&event);              break;
            case keyUp:                                         break;
            case autoKey:           DoKey(&event);              break;
            case updateEvt:         DoUpdate(&event);           break;
            case diskEvt:                                       break;
            case activateEvt:       DoActivate(&event);         break;
            case networkEvt:                                    break;
            case driverEvt:                                     break;
            case app1Evt:                                       break;
            case app2Evt:                                       break;
            case app3Evt:                                       break;
            case osEvt:             DoMFinder(&event);          break;
            default:                                            break;
        }
    }
}