Ryan Brignoni: Updating AppleRemote with latest files from VideoLAN repo and adding support for new 2009 Apple remote buttons in Cog.

CQTexperiment
Chris Moeller 2013-10-12 14:47:39 -07:00
parent 505d145f94
commit e87fd1b4b7
3 changed files with 195 additions and 229 deletions

View File

@ -129,6 +129,7 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
{ {
switch( buttonIdentifier ) switch( buttonIdentifier )
{ {
case k2009RemoteButtonPlay:
case kRemoteButtonPlay: case kRemoteButtonPlay:
[self clickPlay]; [self clickPlay];
@ -160,6 +161,9 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
break; break;
case kRemoteButtonMenu: case kRemoteButtonMenu:
break; break;
case k2009RemoteButtonFullscreen:
[mainWindow toggleFullScreen:nil];
break;
default: default:
/* Add here whatever you want other buttons to do */ /* Add here whatever you want other buttons to do */
break; break;

View File

@ -1,12 +1,12 @@
/***************************************************************************** /*****************************************************************************
* AppleRemote.h * AppleRemote.h
* AppleRemote * AppleRemote
* $Id: AppleRemote.h 18683 2007-02-02 09:12:37Z fkuehne $ * $Id$
* *
* Created by Martin Kahr on 11.03.06 under a MIT-style license. * Created by Martin Kahr on 11.03.06 under a MIT-style license.
* Copyright (c) 2006 martinkahr.com. All rights reserved. * Copyright (c) 2006 martinkahr.com. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation * to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * the rights to use, copy, modify, merge, publish, distribute, sublicense,
@ -18,7 +18,7 @@
* *
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
@ -29,10 +29,10 @@
* Note that changes made by any members or contributors of the VideoLAN team * Note that changes made by any members or contributors of the VideoLAN team
* (i.e. changes that were checked in exclusively into one of VideoLAN's source code * (i.e. changes that were checked in exclusively into one of VideoLAN's source code
* repositories) are licensed under the GNU General Public License version 2, * repositories) are licensed under the GNU General Public License version 2,
* or (at your option) any later version. * or (at your option) any later version.
* Thus, the following statements apply to our changes: * Thus, the following statements apply to our changes:
* *
* Copyright (C) 2006-2007 the VideoLAN team * Copyright (C) 2006-2007 VLC authors and VideoLAN
* Authors: Eric Petit <titer@m0k.org> * Authors: Eric Petit <titer@m0k.org>
* Felix Kühne <fkuehne at videolan dot org> * Felix Kühne <fkuehne at videolan dot org>
* *
@ -73,7 +73,9 @@ enum AppleRemoteEventIdentifier
kRemoteButtonPlay_Sleep =1<<10, kRemoteButtonPlay_Sleep =1<<10,
kRemoteControl_Switched =1<<11, kRemoteControl_Switched =1<<11,
kRemoteButtonVolume_Plus_Hold =1<<12, kRemoteButtonVolume_Plus_Hold =1<<12,
kRemoteButtonVolume_Minus_Hold =1<<13 kRemoteButtonVolume_Minus_Hold =1<<13,
k2009RemoteButtonPlay =1<<14,
k2009RemoteButtonFullscreen =1<<15
}; };
typedef enum AppleRemoteEventIdentifier AppleRemoteEventIdentifier; typedef enum AppleRemoteEventIdentifier AppleRemoteEventIdentifier;
@ -84,37 +86,34 @@ The class is not thread safe
@interface AppleRemote : NSObject { @interface AppleRemote : NSObject {
IOHIDDeviceInterface** hidDeviceInterface; IOHIDDeviceInterface** hidDeviceInterface;
IOHIDQueueInterface** queue; IOHIDQueueInterface** queue;
NSMutableArray* allCookies; NSArray* _allCookies;
NSMutableDictionary* cookieToButtonMapping; NSDictionary* _cookieToButtonMapping;
CFRunLoopSourceRef eventSource;
BOOL openInExclusiveMode;
BOOL simulatePlusMinusHold; BOOL _openInExclusiveMode;
BOOL processesBacklog; BOOL _simulatePlusMinusHold;
BOOL _processesBacklog;
/* state for simulating plus/minus hold */ /* state for simulating plus/minus hold */
BOOL lastEventSimulatedHold; BOOL lastEventSimulatedHold;
AppleRemoteEventIdentifier lastPlusMinusEvent; AppleRemoteEventIdentifier lastPlusMinusEvent;
NSTimeInterval lastPlusMinusEventTime; NSTimeInterval lastPlusMinusEventTime;
int remoteId; int remoteId;
unsigned int clickCountEnabledButtons; unsigned int _clickCountEnabledButtons;
NSTimeInterval maxClickTimeDifference; NSTimeInterval _maxClickTimeDifference;
NSTimeInterval lastClickCountEventTime; NSTimeInterval lastClickCountEventTime;
AppleRemoteEventIdentifier lastClickCountEvent; AppleRemoteEventIdentifier lastClickCountEvent;
unsigned int eventClickCount; unsigned int eventClickCount;
IBOutlet id delegate; id delegate;
} }
+ (AppleRemote *)sharedInstance;
- (int) remoteId; @property (readonly) int remoteId;
@property (readonly) BOOL remoteAvailable;
- (BOOL) isRemoteAvailable; @property (readwrite) BOOL listeningToRemote;
@property (readwrite) BOOL openInExclusiveMode;
- (BOOL) isListeningToRemote;
- (void) setListeningToRemote: (BOOL) value;
- (BOOL) isOpenInExclusiveMode;
- (void) setOpenInExclusiveMode: (BOOL) value;
/* click counting makes it possible to recognize if the user has pressed a button repeatedly /* click counting makes it possible to recognize if the user has pressed a button repeatedly
* click counting does delay each event as it has to wait if there is another event (second click) * click counting does delay each event as it has to wait if there is another event (second click)
@ -122,38 +121,31 @@ The class is not thread safe
* of the user and the call of your delegate method * of the user and the call of your delegate method
* click counting can be enabled individually for specific buttons. Use the property clickCountEnableButtons * click counting can be enabled individually for specific buttons. Use the property clickCountEnableButtons
* to set the buttons for which click counting shall be enabled */ * to set the buttons for which click counting shall be enabled */
- (BOOL) clickCountingEnabled; @property (readwrite) BOOL clickCountingEnabled;
- (void) setClickCountingEnabled: (BOOL) value;
- (unsigned int) clickCountEnabledButtons; @property (readwrite) unsigned int clickCountEnabledButtons;
- (void) setClickCountEnabledButtons: (unsigned int)value;
/* the maximum time difference till which clicks are recognized as multi clicks */ /* the maximum time difference till which clicks are recognized as multi clicks */
- (NSTimeInterval) maximumClickCountTimeDifference; @property (readwrite) NSTimeInterval maximumClickCountTimeDifference;
- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff;
/* When your application needs to much time on the main thread when processing an event other events /* When your application needs to much time on the main thread when processing an event other events
* may already be received which are put on a backlog. As soon as your main thread * may already be received which are put on a backlog. As soon as your main thread
* has some spare time this backlog is processed and may flood your delegate with calls. * has some spare time this backlog is processed and may flood your delegate with calls.
* Backlog processing is turned off by default. */ * Backlog processing is turned off by default. */
- (BOOL) processesBacklog; @property (readwrite) BOOL processesBacklog;
- (void) setProcessesBacklog: (BOOL) value;
/* Sets an NSApplication delegate which starts listening when application is becoming active /* Sets an NSApplication delegate which starts listening when application is becoming active
* and stops listening when application resigns being active. * and stops listening when application resigns being active.
* If an NSApplication delegate has been already set all method calls will be forwarded to this delegate, too. */ * If an NSApplication delegate has been already set all method calls will be forwarded to this delegate, too. */
- (BOOL) listeningOnAppActivate; @property (readwrite) BOOL listeningOnAppActivate;
- (void) setListeningOnAppActivate: (BOOL) value;
/* Simulating plus/minus hold does deactivate sending of individual requests for plus/minus pressed down/released. /* Simulating plus/minus hold does deactivate sending of individual requests for plus/minus pressed down/released.
* Instead special hold events are being triggered when the user is pressing and holding plus/minus for a small period. * Instead special hold events are being triggered when the user is pressing and holding plus/minus for a small period.
* With simulating enabled the plus/minus buttons do behave as the left/right buttons */ * With simulating enabled the plus/minus buttons do behave as the left/right buttons */
- (BOOL) simulatesPlusMinusHold; @property (readwrite) BOOL simulatesPlusMinusHold;
- (void) setSimulatesPlusMinusHold: (BOOL) value;
/* Delegates are not retained */ /* Delegates are not retained */
- (void) setDelegate: (id) delegate; @property (readwrite, assign) id delegate;
- (id) delegate;
- (IBAction) startListening: (id) sender; - (IBAction) startListening: (id) sender;
- (IBAction) stopListening: (id) sender; - (IBAction) stopListening: (id) sender;
@ -172,15 +164,16 @@ The class is not thread safe
@end @end
@interface AppleRemote (PrivateMethods) @interface AppleRemote (PrivateMethods)
@property (readonly) NSDictionary * cookieToButtonMapping;
- (void) setRemoteId: (int) aValue; - (void) setRemoteId: (int) aValue;
- (NSDictionary*) cookieToButtonMapping;
- (IOHIDQueueInterface**) queue; - (IOHIDQueueInterface**) queue;
- (IOHIDDeviceInterface**) hidDeviceInterface; - (IOHIDDeviceInterface**) hidDeviceInterface;
- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; - (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues;
@end @end
@interface AppleRemote (IOKitMethods) @interface AppleRemote (IOKitMethods)
- (io_object_t) findAppleRemoteDevice; - (io_object_t) findAppleRemoteDevice;
- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice; - (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice;
- (BOOL) initializeCookies; - (BOOL) initializeCookies;

View File

@ -3,10 +3,10 @@
* AppleRemote * AppleRemote
* $Id: AppleRemote.m 18683 2007-02-02 09:12:37Z fkuehne $ * $Id: AppleRemote.m 18683 2007-02-02 09:12:37Z fkuehne $
* *
* Created by Martin Kahr on 11.03.06 under a MIT-style license. * Created by Martin Kahr on 11.03.06 under a MIT-style license.
* Copyright (c) 2006 martinkahr.com. All rights reserved. * Copyright (c) 2006 martinkahr.com. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation * to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * the rights to use, copy, modify, merge, publish, distribute, sublicense,
@ -18,7 +18,7 @@
* *
* THE SOFTWARE IS PROVIDEDAS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDEDAS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
@ -29,10 +29,10 @@
* Note that changes made by any members or contributors of the VideoLAN team * Note that changes made by any members or contributors of the VideoLAN team
* (i.e. changes that were exclusively checked in to one of VideoLAN's source code * (i.e. changes that were exclusively checked in to one of VideoLAN's source code
* repositories) are licensed under the GNU General Public License version 2, * repositories) are licensed under the GNU General Public License version 2,
* or (at your option) any later version. * or (at your option) any later version.
* Thus, the following statements apply to our changes: * Thus, the following statements apply to our changes:
* *
* Copyright (C) 2006-2007 the VideoLAN team * Copyright (C) 2006-2009 VLC authors and VideoLAN
* Authors: Eric Petit <titer@m0k.org> * Authors: Eric Petit <titer@m0k.org>
* Felix Kühne <fkuehne at videolan dot org> * Felix Kühne <fkuehne at videolan dot org>
* *
@ -62,89 +62,81 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
@implementation AppleRemote @implementation AppleRemote
@synthesize openInExclusiveMode = _openInExclusiveMode, clickCountEnabledButtons = _clickCountEnabledButtons, maximumClickCountTimeDifference = _maxClickTimeDifference, processesBacklog=_processesBacklog, simulatesPlusMinusHold = _simulatePlusMinusHold;
#pragma public interface #pragma public interface
#ifndef NSAppKitVersionNumber10_4 static AppleRemote *_o_sharedInstance = nil;
#define NSAppKitVersionNumber10_4 824
#endif
- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping { + (AppleRemote *)sharedInstance
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) { {
// 10.4.x Tiger return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"14_12_11_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Minus] forKey:@"14_13_11_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"14_7_6_14_7_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"14_8_6_14_8_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"14_9_6_14_9_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"14_10_6_14_10_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"14_6_4_2_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_2_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"18_14_6_18_14_6_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
} else {
// 10.5.x Leopard
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"31_29_28_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Minus] forKey:@"31_30_28_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"31_20_19_18_31_20_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"31_21_19_18_31_21_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"31_22_19_18_31_22_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"31_23_19_18_31_23_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"31_19_18_4_2_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"31_19_18_3_2_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"31_19_18_31_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"35_31_19_18_35_31_19_18_"];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
}
} }
- (id) init { - (id)init
if ( self = [super init] ) { {
openInExclusiveMode = YES; if (_o_sharedInstance) {
[self dealloc];
} else {
_o_sharedInstance = [super init];
_openInExclusiveMode = YES;
queue = NULL; queue = NULL;
hidDeviceInterface = NULL; hidDeviceInterface = NULL;
cookieToButtonMapping = [[NSMutableDictionary alloc] init]; NSMutableDictionary * mutableCookieToButtonMapping = [[NSMutableDictionary alloc] init];
[self setCookieMappingInDictionary:cookieToButtonMapping];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonVolume_Plus) forKey:@"33_31_30_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonVolume_Minus) forKey:@"33_32_30_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonMenu) forKey:@"33_22_21_20_2_33_22_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonPlay) forKey:@"33_23_21_20_2_33_23_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonRight) forKey:@"33_24_21_20_2_33_24_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonLeft) forKey:@"33_25_21_20_2_33_25_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonRight_Hold) forKey:@"33_21_20_14_12_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonLeft_Hold) forKey:@"33_21_20_13_12_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonMenu_Hold) forKey:@"33_21_20_2_33_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(kRemoteButtonPlay_Sleep) forKey:@"37_33_21_20_2_37_33_21_20_2_"];
[mutableCookieToButtonMapping setObject:@(k2009RemoteButtonPlay) forKey:@"33_21_20_8_2_33_21_20_8_2_"];
[mutableCookieToButtonMapping setObject:@(k2009RemoteButtonFullscreen) forKey:@"33_21_20_3_2_33_21_20_3_2_"];
if( floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
/* 10.6.2+ Snow Leopard cookies */
[mutableCookieToButtonMapping setObject:@(kRemoteControl_Switched) forKey:@"19_"];
else
/* Lion cookies */
[mutableCookieToButtonMapping setObject:@(kRemoteControl_Switched) forKey:@"42_33_23_21_20_2_33_23_21_20_2_"];
_cookieToButtonMapping = [[NSDictionary alloc] initWithDictionary: mutableCookieToButtonMapping];
[mutableCookieToButtonMapping release];
/* defaults */ /* defaults */
[self setSimulatesPlusMinusHold: YES]; _simulatePlusMinusHold = YES;
maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE; _maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE;
} }
return self; return _o_sharedInstance;
} }
- (void) dealloc { - (void) dealloc {
[self stopListening:self]; [self stopListening:self];
[cookieToButtonMapping release]; [_cookieToButtonMapping release];
[super dealloc]; [super dealloc];
} }
/* this was added by the VideoLAN team to ensure Leopard-compatibility and is VLC-only */
#if GC_ENABLED
- (void)finalize
{
[self stopListening: self];
[super finalize];
}
#endif
- (int) remoteId { - (int) remoteId {
return remoteId; return remoteId;
} }
- (BOOL) isRemoteAvailable { - (BOOL) remoteAvailable {
io_object_t hidDevice = [self findAppleRemoteDevice]; io_object_t hidDevice = [self findAppleRemoteDevice];
if (hidDevice != 0) { if (hidDevice != 0) {
IOObjectRelease(hidDevice); IOObjectRelease(hidDevice);
return YES; return YES;
} else { } else {
return NO; return NO;
} }
} }
- (BOOL) isListeningToRemote { - (BOOL) listeningToRemote {
return (hidDeviceInterface != NULL && allCookies != NULL && queue != NULL); return (hidDeviceInterface != NULL && _allCookies != NULL && queue != NULL);
} }
- (void) setListeningToRemote: (BOOL) value { - (void) setListeningToRemote: (BOOL) value {
@ -157,7 +149,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
/* Delegates are not retained! /* Delegates are not retained!
* http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html * http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html
* Delegating objects do not (and should not) retain their delegates. * Delegating objects do not (and should not) retain their delegates.
* However, clients of delegating objects (applications, usually) are responsible for ensuring that their delegates are around * However, clients of delegating objects (applications, usually) are responsible for ensuring that their delegates are around
* to receive delegation messages. To do this, they may have to retain the delegate. */ * to receive delegation messages. To do this, they may have to retain the delegate. */
- (void) setDelegate: (id) _delegate { - (void) setDelegate: (id) _delegate {
@ -169,45 +161,17 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
return delegate; return delegate;
} }
- (BOOL) isOpenInExclusiveMode {
return openInExclusiveMode;
}
- (void) setOpenInExclusiveMode: (BOOL) value {
openInExclusiveMode = value;
}
- (BOOL) clickCountingEnabled { - (BOOL) clickCountingEnabled {
return clickCountEnabledButtons != 0; return self.clickCountEnabledButtons != 0;
} }
- (void) setClickCountingEnabled: (BOOL) value { - (void) setClickCountingEnabled: (BOOL) value {
if (value) { if (value) {
[self setClickCountEnabledButtons: kRemoteButtonVolume_Plus | kRemoteButtonVolume_Minus | kRemoteButtonPlay | kRemoteButtonLeft | kRemoteButtonRight | kRemoteButtonMenu]; [self setClickCountEnabledButtons: kRemoteButtonVolume_Plus | kRemoteButtonVolume_Minus | kRemoteButtonPlay | kRemoteButtonLeft | kRemoteButtonRight | kRemoteButtonMenu | k2009RemoteButtonPlay | k2009RemoteButtonFullscreen];
} else { } else {
[self setClickCountEnabledButtons: 0]; [self setClickCountEnabledButtons: 0];
} }
} }
- (unsigned int) clickCountEnabledButtons {
return clickCountEnabledButtons;
}
- (void) setClickCountEnabledButtons: (unsigned int)value {
clickCountEnabledButtons = value;
}
- (NSTimeInterval) maximumClickCountTimeDifference {
return maxClickTimeDifference;
}
- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff {
maxClickTimeDifference = timeDiff;
}
- (BOOL) processesBacklog {
return processesBacklog;
}
- (void) setProcessesBacklog: (BOOL) value {
processesBacklog = value;
}
- (BOOL) listeningOnAppActivate { - (BOOL) listeningOnAppActivate {
id appDelegate = [NSApp delegate]; id appDelegate = [NSApp delegate];
return (appDelegate!=nil && [appDelegate isKindOfClass: [AppleRemoteApplicationDelegate class]]); return (appDelegate!=nil && [appDelegate isKindOfClass: [AppleRemoteApplicationDelegate class]]);
@ -227,15 +191,8 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
} }
} }
- (BOOL) simulatesPlusMinusHold { - (IBAction) startListening: (id) sender {
return simulatePlusMinusHold; if ([self listeningToRemote]) return;
}
- (void) setSimulatesPlusMinusHold: (BOOL) value {
simulatePlusMinusHold = value;
}
- (IBAction) startListening: (id) sender {
if ([self isListeningToRemote]) return;
io_object_t hidDevice = [self findAppleRemoteDevice]; io_object_t hidDevice = [self findAppleRemoteDevice];
if (hidDevice == 0) return; if (hidDevice == 0) return;
@ -253,49 +210,54 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
} }
goto cleanup; goto cleanup;
error: error:
[self stopListening:self]; [self stopListening:self];
cleanup: cleanup:
IOObjectRelease(hidDevice); IOObjectRelease(hidDevice);
} }
- (IBAction) stopListening: (id) sender { - (IBAction) stopListening: (id) sender {
if (eventSource != NULL) {
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode);
CFRelease(eventSource);
eventSource = NULL;
}
if (queue != NULL) { if (queue != NULL) {
(*queue)->stop(queue); (*queue)->stop(queue);
//dispose of queue //dispose of queue
(*queue)->dispose(queue); (*queue)->dispose(queue);
//release the queue we allocated //release the queue we allocated
(*queue)->Release(queue); (*queue)->Release(queue);
queue = NULL; queue = NULL;
} }
if (allCookies != nil) { if (_allCookies != nil) {
[allCookies autorelease]; [_allCookies autorelease];
allCookies = nil; _allCookies = nil;
} }
if (hidDeviceInterface != NULL) { if (hidDeviceInterface != NULL) {
//close the device //close the device
(*hidDeviceInterface)->close(hidDeviceInterface); (*hidDeviceInterface)->close(hidDeviceInterface);
//release the interface //release the interface
(*hidDeviceInterface)->Release(hidDeviceInterface); (*hidDeviceInterface)->Release(hidDeviceInterface);
hidDeviceInterface = NULL; hidDeviceInterface = NULL;
} }
} }
@end @end
@implementation AppleRemote (Singleton) @implementation AppleRemote (Singleton)
static AppleRemote* sharedInstance=nil; static AppleRemote* sharedInstance=nil;
+ (AppleRemote*) sharedRemote { + (AppleRemote*) sharedRemote {
@synchronized(self) { @synchronized(self) {
if (sharedInstance == nil) { if (sharedInstance == nil) {
sharedInstance = [[self alloc] init]; sharedInstance = [[self alloc] init];
@ -308,7 +270,7 @@ static AppleRemote* sharedInstance=nil;
if (sharedInstance == nil) { if (sharedInstance == nil) {
return [super allocWithZone:zone]; return [super allocWithZone:zone];
} }
} }
return sharedInstance; return sharedInstance;
} }
- (id)copyWithZone:(NSZone *)zone { - (id)copyWithZone:(NSZone *)zone {
@ -317,7 +279,7 @@ static AppleRemote* sharedInstance=nil;
- (id)retain { - (id)retain {
return self; return self;
} }
- (unsigned)retainCount { - (NSUInteger)retainCount {
return UINT_MAX; //denotes an object that cannot be released return UINT_MAX; //denotes an object that cannot be released
} }
- (void)release { - (void)release {
@ -329,7 +291,7 @@ static AppleRemote* sharedInstance=nil;
@end @end
@implementation AppleRemote (PrivateMethods) @implementation AppleRemote (PrivateMethods)
- (void) setRemoteId: (int) value { - (void) setRemoteId: (int) value {
remoteId = value; remoteId = value;
@ -343,16 +305,17 @@ static AppleRemote* sharedInstance=nil;
return hidDeviceInterface; return hidDeviceInterface;
} }
- (NSDictionary*) cookieToButtonMapping { - (NSDictionary*) cookieToButtonMapping {
return cookieToButtonMapping; return _cookieToButtonMapping;
} }
- (NSString*) validCookieSubstring: (NSString*) cookieString { - (NSString*) validCookieSubstring: (NSString*) cookieString {
if (cookieString == nil || [cookieString length] == 0) return nil; if (cookieString == nil || [cookieString length] == 0) return nil;
for (NSString *key in [[self cookieToButtonMapping] allKeys]) { NSEnumerator* keyEnum = [[self cookieToButtonMapping] keyEnumerator];
NSString* key;
while((key = [keyEnum nextObject])) {
NSRange range = [cookieString rangeOfString:key]; NSRange range = [cookieString rangeOfString:key];
if (range.location == 0) return key; if (range.location == 0) return key;
} }
return nil; return nil;
} }
@ -372,13 +335,13 @@ static AppleRemote* sharedInstance=nil;
- (void) sendRemoteButtonEvent: (AppleRemoteEventIdentifier) event pressedDown: (BOOL) pressedDown { - (void) sendRemoteButtonEvent: (AppleRemoteEventIdentifier) event pressedDown: (BOOL) pressedDown {
if (delegate) { if (delegate) {
if (simulatePlusMinusHold) { if (self.simulatesPlusMinusHold) {
if (event == kRemoteButtonVolume_Plus || event == kRemoteButtonVolume_Minus) { if (event == kRemoteButtonVolume_Plus || event == kRemoteButtonVolume_Minus) {
if (pressedDown) { if (pressedDown) {
lastPlusMinusEvent = event; lastPlusMinusEvent = event;
lastPlusMinusEventTime = [NSDate timeIntervalSinceReferenceDate]; lastPlusMinusEventTime = [NSDate timeIntervalSinceReferenceDate];
[self performSelector:@selector(sendSimulatedPlusMinusEvent:) [self performSelector:@selector(sendSimulatedPlusMinusEvent:)
withObject:[NSNumber numberWithDouble:lastPlusMinusEventTime] withObject:@(lastPlusMinusEventTime)
afterDelay:HOLD_RECOGNITION_TIME_INTERVAL]; afterDelay:HOLD_RECOGNITION_TIME_INTERVAL];
return; return;
} else { } else {
@ -396,7 +359,7 @@ static AppleRemote* sharedInstance=nil;
} }
} }
if (([self clickCountEnabledButtons] & event) == event) { if ((self.clickCountEnabledButtons & event) == event) {
if (pressedDown==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) { if (pressedDown==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) {
return; // this one is triggered automatically by the handler return; // this one is triggered automatically by the handler
} }
@ -410,32 +373,32 @@ static AppleRemote* sharedInstance=nil;
eventClickCount = 1; eventClickCount = 1;
} }
lastClickCountEvent = event; lastClickCountEvent = event;
timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime]; timeNumber = @(lastClickCountEventTime);
eventNumber= [NSNumber numberWithUnsignedInt:event]; eventNumber= @(event);
} }
[self performSelector: @selector(executeClickCountEvent:) [self performSelector: @selector(executeClickCountEvent:)
withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil] withObject: @[eventNumber, timeNumber]
afterDelay: maxClickTimeDifference]; afterDelay: _maxClickTimeDifference];
} else { } else {
[delegate appleRemoteButton:event pressedDown: pressedDown clickCount:1]; [delegate appleRemoteButton:event pressedDown: pressedDown clickCount:1];
} }
} }
} }
- (void) executeClickCountEvent: (NSArray*) values { - (void) executeClickCountEvent: (NSArray*) values {
AppleRemoteEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue]; AppleRemoteEventIdentifier event = [[values objectAtIndex:0] unsignedIntValue];
NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue]; NSTimeInterval eventTimePoint = [[values objectAtIndex:1] doubleValue];
BOOL finishedClicking = NO; BOOL finishedClicking = NO;
int finalClickCount = eventClickCount; int finalClickCount = eventClickCount;
@synchronized(self) { @synchronized(self) {
finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime); finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime);
if (finishedClicking) eventClickCount = 0; if (finishedClicking) eventClickCount = 0;
} }
if (finishedClicking) { if (finishedClicking) {
[delegate appleRemoteButton:event pressedDown: YES clickCount:finalClickCount]; [delegate appleRemoteButton:event pressedDown: YES clickCount:finalClickCount];
if ([self simulatesPlusMinusHold]==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) { if ([self simulatesPlusMinusHold]==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) {
// trigger a button release event, too // trigger a button release event, too
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]]; [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]];
@ -449,8 +412,8 @@ static AppleRemote* sharedInstance=nil;
/* /*
if (previousRemainingCookieString) { if (previousRemainingCookieString) {
cookieString = [previousRemainingCookieString stringByAppendingString: cookieString]; cookieString = [previousRemainingCookieString stringByAppendingString: cookieString];
DLog(@"New cookie string is %@", cookieString); NSLog(@"New cookie string is %@", cookieString);
[previousRemainingCookieString release], previousRemainingCookieString=nil; [previousRemainingCookieString release], previousRemainingCookieString=nil;
}*/ }*/
if (cookieString == nil || [cookieString length] == 0) return; if (cookieString == nil || [cookieString length] == 0) return;
NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString]; NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString];
@ -464,18 +427,18 @@ static AppleRemote* sharedInstance=nil;
while((subCookieString = [self validCookieSubstring: cookieString])) { while((subCookieString = [self validCookieSubstring: cookieString])) {
cookieString = [cookieString substringFromIndex: [subCookieString length]]; cookieString = [cookieString substringFromIndex: [subCookieString length]];
lastSubCookieString = subCookieString; lastSubCookieString = subCookieString;
if (processesBacklog) [self handleEventWithCookieString: subCookieString sumOfValues:sumOfValues]; if (self.processesBacklog) [self handleEventWithCookieString: subCookieString sumOfValues:sumOfValues];
} }
if (processesBacklog == NO && lastSubCookieString != nil) { if (self.processesBacklog == NO && lastSubCookieString != nil) {
// process the last event of the backlog and assume that the button is not pressed down any longer. // process the last event of the backlog and assume that the button is not pressed down any longer.
// The events in the backlog do not seem to be in order and therefore (in rare cases) the last event might be // The events in the backlog do not seem to be in order and therefore (in rare cases) the last event might be
// a button pressed down event while in reality the user has released it. // a button pressed down event while in reality the user has released it.
// DLog(@"processing last event of backlog"); // NSLog(@"processing last event of backlog");
[self handleEventWithCookieString: lastSubCookieString sumOfValues:0]; [self handleEventWithCookieString: lastSubCookieString sumOfValues:0];
} }
if ([cookieString length] > 0) { if ([cookieString length] > 0) {
ALog(@"Unknown button for cookiestring %@", cookieString); ALog(@"Unknown button for cookiestring %s", [cookieString UTF8String]);
} }
} }
} }
@ -484,28 +447,33 @@ static AppleRemote* sharedInstance=nil;
/* Callback method for the device queue /* Callback method for the device queue
Will be called for any event of any type (cookie) to which we subscribe Will be called for any event of any type (cookie) to which we subscribe
*/ */
static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, void* sender) { static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, void* sender) {
AppleRemote* remote = (AppleRemote*)target; AppleRemote* remote = (AppleRemote*)target;
IOHIDEventStruct event; IOHIDEventStruct event;
AbsoluteTime zeroTime = {0,0}; AbsoluteTime zeroTime = {0,0};
NSMutableString* cookieString = [NSMutableString string]; NSMutableString* cookieString = [NSMutableString string];
SInt32 sumOfValues = 0; SInt32 sumOfValues = 0;
while (result == kIOReturnSuccess) while (result == kIOReturnSuccess)
{ {
result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0); result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0);
if ( result != kIOReturnSuccess ) if ( result != kIOReturnSuccess )
continue; continue;
//printf("%d %d %d\n", event.elementCookie, event.value, event.longValue); //printf("%d %d %d\n", event.elementCookie, event.value, event.longValue);
if (((int)event.elementCookie)!=5) { if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie) {
sumOfValues+=event.value; [remote setRemoteId: event.value];
[cookieString appendString:[NSString stringWithFormat:@"%u_", event.elementCookie]]; [remote handleEventWithCookieString: @"19_" sumOfValues: 0];
} } else {
if (((int)event.elementCookie)!=5) {
sumOfValues+=event.value;
[cookieString appendString:[NSString stringWithFormat:@"%d_", event.elementCookie]];
}
}
} }
[remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues]; [remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues];
} }
@implementation AppleRemote (IOKitMethods) @implementation AppleRemote (IOKitMethods)
@ -527,10 +495,10 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
} }
ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice,
kIOHIDDeviceUserClientTypeID, kIOHIDDeviceUserClientTypeID,
kIOCFPlugInInterfaceID, kIOCFPlugInInterfaceID,
&plugInInterface, &plugInInterface,
&score); &score);
if (ioReturnValue == kIOReturnSuccess) if (ioReturnValue == kIOReturnSuccess)
{ {
//Call a method of the intermediate plug-in to create the device interface //Call a method of the intermediate plug-in to create the device interface
@ -547,7 +515,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
- (io_object_t) findAppleRemoteDevice { - (io_object_t) findAppleRemoteDevice {
CFMutableDictionaryRef hidMatchDictionary = NULL; CFMutableDictionaryRef hidMatchDictionary = NULL;
IOReturn ioReturnValue = kIOReturnSuccess; IOReturn ioReturnValue = kIOReturnSuccess;
io_iterator_t hidObjectIterator = 0; io_iterator_t hidObjectIterator = 0;
io_object_t hidDevice = 0; io_object_t hidDevice = 0;
@ -574,7 +542,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
long usage; long usage;
long usagePage; long usagePage;
id object; id object;
NSArray* elements = nil; NSArray* elements;
NSDictionary* element; NSDictionary* element;
IOReturn success; IOReturn success;
@ -587,15 +555,13 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements);
if (success == kIOReturnSuccess) { if (success == kIOReturnSuccess) {
[elements autorelease];
/* /*
cookies = calloc(NUMBER_OF_APPLE_REMOTE_ACTIONS, sizeof(IOHIDElementCookie)); cookies = calloc(NUMBER_OF_APPLE_REMOTE_ACTIONS, sizeof(IOHIDElementCookie));
memset(cookies, 0, sizeof(IOHIDElementCookie) * NUMBER_OF_APPLE_REMOTE_ACTIONS); memset(cookies, 0, sizeof(IOHIDElementCookie) * NUMBER_OF_APPLE_REMOTE_ACTIONS);
*/ */
allCookies = [[NSMutableArray alloc] init]; NSMutableArray *mutableAllCookies = [[NSMutableArray alloc] init];
int i; NSUInteger elementCount = [elements count];
for (i=0; i< [elements count]; i++) { for (NSUInteger i=0; i< elementCount; i++) {
element = [elements objectAtIndex:i]; element = [elements objectAtIndex:i];
//Get cookie //Get cookie
@ -606,17 +572,22 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
//Get usage //Get usage
object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsageKey) ]; object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsageKey) ];
if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue;
usage = [object longValue]; usage = [object longValue];
//Get usage page //Get usage page
object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsagePageKey) ]; object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsagePageKey) ];
if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue;
usagePage = [object longValue]; usagePage = [object longValue];
[allCookies addObject: [NSNumber numberWithInt:(int)cookie]]; [mutableAllCookies addObject: @((int)cookie)];
} }
_allCookies = [[NSArray alloc] initWithArray: mutableAllCookies];
[mutableAllCookies release];
[elements release];
} else { } else {
if (elements)
[elements release];
return NO; return NO;
} }
@ -627,29 +598,28 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
HRESULT result; HRESULT result;
IOHIDOptionsType openMode = kIOHIDOptionsTypeNone; IOHIDOptionsType openMode = kIOHIDOptionsTypeNone;
if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; if ([self openInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice;
IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode); IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode);
if (ioReturnValue == KERN_SUCCESS) { if (ioReturnValue == KERN_SUCCESS) {
queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
if (queue) { if (queue) {
result = (*queue)->create(queue, 0, 12); //depth: maximum number of elements in queue before oldest elements in queue begin to be lost. result = (*queue)->create(queue, 0, 12); //depth: maximum number of elements in queue before oldest elements in queue begin to be lost.
int i=0; NSUInteger cookieCount = [_allCookies count];
for(i=0; i<[allCookies count]; i++) { for(NSUInteger i=0; i<cookieCount; i++) {
IOHIDElementCookie cookie = (IOHIDElementCookie)[[allCookies objectAtIndex:i] intValue]; IOHIDElementCookie cookie = (IOHIDElementCookie)[[_allCookies objectAtIndex:i] intValue];
(*queue)->addElement(queue, cookie, 0); (*queue)->addElement(queue, cookie, 0);
} }
// add callback for async events // add callback for async events
CFRunLoopSourceRef eventSource;
ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource); ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource);
if (ioReturnValue == KERN_SUCCESS) { if (ioReturnValue == KERN_SUCCESS) {
ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL); ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL);
if (ioReturnValue == KERN_SUCCESS) { if (ioReturnValue == KERN_SUCCESS) {
CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode);
//start data delivery to queue //start data delivery to queue
(*queue)->start(queue); (*queue)->start(queue);
return YES; return YES;
} else { } else {
ALog(@"Error when setting event callout"); ALog(@"Error when setting event callout");
@ -661,7 +631,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
ALog(@"Error when opening device"); ALog(@"Error when opening device");
} }
} }
return NO; return NO;
} }
@end @end
@ -669,9 +639,8 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
@implementation AppleRemoteApplicationDelegate @implementation AppleRemoteApplicationDelegate
- (id) initWithApplicationDelegate: (id) delegate { - (id) initWithApplicationDelegate: (id) delegate {
if (self = [super init]) { if((self = [super init]))
applicationDelegate = [delegate retain]; applicationDelegate = [delegate retain];
}
return self; return self;
} }
@ -694,19 +663,19 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
if ([applicationDelegate respondsToSelector: @selector(applicationDidBecomeActive:)]) { if ([applicationDelegate respondsToSelector: @selector(applicationDidBecomeActive:)]) {
[applicationDelegate applicationDidBecomeActive: aNotification]; [applicationDelegate applicationDidBecomeActive: aNotification];
} }
} }
- (void)applicationWillResignActive:(NSNotification *)aNotification { - (void)applicationWillResignActive:(NSNotification *)aNotification {
[[AppleRemote sharedRemote] setListeningToRemote: NO]; [[AppleRemote sharedRemote] setListeningToRemote: NO];
if ([applicationDelegate respondsToSelector: @selector(applicationWillResignActive:)]) { if ([applicationDelegate respondsToSelector: @selector(applicationWillResignActive:)]) {
[applicationDelegate applicationWillResignActive: aNotification]; [applicationDelegate applicationWillResignActive: aNotification];
} }
} }
- (void)applicationDidResignActive:(NSNotification *)aNotification { - (void)applicationDidResignActive:(NSNotification *)aNotification {
if ([applicationDelegate respondsToSelector: @selector(applicationDidResignActive:)]) { if ([applicationDelegate respondsToSelector: @selector(applicationDidResignActive:)]) {
[applicationDelegate applicationDidResignActive: aNotification]; [applicationDelegate applicationDidResignActive: aNotification];
} }
} }
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {