@desklink/host 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +44 -0
  3. package/README.md +266 -0
  4. package/bin/desklink-host.mjs +113 -0
  5. package/dist/bridge.d.ts +57 -0
  6. package/dist/bridge.d.ts.map +1 -0
  7. package/dist/bridge.js +208 -0
  8. package/dist/bridge.js.map +1 -0
  9. package/dist/engineProcess.d.ts +82 -0
  10. package/dist/engineProcess.d.ts.map +1 -0
  11. package/dist/engineProcess.js +243 -0
  12. package/dist/engineProcess.js.map +1 -0
  13. package/dist/index.d.ts +12 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +12 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/protocol.d.ts +169 -0
  18. package/dist/protocol.d.ts.map +1 -0
  19. package/dist/protocol.js +18 -0
  20. package/dist/protocol.js.map +1 -0
  21. package/dist/resolveEngine.d.ts +34 -0
  22. package/dist/resolveEngine.d.ts.map +1 -0
  23. package/dist/resolveEngine.js +103 -0
  24. package/dist/resolveEngine.js.map +1 -0
  25. package/docs/BOUNDARY.md +145 -0
  26. package/docs/PROTOCOL.md +363 -0
  27. package/engine/Cargo.lock +3077 -0
  28. package/engine/Cargo.toml +37 -0
  29. package/engine/build.rs +107 -0
  30. package/engine/native/inputtino_shim.cpp +11 -0
  31. package/engine/native/vpx_shim.c +184 -0
  32. package/engine/native/wrapper.h +7 -0
  33. package/engine/src/capture.rs +510 -0
  34. package/engine/src/clipboard.rs +132 -0
  35. package/engine/src/convert.rs +299 -0
  36. package/engine/src/encoder.rs +204 -0
  37. package/engine/src/input.rs +355 -0
  38. package/engine/src/keymap.rs +338 -0
  39. package/engine/src/main.rs +614 -0
  40. package/engine/src/peer.rs +775 -0
  41. package/engine/src/portal.rs +115 -0
  42. package/engine/src/protocol.rs +331 -0
  43. package/engine/src/session.rs +2159 -0
  44. package/engine/src/x11.rs +244 -0
  45. package/engine/vendor/inputtino/.clang-format +166 -0
  46. package/engine/vendor/inputtino/.clang-tidy +30 -0
  47. package/engine/vendor/inputtino/.dockerignore +11 -0
  48. package/engine/vendor/inputtino/.github/workflows/mirror-repo.yml +14 -0
  49. package/engine/vendor/inputtino/.github/workflows/python-lint-format-test-typecheck.yml +124 -0
  50. package/engine/vendor/inputtino/.github/workflows/python-test-install.yaml +49 -0
  51. package/engine/vendor/inputtino/.github/workflows/rust.yml +40 -0
  52. package/engine/vendor/inputtino/CMakeLists.txt +187 -0
  53. package/engine/vendor/inputtino/LICENSE +21 -0
  54. package/engine/vendor/inputtino/README.md +110 -0
  55. package/engine/vendor/inputtino/bindings/python/.devcontainer/Dockerfile +23 -0
  56. package/engine/vendor/inputtino/bindings/python/.devcontainer/devcontainer.json +28 -0
  57. package/engine/vendor/inputtino/bindings/python/.python-version +1 -0
  58. package/engine/vendor/inputtino/bindings/python/CMakeLists.txt +23 -0
  59. package/engine/vendor/inputtino/bindings/python/CPPLINT.cfg +2 -0
  60. package/engine/vendor/inputtino/bindings/python/Makefile +49 -0
  61. package/engine/vendor/inputtino/bindings/python/README.md +215 -0
  62. package/engine/vendor/inputtino/bindings/python/pyproject.toml +178 -0
  63. package/engine/vendor/inputtino/bindings/python/src/inputtino/__init__.py +43 -0
  64. package/engine/vendor/inputtino/bindings/python/src/inputtino/_core.pyi +533 -0
  65. package/engine/vendor/inputtino/bindings/python/src/inputtino/base.py +63 -0
  66. package/engine/vendor/inputtino/bindings/python/src/inputtino/joypad.py +248 -0
  67. package/engine/vendor/inputtino/bindings/python/src/inputtino/keyboard.py +256 -0
  68. package/engine/vendor/inputtino/bindings/python/src/inputtino/mouse.py +106 -0
  69. package/engine/vendor/inputtino/bindings/python/src/inputtino/pentablet.py +73 -0
  70. package/engine/vendor/inputtino/bindings/python/src/inputtino/py.typed +0 -0
  71. package/engine/vendor/inputtino/bindings/python/src/inputtino/touchscreen.py +61 -0
  72. package/engine/vendor/inputtino/bindings/python/src/inputtino/trackpad.py +74 -0
  73. package/engine/vendor/inputtino/bindings/python/src/main.cpp +217 -0
  74. package/engine/vendor/inputtino/bindings/python/tests/__init__.py +0 -0
  75. package/engine/vendor/inputtino/bindings/python/tests/helpers.py +3 -0
  76. package/engine/vendor/inputtino/bindings/python/tests/test_base.py +60 -0
  77. package/engine/vendor/inputtino/bindings/python/tests/test_inputtino.py +5 -0
  78. package/engine/vendor/inputtino/bindings/python/tests/test_joypad.py +332 -0
  79. package/engine/vendor/inputtino/bindings/python/tests/test_keyboard.py +164 -0
  80. package/engine/vendor/inputtino/bindings/python/tests/test_mouse.py +185 -0
  81. package/engine/vendor/inputtino/bindings/python/tests/test_pentablet.py +198 -0
  82. package/engine/vendor/inputtino/bindings/python/tests/test_touchscreen.py +144 -0
  83. package/engine/vendor/inputtino/bindings/python/tests/test_trackpad.py +146 -0
  84. package/engine/vendor/inputtino/bindings/python/uv.lock +390 -0
  85. package/engine/vendor/inputtino/bindings/rust/Cargo.toml +6 -0
  86. package/engine/vendor/inputtino/bindings/rust/inputtino/.dockerignore +1 -0
  87. package/engine/vendor/inputtino/bindings/rust/inputtino/Cargo.toml +18 -0
  88. package/engine/vendor/inputtino/bindings/rust/inputtino/examples/keyboard.rs +33 -0
  89. package/engine/vendor/inputtino/bindings/rust/inputtino/examples/mouse.rs +17 -0
  90. package/engine/vendor/inputtino/bindings/rust/inputtino/src/common.rs +116 -0
  91. package/engine/vendor/inputtino/bindings/rust/inputtino/src/error.rs +17 -0
  92. package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad.rs +74 -0
  93. package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad_nintendo.rs +135 -0
  94. package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad_ps5.rs +280 -0
  95. package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad_xbox.rs +134 -0
  96. package/engine/vendor/inputtino/bindings/rust/inputtino/src/keyboard.rs +76 -0
  97. package/engine/vendor/inputtino/bindings/rust/inputtino/src/lib.rs +32 -0
  98. package/engine/vendor/inputtino/bindings/rust/inputtino/src/mouse.rs +178 -0
  99. package/engine/vendor/inputtino/bindings/rust/inputtino/tests/common.rs +38 -0
  100. package/engine/vendor/inputtino/bindings/rust/inputtino/tests/joypads.rs +150 -0
  101. package/engine/vendor/inputtino/bindings/rust/inputtino/tests/keyboard.rs +73 -0
  102. package/engine/vendor/inputtino/bindings/rust/inputtino/tests/mouse.rs +139 -0
  103. package/engine/vendor/inputtino/bindings/rust/inputtino-sys/.dockerignore +1 -0
  104. package/engine/vendor/inputtino/bindings/rust/inputtino-sys/Cargo.toml +12 -0
  105. package/engine/vendor/inputtino/bindings/rust/inputtino-sys/build.rs +48 -0
  106. package/engine/vendor/inputtino/bindings/rust/inputtino-sys/src/lib.rs +5 -0
  107. package/engine/vendor/inputtino/bindings/rust/inputtino-sys/wrapper.h +1 -0
  108. package/engine/vendor/inputtino/cmake/utils.cmake +9 -0
  109. package/engine/vendor/inputtino/docker/Dockerfile +70 -0
  110. package/engine/vendor/inputtino/include/inputtino/input.h +324 -0
  111. package/engine/vendor/inputtino/include/inputtino/input.hpp +466 -0
  112. package/engine/vendor/inputtino/include/inputtino/result.hpp +37 -0
  113. package/engine/vendor/inputtino/share/pkgconfig/libinputtino.pc.in +17 -0
  114. package/engine/vendor/inputtino/src/c-bindings/helpers.hpp +19 -0
  115. package/engine/vendor/inputtino/src/c-bindings/joypad_ps5.cpp +115 -0
  116. package/engine/vendor/inputtino/src/c-bindings/joypad_switch.cpp +63 -0
  117. package/engine/vendor/inputtino/src/c-bindings/joypad_xone.cpp +62 -0
  118. package/engine/vendor/inputtino/src/c-bindings/keyboard.cpp +42 -0
  119. package/engine/vendor/inputtino/src/c-bindings/mouse.cpp +67 -0
  120. package/engine/vendor/inputtino/src/c-bindings/pen_tablet.cpp +50 -0
  121. package/engine/vendor/inputtino/src/c-bindings/touchscreen.cpp +43 -0
  122. package/engine/vendor/inputtino/src/c-bindings/trackpad.cpp +49 -0
  123. package/engine/vendor/inputtino/src/uhid/README.adoc +63 -0
  124. package/engine/vendor/inputtino/src/uhid/include/crc32.hpp +38 -0
  125. package/engine/vendor/inputtino/src/uhid/include/uhid/protected_types.hpp +36 -0
  126. package/engine/vendor/inputtino/src/uhid/include/uhid/ps5.hpp +550 -0
  127. package/engine/vendor/inputtino/src/uhid/include/uhid/uhid.hpp +168 -0
  128. package/engine/vendor/inputtino/src/uhid/joypad_ps5.cpp +580 -0
  129. package/engine/vendor/inputtino/src/uinput/include/inputtino/keyboard.hpp +84 -0
  130. package/engine/vendor/inputtino/src/uinput/include/inputtino/protected_ps5_types.hpp +7 -0
  131. package/engine/vendor/inputtino/src/uinput/include/inputtino/protected_types.hpp +110 -0
  132. package/engine/vendor/inputtino/src/uinput/joypad_nintendo.cpp +190 -0
  133. package/engine/vendor/inputtino/src/uinput/joypad_ps.cpp +203 -0
  134. package/engine/vendor/inputtino/src/uinput/joypad_utils.hpp +246 -0
  135. package/engine/vendor/inputtino/src/uinput/joypad_xbox.cpp +190 -0
  136. package/engine/vendor/inputtino/src/uinput/keyboard.cpp +120 -0
  137. package/engine/vendor/inputtino/src/uinput/mouse.cpp +199 -0
  138. package/engine/vendor/inputtino/src/uinput/pentablet.cpp +162 -0
  139. package/engine/vendor/inputtino/src/uinput/touchscreen.cpp +140 -0
  140. package/engine/vendor/inputtino/src/uinput/trackpad.cpp +192 -0
  141. package/examples/reference-client.html +428 -0
  142. package/package.json +38 -0
