Ejemplo n.º 1
0
void do_input(int fd, unsigned char* buf, struct dev_input input)
{
    b1 = buf[3];
    b2 = buf[4];
    b3 = buf[5];
    lx = buf[7] - 128;
    ly = buf[8] - 128;
    rx = buf[9] - 128;
    ry = buf[10] - 128;

    //deadzones
    if (lx > -10 && lx < 10) lx = 0;
    if (ly > -10 && ly < 10) ly = 0;
    if (rx > -11 && rx < 11) rx = 0;
    if (ry > -11 && ry < 11) ry = 0;

    //lr3 enable/disable
    if ((b1 & SIXAXIS_KEY_L3) && b1 != last_b1)
      lr3_axis = !lr3_axis;

    if ((b1 & SIXAXIS_KEY_R3) && b1 != last_b1)
      lr3_buttons = !lr3_buttons;

    last_b1 = b1;

    //buttons
    if (!input.use_lr3 || (input.use_lr3 && lr3_buttons)) {
        //part1
        if (last_ib1 != b1) {
            if (input.key_select) uinput_send(fd, EV_KEY, input.key_select, b1 & 0x01 ? 1 : 0);
            if (input.key_l3) uinput_send(fd, EV_KEY, input.key_l3, b1 & 0x02 ? 1 : 0);
            if (input.key_r3) uinput_send(fd, EV_KEY, input.key_r3, b1 & 0x04 ? 1 : 0);
            if (input.key_start) uinput_send(fd, EV_KEY, input.key_start, b1 & 0x08 ? 1 : 0);
            if (input.key_up) uinput_send(fd, EV_KEY, input.key_up, b1 & 0x10 ? 1 : 0);
            if (input.key_right) uinput_send(fd, EV_KEY, input.key_right, b1 & 0x20 ? 1 : 0);
            if (input.key_down) uinput_send(fd, EV_KEY, input.key_down, b1 & 0x40 ? 1 : 0);
            if (input.key_left) uinput_send(fd, EV_KEY, input.key_left, b1 & 0x80 ? 1 : 0);
        }
        //part2
        if (last_ib2 != b2) {
            if (input.key_l2) uinput_send(fd, EV_KEY, input.key_l2, b2 & 0x01 ? 1 : 0);
            if (input.key_r2) uinput_send(fd, EV_KEY, input.key_r2, b2 & 0x02 ? 1 : 0);
            if (input.key_l1) uinput_send(fd, EV_KEY, input.key_l1, b2 & 0x04 ? 1 : 0);
            if (input.key_r1) uinput_send(fd, EV_KEY, input.key_r1, b2 & 0x08 ? 1 : 0);
            if (input.key_tri) uinput_send(fd, EV_KEY, input.key_tri, b2 & 0x10 ? 1 : 0);
            if (input.key_cir) uinput_send(fd, EV_KEY, input.key_cir, b2 & 0x20 ? 1 : 0);
            if (input.key_cro) uinput_send(fd, EV_KEY, input.key_cro, b2 & 0x40 ? 1 : 0);
            if (input.key_squ) uinput_send(fd, EV_KEY, input.key_squ, b2 & 0x80 ? 1 : 0);
        }
        //part3
        if (last_ib3 != b3) {
            if (input.key_ps) uinput_send(fd, EV_KEY, input.key_ps, b3 & 0x01 ? 1 : 0);
        }
    }

    //axis
    if (!input.use_lr3 || (input.use_lr3 && lr3_axis)) {
      int rel;
      bool rw_do;

      if (rw_timer%(input.axis_speed*2) == 0)
        rw_do = true;
      else
        rw_do = false;

      if (input.axis_l_type == INPUT_TYPE_KEYS)
      {
          uinput_send(fd, EV_KEY, input.axis_l_right, (lx > 100));
          uinput_send(fd, EV_KEY, input.axis_l_left, (lx < -100));
          uinput_send(fd, EV_KEY, input.axis_l_up, (ly > 100));
          uinput_send(fd, EV_KEY, input.axis_l_down, (ly < -100));
      }
      else if (input.axis_l_type == INPUT_TYPE_MOUSE)
      {
          rel = input.axis_l_right;
          if (rel == REL_X || rel == REL_Y) {
            uinput_send(fd, EV_REL, rel, lx/4/input.axis_speed);
          } else if (rw_do && (rel == REL_WHEEL || rel == REL_HWHEEL)) {
            lx = lx/20;
            if (rel == REL_WHEEL) lx = -lx; //Inverted
            uinput_send(fd, EV_REL, rel, lx);
          }

          rel = input.axis_l_up;
          if (rel == REL_X || rel == REL_Y) {
            uinput_send(fd, EV_REL, rel, ly/4/input.axis_speed);
          } else if (rw_do && (rel == REL_WHEEL || rel == REL_HWHEEL)) {
            ly = ly/20;
            if (rel == REL_WHEEL) ly = -ly; //Inverted
            uinput_send(fd, EV_REL, rel, ly);
          }
      }

      if (input.axis_r_type == INPUT_TYPE_KEYS)
      {
          uinput_send(fd, EV_KEY, input.axis_r_right, (rx > 100));
          uinput_send(fd, EV_KEY, input.axis_r_left, (rx < -100));
          uinput_send(fd, EV_KEY, input.axis_r_up, (ry > 100));
          uinput_send(fd, EV_KEY, input.axis_r_down, (ry < -100));
      }
      else if (input.axis_r_type == INPUT_TYPE_MOUSE)
      {
          rel = input.axis_r_right;
          if (rel == REL_X || rel == REL_Y) {
            uinput_send(fd, EV_REL, rel, rx/4/input.axis_speed);
          } else if (rw_do && (rel == REL_WHEEL || rel == REL_HWHEEL)) {
            rx = rx/20;
            if (rel == REL_WHEEL) rx = -rx; //Inverted
            uinput_send(fd, EV_REL, rel, rx);
          }

          rel = input.axis_r_up;
          if (rel == REL_X || rel == REL_Y) {
            uinput_send(fd, EV_REL, rel, ry/4/input.axis_speed);
          } else if (rw_do && (rel == REL_WHEEL || rel == REL_HWHEEL)) {
            ry = ry/20;
            if (rel == REL_WHEEL) ry = -ry; //Inverted
            uinput_send(fd, EV_REL, rel, ry);
          }
      }
    }

    if (b1 > 0 || b2 > 0 || b3 > 0 || lx != 0 || ly != 0 || rx != 0 || ry != 0) {
      set_active(true);
    }

    last_ib1 = b1;
    last_ib2 = b2;
    last_ib3 = b3;

    uinput_send(fd, EV_SYN, SYN_REPORT, 0);

    if (rw_timer > 0xff)
      rw_timer = 0;
    else
      rw_timer += 1;

}
Ejemplo n.º 2
0
void do_joystick(int fd, unsigned char* buf, struct dev_joystick joystick)
{
    newH.time = tv.tv_sec + tv.tv_usec*1e-6;
    newH.ax = buf[42]<<8 | buf[43];
    newH.ay = buf[44]<<8 | buf[45];
    newH.az = buf[46]<<8 | buf[47];
    if ( ! prev.time ) {
        prev.time = newH.time;
        prev.ax = newH.ax;
        prev.ay = newH.ay;
        prev.az = newH.az;
    }
    dt = newH.time - prev.time; //(time constants were recuced by half)
    if (joystick.accon) {
        rc_dd = 1.0;  // Time constant for highpass filter on acceleration
        alpha_dd = rc_dd / (rc_dd+dt);
        newH.ddx = alpha_dd*(prev.ddx + (newH.ax-prev.ax)*0.01);
        newH.ddy = alpha_dd*(prev.ddy + (newH.ay-prev.ay)*0.01);
        newH.ddz = alpha_dd*(prev.ddz - (newH.az-prev.az)*0.01);
    }
    if (joystick.speed) {
        rc_d = 1.0;  // Time constant for highpass filter on speed
        alpha_d = rc_d / (rc_d+dt);
        newH.dx = alpha_d*(prev.dx + newH.ddx*dt);
        newH.dy = alpha_d*(prev.dy + newH.ddy*dt);
        newH.dz = alpha_d*(prev.dz + newH.ddz*dt);
    }
    if (joystick.pos) {
        rc = 0.5;  // Time constant for highpass filter on position
        alpha = rc / (rc+dt);
        newH.x = alpha*(prev.x + newH.dx*dt);
        newH.y = alpha*(prev.y + newH.dy*dt);
        newH.z = alpha*(prev.z + newH.dz*dt);
    }
    prev = newH;

    b1 = buf[3];
    b2 = buf[4];
    b3 = buf[5];
    lx = buf[7] - 128;
    ly = buf[8] - 128;
    rx = buf[9] - 128;
    ry = buf[10] - 128;
    acx = - (buf[42]<<8 | buf[43]); //reversed
    acy = buf[44]<<8 | buf[45];
    acz = buf[46]<<8 | buf[47];
    gyro = 0; // FIXME - What is the gyro suppose to do?
    up = buf[15];
    right = buf[16];
    down = buf[17];
    left = buf[18];
    l2 = buf[19];
    r2 = buf[20];
    l1 = buf[21];
    r1 = buf[22];
    tri = buf[23];
    cir = buf[24];
    cro = buf[25];
    squ = buf[26];
    posX = (int)(newH.x*1000);
    posY = (int)(newH.y*1000);
    posZ = (int)(newH.z*1000);
    accX = (int)(newH.ddx*1000);
    accY = (int)(newH.ddy*1000);
    accZ = (int)(newH.ddz*1000);
    velX = (int)(newH.dx*1000);
    velY = (int)(newH.dy*1000);
    velZ = (int)(newH.dz*1000);

    //deadzones
    if (lx > -10 && lx < 10) lx = 0;
    if (ly > -10 && ly < 10) ly = 0;
    if (rx > -11 && rx < 11) rx = 0;
    if (ry > -11 && ry < 11) ry = 0;
    if (acx < -508 && acx > -516) acx = -512; //acx is reversed
    if (acy > 508 && acy < 516) acy = 512;
    if (acz > 508 && acz < 516) acz = 512;
    if (posX > -30 && posX < 30) posX = 0;
    if (posY > -30 && posY < 30) posY = 0;
    if (posZ > -30 && posZ < 30) posZ = 0;
    if (accX > -30 && accX < 30) accX = 0;
    if (accY > -30 && accY < 30) accY = 0;
    if (accZ > -30 && accZ < 30) accZ = 0;
    if (velX > -30 && velX < 30) velX = 0;
    if (velY > -30 && velY < 30) velY = 0;
    if (velZ > -30 && velZ < 30) velZ = 0;

    if (joystick.buttons) {
        //part1
        if (last_jb1 != b1) {
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 0, b1 & 0x01 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 1, b1 & 0x02 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 2, b1 & 0x04 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 3, b1 & 0x08 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 4, b1 & 0x10 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 5, b1 & 0x20 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 6, b1 & 0x40 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 7, b1 & 0x80 ? 1 : 0);
        }
        //part2
        if (last_jb2 != b2) {
            uinput_send(fd, EV_KEY, BTN_JOYSTICK +  8, b2 & 0x01 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK +  9, b2 & 0x02 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 10, b2 & 0x04 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 11, b2 & 0x08 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 12, b2 & 0x10 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 13, b2 & 0x20 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 14, b2 & 0x40 ? 1 : 0);
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 15, b2 & 0x80 ? 1 : 0);
        }
        //part3
        if (last_jb3 != b3) {
            uinput_send(fd, EV_KEY, BTN_JOYSTICK + 16, b3 & 0x01 ? 1 : 0);
        }

        if (b1 > 0 || b2 > 0 || b3 > 0) {
          set_active(true);
        }
    }

    //axis
    if (joystick.axis) {
        uinput_send(fd, EV_ABS, 0, lx);
        uinput_send(fd, EV_ABS, 1, ly);
        uinput_send(fd, EV_ABS, 2, rx);
        uinput_send(fd, EV_ABS, 3, ry);

        if (lx != 0 || ly != 0 || rx != 0 || ry != 0) {
          set_active(true);
        }
    }

    //accelerometer RAW
    if (joystick.accel) {
        uinput_send(fd, EV_ABS, 4, acx);
        uinput_send(fd, EV_ABS, 5, acy);
        uinput_send(fd, EV_ABS, 6, acz);
        uinput_send(fd, EV_ABS, 7, gyro);
    }

    //buttons (sensible, as axis)
    if (joystick.sbuttons) {
        uinput_send(fd, EV_ABS, 8, up);
        uinput_send(fd, EV_ABS, 9, right);
        uinput_send(fd, EV_ABS, 10, down);
        uinput_send(fd, EV_ABS, 11, left);
        uinput_send(fd, EV_ABS, 12, l2);
        uinput_send(fd, EV_ABS, 13, r2);
        uinput_send(fd, EV_ABS, 14, l1);
        uinput_send(fd, EV_ABS, 15, r1);
        uinput_send(fd, EV_ABS, 16+AXIS_PADDING, tri);
        uinput_send(fd, EV_ABS, 17+AXIS_PADDING, cir);
        uinput_send(fd, EV_ABS, 18+AXIS_PADDING, cro);
        uinput_send(fd, EV_ABS, 19+AXIS_PADDING, squ);

        if (up > 0 || right > 0 || down > 0 || left > 0 || l2 > 0 || r2 > 0 || l1 > 0 || r1 > 0 || tri > 0 || cir > 0 || cro > 0 || squ > 0 ) {
          set_active(true);
        }
    }

    //acceleration
    if (joystick.accon) {
        uinput_send(fd, EV_ABS, 20+AXIS_PADDING, accX);
        uinput_send(fd, EV_ABS, 21+AXIS_PADDING, accY);
        uinput_send(fd, EV_ABS, 22+AXIS_PADDING, accZ);
    }

    //speed
    if (joystick.speed) {
        uinput_send(fd, EV_ABS, 23+AXIS_PADDING, velX);
        uinput_send(fd, EV_ABS, 24+AXIS_PADDING, velY);
        uinput_send(fd, EV_ABS, 25+AXIS_PADDING, velZ);
    }

    //position
    if (joystick.pos) {
        uinput_send(fd, EV_ABS, 26+AXIS_PADDING, posX);
        uinput_send(fd, EV_ABS, 27+AXIS_PADDING, posY);
        uinput_send(fd, EV_ABS, 28+AXIS_PADDING, posZ);
    }

    last_jb1 = b1;
    last_jb2 = b2;
    last_jb3 = b3;

    uinput_send(fd, EV_SYN, SYN_REPORT, 0);
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
    int fd, nr;
    unsigned char buf[128];
    struct uinput_fd *ufd;
    struct device_settings settings;

    if (argc < 2) {
        std::cout << "Usage: " << argv[0] << " /dev/hidrawX" << std::endl;
        return 1;
    }

    if ((fd = open(argv[1], O_RDONLY|O_NONBLOCK)) < 0) {
        std::cerr << "sixad-3in1::open(hidrawX) - failed to open hidraw device" << std::endl;
        return 1;
    }

    nr=read(fd, buf, sizeof(buf));
    if (nr < 0 && errno != EAGAIN) {
        std::cerr << "sixad-3in1::read(fd) - failed to read from device" << std::endl;
        return 1;
    }

    if (nr != -1 && nr != 19) {
        std::cerr <<  "sixad-3in1::read(fd) - not a 3in1 keymote (nr = " << nr << ")" << std::endl;
        return 1;
    }

    open_log("sixad-3in1");

    memset(&settings, 0, sizeof(device_settings));

    settings.led.enabled = 0;
    settings.joystick.enabled = 0;
    settings.remote.enabled = 0;
    settings.input.enabled = 1;
    settings.input.key_select = 29;
    settings.input.key_l3 = 0;
    settings.input.key_r3 = 0;
    settings.input.key_start = 56;
    settings.input.key_up = 103;
    settings.input.key_right = 106;
    settings.input.key_down = 108;
    settings.input.key_left = 105;
    settings.input.key_l2 = 102;
    settings.input.key_r2 = 107;
    settings.input.key_l1 = 67;
    settings.input.key_r1 = 87;
    settings.input.key_tri = 14;
    settings.input.key_cir = 273;
    settings.input.key_squ = 28;
    settings.input.key_cro = 272;
    settings.input.key_ps = 42;
    settings.input.axis_l_type = 3;
    settings.input.axis_l_up = 1;
    settings.input.axis_l_right = 0;
    settings.input.axis_l_down = 0;
    settings.input.axis_l_left = 0;
    settings.input.axis_r_type = 3;
    settings.input.axis_r_up = 8;
    settings.input.axis_r_right = 6;
    settings.input.axis_r_down = 0;
    settings.input.axis_r_left = 0;
    settings.input.axis_speed = 9;
    settings.input.use_lr3 = 1;
    settings.rumble.enabled = 0;

    ufd = uinput_open(DEV_TYPE_3IN1, "3in1", settings);

    if (ufd->js != 0 || ufd->mk == 0) {
        syslog(LOG_ERR, "Error! something  is not right...");
        return 1;
    }

    syslog(LOG_INFO, "Connected 'Brooklyn 3in1 KeyMote'");

    int b0, b1, lx, ly, rx, ry;
    int kUp, kDown, kLeft, kRight;
    int last_b1 = 0;
    int last_ib0 = 0;
    int last_ib1 = 0;
    int last_lx = 0;
    int last_ly = 0;
    int last_rx = 0;
    int last_ry = 0;
    int last_kUp = 0;
    int last_kDown = 0;
    int last_kLeft = 0;
    int last_kRight = 0;
    bool lr3_axis = true;
    bool lr3_buttons = true;
    int rw_timer = 0;

    while (true) {
        nr=read(fd, buf, sizeof(buf));

        if (nr == 19) {
          // read successful
          b0 = buf[0];
          b1 = buf[1];
          lx = buf[3] - 128;
          ly = buf[4] - 128;
          rx = buf[5] - 128;
          ry = buf[6] - 128;
          kRight = buf[7];
          kLeft  = buf[8];
          kUp    = buf[9];
          kDown  = buf[10];
          //min value is -127
          if (lx < -127) lx = -127;
          if (ly < -127) ly = -127;
          if (rx < -127) rx = -127;
          if (ry < -127) ry = -127;

        } else {
          if (errno != EAGAIN) {
            std::cerr <<  "sixad-3in1::read(fd, buf) - failed to read from device" << std::endl;
            break;
          }

          b0 = last_ib0;
          b1 = last_ib1;
          lx = last_lx;
          ly = last_ly;
          rx = last_rx;
          ry = last_ry;
          kRight = last_kRight;
          kLeft  = last_kLeft;
          kUp    = last_kUp;
          kDown  = last_kDown;
        }

        //lr3 enable/disable
        if ((b1 & KEYMOTE_KEY_L3) && b1 != last_b1)
          lr3_axis = !lr3_axis;

        if ((b1 & KEYMOTE_KEY_R3) && b1 != last_b1)
          lr3_buttons = !lr3_buttons;

        last_b1 = b1;

        //buttons
        if (lr3_buttons) {
            //part1
            if (last_ib0 != b0) {
                uinput_send(ufd->mk, EV_KEY, settings.input.key_l2, b0 & KEYMOTE_KEY_L2 ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_r2, b0 & KEYMOTE_KEY_R2 ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_l1, b0 & KEYMOTE_KEY_L1 ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_r1, b0 & KEYMOTE_KEY_R1 ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_tri, b0 & KEYMOTE_KEY_TRIANGLE ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_cir, b0 & KEYMOTE_KEY_CIRCLE ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_cro, b0 & KEYMOTE_KEY_CROSS ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_squ, b0 & KEYMOTE_KEY_SQUARE ? 1 : 0);
            }
            //part2
            if (last_ib1 != b1) {
                uinput_send(ufd->mk, EV_KEY, settings.input.key_select, b1 & KEYMOTE_KEY_SELECT ? 1 : 0);
                uinput_send(ufd->mk, EV_KEY, settings.input.key_start, b1 & KEYMOTE_KEY_START ? 1 : 0);
            }
            uinput_send(ufd->mk, EV_KEY, settings.input.key_up, kUp ? 1 : 0);
            uinput_send(ufd->mk, EV_KEY, settings.input.key_right, kRight ? 1 : 0);
            uinput_send(ufd->mk, EV_KEY, settings.input.key_down, kDown ? 1 : 0);
            uinput_send(ufd->mk, EV_KEY, settings.input.key_left, kLeft ? 1 : 0);
        }

        //axis
        if (lr3_axis) {
          bool rw_do;

          if (rw_timer%(settings.input.axis_speed*2) == 0)
            rw_do = true;
          else
            rw_do = false;

          uinput_send(ufd->mk, EV_REL, REL_X, lx/4/settings.input.axis_speed);
          uinput_send(ufd->mk, EV_REL, REL_Y, ly/4/settings.input.axis_speed);

          if (rw_do) {
            rx = rx/20;
            ry = ry/20;
            ry = -ry; //Inverted

            uinput_send(ufd->mk, EV_REL, REL_HWHEEL, rx);
            uinput_send(ufd->mk, EV_REL, REL_WHEEL, ry);
          }
        }

        last_ib0 = b0;
        last_ib1 = b1;
        last_lx = lx;
        last_ly = ly;
        last_rx = rx;
        last_ry = ry;
        last_kUp = kUp;
        last_kDown = kDown;
        last_kLeft = kLeft;
        last_kRight = kRight;

        uinput_send(ufd->mk, EV_SYN, SYN_REPORT, 0);

        if (rw_timer > 0xff)
          rw_timer = 0;
        else
          rw_timer += 1;

        if (nr != 19)
          usleep(10000);
    }

    uinput_close(ufd->mk, 0);

    std::cerr <<  "sixad-3in1::read(buf) - connection has been broken" << std::endl;
    
    delete ufd;

    return 0;
}