// 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; }
/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */ static int init_hid_manager(void) { /* Initialize all the HID Manager Objects */ hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_mgr) { IOHIDManagerSetDeviceMatching(hid_mgr, NULL); IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); return 0; } return -1; }
static int OSX_Mouse_Thread(void *ctx) { if (!ctx) return 0; struct osx_mouse_data *mdata = static_cast<struct osx_mouse_data *>(ctx); IOHIDManagerRef hid_manager = IOHIDManagerCreate(kCFAllocatorSystemDefault, kIOHIDOptionsTypeNone); if (!hid_manager) { SDL_DestroyMutex(mdata->mouse_mutex); delete mdata; return 0; } if (IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone) != kIOReturnSuccess) { CFRelease(hid_manager); SDL_DestroyMutex(mdata->mouse_mutex); delete mdata; return 0; } IOHIDManagerRegisterInputValueCallback(hid_manager, input_callback, mdata); IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); uint32_t page = kHIDPage_GenericDesktop; uint32_t usage = kHIDUsage_GD_Mouse; CFDictionaryRef dict = NULL; CFNumberRef pageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); CFNumberRef usageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); const void *keys[2] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) }; const void *vals[2] = { pageNumRef, usageNumRef }; if (pageNumRef && usageNumRef) dict = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (pageNumRef) CFRelease(pageNumRef); if (usageNumRef) CFRelease(usageNumRef); IOHIDManagerSetDeviceMatching(hid_manager, dict); if (dict) CFRelease(dict); while (!mdata->should_exit) { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false); } IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerClose(hid_manager, kIOHIDOptionsTypeNone); CFRelease(hid_manager); SDL_DestroyMutex(mdata->mouse_mutex); delete mdata; return 0; }
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); } }
int usbinit(){ // Create the device manager if(!(usbmanager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeSeizeDevice))){ printf("Fatal: Failed to create device manager\n"); return -1; } // Start the device thread if(pthread_create(&usbthread, 0, threadrun, 0)){ printf("Fatal: Failed to start USB thread\n"); return -1; } return 0; }
static int init_hid_manager(void) { IOReturn res; /* Initialize all the HID Manager Objects */ hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); IOHIDManagerSetDeviceMatching(hid_mgr, NULL); IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); res = IOHIDManagerOpen(hid_mgr, kIOHIDOptionsTypeNone); if(res == kIOReturnSuccess) return 0; fprintf(stderr, "IOReturn error code: 0x%x\n", err_get_code(res)); return -1; }
static void initializeResumeNotifications (void) // see TN 2187 { IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (! hidManager) { message (LOG_ERR, "IOHIDManagerCreate failed\n"); exit (1); } if (IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone) != kIOReturnSuccess) { message (LOG_ERR, "IOHIDManagerOpen failed\n"); exit (1); } IOHIDManagerScheduleWithRunLoop (hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerSetDeviceMatchingMultiple (hidManager, createGenericDesktopMatchingDictionaries()); IOHIDManagerRegisterInputValueCallback (hidManager, hidCallback, (void *) -1); }
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); }
static int iohidmanager_hid_manager_init(iohidmanager_hid_t *hid) { if (!hid) return -1; if (hid->ptr) /* already initialized. */ return 0; hid->ptr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!hid->ptr) return -1; IOHIDManagerSetDeviceMatching(hid->ptr, NULL); IOHIDManagerScheduleWithRunLoop(hid->ptr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); return 0; }
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); }
int joy_hidlib_init(void) { if ( !mgr ) { // create the manager mgr = IOHIDManagerCreate( kCFAllocatorDefault, 0L ); } if ( mgr ) { // open it IOReturn tIOReturn = IOHIDManagerOpen( mgr, 0L); if ( kIOReturnSuccess != tIOReturn ) { return -1; } else { IOHIDManagerSetDeviceMatching( mgr, NULL ); return 0; } } else { return -1; } }
void setAllKeyboards(LedState changes[]) { IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!manager) { fprintf(stderr, "Failed to create IOHID manager.\n"); return; } CFDictionaryRef keyboard = getKeyboardDictionary(); if (!keyboard) { fprintf(stderr, "Failed to get dictionary usage page for kHIDUsage_GD_Keyboard.\n"); return; } IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone); IOHIDManagerSetDeviceMatching(manager, keyboard); CFSetRef devices = IOHIDManagerCopyDevices(manager); if (devices) { CFIndex deviceCount = CFSetGetCount(devices); if (deviceCount == 0) { fprintf(stderr, "Could not find any keyboard devices.\n"); } else { // Loop through all keyboards attempting to get or display led state IOHIDDeviceRef *deviceRefs = malloc(sizeof(IOHIDDeviceRef) * deviceCount); if (deviceRefs) { CFSetGetValues(devices, (const void **) deviceRefs); for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) if (isKeyboardDevice(deviceRefs[deviceIndex])) setKeyboard(deviceRefs[deviceIndex], keyboard, changes); free(deviceRefs); } } CFRelease(devices); } CFRelease(keyboard); }
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; }
int main(void) { IOHIDManagerRef mgr; int i; mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); IOHIDManagerSetDeviceMatching(mgr, NULL); IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone); CFSetRef device_set = IOHIDManagerCopyDevices(mgr); if (device_set==NULL) { return 0; } CFIndex 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++) { IOHIDDeviceRef dev = device_array[i]; printf("Device: %p\n", dev); printf(" %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev)); wchar_t serial[256], buf[256]; char cbuf[256]; get_serial_number(dev, serial, 256); printf(" Serial: %ls\n", serial); printf(" Loc: %ld\n", get_location_id(dev)); get_transport(dev, buf, 256); printf(" Trans: %ls\n", buf); make_path(dev, cbuf, 256); printf(" Path: %s\n", cbuf); } 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); }
static void *Sys_Input_Thread(void *inarg) { struct input_data *input; IOReturn tIOReturn; input = inarg; pthread_mutex_lock(&input->thread_mutex); input->threadrunloop = CFRunLoopGetCurrent(); pthread_cond_signal(&input->thread_has_spawned); pthread_mutex_unlock(&input->thread_mutex); input->hid_manager = IOHIDManagerCreate(kCFAllocatorSystemDefault, kIOHIDOptionsTypeNone); if (input->hid_manager) { IOHIDManagerSetDeviceMatching(input->hid_manager, NULL); IOHIDManagerRegisterInputValueCallback(input->hid_manager, input_callback, input); IOHIDManagerScheduleWithRunLoop(input->hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); tIOReturn = IOHIDManagerOpen(input->hid_manager, kIOHIDOptionsTypeNone); if (tIOReturn == kIOReturnSuccess) { do { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, true); } while (!input->thread_shutdown); } IOHIDManagerUnscheduleFromRunLoop(input->hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); } CFRelease(input->hid_manager); return 0; }
// RetroArch joypad driver: static bool apple_joypad_init(void) { #ifdef OSX CFMutableArrayRef matcher; if (!g_hid_manager) { g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); 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, hid_manager_device_attached, 0); IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone); } #endif return true; }
CPH_HidMacOSX::CPH_HidMacOSX() { m_bindings[PS2::CControllerInfo::ANALOG_LEFT_X] = std::make_shared<CSimulatedAxisBinding>(kHIDUsage_KeyboardD, kHIDUsage_KeyboardG); m_bindings[PS2::CControllerInfo::ANALOG_LEFT_Y] = std::make_shared<CSimulatedAxisBinding>(kHIDUsage_KeyboardR, kHIDUsage_KeyboardF); m_bindings[PS2::CControllerInfo::ANALOG_RIGHT_X] = std::make_shared<CSimulatedAxisBinding>(kHIDUsage_KeyboardH, kHIDUsage_KeyboardK); m_bindings[PS2::CControllerInfo::ANALOG_RIGHT_Y] = std::make_shared<CSimulatedAxisBinding>(kHIDUsage_KeyboardU, kHIDUsage_KeyboardJ); m_bindings[PS2::CControllerInfo::START] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardReturnOrEnter); m_bindings[PS2::CControllerInfo::SELECT] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardRightShift); m_bindings[PS2::CControllerInfo::DPAD_LEFT] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardLeftArrow); m_bindings[PS2::CControllerInfo::DPAD_RIGHT] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardRightArrow); m_bindings[PS2::CControllerInfo::DPAD_UP] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardUpArrow); m_bindings[PS2::CControllerInfo::DPAD_DOWN] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardDownArrow); m_bindings[PS2::CControllerInfo::SQUARE] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardA); m_bindings[PS2::CControllerInfo::CROSS] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardZ); m_bindings[PS2::CControllerInfo::TRIANGLE] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardS); m_bindings[PS2::CControllerInfo::CIRCLE] = std::make_shared<CSimpleBinding>(kHIDUsage_KeyboardX); m_bindings[PS2::CControllerInfo::L1] = std::make_shared<CSimpleBinding>(kHIDUsage_Keyboard1); m_bindings[PS2::CControllerInfo::L2] = std::make_shared<CSimpleBinding>(kHIDUsage_Keyboard2); m_bindings[PS2::CControllerInfo::L3] = std::make_shared<CSimpleBinding>(kHIDUsage_Keyboard3); m_bindings[PS2::CControllerInfo::R1] = std::make_shared<CSimpleBinding>(kHIDUsage_Keyboard8); m_bindings[PS2::CControllerInfo::R2] = std::make_shared<CSimpleBinding>(kHIDUsage_Keyboard9); m_bindings[PS2::CControllerInfo::R3] = std::make_shared<CSimpleBinding>(kHIDUsage_Keyboard0); m_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, 0); { CFDictionaryRef matchingDict = CreateDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard); IOHIDManagerSetDeviceMatching(m_hidManager, matchingDict); CFRelease(matchingDict); } IOHIDManagerScheduleWithRunLoop(m_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerOpen(m_hidManager, kIOHIDOptionsTypeNone); IOHIDManagerRegisterInputValueCallback(m_hidManager, InputValueCallbackStub, this); }
int main( int argc, const char * argv[] ) { Boolean initialized = FALSE; if (( argc != 4 ) && ( argc != 5 )) { printf ( "usage: Dream Cheeky Notifier R G B [A]\n\tRGB values should be 0-31. A is an optional parameter on whether to do the LED activation sequence. Anything larger than 0 is YES, default is 0 (activate).\n\n"); exit ( -1 ); } char r = (int)strtol ( argv[1], NULL, 10 ); char g = (int)strtol ( argv[2], NULL, 10 ); char b = (int)strtol ( argv[3], NULL, 10 ); if ( argc == 5 ) { initialized = TRUE; } if ((r < 0) || (r > 31) || (g < 0) || (g > 31) || (b < 0) || (b > 31)) { printf("RGB values must be within 0-31."); exit -1; } // create a IO HID Manager reference IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone ); // Create a device matching dictionary CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE, kHIDPage_GenericDesktop, 0x10 ); // set the HID device matching dictionary IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef ); if ( matchingCFDictRef ) { CFRelease( matchingCFDictRef ); } // Now open the IO HID Manager reference IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone ); // and copy out its devices CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef ); // how many devices in the set? CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef ); // allocate a block of memory to extact the device ref's from the set into IOHIDDeviceRef * tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount ); // now extract the device ref's from the set CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs ); // before we get into the device loop we'll setup our element matching dictionary (Note: we don't do element matching anymore) matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, 0, 0 ); for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) { // if this isn't the notifier device... TODO: let's detect via vendor/product ids instead long vendor_id = 0; IOHIDDevice_GetLongProperty(tIOHIDDeviceRefs[deviceIndex], CFSTR(kIOHIDVendorIDKey), &vendor_id); long product_id = 0; IOHIDDevice_GetLongProperty(tIOHIDDeviceRefs[deviceIndex], CFSTR(kIOHIDProductIDKey), &product_id); if ((vendor_id != 0x1D34 ) || (product_id != 0x0004 )) { printf(" skipping device %p.\n", tIOHIDDeviceRefs[deviceIndex] ); continue; // ...skip it } printf( " device = %p.\n", tIOHIDDeviceRefs[deviceIndex] ); unsigned char report[8]; if (initialized == FALSE) { report[0] = 0x1F; // turn on LEDs report[1] = 0x02; report[2] = 0x00; report[3] = 0x5F; report[4] = 0x00; report[5] = 0x00; report[6] = 0x1A; report[7] = 0x03; // Note: We don't use the returned value here, so the compiler might throw a warning. IOReturn tIOReturn = IOHIDDeviceSetReport( tIOHIDDeviceRefs[deviceIndex], // IOHIDDeviceRef for the HID device kIOHIDReportTypeInput, // IOHIDReportType for the report (input, output, feature) 0, // CFIndex for the report ID report, // address of report buffer 8); // length of the report initialized = TRUE; } report[0] = r; // set brightness on LEDs to r, g, & b report[1] = g; report[2] = b; report[3] = 0x00; report[4] = 0x00; report[5] = 0x00; report[6] = 0x1A; report[7] = 0x05; tIOReturn = IOHIDDeviceSetReport( tIOHIDDeviceRefs[deviceIndex], // IOHIDDeviceRef for the HID device kIOHIDReportTypeInput, // IOHIDReportType for the report (input, output, feature) 0, // CFIndex for the report ID report, // address of report buffer 8); // length of the report next_device: ; continue; } if ( tIOHIDManagerRef ) { CFRelease( tIOHIDManagerRef ); } if ( matchingCFDictRef ) { CFRelease( matchingCFDictRef ); } Oops: ; return -1; } /* main */
//int main( int argc, const char * argv[] ) int manipulate_led( int which_led, int led_value ) { #pragma unused ( argc, argv ) IOHIDDeviceRef * tIOHIDDeviceRefs = nil; // create a IO HID Manager reference IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone ); require( tIOHIDManagerRef, Oops ); // Create a device matching dictionary CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard ); require( matchingCFDictRef, Oops ); // set the HID device matching dictionary IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef ); if ( matchingCFDictRef ) { CFRelease( matchingCFDictRef ); } // Now open the IO HID Manager reference IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone ); require_noerr( tIOReturn, Oops ); // and copy out its devices CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef ); require( deviceCFSetRef, Oops ); // how many devices in the set? CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef ); // allocate a block of memory to extact the device ref's from the set into tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount ); if (!tIOHIDDeviceRefs) { CFRelease(deviceCFSetRef); deviceCFSetRef = NULL; goto Oops; } // now extract the device ref's from the set CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs ); CFRelease(deviceCFSetRef); deviceCFSetRef = NULL; // before we get into the device loop we'll setup our element matching dictionary matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, kHIDPage_LEDs, 0 ); require( matchingCFDictRef, Oops ); int pass; // do 256 passes //for ( pass = 0; pass < 256; pass++ ) { Boolean delayFlag = FALSE; // if we find an LED element we'll set this to TRUE //printf( "pass = %d.\n", pass ); for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) { // if this isn't a keyboard device... if ( !IOHIDDeviceConformsTo( tIOHIDDeviceRefs[deviceIndex], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard ) ) { continue; // ...skip it } //printf( " device = %p.\n", tIOHIDDeviceRefs[deviceIndex] ); // copy all the elements CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements( tIOHIDDeviceRefs[deviceIndex], matchingCFDictRef, kIOHIDOptionsTypeNone ); require( elementCFArrayRef, next_device ); // for each device on the system these values are divided by the value ranges of all LED elements found // for example, if the first four LED element have a range of 0-1 then the four least significant bits of // this value will be sent to these first four LED elements, etc. int device_value = pass; // iterate over all the elements CFIndex elementIndex, elementCount = CFArrayGetCount( elementCFArrayRef ); for ( elementIndex = 0; elementIndex < elementCount; elementIndex++ ) { IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elementCFArrayRef, elementIndex ); require( tIOHIDElementRef, next_element ); uint32_t usagePage = IOHIDElementGetUsagePage( tIOHIDElementRef ); // if this isn't an LED element... if ( kHIDPage_LEDs != usagePage ) { continue; // ...skip it } uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef ); IOHIDElementType tIOHIDElementType = IOHIDElementGetType( tIOHIDElementRef ); //printf( " element = %p (page: %d, usage: %d, type: %d ).\n", // tIOHIDElementRef, usagePage, usage, tIOHIDElementType ); // get the logical mix/max for this LED element CFIndex minCFIndex = IOHIDElementGetLogicalMin( tIOHIDElementRef ); CFIndex maxCFIndex = IOHIDElementGetLogicalMax( tIOHIDElementRef ); // calculate the range CFIndex modCFIndex = maxCFIndex - minCFIndex + 1; // compute the value for this LED element //CFIndex tCFIndex = minCFIndex + ( device_value % modCFIndex ); CFIndex tCFIndex = led_value; device_value /= modCFIndex; //printf( " value = 0x%08lX.\n", tCFIndex ); uint64_t timestamp = 0; // create the IO HID Value to be sent to this LED element IOHIDValueRef tIOHIDValueRef = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, tIOHIDElementRef, timestamp, tCFIndex ); if ( tIOHIDValueRef ) { // now set it on the device tIOReturn = IOHIDDeviceSetValue( tIOHIDDeviceRefs[deviceIndex], tIOHIDElementRef, tIOHIDValueRef ); CFRelease( tIOHIDValueRef ); require_noerr( tIOReturn, next_element ); delayFlag = TRUE; // set this TRUE so we'll delay before changing our LED values again } next_element: ; continue; } CFRelease( elementCFArrayRef ); next_device: ; continue; } // if we found an LED we'll delay before continuing //if ( delayFlag ) { // usleep( 500000 ); // sleep one half second //} // if the mouse is down… //if (GetCurrentButtonState()) { // break; // abort pass loop //} //} // next pass if ( matchingCFDictRef ) { CFRelease( matchingCFDictRef ); } Oops: ; if ( tIOHIDDeviceRefs ) { free(tIOHIDDeviceRefs); } if ( tIOHIDManagerRef ) { CFRelease( tIOHIDManagerRef ); } return 0; } /* main */
bool GPUSB_Open() { // VID = 4938 PID = 36897 IOHIDManagerRef managerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); pGPUSB = FindDevice(managerRef, 4938, 36896); if(!pGPUSB) { CFRelease(managerRef); return false; } GPUSB_Model = 0; CFArrayRef arrayElements = IOHIDDeviceCopyMatchingElements(pGPUSB, NULL, kIOHIDOptionsTypeNone); CFIndex elementCount = CFArrayGetCount(arrayElements); int countInputElements = 0; for(int i = 0; i < elementCount; i++) { IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(arrayElements, i); if(!tIOHIDElementRef) { continue; } IOHIDElementType type = IOHIDElementGetType(tIOHIDElementRef); switch ( type ) { case kIOHIDElementTypeInput_Misc: case kIOHIDElementTypeInput_Button: case kIOHIDElementTypeInput_Axis: case kIOHIDElementTypeInput_ScanCodes: { countInputElements++; break; } default: break; } CFRelease(tIOHIDElementRef); } CFRelease(arrayElements); if(countInputElements == 1) GPUSB_Model = 1; // now opening the device for communication IOReturn ioReturnValue = IOHIDDeviceOpen(pGPUSB, kIOHIDOptionsTypeSeizeDevice); if(ioReturnValue != kIOReturnSuccess) { CFRelease(pGPUSB); pGPUSB = NULL; CFRelease(managerRef); return false; } CFRelease(managerRef); // check if this is ok return true; }
int _ykusb_start(void) { ykosxManager = IOHIDManagerCreate( kCFAllocatorDefault, 0L ); return 1; }
/** * @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; }
bool Joystick::init() { SYNC; if(!p->hidManager) { VERIFY(p->hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); IOHIDManagerSetDeviceMatching((IOHIDManagerRef) p->hidManager, 0); IOHIDManagerOpen((IOHIDManagerRef) p->hidManager, kIOHIDOptionsTypeNone); p->nextDevice = 0; } CFSetRef copyOfDevices = IOHIDManagerCopyDevices((IOHIDManagerRef) p->hidManager); CFMutableArrayRef devArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFSetApplyFunction(copyOfDevices, Joystick::Private::copyCallBack, (void*) devArray); CFRelease(copyOfDevices); while(!p->deviceId && p->nextDevice < (unsigned) CFArrayGetCount(devArray)) { p->deviceId = CFArrayGetValueAtIndex(devArray, p->nextDevice++); if(p->deviceId) { CFArrayRef elemAry = IOHIDDeviceCopyMatchingElements((IOHIDDeviceRef) p->deviceId, 0, 0); bool isJoystick = false; for(int i = 0; !isJoystick && i < (int) CFArrayGetCount(elemAry); ++i) { IOHIDElementRef elem = (IOHIDElementRef) CFArrayGetValueAtIndex(elemAry, i); isJoystick = IOHIDElementGetUsagePage(elem) == kHIDPage_GenericDesktop && (IOHIDElementGetUsage(elem) == kHIDUsage_GD_Joystick || IOHIDElementGetUsage(elem) == kHIDUsage_GD_GamePad); } if(isJoystick) { CFRetain((IOHIDDeviceRef) p->deviceId); ++(p->usedJoysticks); for(int i = 0; i < (int) CFArrayGetCount(elemAry); ++i) { IOHIDElementRef elem = (IOHIDElementRef) CFArrayGetValueAtIndex(elemAry, i); IOHIDElementType elemType = IOHIDElementGetType(elem); if(elemType == kIOHIDElementTypeInput_Misc || elemType == kIOHIDElementTypeInput_Button || elemType == kIOHIDElementTypeInput_Axis || elemType == kIOHIDElementTypeInput_ScanCodes) { if(IOHIDElementGetUsagePage(elem) == kHIDPage_GenericDesktop) switch(IOHIDElementGetUsage(elem)) { case kHIDUsage_GD_X: case kHIDUsage_GD_Y: case kHIDUsage_GD_Z: case kHIDUsage_GD_Rx: case kHIDUsage_GD_Ry: case kHIDUsage_GD_Rz: { CFRetain(elem); int axis = IOHIDElementGetUsage(elem) - kHIDUsage_GD_X; p->axisIds[axis] = elem; p->axisMin[axis] = (int) IOHIDElementGetLogicalMin(elem); p->axisMax[axis] = (int) IOHIDElementGetLogicalMax(elem); break; } case kHIDUsage_GD_Hatswitch: CFRetain(elem); p->hatId = elem; p->axisMin[6] = p->axisMin[7] = -1; p->axisMax[6] = p->axisMax[7] = 1; break; } else if(IOHIDElementGetUsagePage(elem) == kHIDPage_Button) { int button = IOHIDElementGetUsage(elem) - 1; if(button >= 0 && button < numOfButtons) { CFRetain(elem); p->buttonIds[button] = elem; } } } } } else p->deviceId = 0; CFRelease(elemAry); } } CFRelease(devArray); return p->deviceId != 0; }
// ---------------------------------------------------- int main(int argc, const char * argv[]) { #pragma unused ( argc, argv ) IOHIDManagerRef tIOHIDManagerRef = NULL; CFSetRef deviceCFSetRef = NULL; IOHIDDeviceRef *tIOHIDDeviceRefs = nil; do { tIOHIDManagerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (!tIOHIDManagerRef) { break; } IOHIDManagerSetDeviceMatching(tIOHIDManagerRef, NULL); IOReturn tIOReturn = IOHIDManagerOpen(tIOHIDManagerRef, kIOHIDOptionsTypeNone); if (noErr != tIOReturn) { break; } deviceCFSetRef = IOHIDManagerCopyDevices(tIOHIDManagerRef); if (!deviceCFSetRef) { break; } CFIndex deviceIndex, deviceCount = CFSetGetCount(deviceCFSetRef); tIOHIDDeviceRefs = malloc(sizeof(IOHIDDeviceRef) * deviceCount); if (!tIOHIDDeviceRefs) { break; } CFSetGetValues(deviceCFSetRef, (const void **)tIOHIDDeviceRefs); CFRelease(deviceCFSetRef); deviceCFSetRef = NULL; for (deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) { if (!tIOHIDDeviceRefs[deviceIndex]) { continue; } HIDDumpDeviceInfo(tIOHIDDeviceRefs[deviceIndex]); #if true // and copy all the elements CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRefs[deviceIndex], NULL /* matchingCFDictRef */, kIOHIDOptionsTypeNone); if (elementCFArrayRef) { // iterate over all the elements CFIndex elementIndex, elementCount = CFArrayGetCount(elementCFArrayRef); for (elementIndex = 0; elementIndex < elementCount; elementIndex++) { IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(elementCFArrayRef, elementIndex); if (tIOHIDElementRef) { HIDDumpElementInfo(tIOHIDElementRef); } } CFRelease(elementCFArrayRef); } #endif } } while (false); if (tIOHIDDeviceRefs) { free(tIOHIDDeviceRefs); } if (deviceCFSetRef) { CFRelease(deviceCFSetRef); deviceCFSetRef = NULL; } if (tIOHIDManagerRef) { CFRelease(tIOHIDManagerRef); } return (0); } // main
// 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; }
static int find_osx_devices(void) { IOReturn tIOReturn; CFMutableDictionaryRef result; CFSetRef devset; CFArrayRef matching; gIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, 0L ); tIOReturn = IOHIDManagerOpen( gIOHIDManagerRef, 0L); if ( kIOReturnSuccess != tIOReturn ) { ERR("Couldn't open IOHIDManager.\n"); return 0; } matching = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks ); /* build matching dictionary */ result = creates_osx_device_match(kHIDUsage_GD_Joystick); if (!result) { CFRelease(matching); return 0; } CFArrayAppendValue( ( CFMutableArrayRef )matching, result ); result = creates_osx_device_match(kHIDUsage_GD_GamePad); if (!result) { CFRelease(matching); return 0; } CFArrayAppendValue( ( CFMutableArrayRef )matching, result ); IOHIDManagerSetDeviceMatchingMultiple( gIOHIDManagerRef, matching); devset = IOHIDManagerCopyDevices( gIOHIDManagerRef ); if (devset) { CFIndex countDevices, countCollections, idx; CFArrayRef gDevices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFSetApplyFunction(devset, CFSetApplierFunctionCopyToCFArray, (void*)gDevices); CFRelease( devset); countDevices = CFArrayGetCount(gDevices); gCollections = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if (!gCollections) return 0; countCollections = 0; for (idx = 0; idx < countDevices; idx++) { CFIndex tTop; IOHIDDeviceRef tDevice; tDevice = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDevices, idx); tTop = find_top_level(tDevice, gCollections); countCollections += tTop; } CFRelease(gDevices); TRACE("found %i device(s), %i collection(s)\n",(int)countDevices,(int)countCollections); return (int)countCollections; } return 0; }
/************************************************************************** * find_osx_devices */ static int find_osx_devices(void) { IOHIDManagerRef hid_manager; int usages[] = { kHIDUsage_GD_Joystick, kHIDUsage_GD_GamePad }; int i; CFDictionaryRef matching_dicts[sizeof(usages) / sizeof(usages[0])]; CFArrayRef matching; CFSetRef devset; TRACE("()\n"); hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, 0L); if (IOHIDManagerOpen(hid_manager, 0) != kIOReturnSuccess) { ERR("Couldn't open IOHIDManager.\n"); CFRelease(hid_manager); return 0; } for (i = 0; i < sizeof(matching_dicts) / sizeof(matching_dicts[0]); i++) { matching_dicts[i] = create_osx_device_match(usages[i]); if (!matching_dicts[i]) { while (i > 0) CFRelease(matching_dicts[--i]); goto fail; } } matching = CFArrayCreate(NULL, (const void**)matching_dicts, sizeof(matching_dicts) / sizeof(matching_dicts[0]), &kCFTypeArrayCallBacks); for (i = 0; i < sizeof(matching_dicts) / sizeof(matching_dicts[0]); i++) CFRelease(matching_dicts[i]); IOHIDManagerSetDeviceMatchingMultiple(hid_manager, matching); CFRelease(matching); devset = IOHIDManagerCopyDevices(hid_manager); if (devset) { CFIndex num_devices, num_main_elements; const void** refs; CFArrayRef devices; num_devices = CFSetGetCount(devset); refs = HeapAlloc(GetProcessHeap(), 0, num_devices * sizeof(*refs)); if (!refs) { CFRelease(devset); goto fail; } CFSetGetValues(devset, refs); devices = CFArrayCreate(NULL, refs, num_devices, &kCFTypeArrayCallBacks); HeapFree(GetProcessHeap(), 0, refs); CFRelease(devset); if (!devices) goto fail; device_main_elements = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if (!device_main_elements) { CFRelease(devices); goto fail; } num_main_elements = 0; for (i = 0; i < num_devices; i++) { IOHIDDeviceRef hid_device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, i); TRACE("hid_device %s\n", debugstr_device(hid_device)); num_main_elements += find_top_level(hid_device, device_main_elements); } CFRelease(devices); TRACE("found %i device(s), %i collection(s)\n",(int)num_devices,(int)num_main_elements); return (int)num_main_elements; } fail: IOHIDManagerClose(hid_manager, 0); CFRelease(hid_manager); return 0; }