@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,244 @@
1
+ //! An X11 desktop: capture and input over one connection.
2
+ //!
3
+ //! This is the second capture backend, and the one a machine without a working
4
+ //! screen-cast portal uses — a headless X server, a remote X session, or
5
+ //! XWayland. It is capability-detected rather than assumed: the portal is
6
+ //! preferred when it is there, because the portal is what carries the user's
7
+ //! consent on a Wayland desktop.
8
+ //!
9
+ //! Capture reads the root window directly and input goes through XTest, so on an
10
+ //! X server this process owns, **nothing it does can reach another session's
11
+ //! keyboard**: XTest is scoped to the X server it is connected to, unlike
12
+ //! `uinput`, which the kernel delivers to whatever holds the seat.
13
+
14
+ use crate::convert::{fit, to_i420, I420};
15
+ use anyhow::{Context, Result};
16
+ use x11rb::connection::Connection;
17
+ use x11rb::protocol::xproto::{ConnectionExt as _, ImageFormat, Screen};
18
+ use x11rb::protocol::xtest::ConnectionExt as _;
19
+ use x11rb::rust_connection::RustConnection;
20
+
21
+ /// X key codes are evdev codes offset by 8 on every evdev-backed server,
22
+ /// including Xvfb, so the layout mapping the engine already has applies here too.
23
+ const X_KEYCODE_OFFSET: u8 = 8;
24
+
25
+ /// X core-protocol button numbers.
26
+ pub mod button {
27
+ pub const LEFT: u8 = 1;
28
+ pub const MIDDLE: u8 = 2;
29
+ pub const RIGHT: u8 = 3;
30
+ pub const WHEEL_UP: u8 = 4;
31
+ pub const WHEEL_DOWN: u8 = 5;
32
+ pub const WHEEL_LEFT: u8 = 6;
33
+ pub const WHEEL_RIGHT: u8 = 7;
34
+ }
35
+
36
+ pub struct X11Desktop {
37
+ connection: RustConnection,
38
+ root: u32,
39
+ pub width: usize,
40
+ pub height: usize,
41
+ /// Bytes per pixel the server reports; 4 for the 24/32-bit TrueColor that
42
+ /// every normal server uses, and the only depth this backend reads.
43
+ depth: u8,
44
+ }
45
+
46
+ impl X11Desktop {
47
+ /// Connect to `display` (`:99`, or the `DISPLAY` environment when omitted).
48
+ pub fn connect(display: Option<&str>) -> Result<Self> {
49
+ let (connection, screen_number) = match display {
50
+ Some(display) => RustConnection::connect(Some(display))
51
+ .with_context(|| format!("cannot open X display {display}"))?,
52
+ None => {
53
+ RustConnection::connect(None).context("cannot open the X display in DISPLAY")?
54
+ }
55
+ };
56
+ let screen: &Screen = connection
57
+ .setup()
58
+ .roots
59
+ .get(screen_number as usize)
60
+ .context("the X display has no screen")?;
61
+ if screen.root_depth != 24 {
62
+ anyhow::bail!(
63
+ "unsupported X root depth {}; this backend reads 24-bit TrueColor",
64
+ screen.root_depth
65
+ );
66
+ }
67
+ Ok(Self {
68
+ root: screen.root,
69
+ width: screen.width_in_pixels as usize,
70
+ height: screen.height_in_pixels as usize,
71
+ depth: screen.root_depth,
72
+ connection,
73
+ })
74
+ }
75
+
76
+ pub fn screen_size(&self) -> (i32, i32) {
77
+ (self.width as i32, self.height as i32)
78
+ }
79
+
80
+ /// Read the whole root window as I420, downscaled into the caller's box.
81
+ ///
82
+ /// The root image is the composited screen contents: on a server with no
83
+ /// compositor this is every window drawn onto the framebuffer, which is what
84
+ /// the viewer expects to see.
85
+ pub fn capture(&mut self, max_width: usize, max_height: usize) -> Result<I420> {
86
+ let image = self
87
+ .connection
88
+ .get_image(
89
+ ImageFormat::Z_PIXMAP,
90
+ self.root,
91
+ 0,
92
+ 0,
93
+ self.width as u16,
94
+ self.height as u16,
95
+ u32::MAX,
96
+ )
97
+ .context("X11 GetImage failed")?
98
+ .reply()
99
+ .context("X11 GetImage returned no reply")?;
100
+ let stride = self.width * 4;
101
+ if image.data.len() < stride * self.height {
102
+ anyhow::bail!(
103
+ "X11 returned {} bytes for a {}x{} screen",
104
+ image.data.len(),
105
+ self.width,
106
+ self.height
107
+ );
108
+ }
109
+ let (width, height) = fit(self.width, self.height, max_width, max_height);
110
+ // The server's depth is the only field that can tell us how the pixel is
111
+ // packed; the engine assumes the byte order every TrueColor server uses.
112
+ let _ = self.depth;
113
+ to_i420(
114
+ &image.data,
115
+ self.width,
116
+ self.height,
117
+ stride,
118
+ crate::capture::PixelFormat::Bgrx,
119
+ width,
120
+ height,
121
+ )
122
+ .context("the captured X11 pixels are not a format this engine can read")
123
+ }
124
+
125
+ fn flush(&self) -> Result<()> {
126
+ self.connection
127
+ .flush()
128
+ .context("the X11 connection dropped")
129
+ }
130
+
131
+ pub fn move_pointer(&self, x: i64, y: i64) -> Result<()> {
132
+ let (x, y) = self.clamp(x, y);
133
+ self.connection
134
+ .xtest_fake_input(
135
+ x11rb::protocol::xproto::MOTION_NOTIFY_EVENT,
136
+ false as u8,
137
+ 0,
138
+ self.root,
139
+ x as i16,
140
+ y as i16,
141
+ 0,
142
+ )
143
+ .context("XTest motion failed")?;
144
+ self.flush()
145
+ }
146
+
147
+ pub fn button(&self, button: u8, down: bool) -> Result<()> {
148
+ self.connection
149
+ .xtest_fake_input(
150
+ x11rb::protocol::xproto::BUTTON_PRESS_EVENT + u8::from(!down),
151
+ button,
152
+ 0,
153
+ self.root,
154
+ 0,
155
+ 0,
156
+ 0,
157
+ )
158
+ .context("XTest button failed")?;
159
+ self.flush()
160
+ }
161
+
162
+ /// A wheel notch. `dy` is in detents and positive means "down", matching the
163
+ /// control channel's convention.
164
+ pub fn scroll(&self, dx: i64, dy: i64) -> Result<()> {
165
+ for _ in 0..dy.abs().min(20) {
166
+ self.button(
167
+ if dy > 0 {
168
+ button::WHEEL_DOWN
169
+ } else {
170
+ button::WHEEL_UP
171
+ },
172
+ true,
173
+ )?;
174
+ self.button(
175
+ if dy > 0 {
176
+ button::WHEEL_DOWN
177
+ } else {
178
+ button::WHEEL_UP
179
+ },
180
+ false,
181
+ )?;
182
+ }
183
+ for _ in 0..dx.abs().min(20) {
184
+ self.button(
185
+ if dx > 0 {
186
+ button::WHEEL_RIGHT
187
+ } else {
188
+ button::WHEEL_LEFT
189
+ },
190
+ true,
191
+ )?;
192
+ self.button(
193
+ if dx > 0 {
194
+ button::WHEEL_RIGHT
195
+ } else {
196
+ button::WHEEL_LEFT
197
+ },
198
+ false,
199
+ )?;
200
+ }
201
+ Ok(())
202
+ }
203
+
204
+ /// `evdev_code` is the layout layer's Linux key code; the X server's own key
205
+ /// code for it is that value plus eight.
206
+ pub fn key(&self, evdev_code: i16, down: bool) -> Result<()> {
207
+ let keycode = evdev_code.saturating_add(X_KEYCODE_OFFSET as i16);
208
+ if !(8..=255).contains(&keycode) {
209
+ anyhow::bail!("{evdev_code} is not a key this X server can press");
210
+ }
211
+ self.connection
212
+ .xtest_fake_input(
213
+ x11rb::protocol::xproto::KEY_PRESS_EVENT + u8::from(!down),
214
+ keycode as u8,
215
+ 0,
216
+ 0,
217
+ 0,
218
+ 0,
219
+ 0,
220
+ )
221
+ .context("XTest key failed")?;
222
+ self.flush()
223
+ }
224
+
225
+ fn clamp(&self, x: i64, y: i64) -> (i64, i64) {
226
+ (
227
+ x.clamp(0, self.width.saturating_sub(1) as i64),
228
+ y.clamp(0, self.height.saturating_sub(1) as i64),
229
+ )
230
+ }
231
+ }
232
+
233
+ #[cfg(test)]
234
+ mod tests {
235
+ use super::*;
236
+
237
+ #[test]
238
+ fn fitting_never_upscales_and_keeps_even_dimensions() {
239
+ assert_eq!(fit(800, 600, 1280, 800), (800, 600));
240
+ assert_eq!(fit(1920, 1080, 1280, 720), (1280, 720));
241
+ let (w, h) = fit(1000, 1000, 600, 600);
242
+ assert_eq!((w, h), (600, 600));
243
+ }
244
+ }
@@ -0,0 +1,166 @@
1
+ ---
2
+ Language: Cpp
3
+ # BasedOnStyle: LLVM with a few personal changes
4
+ AccessModifierOffset: -2
5
+ AlignAfterOpenBracket: Align
6
+ AlignConsecutiveMacros: None
7
+ AlignConsecutiveAssignments: None
8
+ AlignConsecutiveBitFields: None
9
+ AlignConsecutiveDeclarations: None
10
+ AlignEscapedNewlines: Right
11
+ AlignOperands: Align
12
+ AlignTrailingComments: true
13
+ AllowAllArgumentsOnNextLine: false
14
+ AllowAllConstructorInitializersOnNextLine: true
15
+ AllowAllParametersOfDeclarationOnNextLine: true
16
+ AllowShortEnumsOnASingleLine: false
17
+ AllowShortBlocksOnASingleLine: Never
18
+ AllowShortCaseLabelsOnASingleLine: false
19
+ AllowShortFunctionsOnASingleLine: Empty
20
+ AllowShortLambdasOnASingleLine: All
21
+ AllowShortIfStatementsOnASingleLine: Never
22
+ AllowShortLoopsOnASingleLine: false
23
+ AlwaysBreakAfterDefinitionReturnType: None
24
+ AlwaysBreakAfterReturnType: None
25
+ AlwaysBreakBeforeMultilineStrings: false
26
+ AlwaysBreakTemplateDeclarations: MultiLine
27
+ AttributeMacros:
28
+ - __capability
29
+ BinPackArguments: false
30
+ BinPackParameters: false
31
+ BraceWrapping:
32
+ AfterCaseLabel: false
33
+ AfterClass: false
34
+ AfterControlStatement: Never
35
+ AfterEnum: false
36
+ AfterFunction: false
37
+ AfterNamespace: false
38
+ AfterObjCDeclaration: false
39
+ AfterStruct: false
40
+ AfterUnion: false
41
+ AfterExternBlock: false
42
+ BeforeCatch: false
43
+ BeforeElse: false
44
+ BeforeLambdaBody: false
45
+ BeforeWhile: false
46
+ IndentBraces: false
47
+ SplitEmptyFunction: true
48
+ SplitEmptyRecord: true
49
+ SplitEmptyNamespace: true
50
+ BreakBeforeBinaryOperators: None
51
+ BreakBeforeConceptDeclarations: true
52
+ BreakBeforeBraces: Attach
53
+ BreakBeforeInheritanceComma: false
54
+ BreakInheritanceList: BeforeColon
55
+ BreakBeforeTernaryOperators: true
56
+ BreakConstructorInitializersBeforeComma: false
57
+ BreakConstructorInitializers: BeforeColon
58
+ BreakAfterJavaFieldAnnotations: false
59
+ BreakStringLiterals: true
60
+ ColumnLimit: 120
61
+ CommentPragmas: '^ IWYU pragma:'
62
+ CompactNamespaces: false
63
+ ConstructorInitializerAllOnOneLineOrOnePerLine: false
64
+ ConstructorInitializerIndentWidth: 4
65
+ ContinuationIndentWidth: 4
66
+ Cpp11BracedListStyle: true
67
+ DeriveLineEnding: true
68
+ DerivePointerAlignment: false
69
+ DisableFormat: false
70
+ EmptyLineBeforeAccessModifier: LogicalBlock
71
+ ExperimentalAutoDetectBinPacking: false
72
+ FixNamespaceComments: true
73
+ ForEachMacros:
74
+ - foreach
75
+ - Q_FOREACH
76
+ - BOOST_FOREACH
77
+ StatementAttributeLikeMacros:
78
+ - Q_EMIT
79
+ IncludeBlocks: Preserve
80
+ IncludeCategories:
81
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
82
+ Priority: 2
83
+ SortPriority: 0
84
+ CaseSensitive: false
85
+ - Regex: '^(<|"(gtest|gmock|isl|json)/)'
86
+ Priority: 3
87
+ SortPriority: 0
88
+ CaseSensitive: false
89
+ - Regex: '.*'
90
+ Priority: 1
91
+ SortPriority: 0
92
+ CaseSensitive: false
93
+ IncludeIsMainRegex: '(Test)?$'
94
+ IncludeIsMainSourceRegex: ''
95
+ IndentCaseLabels: false
96
+ IndentCaseBlocks: false
97
+ IndentGotoLabels: true
98
+ IndentPPDirectives: None
99
+ IndentExternBlock: AfterExternBlock
100
+ IndentRequires: false
101
+ IndentWidth: 2
102
+ IndentWrappedFunctionNames: false
103
+ InsertTrailingCommas: None
104
+ JavaScriptQuotes: Leave
105
+ JavaScriptWrapImports: true
106
+ KeepEmptyLinesAtTheStartOfBlocks: true
107
+ MacroBlockBegin: ''
108
+ MacroBlockEnd: ''
109
+ MaxEmptyLinesToKeep: 1
110
+ NamespaceIndentation: None
111
+ ObjCBinPackProtocolList: Auto
112
+ ObjCBlockIndentWidth: 2
113
+ ObjCBreakBeforeNestedBlockParam: true
114
+ ObjCSpaceAfterProperty: false
115
+ ObjCSpaceBeforeProtocolList: true
116
+ PenaltyBreakAssignment: 20
117
+ PenaltyBreakBeforeFirstCallParameter: 0
118
+ PenaltyBreakComment: 300
119
+ PenaltyBreakFirstLessLess: 120
120
+ PenaltyBreakString: 1000
121
+ PenaltyBreakTemplateDeclaration: 10
122
+ PenaltyExcessCharacter: 1000000
123
+ PenaltyReturnTypeOnItsOwnLine: 60
124
+ PenaltyIndentedWhitespace: 0
125
+ PointerAlignment: Right
126
+ ReflowComments: true
127
+ SortIncludes: CaseInsensitive
128
+ SortJavaStaticImport: Before
129
+ SortUsingDeclarations: true
130
+ SpaceAfterCStyleCast: false
131
+ SpaceAfterLogicalNot: false
132
+ SpaceAfterTemplateKeyword: true
133
+ SpaceBeforeAssignmentOperators: true
134
+ SpaceBeforeCaseColon: false
135
+ SpaceBeforeCpp11BracedList: false
136
+ SpaceBeforeCtorInitializerColon: true
137
+ SpaceBeforeInheritanceColon: true
138
+ SpaceBeforeParens: ControlStatements
139
+ SpaceAroundPointerQualifiers: Default
140
+ SpaceBeforeRangeBasedForLoopColon: true
141
+ SpaceInEmptyBlock: false
142
+ SpaceInEmptyParentheses: false
143
+ SpacesBeforeTrailingComments: 1
144
+ SpacesInAngles: false
145
+ SpacesInConditionalStatement: false
146
+ SpacesInContainerLiterals: true
147
+ SpacesInCStyleCastParentheses: false
148
+ SpacesInParentheses: false
149
+ SpacesInSquareBrackets: false
150
+ SpaceBeforeSquareBrackets: false
151
+ BitFieldColonSpacing: Both
152
+ Standard: Latest
153
+ StatementMacros:
154
+ - Q_UNUSED
155
+ - QT_REQUIRE_VERSION
156
+ TabWidth: 8
157
+ UseCRLF: false
158
+ UseTab: Never
159
+ WhitespaceSensitiveMacros:
160
+ - STRINGIZE
161
+ - PP_STRINGIZE
162
+ - BOOST_PP_STRINGIZE
163
+ - NS_SWIFT_NAME
164
+ - CF_SWIFT_NAME
165
+ ...
166
+
@@ -0,0 +1,30 @@
1
+ # Generated from CLion Inspection settings
2
+ ---
3
+ Checks: '-*,
4
+ bugprone-*,
5
+ mpi-*,
6
+ cert-err52-cpp,
7
+ cert-err60-cpp,
8
+ cert-err34-c,
9
+ cert-str34-c,
10
+ cert-dcl21-cpp,
11
+ cert-msc50-cpp,
12
+ cert-msc51-cpp,
13
+ cert-dcl58-cpp,
14
+ cert-flp30-c,
15
+ cppcoreguidelines-*,
16
+ -cppcoreguidelines-avoid-do-while,
17
+ google-default-arguments,
18
+ google-runtime-operator,
19
+ google-explicit-constructor,
20
+ hicpp-multiway-paths-covered,
21
+ hicpp-exception-baseclass,
22
+ misc-unconventional-assign-operator,
23
+ misc-misplaced-const,
24
+ misc-new-delete-overloads,
25
+ misc-non-copyable-objects,
26
+ misc-no-recursion,
27
+ misc-throw-by-value-catch-by-reference,
28
+ misc-uniqueptr-reset-release,
29
+ openmp-use-default-none,
30
+ portability-simd-intrinsics'
@@ -0,0 +1,11 @@
1
+ # Start by removing everything and add just the things we need
2
+ *
3
+ !src
4
+ !CMakeLists.txt
5
+ !include
6
+ !cmake/
7
+ !docker/startup.sh
8
+ !share/
9
+
10
+ # Rust bindings
11
+ !bindings/rust/
@@ -0,0 +1,14 @@
1
+ # Pushes the contents of the repo to the Codeberg mirror
2
+ name: Repo Mirror
3
+ on: [ push ]
4
+ jobs:
5
+ codeberg:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v3
9
+ with:
10
+ fetch-depth: 0
11
+ - uses: pixta-dev/repository-mirroring-action@v1
12
+ with:
13
+ target_repo_url: "git@codeberg.org:games-on-whales/inputtino.git"
14
+ ssh_private_key: ${{ secrets.CODEBERG_SSH }}
@@ -0,0 +1,124 @@
1
+ name: "Python: Lint / Format / Test / Type Check"
2
+
3
+ on:
4
+ push:
5
+ branches: [stable]
6
+ pull_request:
7
+ branches: [stable]
8
+
9
+ defaults:
10
+ run:
11
+ shell: bash
12
+ working-directory: ./bindings/python
13
+
14
+ env:
15
+ PYTHON_VERSION: "3.10"
16
+ UV_VERSION: "0.5.10"
17
+
18
+ jobs:
19
+ run_linter:
20
+ runs-on: ubuntu-24.04
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Install system dependencies
25
+ run: |
26
+ sudo apt-get update
27
+ sudo apt-get install -y clang-format cpplint cppcheck make build-essential cmake libevdev-dev pkg-config
28
+
29
+ - name: Set up Python
30
+ uses: astral-sh/setup-uv@v4
31
+ with:
32
+ version: ${{ env.UV_VERSION }}
33
+ python-version: ${{ env.PYTHON_VERSION }}
34
+ enable-cache: true
35
+
36
+ - name: Run linter
37
+ run: make lint
38
+
39
+ run_formatter:
40
+ runs-on: ubuntu-24.04
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+
44
+ - name: Install system dependencies
45
+ run: |
46
+ sudo apt-get update
47
+ sudo apt-get install -y clang-format cpplint cppcheck make build-essential cmake libevdev-dev pkg-config
48
+
49
+ - name: Set up Python
50
+ uses: astral-sh/setup-uv@v4
51
+ with:
52
+ version: ${{ env.UV_VERSION }}
53
+ python-version: ${{ env.PYTHON_VERSION }}
54
+ enable-cache: true
55
+
56
+ - name: Run formatter
57
+ run: make format
58
+
59
+ run_tests:
60
+ runs-on: ${{ matrix.os }}
61
+ strategy:
62
+ fail-fast: false
63
+ matrix:
64
+ os: ["ubuntu-latest"]
65
+ python-version: ["3.10", "3.11","3.12", "3.13"]
66
+
67
+ timeout-minutes: 20
68
+
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Install uv and set the python version
73
+ uses: astral-sh/setup-uv@v4
74
+ with:
75
+ version: ${{ env.UV_VERSION }}
76
+ python-version: ${{ matrix.python-version }}
77
+ enable-cache: true
78
+
79
+ - name: Install system dependencies
80
+ run: |
81
+ sudo apt-get update
82
+ sudo apt-get install -y build-essential cmake libevdev-dev pkg-config
83
+
84
+ - name: Cache uv dependencies
85
+ uses: actions/cache@v4
86
+ with:
87
+ path: .venv
88
+ key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
89
+
90
+ - name: Install dependencies
91
+ run: uv sync --reinstall
92
+
93
+ - name: Run pytest with coverage
94
+ run: |
95
+ uv run pytest -v --log-level INFO --cov -m "not practical"
96
+
97
+ run_type-check:
98
+ runs-on: ubuntu-24.04
99
+ steps:
100
+ - uses: actions/checkout@v4
101
+
102
+ - name: Install system dependencies
103
+ run: |
104
+ sudo apt-get update
105
+ sudo apt-get install -y build-essential cmake libevdev-dev pkg-config
106
+
107
+ - name: Set up Python
108
+ uses: astral-sh/setup-uv@v4
109
+ with:
110
+ version: ${{ env.UV_VERSION }}
111
+ python-version: ${{ env.PYTHON_VERSION }}
112
+ enable-cache: true
113
+
114
+ - name: Cache uv dependencies
115
+ uses: actions/cache@v4
116
+ with:
117
+ path: .venv
118
+ key: uv-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
119
+
120
+ - name: Install dependencies
121
+ run: uv sync
122
+
123
+ - name: Run pyright
124
+ run: uv run pyright src
@@ -0,0 +1,49 @@
1
+ name: "Python: Installation Test"
2
+
3
+ on:
4
+ push:
5
+ branches: [stable]
6
+ pull_request:
7
+ branches: [stable]
8
+
9
+ defaults:
10
+ run:
11
+ shell: bash
12
+ working-directory: ./bindings/python
13
+
14
+ jobs:
15
+ test-install:
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ container:
21
+ - image: ubuntu:22.04
22
+ install: >-
23
+ apt-get update &&
24
+ apt-get install -y build-essential cmake libevdev-dev pkg-config git python3 python3-pip &&
25
+ python3 -m pip install --upgrade pip
26
+ - image: ubuntu:24.04
27
+ install: >-
28
+ apt-get update &&
29
+ apt-get install -y build-essential cmake libevdev-dev pkg-config git python3 python3-pip
30
+ - image: archlinux:latest
31
+ install: >-
32
+ pacman -Syu --noconfirm &&
33
+ pacman -S --noconfirm git cmake base-devel pkgconf libevdev python python-pip &&
34
+ python -m pip install --upgrade pip --break-system-packages
35
+ - image: fedora:latest
36
+ install: >-
37
+ dnf install -y git cmake gcc gcc-c++ make pkgconf-pkg-config libevdev-devel python3-devel python3-pip &&
38
+ python -m pip install --upgrade pip --break-system-packages
39
+ container:
40
+ image: ${{ matrix.container.image }}
41
+
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+
45
+ - name: Install dependencies
46
+ run: ${{ matrix.container.install }}
47
+
48
+ - name: Install package
49
+ run: python3 -m pip install . --break-system-packages
@@ -0,0 +1,40 @@
1
+ name: Test Rust bindings
2
+
3
+ on:
4
+ push:
5
+ branches: [ "stable" ]
6
+ pull_request:
7
+ branches: [ "stable" ]
8
+
9
+ env:
10
+ CARGO_TERM_COLOR: always
11
+
12
+ jobs:
13
+ build:
14
+ name: Build
15
+ runs-on: ubuntu-latest
16
+
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v3
20
+
21
+ - name: Setup dependencies
22
+ run: |
23
+ sudo apt-get update
24
+ sudo apt-get install -y build-essential cmake libevdev-dev pkg-config
25
+ shell: bash
26
+
27
+ - name: Build
28
+ working-directory: bindings/rust
29
+ run: |
30
+ cargo build --verbose
31
+ shell: bash
32
+
33
+ # Disabled testing as uinput / uhid doesn't work in Github Actions.
34
+ # - name: Run tests
35
+ # run: |
36
+ # cargo test --verbose
37
+ # shell: bash
38
+
39
+ - name: Machete
40
+ uses: bnjbvr/cargo-machete@main