summaryrefslogtreecommitdiff
path: root/tests/helpers/run_x11_tablet.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/helpers/run_x11_tablet.py')
-rw-r--r--tests/helpers/run_x11_tablet.py124
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/helpers/run_x11_tablet.py b/tests/helpers/run_x11_tablet.py
new file mode 100644
index 0000000..cdd36ab
--- /dev/null
+++ b/tests/helpers/run_x11_tablet.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+"""Run pen pressure through Xorg's virtual input driver and the example app."""
+
+import os
+from pathlib import Path
+import subprocess
+import sys
+import tempfile
+import time
+
+
+def main():
+ xorg, test = sys.argv[1:]
+ module_path = os.environ.get("YASL_XORG_MODULE_PATH")
+ if not module_path:
+ module_path = subprocess.check_output(
+ [xorg, "-showDefaultModulePath"], text=True, timeout=5).strip()
+ if any(c in module_path for c in ('"', "\n", "\r")):
+ raise ValueError("Invalid Xorg module path")
+ paths = [Path(path) for path in module_path.split(",")]
+ for module in ("drivers/dummy_drv.so", "input/inputtest_drv.so"):
+ if not any((path / module).is_file() for path in paths):
+ raise RuntimeError(f"Missing Xorg module: {module}")
+ with tempfile.TemporaryDirectory(prefix="yasl-tablet-") as directory:
+ root = Path(directory)
+ pen, eraser = root / "pen.sock", root / "eraser.sock"
+ config = root / "xorg.conf"
+ config.write_text(f'''
+Section "ServerFlags"
+ Option "AutoAddDevices" "false"
+ Option "AutoAddGPU" "false"
+ Option "DontVTSwitch" "true"
+EndSection
+Section "Files"
+ ModulePath "{module_path}"
+EndSection
+Section "Module"
+ Disable "glx"
+EndSection
+Section "Device"
+ Identifier "virtual-video"
+ Driver "dummy"
+ VideoRam 16384
+EndSection
+Section "Monitor"
+ Identifier "virtual-monitor"
+ HorizSync 5.0 - 1000.0
+ VertRefresh 5.0 - 200.0
+ Modeline "1200x900" 96.96 1200 1280 1408 1616 900 901 904 932
+EndSection
+Section "Screen"
+ Identifier "virtual-screen"
+ Device "virtual-video"
+ Monitor "virtual-monitor"
+ DefaultDepth 24
+ SubSection "Display"
+ Depth 24
+ Modes "1200x900"
+ EndSubSection
+EndSection
+Section "InputDevice"
+ Identifier "YASL Test Pen"
+ Driver "inputtest"
+ Option "DeviceType" "PointerAbsoluteProximity"
+ Option "PointerHasPressure" "true"
+ Option "SocketPath" "{pen}"
+EndSection
+Section "InputDevice"
+ Identifier "YASL Test Reverse Tool"
+ Driver "inputtest"
+ Option "DeviceType" "PointerAbsoluteProximity"
+ Option "PointerHasPressure" "true"
+ Option "SocketPath" "{eraser}"
+EndSection
+Section "InputDevice"
+ Identifier "YASL Test Keyboard"
+ Driver "inputtest"
+ Option "DeviceType" "Keyboard"
+ Option "SocketPath" "{root / 'keyboard.sock'}"
+EndSection
+Section "ServerLayout"
+ Identifier "virtual-layout"
+ Screen "virtual-screen"
+ InputDevice "YASL Test Pen" "CorePointer"
+ InputDevice "YASL Test Reverse Tool" "SendCoreEvents"
+ InputDevice "YASL Test Keyboard" "CoreKeyboard"
+EndSection
+''')
+ display_file = root / "display"
+ with display_file.open("w") as display_fd, (root / "server.log").open("w+") as log:
+ server = subprocess.Popen([
+ xorg, "-config", str(config), "-logfile", str(root / "xorg.log"),
+ "-displayfd", str(display_fd.fileno()), "-noreset", "-nolisten", "tcp",
+ "-novtswitch", "-sharevts", "-seat", f"yasl-tablet-test-{os.getpid()}",
+ ], pass_fds=(display_fd.fileno(),), stdout=log, stderr=log)
+ try:
+ deadline = time.monotonic() + 10
+ while not (display_file.read_text().strip() and pen.is_socket() and eraser.is_socket()):
+ if server.poll() is not None:
+ raise RuntimeError("The virtual X server stopped")
+ if time.monotonic() >= deadline:
+ raise TimeoutError("The virtual X server did not start")
+ time.sleep(0.02)
+ env = os.environ.copy()
+ env["DISPLAY"] = ":" + display_file.read_text().strip()
+ env.pop("XAUTHORITY", None)
+ subprocess.run([test, str(pen), str(eraser)], env=env, check=True, timeout=10)
+ except BaseException:
+ log.flush()
+ log.seek(0, 2)
+ log.seek(max(0, log.tell() - 8000))
+ print(log.read(), file=sys.stderr)
+ raise
+ finally:
+ server.terminate()
+ try:
+ server.wait(timeout=5)
+ except subprocess.TimeoutExpired:
+ server.kill()
+ server.wait()
+
+
+if __name__ == "__main__":
+ main()