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,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* 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.
@ -32,7 +32,7 @@
* 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,12 +86,13 @@ 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 _openInExclusiveMode;
BOOL simulatePlusMinusHold; BOOL _simulatePlusMinusHold;
BOOL processesBacklog; BOOL _processesBacklog;
/* state for simulating plus/minus hold */ /* state for simulating plus/minus hold */
BOOL lastEventSimulatedHold; BOOL lastEventSimulatedHold;
@ -97,24 +100,20 @@ The class is not thread safe
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;
@ -173,8 +165,9 @@ 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;

View File

@ -32,7 +32,7 @@
* 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,78 +62,70 @@ 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_"]; - (id)init
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"14_8_6_14_8_6_"]; {
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"14_9_6_14_9_6_"]; if (_o_sharedInstance) {
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"14_10_6_14_10_6_"]; [self dealloc];
[_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 { } else {
// 10.5.x Leopard _o_sharedInstance = [super init];
[_cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"31_29_28_19_18_"]; _openInExclusiveMode = YES;
[_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 {
if ( self = [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);
@ -143,8 +135,8 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
} }
} }
- (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 {
@ -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 {
return simulatePlusMinusHold;
}
- (void) setSimulatesPlusMinusHold: (BOOL) value {
simulatePlusMinusHold = value;
}
- (IBAction) startListening: (id) sender { - (IBAction) startListening: (id) sender {
if ([self isListeningToRemote]) return; if ([self listeningToRemote]) return;
io_object_t hidDevice = [self findAppleRemoteDevice]; io_object_t hidDevice = [self findAppleRemoteDevice];
if (hidDevice == 0) return; if (hidDevice == 0) return;
@ -261,6 +218,11 @@ cleanup:
} }
- (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);
@ -273,9 +235,9 @@ cleanup:
queue = NULL; queue = NULL;
} }
if (allCookies != nil) { if (_allCookies != nil) {
[allCookies autorelease]; [_allCookies autorelease];
allCookies = nil; _allCookies = nil;
} }
if (hidDeviceInterface != NULL) { if (hidDeviceInterface != NULL) {
@ -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 {
@ -343,14 +305,15 @@ 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;
} }
@ -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,12 +373,12 @@ 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];
} }
@ -449,7 +412,7 @@ 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;
@ -464,17 +427,17 @@ 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]);
} }
} }
} }
@ -499,9 +462,14 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
//printf("%d %d %d\n", event.elementCookie, event.value, event.longValue); //printf("%d %d %d\n", event.elementCookie, event.value, event.longValue);
if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie) {
[remote setRemoteId: event.value];
[remote handleEventWithCookieString: @"19_" sumOfValues: 0];
} else {
if (((int)event.elementCookie)!=5) { if (((int)event.elementCookie)!=5) {
sumOfValues+=event.value; sumOfValues+=event.value;
[cookieString appendString:[NSString stringWithFormat:@"%u_", event.elementCookie]]; [cookieString appendString:[NSString stringWithFormat:@"%d_", event.elementCookie]];
}
} }
} }
@ -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
@ -614,9 +580,14 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
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,7 +598,7 @@ 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) {
@ -635,14 +606,13 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
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);
@ -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;
} }