Initialize.c

/*------------------------------------------------------------------------------
*
*  Apple Developer Technical Support
*
*  
*
*  Program:    AEObject-Edition Sample
*  File:   Initialize.c -C Source
*
*  by: C.K. Haun <TR>
*
*  Copyright © 1990-1992 Apple Computer, Inc.
*  All rights reserved.
*
*------------------------------------------------------------------------------
* This file contains some of our window handling routines.  I created it 
* primarily to take some of the clutter out of the main.c file.
* It also contains the clipboard handlers
*----------------------------------------------------------------------------*/
 
#define __INIT__
 
#include "Sampdefines.h"
#include <SegLoad.h>
 
#pragma segment MyInit
/* StartStuff initializes the managers and does some other init stuff */
void StartStuff(void)
{
    long aLong;
    OSErr myErr;    
    MaxApplZone();
    MaxMem(&aLong);
    /* Nobody every says this, it's always assumed, but I'll tell yah... */
    /* 'qd' is in the Runtime.o library (which is one reason you have to link it)  */
    /* it doesn't come from the toolbox or any other magic place */
    InitGraf((Ptr)&qd.thePort);
    InitFonts();
    InitWindows();
    InitMenus();
    TEInit();
    InitDialogs(nil);
    MoreMasters();
    /* See if AppleEvents and the Edition manager are available */
    InitAEStuff();                                          /* In AppleEventM.c */
    gHasEditionManager = (Gestalt(gestaltEditionMgrAttr, &aLong) == noErr);
    /* the value returned will be 1, but we don't really care here, since there aren't */
    /* multiple versions of the Edition Manager yet */
    if (gHasEditionManager) {
        InitEditionPack();
        
    } else {
        ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
        Alert(kNoEditionManager, upp);                      /* tell 'em and exit */
        DisposeRoutineDescriptor(upp);
        ExitToShell();
    }
    GetCurrentProcess(&gOurSN);                             /* grab our applications process serial number */
    /* so we can communicate (send appleevents) to */
    /* ourself easily */
    myErr = Gestalt(gestaltQuickdrawVersion, &aLong);
    if(myErr == noErr && (aLong & 0xff00)) 
        gHasColor = true;
    StartMenus();                                           /* load the menu bar and set up the menus */
 
    CreateClipBoard();
 
    CreateAEStatus();
    /* ¥¥¥ NOTE: I am not opening a document window here.  The application will wait for an */
    /* 'oapp' or 'odoc' AppleEvent before opening a window.  This makes it a whole lot easier */
    /* to deal with ODOC events, since you needn't special case anything */
    gMySleep = 5;                                           /* initialize sleep at some reasonable level */
    gWindObjSpecHandle = (WindowObjectDefHandle)NewHandleClear(sizeof(WindowObjectDef));
    gTextObjSpecHandle = (TextObjectDefHandle)NewHandleClear(sizeof(TextObjectDef));
    gShapeObjSpecHandle = (ShapeObjectDefHandle)NewHandleClear(sizeof(ShapeObjectDef));
    gLocalInteraction = 0;  /* default this */
    gAESendInteraction = 0;
    gReplyMode = 1;
    LoadPrefs();
    gPreferences.prefsChanged = false;
    /* and set it, it may have changed with the Prefs */
     AESetInteractionAllowed(gLocalInteraction);
    InitCursor();
 
}
 
/* end StartStuff */
 
 
#pragma segment MyInit
 
 
/* CreateClipBoard creates our invisible clipboard window at application */
/* start time, and keeps it open always.  Visibility is toggled from the edit menu, */
/* but the window always exists */
 
void CreateClipBoard(void)
{
    WindowPtr tempWindow;
    windowCHandle tempWC;
    
    /* open my clipboard window */
    tempWindow = GetNewWindow(kClipWindow, 0, (WindowPtr)-1);
    
    /* since I'm using the same function for my clipboard as for a document window, I have */
    /* to change some of the fields */
    ((WindowPeek)tempWindow)->windowKind = kClipboardWindow;
    ((WindowPeek)tempWindow)->refCon = NewHandleClear(sizeof(windowControl));        /* add our control structure to it */
    tempWC = (windowCHandle)GetWRefCon(tempWindow);         /* and put it where we can use it */
    HLock((Handle)tempWC);                                  /* lock it down */
 
    /* add pointers to our procedures for drawing, saving, and closing */
    (*tempWC)->drawMe = (ProcPtr)DrawClip;
    (*tempWC)->saveMe = (ProcPtr)nil;
    (*tempWC)->closeMe = (ProcPtr)CloseClip;
    (*tempWC)->clickMe = (ProcPtr)ClipClick;
    (*tempWC)->sizeMe = (ProcPtr)SizeClip;
    (*tempWC)->currentAction = nil;
    (*tempWC)->undoAction = nil;
    (*tempWC)->hasSelection = false;
    (*tempWC)->windowDirty = false;
    (*tempWC)->boxHandle = nil;
    (*tempWC)->textSections = nil;
    HUnlock((Handle)tempWC);
    gScrapData = NewHandle(0);
    UpdateScrap(false);                                     /* not visible, don't refresh */
}
 
