1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;
}
|