#!/usr/bin/env python3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Description: # # Class for injecting input events to linux 'evdev' input devices. # # Provides evemu-play-like functionality if run from the command line: # $ input_event_player.py -d /dev/input/event6 """ Playback input events on a linux input device. """ from __future__ import division from __future__ import print_function import glob import os.path import re import time from optparse import OptionParser # Try to import from the autotest_lib structure. If it fails try the default. # If this script was run outside of autotest the "except" would be the flow. # If run within, the "try" is the flow. try: from autotest_lib.client.bin.input.input_device import InputDevice, InputEvent except ImportError: from input_device import InputDevice, InputEvent class InputEventPlayer: """ Linux evdev input event player. An "evdev" input event player injects a stream of "input events" to kernel evdev driver. With this player, we could easily playback an input event file which was recorded with the tool evemu-record previously. """ def __init__(self): self.tv_sec = None self.tv_usec = None def playback(self, device, gesture_file): """ Play the events in gesture_file on device. Keyword arguments: device -- the InputDevice device object gesture_file -- the name of the event file recorded previously """ if not device: raise event_str = 'E: (\d+)\.(\d+) ([0-9a-f]{4}) ([0-9a-f]{4}) ([-]?\d+)' event_pattern = re.compile(event_str) for line in open(gesture_file, 'rt'): m = event_pattern.match(line) if not m: raise event = InputEvent(int(m.group(1)), int(m.group(2)), int(m.group(3), 16), int(m.group(4), 16), int(m.group(5))) if not self.tv_sec: self.tv_sec = event.tv_sec self.tv_usec = event.tv_usec delta = event.tv_sec - self.tv_sec delta += ((event.tv_usec - self.tv_usec) / 1000000.0) # Sleep only if the event is 0.05 ms later than the previous one if delta > 0.0000500: time.sleep(delta) self.tv_sec = event.tv_sec self.tv_usec = event.tv_usec event.write(device.f) if __name__ == '__main__': parser = OptionParser() parser.add_option('-d', '--devpath', dest='devpath', default='', help='device path (/dev/input/event0)') parser.add_option('-t', '--touchpad', action='store_true', dest='touchpad', default=False, help='Find and use first touchpad device') parser.add_option('-f', '--file', action='store', dest='gesture_file', help='Event file to playback') (options, args) = parser.parse_args() if options.touchpad: for evdev in glob.glob('/dev/input/event*'): device = InputDevice(evdev) if device.is_touchpad(): break else: print('Can not find a touchpad device') exit() elif not os.path.exists(options.devpath): print('Can not find the input device "%s".' % options.devpath) exit() else: device = InputDevice(options.devpath) if not options.gesture_file: print('Gesture file is not specified.') exit() if not os.path.exists(options.gesture_file): print('Can not find the gesture file %s.' % options.gesture_file) exit() InputEventPlayer().playback(device, options.gesture_file) print('Gesture file %s has been played.' % options.gesture_file)