// 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; }
Burger::Mouse::Mouse(GameApp *pGameApp) : m_pGameApp(pGameApp), m_MouseLock(), m_pHIDManager(NULL), m_uMiceCount(0), m_uX(0), m_uY(0), m_uBoundsX(640), m_uBoundsY(480), m_iDeltaX(0), m_iDeltaY(0), m_iMouseWheelX(0), m_iMouseWheelY(0), m_uButtons(0), m_uPressedButtons(0), m_bButtonSwap(FALSE), m_uArrayStart(0), m_uArrayEnd(0) { // Back link to the game app CFMutableDictionaryRef pDictionary = Globals::CreateHIDDictionary(kHIDPage_GenericDesktop,kHIDUsage_GD_Mouse); if (pDictionary != NULL) { m_pHIDManager = IOHIDManagerCreate(kCFAllocatorDefault,kIOHIDOptionsTypeNone); if (m_pHIDManager != NULL) { CFRunLoopRef pRunLoop = CFRunLoopGetCurrent(); IOHIDManagerRegisterDeviceMatchingCallback(m_pHIDManager,EnumerationCallback,this); IOHIDManagerScheduleWithRunLoop(m_pHIDManager,pRunLoop,g_BurgerMouse); IOHIDManagerSetDeviceMatching(m_pHIDManager,pDictionary); IOHIDManagerOpen(m_pHIDManager,kIOHIDOptionsTypeNone); // Handle the run loops Poll(this); // All scanned! IOHIDManagerUnscheduleFromRunLoop(m_pHIDManager,pRunLoop,g_BurgerMouse); IOHIDManagerRegisterDeviceMatchingCallback(m_pHIDManager,NULL, NULL); // Open all the located devices Word i; DeviceStruct *pRat = m_Mice; for (i = 0; i < m_uMiceCount; i++) { IOHIDDeviceRef pDevice = pRat->m_pDevice; if (IOHIDDeviceOpen(pDevice,kIOHIDOptionsTypeNone) != kIOReturnSuccess) { pRat->m_pDevice = NULL; // Hmm. Toast it pRat->m_bUnplugged = FALSE; // Don't attempt to reconnect } else { IOHIDDeviceRegisterRemovalCallback(pDevice,DisconnectionCallback,this); IOHIDDeviceRegisterInputValueCallback(pDevice,InputCallback,this); IOHIDDeviceScheduleWithRunLoop(pDevice,pRunLoop,g_BurgerMouse); } ++pRat; } pGameApp->AddRoutine(Poll,NULL,this,RunQueue::PRIORITY_MOUSE); } CFRelease(pDictionary); } }
static SDL_bool ConfigHIDManager(CFArrayRef matchingArray) { CFRunLoopRef runloop = CFRunLoopGetCurrent(); /* Run in a custom RunLoop mode just while initializing, so we can detect sticks without messing with everything else. */ CFStringRef tempRunLoopMode = CFSTR("SDLJoystickInit"); if (IOHIDManagerOpen(hidman, kIOHIDOptionsTypeNone) != kIOReturnSuccess) { return SDL_FALSE; } IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL); IOHIDManagerScheduleWithRunLoop(hidman, runloop, tempRunLoopMode); IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray); while (CFRunLoopRunInMode(tempRunLoopMode,0,TRUE)==kCFRunLoopRunHandledSource) { /* no-op. Callback fires once per existing device. */ } /* Put this in the normal RunLoop mode now, for future hotplug events. */ IOHIDManagerUnscheduleFromRunLoop(hidman, runloop, tempRunLoopMode); IOHIDManagerScheduleWithRunLoop(hidman, runloop, kCFRunLoopDefaultMode); return SDL_TRUE; /* good to go. */ }
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"); } }
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; }
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); } }
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); }
int main() { initscr(); start_color(); use_default_colors(); init_pair(1, COLOR_RED, -1); IOHIDManagerRef hidManager = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone); IOHIDManagerRegisterDeviceMatchingCallback( hidManager, match_callback, NULL); IOHIDManagerScheduleWithRunLoop( hidManager, CFRunLoopGetMain(), kCFRunLoopCommonModes); // all keyboards CFDictionaryRef match = matching_dictionary_create(0, 0, 1, 6); // kinesis /* CFDictionaryRef match = matching_dictionary_create(0x05f3, 0x0007, 0, 0); */ // noppoo /* CFDictionaryRef match = matching_dictionary_create(0x1006, 0x0022, 1, 6); */ // a4tech /* CFDictionaryRef match = matching_dictionary_create(0x1241, 0x1603, 0, 0); */ IOHIDManagerSetDeviceMatching(hidManager, match); CFRelease(match); CFRunLoopRun(); }
void* threadrun(void* context){ // Tell the device manager which devices we want to look for CFMutableArrayRef devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if(devices){ int vendor = V_CORSAIR; int products[] = { P_K65, P_K70, P_K70_NRGB, P_K95, P_K95_NRGB }; for(uint i = 0; i < sizeof(products) / sizeof(int); i++){ int product = products[i]; CFMutableDictionaryRef device = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if(device){ CFDictionarySetValue(device, CFSTR(kIOHIDVendorIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor)); CFDictionarySetValue(device, CFSTR(kIOHIDProductIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product)); CFArrayAppendValue(devices, device); CFRelease(device); } } IOHIDManagerSetDeviceMatchingMultiple(usbmanager, devices); CFRelease(devices); } // Set up device add callback IOHIDManagerRegisterDeviceMatchingCallback(usbmanager, usbadd, 0); IOHIDManagerScheduleWithRunLoop(usbmanager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerOpen(usbmanager, kIOHIDOptionsTypeSeizeDevice); // Make a new thread to handle key repeats. The OS won't do it for us. pthread_create(&keyrepeatthread, 0, krthread, 0); // Run the event loop. Existing devices will be detected automatically. while(1){ CFRunLoopRun(); } return 0; }
void CInputProviderMacOsHid::InputDeviceListenerThread() { m_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, 0); { CFDictionaryRef matchingDict[3]; matchingDict[0] = CreateDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); matchingDict[1] = CreateDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); matchingDict[2] = CreateDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController); CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, (const void**)matchingDict, 3, &kCFTypeArrayCallBacks); CFRelease(matchingDict[0]); CFRelease(matchingDict[1]); CFRelease(matchingDict[2]); IOHIDManagerSetDeviceMatchingMultiple(m_hidManager, array); } IOHIDManagerRegisterDeviceMatchingCallback(m_hidManager, OnDeviceMatchedStub, this); IOHIDManagerOpen(m_hidManager, kIOHIDOptionsTypeNone); IOHIDManagerScheduleWithRunLoop(m_hidManager, CFRunLoopGetCurrent(), CFSTR("CustomLoop")); while(CFRunLoopRunInMode(CFSTR("CustomLoop"), 1, true) != kCFRunLoopRunStopped && m_running) { } IOHIDManagerClose(m_hidManager, 0); }
static bool apple_hid_init(void) { CFMutableArrayRef matcher; if (!(g_hid_manager = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone))) return false; matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher); CFRelease(matcher); IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, add_device, 0); IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone); return true; }
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 JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { CFRunLoopRef runloop = CFRunLoopGetCurrent(); IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); ERR_FAIL_COND(ret != kIOReturnSuccess); IOHIDManagerSetDeviceMatchingMultiple(hid_manager, p_matching_array); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, joypad_added_callback, NULL); IOHIDManagerScheduleWithRunLoop(hid_manager, runloop, GODOT_JOY_LOOP_RUN_MODE); while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { /* no-op. Callback fires once per existing device. */ } }
/** * @brief Called by the USB system * @param dev The device that was attached */ void pjrc_rawhid::attach(IOHIDDeviceRef d) { // Store the device handle dev = d; if (IOHIDDeviceOpen(dev, kIOHIDOptionsTypeNone) != kIOReturnSuccess) return; // Disconnect the attach callback since we don't want to automatically reconnect IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); IOHIDDeviceScheduleWithRunLoop(dev, the_correct_runloop, kCFRunLoopDefaultMode); IOHIDDeviceRegisterInputReportCallback(dev, buffer, sizeof(buffer), pjrc_rawhid::input_callback, this); attach_count++; device_open = true; unplugged = false; }
void StartUp() { g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher); CFRelease(matcher); IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, DeviceAttached, 0); IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone); }
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); } }
static SDL_bool ConfigHIDManager(CFArrayRef matchingArray) { CFRunLoopRef runloop = CFRunLoopGetCurrent(); if (IOHIDManagerOpen(hidman, kIOHIDOptionsTypeNone) != kIOReturnSuccess) { return SDL_FALSE; } IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL); IOHIDManagerScheduleWithRunLoop(hidman, runloop, SDL_JOYSTICK_RUNLOOP_MODE); IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray); while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) { /* no-op. Callback fires once per existing device. */ } /* future hotplug events will come through SDL_JOYSTICK_RUNLOOP_MODE now. */ return SDL_TRUE; /* good to go. */ }
static int apple_hid_manager_set_device_matching(apple_hid_t *hid) { CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if (!matcher) return -1; apple_hid_append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); apple_hid_append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); IOHIDManagerSetDeviceMatchingMultiple(hid->ptr, matcher); IOHIDManagerRegisterDeviceMatchingCallback(hid->ptr, apple_hid_device_add, 0); CFRelease(matcher); return 0; }
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; }
void* threadrun(void* context){ // Tell it which devices we want to look for CFMutableArrayRef devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if(devices){ int vendor = V_CORSAIR, product1 = P_K70, product2 = P_K95; CFMutableDictionaryRef device = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if(device){ CFDictionarySetValue(device, CFSTR(kIOHIDVendorIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor)); CFDictionarySetValue(device, CFSTR(kIOHIDProductIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product1)); CFArrayAppendValue(devices, device); CFRelease(device); } device = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if(device){ CFDictionarySetValue(device, CFSTR(kIOHIDVendorIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor)); CFDictionarySetValue(device, CFSTR(kIOHIDProductIDKey), CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product2)); CFArrayAppendValue(devices, device); CFRelease(device); } IOHIDManagerSetDeviceMatchingMultiple(usbmanager, devices); CFRelease(devices); } // Set up device add callback IOHIDManagerRegisterDeviceMatchingCallback(usbmanager, usbadd, 0); IOHIDManagerScheduleWithRunLoop(usbmanager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerOpen(usbmanager, kIOHIDOptionsTypeNone); // Run an event tap to modify the state of mouse events. The OS won't take care of this for us so this is needed for Shift and other modifiers to work CFRunLoopAddSource(CFRunLoopGetCurrent(), CFMachPortCreateRunLoopSource(kCFAllocatorDefault, CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionDefault, CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventLeftMouseUp) | CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventRightMouseUp), tapcallback, 0), 0), kCFRunLoopDefaultMode); // Another thing the OS won't do on its own: key repeats. Make a new thread for that pthread_create(&keyrepeatthread, 0, krthread, 0); // Run the event loop. Existing devices will be detected automatically. while(1){ CFRunLoopRun(); } return 0; }
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); }
// 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; }
/** * @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; }
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); }