Esempio n. 1
0
int setactive_mouse(usbdevice* kb, int active){
    if(NEEDS_FW_UPDATE(kb))
        return 0;
    uchar msg[2][MSG_SIZE] = {
        { 0x07, 0x04, 0 },                                                          // Disables or enables HW control for DPI and Sniper button
        { 0x07, 0x40, 0x08, 0,
          1, 0x80, 2, 0x80, 3, 0x80, 4, 0x80, 5, 0x80, 6, 0x80, 7, 0x80, 8, 0x80 }, // Enable button input. This is similar to the keyboard input selection, but we want everything to come through the HID reports.
    };
    if(active)
        // Put the mouse into SW mode
        msg[0][2] = 2;
    else
        // Restore HW mode
        msg[0][2] = 1;
    pthread_mutex_lock(imutex(kb));
    kb->active = !!active;
    kb->profile->lastlight.forceupdate = 1;
    // Clear input
    memset(&kb->input.keys, 0, sizeof(kb->input.keys));
    inputupdate(kb);
    pthread_mutex_unlock(imutex(kb));
    if(!usbsend(kb, msg[0], 1))
        return -1;
    if(active && !usbsend(kb, msg[1], 1))
        return -1;
    return 0;
}
Esempio n. 2
0
static void intreport(void* context, IOReturn result, void* sender, IOHIDReportType reporttype, uint32_t reportid, uint8_t* data, CFIndex length){
    usbdevice* kb = context;
    pthread_mutex_lock(imutex(kb));
    if(IS_MOUSE(kb->vendor, kb->product)){
        if(length == 10)
            hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -2, length, data);
    } else if(HAS_FEATURES(kb, FEAT_RGB)){
        switch(length){
        case 8:
            // RGB EP 1: 6KRO (BIOS mode) input
            hid_kb_translate(kb->input.keys, -1, length, data);
            break;
        case 21:
        case 5:
            // RGB EP 2: NKRO (non-BIOS) input. Accept only if keyboard is inactive
            if(!kb->active)
                hid_kb_translate(kb->input.keys, -2, length, data);
            break;
        case MSG_SIZE:
            // RGB EP 3: Corsair input
            memcpy(kb->input.keys, data, N_KEYBYTES_KB);
            break;
        }
    } else {
        switch(length){
        case 8:
            // Non-RGB EP 1: 6KRO input
            hid_kb_translate(kb->input.keys, 1, length, data);
            break;
        case 4:
            // Non-RGB EP 2: media keys
            hid_kb_translate(kb->input.keys, 2, length, data);
            break;
        case 15:
            // Non-RGB EP 3: NKRO input
            hid_kb_translate(kb->input.keys, 3, length, data);
            break;
        }
    }
    inputupdate(kb);
    pthread_mutex_unlock(imutex(kb));
}
Esempio n. 3
0
void* intreap(void* context){
    usbdevice* kb = context;
    int fd = kb->handle;
    while(1){
        struct usbdevfs_urb* urb;
        if(ioctl(fd, USBDEVFS_REAPURB, &urb) && errno == ENODEV){
            // Stop the thread if the handle closes
            break;
        }
        if(urb){
            // Otherwise, re-submit the URB
            ioctl(fd, USBDEVFS_SUBMITURB, urb);
            // And process input (if any)
            if(urb->actual_length == MSG_SIZE)
                inputupdate(kb);
            // Mark the keyboard as having received input
            kb->INPUT_TEST = 1;
        }
    }
    return 0;
}
Esempio n. 4
0
File: usb_mac.c Progetto: jsnel/ckb
void reportcallback(void* context, IOReturn result, void* sender, IOHIDReportType reporttype, uint32_t reportid, uint8_t* data, CFIndex length){
    usbdevice* kb = context;
    if(HAS_FEATURES(kb, FEAT_RGB)){
        switch(length){
        case 8:
            // RGB EP 1: 6KRO (BIOS mode) input
            hid_translate(kb->kbinput, -1, 8, kb->urbinput);
            inputupdate(kb);
            break;
        case 21:
        case 5:
            // RGB EP 2: NKRO (non-BIOS) input. Accept only if keyboard is inactive
            if(!kb->active){
                hid_translate(kb->kbinput, -2, 21, kb->urbinput + 8);
                inputupdate(kb);
            }
            break;
        case MSG_SIZE:
            // RGB EP 3: Corsair input
            inputupdate(kb);
            break;
        }
    } else {
        switch(length){
        case 8:
            // Non-RGB EP 1: 6KRO input
            hid_translate(kb->kbinput, 1, 8, kb->urbinput);
            inputupdate(kb);
            break;
        case 4:
            // Non-RGB EP 2: media keys
            hid_translate(kb->kbinput, 2, 4, kb->urbinput + 8);
            inputupdate(kb);
            break;
        case 15:
            // Non-RGB EP 3: NKRO input
            hid_translate(kb->kbinput, 3, 15, kb->urbinput + 8 + 4);
            inputupdate(kb);
            break;
        }
    }
}
Esempio n. 5
0
void* os_inputmain(void* context){
    usbdevice* kb = context;
    int fd = kb->handle;
    short vendor = kb->vendor, product = kb->product;
    int index = INDEX_OF(kb, keyboard);
    ckb_info("Starting input thread for %s%d\n", devpath, index);

    // Monitor input transfers on all endpoints
    int urbcount = 3;
    struct usbdevfs_urb urbs[urbcount];
    memset(urbs, 0, sizeof(urbs));
    urbs[0].buffer_length = 8;
    if(IS_RGB(vendor, product)){
        if(IS_MOUSE(vendor, product))
            urbs[1].buffer_length = 10;
        else
            urbs[1].buffer_length = 21;
        urbs[2].buffer_length = MSG_SIZE;
        urbs[3].buffer_length = MSG_SIZE;
    } else {
        urbs[1].buffer_length = 4;
        urbs[2].buffer_length = 15;
    }
    // Submit URBs
    for(int i = 0; i < urbcount; i++){
        urbs[i].type = USBDEVFS_URB_TYPE_INTERRUPT;
        urbs[i].endpoint = 0x80 | (i + 1);
        urbs[i].buffer = malloc(urbs[i].buffer_length);
        ioctl(fd, USBDEVFS_SUBMITURB, urbs + i);
    }
    // Start monitoring input
    while(1){
        struct usbdevfs_urb* urb = 0;
        if(ioctl(fd, USBDEVFS_REAPURB, &urb)){
            if(errno == ENODEV || errno == ENOENT || errno == ESHUTDOWN)
                // Stop the thread if the handle closes
                break;
            else if(errno == EPIPE && urb){
                // On EPIPE, clear halt on the endpoint
                ioctl(fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
                // Re-submit the URB
                if(urb)
                    ioctl(fd, USBDEVFS_SUBMITURB, urb);
                urb = 0;
            }
        }
        if(urb){
            // Process input (if any)
            pthread_mutex_lock(imutex(kb));
            if(IS_MOUSE(vendor, product)){
                if(urb->endpoint == 0x82){
                    // RGB mouse input
                    hid_mouse_translate(kb->input.keys, &kb->input.rel_x, &kb->input.rel_y, -(urb->endpoint & 0xF), urb->actual_length, urb->buffer);
                }
            } else if(IS_RGB(vendor, product)){
                switch(urb->endpoint){
                case 0x81:
                    // RGB EP 1: 6KRO (BIOS mode) input
                    hid_kb_translate(kb->input.keys, -1, urb->actual_length, urb->buffer);
                    break;
                case 0x82:
                    // RGB EP 2: NKRO (non-BIOS) input. Accept only if keyboard is inactive
                    if(!kb->active)
                        hid_kb_translate(kb->input.keys, -2, urb->actual_length, urb->buffer);
                    break;
                case 0x83:
                    // RGB EP 3: Corsair input
                    memcpy(kb->input.keys, urb->buffer, N_KEYBYTES_KB);
                    break;
                }
            } else
                // Non-RGB input
                hid_kb_translate(kb->input.keys, urb->endpoint & 0xF, urb->actual_length, urb->buffer);
            inputupdate(kb);
            pthread_mutex_unlock(imutex(kb));
            // Re-submit the URB
            ioctl(fd, USBDEVFS_SUBMITURB, urb);
            urb = 0;
        }
    }
    // Clean up
    ckb_info("Stopping input thread for %s%d\n", devpath, index);
    for(int i = 0; i < urbcount; i++){
        ioctl(fd, USBDEVFS_DISCARDURB, urbs + i);
        free(urbs[i].buffer);
    }
    return 0;
}
Esempio n. 6
0
void reportcallback(void* context, IOReturn result, void* sender, IOHIDReportType reporttype, uint32_t reportid, uint8_t* data, CFIndex length){
    usbdevice* kb = context;
    if(length == MSG_SIZE)
        inputupdate(kb);
}