#include #include #include #include #include #include #include #include #include auto flush(std::vector & 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{}; auto deferred_frame = std::vector{}; 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{}; 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; }