MyApplication.c

/*
    File:       MyApplication.c
    
    Contains:   My Application Shell.
 
    Written by: John Wang
 
    Copyright:  © 1994 by Apple Computer, Inc., all rights reserved.
 
    Change History (most recent first):
 
        <1>     03/14/94    JW      Re-Created for Universal Headers.
 
    To Do:
    
*/
 
#ifdef THINK_C
#define     applec
#endif
 
#include    <Types.h>
#include    <Memory.h>
#include    <QuickDraw.h>
#include    <Palettes.h>
#include    <QDOffscreen.h>
#include    <Errors.h>
#include    <Fonts.h>
#include    <Dialogs.h>
#include    <Windows.h>
#include    <Menus.h>
#include    <Events.h>
#include    <Desk.h>
#include    <DiskInit.h>
#include    <OSUtils.h>
#include    <Resources.h>
#include    <ToolUtils.h>
#include    <AppleEvents.h>
#include    <EPPC.h>
#include    <GestaltEqu.h>
#include    <Processes.h>
#include    <Balloons.h>
#include    <Aliases.h>
#include    <MixedMode.h>
#include    <Scrap.h>
#include    <LowMem.h>
 
#include    <Movies.h>
 
#include    "MyApplication Shell (2.0).h"
#include    "MyApplication.h"
#include    "BetterFlattenMovie.h"
#include    "MyMovieStuff.h"
 
/* ------------------------------------------------------------------------- */
 
//  These globals are used by the shell and must be defined:
 
long        gQDfeature, gWindowCount;
Str255      gMyAboutTitle = "\pQuickTime App";
Str255      gMyAboutDesc = "\pThis is a multiple movie playback app.";
 
/* ------------------------------------------------------------------------- */
 
//  MyInitialize is called at init time after the toolbox is initialized.  This routine is
//  called only once.
 
OSErr MyInitialize()
{
    OSErr       err;
 
    //  We require QuickTime so make sure it is available.
    err = Gestalt(gestaltQuickTime, &gQDfeature);
    if ( err != noErr )
        return ( err );
 
    err = EnterMovies();
    if ( err != noErr )
        return ( err );
        
    return ( noErr );
}
 
//  Depending on the value of the constant MYEVENTDEF, this routine may have different
//  calling frequency.
//  If MYEVENTDEF == 2, then this routine gets called for every
//     window owned by the application of type MAS_WINDOWDOC per iteration of the event loop
//     if the event is NOT a null event.  MyEvent can assume that the grafport and gdevice
//     are set to the window being passed.
//  If MYEVENTDEF == 1, then this routine gets called once per event loop is the
//     event is NOT a null event.  theWindow will be nil.
//  If MYEVENTDEF == 0, this routine never gets called.
//  Returning true indicates that the event was handled and can be ignored by the normal
//  event handler.
 
Boolean MyEvent(WindowPtr theWindow, EventRecord *myEvent)
{
    WindowInfoHandle    myWinfo;
    Boolean             ret;
    
    ret = false;
    myWinfo = (WindowInfoHandle) GetWRefCon(theWindow);
    if ( (**myWinfo).theMC != nil ) {
        ret = MCIsPlayerEvent((**myWinfo).theMC, myEvent);
    }
    
    return ( ret );
}
 
//  Depending on the value of the constant MYIDLEDEF, this routine may have different
//  calling frequency.
//  If MYIDLEDEF == 2, then this routine gets called for every
//     window owned by the application of type MAS_WINDOWDOC per iteration of
//     the event loop.  You can assume that the port and gdevice are set to the window.
//  If MYIDLEDEF == 1, then this routine gets called once per event loop.  theWindow will be nil.
//  If MYIDLEDEF == 0, this routine never gets called.
 
void MyIdle(WindowPtr theWindow)
{
    WindowInfoHandle    myWinfo;
    
    myWinfo = (WindowInfoHandle) GetWRefCon(theWindow);
    if ( (**myWinfo).theMC != nil ) {
        MCIdle((**myWinfo).theMC);
    }
}
 
//  MyDraw is called when redrawing the window is needed.  The port and gdevice
//  is already set and begin and end update are called for MyDraw.
 
