int usbmain(){ int vendor = V_CORSAIR; int products[] = { P_K65, P_K70, P_K70_NRGB, P_K95, P_K95_NRGB/*, P_M65*/ }; // Tell IOService which type of devices we want (IOHIDDevices matching the supported vendor/products) CFMutableDictionaryRef match = IOServiceMatching(kIOHIDDeviceKey); CFNumberRef cfvendor = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor); CFDictionarySetValue(match, CFSTR(kIOHIDVendorIDKey), cfvendor); CFRelease(cfvendor); CFMutableArrayRef cfproducts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); for(uint i = 0; i < sizeof(products) / sizeof(int); i++){ int product = products[i]; CFNumberRef cfproduct = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product); CFArrayAppendValue(cfproducts, cfproduct); CFRelease(cfproduct); } CFDictionarySetValue(match, CFSTR(kIOHIDProductIDArrayKey), cfproducts); CFRelease(cfproducts); notify = IONotificationPortCreate(kIOMasterPortDefault); CFRunLoopAddSource(mainloop = CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notify), kCFRunLoopDefaultMode); io_iterator_t iterator; IOReturn res = IOServiceAddMatchingNotification(notify, kIOMatchedNotification, match, iterate_devices, 0, &iterator); if(res != kIOReturnSuccess){ ckb_fatal("Failed to list devices: %x\n", res); return -1; } // Iterate existing devices iterate_devices(0, iterator); // Enter loop to scan/connect new devices CFRunLoopRun(); return 0; }
int usbmain(){ // Load the uinput module (if it's not loaded already) if(system("modprobe uinput") != 0) ckb_warn("Failed to load uinput module\n"); // Create the udev object if(!(udev = udev_new())){ ckb_fatal("Failed to initialize udev\n"); return -1; } // Enumerate all currently connected devices udev_enum(); // Done scanning. Enter a loop to poll for device updates struct udev_monitor* monitor = udev_monitor_new_from_netlink(udev, "udev"); udev_monitor_filter_add_match_subsystem_devtype(monitor, "usb", 0); udev_monitor_enable_receiving(monitor); // Get an fd for the monitor int fd = udev_monitor_get_fd(monitor); fd_set fds; while(udev){ FD_ZERO(&fds); FD_SET(fd, &fds); // Block until an event is read if(select(fd + 1, &fds, 0, 0, 0) > 0 && FD_ISSET(fd, &fds)){ struct udev_device* dev = udev_monitor_receive_device(monitor); if(!dev) continue; const char* action = udev_device_get_action(dev); if(!action){ udev_device_unref(dev); continue; } // Add/remove device if(!strcmp(action, "add")){ int res = usb_add_device(dev); if(res == 0) continue; // If the device matched but the handle wasn't opened correctly, re-enumerate (this sometimes solves the problem) if(res == -1) udev_enum(); } else if(!strcmp(action, "remove")) usb_rm_device(dev); udev_device_unref(dev); } } udev_monitor_unref(monitor); return 0; }