From bd8123e459aa134093186cebdf3dbba901584517 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 4 Sep 2019 13:51:07 +1000 Subject: [PATCH] tools: install local quirks during libinput replay The quirks for each device are listed in the recording but they may not apply during libinput replay (e.g. for DMI matches). Work around this by writing out the local-overrides.quirks file before initializing the devices. This way we're guaranteed that the device is identical as on the reporter's machine. Signed-off-by: Peter Hutterer --- tools/libinput-replay | 46 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/tools/libinput-replay b/tools/libinput-replay index f41ef18f..314b98cd 100755 --- a/tools/libinput-replay +++ b/tools/libinput-replay @@ -28,6 +28,7 @@ import sys import time import multiprocessing import argparse +from pathlib import Path try: import libevdev @@ -174,6 +175,43 @@ def loop(args, recording): del processes +def create_device_quirk(device): + quirks = fetch(device, 'quirks') + if not quirks: + return None + # Where the device has a quirk, we match on name, vendor and product. + # That's the best match we can assemble here from the info we have. + evdev = fetch(device, 'evdev') + name = fetch(evdev, 'name') + id = fetch(evdev, 'id') + quirk = ('[libinput-replay {name}]\n' + 'MatchName={name}\n' + 'MatchVendor=0x{id[1]:04X}\n' + 'MatchProduct=0x{id[2]:04X}\n').format(name=name, id=id) + quirk += '\n'.join(quirks) + return quirk + + +def setup_quirks(recording): + devices = fetch(recording, 'devices') + overrides = None + quirks = [create_device_quirk(d) for d in devices if fetch(d, 'quirks')] + if not quirks: + return None + + overrides = Path('/etc/libinput/local-overrides.quirks') + if overrides.exists(): + print('{} exists, please move it out of the way first'.format(overrides), file=sys.stderr) + sys.exit(1) + + with overrides.open('w+') as fd: + fd.write('# This file was generated by libinput replay\n') + fd.write('# Unless libinput replay is running right now, remove this file.\n') + fd.write('\n\n'.join(quirks)) + + return overrides + + def check_file(recording): version = fetch(recording, 'version') if version != SUPPORTED_FILE_VERSION: @@ -194,10 +232,13 @@ def main(): parser.add_argument('--verbose', action='store_true') args = parser.parse_args() + quirks_file = None + try: with open(args.recording) as f: y = yaml.safe_load(f) - check_file(recording) + check_file(y) + quirks_file = setup_quirks(y) loop(args, y) except KeyboardInterrupt: pass @@ -205,6 +246,9 @@ def main(): error('Error: failed to open device: {}'.format(e)) except YamlException as e: error('Error: failed to parse recording: {}'.format(e)) + finally: + if quirks_file: + quirks_file.unlink() if __name__ == '__main__':