void MyDraw(WindowPtr theWindow)
{
    //  Erase a black background for movie.
    PaintRect(&(theWindow->portRect));
}
 
//  This routine gets called once when the application is quitting.
//  This gives the app the chance to clean up.
 
void MyFinishup()
{
    //  As discussed in issue #13 of 'develop' magazine, it is better to let QuickTime
    //  call ExitMovies().
}
 
//  This routine is called whenever the app receives a suspend or resume event.  This
//  allows the yield time (passed to WaitNextEvent) to be changed.  I.e., if you don't
//  do much processing the in background, you should set the yield to a high value
//  when the suspend message is received.
 
long MyYieldTime(long message)
{
    if ( message )
        //  Resume message
        return ( 0 );
    else
        //  Suspend message
        return ( 30 );
}
 
//  If the shell's doCommand routine can not process the menu selection, then this routine is
//  called.  Do not call HiliteMenu because it is called by the shell.
//  If the command can not be handled, this it must be an error and the shell will
//  present a FATAL error to the user.
 
OSErr MyDoCommand(short theMenu, short theItem)
{
    WindowPtr               frontWindow;
    WindowInfoHandle        myWinfo;
    
    switch ( theMenu ) {
        case kMENU_COLLECTION:
            if ( IsMyWindow(frontWindow = FrontWindow()) ) {
                myWinfo = (WindowInfoHandle) GetWRefCon(frontWindow);
                switch ( theItem ) {
                    case kMENU_MACADDRESATOM:
                        Mac_AddMovieResAtom(&((**myWinfo).refNum), &((**myWinfo).theFSSpec));
                        break;
                    case kMENU_MACADDALL:
                        Mac_AddMovieAll(&((**myWinfo).refNum), &((**myWinfo).theFSSpec));
                        break;
                    case kMENU_CROSSADDALL:
                        Cross_AddMovieAll(&((**myWinfo).refNum), &((**myWinfo).theFSSpec));
                        break;
                    case kMENU_BOTHADDALL:
                        Both_AddMovieAll(&((**myWinfo).refNum), &((**myWinfo).theFSSpec));
                        break;
                    default:
                        return ( theItem );
                }
                adjustMoviesMenu(frontWindow);
            } else
                SysBeep(50);
            break;
            
        case kMENU_MOVIES:
            if ( IsMyWindow(frontWindow = FrontWindow()) )
                SelectThisMovie(theItem);
            else
                SysBeep(50);
            break;
            
        default:
            return ( theItem );
    }
    
    return ( noErr );
}
 
void MyDoKeyDown(EventRecord *myEvent)
{
}
 
void MyInContent(WindowPtr foundWindow, Point where)
{
}
 
void MyZoomWindow(WindowPtr foundWindow, short windowPart)
{
    if ( windowPart == 8 ) {
    } else {
    }
 
    ZoomWindow(foundWindow, windowPart, true);
}
 
void MyAdjustMenus()
{
}
 
/* ------------------------------------------------------------------------- */
 
WindowPtr createMoviesWindow(FSSpec *movieFSSpec, short theRefNum);
WindowPtr createMoviesWindow(FSSpec *movieFSSpec, short theRefNum)
{
    WindowPtr               myWindow;
    WindowInfoHandle        myWinfo;
    Rect                    windowRect;
    GDHandle                myMaxDevice;
 
    //  Create window.
    myMaxDevice = GetMaxDevice(&((**LMGetGrayRgn()).rgnBBox));
    windowRect = (**((**myMaxDevice).gdPMap)).bounds;
    myWindow = NewCWindow(0L, &windowRect, (*movieFSSpec).name, 1, noGrowDocProc, (WindowPtr) -1, true, 0L);
    OffsetRect(&windowRect, -windowRect.left, -windowRect.top);
    SetMyWindow(myWindow);
    SetGWorld((CGrafPtr) myWindow, GetMainDevice());
    
    //  This handle must be locked because we dereference it all the time.
    myWinfo = (WindowInfoHandle) NewHandle(sizeof(WindowInfo));
    MoveHHi((Handle) myWinfo);
    HLock((Handle) myWinfo);
    SetWRefCon(myWindow, (long) myWinfo);
    
    (**myWinfo).theFSSpec = *movieFSSpec;
    (**myWinfo).refNum = theRefNum;
    (**myWinfo).theMovie = nil;
    (**myWinfo).theMC = nil;
    (**myWinfo).moviename[0] = 0;
    (**myWinfo).resId = -1;
    (**myWinfo).movieOffset = -1;
    
    return ( myWindow );
}
 
void MyNew()
{
    WindowPtr               myWindow;
    StandardFileReply       reply;
    short                   myRefNum;
    MenuHandle              myMenu;
    
    if ( gWindowCount > 0 ) {
        SysBeep(50);
        return;
    }
    
    //  Ask for a new document file.  If none given, then quit.
    StandardPutFile("\pNew document", "\pMovie Collection", &reply);
    if ( !reply.sfGood )
        return;
 
    //  Use QuickTime to create movie file.
    if ( CreateMovieFile(&reply.sfFile, 'WnG1', smSystemScript,
            createMovieFileDeleteCurFile | createMovieFileDontCreateMovie, &myRefNum, nil) ) {
        Alert(kALERT_CANTNEW, nil);
        return;
    }
    
    myWindow = createMoviesWindow(&(reply.sfFile), myRefNum);
    gWindowCount += 1;
    
    //  Add new menu.
    adjustMoviesMenu(myWindow);
}
 
//  If theFSS is not nil, then the file to be opened is specified in the FSSpec.
//  MyOpen must make window frontmost so that it can be printed from finder.
void MyOpen(FSSpec *theFSS)
{
    OSErr                   err;
    WindowPtr               myWindow;
    StandardFileReply       reply;
    FSSpec                  myFSSpec;
    SFTypeList              types;
    short                   myRefNum;
    MenuHandle              myMenu;
 
    if ( gWindowCount > 0 ) {
        SysBeep(50);
        return;
    }
    
    //  If theFSS was nil, then open a file manually.
    if ( theFSS == nil ) {
        types[0] = 'MooV';
        StandardGetFilePreview(nil, 1, types, &reply);
        if (!reply.sfGood)
            return;
        myFSSpec = reply.sfFile;
    } else {
        myFSSpec = *theFSS;
    }
 
    //  Open movie file.
    err = OpenMovieFile(&myFSSpec, &myRefNum, fsRdWrPerm);
    if ( myRefNum == -1 || err ) {
        Alert(kALERT_ERROROPEN, nil);
        return;
    }
    
    myWindow = createMoviesWindow(&myFSSpec, myRefNum);
    gWindowCount += 1;
 
    //  Add new menu.
    adjustMoviesMenu(myWindow);
}
 
void MyClose()
{
    WindowPtr           closeWindow;
    WindowInfoHandle    myWinfo;
    MenuHandle          myMenu;
    
    if ((closeWindow = FrontWindow()) == nil)
        return;
        
    myWinfo = (WindowInfoHandle) GetWRefCon(closeWindow);
 
    if ((**myWinfo).theMC != nil)
        DisposeMovieController((**myWinfo).theMC);
    if ((**myWinfo).theMovie != nil);
        DisposeMovie((**myWinfo).theMovie);
    if ((**myWinfo).refNum != -1)
        CloseMovieFile((**myWinfo).refNum);
    DisposHandle((Handle) myWinfo);
    DisposeWindow(closeWindow);
    gWindowCount -= 1;
    
    //  Delete old menu.
    adjustMoviesMenu(nil);
    CompactMem(0xfffffff);
}
 
void MySave()
{
    SysBeep(50);
}
 
void MySaveAs()
{
    SysBeep(50);
}
 
void MyPageSetup()
{
    SysBeep(50);
}
 
void MyPrint()
{
    SysBeep(50);
}
 
/* ------------------------------------------------------------------------- */
 
void MyUndo(void)
{
    SysBeep(50);
}
 
void MyCut(void)
{
    SysBeep(50);
}
 
void MyCopy(void)
{
    SysBeep(50);
}
 
void MyPaste(void)
{
    SysBeep(50);
}
 
void MyClear(void)
{
    SysBeep(50);
}
 
void MySelectAll(void)
{
    SysBeep(50);
}