Sample Components/PictMediaHandler.c

/*
    File:       PictMediaHandler.r
 
    Written by: Peter Hoddie
 
    Copyright:  © 1992 by Apple Computer, Inc., all rights reserved.
 
*/
 
#include <ToolUtils.h>
 
#include <MediaHandlers.h>
#include <Movies.h>
 
typedef struct {
    ComponentInstance   self;
    ComponentInstance   parent;
    ComponentInstance   delegateComponent;
 
    Fixed               width;
    Fixed               height;
 
    MatrixRecord        matrix;
 
    Media               media;
    Track               track;
} PictGlobalsRecord, *PictGlobals;
 
pascal ComponentResult PictMediaDispatch(ComponentParameters *params, Handle storage);
pascal ComponentResult PictOpen(PictGlobals globals, ComponentInstance self);
pascal ComponentResult PictClose(PictGlobals globals, ComponentInstance self);
pascal ComponentResult PictCanDo(PictGlobals globals, short ftnNumber);
pascal ComponentResult PictVersion(PictGlobals globals);
pascal ComponentResult PictTarget(PictGlobals store, ComponentInstance parentComponent);
pascal ComponentResult PictInitialize (PictGlobals store, GetMovieCompleteParams *gmc);
pascal ComponentResult PictIdle (PictGlobals store, TimeValue atMediaTime, long flagsIn, 
                long *flagsOut, const TimeValue *tr);
pascal ComponentResult PictSetDimensions (PictGlobals store, Fixed width, Fixed height);
pascal ComponentResult PictSetMatrix (PictGlobals store, MatrixRecord *trackMovieMatrix);
 
// entry point for all Component Manager requests
pascal ComponentResult PictMediaDispatch(ComponentParameters *params, Handle storage)
{
    OSErr err = badComponentSelector;
    ComponentFunction componentProc = 0;
 
    switch (params->what) {
        case kComponentOpenSelect: componentProc = PictOpen; break;
        case kComponentCloseSelect: componentProc = PictClose; break;
        case kComponentCanDoSelect: componentProc = PictCanDo; break;
        case kComponentVersionSelect: componentProc = PictVersion; break;
        case kComponentTargetSelect: componentProc = PictVersion; break;
 
        case kMediaInitializeSelect: componentProc = PictInitialize; break;
        case kMediaIdleSelect: componentProc = PictIdle; break;
        case kMediaSetDimensionsSelect: componentProc = PictSetDimensions; break;
        case kMediaSetMatrixSelect: componentProc = PictSetMatrix; break;
    }
 
    if (componentProc)
        err = CallComponentFunctionWithStorage(storage, params, componentProc);
    else
        err = DelegateComponentCall(params, ((PictGlobals)storage)->delegateComponent);
 
    return err;
}
 
pascal ComponentResult PictCanDo(PictGlobals globals, short ftnNumber)
{
    switch (ftnNumber) {
        case kComponentOpenSelect:
        case kComponentCloseSelect:
        case kComponentCanDoSelect:
        case kComponentVersionSelect: 
        case kComponentTargetSelect: 
 
        case kMediaInitializeSelect: 
        case kMediaIdleSelect: 
        case kMediaSetDimensionsSelect:
        case kMediaSetMatrixSelect: 
            return true;
        default:
            return ComponentFunctionImplemented( globals->delegateComponent, ftnNumber );
    }
}
 
pascal ComponentResult PictVersion(PictGlobals globals)
{
    return 0x00020001;
}
 
pascal ComponentResult PictOpen(PictGlobals globals, ComponentInstance self)
{
    OSErr err;
 
    // allocate storage
    globals = (PictGlobals)NewPtrClear(sizeof(PictGlobalsRecord));
    if (err = MemError()) return err;
 
    SetComponentInstanceStorage(self, (Handle)globals);
    globals->self = self;
    globals->parent = self;
 
    // find a Base Media Handler to delegate to
    globals->delegateComponent = OpenDefaultComponent(MediaHandlerType, BaseMediaType);
    if (globals->delegateComponent)
        PictTarget(globals, self);      // set up the calling chain
    else {
        DisposePtr((Ptr)globals);
        err = cantOpenHandler;
    }
 
    return err;
}
 
pascal ComponentResult PictClose(PictGlobals globals, ComponentInstance self)
{
    if (globals) {
        if (globals->delegateComponent)
            CloseComponent(globals->delegateComponent);
 
        DisposePtr((Ptr)globals);
    }
    
    return noErr;
}
 
pascal ComponentResult PictTarget(PictGlobals store, ComponentInstance parentComponent)
{
    // remember who is at the top of our calling chain
    store->parent = parentComponent;
    // and inform out delegate component of the change as well
    ComponentSetTarget(store->delegateComponent, parentComponent);
 
    return noErr;
}
 
pascal ComponentResult PictInitialize (PictGlobals store, GetMovieCompleteParams *gmc)
{
    // remember some useful parameters
    store->width = gmc->width;
    store->height = gmc->height;
    store->matrix = gmc->trackMovieMatrix;
    store->media = gmc->theMedia;
    store->track = gmc->theTrack;
 
    // tell the Base Media Handler about ourselves
    MediaSetHandlerCapabilities(store->delegateComponent, handlerHasSpatial, handlerHasSpatial);
 
    return noErr;
}
 
pascal ComponentResult PictIdle (PictGlobals store, TimeValue atMediaTime, long flagsIn, 
            long *flagsOut, const TimeValue *tr)
{
    OSErr err;
    Rect r;
    Handle sample = NewHandle(0);
 
    if (err = MemError()) goto bail;
 
    // get the current sample
    err = GetMediaSample(store->media, sample, 0, nil,
        atMediaTime, nil, 0, 0, 0, 0, 0, 0);
    if (err) goto bail;
 
    // draw it using the current matrix
    SetRect(&r, 0, 0, FixRound(store->width), FixRound(store->height)); 
    TransformRect(&store->matrix, &r, nil);
    EraseRect(&r);
    DrawPicture((PicHandle)sample, &r);
 
bail:
    DisposeHandle(sample);
    *flagsOut |= mDidDraw;      // let MovieToolbox know we drew something
 
    return err;
}
 
pascal ComponentResult PictSetDimensions (PictGlobals store, Fixed width, Fixed height)
{
    // remember the new track dimensions
    store->width = width;
    store->height = height;
 
    return noErr;
}
 
pascal ComponentResult PictSetMatrix (PictGlobals store, MatrixRecord *trackMovieMatrix)
{
    // remember the new display matrix
    store->matrix = *trackMovieMatrix;
 
    return noErr;
}