// open - open 1 or more devices // // Inputs: // max = maximum number of devices to open // vid = Vendor ID, or -1 if any // pid = Product ID, or -1 if any // usage_page = top level usage page, or -1 if any // usage = top level usage number, or -1 if any // Output: // actual number of devices opened // int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage) { static IOHIDManagerRef hid_manager=NULL; CFMutableDictionaryRef dict; CFNumberRef num; IOReturn ret; hid_t *p; int count=0; if (first_hid) free_all_hid(); //printf("pjrc_rawhid_open, max=%d\n", max); if (max < 1) return 0; // Start the HID Manager // http://developer.apple.com/technotes/tn2007/tn2187.html if (!hid_manager) { hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { if (hid_manager) CFRelease(hid_manager); return 0; } } if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) { // Tell the HID Manager what type of devices we want dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dict) return 0; if (vid > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid); CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num); CFRelease(num); } if (pid > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid); CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num); CFRelease(num); } if (usage_page > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page); CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num); CFRelease(num); } if (usage > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num); CFRelease(num); } IOHIDManagerSetDeviceMatching(hid_manager, dict); CFRelease(dict); } else { IOHIDManagerSetDeviceMatching(hid_manager, NULL); } // set up a callbacks for device attach & detach IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { printf("Could not start IOHIDManager"); IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(hid_manager); return 0; } printf("run loop\n"); // let it do the callback for all devices while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ; // count up how many were added by the callback for (p = first_hid; p; p = p->next) count++; return count; }
static void init_hid_manager(void) { CFMutableDictionaryRef dict; IOReturn ret; if (hid_manager) return; hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { if (hid_manager) CFRelease(hid_manager); printf_verbose("no HID Manager - maybe this is a pre-Leopard (10.5) system?\n"); return; } dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dict) return; IOHIDManagerSetDeviceMatching(hid_manager, dict); CFRelease(dict); IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(hid_manager); printf_verbose("Error opening HID Manager"); } }
HIDJoystickManager::HIDJoystickManager() : m_manager(0), m_joystickCount(0) { m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); CFDictionaryRef mask0 = HIDInputManager::copyDevicesMask(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); CFDictionaryRef mask1 = HIDInputManager::copyDevicesMask(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); CFDictionaryRef maskArray[2]; maskArray[0] = mask0; maskArray[1] = mask1; CFArrayRef mask = CFArrayCreate(NULL, (const void**)maskArray, 2, NULL); IOHIDManagerSetDeviceMatchingMultiple(m_manager, mask); CFRelease(mask); CFRelease(mask1); CFRelease(mask0); IOHIDManagerRegisterDeviceMatchingCallback(m_manager, pluggedIn, this); IOHIDManagerRegisterDeviceRemovalCallback(m_manager, pluggedOut, this); IOHIDManagerScheduleWithRunLoop(m_manager, CFRunLoopGetCurrent(), RunLoopMode); IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone); }
void TeensyControls_usb_close(void) { teensy_t *t; int wait=0; for (t = TeensyControls_first_teensy; t; t = t->next) { if (t->online) { printf("close USB device\n"); IOHIDDeviceRegisterInputReportCallback(t->usb.dev, t->usb.inbuf, 64, NULL, NULL); // TODO: how to terminate input thread? // TODO: how to terminate output thread? pthread_cond_signal(&t->output_event); IOHIDDeviceClose(t->usb.dev, 0); t->online = 0; } } if (hmgr) { printf("closing hid manager\n"); IOHIDManagerRegisterDeviceMatchingCallback(hmgr, NULL, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hmgr, NULL, NULL); IOHIDManagerClose(hmgr, 0); hmgr = NULL; } while (++wait < 20 && num_thread_alive() > 0) { usleep(10000); printf("wait #%d for thread exit\n", wait); } }
int TeensyControls_usb_init(void) { CFMutableArrayRef array = NULL; IOReturn ret; hmgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!hmgr) goto fail; if (CFGetTypeID(hmgr) != IOHIDManagerGetTypeID()) goto fail; array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if (!array) goto fail; add_to_array(array, 0x16C0, 0x0488, 0xFF1C, 0xA739); // Teensyduino Flight Sim IOHIDManagerSetDeviceMatchingMultiple(hmgr, array); CFRelease(array); array = NULL; IOHIDManagerScheduleWithRunLoop(hmgr, CFRunLoopGetCurrent(), dev_run_mode); IOHIDManagerRegisterDeviceMatchingCallback(hmgr, attach_callback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hmgr, detach_callback, NULL); ret = IOHIDManagerOpen(hmgr, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { IOHIDManagerUnscheduleFromRunLoop(hmgr, CFRunLoopGetCurrent(), dev_run_mode); goto fail; } CFRunLoopAddCommonMode(CFRunLoopGetCurrent(), dev_run_mode); return 1; fail: if (array) CFRelease(array); if (hmgr) CFRelease(hmgr); return 0; }
osxHIDInputDevice::osxHIDInputDevice(URI uri, const char *device_description, const char *elements_description):parser(0) { theDevice = 0 ; inputreport_callback = 0 ; inputreport_context = 0 ; value_callback = 0 ; value_context = 0 ; queue_callback = 0 ; queue_context = 0 ; debugLevel = OSX_DEFAULT_DEBUGLEVEL ; seizeDevice = OSX_DEFAULT_SEIZEDEVICE ; this->uri = uri ; this->uri.generalize() ; URI::getQueryArg(uri.query, "debugLevel", &debugLevel) ; URI::getQueryArg(uri.query, "seize", &seizeDevice) ; parser = new HIDReportParser(NULL, 0, debugLevel); manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone) ; if (!manager) throw std::runtime_error("IOHIDManagerCreate failed") ; device_match = 0 ; if (device_description) { if (!strncmp(device_description, "<?xml", 5)) { device_match = (CFMutableDictionaryRef)getPropertyListFromXML(device_description) ; if (debugLevel>1) std::cerr << "Filtering devices based on XML description: " << device_description << std::endl ; } else { device_match = (CFMutableDictionaryRef)getPropertyListFromFile(device_description) ; if (debugLevel>1) std::cerr << "Filtering devices based on file " << device_description << std::endl ; } } IOHIDManagerSetDeviceMatching(manager, device_match) ; elements_match = 0 ; if (elements_description) { if (!strncmp(elements_description, "<?xml", 5)) { elements_match = (CFArrayRef)getPropertyListFromXML(elements_description) ; if (debugLevel>1) std::cerr << "Filtering elements based on XML description: " << elements_description << std::endl ; } else { elements_match = (CFArrayRef)getPropertyListFromFile(elements_description) ; if (debugLevel>1) std::cerr << "Filtering elements based on file " << elements_description << std::endl ; } } IOHIDManagerRegisterDeviceMatchingCallback(manager, AddDevice, (void*)this) ; IOHIDManagerRegisterDeviceRemovalCallback(manager, RemoveDevice, (void*)this) ; IOHIDManagerScheduleWithRunLoop(manager, CFRunLoopGetMain(), kCFRunLoopDefaultMode) ; IOOptionBits inOptions = seizeDevice ? kIOHIDOptionsTypeSeizeDevice : kIOHIDOptionsTypeNone ; if (IOHIDManagerOpen(manager, inOptions)!=kIOReturnSuccess) throw std::runtime_error("IOHIDManagerOpen failed") ; }
UsbMonitor_mac::UsbMonitor_mac(): QObject() { // Create an HID Manager hidmanager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); // Create a Matching Dictionary for filtering HID devices CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // Set device info in the Matching Dictionary (pid/vid/usage/usagepage) //VendorID int val = MOOLTIPASS_VENDORID; CFNumberRef vid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &val); CFDictionarySetValue(matchDict, CFSTR(kIOHIDVendorIDKey), vid); CFRelease(vid); //ProductID val = MOOLTIPASS_PRODUCTID; CFNumberRef pid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &val); CFDictionarySetValue(matchDict, CFSTR(kIOHIDProductIDKey), pid); CFRelease(pid); //Usage val = MOOLTIPASS_USAGE; CFNumberRef usage = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &val); CFDictionarySetValue(matchDict, CFSTR(kIOHIDDeviceUsageKey), usage); CFRelease(usage); //Usage Page val = MOOLTIPASS_USAGE_PAGE; CFNumberRef usagep = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &val); CFDictionarySetValue(matchDict, CFSTR(kIOHIDDeviceUsagePageKey), usagep); CFRelease(usagep); // Register the Matching Dictionary to the HID Manager IOHIDManagerSetDeviceMatching(hidmanager, matchDict); // Register a callback for USB device detection with the HID Manager IOHIDManagerRegisterDeviceMatchingCallback(hidmanager, &_device_matching_callback, this); // Register a callback fro USB device removal with the HID Manager IOHIDManagerRegisterDeviceRemovalCallback(hidmanager, &_device_removal_callback, this); // Register the HID Manager on our app’s run loop // CFRunLoopGetCurrent() can safely be used because Qt uses CFRunloop in its backend platform plugin IOHIDManagerScheduleWithRunLoop(hidmanager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); // Open the HID Manager IOReturn ioret = IOHIDManagerOpen(hidmanager, kIOHIDOptionsTypeNone); if (ioret) qWarning() << "Failed to open IOHIDManager"; }
void Gamepad_init() { if (hidManager == NULL) { CFStringRef keys[2]; int value; CFNumberRef values[2]; CFDictionaryRef dictionaries[3]; CFArrayRef array; hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); keys[0] = CFSTR(kIOHIDDeviceUsagePageKey); keys[1] = CFSTR(kIOHIDDeviceUsageKey); value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_Joystick; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_GamePad; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_MultiAxisController; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[2] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); array = CFArrayCreate(kCFAllocatorDefault, (const void **) dictionaries, 3, &kCFTypeArrayCallBacks); CFRelease(dictionaries[0]); CFRelease(dictionaries[1]); CFRelease(dictionaries[2]); IOHIDManagerSetDeviceMatchingMultiple(hidManager, array); CFRelease(array); IOHIDManagerRegisterDeviceMatchingCallback(hidManager, onDeviceMatched, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hidManager, onDeviceRemoved, NULL); IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone); // Force gamepads to be recognized immediately. The normal run loop mode takes a few frames, // but we can run one iteration with a custom mode to do it without a delay. IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), GAMEPAD_RUN_LOOP_MODE); CFRunLoopRunInMode(GAMEPAD_RUN_LOOP_MODE, 0, true); } }
HIDJoystickManager::~HIDJoystickManager() { IOHIDManagerUnscheduleFromRunLoop(m_manager, CFRunLoopGetCurrent(), RunLoopMode); IOHIDManagerRegisterDeviceMatchingCallback(m_manager, NULL, 0); IOHIDManagerRegisterDeviceRemovalCallback(m_manager, NULL, 0); IOHIDManagerClose(m_manager, kIOHIDOptionsTypeNone); }
void Gamepad_init() { if (hidManager == NULL) { CFStringRef keys[2]; int value; CFNumberRef values[2]; CFDictionaryRef dictionaries[3]; CFArrayRef array; hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone); IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); keys[0] = CFSTR(kIOHIDDeviceUsagePageKey); keys[1] = CFSTR(kIOHIDDeviceUsageKey); value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_Joystick; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_GamePad; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_MultiAxisController; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[2] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); array = CFArrayCreate(kCFAllocatorDefault, (const void **) dictionaries, 3, &kCFTypeArrayCallBacks); CFRelease(dictionaries[0]); CFRelease(dictionaries[1]); CFRelease(dictionaries[2]); IOHIDManagerSetDeviceMatchingMultiple(hidManager, array); CFRelease(array); IOHIDManagerRegisterDeviceMatchingCallback(hidManager, onDeviceMatched, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hidManager, onDeviceRemoved, NULL); } }
void HID_API_EXPORT hid_close(hid_device *dev) { if ( !dev ) { return; } /* Disconnect the report callback before close. */ if (!dev->disconnected) { IOHIDDeviceRegisterInputReportCallback( dev->device_handle, dev->input_report_buf, dev->max_input_report_len, NULL, dev); IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, NULL, dev); IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode); IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode); } /* Cause read_thread() to stop. */ dev->shutdown_thread = 1; /* Wake up the run thread's event loop so that the thread can exit. */ CFRunLoopSourceSignal(dev->source); CFRunLoopWakeUp(dev->run_loop); /* Notify the read thread that it can shut down now. */ pthread_barrier_wait(&dev->shutdown_barrier); /* Wait for read_thread() to end. */ pthread_join(dev->thread, NULL); /* Close the OS handle to the device, but only if it's not been unplugged. If it's been unplugged, then calling IOHIDDeviceClose() will crash. */ if (!dev->disconnected) { IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone); } /* Clear out the queue of received reports. */ pthread_mutex_lock(&dev->mutex); while (dev->input_reports) { return_data(dev, NULL, 0); } pthread_mutex_unlock(&dev->mutex); free_hid_device(dev); }
int yUSB_init(yContextSt *ctx,char *errmsg) { int c_vendorid = YOCTO_VENDORID; IOReturn tIOReturn; CFMutableDictionaryRef dictionary; CFNumberRef Vendorid; if(!yReserveGlobalAccess(ctx)){ return YERRMSG(YAPI_DOUBLE_ACCES,"Another process is already using yAPI"); } ctx->usb_thread_state = USB_THREAD_NOT_STARTED; pthread_create(&ctx->usb_thread, NULL, event_thread, ctx); yInitializeCriticalSection(&ctx->hidMCS); // Initialize HID Manager ctx->hidM = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); // create dictionary to match Yocto devices dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault,1,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks); Vendorid = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &c_vendorid ); CFDictionarySetValue( dictionary, CFSTR( kIOHIDVendorIDKey ), Vendorid ); // register the dictionary IOHIDManagerSetDeviceMatching( ctx->hidM, dictionary ); // now we can release the dictionary CFRelease(dictionary); IOHIDManagerRegisterDeviceRemovalCallback(ctx->hidM,hid_device_removal_callback,ctx); //register hid into read_thead's RunnLoop while(ctx->usb_thread_state != USB_THREAD_RUNNING){ usleep(50000); } IOHIDManagerScheduleWithRunLoop(ctx->hidM, ctx->usb_run_loop, kCFRunLoopDefaultMode); // Now open the IO HID Manager reference tIOReturn = IOHIDManagerOpen( ctx->hidM, kIOHIDOptionsTypeNone ); CFRelease(Vendorid); if(kIOReturnSuccess != tIOReturn ||CFGetTypeID(ctx->hidM) != IOHIDManagerGetTypeID()){ HALLOG("Unable to Open HID Manager"); return YERRMSG(YAPI_NOT_SUPPORTED,"Unable to Open HID Manager"); } return YAPI_SUCCESS; }
HIDGamepadProvider::HIDGamepadProvider() : m_shouldDispatchCallbacks(false) , m_connectionDelayTimer(this, &HIDGamepadProvider::connectionDelayTimerFired) , m_inputNotificationTimer(this, &HIDGamepadProvider::inputNotificationTimerFired) { m_manager = adoptCF(IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); RetainPtr<CFDictionaryRef> joystickDictionary = deviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); RetainPtr<CFDictionaryRef> gamepadDictionary = deviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); CFDictionaryRef devices[] = { joystickDictionary.get(), gamepadDictionary.get() }; RetainPtr<CFArrayRef> matchingArray = adoptCF(CFArrayCreate(kCFAllocatorDefault, (const void**)devices, 2, &kCFTypeArrayCallBacks)); IOHIDManagerSetDeviceMatchingMultiple(m_manager.get(), matchingArray.get()); IOHIDManagerRegisterDeviceMatchingCallback(m_manager.get(), deviceAddedCallback, this); IOHIDManagerRegisterDeviceRemovalCallback(m_manager.get(), deviceRemovedCallback, this); IOHIDManagerRegisterInputValueCallback(m_manager.get(), deviceValuesChangedCallback, this); }
dump_hid_value(void) { manager_ = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!manager_) { return; } auto device_matching_dictionaries = iokit_utility::create_device_matching_dictionaries({ std::make_pair(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard), std::make_pair(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse), std::make_pair(kHIDPage_GenericDesktop, kHIDUsage_GD_Pointer), }); if (device_matching_dictionaries) { IOHIDManagerSetDeviceMatchingMultiple(manager_, device_matching_dictionaries); CFRelease(device_matching_dictionaries); IOHIDManagerRegisterDeviceMatchingCallback(manager_, static_device_matching_callback, this); IOHIDManagerRegisterDeviceRemovalCallback(manager_, static_device_removal_callback, this); IOHIDManagerScheduleWithRunLoop(manager_, CFRunLoopGetMain(), kCFRunLoopDefaultMode); } }
void IOKitHIDEventPublisher::restart() { if (run_loop_ == nullptr) { // There is no run loop to restart. return; } // Remove any existing stream. stop(); if (manager_ == nullptr) { manager_ = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); } // Match anything. IOHIDManagerSetDeviceMatching(manager_, nullptr); auto status = IOHIDManagerOpen(manager_, kIOHIDOptionsTypeNone); if (status != kIOReturnSuccess) { LOG(WARNING) << RLOG(617) << "Cannot open IOKit HID Manager"; return; } // Enumerate initial set of devices matched before time=0. CFSetRef devices = IOHIDManagerCopyDevices(manager_); if (devices == nullptr) { return; } initial_device_count_ = CFSetGetCount(devices); CFRelease(devices); // Register callbacks. IOHIDManagerRegisterDeviceMatchingCallback( manager_, IOKitHIDEventPublisher::MatchingCallback, nullptr); IOHIDManagerRegisterDeviceRemovalCallback( manager_, IOKitHIDEventPublisher::RemovalCallback, nullptr); IOHIDManagerScheduleWithRunLoop(manager_, run_loop_, kCFRunLoopDefaultMode); manager_started_ = true; }
//! Close the HID device void pjrc_rawhid::close(int) { // Make sure any pending locks are done QMutexLocker lock(m_writeMutex); if (device_open) { device_open = false; CFRunLoopStop(the_correct_runloop); if (!unplugged) { IOHIDDeviceUnscheduleFromRunLoop(dev, the_correct_runloop, kCFRunLoopDefaultMode); IOHIDDeviceRegisterInputReportCallback(dev, buffer, sizeof(buffer), NULL, NULL); IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone); } IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); IOHIDManagerClose(hid_manager, 0); dev = NULL; hid_manager = NULL; } }
osxPointingDeviceManager::osxPointingDeviceManager() { manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!manager) throw std::runtime_error("IOHIDManagerCreate failed"); const char *plist = hidDeviceFromVendorProductUsagePageUsage(0, 0, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse).c_str(); CFMutableDictionaryRef device_match = (CFMutableDictionaryRef)getPropertyListFromXML(plist); IOHIDManagerSetDeviceMatching(manager, device_match); IOHIDManagerRegisterDeviceMatchingCallback(manager, AddDevice, (void*)this); IOHIDManagerRegisterDeviceRemovalCallback(manager, RemoveDevice, (void*)this); #if USE_CURRENT_RUNLOOP CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFStringRef runLoopMode = kCFRunLoopDefaultMode; #else CFRunLoopRef runLoop = CFRunLoopGetMain(); CFStringRef runLoopMode = kCFRunLoopCommonModes; #endif IOHIDManagerScheduleWithRunLoop(manager, runLoop, runLoopMode); }
GamepadManager::GamepadManager() : bStateChanged(false) { HidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); IOHIDManagerOpen(HidManager, kIOHIDOptionsTypeNone); IOHIDManagerScheduleWithRunLoop(HidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); // Setup device matching. CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey)}; int value; CFNumberRef values[2]; CFDictionaryRef dictionaries[2]; // Match joysticks. value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_Joystick; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); // Match gamepads. value = kHIDPage_GenericDesktop; values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); value = kHIDUsage_GD_GamePad; values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, (const void **) values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease(values[0]); CFRelease(values[1]); CFArrayRef array = CFArrayCreate( kCFAllocatorDefault, (const void **) dictionaries, 2, &kCFTypeArrayCallBacks); CFRelease(dictionaries[0]); CFRelease(dictionaries[1]); IOHIDManagerSetDeviceMatchingMultiple(HidManager, array); CFRelease(array); IOHIDManagerRegisterDeviceMatchingCallback(HidManager, staticOnDeviceMatched, this); IOHIDManagerRegisterDeviceRemovalCallback(HidManager, staticOnDeviceRemoved, this); }
/** * @brief open - open 1 or more devices * @param[in] max maximum number of devices to open * @param[in] vid Vendor ID, or -1 if any * @param[in] pid Product ID, or -1 if any * @param[in] usage_page top level usage page, or -1 if any * @param[in] usage top level usage number, or -1 if any * @returns actual number of devices opened */ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage) { CFMutableDictionaryRef dict; CFNumberRef num; IOReturn ret; Q_ASSERT(hid_manager == NULL); Q_ASSERT(device_open == false); attach_count = 0; // Start the HID Manager hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { if (hid_manager) CFRelease(hid_manager); return 0; } if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) { // Tell the HID Manager what type of devices we want dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dict) return 0; if (vid > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid); CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num); CFRelease(num); } if (pid > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid); CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num); CFRelease(num); } if (usage_page > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page); CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num); CFRelease(num); } if (usage > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num); CFRelease(num); } IOHIDManagerSetDeviceMatching(hid_manager, dict); CFRelease(dict); } else { IOHIDManagerSetDeviceMatching(hid_manager, NULL); } // Set the run loop reference before configuring the attach callback the_correct_runloop = CFRunLoopGetCurrent(); // set up a callbacks for device attach & detach IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, pjrc_rawhid::attach_callback, this); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, pjrc_rawhid::dettach_callback, this); ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(hid_manager); return 0; } // let it do the callback for all devices while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ; // count up how many were added by the callback return attach_count; }
hid_device * HID_API_EXPORT hid_open_path(const char *path) { int i; hid_device *dev = NULL; CFIndex num_devices; dev = new_hid_device(); /* Set up the HID Manager if it hasn't been done */ hid_init(); CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); num_devices = CFSetGetCount(device_set); IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef)); CFSetGetValues(device_set, (const void **) device_array); for (i = 0; i < num_devices; i++) { char cbuf[BUF_LEN]; size_t len; IOHIDDeviceRef os_dev = device_array[i]; len = make_path(os_dev, cbuf, sizeof(cbuf)); if (!strcmp(cbuf, path)) { // Matched Paths. Open this Device. IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone); if (ret == kIOReturnSuccess) { char str[32]; free(device_array); CFRelease(device_set); dev->device_handle = os_dev; /* Create the buffers for receiving data */ dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev); dev->input_report_buf = calloc(dev->max_input_report_len, sizeof(uint8_t)); /* Create the Run Loop Mode for this device. printing the reference seems to work. */ sprintf(str, "HIDAPI_%p", os_dev); dev->run_loop_mode = CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); /* Attach the device to a Run Loop */ IOHIDDeviceRegisterInputReportCallback( os_dev, dev->input_report_buf, dev->max_input_report_len, &hid_report_callback, dev); IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, hid_device_removal_callback, NULL); /* Start the read thread */ pthread_create(&dev->thread, NULL, read_thread, dev); /* Wait here for the read thread to be initialized. */ pthread_barrier_wait(&dev->barrier); return dev; } else { goto return_error; } } } return_error: free(device_array); CFRelease(device_set); free_hid_device(dev); return NULL; }
// rawhid_open - open 1 or more devices // // Inputs: // max = maximum number of devices to open // vid = Vendor ID, or -1 if any // pid = Product ID, or -1 if any // usage_page = top level usage page, or -1 if any // usage = top level usage number, or -1 if any // Output: // actual number of devices opened // int rawhid_open(int max, int vid, int pid, int usage_page, int usage) { //*** kern_return_t result; mach_port_t masterPort; CFMutableDictionaryRef matchingDict; CFRunLoopSourceRef runLoopSource; //Create a master port for communication with the I/O Kit result = IOMasterPort(MACH_PORT_NULL, &masterPort); if (result || !masterPort) { return -1; } //To set up asynchronous notifications, create a notification port and //add its run loop event source to the programs run loop gNotifyPort = IONotificationPortCreate(masterPort); runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); // *** /* IOServiceAddMatchingNotification( gNotifyPort, kIOFirstMatchNotification, matchingDict, attach_callback, NULL, &gAddedIter); */ // *** static IOHIDManagerRef hid_manager=NULL; CFMutableDictionaryRef dict; CFNumberRef num; IOReturn ret; hid_t *p; int count=0; //fprintf(stderr,"fprintf rawhid_open\n"); if (first_hid) free_all_hid(); //printf("rawhid_open, max=%d\n", max); //fflush (stdout); if (max < 1) return 0; // Start the HID Manager // http://developer.apple.com/technotes/tn2007/tn2187.html if (!hid_manager) { hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { if (hid_manager) CFRelease(hid_manager); return 0; } } if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) { // Tell the HID Manager what type of devices we want dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dict) return 0; if (vid > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid); CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num); CFRelease(num); } if (pid > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid); CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num); CFRelease(num); } if (usage_page > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page); CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num); CFRelease(num); } if (usage > 0) { num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num); CFRelease(num); } IOHIDManagerSetDeviceMatching(hid_manager, dict); CFRelease(dict); } else { IOHIDManagerSetDeviceMatching(hid_manager, NULL); } // set up a callbacks for device attach & detach IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(hid_manager); return 0; } printf("run loop\n"); // let it do the callback for all devices while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ; // count up how many were added by the callback for (p = first_hid; p; p = p->next) count++; usbstatus=count; return count; }