sources/AppSupport.c

/*
    File:       AppSupport.c
 
    Copyright:  © 2000-2001 by Apple Computer, Inc., all rights reserved.
 
 
*/
 
#include <Devices.h>
#include <FixMath.h>
#include <Fonts.h>
#include <Gestalt.h>
#include <LowMem.h>
#include <Menus.h>
#include <Quickdraw.h>
#include <TextUtils.h>
 
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
 
#include <QuickTimeStreaming.h>
#include <QTStreamingComponents.h>
 
 
#include "AppSupport.h"
#include "QTSSampleCodeUtils.h"
#include "UsherBroadcast.h"
#include "UsherCommands.h"
#include "UsherNew.h"
#include "usherrezdefines.h"
#include "WindowSupport.h"
 
 
// ---------------------------------------------------------------------------
//      D E F I N I T I O N S
// ---------------------------------------------------------------------------
 
 
// min qt version
#define kMinQTVersion           0x05018000
#define kMinQTSVersion          0x05018000
 
#define kGMVersionMask          0xFFFF0000
 
 
#if TARGET_RT_MAC_MACHO
    #define kAppDefaultSleepTime        6
#else
    #define kAppDefaultSleepTime        60
#endif
 
 
AppGlobals gGlobals;
 
// ---------------------------------------------------------------------------
//      P R O T O T Y P E S
// ---------------------------------------------------------------------------
 
static OSErr Initialize(void);
static OSErr AppGlobals_Initialize(void);
static void InitToolbox(void);
static OSErr InstallMenus(void);
static OSErr CheckConfig(void);
 
static void CleanUp(void);
static void AppGlobals_CleanUp(void);
 
// ----- events
 
static void EventLoop(void);
static void DoEvent(EventRecord *event);
 
static void AdjustCursor(Point inMouse, RgnHandle inRegion);
static void AdjustMenus(void);
 
static void DoMenuCommand(long inMenuResult);
static long GetMenuCommand(long inMenuResult, void **outCommandParams);
static void DoKeyDown(EventRecord *inEvent);
static long GetKeyDownCommand(EventRecord *inEvent);
 
static void DoCommand(long inCommand, void *inCommandParams);
static void DoOpen(void);
 
static void DoIdle(void);
static void DoQuit(void);
static void DoAbout(void);
 
static void DoCloseWindow(WindowPtr inWindow, Boolean inAdjustMenus);
static void DoCloseAllWindows(void);
 
static void ShowLog(void);
 
#if TARGET_OS_MAC
// ----- apple events
 
static void InitAppleEvents(void);
static void DoAppleEvent(EventRecord *inEvent);
 
static pascal OSErr DoAEOpenApp(const AppleEvent *message, AppleEvent *reply, UInt32 refcon);
static pascal OSErr DoAEOpenDocument(const AppleEvent *message, AppleEvent *reply, UInt32 refcon);
static pascal OSErr DoAEQuit(const AppleEvent *message, AppleEvent *reply, UInt32 refcon);          
static OSErr OpenWindowsForAEDescItems(AEDescList descList);
 
#endif /* TARGET_OS_MAC */
 
// ----- utils
 
#define OptionDown()        ( (*(char*)0x17b) & 0x04 )
 
static void SetArrowCursor(void);
static void MyGetGlobalMouse(Point *outMouse);
 
static Boolean ShiftKeyDown(void);
static Boolean CapsLockDown(void);
static Boolean OptionKeyDown(void);
static Boolean ControlKeyDown(void);
 
#define kUsherStandardLogDelimiterString            "--------------------------------------------"
 
// ---------------------------------------------------------------------------
//      main
// ---------------------------------------------------------------------------
 
void main(void)
{
    if (noErr == Initialize())  {       /* initialize the program */
        EventLoop();                /* call the main event loop */
    }
 
    //DoCloseAllWindows();
}
 
// ---------------------------------------------------------------------------
//      Initialize
// ---------------------------------------------------------------------------
 
