share the source code first, dig latter
1 # encoding: utf-8 2 3 ''' 4 This module provides the :class:`InputEvent` class, which closely 5 resembles the ``input_event`` C struct in ``linux/input.h``: 6 7 .. code-block:: c 8 9 struct input_event { 10 struct timeval time; 11 __u16 type; 12 __u16 code; 13 __s32 value; 14 }; 15 16 This module also defines several abstractions on top of :class:`InputEvent` 17 that know more about the different event types (key, abs, rel etc). The 18 :data:`event_factory` dictionary maps event types to these classes. 19 20 Assuming you use the provided :func:`evdev.util.categorize()` function to 21 categorize events according to type, adding or replacing a class for a specific 22 event type becomes a matter of modifying :data:`event_factory`. 23 24 All of the provided classes have reasonable ``str()`` and ``repr()`` methods:: 25 26 >>> print(event) 27 event at 1337197425.477827, code 04, type 04, val 458792 28 >>> print(repr(event)) 29 InputEvent(1337197425L, 477827L, 4, 4, 458792L) 30 31 >>> print(key_event) 32 key event at 1337197425.477835, 28 (KEY_ENTER), up 33 >>> print(repr(key_event)) 34 KeyEvent(InputEvent(1337197425L, 477835L, 1, 28, 0L)) 35 ''' 36 37 # event type descriptions have been taken mot-a-mot from: 38 # http://www.kernel.org/doc/Documentation/input/event-codes.txt 39 40 from evdev.ecodes import keys, KEY, SYN, REL, ABS, EV_KEY, EV_REL, EV_ABS, EV_SYN 41 42 43 class InputEvent(object): 44 ''' 45 A generic input event. This closely resembles the ``input_event`` C struct. 46 ''' 47 48 __slots__ = 'sec', 'usec', 'type', 'code', 'value' 49 50 def __init__(self, sec, usec, type, code, value): 51 #: Time in seconds since epoch at which event occurred 52 self.sec = sec 53 54 #: Microsecond portion of the timestamp 55 self.usec = usec 56 57 #: Event type - one of ``ecodes.EV_*`` 58 self.type = type 59 60 #: Event code related to the event type 61 self.code = code 62 63 #: Event value related to the event type 64 self.value = value 65 66 def timestamp(self): 67 ''' Return event timestamp as a python float. ''' 68 return self.sec + (self.usec / 1000000.0) 69 70 def __str__(s): 71 msg = 'event at {0:f}, code {1:02d}, type {2:02d}, val {3:02d}' 72 return msg.format(s.timestamp(), s.code, s.type, s.value) 73 74 def __repr__(s): 75 msg = '{0}({1!r}, {2!r}, {3!r}, {4!r}, {5!r})' 76 return msg.format(s.__class__.__name__, 77 s.sec, s.usec, s.type, s.code, s.value) 78 79 80 class KeyEvent(object): 81 ''' 82 Used to describe state changes of keyboards, buttons, or other 83 key-like devices. 84 ''' 85 86 key_up = 0x0 87 key_down = 0x1 88 key_hold = 0x2 89 90 __slots__ = 'scancode', 'keycode', 'keystate', 'event' 91 92 def __init__(self, event): 93 if event.value == 0: 94 self.keystate = KeyEvent.key_up 95 elif event.value == 2: 96 self.keystate = KeyEvent.key_hold 97 elif event.value == 1: 98 self.keystate = KeyEvent.key_down 99 100 self.keycode = keys[event.code] # :todo: 101 self.scancode = event.code 102 103 #: :class:`InputEvent` instance 104 self.event = event 105 106 def __str__(self): 107 try: ks = ('up', 'down', 'hold')[self.keystate] 108 except: ks = 'unknown' 109 110 msg = 'key event at {0:f}, {1} ({2}), {3}' 111 return msg.format(self.event.timestamp(), 112 self.scancode, self.keycode, ks) 113 114 def __repr__(s): 115 return '{0}({1!r})'.format(s.__class__.__name__, s.event) 116 117 118 class RelEvent(object): 119 ''' 120 Used to describe relative axis value changes, e.g. moving the 121 mouse 5 units to the left. 122 ''' 123 124 __slots__ = 'event' 125 126 def __init__(self, event): 127 #: :class:`InputEvent` instance 128 self.event = event 129 130 def __str__(self): 131 msg = 'relative axis event at {0:f}, {1} ' 132 return msg.format(self.event.timestamp(), REL[self.event.code]) 133 134 def __repr__(s): 135 return '{0}({1!r})'.format(s.__class__.__name__, s.event) 136 137 138 class AbsEvent(object): 139 ''' 140 Used to describe absolute axis value changes, e.g. describing the 141 coordinates of a touch on a touchscreen. 142 ''' 143 144 __slots__ = 'event' 145 146 def __init__(self, event): 147 #: :class:`InputEvent` instance 148 self.event = event 149 150 def __str__(self): 151 msg = 'absolute axis event at {0:f}, {1} ' 152 return msg.format(self.event.timestamp(), ABS[self.event.code]) 153 154 def __repr__(s): 155 return '{0}({1!r})'.format(s.__class__.__name__, s.event) 156 157 158 class SynEvent(object): 159 ''' 160 Used as markers to separate events. Events may be separated in time or 161 in space, such as with the multitouch protocol. 162 ''' 163 164 __slots__ = 'event' 165 166 def __init__(self, event): 167 #: :class:`InputEvent` instance 168 self.event = event 169 170 def __str__(self): 171 msg = 'synchronization event at {0:f}, {1} ' 172 return msg.format(self.event.timestamp(), SYN[self.event.code]) 173 174 def __repr__(s): 175 return '{0}({1!r})'.format(s.__class__.__name__, s.event) 176 177 178 #: Used by :func:`evdev.util.categorize()` 179 event_factory = { 180 EV_KEY: KeyEvent, 181 EV_REL: RelEvent, 182 EV_ABS: AbsEvent, 183 EV_SYN: SynEvent, 184 } 185 186 187 __all__ = InputEvent, KeyEvent, RelEvent, SynEvent, AbsEvent, event_factory