mcp-remotetouch 0.1.0 → 0.1.1
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/README.md +46 -74
- package/build/index.js +10 -5
- package/build/index.js.map +1 -1
- package/build/python-daemon.d.ts +1 -1
- package/build/python-daemon.js +176 -84
- package/build/python-daemon.js.map +1 -1
- package/build/ssh-touch-session.js +11 -2
- package/build/ssh-touch-session.js.map +1 -1
- package/build/types.d.ts +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
An MCP server for remotely controlling a touchscreen on any Linux device over SSH.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Injects tap, swipe, long press, and double tap events directly into the physical touchscreen device. The daemon auto-detects the touchscreen and screen resolution. **No installation required on the remote device** — the Python daemon is sent via stdin over SSH, using only Python's standard library.
|
|
6
6
|
|
|
7
7
|
## Architecture
|
|
8
8
|
|
|
@@ -14,14 +14,17 @@ Dev Machine Remote Linux Device
|
|
|
14
14
|
│ MCP Server (TS) │ ──────────────────> │ Python daemon │
|
|
15
15
|
│ stdio transport │ JSON-line proto │ (stdlib only) │
|
|
16
16
|
│ │ <────────────────── │ │
|
|
17
|
-
│ touch_tap │ │
|
|
18
|
-
│ touch_swipe │ │
|
|
19
|
-
│ touch_long_press │ │
|
|
20
|
-
│ touch_double_tap │ │
|
|
21
|
-
│ touch_disconnect │ │
|
|
17
|
+
│ touch_tap │ │ Auto-detect │
|
|
18
|
+
│ touch_swipe │ │ touchscreen │
|
|
19
|
+
│ touch_long_press │ │ ↓ │
|
|
20
|
+
│ touch_double_tap │ │ /dev/input/eventN│
|
|
21
|
+
│ touch_disconnect │ │ ↓ │
|
|
22
|
+
│ │ │ Linux Input │
|
|
22
23
|
└──────────────────┘ └──────────────────┘
|
|
23
24
|
```
|
|
24
25
|
|
|
26
|
+
The daemon scans `/proc/bus/input/devices` to find the physical touchscreen (by checking `INPUT_PROP_DIRECT` and `ABS_MT_POSITION_X`), then injects events directly into it. This works reliably with containerized compositors (e.g., Torizon with Qt EGLFS) where virtual uinput devices may not be detected.
|
|
27
|
+
|
|
25
28
|
### HTTP server mode (`--server`)
|
|
26
29
|
|
|
27
30
|
```
|
|
@@ -45,7 +48,7 @@ AI Agent (remote) ──HTTP/SSE──> Express + StreamableHTTPServerTransport
|
|
|
45
48
|
|
|
46
49
|
- Any Linux device with a touchscreen (Raspberry Pi, SBC, embedded system, etc.)
|
|
47
50
|
- Python 3
|
|
48
|
-
-
|
|
51
|
+
- Read/write access to `/dev/input/eventN` (the touchscreen device)
|
|
49
52
|
|
|
50
53
|
Add the user to the `input` group on the remote device:
|
|
51
54
|
|
|
@@ -53,48 +56,48 @@ Add the user to the `input` group on the remote device:
|
|
|
53
56
|
sudo usermod -aG input $USER
|
|
54
57
|
```
|
|
55
58
|
|
|
56
|
-
Re-login for the change to take effect.
|
|
59
|
+
Re-login for the change to take effect. Alternatively, use the `useSudo` option.
|
|
57
60
|
|
|
58
61
|
## Installation
|
|
59
62
|
|
|
60
63
|
```bash
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
npm install -g mcp-remotetouch
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or run directly with `npx`:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx mcp-remotetouch
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
##
|
|
73
|
+
## Usage
|
|
68
74
|
|
|
69
|
-
Add to Claude Desktop's `claude_desktop_config.json
|
|
75
|
+
Add to your MCP client configuration (e.g. Claude Desktop's `claude_desktop_config.json`):
|
|
70
76
|
|
|
71
77
|
```json
|
|
72
78
|
{
|
|
73
79
|
"mcpServers": {
|
|
74
80
|
"remotetouch": {
|
|
75
|
-
"command": "
|
|
76
|
-
"args": ["
|
|
77
|
-
"env": {
|
|
78
|
-
"REMOTETOUCH_SSH_HOST": "192.168.1.100",
|
|
79
|
-
"REMOTETOUCH_SSH_USER": "pi",
|
|
80
|
-
"REMOTETOUCH_SCREEN_WIDTH": "800",
|
|
81
|
-
"REMOTETOUCH_SCREEN_HEIGHT": "480"
|
|
82
|
-
}
|
|
81
|
+
"command": "npx",
|
|
82
|
+
"args": ["mcp-remotetouch"],
|
|
83
|
+
"env": {}
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
```
|
|
87
88
|
|
|
89
|
+
Screen resolution is auto-detected from the device. You can override it with `REMOTETOUCH_SCREEN_WIDTH` and `REMOTETOUCH_SCREEN_HEIGHT` if needed.
|
|
90
|
+
|
|
88
91
|
## Environment Variables
|
|
89
92
|
|
|
90
93
|
| Variable | Default | Description |
|
|
91
94
|
|---|---|---|
|
|
92
|
-
| `REMOTETOUCH_SSH_HOST` | (
|
|
95
|
+
| `REMOTETOUCH_SSH_HOST` | (none) | SSH host of the remote device |
|
|
93
96
|
| `REMOTETOUCH_SSH_USER` | `pi` | SSH username |
|
|
94
97
|
| `REMOTETOUCH_SSH_PORT` | `22` | SSH port |
|
|
95
98
|
| `REMOTETOUCH_SSH_KEY` | (none) | Path to SSH private key |
|
|
96
|
-
| `REMOTETOUCH_SCREEN_WIDTH` |
|
|
97
|
-
| `REMOTETOUCH_SCREEN_HEIGHT` |
|
|
99
|
+
| `REMOTETOUCH_SCREEN_WIDTH` | auto-detected | Screen width in pixels |
|
|
100
|
+
| `REMOTETOUCH_SCREEN_HEIGHT` | auto-detected | Screen height in pixels |
|
|
98
101
|
| `REMOTETOUCH_USE_SUDO` | `false` | Run daemon with sudo |
|
|
99
102
|
|
|
100
103
|
## Tools
|
|
@@ -109,8 +112,8 @@ Connect to a remote Linux device via SSH and start the touch daemon. Returns a s
|
|
|
109
112
|
| `user` | string? | SSH username |
|
|
110
113
|
| `port` | number? | SSH port |
|
|
111
114
|
| `sshKey` | string? | Path to SSH private key |
|
|
112
|
-
| `screenWidth` | number? | Screen width
|
|
113
|
-
| `screenHeight` | number? | Screen height
|
|
115
|
+
| `screenWidth` | number? | Screen width (auto-detected if omitted) |
|
|
116
|
+
| `screenHeight` | number? | Screen height (auto-detected if omitted) |
|
|
114
117
|
| `useSudo` | boolean? | Run with sudo |
|
|
115
118
|
|
|
116
119
|
### `touch_tap`
|
|
@@ -179,13 +182,10 @@ Instead of running as a stdio MCP server, you can run `mcp-remotetouch` as an HT
|
|
|
179
182
|
|
|
180
183
|
```bash
|
|
181
184
|
# Default: listen on 0.0.0.0:3000
|
|
182
|
-
|
|
185
|
+
npx mcp-remotetouch --server
|
|
183
186
|
|
|
184
187
|
# Custom port and host
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
# Or use the convenience script
|
|
188
|
-
npm run start:server
|
|
188
|
+
npx mcp-remotetouch --server --port 8080 --host 127.0.0.1
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
### CLI arguments
|
|
@@ -198,58 +198,30 @@ npm run start:server
|
|
|
198
198
|
|
|
199
199
|
Without `--server`, the process runs in stdio mode (the default, backward-compatible behavior).
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
The server exposes a single endpoint at `/mcp` that speaks the MCP Streamable HTTP transport protocol.
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
# Initialize a session
|
|
207
|
-
curl -X POST http://localhost:3000/mcp \
|
|
208
|
-
-H "Content-Type: application/json" \
|
|
209
|
-
-H "Accept: application/json, text/event-stream" \
|
|
210
|
-
-d '{
|
|
211
|
-
"jsonrpc": "2.0",
|
|
212
|
-
"method": "initialize",
|
|
213
|
-
"params": {
|
|
214
|
-
"protocolVersion": "2025-03-26",
|
|
215
|
-
"capabilities": {},
|
|
216
|
-
"clientInfo": { "name": "test", "version": "1.0" }
|
|
217
|
-
},
|
|
218
|
-
"id": 1
|
|
219
|
-
}'
|
|
220
|
-
```
|
|
201
|
+
## Workflow
|
|
221
202
|
|
|
222
|
-
|
|
203
|
+
A typical session from Claude Desktop:
|
|
223
204
|
|
|
224
|
-
```bash
|
|
225
|
-
curl -X POST http://localhost:3000/mcp \
|
|
226
|
-
-H "Content-Type: application/json" \
|
|
227
|
-
-H "Accept: application/json, text/event-stream" \
|
|
228
|
-
-H "mcp-session-id: <session-id>" \
|
|
229
|
-
-d '{"jsonrpc":"2.0","method":"tools/list","id":2}'
|
|
230
|
-
```
|
|
231
205
|
|
|
232
|
-
|
|
206
|
+
1. `touch_connect` — connect to the remote device
|
|
207
|
+
2. `touch_tap` / `touch_swipe` / `touch_long_press` / `touch_double_tap` — interact with the screen
|
|
208
|
+
3. `touch_disconnect` — end the session
|
|
233
209
|
|
|
234
|
-
|
|
210
|
+
## Troubleshooting
|
|
235
211
|
|
|
236
|
-
|
|
237
|
-
2. `touch_tap` to tap a coordinate on the screen
|
|
238
|
-
3. `touch_swipe` to scroll or swipe
|
|
239
|
-
4. `touch_disconnect` to end the session
|
|
212
|
+
### Permission denied
|
|
240
213
|
|
|
241
|
-
|
|
214
|
+
The user on the remote device needs access to `/dev/input/eventN`. Either:
|
|
242
215
|
|
|
243
|
-
|
|
216
|
+
- Add the user to the `input` group: `sudo usermod -aG input $USER` (re-login required)
|
|
217
|
+
- Or set `REMOTETOUCH_USE_SUDO=true`
|
|
244
218
|
|
|
245
|
-
|
|
219
|
+
### No physical touchscreen device found
|
|
246
220
|
|
|
247
|
-
|
|
248
|
-
sudo usermod -aG input $USER
|
|
249
|
-
# Re-login for the change to take effect
|
|
250
|
-
```
|
|
221
|
+
The daemon could not find a touchscreen in `/proc/bus/input/devices`. Verify:
|
|
251
222
|
|
|
252
|
-
|
|
223
|
+
- The device has a touchscreen connected and its driver is loaded
|
|
224
|
+
- The device shows `INPUT_PROP_DIRECT` and has `ABS_MT_POSITION_X` capability
|
|
253
225
|
|
|
254
226
|
### SSH connection fails
|
|
255
227
|
|
package/build/index.js
CHANGED
|
@@ -8,13 +8,15 @@ import { SshTouchSessionManager } from "./ssh-touch-session.js";
|
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
// Defaults from environment variables
|
|
10
10
|
function defaultConfig(overrides = {}) {
|
|
11
|
+
const envWidth = process.env.REMOTETOUCH_SCREEN_WIDTH;
|
|
12
|
+
const envHeight = process.env.REMOTETOUCH_SCREEN_HEIGHT;
|
|
11
13
|
return {
|
|
12
14
|
host: overrides.host ?? process.env.REMOTETOUCH_SSH_HOST ?? "",
|
|
13
15
|
user: overrides.user ?? process.env.REMOTETOUCH_SSH_USER ?? "pi",
|
|
14
16
|
port: overrides.port ?? Number(process.env.REMOTETOUCH_SSH_PORT ?? "22"),
|
|
15
17
|
sshKey: overrides.sshKey ?? process.env.REMOTETOUCH_SSH_KEY ?? undefined,
|
|
16
|
-
screenWidth: overrides.screenWidth ?? Number(
|
|
17
|
-
screenHeight: overrides.screenHeight ?? Number(
|
|
18
|
+
screenWidth: overrides.screenWidth ?? (envWidth ? Number(envWidth) : undefined),
|
|
19
|
+
screenHeight: overrides.screenHeight ?? (envHeight ? Number(envHeight) : undefined),
|
|
18
20
|
useSudo: overrides.useSudo ?? (process.env.REMOTETOUCH_USE_SUDO === "true"),
|
|
19
21
|
};
|
|
20
22
|
}
|
|
@@ -29,8 +31,8 @@ function createServer(manager) {
|
|
|
29
31
|
user: z.string().optional().describe("SSH user (default: env REMOTETOUCH_SSH_USER or 'pi')"),
|
|
30
32
|
port: z.number().optional().describe("SSH port (default: env REMOTETOUCH_SSH_PORT or 22)"),
|
|
31
33
|
sshKey: z.string().optional().describe("Path to SSH private key"),
|
|
32
|
-
screenWidth: z.number().optional().describe("Screen width in pixels (default:
|
|
33
|
-
screenHeight: z.number().optional().describe("Screen height in pixels (default:
|
|
34
|
+
screenWidth: z.number().optional().describe("Screen width in pixels (default: auto-detected from device, or env REMOTETOUCH_SCREEN_WIDTH)"),
|
|
35
|
+
screenHeight: z.number().optional().describe("Screen height in pixels (default: auto-detected from device, or env REMOTETOUCH_SCREEN_HEIGHT)"),
|
|
34
36
|
useSudo: z.boolean().optional().describe("Run daemon with sudo (default: env REMOTETOUCH_USE_SUDO or false)"),
|
|
35
37
|
}, async (params) => {
|
|
36
38
|
const config = defaultConfig({
|
|
@@ -50,8 +52,11 @@ function createServer(manager) {
|
|
|
50
52
|
}
|
|
51
53
|
try {
|
|
52
54
|
const sessionId = await manager.connect(config);
|
|
55
|
+
const session = manager.getSession(sessionId);
|
|
56
|
+
const w = session.config.screenWidth ?? "unknown";
|
|
57
|
+
const h = session.config.screenHeight ?? "unknown";
|
|
53
58
|
return {
|
|
54
|
-
content: [{ type: "text", text: `Connected. Session ID: ${sessionId}\nHost: ${config.user}@${config.host}:${config.port}\nScreen: ${
|
|
59
|
+
content: [{ type: "text", text: `Connected. Session ID: ${sessionId}\nHost: ${config.user}@${config.host}:${config.port}\nScreen: ${w}x${h}` }],
|
|
55
60
|
};
|
|
56
61
|
}
|
|
57
62
|
catch (err) {
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/build/python-daemon.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PYTHON_DAEMON_SCRIPT = "\nimport sys\nimport os\nimport json\nimport struct\nimport fcntl\nimport time\n\n# ioctl constants\nUI_SET_EVBIT = 0x40045564\nUI_SET_ABSBIT = 0x40045567\nUI_SET_PROPBIT = 0x4004556e\nUI_DEV_SETUP = 0x405c5503\nUI_DEV_CREATE = 0x5501\nUI_DEV_DESTROY = 0x5502\n\n# Event types\nEV_SYN = 0x00\nEV_ABS = 0x03\n\n# Sync codes\nSYN_REPORT = 0x00\n\n# ABS codes\nABS_MT_SLOT = 0x2f\nABS_MT_TRACKING_ID = 0x39\nABS_MT_POSITION_X = 0x35\nABS_MT_POSITION_Y = 0x36\n\n# Input properties\nINPUT_PROP_DIRECT = 0x01\n\n# uinput_abs_setup struct: __u16 code, struct input_absinfo { __s32 value, min, max, fuzz, flat, resolution }\n# = HiiiiiI -> but let's use the raw struct\n# Actually uinput_abs_setup = __u16 + padding + input_absinfo(6 x __s32)\n# struct uinput_abs_setup { __u16 code; __u16 pad; struct input_absinfo { __s32 value, minimum, maximum, fuzz, flat, resolution; }; };\nUI_ABS_SETUP = 0x405c5504\n\nUINPUT_MAX_NAME_SIZE = 80\n\ndef make_input_event(tv_sec, tv_usec, ev_type, code, value):\n # struct input_event uses struct timeval (long, long) + __u16 + __u16 + __s32\n # native long size handles 32/64 bit automatically\n return struct.pack('llHHi', tv_sec, tv_usec, ev_type, code, value)\n\ndef write_event(fd, ev_type, code, value):\n now = time.time()\n sec = int(now)\n usec = int((now - sec) * 1000000)\n os.write(fd, make_input_event(sec, usec, ev_type, code, value))\n\ndef syn_report(fd):\n write_event(fd, EV_SYN, SYN_REPORT, 0)\n\ndef touch_down(fd, slot, tracking_id, x, y):\n write_event(fd, EV_ABS, ABS_MT_SLOT, slot)\n write_event(fd, EV_ABS, ABS_MT_TRACKING_ID, tracking_id)\n write_event(fd, EV_ABS, ABS_MT_POSITION_X, x)\n write_event(fd, EV_ABS, ABS_MT_POSITION_Y, y)\n syn_report(fd)\n\ndef touch_move(fd, slot, x, y):\n write_event(fd, EV_ABS, ABS_MT_SLOT, slot)\n write_event(fd, EV_ABS, ABS_MT_POSITION_X, x)\n write_event(fd, EV_ABS, ABS_MT_POSITION_Y, y)\n syn_report(fd)\n\ndef touch_up(fd, slot):\n write_event(fd, EV_ABS, ABS_MT_SLOT, slot)\n write_event(fd, EV_ABS, ABS_MT_TRACKING_ID, -1)\n syn_report(fd)\n\ndef setup_uinput(screen_width, screen_height):\n fd = os.open('/dev/uinput', os.O_WRONLY | os.O_NONBLOCK)\n\n # Enable EV_ABS\n fcntl.ioctl(fd, UI_SET_EVBIT, EV_ABS)\n\n # Enable ABS axes\n fcntl.ioctl(fd, UI_SET_ABSBIT, ABS_MT_SLOT)\n fcntl.ioctl(fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID)\n fcntl.ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_X)\n fcntl.ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y)\n\n # Set INPUT_PROP_DIRECT for touchscreen\n fcntl.ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT)\n\n # Setup ABS axes with uinput_abs_setup\n # struct uinput_abs_setup { __u16 code; __u16 pad; struct input_absinfo { __s32 value, minimum, maximum, fuzz, flat, resolution; }; };\n abs_setup_fmt = 'HH6i'\n\n # ABS_MT_SLOT: 0 to 9\n data = struct.pack(abs_setup_fmt, ABS_MT_SLOT, 0, 0, 0, 9, 0, 0, 0)\n fcntl.ioctl(fd, UI_ABS_SETUP, data)\n\n # ABS_MT_TRACKING_ID: 0 to 65535\n data = struct.pack(abs_setup_fmt, ABS_MT_TRACKING_ID, 0, 0, 0, 65535, 0, 0, 0)\n fcntl.ioctl(fd, UI_ABS_SETUP, data)\n\n # ABS_MT_POSITION_X: 0 to screen_width - 1\n data = struct.pack(abs_setup_fmt, ABS_MT_POSITION_X, 0, 0, 0, screen_width - 1, 0, 0, 0)\n fcntl.ioctl(fd, UI_ABS_SETUP, data)\n\n # ABS_MT_POSITION_Y: 0 to screen_height - 1\n data = struct.pack(abs_setup_fmt, ABS_MT_POSITION_Y, 0, 0, 0, screen_height - 1, 0, 0, 0)\n fcntl.ioctl(fd, UI_ABS_SETUP, data)\n\n # uinput_setup: char name[UINPUT_MAX_NAME_SIZE]; struct input_id { __u16 bustype, vendor, product, version; };\n # struct input_id: HHH H (bustype=0x03 USB, vendor=0x1234, product=0x5678, version=1)\n # struct uinput_setup: 80s HHHH I (ff_effects_max)\n name = b'mcp-remotetouch'\n setup_data = struct.pack('80sHHHHI', name.ljust(UINPUT_MAX_NAME_SIZE, b'\\x00'), 0x03, 0x1234, 0x5678, 1, 0)\n fcntl.ioctl(fd, UI_DEV_SETUP, setup_data)\n\n # Create the device\n fcntl.ioctl(fd, UI_DEV_CREATE)\n\n # Give udev time to create the device node\n time.sleep(0.2)\n\n return fd\n\ndef send_response(cmd_id, status, message=None):\n resp = {'id': cmd_id, 'status': status}\n if message is not None:\n resp['message'] = message\n sys.stdout.write(json.dumps(resp) + '\\n')\n sys.stdout.flush()\n\ntracking_id_counter = 0\n\ndef next_tracking_id():\n global tracking_id_counter\n tracking_id_counter = (tracking_id_counter + 1) % 65536\n return tracking_id_counter\n\ndef handle_tap(fd, cmd):\n x = int(cmd['x'])\n y = int(cmd['y'])\n duration_ms = cmd.get('duration_ms', 50)\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(duration_ms / 1000.0)\n touch_up(fd, 0)\n\ndef handle_swipe(fd, cmd):\n x1 = int(cmd['x'])\n y1 = int(cmd['y'])\n x2 = int(cmd['x2'])\n y2 = int(cmd['y2'])\n duration_ms = cmd.get('duration_ms', 300)\n steps = cmd.get('steps', max(int(duration_ms / 15), 2))\n tid = next_tracking_id()\n\n touch_down(fd, 0, tid, x1, y1)\n for i in range(1, steps + 1):\n t = i / steps\n cx = int(x1 + (x2 - x1) * t)\n cy = int(y1 + (y2 - y1) * t)\n time.sleep(duration_ms / 1000.0 / steps)\n touch_move(fd, 0, cx, cy)\n touch_up(fd, 0)\n\ndef handle_long_press(fd, cmd):\n x = int(cmd['x'])\n y = int(cmd['y'])\n duration_ms = cmd.get('duration_ms', 800)\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(duration_ms / 1000.0)\n touch_up(fd, 0)\n\ndef handle_double_tap(fd, cmd):\n x = int(cmd['x'])\n y = int(cmd['y'])\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(0.05)\n touch_up(fd, 0)\n time.sleep(0.1)\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(0.05)\n touch_up(fd, 0)\n\ndef main():\n fd = None\n try:\n for line in sys.stdin:\n line = line.strip()\n if not line:\n continue\n try:\n cmd = json.loads(line)\n except json.JSONDecodeError as e:\n sys.stderr.write('Invalid JSON: ' + str(e) + '\\n')\n continue\n\n cmd_id = cmd.get('id', '?')\n cmd_type = cmd.get('type', '')\n\n try:\n if cmd_type == 'init':\n screen_width = cmd.get('screen_width', 800)\n screen_height = cmd.get('screen_height', 480)\n fd = setup_uinput(screen_width, screen_height)\n send_response(cmd_id, 'ready', 'uinput device created')\n elif cmd_type == 'shutdown':\n send_response(cmd_id, 'ok', 'shutting down')\n break\n elif fd is None:\n send_response(cmd_id, 'error', 'device not initialized, send init first')\n elif cmd_type == 'tap':\n handle_tap(fd, cmd)\n send_response(cmd_id, 'ok')\n elif cmd_type == 'swipe':\n handle_swipe(fd, cmd)\n send_response(cmd_id, 'ok')\n elif cmd_type == 'long_press':\n handle_long_press(fd, cmd)\n send_response(cmd_id, 'ok')\n elif cmd_type == 'double_tap':\n handle_double_tap(fd, cmd)\n send_response(cmd_id, 'ok')\n else:\n send_response(cmd_id, 'error', 'unknown command: ' + cmd_type)\n except PermissionError:\n send_response(cmd_id, 'error', 'Permission denied accessing /dev/uinput. Ensure user is in the input group: sudo usermod -aG input $USER')\n except Exception as e:\n send_response(cmd_id, 'error', str(e))\n finally:\n if fd is not None:\n try:\n fcntl.ioctl(fd, UI_DEV_DESTROY)\n os.close(fd)\n except Exception:\n pass\n\nif __name__ == '__main__':\n main()\n";
|
|
1
|
+
export declare const PYTHON_DAEMON_SCRIPT = "\nimport sys\nimport os\nimport json\nimport struct\nimport time\nimport glob\nimport re\n\n# Event types\nEV_SYN = 0x00\nEV_KEY = 0x01\nEV_ABS = 0x03\n\n# Sync codes\nSYN_REPORT = 0x00\n\n# Key codes\nBTN_TOUCH = 0x14a\n\n# ABS codes\nABS_X = 0x00\nABS_Y = 0x01\nABS_MT_SLOT = 0x2f\nABS_MT_TRACKING_ID = 0x39\nABS_MT_POSITION_X = 0x35\nABS_MT_POSITION_Y = 0x36\n\n# EVIOCGABS ioctl: _IOR('E', 0x40 + abs_code, struct input_absinfo)\n# struct input_absinfo = 6 x __s32 = 24 bytes\n# _IOR('E', N, 24) = (2 << 30) | (24 << 16) | (ord('E') << 8) | N\ndef EVIOCGABS(abs_code):\n return (2 << 30) | (24 << 16) | (ord('E') << 8) | (0x40 + abs_code)\n\ndef make_input_event(tv_sec, tv_usec, ev_type, code, value):\n return struct.pack('llHHi', tv_sec, tv_usec, ev_type, code, value)\n\ndef write_event(fd, ev_type, code, value):\n now = time.time()\n sec = int(now)\n usec = int((now - sec) * 1000000)\n os.write(fd, make_input_event(sec, usec, ev_type, code, value))\n\ndef syn_report(fd):\n write_event(fd, EV_SYN, SYN_REPORT, 0)\n\ndef touch_down(fd, slot, tracking_id, x, y):\n write_event(fd, EV_ABS, ABS_MT_SLOT, slot)\n write_event(fd, EV_ABS, ABS_MT_TRACKING_ID, tracking_id)\n write_event(fd, EV_ABS, ABS_MT_POSITION_X, x)\n write_event(fd, EV_ABS, ABS_MT_POSITION_Y, y)\n write_event(fd, EV_ABS, ABS_X, x)\n write_event(fd, EV_ABS, ABS_Y, y)\n write_event(fd, EV_KEY, BTN_TOUCH, 1)\n syn_report(fd)\n\ndef touch_move(fd, slot, x, y):\n write_event(fd, EV_ABS, ABS_MT_SLOT, slot)\n write_event(fd, EV_ABS, ABS_MT_POSITION_X, x)\n write_event(fd, EV_ABS, ABS_MT_POSITION_Y, y)\n write_event(fd, EV_ABS, ABS_X, x)\n write_event(fd, EV_ABS, ABS_Y, y)\n syn_report(fd)\n\ndef touch_up(fd, slot):\n write_event(fd, EV_ABS, ABS_MT_SLOT, slot)\n write_event(fd, EV_ABS, ABS_MT_TRACKING_ID, -1)\n write_event(fd, EV_KEY, BTN_TOUCH, 0)\n syn_report(fd)\n\ndef detect_screen_resolution():\n \"\"\"Detect screen resolution from framebuffer or DRM.\"\"\"\n # Try framebuffer first\n try:\n with open('/sys/class/graphics/fb0/virtual_size', 'r') as f:\n parts = f.read().strip().split(',')\n if len(parts) == 2:\n return int(parts[0]), int(parts[1])\n except Exception:\n pass\n\n # Try DRM\n try:\n import glob as g\n for mode_path in g.glob('/sys/class/drm/*/modes'):\n with open(mode_path, 'r') as f:\n line = f.readline().strip()\n if 'x' in line:\n parts = line.split('x')\n return int(parts[0]), int(parts[1])\n except Exception:\n pass\n\n return None, None\n\ndef find_touchscreen():\n \"\"\"Find the physical touchscreen event device by scanning /proc/bus/input/devices.\"\"\"\n try:\n with open('/proc/bus/input/devices', 'r') as f:\n content = f.read()\n except Exception:\n return None\n\n for block in content.split('\\n\\n'):\n lines = block.strip().split('\\n')\n name = ''\n handlers = ''\n props = ''\n evbits = ''\n absbits = ''\n for line in lines:\n if line.startswith('N: Name='):\n name = line.split('=', 1)[1].strip('\"')\n elif line.startswith('H: Handlers='):\n handlers = line.split('=', 1)[1]\n elif line.startswith('B: PROP='):\n props = line.split('=', 1)[1]\n elif line.startswith('B: EV='):\n evbits = line.split('=', 1)[1]\n elif line.startswith('B: ABS='):\n absbits = line.split('=', 1)[1]\n\n # Skip virtual devices (mcp-remotetouch)\n if 'mcp-remotetouch' in name:\n continue\n\n # Check for INPUT_PROP_DIRECT (bit 1 in PROP)\n try:\n prop_val = int(props.strip(), 16)\n except (ValueError, IndexError):\n prop_val = 0\n if not (prop_val & 0x02):\n continue\n\n # Check that it has ABS_MT_POSITION_X (bit 0x35) in ABS bitmask\n try:\n abs_parts = absbits.strip().split()\n abs_val = 0\n for i, part in enumerate(reversed(abs_parts)):\n abs_val |= int(part, 16) << (i * 32)\n except (ValueError, IndexError):\n abs_val = 0\n if not (abs_val & (1 << ABS_MT_POSITION_X)):\n continue\n\n # Extract event device number\n m = re.search(r'event(\\d+)', handlers)\n if m:\n return '/dev/input/event' + m.group(1)\n\n return None\n\nimport fcntl\n\ndef get_abs_range(fd, abs_code):\n \"\"\"Get the min/max range of an ABS axis using EVIOCGABS ioctl.\"\"\"\n try:\n buf = bytearray(24)\n fcntl.ioctl(fd, EVIOCGABS(abs_code), buf)\n value, minimum, maximum, fuzz, flat, resolution = struct.unpack('6i', buf)\n return minimum, maximum\n except Exception:\n return None, None\n\ndef open_touch_device(screen_width, screen_height):\n \"\"\"Open the physical touchscreen device for event injection.\"\"\"\n dev_path = find_touchscreen()\n if dev_path is None:\n raise RuntimeError('No physical touchscreen device found')\n\n fd = os.open(dev_path, os.O_WRONLY)\n\n # Read the actual ABS ranges from the device\n rd_fd = os.open(dev_path, os.O_RDONLY)\n x_min, x_max = get_abs_range(rd_fd, ABS_MT_POSITION_X)\n y_min, y_max = get_abs_range(rd_fd, ABS_MT_POSITION_Y)\n os.close(rd_fd)\n\n if x_max is None or y_max is None:\n x_max = screen_width - 1\n y_max = screen_height - 1\n x_min = 0\n y_min = 0\n\n return fd, dev_path, x_min, x_max, y_min, y_max\n\ndef send_response(cmd_id, status, message=None, screen_width=None, screen_height=None):\n resp = {'id': cmd_id, 'status': status}\n if message is not None:\n resp['message'] = message\n if screen_width is not None:\n resp['screen_width'] = screen_width\n if screen_height is not None:\n resp['screen_height'] = screen_height\n sys.stdout.write(json.dumps(resp) + '\\n')\n sys.stdout.flush()\n\ntracking_id_counter = 0\n\ndef next_tracking_id():\n global tracking_id_counter\n tracking_id_counter = (tracking_id_counter + 1) % 65536\n return tracking_id_counter\n\n# Coordinate mapping globals\ndev_x_min = 0\ndev_x_max = 0\ndev_y_min = 0\ndev_y_max = 0\nscr_w = 0\nscr_h = 0\n\ndef map_x(x):\n \"\"\"Map screen coordinate to device coordinate.\"\"\"\n return dev_x_min + int(x * (dev_x_max - dev_x_min) / (scr_w - 1))\n\ndef map_y(y):\n \"\"\"Map screen coordinate to device coordinate.\"\"\"\n return dev_y_min + int(y * (dev_y_max - dev_y_min) / (scr_h - 1))\n\ndef handle_tap(fd, cmd):\n x = map_x(int(cmd['x']))\n y = map_y(int(cmd['y']))\n duration_ms = cmd.get('duration_ms', 50)\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(duration_ms / 1000.0)\n touch_up(fd, 0)\n\ndef handle_swipe(fd, cmd):\n x1 = int(cmd['x'])\n y1 = int(cmd['y'])\n x2 = int(cmd['x2'])\n y2 = int(cmd['y2'])\n duration_ms = cmd.get('duration_ms', 300)\n steps = cmd.get('steps', max(int(duration_ms / 15), 2))\n tid = next_tracking_id()\n\n touch_down(fd, 0, tid, map_x(x1), map_y(y1))\n for i in range(1, steps + 1):\n t = i / steps\n cx = int(x1 + (x2 - x1) * t)\n cy = int(y1 + (y2 - y1) * t)\n time.sleep(duration_ms / 1000.0 / steps)\n touch_move(fd, 0, map_x(cx), map_y(cy))\n touch_up(fd, 0)\n\ndef handle_long_press(fd, cmd):\n x = map_x(int(cmd['x']))\n y = map_y(int(cmd['y']))\n duration_ms = cmd.get('duration_ms', 800)\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(duration_ms / 1000.0)\n touch_up(fd, 0)\n\ndef handle_double_tap(fd, cmd):\n x = map_x(int(cmd['x']))\n y = map_y(int(cmd['y']))\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(0.05)\n touch_up(fd, 0)\n time.sleep(0.1)\n tid = next_tracking_id()\n touch_down(fd, 0, tid, x, y)\n time.sleep(0.05)\n touch_up(fd, 0)\n\ndef main():\n global dev_x_min, dev_x_max, dev_y_min, dev_y_max, scr_w, scr_h\n fd = None\n try:\n for line in sys.stdin:\n line = line.strip()\n if not line:\n continue\n try:\n cmd = json.loads(line)\n except json.JSONDecodeError as e:\n sys.stderr.write('Invalid JSON: ' + str(e) + '\\n')\n continue\n\n cmd_id = cmd.get('id', '?')\n cmd_type = cmd.get('type', '')\n\n try:\n if cmd_type == 'init':\n scr_w = cmd.get('screen_width', 0)\n scr_h = cmd.get('screen_height', 0)\n if scr_w <= 0 or scr_h <= 0:\n det_w, det_h = detect_screen_resolution()\n if det_w and det_h:\n scr_w = det_w\n scr_h = det_h\n else:\n scr_w = scr_w or 800\n scr_h = scr_h or 480\n fd, dev_path, dev_x_min, dev_x_max, dev_y_min, dev_y_max = open_touch_device(scr_w, scr_h)\n send_response(cmd_id, 'ready', 'injecting into ' + dev_path, scr_w, scr_h)\n elif cmd_type == 'shutdown':\n send_response(cmd_id, 'ok', 'shutting down')\n break\n elif fd is None:\n send_response(cmd_id, 'error', 'device not initialized, send init first')\n elif cmd_type == 'tap':\n handle_tap(fd, cmd)\n send_response(cmd_id, 'ok')\n elif cmd_type == 'swipe':\n handle_swipe(fd, cmd)\n send_response(cmd_id, 'ok')\n elif cmd_type == 'long_press':\n handle_long_press(fd, cmd)\n send_response(cmd_id, 'ok')\n elif cmd_type == 'double_tap':\n handle_double_tap(fd, cmd)\n send_response(cmd_id, 'ok')\n else:\n send_response(cmd_id, 'error', 'unknown command: ' + cmd_type)\n except PermissionError:\n send_response(cmd_id, 'error', 'Permission denied. Run with sudo or ensure user is in the input group: sudo usermod -aG input $USER')\n except Exception as e:\n send_response(cmd_id, 'error', str(e))\n finally:\n if fd is not None:\n try:\n os.close(fd)\n except Exception:\n pass\n\nif __name__ == '__main__':\n main()\n";
|
package/build/python-daemon.js
CHANGED
|
@@ -3,44 +3,36 @@ import sys
|
|
|
3
3
|
import os
|
|
4
4
|
import json
|
|
5
5
|
import struct
|
|
6
|
-
import fcntl
|
|
7
6
|
import time
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
UI_SET_EVBIT = 0x40045564
|
|
11
|
-
UI_SET_ABSBIT = 0x40045567
|
|
12
|
-
UI_SET_PROPBIT = 0x4004556e
|
|
13
|
-
UI_DEV_SETUP = 0x405c5503
|
|
14
|
-
UI_DEV_CREATE = 0x5501
|
|
15
|
-
UI_DEV_DESTROY = 0x5502
|
|
7
|
+
import glob
|
|
8
|
+
import re
|
|
16
9
|
|
|
17
10
|
# Event types
|
|
18
11
|
EV_SYN = 0x00
|
|
12
|
+
EV_KEY = 0x01
|
|
19
13
|
EV_ABS = 0x03
|
|
20
14
|
|
|
21
15
|
# Sync codes
|
|
22
16
|
SYN_REPORT = 0x00
|
|
23
17
|
|
|
18
|
+
# Key codes
|
|
19
|
+
BTN_TOUCH = 0x14a
|
|
20
|
+
|
|
24
21
|
# ABS codes
|
|
22
|
+
ABS_X = 0x00
|
|
23
|
+
ABS_Y = 0x01
|
|
25
24
|
ABS_MT_SLOT = 0x2f
|
|
26
25
|
ABS_MT_TRACKING_ID = 0x39
|
|
27
26
|
ABS_MT_POSITION_X = 0x35
|
|
28
27
|
ABS_MT_POSITION_Y = 0x36
|
|
29
28
|
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# Actually uinput_abs_setup = __u16 + padding + input_absinfo(6 x __s32)
|
|
36
|
-
# struct uinput_abs_setup { __u16 code; __u16 pad; struct input_absinfo { __s32 value, minimum, maximum, fuzz, flat, resolution; }; };
|
|
37
|
-
UI_ABS_SETUP = 0x405c5504
|
|
38
|
-
|
|
39
|
-
UINPUT_MAX_NAME_SIZE = 80
|
|
29
|
+
# EVIOCGABS ioctl: _IOR('E', 0x40 + abs_code, struct input_absinfo)
|
|
30
|
+
# struct input_absinfo = 6 x __s32 = 24 bytes
|
|
31
|
+
# _IOR('E', N, 24) = (2 << 30) | (24 << 16) | (ord('E') << 8) | N
|
|
32
|
+
def EVIOCGABS(abs_code):
|
|
33
|
+
return (2 << 30) | (24 << 16) | (ord('E') << 8) | (0x40 + abs_code)
|
|
40
34
|
|
|
41
35
|
def make_input_event(tv_sec, tv_usec, ev_type, code, value):
|
|
42
|
-
# struct input_event uses struct timeval (long, long) + __u16 + __u16 + __s32
|
|
43
|
-
# native long size handles 32/64 bit automatically
|
|
44
36
|
return struct.pack('llHHi', tv_sec, tv_usec, ev_type, code, value)
|
|
45
37
|
|
|
46
38
|
def write_event(fd, ev_type, code, value):
|
|
@@ -57,73 +49,149 @@ def touch_down(fd, slot, tracking_id, x, y):
|
|
|
57
49
|
write_event(fd, EV_ABS, ABS_MT_TRACKING_ID, tracking_id)
|
|
58
50
|
write_event(fd, EV_ABS, ABS_MT_POSITION_X, x)
|
|
59
51
|
write_event(fd, EV_ABS, ABS_MT_POSITION_Y, y)
|
|
52
|
+
write_event(fd, EV_ABS, ABS_X, x)
|
|
53
|
+
write_event(fd, EV_ABS, ABS_Y, y)
|
|
54
|
+
write_event(fd, EV_KEY, BTN_TOUCH, 1)
|
|
60
55
|
syn_report(fd)
|
|
61
56
|
|
|
62
57
|
def touch_move(fd, slot, x, y):
|
|
63
58
|
write_event(fd, EV_ABS, ABS_MT_SLOT, slot)
|
|
64
59
|
write_event(fd, EV_ABS, ABS_MT_POSITION_X, x)
|
|
65
60
|
write_event(fd, EV_ABS, ABS_MT_POSITION_Y, y)
|
|
61
|
+
write_event(fd, EV_ABS, ABS_X, x)
|
|
62
|
+
write_event(fd, EV_ABS, ABS_Y, y)
|
|
66
63
|
syn_report(fd)
|
|
67
64
|
|
|
68
65
|
def touch_up(fd, slot):
|
|
69
66
|
write_event(fd, EV_ABS, ABS_MT_SLOT, slot)
|
|
70
67
|
write_event(fd, EV_ABS, ABS_MT_TRACKING_ID, -1)
|
|
68
|
+
write_event(fd, EV_KEY, BTN_TOUCH, 0)
|
|
71
69
|
syn_report(fd)
|
|
72
70
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
71
|
+
def detect_screen_resolution():
|
|
72
|
+
"""Detect screen resolution from framebuffer or DRM."""
|
|
73
|
+
# Try framebuffer first
|
|
74
|
+
try:
|
|
75
|
+
with open('/sys/class/graphics/fb0/virtual_size', 'r') as f:
|
|
76
|
+
parts = f.read().strip().split(',')
|
|
77
|
+
if len(parts) == 2:
|
|
78
|
+
return int(parts[0]), int(parts[1])
|
|
79
|
+
except Exception:
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
# Try DRM
|
|
83
|
+
try:
|
|
84
|
+
import glob as g
|
|
85
|
+
for mode_path in g.glob('/sys/class/drm/*/modes'):
|
|
86
|
+
with open(mode_path, 'r') as f:
|
|
87
|
+
line = f.readline().strip()
|
|
88
|
+
if 'x' in line:
|
|
89
|
+
parts = line.split('x')
|
|
90
|
+
return int(parts[0]), int(parts[1])
|
|
91
|
+
except Exception:
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
return None, None
|
|
95
|
+
|
|
96
|
+
def find_touchscreen():
|
|
97
|
+
"""Find the physical touchscreen event device by scanning /proc/bus/input/devices."""
|
|
98
|
+
try:
|
|
99
|
+
with open('/proc/bus/input/devices', 'r') as f:
|
|
100
|
+
content = f.read()
|
|
101
|
+
except Exception:
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
for block in content.split('\\n\\n'):
|
|
105
|
+
lines = block.strip().split('\\n')
|
|
106
|
+
name = ''
|
|
107
|
+
handlers = ''
|
|
108
|
+
props = ''
|
|
109
|
+
evbits = ''
|
|
110
|
+
absbits = ''
|
|
111
|
+
for line in lines:
|
|
112
|
+
if line.startswith('N: Name='):
|
|
113
|
+
name = line.split('=', 1)[1].strip('"')
|
|
114
|
+
elif line.startswith('H: Handlers='):
|
|
115
|
+
handlers = line.split('=', 1)[1]
|
|
116
|
+
elif line.startswith('B: PROP='):
|
|
117
|
+
props = line.split('=', 1)[1]
|
|
118
|
+
elif line.startswith('B: EV='):
|
|
119
|
+
evbits = line.split('=', 1)[1]
|
|
120
|
+
elif line.startswith('B: ABS='):
|
|
121
|
+
absbits = line.split('=', 1)[1]
|
|
122
|
+
|
|
123
|
+
# Skip virtual devices (mcp-remotetouch)
|
|
124
|
+
if 'mcp-remotetouch' in name:
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
# Check for INPUT_PROP_DIRECT (bit 1 in PROP)
|
|
128
|
+
try:
|
|
129
|
+
prop_val = int(props.strip(), 16)
|
|
130
|
+
except (ValueError, IndexError):
|
|
131
|
+
prop_val = 0
|
|
132
|
+
if not (prop_val & 0x02):
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
# Check that it has ABS_MT_POSITION_X (bit 0x35) in ABS bitmask
|
|
136
|
+
try:
|
|
137
|
+
abs_parts = absbits.strip().split()
|
|
138
|
+
abs_val = 0
|
|
139
|
+
for i, part in enumerate(reversed(abs_parts)):
|
|
140
|
+
abs_val |= int(part, 16) << (i * 32)
|
|
141
|
+
except (ValueError, IndexError):
|
|
142
|
+
abs_val = 0
|
|
143
|
+
if not (abs_val & (1 << ABS_MT_POSITION_X)):
|
|
144
|
+
continue
|
|
145
|
+
|
|
146
|
+
# Extract event device number
|
|
147
|
+
m = re.search(r'event(\\d+)', handlers)
|
|
148
|
+
if m:
|
|
149
|
+
return '/dev/input/event' + m.group(1)
|
|
150
|
+
|
|
151
|
+
return None
|
|
120
152
|
|
|
121
|
-
|
|
153
|
+
import fcntl
|
|
122
154
|
|
|
123
|
-
def
|
|
155
|
+
def get_abs_range(fd, abs_code):
|
|
156
|
+
"""Get the min/max range of an ABS axis using EVIOCGABS ioctl."""
|
|
157
|
+
try:
|
|
158
|
+
buf = bytearray(24)
|
|
159
|
+
fcntl.ioctl(fd, EVIOCGABS(abs_code), buf)
|
|
160
|
+
value, minimum, maximum, fuzz, flat, resolution = struct.unpack('6i', buf)
|
|
161
|
+
return minimum, maximum
|
|
162
|
+
except Exception:
|
|
163
|
+
return None, None
|
|
164
|
+
|
|
165
|
+
def open_touch_device(screen_width, screen_height):
|
|
166
|
+
"""Open the physical touchscreen device for event injection."""
|
|
167
|
+
dev_path = find_touchscreen()
|
|
168
|
+
if dev_path is None:
|
|
169
|
+
raise RuntimeError('No physical touchscreen device found')
|
|
170
|
+
|
|
171
|
+
fd = os.open(dev_path, os.O_WRONLY)
|
|
172
|
+
|
|
173
|
+
# Read the actual ABS ranges from the device
|
|
174
|
+
rd_fd = os.open(dev_path, os.O_RDONLY)
|
|
175
|
+
x_min, x_max = get_abs_range(rd_fd, ABS_MT_POSITION_X)
|
|
176
|
+
y_min, y_max = get_abs_range(rd_fd, ABS_MT_POSITION_Y)
|
|
177
|
+
os.close(rd_fd)
|
|
178
|
+
|
|
179
|
+
if x_max is None or y_max is None:
|
|
180
|
+
x_max = screen_width - 1
|
|
181
|
+
y_max = screen_height - 1
|
|
182
|
+
x_min = 0
|
|
183
|
+
y_min = 0
|
|
184
|
+
|
|
185
|
+
return fd, dev_path, x_min, x_max, y_min, y_max
|
|
186
|
+
|
|
187
|
+
def send_response(cmd_id, status, message=None, screen_width=None, screen_height=None):
|
|
124
188
|
resp = {'id': cmd_id, 'status': status}
|
|
125
189
|
if message is not None:
|
|
126
190
|
resp['message'] = message
|
|
191
|
+
if screen_width is not None:
|
|
192
|
+
resp['screen_width'] = screen_width
|
|
193
|
+
if screen_height is not None:
|
|
194
|
+
resp['screen_height'] = screen_height
|
|
127
195
|
sys.stdout.write(json.dumps(resp) + '\\n')
|
|
128
196
|
sys.stdout.flush()
|
|
129
197
|
|
|
@@ -134,9 +202,25 @@ def next_tracking_id():
|
|
|
134
202
|
tracking_id_counter = (tracking_id_counter + 1) % 65536
|
|
135
203
|
return tracking_id_counter
|
|
136
204
|
|
|
205
|
+
# Coordinate mapping globals
|
|
206
|
+
dev_x_min = 0
|
|
207
|
+
dev_x_max = 0
|
|
208
|
+
dev_y_min = 0
|
|
209
|
+
dev_y_max = 0
|
|
210
|
+
scr_w = 0
|
|
211
|
+
scr_h = 0
|
|
212
|
+
|
|
213
|
+
def map_x(x):
|
|
214
|
+
"""Map screen coordinate to device coordinate."""
|
|
215
|
+
return dev_x_min + int(x * (dev_x_max - dev_x_min) / (scr_w - 1))
|
|
216
|
+
|
|
217
|
+
def map_y(y):
|
|
218
|
+
"""Map screen coordinate to device coordinate."""
|
|
219
|
+
return dev_y_min + int(y * (dev_y_max - dev_y_min) / (scr_h - 1))
|
|
220
|
+
|
|
137
221
|
def handle_tap(fd, cmd):
|
|
138
|
-
x = int(cmd['x'])
|
|
139
|
-
y = int(cmd['y'])
|
|
222
|
+
x = map_x(int(cmd['x']))
|
|
223
|
+
y = map_y(int(cmd['y']))
|
|
140
224
|
duration_ms = cmd.get('duration_ms', 50)
|
|
141
225
|
tid = next_tracking_id()
|
|
142
226
|
touch_down(fd, 0, tid, x, y)
|
|
@@ -152,18 +236,18 @@ def handle_swipe(fd, cmd):
|
|
|
152
236
|
steps = cmd.get('steps', max(int(duration_ms / 15), 2))
|
|
153
237
|
tid = next_tracking_id()
|
|
154
238
|
|
|
155
|
-
touch_down(fd, 0, tid, x1, y1)
|
|
239
|
+
touch_down(fd, 0, tid, map_x(x1), map_y(y1))
|
|
156
240
|
for i in range(1, steps + 1):
|
|
157
241
|
t = i / steps
|
|
158
242
|
cx = int(x1 + (x2 - x1) * t)
|
|
159
243
|
cy = int(y1 + (y2 - y1) * t)
|
|
160
244
|
time.sleep(duration_ms / 1000.0 / steps)
|
|
161
|
-
touch_move(fd, 0, cx, cy)
|
|
245
|
+
touch_move(fd, 0, map_x(cx), map_y(cy))
|
|
162
246
|
touch_up(fd, 0)
|
|
163
247
|
|
|
164
248
|
def handle_long_press(fd, cmd):
|
|
165
|
-
x = int(cmd['x'])
|
|
166
|
-
y = int(cmd['y'])
|
|
249
|
+
x = map_x(int(cmd['x']))
|
|
250
|
+
y = map_y(int(cmd['y']))
|
|
167
251
|
duration_ms = cmd.get('duration_ms', 800)
|
|
168
252
|
tid = next_tracking_id()
|
|
169
253
|
touch_down(fd, 0, tid, x, y)
|
|
@@ -171,8 +255,8 @@ def handle_long_press(fd, cmd):
|
|
|
171
255
|
touch_up(fd, 0)
|
|
172
256
|
|
|
173
257
|
def handle_double_tap(fd, cmd):
|
|
174
|
-
x = int(cmd['x'])
|
|
175
|
-
y = int(cmd['y'])
|
|
258
|
+
x = map_x(int(cmd['x']))
|
|
259
|
+
y = map_y(int(cmd['y']))
|
|
176
260
|
tid = next_tracking_id()
|
|
177
261
|
touch_down(fd, 0, tid, x, y)
|
|
178
262
|
time.sleep(0.05)
|
|
@@ -184,6 +268,7 @@ def handle_double_tap(fd, cmd):
|
|
|
184
268
|
touch_up(fd, 0)
|
|
185
269
|
|
|
186
270
|
def main():
|
|
271
|
+
global dev_x_min, dev_x_max, dev_y_min, dev_y_max, scr_w, scr_h
|
|
187
272
|
fd = None
|
|
188
273
|
try:
|
|
189
274
|
for line in sys.stdin:
|
|
@@ -201,10 +286,18 @@ def main():
|
|
|
201
286
|
|
|
202
287
|
try:
|
|
203
288
|
if cmd_type == 'init':
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
289
|
+
scr_w = cmd.get('screen_width', 0)
|
|
290
|
+
scr_h = cmd.get('screen_height', 0)
|
|
291
|
+
if scr_w <= 0 or scr_h <= 0:
|
|
292
|
+
det_w, det_h = detect_screen_resolution()
|
|
293
|
+
if det_w and det_h:
|
|
294
|
+
scr_w = det_w
|
|
295
|
+
scr_h = det_h
|
|
296
|
+
else:
|
|
297
|
+
scr_w = scr_w or 800
|
|
298
|
+
scr_h = scr_h or 480
|
|
299
|
+
fd, dev_path, dev_x_min, dev_x_max, dev_y_min, dev_y_max = open_touch_device(scr_w, scr_h)
|
|
300
|
+
send_response(cmd_id, 'ready', 'injecting into ' + dev_path, scr_w, scr_h)
|
|
208
301
|
elif cmd_type == 'shutdown':
|
|
209
302
|
send_response(cmd_id, 'ok', 'shutting down')
|
|
210
303
|
break
|
|
@@ -225,13 +318,12 @@ def main():
|
|
|
225
318
|
else:
|
|
226
319
|
send_response(cmd_id, 'error', 'unknown command: ' + cmd_type)
|
|
227
320
|
except PermissionError:
|
|
228
|
-
send_response(cmd_id, 'error', 'Permission denied
|
|
321
|
+
send_response(cmd_id, 'error', 'Permission denied. Run with sudo or ensure user is in the input group: sudo usermod -aG input $USER')
|
|
229
322
|
except Exception as e:
|
|
230
323
|
send_response(cmd_id, 'error', str(e))
|
|
231
324
|
finally:
|
|
232
325
|
if fd is not None:
|
|
233
326
|
try:
|
|
234
|
-
fcntl.ioctl(fd, UI_DEV_DESTROY)
|
|
235
327
|
os.close(fd)
|
|
236
328
|
except Exception:
|
|
237
329
|
pass
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-daemon.js","sourceRoot":"","sources":["../src/python-daemon.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG
|
|
1
|
+
{"version":3,"file":"python-daemon.js","sourceRoot":"","sources":["../src/python-daemon.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4UnC,CAAC"}
|
|
@@ -16,8 +16,7 @@ export class SshTouchSessionManager {
|
|
|
16
16
|
pending: null,
|
|
17
17
|
};
|
|
18
18
|
this.sessions.set(sessionId, session);
|
|
19
|
-
const
|
|
20
|
-
const pythonCmd = `python3 -u -c "import base64,sys;exec(base64.b64decode(sys.argv[1]))" "${scriptBase64}"`;
|
|
19
|
+
const pythonCmd = `python3 -u -c "import sys,base64;exec(base64.b64decode(input()))"`;
|
|
21
20
|
const remoteCmd = config.useSudo ? `sudo ${pythonCmd}` : pythonCmd;
|
|
22
21
|
const sshArgs = [
|
|
23
22
|
"-T",
|
|
@@ -35,6 +34,9 @@ export class SshTouchSessionManager {
|
|
|
35
34
|
stdio: ["pipe", "pipe", "pipe"],
|
|
36
35
|
});
|
|
37
36
|
session.process = proc;
|
|
37
|
+
// Send the daemon script via stdin to avoid ARG_MAX limits on embedded systems
|
|
38
|
+
const scriptBase64 = Buffer.from(PYTHON_DAEMON_SCRIPT).toString("base64");
|
|
39
|
+
proc.stdin.write(scriptBase64 + "\n");
|
|
38
40
|
const rl = createInterface({ input: proc.stdout });
|
|
39
41
|
rl.on("line", (line) => {
|
|
40
42
|
let resp;
|
|
@@ -83,6 +85,13 @@ export class SshTouchSessionManager {
|
|
|
83
85
|
this.cleanup(session);
|
|
84
86
|
throw new Error(`Daemon init failed: ${resp.message}`);
|
|
85
87
|
}
|
|
88
|
+
// Update config with daemon-detected screen resolution
|
|
89
|
+
if (resp.screen_width) {
|
|
90
|
+
session.config.screenWidth = resp.screen_width;
|
|
91
|
+
}
|
|
92
|
+
if (resp.screen_height) {
|
|
93
|
+
session.config.screenHeight = resp.screen_height;
|
|
94
|
+
}
|
|
86
95
|
session.active = true;
|
|
87
96
|
}
|
|
88
97
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssh-touch-session.js","sourceRoot":"","sources":["../src/ssh-touch-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,oBAAoB,GAAG,KAAK,CAAC;AACnC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAEjC,MAAM,OAAO,sBAAsB;IACzB,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEnD,KAAK,CAAC,OAAO,CAAC,MAAqB;QACjC,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAiB;YAC5B,EAAE,EAAE,SAAS;YACb,MAAM;YACN,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI;SACd,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEtC,MAAM,
|
|
1
|
+
{"version":3,"file":"ssh-touch-session.js","sourceRoot":"","sources":["../src/ssh-touch-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,oBAAoB,GAAG,KAAK,CAAC;AACnC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAEjC,MAAM,OAAO,sBAAsB;IACzB,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEnD,KAAK,CAAC,OAAO,CAAC,MAAqB;QACjC,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAiB;YAC5B,EAAE,EAAE,SAAS;YACb,MAAM;YACN,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI;SACd,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEtC,MAAM,SAAS,GAAG,mEAAmE,CAAC;QACtF,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAEnE,MAAM,OAAO,GAAa;YACxB,IAAI;YACJ,IAAI,EAAE,kCAAkC;YACxC,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,wBAAwB;YAC9B,IAAI,EAAE,uBAAuB;YAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;SAC1B,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;QAEzD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE;YACjC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QAEH,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QAEvB,+EAA+E;QAC/E,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1E,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;QAEtC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACnD,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YAC7B,IAAI,IAAoB,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;YACT,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;gBAC1B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACvC,SAAS,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAmB,EAAE,EAAE;YACvC,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;YACvB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;gBAC1B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,IAAI,aAAa,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC9B,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;YACvB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;gBAC1B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,2CAA2C;QAC3C,MAAM,OAAO,GAAkB;YAC7B,EAAE,EAAE,OAAO,GAAG,SAAS;YACvB,IAAI,EAAE,MAAM;YACZ,YAAY,EAAE,MAAM,CAAC,WAAW;YAChC,aAAa,EAAE,MAAM,CAAC,YAAY;SACnC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC;YAC/E,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACzD,CAAC;YACD,uDAAuD;YACvD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;YACjD,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,OAAO,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;YACnD,CAAC;YACD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAChC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,SAAiB,EAAE,GAAkB;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAC/D,CAAC;IAEO,cAAc,CAAC,OAAqB,EAAE,GAAkB,EAAE,SAAiB;QACjF,OAAO,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrD,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,SAAS,IAAI,CAAC,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,OAAO,CAAC,OAAO,GAAG;gBAChB,OAAO,EAAE,CAAC,IAAoB,EAAE,EAAE;oBAChC,YAAY,CAAC,KAAK,CAAC,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;gBACD,MAAM,EAAE,CAAC,GAAU,EAAE,EAAE;oBACrB,YAAY,CAAC,KAAK,CAAC,CAAC;oBACpB,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;aACF,CAAC;YAEF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YACxC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,WAAW,GAAkB;oBACjC,EAAE,EAAE,WAAW,GAAG,SAAS;oBAC3B,IAAI,EAAE,UAAU;iBACjB,CAAC;gBACF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAEO,OAAO,CAAC,OAAqB;QACnC,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;QACvB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,YAAY;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpD,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;YAC1D,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;CACF"}
|
package/build/types.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ export interface SessionConfig {
|
|
|
4
4
|
user: string;
|
|
5
5
|
port: number;
|
|
6
6
|
sshKey?: string;
|
|
7
|
-
screenWidth
|
|
8
|
-
screenHeight
|
|
7
|
+
screenWidth?: number;
|
|
8
|
+
screenHeight?: number;
|
|
9
9
|
useSudo: boolean;
|
|
10
10
|
}
|
|
11
11
|
export interface TouchSession {
|
|
@@ -35,4 +35,6 @@ export interface DaemonResponse {
|
|
|
35
35
|
id: string;
|
|
36
36
|
status: "ok" | "error" | "ready";
|
|
37
37
|
message?: string;
|
|
38
|
+
screen_width?: number;
|
|
39
|
+
screen_height?: number;
|
|
38
40
|
}
|