static OSErr Initialize(void)
{
    OSErr           err = noErr;
    InitToolbox();
 
    EXITIFERR( err = AppGlobals_Initialize() );
    AppGlobals_SetInBackground(false);
 
    EXITIFERR( err = CheckConfig() );
    EXITIFERR( err = InstallMenus() );
    
    AppGlobals_SetDefaultOffset(20, 12)
    InitAppleEvents();
 
 
 
    SetArrowCursor();
 
exit:
    if (err != noErr)  {
        short        index = err;
        if ((err < 1)  ||  (err > rAppError_MaxHandledStrings))  {
            index = rAppError_GeneralStartup;
        }
        GenericAlertUser(rStringList_AppErrors, index, err);
    }
    return err;
}
 
// ---------------------------------------------------------------------------
//      InitToolbox
// ---------------------------------------------------------------------------
 
static void InitToolbox(void)
{
#if TARGET_OS_MAC
  MoreMasters();
  MoreMasters();
 
#if !TARGET_API_MAC_CARBON
  InitGraf(&qd.thePort);
  InitFonts();
  FlushEvents(0xffff,0);
  InitWindows();
  InitMenus();
  InitDialogs(0);
  TEInit();
  MaxApplZone();
#endif /* not TARGET_API_MAC_CARBON */
  InitCursor();
#endif
  }
 
// ---------------------------------------------------------------------------
//      AppGlobals_Initialize
// ---------------------------------------------------------------------------
 
static OSErr AppGlobals_Initialize(void)
{
    FSSpec      logSpec;
    OSErr       err = noErr;
 
    memset(&gGlobals, 0, sizeof(gGlobals));
    AppGlobals_SetSleepTime(kAppDefaultSleepTime);
    // Make a backup port to use for safety purposes.
#if TARGET_API_MAC_CARBON
    //@@@ do I need to check the error?
    gGlobals.safetyPort = CreateNewPort();
    if (gGlobals.safetyPort == NULL)  {
        EXITERR( err = -333 );
    }
#else
    GetWMgrPort( &gGlobals.safetyPort );
#endif
 
    GetAppRelativeFolderSpec(NULL, &logSpec);
    pstrcpy(logSpec.name, "\pusherlog.txt");
#define kLogFileCreator     'CWIE'
#define kLogFileType        'TEXT'
 
    EXITIFERR( err = Logger_New(&logSpec, 0, kLogFileCreator, kLogFileType, &gGlobals.log) );
    {
        //SInt32        flags = kDebugFlag_WriteToLog | kDebugFlag_DebugStr;
        SInt32      flags = kDebugFlag_WriteToLog;
        SetDebugLog(gGlobals.log);
        SetDebugFlags(flags, flags); 
 
        Logger_Printf(gGlobals.log, kLoggerWriteFlag_AddDateTime | kLoggerWriteFlag_AddEOL,
                        kUsherStandardLogDelimiterString);
        Logger_Printf(gGlobals.log, kLoggerWriteFlag_AddDateTime | kLoggerWriteFlag_AddEOL,
                        "usher started");
    }   
exit:
    return err;
}
 
// ---------------------------------------------------------------------------
//      CheckConfig
// ---------------------------------------------------------------------------
 
static OSErr CheckConfig(void)
{
    OSErr       err = noErr;
    long        result;
 
 
 
 
    // check quicktime version
    err = Gestalt( gestaltQuickTimeVersion, &result );
    if ( (noErr != err) || ((result < kMinQTVersion)  &&  (result != (kMinQTVersion & kGMVersionMask))) )  {
        EXITERR( err = rAppError_QTVersion );
    }
    
    // check quicktime streaming version
    err = Gestalt(gestaltQuickTimeStreamingVersion, &result);
    if ( (noErr != err) || ((result < kMinQTSVersion)  &&  (result != (kMinQTSVersion & kGMVersionMask))) )  {
        EXITERR( err = rAppError_QTSVersion );
    }
    
#if TARGET_API_MAC_CARBON
    //  work around initialization bugs in Carbon.
    {
        GrafPtr dummyPort;
        CurResFile();           // forces CarbonCore to load.
        GetPort(&dummyPort);    // forces Quickdraw to load.
        FrontWindow();          // forces HLTB to load.
    }
#endif
    
    EXITIFERR( err = EnterMovies() );
 
#if TARGET_OS_MAC
    if ((noErr == Gestalt(gestaltAppearanceAttr, &result))  &&
        (result & (1L << gestaltAppearanceExists)) )  {
        AppGlobals_SetUseAppearance( (result & (1L << gestaltAppearanceCompatMode)) == 0 );
    }  else  {
        AppGlobals_SetUseAppearance(false);
    }
#endif
exit:
    return err;
}
 