/* end CreateClipBoard */
 
 
/* CreateAEStatus creates our invisible AEStatus window at application */
/* start time, and keeps it open always.  Visibility is toggled from the edit menu, */
/* but the window always exists */
void CreateAEStatus(void)
{
    WindowPtr tempWindow;
    windowCHandle tempWC;
    WindowPtr tempPort;
    Rect dest;
    /* open my clipboard window */
    tempWindow = GetNewWindow(kAEStatusWindowID, 0, (WindowPtr)-1);
    ((WindowPeek)tempWindow)->windowKind = kAEStatusWindow;
    /* since I'm using the same function for my clipboard as for a document window, I have */
    /* to change some of the fields */
    ((WindowPeek)tempWindow)->refCon = NewHandleClear(sizeof(windowControl));        /* add our control structure to it */
    tempWC = (windowCHandle)GetWRefCon(tempWindow);         /* and put it where we can use it */
    HLock((Handle)tempWC);                                  /* lock it down */
    /* add pointers to our procedures for drawing, saving, and closing */
    (*tempWC)->drawMe = (ProcPtr)DrawAES;
    (*tempWC)->saveMe = (ProcPtr)SaveAES;
    (*tempWC)->closeMe = (ProcPtr)CloseAES;
    (*tempWC)->clickMe = (ProcPtr)ClickAES;
    (*tempWC)->sizeMe = (ProcPtr)SizeAES;
    (*tempWC)->currentAction = nil;
    (*tempWC)->undoAction = nil;
    (*tempWC)->hasSelection = false;
    (*tempWC)->windowDirty = false;
    
    (*tempWC)->textSections = nil;
    (*tempWC)->fileAliasHandle = (AliasHandle)NewHandle(0);
    (*tempWC)->windowDirty = false;
    (*tempWC)->windowIndex = 999999; /* make abnormally large */
    HUnlock((Handle)tempWC);
    /* and this window has a  text edit field */
    GetPort(&tempPort);                                     /* save and set port so TextEdit puts the record in the right place */
    SetPort(tempWindow);
    
    dest = tempWindow->portRect;
    dest.right -= 16;
    (*tempWC)->boxHandle = TENew(&dest, &dest);
    TEAutoView(true, (*tempWC)->boxHandle);                 /* make the text auto-scrolling */
    SetPort(tempPort);
}
 
/* StartMenus loads our menu bar resource, and initializes the menus 
*   and some settings related to the menu items 
*/
 
void StartMenus(void)
{
    MenuHandle tempHandle;
    StringHandle helpString;
    Handle myMBar;
    short count;
    myMBar = GetNewMBar(kOurMenuBar);
    SetMenuBar(myMBar);
    gAppleMenuHandle = GetMenuHandle(kAppleMenu);
    gFileMenuHandle = GetMenuHandle(kFileMenu);
    gEditMenuHandle = GetMenuHandle(kEditMenu);
    gToolMenuHandle = GetMenuHandle(kToolsMenu);
    gAppleEventMenuHandle = GetMenuHandle(kAEMenu);
    gEditionMenuHandle = GetMenuHandle(kEditionMenu);
    gWindowMenuHandle = GetMenuHandle(kWindowMenu);
    if(gHasColor){
        gColorMenuHandle = GetMenu(kColorMenu);
        InsertMenu(gColorMenuHandle,0);
        CheckItem(gColorMenuHandle,kBlackColorItem,true);
        }
        DrawMenuBar();  
    /* The following lines add my Help item to the Sys 7 Help menu. */
    /* That's where help should go now, _not_ under the Apple Menu as we have  */
    /* been doing for so long.  Since we now have an actual Help menu, use it, */
    /* since your users will expect it. */
    /* get the Help menu handle */
    HMGetHelpMenuHandle(&tempHandle);
    /* How many items does it have? */
    count = CountMItems(tempHandle);
    /* get our help string from our resource fork */
    helpString = GetString(kHelpString);
    DetachResource(helpString);
    HNoPurge(helpString);
    MoveHHi((Handle)helpString);
    HLock((Handle)helpString);
    /* Add our help item to the help menu */
    InsertMenuItem(tempHandle, (Ptr)*helpString, count + 1);
    HUnlock(helpString);
    HPurge(helpString);
    /* Remember what our help item number is */
    gHelpItem = CountMItems(tempHandle);
    
    /* add heirarchical menus for AppleEvent menu */
    tempHandle = GetMenu(kGetDataSubmenu);
    InsertMenu(tempHandle, -1);
    /* and the setdata hier */
    tempHandle = GetMenu(kSetDataSubmenu);
    InsertMenu(tempHandle, -1);
    
    AppendResMenu(gAppleMenuHandle, 'DRVR');                   /* add DAs */
}
 
/* end StartMenus */
 
