/* Subtitling-specific stuff */ #include "WEDemoIntf.h" #include "MBar.h" #include "ClockTime.h" #include "Format.h" #include "RunScript.h" #include "ScriptText.h" #include #include #include WindowRecord scrnWRec; WindowPtr scrnWindow; WindowRecord timeWRec; WindowPtr timeWindow; extern UInt32 sSleepTime; SInt32 lastClockTime; long gLastScrnClick; UInt16 gOvlyType; WindowPtr scriptWindow; RGBColor chromaCol; long keyColor; // the following are for the sequence grabber overlay stuff Boolean gEnteredMovies; SeqGrabComponent gSeqGrabber; SGChannel gVideoChannel; //SGChannel gSoundChannel; Rect gActiveVideoRect; ICMAlignmentProcRecordPtr gSeqGrabberAlignProc; // move this to the drag proc static OSErr XorRectToRgn(Rect* srcRectA, Rect* srcRectB, RgnHandle* destRgn); void DoVideoSettings( void ); void DrawTimeWindow ( void ); void SetOverlayType( UInt16 ovlyType ); void StartGrabber( void ); void StopGrabber( void ); void PrepareSpecialMenu( void ) { SInt16 item; MenuHandle menu; WindowPtr front; Str255 str; menu = GetMenuHandle ( kMenuSpecial ) ; for ( item = CountMenuItems ( menu ) ; item >= 1 ; item -- ) { CheckItem ( menu, item, false ) ; } CheckItem( menu, kSpecialClock, ClockRunning() ) ; CheckItem( menu, kSpecialCKey + gOvlyType - 1, true ); DisableItem ( menu, kSpecialVidSet ) ; if ( gOvlyType == ovlyGrab ) EnableItem ( menu, kSpecialVidSet ) ; EnableItem ( menu, kSpecialScript ); if ( GetWindowDocument( FrontWindow( ) ) == nil ) DisableItem ( menu, kSpecialScript ); EnableItem ( menu, kSpecialRun ); if ( scriptWindow == nil || subRunning /*|| !compiled*/ ) DisableItem ( menu, kSpecialRun ); EnableItem ( menu, kResetClock ); EnableItem ( menu, kSpecialClock ); DisableItem( menu, kSpecialStop ); if (subRunning) { DisableItem( menu, kResetClock ); DisableItem( menu, kSpecialClock ); EnableItem ( menu, kSpecialStop ); } EnableItem ( menu, kSpecialCompile ); if (scriptWindow == nil || subRunning) { DisableItem( menu, kSpecialCompile ); } DisableItem ( menu, kSpecialContinue ); if (subStarted) { EnableItem( menu, kSpecialContinue ); } // clear windows menu menu = GetMenuHandle ( kMenuWindows ) ; while( CountMItems( menu ) != 0) DeleteMenuItem( menu, 1 ); // rebuild windows menu front = FrontWindow( ); item = 1; while( front != nil) { AppendMenu( menu, "\p-" ); GetWTitle( front, str ); SetMenuItemText( menu, item, str ); if ( front == FrontWindow( ) ) CheckItem( menu, item, TRUE ); if ( front == scriptWindow ) SetItemMark( menu, item, diamondMark ); item++; front = (WindowPtr) ((WindowPeek) front) -> nextWindow; } } void DoSpecialChoice ( SInt16 menuItem ) { switch( menuItem ) { case kSpecialMenuBar: MBarToggle(); break; case kResetClock: ResetClock( ); break; case kSpecialClock: if (ClockRunning( )) StopClock( ); else StartClock( ); //clockStart = TickCount(); break; case kSpecialCKey: case kSpecialAlpha: case kSpecialGrab: SetOverlayType( menuItem - kSpecialCKey + 1 ); break; case kSpecialVidSet: DoVideoSettings( ); break; case kSpecialScript: if ( GetWindowDocument( FrontWindow( ) ) != nil ) scriptWindow = FrontWindow( ); break; case kSpecialRun: StartScript( ); break; case kSpecialStop: StopScript( ); break; case kSpecialCompile: CompileScript( ); break; case kSpecialContinue: ResumeScript( ); break; case kSpecialTest: ScriptTextTest( ); break; } } void DoWindowsChoice ( SInt16 menuItem ) { WindowPtr front; UInt16 i; front = FrontWindow( ); for( i = 1; i < menuItem; i++ ) front = (WindowPtr) ((WindowPeek) front) -> nextWindow; SelectWindow( front ); } static OSErr XorRectToRgn(Rect* srcRectA, Rect* srcRectB, RgnHandle* destRgn) { RgnHandle srcRgnA = NewRgn(); RgnHandle srcRgnB = NewRgn(); OSErr result = noErr; if ((destRgn != nil) && (*destRgn != nil)) { if ((srcRgnA != nil) && (srcRgnB != nil)) { RectRgn(srcRgnA, srcRectA); RectRgn(srcRgnB, srcRectB); XorRgn(srcRgnA, srcRgnB, *destRgn); } else { result = memFullErr; } } else { result = nilHandleErr; } return (result); } void DoVideoSettings( void ) { ComponentResult result = noErr; short width; short height; Rect curBounds; Rect curVideoRect; Rect newVideoRect; Rect newBounds; GrafPtr savedPort; RgnHandle deadRgn; Rect boundsRect; if ((gSeqGrabber != 0L) && (gVideoChannel != 0L)) { Rect newActiveVideoRect; Rect adjustedActiveVideoRect; // Get our current state result = SGGetChannelBounds(gVideoChannel, &curBounds); result = SGGetVideoRect(gVideoChannel, &curVideoRect); // Pause result = SGPause(gSeqGrabber, true); // Do the dialog thang result = SGSettingsDialog(gSeqGrabber, gVideoChannel, 0, nil, 0L, nil /*SeqGrabberModalFilterProc*/, (long)StripAddress((Ptr) scrnWindow)); // What happened? result = SGGetVideoRect(gVideoChannel, &newVideoRect); result = SGGetSrcVideoBounds(gVideoChannel, &newActiveVideoRect); // Set up our port GetPort(&savedPort); SetPort(scrnWindow); // Has our active rect changed? // If so, it's because our video standard changed (e.g., NTSC to PAL), // and we need to adjust our monitor window if (!EqualRect(&gActiveVideoRect, &newActiveVideoRect)) { width = newActiveVideoRect.right - newActiveVideoRect.left; height = newActiveVideoRect.bottom - newActiveVideoRect.top; gActiveVideoRect = newActiveVideoRect; SizeWindow(scrnWindow, width, height, false); result = SGSetChannelBounds(gVideoChannel, &(scrnWindow->portRect)); } // Has our crop changed? // This code shows how to be crop video panel friendly // Two important things - // 1) Be aware that you might have been cropped and adjust your // video window appropriately // 2) Be aware that you might have been adjusted and attempt to // account for this. Adjusting refers to using the digitizer // rect to "adjust" the active source rect within the maximum // source rect. This is useful if you're getting those nasty // black bands on the sides of your video display - you can use // the control-arrow key sequence to shift the active source // rect around when you're in the crop video panel adjustedActiveVideoRect = gActiveVideoRect; if (!EqualRect(&curVideoRect, &newVideoRect)) { if ((newVideoRect.left < gActiveVideoRect.left) || (newVideoRect.right > gActiveVideoRect.right) || (newVideoRect.top < gActiveVideoRect.top) || (newVideoRect.bottom > gActiveVideoRect.bottom)) { if (newVideoRect.left < gActiveVideoRect.left) { adjustedActiveVideoRect.left = newVideoRect.left; adjustedActiveVideoRect.right -= (gActiveVideoRect.left - newVideoRect.left); } if (newVideoRect.right > gActiveVideoRect.right) { adjustedActiveVideoRect.right = newVideoRect.right; adjustedActiveVideoRect.left += (newVideoRect.right - gActiveVideoRect.right); } if (newVideoRect.top < gActiveVideoRect.top) { adjustedActiveVideoRect.top = newVideoRect.top; adjustedActiveVideoRect.bottom -= (gActiveVideoRect.top - newVideoRect.top); } if (newVideoRect.bottom > gActiveVideoRect.bottom) { adjustedActiveVideoRect.bottom = newVideoRect.bottom; adjustedActiveVideoRect.top += (newVideoRect.bottom - gActiveVideoRect.bottom); } newBounds = newVideoRect; MapRect(&newBounds, &adjustedActiveVideoRect, &(scrnWindow->portRect)); } else // Can't tell if we've been adjusted (digitizer rect is smaller on all sides // than the active source rect) { newBounds = newVideoRect; MapRect(&newBounds, &gActiveVideoRect, &(scrnWindow->portRect)); } width = newBounds.right - newBounds.left; height = newBounds.bottom - newBounds.top; result = SGSetChannelBounds(gVideoChannel, &newBounds); } // Clean out the part of the port that isn't being drawn in deadRgn = NewRgn(); if (deadRgn != nil) { result = SGGetChannelBounds(gVideoChannel, &boundsRect); result = XorRectToRgn(&boundsRect, &(scrnWindow->portRect), &deadRgn); EraseRgn(deadRgn); DisposeRgn(deadRgn); } SetPort(savedPort); // The pause that refreshes result = SGPause(gSeqGrabber, false); } } void DrawTimeWindow( void ) { SInt32 t; Str255 s = "\p??:??:??.??"; t = GetClockTime( ); ClockToStr( t, & s ); SetPort(timeWindow); // EraseRect( & timeWindow -> portRect); MoveTo(10,30); DrawString( s ); DrawString("\p "); // NumToString( GetClockMS( ), s ); // DrawString( s ); lastClockTime = t; } void DragScrnWindow( const EventRecord *event ) { if ( event -> when - gLastScrnClick <= LMGetDoubleTime( ) ) { MoveWindow( scrnWindow, 0, 0, true ); // really this should center the window gLastScrnClick = event -> when; // on the screen which it is "mostly" in } // while respecting alignment rules gLastScrnClick = event -> when; if ( gSeqGrabber != nil) { ComponentResult result = noErr; Rect limitRect; RgnHandle grayRgn = GetGrayRgn(); Rect boundsRect; // Find bounds if (grayRgn != nil) { limitRect = (*grayRgn)->rgnBBox; } else { limitRect = qd.screenBits.bounds; } // Pause the sequence grabber //result = SGPause(gSeqGrabber, true); if (gVideoChannel != nil) { // Get the alignment proc result = SGGetAlignmentProc(gSeqGrabber, gSeqGrabberAlignProc); // Drag it with the totally cool DragAlignedWindow // Note that the sequence grabber can get real confused when you use this // call if you've got multiple video channels - this'll get fixed in the // next release. result = SGGetChannelBounds(gVideoChannel, &boundsRect); DragAlignedWindow(scrnWindow, event -> where, &limitRect, &boundsRect, gSeqGrabberAlignProc); } else { DragWindow(scrnWindow, event -> where, &limitRect); } // Start up the sequence grabber //result = SGPause(gSeqGrabber, false); } else DoDrag ( event -> where, scrnWindow ) ; } void UpdateSubWindow( WindowPtr window ) { RgnHandle updateRgn ; OSErr err; if (window == scrnWindow) { switch (gOvlyType) { case ovlyAlpha: // add this when I figure out how to do it right // break; case ovlyCKey: BeginUpdate ( window ) ; updateRgn = window -> visRgn ; EraseRgn ( updateRgn ) ; if ( ! EmptyRgn ( updateRgn ) ) { // RGBForeColor( & chromaCol ); // PaintRect( & scrnWindow -> portRect ); ForeColor( blackColor ); // text to test overlay // MoveTo(200,300); // ForeColor(yellowColor); // TextMode( srcOr ); // TextSize( 24 ); // DrawString("\pThis is a test"); // ForeColor(blackColor); UpdateSubLines( ); } EndUpdate ( window ) ; break; case ovlyGrab: if ( gSeqGrabber != nil ) { err;// err = SGUpdate( gSeqGrabber, scrnWindow -> visRgn ); } BeginUpdate ( window ) ; PmForeColor(keyColor); // RGBForeColor( & chromaCol ); // PaintRect( & scrnWindow -> portRect ); ForeColor( blackColor ); // text to test overlay // MoveTo(200,300); // ForeColor(yellowColor); // TextMode( srcOr ); // TextSize( 24 ); // DrawString("\pThis is a test"); // ForeColor(blackColor); UpdateSubLines( ); EndUpdate ( window ) ; break; } } if (window == timeWindow) { BeginUpdate ( window ) ; EraseRect( & window -> portRect); EndUpdate ( window ) ; DrawTimeWindow(); } } void ActivateSubWindow( Boolean isActivating, WindowPtr window ) { #pragma unused (isActivating) if ((window == scrnWindow) || (window == timeWindow)) { InvalMenuBar ( ) ; PrepareMenus ( ) ; } } void SubWindowKey( WindowPtr window, SInt16 key, const EventRecord * event ) { SInt16 delta; if (subStarted && (window==scrnWindow || window==timeWindow)) { delta = 0; switch(key) { case 28: // left arrow delta = 100; if (event->modifiers & optionKey) delta = 1000 / timeres; break; case 29: // right arrow delta = -100; if (event->modifiers & optionKey) delta = -1000 / timeres; break; case 30: // up arrow case 31: // down arrow break; } if (delta) SetClock( GetClockTime() + delta ); } } void StartGrabber( ) { ComponentDescription theDesc; ComponentResult result = noErr; Component sgCompID = nil; GrafPtr savedPort; if ( !gEnteredMovies ) { EnterMovies( ); gEnteredMovies = true; } // Find and open a sequence grabber theDesc.componentType = SeqGrabComponentType; theDesc.componentSubType = nil; theDesc.componentManufacturer = 'appl'; theDesc.componentFlags = nil; theDesc.componentFlagsMask = nil; sgCompID = FindNextComponent(nil, &theDesc); if (sgCompID != nil) { gSeqGrabber = OpenComponent(sgCompID); } // If we got a sequence grabber, set it up if (gSeqGrabber != nil) { // Initialize the sequence grabber GetPort(&savedPort); SetPort(scrnWindow); result = SGInitialize(gSeqGrabber); if (result == noErr) { result = SGSetGWorld(gSeqGrabber, (CGrafPtr)scrnWindow, nil); // Get a video channel result = SGNewChannel(gSeqGrabber, VideoMediaType, &gVideoChannel); if ((gVideoChannel != nil) && (result == noErr)) { short width; short height; PixMapPtr pm; RGBColor colr; result = SGGetSrcVideoBounds(gVideoChannel, &gActiveVideoRect); width = (gActiveVideoRect.right - gActiveVideoRect.left); height = (gActiveVideoRect.bottom - gActiveVideoRect.top); SizeWindow(scrnWindow, width, height, false); ShowWindow(scrnWindow); result = SGSetChannelUsage(gVideoChannel, seqGrabPreview); result = SGSetChannelBounds(gVideoChannel, &(scrnWindow->portRect)); pm = (PixMapPtr) &qd.screenBits; result = VDUseThisCLUT(gVideoChannel, pm->pmTable); keyColor = Color2Index(&chromaCol); // result = VDSetKeyColor(gVideoChannel, keyColor); result = VDGetKeyColor(gVideoChannel, &keyColor); Index2Color( keyColor, &colr/*chromaCol*/ ); } // Get a sound channel // result = SGNewChannel(gSeqGrabber, SoundMediaType, &gSoundChannel); // if ((gSoundChannel != nil) && (result == noErr)) // { // result = SGSetChannelUsage(gSoundChannel, seqGrabPreview); // } // Get readyÉ result = SGPrepare(gSeqGrabber, true, false); } // Go! result = SGStartPreview(gSeqGrabber); SetPort(savedPort); } } void StopGrabber( ) { OSErr err; if (gOvlyType == ovlyCKey) { } if ( gSeqGrabber != nil ) { err = CloseComponent( gSeqGrabber ); gSeqGrabber = nil; } } void SetOverlayType( UInt16 ovlyType ) { if (ovlyType != gOvlyType) { StopGrabber( ); gOvlyType = ovlyType; switch (ovlyType) { case ovlyAlpha: break; case ovlyCKey: RGBBackColor( & chromaCol ); break; case ovlyGrab: StartGrabber( ); break; } SetPort( scrnWindow ); InvalRect( & scrnWindow -> portRect ); } } void SubIdle( void ) { SInt32 t; Boolean subPriority; OSErr err; subPriority = ClockRunning( ); if (subPriority) sSleepTime = 0; t = GetClockTime ( ); if ( lastClockTime != t ) DrawTimeWindow( ); if (gSeqGrabber != nil) err = SGIdle( gSeqGrabber ); RunScriptIdle( ); } void SubInit( void ) { MBarInit( ); gLastScrnClick = 0; gOvlyType = ovlyCKey; scriptWindow = nil; subRunning = false; chromaCol.red = 0xffff; chromaCol.green = 0xffff; chromaCol.blue = 0xFFFF; // initialize frame grabber stuff gEnteredMovies = false; gSeqGrabber = nil; gVideoChannel = nil; // gSoundChannel = nil; ClockTimeInit( ); lastClockTime = 0; scrnWindow = GetNewCWindow( 129, & scrnWRec, ( WindowPtr ) -1L ); timeWindow = GetNewCWindow( 130, & timeWRec, ( WindowPtr ) -1L ); SetPort( timeWindow ); ForeColor( yellowColor ); BackColor( blackColor ); TextMode( srcCopy ); TextSize( 24 ); SetPort( scrnWindow ); RGBBackColor( & chromaCol ); // Index2Color( Color2Index( &chromaCol ), &chromaCol ); ShowWindow( scrnWindow ); ShowWindow( timeWindow ); RunScriptInit( ); FormatInit( ); DirectivesInit( ); } void SubFinal( void ) { ShowMenuBar( ); DirectivesFinal( ); FormatFinal( ); RunScriptFinal( ); ClockTimeFinal( ); StopGrabber( ); CloseWindow( scrnWindow ); CloseWindow( timeWindow ); if (gEnteredMovies) ExitMovies( ); }