@@ -0,0 +1,199 @@
1
+ #include "inputtino/input.hpp"
2
+ #include <cmath>
3
+ #include <inputtino/protected_types.hpp>
4
+ #include <string.h>
5
+
6
+ namespace inputtino {
7
+
8
+ std::vector<std::string> Mouse::get_nodes() const {
9
+ std::vector<std::string> nodes;
10
+
11
+ if (auto mouse = _state->mouse_rel.get()) {
12
+ nodes.emplace_back(libevdev_uinput_get_devnode(mouse));
13
+ }
14
+
15
+ if (auto mouse = _state->mouse_abs.get()) {
16
+ nodes.emplace_back(libevdev_uinput_get_devnode(mouse));
17
+ }
18
+
19
+ return nodes;
20
+ }
21
+
22
+ constexpr int ABS_MAX_WIDTH = 19200;
23
+ constexpr int ABS_MAX_HEIGHT = 12000;
24
+
25
+ static Result<libevdev_uinput_ptr> create_mouse(const DeviceDefinition &device) {
26
+ libevdev *dev = libevdev_new();
27
+ libevdev_uinput *uidev;
28
+
29
+ libevdev_set_name(dev, device.name.c_str());
30
+ libevdev_set_id_vendor(dev, device.vendor_id);
31
+ libevdev_set_id_product(dev, device.product_id);
32
+ libevdev_set_id_version(dev, device.version);
33
+ libevdev_set_id_bustype(dev, BUS_USB);
34
+
35
+ libevdev_enable_event_type(dev, EV_KEY);
36
+ libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, nullptr);
37
+ libevdev_enable_event_code(dev, EV_KEY, BTN_RIGHT, nullptr);
38
+ libevdev_enable_event_code(dev, EV_KEY, BTN_MIDDLE, nullptr);
39
+ libevdev_enable_event_code(dev, EV_KEY, BTN_SIDE, nullptr);
40
+ libevdev_enable_event_code(dev, EV_KEY, BTN_EXTRA, nullptr);
41
+ libevdev_enable_event_code(dev, EV_KEY, BTN_FORWARD, nullptr);
42
+ libevdev_enable_event_code(dev, EV_KEY, BTN_BACK, nullptr);
43
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TASK, nullptr);
44
+
45
+ libevdev_enable_event_type(dev, EV_REL);
46
+ libevdev_enable_event_code(dev, EV_REL, REL_X, nullptr);
47
+ libevdev_enable_event_code(dev, EV_REL, REL_Y, nullptr);
48
+
49
+ libevdev_enable_event_code(dev, EV_REL, REL_WHEEL, nullptr);
50
+ libevdev_enable_event_code(dev, EV_REL, REL_WHEEL_HI_RES, nullptr);
51
+ libevdev_enable_event_code(dev, EV_REL, REL_HWHEEL, nullptr);
52
+ libevdev_enable_event_code(dev, EV_REL, REL_HWHEEL_HI_RES, nullptr);
53
+
54
+ libevdev_enable_event_type(dev, EV_MSC);
55
+ libevdev_enable_event_code(dev, EV_MSC, MSC_SCAN, nullptr);
56
+
57
+ auto err = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
58
+ libevdev_free(dev);
59
+ if (err != 0) {
60
+ return Error(strerror(-err));
61
+ }
62
+
63
+ return libevdev_uinput_ptr{uidev, ::libevdev_uinput_destroy};
64
+ }
65
+
66
+ static Result<libevdev_uinput_ptr> create_mouse_abs(const DeviceDefinition &device) {
67
+ libevdev *dev = libevdev_new();
68
+ libevdev_uinput *uidev;
69
+
70
+ libevdev_set_name(dev, (device.name + " (absolute)").c_str());
71
+ libevdev_set_id_vendor(dev, device.vendor_id);
72
+ libevdev_set_id_product(dev, device.product_id);
73
+ libevdev_set_id_version(dev, device.version);
74
+ libevdev_set_id_bustype(dev, BUS_USB);
75
+
76
+ libevdev_enable_property(dev, INPUT_PROP_DIRECT);
77
+ libevdev_enable_event_type(dev, EV_KEY);
78
+ libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, nullptr);
79
+
80
+ struct input_absinfo absinfo {
81
+ .value = 0, .minimum = 0, .maximum = 0, .fuzz = 1, .flat = 0, .resolution = 28
82
+ };
83
+ libevdev_enable_event_type(dev, EV_ABS);
84
+
85
+ absinfo.maximum = ABS_MAX_WIDTH;
86
+ libevdev_enable_event_code(dev, EV_ABS, ABS_X, &absinfo);
87
+ absinfo.maximum = ABS_MAX_HEIGHT;
88
+ libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &absinfo);
89
+
90
+ auto err = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
91
+ libevdev_free(dev);
92
+ if (err != 0) {
93
+ return Error(strerror(-err));
94
+ }
95
+
96
+ return libevdev_uinput_ptr{uidev, ::libevdev_uinput_destroy};
97
+ }
98
+
99
+ Mouse::Mouse() : _state(std::make_shared<MouseState>()) {}
100
+
101
+ Mouse::~Mouse() {
102
+ if (_state) {
103
+ _state.reset();
104
+ }
105
+ }
106
+
107
+ Result<Mouse> Mouse::create(const DeviceDefinition &device) {
108
+ auto mouse = Mouse();
109
+
110
+ auto mouse_rel_or_error = create_mouse(device);
111
+ if (mouse_rel_or_error) {
112
+ mouse._state->mouse_rel = std::move(*mouse_rel_or_error);
113
+ } else {
114
+ return Error(mouse_rel_or_error.getErrorMessage());
115
+ }
116
+
117
+ auto mouse_abs_or_error = create_mouse_abs(device);
118
+ if (mouse_abs_or_error) {
119
+ mouse._state->mouse_abs = std::move(*mouse_abs_or_error);
120
+ } else {
121
+ return Error(mouse_abs_or_error.getErrorMessage());
122
+ }
123
+
124
+ return std::move(mouse);
125
+ }
126
+
127
+ void Mouse::move(int delta_x, int delta_y) {
128
+ if (auto mouse = _state->mouse_rel.get()) {
129
+ libevdev_uinput_write_event(mouse, EV_REL, REL_X, delta_x);
130
+ libevdev_uinput_write_event(mouse, EV_REL, REL_Y, delta_y);
131
+ libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
132
+ }
133
+ }
134
+
135
+ void Mouse::move_abs(int x, int y, int screen_width, int screen_height) {
136
+ int scaled_x = (int)std::lround((ABS_MAX_WIDTH / (double)screen_width) * x);
137
+ int scaled_y = (int)std::lround((ABS_MAX_HEIGHT / (double)screen_height) * y);
138
+
139
+ if (auto mouse = _state->mouse_abs.get()) {
140
+ libevdev_uinput_write_event(mouse, EV_ABS, ABS_X, scaled_x);
141
+ libevdev_uinput_write_event(mouse, EV_ABS, ABS_Y, scaled_y);
142
+ libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
143
+ }
144
+ }
145
+
146
+ static std::pair<int, int> btn_to_uinput(Mouse::MOUSE_BUTTON button) {
147
+ switch (button) {
148
+ case Mouse::LEFT:
149
+ return {BTN_LEFT, 90001};
150
+ case Mouse::MIDDLE:
151
+ return {BTN_MIDDLE, 90003};
152
+ case Mouse::RIGHT:
153
+ return {BTN_RIGHT, 90002};
154
+ case Mouse::SIDE:
155
+ return {BTN_SIDE, 90004};
156
+ default:
157
+ return {BTN_EXTRA, 90005};
158
+ }
159
+ }
160
+
161
+ void Mouse::press(Mouse::MOUSE_BUTTON button) {
162
+ if (auto mouse = _state->mouse_rel.get()) {
163
+ auto [btn_type, scan_code] = btn_to_uinput(button);
164
+ libevdev_uinput_write_event(mouse, EV_MSC, MSC_SCAN, scan_code);
165
+ libevdev_uinput_write_event(mouse, EV_KEY, btn_type, 1);
166
+ libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
167
+ }
168
+ }
169
+
170
+ void Mouse::release(Mouse::MOUSE_BUTTON button) {
171
+ if (auto mouse = _state->mouse_rel.get()) {
172
+ auto [btn_type, scan_code] = btn_to_uinput(button);
173
+ libevdev_uinput_write_event(mouse, EV_MSC, MSC_SCAN, scan_code);
174
+ libevdev_uinput_write_event(mouse, EV_KEY, btn_type, 0);
175
+ libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
176
+ }
177
+ }
178
+
179
+ void Mouse::horizontal_scroll(int high_res_distance) {
180
+ int distance = high_res_distance / 120;
181
+
182
+ if (auto mouse = _state->mouse_rel.get()) {
183
+ libevdev_uinput_write_event(mouse, EV_REL, REL_HWHEEL, distance);
184
+ libevdev_uinput_write_event(mouse, EV_REL, REL_HWHEEL_HI_RES, high_res_distance);
185
+ libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
186
+ }
187
+ }
188
+
189
+ void Mouse::vertical_scroll(int high_res_distance) {
190
+ int distance = high_res_distance / 120;
191
+
192
+ if (auto mouse = _state->mouse_rel.get()) {
193
+ libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL, distance);
194
+ libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL_HI_RES, high_res_distance);
195
+ libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
196
+ }
197
+ }
198
+
199
+ } // namespace inputtino
@@ -0,0 +1,162 @@
1
+ #include "inputtino/input.hpp"
2
+ #include <algorithm>
3
+ #include <cmath>
4
+ #include <cstring>
5
+ #include <inputtino/protected_types.hpp>
6
+
7
+ namespace inputtino {
8
+
9
+ static const std::map<int, int> tool_to_linux = {
10
+ {PenTablet::PEN, BTN_TOOL_PEN},
11
+ {PenTablet::ERASER, BTN_TOOL_RUBBER},
12
+ {PenTablet::BRUSH, BTN_TOOL_BRUSH},
13
+ {PenTablet::PENCIL, BTN_TOOL_PENCIL},
14
+ {PenTablet::AIRBRUSH, BTN_TOOL_AIRBRUSH},
15
+ {PenTablet::TOUCH, BTN_TOUCH},
16
+ };
17
+
18
+ static const std::map<int, int> btn_to_linux = {
19
+ {PenTablet::PRIMARY, BTN_STYLUS},
20
+ {PenTablet::SECONDARY, BTN_STYLUS2},
21
+ {PenTablet::TERTIARY, BTN_STYLUS3},
22
+ };
23
+
24
+ static constexpr int MAX_X = 19200;
25
+ static constexpr int MAX_Y = 10800;
26
+ static constexpr int PRESSURE_MAX = 4096;
27
+ static constexpr int DISTANCE_MAX = 1024;
28
+ static constexpr int RESOLUTION = 28;
29
+
30
+ Result<libevdev_uinput_ptr> create_tablet(const DeviceDefinition &device) {
31
+ libevdev *dev = libevdev_new();
32
+ libevdev_uinput *uidev;
33
+
34
+ libevdev_set_name(dev, device.name.c_str());
35
+ libevdev_set_id_vendor(dev, device.vendor_id);
36
+ libevdev_set_id_product(dev, device.product_id);
37
+ libevdev_set_id_version(dev, device.version);
38
+ libevdev_set_id_bustype(dev, BUS_USB);
39
+
40
+ libevdev_enable_event_type(dev, EV_KEY);
41
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOUCH, nullptr);
42
+ libevdev_enable_event_code(dev, EV_KEY, BTN_STYLUS, nullptr);
43
+ libevdev_enable_event_code(dev, EV_KEY, BTN_STYLUS2, nullptr);
44
+ libevdev_enable_event_code(dev, EV_KEY, BTN_STYLUS3, nullptr);
45
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_PEN, nullptr);
46
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_RUBBER, nullptr);
47
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_BRUSH, nullptr);
48
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_PENCIL, nullptr);
49
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_AIRBRUSH, nullptr);
50
+
51
+ libevdev_enable_event_type(dev, EV_ABS);
52
+ input_absinfo abs_x{0, 0, MAX_X, 1, 0, RESOLUTION};
53
+ libevdev_enable_event_code(dev, EV_ABS, ABS_X, &abs_x);
54
+
55
+ input_absinfo abs_y{0, 0, MAX_Y, 1, 0, RESOLUTION};
56
+ libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &abs_y);
57
+
58
+ input_absinfo pressure{0, 0, PRESSURE_MAX, 0, 0, 0};
59
+ libevdev_enable_event_code(dev, EV_ABS, ABS_PRESSURE, &pressure);
60
+
61
+ input_absinfo distance{0, 0, DISTANCE_MAX, 0, 0, 0};
62
+ libevdev_enable_event_code(dev, EV_ABS, ABS_DISTANCE, &distance);
63
+ input_absinfo abs_tilt{0, -90, 90, 0, 0, RESOLUTION}; // If resolution is nonzero, it's in units/radian.
64
+ libevdev_enable_event_code(dev, EV_ABS, ABS_TILT_X, &abs_tilt);
65
+ libevdev_enable_event_code(dev, EV_ABS, ABS_TILT_Y, &abs_tilt);
66
+
67
+ // https://docs.kernel.org/input/event-codes.html#tablets
68
+ libevdev_enable_property(dev, INPUT_PROP_POINTER);
69
+ libevdev_enable_property(dev, INPUT_PROP_DIRECT);
70
+ auto err = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
71
+ libevdev_free(dev);
72
+ if (err != 0) {
73
+ return Error(strerror(-err));
74
+ }
75
+
76
+ return libevdev_uinput_ptr{uidev, ::libevdev_uinput_destroy};
77
+ }
78
+
79
+ PenTablet::PenTablet() : _state(std::make_shared<PenTabletState>()) {}
80
+
81
+ PenTablet::~PenTablet() {
82
+ if (_state) {
83
+ _state.reset();
84
+ }
85
+ }
86
+
87
+ Result<PenTablet> PenTablet::create(const DeviceDefinition &device) {
88
+ auto tablet = create_tablet(device);
89
+ if (tablet) {
90
+ PenTablet pt;
91
+ pt._state->pen_tablet = std::move(*tablet);
92
+ return std::move(pt);
93
+ } else {
94
+ return Error(tablet.getErrorMessage());
95
+ }
96
+ }
97
+
98
+ std::vector<std::string> PenTablet::get_nodes() const {
99
+ std::vector<std::string> nodes;
100
+
101
+ if (auto kb = _state->pen_tablet.get()) {
102
+ nodes.emplace_back(libevdev_uinput_get_devnode(kb));
103
+ }
104
+
105
+ return nodes;
106
+ }
107
+
108
+ static inline float deg2rad(float degree) {
109
+ return M_PI * degree / 180.0;
110
+ }
111
+
112
+ void PenTablet::place_tool(
113
+ PenTablet::TOOL_TYPE tool_type, float x, float y, float pressure, float distance, float tilt_x, float tilt_y) {
114
+ if (auto tablet = _state->pen_tablet.get()) {
115
+ if (tool_type != PenTablet::SAME_AS_BEFORE && tool_type != _state->last_tool) {
116
+ libevdev_uinput_write_event(tablet, EV_KEY, tool_to_linux.at(tool_type), 1);
117
+
118
+ if (_state->last_tool != PenTablet::SAME_AS_BEFORE)
119
+ libevdev_uinput_write_event(tablet, EV_KEY, tool_to_linux.at(_state->last_tool), 0);
120
+
121
+ _state->last_tool = tool_type;
122
+ }
123
+
124
+ int scaled_x = (int)std::lround(MAX_X * x);
125
+ int scaled_y = (int)std::lround(MAX_Y * y);
126
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_X, scaled_x);
127
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_Y, scaled_y);
128
+
129
+ if (pressure >= 0) {
130
+ int scaled_pressure = (int)std::lround(pressure * PRESSURE_MAX);
131
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_PRESSURE, scaled_pressure);
132
+ // when there's pressure, the tool must be touching the tablet
133
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_DISTANCE, 0);
134
+ }
135
+
136
+ if (distance >= 0) {
137
+ int scaled_distance = (int)std::lround(distance * DISTANCE_MAX);
138
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_DISTANCE, scaled_distance);
139
+ // when there's distance, the tool can't be touching the tablet
140
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_PRESSURE, 0);
141
+ }
142
+
143
+ auto scaled_tilt_x = std::clamp(tilt_x, -90.0f, 90.0f);
144
+ scaled_tilt_x = deg2rad(scaled_tilt_x * RESOLUTION);
145
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_TILT_X, (int)std::lround(scaled_tilt_x));
146
+
147
+ auto scaled_tilt_y = std::clamp(tilt_y, -90.0f, 90.0f);
148
+ scaled_tilt_y = deg2rad(scaled_tilt_y * RESOLUTION);
149
+ libevdev_uinput_write_event(tablet, EV_ABS, ABS_TILT_Y, (int)std::lround(scaled_tilt_y));
150
+
151
+ libevdev_uinput_write_event(tablet, EV_SYN, SYN_REPORT, 0);
152
+ }
153
+ }
154
+
155
+ void PenTablet::set_btn(PenTablet::BTN_TYPE btn, bool pressed) {
156
+ if (auto tablet = _state->pen_tablet.get()) {
157
+ libevdev_uinput_write_event(tablet, EV_KEY, btn_to_linux.at(btn), pressed ? 1 : 0);
158
+ libevdev_uinput_write_event(tablet, EV_SYN, SYN_REPORT, 0);
159
+ }
160
+ }
161
+
162
+ } // namespace inputtino
@@ -0,0 +1,140 @@
1
+ #include "inputtino/input.hpp"
2
+ #include <algorithm>
3
+ #include <cmath>
4
+ #include <cstring>
5
+ #include <inputtino/protected_types.hpp>
6
+
7
+ namespace inputtino {
8
+
9
+ std::vector<std::string> TouchScreen::get_nodes() const {
10
+ std::vector<std::string> nodes;
11
+
12
+ if (auto kb = _state->touch_screen.get()) {
13
+ nodes.emplace_back(libevdev_uinput_get_devnode(kb));
14
+ }
15
+
16
+ return nodes;
17
+ }
18
+
19
+ static constexpr int TOUCH_MAX_X = 19200;
20
+ static constexpr int TOUCH_MAX_Y = 10800;
21
+ static constexpr int NUM_FINGERS = 16;
22
+ static constexpr int PRESSURE_MAX = 253;
23
+
24
+ Result<libevdev_uinput_ptr> create_touch_screen(const DeviceDefinition &device) {
25
+ libevdev *dev = libevdev_new();
26
+ libevdev_uinput *uidev;
27
+
28
+ libevdev_set_name(dev, device.name.c_str());
29
+ libevdev_set_id_vendor(dev, device.vendor_id);
30
+ libevdev_set_id_product(dev, device.product_id);
31
+ libevdev_set_id_version(dev, device.version);
32
+ libevdev_set_id_bustype(dev, BUS_USB);
33
+
34
+ libevdev_enable_event_type(dev, EV_KEY);
35
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOUCH, nullptr);
36
+
37
+ libevdev_enable_event_type(dev, EV_ABS);
38
+ input_absinfo mt_slot{0, 0, NUM_FINGERS - 1, 0, 0, 0};
39
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_SLOT, &mt_slot);
40
+
41
+ input_absinfo abs_x{0, 0, TOUCH_MAX_X, 0, 0, 0};
42
+ libevdev_enable_event_code(dev, EV_ABS, ABS_X, &abs_x);
43
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_POSITION_X, &abs_x);
44
+
45
+ input_absinfo abs_y{0, 0, TOUCH_MAX_Y, 0, 0, 0};
46
+ libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &abs_y);
47
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_POSITION_Y, &abs_y);
48
+
49
+ input_absinfo tracking{0, 0, 65535, 0, 0, 0};
50
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TRACKING_ID, &tracking);
51
+
52
+ input_absinfo abs_pressure{0, 0, PRESSURE_MAX, 0, 0, 0};
53
+ libevdev_enable_event_code(dev, EV_ABS, ABS_PRESSURE, &abs_pressure);
54
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_PRESSURE, &abs_pressure);
55
+ // TODO:
56
+ // input_absinfo touch{0, 0, TOUCH_MAX, 4, 0, 0};
57
+ // libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TOUCH_MAJOR, &touch);
58
+ // libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TOUCH_MINOR, &touch);
59
+ input_absinfo orientation{0, -90, 90, 0, 0, 0};
60
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_ORIENTATION, &orientation);
61
+
62
+ // https://docs.kernel.org/input/event-codes.html#touchscreens
63
+ libevdev_enable_property(dev, INPUT_PROP_DIRECT);
64
+
65
+ auto err = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
66
+ libevdev_free(dev);
67
+ if (err != 0) {
68
+ return Error(strerror(-err));
69
+ }
70
+
71
+ return libevdev_uinput_ptr{uidev, ::libevdev_uinput_destroy};
72
+ }
73
+
74
+ TouchScreen::TouchScreen() : _state(std::make_shared<TouchScreenState>()) {}
75
+
76
+ TouchScreen::~TouchScreen() {
77
+ if (_state) {
78
+ _state.reset();
79
+ }
80
+ }
81
+
82
+ Result<TouchScreen> TouchScreen::create(const DeviceDefinition &device) {
83
+ auto touch_screen = create_touch_screen(device);
84
+ if (touch_screen) {
85
+ TouchScreen ts;
86
+ ts._state->touch_screen = std::move(*touch_screen);
87
+ return ts;
88
+ } else {
89
+ return Error(touch_screen.getErrorMessage());
90
+ }
91
+ }
92
+
93
+ void TouchScreen::place_finger(int finger_nr, float x, float y, float pressure, int orientation) {
94
+ if (auto ts = this->_state->touch_screen.get()) {
95
+ int scaled_x = (int)std::lround(TOUCH_MAX_X * x);
96
+ int scaled_y = (int)std::lround(TOUCH_MAX_Y * y);
97
+ int scaled_orientation = std::clamp(orientation, -90, 90);
98
+
99
+ if (_state->fingers.find(finger_nr) == _state->fingers.end()) {
100
+ // Wow, a wild finger appeared!
101
+ auto finger_slot = _state->fingers.size() + 1;
102
+ _state->fingers[finger_nr] = finger_slot;
103
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_SLOT, finger_slot);
104
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_TRACKING_ID, finger_slot);
105
+ } else {
106
+ // I already know this finger, let's check the slot
107
+ auto finger_slot = _state->fingers[finger_nr];
108
+ if (_state->current_slot != finger_slot) {
109
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_SLOT, finger_slot);
110
+ _state->current_slot = finger_slot;
111
+ }
112
+ }
113
+
114
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_X, scaled_x);
115
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_POSITION_X, scaled_x);
116
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_Y, scaled_y);
117
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_POSITION_Y, scaled_y);
118
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
119
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
120
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_ORIENTATION, scaled_orientation);
121
+
122
+ libevdev_uinput_write_event(ts, EV_SYN, SYN_REPORT, 0);
123
+ }
124
+ }
125
+
126
+ void TouchScreen::release_finger(int finger_nr) {
127
+ if (auto ts = this->_state->touch_screen.get()) {
128
+ auto finger_slot = _state->fingers[finger_nr];
129
+ if (_state->current_slot != finger_slot) {
130
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_SLOT, finger_slot);
131
+ _state->current_slot = -1;
132
+ }
133
+ _state->fingers.erase(finger_nr);
134
+ libevdev_uinput_write_event(ts, EV_ABS, ABS_MT_TRACKING_ID, -1);
135
+
136
+ libevdev_uinput_write_event(ts, EV_SYN, SYN_REPORT, 0);
137
+ }
138
+ }
139
+
140
+ } // namespace inputtino
@@ -0,0 +1,192 @@
1
+ #include "inputtino/input.hpp"
2
+ #include <algorithm>
3
+ #include <cmath>
4
+ #include <cstring>
5
+ #include <inputtino/protected_types.hpp>
6
+
7
+ namespace inputtino {
8
+
9
+ std::vector<std::string> Trackpad::get_nodes() const {
10
+ std::vector<std::string> nodes;
11
+
12
+ if (auto kb = _state->trackpad.get()) {
13
+ nodes.emplace_back(libevdev_uinput_get_devnode(kb));
14
+ }
15
+
16
+ return nodes;
17
+ }
18
+
19
+ static constexpr int TOUCH_MAX_X = 19200;
20
+ static constexpr int TOUCH_MAX_Y = 10800;
21
+ // static constexpr int TOUCH_MAX = 1020;
22
+ static constexpr int NUM_FINGERS = 16; // Apple's touchpads support 16 touches
23
+ static constexpr int PRESSURE_MAX = 253;
24
+
25
+ Result<libevdev_uinput_ptr> create_trackpad(const DeviceDefinition &device) {
26
+ libevdev *dev = libevdev_new();
27
+ libevdev_uinput *uidev;
28
+
29
+ libevdev_set_name(dev, device.name.c_str());
30
+ libevdev_set_id_vendor(dev, device.vendor_id);
31
+ libevdev_set_id_product(dev, device.product_id);
32
+ libevdev_set_id_version(dev, device.version);
33
+ libevdev_set_id_bustype(dev, BUS_USB);
34
+
35
+ libevdev_enable_event_type(dev, EV_KEY);
36
+ libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, nullptr);
37
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOUCH, nullptr);
38
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_FINGER, nullptr);
39
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_DOUBLETAP, nullptr);
40
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_TRIPLETAP, nullptr);
41
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_QUADTAP, nullptr);
42
+ libevdev_enable_event_code(dev, EV_KEY, BTN_TOOL_QUINTTAP, nullptr);
43
+
44
+ libevdev_enable_event_type(dev, EV_ABS);
45
+ input_absinfo mt_slot{0, 0, NUM_FINGERS - 1, 0, 0, 0};
46
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_SLOT, &mt_slot);
47
+
48
+ input_absinfo abs_x{0, 0, TOUCH_MAX_X, 0, 0, 0};
49
+ libevdev_enable_event_code(dev, EV_ABS, ABS_X, &abs_x);
50
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_POSITION_X, &abs_x);
51
+
52
+ input_absinfo abs_y{0, 0, TOUCH_MAX_Y, 0, 0, 0};
53
+ libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &abs_y);
54
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_POSITION_Y, &abs_y);
55
+
56
+ input_absinfo tracking{0, 0, 65535, 0, 0, 0};
57
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TRACKING_ID, &tracking);
58
+
59
+ input_absinfo abs_pressure{0, 0, PRESSURE_MAX, 0, 0, 0};
60
+ libevdev_enable_event_code(dev, EV_ABS, ABS_PRESSURE, &abs_pressure);
61
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_PRESSURE, &abs_pressure);
62
+ // TODO:
63
+ // input_absinfo touch{0, 0, TOUCH_MAX, 4, 0, 0};
64
+ // libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TOUCH_MAJOR, &touch);
65
+ // libevdev_enable_event_code(dev, EV_ABS, ABS_MT_TOUCH_MINOR, &touch);
66
+ input_absinfo orientation{0, -90, 90, 0, 0, 0};
67
+ libevdev_enable_event_code(dev, EV_ABS, ABS_MT_ORIENTATION, &orientation);
68
+
69
+ // https://docs.kernel.org/input/event-codes.html#trackpads
70
+ libevdev_enable_property(dev, INPUT_PROP_POINTER);
71
+ libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD);
72
+
73
+ auto err = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
74
+ libevdev_free(dev);
75
+ if (err != 0) {
76
+ return Error(strerror(-err));
77
+ }
78
+
79
+ return libevdev_uinput_ptr{uidev, ::libevdev_uinput_destroy};
80
+ }
81
+
82
+ Trackpad::Trackpad() : _state(std::make_shared<TrackpadState>()) {}
83
+ Trackpad::~Trackpad() {
84
+ if (_state) {
85
+ _state.reset();
86
+ }
87
+ }
88
+
89
+ Result<Trackpad> Trackpad::create(const DeviceDefinition &device) {
90
+ auto trackpad_el = create_trackpad(device);
91
+ if (trackpad_el) {
92
+ Trackpad trackpad;
93
+ trackpad._state->trackpad = std::move(*trackpad_el);
94
+ return std::move(trackpad);
95
+ } else {
96
+ return Error(trackpad_el.getErrorMessage());
97
+ }
98
+ }
99
+
100
+ void Trackpad::place_finger(int finger_nr, float x, float y, float pressure, int orientation) {
101
+ if (auto touchpad = this->_state->trackpad.get()) {
102
+ int scaled_x = (int)std::lround(TOUCH_MAX_X * x);
103
+ int scaled_y = (int)std::lround(TOUCH_MAX_Y * y);
104
+ int scaled_orientation = std::clamp(orientation, -90, 90);
105
+
106
+ if (_state->fingers.find(finger_nr) == _state->fingers.end()) {
107
+ // Wow, a wild finger appeared!
108
+ auto finger_slot = _state->fingers.size() + 1;
109
+ _state->fingers[finger_nr] = finger_slot;
110
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_SLOT, finger_slot);
111
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_TRACKING_ID, finger_slot);
112
+ auto nr_fingers = _state->fingers.size();
113
+ { // Update number of fingers pressed
114
+ if (nr_fingers == 1) {
115
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_FINGER, 1);
116
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOUCH, 1);
117
+ } else if (nr_fingers == 2) {
118
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_FINGER, 0);
119
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
120
+ } else if (nr_fingers == 3) {
121
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
122
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
123
+ } else if (nr_fingers == 4) {
124
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
125
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_QUADTAP, 1);
126
+ } else if (nr_fingers == 5) {
127
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_QUADTAP, 0);
128
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_QUINTTAP, 1);
129
+ }
130
+ }
131
+ } else {
132
+ // I already know this finger, let's check the slot
133
+ auto finger_slot = _state->fingers[finger_nr];
134
+ if (_state->current_slot != finger_slot) {
135
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_SLOT, finger_slot);
136
+ _state->current_slot = finger_slot;
137
+ }
138
+ }
139
+
140
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_X, scaled_x);
141
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_POSITION_X, scaled_x);
142
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_Y, scaled_y);
143
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_POSITION_Y, scaled_y);
144
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
145
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_PRESSURE, (int)std::lround(pressure * PRESSURE_MAX));
146
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_ORIENTATION, scaled_orientation);
147
+
148
+ libevdev_uinput_write_event(touchpad, EV_SYN, SYN_REPORT, 0);
149
+ }
150
+ }
151
+
152
+ void Trackpad::release_finger(int finger_nr) {
153
+ if (auto touchpad = this->_state->trackpad.get()) {
154
+ auto finger_slot = _state->fingers[finger_nr];
155
+ if (_state->current_slot != finger_slot) {
156
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_SLOT, finger_slot);
157
+ _state->current_slot = -1;
158
+ }
159
+ _state->fingers.erase(finger_nr);
160
+ libevdev_uinput_write_event(touchpad, EV_ABS, ABS_MT_TRACKING_ID, -1);
161
+ auto nr_fingers = _state->fingers.size();
162
+ { // Update number of fingers pressed
163
+ if (nr_fingers == 0) {
164
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_FINGER, 0);
165
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOUCH, 0);
166
+ } else if (nr_fingers == 1) {
167
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_FINGER, 1);
168
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
169
+ } else if (nr_fingers == 2) {
170
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
171
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
172
+ } else if (nr_fingers == 3) {
173
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
174
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_QUADTAP, 0);
175
+ } else if (nr_fingers == 4) {
176
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_QUADTAP, 1);
177
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_TOOL_QUINTTAP, 0);
178
+ }
179
+ }
180
+
181
+ libevdev_uinput_write_event(touchpad, EV_SYN, SYN_REPORT, 0);
182
+ }
183
+ }
184
+
185
+ void Trackpad::set_left_btn(bool pressed) {
186
+ if (auto touchpad = this->_state->trackpad.get()) {
187
+ libevdev_uinput_write_event(touchpad, EV_KEY, BTN_LEFT, pressed ? 1 : 0);
188
+ libevdev_uinput_write_event(touchpad, EV_SYN, SYN_REPORT, 0);
189
+ }
190
+ }
191
+
192
+ } // namespace inputtino