Switched over to the remodeled Audio Toolbox version of the System Sound API. Fixes #70 and suppresses a few deprecated-API warnings. maintenance-1.2
authorPeter Hosey <hg@boredzo.org>
Sat Jan 01 13:12:53 2011 -0800 (2011-01-01)
branchmaintenance-1.2
changeset 4670033e8fb1a6dd
parent 4669 9dd57a3e1bcf
child 4671 602f5298e952
child 4672 5fd480ef577f
Switched over to the remodeled Audio Toolbox version of the System Sound API. Fixes #70 and suppresses a few deprecated-API warnings.
Core/Source/GrowlApplicationController.h
Core/Source/GrowlApplicationController.m
Growl.xcodeproj/project.pbxproj
     1.1 --- a/Core/Source/GrowlApplicationController.h	Sat Jan 01 12:37:10 2011 -0800
     1.2 +++ b/Core/Source/GrowlApplicationController.h	Sat Jan 01 13:12:53 2011 -0800
     1.3 @@ -38,8 +38,6 @@
     1.4  	CFRunLoopTimerRef			updateTimer;
     1.5  
     1.6  	NSThread					*mainThread;
     1.7 -
     1.8 -	SystemSoundCompletionUPP	soundCompletionCallback;
     1.9  }
    1.10  
    1.11  + (GrowlApplicationController *) sharedController;
     2.1 --- a/Core/Source/GrowlApplicationController.m	Sat Jan 01 12:37:10 2011 -0800
     2.2 +++ b/Core/Source/GrowlApplicationController.m	Sat Jan 01 13:12:53 2011 -0800
     2.3 @@ -34,6 +34,7 @@
     2.4  #include "CFMutableDictionaryAdditions.h"
     2.5  #include "cdsa.h"
     2.6  #include <SystemConfiguration/SystemConfiguration.h>
     2.7 +#include <AudioToolbox/AudioToolbox.h>
     2.8  #include <sys/errno.h>
     2.9  #include <string.h>
    2.10  #include <sys/socket.h>
    2.11 @@ -48,7 +49,7 @@
    2.12  #define USER_WENT_IDLE_NOTIFICATION		@"User went idle"
    2.13  #define USER_RETURNED_NOTIFICATION		@"User returned"
    2.14  
    2.15 -static OSStatus soundCompletionCallbackProc(SystemSoundActionID actionID, void *refcon);
    2.16 +static void soundCompletionCallbackProc(SystemSoundID soundID, void *refcon);
    2.17  
    2.18  extern CFRunLoopRef CFRunLoopGetMain(void);
    2.19  
    2.20 @@ -244,8 +245,6 @@
    2.21  		[growlNotificationCenterConnection setRootObject:growlNotificationCenter];
    2.22  		if (![growlNotificationCenterConnection registerName:@"GrowlNotificationCenter"])
    2.23  			NSLog(@"WARNING: could not register GrowlNotificationCenter for interprocess access");
    2.24 -
    2.25 -		soundCompletionCallback = NewSystemSoundCompletionUPP(soundCompletionCallbackProc);
    2.26  	}
    2.27  
    2.28  	return self;
    2.29 @@ -308,8 +307,6 @@
    2.30  
    2.31  	cdsaShutdown();
    2.32  	
    2.33 -	DisposeSystemSoundCompletionUPP(soundCompletionCallback);
    2.34 -
    2.35  	[super destroy];
    2.36  }
    2.37  
    2.38 @@ -545,6 +542,19 @@
    2.39  
    2.40  	return err;
    2.41  }
    2.42 +- (OSStatus) getURL:(out NSURL **)outURL forSoundNamed:(NSString *)soundName {
    2.43 +	FSRef ref;
    2.44 +	OSStatus err = [self getFSRef:&ref forSoundNamed:soundName];
    2.45 +	if (err == noErr) {
    2.46 +		CFURLRef CFURL = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref);
    2.47 +		NSURL *URL = [NSMakeCollectable(CFURL) autorelease];
    2.48 +		if (outURL != NULL)
    2.49 +			*outURL = URL;
    2.50 +		if (!URL)
    2.51 +			err = errFSBadFSRef; //For lack of any more specific knowledge.
    2.52 +	}
    2.53 +	return err;
    2.54 +}
    2.55  
    2.56  #pragma mark Dispatching notifications
    2.57  
    2.58 @@ -677,14 +687,19 @@
    2.59  			NSError *error = nil;
    2.60  			NSDictionary *userInfo;
    2.61  
    2.62 -			FSRef soundRef;
    2.63 -			OSStatus err = [self getFSRef:&soundRef forSoundNamed:soundName];
    2.64 +			NSURL *soundURL;
    2.65 +			OSStatus err = [self getURL:&soundURL forSoundNamed:soundName];
    2.66  			if (err == noErr) {
    2.67 -				SystemSoundActionID actionID;
    2.68 -				err = SystemSoundGetActionID(&soundRef, &actionID);
    2.69 -				if (err == noErr) {
    2.70 -					err = SystemSoundSetCompletionRoutine(actionID, CFRunLoopGetCurrent(), /*runLoopMode*/ NULL, soundCompletionCallback, /*refcon*/ NULL);
    2.71 -					SystemSoundPlay(actionID);
    2.72 +				SystemSoundID soundID;
    2.73 +				err = AudioServicesCreateSystemSoundID((CFURLRef)soundURL, &soundID);
    2.74 +				if (err == kAudioServicesNoError) {
    2.75 +					err = AudioServicesAddSystemSoundCompletion(soundID, CFRunLoopGetCurrent(), /*runLoopMode*/ NULL, soundCompletionCallbackProc, /*refcon*/ NULL);
    2.76 +
    2.77 +					//GCH ticket #70: Since the user set up this sound, we should play it regardless of the system's UI-sounds preference.
    2.78 +					UInt32 shouldBeSubjectToUISoundsPref = false;
    2.79 +					err = AudioServicesSetProperty(kAudioServicesPropertyIsUISound, sizeof(soundID), &soundID, sizeof(shouldBeSubjectToUISoundsPref), &shouldBeSubjectToUISoundsPref);
    2.80 +
    2.81 +					AudioServicesPlaySystemSound(soundID);
    2.82  					userInfo = nil;
    2.83  				} else {
    2.84  					userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
    2.85 @@ -1279,11 +1294,11 @@
    2.86  
    2.87  @end
    2.88  
    2.89 -static OSStatus soundCompletionCallbackProc(SystemSoundActionID actionID, void *refcon) 
    2.90 +static void soundCompletionCallbackProc(SystemSoundID soundID, void *refcon) 
    2.91  {
    2.92  #pragma unused(refcon)
    2.93  
    2.94 -	SystemSoundRemoveCompletionRoutine(actionID);
    2.95 -
    2.96 -	return SystemSoundRemoveActionID(actionID);
    2.97 -}
    2.98 +	AudioServicesRemoveSystemSoundCompletion(soundID);
    2.99 +
   2.100 +	AudioServicesDisposeSystemSoundID(soundID);
   2.101 +}
     3.1 --- a/Growl.xcodeproj/project.pbxproj	Sat Jan 01 12:37:10 2011 -0800
     3.2 +++ b/Growl.xcodeproj/project.pbxproj	Sat Jan 01 13:12:53 2011 -0800
     3.3 @@ -96,6 +96,7 @@
     3.4  		0A7F62600767C84E00E1C1E4 /* GrowlMusicVideoWindowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A7F62570767C84E00E1C1E4 /* GrowlMusicVideoWindowView.m */; };
     3.5  		0AEE179D0702C4960024B1A0 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AEE179C0702C4960024B1A0 /* ApplicationServices.framework */; };
     3.6  		31340CDD0D5B8E7100B9BEE0 /* GrowlPropertyListFilePathway.m in Sources */ = {isa = PBXBuildFile; fileRef = 31340CDB0D5B8E7100B9BEE0 /* GrowlPropertyListFilePathway.m */; };
     3.7 +		317ED5CC12CFCB7F00263CFC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 317ED5CB12CFCB7F00263CFC /* AudioToolbox.framework */; };
     3.8  		318984C5108825F10086E973 /* TestVersionUnparsing.m in Sources */ = {isa = PBXBuildFile; fileRef = 318984C4108825F10086E973 /* TestVersionUnparsing.m */; };
     3.9  		31B9BA5C1086C4CA007DA1E2 /* TestVersionComparisonBetweenStringsConverting1_0To0_5.m in Sources */ = {isa = PBXBuildFile; fileRef = 31B9BA5B1086C4CA007DA1E2 /* TestVersionComparisonBetweenStringsConverting1_0To0_5.m */; };
    3.10  		31C7594B1047202B008547BF /* simple-mailer.py in Resources */ = {isa = PBXBuildFile; fileRef = 31C7594A1047202B008547BF /* simple-mailer.py */; };
    3.11 @@ -697,6 +698,7 @@
    3.12  		31340CDA0D5B8E7100B9BEE0 /* GrowlPropertyListFilePathway.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GrowlPropertyListFilePathway.h; path = Core/Source/GrowlPropertyListFilePathway.h; sourceTree = "<group>"; };
    3.13  		31340CDB0D5B8E7100B9BEE0 /* GrowlPropertyListFilePathway.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GrowlPropertyListFilePathway.m; path = Core/Source/GrowlPropertyListFilePathway.m; sourceTree = "<group>"; };
    3.14  		315C88BB1068F9A200880530 /* Localization.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Localization.xcconfig; path = xcconfig/Localization.xcconfig; sourceTree = "<group>"; };
    3.15 +		317ED5CB12CFCB7F00263CFC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
    3.16  		318984C3108825F10086E973 /* TestVersionUnparsing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestVersionUnparsing.h; sourceTree = "<group>"; };
    3.17  		318984C4108825F10086E973 /* TestVersionUnparsing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestVersionUnparsing.m; sourceTree = "<group>"; };
    3.18  		31B9BA5A1086C4CA007DA1E2 /* TestVersionComparisonBetweenStringsConverting1_0To0_5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestVersionComparisonBetweenStringsConverting1_0To0_5.h; sourceTree = "<group>"; };
    3.19 @@ -1312,6 +1314,7 @@
    3.20  				95C36A640753299E009FAEA2 /* AppKit.framework in Frameworks */,
    3.21  				95AA8654080065DE0045589D /* SystemConfiguration.framework in Frameworks */,
    3.22  				93CD92E80B5AFAAE000C39CD /* QuartzCore.framework in Frameworks */,
    3.23 +				317ED5CC12CFCB7F00263CFC /* AudioToolbox.framework in Frameworks */,
    3.24  			);
    3.25  			runOnlyForDeploymentPostprocessing = 0;
    3.26  		};
    3.27 @@ -1694,6 +1697,7 @@
    3.28  				343354B20792F84B00C84B15 /* Carbon.framework */,
    3.29  				93FCE57D0812D93B00320D8E /* SystemUIPlugin.framework */,
    3.30  				31E184DF108462F30011C78B /* SenTestingKit.framework */,
    3.31 +				317ED5CB12CFCB7F00263CFC /* AudioToolbox.framework */,
    3.32  			);
    3.33  			name = "Linked Frameworks";
    3.34  			sourceTree = "<group>";