Post

Replies

Boosts

Views

Activity

Reply to How to get Magic Mouse/Trackpad InputValueCallback
USBHIDDevice *currentDevice; @interface USBHIDDevice() { IOHIDDeviceRef deviceRef; } @end @implementation USBHIDDevice -(instancetype)initWithDevice:(IOHIDDeviceRef)deviceRef { self = [super init]; if (self) { [self setDeviceRef:deviceRef]; } return self; } -(void)connectHID{ [self openDevice]; } -(void)disConnectHID { if(deviceRef){ [self closeDevice]; } } -(IOReturn)openDevice { if (!deviceRef) { return kIOReturnError; } currentDevice = self; IOReturn ioReturn = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone); if ( kIOReturnSuccess == ioReturn ) { char *inputbuffer = malloc(64); IOHIDDeviceRegisterInputReportCallback(deviceRef, (uint8_t*)inputbuffer, 64, inputCallback, NULL); NSDictionary *inputMatchingDict = @{@(kIOHIDElementUsagePageKey): @(0x09), @(kIOHIDElementUsageKey): @(0x02)}; IOHIDDeviceSetInputValueMatching(deviceRef, (__bridge CFDictionaryRef)inputMatchingDict); IOHIDDeviceRegisterInputValueCallback(deviceRef, mouseInputValueCallback, NULL); }else{ [self setDeviceRef:NULL]; } return ioReturn; } -(IOReturn)closeDevice { IOReturn ioReturn = [self checkHIDDevice]; if (kIOReturnSuccess == ioReturn) { ioReturn = IOHIDDeviceClose(deviceRef, kIOHIDOptionsTypeNone); } [self setDeviceRef:NULL]; return ioReturn; } -(IOReturn)checkHIDDevice{ if (!deviceRef) { NSLog(@"close devie failed(%x).", kIOReturnNotOpen); return kIOReturnNotOpen; } return kIOReturnSuccess; } -(NSArray *)getHIDReprots { if (!deviceRef) { return nil; } NSMutableArray *reports = [[NSMutableArray alloc] init]; CFArrayRef elements; CFIndex i; elements = __IOHIDDeviceCopyMatchingInputElements(deviceRef, NULL); elements = IOHIDDeviceCopyMatchingElements(deviceRef, NULL, kIOHIDOptionsTypeNone); for (i = 0; i<CFArrayGetCount(elements); i++) { const IOHIDElementRef element = (void*)CFArrayGetValueAtIndex(elements, i); IOHIDElementType eleType = IOHIDElementGetType(element); NSString *eleTypeStr = @""; switch (eleType) { case kIOHIDElementTypeInput_Misc: eleTypeStr = @"kIOHIDElementTypeInput_Misc"; break; case kIOHIDElementTypeInput_Button: eleTypeStr = @"kIOHIDElementTypeInput_Button"; break; case kIOHIDElementTypeInput_Axis: eleTypeStr = @"kIOHIDElementTypeInput_Axis"; break; case kIOHIDElementTypeInput_ScanCodes: eleTypeStr = @"kIOHIDElementTypeInput_ScanCodes"; break; case kIOHIDElementTypeInput_NULL: eleTypeStr = @"kIOHIDElementTypeInput_NULL"; break; case kIOHIDElementTypeOutput: eleTypeStr = @"kIOHIDElementTypeOutput"; break; case kIOHIDElementTypeFeature: eleTypeStr = @"kIOHIDElementTypeFeature"; break; case kIOHIDElementTypeCollection: eleTypeStr = @"kIOHIDElementTypeCollection"; break; default: break; } uint32_t page = IOHIDElementGetUsagePage(element); uint32_t usage = IOHIDElementGetUsage(element); uint32_t reportID = IOHIDElementGetReportID(element); uint32_t reportSize = IOHIDElementGetReportSize(element); uint32_t reportCount = IOHIDElementGetReportCount(element); NSString *elementStr = [[NSString alloc] initWithFormat:@" reportID:%d, reportSize:%d, type:%@, UsagePage:%d, usage:%d, reportCount:%d\n\n",reportID, reportSize, eleTypeStr, page, usage, reportCount]; [reports addObject:elementStr]; } return reports; } CFArrayRef __IOHIDDeviceCopyMatchingInputElements(IOHIDDeviceRef device, CFArrayRef multiple) { CFMutableArrayRef inputElements = NULL; CFArrayRef elements = NULL; CFIndex index, count; // Grab the matching multiple. If one has not already been specified, // fallback to the default if ( multiple ) { CFRetain(multiple); } else { uint32_t inputTypes[] = { kIOHIDElementTypeInput_Misc, kIOHIDElementTypeInput_Button, kIOHIDElementTypeInput_Axis, kIOHIDElementTypeInput_ScanCodes}; count = sizeof(inputTypes) / sizeof(uint32_t); CFDictionaryRef matching[count]; bzero(matching, sizeof(CFDictionaryRef) * count); CFStringRef key = CFSTR(kIOHIDElementTypeKey); for ( index=0; index<count; index++ ) { CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &inputTypes[index]); matching[index] = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&key, (const void **)&number, 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(number); } multiple = CFArrayCreate(kCFAllocatorDefault, (const void **)matching, count, &kCFTypeArrayCallBacks); for ( index=0; index<count; index++ ) CFRelease(matching[index]); } if ( !multiple ) return NULL; count = CFArrayGetCount( multiple ); for ( index=0; index<count; index++) { elements = IOHIDDeviceCopyMatchingElements( device, CFArrayGetValueAtIndex(multiple, index), 0); if ( !elements ) continue; if ( !inputElements ) inputElements = CFArrayCreateMutableCopy( kCFAllocatorDefault, 0, elements); else CFArrayAppendArray( inputElements, elements, CFRangeMake(0, CFArrayGetCount(elements))); CFRelease(elements); } CFRelease(multiple); return inputElements; } static void inputCallback(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report, CFIndex reportLength) { [currentDevice sendMessageWithDelegate:report length:reportLength]; } static void mouseInputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) { NSLog(@"handle input value"); } -(void)sendMessageWithDelegate:(uint8_t*)recvData length:(CFIndex)reportLength{ }
Jun ’24