static void serviceClientCallback(void * target, void * refcon, IOHIDServiceClientRef service) { CFStringRef string; if ( refcon == kServiceAdded ) { IOHIDServiceClientRegisterRemovalCallback(service, serviceClientCallback, NULL, (void*)kServiceRemoved); } printf("SERVICE %s:\n", (char *)refcon); string = CFCopyDescription(service); if ( string ) { printf("%s\n", CFStringGetCStringPtr(string, kCFStringEncodingMacRoman)); CFRelease(string); } if ( __clientType == kIOHIDEventSystemClientTypeRateControlled ) { CFNumberRef number; uint32_t primaryUsagePage=0, primaryUsage=0; number = IOHIDServiceClientCopyProperty(service, CFSTR(kIOHIDServicePrimaryUsagePageKey)); if ( number ) { CFNumberGetValue(number, kCFNumberSInt32Type, &primaryUsagePage); CFRelease(number); } number = IOHIDServiceClientCopyProperty(service, CFSTR(kIOHIDServicePrimaryUsageKey)); if ( number ) { CFNumberGetValue(number, kCFNumberSInt32Type, &primaryUsage); CFRelease(number); } if ( primaryUsagePage == __matchingUsagePage && primaryUsage == __matchingUsage ) { number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &__matchingInterval); if ( number ) { IOHIDServiceClientSetProperty(service, CFSTR(kIOHIDServiceReportIntervalKey), number); CFRelease(number); } } } }
kern_return_t IOHIDGetModifierLockState( io_connect_t handle __unused, int selector, bool *state ) { kern_return_t err = kIOReturnSuccess; boolean_t modifierState = false; IOHIDEventSystemClientRef client = NULL; CFArrayRef services = NULL; if (selector != kIOHIDCapsLockState && selector != kIOHIDNumLockState) { err = kIOReturnBadArgument; goto exit; } client = IOHIDEventSystemClientCreateWithType (kCFAllocatorDefault, kIOHIDEventSystemClientTypePassive, NULL); if (client == NULL) { os_log_error (OS_LOG_DEFAULT, "Failed to create event system client"); return kIOReturnError; } services = (CFArrayRef) IOHIDEventSystemClientCopyServices (client); if (services == NULL || CFArrayGetCount(services) == 0) { err = kIOReturnNoDevice; goto exit; } for (CFIndex index = 0; index < CFArrayGetCount(services); index++) { IOHIDServiceClientRef service = (IOHIDServiceClientRef) CFArrayGetValueAtIndex(services, index); if (service && IOHIDServiceClientConformsTo (service, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) { CFStringRef key = (selector == kIOHIDCapsLockState) ? CFSTR(kIOHIDServiceCapsLockStateKey) : CFSTR(kIOHIDServiceNumLockStateKey); CFBooleanRef modifierStateProp = (CFBooleanRef)IOHIDServiceClientCopyProperty(service, key); if (modifierStateProp) { modifierState = CFBooleanGetValue(modifierStateProp); if (modifierState) { break; } CFRelease(modifierStateProp); } } } exit: *state = modifierState; if (services) { CFRelease(services); } if (client) { CFRelease(client); } return err; }
kern_return_t IOHIDCopyHIDParameterFromEventSystem(io_connect_t handle, CFStringRef key, CFTypeRef *parameter) { CFTypeRef param = NULL; IOHIDEventSystemClientRef client = IOHIDEventSystemClientCreateWithType (kCFAllocatorDefault, kIOHIDEventSystemClientTypePassive, NULL); kern_return_t kr = kIOReturnNotReady; if (!client) { goto exit; } io_service_t service = 0; if (IOConnectGetService (handle, &service) == kIOReturnSuccess) { if (IOObjectConformsTo (service, "IOHIDSystem")) { param = IOHIDEventSystemClientCopyProperty(client, key); } else { uint64_t entryID = 0; if (IORegistryEntryGetRegistryEntryID (service, &entryID) == kIOReturnSuccess) { IOHIDServiceClientRef serviceClient = IOHIDEventSystemClientCopyServiceForRegistryID(client, entryID); if (serviceClient) { param = IOHIDServiceClientCopyProperty(serviceClient, key); CFRelease(serviceClient); } } } IOObjectRelease(service); } exit: if (param) { *parameter = param; kr = kIOReturnSuccess; } if (client) { CFRelease(client); } if (kr) { os_log_error(_IOHIDLog(), "Fail to get parameter with status 0x%x", kr); } return kr; }