@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.
- package/LICENSE +202 -0
- package/NOTICE +44 -0
- package/README.md +266 -0
- package/bin/desklink-host.mjs +113 -0
- package/dist/bridge.d.ts +57 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +208 -0
- package/dist/bridge.js.map +1 -0
- package/dist/engineProcess.d.ts +82 -0
- package/dist/engineProcess.d.ts.map +1 -0
- package/dist/engineProcess.js +243 -0
- package/dist/engineProcess.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +169 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +18 -0
- package/dist/protocol.js.map +1 -0
- package/dist/resolveEngine.d.ts +34 -0
- package/dist/resolveEngine.d.ts.map +1 -0
- package/dist/resolveEngine.js +103 -0
- package/dist/resolveEngine.js.map +1 -0
- package/docs/BOUNDARY.md +145 -0
- package/docs/PROTOCOL.md +363 -0
- package/engine/Cargo.lock +3077 -0
- package/engine/Cargo.toml +37 -0
- package/engine/build.rs +107 -0
- package/engine/native/inputtino_shim.cpp +11 -0
- package/engine/native/vpx_shim.c +184 -0
- package/engine/native/wrapper.h +7 -0
- package/engine/src/capture.rs +510 -0
- package/engine/src/clipboard.rs +132 -0
- package/engine/src/convert.rs +299 -0
- package/engine/src/encoder.rs +204 -0
- package/engine/src/input.rs +355 -0
- package/engine/src/keymap.rs +338 -0
- package/engine/src/main.rs +614 -0
- package/engine/src/peer.rs +775 -0
- package/engine/src/portal.rs +115 -0
- package/engine/src/protocol.rs +331 -0
- package/engine/src/session.rs +2159 -0
- package/engine/src/x11.rs +244 -0
- package/engine/vendor/inputtino/.clang-format +166 -0
- package/engine/vendor/inputtino/.clang-tidy +30 -0
- package/engine/vendor/inputtino/.dockerignore +11 -0
- package/engine/vendor/inputtino/.github/workflows/mirror-repo.yml +14 -0
- package/engine/vendor/inputtino/.github/workflows/python-lint-format-test-typecheck.yml +124 -0
- package/engine/vendor/inputtino/.github/workflows/python-test-install.yaml +49 -0
- package/engine/vendor/inputtino/.github/workflows/rust.yml +40 -0
- package/engine/vendor/inputtino/CMakeLists.txt +187 -0
- package/engine/vendor/inputtino/LICENSE +21 -0
- package/engine/vendor/inputtino/README.md +110 -0
- package/engine/vendor/inputtino/bindings/python/.devcontainer/Dockerfile +23 -0
- package/engine/vendor/inputtino/bindings/python/.devcontainer/devcontainer.json +28 -0
- package/engine/vendor/inputtino/bindings/python/.python-version +1 -0
- package/engine/vendor/inputtino/bindings/python/CMakeLists.txt +23 -0
- package/engine/vendor/inputtino/bindings/python/CPPLINT.cfg +2 -0
- package/engine/vendor/inputtino/bindings/python/Makefile +49 -0
- package/engine/vendor/inputtino/bindings/python/README.md +215 -0
- package/engine/vendor/inputtino/bindings/python/pyproject.toml +178 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/__init__.py +43 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/_core.pyi +533 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/base.py +63 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/joypad.py +248 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/keyboard.py +256 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/mouse.py +106 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/pentablet.py +73 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/py.typed +0 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/touchscreen.py +61 -0
- package/engine/vendor/inputtino/bindings/python/src/inputtino/trackpad.py +74 -0
- package/engine/vendor/inputtino/bindings/python/src/main.cpp +217 -0
- package/engine/vendor/inputtino/bindings/python/tests/__init__.py +0 -0
- package/engine/vendor/inputtino/bindings/python/tests/helpers.py +3 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_base.py +60 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_inputtino.py +5 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_joypad.py +332 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_keyboard.py +164 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_mouse.py +185 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_pentablet.py +198 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_touchscreen.py +144 -0
- package/engine/vendor/inputtino/bindings/python/tests/test_trackpad.py +146 -0
- package/engine/vendor/inputtino/bindings/python/uv.lock +390 -0
- package/engine/vendor/inputtino/bindings/rust/Cargo.toml +6 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/.dockerignore +1 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/Cargo.toml +18 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/examples/keyboard.rs +33 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/examples/mouse.rs +17 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/common.rs +116 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/error.rs +17 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad.rs +74 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad_nintendo.rs +135 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad_ps5.rs +280 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/joypad_xbox.rs +134 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/keyboard.rs +76 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/lib.rs +32 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/src/mouse.rs +178 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/tests/common.rs +38 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/tests/joypads.rs +150 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/tests/keyboard.rs +73 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino/tests/mouse.rs +139 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino-sys/.dockerignore +1 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino-sys/Cargo.toml +12 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino-sys/build.rs +48 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino-sys/src/lib.rs +5 -0
- package/engine/vendor/inputtino/bindings/rust/inputtino-sys/wrapper.h +1 -0
- package/engine/vendor/inputtino/cmake/utils.cmake +9 -0
- package/engine/vendor/inputtino/docker/Dockerfile +70 -0
- package/engine/vendor/inputtino/include/inputtino/input.h +324 -0
- package/engine/vendor/inputtino/include/inputtino/input.hpp +466 -0
- package/engine/vendor/inputtino/include/inputtino/result.hpp +37 -0
- package/engine/vendor/inputtino/share/pkgconfig/libinputtino.pc.in +17 -0
- package/engine/vendor/inputtino/src/c-bindings/helpers.hpp +19 -0
- package/engine/vendor/inputtino/src/c-bindings/joypad_ps5.cpp +115 -0
- package/engine/vendor/inputtino/src/c-bindings/joypad_switch.cpp +63 -0
- package/engine/vendor/inputtino/src/c-bindings/joypad_xone.cpp +62 -0
- package/engine/vendor/inputtino/src/c-bindings/keyboard.cpp +42 -0
- package/engine/vendor/inputtino/src/c-bindings/mouse.cpp +67 -0
- package/engine/vendor/inputtino/src/c-bindings/pen_tablet.cpp +50 -0
- package/engine/vendor/inputtino/src/c-bindings/touchscreen.cpp +43 -0
- package/engine/vendor/inputtino/src/c-bindings/trackpad.cpp +49 -0
- package/engine/vendor/inputtino/src/uhid/README.adoc +63 -0
- package/engine/vendor/inputtino/src/uhid/include/crc32.hpp +38 -0
- package/engine/vendor/inputtino/src/uhid/include/uhid/protected_types.hpp +36 -0
- package/engine/vendor/inputtino/src/uhid/include/uhid/ps5.hpp +550 -0
- package/engine/vendor/inputtino/src/uhid/include/uhid/uhid.hpp +168 -0
- package/engine/vendor/inputtino/src/uhid/joypad_ps5.cpp +580 -0
- package/engine/vendor/inputtino/src/uinput/include/inputtino/keyboard.hpp +84 -0
- package/engine/vendor/inputtino/src/uinput/include/inputtino/protected_ps5_types.hpp +7 -0
- package/engine/vendor/inputtino/src/uinput/include/inputtino/protected_types.hpp +110 -0
- package/engine/vendor/inputtino/src/uinput/joypad_nintendo.cpp +190 -0
- package/engine/vendor/inputtino/src/uinput/joypad_ps.cpp +203 -0
- package/engine/vendor/inputtino/src/uinput/joypad_utils.hpp +246 -0
- package/engine/vendor/inputtino/src/uinput/joypad_xbox.cpp +190 -0
- package/engine/vendor/inputtino/src/uinput/keyboard.cpp +120 -0
- package/engine/vendor/inputtino/src/uinput/mouse.cpp +199 -0
- package/engine/vendor/inputtino/src/uinput/pentablet.cpp +162 -0
- package/engine/vendor/inputtino/src/uinput/touchscreen.cpp +140 -0
- package/engine/vendor/inputtino/src/uinput/trackpad.cpp +192 -0
- package/examples/reference-client.html +428 -0
- 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
|