diff options
author | MaestroDD <MaestroDD@svn> | 2009-12-10 16:30:55 +0000 |
---|---|---|
committer | MaestroDD <MaestroDD@svn> | 2009-12-10 16:30:55 +0000 |
commit | 9ccfe09f0b1a0a98779e09dfc2fd563eab8b2c12 (patch) | |
tree | 157f8d517bb60d775e4e0ec1cdce131209e334fa /tools/EventClients | |
parent | 52e57767d4437054fe08f23986825b3aa733429e (diff) |
[OSX]XBMCHelper: updatee to HIDRemote 1.1; use new naming scheme
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@25524 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
Diffstat (limited to 'tools/EventClients')
5 files changed, 528 insertions, 188 deletions
diff --git a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h index 358a9b0bc3..118c32101d 100644 --- a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h +++ b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h @@ -1,6 +1,6 @@ // // HIDRemote.h -// HIDRemote V1.0 +// HIDRemote V1.1 // // Created by Felix Schwarz on 06.04.07. // Copyright 2007-2009 IOSPIRIT GmbH. All rights reserved. @@ -89,26 +89,41 @@ typedef enum /* A code reserved for "no button" (needed for tracking) */ kHIDRemoteButtonCodeNone = 0L, - /* HID Remote standard codes - you'll be able to receive all of these in your HIDRemote delegate */ - kHIDRemoteButtonCodePlus, - kHIDRemoteButtonCodeMinus, + /* Standard codes - available for white plastic and aluminum remote */ + kHIDRemoteButtonCodeUp, + kHIDRemoteButtonCodeDown, kHIDRemoteButtonCodeLeft, kHIDRemoteButtonCodeRight, - kHIDRemoteButtonCodePlayPause, + kHIDRemoteButtonCodeCenter, kHIDRemoteButtonCodeMenu, + /* Extra codes - Only available for the new aluminum version of the remote */ + kHIDRemoteButtonCodePlay, + /* Masks */ - kHIDRemoteButtonCodeCodeMask = 0xFFL, - kHIDRemoteButtonCodeHoldMask = (1L << 16L), - kHIDRemoteButtonCodeSpecialMask = (1L << 17L), - - /* Hold button codes */ - kHIDRemoteButtonCodePlusHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodePlus), - kHIDRemoteButtonCodeMinusHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeMinus), - kHIDRemoteButtonCodeLeftHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeLeft), - kHIDRemoteButtonCodeRightHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeRight), - kHIDRemoteButtonCodePlayPauseHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodePlayPause), - kHIDRemoteButtonCodeMenuHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeMenu), + kHIDRemoteButtonCodeCodeMask = 0xFFL, + kHIDRemoteButtonCodeHoldMask = (1L << 16L), + kHIDRemoteButtonCodeSpecialMask = (1L << 17L), + kHIDRemoteButtonCodeAluminumMask = (1L << 21L), // PRIVATE - only used internally + + /* Hold button standard codes - available for white plastic and aluminum remote */ + kHIDRemoteButtonCodeUpHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeUp), + kHIDRemoteButtonCodeDownHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeDown), + kHIDRemoteButtonCodeLeftHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeLeft), + kHIDRemoteButtonCodeRightHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeRight), + kHIDRemoteButtonCodeCenterHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeCenter), + kHIDRemoteButtonCodeMenuHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeMenu), + + /* Hold button extra codes - Only available for aluminum version of the remote */ + kHIDRemoteButtonCodePlayHold = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodePlay), + + /* DEPRECATED codes - compatibility with HIDRemote 1.0 */ + kHIDRemoteButtonCodePlus = kHIDRemoteButtonCodeUp, + kHIDRemoteButtonCodePlusHold = kHIDRemoteButtonCodeUpHold, + kHIDRemoteButtonCodeMinus = kHIDRemoteButtonCodeDown, + kHIDRemoteButtonCodeMinusHold = kHIDRemoteButtonCodeDownHold, + kHIDRemoteButtonCodePlayPause = kHIDRemoteButtonCodeCenter, + kHIDRemoteButtonCodePlayPauseHold = kHIDRemoteButtonCodeCenterHold, /* Special purpose codes */ kHIDRemoteButtonCodeIDChanged = (kHIDRemoteButtonCodeSpecialMask|(1L << 18L)), // (the ID of the connected remote has changed, you can safely ignore this) @@ -119,6 +134,20 @@ typedef enum #endif /* _HIDREMOTE_EXTENSIONS */ } HIDRemoteButtonCode; +typedef enum +{ + kHIDRemoteModelUndetermined = 0L, // Assume a white plastic remote + kHIDRemoteModelWhitePlastic, // Signal *likely* to be coming from a white plastic remote + kHIDRemoteModelAluminum // Signal *definitely* coming from an aluminum remote +} HIDRemoteModel; + +typedef enum +{ + kHIDRemoteAluminumRemoteSupportLevelNone = 0L, // This system has no support for the Aluminum Remote at all + kHIDRemoteAluminumRemoteSupportLevelEmulation, // This system possibly has support for the Aluminum Remote (via emulation) + kHIDRemoteAluminumRemoteSupportLevelNative // This system has native support for the Aluminum Remote +} HIDRemoteAluminumRemoteSupportLevel; + @class HIDRemote; #pragma mark -- Delegate protocol (mandatory) -- @@ -183,6 +212,9 @@ typedef enum // Matching iterator io_iterator_t _matchingServicesIterator; + // SecureInput notification + io_object_t _secureInputNotification; + // Service attributes NSMutableDictionary *_serviceAttribMap; @@ -194,8 +226,10 @@ typedef enum // Delegate NSObject <HIDRemoteDelegate> *_delegate; - // Last seen ID + // Last seen ID and remote model SInt32 _lastSeenRemoteID; + HIDRemoteModel _lastSeenModel; + SInt32 _lastSeenModelRemoteID; // Unused button codes NSArray *_unusedButtonCodes; @@ -205,7 +239,8 @@ typedef enum // SecureEventInput workaround BOOL _secureEventInputWorkAround; - BOOL _statusSecureEventInputWorkAroundEnabled; + UInt64 _lastSecureEventInputPIDSum; + uid_t _lastFrontUserSession; // Exclusive lock lending BOOL _exclusiveLockLending; @@ -219,6 +254,7 @@ typedef enum #pragma mark -- PUBLIC: System Information -- + (BOOL)isCandelairInstalled; + (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode; +- (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel; #pragma mark -- PUBLIC: Interface / API -- - (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode; @@ -229,6 +265,7 @@ typedef enum - (unsigned)activeRemoteControlCount; - (SInt32)lastSeenRemoteControlID; +- (HIDRemoteModel)lastSeenModel; - (void)setDelegate:(NSObject <HIDRemoteDelegate> *)newDelegate; - (NSObject <HIDRemoteDelegate> *)delegate; @@ -240,7 +277,6 @@ typedef enum - (NSArray *)unusedButtonCodes; #pragma mark -- PUBLIC: Expert APIs -- - - (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround; - (BOOL)enableSecureEventInputWorkaround; @@ -255,6 +291,7 @@ typedef enum #pragma mark -- PRIVATE: Service setup and destruction -- - (BOOL)_prematchService:(io_object_t)service; +- (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage; - (BOOL)_setupService:(io_object_t)service; - (void)_destructService:(io_object_t)service; @@ -269,6 +306,8 @@ typedef enum #pragma mark -- PRIVATE: Notification handling -- - (void)_serviceMatching:(io_iterator_t)iterator; - (void)_serviceNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument; +- (void)_updateSessionInformation; +- (void)_secureInputNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument; @end @@ -288,6 +327,8 @@ extern NSString *kHIDRemoteLastButtonPressed; extern NSString *kHIDRemoteService; extern NSString *kHIDRemoteSimulateHoldEventsTimer; extern NSString *kHIDRemoteSimulateHoldEventsOriginButtonCode; +extern NSString *kHIDRemoteAluminumRemoteSupportLevel; +extern NSString *kHIDRemoteAluminumRemoteSupportOnDemand; #pragma mark -- Distributed notifications -- extern NSString *kHIDRemoteDNHIDRemotePing; diff --git a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m index 9b3769d304..502100250f 100644 --- a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m +++ b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m @@ -1,6 +1,6 @@ // // HIDRemote.m -// HIDRemote V1.0 +// HIDRemote V1.1 (13th November 2009) // // Created by Felix Schwarz on 06.04.07. // Copyright 2007-2009 IOSPIRIT GmbH. All rights reserved. @@ -40,8 +40,6 @@ // // ************************************************************************************ - - // ************************************************************************************ // ********************************** DOCUMENTATION *********************************** // ************************************************************************************ @@ -51,7 +49,6 @@ // // ************************************************************************************ - #import "HIDRemote.h" // Callback Prototypes @@ -68,6 +65,11 @@ static void ServiceNotificationCallback(void * refCon, natural_t messageType, void * messageArgument); +static void SecureInputNotificationCallback( void * refCon, + io_service_t service, + natural_t messageType, + void * messageArgument); + // Shared HIDRemote instance static HIDRemote *sHIDRemote = nil; @@ -87,7 +89,7 @@ static HIDRemote *sHIDRemote = nil; - (id)init { - if (self = [super init]) + if ((self = [super init]) != nil) { // Detect application becoming active/inactive [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]]; @@ -101,12 +103,13 @@ static HIDRemote *sHIDRemote = nil; // Enabled by default: simulate hold events for plus/minus _simulateHoldEvents = YES; - // Enabled by default: work around for a locking issue introduced with Security Update 2008-004 / 10.4.9 and beyond + // Enabled by default: work around for a locking issue introduced with Security Update 2008-004 / 10.4.9 and beyond (credit for finding this workaround goes to Martin Kahr) _secureEventInputWorkAround = YES; - _statusSecureEventInputWorkAroundEnabled = NO; + _secureInputNotification = 0; // Initialize instance variables _lastSeenRemoteID = -1; + _lastSeenModel = kHIDRemoteModelUndetermined; _unusedButtonCodes = [[NSMutableArray alloc] init]; _exclusiveLockLending = NO; } @@ -171,11 +174,6 @@ static HIDRemote *sHIDRemote = nil; // OS X 10.6(.0) and OS X 10.6.1 require the Candelair driver for to be installed, // so that third party apps can acquire an exclusive lock on the receiver HID Device // via IOKit. - // - // IMPORTANT: - // We do not include later OS releases here, because the issue may be fixed in these. - // We simply don't know at this point. Updated sourcecode will be available at - // candelair.com as necessary. switch (remoteMode) { @@ -194,25 +192,38 @@ static HIDRemote *sHIDRemote = nil; return (NO); } -#pragma mark -- PUBLIC: Interface / API -- -- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode +- (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel { - if ((_mode == kHIDRemoteModeNone) && (hidRemoteMode != kHIDRemoteModeNone)) + HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone; + NSEnumerator *attribDictsEnum; + NSDictionary *hidAttribsDict; + + attribDictsEnum = [_serviceAttribMap objectEnumerator]; + + while ((hidAttribsDict = [attribDictsEnum nextObject]) != nil) { - kern_return_t kernReturn; - CFMutableDictionaryRef matchDict=NULL; + NSNumber *deviceSupportLevel; - // Work around a locking issue introduced with Security Update 2008-004 / 10.4.9 and beyond - if ((_mode != kHIDRemoteModeShared) && (_secureEventInputWorkAround)) + if ((deviceSupportLevel = [hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel]) != nil) { - if (!_statusSecureEventInputWorkAroundEnabled) + if ([deviceSupportLevel intValue] > supportLevel) { - EnableSecureEventInput(); - - // Keep track of our use of EnableSecureEventInput()/DisableSecureEventInput() to avoid count "leaks" - _statusSecureEventInputWorkAroundEnabled = YES; + supportLevel = [deviceSupportLevel intValue]; } } + } + + return (supportLevel); +} + +#pragma mark -- PUBLIC: Interface / API -- +- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode +{ + if ((_mode == kHIDRemoteModeNone) && (hidRemoteMode != kHIDRemoteModeNone)) + { + kern_return_t kernReturn; + CFMutableDictionaryRef matchDict=NULL; + io_service_t rootService; do { @@ -223,7 +234,7 @@ static HIDRemote *sHIDRemote = nil; // Setup notification port _notifyPort = IONotificationPortCreate(_masterPort); - if (_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) + if ((_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) != NULL) { CFRunLoopAddSource( CFRunLoopGetCurrent(), _notifyRLSource, @@ -233,6 +244,27 @@ static HIDRemote *sHIDRemote = nil; { break; } + + // Setup SecureInput notification + if ((hidRemoteMode == kHIDRemoteModeExclusive) || (hidRemoteMode == kHIDRemoteModeExclusiveAuto)) + { + if ((rootService = IORegistryEntryFromPath(_masterPort, kIOServicePlane ":/")) != 0) + { + kernReturn = IOServiceAddInterestNotification( _notifyPort, + rootService, + kIOBusyInterest, + SecureInputNotificationCallback, + (void *)self, + &_secureInputNotification); + if (kernReturn != kIOReturnSuccess) { break; } + + [self _updateSessionInformation]; + } + else + { + break; + } + } // Setup notification matching dict matchDict = IOServiceMatching(kIOHIDDeviceKey); @@ -296,7 +328,7 @@ static HIDRemote *sHIDRemote = nil; NSEnumerator *mapKeyEnum = [cloneDict keyEnumerator]; NSNumber *serviceValue; - while (serviceValue = [mapKeyEnum nextObject]) + while ((serviceValue = [mapKeyEnum nextObject]) != nil) { [self _destructService:(io_object_t)[serviceValue unsignedIntValue]]; }; @@ -314,6 +346,12 @@ static HIDRemote *sHIDRemote = nil; IOObjectRelease((io_object_t) _matchingServicesIterator); _matchingServicesIterator = 0; } + + if (_secureInputNotification) + { + IOObjectRelease((io_object_t) _secureInputNotification); + _secureInputNotification = 0; + } if (_notifyRLSource) { @@ -333,12 +371,6 @@ static HIDRemote *sHIDRemote = nil; mach_port_deallocate(mach_task_self(), _masterPort); } - if (_statusSecureEventInputWorkAroundEnabled) - { - DisableSecureEventInput(); - _statusSecureEventInputWorkAroundEnabled = NO; - } - [self _postStatusWithAction:kHIDRemoteDNStatusActionStop]; [_returnToPID release]; @@ -362,6 +394,11 @@ static HIDRemote *sHIDRemote = nil; return (_lastSeenRemoteID); } +- (HIDRemoteModel)lastSeenModel +{ + return (_lastSeenModel); +} + - (void)setSimulateHoldEvents:(BOOL)newSimulateHoldEvents { _simulateHoldEvents = newSimulateHoldEvents; @@ -401,25 +438,6 @@ static HIDRemote *sHIDRemote = nil; - (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround { _secureEventInputWorkAround = newEnableSecureEventInputWorkaround; - - if ([self isStarted]) - { - if (_mode != kHIDRemoteModeShared) - { - // Changes go live immediately - if (_secureEventInputWorkAround && !_statusSecureEventInputWorkAroundEnabled) - { - EnableSecureEventInput(); - _statusSecureEventInputWorkAroundEnabled = YES; - } - - if (!_secureEventInputWorkAround && _statusSecureEventInputWorkAroundEnabled) - { - DisableSecureEventInput(); - _statusSecureEventInputWorkAroundEnabled = NO; - } - } - } } - (BOOL)enableSecureEventInputWorkaround @@ -663,16 +681,8 @@ static HIDRemote *sHIDRemote = nil; if (_waitForReturnByPID != nil) { - BOOL cachedStatusSecureEventInputWorkAroundEnabled; - - // Workaround for what seems to be a missing lock on the counter in the EnableSecureEventInput() / DisableSecureEventInput() API - cachedStatusSecureEventInputWorkAroundEnabled = _statusSecureEventInputWorkAroundEnabled; - _statusSecureEventInputWorkAroundEnabled = NO; - [self stopRemoteControl]; - _statusSecureEventInputWorkAroundEnabled = cachedStatusSecureEventInputWorkAroundEnabled; - [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry object:[NSString stringWithFormat:@"%d", [_waitForReturnByPID intValue]] userInfo:[NSDictionary dictionaryWithObjectsAndKeys: @@ -761,6 +771,101 @@ static HIDRemote *sHIDRemote = nil; return (serviceMatches); } +- (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage +{ + HIDRemoteButtonCode buttonCode = kHIDRemoteButtonCodeNone; + + switch (usagePage) + { + case kHIDPage_Consumer: + switch (usage) + { + case kHIDUsage_Csmr_MenuPick: + // Aluminum Remote: Center + buttonCode = (kHIDRemoteButtonCodeCenter|kHIDRemoteButtonCodeAluminumMask); + break; + + case kHIDUsage_Csmr_ModeStep: + // Aluminium Remote: Center Hold + buttonCode = (kHIDRemoteButtonCodeCenterHold|kHIDRemoteButtonCodeAluminumMask); + break; + + case kHIDUsage_Csmr_PlayOrPause: + // Aluminum Remote: Play/Pause + buttonCode = (kHIDRemoteButtonCodePlay|kHIDRemoteButtonCodeAluminumMask); + break; + + case kHIDUsage_Csmr_Rewind: + buttonCode = kHIDRemoteButtonCodeLeftHold; + break; + + case kHIDUsage_Csmr_FastForward: + buttonCode = kHIDRemoteButtonCodeRightHold; + break; + + case kHIDUsage_Csmr_Menu: + buttonCode = kHIDRemoteButtonCodeMenuHold; + break; + } + break; + + case kHIDPage_GenericDesktop: + switch (usage) + { + case kHIDUsage_GD_SystemAppMenu: + buttonCode = kHIDRemoteButtonCodeMenu; + break; + + case kHIDUsage_GD_SystemMenu: + buttonCode = kHIDRemoteButtonCodeCenter; + break; + + case kHIDUsage_GD_SystemMenuRight: + buttonCode = kHIDRemoteButtonCodeRight; + break; + + case kHIDUsage_GD_SystemMenuLeft: + buttonCode = kHIDRemoteButtonCodeLeft; + break; + + case kHIDUsage_GD_SystemMenuUp: + buttonCode = kHIDRemoteButtonCodeUp; + break; + + case kHIDUsage_GD_SystemMenuDown: + buttonCode = kHIDRemoteButtonCodeDown; + break; + } + break; + + case 0x06: /* Reserved */ + switch (usage) + { + case 0x22: + buttonCode = kHIDRemoteButtonCodeIDChanged; + break; + } + break; + + case 0xFF01: /* Vendor specific */ + switch (usage) + { + case 0x23: + buttonCode = kHIDRemoteButtonCodeCenterHold; + break; + + #ifdef _HIDREMOTE_EXTENSIONS + #define _HIDREMOTE_EXTENSIONS_SECTION 2 + #include "HIDRemoteAdditions.h" + #undef _HIDREMOTE_EXTENSIONS_SECTION + #endif /* _HIDREMOTE_EXTENSIONS */ + } + break; + } + + return (buttonCode); +} + - (BOOL)_setupService:(io_object_t)service { kern_return_t kernResult; @@ -913,78 +1018,14 @@ static HIDRemote *sHIDRemote = nil; if (usage && usagePage && cookie) { // Find the button codes for the ID combos - switch ([usagePage unsignedIntValue]) - { - case kHIDPage_Consumer: - switch ([usage unsignedIntValue]) - { - case kHIDUsage_Csmr_Rewind: - buttonCode = kHIDRemoteButtonCodeLeftHold; - break; - - case kHIDUsage_Csmr_FastForward: - buttonCode = kHIDRemoteButtonCodeRightHold; - break; - - case kHIDUsage_Csmr_Menu: - buttonCode = kHIDRemoteButtonCodeMenuHold; - break; - } - break; - - case kHIDPage_GenericDesktop: - switch ([usage unsignedIntValue]) - { - case kHIDUsage_GD_SystemAppMenu: - buttonCode = kHIDRemoteButtonCodeMenu; - break; - - case kHIDUsage_GD_SystemMenu: - buttonCode = kHIDRemoteButtonCodePlayPause; - break; - - case kHIDUsage_GD_SystemMenuRight: - buttonCode = kHIDRemoteButtonCodeRight; - break; - - case kHIDUsage_GD_SystemMenuLeft: - buttonCode = kHIDRemoteButtonCodeLeft; - break; - - case kHIDUsage_GD_SystemMenuUp: - buttonCode = kHIDRemoteButtonCodePlus; - break; - - case kHIDUsage_GD_SystemMenuDown: - buttonCode = kHIDRemoteButtonCodeMinus; - break; - } - break; - - case 0x06: /* Resered */ - switch ([usage unsignedIntValue]) - { - case 0x22: - buttonCode = kHIDRemoteButtonCodeIDChanged; - break; - } - break; - - case 0xff01: /* Vendor specific */ - switch ([usage unsignedIntValue]) - { - case 0x23: - buttonCode = kHIDRemoteButtonCodePlayPauseHold; - break; - - #ifdef _HIDREMOTE_EXTENSIONS - #define _HIDREMOTE_EXTENSIONS_SECTION 2 - #include "HIDRemoteAdditions.h" - #undef _HIDREMOTE_EXTENSIONS_SECTION - #endif /* _HIDREMOTE_EXTENSIONS */ - } - break; - } + buttonCode = [self buttonCodeForUsage:[usage unsignedIntValue] usagePage:[usagePage unsignedIntValue]]; + + #ifdef _HIDREMOTE_EXTENSIONS + // Debug logging code + #define _HIDREMOTE_EXTENSIONS_SECTION 3 + #include "HIDRemoteAdditions.h" + #undef _HIDREMOTE_EXTENSIONS_SECTION + #endif /* _HIDREMOTE_EXTENSIONS */ // Did record match? if (buttonCode != kHIDRemoteButtonCodeNone) @@ -992,6 +1033,13 @@ static HIDRemote *sHIDRemote = nil; NSString *pairString = [[NSString alloc] initWithFormat:@"%u_%u", [usagePage unsignedIntValue], [usage unsignedIntValue]]; NSNumber *buttonCodeNumber = [[NSNumber alloc] initWithUnsignedInt:(unsigned int)buttonCode]; + #ifdef _HIDREMOTE_EXTENSIONS + // Debug logging code + #define _HIDREMOTE_EXTENSIONS_SECTION 4 + #include "HIDRemoteAdditions.h" + #undef _HIDREMOTE_EXTENSIONS_SECTION + #endif /* _HIDREMOTE_EXTENSIONS */ + [cookieCount setObject:buttonCodeNumber forKey:pairString]; [cookieButtonCodeLUT setObject:buttonCodeNumber forKey:cookie]; @@ -1131,6 +1179,91 @@ static HIDRemote *sHIDRemote = nil; } } + // Determine Aluminum Remote support + { + CFNumberRef aluSupport; + HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone; + + if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto)) + { + // Determine if this driver offers on-demand support for the Aluminum Remote (only relevant under OS versions < 10.6.2) + if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, + (CFStringRef) @"AluminumRemoteSupportLevelOnDemand", + kCFAllocatorDefault, + 0)) != nil) + { + // There is => request the driver to enable it for us + if (IORegistryEntrySetCFProperty((io_registry_entry_t)service, + CFSTR("EnableAluminumRemoteSupportForMe"), + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithLongLong:(long long)getpid()], @"pid", + [NSNumber numberWithLongLong:(long long)getuid()], @"uid", + nil]) == kIOReturnSuccess) + { + if (CFGetTypeID(aluSupport) == CFNumberGetTypeID()) + { + supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(NSNumber *)aluSupport intValue]; + } + + [hidAttribsDict setObject:[NSNumber numberWithBool:YES] forKey:kHIDRemoteAluminumRemoteSupportOnDemand]; + } + + CFRelease(aluSupport); + } + } + + if (supportLevel == kHIDRemoteAluminumRemoteSupportLevelNone) + { + if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, + (CFStringRef) @"AluminumRemoteSupportLevel", + kCFAllocatorDefault, + 0)) != nil) + { + if (CFGetTypeID(aluSupport) == CFNumberGetTypeID()) + { + supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(NSNumber *)aluSupport intValue]; + } + + CFRelease(aluSupport); + } + else + { + CFStringRef ioKitClassName; + + if ((ioKitClassName = IORegistryEntryCreateCFProperty( (io_registry_entry_t)service, + CFSTR(kIOClassKey), + kCFAllocatorDefault, + 0)) != nil) + { + if ([(NSString *)ioKitClassName isEqual:@"AppleIRController"]) + { + SInt32 systemVersion; + + if (Gestalt(gestaltSystemVersion, &systemVersion) == noErr) + { + if (systemVersion >= 0x1062) + { + // Support for the Aluminum Remote was added only with OS 10.6.2. Previous versions can not distinguish + // between the Center and the new, seperate Play/Pause button. They'll recognize both as presses of the + // "Center" button. + // + // You CAN, however, receive Aluminum Remote button presses even under OS 10.5 when using Remote Buddy's + // Virtual Remote. While Remote Buddy does support the Aluminum Remote across all OS releases it runs on, + // its Virtual Remote can only emulate Aluminum Remote button presses under OS 10.5 and up in order not to + // break compatibility with applications whose IR Remote code relies on driver internals. [13-Nov-09] + supportLevel = kHIDRemoteAluminumRemoteSupportLevelNative; + } + } + } + + CFRelease(ioKitClassName); + } + } + } + + [hidAttribsDict setObject:(NSNumber *)[NSNumber numberWithInt:(int)supportLevel] forKey:kHIDRemoteAluminumRemoteSupportLevel]; + } + // Add it to the serviceAttribMap [_serviceAttribMap setObject:hidAttribsDict forKey:[NSNumber numberWithUnsignedInt:(unsigned int)service]]; @@ -1255,6 +1388,17 @@ static HIDRemote *sHIDRemote = nil; [serviceDict retain]; [_serviceAttribMap removeObjectForKey:serviceValue]; + if (([serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand]!=nil) && [[serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand] boolValue] && (theService != 0)) + { + // We previously requested the driver to enable Aluminum Remote support for us. Tell it to turn it off again - now that we no longer need it + IORegistryEntrySetCFProperty( (io_registry_entry_t)theService, + CFSTR("DisableAluminumRemoteSupportForMe"), + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithLongLong:(long long)getpid()], @"pid", + [NSNumber numberWithLongLong:(long long)getuid()], @"uid", + nil]); + } + if (([self delegate]!=nil) && ([[self delegate] respondsToSelector:@selector(hidRemote:releasedHardwareWithAttributes:)])) { @@ -1283,7 +1427,7 @@ static HIDRemote *sHIDRemote = nil; NSEnumerator *cookieEnum = [cookieButtonMap keyEnumerator]; NSNumber *cookie; - while (cookie = [cookieEnum nextObject]) + while ((cookie = [cookieEnum nextObject]) != nil) { if ((*hidQueueInterface)->hasElement(hidQueueInterface, (IOHIDElementCookie) [cookie unsignedIntValue])) { @@ -1349,8 +1493,8 @@ static HIDRemote *sHIDRemote = nil; // Do nothing, this is handled seperately break; - case kHIDRemoteButtonCodePlus: - case kHIDRemoteButtonCodeMinus: + case kHIDRemoteButtonCodeUp: + case kHIDRemoteButtonCodeDown: if (_simulateHoldEvents) { NSTimer *shTimer = nil; @@ -1412,7 +1556,38 @@ static HIDRemote *sHIDRemote = nil; if (([self delegate]!=nil) && ([[self delegate] respondsToSelector:@selector(hidRemote:eventWithButton:isPressed:fromHardwareWithAttributes:)])) { - [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self eventWithButton:buttonCode isPressed:isPressed fromHardwareWithAttributes:hidAttribsDict]; + switch (buttonCode & (~kHIDRemoteButtonCodeAluminumMask)) + { + case kHIDRemoteButtonCodePlay: + case kHIDRemoteButtonCodeCenter: + if (buttonCode & kHIDRemoteButtonCodeAluminumMask) + { + _lastSeenModel = kHIDRemoteModelAluminum; + _lastSeenModelRemoteID = _lastSeenRemoteID; + } + else + { + switch ((HIDRemoteAluminumRemoteSupportLevel)[[hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel] intValue]) + { + case kHIDRemoteAluminumRemoteSupportLevelNone: + case kHIDRemoteAluminumRemoteSupportLevelEmulation: + // Remote type can't be determined by just the Center button press + break; + + case kHIDRemoteAluminumRemoteSupportLevelNative: + // Remote type can be safely determined by just the Center button press + if (((_lastSeenModel == kHIDRemoteModelAluminum) && (_lastSeenModelRemoteID != _lastSeenRemoteID)) || + (_lastSeenModel == kHIDRemoteModelUndetermined)) + { + _lastSeenModel = kHIDRemoteModelWhitePlastic; + } + break; + } + } + break; + } + + [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self eventWithButton:(buttonCode & (~kHIDRemoteButtonCodeAluminumMask)) isPressed:isPressed fromHardwareWithAttributes:hidAttribsDict]; } } @@ -1453,6 +1628,13 @@ static HIDRemote *sHIDRemote = nil; { NSNumber *buttonCodeNumber = [cookieButtonMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int) hidEvent.elementCookie]]; + #ifdef _HIDREMOTE_EXTENSIONS + // Debug logging code + #define _HIDREMOTE_EXTENSIONS_SECTION 5 + #include "HIDRemoteAdditions.h" + #undef _HIDREMOTE_EXTENSIONS_SECTION + #endif /* _HIDREMOTE_EXTENSIONS */ + if (buttonCodeNumber) { HIDRemoteButtonCode buttonCode = [buttonCodeNumber unsignedIntValue]; @@ -1483,6 +1665,7 @@ static HIDRemote *sHIDRemote = nil; } _lastSeenRemoteID = hidEvent.value; + _lastSeenModel = kHIDRemoteModelUndetermined; } [self _handleButtonCode:buttonCode isPressed:YES hidAttribsDict:hidAttribsDict]; @@ -1494,6 +1677,13 @@ static HIDRemote *sHIDRemote = nil; [hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:lastButtonPressed] forKey:kHIDRemoteLastButtonPressed]; } + + #ifdef _HIDREMOTE_EXTENSIONS + // Debug logging code + #define _HIDREMOTE_EXTENSIONS_SECTION 6 + #include "HIDRemoteAdditions.h" + #undef _HIDREMOTE_EXTENSIONS_SECTION + #endif /* _HIDREMOTE_EXTENSIONS */ } } @@ -1502,7 +1692,7 @@ static HIDRemote *sHIDRemote = nil; { io_object_t matchingService = 0; - while (matchingService = IOIteratorNext(iterator)) + while ((matchingService = IOIteratorNext(iterator)) != 0) { [self _setupService:matchingService]; @@ -1518,6 +1708,89 @@ static HIDRemote *sHIDRemote = nil; } } +- (void)_updateSessionInformation +{ + NSArray *consoleUsersArray; + io_service_t rootService; + + if ((rootService = IORegistryGetRootEntry(_masterPort)) != 0) + { + if ((consoleUsersArray = (NSArray *)IORegistryEntryCreateCFProperty((io_registry_entry_t)rootService, CFSTR("IOConsoleUsers"), kCFAllocatorDefault, 0)) != nil) + { + if ([consoleUsersArray isKindOfClass:[NSArray class]]) // Be careful - ensure this really is an array + { + NSEnumerator *consoleUsersEnum; // I *love* Obj-C2's fast enumerators, but we need to stay compatible with 10.4 :-/ + + if ((consoleUsersEnum = [consoleUsersArray objectEnumerator]) != nil) + { + UInt64 secureEventInputPIDSum = 0; + uid_t frontUserSession = 0; + NSDictionary *consoleUserDict; + + while ((consoleUserDict = [consoleUsersEnum nextObject]) != nil) + { + if ([consoleUserDict isKindOfClass:[NSDictionary class]]) // Be careful - ensure this really is a dictionary + { + NSNumber *secureInputPID; + NSNumber *onConsole; + NSNumber *userID; + + if ((secureInputPID = [consoleUserDict objectForKey:@"kCGSSessionSecureInputPID"]) != nil) + { + if ([secureInputPID isKindOfClass:[NSNumber class]]) + { + secureEventInputPIDSum += ((UInt64) [secureInputPID intValue]); + } + } + + if (((onConsole = [consoleUserDict objectForKey:@"kCGSSessionOnConsoleKey"]) != nil) && + ((userID = [consoleUserDict objectForKey:@"kCGSSessionUserIDKey"]) != nil)) + { + if ([onConsole isKindOfClass:[NSNumber class]] && [userID isKindOfClass:[NSNumber class]]) + { + if ([onConsole boolValue]) + { + frontUserSession = (uid_t) [userID intValue]; + } + } + } + } + } + + _lastSecureEventInputPIDSum = secureEventInputPIDSum; + _lastFrontUserSession = frontUserSession; + } + } + + CFRelease((CFTypeRef)consoleUsersArray); + } + + IOObjectRelease((io_object_t) rootService); + } +} + +- (void)_secureInputNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument +{ + if (messageType == kIOMessageServiceBusyStateChange) + { + UInt64 old_lastSecureEventInputPIDSum = _lastSecureEventInputPIDSum; + uid_t old_lastFrontUserSession = _lastFrontUserSession; + + [self _updateSessionInformation]; + + if (((old_lastSecureEventInputPIDSum != _lastSecureEventInputPIDSum) || (old_lastFrontUserSession != _lastFrontUserSession)) && _secureEventInputWorkAround) + { + if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto)) + { + HIDRemoteMode restartInMode = _mode; + + [self stopRemoteControl]; + [self startRemoteControl:restartInMode]; + } + } + } +} + @end #pragma mark -- PRIVATE: IOKitLib Callbacks -- @@ -1562,6 +1835,21 @@ static void ServiceNotificationCallback(void * refCon, [pool release]; } +static void SecureInputNotificationCallback( void * refCon, + io_service_t service, + natural_t messageType, + void * messageArgument) +{ + HIDRemote *hidRemote = (HIDRemote *)refCon; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [hidRemote _secureInputNotificationFor:service + messageType:messageType + messageArgument:messageArgument]; + + [pool release]; +} + // Attribute dictionary keys NSString *kHIDRemoteCFPluginInterface = @"CFPluginInterface"; NSString *kHIDRemoteHIDDeviceInterface = @"HIDDeviceInterface"; @@ -1573,6 +1861,8 @@ NSString *kHIDRemoteLastButtonPressed = @"LastButtonPressed"; NSString *kHIDRemoteService = @"Service"; NSString *kHIDRemoteSimulateHoldEventsTimer = @"SimulateHoldEventsTimer"; NSString *kHIDRemoteSimulateHoldEventsOriginButtonCode = @"SimulateHoldEventsOriginButtonCode"; +NSString *kHIDRemoteAluminumRemoteSupportLevel = @"AluminumRemoteSupportLevel"; +NSString *kHIDRemoteAluminumRemoteSupportOnDemand = @"AluminumRemoteSupportLevelOnDemand"; NSString *kHIDRemoteManufacturer = @"Manufacturer"; NSString *kHIDRemoteProduct = @"Product"; diff --git a/tools/EventClients/Clients/OSXRemote/XBMCHelper.m b/tools/EventClients/Clients/OSXRemote/XBMCHelper.m index a4b8490cb5..44f9502bd0 100644 --- a/tools/EventClients/Clients/OSXRemote/XBMCHelper.m +++ b/tools/EventClients/Clients/OSXRemote/XBMCHelper.m @@ -125,13 +125,13 @@ } switch(buttonCode) { - case kHIDRemoteButtonCodePlus: + case kHIDRemoteButtonCodeUp: if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_UP]; else [mp_wrapper handleEvent:ATV_BUTTON_UP_RELEASE]; break; - case kHIDRemoteButtonCodeMinus: + case kHIDRemoteButtonCodeDown: if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_DOWN]; else @@ -143,29 +143,14 @@ else [mp_wrapper handleEvent:ATV_BUTTON_LEFT_RELEASE]; break; - case kHIDRemoteButtonCodeLeftHold: - if(isPressed) - [mp_wrapper handleEvent:ATV_BUTTON_LEFT_H]; - else - [mp_wrapper handleEvent:ATV_BUTTON_LEFT_H_RELEASE]; - break; case kHIDRemoteButtonCodeRight: if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_RIGHT]; else [mp_wrapper handleEvent:ATV_BUTTON_RIGHT_RELEASE]; - break; - case kHIDRemoteButtonCodeRightHold: - if(isPressed) - [mp_wrapper handleEvent:ATV_BUTTON_RIGHT_H]; - else - [mp_wrapper handleEvent:ATV_BUTTON_RIGHT_H_RELEASE]; - break; - case kHIDRemoteButtonCodePlayPause: - if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_PLAY]; - break; - case kHIDRemoteButtonCodePlayPauseHold: - if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_PLAY_H]; + break; + case kHIDRemoteButtonCodeCenter: + if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_CENTER]; break; case kHIDRemoteButtonCodeMenu: if(isPressed){ @@ -173,12 +158,36 @@ [mp_wrapper handleEvent:ATV_BUTTON_MENU]; } break; + case kHIDRemoteButtonCodeUpHold: + //TODO + break; + case kHIDRemoteButtonCodeDownHold: + //TODO + break; + case kHIDRemoteButtonCodeLeftHold: + if(isPressed) + [mp_wrapper handleEvent:ATV_BUTTON_LEFT_H]; + else + [mp_wrapper handleEvent:ATV_BUTTON_LEFT_H_RELEASE]; + break; + case kHIDRemoteButtonCodeRightHold: + if(isPressed) + [mp_wrapper handleEvent:ATV_BUTTON_RIGHT_H]; + else + [mp_wrapper handleEvent:ATV_BUTTON_RIGHT_H_RELEASE]; + break; + case kHIDRemoteButtonCodeCenterHold: + if(isPressed) [mp_wrapper handleEvent:ATV_BUTTON_CENTER_H]; + break; case kHIDRemoteButtonCodeMenuHold: if(isPressed) { [self checkAndLaunchApp]; //launch mp_app_path if it's not running [mp_wrapper handleEvent:ATV_BUTTON_MENU_H]; } break; + case kHIDRemoteButtonCodePlayHold: + //TODO + break; default: NSLog(@"Oha, remote button not recognized %i pressed/released %i", buttonCode, isPressed); } diff --git a/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.h b/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.h index cd27e290fa..60c1d8e459 100644 --- a/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.h +++ b/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.h @@ -22,8 +22,8 @@ typedef enum{ ATV_BUTTON_DONT_USE_THIS = 0, //don't use zero, as those enums get converted to strings later - ATV_BUTTON_PLAY=1, - ATV_BUTTON_PLAY_H, //present on ATV>=2.2 + ATV_BUTTON_CENTER=1, + ATV_BUTTON_CENTER_H, //present on ATV>=2.2 ATV_BUTTON_RIGHT, ATV_BUTTON_RIGHT_RELEASE, ATV_BUTTON_RIGHT_H, //present on ATV<=2.1 and OSX v? diff --git a/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.mm b/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.mm index 42369e516b..3475f2191d 100644 --- a/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.mm +++ b/tools/EventClients/Clients/OSXRemote/xbmcclientwrapper.mm @@ -261,7 +261,7 @@ void XBMCClientWrapperImpl::handleEvent(eATVClientEvent f_event){ void XBMCClientWrapperImpl::populateEventMap(){ tEventMap& lr_map = m_event_map; - lr_map.insert(std::make_pair(ATV_BUTTON_PLAY, new CPacketBUTTON(5, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + lr_map.insert(std::make_pair(ATV_BUTTON_CENTER, new CPacketBUTTON(5, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); lr_map.insert(std::make_pair(ATV_BUTTON_RIGHT, new CPacketBUTTON(4, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); lr_map.insert(std::make_pair(ATV_BUTTON_RIGHT_RELEASE, new CPacketBUTTON(4, "JS0:AppleRemote", BTN_UP | BTN_NO_REPEAT | BTN_QUEUE))); lr_map.insert(std::make_pair(ATV_BUTTON_LEFT, new CPacketBUTTON(3, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT| BTN_QUEUE))); @@ -280,7 +280,7 @@ void XBMCClientWrapperImpl::populateEventMap(){ lr_map.insert(std::make_pair(ATV_BUTTON_LEFT_H_RELEASE, new CPacketBUTTON(11, "JS0:AppleRemote", BTN_UP | BTN_QUEUE))); // only present on atv >= 2.2 - lr_map.insert(std::make_pair(ATV_BUTTON_PLAY_H, new CPacketBUTTON(7, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + lr_map.insert(std::make_pair(ATV_BUTTON_CENTER_H, new CPacketBUTTON(7, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); //learned remote buttons (ATV >=2.3) lr_map.insert(std::make_pair(ATV_LEARNED_PLAY, new CPacketBUTTON(70, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -300,7 +300,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ XBMCClientEventSequence sequence_prefix; sequence_prefix << ATV_BUTTON_MENU_H; m_sequence_map.insert(std::make_pair(sequence_prefix, new CPacketBUTTON(8, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); - m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_PLAY, new CPacketBUTTON(20, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_CENTER, new CPacketBUTTON(20, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_RIGHT, new CPacketBUTTON(21, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_LEFT, new CPacketBUTTON(22, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_UP, new CPacketBUTTON(23, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -308,8 +308,8 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_MENU, new CPacketBUTTON(25, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); sequence_prefix.clear(); - sequence_prefix << ATV_BUTTON_MENU_H << ATV_BUTTON_PLAY; - m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_PLAY, new CPacketBUTTON(26, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + sequence_prefix << ATV_BUTTON_MENU_H << ATV_BUTTON_CENTER; + m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_CENTER, new CPacketBUTTON(26, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_RIGHT, new CPacketBUTTON(27, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_LEFT, new CPacketBUTTON(28, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_UP, new CPacketBUTTON(29, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -318,7 +318,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ sequence_prefix.clear(); sequence_prefix << ATV_BUTTON_MENU_H << ATV_BUTTON_UP; - m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_PLAY, new CPacketBUTTON(32, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_CENTER, new CPacketBUTTON(32, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_RIGHT, new CPacketBUTTON(33, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_LEFT, new CPacketBUTTON(34, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_UP, new CPacketBUTTON(35, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -327,7 +327,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ sequence_prefix.clear(); sequence_prefix << ATV_BUTTON_MENU_H << ATV_BUTTON_DOWN; - m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_PLAY, new CPacketBUTTON(38, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_CENTER, new CPacketBUTTON(38, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_RIGHT, new CPacketBUTTON(39, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_LEFT, new CPacketBUTTON(40, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_UP, new CPacketBUTTON(41, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -336,7 +336,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ sequence_prefix.clear(); sequence_prefix << ATV_BUTTON_MENU_H << ATV_BUTTON_RIGHT; - m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_PLAY, new CPacketBUTTON(44, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_CENTER, new CPacketBUTTON(44, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_RIGHT, new CPacketBUTTON(45, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_LEFT, new CPacketBUTTON(46, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_UP, new CPacketBUTTON(47, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -345,7 +345,7 @@ void XBMCClientWrapperImpl::populateSequenceMap(){ sequence_prefix.clear(); sequence_prefix << ATV_BUTTON_MENU_H << ATV_BUTTON_LEFT; - m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_PLAY, new CPacketBUTTON(50, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_CENTER, new CPacketBUTTON(50, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_RIGHT, new CPacketBUTTON(51, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_LEFT, new CPacketBUTTON(52, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_sequence_map.insert(std::make_pair( sequence_prefix + ATV_BUTTON_UP, new CPacketBUTTON(53, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); @@ -379,9 +379,9 @@ void XBMCClientWrapperImpl::populateMultiRemoteModeMap(){ m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_RIGHT), new CPacketBUTTON(4 + offset, "JS0:Harmony", BTN_DOWN | BTN_QUEUE))); m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_RIGHT_RELEASE), new CPacketBUTTON(4 + offset, "JS0:Harmony", BTN_UP | BTN_QUEUE))); - m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_PLAY), new CPacketBUTTON(5 + offset, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_CENTER), new CPacketBUTTON(5 + offset, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_MENU), new CPacketBUTTON(6 + offset, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); - m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_PLAY_H), new CPacketBUTTON(7 + offset, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); + m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_CENTER_H), new CPacketBUTTON(7 + offset, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_MENU_H), new CPacketBUTTON(8 + offset, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE))); m_multiremote_map.insert(std::make_pair(std::make_pair(*device_id,ATV_BUTTON_RIGHT_H), new CPacketBUTTON(9 + offset, "JS0:Harmony", BTN_DOWN | BTN_QUEUE))); |