// ---------------------------------------------------------------------------
//      InstallMenus
// ---------------------------------------------------------------------------
 
static OSErr InstallMenus(void)
{
    Handle          menuBar;
    OSErr           err = noErr;
 
    /* read menus into menu bar */
    menuBar = GetNewMBar(rMenuBar_Main);
    if (menuBar == NULL)  {
        EXITERR( err = memFullErr );
    }
    SetMenuBar(menuBar);                    /* install menus */
    DisposeHandle(menuBar);
#if TARGET_API_MAC_CARBON
{
    OSErr           tempErr;
    long            result = 0;
 
    tempErr = Gestalt( gestaltMenuMgrAttr, &result );
    if( (noErr == tempErr) && (result & gestaltMenuMgrAquaLayoutMask)) {
        // Delete Quit item from the File menu.
        DeleteMenuItem( GetMenuHandle(rMenu_File), rMenuItem_Quit );
        DeleteMenuItem( GetMenuHandle(rMenu_File), rMenuItem_Quit-1 );
    }
}
#else // not TARGET_API_MAC_CARBON
    AppendResMenu(GetMenuHandle(rMenu_Apple), 'DRVR');  /* add DA names to Apple menu */
#endif
    AdjustMenus();  // calls MacDrawMenuBar
 
 
exit:
    return err;
}
 
// ---------------------------------------------------------------------------
//      CleanUp
// ---------------------------------------------------------------------------
 
static void CleanUp(void)
{
    UsherBroadcast_CleanUp();
    AppGlobals_CleanUp();
}
 
// ---------------------------------------------------------------------------
//      AppGlobals_CleanUp
// ---------------------------------------------------------------------------
 
static void AppGlobals_CleanUp(void)
{
    if (gGlobals.log != NULL)  {
        Logger_Printf(gGlobals.log, kLoggerWriteFlag_AddDateTime | kLoggerWriteFlag_AddEOL,
                        "usher stopped"); 
 
        Logger_Dispose(gGlobals.log);
        gGlobals.log = NULL;
    }
}
 
#pragma mark -
#pragma mark .----- events -----
 
// ---------------------------------------------------------------------------
//      EventLoop
// ---------------------------------------------------------------------------
 
static void EventLoop(void)
{
    Boolean     gotEvent;
    EventRecord event;
 
    do {
        gotEvent = WaitNextEvent(everyEvent, &event, AppGlobals_GetSleepTime(), NULL);
        if (gotEvent)  {
            /* make sure we have the right cursor before handling the event */
            AdjustCursor(event.where, nil);
            DoEvent(&event);
        }  else  {
            DoIdle();               /* perform idle tasks when itÕs not our event */
        }
    } while (!AppGlobals_GetExitNow());
    
    CleanUp();
    
} /*EventLoop*/
 
 
// ---------------------------------------------------------------------------
//      DoEvent
// ---------------------------------------------------------------------------
 
static void DoEvent(EventRecord *event) 
{
    short       part;
    WindowPtr   window;
    short       key;
 
    switch (event->what) {
        case nullEvent:
            DoIdle();
            break;
        case mouseDown:
            part = MacFindWindow(event->where, &window);
            switch ( part ) {
                case inMenuBar: 
                    AdjustMenus();
                    DoMenuCommand(MenuSelect(event->where));
                    break;
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
                case inSysWindow:           /* let the system handle the mouseDown */
                    SystemClick(event, window);
                    break;
#endif
 
                case inContent:
                    if ( window != FrontWindow() ) {
                        SelectWindow(window);
                    } else  {
                        WindowSupport_DoContentClick(window, event);
                    }
                    break;
                case inDrag:                /* pass screenBits.bounds to get all gDevices */
#if TARGET_API_MAC_CARBON
                    DragWindow(window, event->where, nil);
#else
                    DragWindow(window, event->where, &qd.screenBits.bounds);
#endif
                    break;
                case inGoAway:
                    if ( TrackGoAway(window, event->where) ) {
#if TARGET_OS_MAC
                        if ( event->modifiers & optionKey )  {
                            DoCommand(kCommand_CloseAll, NULL);
                        }  else
#endif
                            DoCommand(kCommand_Close, window);
                    }
                    break;
#if TARGET_OS_MAC
                case inGrow:
                    WindowSupport_GrowWindow(window, event);
                    break;
                case inZoomIn:
                case inZoomOut:
                    break;
#endif
 
            }
            break;
        case keyDown:
        case autoKey:                           /* check for menukey equivalents */
            key = (short)(event->message & charCodeMask);
            if (event->modifiers & cmdKey) {    /* Command key down */
                if (event->what == keyDown) {
                    AdjustMenus();              /* enable/disable/check menu items properly */
#if TARGET_OS_MAC
                    if (AppGlobals_GetUseAppearance())
                        DoMenuCommand(MenuEvent(event));
                    else
#endif
                        DoMenuCommand(MenuKey(key));
                }
            } else  {
                DoKeyDown(event);
            }
            break;
        case activateEvt:
            WindowSupport_ActivateWindow((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
            break;
        case updateEvt:
            WindowSupport_DoUpdate((WindowPtr)event->message);
            break;
        case osEvt:
            switch ((event->message & osEvtMessageMask) >> 24) {        /* high byte of message */
                case mouseMovedMessage:
                    DoIdle();
                    break;
                case suspendResumeMessage:      /* suspend/resume is also an activate/deactivate */
                    AppGlobals_SetInBackground((event->message & resumeFlag) == 0);
                    WindowSupport_ActivateWindow(FrontWindow(), !AppGlobals_GetInBackground());
                    break;
            }
            break;
 
#if TARGET_OS_MAC
        case kHighLevelEvent: 
            DoAppleEvent(event);
            break;
#endif
        default:
            break;
    }
}
 
// ---------------------------------------------------------------------------
//      AdjustCursor
// ---------------------------------------------------------------------------
 
static void AdjustCursor(Point inMouse, RgnHandle inRegion)
{
#pragma unused(inMouse, inRegion)
    WindowPtr   window;
 
    window = FrontWindow(); /* we only adjust the cursor when we are in front */
    if ( !AppGlobals_GetInBackground() && !WindowSupport_IsDAWindow(window) ) {
        SetArrowCursor();
 
    }
}
 
// ---------------------------------------------------------------------------
//      AdjustMenus
// ---------------------------------------------------------------------------
 
static void AdjustMenus(void)
{
//@@@
    MacDrawMenuBar();
}
 
// ---------------------------------------------------------------------------
//      DoMenuCommand
// ---------------------------------------------------------------------------
 
static void DoMenuCommand(long inMenuResult)
{
    long        command;
    void        *commandParams = NULL;
 
    command = GetMenuCommand(inMenuResult, &commandParams);
    if (command != kCommand_Nothing)  {
        DoCommand(command, commandParams);
    }  else  {
        if (MYLOWORD(inMenuResult) != 0)  {
            SysBeep(0);
        }
    }
}
 
// ---------------------------------------------------------------------------
//      GetMenuCommand
// ---------------------------------------------------------------------------
 
static long GetMenuCommand(long inMenuResult, void **outCommandParams)
{
    short       menuID, menuItem;
    SInt32      command = kCommand_Nothing;
    Boolean     commandFound = true;
 
    menuID = (short)MYHIWORD(inMenuResult);
    menuItem = (short)MYLOWORD(inMenuResult);
 
    switch (menuID)  {
        case rMenu_Apple:
            switch  (menuItem) {
                case rMenuItem_About:       /* bring up alert for About */
                    command = kCommand_About;
                    break;
                default:            /* all non-About items in this menu are DAs et al */
                    command = kCommand_OpenDeskAcc;
                    *outCommandParams = (void*)menuItem;
                    break;
            }
            break;
 
        case rMenu_File:
            switch (menuItem) {
                case rMenuItem_Open:
                    command = kCommand_Open;
                    break;
                case rMenuItem_Close:
#if TARGET_OS_MAC
                    if (OptionKeyDown())  {
                        command = kCommand_CloseAll;
                    }  else
#endif
                    {   
                        command = kCommand_Close;
                        *outCommandParams = FrontWindow();
                    }
                    break;
#if !TARGET_API_MAC_CARBON
                case rMenuItem_Quit:
                    command = kCommand_Quit;
                    //DoCommand(kCommand_Quit, NULL);
                    break;
#endif
                default:
                    commandFound = false;
                    break;
            }
            break;
 
        case rMenu_Edit:            /* call SystemEdit for DA editing & MultiFinder */
#if !TARGET_API_MAC_CARBON
            if (!SystemEdit((short)(menuItem-1)))
#endif
            {
                switch (menuItem)  {
                    default:
                        break;
                }
            }
            break;
    
        case rMenu_Presentation:
            switch (menuItem)  {
                case rMenuItem_ShowLog:
                    command = kCommand_ShowLog;
                    break;
                default:
                    commandFound = false;
                    break;
            }
                    
        default:
            commandFound = false;
            break;
    }
 
    if (!commandFound)  {
        WindowPtr       window = FrontWindow();
        
        if (window != NULL)  {
            command = WindowSupport_GetMenuCommand(window, inMenuResult, outCommandParams);
        }
    }
 
    HiliteMenu(0);                  /* unhighlight what MenuSelect (or MenuKey) hilited */
    return command;
}
 
// ---------------------------------------------------------------------------
//      DoKeyDown
// ---------------------------------------------------------------------------
 
static void DoKeyDown(EventRecord *inEvent)
{
    long        command = kCommand_Nothing;
    
    command = GetKeyDownCommand(inEvent);
    if (command != kCommand_Nothing)  {
        DoCommand(command, NULL);
    }
}
 
// ---------------------------------------------------------------------------
//      GetKeyDownCommand
// ---------------------------------------------------------------------------
 
static long GetKeyDownCommand(EventRecord *inEvent)
{
#if TARGET_OS_MAC
    long        command = kCommand_Nothing;
 
    if ((inEvent->message & charCodeMask) == 0x09)  { // tab
        if (inEvent->modifiers & shiftKey)  {
            command = kCommand_SelectPrevWindow;
        }  else  {
            command = kCommand_SelectPrevWindow;
        }
    }
    return command;
#else
    return kCommand_Nothing;
#endif
}
 
#pragma mark -
#pragma mark .----- commands -----
 
// ---------------------------------------------------------------------------
//      DoCommand
// ---------------------------------------------------------------------------
 
static void DoCommand(long inCommand, void *inCommandParams)
{
    OSErr           err = noErr;
    Boolean         handled = true;
 
    switch (inCommand)  {
        case kCommand_About:
            DoAbout();
            break;
            
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON //@@QTML
        case kCommand_OpenDeskAcc:
        {
            GrafPtr     savePort;
            Str255      daName;
                            
            GetPort(&savePort);
            GetMenuItemText(GetMenuHandle(rMenu_Apple), (short)inCommandParams, daName);
            OpenDeskAcc(daName);
            MacSetPort(savePort);
            break;
        }
#endif
 
 
        case kCommand_Open:
            DoOpen();
            break;
            
        case kCommand_OpenFromFSSpec:
        {
            long        numbroadcasts;
            
            numbroadcasts = UsherBroadcast_GetNumBroadcasts();
            if (OptionDown()  ||  (numbroadcasts < 1))  {
                err = Usher_NewBroadcastFromFile((const FSSpec*)inCommandParams, 0);
            }  else  {
                SysBeep(0);
            
            }
            break;
        }
 
        case kCommand_Close:
            DoCloseWindow((WindowPtr)inCommandParams, true);
            break;
            
        case kCommand_CloseAll:
            DoCloseAllWindows();
            break;
            
        case kCommand_Quit:
            DoQuit();
            break;
            
        case kCommand_ShowLog:
            ShowLog();
            break;
 
        default:
            handled = false;
            break;  
    }
    if (!handled)  {
        WindowPtr       window = FrontWindow();
        
        err = WindowSupport_DoCommand(window, inCommand, inCommandParams);
    }
    
    if (err == kErr_AppUnhandledCommand)  {
        DEBUGF(("DoCommand %ld - no one handled it", inCommand));
    }  else if (err != noErr)  {
        DEBUGF(("DoCommand %ld - err %ld params $%.8x", inCommand, err, inCommandParams));
    }
}
 
// ---------------------------------------------------------------------------
//      DoAbout
// ---------------------------------------------------------------------------
 
static void DoAbout(void)
{
    Handle          versHandle = NULL;
    unsigned char   *stringPtr;
    char            oldState;
    
    versHandle = GetResource('vers', 2);
    if (versHandle != NULL)  {
        oldState = HGetState(versHandle);
        HLock(versHandle);
        stringPtr = (unsigned char*)((*versHandle) + 7 + ((*versHandle)[6]));
    
    }  else  {
        stringPtr = EMPTY_PSTR;
    }
    ParamText(stringPtr, EMPTY_PSTR, EMPTY_PSTR, EMPTY_PSTR);
    if (versHandle != NULL)  {
        HSetState(versHandle, oldState);
    }
    Alert(rAlert_AboutBox, NULL);
 
 
}
 
// ---------------------------------------------------------------------------
//      DoOpen
// ---------------------------------------------------------------------------
 
static void DoOpen(void)
{
#if TARGET_API_MAC_CARBON
    OSType movieTypeList[1] = {'sdp '};
    StandardFileReply reply;
    OSErr       err = noErr;
    FSSpec      myFSSpec;
 
    //@@@ need to change this to use Nav
    // -1 means allow all files
    StandardGetFilePreview( nil, -1, movieTypeList, &reply );
    if (reply.sfGood) {
        myFSSpec = reply.sfFile;
        DoCommand(kCommand_OpenFromFSSpec, &myFSSpec);
    }
#else
    StandardFileReply reply;
    SFTypeList  typeList;
    OSErr       err = noErr;
 
    typeList[0] = 'sdp ';
    typeList[1] = 'atom';
    typeList[2] = 'TEXT';
    StandardGetFilePreview( NULL, 3, typeList, &reply );
    if (reply.sfGood)  {
        DoCommand(kCommand_OpenFromFSSpec, &reply.sfFile);
    }
 
    if (err != noErr)  {
        DEBUGF(("DoOpen err %ld", err));
    }
    return;
#endif
}
 
// ---------------------------------------------------------------------------
//      DoIdle
// ---------------------------------------------------------------------------
 
static void DoIdle(void)
{
    UsherBroadcast_IdleAll();
}
 
// ---------------------------------------------------------------------------
//      DoQuit
// ---------------------------------------------------------------------------
 
static void DoQuit(void)
{
    AppGlobals_SetExitNow(true);
}
 
// ---------------------------------------------------------------------------
//      DoSelectWindow
// ---------------------------------------------------------------------------
 
static void DoSelectWindow(long inCommand)
{
    WindowPtr       window;
    
    window = FrontWindow();
    if (window != NULL)  {
        if (inCommand == kCommand_SelectNextWindow)  {
            while(MacGetNextWindow(window) != NULL)  {
                window = MacGetNextWindow(window);
            }
            SelectWindow(window);
        }  else if (inCommand == kCommand_SelectPrevWindow)  {
#if !TARGET_API_MAC_CARBON
            SInt16      savePaintWhite = LMGetPaintWhite();
#endif
            if (MacGetNextWindow(window) != NULL)  {
                SelectWindow(MacGetNextWindow(window));
            }
#if !TARGET_API_MAC_CARBON
            LMSetPaintWhite(0);
#endif
            SendBehind(window, NULL);
#if !TARGET_API_MAC_CARBON
            LMSetPaintWhite(savePaintWhite);
#endif
        }  else  {
            DEBUGF(("DoSelectWindow-bad command %ld", inCommand));
        }
    }
}
 
// ---------------------------------------------------------------------------
//      DoCloseWindow
// ---------------------------------------------------------------------------
/* Close a window. This handles desk accessory and application windows. */
 
static void DoCloseWindow(WindowPtr inWindow, Boolean inAdjustMenus)
{
#if TARGET_OS_MAC && ! TARGET_API_MAC_CARBON
    if ( WindowSupport_IsDAWindow(inWindow) ) {
        CloseDeskAcc(GetWindowKind(inWindow));
    }
    else 
#endif
    {
        WindowSupport_CloseWindow(inWindow);
    }
    
    /* SetPort to a valid port for safety */
    if (FrontWindow() != NULL)  {
        SetPortWindowPort(FrontWindow());
    }  else  {
        MacSetPort( gGlobals.safetyPort );
    }
    
    if (inAdjustMenus)  {
        // Adjust the menus because we may now have no frontmost window.
        AdjustMenus();
    }
}
 
// ---------------------------------------------------------------------------
//      DoCloseAllWindows
// ---------------------------------------------------------------------------
 
static void DoCloseAllWindows(void)
{
    WindowPtr window, nextWindow = FrontWindow();
 
    while (nextWindow != NULL)  {
        window = nextWindow;
        nextWindow = MacGetNextWindow( window );
 
        DoCloseWindow(window, false);
    }
    AdjustMenus();
}
 
// ---------------------------------------------------------------------------
//      ShowLog
// ---------------------------------------------------------------------------
 
static void ShowLog(void)
{
}
 
#pragma mark -
#pragma mark .----- alerts -----
 
// ---------------------------------------------------------------------------
//      GenericAlertUser
// ---------------------------------------------------------------------------
 
void GenericAlertUser(short inStringList, short inStringIndex, short inErrorCode)
{
    short       itemHit;
    Str255      message;
    Str255      codeString;
 
    SetArrowCursor();
    GetIndString(message, inStringList, inStringIndex);
    NumToString(inErrorCode, codeString);
    ParamText(message, codeString, EMPTY_PSTR, EMPTY_PSTR);
    itemHit = Alert(rAlert_Generic, NULL);
}
 
// ---------------------------------------------------------------------------
//      GenericAlertUserString
// ---------------------------------------------------------------------------
 
void GenericAlertUserString(Str255 inMessage, short inErrorCode)
{
    short       itemHit;
    Str255      codeString;
 
    SetArrowCursor();
    NumToString(inErrorCode, codeString);
    ParamText(inMessage, codeString, EMPTY_PSTR, EMPTY_PSTR);
    itemHit = Alert(rAlert_Generic, NULL);
}
 
// ---------------------------------------------------------------------------
//      GenericErrorAlert
// ---------------------------------------------------------------------------
 
void GenericErrorAlert(OSErr inErrorCode)
{
    short       itemHit;
    Str255      codeString;
 
    SetArrowCursor();
    NumToString(inErrorCode, codeString);
    ParamText(codeString, EMPTY_PSTR, EMPTY_PSTR, EMPTY_PSTR);
    itemHit = Alert(rAlert_Error, NULL);
}
 
 
// ---------------------------------------------------------------------------
//      ProcessUserMessage
// ---------------------------------------------------------------------------
 
void ProcessUserMessage(SInt32 inFlags, const char* format, ...)
{
#define kMaxDebugFBufferSize        512
 
    unsigned char buffer[kMaxDebugFBufferSize];
    va_list     ptr;
    
    va_start(ptr, format);
    buffer[0] = (unsigned char)vsprintf((char*)buffer + 1, format, ptr);
    va_end(ptr);
 
    if (inFlags & kProcessMessageFlag_Log)  {
        Logger      log = AppGlobals_GetLog();
        
        if (log != 0)  {
            Logger_Write(log, kLoggerWriteFlag_AddDateTime | kLoggerWriteFlag_AddEOL,
                    (const char*)&(buffer[1]), buffer[0] );
        }
    }
    if (inFlags & kProcessMessageFlag_ShowDialog)  {
        GenericAlertUserString(buffer, noErr);
    }
}
 
 
#pragma mark -
#pragma mark .----- apple events -----
 
#if TARGET_OS_MAC
// ---------------------------------------------------------------------------
//      InitAppleEvents
// ---------------------------------------------------------------------------
 
static void InitAppleEvents(void)
{
    const long  noRefCon = 0;
    OSErr       aevtErr;
    
    aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(DoAEOpenApp), noRefCon, false) ;
    aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments,   NewAEEventHandlerProc(DoAEOpenDocument), noRefCon, false) ;
    aevtErr = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(DoAEQuit), noRefCon, false) ;
}
 
