コード例 #1
0
ファイル: usb.c プロジェクト: gtjoseph/ckb
// USB device main loop
static void* devmain(usbdevice* kb){
    // dmutex should still be locked when this is called
    int kbfifo = kb->infifo - 1;
    readlines_ctx linectx;
    readlines_ctx_init(&linectx);
    while(1){
        pthread_mutex_unlock(dmutex(kb));
        // Read from FIFO
        const char* line;
        int lines = readlines(kbfifo, linectx, &line);
        pthread_mutex_lock(dmutex(kb));
        // End thread when the handle is removed
        if(!IS_CONNECTED(kb))
            break;
        if(lines){
            if(readcmd(kb, line)){
                // USB transfer failed; destroy device
                closeusb(kb);
                break;
            }
        }
    }
    pthread_mutex_unlock(dmutex(kb));
    readlines_ctx_free(linectx);
    return 0;
}
コード例 #2
0
ファイル: usb.c プロジェクト: shazron/ckb
// USB device main loop
static void* devmain(usbdevice* kb){
    readlines_ctx linectx;
    readlines_ctx_init(&linectx);
    while(1){
        pthread_mutex_lock(dmutex(kb));
        // End thread when the handle is removed
        if(!IS_CONNECTED(kb))
            break;
        // Read from FIFO
        const char* line;
        euid_guard_start;
        int lines = readlines(kb->infifo - 1, linectx, &line);
        euid_guard_stop;
        if(lines){
            if(readcmd(kb, line)){
                // USB transfer failed; destroy device
                closeusb(kb);
                break;
            }
        }
        // Update indicator LEDs for this keyboard. These are polled rather than processed during events because they don't update
        // immediately and may be changed externally by the OS.
        // (also, they can lock the keyboard if they're sent at the wrong time, at least on some firmwares)
        kb->vtable->updateindicators(kb, 0);
        // Wait a little bit and then read again
        pthread_mutex_unlock(dmutex(kb));
        DELAY_SHORT(kb);
    }
    pthread_mutex_unlock(dmutex(kb));
    readlines_ctx_free(linectx);
    return 0;
}
コード例 #3
0
ファイル: usb_mac.c プロジェクト: jsnel/ckb
void usbremove(void* context, IOReturn result, void* sender){
    pthread_mutex_lock(&kblistmutex);
    usbdevice* kb = context;
    for(int i = 0; i < DEV_MAX; i++){
        if(keyboard + i == kb){
            pthread_mutex_lock(&keyboard[i].mutex);
            closeusb(keyboard + i);
        }
    }
    pthread_mutex_unlock(&kblistmutex);
}
コード例 #4
0
ファイル: usb.c プロジェクト: gtjoseph/ckb
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;
}
コード例 #5
0
ファイル: usb_linux.c プロジェクト: SwellDesignsNYC/ckb
// Remove a udev device.
static void usb_rm_device(struct udev_device* dev){
    // Device removed. Look for it in our list of keyboards
    const char* syspath = udev_device_get_syspath(dev);
    if(!syspath || syspath[0] == 0)
        return;
    for(int i = 1; i < DEV_MAX; i++){
        pthread_mutex_lock(devmutex + i);
        if(!strcmp(syspath, kbsyspath[i]))
            closeusb(keyboard + i);
        pthread_mutex_unlock(devmutex + i);
    }
}
コード例 #6
0
ファイル: usb_mac.c プロジェクト: akosipc/ckb
static void remove_device(void* context, io_service_t device, uint32_t message_type, void* message_argument){
    if(message_type != kIOMessageServiceIsTerminated)
        return;
    usbdevice* kb = context;
    if(kb){
        // If the handle is connected to a device, close it
        pthread_mutex_lock(dmutex(kb));
        closeusb(kb);
        pthread_mutex_unlock(dmutex(kb));
    }
    IOObjectRelease(device);
}
コード例 #7
0
ファイル: usb_linux.c プロジェクト: TricksterGuy/ckb
void* udevmain(void* context){
    // Enumerate all currently connected devices
    udevenum();
    if(connectstatus & 2)
        // If a device failed to connect, enumerate again to make sure we reconnect it (if possible)
        udevenum();

    // 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){
                const char* action = udev_device_get_action(dev);
                if(action && !strcmp(action, "add")){
                    // Device added. Check vendor and product ID and add the device if it matches.
                    const char* vendor = udev_device_get_sysattr_value(dev, "idVendor");
                    if(vendor && !strcmp(vendor, V_CORSAIR_STR)){
                        const char* product = udev_device_get_sysattr_value(dev, "idProduct");
                        if(product && !strcmp(product, P_K70_STR)){
                            pthread_mutex_lock(&kblistmutex);
                            openusb(dev, 70);
                            pthread_mutex_unlock(&kblistmutex);
                        } else if(product && !strcmp(product, P_K95_STR)){
                            pthread_mutex_lock(&kblistmutex);
                            openusb(dev, 95);
                            pthread_mutex_unlock(&kblistmutex);
                        } else
                            // Free the device if it wasn't used
                            udev_device_unref(dev);
                    } else
                        udev_device_unref(dev);
                    // Wait a little bit and then re-enumerate devices. Sometimes the keyboard doesn't get picked up right away.
                    usleep(100000);
                    connectstatus = 0;
                    udevenum();
                    if(connectstatus & 2)
                        udevenum();
                } else if(!strcmp(action, "remove")){
                    // Device removed. Look for it in our list of keyboards
                    pthread_mutex_lock(&kblistmutex);
                    const char* path = udev_device_get_syspath(dev);
                    for(int i = 1; i < DEV_MAX; i++){
                        if(keyboard[i].udev && !strcmp(path, udev_device_get_syspath(keyboard[i].udev))){
                            pthread_mutex_lock(&keyboard[i].mutex);
                            closeusb(i);
                            break;
                        }
                    }
                    pthread_mutex_unlock(&kblistmutex);
                }
            }
        }
    }
    udev_monitor_unref(monitor);
    return 0;
}