Commit da380a41 authored by Felix Paul Kühne's avatar Felix Paul Kühne

macosx: updated cookie for the 2009 Apple Remote and fixed a minor issue when...

macosx: updated cookie for the 2009 Apple Remote and fixed a minor issue when switching between multiple remotes
parent 302e7eb5
...@@ -32,7 +32,7 @@ ...@@ -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-2011 the VideoLAN team
* 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>
* *
...@@ -74,38 +74,40 @@ enum AppleRemoteEventIdentifier ...@@ -74,38 +74,40 @@ enum AppleRemoteEventIdentifier
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, k2009RemoteButtonPlay =1<<14,
k2009RemoteButtonFullscreen =1<<15 k2009RemoteButtonFullscreen =1<<15,
k2009RemoteButtonSwitched =1<<16
}; };
typedef enum AppleRemoteEventIdentifier AppleRemoteEventIdentifier; typedef enum AppleRemoteEventIdentifier AppleRemoteEventIdentifier;
/* Encapsulates usage of the apple remote control /* Encapsulates usage of the apple remote control
This class is implemented as a singleton as there is exactly one remote per machine (until now) This class is implemented as a singleton as there is exactly one remote per machine (until now)
The class is not thread safe The class is not thread safe
*/ */
@interface AppleRemote : NSObject { @interface AppleRemote : NSObject {
IOHIDDeviceInterface** hidDeviceInterface; IOHIDDeviceInterface** hidDeviceInterface;
IOHIDQueueInterface** queue; IOHIDQueueInterface** queue;
NSMutableArray* allCookies; NSMutableArray* allCookies;
NSMutableDictionary* cookieToButtonMapping; NSMutableDictionary* cookieToButtonMapping;
NSString* switchCookie;
CFRunLoopSourceRef eventSource; 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;
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; IBOutlet id delegate;
} }
...@@ -178,6 +180,7 @@ The class is not thread safe ...@@ -178,6 +180,7 @@ The class is not thread safe
@interface AppleRemote (PrivateMethods) @interface AppleRemote (PrivateMethods)
- (void) setRemoteId: (int) aValue; - (void) setRemoteId: (int) aValue;
- (NSDictionary*) cookieToButtonMapping; - (NSDictionary*) cookieToButtonMapping;
- (NSString *) switchCookie;
- (IOHIDQueueInterface**) queue; - (IOHIDQueueInterface**) queue;
- (IOHIDDeviceInterface**) hidDeviceInterface; - (IOHIDDeviceInterface**) hidDeviceInterface;
- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues; - (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues;
......
...@@ -32,7 +32,7 @@ ...@@ -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-2009 the VideoLAN team * Copyright (C) 2006-2011 the VideoLAN team
* 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>
* *
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
const char* AppleRemoteDeviceName = "AppleIRController"; const char* AppleRemoteDeviceName = "AppleIRController";
const int REMOTE_SWITCH_COOKIE=19; const int REMOTE_SWITCH_COOKIE=19;
const int FUTURE_REMOTE_SWITCH_COOKIE=42;
const NSTimeInterval DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE=0.35; const NSTimeInterval DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE=0.35;
const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
...@@ -71,7 +72,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; ...@@ -71,7 +72,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
queue = NULL; queue = NULL;
hidDeviceInterface = NULL; hidDeviceInterface = NULL;
cookieToButtonMapping = [[NSMutableDictionary alloc] init]; cookieToButtonMapping = [[NSMutableDictionary alloc] init];
if( NSAppKitVersionNumber < 1038.13 ) if( NSAppKitVersionNumber < 1038.13 )
{ {
/* Leopard and early Snow Leopard Cookies */ /* Leopard and early Snow Leopard Cookies */
...@@ -87,6 +88,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; ...@@ -87,6 +88,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"31_18_31_18_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"31_18_31_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"35_31_18_35_31_18_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"35_31_18_35_31_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
switchCookie = @"19_";
} }
else if( NSAppKitVersionNumber >= 1115.2 ) else if( NSAppKitVersionNumber >= 1115.2 )
{ {
...@@ -103,8 +105,10 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; ...@@ -103,8 +105,10 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"33_21_20_2_33_21_20_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"33_21_20_2_33_21_20_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"37_33_21_20_2_37_33_21_20_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"37_33_21_20_2_37_33_21_20_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"42_33_23_21_20_2_33_23_21_20_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"42_33_23_21_20_2_33_23_21_20_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonSwitched] forKey:@"42_33_21_20_8_2_33_21_20_8_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonFullscreen] forKey:@"33_21_20_3_2_33_21_20_3_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonFullscreen] forKey:@"33_21_20_3_2_33_21_20_3_2_"];
switchCookie = @"42_33_23_21_20_2_33_23_21_20_2_";
} }
else else
{ {
...@@ -123,19 +127,21 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; ...@@ -123,19 +127,21 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonFullscreen] forKey:@"33_21_20_3_2_33_21_20_3_2_"]; [cookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonFullscreen] forKey:@"33_21_20_3_2_33_21_20_3_2_"];
switchCookie = @"19_";
} }
} }
/* defaults */ /* defaults */
[self setSimulatesPlusMinusHold: YES]; [self setSimulatesPlusMinusHold: YES];
maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE; maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE;
return self; return self;
} }
- (void) dealloc { - (void) dealloc {
[self stopListening:self]; [self stopListening:self];
[cookieToButtonMapping release]; [cookieToButtonMapping release];
[switchCookie release];
[super dealloc]; [super dealloc];
} }
...@@ -172,7 +178,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; ...@@ -172,7 +178,7 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
* 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 {
if (_delegate && [_delegate respondsToSelector:@selector(appleRemoteButton:pressedDown:clickCount:)]==NO) return; if (_delegate && [_delegate respondsToSelector:@selector(appleRemoteButton:pressedDown:clickCount:)]==NO) return;
delegate = _delegate; delegate = _delegate;
} }
- (id) delegate { - (id) delegate {
...@@ -246,26 +252,26 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4; ...@@ -246,26 +252,26 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
- (IBAction) startListening: (id) sender { - (IBAction) startListening: (id) sender {
if ([self isListeningToRemote]) return; if ([self isListeningToRemote]) return;
io_object_t hidDevice = [self findAppleRemoteDevice]; io_object_t hidDevice = [self findAppleRemoteDevice];
if (hidDevice == 0) return; if (hidDevice == 0) return;
if ([self createInterfaceForDevice:hidDevice] == NULL) { if ([self createInterfaceForDevice:hidDevice] == NULL) {
goto error; goto error;
} }
if ([self initializeCookies]==NO) { if ([self initializeCookies]==NO) {
goto error; goto error;
} }
if ([self openDevice]==NO) { if ([self openDevice]==NO) {
goto error; goto error;
} }
goto cleanup; goto cleanup;
error: error:
[self stopListening:self]; [self stopListening:self];
cleanup: cleanup:
IOObjectRelease(hidDevice); IOObjectRelease(hidDevice);
} }
...@@ -278,28 +284,28 @@ cleanup: ...@@ -278,28 +284,28 @@ cleanup:
} }
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;
} }
} }
...@@ -358,6 +364,9 @@ static AppleRemote* sharedInstance=nil; ...@@ -358,6 +364,9 @@ static AppleRemote* sharedInstance=nil;
return hidDeviceInterface; return hidDeviceInterface;
} }
- (NSString *) switchCookie {
return switchCookie;
}
- (NSDictionary*) cookieToButtonMapping { - (NSDictionary*) cookieToButtonMapping {
return cookieToButtonMapping; return cookieToButtonMapping;
...@@ -412,7 +421,7 @@ static AppleRemote* sharedInstance=nil; ...@@ -412,7 +421,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
...@@ -442,15 +451,15 @@ static AppleRemote* sharedInstance=nil; ...@@ -442,15 +451,15 @@ static AppleRemote* sharedInstance=nil;
- (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)) {
...@@ -459,16 +468,16 @@ static AppleRemote* sharedInstance=nil; ...@@ -459,16 +468,16 @@ static AppleRemote* sharedInstance=nil;
[delegate appleRemoteButton:event pressedDown: NO clickCount:finalClickCount]; [delegate appleRemoteButton:event pressedDown: NO clickCount:finalClickCount];
} }
} }
} }
- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues { - (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues {
/* /*
if (previousRemainingCookieString) { if (previousRemainingCookieString) {
cookieString = [previousRemainingCookieString stringByAppendingString: cookieString]; cookieString = [previousRemainingCookieString stringByAppendingString: cookieString];
NSLog(@"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];
if (buttonId != nil) { if (buttonId != nil) {
...@@ -499,11 +508,11 @@ static AppleRemote* sharedInstance=nil; ...@@ -499,11 +508,11 @@ static AppleRemote* sharedInstance=nil;
@end @end
/* 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];
...@@ -513,12 +522,12 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -513,12 +522,12 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
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 (REMOTE_SWITCH_COOKIE == (int)event.elementCookie) { if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie || FUTURE_REMOTE_SWITCH_COOKIE == (int)event.elementCookie) {
[remote setRemoteId: event.value]; [remote setRemoteId: event.value];
[remote handleEventWithCookieString: @"19_" sumOfValues: 0]; [remote handleEventWithCookieString: [remote switchCookie] sumOfValues: 0];
} else { } else {
if (((int)event.elementCookie)!=5) { if (((int)event.elementCookie)!=5) {
sumOfValues+=event.value; sumOfValues+=event.value;
...@@ -526,7 +535,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -526,7 +535,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
} }
} }
} }
[remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues]; [remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues];
} }
...@@ -538,16 +547,16 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -538,16 +547,16 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
HRESULT plugInResult = S_OK; HRESULT plugInResult = S_OK;
SInt32 score = 0; SInt32 score = 0;
IOReturn ioReturnValue = kIOReturnSuccess; IOReturn ioReturnValue = kIOReturnSuccess;
hidDeviceInterface = NULL; hidDeviceInterface = NULL;
ioReturnValue = IOObjectGetClass(hidDevice, className); ioReturnValue = IOObjectGetClass(hidDevice, className);
if (ioReturnValue != kIOReturnSuccess) { if (ioReturnValue != kIOReturnSuccess) {
msg_Err( VLCIntf, "Failed to get IOKit class name."); msg_Err( VLCIntf, "Failed to get IOKit class name.");
return NULL; return NULL;
} }
ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice, ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice,
kIOHIDDeviceUserClientTypeID, kIOHIDDeviceUserClientTypeID,
kIOCFPlugInInterfaceID, kIOCFPlugInInterfaceID,
...@@ -557,7 +566,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -557,7 +566,7 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
{ {
//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
plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &hidDeviceInterface); plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &hidDeviceInterface);
if (plugInResult != S_OK) { if (plugInResult != S_OK) {
msg_Err( VLCIntf, "Couldn't create HID class device interface"); msg_Err( VLCIntf, "Couldn't create HID class device interface");
} }
...@@ -572,21 +581,21 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -572,21 +581,21 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
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;
// Set up a matching dictionary to search the I/O Registry by class // Set up a matching dictionary to search the I/O Registry by class
// name for all HID class devices // name for all HID class devices
hidMatchDictionary = IOServiceMatching(AppleRemoteDeviceName); hidMatchDictionary = IOServiceMatching(AppleRemoteDeviceName);
// Now search I/O Registry for matching devices. // Now search I/O Registry for matching devices.
ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator); ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator);
if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) { if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) {
hidDevice = IOIteratorNext(hidObjectIterator); hidDevice = IOIteratorNext(hidObjectIterator);
} }
// release the iterator // release the iterator
IOObjectRelease(hidObjectIterator); IOObjectRelease(hidObjectIterator);
return hidDevice; return hidDevice;
} }
...@@ -599,70 +608,70 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -599,70 +608,70 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
NSArray* elements = nil; NSArray* elements = nil;
NSDictionary* element; NSDictionary* element;
IOReturn success; IOReturn success;
if (!handle || !(*handle)) return NO; if (!handle || !(*handle)) return NO;
/* Copy all elements, since we're grabbing most of the elements /* Copy all elements, since we're grabbing most of the elements
* for this device anyway, and thus, it's faster to iterate them * for this device anyway, and thus, it's faster to iterate them
* ourselves. When grabbing only one or two elements, a matching * ourselves. When grabbing only one or two elements, a matching
* dictionary should be passed in here instead of NULL. */ * dictionary should be passed in here instead of NULL. */
success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements);
if (success == kIOReturnSuccess) { if (success == kIOReturnSuccess) {
[elements autorelease]; [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]; allCookies = [[NSMutableArray alloc] init];
unsigned int i; unsigned int i;
for (i=0; i< [elements count]; i++) { for (i=0; i< [elements count]; i++) {
element = [elements objectAtIndex:i]; element = [elements objectAtIndex:i];
//Get cookie //Get cookie
object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementCookieKey) ]; object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementCookieKey) ];
if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue; if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue;
if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) continue; if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) continue;
cookie = (IOHIDElementCookie) [object longValue]; cookie = (IOHIDElementCookie) [object longValue];
//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]]; [allCookies addObject: [NSNumber numberWithInt:(int)cookie]];
} }
} else { } else {
return NO; return NO;
} }
return YES; return YES;
} }
- (BOOL) openDevice { - (BOOL) openDevice {
HRESULT result; HRESULT result;
IOHIDOptionsType openMode = kIOHIDOptionsTypeNone; IOHIDOptionsType openMode = kIOHIDOptionsTypeNone;
if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice; if ([self isOpenInExclusiveMode]) 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.
unsigned int i=0; unsigned int i=0;
for(i=0; i<[allCookies count]; i++) { for(i=0; i<[allCookies count]; 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
ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource); ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource);
if (ioReturnValue == KERN_SUCCESS) { if (ioReturnValue == KERN_SUCCESS) {
...@@ -711,14 +720,14 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -711,14 +720,14 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
} }
- (void)applicationDidBecomeActive:(NSNotification *)aNotification { - (void)applicationDidBecomeActive:(NSNotification *)aNotification {
[[AppleRemote sharedRemote] setListeningToRemote: YES]; [[AppleRemote sharedRemote] setListeningToRemote: YES];
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];
} }
...@@ -739,12 +748,12 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, ...@@ -739,12 +748,12 @@ static void QueueCallbackFunction(void* target, IOReturn result, void* refcon,
- (void)forwardInvocation:(NSInvocation *)invocation { - (void)forwardInvocation:(NSInvocation *)invocation {
SEL aSelector = [invocation selector]; SEL aSelector = [invocation selector];
if (applicationDelegate==nil || [applicationDelegate respondsToSelector:aSelector]==NO) { if (applicationDelegate==nil || [applicationDelegate respondsToSelector:aSelector]==NO) {
[super forwardInvocation: invocation]; [super forwardInvocation: invocation];
return; return;
} }
[invocation invokeWithTarget:applicationDelegate]; [invocation invokeWithTarget:applicationDelegate];
} }
@end @end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment