MacApplication.c

/*
    File:       MacApplication.c
 
    Contains:   Digitizer Shell specific functions concerning the application shell.
 
    Written by:     
 
    Copyright:  Copyright © 1994-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/28/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
 
// INCLUDES
#include "MacApplication.h"
#include "MacFramework.h"
#include "AppConfiguration.h"
#include "DTSQTUtilities.h"
 
// Header file for the specific test functions.
#include "TestFunctions.h"
 
// GLOBALS
long gMaxMilliSecToUse = 0L;        
 
// These are our global SG settings, if needed we need to export these using get/set functions
// as these are internal to this file (.c).
SeqGrabComponent    gSG = NULL;
WindowPtr               gCaptureWindow = NULL;
SGChannel                   gVideoChannel = NULL;
SGChannel                   gAudioChannel = NULL;
SGGrabCompleteBottleUPP gSGGrabCompleteUPP = 0;
 
static long                 gGrabCompleteCounter = 0L;
static long                 gGrabCompleteTimer = 0L;
 
 
// FUNCTIONS
// ______________________________________________________________________
void DoIdle(WindowRef theWindow)
{
    GrafPtr                 aSavedPort;
    
    GetPort(&aSavedPort);
    SetPort(theWindow);
    
    // Update the SG port assuming it's in use.
    if(gSG != NULL)
        SGIdle(gSG);
    
// @@@INSERT ANY IDLE BASED FUNCTIONALITY HERE
 
    SetPort(aSavedPort);
}
 
 
// ______________________________________________________________________
void DoUpdateWindow(WindowRef theWindow, Rect *theRefreshArea)
{
    #pragma unused(theRefreshArea)
    GrafPtr aSavedPort;
    
    GetPort(&aSavedPort);
    SetPort(theWindow);
    
    BeginUpdate(theWindow);
 
    if(gSG != NULL)
        SGUpdate(gSG, NULL);
        
// @@@INSERT WINDOW SPECIFIC DRAWING FUNCTIONALITY HERE
 
    EndUpdate(theWindow);
    SetPort(aSavedPort);
}
 
 
 
// ______________________________________________________________________
void DoCloseWindow(WindowRef theWindow)
{
    #pragma unused(theWindow)
    OSErr anErr = noErr;
    long nTicks = 0L;
    long finalTicks = TickCount(); 
    float  result;
 
    // Clean up the channels (CloseComponent will handle that).
    anErr = CloseComponent(gSG);  DebugAssert(anErr != noErr);
    gSG = NULL; gVideoChannel = NULL; gAudioChannel = NULL;
    gCaptureWindow = NULL;
 
    // Show any statistics generated while we digitized (weird code but I had problems with float conversions)
    nTicks = finalTicks - gGrabCompleteTimer;           // 1/60:th of a second units
    result = (float) gGrabCompleteCounter/nTicks ;
    printf("The GrabFrameComplete callback was called %7.2f times a second.\n", result * 60.0 );
}
 
 
// ______________________________________________________________________
void     DoDragWindow(WindowRef theWindow, EventRecord *theEvent)
{
    GrafPtr aSavedPort;
    ICMAlignmentProcRecord alignProc;
    
    GetPort(&aSavedPort);
    SetPort(theWindow);
    
    if(gSG != NULL)
    {
        SGPause(gSG, true);
        SGGetAlignmentProc(gSG, &alignProc);
        
        DragAlignedWindow(theWindow, theEvent->where, &qd.screenBits.bounds, NULL, &alignProc);
        SGPause(gSG, false);
    }
    // @@@INSERT WINDOW DRAGGING SPECIFIC FUNCTIONALITY HERE
        
    SetPort(aSavedPort);
}
 
// ______________________________________________________________________
void HandleContentClick(WindowRef theWindow, EventRecord *theEvent)
{
    #pragma unused(theEvent)
    GrafPtr aSavedPort;
    
    GetPort(&aSavedPort);
    SetPort(theWindow);
 
    // @@@INSERT APPLICATION SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
 
    SetPort(aSavedPort);
}
 
 
 
// ______________________________________________________________________
WindowRef CreateMovieWindow(Rect *theRect, Str255 theTitle)
{
    WindowPtr   aWindow     = NULL;
    Rect                devRect     = {0, 0, 0, 0};
    
        GetBestDeviceRect(NULL, &devRect);
        
        OffsetRect(theRect, devRect.left + 20, devRect.top + 20);
        aWindow = NewCWindow( NULL, theRect, theTitle, true, noGrowDocProc, (WindowPtr)-1,
                                                true, 0);
    return aWindow;
}
 
// ______________________________________________________________________
void HandleApplicationMenu(short theMenuID, short theMenuItem)
{
    //  HANDLE ANY ADDITIONAL MENU ENTRIES HERE
    switch(theMenuID)
    {
        // Test menus.
        case mTesting:
            switch(theMenuItem)
            {
                case iTest1:
                {
                    ShowVDIGInfo();
                    break;
                }
                
                case iTest2:
                {
                    SetMyVideoChannelSettings();
                    break;
                }
                
                case iTest3:
                {
                    SetMyAudioChannelSettings();
                    break;
                }
                
                case iTest5:                // Record to file.
                {
                    RecordSamplesToFile();
                    break;
                }
            }
            break;
        
        // Capture Size Menus.
        case mCaptureSize:
        {
            switch(theMenuItem)
            {
                case iSizeNormal:
                {
                    if( QTUChangeSGWindowSize( GetDefaultSGInstance(), GetDefaultVideoChannel() , gCaptureWindow, 320L, 240L) != noErr)
                        SysBeep(kDefaultSysBeep);
                    break;
                }
                
                case iSizeSmall:
                {
                    if ( QTUChangeSGWindowSize( GetDefaultSGInstance(), GetDefaultVideoChannel() , gCaptureWindow,160L, 120L) != noErr)
                            SysBeep(kDefaultSysBeep);
                    break;
                }
                
                case iSizeBig:
                {
                    if ( QTUChangeSGWindowSize( GetDefaultSGInstance(), GetDefaultVideoChannel() , gCaptureWindow, 640L, 480L) != noErr)
                        SysBeep(kDefaultSysBeep);
                    break;
                }
            }
        break;
        }
        
        // End testing menus
    }
}
 
 
// ______________________________________________________________________
void    AdjustApplicationMenus(void)
{
    MenuHandle mHandle = NULL;
    
    // For the time being always dim the edit entries (maybe later if needed enable these)
    mHandle = GetMenuHandle(mEdit);
    DisableItem(mHandle, iUndo);
    DisableItem(mHandle, iCut);
    DisableItem(mHandle, iCopy);
    DisableItem(mHandle, iPaste);
    DisableItem(mHandle, iClear);
    DisableItem(mHandle, iSelectAll);
    
    // Test if we have a valid capture window open, if true, then enable the right menus, otherwise
    // disable them.
    if(gCaptureWindow != NULL)
    {
        DisableItem(GetMenuHandle(mFile), iNew);
        EnableItem(GetMenuHandle(mFile), iClose);
    
        mHandle = GetMenuHandle(mTesting);
        EnableItem(mHandle, iTest1);
        EnableItem(mHandle, iTest2);
        EnableItem(mHandle, iTest3);
        EnableItem(mHandle, iTest5);
 
        mHandle = GetMenuHandle(mCaptureSize);
        EnableItem(mHandle, iSizeNormal);
        EnableItem(mHandle, iSizeSmall);
        EnableItem(mHandle, iSizeBig);
    }
    else
    {
        EnableItem(GetMenuHandle(mFile), iNew);
        DisableItem(GetMenuHandle(mFile), iClose);
 
        mHandle = GetMenuHandle(mTesting);
        DisableItem(mHandle, iTest1);
        DisableItem(mHandle, iTest2);
        DisableItem(mHandle, iTest3);
        DisableItem(mHandle, iTest5);
 
        mHandle = GetMenuHandle(mCaptureSize);
        DisableItem(mHandle, iSizeNormal);
        DisableItem(mHandle, iSizeSmall);
        DisableItem(mHandle, iSizeBig);
    }
}
 
 
// ______________________________________________________________________
void CreateSGEnviroment(void)
{
    OSErr                       anErr = noErr;
    WindowPtr               aWin = NULL;
    Rect                            defRect = {20, 20, 260, 340};
    
    if(gSG != NULL || gCaptureWindow != NULL)   // already in use
        return;
    
    gCaptureWindow = CreateMovieWindow(&defRect, "\pSG Grabber Window");
    DebugAssert(gCaptureWindow != NULL);
    
    gSG = QTUCreateSequenceGrabber(gCaptureWindow); DebugAssert(sg != NULL);
    if(gSG == NULL) 
    {
        printf("ERROR: Problem opening the default Sequence Grabber component.\n");
        goto Closure;
    }
    
    anErr = QTUCreateSGGrabChannels(gSG, &gCaptureWindow->portRect, seqGrabPlayDuringRecord + seqGrabRecord,
                        &gVideoChannel, &gAudioChannel); DebugAssert(anErr == noErr); DebugAssert(anErr != noErr);
    if(anErr != noErr) 
    {
        printf("ERROR: Problems creating the Video and Audio SG Channels: %ld.\n", anErr);  
        goto Closure;
    }           
 
#ifdef BOTTLENECKS  
     anErr = SetupVideoBottleNecks(gVideoChannel, gCaptureWindow,  &tempPort); DebugAssert(anErr == noErr);
     if(anErr != noErr)
     {
        printf("ERROR: Problems installing the new video bottle necks: %ld.\n", anErr);
        goto Closure;
     }
     else
        printf("STATUS: Installed video bottle necks.\n");
#endif // BOTTLENECKS
 
    anErr = SGStartPreview(gSG); DebugAssert(anErr == noErr);
    if(anErr != noErr) 
    {
        printf("ERROR: Problems starting the SG Preview: %ld.\n", anErr);
        goto Closure;
    }
    else
        printf("STATUS: Opened Default SG component, created channels (audio, sound), started Preview.\n");
 
Closure:
    return;
}
 
 
 
// ______________________________________________________________________
SeqGrabComponent    GetDefaultSGInstance(void)
{
    return gSG;
}
 
 
SGChannel GetDefaultVideoChannel(void)
{
    return gVideoChannel;
}
 
 
SGChannel GetDefaultAudioChannel(void)
{
    return gAudioChannel;
}
 
 
pascal ComponentResult SpecialGrabFrameComplete(SGChannel c, short bufferNum,
                                                                                Boolean *done, long refCon)
{
    ComponentResult anErr = noErr;
 
    anErr = SGGrabFrameComplete(c, bufferNum, done); DebugAssert(anErr == noErr);
    
    if(gGrabCompleteCounter != 0)
        gGrabCompleteCounter++;
    else
    {
        gGrabCompleteTimer = TickCount();
        gGrabCompleteCounter++;
    }
        
    if(*done) { // Frame is done?
        CGrafPtr            tempPort = (CGrafPtr)refCon;
 
#if DRAWING 
        Rect                    bufferRect;
        GDHandle            saveGD;
        PixMapHandle    savePM;
        CGrafPtr            aSavedPort;
        PixMapHandle    bufferPM;
 
        GetGWorld(&aSavedPort, &saveGD);
        SetGWorld(tempPort, NULL);
        
        anErr = SGGetBufferInfo(c, bufferNum, &bufferPM, &bufferRect, NULL, NULL);
        DebugAssert(anErr == noErr);
        
        if(!anErr) {
            
            savePM = tempPort->portPixMap;
            SetPortPix(bufferPM);
            
            TextMode(srcXor);
            MoveTo(bufferRect.right - 20, bufferRect.bottom - 14);
            DrawString("\pHello");
            TextMode(srcOr);
            SetPortPix(savePM);
        }
        SetGWorld(aSavedPort, saveGD);
#endif // DRAWING
    }
    return anErr;
}
 
 
 
OSErr SetupVideoBottleNecks(SGChannel videoChannel, WindowPtr theWindow, CGrafPtr tempPort)
{
    #pragma unused(theWindow)
    OSErr anErr = noErr;
 
    OpenCPort(tempPort);
    SetRectRgn(tempPort->visRgn, -32000, -32000, 32000, 32000);
    CopyRgn(tempPort->visRgn, tempPort->clipRgn);
    PortChanged((GrafPtr)tempPort);
    
    anErr = SGSetChannelRefCon(videoChannel, (long)tempPort); DebugAssert(anErr == noErr);
    if(!anErr){
        VideoBottles vb;
        
        vb.procCount = 9;
        anErr = SGGetVideoBottlenecks(videoChannel, &vb); DebugAssert(anErr == noErr);
        if(!anErr){
            gSGGrabCompleteUPP = NewSGGrabCompleteBottleProc(SpecialGrabFrameComplete);
            vb.grabCompleteProc = gSGGrabCompleteUPP;
            
            anErr = SGSetVideoBottlenecks(videoChannel, &vb); DebugAssert(anErr == noErr);
        }
        
    gGrabCompleteCounter = 0L;  // Setup the timer counter value.
    }
    return anErr;
}