diff --git a/scripts/xteink-type-keyboard.py b/scripts/xteink-type-keyboard.py new file mode 100755 index 0000000000..2488d74b56 --- /dev/null +++ b/scripts/xteink-type-keyboard.py @@ -0,0 +1,81 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = [] +# /// + +import json +import socket +import sys +import time + +state, mode, text = sys.argv[1:4] +buttons = { + "up": ("/machine/adc", "adci[2]", 2242, 4095), + "down": ("/machine/adc", "adci[2]", 5, 4095), + "left": ("/machine/adc", "adci[1]", 1493, 4095), + "right": ("/machine/adc", "adci[1]", 5, 4095), + "select": ("/machine/adc", "adci[1]", 2694, 4095), +} +rows = ["1234567890", "qwertyuiop", "asdfghjkl", "zxcvbnm"] +widths = [10, 10, 9, 9, 6 if mode == "url" else 5] +keys = {char: (row, col) for row, chars in enumerate(rows) for col, char in enumerate(chars)} +if mode == "url": + keys.update({":": (4, 1), "/": (4, 2), ".": (4, 3)}) + ok = (4, 5) +else: + ok = (4, 4) + +sock = socket.socket(socket.AF_UNIX) +sock.connect(f"{state}/qmp.sock") +stream = sock.makefile("rw") +json.loads(stream.readline()) + +def command(execute, arguments=None): + payload = {"execute": execute} + if arguments is not None: + payload["arguments"] = arguments + stream.write(json.dumps(payload) + "\n") + stream.flush() + while True: + response = json.loads(stream.readline()) + if "return" in response or "error" in response: + if "error" in response: + raise RuntimeError(response["error"]) + return + +command("qmp_capabilities") + +def press(name): + path, prop, pressed, released = buttons[name] + command("qom-set", {"path": path, "property": prop, "value": pressed}) + time.sleep(0.06) + command("qom-set", {"path": path, "property": prop, "value": released}) + time.sleep(1 if name == "select" else 0.12) + +row = col = 0 + +def move_to(target_row, target_col): + global row, col + while row: + old_width = widths[row] + press("up") + row -= 1 + col = col * widths[row] // old_width + while col: + press("left") + col -= 1 + while row < target_row: + old_width = widths[row] + press("down") + row += 1 + col = col * widths[row] // old_width + while col < target_col: + press("right") + col += 1 + +for char in text.lower(): + move_to(*keys[char]) + press("select") +move_to(*ok) +press("select")