diff --git a/Application/AppController.m b/Application/AppController.m index d26f54d4e..41136cd3b 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -129,6 +129,7 @@ increase/decrease as long as the user holds the left/right, plus/minus button */ { switch( buttonIdentifier ) { + case k2009RemoteButtonPlay: case kRemoteButtonPlay: [self clickPlay]; @@ -160,6 +161,9 @@ increase/decrease as long as the user holds the left/right, plus/minus button */ break; case kRemoteButtonMenu: break; + case k2009RemoteButtonFullscreen: + [mainWindow toggleFullScreen:nil]; + break; default: /* Add here whatever you want other buttons to do */ break; diff --git a/ThirdParty/AppleRemote/AppleRemote.h b/ThirdParty/AppleRemote/AppleRemote.h index 8ca112ae8..045b9a0c0 100644 --- a/ThirdParty/AppleRemote/AppleRemote.h +++ b/ThirdParty/AppleRemote/AppleRemote.h @@ -1,12 +1,12 @@ /***************************************************************************** * AppleRemote.h * 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. * - * 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"), * to deal in the Software without restriction, including without limitation * 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 * 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 * 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 @@ -29,10 +29,10 @@ * 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 * 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: * - * Copyright (C) 2006-2007 the VideoLAN team + * Copyright (C) 2006-2007 VLC authors and VideoLAN * Authors: Eric Petit * Felix Kühne * @@ -73,7 +73,9 @@ enum AppleRemoteEventIdentifier kRemoteButtonPlay_Sleep =1<<10, kRemoteControl_Switched =1<<11, 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; @@ -84,37 +86,34 @@ The class is not thread safe @interface AppleRemote : NSObject { IOHIDDeviceInterface** hidDeviceInterface; IOHIDQueueInterface** queue; - NSMutableArray* allCookies; - NSMutableDictionary* cookieToButtonMapping; - - BOOL openInExclusiveMode; - BOOL simulatePlusMinusHold; - BOOL processesBacklog; - + NSArray* _allCookies; + NSDictionary* _cookieToButtonMapping; + CFRunLoopSourceRef eventSource; + + BOOL _openInExclusiveMode; + BOOL _simulatePlusMinusHold; + BOOL _processesBacklog; + /* state for simulating plus/minus hold */ BOOL lastEventSimulatedHold; AppleRemoteEventIdentifier lastPlusMinusEvent; NSTimeInterval lastPlusMinusEventTime; - + int remoteId; - unsigned int clickCountEnabledButtons; - NSTimeInterval maxClickTimeDifference; - NSTimeInterval lastClickCountEventTime; + unsigned int _clickCountEnabledButtons; + NSTimeInterval _maxClickTimeDifference; + NSTimeInterval lastClickCountEventTime; AppleRemoteEventIdentifier lastClickCountEvent; unsigned int eventClickCount; - - IBOutlet id delegate; + + id delegate; } ++ (AppleRemote *)sharedInstance; -- (int) remoteId; - -- (BOOL) isRemoteAvailable; - -- (BOOL) isListeningToRemote; -- (void) setListeningToRemote: (BOOL) value; - -- (BOOL) isOpenInExclusiveMode; -- (void) setOpenInExclusiveMode: (BOOL) value; +@property (readonly) int remoteId; +@property (readonly) BOOL remoteAvailable; +@property (readwrite) BOOL listeningToRemote; +@property (readwrite) BOOL openInExclusiveMode; /* 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) @@ -122,38 +121,31 @@ The class is not thread safe * of the user and the call of your delegate method * click counting can be enabled individually for specific buttons. Use the property clickCountEnableButtons * to set the buttons for which click counting shall be enabled */ -- (BOOL) clickCountingEnabled; -- (void) setClickCountingEnabled: (BOOL) value; +@property (readwrite) BOOL clickCountingEnabled; -- (unsigned int) clickCountEnabledButtons; -- (void) setClickCountEnabledButtons: (unsigned int)value; +@property (readwrite) unsigned int clickCountEnabledButtons; /* the maximum time difference till which clicks are recognized as multi clicks */ -- (NSTimeInterval) maximumClickCountTimeDifference; -- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff; +@property (readwrite) NSTimeInterval maximumClickCountTimeDifference; /* 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 * has some spare time this backlog is processed and may flood your delegate with calls. * Backlog processing is turned off by default. */ -- (BOOL) processesBacklog; -- (void) setProcessesBacklog: (BOOL) value; +@property (readwrite) BOOL processesBacklog; /* 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. */ -- (BOOL) listeningOnAppActivate; -- (void) setListeningOnAppActivate: (BOOL) value; +@property (readwrite) BOOL listeningOnAppActivate; /* 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. * With simulating enabled the plus/minus buttons do behave as the left/right buttons */ -- (BOOL) simulatesPlusMinusHold; -- (void) setSimulatesPlusMinusHold: (BOOL) value; +@property (readwrite) BOOL simulatesPlusMinusHold; /* Delegates are not retained */ -- (void) setDelegate: (id) delegate; -- (id) delegate; +@property (readwrite, assign) id delegate; - (IBAction) startListening: (id) sender; - (IBAction) stopListening: (id) sender; @@ -172,15 +164,16 @@ The class is not thread safe @end -@interface AppleRemote (PrivateMethods) +@interface AppleRemote (PrivateMethods) +@property (readonly) NSDictionary * cookieToButtonMapping; + - (void) setRemoteId: (int) aValue; -- (NSDictionary*) cookieToButtonMapping; - (IOHIDQueueInterface**) queue; - (IOHIDDeviceInterface**) hidDeviceInterface; -- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; +- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; @end -@interface AppleRemote (IOKitMethods) +@interface AppleRemote (IOKitMethods) - (io_object_t) findAppleRemoteDevice; - (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice; - (BOOL) initializeCookies; diff --git a/ThirdParty/AppleRemote/AppleRemote.m b/ThirdParty/AppleRemote/AppleRemote.m index c44e0d798..62aa9945d 100644 --- a/ThirdParty/AppleRemote/AppleRemote.m +++ b/ThirdParty/AppleRemote/AppleRemote.m @@ -3,10 +3,10 @@ * AppleRemote * $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. * - * 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"), * to deal in the Software without restriction, including without limitation * 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 * 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 * 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 @@ -29,10 +29,10 @@ * 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 * 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: * - * Copyright (C) 2006-2007 the VideoLAN team + * Copyright (C) 2006-2009 VLC authors and VideoLAN * Authors: Eric Petit * Felix Kühne * @@ -62,89 +62,81 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; @implementation AppleRemote +@synthesize openInExclusiveMode = _openInExclusiveMode, clickCountEnabledButtons = _clickCountEnabledButtons, maximumClickCountTimeDifference = _maxClickTimeDifference, processesBacklog=_processesBacklog, simulatesPlusMinusHold = _simulatePlusMinusHold; + #pragma public interface -#ifndef NSAppKitVersionNumber10_4 - #define NSAppKitVersionNumber10_4 824 -#endif +static AppleRemote *_o_sharedInstance = nil; -- (void) setCookieMappingInDictionary: (NSMutableDictionary*) _cookieToButtonMapping { - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) { - // 10.4.x Tiger - [_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_"]; - } ++ (AppleRemote *)sharedInstance +{ + return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init]; } -- (id) init { - if ( self = [super init] ) { - openInExclusiveMode = YES; +- (id)init +{ + if (_o_sharedInstance) { + [self dealloc]; + } else { + _o_sharedInstance = [super init]; + _openInExclusiveMode = YES; queue = NULL; hidDeviceInterface = NULL; - cookieToButtonMapping = [[NSMutableDictionary alloc] init]; - [self setCookieMappingInDictionary:cookieToButtonMapping]; + NSMutableDictionary * mutableCookieToButtonMapping = [[NSMutableDictionary alloc] init]; + + [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 */ - [self setSimulatesPlusMinusHold: YES]; - maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE; + _simulatePlusMinusHold = YES; + _maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE; } - return self; + return _o_sharedInstance; } - (void) dealloc { [self stopListening:self]; - [cookieToButtonMapping release]; + [_cookieToButtonMapping release]; [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 { return remoteId; } -- (BOOL) isRemoteAvailable { +- (BOOL) remoteAvailable { io_object_t hidDevice = [self findAppleRemoteDevice]; if (hidDevice != 0) { IOObjectRelease(hidDevice); return YES; } else { - return NO; + return NO; } } -- (BOOL) isListeningToRemote { - return (hidDeviceInterface != NULL && allCookies != NULL && queue != NULL); +- (BOOL) listeningToRemote { + return (hidDeviceInterface != NULL && _allCookies != NULL && queue != NULL); } - (void) setListeningToRemote: (BOOL) value { @@ -157,7 +149,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; /* Delegates are not retained! * 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 * to receive delegation messages. To do this, they may have to retain the delegate. */ - (void) setDelegate: (id) _delegate { @@ -169,45 +161,17 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; return delegate; } -- (BOOL) isOpenInExclusiveMode { - return openInExclusiveMode; -} -- (void) setOpenInExclusiveMode: (BOOL) value { - openInExclusiveMode = value; -} - - (BOOL) clickCountingEnabled { - return clickCountEnabledButtons != 0; + return self.clickCountEnabledButtons != 0; } - (void) setClickCountingEnabled: (BOOL) 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 { [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 { id appDelegate = [NSApp delegate]; return (appDelegate!=nil && [appDelegate isKindOfClass: [AppleRemoteApplicationDelegate class]]); @@ -227,15 +191,8 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; } } -- (BOOL) simulatesPlusMinusHold { - return simulatePlusMinusHold; -} -- (void) setSimulatesPlusMinusHold: (BOOL) value { - simulatePlusMinusHold = value; -} - -- (IBAction) startListening: (id) sender { - if ([self isListeningToRemote]) return; +- (IBAction) startListening: (id) sender { + if ([self listeningToRemote]) return; io_object_t hidDevice = [self findAppleRemoteDevice]; if (hidDevice == 0) return; @@ -253,49 +210,54 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; } goto cleanup; -error: + error: [self stopListening:self]; -cleanup: + cleanup: IOObjectRelease(hidDevice); } - (IBAction) stopListening: (id) sender { + if (eventSource != NULL) { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); + CFRelease(eventSource); + eventSource = NULL; + } if (queue != NULL) { - (*queue)->stop(queue); + (*queue)->stop(queue); //dispose of queue - (*queue)->dispose(queue); + (*queue)->dispose(queue); //release the queue we allocated - (*queue)->Release(queue); + (*queue)->Release(queue); queue = NULL; } - if (allCookies != nil) { - [allCookies autorelease]; - allCookies = nil; + if (_allCookies != nil) { + [_allCookies autorelease]; + _allCookies = nil; } if (hidDeviceInterface != NULL) { //close the device (*hidDeviceInterface)->close(hidDeviceInterface); - //release the interface + //release the interface (*hidDeviceInterface)->Release(hidDeviceInterface); - hidDeviceInterface = NULL; - } + hidDeviceInterface = NULL; + } } @end -@implementation AppleRemote (Singleton) +@implementation AppleRemote (Singleton) static AppleRemote* sharedInstance=nil; -+ (AppleRemote*) sharedRemote { ++ (AppleRemote*) sharedRemote { @synchronized(self) { if (sharedInstance == nil) { sharedInstance = [[self alloc] init]; @@ -308,7 +270,7 @@ static AppleRemote* sharedInstance=nil; if (sharedInstance == nil) { return [super allocWithZone:zone]; } - } + } return sharedInstance; } - (id)copyWithZone:(NSZone *)zone { @@ -317,7 +279,7 @@ static AppleRemote* sharedInstance=nil; - (id)retain { return self; } -- (unsigned)retainCount { +- (NSUInteger)retainCount { return UINT_MAX; //denotes an object that cannot be released } - (void)release { @@ -329,7 +291,7 @@ static AppleRemote* sharedInstance=nil; @end -@implementation AppleRemote (PrivateMethods) +@implementation AppleRemote (PrivateMethods) - (void) setRemoteId: (int) value { remoteId = value; @@ -343,16 +305,17 @@ static AppleRemote* sharedInstance=nil; return hidDeviceInterface; } - - (NSDictionary*) cookieToButtonMapping { - return cookieToButtonMapping; + return _cookieToButtonMapping; } - (NSString*) validCookieSubstring: (NSString*) cookieString { 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]; - if (range.location == 0) return key; + if (range.location == 0) return key; } return nil; } @@ -372,13 +335,13 @@ static AppleRemote* sharedInstance=nil; - (void) sendRemoteButtonEvent: (AppleRemoteEventIdentifier) event pressedDown: (BOOL) pressedDown { if (delegate) { - if (simulatePlusMinusHold) { + if (self.simulatesPlusMinusHold) { if (event == kRemoteButtonVolume_Plus || event == kRemoteButtonVolume_Minus) { if (pressedDown) { lastPlusMinusEvent = event; lastPlusMinusEventTime = [NSDate timeIntervalSinceReferenceDate]; - [self performSelector:@selector(sendSimulatedPlusMinusEvent:) - withObject:[NSNumber numberWithDouble:lastPlusMinusEventTime] + [self performSelector:@selector(sendSimulatedPlusMinusEvent:) + withObject:@(lastPlusMinusEventTime) afterDelay:HOLD_RECOGNITION_TIME_INTERVAL]; return; } 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)) { return; // this one is triggered automatically by the handler } @@ -410,32 +373,32 @@ static AppleRemote* sharedInstance=nil; eventClickCount = 1; } lastClickCountEvent = event; - timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime]; - eventNumber= [NSNumber numberWithUnsignedInt:event]; + timeNumber = @(lastClickCountEventTime); + eventNumber= @(event); } - [self performSelector: @selector(executeClickCountEvent:) - withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil] - afterDelay: maxClickTimeDifference]; + [self performSelector: @selector(executeClickCountEvent:) + withObject: @[eventNumber, timeNumber] + afterDelay: _maxClickTimeDifference]; } else { [delegate appleRemoteButton:event pressedDown: pressedDown clickCount:1]; - } + } } } - (void) executeClickCountEvent: (NSArray*) values { - AppleRemoteEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue]; - NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue]; + AppleRemoteEventIdentifier event = [[values objectAtIndex:0] unsignedIntValue]; + NSTimeInterval eventTimePoint = [[values objectAtIndex:1] doubleValue]; BOOL finishedClicking = NO; - int finalClickCount = eventClickCount; + int finalClickCount = eventClickCount; @synchronized(self) { finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime); - if (finishedClicking) eventClickCount = 0; + if (finishedClicking) eventClickCount = 0; } - if (finishedClicking) { - [delegate appleRemoteButton:event pressedDown: YES clickCount:finalClickCount]; + if (finishedClicking) { + [delegate appleRemoteButton:event pressedDown: YES clickCount:finalClickCount]; if ([self simulatesPlusMinusHold]==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) { // trigger a button release event, too [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]]; @@ -449,8 +412,8 @@ static AppleRemote* sharedInstance=nil; /* if (previousRemainingCookieString) { cookieString = [previousRemainingCookieString stringByAppendingString: cookieString]; - DLog(@"New cookie string is %@", cookieString); - [previousRemainingCookieString release], previousRemainingCookieString=nil; + NSLog(@"New cookie string is %@", cookieString); + [previousRemainingCookieString release], previousRemainingCookieString=nil; }*/ if (cookieString == nil || [cookieString length] == 0) return; NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString]; @@ -464,18 +427,18 @@ static AppleRemote* sharedInstance=nil; while((subCookieString = [self validCookieSubstring: cookieString])) { cookieString = [cookieString substringFromIndex: [subCookieString length]]; 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. - // 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. - // DLog(@"processing last event of backlog"); + // 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. + // NSLog(@"processing last event of backlog"); [self handleEventWithCookieString: lastSubCookieString sumOfValues: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 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; - IOHIDEventStruct event; + IOHIDEventStruct event; AbsoluteTime zeroTime = {0,0}; NSMutableString* cookieString = [NSMutableString string]; SInt32 sumOfValues = 0; while (result == kIOReturnSuccess) { - result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0); + result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0); if ( result != kIOReturnSuccess ) 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) { - sumOfValues+=event.value; - [cookieString appendString:[NSString stringWithFormat:@"%u_", event.elementCookie]]; - } + if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie) { + [remote setRemoteId: event.value]; + [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) @@ -527,10 +495,10 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, } ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score); + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &plugInInterface, + &score); if (ioReturnValue == kIOReturnSuccess) { //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 { CFMutableDictionaryRef hidMatchDictionary = NULL; - IOReturn ioReturnValue = kIOReturnSuccess; + IOReturn ioReturnValue = kIOReturnSuccess; io_iterator_t hidObjectIterator = 0; io_object_t hidDevice = 0; @@ -574,7 +542,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, long usage; long usagePage; id object; - NSArray* elements = nil; + NSArray* elements; NSDictionary* element; IOReturn success; @@ -587,15 +555,13 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); 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); */ - allCookies = [[NSMutableArray alloc] init]; - int i; - for (i=0; i< [elements count]; i++) { + NSMutableArray *mutableAllCookies = [[NSMutableArray alloc] init]; + NSUInteger elementCount = [elements count]; + for (NSUInteger i=0; i< elementCount; i++) { element = [elements objectAtIndex:i]; //Get cookie @@ -606,17 +572,22 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, //Get usage 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]; //Get usage page 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]; - [allCookies addObject: [NSNumber numberWithInt:(int)cookie]]; + [mutableAllCookies addObject: @((int)cookie)]; } + _allCookies = [[NSArray alloc] initWithArray: mutableAllCookies]; + [mutableAllCookies release]; + [elements release]; } else { + if (elements) + [elements release]; return NO; } @@ -627,29 +598,28 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, HRESULT result; IOHIDOptionsType openMode = kIOHIDOptionsTypeNone; - if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; - IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode); + if ([self openInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; + IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode); if (ioReturnValue == KERN_SUCCESS) { queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); if (queue) { 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; - for(i=0; i<[allCookies count]; i++) { - IOHIDElementCookie cookie = (IOHIDElementCookie)[[allCookies objectAtIndex:i] intValue]; + NSUInteger cookieCount = [_allCookies count]; + for(NSUInteger i=0; iaddElement(queue, cookie, 0); } // add callback for async events - CFRunLoopSourceRef eventSource; ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource); if (ioReturnValue == KERN_SUCCESS) { ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL); if (ioReturnValue == KERN_SUCCESS) { - CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); + CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode); //start data delivery to queue - (*queue)->start(queue); + (*queue)->start(queue); return YES; } else { ALog(@"Error when setting event callout"); @@ -661,7 +631,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ALog(@"Error when opening device"); } } - return NO; + return NO; } @end @@ -669,9 +639,8 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, @implementation AppleRemoteApplicationDelegate - (id) initWithApplicationDelegate: (id) delegate { - if (self = [super init]) { + if((self = [super init])) applicationDelegate = [delegate retain]; - } return self; } @@ -694,19 +663,19 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, if ([applicationDelegate respondsToSelector: @selector(applicationDidBecomeActive:)]) { [applicationDelegate applicationDidBecomeActive: aNotification]; - } + } } - (void)applicationWillResignActive:(NSNotification *)aNotification { [[AppleRemote sharedRemote] setListeningToRemote: NO]; if ([applicationDelegate respondsToSelector: @selector(applicationWillResignActive:)]) { [applicationDelegate applicationWillResignActive: aNotification]; - } + } } - (void)applicationDidResignActive:(NSNotification *)aNotification { if ([applicationDelegate respondsToSelector: @selector(applicationDidResignActive:)]) { [applicationDelegate applicationDidResignActive: aNotification]; - } + } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {