Пример #1
0
int main(int argc, char *argv[])
{
    struct pollfd p[3];
    struct timespec timeout;
    struct device_settings settings;
    struct sigaction sa;
    sigset_t sigs;
    short events;

    if (argc < 3) {
        std::cout << "Running " << argv[0] << " requires 'sixad'. Please run sixad instead" << std::endl;
        return 1;
    }

    const char *mac = argv[1];
    debug = atoi(argv[2]);

    open_log("sixad-remote");
    settings = init_values(mac);
    settings.joystick.axis = false;
    settings.joystick.sbuttons = false;
    settings.joystick.accel = false;
    settings.joystick.speed = false;
    settings.joystick.pos = false;;
    settings.led.enabled = false;
    settings.rumble.enabled = false;

    ufd = uinput_open(DEV_TYPE_REMOTE, mac, settings);

    if (ufd->js < 0 || ufd->mk < 0) {
        return 1;
    } else if (ufd->js == 0 && ufd->mk == 0) {
        syslog(LOG_ERR, "remote config has no joystick or input mode selected - please choose one!");
        return 1;
    }

    int modes = 0;
    if (settings.remote.numeric) modes |= REMOTE_KEYMODE_NUMBERIC;
    if (settings.remote.dvd) modes |= REMOTE_KEYMODE_DVD;
    if (settings.remote.directional) modes |= REMOTE_KEYMODE_DIRECTIONAL;
    if (settings.remote.multimedia) modes |= REMOTE_KEYMODE_MULTIMEDIA;

    sigfillset(&sigs);
//    sigdelset(&sigs, SIGCHLD);
//    sigdelset(&sigs, SIGPIPE);
//    sigdelset(&sigs, SIGTERM);
//    sigdelset(&sigs, SIGINT);
//    sigdelset(&sigs, SIGHUP);

    memset(&sa, 0, sizeof(sa));
    sa.sa_flags = SA_NOCLDSTOP;

    sa.sa_handler = sig_term;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction(SIGCHLD, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);

    if (debug) syslog(LOG_INFO, "Press any to activate");

    p[0].fd = 0;
    p[0].events = POLLIN | POLLERR | POLLHUP;

    p[1].fd = 1;
    p[1].events = POLLIN | POLLERR | POLLHUP;

    p[2].fd = ufd->mk ? ufd->mk : ufd->js;
    p[2].events = POLLIN | POLLERR | POLLHUP;

    while (!io_canceled()) {
        int i, idx = 3;
        for (i = 0; i < idx; i++)
            p[i].revents = 0;

        timeout.tv_sec = 1;
        timeout.tv_nsec = 0;

        if (ppoll(p, idx, &timeout, &sigs) < 1)
            continue;

        if (p[1].revents & POLLIN) {
            process_remote(settings, mac, modes);
        }

        events = p[0].revents | p[1].revents | p[2].revents;

        if (events & (POLLERR | POLLHUP)) {
            break;
        }
    }

    if (debug) syslog(LOG_INFO, "Closing uinput...");

    if (settings.joystick.enabled) {
        uinput_close(ufd->js, debug);
    }
    if (settings.remote.enabled || settings.input.enabled) {
        uinput_close(ufd->mk, debug);
    }
    
    delete ufd;

    shutdown(isk, SHUT_RDWR);
    shutdown(csk, SHUT_RDWR);

    if (debug) syslog(LOG_INFO, "Done");

    return 0;
}
Пример #2
0
int main(int argc, char **argv)
{
    int i, 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)) < 0) {
        std::cerr << "sixad-raw::open(hidrawX) - failed to open hidraw device" << std::endl;
        return 1;
    }

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

    if (nr < 49 || nr > 50) {
        std::cerr <<  "sixad-raw::read(fd) - not a sixaxis (nr = " << nr << ")" << std::endl;
        return 1;
    }

    open_log("sixad-raw");
    settings = init_values("hidraw");

    // hidraw has no rumble/led support
    settings.remote.enabled = false;
    settings.led.enabled = false;
    settings.rumble.enabled = false;

    ufd = uinput_open(DEV_TYPE_SIXAXIS, "hidraw", settings);

    if (ufd->js < 0 || ufd->mk < 0) {
        return 1;
    } else if (ufd->js == 0 && ufd->mk == 0) {
        syslog(LOG_ERR, "sixaxis config has no joystick or input mode selected - please choose one!");
        return 1;
    }

    bool msg = true;
    while (true) {

        nr=read(fd, buf, sizeof(buf));

        if (nr < 49 || nr > 50) {
          std::cerr <<  "sixad-raw::read(fd, buf) - failed to read from device" << std::endl;
          break;
        } else if (nr == 49) {
          for (i=50; i>0; i--) {
            buf[i] = buf[i-1];
          }
        }

        if (msg) {
            syslog(LOG_INFO, "Connected 'PLAYSTATION(R)3 Controller (hidraw)' [Battery %02X]", buf[31]);
            if (nr == 49) syslog(LOG_INFO, "Notice: non-standard Sixaxis buffer size (49)");
            msg = false;
        }

        if (settings.joystick.enabled) do_joystick(ufd->js, buf, settings.joystick);
        if (settings.input.enabled) do_input(ufd->mk, buf, settings.input);
    }

    if (settings.joystick.enabled) {
        uinput_close(ufd->js, 0);
    }
    if (settings.input.enabled) {
        uinput_close(ufd->mk, 0);
    }

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

    return 0;
}
Пример #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;
}