// ---------------------------------------------------------------------------
//      DoAppleEvent
// ---------------------------------------------------------------------------
 
static void DoAppleEvent(EventRecord *inEvent)
{
    OSErr       err;
 
  // should check for your own event message types here - if you have any
    err = AEProcessAppleEvent(inEvent);
}
 
// ---------------------------------------------------------------------------
//      DoAEOpenApp
// ---------------------------------------------------------------------------
 
static pascal OSErr DoAEOpenApp(const AppleEvent *message, AppleEvent *reply, UInt32 refcon)
{
#pragma unused(message, reply, refcon)
    return noErr;
}
 
// ---------------------------------------------------------------------------
//      DoAEOpenDocument
// ---------------------------------------------------------------------------
 
static pascal OSErr DoAEOpenDocument(const AppleEvent *message, AppleEvent *reply, UInt32 refcon)
{
#pragma unused(reply, refcon)
    OSErr       err;
    OSErr       ignoreErr;
    AEDescList  docList;
 
    /*open the specified documents*/
 
    docList.dataHandle = nil;
 
    err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
 
    if (err == noErr)  {
        err = OpenWindowsForAEDescItems( docList );
    }
    
    ignoreErr = AEDisposeDesc(&docList);
    
    return err;
}
 
// ---------------------------------------------------------------------------
//      OpenWindowsForAEDescItems
// ---------------------------------------------------------------------------
 
