static void listClients() { IOHIDEventSystemClientRef eventSystem = IOHIDEventSystemClientCreateWithType(kCFAllocatorDefault, kIOHIDEventSystemClientTypeAdmin, NULL); CFIndex types; require(eventSystem, exit); for ( types=kIOHIDEventSystemClientTypeAdmin; types<=kIOHIDEventSystemClientTypeRateControlled; types++ ) { CFArrayRef clients = _IOHIDEventSystemClientCopyClientDescriptions(eventSystem, (IOHIDEventSystemClientType)types); CFIndex index; if ( !clients ) continue; for ( index=0; index<CFArrayGetCount(clients); index++ ) { CFStringRef clientDebugDesc = (CFStringRef)CFArrayGetValueAtIndex(clients, index); printf("%s\n", CFStringGetCStringPtr(clientDebugDesc, CFStringGetSystemEncoding())); } CFRelease(clients); } exit: if (eventSystem) CFRelease(eventSystem); }
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; }
static void runClient() { IOHIDEventSystemClientRef eventSystem = IOHIDEventSystemClientCreateWithType(kCFAllocatorDefault, __clientType, NULL); require_action(eventSystem, exit, printf("Unable to create client")); require_action(!__dispatchOnly, exit, dispatchClientEvents(eventSystem, __dispatchEventMask)); if ( __dispatchEventMask ) { pthread_attr_t attr; pthread_t tid; assert(!pthread_attr_init(&attr)); assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); assert(!pthread_create(&tid, &attr, &dispatchClientThread, eventSystem)); assert(!pthread_attr_destroy(&attr)); } IOHIDEventSystemClientScheduleWithRunLoop(eventSystem, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); IOHIDEventSystemClientRegisterEventCallback(eventSystem, (IOHIDEventCallback)eventCallback, NULL, NULL); IOHIDEventSystemClientRegisterDeviceMatchingCallback(eventSystem, serviceClientCallback, NULL, (void*)kServiceAdded); CFArrayRef services = IOHIDEventSystemClientCopyServices(eventSystem); if ( services ) { CFIndex index, count; for(index=0, count = CFArrayGetCount(services); index<count; index++) serviceClientCallback(NULL, (void*)kServiceAdded, (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, index)); CFRelease(services); } CFRunLoopRun(); exit: if ( eventSystem ) CFRelease(eventSystem); }
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; }
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; }
static void listServices() { IOHIDEventSystemClientRef eventSystem = IOHIDEventSystemClientCreateWithType(kCFAllocatorDefault, kIOHIDEventSystemClientTypeAdmin, NULL); CFArrayRef services = NULL; CFIndex index; require(eventSystem, exit); services = _IOHIDEventSystemClientCopyServiceDescriptions(eventSystem); require(services, exit); for ( index=0; index<CFArrayGetCount(services); index++ ) { CFStringRef serviceDebugDesc = (CFStringRef)CFArrayGetValueAtIndex(services, index); printf("%s\n", CFStringGetCStringPtr(serviceDebugDesc, CFStringGetSystemEncoding())); } exit: if ( services ) CFRelease(services); if (eventSystem) CFRelease(eventSystem); }