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 IOHIDSetModifierLockState( io_connect_t handle __unused, int selector, bool state ) { kern_return_t err = kIOReturnSuccess; 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); IOHIDServiceClientSetProperty(service, key, state ? kCFBooleanTrue : kCFBooleanFalse); } } exit: if (services) { CFRelease(services); } if (client) { CFRelease(client); } return err; }
kern_return_t IOHIDSetHIDParameterToEventSystem(io_connect_t handle, CFStringRef key, CFTypeRef parameter) { IOHIDEventSystemClientRef client = IOHIDEventSystemClientCreateWithType (kCFAllocatorDefault, kIOHIDEventSystemClientTypeMonitor, NULL); kern_return_t kr = kIOReturnNotReady; if (!client) { goto exit; } kr = kIOReturnUnsupported; io_service_t service = 0; if (IOConnectGetService (handle, &service) == kIOReturnSuccess) { if (IOObjectConformsTo (service, "IOHIDSystem")) { IOHIDEventSystemClientSetProperty(client, key, parameter); kr = kIOReturnSuccess; } else { uint64_t entryID = 0; if (IORegistryEntryGetRegistryEntryID (service, &entryID) == kIOReturnSuccess) { IOHIDServiceClientRef serviceClient = IOHIDEventSystemClientCopyServiceForRegistryID(client, entryID); if (serviceClient) { if (IOHIDServiceClientSetProperty(serviceClient, key, parameter)) { kr = kIOReturnSuccess; } else { kr = kIOReturnInternalError; } CFRelease(serviceClient); } } } IOObjectRelease(service); } exit: if (client) { CFRelease(client); } if (kr) { os_log_error(_IOHIDLog(), "Fail to set parameter with status 0x%x", kr); } return kr; }