static OSErr OpenWindowsForAEDescItems(AEDescList descList)
{
    OSErr err = noErr;
    FSSpec fileSpec;
    long index;
    long itemsInList = 0;
    AEKeyword keyword;
    DescType actualType;
    Size actualSize;
    Boolean isLastItem;
    
    EXITIFERR( err = AECountItems( &descList, &itemsInList ) );
    
    for( index = 1; index <= itemsInList; index++ ) {
        EXITIFERR( err = AEGetNthPtr( &descList, index, typeFSS, &keyword, &actualType, &fileSpec,
                                sizeof(fileSpec), &actualSize ) );
        
        isLastItem = (index == itemsInList);
//@@@ should stop if there's an error from docommand
        DoCommand(kCommand_OpenFromFSSpec, &fileSpec);
    }
    
exit:
    return err;
}
 
// ---------------------------------------------------------------------------
//      DoAEQuit
// ---------------------------------------------------------------------------
 
static pascal OSErr DoAEQuit(const AppleEvent *message, AppleEvent *reply, UInt32 refcon )          
{
#pragma unused(message, reply, refcon)
    DoCommand(kCommand_Quit, NULL);
    return noErr;
}
 
#endif /* TARGET_OS_MAC */
 
 
#pragma mark -
#pragma mark .----- utils -----
 
 
// ---------------------------------------------------------------------------
//      SetArrowCursor
// ---------------------------------------------------------------------------
 
