Home | History | Annotate | Download | only in input
      1 #!/usr/bin/env python
      2 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 # Description:
      7 #
      8 # Class for injecting input events to linux 'evdev' input devices.
      9 #
     10 # Provides evemu-play-like functionality if run from the command line:
     11 # $ input_event_player.py -d /dev/input/event6
     12 
     13 """ Playback input events on a linux input device. """
     14 
     15 import glob
     16 import os.path
     17 import re
     18 import time
     19 
     20 from input_device import InputDevice, InputEvent
     21 from optparse import OptionParser
     22 
     23 
     24 class InputEventPlayer:
     25     """ Linux evdev input event player.
     26 
     27     An "evdev" input event player injects a stream of "input events" to kernel
     28     evdev driver. With this player, we could easily playback an input event file
     29     which was recorded with the tool evemu-record previously.
     30 
     31     """
     32 
     33     def __init__(self):
     34         self.tv_sec = None
     35         self.tv_usec = None
     36 
     37     def playback(self, device, gesture_file):
     38         """ Play the events in gesture_file on device.
     39 
     40         Keyword arguments:
     41         device -- the InputDevice device object
     42         gesture_file -- the name of the event file recorded previously
     43         """
     44         if not device:
     45             raise
     46         event_str = 'E: (\d+)\.(\d+) ([0-9a-f]{4}) ([0-9a-f]{4}) ([-]?\d+)'
     47         event_pattern = re.compile(event_str)
     48         for line in open(gesture_file, 'rt'):
     49             m = event_pattern.match(line)
     50             if not m:
     51                 raise
     52             event = InputEvent(int(m.group(1)),
     53                                int(m.group(2)),
     54                                int(m.group(3), 16),
     55                                int(m.group(4), 16),
     56                                int(m.group(5)))
     57             if not self.tv_sec:
     58                 self.tv_sec = event.tv_sec
     59                 self.tv_usec = event.tv_usec
     60             delta = event.tv_sec - self.tv_sec
     61             delta += ((event.tv_usec - self.tv_usec) / 1000000.0)
     62             # Sleep only if the event is 0.05 ms later than the previous one
     63             if delta > 0.0000500:
     64                 time.sleep(delta)
     65             self.tv_sec = event.tv_sec
     66             self.tv_usec = event.tv_usec
     67             event.write(device.f)
     68 
     69 
     70 if __name__ == '__main__':
     71     parser = OptionParser()
     72 
     73     parser.add_option('-d', '--devpath', dest='devpath', default='',
     74                       help='device path (/dev/input/event0)')
     75     parser.add_option('-t', '--touchpad', action='store_true', dest='touchpad',
     76                       default=False, help='Find and use first touchpad device')
     77     parser.add_option('-f', '--file', action='store', dest='gesture_file',
     78                       help='Event file to playback')
     79     (options, args) = parser.parse_args()
     80 
     81     if options.touchpad:
     82         for evdev in glob.glob('/dev/input/event*'):
     83             device = InputDevice(evdev)
     84             if device.is_touchpad():
     85                 break
     86         else:
     87             print 'Can not find a touchpad device'
     88             exit()
     89     elif not os.path.exists(options.devpath):
     90         print 'Can not find the input device "%s".' % options.devpath
     91         exit()
     92     else:
     93         device = InputDevice(options.devpath)
     94     if not options.gesture_file:
     95         print 'Gesture file is not specified.'
     96         exit()
     97     if not os.path.exists(options.gesture_file):
     98         print 'Can not find the gesture file %s.' % options.gesture_file
     99         exit()
    100 
    101     InputEventPlayer().playback(device, options.gesture_file)
    102     print 'Gesture file %s has been played.' % options.gesture_file
    103