static void* _setupusb(void* context){ usbdevice* kb = context; // Set standard fields short vendor = kb->vendor, product = kb->product; const devcmd* vt = kb->vtable = get_vtable(vendor, product); kb->features = (IS_RGB(vendor, product) ? FEAT_STD_RGB : FEAT_STD_NRGB) & features_mask; if(IS_MOUSE(vendor, product)) kb->features |= FEAT_ADJRATE; if(IS_MONOCHROME(vendor, product)) kb->features |= FEAT_MONOCHROME; kb->usbdelay = USB_DELAY_DEFAULT; // Perform OS-specific setup DELAY_LONG(kb); if(os_setupusb(kb)) goto fail; // Make up a device name and serial if they weren't assigned if(!kb->serial[0]) snprintf(kb->serial, SERIAL_LEN, "%04x:%04x-NoID", kb->vendor, kb->product); if(!kb->name[0]) snprintf(kb->name, KB_NAME_LEN, "%s %s", vendor_str(kb->vendor), product_str(kb->product)); // Set up an input device for key events if(os_inputopen(kb)) goto fail; if(pthread_create(&kb->inputthread, 0, os_inputmain, kb)) goto fail; pthread_detach(kb->inputthread); if(os_setupindicators(kb)) goto fail; // Set up device vt->allocprofile(kb); vt->updateindicators(kb, 1); pthread_mutex_unlock(imutex(kb)); if(vt->start(kb, 0) && usb_tryreset(kb)) goto fail_noinput; // Make /dev path if(mkdevpath(kb)) goto fail_noinput; // Finished. Enter main loop int index = INDEX_OF(kb, keyboard); ckb_info("Setup finished for %s%d\n", devpath, index); updateconnected(); return devmain(kb); fail: pthread_mutex_unlock(imutex(kb)); fail_noinput: closeusb(kb); pthread_mutex_unlock(dmutex(kb)); return 0; }
void openusb(usbdevice* kb, short vendor, short product){ kb->lastkeypress = KEY_NONE; if(IS_RGB(vendor, product)) // Handle 3 is the control handle kb->handle = kb->handles[3]; else // Non RGB keyboards don't have one, so just use 0 kb->handle = kb->handles[0]; // Set up the device int setup = setupusb(kb, vendor, product); if(setup == -1 || (setup && usb_tryreset(kb))){ closehandle(kb); pthread_mutex_unlock(&kb->mutex); pthread_mutex_destroy(&kb->mutex); pthread_mutex_destroy(&kb->keymutex); return; } // Start handling HID reports for the input IOHIDDeviceRegisterInputReportCallback(kb->handles[0], kb->urbinput, 8, reportcallback, kb); if(IS_RGB(vendor, product)) IOHIDDeviceRegisterInputReportCallback(kb->handles[1], kb->urbinput + 8, 21, reportcallback, kb); else IOHIDDeviceRegisterInputReportCallback(kb->handles[1], kb->urbinput + 8, 4, reportcallback, kb); if(IS_RGB(vendor, product)) IOHIDDeviceRegisterInputReportCallback(kb->handles[2], kb->kbinput, MSG_SIZE, reportcallback, kb); else IOHIDDeviceRegisterInputReportCallback(kb->handles[2], kb->urbinput + 8 + 4, 15, reportcallback, kb); // Register for close notification IOHIDDeviceRegisterRemovalCallback(kb->handle, usbremove, kb); // Update connected updateconnected(); notifyconnect(kb, 1); int index = INDEX_OF(kb, keyboard); printf("Device ready at %s%d\n", devpath, index); pthread_mutex_unlock(&kb->mutex); }