static void SetArrowCursor(void)
{
#if TARGET_API_MAC_CARBON
    Cursor arrow;
    GetQDGlobalsArrow(&arrow);
    SetCursor(&arrow);
#else
    MacSetCursor(&qd.arrow);
#endif
}
 
// ---------------------------------------------------------------------------
//      MyGetGlobalMouse
// ---------------------------------------------------------------------------
 
static void MyGetGlobalMouse(Point *outMouse)
{
    EventRecord event;
 
//@@@ use GetGlobalMouse in carbon?
    
#if TARGET_API_MAC_CARBON
        EventAvail(0, &event);
#else
    OSEventAvail(nullEvent, &event);    /* we aren't interested in any events */
#endif
    *outMouse = event.where;            /* just the mouse position */
}
 
// ---------------------------------------------------------------------------
//      ShiftKeyDown
// ---------------------------------------------------------------------------
 
static Boolean ShiftKeyDown(void)
{
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
    return (*(char *)0x17b & 1) ? true : false;
#else
    MacKeyMap   keys;
    GetKeys(keys);
    return (keys[7] & 1) ? true : false;
#endif
}
 
// ---------------------------------------------------------------------------
//      CapsLockDown
// ---------------------------------------------------------------------------
 
static Boolean CapsLockDown(void)
{
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
    return (*(char *)0x17b & 2) ? true : false;
#else
    MacKeyMap   keys;
    GetKeys(keys);
    return (keys[7] & 2) ? true : false;
#endif
}
 
// ---------------------------------------------------------------------------
//      OptionKeyDown
// ---------------------------------------------------------------------------
 
static Boolean OptionKeyDown(void)
{
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
    return (*(char *)0x17b & 4) ? true : false;
#else
    MacKeyMap   keys;
    GetKeys(keys);
    return (keys[7] & 4) ? true : false;
#endif
}
 
// ---------------------------------------------------------------------------
//      ControlKeyDown
// ---------------------------------------------------------------------------
 
static Boolean ControlKeyDown(void)
{
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
    return (*(char *)0x17b & 8) ? true : false;
#else
    MacKeyMap   keys;
    GetKeys(keys);
    return (keys[7] & 8) ? true : false;
#endif
}