diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2026-04-09 17:46:26 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2026-04-09 17:46:26 +0200 |
| commit | 614037c9af4641217ecd03d36baa41911d3c2680 (patch) | |
| tree | 4e719d98caf85fcb61c4eac6ff1e4bc0ac5d7e21 /pen-fix | |
| download | pen-fix-master.tar.xz pen-fix-master.zip | |
initial commitmaster
Diffstat (limited to 'pen-fix')
| -rw-r--r-- | pen-fix/main.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/pen-fix/main.cpp b/pen-fix/main.cpp new file mode 100644 index 0000000..4688f28 --- /dev/null +++ b/pen-fix/main.cpp @@ -0,0 +1,113 @@ +#include <algorithm> +#include <cstdio> +#include <linux/input-event-codes.h> +#include <linux/input.h> +#include <poll.h> +#include <sys/poll.h> +#include <unistd.h> +#include <utility> +#include <vector> + +auto flush(std::vector<input_event> & frame) -> void +{ + std::ranges::for_each(frame, [](auto event) { std::fwrite(&event, sizeof(event), 1, stdout); }); + + std::fflush(stdout); + frame.clear(); +} + +auto main() -> int +{ + auto poll_descriptor = pollfd{.fd = STDIN_FILENO, .events = POLLIN, .revents = 0}; + + auto current_frame = std::vector<struct input_event>{}; + auto deferred_frame = std::vector<struct input_event>{}; + auto waiting_for_rubber_tool = false; + + while (true) + { + auto timeout_ms = waiting_for_rubber_tool ? 50 : -1; + auto ret = poll(&poll_descriptor, 1, timeout_ms); + + if (ret == 0) + { + if (waiting_for_rubber_tool) + { + flush(deferred_frame); + waiting_for_rubber_tool = false; + } + continue; + } + + if (ret < 0) + { + break; + } + + auto event = input_event{}; + if (std::fread(&event, sizeof(event), 1, stdin) != 1) + { + break; + } + + current_frame.push_back(event); + + if (event.type == EV_SYN && event.code == SYN_REPORT) + { + auto has_pen_leave = false; + auto has_rubber_enter = false; + auto has_rubber_leave = false; + + std::ranges::for_each(current_frame, [&](auto event) { + if (event.type == EV_KEY && event.code == BTN_TOOL_PEN && event.value == 0) + has_pen_leave = true; + if (event.type == EV_KEY && event.code == BTN_TOOL_RUBBER && event.value == 1) + has_rubber_enter = true; + if (event.type == EV_KEY && event.code == BTN_TOOL_RUBBER && event.value == 0) + has_rubber_leave = true; + }); + + if (has_pen_leave) + { + deferred_frame = std::move(current_frame); + waiting_for_rubber_tool = true; + } + else if (has_rubber_enter || has_rubber_leave) + { + auto mutated_frame = std::vector<input_event>{}; + + for (auto const & e : current_frame) + { + if (e.type == EV_KEY && e.code == BTN_TOOL_RUBBER) + { + struct input_event mutated_btn = e; + mutated_btn.code = BTN_STYLUS2; + mutated_frame.push_back(mutated_btn); + } + else if (e.type == EV_ABS) + { + continue; + } + else + { + mutated_frame.push_back(e); + } + } + deferred_frame.clear(); + waiting_for_rubber_tool = false; + flush(mutated_frame); + } + else + { + if (waiting_for_rubber_tool) + { + flush(deferred_frame); + waiting_for_rubber_tool = false; + } + flush(current_frame); + } + current_frame.clear(); + } + } + return 0; +} |
