-
Notifications
You must be signed in to change notification settings - Fork 3
/
listing9.html
executable file
·2066 lines (1683 loc) · 63.6 KB
/
listing9.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>vrmovies - /Common Files/QTUtilities.c</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/QuickTime/index.html">QuickTime</a> > <a href="../../samplecode/QuickTime/idxVirtualReality-date.html">Virtual Reality</a> > <A HREF="javascript:location.replace('index.html');">vrmovies</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">vrmovies</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/Common Files/QTUtilities.c</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/Application Files/ComApplication.c</option>
<option value="listing2.html">/Application Files/ComApplication.h</option>
<option value="listing3.html">/Application Files/ComResource.h</option>
<option value="listing4.html">/Common Files/ComFramework.c</option>
<option value="listing5.html">/Common Files/ComFramework.h</option>
<option value="listing6.html">/Common Files/MacFramework.c</option>
<option value="listing7.html">/Common Files/MacFramework.h</option>
<option value="listing8.html">/Common Files/MacPrefix.h</option>
<option value="listing9.html">/Common Files/QTUtilities.c</option>
<option value="listing10.html">/Common Files/QTUtilities.h</option>
<option value="listing11.html">/Common Files/QTVRUtilities.c</option>
<option value="listing12.html">/Common Files/QTVRUtilities.h</option>
<option value="listing13.html">/Common Files/WinFramework.c</option>
<option value="listing14.html">/Common Files/WinFramework.h</option>
<option value="listing15.html">/Common Files/WinPrefix.h</option>
<option value="listing16.html">/README.txt</option>
<option value="listing17.html">/VRMovies.c</option>
<option value="listing18.html">/VRMovies.h</option></select>
</p>
</form>
<p><strong><a href="vrmovies.zip">Download Sample</a></strong> (“vrmovies.zip”, 1.00M)<BR>
<strong><a href="vrmovies.dmg">Download Sample</a></strong> (“vrmovies.dmg”, 1.46M)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">////////////// File: QTUtilities.c//// Contains: Some utilities for working with QuickTime movies.// All utilities start with the prefix "QTUtils_".//// Written by: Tim Monroe// Based on the DTSQTUtilities package by Apple DTS.// This began as essentially a subset of that package, revised for cross-platform use.//// Copyright: © 1996-1999 by Apple Computer, Inc., all rights reserved.//// Change History (most recent first)://// <36> 10/08/00 rtm tweaked QTUtils_ConvertCToPascalString to copy at most 255 characters// <35> 09/29/00 rtm added QTUtils_IsAutoPlayMovie// <34> 04/28/00 rtm fixed bug in QTUtils_AddUserDataTextToMovie (had a script system, not a region code)// <33> 03/08/00 rtm removed QTUtils_SaveMovie and QTUtils_PrintMoviePICT// <32> 03/02/00 rtm added QTUtils_SelectNoneMovie// <31> 01/10/00 rtm tweaked QTUtils_IsQuickTimeInstalled// <30> 12/20/99 rtm reworked QTUtils_IsMovieFile, to first test for files of type kQTFileTypeMovie// <29> 12/09/99 rtm added QTUtils_PutControllerBarOnTop// <28> 12/08/99 rtm reworked controller button functions to support custom buttom (its mcFlags constant// is a "Use" constant and not a "Suppress" constant)// <27> 11/26/99 rtm added endian adjustments to _GetMovieFileLoopingInfo and _GetWindowPositionFromFile// <26> 11/17/99 rtm added QTUtils_GetWindowPositionFromFile// <25> 05/19/99 rtm removed QTUtils_GetMovie// <24> 05/10/99 rtm added QTUtils_UpdateMovieVolumeSetting// <23> 03/22/99 rtm updated connection speed code to use constants/data types now in Movies.h// <22> 03/11/99 rtm moved _GetControllerType and _SetControllerType from QTVRUtilities to here;// added QTUtils_ChangeControllerType// <21> 02/03/99 rtm moved non-QTVR-specific utilities from QTVRUtilities to here// <20> 01/26/99 rtm added QTUtils_ConvertCToPascalString; removed "\p" from any constant strings// <19> 01/25/99 rtm #define'd away QTUtils_GetUsersContentRating and siblings, since content rating// capability is not in latest feature set// <18> 12/09/98 rtm added QTUtils_GetUsersContentRating// <17> 11/18/98 rtm added QTUtils_GetFrameCount// <16> 10/27/98 rtm added QTUtils_MakeMovieLoop// <15> 09/14/98 rtm added QTUtils_GetUsersConnectionSpeed and QTUtils_SetUsersConnectionSpeed// <14> 06/24/98 rtm added QTUtils_GetMaxWindowDepth and QTUtils_GetMaxScreenDepth// <13> 06/04/98 rtm added QTUtils_DeleteAllReferencesToTrack// <12> 05/28/98 rtm added some typecasting to minimize MSDev compiler warnings// <11> 05/19/98 rtm added QTUtils_MovieHasTimeCodeTrack// <10> 05/04/98 rtm added QTUtils_GetTrackName, QTUtils_SetTrackName, QTUtils_MakeTrackNameByType,// QTUtils_IsImageFile, and QTUtils_IsMovieFile// <9> 02/28/98 rtm fixed QTUtils_GetMovieFileLoopingInfo and the like// <8> 01/14/98 rtm added QTUtils_ConvertFloatToBigEndian// <7> 12/19/97 rtm added QTUtils_AddUserDataTextToMovie and associated routines;// added QTUtils_GetMovieFileLoopingInfo and the like// <6> 11/06/97 rtm added QTUtils_MakeSampleDescription// <5> 10/29/97 rtm modified QTUtils_IsMediaTypeInMovie and similar routines to use GetMovieIndTrackType// <4> 10/27/97 rtm added QTUtils_HasQuickTimeVideoEffects// <3> 10/17/97 rtm added QTUtils_MovieHasSoundTrack// <2> 09/23/97 rtm added endian adjustment to QTUtils_PrintMoviePICT// <1> 09/10/97 rtm first file// //////////////////////// header files////////////#ifndef __QTUtilities__#include "QTUtilities.h"/////////////////////////////////////////////////////////////////////////////////////////////////////////////// General utilities.//// Use these functions to get information about the availability/features of QuickTime or other services./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QTUtils_TrapAvailable// Check to see whether a given trap is implemented. This is based on IM: Operating System Utilities (p. 8-22).////////////#if TARGET_OS_MAC && !TARGET_API_MAC_CARBONBoolean QTUtils_TrapAvailable (short theTrapWord){ TrapType myTrapType; short myNumToolboxTraps; // determine whether this is a Toolbox or an Operating System trap if ((theTrapWord & 0x0800) > 0) myTrapType = ToolTrap; else myTrapType = OSTrap; if (myTrapType == ToolTrap) { theTrapWord = theTrapWord & 0x07FF; if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap)) myNumToolboxTraps = 0x0200; else myNumToolboxTraps = 0x0400; if (theTrapWord >= myNumToolboxTraps) theTrapWord = _Unimplemented; } return(NGetTrapAddress(theTrapWord, myTrapType) != NGetTrapAddress(_Unimplemented, ToolTrap));}#endif////////////// QTUtils_IsQuickTimeInstalled// Is QuickTime installed?////////////Boolean QTUtils_IsQuickTimeInstalled (void) { long myAttrs; OSErr myErr = noErr; myErr = Gestalt(gestaltQuickTime, &myAttrs); return(myErr == noErr);}////////////// QTUtils_IsQuickTimeCFMInstalled// Are the QuickTime CFM libraries installed?////////////#if TARGET_CPU_PPCBoolean QTUtils_IsQuickTimeCFMInstalled (void) { Boolean myQTCFMAvail = false; long myAttrs; OSErr myErr = noErr; // test whether the PowerPC QuickTime glue library is present myErr = Gestalt(gestaltQuickTimeFeatures, &myAttrs); if (myErr == noErr) if (myAttrs & (1L << gestaltPPCQuickTimeLibPresent)) myQTCFMAvail = true; // test whether a function is available (the library is not moved from the Extension folder); // this is the trick to be used when testing if a function is available via CFM if (!CompressImage) myQTCFMAvail = false; return(myQTCFMAvail);}#endif////////////// QTUtils_GetQTVersion// Get the version of QuickTime installed.// The high-order word of the returned long integer contains the version number,// so you can test a version like this://// if (((QTUtils_GetQTVersion() >> 16) & 0xffff) >= 0x0210) // we require QT 2.1 or greater// return;////////////long QTUtils_GetQTVersion (void) { long myVersion = 0L; OSErr myErr = noErr; myErr = Gestalt(gestaltQuickTime, &myVersion); if (myErr == noErr) return(myVersion); else return(0L);}////////////// QTUtils_HasQuickTimeVideoEffects// Does the installed version of QuickTime support video effects?//// Note: this is a pretty cheesy way of determining whether video effects are available.////////////Boolean QTUtils_HasQuickTimeVideoEffects (void) { return(((QTUtils_GetQTVersion() >> 16) & 0xffff) >= kQTVideoEffectsMinVers);}////////////// QTUtils_HasFullScreenSupport// Does the installed version of QuickTime support the full-screen routines?//// Note: this is a pretty cheesy way of determining whether full-screen routines are available.////////////Boolean QTUtils_HasFullScreenSupport (void) { return(((QTUtils_GetQTVersion() >> 16) & 0xffff) >= kQTFullScreenMinVers);}////////////// QTUtils_HasWiredSprites// Does the installed version of QuickTime support wired sprites?//// Note: this is a pretty cheesy way of determining whether wired sprites are available.////////////Boolean QTUtils_HasWiredSprites (void) { return(((QTUtils_GetQTVersion() >> 16) & 0xffff) >= kQTWiredSpritesMinVers);}////////////// QTUtils_IsQTVRMovie// Is the specified movie a QTVR movie?//// WARNING: This function is intended for use ONLY when you want to determine if you've got a QTVR movie// but you don't want to use the QuickTime VR API (perhaps QTVR isn't installed...). The preferred way to// determine if a movie is a QTVR movie is to call QTVRGetQTVRTrack and then QTVRGetQTVRInstance; if you// get back a non-NULL instance, you've got a QTVR movie.////////////Boolean QTUtils_IsQTVRMovie (Movie theMovie) { Boolean myIsQTVRMovie = false; OSType myType; // QTVR movies have a special piece of user data identifying the movie controller type myType = QTUtils_GetControllerType(theMovie); if ((myType == kQTVRQTVRType) || (myType == kQTVROldPanoType) || (myType == kQTVROldObjectType)) myIsQTVRMovie = true; return(myIsQTVRMovie);}////////////// QTUtils_IsStreamedMovie// Is the specified movie a streamed movie?////////////Boolean QTUtils_IsStreamedMovie (Movie theMovie) { return(GetMovieIndTrackType(theMovie, 1, kQTSStreamMediaType, movieTrackMediaType | movieTrackEnabledOnly) != NULL);}////////////// QTUtils_IsAutoPlayMovie// Get the autoplay state of a movie file.//// A movie file can have information about its autoplay state in a user data item of type 'play'.// If the movie doesn't contain an item of this type, then we'll assume that it doesn't autoplay.// If it does contain an item of this type, then the item data (a Boolean) is 0 for normal play// and 1 for autoplay.////////////Boolean QTUtils_IsAutoPlayMovie (Movie theMovie){ UserData myUserData = NULL; Boolean myAutoPlay = false; OSErr myErr = paramErr; // make sure we've got a movie if (theMovie == NULL) return(myAutoPlay); // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData != NULL) { myErr = GetUserDataItem(myUserData, &myAutoPlay, sizeof(myAutoPlay), FOUR_CHAR_CODE('play'), 0); if (myErr != noErr) myAutoPlay = false; } return(myAutoPlay);}/////////////////////////////////////////////////////////////////////////////////////////////////////////////// Controller bar utilities.//// Use these functions to manipulate the controller bar, its buttons, and the help text displayed in it./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QTUtils_IsControllerBarVisible// Is the controller bar currently visible?////////////Boolean QTUtils_IsControllerBarVisible (MovieController theMC) { return((Boolean)MCGetVisible(theMC));}////////////// QTUtils_GetControllerBarHeight// Return the height of the controller bar displayed by the movie controller.//// Note that MCGetControllerBoundsRect returns the rectangle of bar and movie, if attached;// so we need to detach the controller bar first.////////////short QTUtils_GetControllerBarHeight (MovieController theMC) { Boolean wasAttached = false; Rect myRect; // if the controller bar is attached, detach it (and remember we did so) if (MCIsControllerAttached(theMC) == 1) { wasAttached = true; MCSetControllerAttached(theMC, false); } // get the rectangle of the controller MCGetControllerBoundsRect(theMC, &myRect); // now reattach the controller bar, if it was originally attached if (wasAttached) MCSetControllerAttached(theMC, true); return(myRect.bottom - myRect.top);}////////////// QTUtils_HideControllerBar// Hide the controller bar provided by the movie controller.////////////void QTUtils_HideControllerBar (MovieController theMC) { MCSetVisible(theMC, false);}////////////// QTUtils_ShowControllerBar// Show the controller bar provided by the movie controller.////////////void QTUtils_ShowControllerBar (MovieController theMC) { MCSetVisible(theMC, true);}////////////// QTUtils_ToggleControllerBar// Toggle the state of the controller bar provided by the movie controller.////////////void QTUtils_ToggleControllerBar (MovieController theMC) { if (QTUtils_IsControllerBarVisible(theMC)) QTUtils_HideControllerBar(theMC); else QTUtils_ShowControllerBar(theMC);}////////////// QTUtils_PutControllerBarOnTop// Put the movie controller bar at the top of the movie window.////////////void QTUtils_PutControllerBarOnTop (MovieController theMC) { if (theMC == NULL) return; if (MCIsControllerAttached(theMC) == 1) { Rect myMCRect; Rect myMovieRect; MCGetControllerBoundsRect(theMC, &myMCRect); myMovieRect = myMCRect; myMCRect.bottom = myMCRect.top + QTUtils_GetControllerBarHeight(theMC); myMovieRect.top = myMCRect.bottom + 1; MCSetControllerAttached(theMC, false); MCPositionController(theMC, &myMovieRect, &myMCRect, 0L); }}////////////// QTUtils_HideControllerButton// Hide the specified button in the controller bar.//// Some explanation is probably useful here: the first thing to understand is that every VR movie has // TWO sets of movie controller flags: (1) a set of "control flags" and (2) a set of "explicit flags".//// The control flags work as documented in IM: QuickTime Components (pp. 2-20f) and in VRPWQTVR2.0 (pp. 2-23f):// if a bit in the set of control flags is set (that is, equal to 1), then the associated action or property is// enabled. For instance, bit 17 (mcFlagQTVRSuppressZoomBtns) means to suppress the zoom buttons. So, if that// bit is set in a VR movie's control flags, the zoom buttons are NOT displayed. If that bit is clear, the zoom// buttons are displayed.//// However, the QuickTime VR movie controller sometimes suppresses buttons even when those buttons // have not been explicitly suppressed in the control flags. For example, if a particular VR movie does not// contain a sound track, then the movie controller automatically suppresses the speaker/volume button. Likewise,// if a movie does contain a sound track, then the speaker/volume button is automatically displayed, again without// regard to the actual value of bit 2 in the control flags.//// This might not be what you'd like to happen. For instance, if your application is playing a sound that it// loaded from a sound resource, you might want the user to be able to adjust the sound's volume using the volume// control. To do that, you need a way to *force* the speaker/volume button to appear. For this reason, the// explicit flags were introduced.//// The explicit flags indicate which bits in the control flags are to be used explicitly (that is, taken at// face value). If a certain bit is set in a movie's explicit flags, then the corresponding bit in the control// flags is interpreted as the desired setting for the feature (and the movie controller will not attempt to// do anything "clever"). In other words, if bit 17 is set in a movie's explicit flags and bit 17 is clear in// that movie's control flags, then the zoom buttons are displayed. Similarly, if bit 2 is set in a movie's // explicit flags and bit 2 is clear in that movie's control flags, then the speaker/volume button is displayed,// whether or not the movie contains a sound track.//// The final thing to understand: to get or set a bit in a movie's explicit flags, you must set the flag // mcFlagQTVRExplicitFlagSet in your call to mcActionGetFlags or mcActionSetFlags. To get or set a bit in a // movie's control flags, you must clear the flag mcFlagQTVRExplicitFlagSet in your call to mcActionGetFlags // or mcActionSetFlags. Note that when you use the defined constants to set values in the explicit flags, the // constant names might be confusing. For instance, setting the bit mcFlagSuppressSpeakerButton in a movie's// explicit flags doesn't cause the speaker to be suppressed; it just means: "use the actual value of the// mcFlagSuppressSpeakerButton bit in the control flags".//// Whew! Any questions? Okay, then now you'll understand how to hide or show a button in the controller bar:// set the appropriate explicit flag to 1 and set the corresponding control flag to the desired value. And// you'll understand how to let the movie controller do its "clever" work: clear the appropriate explicit flag.//// There is one final twist to this story: the mcFlag bit for the custom controller button indicates that the// custom button should be shown, not (like all other button flags) that the button should be suppressed. So// we need to treat the custom button specially. Sigh.////////////void QTUtils_HideControllerButton (MovieController theMC, long theButton) { long myControllerFlags; // handle the custom button separately if (theButton == kQTUtilsCustomButton) { MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags & ~theButton)); } else { // get the current explicit flags and set the explicit flag for the specified button myControllerFlags = mcFlagQTVRExplicitFlagSet; MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)((myControllerFlags | theButton) | mcFlagQTVRExplicitFlagSet)); // get the current control flags and set the suppress flag for the specified button myControllerFlags = 0; MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)((myControllerFlags | theButton) & ~mcFlagQTVRExplicitFlagSet)); }}////////////// QTUtils_ShowControllerButton// Show the specified button in the controller bar.////////////void QTUtils_ShowControllerButton (MovieController theMC, long theButton) { long myControllerFlags; // handle the custom button separately if (theButton == kQTUtilsCustomButton) { MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | theButton)); } else { // get the current explicit flags and set the explicit flag for the specified button myControllerFlags = mcFlagQTVRExplicitFlagSet; MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)((myControllerFlags | theButton) | mcFlagQTVRExplicitFlagSet)); // get the current control flags and clear the suppress flag for the specified button myControllerFlags = 0; MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags & ~theButton & ~mcFlagQTVRExplicitFlagSet)); }}////////////// QTUtils_ToggleControllerButton// Toggle the state of the specified button in the controller bar.////////////void QTUtils_ToggleControllerButton (MovieController theMC, long theButton) { if (QTUtils_IsControllerButtonVisible(theMC, theButton)) QTUtils_HideControllerButton(theMC, theButton); else QTUtils_ShowControllerButton(theMC, theButton);}////////////// QTUtils_ResetControllerButton// Remove any explicit setting of the specified button in the controller bar.// (This allows the QuickTime VR movie controller to be as clever as it knows how to be.)////////////void QTUtils_ResetControllerButton (MovieController theMC, long theButton) { long myControllerFlags = mcFlagQTVRExplicitFlagSet; // get the current explicit flags and clear the explicit flag for the specified button MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); MCDoAction(theMC, mcActionSetFlags, (void *)((myControllerFlags | theButton) & ~mcFlagQTVRExplicitFlagSet));}////////////// QTUtils_IsControllerButtonVisible// Is the specified button in the controller bar currently visible?////////////Boolean QTUtils_IsControllerButtonVisible (MovieController theMC, long theButton) { long myControllerFlags; // get the current control flags myControllerFlags = 0; MCDoAction(theMC, mcActionGetFlags, &myControllerFlags); // the speaker button requires some additional logic, because the QTVR movie controller treats it special; // be advised that that controller's special behavior could change in the future, so you might need to tweak this code if (theButton == mcFlagSuppressSpeakerButton) { long myExplicitFlags; // get the current explicit flags myExplicitFlags = mcFlagQTVRExplicitFlagSet; MCDoAction(theMC, mcActionGetFlags, &myExplicitFlags); // the speaker button is not showing if the movie has no sound track and the explicit flag is not set if (!QTUtils_MovieHasSoundTrack(MCGetMovie(theMC)) && !(myExplicitFlags & theButton)) return(false); } // the custom button requires some different treatment, since it doesn't have a "Suppress" button constant if (theButton == mcFlagsUseCustomButton) if (myControllerFlags & theButton) return(true); else return(false); // examine the suppress flag for the specified button if (myControllerFlags & theButton) // if the button is currently suppressed... return(false); else return(true);}/////////////////////////////////////////////////////////////////////////////////////////////////////////////// Media utilities./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QTUtils_IsMediaTypeInMovie// Determine whether a specific media type is in a movie.// //////////Boolean QTUtils_IsMediaTypeInMovie (Movie theMovie, OSType theMediaType){ return(GetMovieIndTrackType(theMovie, 1, theMediaType, movieTrackMediaType | movieTrackEnabledOnly) != NULL);}////////////// QTUtils_MovieHasTimeCodeTrack// Determine whether a movie contains a timecode track.// //////////Boolean QTUtils_MovieHasTimeCodeTrack (Movie theMovie){ return(GetMovieIndTrackType(theMovie, 1, TimeCodeMediaType, movieTrackMediaType) != NULL);}////////////// QTUtils_MovieHasSoundTrack// Determine whether a movie contains a sound track.// //////////Boolean QTUtils_MovieHasSoundTrack (Movie theMovie){ return(GetMovieIndTrackType(theMovie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly) != NULL);}////////////// QTUtils_GetSoundMediaHandler// Return the sound media handler for a movie.// //////////MediaHandler QTUtils_GetSoundMediaHandler (Movie theMovie){ Track myTrack; Media myMedia; myTrack = GetMovieIndTrackType(theMovie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly); if (myTrack != NULL) { myMedia = GetTrackMedia(myTrack); return(GetMediaHandler(myMedia)); } return(NULL);}////////////// QTUtils_UpdateMovieVolumeSetting// Update the preferred volume setting of the specified movie.// //////////OSErr QTUtils_UpdateMovieVolumeSetting (Movie theMovie){ short myPrefVolume; short myCurrVolume; OSErr myErr = noErr; myPrefVolume = GetMoviePreferredVolume(theMovie); myCurrVolume = GetMovieVolume(theMovie); myCurrVolume = abs(myCurrVolume); if (myPrefVolume != myCurrVolume) { SetMoviePreferredVolume(theMovie, myCurrVolume); myErr = GetMoviesError(); } return(myErr);}////////////// QTUtils_SelectAllMovie// Select the entire movie associated with the specified movie controller.// //////////OSErr QTUtils_SelectAllMovie (MovieController theMC){ TimeRecord myTimeRecord; Movie myMovie = NULL; ComponentResult myErr = noErr; if (theMC == NULL) return(paramErr); myMovie = MCGetMovie(theMC); if (myMovie == NULL) return(paramErr); myTimeRecord.value.hi = 0; myTimeRecord.value.lo = 0; myTimeRecord.base = 0; myTimeRecord.scale = GetMovieTimeScale(myMovie); myErr = MCDoAction(theMC, mcActionSetSelectionBegin, &myTimeRecord); if (myErr != noErr) return((OSErr)myErr); myTimeRecord.value.hi = 0; myTimeRecord.value.lo = GetMovieDuration(myMovie); myTimeRecord.base = 0; myTimeRecord.scale = GetMovieTimeScale(myMovie); myErr = MCDoAction(theMC, mcActionSetSelectionDuration, &myTimeRecord); return((OSErr)myErr);}////////////// QTUtils_SelectNoneMovie// Select none of the movie associated with the specified movie controller.// //////////OSErr QTUtils_SelectNoneMovie (MovieController theMC){ TimeRecord myTimeRecord; Movie myMovie = NULL; ComponentResult myErr = noErr; if (theMC == NULL) return(paramErr); myMovie = MCGetMovie(theMC); if (myMovie == NULL) return(paramErr); myTimeRecord.value.hi = 0; myTimeRecord.value.lo = 0; myTimeRecord.base = 0; myTimeRecord.scale = GetMovieTimeScale(myMovie); myErr = MCDoAction(theMC, mcActionSetSelectionDuration, &myTimeRecord); return((OSErr)myErr);}////////////// QTUtils_MakeSampleDescription// Return a new image description with default and specified values.// //////////ImageDescriptionHandle QTUtils_MakeSampleDescription (long theEffectType, short theWidth, short theHeight){ ImageDescriptionHandle mySampleDesc = NULL; // create a new sample description mySampleDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); if (mySampleDesc == NULL) return(NULL); // fill in the fields of the sample description (**mySampleDesc).idSize = sizeof(ImageDescription); (**mySampleDesc).cType = theEffectType; (**mySampleDesc).vendor = kAppleManufacturer; (**mySampleDesc).temporalQuality = codecNormalQuality; (**mySampleDesc).spatialQuality = codecNormalQuality; (**mySampleDesc).width = theWidth; (**mySampleDesc).height = theHeight; (**mySampleDesc).hRes = 72L << 16; (**mySampleDesc).vRes = 72L << 16; (**mySampleDesc).dataSize = 0L; (**mySampleDesc).frameCount = 1; (**mySampleDesc).depth = 24; (**mySampleDesc).clutID = -1; return(mySampleDesc);}/////////////////////////////////////////////////////////////////////////////////////////////////////////////// User data utilities./////////////////////////////////////////////////////////////////////////////////////////////////////////////#if CONTENT_RATING_AVAIL////////////// QTUtils_GetContentRatingFromMovie// Get the content rating from a movie; return an error if it has none. In any case, return a meaningful// content rating.////////////OSErr QTUtils_GetContentRatingFromMovie (Movie theMovie, UInt16 *theRating, UInt32 *theReasons){ UserData myUserData = NULL; QTAltContentRatingRecord myContentRec; OSErr myErr = paramErr; *theRating = kQTContentTVYRating; *theReasons = 0L; // make sure we've got a movie if (theMovie == NULL) return(myErr); // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData != NULL) { myErr = GetUserDataItem(myUserData, &myContentRec, sizeof(myContentRec), FOUR_CHAR_CODE('crat'), 0); if (myErr == noErr) { *theRating = EndianU16_BtoN(myContentRec.ratings); *theReasons = EndianU32_BtoN(myContentRec.contentType); } } return(myErr);}////////////// QTUtils_AddContentRatingToMovie// Add a content rating to a movie.//// A content rating is stored as a user data item that indicates both the general rating// (for example, TV-MA [mature audiences only]) and any additional information about the// content (for example, coarse language). Let's call this additional information the// "reasons" for the rating. Both the rating and the reasons are specified using constants// in the file MoviesFormat.h.//// This function adds the specified content rating to the movie's user data;// the updated user data is written to the movie file when the movie is next updated// (by calling UpdateMovieResource).// //////////OSErr QTUtils_AddContentRatingToMovie (Movie theMovie, UInt16 theRating, UInt32 theReasons){ UserData myUserData = NULL; QTAltContentRatingRecord myContentRec; OSErr myErr = noErr; // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData == NULL) return(paramErr); myContentRec.flags = 0; myContentRec.contentType = EndianU32_NtoB(theReasons); myContentRec.ratings = EndianU16_NtoB(theRating); // for simplicity, we assume that we want only one content rating in the movie; // as a result, we won't worry about overwriting any existing item of that type // add the data to the movie's user data myErr = SetUserDataItem(myUserData, &myContentRec, sizeof(myContentRec), FOUR_CHAR_CODE('crat'), 0); return(myErr);}#endif // #if CONTENT_RATING_AVAIL////////////// QTUtils_AddUserDataTextToMovie// Add a user data item, of the specified type, containing the specified text to a movie.//// This function adds the specified text to the movie's user data;// the updated user data is written to the movie file when the movie is next updated// (by calling UpdateMovieResource).// //////////OSErr QTUtils_AddUserDataTextToMovie (Movie theMovie, char *theText, OSType theType){ UserData myUserData = NULL; Handle myHandle = NULL; long myLength = strlen(theText); OSErr myErr = noErr; // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData == NULL) return(paramErr); // copy the specified text into a new handle myHandle = NewHandleClear(myLength); if (myHandle == NULL) return(MemError()); BlockMoveData(theText, *myHandle, myLength); // for simplicity, we assume that we want only one user data item of the specified type in the movie; // as a result, we won't worry about overwriting any existing item of that type.... // // if you need multiple user data items of a given type (for example, a copyright notice // in several different languages), you would need to modify this code; this is left as an exercise // for the reader.... // add the data to the movie's user data myErr = AddUserDataText(myUserData, myHandle, theType, 1, (short)GetScriptManagerVariable(smRegionCode)); // clean up DisposeHandle(myHandle); return(myErr);}////////////// QTUtils_AddCopyrightToMovie// Add a user data item containing the specified copyright text to a movie.////////////OSErr QTUtils_AddCopyrightToMovie (Movie theMovie, char *theText){ return(QTUtils_AddUserDataTextToMovie(theMovie, theText, kUserDataTextCopyright));}////////////// QTUtils_AddMovieNameToMovie// Add a user data item containing the specified name to a movie.////////////OSErr QTUtils_AddMovieNameToMovie (Movie theMovie, char *theText){ return(QTUtils_AddUserDataTextToMovie(theMovie, theText, kUserDataTextFullName));}////////////// QTUtils_AddMovieInfoToMovie// Add a user data item containing the specified information to a movie.////////////OSErr QTUtils_AddMovieInfoToMovie (Movie theMovie, char *theText){ return(QTUtils_AddUserDataTextToMovie(theMovie, theText, kUserDataTextInformation));}////////////// QTUtils_GetMovieFileLoopingInfo// Get the looping state of a movie file.//// A movie file can have information about its looping state in a user data item of type 'LOOP'.// If the movie doesn't contain an item of this type, then we'll assume that it isn't looping.// If it does contain an item of this type, then the item data (a long integer) is 0 for normal// looping and 1 for palindrome looping. Accordingly, this function returns the following values// in the theLoopInfo parameter://// 0 == normal looping// 1 == palindrome looping// 2 == no looping//// Return an error if the movie has no looping state. In any case, return a meaningful looping state.////////////OSErr QTUtils_GetMovieFileLoopingInfo (Movie theMovie, long *theLoopInfo){ UserData myUserData = NULL; long myLoopInfo = kNoLooping; OSErr myErr = paramErr; // make sure we've got a movie if (theMovie == NULL) goto bail; // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData != NULL) { myErr = GetUserDataItem(myUserData, &myLoopInfo, sizeof(myLoopInfo), FOUR_CHAR_CODE('LOOP'), 0); if (myErr == noErr) myLoopInfo = EndianS32_BtoN(myLoopInfo); }bail: *theLoopInfo = myLoopInfo; return(myErr);}////////////// QTUtils_SetMovieFileLoopingInfo// Set the looping state for a movie file.////////////OSErr QTUtils_SetMovieFileLoopingInfo (Movie theMovie, long theLoopInfo){ UserData myUserData = NULL; long myLoopInfo; short myCount = 0; OSErr myErr = paramErr; // get the movie's user data myUserData = GetMovieUserData(theMovie); if (myUserData == NULL) goto bail; // we want to end up with at most one user data item of type 'LOOP', // so let's remove any existing ones myCount = CountUserDataType(myUserData, FOUR_CHAR_CODE('LOOP')); while (myCount--) RemoveUserData(myUserData, FOUR_CHAR_CODE('LOOP'), 1); // make sure we're writing big-endian data myLoopInfo = EndianU32_NtoB(theLoopInfo); switch (theLoopInfo) { case kNormalLooping: case kPalindromeLooping: myErr = SetUserDataItem(myUserData, &myLoopInfo, sizeof(long), FOUR_CHAR_CODE('LOOP'), 0); break; case kNoLooping: default: myErr = noErr; break; }bail: return(myErr);}////////////// QTUtils_SetLoopingStateFromFile// Set the looping state for a movie based on the looping information in the movie file.////////////OSErr QTUtils_SetLoopingStateFromFile (Movie theMovie, MovieController theMC){ long myLoopInfo = kNoLooping; OSErr myErr = noErr; myErr = QTUtils_GetMovieFileLoopingInfo(theMovie, &myLoopInfo); switch (myLoopInfo) { case kNormalLooping: MCDoAction(theMC, mcActionSetLooping, (void *)true); MCDoAction(theMC, mcActionSetLoopIsPalindrome, (void *)false); break; case kPalindromeLooping: MCDoAction(theMC, mcActionSetLooping, (void *)true); MCDoAction(theMC, mcActionSetLoopIsPalindrome, (void *)true); break; case kNoLooping: default: MCDoAction(theMC, mcActionSetLooping, (void *)false); MCDoAction(theMC, mcActionSetLoopIsPalindrome, (void *)false); break; } return(myErr);}////////////// QTUtils_MakeMovieLoop// Set the specified movie to loop.//// Based on the function MakeMovieLoop by Kevin Marks.////////////OSErr QTUtils_MakeMovieLoop (Movie theMovie, Boolean isPalindrome){ TimeBase myTimeBase = NULL; long myFlags = 0L; OSErr myErr = paramErr; // make sure we've got a movie if (theMovie == NULL) goto bail; myErr = noErr; // set the movie's play hints to enhance looping performance SetMoviePlayHints(theMovie, hintsLoop, hintsLoop); // set the looping flag of the movie's time base myTimeBase = GetMovieTimeBase(theMovie); myFlags = GetTimeBaseFlags(myTimeBase); myFlags |= loopTimeBase; // set or clear the palindrome flag, depending on the specified setting if (isPalindrome) myFlags |= palindromeLoopTimeBase; else myFlags &= ~palindromeLoopTimeBase; SetTimeBaseFlags(myTimeBase, myFlags);bail: return(myErr);}////////////// QTUtils_GetWindowPositionFromFile// Return, through thePoint, the stored position of the specified movie.//// Return an error if the movie has no stored position. In any case, return a meaningful position.////////////OSErr QTUtils_GetWindowPositionFromFile (Movie theMovie, Point *thePoint){ UserData myUserData = NULL; Point myPoint = {kDefaultWindowX, kDefaultWindowY}; OSErr myErr = paramErr; // make sure we've got a movie if (theMovie == NULL) goto bail; // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData != NULL) { myErr = GetUserDataItem(myUserData, &myPoint, sizeof(Point), FOUR_CHAR_CODE('WLOC'), 0); if (myErr == noErr) { myPoint.v = EndianS16_BtoN(myPoint.v); myPoint.h = EndianS16_BtoN(myPoint.h); } }bail: if (thePoint != NULL) *thePoint = myPoint; return(myErr);}////////////// QTUtils_GetTrackName// Get the name of the specified movie track.//// This routine is modelled on the one contained in Dispatch 2 from the Ice Floe;// I've modified it to return a C string instead of a Pascal string.//// The caller is responsible for disposing of the pointer returned by this function (by calling free).////////////char *QTUtils_GetTrackName (Track theTrack){ UserData myUserData = NULL; char *myString = NULL; OSErr myErr = noErr; // make sure we've got a track if (theTrack == NULL) return(NULL); // a track's name (if it has one) is stored in the track's user data myUserData = GetTrackUserData(theTrack); if (myUserData != NULL) { Handle myHandle = NewHandle(0); // get the user data item of type kUserDataName; // the handle we pass to GetUserData is resized to contain the track name myErr = GetUserData(myUserData, myHandle, kUserDataName, 1); if (myErr == noErr) { long myLength = GetHandleSize(myHandle); if (myLength > 0) { myString = malloc(myLength + 1); if (myString != NULL) { memcpy(myString, *myHandle, myLength); myString[myLength] = '\0'; } } } DisposeHandle(myHandle); } return(myString);}////////////// QTUtils_SetTrackName// Set the name of the specified movie track.//// This function adds the specified text to the track's user data;// the updated user data is written to the movie file when the movie is next updated// (by calling UpdateMovieResource).////////////OSErr QTUtils_SetTrackName (Track theTrack, char *theText){ UserData myUserData = NULL; OSErr myErr = noErr; // make sure we've got a track and a name if ((theTrack == NULL) || (theText == NULL)) return(paramErr); // get the track's user data list myUserData = GetTrackUserData(theTrack); if (myUserData == NULL) return(paramErr); // remove any existing track name while (RemoveUserData(myUserData, kUserDataName, 1) == noErr) ; myErr = SetUserDataItem(myUserData, theText, strlen(theText), kUserDataName, 0); return(myErr);}////////////// QTUtils_MakeTrackNameByType// Create a (unique) name for the specified track, based on the track's type.//// Given a movie track, this routine constructs a name for that track based on// the media type of that track. For instance, if the track is a sound track,// this routine returns the name "Sound". However, if there is more than one// track of that media type, then this routine numbers the track names. So, if// there are two sound tracks, this routine names them "Sound 1" and "Sound 2".//// This routine is modelled on the one contained in Dispatch 2 from the Ice Floe;// I've modified it to return a C string instead of a Pascal string.//// The caller is responsible for disposing of the pointer returned by this function (by calling free).////////////char *QTUtils_MakeTrackNameByType (Track theTrack){ Media myMedia; char *myString = NULL; ComponentResult myErr = noErr; // make sure we've got a track if (theTrack == NULL) return(NULL); myMedia = GetTrackMedia(theTrack); if (myMedia != NULL) { MediaHandler myMediaHandler = GetMediaHandler(myMedia); OSType myMediaType; Str255 myName; // get the media type of the track GetMediaHandlerDescription(myMedia, &myMediaType, NULL, NULL); // get the text of the media type myErr = MediaGetName(myMediaHandler, myName, 0, NULL); if (myErr == noErr) { // determine whether there's more than one track with this media type if (GetMovieIndTrackType(GetTrackMovie(theTrack), 2, myMediaType, movieTrackMediaType) != NULL) { // add an index number to the track type string we constructed above long myIndex = 1; Str255 myNumString; while (GetMovieIndTrackType(GetTrackMovie(theTrack), myIndex, myMediaType, movieTrackMediaType) != theTrack) myIndex++; NumToString(myIndex, myNumString); myName[++myName[0]] = ' '; BlockMoveData(&myNumString[1], &myName[myName[0] + 1], myNumString[0]); myName[0] += myNumString[0]; } // now copy the string data from the Pascal string to a C string if (myName[0] > 0) { myString = malloc(myName[0] + 1); if (myString != NULL) { memcpy(myString, &myName[1], myName[0]); myString[myName[0]] = '\0'; } } } } return(myString);}////////////// QTUtils_IsImageFile// Is the specified file an image file?////////////Boolean QTUtils_IsImageFile (FSSpec *theFSSpec){ GraphicsImportComponent myImporter = NULL; GetGraphicsImporterForFile(theFSSpec, &myImporter); if (myImporter != NULL) CloseComponent(myImporter); return(myImporter != NULL);}////////////// QTUtils_IsMovieFile// Is the specified file a file that can be opened by QuickTime as a movie?////////////Boolean QTUtils_IsMovieFile (FSSpec *theFSSpec){ Boolean isMovieFile = false; AliasHandle myAlias = NULL; Component myImporter = NULL; FInfo myFinderInfo; OSErr myErr = noErr; // see whether the file type is MovieFileType; to do this, get the Finder information myErr = FSpGetFInfo(theFSSpec, &myFinderInfo); if (myErr == noErr) if (myFinderInfo.fdType == kQTFileTypeMovie) return(true); // if it isn't a movie file, see whether the file can be imported as a movie myErr = QTNewAlias(theFSSpec, &myAlias, true); if (myErr == noErr) { if (myAlias != NULL) { myErr = GetMovieImporterForDataRef(rAliasType, (Handle)myAlias, kGetMovieImporterDontConsiderGraphicsImporters, &myImporter); DisposeHandle((Handle)myAlias); } } if ((myErr == noErr) && (myImporter != NULL)) // this file is a movie file isMovieFile = true; return(isMovieFile);}////////////// QTUtils_ConvertFloatToBigEndian// Convert the specified floating-point number to big-endian format.////////////void QTUtils_ConvertFloatToBigEndian (float *theFloat){ unsigned long *myLongPtr; myLongPtr = (unsigned long *)theFloat; *myLongPtr = EndianU32_NtoB(*myLongPtr);}////////////// QTUtils_ConvertCToPascalString// Convert a C string into a Pascal string.//// The caller is responsible for disposing of the pointer returned by this function (by calling free).////////////StringPtr QTUtils_ConvertCToPascalString (char *theString){ StringPtr myString = malloc(min(strlen(theString) + 1, 256)); short myIndex = 0; while ((theString[myIndex] != '\0') && (myIndex < 255)) { myString[myIndex + 1] = theString[myIndex]; myIndex++; } myString[0] = (unsigned char)myIndex; return(myString);}////////////// QTUtils_ConvertPascalToCString// Convert a Pascal string into a C string.//// The caller is responsible for disposing of the pointer returned by this function (by calling free).////////////char *QTUtils_ConvertPascalToCString (StringPtr theString){ char *myString = malloc(theString[0] + 1); short myIndex = 0; for (myIndex = 0; myIndex < theString[0]; myIndex++) myString[myIndex] = theString[myIndex + 1]; myString[theString[0]] = '\0'; return(myString);}////////////// QTUtils_DeleteAllReferencesToTrack// Delete all existing track references to the specified track.////////////OSErr QTUtils_DeleteAllReferencesToTrack (Track theTrack){ Movie myMovie = NULL; Track myTrack = NULL; long myTrackCount = 0L; long myTrRefCount = 0L; long myTrackIndex; long myTrRefIndex; OSErr myErr = noErr; myMovie = GetTrackMovie(theTrack); if (myMovie == NULL) return(paramErr); // iterate thru all the tracks in the movie (that are different from the specified track) myTrackCount = GetMovieTrackCount(myMovie); for (myTrackIndex = 1; myTrackIndex <= myTrackCount; myTrackIndex++) { myTrack = GetMovieIndTrack(myMovie, myTrackIndex); if ((myTrack != NULL) && (myTrack != theTrack)) { OSType myType = 0L; // iterate thru all track reference types contained in the current track myType = GetNextTrackReferenceType(myTrack, myType); while (myType != 0L) { // iterate thru all track references of the current type; // note that we count down to 1, since DeleteTrackReference will cause // any higher-indexed track references to be renumbered myTrRefCount = GetTrackReferenceCount(myTrack, myType); for (myTrRefIndex = myTrRefCount; myTrRefIndex >= 1; myTrRefIndex--) { Track myRefTrack = NULL; myRefTrack = GetTrackReference(myTrack, myType, myTrRefIndex); if (myRefTrack == theTrack) myErr = DeleteTrackReference(myTrack, myType, myTrRefIndex); } myType = GetNextTrackReferenceType(myTrack, myType); } } } return(myErr);}////////////// QTUtils_GetFrameDuration// Get the duration of the first sample frame in the specified movie track.////////////TimeValue QTUtils_GetFrameDuration (Track theTrack){ TimeValue mySampleDuration; OSErr myErr = noErr; myErr = GetMediaSample( GetTrackMedia(theTrack), NULL, // don't return sample data 0, NULL, // don't return number of bytes of sample data returned 0, NULL, &mySampleDuration, NULL, // don't return sample description NULL, // don't return sample description index 0, // no max number of samples NULL, // don't return number of samples returned NULL); // don't return sample flags // make sure we return a legitimate value even if GetMediaSample encounters an error if (myErr != noErr) mySampleDuration = 0; return(mySampleDuration);}////////////// QTUtils_GetFrameCount// Get the number of frames in the specified movie track. We return the value -1 if// an error occurs and we cannot determine the number of frames in the track.//// Based (loosely) on frame-counting code in ConvertToMovie Jr.c.// // We count the frames in the track by stepping through all of its interesting times// (the places where the track displays a new sample).////////////long QTUtils_GetFrameCount (Track theTrack){ long myCount = -1; short myFlags; TimeValue myTime = 0; if (theTrack == NULL) goto bail; // we want to begin with the first frame (sample) in the track myFlags = nextTimeMediaSample + nextTimeEdgeOK; while (myTime >= 0) { myCount++; // look for the next frame in the track; when there are no more frames, // myTime is set to -1, so we'll exit the while loop GetTrackNextInterestingTime(theTrack, myFlags, myTime, fixed1, &myTime, NULL); // after the first interesting time, don't include the time we're currently at myFlags = nextTimeStep; }bail: return(myCount);}////////////// QTUtils_GetMaxWindowDepth// Get the deepest pixel type and size of the screen area intersected by a specified window.////////////#if TARGET_OS_MACvoid QTUtils_GetMaxWindowDepth (CWindowPtr theWindow, short *thePixelType, short *thePixelSize){ Rect myRect; Point myPoint = {0, 0}; // initialize returned values *thePixelType = k1MonochromePixelFormat; *thePixelSize = 0; if (theWindow == NULL) return; GetWindowPortBounds(theWindow, &myRect); // assume the window is the current port LocalToGlobal(&myPoint); // offset the rectangle to global coordinates MacOffsetRect(&myRect, myPoint.h, myPoint.v); // get the max data for the global rectangle QTUtils_GetMaxScreenDepth(&myRect, thePixelType, thePixelSize);}#endif////////////// QTUtils_GetMaxScreenDepth// Get the deepest pixel type and size of the screen area intersected by a specified rectangle.////////////void QTUtils_GetMaxScreenDepth (Rect *theGlobalRect, short *thePixelType, short *thePixelSize){ GDHandle myGDevice = NULL; PixMapHandle myPixMap = NULL; myGDevice = GetMaxDevice(theGlobalRect); // get the max device if (myGDevice != NULL) { // get the pixmap for the max device myPixMap = (**myGDevice).gdPMap; if (myPixMap != NULL) { // extract the interesting info from the pixmap of the device *thePixelType = (**myPixMap).pixelType; *thePixelSize = (**myPixMap).pixelSize; } }}////////////// QTUtils_GetUsersConnectionSpeed// Return the connection speed selected by the user in the QuickTime Settings control panel;// return kDataRate288ModemRate if the user's QuickTime preferences cannot be read of if some// other error occurs.//// Based on code in Ice Floe Dispatch 17 by Mike Dodd.////////////long QTUtils_GetUsersConnectionSpeed (void){ QTAtomContainer myPrefsContainer = NULL; QTAtom myPrefsAtom = 0; ConnectionSpeedPrefsRecord myPrefsRec; long myDataSize = 0L; long mySpeed = kDataRate288ModemRate; Ptr myAtomData = NULL; OSErr myErr = noErr; // you can retrieve the user's QuickTime preferences by calling GetQuickTimePreference; // the first parameter indicates the type of preference you want information about, and // the second parameter is an atom container that contains the returned preference data myErr = GetQuickTimePreference(ConnectionSpeedPrefsType, &myPrefsContainer); if (myErr == noErr) { // find the atom of the desired type myPrefsAtom = QTFindChildByID(myPrefsContainer, kParentAtomIsContainer, ConnectionSpeedPrefsType, 1, NULL); if (myPrefsAtom != 0) { // we found the desired atom in the returned atom container; // read the data contained in that atom and verify that the data is of the // size we are expecting QTGetAtomDataPtr(myPrefsContainer, myPrefsAtom, &myDataSize, &myAtomData); if (myDataSize == sizeof(ConnectionSpeedPrefsRecord)) { // read the connection speed // NOTE: the data in this atom is native-endian, so we do not need to // perform any endian-swapping when extracting the speed from the atom. // (This is an exception to the rule that data in atom containers is // always big-endian.) myPrefsRec = *(ConnectionSpeedPrefsRecord *)myAtomData; mySpeed = myPrefsRec.connectionSpeed; } } QTDisposeAtomContainer(myPrefsContainer); } return(mySpeed);}////////////// QTUtils_SetUsersConnectionSpeed// Set the connection speed in the QuickTime Settings control panel to the specified value.//// NOTE: In general, you should let the user decide the connection speed (using the QuickTime// Settings control panel). In some cases, however, you might need to do this programmatically.// Also, you should in general use values for theSpeed that are enumerated in the header file// MoviesFormat.h.//// Based on code in Ice Floe Dispatch 17 by Mike Dodd.////////////OSErr QTUtils_SetUsersConnectionSpeed (long theSpeed){ QTAtomContainer myPrefsContainer = NULL; ConnectionSpeedPrefsRecord myPrefsRec; OSErr myErr = noErr; myErr = QTNewAtomContainer(&myPrefsContainer); if (myErr == noErr) { // NOTE: the data in this atom is native-endian, so we do not need to // perform any endian-swapping when inserting the speed into the atom. // (This is an exception to the rule that data in atom containers is // always big-endian.) myPrefsRec.connectionSpeed = theSpeed; myErr = QTInsertChild(myPrefsContainer, kParentAtomIsContainer, ConnectionSpeedPrefsType, 1, 0, sizeof(ConnectionSpeedPrefsRecord), &myPrefsRec, NULL); if (myErr == noErr) myErr = SetQuickTimePreference(ConnectionSpeedPrefsType, myPrefsContainer); QTDisposeAtomContainer(myPrefsContainer); } return(myErr);}#if CONTENT_RATING_AVAIL////////////// QTUtils_GetUsersContentRating// Return, through the function's parameters, the content rating and acceptable content types// selected by the user in the QuickTime Settings control panel; return an error if the user's// QuickTime preferences cannot be read.//// Based on QTUtils_GetUsersConnectionSpeed.////////////OSErr QTUtils_GetUsersContentRating (UInt32 *theType, UInt16 *theRating){ QTAtomContainer myPrefsContainer = NULL; QTAtom myPrefsAtom = 0; ContentRatingPrefsRecord myContentRec; long myDataSize = 0L; Ptr myAtomData = NULL; OSErr myErr = noErr; // you can retrieve the user's QuickTime preferences by calling GetQuickTimePreference; // the first parameter indicates the type of preference you want information about, and // the second parameter is an atom container that contains the returned preference data myErr = GetQuickTimePreference(kContentRatingPrefsType, &myPrefsContainer); if (myErr == noErr) { // find the atom of the desired type myPrefsAtom = QTFindChildByID(myPrefsContainer, kParentAtomIsContainer, kContentRatingPrefsType, 1, NULL); if (myPrefsAtom == 0) { // we did not find any such atom in the returned atom container, so we'll // return default settings *theType = 0L; *theRating = kQTContentTVYRating; } else { // we found the desired atom in the returned atom container; // read the data contained in that atom and verify that the data is of the // size we are expecting myErr = QTGetAtomDataPtr(myPrefsContainer, myPrefsAtom, &myDataSize, &myAtomData); if (myDataSize != sizeof(ContentRatingPrefsRecord)) { // the data in the atom isn't the right size, so it must be corrupt; // return default settings *theType = 0L; *theRating = kQTContentTVYRating; } else { // everything is fine: read the content information // NOTE: the data in this atom is native-endian, so we do not need to // perform any endian-swapping when extracting the data from the atom. // (This is an exception to the rule that data in atom containers is // always big-endian.) // WARNING: the format of the data in a content rating atom is, to my // knowledge, currently undocumented; the following method of extracting // that info is based on empirical investigation. myContentRec = *(ContentRatingPrefsRecord *)myAtomData; *theType = (UInt32)(~(myContentRec.fContentTypes) & 0x00ff); *theRating = myContentRec.fContentRating; } } QTDisposeAtomContainer(myPrefsContainer); } return(myErr);}#endif // #if CONTENT_RATING_AVAIL/////////////////////////////////////////////////////////////////////////////////////////////////////////////// Controller utilities.//// Use these functions to manipulate movie controllers./////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QTUtils_GetControllerType// Get the controller type of the specified movie.////////////OSType QTUtils_GetControllerType (Movie theMovie) { UserData myUserData = NULL; OSType myType = kUnknownType; OSErr myErr = noErr; // make sure we've got a movie if (theMovie == NULL) return(myType); myUserData = GetMovieUserData(theMovie); if (myUserData != NULL) { myErr = GetUserDataItem(myUserData, &myType, sizeof(myType), kUserDataMovieControllerType, 0); if (myErr == noErr) myType = EndianU32_BtoN(myType); } return(myType);}////////////// QTUtils_SetControllerType// Set the controller type of the specified movie.//// This function adds an item to the movie's user data;// the updated user data is written to the movie file when the movie is next updated// (by calling AddMovieResource or UpdateMovieResource).//// NOTE: This function is intended to set the controller type of a movie you're building;// to change the controller of an open movie, use QTUtils_ChangeControllerType.////////////OSErr QTUtils_SetControllerType (Movie theMovie, OSType theType){ UserData myUserData; OSErr myErr = noErr; // make sure we've got a movie if (theMovie == NULL) return(paramErr); // get the movie's user data list myUserData = GetMovieUserData(theMovie); if (myUserData == NULL) return(paramErr); theType = EndianU32_NtoB(theType); myErr = SetUserDataItem(myUserData, &theType, sizeof(theType), kUserDataMovieControllerType, 0); return(myErr);}////////////// QTUtils_ChangeControllerType// Change the controller type of the movie that uses the specified controller, "on the fly",// and return the new movie controller to the caller; if for some reason we cannot create a// new movie controller, return NULL.////////////MovieController QTUtils_ChangeControllerType (MovieController theMC, OSType theType, long theFlags){ MovieController myMC = NULL; Movie myMovie = NULL; Rect myRect; OSErr myErr = noErr; // make sure we've got a movie controller if (theMC == NULL) return(NULL); // get the movie associated with that controller myMovie = MCGetMovie(theMC); if (myMovie == NULL) return(NULL); GetMovieBox(myMovie, &myRect); // set the new controller type in the movie's user data list myErr = QTUtils_SetControllerType(myMovie, theType); if (myErr != noErr) return(NULL); // dispose of the existing controller DisposeMovieController(theMC); // create a new controller of the specified type myMC = NewMovieController(myMovie, &myRect, theFlags); return(myMC);}#endif // ifndef __QTUtilities__</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/vrmovies/listing9.html%3Fid%3DDTS10001030-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/vrmovies/listing9.html%3Fid%3DDTS10001030-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/vrmovies/listing9.html%3Fid%3DDTS10001030-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>