Revision: 15673 http://sourceforge.net/p/skim-app/code/15673 Author: hofman Date: 2025-08-17 17:12:35 +0000 (Sun, 17 Aug 2025) Log Message: ----------- replace HIDRemote sources with newest version
Modified Paths: -------------- trunk/SKColorPicker.m trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.h trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.m Modified: trunk/SKColorPicker.m =================================================================== --- trunk/SKColorPicker.m 2025-08-17 16:38:37 UTC (rev 15672) +++ trunk/SKColorPicker.m 2025-08-17 17:12:35 UTC (rev 15673) @@ -100,7 +100,7 @@ NSScrubberItemView *itemView = [aScrubber makeItemWithIdentifier:COLOR_IDENTIFIER owner:nil]; NSImageView *imageView = [[itemView subviews] firstObject]; if (imageView == nil || [imageView isKindOfClass:[NSImageView class]] == NO || [[imageView cell] isKindOfClass:[SKColorCell class]] == NO) { - imageView = [[NSImageView alloc] initWithFrame:[itemView bounds]]; + imageView = [[SKColorView alloc] initWithFrame:[itemView bounds]]; SKColorCell *colorCell = [[SKColorCell alloc] init]; [colorCell setShouldFill:YES]; [imageView setCell:colorCell]; Modified: trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.h =================================================================== --- trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.h 2025-08-17 16:38:37 UTC (rev 15672) +++ trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.h 2025-08-17 17:12:35 UTC (rev 15673) @@ -1,9 +1,9 @@ // -// HIDRemote.h -// HIDRemote V1.2 +// HIDRemote.m +// HIDRemote V1.7 (5th September 2018) // // Created by Felix Schwarz on 06.04.07. -// Copyright 2007-2011 IOSPIRIT GmbH. All rights reserved. +// Copyright 2007-2018 IOSPIRIT GmbH. All rights reserved. // // The latest version of this class is available at // http://www.iospirit.com/developers/hidremote/ @@ -10,23 +10,23 @@ // // ** LICENSE ************************************************************************* // -// Copyright (c) 2007-2011 IOSPIRIT GmbH (http://www.iospirit.com/) +// Copyright (c) 2007-2017 IOSPIRIT GmbH (http://www.iospirit.com/) // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: -// +// // * Redistributions of source code must retain the above copyright notice, this list // of conditions and the following disclaimer. -// +// // * Redistributions in binary form must reproduce the above copyright notice, this // list of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior // written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT @@ -40,7 +40,6 @@ // // ************************************************************************************ - // ************************************************************************************ // ********************************** DOCUMENTATION *********************************** // ************************************************************************************ @@ -50,9 +49,32 @@ // // ************************************************************************************ - #import <Cocoa/Cocoa.h> +// For legacy SDKs +#ifndef MAC_OS_X_VERSION_10_9 +#define MAC_OS_X_VERSION_10_9 1090 +#endif /* MAC_OS_X_VERSION_10_9 */ + +#ifndef MAC_OS_X_VERSION_10_10 +#define MAC_OS_X_VERSION_10_10 101000 +#endif /* MAC_OS_X_VERSION_10_10 */ + +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10 +// Carbon is only required on OS X versions prior to 10.10 (for getting the OS version via Gestalt() - +// replaced by [[NSProcessInfo processInfo] operatingSystemVersion] in 10.10) +#include <Carbon/Carbon.h> +#endif + +#ifndef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + // Enable thread-safe notification handling by default if deploying to OS X >= 10.5 + #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING 1 + #else + #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING 0 + #endif +#endif + #include <unistd.h> #include <mach/mach.h> #include <sys/types.h> @@ -67,209 +89,213 @@ #include <IOKit/hidsystem/IOHIDParameter.h> #include <IOKit/hidsystem/IOHIDShared.h> -#pragma mark -- Enums / Codes -- +#pragma mark - Enums / Codes +#ifndef HID_REMOTE_MODE_ENUM +#define HID_REMOTE_MODE_ENUM 1 typedef enum { - kHIDRemoteModeNone = 0L, - kHIDRemoteModeShared, // Share the remote with others - let's you listen to the remote control events as long as noone has an exclusive lock on it - // (RECOMMENDED ONLY FOR SPECIAL PURPOSES) + kHIDRemoteModeNone = 0L, + kHIDRemoteModeShared, // Share the remote with others - let's you listen to the remote control events as long as noone has an exclusive lock on it + // (RECOMMENDED ONLY FOR SPECIAL PURPOSES) - kHIDRemoteModeExclusive, // Try to acquire an exclusive lock on the remote (NOT RECOMMENDED) + kHIDRemoteModeExclusive, // Try to acquire an exclusive lock on the remote (NOT RECOMMENDED) - kHIDRemoteModeExclusiveAuto // Try to acquire an exclusive lock on the remote whenever the application has focus. Temporarily release control over the - // remote when another application has focus (RECOMMENDED) + kHIDRemoteModeExclusiveAuto // Try to acquire an exclusive lock on the remote whenever the application has focus. Temporarily release control over the + // remote when another application has focus (RECOMMENDED) } HIDRemoteMode; +#endif /* HID_REMOTE_MODE_ENUM */ typedef enum { - /* A code reserved for "no button" (needed for tracking) */ - kHIDRemoteButtonCodeNone = 0L, + /* A code reserved for "no button" (needed for tracking) */ + kHIDRemoteButtonCodeNone = 0L, - /* Standard codes - available for white plastic and aluminum remote */ - kHIDRemoteButtonCodeUp, - kHIDRemoteButtonCodeDown, - kHIDRemoteButtonCodeLeft, - kHIDRemoteButtonCodeRight, - kHIDRemoteButtonCodeCenter, - kHIDRemoteButtonCodeMenu, + /* Standard codes - available for white plastic and aluminum remote */ + kHIDRemoteButtonCodeUp, + kHIDRemoteButtonCodeDown, + kHIDRemoteButtonCodeLeft, + kHIDRemoteButtonCodeRight, + kHIDRemoteButtonCodeCenter, + kHIDRemoteButtonCodeMenu, - /* Extra codes - Only available for the new aluminum version of the remote */ - kHIDRemoteButtonCodePlay, + /* Extra codes - Only available for the new aluminum version of the remote */ + kHIDRemoteButtonCodePlay, - /* Masks */ - kHIDRemoteButtonCodeCodeMask = 0xFFL, - kHIDRemoteButtonCodeHoldMask = (1L << 16L), - kHIDRemoteButtonCodeSpecialMask = (1L << 17L), - kHIDRemoteButtonCodeAluminumMask = (1L << 21L), // PRIVATE - only used internally + /* Masks */ + 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 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), + /* 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, + /* 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) - #ifdef _HIDREMOTE_EXTENSIONS - #define _HIDREMOTE_EXTENSIONS_SECTION 1 - #include "HIDRemoteAdditions.h" - #undef _HIDREMOTE_EXTENSIONS_SECTION - #endif /* _HIDREMOTE_EXTENSIONS */ + /* Special purpose codes */ + kHIDRemoteButtonCodeIDChanged = (kHIDRemoteButtonCodeSpecialMask|(1L << 18L)), // (the ID of the connected remote has changed, you can safely ignore this) + #ifdef _HIDREMOTE_EXTENSIONS + #define _HIDREMOTE_EXTENSIONS_SECTION 1 + #include "HIDRemoteAdditions.h" + #undef _HIDREMOTE_EXTENSIONS_SECTION + #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 + 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 + 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) -- +#pragma mark - Delegate protocol (mandatory) @protocol HIDRemoteDelegate // Notification of button events -- (void)hidRemote:(HIDRemote *)hidRemote // The instance of HIDRemote sending this - eventWithButton:(HIDRemoteButtonCode)buttonCode // Event for the button specified by code - isPressed:(BOOL)isPressed // The button was pressed (YES) / released (NO) - fromHardwareWithAttributes:(NSMutableDictionary *)attributes; // Information on the device this event comes from +- (void)hidRemote:(HIDRemote *)hidRemote // The instance of HIDRemote sending this + eventWithButton:(HIDRemoteButtonCode)buttonCode // Event for the button specified by code + isPressed:(BOOL)isPressed // The button was pressed (YES) / released (NO) + fromHardwareWithAttributes:(NSMutableDictionary *)attributes; // Information on the device this event comes from @optional // Notification of ID changes -- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when the user switched to a remote control with a different ID - remoteIDChangedOldID:(SInt32)old - newID:(SInt32)newID - forHardwareWithAttributes:(NSMutableDictionary *)attributes; +- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when the user switched to a remote control with a different ID + remoteIDChangedOldID:(SInt32)old + newID:(SInt32)newID + forHardwareWithAttributes:(NSMutableDictionary *)attributes; -// Notification about hardware additions/removals -- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware was found / added to HIDRemote's pool - foundNewHardwareWithAttributes:(NSMutableDictionary *)attributes; +// Notification about hardware additions/removals +- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware was found / added to HIDRemote's pool + foundNewHardwareWithAttributes:(NSMutableDictionary *)attributes; -- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when initialization of new hardware as requested failed - failedNewHardwareWithError:(NSError *)error; +- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when initialization of new hardware as requested failed + failedNewHardwareWithError:(NSError *)error; -- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when hardware was removed from HIDRemote's pool - releasedHardwareWithAttributes:(NSMutableDictionary *)attributes; +- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when hardware was removed from HIDRemote's pool + releasedHardwareWithAttributes:(NSMutableDictionary *)attributes; // ### WARNING: Unless you know VERY PRECISELY what you are doing, do not implement any of the delegate methods below. ### // Matching of newly found receiver hardware -- (BOOL)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware is inspected - inspectNewHardwareWithService:(io_service_t)service // - prematchResult:(BOOL)prematchResult; // Return YES if HIDRemote should go on with this hardware and try - // to use it, or NO if it should not be persued further. +- (BOOL)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware is inspected + inspectNewHardwareWithService:(io_service_t)service // + prematchResult:(BOOL)prematchResult; // Return YES if HIDRemote should go on with this hardware and try + // to use it, or NO if it should not be persued further. // Exlusive lock lending - (BOOL)hidRemote:(HIDRemote *)hidRemote - lendExclusiveLockToApplicationWithInfo:(NSDictionary *)applicationInfo; + lendExclusiveLockToApplicationWithInfo:(NSDictionary *)applicationInfo; - (void)hidRemote:(HIDRemote *)hidRemote - exclusiveLockReleasedByApplicationWithInfo:(NSDictionary *)applicationInfo; + exclusiveLockReleasedByApplicationWithInfo:(NSDictionary *)applicationInfo; - (BOOL)hidRemote:(HIDRemote *)hidRemote - shouldRetryExclusiveLockWithInfo:(NSDictionary *)applicationInfo; + shouldRetryExclusiveLockWithInfo:(NSDictionary *)applicationInfo; -@end +@end -#pragma mark -- Actual header file for class -- - +#pragma mark - Actual header file for class @interface HIDRemote : NSObject { - // IOMasterPort - mach_port_t _masterPort; + // IOMasterPort + mach_port_t _masterPort; - // Notification ports - IONotificationPortRef _notifyPort; - CFRunLoopSourceRef _notifyRLSource; - - // Matching iterator - io_iterator_t _matchingServicesIterator; - - // SecureInput notification - io_object_t _secureInputNotification; - - // Service attributes - NSMutableDictionary *_serviceAttribMap; - - // Mode - HIDRemoteMode _mode; - BOOL _autoRecover; - NSTimer *_autoRecoveryTimer; - - // Delegate - NSObject <HIDRemoteDelegate> *_delegate; - - // Last seen ID and remote model - SInt32 _lastSeenRemoteID; - HIDRemoteModel _lastSeenModel; - SInt32 _lastSeenModelRemoteID; - - // Unused button codes - NSArray *_unusedButtonCodes; - - // Simulate Plus/Minus Hold - BOOL _simulateHoldEvents; - - // SecureEventInput workaround - BOOL _secureEventInputWorkAround; - UInt64 _lastSecureEventInputPIDSum; - uid_t _lastFrontUserSession; - - // Exclusive lock lending - BOOL _exclusiveLockLending; - BOOL _sendExclusiveResourceReuseNotification; - NSNumber *_waitForReturnByPID; - NSNumber *_returnToPID; - BOOL _isRestarting; - - // Status notifications - BOOL _sendStatusNotifications; - NSString *_pidString; - - // Status - BOOL _applicationIsTerminating; - BOOL _isStopping; - - // Thread safety - #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */ - NSThread *_runOnThread; - #endif + // Notification ports + IONotificationPortRef _notifyPort; + CFRunLoopSourceRef _notifyRLSource; + + // Matching iterator + io_iterator_t _matchingServicesIterator; + + // SecureInput notification + io_object_t _secureInputNotification; + + // Service attributes + NSMutableDictionary *_serviceAttribMap; + + // Mode + HIDRemoteMode _mode; + BOOL _autoRecover; + NSTimer *_autoRecoveryTimer; + + // Delegate + NSObject <HIDRemoteDelegate> *_delegate; + + // Last seen ID and remote model + SInt32 _lastSeenRemoteID; + HIDRemoteModel _lastSeenModel; + SInt32 _lastSeenModelRemoteID; + + // Unused button codes + NSArray *_unusedButtonCodes; + + // Simulate Plus/Minus Hold + BOOL _simulateHoldEvents; + + // SecureEventInput workaround + BOOL _secureEventInputWorkAround; + UInt64 _lastSecureEventInputPIDSum; + uid_t _lastFrontUserSession; + BOOL _lastScreenIsLocked; + + // Exclusive lock lending + BOOL _exclusiveLockLending; + BOOL _sendExclusiveResourceReuseNotification; + NSNumber *_waitForReturnByPID; + NSNumber *_returnToPID; + BOOL _isRestarting; + + // Status notifications + BOOL _sendStatusNotifications; + NSString *_pidString; + + // Status + BOOL _applicationIsTerminating; + BOOL _isStopping; + + // Thread safety + #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */ + NSThread *_runOnThread; + #endif } -#pragma mark -- PUBLIC: Shared HID Remote -- +#pragma mark - PUBLIC: Shared HID Remote + (HIDRemote *)sharedHIDRemote; -#pragma mark -- PUBLIC: System Information -- +#pragma mark - PUBLIC: System Information + (BOOL)isCandelairInstalled; + (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode; ++ (SInt32)OSXVersion; - (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel; -#pragma mark -- PUBLIC: Interface / API -- -- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode; +#pragma mark - PUBLIC: Interface / API +- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode; - (void)stopRemoteControl; - (BOOL)isStarted; @@ -291,7 +317,7 @@ - (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers; - (NSArray *)unusedButtonCodes; -#pragma mark -- PUBLIC: Expert APIs -- +#pragma mark - PUBLIC: Expert APIs - (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround; - (BOOL)enableSecureEventInputWorkaround; @@ -301,28 +327,28 @@ - (BOOL)isApplicationTerminating; - (BOOL)isStopping; -#pragma mark -- PRIVATE: HID Event handling -- +#pragma mark - PRIVATE: HID Event handling - (void)_handleButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict; - (void)_sendButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict; - (void)_hidEventFor:(io_service_t)hidDevice from:(IOHIDQueueInterface **)interface withResult:(IOReturn)result; -#pragma mark -- PRIVATE: Service setup and destruction -- +#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; -#pragma mark -- PRIVATE: Distributed notifiations handling -- +#pragma mark - PRIVATE: Distributed notifiations handling - (void)_postStatusWithAction:(NSString *)action; - (void)_handleNotifications:(NSNotification *)notification; - (void)_setSendStatusNotifications:(BOOL)doSend; - (BOOL)_sendStatusNotifications; -#pragma mark -- PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto -- +#pragma mark - PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto - (void)_appStatusChanged:(NSNotification *)notification; - (void)_delayedAutoRecovery:(NSTimer *)aTimer; -#pragma mark -- PRIVATE: Notification handling -- +#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; @@ -330,12 +356,12 @@ @end -#pragma mark -- Information attribute keys -- +#pragma mark - Information attribute keys extern NSString *kHIDRemoteManufacturer; extern NSString *kHIDRemoteProduct; extern NSString *kHIDRemoteTransport; -#pragma mark -- Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do) -- +#pragma mark - Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do) extern NSString *kHIDRemoteCFPluginInterface; extern NSString *kHIDRemoteHIDDeviceInterface; extern NSString *kHIDRemoteCookieButtonCodeLUT; @@ -349,7 +375,7 @@ extern NSString *kHIDRemoteAluminumRemoteSupportLevel; extern NSString *kHIDRemoteAluminumRemoteSupportOnDemand; -#pragma mark -- Distributed notifications -- +#pragma mark - Distributed notifications extern NSString *kHIDRemoteDNHIDRemotePing; extern NSString *kHIDRemoteDNHIDRemoteRetry; extern NSString *kHIDRemoteDNHIDRemoteStatus; @@ -356,7 +382,7 @@ extern NSString *kHIDRemoteDNHIDRemoteRetryGlobalObject; -#pragma mark -- Distributed notifications userInfo keys and values -- +#pragma mark - Distributed notifications userInfo keys and values extern NSString *kHIDRemoteDNStatusHIDRemoteVersionKey; extern NSString *kHIDRemoteDNStatusPIDKey; extern NSString *kHIDRemoteDNStatusModeKey; @@ -369,8 +395,11 @@ extern NSString *kHIDRemoteDNStatusActionUpdate; extern NSString *kHIDRemoteDNStatusActionNoNeed; -#pragma mark -- Driver compatibility flags -- +#pragma mark - Driver compatibility flags +#ifndef HID_REMOTE_COMPATIBILITY_FLAGS_ENUM +#define HID_REMOTE_COMPATIBILITY_FLAGS_ENUM 1 typedef enum { - kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice = 1L, + kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice = 1L, } HIDRemoteCompatibilityFlags; +#endif /* HID_REMOTE_COMPATIBILITY_FLAGS_ENUM */ Modified: trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.m =================================================================== --- trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.m 2025-08-17 16:38:37 UTC (rev 15672) +++ trunk/vendorsrc/iospirit/HIDRemote/HIDRemote.m 2025-08-17 17:12:35 UTC (rev 15673) @@ -1,9 +1,9 @@ // // HIDRemote.m -// HIDRemote V1.2 (27th May 2011) +// HIDRemote V1.7 (5th September 2018) // // Created by Felix Schwarz on 06.04.07. -// Copyright 2007-2011 IOSPIRIT GmbH. All rights reserved. +// Copyright 2007-2018 IOSPIRIT GmbH. All rights reserved. // // The latest version of this class is available at // http://www.iospirit.com/developers/hidremote/ @@ -10,23 +10,23 @@ // // ** LICENSE ************************************************************************* // -// Copyright (c) 2007-2011 IOSPIRIT GmbH (http://www.iospirit.com/) +// Copyright (c) 2007-2017 IOSPIRIT GmbH (http://www.iospirit.com/) // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: -// +// // * Redistributions of source code must retain the above copyright notice, this list // of conditions and the following disclaimer. -// +// // * Redistributions in binary form must reproduce the above copyright notice, this // list of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior // written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT @@ -51,24 +51,55 @@ #import "HIDRemote.h" +// ARC support +#if !__has_feature(objc_arc) + #define HIDRemoteRetain(object) [object retain] + #define HIDRemoteRetained(object) [object retain] + #define HIDRemoteRelease(object) [object release] + #define HIDRemoteReleaseNil(object) [object release]; object=nil + #define HIDRemoteAutoreleased(object) [object autorelease] + #define HIDRemoteSuperDealloc(object) [super dealloc] + + #define HIDRemoteAutoreleasePoolOpen() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + #define HIDRemoteAutoreleasePoolClose() [pool release]; + + #define __HIDRemoteBridge + #define HIDRemoteBridgingRelease + #define HIDRemoteBridgingRetain +#else /* !__has_feature(objc_arc) */ + #define HIDRemoteRetain(object) + #define HIDRemoteRetained(object) object + #define HIDRemoteRelease(object) + #define HIDRemoteReleaseNil(object) object=nil + #define HIDRemoteAutoreleased(object) object + #define HIDRemoteSuperDealloc(object) + + #define HIDRemoteAutoreleasePoolOpen() @autoreleasepool { + #define HIDRemoteAutoreleasePoolClose() } + + #define __HIDRemoteBridge __bridge + #define HIDRemoteBridgingRelease CFBridgingRelease + #define HIDRemoteBridgingRetain CFBridgingRetain +#endif + // Callback Prototypes -static void HIDEventCallback( void * target, - IOReturn result, - void * refcon, - void * sender); +static void HIDEventCallback( void * target, + IOReturn result, + void * refcon, + void * sender); -static void ServiceMatchingCallback( void *refCon, - io_iterator_t iterator); +static void ServiceMatchingCallback( void *refCon, + io_iterator_t iterator); -static void ServiceNotificationCallback(void * refCon, - io_service_t service, - natural_t messageType, - void * messageArgument); +static void ServiceNotificationCallback(void * refCon, + io_service_t service, + natural_t messageType, + void * messageArgument); -static void SecureInputNotificationCallback( void * refCon, - io_service_t service, - 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; @@ -75,1967 +106,2095 @@ @implementation HIDRemote -#pragma mark -- Init, dealloc & shared instance -- +#pragma mark - Init, dealloc & shared instance + (HIDRemote *)sharedHIDRemote { - if (sHIDRemote==nil) - { - sHIDRemote = [[HIDRemote alloc] init]; - } - - return (sHIDRemote); + if (sHIDRemote==nil) + { + sHIDRemote = [[HIDRemote alloc] init]; + } + + return (sHIDRemote); } - (id)init { - if ((self = [super init]) != nil) - { - #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING - _runOnThread = [NSThread currentThread]; - #endif - - // Detect application becoming active/inactive - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationWillTerminateNotification object:[NSApplication sharedApplication]]; + if ((self = [super init]) != nil) + { + #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING + _runOnThread = HIDRemoteRetained([NSThread currentThread]); + #endif + + // Detect application becoming active/inactive + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationWillTerminateNotification object:[NSApplication sharedApplication]]; - // Handle distributed notifications - _pidString = [[NSString alloc] initWithFormat:@"%d", getpid()]; - - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemotePing object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry object:_pidString]; + // Handle distributed notifications + _pidString = [[NSString alloc] initWithFormat:@"%d", getpid()]; + + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemotePing object:nil]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry object:_pidString]; - // 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 (credit for finding this workaround goes to Martin Kahr) - _secureEventInputWorkAround = YES; - _secureInputNotification = 0; - - // Initialize instance variables - _lastSeenRemoteID = -1; - _lastSeenModel = kHIDRemoteModelUndetermined; - _unusedButtonCodes = [[NSMutableArray alloc] init]; - _exclusiveLockLending = NO; - _sendExclusiveResourceReuseNotification = YES; - _applicationIsTerminating = NO; - - // Send status notifications - _sendStatusNotifications = YES; - } + // 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 (credit for finding this workaround goes to Martin Kahr) + _secureEventInputWorkAround = YES; + _secureInputNotification = 0; + + // Initialize instance variables + _lastSeenRemoteID = -1; + _lastSeenModel = kHIDRemoteModelUndetermined; + _unusedButtonCodes = [[NSMutableArray alloc] init]; + _exclusiveLockLending = NO; + _sendExclusiveResourceReuseNotification = YES; + _applicationIsTerminating = NO; + + // Send status notifications + _sendStatusNotifications = YES; + } - return (self); + return (self); } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:[NSApplication sharedApplication]]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:[NSApplication sharedApplication]]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]]; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemotePing object:nil]; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject]; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:_pidString]; - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:nil object:nil]; /* As demanded by the documentation for -[NSDistributedNotificationCenter removeObserver:name:object:] */ - - [self stopRemoteControl]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemotePing object:nil]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:_pidString]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:nil object:nil]; /* As demanded by the documentation for -[NSDistributedNotificationCenter removeObserver:name:object:] */ + + [self stopRemoteControl]; - [self setExclusiveLockLendingEnabled:NO]; + [self setExclusiveLockLendingEnabled:NO]; - [self setDelegate:nil]; + [self setDelegate:nil]; - if (_unusedButtonCodes != nil) - { - _unusedButtonCodes = nil; - } + if (_unusedButtonCodes != nil) + { + HIDRemoteReleaseNil(_unusedButtonCodes); + } - #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING - _runOnThread = nil; - #endif + #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING + HIDRemoteReleaseNil(_runOnThread); + #endif - _pidString = nil; + HIDRemoteReleaseNil(_pidString); + + HIDRemoteSuperDealloc(); } -#pragma mark -- PUBLIC: System Information -- +#pragma mark - PUBLIC: System Information + (BOOL)isCandelairInstalled { - mach_port_t masterPort = 0; - kern_return_t kernResult; - io_service_t matchingService = 0; - BOOL isInstalled = NO; + mach_port_t masterPort = 0; + kern_return_t kernResult; + io_service_t matchingService = 0; + BOOL isInstalled = NO; - kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); - if ((kernResult!=kIOReturnSuccess) || (masterPort==0)) { return(NO); } + kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); + if ((kernResult!=kIOReturnSuccess) || (masterPort==0)) { return(NO); } - if ((matchingService = IOServiceGetMatchingService(masterPort, IOServiceMatching("IOSPIRITIRController"))) != 0) - { - isInstalled = YES; - IOObjectRelease((io_object_t) matchingService); - } + if ((matchingService = IOServiceGetMatchingService(masterPort, IOServiceMatching("IOSPIRITIRController"))) != 0) + { + isInstalled = YES; + IOObjectRelease((io_object_t) matchingService); + } - mach_port_deallocate(mach_task_self(), masterPort); + mach_port_deallocate(mach_task_self(), masterPort); - return (isInstalled); + return (isInstalled); } + (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode { - /* - SInt32 systemVersionMajor = 0, systemVersionMinor = 0, systemVersionBugFix; - - // Determine OS version, use components as gestaltSystemVersion breaks on 10.10 - if (Gestalt(gestaltSystemVersionMajor, &systemVersionMajor) == noErr && - Gestalt(gestaltSystemVersionMinor, &systemVersionMinor) == noErr && - Gestalt(gestaltSystemVersionBugFix, &systemVersionBugFix) == noErr) - { - if (systemVersionMajor == 10 && systemVersionMinor == 6 && systemVersionBugFix <= 1) - { - // 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. + // Determine OS version + switch ([self OSXVersion]) + { + case 0x1060: // OS 10.6 + case 0x1061: // OS 10.6.1 + // 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. - switch (remoteMode) - { - case kHIDRemoteModeExclusive: - case kHIDRemoteModeExclusiveAuto: - if (![self isCandelairInstalled]) - { - return (YES); - } - break; - default: - break; - } - } - } - */ + switch (remoteMode) + { + case kHIDRemoteModeExclusive: + case kHIDRemoteModeExclusiveAuto: + if (![self isCandelairInstalled]) + { + return (YES); + } + break; + + default: + return (NO); + break; + } + break; + } - return (NO); + return (NO); } +// Drop-in replacement for Gestalt(gestaltSystemVersion, &osXVersion) that avoids use of Gestalt for code targeting 10.10 or later ++ (SInt32)OSXVersion +{ + static SInt32 sHRGestaltOSXVersion = 0; + + if (sHRGestaltOSXVersion==0) + { + #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 + // Code for builds targeting OS X 10.10+ + NSOperatingSystemVersion osVersion; + + osVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; + + sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion); + #else + #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 + // Code for builds using the OS X 10.10 SDK or later + NSOperatingSystemVersion osVersion; + + if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) + { + osVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; + + sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion); + } + else + { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + Gestalt (gestaltSystemVersion, &sHRGestaltOSXVersion); + #pragma clang diagnostic pop + } + #else /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */ + // Code for builds using an SDK older than 10.10 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + Gestalt (gestaltSystemVersion, &sHRGestaltOSXVersion); + #pragma clang diagnostic pop + #endif /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */ + #endif /* MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 */ + } + + return (sHRGestaltOSXVersion); +} + - (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel { - HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone; - NSEnumerator *attribDictsEnum; - NSDictionary *hidAttribsDict; - - attribDictsEnum = [_serviceAttribMap objectEnumerator]; - - while ((hidAttribsDict = [attribDictsEnum nextObject]) != nil) - { - NSNumber *deviceSupportLevel; - - if ((deviceSupportLevel = [hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel]) != nil) - { - if ([deviceSupportLevel intValue] > (int)supportLevel) - { - supportLevel = [deviceSupportLevel intValue]; - } - } - } - - return (supportLevel); + HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone; + NSEnumerator *attribDictsEnum; + NSDictionary *hidAttribsDict; + + attribDictsEnum = [_serviceAttribMap objectEnumerator]; + + while ((hidAttribsDict = [attribDictsEnum nextObject]) != nil) + { + NSNumber *deviceSupportLevel; + + if ((deviceSupportLevel = [hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel]) != nil) + { + if ([deviceSupportLevel intValue] > (int)supportLevel) + { + supportLevel = [deviceSupportLevel intValue]; + } + } + } + + return (supportLevel); } -#pragma mark -- PUBLIC: Interface / API -- +#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 - { - // Get IOKit master port - kernReturn = IOMasterPort(bootstrap_port, &_masterPort); - if ((kernReturn!=kIOReturnSuccess) || (_masterPort==0)) { break; } - - // Setup notification port - _notifyPort = IONotificationPortCreate(_masterPort); - - if ((_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) != NULL) - { - CFRunLoopAddSource( CFRunLoopGetCurrent(), - _notifyRLSource, - kCFRunLoopCommonModes); - } - else - { - break; - } - - // Setup SecureInput notification - if ((hidRemoteMode == kHIDRemoteModeExclusive) || (hidRemoteMode == kHIDRemoteModeExclusiveAuto)) - { - if ((rootService = IORegistryEntryFromPath(_masterPort, kIOServicePlane ":/")) != 0) - { - kernReturn = IOServiceAddInterestNotification( _notifyPort, - rootService, - kIOBusyInterest, - SecureInputNotificationCallback, - (__bridge void *)self, - &_secureInputNotification); - if (kernReturn != kIOReturnSuccess) { break; } - - [self _updateSessionInformation]; - } - else - { - break; - } - } + if ((_mode == kHIDRemoteModeNone) && (hidRemoteMode != kHIDRemoteModeNone)) + { + kern_return_t kernReturn; + CFMutableDictionaryRef matchDict=NULL; + io_service_t rootService; + + do + { + // Get IOKit master port + kernReturn = IOMasterPort(bootstrap_port, &_masterPort); + if ((kernReturn!=kIOReturnSuccess) || (_masterPort==0)) { break; } + + // Setup notification port + _notifyPort = IONotificationPortCreate(_masterPort); + + if ((_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) != NULL) + { + CFRunLoopAddSource( CFRunLoopGetCurrent(), + _notifyRLSource, + kCFRunLoopCommonModes); + } + else + { + break; + } + + // Setup SecureInput notification + if ((hidRemoteMode == kHIDRemoteModeExclusive) || (hidRemoteMode == kHIDRemoteModeExclusiveAuto)) + { + if ((rootService = IORegistryEntryFromPath(_masterPort, kIOServicePlane ":/")) != 0) + { + kernReturn = IOServiceAddInterestNotification( _notifyPort, + rootService, + kIOBusyInterest, + SecureInputNotificationCallback, + (__HIDRemoteBridge void *)self, + &_secureInputNotification); + if (kernReturn != kIOReturnSuccess) { break; } + + [self _updateSessionInformation]; + } + else + { + break; + } + } - // Setup notification matching dict - matchDict = IOServiceMatching(kIOHIDDeviceKey); - CFRetain(matchDict); + // Setup notification matching dict + matchDict = IOServiceMatching(kIOHIDDeviceKey); + CFRetain(matchDict); - // Actually add notification - kernReturn = IOServiceAddMatchingNotification( _notifyPort, - kIOFirstMatchNotification, - matchDict, // one reference count consumed by this call - ServiceMatchingCallback, - (__bridge void *) self, - &_matchingServicesIterator); - if (kernReturn != kIOReturnSuccess) { break; } + // Actually add notification + kernReturn = IOServiceAddMatchingNotification( _notifyPort, + kIOFirstMatchNotification, + matchDict, // one reference count consumed by this call + ServiceMatchingCallback, + (__HIDRemoteBridge void *) self, + &_matchingServicesIterator); + if (kernReturn != kIOReturnSuccess) { break; } - // Setup serviceAttribMap - _serviceAttribMap = [[NSMutableDictionary alloc] init]; - if (_serviceAttribMap==nil) { break; } - - // Phew .. everything went well! - _mode = hidRemoteMode; - CFRelease(matchDict); - - [self _serviceMatching:_matchingServicesIterator]; - - [self _postStatusWithAction:kHIDRemoteDNStatusActionStart]; - - return (YES); + // Setup serviceAttribMap + _serviceAttribMap = [[NSMutableDictionary alloc] init]; + if (_serviceAttribMap==nil) { break; } + + // Phew .. everything went well! + _mode = hidRemoteMode; + CFRelease(matchDict); + + [self _serviceMatching:_matchingServicesIterator]; + + [self _postStatusWithAction:kHIDRemoteDNStatusActionStart]; + + // Register for system wake notifications + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(_computerDidWake:) name:NSWorkspaceDidWakeNotification object:nil]; + + return (YES); - }while(0); - - // An error occured. Do necessary clean up. - if (matchDict!=NULL) - { - CFRelease(matchDict); - matchDict = NULL; - } - - [self stopRemoteControl]; - } - - return (NO); + }while(0); + + // An error occured. Do necessary clean up. + if (matchDict!=NULL) + { + CFRelease(matchDict); + matchDict = NULL; + } + + [self stopRemoteControl]; + } + + return (NO); } - (void)stopRemoteControl { - UInt32 serviceCount = 0; + UInt32 serviceCount = 0; - _autoRecover = NO; - _isStopping = YES; - - if (_autoRecoveryTimer!=nil) - { - [_autoRecoveryTimer invalidate]; - _autoRecoveryTimer = nil; - } + _autoRecover = NO; + _isStopping = YES; - if (_serviceAttribMap!=nil) - { - NSDictionary *cloneDict = [[NSDictionary alloc] initWithDictionary:_serviceAttribMap]; - - if (cloneDict!=nil) - { - NSEnumerator *mapKeyEnum = [cloneDict keyEnumerator]; - NSNumber *serviceValue; - - while ((serviceValue = [mapKeyEnum nextObject]) != nil) - { - [self _destructService:(io_object_t)[serviceValue unsignedIntValue]]; - serviceCount++; - }; - - cloneDict = nil; - } - - _serviceAttribMap = nil; - } + if (_autoRecoveryTimer!=nil) + { + [_autoRecoveryTimer invalidate]; + HIDRemoteReleaseNil(_autoRecoveryTimer); + } - if (_matchingServicesIterator!=0) - { - IOObjectRelease((io_object_t) _matchingServicesIterator); - _matchingServicesIterator = 0; - } - - if (_secureInputNotification!=0) - { - IOObjectRelease((io_object_t) _secureInputNotification); - _secureInputNotification = 0; - } + if (_serviceAttribMap!=nil) + { + NSDictionary *cloneDict = [[NSDictionary alloc] initWithDictionary:_serviceAttribMap]; + + if (cloneDict!=nil) + { + NSEnumerator *mapKeyEnum = [cloneDict keyEnumerator]; + NSNumber *serviceValue; + + while ((serviceValue = [mapKeyEnum nextObject]) != nil) + { + [self _destructService:(io_object_t)[serviceValue unsignedIntValue]]; + serviceCount++; + }; + + HIDRemoteReleaseNil(cloneDict); + } + + HIDRemoteReleaseNil(_serviceAttribMap); + } - if (_notifyRLSource!=NULL) - { - CFRunLoopSourceInvalidate(_notifyRLSource); - _notifyRLSource = NULL; - } + if (_matchingServicesIterator!=0) + { + IOObjectRelease((io_object_t) _matchingServicesIterator); + _matchingServicesIterator = 0; + } + + if (_secureInputNotification!=0) + { + IOObjectRelease((io_object_t) _secureInputNotification); + _secureInputNotification = 0; + } - if (_notifyPort!=NULL) - { - IONotificationPortDestroy(_notifyPort); - _notifyPort = NULL; - } + if (_notifyRLSource!=NULL) + { + CFRunLoopSourceInvalidate(_notifyRLSource); + _notifyRLSource = NULL; + } - if (_masterPort!=0) - { - mach_port_deallocate(mach_task_self(), _masterPort); - _masterPort = 0; - } + if (_notifyPort!=NULL) + { + IONotificationPortDestroy(_notifyPort); + _notifyPort = NULL; + } - if (_returnToPID!=nil) - { - _returnToPID = nil; - } + if (_masterPort!=0) + { + mach_port_deallocate(mach_task_self(), _masterPort); + _masterPort = 0; + } - if (_mode!=kHIDRemoteModeNone) - { - // Post status - [self _postStatusWithAction:kHIDRemoteDNStatusActionStop]; + if (_returnToPID!=nil) + { + HIDRemoteReleaseNil(_returnToPID); + } - if (_sendStatusNotifications) - { - // In case we were not ready to lend it earlier, tell other HIDRemote apps that the resources (if any were used) are now again available for use by other applications - if (((_mode==kHIDRemoteModeExclusive) || (_mode==kHIDRemoteModeExclusiveAuto)) && (_sendExclusiveResourceReuseNotification==YES) && (_exclusiveLockLending==NO) && (serviceCount>0)) - { - _mode = kHIDRemoteModeNone; - - if (!_isRestarting) - { - [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry - object:kHIDRemoteDNHIDRemoteRetryGlobalObject - userInfo:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey, - [[NSBundle mainBundle] bundleIdentifier], (__bridge NSString *)kCFBundleIdentifierKey, - nil] - deliverImmediately:YES]; - } - } - } - } - - _mode = kHIDRemoteModeNone; - _isStopping = NO; + if (_mode!=kHIDRemoteModeNone) + { + // Post status + [self _postStatusWithAction:kHIDRemoteDNStatusActionStop]; + + if (_sendStatusNotifications) + { + // In case we were not ready to lend it earlier, tell other HIDRemote apps that the resources (if any were used) are now again available for use by other applications + if (((_mode==kHIDRemoteModeExclusive) || (_mode==kHIDRemoteModeExclusiveAuto)) && (_sendExclusiveResourceReuseNotification==YES) && (_exclusiveLockLending==NO) && (serviceCount>0)) + { + _mode = kHIDRemoteModeNone; + + if (!_isRestarting) + { + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry + object:kHIDRemoteDNHIDRemoteRetryGlobalObject + userInfo:[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey, + [[NSBundle mainBundle] bundleIdentifier], (NSString *)kCFBundleIdentifierKey, + nil] + deliverImmediately:YES]; + } + } + } + + // Unregister from system wake notifications + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidWakeNotification object:nil]; + } + + _mode = kHIDRemoteModeNone; + _isStopping = NO; } - (BOOL)isStarted { - return (_mode != kHIDRemoteModeNone); + return (_mode != kHIDRemoteModeNone); } - (HIDRemoteMode)startedInMode { - return (_mode); + return (_mode); } - (unsigned)activeRemoteControlCount { - return ([_serviceAttribMap count]); + return ((unsigned)[_serviceAttribMap count]); } - (SInt32)lastSeenRemoteControlID { - return (_lastSeenRemoteID); + return (_lastSeenRemoteID); } - (HIDRemoteModel)lastSeenModel { - return (_lastSeenModel); + return (_lastSeenModel); } - (void)setLastSeenModel:(HIDRemoteModel)aModel { - _lastSeenModel = aModel; + _lastSeenModel = aModel; } - (void)setSimulateHoldEvents:(BOOL)newSimulateHoldEvents { - _simulateHoldEvents = newSimulateHoldEvents; + _simulateHoldEvents = newSimulateHoldEvents; } - (BOOL)simulateHoldEvents { - return (_simulateHoldEvents); + return (_simulateHoldEvents); } - (NSArray *)unusedButtonCodes { - return (_unusedButtonCodes); + return (_unusedButtonCodes); } - (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers { - _unusedButtonCodes = newArrayWithUnusedButtonCodesAsNSNumbers; + HIDRemoteRetain(newArrayWithUnusedButtonCodesAsNSNumbers); + HIDRemoteRelease(_unusedButtonCodes); + + _unusedButtonCodes = newArrayWithUnusedButtonCodesAsNSNumbers; - [self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate]; + [self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate]; } - (void)setDelegate:(NSObject <HIDRemoteDelegate> *)newDelegate { - _delegate = newDelegate; + _delegate = newDelegate; } - (NSObject <HIDRemoteDelegate> *)delegate { - return (_delegate); + return (_delegate); } -#pragma mark -- PUBLIC: Expert APIs -- +#pragma mark - PUBLIC: Expert APIs - (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround { - _secureEventInputWorkAround = newEnableSecureEventInputWorkaround; + _secureEventInputWorkAround = newEnableSecureEventInputWorkaround; } - (BOOL)enableSecureEventInputWorkaround { - return (_secureEventInputWorkAround); + return (_secureEventInputWorkAround); } - (void)setExclusiveLockLendingEnabled:(BOOL)newExclusiveLockLendingEnabled { - if (newExclusiveLockLendingEnabled != _exclusiveLockLending) - { - _exclusiveLockLending = newExclusiveLockLendingEnabled; - - if (_exclusiveLockLending) - { - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteStatus object:nil]; - } - else - { - [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteStatus object:nil]; - - _waitForReturnByPID = nil; - } - } + if (newExclusiveLockLendingEnabled != _exclusiveLockLending) + { + _exclusiveLockLending = newExclusiveLockLendingEnabled; + + if (_exclusiveLockLending) + { + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteStatus object:nil]; + } + else + { + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteStatus object:nil]; + + HIDRemoteReleaseNil(_waitForReturnByPID); + } + } } - (BOOL)exclusiveLockLendingEnabled { - return (_exclusiveLockLending); + return (_exclusiveLockLending); } - (void)setSendExclusiveResourceReuseNotification:(BOOL)newSendExclusiveResourceReuseNotification { - _sendExclusiveResourceReuseNotification = newSendExclusiveResourceReuseNotification; + _sendExclusiveResourceReuseNotification = newSendExclusiveResourceReuseNotification; } - (BOOL)sendExclusiveResourceReuseNotification { - return (_sendExclusiveResourceReuseNotification); + return (_sendExclusiveResourceReuseNotification); } - (BOOL)isApplicationTerminating { - return (_applicationIsTerminating); + return (_applicationIsTerminating); } - (BOOL)isStopping { - return (_isStopping); + return (_isStopping); } -#pragma mark -- PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto -- +#pragma mark - PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto - (void)_appStatusChanged:(NSNotification *)notification { - #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING - if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only - { - if ([NSThread currentThread] != _runOnThread) - { - if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification]) - { - if (!_autoRecover) - { - return; - } - } - - if ([[notification name] isEqual:NSApplicationWillResignActiveNotification]) - { - if (_mode != kHIDRemoteModeExclusiveAuto) - { - return; - } - } - - [self performSelector:@selector(_appStatusChanged:) onThread:_runOnThread withObject:notification waitUntilDone:[[notification name] isEqual:NSApplicationWillTerminateNotification]]; - return; - } - } - #endif + #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING + if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only + { + if ([NSThread currentThread] != _runOnThread) + { + if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification]) + { + if (!_autoRecover) + { + return; + } + } + + if ([[notification name] isEqual:NSApplicationWillResignActiveNotification]) + { + if (_mode != kHIDRemoteModeExclusiveAuto) + { + return; + } + } + + [self performSelector:@selector(_appStatusChanged:) onThread:_runOnThread withObject:notification waitUntilDone:[[notification name] isEqual:NSApplicationWillTerminateNotification]]; + return; + } + } + #endif - if (notification!=nil) - { - if (_autoRecoveryTimer!=nil) - { - [_autoRecoveryTimer invalidate]; - _autoRecoveryTimer = nil; - } + if (notification!=nil) + { + if (_autoRecoveryTimer!=nil) + { + [_autoRecoveryTimer invalidate]; + HIDRemoteReleaseNil(_autoRecoveryTimer); + } - if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification]) - { - if (_autoRecover) - { - // Delay autorecover by 0.1 to avoid race conditions - if ((_autoRecoveryTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.1] interval:0.1 target:self selector:@selector(_delayedAutoRecovery:) userInfo:nil repeats:NO]) != nil) - { - // Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes. - // The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code - // is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0. - CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)_autoRecoveryTimer, kCFRunLoopCommonModes); - } - } - } + if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification]) + { + if (_autoRecover) + { + // Delay autorecover by 0.1 to avoid race conditions + if ((_autoRecoveryTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.1] interval:0.1 target:self selector:@selector(_delayedAutoRecovery:) userInfo:nil repeats:NO]) != nil) + { + // Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes. + // The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code + // is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0. + CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)_autoRecoveryTimer, kCFRunLoopCommonModes); + } + } + } - if ([[notification name] isEqual:NSApplicationWillResignActiveNotification]) - { - if (_mode == kHIDRemoteModeExclusiveAuto) - { - [self stopRemoteControl]; - _autoRecover = YES; - } - } - - if ([[notification name] isEqual:NSApplicationWillTerminateNotification]) - { - _applicationIsTerminating = YES; - - if ([self isStarted]) - { - [self stopRemoteControl]; - } - } - } + if ([[notification name] isEqual:NSApplicationWillResignActiveNotification]) + { + if (_mode == kHIDRemoteModeExclusiveAuto) + { + [self stopRemoteControl]; + _autoRecover = YES; + } + } + + if ([[notification name] isEqual:NSApplicationWillTerminateNotification]) + { + _applicationIsTerminating = YES; + + if ([self isStarted]) + { + [self stopRemoteControl]; + } + } + } } - (void)_delayedAutoRecovery:(NSTimer *)aTimer { - [_autoRecoveryTimer invalidate]; - _autoRecoveryTimer = nil; + [_autoRecoveryTimer invalidate]; + HIDRemoteReleaseNil(_autoRecoveryTimer); - if (_autoRecover) - { - [self startRemoteControl:kHIDRemoteModeExclusiveAuto]; - _autoRecover = NO; - } + if (_autoRecover) + { + [self startRemoteControl:kHIDRemoteModeExclusiveAuto]; + _autoRecover = NO; + } } -#pragma mark -- PRIVATE: Distributed notifiations handling -- +#pragma mark - PRIVATE: Distributed notifiations handling - (void)_postStatusWithAction:(NSString *)action { - if (_sendStatusNotifications) - { - [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteStatus - object:((_pidString!=nil) ? _pidString : [NSString stringWithFormat:@"%d",getpid()]) - userInfo:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:1], kHIDRemoteDNStatusHIDRemoteVersionKey, - [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey, - [NSNumber numberWithInt:(int)_mode], kHIDRemoteDNStatusModeKey, - [NSNumber numberWithUnsignedInt:(unsigned int)[self activeRemoteControlCount]], kHIDRemoteDNStatusRemoteControlCountKey, - ((_unusedButtonCodes!=nil) ? _unusedButtonCodes : [NSArray array]), kHIDRemoteDNStatusUnusedButtonCodesKey, - action, kHIDRemoteDNStatusActionKey, - [[NSBundle mainBundle] bundleIdentifier], (__bridge NSString *)kCFBundleIdentifierKey, - _returnToPID, kHIDRemoteDNStatusReturnToPIDKey, - nil] - deliverImmediately:YES - ]; - } + if (_sendStatusNotifications) + { + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteStatus + object:((_pidString!=nil) ? _pidString : [NSString stringWithFormat:@"%d",getpid()]) + userInfo:[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt:1], kHIDRemoteDNStatusHIDRemoteVersionKey, + [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey, + [NSNumber numberWithInt:(int)_mode], kHIDRemoteDNStatusModeKey, + [NSNumber numberWithUnsignedInt:(unsigned int)[self activeRemoteControlCount]], kHIDRemoteDNStatusRemoteControlCountKey, + ((_unusedButtonCodes!=nil) ? _unusedButtonCodes : [NSArray array]), kHIDRemoteDNStatusUnusedButtonCodesKey, + action, kHIDRemoteDNStatusActionKey, + [[NSBundle mainBundle] bundleIdentifier], (NSString *)kCFBundleIdentifierKey, + _returnToPID, kHIDRemoteDNStatusReturnToPIDKey, + nil] + deliverImmediately:YES + ]; + } } - (void)_handleNotifications:(NSNotification *)notification { - NSString *notificationName; + NSString *notificationName; - #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING - if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only - { - if ([NSThread currentThread] != _runOnThread) - { - [self performSelector:@selector(_handleNotifications:) onThread:_runOnThread withObject:notification waitUntilDone:NO]; - return; - } - } - #endif + #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING + if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only + { + if ([NSThread currentThread] != _runOnThread) + { + [self performSelector:@selector(_handleNotifications:) onThread:_runOnThread withObject:notification waitUntilDone:NO]; + return; + } + } + #endif - if ((notification!=nil) && ((notificationName = [notification name]) != nil)) - { - if ([notificationName isEqual:kHIDRemoteDNHIDRemotePing]) - { - [self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate]; - } + if ((notification!=nil) && ((notificationName = [notification name]) != nil)) + { + if ([notificationName isEqual:kHIDRemoteDNHIDRemotePing]) + { + [self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate]; + } - if ([notificationName isEqual:kHIDRemoteDNHIDRemoteRetry]) - { - if ([self isStarted]) - { - BOOL retry = YES; - - // Ignore our own global retry broadcasts - if ([[notification object] isEqual:kHIDRemoteDNHIDRemoteRetryGlobalObject]) - { - NSNumber *fromPID; + if ([notificationName isEqual:kHIDRemoteDNHIDRemoteRetry]) + { + if ([self isStarted]) + { + BOOL retry = YES; + + // Ignore our own global retry broadcasts + if ([[notification object] isEqual:kHIDRemoteDNHIDRemoteRetryGlobalObject]) + { + NSNumber *fromPID; - if ((fromPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil) - { - if (getpid() == (int)[fromPID unsignedIntValue]) - { - retry = NO; - } - } - } - - if (retry) - { - if (([self delegate] != nil) && - ([[self delegate] respondsToSelector:@selector(hidRemote:shouldRetryExclusiveLockWithInfo:)])) - { - retry = [[self delegate] hidRemote:self shouldRetryExclusiveLockWithInfo:[notification userInfo]]; - } - } - - if (retry) - { - HIDRemoteMode restartInMode = _mode; - - if (restartInMode != kHIDRemoteModeNone) - { - _isRestarting = YES; - [self stopRemoteControl]; - - _returnToPID = nil; - - [self startRemoteControl:restartInMode]; - _isRestarting = NO; - - if (restartInMode != kHIDRemoteModeShared) - { - _returnToPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]; - } - } - } - else - { - NSNumber *cacheReturnPID = _returnToPID; + if ((fromPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil) + { + if (getpid() == (int)[fromPID unsignedIntValue]) + { + retry = NO; + } + } + } + + if (retry) + { + if (([self delegate] != nil) && + ([[self delegate] respondsToSelector:@selector(hidRemote:shouldRetryExclusiveLockWithInfo:)])) + { + retry = [[self delegate] hidRemote:self shouldRetryExclusiveLockWithInfo:[notification userInfo]]; + } + } + + if (retry) + { + HIDRemoteMode restartInMode = _mode; + + if (restartInMode != kHIDRemoteModeNone) + { + _isRestarting = YES; + [self stopRemoteControl]; + + HIDRemoteReleaseNil(_returnToPID); + + [self startRemoteControl:restartInMode]; + _isRestarting = NO; + + if (restartInMode != kHIDRemoteModeShared) + { + _returnToPID = HIDRemoteRetained([[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]); + } + } + } + else + { + NSNumber *cacheReturnPID = _returnToPID; - _returnToPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]; - [self _postStatusWithAction:kHIDRemoteDNStatusActionNoNeed]; - - _returnToPID = cacheReturnPID; - } - } - } - - if (_exclusiveLockLending) - { - if ([notificationName isEqual:kHIDRemoteDNHIDRemoteStatus]) - { - NSString *action; - - if ((action = [[notification userInfo] objectForKey:kHIDRemoteDNStatusActionKey]) != nil) - { - if ((_mode == kHIDRemoteModeNone) && (_waitForReturnByPID!=nil)) - { - NSNumber *pidNumber, *returnToPIDNumber; + _returnToPID = HIDRemoteRetained([[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]); + [self _postStatusWithAction:kHIDRemoteDNStatusActionNoNeed]; + HIDRemoteRelease(_returnToPID); + + _returnToPID = cacheReturnPID; + } + } + } + + if (_exclusiveLockLending) + { + if ([notificationName isEqual:kHIDRemoteDNHIDRemoteStatus]) + { + NSString *action; + + if ((action = [[notification userInfo] objectForKey:kHIDRemoteDNStatusActionKey]) != nil) + { + if ((_mode == kHIDRemoteModeNone) && (_waitForReturnByPID!=nil)) + { + NSNumber *pidNumber, *returnToPIDNumber; - if ((pidNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil) - { - returnToPIDNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusReturnToPIDKey]; - - if ([action isEqual:kHIDRemoteDNStatusActionStart]) - { - if ([pidNumber isEqual:_waitForReturnByPID]) - { - NSNumber *startMode; - - if ((startMode = [[notification userInfo] objectForKey:kHIDRemoteDNStatusModeKey]) != nil) - { - if ([startMode intValue] == kHIDRemoteModeShared) - { - returnToPIDNumber = [NSNumber numberWithInt:getpid()]; - action = kHIDRemoteDNStatusActionNoNeed; - } - } - } - } + if ((pidNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil) + { + returnToPIDNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusReturnToPIDKey]; + + if ([action isEqual:kHIDRemoteDNStatusActionStart]) + { + if ([pidNumber isEqual:_waitForReturnByPID]) + { + NSNumber *startMode; + + if ((startMode = [[notification userInfo] objectForKey:kHIDRemoteDNStatusModeKey]) != nil) + { + if ([startMode intValue] == kHIDRemoteModeShared) + { + returnToPIDNumber = [NSNumber numberWithInt:getpid()]; + action = kHIDRemoteDNStatusActionNoNeed; + } + } + } + } - if (returnToPIDNumber != nil) - { - if ([action isEqual:kHIDRemoteDNStatusActionStop] || [action isEqual:kHIDRemoteDNStatusActionNoNeed]) - { - if ([pidNumber isEqual:_waitForReturnByPID] && ([returnToPIDNumber intValue] == getpid())) - { - _waitForReturnByPID = nil; - - if (([self delegate] != nil) && - ([[self delegate] respondsToSelector:@selector(hidRemote:exclusiveLockReleasedByApplicationWithInfo:)])) - { - [[self delegate] hidRemote:self exclusiveLockReleasedByApplicationWithInfo:[notification userInfo]]; - } - else - { - [self startRemoteControl:kHIDRemoteModeExclusive]; - } - } - } - } - } - } + if (returnToPIDNumber != nil) + { + if ([action isEqual:kHIDRemoteDNStatusActionStop] || [action isEqual:kHIDRemoteDNStatusActionNoNeed]) + { + if ([pidNumber isEqual:_waitForReturnByPID] && ([returnToPIDNumber intValue] == getpid())) + { + HIDRemoteReleaseNil(_waitForReturnByPID); + + if (([self delegate] != nil) && + ([[self delegate] respondsToSelector:@selector(hidRemote:exclusiveLockReleasedByApplicationWithInfo:)])) + { + [[self delegate] hidRemote:self exclusiveLockReleasedByApplicationWithInfo:[notification userInfo]]; + } + else + { + [self startRemoteControl:kHIDRemoteModeExclusive]; + } + } + } + } + } + } - if (_mode==kHIDRemoteModeExclusive) - { - if ([action isEqual:kHIDRemoteDNStatusActionStart]) - { - NSNumber *originPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]; - BOOL lendLock = YES; - - if ([originPID intValue] != getpid()) - { - if (([self delegate] != nil) && - ([[self delegate] respondsToSelector:@selector(hidRemote:lendExclusiveLockToApplicationWithInfo:)])) - { - lendLock = [[self delegate] hidRemote:self lendExclusiveLockToApplicationWithInfo:[notification userInfo]]; - } - - if (lendLock) - { - _waitForReturnByPID = originPID; - - if (_waitForReturnByPID != nil) - { - [self stopRemoteControl]; - - [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry - object:[NSString stringWithFormat:@"%d", [_waitForReturnByPID intValue]] - userInfo:[NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey, - [[NSBundle mainBundle] bundleIdentifier], (__bridge NSString *)kCFBundleIdentifierKey, - nil] - deliverImmediately:YES]; - } - } - } - } - } - } - } - } - } + if (_mode==kHIDRemoteModeExclusive) + { + if ([action isEqual:kHIDRemoteDNStatusActionStart]) + { + NSNumber *originPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]; + BOOL lendLock = YES; + + if ([originPID intValue] != getpid()) + { + if (([self delegate] != nil) && + ([[self delegate] respondsToSelector:@selector(hidRemote:lendExclusiveLockToApplicationWithInfo:)])) + { + lendLock = [[self delegate] hidRemote:self lendExclusiveLockToApplicationWithInfo:[notification userInfo]]; + } + + if (lendLock) + { + HIDRemoteRelease(_waitForReturnByPID); + _waitForReturnByPID = HIDRemoteRetained(originPID); + + if (_waitForReturnByPID != nil) + { + [self stopRemoteControl]; + + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry + object:[NSString stringWithFormat:@"%d", [_waitForReturnByPID intValue]] + userInfo:[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey, + [[NSBundle mainBundle] bundleIdentifier], (NSString *)kCFBundleIdentifierKey, + nil] + deliverImmediately:YES]; + } + } + } + } + } + } + } + } + } } - (void)_setSendStatusNotifications:(BOOL)doSend { - _sendStatusNotifications = doSend; + _sendStatusNotifications = doSend; } - (BOOL)_sendStatusNotifications { - return (_sendStatusNotifications); + return (_sendStatusNotifications); } -#pragma mark -- PRIVATE: Service setup and destruction -- +#pragma mark - PRIVATE: Service setup and destruction - (BOOL)_prematchService:(io_object_t)service { - BOOL serviceMatches = NO; - NSString *ioClass; - NSNumber *candelairHIDRemoteCompatibilityMask; - - if (service != 0) - { - // IOClass matching - if ((ioClass = (NSString *)CFBridgingRelease(IORegistryEntryCreateCFProperty((io_registry_entry_t)service, - CFSTR(kIOClassKey), - kCFAllocatorDefault, - 0))) != nil) - { - // Match on Apple's AppleIRController and old versions of the Remote Buddy IR Controller - if ([ioClass isEqual:@"AppleIRController"] || [ioClass isEqual:@"RBIOKitAIREmu"]) - { - CFTypeRef candelairHIDRemoteCompatibilityDevice; + BOOL serviceMatches = NO; + NSString *ioClass; + NSNumber *candelairHIDRemoteCompatibilityMask; + + if (service != 0) + { + // IOClass matching + if ((ioClass = (__HIDRemoteBridge NSString *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service, + CFSTR(kIOClassKey), + kCFAllocatorDefault, + 0)) != nil) + { + // Match on Apple's AppleIRController and old versions of the Remote Buddy IR Controller + if ([ioClass isEqual:@"AppleIRController"] || [ioClass isEqual:@"RBIOKitAIREmu"]) + { + CFTypeRef candelairHIDRemoteCompatibilityDevice; - serviceMatches = YES; - - if ((candelairHIDRemoteCompatibilityDevice = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityDevice"), kCFAllocatorDefault, 0)) != NULL) - { - if (CFEqual(kCFBooleanTrue, candelairHIDRemoteCompatibilityDevice)) - { - serviceMatches = NO; - } - - CFRelease (candelairHIDRemoteCompatibilityDevice); - } - } + serviceMatches = YES; + + if ((candelairHIDRemoteCompatibilityDevice = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityDevice"), kCFAllocatorDefault, 0)) != NULL) + { + if (CFEqual(kCFBooleanTrue, candelairHIDRemoteCompatibilityDevice)) + { + serviceMatches = NO; + } + + CFRelease (candelairHIDRemoteCompatibilityDevice); + } + } - // Match on the virtual IOSPIRIT IR Controller - if ([ioClass isEqual:@"IOSPIRITIRController"]) - { - serviceMatches = YES; - } - } + // Match on the virtual IOSPIRIT IR Controller + if ([ioClass isEqual:@"IOSPIRITIRController"]) + { + serviceMatches = YES; + } + + CFRelease((CFTypeRef)ioClass); + } - // Match on services that claim compatibility with the HID Remote class (Candelair or third-party) by having a property of CandelairHIDRemoteCompatibilityMask = 1 <Type: Number> - if ((candelairHIDRemoteCompatibilityMask = (NSNumber *)CFBridgingRelease(IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityMask"), kCFAllocatorDefault, 0))) != nil) - { - if ([candelairHIDRemoteCompatibilityMask isKindOfClass:[NSNumber class]]) - { - if ([candelairHIDRemoteCompatibilityMask unsignedIntValue] & kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice) - { - serviceMatches = YES; - } - else - { - serviceMatches = NO; - } - } - } - } + // Match on services that claim compatibility with the HID Remote class (Candelair or third-party) by having a property of CandelairHIDRemoteCompatibilityMask = 1 <Type: Number> + if ((candelairHIDRemoteCompatibilityMask = (__HIDRemoteBridge NSNumber *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityMask"), kCFAllocatorDefault, 0)) != nil) + { + if ([candelairHIDRemoteCompatibilityMask isKindOfClass:[NSNumber class]]) + { + if ([candelairHIDRemoteCompatibilityMask unsignedIntValue] & kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice) + { + serviceMatches = YES; + } + else + { + serviceMatches = NO; + } + } + + CFRelease((CFTypeRef)candelairHIDRemoteCompatibilityMask); + } + } - if (([self delegate]!=nil) && - ([[self delegate] respondsToSelector:@selector(hidRemote:inspectNewHardwareWithService:prematchResult:)])) - { - serviceMatches = [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self inspectNewHardwareWithService:service prematchResult:serviceMatches]; - } - - return (serviceMatches); + if (([self delegate]!=nil) && + ([[self delegate] respondsToSelector:@selector(hidRemote:inspectNewHardwareWithService:prematchResult:)])) + { + serviceMatches = [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self inspectNewHardwareWithService:service prematchResult:serviceMatches]; + } + + return (serviceMatches); } - (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage { - HIDRemoteButtonCode buttonCode = kHIDRemoteButtonCodeNone; + 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; + 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_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_Csmr_Menu: + buttonCode = kHIDRemoteButtonCodeMenuHold; + break; + + case kHIDUsage_Csmr_VolumeIncrement: + buttonCode = kHIDRemoteButtonCodeUp; + break; - case kHIDUsage_GD_SystemMenu: - buttonCode = kHIDRemoteButtonCodeCenter; - break; + case kHIDUsage_Csmr_VolumeDecrement: + buttonCode = kHIDRemoteButtonCodeDown; + break; + } + break; + + case kHIDPage_GenericDesktop: + switch (usage) + { + case kHIDUsage_GD_SystemAppMenu: + buttonCode = kHIDRemoteButtonCodeMenu; + break; - case kHIDUsage_GD_SystemMenuRight: - buttonCode = kHIDRemoteButtonCodeRight; - break; + case kHIDUsage_GD_SystemMenu: + buttonCode = kHIDRemoteButtonCodeCenter; + break; - case kHIDUsage_GD_SystemMenuLeft: - buttonCode = kHIDRemoteButtonCodeLeft; - break; + case kHIDUsage_GD_SystemMenuRight: + buttonCode = kHIDRemoteButtonCodeRight; + break; - case kHIDUsage_GD_SystemMenuUp: - buttonCode = kHIDRemoteButtonCodeUp; - break; + case kHIDUsage_GD_SystemMenuLeft: + buttonCode = kHIDRemoteButtonCodeLeft; + 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; + case kHIDUsage_GD_SystemMenuUp: + // macOS 10.13.6 posts kHIDUsage_GD_SystemMenuUp alongside kHIDUsage_Csmr_VolumeIncrement, + // which ends up being interpreted as a double press. To avoid this, this usage is ignored + // when running under 10.13.6 and later. + if ([HIDRemote OSXVersion] < 0x10d6) + { + buttonCode = kHIDRemoteButtonCodeUp; + } + break; - #ifdef _HIDREMOTE_EXTENSIONS - #define _HIDREMOTE_EXTENSIONS_SECTION 2 - #include "HIDRemoteAdditions.h" - #undef _HIDREMOTE_EXTENSIONS_SECTION - #endif /* _HIDREMOTE_EXTENSIONS */ - } - break; - } - - return (buttonCode); + case kHIDUsage_GD_SystemMenuDown: + // macOS 10.13.6 posts kHIDUsage_GD_SystemMenuDown alongside kHIDUsage_Csmr_VolumeDecrement, + // which ends up being interpreted as a double press. To avoid this, this usage is ignored + // when running under 10.13.6 and later. + if ([HIDRemote OSXVersion] < 0x10d6) + { + 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; - IOReturn returnCode; - HRESULT hResult; - SInt32 score; - BOOL opened = NO, queueStarted = NO; - IOHIDDeviceInterface122 **hidDeviceInterface = NULL; - IOCFPlugInInterface **cfPluginInterface = NULL; - IOHIDQueueInterface **hidQueueInterface = NULL; - io_object_t serviceNotification = 0; - CFRunLoopSourceRef queueEventSource = NULL; - NSMutableDictionary *hidAttribsDict = nil; - CFArrayRef hidElements = NULL; - NSError *error = nil; - UInt32 errorCode = 0; + kern_return_t kernResult; + IOReturn returnCode; + HRESULT hResult; + SInt32 score; + BOOL opened = NO, queueStarted = NO; + IOHIDDeviceInterface122 **hidDeviceInterface = NULL; + IOCFPlugInInterface **cfPluginInterface = NULL; + IOHIDQueueInterface **hidQueueInterface = NULL; + io_object_t serviceNotification = 0; + CFRunLoopSourceRef queueEventSource = NULL; + NSMutableDictionary *hidAttribsDict = nil; + CFArrayRef hidElements = NULL; + NSError *error = nil; + UInt32 errorCode = 0; - if (![self _prematchService:service]) - { - return (NO); - } + if (![self _prematchService:service]) + { + return (NO); + } - do - { - // Create a plugin interface .. - kernResult = IOCreatePlugInInterfaceForService( service, - kIOHIDDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &cfPluginInterface, - &score); - - if (kernResult != kIOReturnSuccess) - { - error = [NSError errorWithDomain:NSMachErrorDomain code:kernResult userInfo:nil]; - errorCode = 1; - break; - } + do + { + // Create a plugin interface .. + kernResult = IOCreatePlugInInterfaceForService( service, + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &cfPluginInterface, + &score); + + if (kernResult != kIOReturnSuccess) + { + error = [NSError errorWithDomain:NSMachErrorDomain code:kernResult userInfo:nil]; + errorCode = 1; + break; + } - - // .. use it to get the HID interface .. - hResult = (*cfPluginInterface)->QueryInterface( cfPluginInterface, - CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), - (LPVOID)&hidDeviceInterface); - - if ((hResult!=S_OK) || (hidDeviceInterface==NULL)) - { - error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil]; - errorCode = 2; - break; - } + + // .. use it to get the HID interface .. + hResult = (*cfPluginInterface)->QueryInterface( cfPluginInterface, + CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), + (LPVOID)&hidDeviceInterface); + + if ((hResult!=S_OK) || (hidDeviceInterface==NULL)) + { + error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil]; + errorCode = 2; + break; + } - - // .. then open it .. - switch (_mode) - { - case kHIDRemoteModeShared: - hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeNone); - break; - - case kHIDRemoteModeExclusive: - case kHIDRemoteModeExclusiveAuto: - hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice); - break; - - default: - goto cleanUp; // Ugh! But there are no "double breaks" available in C AFAIK .. - break; - } - - if (hResult!=S_OK) - { - error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil]; - errorCode = 3; - break; - } - - opened = YES; + + // .. then open it .. + switch (_mode) + { + case kHIDRemoteModeShared: + hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeNone); + break; + + case kHIDRemoteModeExclusive: + case kHIDRemoteModeExclusiveAuto: + hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice); + break; + + default: + goto cleanUp; // Ugh! But there are no "double breaks" available in C AFAIK .. + break; + } + + if (hResult!=S_OK) + { + error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil]; + errorCode = 3; + break; + } + + opened = YES; - // .. query the HID elements .. - returnCode = (*hidDeviceInterface)->copyMatchingElements(hidDeviceInterface, - NULL, - &hidElements); - if ((returnCode != kIOReturnSuccess) || (hidElements==NULL)) - { - error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil]; - errorCode = 4; - - break; - } + // .. query the HID elements .. + returnCode = (*hidDeviceInterface)->copyMatchingElements(hidDeviceInterface, + NULL, + &hidElements); + if ((returnCode != kIOReturnSuccess) || (hidElements==NULL)) + { + error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil]; + errorCode = 4; + + break; + } - // Setup an event queue for HID events! - hidQueueInterface = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); - if (hidQueueInterface == NULL) - { - error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil]; - errorCode = 5; + // Setup an event queue for HID events! + hidQueueInterface = (*hidDeviceInterface)->allocQueue(hidDeviceInterface); + if (hidQueueInterface == NULL) + { + error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil]; + errorCode = 5; - break; - } + break; + } - returnCode = (*hidQueueInterface)->create(hidQueueInterface, 0, 32); - if (returnCode != kIOReturnSuccess) - { - error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil]; - errorCode = 6; + returnCode = (*hidQueueInterface)->create(hidQueueInterface, 0, 32); + if (returnCode != kIOReturnSuccess) + { + error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil]; + errorCode = 6; - break; - } + break; + } - // Setup of attributes stored for this HID device - hidAttribsDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys: - [NSValue valueWithPointer:(const void *)cfPluginInterface], kHIDRemoteCFPluginInterface, - [NSValue valueWithPointer:(const void *)hidDeviceInterface], kHIDRemoteHIDDeviceInterface, - [NSValue valueWithPointer:(const void *)hidQueueInterface], kHIDRemoteHIDQueueInterface, - nil]; + // Setup of attributes stored for this HID device + hidAttribsDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys: + [NSValue valueWithPointer:(const void *)cfPluginInterface], kHIDRemoteCFPluginInterface, + [NSValue valueWithPointer:(const void *)hidDeviceInterface], kHIDRemoteHIDDeviceInterface, + [NSValue valueWithPointer:(const void *)hidQueueInterface], kHIDRemoteHIDQueueInterface, @@ Diff output truncated at 100000 characters. @@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ Skim-app-commit mailing list Skim-app-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/skim-app-commit