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; }
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; }
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; }