/* InitAEStuff checks to see if this machine has AppleEvents and 
*   does our setup.
*   If AppleEvents are not found, we alert and exit.
*   This is also the place where all the handlers for AppleEvents we deal
*   with are installed.  This includes the required AppleEvents, and the
*   Edition Manager specific ones used in this app.
*/
#pragma segment MyInit
void InitAEStuff(void)
{
    extern Boolean gHasAppleEvents;
    long aLong;
 
    // leaks Routine Descriptors, but we'll live
    AEinstalls HandlersToInstall[] =  {
        /* The above are the four required AppleEvents. */ {
            kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(AEOpenHandler)
        },  {
            kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(AEOpenDocHandler)
        },  {
            kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc(AEPrintHandler)
        },  {
            kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(AEQuitHandler)
        }, 
        /* These are the five Edition Manager AppleEvents  */ {
            kCoreEventClass, kAECreatePublisher, NewAEEventHandlerProc(AECreatePubHandler)
        },  {
            sectionEventMsgClass, sectionReadMsgID, NewAEEventHandlerProc(AEReadSectionHandler)
        },  {
            sectionEventMsgClass, sectionWriteMsgID, NewAEEventHandlerProc(AEWriteSectionHandler)
        },  {
            sectionEventMsgClass, sectionScrollMsgID, NewAEEventHandlerProc(AEScrollSectionHandler)
        },  {
            sectionEventMsgClass, sectionCancelMsgID, NewAEEventHandlerProc(AECancelSectionHandler)
        }, 
        /*  some core event handlers */ {
            kAECoreSuite, kAEGetData, NewAEEventHandlerProc(AEGetDataHandler)
        },  {
            kAECoreSuite, kAESetData, NewAEEventHandlerProc(AESetDataHandler)
        },  {
            kAECoreSuite, kAEAnswer, NewAEEventHandlerProc(AEAnswerHandler)
        }
    };
    
    // leaks Routine Descriptors, but we'll live
    static CoercionInstalls CoercionsToInstall[] =  {
        {
            typeAlias, typeTargetID, NewAECoercePtrProc(CoerceAliasToTargetID), false
        },  {
            typeBoolean, typeChar, NewAECoercePtrProc(CoerceBooleanToChar), false
        },  {
            typeQDRectangle, typeChar, NewAECoercePtrProc(CoerceQDRectToChar), false
        }, 
        /* and two little coercions I just had to have... */ {
            typeChar, typeMyPString, NewAECoercePtrProc(CoerceCharToPString), false
        },  {
            typeMyPString, typeChar, NewAECoercePtrProc(CoercePStringToChar), false
        }
    };
    
    OSErr aevtErr = noErr;
    aLong = 0;
    /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
    *   then we exit */
    gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
    /* The following series of calls installs all our AppleEvent Handlers.
    *   These handlers are added to the application event handler list that 
    *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
    *   and we call AEProcessEvent, the AppleEvent manager will check our
    *   list of handlers and dispatch to it if there is one.
    */
    if (gHasAppleEvents) {
        register qq;
        for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
            aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
                                            HandlersToInstall[qq].theProc, 0, false);
            
            if (aevtErr) {
                ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
                Str31 text1, text2;
                NumToString((long)aevtErr, text1);
                text2[0] = 4;
                BlockMove((Ptr)&HandlersToInstall[qq].theEvent, (Ptr)text2, 4);
                ParamText(text1, text2, "", "");
                NoteAlert(kBadHInstall, upp);
                DisposeRoutineDescriptor(upp);
            }
        }
        /* now our coercion routines */
        for (qq = 0; qq < ((sizeof(CoercionsToInstall) / sizeof(AEinstalls))); qq++) {
            aevtErr = AEInstallCoercionHandler(CoercionsToInstall[qq].fromType, CoercionsToInstall[qq].toType,
                                               CoercionsToInstall[qq].theProc, nil, false, false);
            if (aevtErr) {
                ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
                Str31 text1, text2;
                NumToString((long)aevtErr, text1);
                text2[0] = 4;
                BlockMove((Ptr)&CoercionsToInstall[qq].fromType, (Ptr)text2, 4);
                ParamText(text1, text2, "", "");
                NoteAlert(kBadHInstall, upp);
                DisposeRoutineDescriptor(upp);
            }
        }
       
   } else {
        ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
        Alert(kNoAppleEvents, upp);
        DisposeRoutineDescriptor(upp);
        ExitToShell();
    }
    /* this function initializes the OSL and installs our handlers */
    aevtErr = InstallObjectHandlers();
    if (aevtErr) {
        
        ShowMe("\p Object Lib error, failing and exiting", aevtErr, __LINE__);
        ExitToShell();
    }
    /* and one more thing, create my null descriptor to build all my objects from. */
    /* you may want to do this each time, personal choice */
    aevtErr = AECreateDesc(typeNull, nil, 0, &gNullDesc);
    mAEErrorDisplay("\pCreating nul desc", aevtErr)
}
 
/* end InitAEStuff */
 
 
#undef __INIT__