From 37860093b0e0a767344673717fa0896c0e22e2ea Mon Sep 17 00:00:00 2001 From: Peter Hutterer <peter.hutterer@who-t.net> Date: Wed, 23 Sep 2020 19:36:20 +1000 Subject: [PATCH] examples: add an example for a fake tablet Testing tablets without acces to the hw is reasonably common, let's provide a simple example that can be extended to the user's liking. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> --- examples/fake-tablet.py | 130 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100755 examples/fake-tablet.py diff --git a/examples/fake-tablet.py b/examples/fake-tablet.py new file mode 100755 index 0000000..f8b91d5 --- /dev/null +++ b/examples/fake-tablet.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +# +# Fake tablet emulator + +import sys +import libevdev +from libevdev import InputEvent, InputAbsInfo +import time + + +def prox_in(x, y, z=0, tilt=(0, 0), pressure=100, distance=0): + return [ + InputEvent(libevdev.EV_ABS.ABS_X, x), + InputEvent(libevdev.EV_ABS.ABS_Y, y), + InputEvent(libevdev.EV_ABS.ABS_Z, z), + # Note: wheel for pen/eraser must be 0 + InputEvent(libevdev.EV_ABS.ABS_WHEEL, 0), + InputEvent(libevdev.EV_ABS.ABS_PRESSURE, pressure), + InputEvent(libevdev.EV_ABS.ABS_DISTANCE, distance), + InputEvent(libevdev.EV_ABS.ABS_TILT_X, tilt[0]), + InputEvent(libevdev.EV_ABS.ABS_TILT_Y, tilt[1]), + InputEvent(libevdev.EV_ABS.ABS_MISC, 2083), + InputEvent(libevdev.EV_MSC.MSC_SERIAL, 297797542), + # Change to BTN_TOOL_RUBBER for the eraser end + InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1), + InputEvent(libevdev.EV_SYN.SYN_REPORT, 0), + ] + + +def prox_out(): + return [ + InputEvent(libevdev.EV_ABS.ABS_X, 0), + InputEvent(libevdev.EV_ABS.ABS_Y, 0), + InputEvent(libevdev.EV_ABS.ABS_Z, 0), + InputEvent(libevdev.EV_ABS.ABS_WHEEL, 0), + InputEvent(libevdev.EV_ABS.ABS_PRESSURE, 0), + InputEvent(libevdev.EV_ABS.ABS_DISTANCE, 0), + InputEvent(libevdev.EV_ABS.ABS_TILT_X, 0), + InputEvent(libevdev.EV_ABS.ABS_TILT_Y, 0), + InputEvent(libevdev.EV_ABS.ABS_MISC, 0), + InputEvent(libevdev.EV_MSC.MSC_SERIAL, 297797542), + InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0), + InputEvent(libevdev.EV_SYN.SYN_REPORT, 0), + ] + + +def motion(x, y, z=0, tilt=(0, 0), pressure=100, distance=0): + return [ + InputEvent(libevdev.EV_ABS.ABS_X, x), + InputEvent(libevdev.EV_ABS.ABS_Y, y), + InputEvent(libevdev.EV_ABS.ABS_Z, z), + InputEvent(libevdev.EV_ABS.ABS_WHEEL, 0), + InputEvent(libevdev.EV_ABS.ABS_PRESSURE, pressure), + InputEvent(libevdev.EV_ABS.ABS_DISTANCE, distance), + InputEvent(libevdev.EV_ABS.ABS_TILT_X, tilt[0]), + InputEvent(libevdev.EV_ABS.ABS_TILT_Y, tilt[1]), + InputEvent(libevdev.EV_MSC.MSC_SERIAL, 297797542), + InputEvent(libevdev.EV_SYN.SYN_REPORT, 0), + ] + + +def main(args): + dev = libevdev.Device() + dev.name = "Wacom Cintiq Pro 16 Pen" + dev.id = {'bustype': 0x3, + 'vendor': 0x56a, + 'product': 0x350, + 'version': 0xb} + dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN) + dev.enable(libevdev.EV_KEY.BTN_TOOL_RUBBER) + dev.enable(libevdev.EV_KEY.BTN_TOOL_BRUSH) + dev.enable(libevdev.EV_KEY.BTN_TOOL_PENCIL) + dev.enable(libevdev.EV_KEY.BTN_TOOL_AIRBRUSH) + dev.enable(libevdev.EV_KEY.BTN_TOUCH) + dev.enable(libevdev.EV_KEY.BTN_STYLUS) + dev.enable(libevdev.EV_KEY.BTN_STYLUS2) + dev.enable(libevdev.EV_KEY.BTN_STYLUS3) + dev.enable(libevdev.EV_MSC.MSC_SERIAL) + dev.enable(libevdev.INPUT_PROP_DIRECT) + + a = InputAbsInfo(minimum=0, maximum=69920, resolution=200) + dev.enable(libevdev.EV_ABS.ABS_X, data=a) + a = InputAbsInfo(minimum=0, maximum=39980, resolution=200) + dev.enable(libevdev.EV_ABS.ABS_Y, data=a) + a = InputAbsInfo(minimum=-900, maximum=899, resolution=287) + dev.enable(libevdev.EV_ABS.ABS_Z, data=a) + a = InputAbsInfo(minimum=0, maximum=2047) + dev.enable(libevdev.EV_ABS.ABS_WHEEL, data=a) + a = InputAbsInfo(minimum=0, maximum=8196) + dev.enable(libevdev.EV_ABS.ABS_PRESSURE, data=a) + a = InputAbsInfo(minimum=0, maximum=63) + dev.enable(libevdev.EV_ABS.ABS_DISTANCE, data=a) + a = InputAbsInfo(minimum=-64, maximum=63, resolution=57) + dev.enable(libevdev.EV_ABS.ABS_TILT_X, data=a) + dev.enable(libevdev.EV_ABS.ABS_TILT_Y, data=a) + a = InputAbsInfo(minimum=0, maximum=0) + dev.enable(libevdev.EV_ABS.ABS_MISC, data=a) + + try: + uinput = dev.create_uinput_device() + print("New device at {} ({})".format(uinput.devnode, uinput.syspath)) + + # Sleep for a bit so udev, libinput, Xorg, Wayland, ... all have had + # a chance to see the device and initialize it. Otherwise the event + # will be sent by the kernel but nothing is ready to listen to the + # device yet. + time.sleep(1) + + x, y = 3000, 5000 + + events = prox_in(x, y) + uinput.send_events(events) + time.sleep(0.012) + + for _ in range(5): + x += 1000 + y += 1000 + events = motion(x, y) + uinput.send_events(events) + time.sleep(0.012) + + events = prox_out() + uinput.send_events(events) + time.sleep(0.012) + except OSError as e: + print(e) + + +if __name__ == "__main__": + main(sys.argv) -- GitLab