diff --git a/src/uhid/include/uhid/uhid.hpp b/src/uhid/include/uhid/uhid.hpp index d77c9b3..009b767 100644 --- a/src/uhid/include/uhid/uhid.hpp +++ b/src/uhid/include/uhid/uhid.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,7 @@ static inputtino::Result uhid_write(int fd, const struct uhid_event *ev) { class Device { private: Device(std::shared_ptr ev_thread, std::shared_ptr state) - : ev_thread(std::move(ev_thread)), state(std::move(state)){}; + : ev_thread(std::move(ev_thread)), state(std::move(state)) {}; std::shared_ptr ev_thread; std::shared_ptr state; std::shared_ptr> on_event; @@ -81,7 +82,7 @@ class Device { ~Device() { if (state) { - struct uhid_event ev {}; + struct uhid_event ev{}; ev.type = UHID_DESTROY; uhid_write(state->fd, &ev); @@ -100,6 +101,8 @@ static void set_c_str(const std::string &str, unsigned char *c_str) { c_str[str.length()] = 0; } +constexpr int UHID_POLL_TIMEOUT = 500; // ms + inputtino::Result Device::create(const DeviceDefinition &definition, const std::function &on_event) { @@ -124,30 +127,28 @@ inputtino::Result Device::create(const DeviceDefinition &definition, state->fd = fd; state->on_event = on_event; auto thread = std::make_shared([state]() { - ssize_t ret; - struct pollfd pfds[1]; - pfds[0].fd = state->fd; - pfds[0].events = POLLIN; + std::array pfds = {pollfd{.fd = state->fd, .events = POLLIN}}; + int poll_rs = 0; while (!state->stop_repeat_thread) { - ret = poll(pfds, 1, -1); - if (ret < 0) { - fprintf(stderr, "Cannot poll for fds: %m\n"); + poll_rs = poll(pfds.data(), pfds.size(), UHID_POLL_TIMEOUT); + if (poll_rs < 0) { + std::cerr << "Failed polling uhid fd; ret=" << strerror(errno) << std::endl; break; } if (pfds[0].revents & POLLHUP) { - fprintf(stderr, "Received HUP on uhid-cdev\n"); + std::cerr << "HUP on uhid-cdev" << std::endl; break; } if (pfds[0].revents & POLLIN) { - struct uhid_event ev {}; - ret = read(state->fd, &ev, sizeof(ev)); + struct uhid_event ev{}; + auto ret = read(state->fd, &ev, sizeof(ev)); if (ret == 0) { - fprintf(stderr, "Read HUP on uhid-cdev\n"); + std::cerr << "Read HUP on uhid-cdev" << std::endl; } else if (ret < 0) { - fprintf(stderr, "Cannot read uhid-cdev: %m\n"); + std::cerr << "Cannot read uhid-cdev: " << strerror(errno) << std::endl; } else if (ret != sizeof(ev)) { - fprintf(stderr, "Invalid size read from uhid-dev: %zd != %zu\n", ret, sizeof(ev)); + std::cerr << "Invalid size read from uhid-dev" << ret << " != " << sizeof(ev) << std::endl; } else { if (state->on_event) { state->on_event(ev, state->fd); diff --git a/src/uinput/joypad_utils.hpp b/src/uinput/joypad_utils.hpp index 823c39f..6822641 100644 --- a/src/uinput/joypad_utils.hpp +++ b/src/uinput/joypad_utils.hpp @@ -10,13 +10,15 @@ #include #include #include +#include #include namespace inputtino { using namespace std::chrono_literals; -static constexpr long MAX_GAIN = 0xFFFF; +constexpr long MAX_GAIN = 0xFFFF; +constexpr int RUMBLE_POLL_TIMEOUT = 500; // ms /** * Joypads will also have one `/dev/input/js*` device as child, we want to expose that as well @@ -165,8 +167,15 @@ static void event_listener(const std::shared_ptr &state) { /* This can only be set globally when receiving FF_GAIN */ unsigned int current_gain = MAX_GAIN; + std::array pfds = {pollfd{.fd = uinput_fd, .events = POLLIN}}; + int poll_rs = 0; + while (!state->stop_listening_events) { - std::this_thread::sleep_for(20ms); // TODO: configurable? + poll_rs = poll(pfds.data(), pfds.size(), RUMBLE_POLL_TIMEOUT); + if (poll_rs < 0) { + std::cerr << "Failed polling uinput fd; ret=" << strerror(errno); + return; + } auto events = fetch_events(uinput_fd); for (auto ev : events) {