root/trunk/SMAC/SMACDispatch.c

Revision 1, 34.4 kB (checked in by gbooker, 3 years ago)

Initial Import

Line 
1 /*      Copyright:      © Copyright 2004 Apple Computer, Inc. All rights reserved.
2
3         Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
4                         ("Apple") in consideration of your agreement to the following terms, and your
5                         use, installation, modification or redistribution of this Apple software
6                         constitutes acceptance of these terms.  If you do not agree with these terms,
7                         please do not use, install, modify or redistribute this Apple software.
8
9                         In consideration of your agreement to abide by the following terms, and subject
10                         to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
11                         copyrights in this original Apple software (the "Apple Software"), to use,
12                         reproduce, modify and redistribute the Apple Software, with or without
13                         modifications, in source and/or binary forms; provided that if you redistribute
14                         the Apple Software in its entirety and without modifications, you must retain
15                         this notice and the following text and disclaimers in all such redistributions of
16                         the Apple Software.  Neither the name, trademarks, service marks or logos of
17                         Apple Computer, Inc. may be used to endorse or promote products derived from the
18                         Apple Software without specific prior written permission from Apple.  Except as
19                         expressly stated in this notice, no other rights or licenses, express or implied,
20                         are granted by Apple herein, including but not limited to any patent rights that
21                         may be infringed by your derivative works or by other works in which the Apple
22                         Software may be incorporated.
23
24                         The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
25                         WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
26                         WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27                         PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
28                         COMBINATION WITH YOUR PRODUCTS.
29
30                         IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
31                         CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
32                         GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33                         ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
34                         OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
35                         (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
36                         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38 /*
39         File:           SMACDispatch.c
40
41         Contains:       Common dispatching for SMAC
42
43         Written by:     Jim Reekes and Kip Olson
44
45         Copyright:      © 1992-1997, 1999-2001 by Apple Computer, Inc., all rights reserved.
46
47 */
48
49 #include <CAConditionalMacros.h>
50 #include <Carbon/Carbon.h>
51
52 #if     !TARGET_API_MAC_CARBON
53 #include <Gestalt.h>
54 #include <LowMem.h>
55 #include <MacMemory.h>
56 #include <Movies.h>
57 #include <Sound.h>
58 #include <SoundPriv.h>
59 #include <LowMemPriv.h>
60 #include <Traps.h>
61 #include <ProcessesPriv.h>
62 #endif
63
64 #if     TARGET_API_MAC_CARBON
65 #define GLUE(a,b)               a##b
66 #define GLUE2(a,b)              GLUE(a,b)
67 #define GLUE3(a,b,c)    GLUE2(GLUE2(a,b),c)
68 #endif
69
70 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71 //      Sound Component Function Prototypes
72 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73
74 // unless SoundComponentBaseName is define, none of the dispatching code will be included
75
76 #ifdef SoundComponentBaseName
77
78 // The SoundComponentBaseName is used to concatenate unique routine names.
79
80 #define SoundComponentDispatch GLUE2(SoundComponentBaseName(), Dispatch)
81 #define __SoundComponentOpen GLUE3(__, SoundComponentBaseName(), Open)
82 #define __SoundComponentClose GLUE3(__, SoundComponentBaseName(), Close)
83 #define __SoundComponentCanDo GLUE3(__, SoundComponentBaseName(), CanDo)
84 #define __SoundComponentVersion GLUE3(__, SoundComponentBaseName(), Version)
85 #define __SoundComponentRegister GLUE3(__, SoundComponentBaseName(), Register)
86 #define __SoundComponentInitOutputDevice GLUE3(__, SoundComponentBaseName(), InitOutputDevice)
87 #define __SoundComponentSetSource GLUE3(__, SoundComponentBaseName(), SetSource)
88 #define __SoundComponentGetSource GLUE3(__, SoundComponentBaseName(), GetSource)
89 #define __SoundComponentGetSourceData GLUE3(__, SoundComponentBaseName(), GetSourceData)
90 #define __SoundComponentSetOutput GLUE3(__, SoundComponentBaseName(), SetOutput)
91 #define __SoundComponentAddSource GLUE3(__, SoundComponentBaseName(), AddSource)
92 #define __SoundComponentRemoveSource GLUE3(__, SoundComponentBaseName(), RemoveSource)
93 #define __SoundComponentGetInfo GLUE3(__, SoundComponentBaseName(), GetInfo)
94 #define __SoundComponentSetInfo GLUE3(__, SoundComponentBaseName(), SetInfo)
95 #define __SoundComponentStartSource GLUE3(__, SoundComponentBaseName(), StartSource)
96 #define __SoundComponentStopSource GLUE3(__, SoundComponentBaseName(), StopSource)
97 #define __SoundComponentPauseSource GLUE3(__, SoundComponentBaseName(), PauseSource)
98 #define __SoundComponentPlaySourceBuffer GLUE3(__, SoundComponentBaseName(), PlaySourceBuffer)
99 #define __SoundComponentAddMChannelSource GLUE3(__, SoundComponentBaseName(), AddMChannelSource)
100 #define __SoundComponentValidSource GLUE3(__, SoundComponentBaseName(), ValidSource)
101
102 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103 // component stuff
104
105 static pascal ComponentResult __SoundComponentOpen(void *unused1, ComponentInstance self);
106 static pascal ComponentResult __SoundComponentClose(SoundComponentGlobalsPtr globals, ComponentInstance self);
107 static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector);
108 #ifdef __SoundComponentVersionRoutine
109 static pascal ComponentResult __SoundComponentVersion(void *unused1);
110 #endif
111 #ifdef __SoundComponentRegisterRoutine
112 static pascal ComponentResult __SoundComponentRegister(SoundComponentGlobalsPtr globals);
113 #endif
114
115 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116 // basic stuff
117
118 #ifdef __SoundComponentInitOutputDeviceRoutine
119 static pascal ComponentResult __SoundComponentInitOutputDevice(SoundComponentGlobalsPtr globals, long actions);
120 #endif
121 #ifdef __SoundComponentSetSourceRoutine
122 static pascal ComponentResult __SoundComponentSetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance source);
123 #endif
124 static pascal ComponentResult __SoundComponentGetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance *source);
125 #ifdef __SoundComponentGetSourceDataRoutine
126 static pascal ComponentResult __SoundComponentGetSourceData(SoundComponentGlobalsPtr globals, SoundComponentDataPtr *sourceData);
127 #endif
128 #ifdef __SoundComponentSetOutputRoutine
129 static pascal ComponentResult __SoundComponentSetOutput(SoundComponentGlobalsPtr globals, SoundComponentDataPtr requested, SoundComponentDataPtr *actual);
130 #endif
131
132 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133 // junction methods (i.e. the mixer) must be called at non-interrupt level
134
135 #ifdef __SoundComponentAddSourceRoutine
136 static pascal ComponentResult __SoundComponentAddSource(SoundComponentGlobalsPtr globals, SoundSource *sourceID);
137 #endif
138 #ifdef __SoundComponentRemoveSourceRoutine
139 static pascal ComponentResult __SoundComponentRemoveSource(SoundComponentGlobalsPtr globals, SoundSource sourceID);
140 #endif
141 #ifdef __SoundComponentAddMChannelSourceRoutine
142 static pascal ComponentResult __SoundComponentAddMChannelSource(SoundComponentGlobalsPtr globals, OSType streamID, SoundSource *sourceID);
143 #endif
144 #ifdef __SoundComponentValidSourceRoutine
145 static pascal ComponentResult __SoundComponentValidSource(SoundComponentGlobalsPtr globals, SoundSource sourceID);
146 #endif
147
148 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
149 // info methods
150
151 #ifdef __SoundComponentGetInfoRoutine
152 static pascal ComponentResult __SoundComponentGetInfo(SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr);
153 #endif
154 #ifdef __SoundComponentSetInfoRoutine
155 static pascal ComponentResult __SoundComponentSetInfo(SoundComponentGlobalsPtr globals, SoundSource sourceID, OSType selector, void *infoPtr);
156 #endif
157
158 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159 // control methods
160 #ifdef __SoundComponentStartSourceRoutine
161 static pascal ComponentResult __SoundComponentStartSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources);
162 #endif
163 #ifdef __SoundComponentStopSourceRoutine
164 static pascal ComponentResult __SoundComponentStopSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources);
165 #endif
166 #ifdef __SoundComponentPauseSourceRoutine
167 static pascal ComponentResult __SoundComponentPauseSource(SoundComponentGlobalsPtr globals, short count, SoundSource *sources);
168 #endif
169 #ifdef __SoundComponentPlaySourceBufferRoutine
170 static pascal ComponentResult __SoundComponentPlaySourceBuffer(SoundComponentGlobalsPtr globals, SoundSource sourceID, SoundParamBlockPtr pb, long actions);
171 #endif
172
173
174 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
175 // types
176 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177
178 #if PRAGMA_STRUCT_ALIGN
179         #pragma options align=mac68k
180 #elif PRAGMA_STRUCT_PACKPUSH
181         #pragma pack(push, 2)
182 #elif PRAGMA_STRUCT_PACK
183         #pragma pack(2)
184 #endif
185
186 // These structs are use in PowerMac builds to cast the
187 // ComponentParameters passed into our component's entry point.
188
189 enum {
190         uppSoundComponentDispatchProcInfo = kPascalStackBased
191                 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
192                 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ComponentParameters *)))
193                 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *)))
194 };
195
196 #define paramsHeader unsigned char flags; unsigned char paramSize; short what
197
198 typedef struct {
199         paramsHeader;
200         ComponentInstance self;
201         void *unused1;
202 } OpenPB, *OpenPBPtr;
203
204 typedef struct {
205         paramsHeader;
206         ComponentInstance self;
207 } ClosePB, *ClosePBPtr;
208
209 typedef struct {
210         paramsHeader;
211         long actions;
212 } InitOutputDevicePB, *InitOutputDevicePBPtr;
213
214 typedef struct {
215         paramsHeader;
216         ComponentInstance source;
217         SoundSource sourceID;
218 } SetSourcePB, *SetSourcePBPtr;
219
220 typedef struct {
221         paramsHeader;
222         ComponentInstance *source;
223         SoundSource sourceID;
224 } GetSourcePB, *GetSourcePBPtr;
225
226 typedef struct {
227         paramsHeader;
228         SoundComponentDataPtr *sourceData;
229 } GetSourceDataPB, *GetSourceDataPBPtr;
230
231 typedef struct {
232         paramsHeader;
233         SoundComponentDataPtr *actual;
234         SoundComponentDataPtr requested;
235 } SetOutputPB, *SetOutputPBPtr;
236
237 typedef struct {
238         paramsHeader;
239         SoundSource *sourceID;
240 } AddSourcePB, *AddSourcePBPtr;
241
242 typedef struct {
243         paramsHeader;
244         SoundSource sourceID;
245 } RemoveSourcePB, *RemoveSourcePBPtr;
246
247 typedef struct {
248         paramsHeader;
249         void *infoPtr;
250         OSType selector;
251         SoundSource sourceID;
252 } GetInfoPB, *GetInfoPBPtr;
253
254 typedef struct {
255         paramsHeader;
256         void *infoPtr;
257         OSType selector;
258         SoundSource sourceID;
259 } SetInfoPB, *SetInfoPBPtr;
260
261 typedef struct {
262         paramsHeader;
263         SoundSource *sources;
264         short count;
265 } StartSourcePB, *StartSourcePBPtr;
266
267 typedef struct {
268         paramsHeader;
269         SoundSource *sources;
270         short count;
271 } StopSourcePB, *StopSourcePBPtr;
272
273 typedef struct {
274         paramsHeader;
275         SoundSource *sources;
276         short count;
277 } PauseSourcePB, *PauseSourcePBPtr;
278
279 typedef struct {
280         paramsHeader;
281         long actions;
282         SoundParamBlockPtr pb;
283         SoundSource sourceID;
284 } PlaySourcePB, *PlaySourcePBPtr;
285
286 typedef struct {
287         paramsHeader;
288         SoundSource *sourceID;
289         OSType streamID;
290 } AddMChannelSourcePB, *AddMChannelSourcePBPtr;
291
292 typedef struct {
293         paramsHeader;
294         SoundSource sourceID;
295 } ValidSourcePB, *ValidSourcePBPtr;
296
297 typedef struct {
298         paramsHeader;
299         TimeRecord *theTime;
300         void * unused1;
301 } GetTimePB, *GetTimePBPtr;
302
303 typedef struct {
304         paramsHeader;
305         UnsignedFixed sampleRate;
306         wide *sampleCount;
307         void * unused1;
308 } SoundTickPB, *SoundTickPBPtr;
309
310 #if PRAGMA_STRUCT_ALIGN
311         #pragma options align=reset
312 #elif PRAGMA_STRUCT_PACKPUSH
313         #pragma pack(pop)
314 #elif PRAGMA_STRUCT_PACK
315         #pragma pack()
316 #endif
317
318
319 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
320 //      Sound Component Entry Point
321 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
322
323 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324 // PowerPC dispatching, entry point is a routine descriptor
325
326 #if TARGET_CPU_PPC || TARGET_API_MAC_CARBON
327
328 #if     TARGET_API_MAC_CARBON
329 pascal ComponentResult SoundComponentDispatch(ComponentParameters *p, SoundComponentGlobalsPtr globals);
330
331 pascal ComponentResult SoundComponentDispatch(ComponentParameters *p, SoundComponentGlobalsPtr globals)
332 #else
333 static pascal ComponentResult SoundComponentProc(ComponentParameters *params, SoundComponentGlobalsPtr globals);
334
335 RoutineDescriptor SoundComponentDispatch = BUILD_ROUTINE_DESCRIPTOR(uppSoundComponentDispatchProcInfo, SoundComponentProc);
336
337 static pascal ComponentResult SoundComponentProc(ComponentParameters *p, SoundComponentGlobalsPtr globals)
338 #endif
339 {
340         ComponentResult                         result = badComponentSelector;
341
342         switch (p->what)        // standard component selectors
343         {
344                 #ifdef __SoundComponentRegisterRoutine
345                 case kComponentRegisterSelect:
346                         result = __SoundComponentRegister(globals);
347                         break;
348                 #endif
349
350                 case kComponentVersionSelect:
351                 #ifdef __SoundComponentVersionRoutine
352                         result = __SoundComponentVersion(0);
353                 #else
354                         result = kSoundComponentVersion;
355                 #endif
356                         break;
357
358                 case kComponentCanDoSelect:
359                         result = __SoundComponentCanDo(0, *((short *) &p->params[0]));
360                         break;
361
362                 #ifdef __SoundComponentCloseRoutine
363                 case kComponentCloseSelect:
364                         result = __SoundComponentClose(globals, ((ClosePBPtr)p)->self);
365                         break;
366                 #endif
367
368                 #ifdef __SoundComponentOpenRoutine
369                 case kComponentOpenSelect:
370                         result = __SoundComponentOpen(globals, ((OpenPBPtr)p)->self);
371                         break;
372                 #endif
373
374                 // selectors that cannot be delegated
375
376                 #ifdef __SoundComponentInitOutputDeviceRoutine
377                 case kSoundComponentInitOutputDeviceSelect:
378                         result = __SoundComponentInitOutputDevice(globals, ((InitOutputDevicePBPtr)p)->actions);
379                         break;
380                 #endif
381
382                 #ifdef __SoundComponentSetSourceRoutine
383                 case kSoundComponentSetSourceSelect:
384                         result = __SoundComponentSetSource(globals, ((SetSourcePBPtr)p)->sourceID, ((SetSourcePBPtr)p)->source);
385                         break;
386                 #endif
387
388                 case kSoundComponentGetSourceSelect:
389                         result = __SoundComponentGetSource(globals, ((GetSourcePBPtr)p)->sourceID, ((GetSourcePBPtr)p)->source);
390                         break;
391
392                 #ifdef __SoundComponentGetSourceDataRoutine
393                 case kSoundComponentGetSourceDataSelect:
394                         result = __SoundComponentGetSourceData(globals, ((GetSourceDataPBPtr)p)->sourceData);
395                         break;
396                 #endif
397
398                 #ifdef __SoundComponentSetOutputRoutine
399                 case kSoundComponentSetOutputSelect:
400                         result = __SoundComponentSetOutput(globals, ((SetOutputPBPtr)p)->requested, ((SetOutputPBPtr)p)->actual);
401                         break;
402                 #endif
403
404                 // selectors that can be delegated
405
406                 #ifdef __SoundComponentAddSourceRoutine
407                 case kSoundComponentAddSourceSelect:
408                         result = __SoundComponentAddSource(globals, ((AddSourcePBPtr)p)->sourceID);
409                         break;
410                 #endif
411
412                 #ifdef __SoundComponentRemoveSourceRoutine
413                 case kSoundComponentRemoveSourceSelect:
414                         result = __SoundComponentRemoveSource(globals, ((RemoveSourcePBPtr)p)->sourceID);
415                         break;
416                 #endif
417
418                 #ifdef __SoundComponentGetInfoRoutine
419                 case kSoundComponentGetInfoSelect:
420 #if     SMInstrumentation_On
421                         if(((GetInfoPBPtr)p)->selector == '1984')
422                         {
423                                 SMInstrumentationFlushTrace(globals->instrumentationTrace);
424                         }
425 #endif
426                         result = __SoundComponentGetInfo(globals, ((GetInfoPBPtr)p)->sourceID, ((GetInfoPBPtr)p)->selector, ((GetInfoPBPtr)p)->infoPtr);
427                         break;
428                 #endif
429
430                 #ifdef __SoundComponentSetInfoRoutine
431                 case kSoundComponentSetInfoSelect:
432                         result = __SoundComponentSetInfo(globals, ((SetInfoPBPtr)p)->sourceID, ((SetInfoPBPtr)p)->selector, ((SetInfoPBPtr)p)->infoPtr);
433                         break;
434                 #endif
435
436                 #ifdef __SoundComponentStartSourceRoutine
437                 case kSoundComponentStartSourceSelect:
438                         result = __SoundComponentStartSource(globals, ((StartSourcePBPtr)p)->count, ((StartSourcePBPtr)p)->sources);
439                         break;
440                 #endif
441
442                 #ifdef __SoundComponentStopSourceRoutine
443                 case kSoundComponentStopSourceSelect:
444                         result = __SoundComponentStopSource(globals, ((StopSourcePBPtr)p)->count, ((StopSourcePBPtr)p)->sources);
445                         break;
446                 #endif
447
448                 #ifdef __SoundComponentPauseSourceRoutine
449                 case kSoundComponentPauseSourceSelect:
450                         result = __SoundComponentPauseSource(globals, ((PauseSourcePBPtr)p)->count, ((PauseSourcePBPtr)p)->sources);
451                         break;
452                 #endif
453
454                 #ifdef __SoundComponentPlaySourceBufferRoutine
455                 case kSoundComponentPlaySourceBufferSelect:
456                         result = __SoundComponentPlaySourceBuffer(globals, ((PlaySourcePBPtr)p)->sourceID, ((PlaySourcePBPtr)p)->pb, ((PlaySourcePBPtr)p)->actions);
457                         break;
458                 #endif
459
460                 #ifdef __SoundComponentAddMChannelSourceRoutine
461                 case kSoundComponentAddMChannelSourceSelect:
462                         result = __SoundComponentAddMChannelSource(globals, ((AddMChannelSourcePBPtr)p)->streamID, ((AddMChannelSourcePBPtr)p)->sourceID);
463                         break;
464                 #endif
465
466                 #ifdef __SoundComponentValidSourceRoutine
467                 case kSoundComponentValidSourceSelect:
468                         result = __SoundComponentValidSource(globals, ((ValidSourcePBPtr)p)->sourceID);
469                         break;
470                 #endif
471
472                 default:
473                         if (p->what > kDelegatedSoundComponentSelectors)
474                                 result = DelegateComponentCall(p, globals->sourceComponent);
475                         break;
476         }
477
478         return (result);
479 }
480
481 #else /* !TARGET_CPU_PPC */
482
483 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
484 // Mac 68k and non Mac OS dispatching
485
486 pascal ComponentResult SoundComponentDispatch(ComponentParameters *params, SoundComponentGlobalsPtr globals);
487
488 pascal ComponentResult SoundComponentDispatch(ComponentParameters *params, SoundComponentGlobalsPtr globals)
489 {
490         ComponentFunctionUPP            theRtn;
491         ComponentResult                         result;
492         short                                           selector = params->what;
493         Boolean                                         checkCanDo = false;
494
495 #define kDelegateSoundComponentCall     ((ComponentFunctionUPP) -1)
496
497 SelectorSwitch:
498         if (selector < 0)
499                 switch (selector - kComponentRegisterSelect)    // standard component selectors
500                 {
501                         case kComponentRegisterSelect - kComponentRegisterSelect:
502                                 #ifdef __SoundComponentRegisterRoutine
503                                         theRtn = (ComponentFunctionUPP) __SoundComponentRegister;
504                                 #else
505                                         theRtn = (ComponentFunctionUPP)nil;
506                                 #endif
507                                 break;
508
509                         case kComponentVersionSelect - kComponentRegisterSelect:
510                                 #ifdef __SoundComponentVersionRoutine
511                                         theRtn = (ComponentFunctionUPP) __SoundComponentVersion;
512                                 #else
513                                         return (kSoundComponentVersion);
514                                 #endif
515                                 break;
516
517                         case kComponentCanDoSelect - kComponentRegisterSelect:
518                                 #ifdef __SoundComponentCanDoRoutine
519                                         theRtn = (ComponentFunctionUPP) __SoundComponentCanDo;
520                                 #else
521                                         selector = *((short *) &params->params[0]);
522                                         checkCanDo = true;
523                                         goto SelectorSwitch;
524                                 #endif
525                                 break;
526
527                         case kComponentCloseSelect - kComponentRegisterSelect:
528                                 #ifdef __SoundComponentCloseRoutine
529                                         theRtn = (ComponentFunctionUPP) __SoundComponentClose;
530                                 #else
531                                         theRtn = (ComponentFunctionUPP)nil;
532                                 #endif
533                                 break;
534
535                         case kComponentOpenSelect - kComponentRegisterSelect:
536                                 #ifdef __SoundComponentOpenRoutine
537                                         theRtn = (ComponentFunctionUPP) __SoundComponentOpen;
538                                 #else
539                                         theRtn = (ComponentFunctionUPP)nil;
540                                 #endif
541                                 break;
542
543                         default:
544                                 theRtn = (ComponentFunctionUPP)nil;
545                                 break;
546                 }
547         else if (selector < kDelegatedSoundComponentSelectors)                  // selectors that cannot be delegated
548                 switch (selector)
549                 {
550                         case kSoundComponentInitOutputDeviceSelect:
551                                 #ifdef __SoundComponentInitOutputDeviceRoutine
552                                         theRtn = (ComponentFunctionUPP) __SoundComponentInitOutputDevice;
553                                 #else
554                                         theRtn = (ComponentFunctionUPP)nil;
555                                 #endif
556                                 break;
557
558                         case kSoundComponentSetSourceSelect:
559                                 #ifdef __SoundComponentSetSourceRoutine
560                                         theRtn = (ComponentFunctionUPP) __SoundComponentSetSource;
561                                 #else
562                                         theRtn = (ComponentFunctionUPP)nil;
563                                 #endif
564                                 break;
565
566                         case kSoundComponentGetSourceSelect:
567                                 #ifdef __SoundComponentGetSourceRoutine
568                                         theRtn = (ComponentFunctionUPP) __SoundComponentGetSource;
569                                 #else
570                                         theRtn = (ComponentFunctionUPP) __SoundComponentGetSource;
571                                 #endif
572                                 break;
573
574                         case kSoundComponentGetSourceDataSelect:
575                                 #ifdef __SoundComponentGetSourceDataRoutine
576                                         theRtn = (ComponentFunctionUPP) __SoundComponentGetSourceData;
577                                 #else
578                                         theRtn = (ComponentFunctionUPP)nil;
579                                 #endif
580                                 break;
581
582                         case kSoundComponentSetOutputSelect:
583                                 #ifdef __SoundComponentSetOutputRoutine
584                                         theRtn = (ComponentFunctionUPP) __SoundComponentSetOutput;
585                                 #else
586                                         theRtn = (ComponentFunctionUPP)nil;
587                                 #endif
588                                 break;
589
590                         default:
591                                 theRtn = (ComponentFunctionUPP)nil;
592                                 break;
593                 }
594         else                                                                                                    // selectors that can be delegated
595                 switch (selector)
596                 {
597                         case kSoundComponentAddSourceSelect:
598                                 #ifdef __SoundComponentAddSourceRoutine
599                                         theRtn = (ComponentFunctionUPP) __SoundComponentAddSource;
600                                 #else
601                                         theRtn = kDelegateSoundComponentCall;
602                                 #endif
603                                 break;
604
605                         case kSoundComponentRemoveSourceSelect:
606                                 #ifdef __SoundComponentRemoveSourceRoutine
607                                         theRtn = (ComponentFunctionUPP) __SoundComponentRemoveSource;
608                                 #else
609                                         theRtn = kDelegateSoundComponentCall;
610                                 #endif
611                                 break;
612
613                         case kSoundComponentGetInfoSelect:
614                                 #ifdef __SoundComponentGetInfoRoutine
615                                         theRtn = (ComponentFunctionUPP) __SoundComponentGetInfo;
616                                 #else
617                                         theRtn = kDelegateSoundComponentCall;
618                                 #endif
619                                 break;
620
621                         case kSoundComponentSetInfoSelect:
622                                 #ifdef __SoundComponentSetInfoRoutine
623                                         theRtn = (ComponentFunctionUPP) __SoundComponentSetInfo;
624                                 #else
625                                         theRtn = kDelegateSoundComponentCall;
626                                 #endif
627                                 break;
628
629                         case kSoundComponentStartSourceSelect:
630                                 #ifdef __SoundComponentStartSourceRoutine
631                                         theRtn = (ComponentFunctionUPP) __SoundComponentStartSource;
632                                 #else
633                                         theRtn = kDelegateSoundComponentCall;
634                                 #endif
635                                 break;
636
637                         case kSoundComponentStopSourceSelect:
638                                 #ifdef __SoundComponentStopSourceRoutine
639                                         theRtn = (ComponentFunctionUPP) __SoundComponentStopSource;
640                                 #else
641                                         theRtn = kDelegateSoundComponentCall;
642                                 #endif
643                                 break;
644
645                         case kSoundComponentPauseSourceSelect:
646                                 #ifdef __SoundComponentPauseSourceRoutine
647                                         theRtn = (ComponentFunctionUPP) __SoundComponentPauseSource;
648                                 #else
649                                         theRtn = kDelegateSoundComponentCall;
650                                 #endif
651                                 break;
652
653                         case kSoundComponentPlaySourceBufferSelect:
654                                 #ifdef __SoundComponentPlaySourceBufferRoutine
655                                         theRtn = (ComponentFunctionUPP) __SoundComponentPlaySourceBuffer;
656                                 #else
657                                         theRtn = kDelegateSoundComponentCall;
658                                 #endif
659                                 break;
660
661                         case kSoundComponentAddMChannelSourceSelect:
662                                 #ifdef __SoundComponentAddMChannelSourceRoutine
663                                         theRtn = (ComponentFunctionUPP) __SoundComponentAddMChannelSource;
664                                 #else
665                                         theRtn = kDelegateSoundComponentCall;
666                                 #endif
667                                 break;
668
669                         case kSoundComponentValidSourceSelect:
670                                 #ifdef __SoundComponentValidSourceRoutine
671                                         theRtn = (ComponentFunctionUPP) __SoundComponentValidSource;
672                                 #else
673                                         theRtn = kDelegateSoundComponentCall;
674                                 #endif
675                                 break;
676
677                         default:
678                                 theRtn = kDelegateSoundComponentCall;
679                                 break;
680                 }
681
682         if (checkCanDo)
683                 result = ((theRtn == nil) || (theRtn == kDelegateSoundComponentCall)) ? 0 : 1;
684         else
685         {
686                 if (theRtn == nil)
687                         result = badComponentSelector;
688                 else if (theRtn == kDelegateSoundComponentCall)
689                         result = DelegateComponentCall(params, globals->sourceComponent);
690                 else
691                         result = CallComponentFunctionWithStorage((Handle) globals, params, theRtn);
692         }
693         return (result);
694 }
695
696 #endif /* !TARGET_CPU_PPC */
697
698
699 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
700 #ifndef __SoundComponentGetSourceRoutine
701 static pascal ComponentResult __SoundComponentGetSource(SoundComponentGlobalsPtr globals, SoundSource sourceID, ComponentInstance *source)
702 {
703 #pragma unused (sourceID)
704
705         *source = globals->sourceComponent;
706         return (noErr);
707 }
708 #endif
709
710 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
711 #ifndef __SoundComponentCanDoRoutine
712 static pascal ComponentResult __SoundComponentCanDo(void *unused1, short selector)
713 {
714 #pragma unused (unused1)
715
716         ComponentResult         result;
717
718         switch (selector)
719         {
720                 #ifdef __SoundComponentRegisterRoutine
721                 case kComponentRegisterSelect:
722                         result = true;
723                         break;
724                 #endif
725
726                 case kComponentVersionSelect:
727                         result = true;
728                         break;
729
730                 case kComponentCanDoSelect:
731                         result = true;
732                         break;
733
734                 #ifdef __SoundComponentCloseRoutine
735                 case kComponentCloseSelect:
736                         result = true;
737                         break;
738                 #endif
739
740                 #ifdef __SoundComponentOpenRoutine
741                 case kComponentOpenSelect:
742                         result = true;
743                         break;
744                 #endif
745
746                 #ifdef __SoundComponentInitOutputDeviceRoutine
747                 case kSoundComponentInitOutputDeviceSelect:
748                         result = true;
749                         break;
750                 #endif
751
752                 #ifdef __SoundComponentSetSourceRoutine
753                 case kSoundComponentSetSourceSelect:
754                         result = true;
755                         break;
756                 #endif
757
758                 case kSoundComponentGetSourceSelect:
759                         result = true;
760                         break;
761
762                 #ifdef __SoundComponentGetSourceDataRoutine
763                 case kSoundComponentGetSourceDataSelect:
764                         result = true;
765                         break;
766                 #endif
767
768                 #ifdef __SoundComponentSetOutputRoutine
769                 case kSoundComponentSetOutputSelect:
770                         result = true;
771                         break;
772                 #endif
773
774                 // selectors that can be delegated
775
776                 #ifdef __SoundComponentAddSourceRoutine
777                 case kSoundComponentAddSourceSelect:
778                         result = true;
779                         break;
780                 #endif
781
782                 #ifdef __SoundComponentRemoveSourceRoutine
783                 case kSoundComponentRemoveSourceSelect:
784                         result = true;
785                         break;
786                 #endif
787
788                 #ifdef __SoundComponentGetInfoRoutine
789                 case kSoundComponentGetInfoSelect:
790                         result = true;
791                         break;
792                 #endif
793
794                 #ifdef __SoundComponentSetInfoRoutine
795                 case kSoundComponentSetInfoSelect:
796                         result = true;
797                         break;
798                 #endif
799
800                 #ifdef __SoundComponentStartSourceRoutine
801                 case kSoundComponentStartSourceSelect:
802                         result = true;
803                         break;
804                 #endif
805
806                 #ifdef __SoundComponentStopSourceRoutine
807                 case kSoundComponentStopSourceSelect:
808                         result = true;
809                         break;
810                 #endif
811
812                 #ifdef __SoundComponentPauseSourceRoutine
813                 case kSoundComponentPauseSourceSelect:
814                         result = true;
815                         break;
816                 #endif
817
818                 #ifdef __SoundComponentPlaySourceBufferRoutine
819                 case kSoundComponentPlaySourceBufferSelect:
820                         result = true;
821                         break;
822                 #endif
823
824                 #ifdef __SoundComponentAddMChannelSourceRoutine
825                 case kSoundComponentAddMChannelSourceSelect:
826                         result = true;
827                         break;
828                 #endif
829
830                 #ifdef __SoundComponentValidSourceRoutine
831                 case kSoundComponentValidSourceSelect:
832                         result = true;
833                         break;
834                 #endif
835
836                 default:
837                         result = false;
838                         break;
839         }
840
841         return (result);
842 }
843 #endif
844
845 #endif /* SoundComponentBaseName */
846
847
848 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
849 // end of common code for sound component dispatching
850 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
851
852 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
853 // misc utility routines used by sound components
854 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
855
856 #if     TARGET_API_MAC_CARBON
857
858 #ifdef SoundComponentBaseName
859 #ifndef PrimeSource
860 #define PrimeSource                                             GLUE3(__, SoundComponentBaseName(), PrimeSource)
861 #endif
862 #endif
863 #endif
864
865 static OSErr NewSoundComponentLocalStorage(long size, Handle *storageHandle, Ptr *storage);
866 static OSErr NewSoundComponentGlobalStorage(long size, Handle *storageHandle, Ptr *storage, Boolean *inAppHeap);
867 static void  DisposeSoundComponentStorage(Handle storageHandle);
868
869 #if     !TARGET_API_MAC_CARBON
870 static OSErr GetAppStorageWithRespect(Handle *storageHandle, long size);
871 static OSErr GetSystemStorageWithRespect(Handle *storageHandle, long size);
872 static OSErr HandleVMCFMCommon(CFragInitBlockPtr initInfo);
873 OSErr HandleVMCFMInitialize(CFragInitBlockPtr initInfo);
874 void HandleVMCFMTerminate(void);
875 static OSErr SetClosureMemory(CFragContextID contextID, CFragClosureID closureID, Boolean holdMemory);
876 #endif
877
878 #if     TARGET_API_MAC_CARBON
879
880 static inline OSErr NewSoundComponentGlobalStorage(long size, Handle *storageHandle, Ptr *storage, Boolean *inAppHeap)
881 {
882         Handle          h = NewHandle(size);
883         if (h != NULL) {
884                 *storageHandle = h;
885                 *storage = *h;
886                 *inAppHeap = true;
887         }
888         return MemError();
889 }
890
891 static inline OSErr NewSoundComponentLocalStorage(long size, Handle *storageHandle, Ptr *storage)
892 {
893         Boolean ignore;
894         return NewSoundComponentGlobalStorage(size, storageHandle, storage, &ignore);
895 }
896
897 static inline void DisposeSoundComponentStorage(Handle storageHandle)
898 {
899         DisposeHandle(storageHandle);
900 }
901
902 #else   /* !TARGET_API_MAC_CARBON */
903
904 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
905 // routines for Power Mac builds, which are simply in-lines for 68k
906 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
907
908 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
909 static long PurgeAppSpaceContiguous(void)
910 {
911         long    totalPurgeSpace;
912         long    contigPurgeSpace;
913
914         PurgeSpace(&totalPurgeSpace, &contigPurgeSpace);
915         return (contigPurgeSpace);
916 }
917
918 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
919 static unsigned long PurgeSpaceSystemContiguous(void)
920 {
921         long    totalPurgeSpace;
922         long    contigPurgeSpace;
923 #if     !TARGET_API_MAC_CARBON
924         THz             curZone;
925
926         curZone = GetZone();
927         SetZone(SystemZone());
928 #endif
929         PurgeSpace(&totalPurgeSpace, &contigPurgeSpace);
930 #if     !TARGET_API_MAC_CARBON
931         SetZone(curZone);
932 #endif
933         return (contigPurgeSpace);
934 }
935
936 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
937 // Try to get space in application's heap and making sure we allocate the memory
938 // allowing enough space in the heap for others.
939 // Hold memory to make it safe for VM during interrupts.
940
941 static OSErr GetAppStorageWithRespect(Handle *storageHandle, long size)
942 {
943         Handle                  h;
944         OSErr                   result;
945
946         ReserveMem(size);                                       // create a low heap object