void fillDescriptorInfo(IOHIDDeviceRef devRef, PointingDeviceDescriptor &desc) { desc.devURI = hidDeviceURI(devRef); desc.vendor = hidDeviceGetStringProperty(devRef, CFSTR(kIOHIDManufacturerKey)); desc.product = hidDeviceGetStringProperty(devRef, CFSTR(kIOHIDProductKey)); desc.vendorID = hidDeviceGetIntProperty(devRef, CFSTR(kIOHIDVendorIDKey)); desc.productID = hidDeviceGetIntProperty(devRef, CFSTR(kIOHIDProductIDKey)); }
void osxHIDInputDevice::AddDevice(void *context, IOReturn /*result*/, void */*sender*/, IOHIDDeviceRef device) { osxHIDInputDevice *self = (osxHIDInputDevice*)context ; URI devUri = hidDeviceURI(device) ; // std::cerr << std::endl << self->uri.asString() << std::endl << devUri.asString() << std::endl << std::endl ; bool match = self->theDevice==0 && (self->uri.isEmpty() || self->uri.scheme=="any" || self->uri.resemble(devUri)) ; if (self->debugLevel>0) { std::cerr << (match?"+ ":" ") ; hidDebugDevice(device, std::cerr) ; std::cerr << std::endl ; } if (!match) return ; self->theDevice = new __device(device) ; self->uri = devUri ; CFDataRef descriptor = (CFDataRef)IOHIDDeviceGetProperty(self->theDevice->device, CFSTR(kIOHIDReportDescriptorKey)) ; if (descriptor) { const UInt8 *bytes = CFDataGetBytePtr(descriptor) ; CFIndex length = CFDataGetLength(descriptor) ; if (self->inputreport_callback && !self->parser->setDescriptor(bytes, length)) std::cerr << "osxHIDInputDevice::AddDevice: unable to parse the HID report descriptor" << std::endl; if (self->debugLevel > 1) { std::cerr << " HID report descriptor: [ " << std::flush ; for (int i=0; i<length; ++i) std::cerr << std::hex << std::setfill('0') << std::setw(2) << (int)bytes[i] << " " ; std::cerr << "]" << std::endl ; } } #if DEBUG_MODE std::cerr << "Setting up callbacks" << std::endl ; #endif // ---------------------------------------------------------------- if (self->inputreport_callback) { #if DEBUG_MODE std::cerr << "Setting up report callback" << std::endl ; #endif #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 IOHIDDeviceRegisterInputReportWithTimeStampCallback(device, self->theDevice->report, sizeof(self->theDevice->report), self->inputreport_callback, self->inputreport_context) ; #else IOHIDDeviceRegisterInputReportCallback(device, self->theDevice->report, sizeof(self->theDevice->report), self->inputreport_callback, self->inputreport_context) ; #endif } // ---------------------------------------------------------------- if (self->value_callback) { #if DEBUG_MODE std::cerr << "Setting up value callback" << std::endl ; #endif IOHIDDeviceSetInputValueMatchingMultiple(device, self->elements_match) ; IOHIDDeviceRegisterInputValueCallback(device, self->value_callback, self->value_context) ; } // ---------------------------------------------------------------- if (self->queue_callback) { #if DEBUG_MODE std::cerr << "Setting up queue callback" << std::endl ; #endif self->theDevice->queue = IOHIDQueueCreate(kCFAllocatorDefault, device, queueSize, kIOHIDOptionsTypeNone) ; if (self->elements_match) { #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "Queue, elements_match" << std::endl ; #endif CFIndex mcount = CFArrayGetCount(self->elements_match) ; for (CFIndex mindex=0; mindex<mcount; ++mindex) { CFDictionaryRef matching = (CFDictionaryRef)CFArrayGetValueAtIndex(self->elements_match, mindex) ; CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, matching, kIOHIDOptionsTypeNone) ; if (!elements) continue ; CFIndex ecount = CFArrayGetCount(elements) ; for (CFIndex eindex=0; eindex<ecount; ++eindex) { IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, eindex) ; IOHIDQueueAddElement(self->theDevice->queue, e) ; #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "elements_match EINDEX: " << eindex << ", usagepage: " << IOHIDElementGetUsagePage(e) << ", usage: " << IOHIDElementGetUsage(e) << std::endl ; #endif } } } else { #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "Queue, no elements_match" << std::endl ; #endif CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, 0, kIOHIDOptionsTypeNone) ; if (elements) { CFIndex ecount = CFArrayGetCount(elements) ; for (CFIndex eindex=0; eindex<ecount; ++eindex) { IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, eindex) ; IOHIDQueueAddElement(self->theDevice->queue, e) ; #if DEBUG && DEBUG_MATCHING_ELEMENTS std::cerr << "!elements_match EINDEX: " << eindex << ", usagepage: " << IOHIDElementGetUsagePage(e) << ", usage: " << IOHIDElementGetUsage(e) << std::endl ; #endif } } } IOHIDQueueRegisterValueAvailableCallback(self->theDevice->queue, self->queue_callback, self->queue_context) ; IOHIDQueueScheduleWithRunLoop(self->theDevice->queue, CFRunLoopGetMain(), kCFRunLoopDefaultMode) ; IOHIDQueueStart(self->theDevice->queue) ; } // ---------------------------------------------------------------- }