1/* 2 * EffectCommand.c -- 3 * 4 * Process the "effect" subcommand. 5 * 6 * Copyright (c) 2000-2003 Mats Bengtsson 7 * 8 * $Id: EffectCommand.c,v 1.5 2005/04/10 14:57:48 matben Exp $ 9 */ 10 11#include "MoviePlayer.h" 12 13/* 14 * Keep a global record of the effect list, and other useful stuff, 15 * for an n'th source effect. We need this since the dialog is handled in the 16 * event loop, and the parameters must be transported to a callback procedure. 17 */ 18 19typedef struct StandardEffectsRecord { 20 MoviePlayer *movPtr; 21 QTParameterDialog dialog; /* Dialog token. 22 * Nonzero => serve in event loop */ 23 QTAtomContainer effectList[3]; /* Cache for n effect list. Keep 24 * Between calls! */ 25 QTAtomContainer theSampleAtom; 26 int nTrackEffect; 27 long trackIDs[2]; 28 PicHandle posterPict[2]; 29 TimeValue movTime; 30 TimeValue movDuration; 31 Boolean doneWithDialog; /* Are we done using the effects 32 * parameters dialog box? */ 33} StandardEffectsRecord; 34 35/* 36 * The effect dialog callback needs the interpreter, and this is the only way. 37 */ 38 39static Tcl_Interp *gInterp; 40 41/* 42 * Keep a global record of the effect list, and other useful stuff, 43 * for an n'th source effect. We need this since the dialog is handled in the 44 * event loop, and the parameters must be transported to a callback procedure. 45 */ 46 47StandardEffectsRecord *gEffectsPtr = NULL; 48 49static void EffectsRespondToDialogSelection( OSErr dialogSelectType ); 50static void EffectsReset( void ); 51 52#if TARGET_OS_WIN32 53static void EffectsDialogCallback( EventRecord *theEvent, 54 DialogRef theDialog, DialogItemIndex theItemHit ); 55LRESULT CALLBACK CustomDialogWndProc( HWND theWnd, UINT theMessage, 56 UINT wParam, LONG lParam ); 57#endif 58 59 60/* 61 *---------------------------------------------------------------------- 62 * 63 * EffectsInit, EffectsFree -- 64 * 65 * Initializes and frees the StandardEffectsRecord 'gEffectsPtr'. 66 * 67 * Results: 68 * None. 69 * 70 * Side effects: 71 * Memory allocated, released. 72 * 73 *---------------------------------------------------------------------- 74 */ 75 76void 77EffectsInit( void ) 78{ 79 gEffectsPtr = (StandardEffectsRecord *) ckalloc(sizeof(StandardEffectsRecord)); 80 memset( gEffectsPtr, '\0', sizeof(StandardEffectsRecord) ); 81 gEffectsPtr->dialog = 0; 82} 83 84void 85EffectsFree( void ) 86{ 87 int i; 88 89 EffectsReset(); 90 91 /* Free cached effect lists. */ 92 for (i = 0; i < 3; i++) { 93 if (gEffectsPtr->effectList[i] != NULL) { 94 QTDisposeAtomContainer( gEffectsPtr->effectList[i] ); 95 } 96 } 97 if (gEffectsPtr != NULL) { 98 ckfree( (char *) gEffectsPtr); 99 gEffectsPtr = NULL; 100 } 101} 102 103/* 104 *---------------------------------------------------------------------- 105 * 106 * ProcessEffectCmd -- 107 * 108 * Process the "effect" command 109 * 110 * Results: 111 * Normal TCL results 112 * 113 * Side effects: 114 * Effects, with dialog. 115 * 116 *---------------------------------------------------------------------- 117 */ 118 119int 120ProcessEffectCmd( Tcl_Interp *interp, 121 MoviePlayer *movPtr, 122 int objc, 123 Tcl_Obj *CONST objv[] ) 124{ 125 int nTrackEffect; 126 long longValue; 127 TimeValue movTime; 128 TimeValue movDuration; 129 Track aTrack = NULL; 130 OSErr err = noErr; 131 int result = TCL_OK; 132 133 if (objc == 2) { 134 135 /* Zero source effect. */ 136 137 nTrackEffect = 0; 138 } else if (objc == 3) { 139 140 /* Single source effect. */ 141 142 nTrackEffect = 1; 143 if (Tcl_GetLongFromObj( interp, objv[2], &longValue ) != TCL_OK) { 144 Tcl_AddErrorInfo( interp, "\n (processing trackOneID value)" ); 145 result = TCL_ERROR; 146 goto bail; 147 } 148 gEffectsPtr->trackIDs[0] = longValue; 149 } else if (objc == 4) { 150 151 /* Two source effect. */ 152 153 nTrackEffect = 2; 154 if (Tcl_GetLongFromObj( interp, objv[2], &longValue ) != TCL_OK) { 155 Tcl_AddErrorInfo( interp, "\n (processing trackOneID value)" ); 156 result = TCL_ERROR; 157 goto bail; 158 } 159 gEffectsPtr->trackIDs[0] = longValue; 160 if (Tcl_GetLongFromObj( interp, objv[3], &longValue ) != TCL_OK) { 161 Tcl_AddErrorInfo( interp, "\n (processing trackTwoID value)" ); 162 result = TCL_ERROR; 163 goto bail; 164 } 165 gEffectsPtr->trackIDs[1] = longValue; 166 } else { 167 Tcl_WrongNumArgs( interp, 0, objv, 168 "pathName effect startTime duration ?trackID? ?trackID?" ); 169 result = TCL_ERROR; 170 goto bail; 171 } 172 gEffectsPtr->nTrackEffect = nTrackEffect; 173 174 if (GetMovieStartTimeFromObj( interp, movPtr->aMovie, objv[0], &longValue ) != TCL_OK) { 175 goto bail; 176 } 177 movTime = longValue; 178 if (GetMovieDurationFromObj( interp, movPtr->aMovie, objv[1], movTime, &longValue ) != TCL_OK) { 179 goto bail; 180 } 181 movDuration = longValue; 182 183 gEffectsPtr->movTime = movTime; 184 gEffectsPtr->movDuration = movDuration; 185 gEffectsPtr->movPtr = movPtr; 186 result = LogUndoState( movPtr, interp ); 187 188 /* 189 * The effect is going on async; need variable to wait for. 190 */ 191 192 Tcl_SetVar( interp, "quicktimetcl::effectfinished", "-1", TCL_GLOBAL_ONLY ); 193 gInterp = interp; 194 195 err = QTNewAtomContainer( &gEffectsPtr->theSampleAtom ); 196 if (err != noErr) { 197 CheckAndSetErrorResult( interp, err ); 198 result = TCL_ERROR; 199 goto bail; 200 } 201 202 /* 203 * If we haven't made and cached the effect list for this n'th source effect, 204 * do it now. 205 */ 206 207 if (gEffectsPtr->effectList[nTrackEffect] == NULL) { 208 err = QTGetEffectsList( 209 &(gEffectsPtr->effectList[nTrackEffect]), 210 nTrackEffect, 211 nTrackEffect, 0 ); 212 if (err != noErr) { 213 CheckAndSetErrorResult( interp, err ); 214 result = TCL_ERROR; 215 goto bail; 216 } 217 } 218 219 /* 220 * Make the standard parameter effects dialog. 221 * Needs to be served in the event loop. 222 * From the event loop the actual procedure 'EffectsRespondToDialogSelection' 223 * is called to make the effect. 224 */ 225 226 err = QTCreateStandardParameterDialog( 227 gEffectsPtr->effectList[nTrackEffect],/* the effects list */ 228 gEffectsPtr->theSampleAtom, /* empty container */ 229 0, 230 &(gEffectsPtr->dialog) ); /* identifier for the 231 * standard dialog */ 232 if (noErr != err) { 233 CheckAndSetErrorResult( interp, err ); 234 result = TCL_ERROR; 235 goto bail; 236 } 237 238 /* 239 * Insert poster frames into dialog. 240 */ 241 242 if (nTrackEffect >= 1) { 243 aTrack = GetMovieTrack( movPtr->aMovie, gEffectsPtr->trackIDs[0] ); 244 if (aTrack != NULL) { 245 gEffectsPtr->posterPict[0] = GetTrackPict( aTrack, 246 GetMoviePosterTime( movPtr->aMovie )); 247 if (gEffectsPtr->posterPict[0] != NULL) { 248 QTParamPreviewRecord myPreviewRecord; 249 250 myPreviewRecord.sourcePicture = gEffectsPtr->posterPict[0]; 251 myPreviewRecord.sourceID = 1; 252 err = QTStandardParameterDialogDoAction( gEffectsPtr->dialog, 253 pdActionSetPreviewPicture, &myPreviewRecord ); 254 } 255 } 256 } 257 /* not very clever since it is the same movie... 258 if (nTrackEffect >= 2) { 259 aTrack = GetMovieTrack( movPtr->aMovie, gEffectsPtr->trackIDs[1] ); 260 if (aTrack != NULL) { 261 gEffectsPtr->posterPict[1] = GetTrackPict( aTrack, 262 GetMoviePosterTime( movPtr->aMovie )); 263 if (gEffectsPtr->posterPict[1] != NULL) { 264 QTParamPreviewRecord myPreviewRecord; 265 266 myPreviewRecord.sourcePicture = gEffectsPtr->posterPict[1]; 267 myPreviewRecord.sourceID = 2; 268 err = QTStandardParameterDialogDoAction( gEffectsPtr->dialog, 269 pdActionSetPreviewPicture, &myPreviewRecord ); 270 } 271 } 272 } 273 */ 274 275 /* 276 * Now, the frontmost window is the standard effects parameter dialog box; 277 * on the Mac, we call EffectsHandleDialogEvents in our main event loop 278 * to find and process events targeted at the effects parameter dialog box; 279 * On Windows, we need to use a different strategy: we install a modeless 280 * dialog callback procedure that is called internally by QTML. 281 */ 282 283#if TARGET_OS_WIN32 284 gEffectsPtr->doneWithDialog = false; 285 286 /* Force the dialog box to be drawn. */ 287 { 288 EventRecord myEvent = {0}; 289 290 EffectsDialogCallback( &myEvent, FrontWindow(), 0 ); 291 } 292 SetModelessDialogCallbackProc( FrontWindow(), 293 (QTModelessCallbackProcPtr) EffectsDialogCallback ); 294 QTMLSetWindowWndProc( FrontWindow(), (void *) CustomDialogWndProc ); 295#endif 296 297 /* Continues in 'EffectsRespondToDialogSelection'... */ 298 299bail: 300 if (result != TCL_OK) { 301 } 302 return result; 303} 304 305/* 306 *---------------------------------------------------------------------- 307 * 308 * EffectsHandleDialogEvents -- 309 * 310 * Process events that might be targeted at the standard effects 311 * parameter dialog box. Return true if the event was completely 312 * handled. 313 * 314 * Results: 315 * Boolean telling if event was handled or not. 316 * 317 * Side effects: 318 * Dialog procedures called. 319 * 320 *---------------------------------------------------------------------- 321 */ 322 323Boolean 324EffectsHandleDialogEvents( EventRecord *eventPtr, DialogItemIndex itemIndex ) 325{ 326 Boolean isHandled; 327 OSErr err = noErr; 328 329 if (eventPtr == NULL) { 330 return false; 331 } 332 if (gEffectsPtr == NULL) { 333 return false; 334 } 335 if (gEffectsPtr->dialog == 0) { 336 return false; 337 } 338 err = QTIsStandardParameterDialogEvent( eventPtr, gEffectsPtr->dialog ); 339 340 switch (err) { 341 342 case codecParameterDialogConfirm: 343 case userCanceledErr: 344 345 /* The user clicked the OK or Cancel button.*/ 346 347 QTStandardParameterDialogDoAction( gEffectsPtr->dialog, pdActionConfirmDialog, NULL ); 348 QTDismissStandardParameterDialog( gEffectsPtr->dialog ); 349 gEffectsPtr->dialog = 0L; 350 EffectsRespondToDialogSelection( err ); 351 isHandled = true; 352 353 /* 354 * The effect is going on async; set variable to wait for. 355 */ 356 357 if (err == userCanceledErr) { 358 Tcl_SetVar( gInterp, "quicktimetcl::effectfinished", "0", TCL_GLOBAL_ONLY ); 359 } else { 360 Tcl_SetVar( gInterp, "quicktimetcl::effectfinished", "1", TCL_GLOBAL_ONLY ); 361 } 362 break; 363 364 case noErr: 365 366 /* 367 * The event was completely handled by 368 * QTIsStandardParameterDialogEvent 369 */ 370 371 isHandled = true; 372 break; 373 374 case featureUnsupported: 375 376 /* 377 * The event was not handled by QTIsStandardParameterDialogEvent; 378 * let the event be processed normally. 379 */ 380 381 isHandled = false; 382 break; 383 384 default: 385 386 /* 387 * The event was not handled by QTIsStandardParameterDialogEvent; 388 * do not let the event be processed normally. 389 */ 390 391 isHandled = true; 392 break; 393 } 394 return( isHandled ); 395} 396 397/* 398 *---------------------------------------------------------------------- 399 * 400 * EffectsRespondToDialogSelection -- 401 * 402 * If dialogSelectType is codecParameterDialogConfirm, make an 403 * effects movie. 404 * If dialogSelectType is userCanceledErr, do any necessary clean up. 405 * 406 * Results: 407 * None. 408 * 409 * Side effects: 410 * New source tracks created, effect track created. 411 * 412 *---------------------------------------------------------------------- 413 */ 414 415static void 416EffectsRespondToDialogSelection( OSErr dialogSelectType ) 417{ 418 MoviePlayer *movPtr; 419 int nTrackEffect = gEffectsPtr->nTrackEffect; 420 TimeValue movTime = gEffectsPtr->movTime; 421 TimeValue movDuration = gEffectsPtr->movDuration; 422 TimeValue sampleTime; 423 Track origTrack[2] = {NULL, NULL}; 424 Track srcTrack[2] = {NULL, NULL}; 425 Track videoTrackFX = NULL; 426 Track aTrack = NULL; 427 Media myMedia = NULL; 428 Media videoMediaFX = NULL; 429 Fixed fixWidth; 430 Fixed fixHeight; 431 Boolean dialogWasCancelled = false; 432 QTAtomContainer theInputMapContainer = NULL; 433 QTAtom inputAtom; 434 QTAtom effectAtom; 435 QTAtomID effectAtomID; 436 OSType theEffectCode; 437 OSType theInputType; 438 OSErr err = noErr; 439 long effectCodeSize; 440 Ptr effectCodePtr = NULL; 441 ImageDescriptionHandle theDesc = NULL; 442 MediaHandler mediaHandler; 443 RGBColor transparentColor = {0x0000, 0x0000, 0x0000}; 444 int copyMovieMedia = false; 445 int timeScale; 446 int i; 447 long aLong; 448 long refIndex1, refIndex2; 449 int result = TCL_OK; 450 451 movPtr = gEffectsPtr->movPtr; 452 if (movPtr->aMovie == NULL) { 453 result = TCL_ERROR; 454 goto bail; 455 } 456 dialogWasCancelled = (dialogSelectType == userCanceledErr); 457 if (dialogWasCancelled) { 458 result = TCL_ERROR; 459 goto bail; 460 } 461 462 /* 463 * First, create any source tracks that is needed by the effect, 464 * and copy the media from the original track. 465 */ 466 467 for (i = 0; i < nTrackEffect; i++) { 468 origTrack[i] = GetMovieTrack( movPtr->aMovie, gEffectsPtr->trackIDs[i] ); 469 if (origTrack[i] == NULL) { 470 CheckAndSetErrorResult( gInterp, noErr ); 471 result = TCL_ERROR; 472 goto bail; 473 } 474 AddEmptyTrackToMovie( origTrack[i], movPtr->aMovie, NULL, 0, 475 &srcTrack[i] ); 476 if (srcTrack[i] == NULL) { 477 CheckAndSetErrorResult( gInterp, noErr ); 478 result = TCL_ERROR; 479 goto bail; 480 } 481 myMedia = GetTrackMedia( srcTrack[i] ); 482 if (myMedia == NULL) { 483 CheckAndSetErrorResult( gInterp, noErr ); 484 result = TCL_ERROR; 485 goto bail; 486 } 487 if (copyMovieMedia) { 488 if (noErr != BeginMediaEdits( myMedia )) { 489 CheckAndSetErrorResult( gInterp, noErr ); 490 result = TCL_ERROR; 491 goto bail; 492 } 493 } 494 if (noErr != (err = InsertTrackSegment( 495 origTrack[i], /* source track */ 496 srcTrack[i], /* destination track */ 497 movTime, /* start time */ 498 movDuration, /* duration */ 499 movTime ))) { /* insert time */ 500 CheckAndSetErrorResult( gInterp, err ); 501 result = TCL_ERROR; 502 goto bail; 503 } 504 if (copyMovieMedia) { 505 if (noErr != EndMediaEdits( myMedia )) { 506 CheckAndSetErrorResult( gInterp, noErr ); 507 result = TCL_ERROR; 508 goto bail; 509 } 510 } 511 } 512 513 /* 514 * Extract the 'what' atom to find out what kind of effect it is. 515 */ 516 517 effectAtom = QTFindChildByIndex( gEffectsPtr->theSampleAtom, 518 kParentAtomIsContainer, kParameterWhatName, kParameterWhatID, 519 &effectAtomID ); 520 521 if (noErr != QTLockContainer( gEffectsPtr->theSampleAtom )) { 522 CheckAndSetErrorResult( gInterp, noErr ); 523 result = TCL_ERROR; 524 goto bail; 525 } 526 if (noErr != QTGetAtomDataPtr( gEffectsPtr->theSampleAtom, effectAtom, 527 &effectCodeSize, &effectCodePtr )) { 528 CheckAndSetErrorResult( gInterp, noErr ); 529 result = TCL_ERROR; 530 goto bail; 531 } 532 if (effectCodeSize != sizeof(OSType)) { 533 result = TCL_ERROR; 534 goto bail; 535 } 536 theEffectCode = *(OSType *) effectCodePtr; /* "tsk" */ 537 538 /* Because the data is read from an atom container. */ 539 theEffectCode = EndianU32_BtoN(theEffectCode); 540 if (noErr != QTUnlockContainer( gEffectsPtr->theSampleAtom )) { 541 CheckAndSetErrorResult( gInterp, noErr ); 542 result = TCL_ERROR; 543 goto bail; 544 } 545 546 /* 547 * Make an empty effect track. 548 */ 549 550 if (nTrackEffect > 0) { 551 GetTrackDimensions( origTrack[0], &fixWidth, &fixHeight ); 552 } else { 553 554 /* 555 * Here we search for a visual track and pick its dimensions. 556 */ 557 558 if (GetFirstVideoTrackInMovie( movPtr->aMovie, &aTrack ) == invalidTrack) { 559 fixWidth = Long2Fix(160); 560 fixHeight = Long2Fix(120); 561 } else { 562 GetTrackDimensions( aTrack, &fixWidth, &fixHeight ); 563 } 564 } 565 videoTrackFX = NewMovieTrack( movPtr->aMovie, fixWidth, fixHeight, kNoVolume ); 566 if (videoTrackFX == NULL) { 567 CheckAndSetErrorResult( gInterp, noErr ); 568 result = TCL_ERROR; 569 goto bail; 570 } 571 timeScale = GetMovieTimeScale( movPtr->aMovie ); 572 videoMediaFX = NewTrackMedia( videoTrackFX, VideoMediaType, timeScale, 573 NULL, 0 ); 574 if (videoMediaFX == NULL) { 575 CheckAndSetErrorResult( gInterp, noErr ); 576 result = TCL_ERROR; 577 goto bail; 578 } 579 580 /* 581 * An effect track has two important attributes: the effect description 582 * and the input map. 583 * The effect description requires two things: 584 * 1) The actual description, which's name and parameters are already 585 * inserted in the atom container 'gEffectsPtr->theSampleAtom' 586 * using 'QTCreateStandardParameterDialog'. 587 * 2) The second is atoms naming the sources. 588 * 589 * Add atoms naming the sources. 590 */ 591 592 if (nTrackEffect >= 1) { 593 aLong = EndianU32_NtoB( kSourceOneName ); 594 QTInsertChild( gEffectsPtr->theSampleAtom, kParentAtomIsContainer, 595 kEffectSourceName, 1, 0, sizeof(aLong), &aLong, NULL ); 596 } 597 if (nTrackEffect >= 2) { 598 aLong = EndianU32_NtoB( kSourceTwoName ); 599 QTInsertChild( gEffectsPtr->theSampleAtom, kParentAtomIsContainer, 600 kEffectSourceName, 2, 0, sizeof(aLong), &aLong, NULL ); 601 } 602 603 theDesc = (ImageDescriptionHandle) NewHandleClear(sizeof(ImageDescription)); 604 if (theDesc == NULL) { 605 CheckAndSetErrorResult( gInterp, noErr ); 606 result = TCL_ERROR; 607 goto bail; 608 } 609 610 /* 611 * Fill in the fields of the sample description. 612 */ 613 614 (**theDesc).idSize = sizeof(ImageDescription); 615 (**theDesc).cType = theEffectCode; 616 (**theDesc).vendor = kAppleManufacturer; 617 (**theDesc).temporalQuality = codecNormalQuality; 618 (**theDesc).spatialQuality = codecNormalQuality; 619 (**theDesc).width = (short) Fix2Long( fixWidth ); 620 (**theDesc).height = (short) Fix2Long( fixHeight ); 621 (**theDesc).hRes = 72L << 16; 622 (**theDesc).vRes = 72L << 16; 623 (**theDesc).dataSize = 0L; 624 (**theDesc).frameCount = 1; 625 (**theDesc).depth = 0; 626 (**theDesc).clutID = -1; 627 628 /* 629 * Add effects sample to movie. 630 */ 631 632 if (noErr != BeginMediaEdits( videoMediaFX )) { 633 CheckAndSetErrorResult( gInterp, noErr ); 634 result = TCL_ERROR; 635 goto bail; 636 } 637 if (noErr != AddMediaSample( videoMediaFX, gEffectsPtr->theSampleAtom, 0, 638 GetHandleSize( gEffectsPtr->theSampleAtom ), movDuration, 639 (SampleDescriptionHandle) theDesc, 1, 0, &sampleTime )) { 640 CheckAndSetErrorResult( gInterp, noErr ); 641 result = TCL_ERROR; 642 goto bail; 643 } 644 if (noErr != EndMediaEdits( videoMediaFX )) { 645 CheckAndSetErrorResult( gInterp, noErr ); 646 result = TCL_ERROR; 647 goto bail; 648 } 649 if (noErr != InsertMediaIntoTrack( videoTrackFX,/* the track */ 650 movTime, /* insert time in movie's 651 * time */ 652 sampleTime, /* media start time in 653 * media's time */ 654 movDuration, /* media's duration in 655 * media's time */ 656 fixed1 )) { /* the media's rate */ 657 CheckAndSetErrorResult( gInterp, noErr ); 658 result = TCL_ERROR; 659 goto bail; 660 } 661 if (gEffectsPtr->theSampleAtom != NULL) { 662 QTDisposeAtomContainer( gEffectsPtr->theSampleAtom ); 663 gEffectsPtr->theSampleAtom = NULL; 664 } 665 DisposeHandle( (Handle) theDesc ); 666 667 /* 668 * Create and add the input map. 669 */ 670 671 QTNewAtomContainer( &theInputMapContainer ); 672 673 /* The first input. */ 674 675 if (nTrackEffect > 0) { 676 AddTrackReference( videoTrackFX, srcTrack[0], kTrackModifierReference, 677 &refIndex1 ); 678 QTInsertChild( theInputMapContainer, kParentAtomIsContainer, 679 kTrackModifierInput, refIndex1, 0, 0, NULL, &inputAtom ); 680 681 theInputType = EndianU32_NtoB( kTrackModifierTypeImage ); 682 QTInsertChild( theInputMapContainer, inputAtom, kTrackModifierType, 683 1, 0, sizeof(theInputType), &theInputType, NULL ); 684 685 aLong = EndianU32_NtoB( kSourceOneName ); 686 QTInsertChild( theInputMapContainer, inputAtom, kEffectDataSourceType, 687 1, 0, sizeof(aLong), &aLong, NULL ); 688 } 689 690 /* The second input. */ 691 692 if (nTrackEffect > 1) { 693 AddTrackReference( videoTrackFX, srcTrack[1], kTrackModifierReference, 694 &refIndex2 ); 695 QTInsertChild( theInputMapContainer, kParentAtomIsContainer, 696 kTrackModifierInput, refIndex2, 0, 0, NULL, &inputAtom ); 697 698 theInputType = EndianU32_NtoB( kTrackModifierTypeImage ); 699 QTInsertChild( theInputMapContainer, inputAtom, kTrackModifierType, 700 1, 0, sizeof(theInputType), &theInputType, NULL ); 701 702 aLong = EndianU32_NtoB( kSourceTwoName ); 703 QTInsertChild( theInputMapContainer, inputAtom, kEffectDataSourceType, 704 1, 0, sizeof(aLong), &aLong, NULL ); 705 } 706 707 /* 708 * Set that mapping. 709 */ 710 711 if (nTrackEffect > 0) { 712 SetMediaInputMap( GetTrackMedia(videoTrackFX), theInputMapContainer ); 713 } 714 715 /* 716 * Set transparent graphics mode for the zero source effect track. 717 */ 718 719 if (nTrackEffect == 0) { 720 mediaHandler = GetMediaHandler( videoMediaFX ); 721 MediaSetGraphicsMode( mediaHandler, transparent, &transparentColor ); 722 } 723 724bail: 725 726 if (result != TCL_OK) { 727 if (srcTrack[0] != NULL) { 728 DisposeMovieTrack( srcTrack[0] ); 729 } 730 if (srcTrack[1] != NULL) { 731 DisposeMovieTrack( srcTrack[1] ); 732 } 733 if (videoTrackFX != NULL) { 734 DisposeMovieTrack( videoTrackFX ); 735 } 736 } 737 if (theInputMapContainer != NULL) { 738 QTDisposeAtomContainer( theInputMapContainer ); 739 } 740 if (theDesc != NULL) { 741 DisposeHandle( (Handle) theDesc ); 742 } 743 EffectsReset(); 744 745 return; 746} 747 748/* 749 *---------------------------------------------------------------------- 750 * 751 * EffectsReset -- 752 * 753 * Resets the StandardEffectsRecord 'gEffectsPtr'. Kills any 754 * poster picts. Keeps any effect lists untouched! 755 * 756 * Results: 757 * None. 758 * 759 * Side effects: 760 * Picts may be killed. Not served in event loop. 761 * 762 *---------------------------------------------------------------------- 763 */ 764 765static void 766EffectsReset( void ) 767{ 768 if (gEffectsPtr == NULL) { 769 return; 770 } 771 gEffectsPtr->movPtr = NULL; 772 gEffectsPtr->dialog = 0L; 773 gEffectsPtr->trackIDs[0] = 0; 774 gEffectsPtr->trackIDs[1] = 0; 775 gEffectsPtr->nTrackEffect = 0; 776 gEffectsPtr->doneWithDialog = false; 777 if (gEffectsPtr->posterPict[0] != NULL) { 778 KillPicture( gEffectsPtr->posterPict[0] ); 779 gEffectsPtr->posterPict[0] = NULL; 780 } 781 if (gEffectsPtr->posterPict[1] != NULL) { 782 KillPicture( gEffectsPtr->posterPict[1] ); 783 gEffectsPtr->posterPict[1] = NULL; 784 } 785 if (gEffectsPtr->theSampleAtom != NULL) { 786 QTDisposeAtomContainer( gEffectsPtr->theSampleAtom ); 787 gEffectsPtr->theSampleAtom = NULL; 788 } 789} 790 791/* 792 *---------------------------------------------------------------------- 793 * 794 * EffectsDialogCallback -- 795 * 796 * This function is called by QTML when it processes events for 797 * the standard or custom effects parameter dialog box. 798 * 799 * Results: 800 * None. 801 * 802 * Side effects: 803 * EffectsHandleDialogEvents called. 804 * 805 *---------------------------------------------------------------------- 806 */ 807#if TARGET_OS_WIN32 || TARGET_API_MAC_CARBON 808 809static void 810EffectsDialogCallback( EventRecord *theEvent, DialogRef theDialog, 811 DialogItemIndex theItemHit ) 812{ 813 QTParamDialogEventRecord myRecord; 814 815 myRecord.theEvent = theEvent; 816 myRecord.whichDialog = theDialog; 817 myRecord.itemHit = theItemHit; 818 819 if (gEffectsPtr->dialog != 0L) { 820 QTStandardParameterDialogDoAction( gEffectsPtr->dialog, 821 pdActionModelessCallback, &myRecord ); 822 823 /* 824 * See if the event is meant for the effects parameter dialog box. 825 */ 826 827 EffectsHandleDialogEvents( theEvent, theItemHit ); 828 } 829} 830#endif 831 832#if TARGET_OS_WIN32 833/* 834 *---------------------------------------------------------------------- 835 * 836 * CustomDialogWndProc -- 837 * 838 * Handle messages for the custom effects parameters dialog box. 839 * 840 * Results: 841 * DefWindowProc. 842 * 843 * Side effects: 844 * DefWindowProc called. 845 * 846 *---------------------------------------------------------------------- 847 */ 848 849LRESULT CALLBACK 850CustomDialogWndProc( HWND theWnd, UINT theMessage, UINT wParam, LONG lParam ) 851{ 852 EventRecord myEvent = {0}; 853 854 if (!gEffectsPtr->doneWithDialog && (theMessage == 0x7FFF)) 855 EffectsDialogCallback( &myEvent, GetNativeWindowPort(theWnd), 0 ); 856 857 return(DefWindowProc( theWnd, theMessage, wParam, lParam )); 858} 859#endif 860 861/*---------------------------------------------------------------------------*/ 862