| |
1 /* |
| |
2 File: Utilities.c |
| |
3 |
| |
4 Description: Miscellaneous Utility routines. |
| |
5 |
| |
6 Copyright: © Copyright 2003 Apple Computer, Inc. All rights reserved. |
| |
7 |
| |
8 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
| |
9 ("Apple") in consideration of your agreement to the following terms, and your |
| |
10 use, installation, modification or redistribution of this Apple software |
| |
11 constitutes acceptance of these terms. If you do not agree with these terms, |
| |
12 please do not use, install, modify or redistribute this Apple software. |
| |
13 |
| |
14 In consideration of your agreement to abide by the following terms, and subject |
| |
15 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s |
| |
16 copyrights in this original Apple software (the "Apple Software"), to use, |
| |
17 reproduce, modify and redistribute the Apple Software, with or without |
| |
18 modifications, in source and/or binary forms; provided that if you redistribute |
| |
19 the Apple Software in its entirety and without modifications, you must retain |
| |
20 this notice and the following text and disclaimers in all such redistributions of |
| |
21 the Apple Software. Neither the name, trademarks, service marks or logos of |
| |
22 Apple Computer, Inc. may be used to endorse or promote products derived from the |
| |
23 Apple Software without specific prior written permission from Apple. Except as |
| |
24 expressly stated in this notice, no other rights or licenses, express or implied, |
| |
25 are granted by Apple herein, including but not limited to any patent rights that |
| |
26 may be infringed by your derivative works or by other works in which the Apple |
| |
27 Software may be incorporated. |
| |
28 |
| |
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
| |
30 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
| |
31 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| |
32 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
| |
33 COMBINATION WITH YOUR PRODUCTS. |
| |
34 |
| |
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
| |
36 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
| |
37 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| |
38 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
| |
39 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
| |
40 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
| |
41 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
42 |
| |
43 Change History (most recent first): |
| |
44 |
| |
45 */ |
| |
46 |
| |
47 #ifndef __UTILITIES__ |
| |
48 #include "Utilities.h" |
| |
49 #endif |
| |
50 |
| |
51 const OSType kApplicationSignature = FOUR_CHAR_CODE('cvmj'); |
| |
52 const ResType kOpenResourceType = FOUR_CHAR_CODE('open'); |
| |
53 const StringPtr kApplicationName = "\pYourAppNameHere"; |
| |
54 |
| |
55 ////////// |
| |
56 // |
| |
57 // GetOneFileWithPreview |
| |
58 // Display the appropriate file-opening dialog box, with an optional QuickTime preview pane. If the user |
| |
59 // selects a file, return information about it using the theFSSpecPtr parameter. |
| |
60 // |
| |
61 // Note that both StandardGetFilePreview and NavGetFile use the function specified by theFilterProc as a |
| |
62 // file filter. This framework always passes NULL in the theFilterProc parameter. If you use this function |
| |
63 // in your own code, keep in mind that on Windows the function specifier must be of type FileFilterUPP and |
| |
64 // on Macintosh it must be of type NavObjectFilterUPP. (You can use the QTFrame_GetFileFilterUPP to create |
| |
65 // a function specifier of the appropriate type.) Also keep in mind that Navigation Services expects a file |
| |
66 // filter function to return true if a file is to be displayed, while the Standard File Package expects the |
| |
67 // filter to return false if a file is to be displayed. |
| |
68 // |
| |
69 ////////// |
| |
70 |
| |
71 OSErr GetOneFileWithPreview (short theNumTypes, TypeListPtr theTypeList, FSSpecPtr theFSSpecPtr, void *theFilterProc) |
| |
72 { |
| |
73 |
| |
74 #if TARGET_OS_WIN32 |
| |
75 StandardFileReply myReply; |
| |
76 #endif |
| |
77 #if TARGET_OS_MAC |
| |
78 NavReplyRecord myReply; |
| |
79 NavDialogOptions myDialogOptions; |
| |
80 NavTypeListHandle myOpenList = NULL; |
| |
81 NavEventUPP myEventUPP = NewNavEventUPP(HandleNavEvent); |
| |
82 #endif |
| |
83 OSErr myErr = noErr; |
| |
84 |
| |
85 if (theFSSpecPtr == NULL) |
| |
86 return(paramErr); |
| |
87 |
| |
88 #if TARGET_OS_WIN32 |
| |
89 // prompt the user for a file |
| |
90 StandardGetFilePreview((FileFilterUPP)theFilterProc, theNumTypes, (ConstSFTypeListPtr)theTypeList, &myReply); |
| |
91 if (!myReply.sfGood) |
| |
92 return(userCanceledErr); |
| |
93 |
| |
94 // make an FSSpec record |
| |
95 myErr = FSMakeFSSpec(myReply.sfFile.vRefNum, myReply.sfFile.parID, myReply.sfFile.name, theFSSpecPtr); |
| |
96 #endif |
| |
97 |
| |
98 #if TARGET_OS_MAC |
| |
99 // specify the options for the dialog box |
| |
100 NavGetDefaultDialogOptions(&myDialogOptions); |
| |
101 myDialogOptions.dialogOptionFlags -= kNavNoTypePopup; |
| |
102 myDialogOptions.dialogOptionFlags -= kNavAllowMultipleFiles; |
| |
103 BlockMoveData(kApplicationName, myDialogOptions.clientName, kApplicationName[0] + 1); |
| |
104 |
| |
105 // create a handle to an 'open' resource |
| |
106 myOpenList = (NavTypeListHandle)CreateOpenHandle(kApplicationSignature, theNumTypes, theTypeList); |
| |
107 if (myOpenList != NULL) |
| |
108 HLock((Handle)myOpenList); |
| |
109 |
| |
110 // prompt the user for a file |
| |
111 myErr = NavGetFile(NULL, &myReply, &myDialogOptions, myEventUPP, NULL, (NavObjectFilterUPP)theFilterProc, myOpenList, NULL); |
| |
112 if ((myErr == noErr) && myReply.validRecord) { |
| |
113 AEKeyword myKeyword; |
| |
114 DescType myActualType; |
| |
115 Size myActualSize = 0; |
| |
116 |
| |
117 // get the FSSpec for the selected file |
| |
118 if (theFSSpecPtr != NULL) |
| |
119 myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); |
| |
120 |
| |
121 NavDisposeReply(&myReply); |
| |
122 } |
| |
123 |
| |
124 if (myOpenList != NULL) { |
| |
125 HUnlock((Handle)myOpenList); |
| |
126 DisposeHandle((Handle)myOpenList); |
| |
127 } |
| |
128 |
| |
129 DisposeNavEventUPP(myEventUPP); |
| |
130 #endif |
| |
131 |
| |
132 return(myErr); |
| |
133 } |
| |
134 |
| |
135 ////////// |
| |
136 // |
| |
137 // CreateOpenHandle |
| |
138 // Get the 'open' resource or dynamically create a NavTypeListHandle. |
| |
139 // |
| |
140 ////////// |
| |
141 |
| |
142 Handle CreateOpenHandle (OSType theApplicationSignature, short theNumTypes, TypeListPtr theTypeList) |
| |
143 { |
| |
144 Handle myHandle = NULL; |
| |
145 |
| |
146 // see if we have an 'open' resource... |
| |
147 myHandle = Get1Resource('open', 128); |
| |
148 if ( myHandle != NULL && ResError() == noErr ) { |
| |
149 DetachResource( myHandle ); |
| |
150 return myHandle; |
| |
151 } else { |
| |
152 myHandle = NULL; |
| |
153 } |
| |
154 |
| |
155 // nope, use the passed in types and dynamically create the NavTypeList |
| |
156 if (theTypeList == NULL) |
| |
157 return myHandle; |
| |
158 |
| |
159 if (theNumTypes > 0) { |
| |
160 myHandle = NewHandle(sizeof(NavTypeList) + (theNumTypes * sizeof(OSType))); |
| |
161 if (myHandle != NULL) { |
| |
162 NavTypeListHandle myOpenResHandle = (NavTypeListHandle)myHandle; |
| |
163 |
| |
164 (*myOpenResHandle)->componentSignature = theApplicationSignature; |
| |
165 (*myOpenResHandle)->osTypeCount = theNumTypes; |
| |
166 BlockMoveData(theTypeList, (*myOpenResHandle)->osType, theNumTypes * sizeof(OSType)); |
| |
167 } |
| |
168 } |
| |
169 |
| |
170 return myHandle; |
| |
171 } |
| |
172 |
| |
173 ////////// |
| |
174 // |
| |
175 // HandleNavEvent |
| |
176 // A callback procedure that handles events while a Navigation Service dialog box is displayed. |
| |
177 // |
| |
178 ////////// |
| |
179 |
| |
180 PASCAL_RTN void HandleNavEvent(NavEventCallbackMessage theCallBackSelector, NavCBRecPtr theCallBackParms, void *theCallBackUD) |
| |
181 { |
| |
182 #pragma unused(theCallBackUD) |
| |
183 |
| |
184 if (theCallBackSelector == kNavCBEvent) { |
| |
185 switch (theCallBackParms->eventData.eventDataParms.event->what) { |
| |
186 case updateEvt: |
| |
187 #if TARGET_OS_MAC |
| |
188 // Handle Update Event |
| |
189 #endif |
| |
190 break; |
| |
191 case nullEvent: |
| |
192 // Handle Null Event |
| |
193 break; |
| |
194 } |
| |
195 } |
| |
196 } |
| |
197 |
| |
198 ////////// |
| |
199 // |
| |
200 // PutFile |
| |
201 // Save a file under the specified name. Return Boolean values indicating whether the user selected a file |
| |
202 // and whether the selected file is replacing an existing file. |
| |
203 // |
| |
204 ////////// |
| |
205 |
| |
206 OSErr PutFile (ConstStr255Param thePrompt, ConstStr255Param theFileName, FSSpecPtr theFSSpecPtr, Boolean *theIsSelected, Boolean *theIsReplacing) |
| |
207 { |
| |
208 NavReplyRecord myReply; |
| |
209 NavDialogOptions myDialogOptions; |
| |
210 NavEventUPP myEventUPP = NewNavEventUPP(HandleNavEvent); |
| |
211 OSErr myErr = noErr; |
| |
212 |
| |
213 if ((theFSSpecPtr == NULL) || (theIsSelected == NULL) || (theIsReplacing == NULL)) |
| |
214 return(paramErr); |
| |
215 |
| |
216 // assume we are not replacing an existing file |
| |
217 *theIsReplacing = false; |
| |
218 |
| |
219 *theIsSelected = false; |
| |
220 |
| |
221 // specify the options for the dialog box |
| |
222 NavGetDefaultDialogOptions(&myDialogOptions); |
| |
223 myDialogOptions.dialogOptionFlags += kNavNoTypePopup; |
| |
224 myDialogOptions.dialogOptionFlags += kNavDontAutoTranslate; |
| |
225 BlockMoveData(theFileName, myDialogOptions.savedFileName, theFileName[0] + 1); |
| |
226 BlockMoveData(thePrompt, myDialogOptions.message, thePrompt[0] + 1); |
| |
227 |
| |
228 // prompt the user for a file |
| |
229 myErr = NavPutFile(NULL, &myReply, &myDialogOptions, myEventUPP, MovieFileType, sigMoviePlayer, NULL); |
| |
230 if ((myErr == noErr) && myReply.validRecord) |
| |
231 { |
| |
232 AEKeyword myKeyword; |
| |
233 DescType myActualType; |
| |
234 Size myActualSize = 0; |
| |
235 |
| |
236 // get the FSSpec for the selected file |
| |
237 if (theFSSpecPtr != NULL) |
| |
238 myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); |
| |
239 |
| |
240 *theIsSelected = myReply.validRecord; |
| |
241 if (myReply.validRecord) |
| |
242 { |
| |
243 *theIsReplacing = myReply.replacing; |
| |
244 } |
| |
245 |
| |
246 NavDisposeReply(&myReply); |
| |
247 } |
| |
248 |
| |
249 |
| |
250 DisposeNavEventUPP(myEventUPP); |
| |
251 |
| |
252 return(myErr); |
| |
253 } |
| |
254 |
| |
255 ////////// |
| |
256 // |
| |
257 // DrawLobsterPICTtoGWorld |
| |
258 // Draws our lobster image to the specified gworld |
| |
259 // |
| |
260 ////////// |
| |
261 |
| |
262 void DrawLobsterPICTtoGWorld(CGrafPtr destGWorld, Rect *srcRect) |
| |
263 { |
| |
264 // put the overlay into the GWorld, move the picture to the bottom right of the movie |
| |
265 PicHandle pict = GetPicture(129); |
| |
266 if (pict) |
| |
267 { |
| |
268 CGrafPtr oldPort; |
| |
269 GDHandle oldDevice; |
| |
270 Rect frame = (**pict).picFrame; |
| |
271 |
| |
272 GetGWorld(&oldPort, &oldDevice); |
| |
273 SetGWorld(destGWorld, nil); |
| |
274 // normalize coordinates |
| |
275 OffsetRect(&frame, -frame.left, -frame.left); |
| |
276 // grow frame to be as big as source rect |
| |
277 OffsetRect(&frame, srcRect->right - frame.right, srcRect->bottom - frame.bottom); |
| |
278 DrawPicture(pict, &frame); |
| |
279 SetGWorld(oldPort, oldDevice); |
| |
280 ReleaseResource((Handle)pict); |
| |
281 } |
| |
282 } |
| |
283 |