See More

# encoding: utf-8 ''' This module provides the :class:`InputEvent` class, which closely resembles the ``input_event`` struct defined in ``linux/input.h``: .. code-block:: c struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; }; This module also defines several :class:`InputEvent` sub-classes that know more about the different types of events (key, abs, rel etc). The :data:`event_factory` dictionary maps event types to these classes. Assuming you use the :func:`evdev.util.categorize()` function to categorize events according to their type, adding or replacing a class for a specific event type becomes a matter of modifying :data:`event_factory`. All classes in this module have reasonable ``str()`` and ``repr()`` methods:: >>> print(event) event at 1337197425.477827, code 04, type 04, val 458792 >>> print(repr(event)) InputEvent(1337197425L, 477827L, 4, 4, 458792L) >>> print(key_event) key event at 1337197425.477835, 28 (KEY_ENTER), up >>> print(repr(key_event)) KeyEvent(InputEvent(1337197425L, 477835L, 1, 28, 0L)) ''' # event type descriptions have been taken mot-a-mot from: # http://www.kernel.org/doc/Documentation/input/event-codes.txt from evdev.ecodes import keys, KEY, SYN, REL, ABS, EV_KEY, EV_REL, EV_ABS, EV_SYN class InputEvent: '''A generic input event.''' __slots__ = 'sec', 'usec', 'type', 'code', 'value' def __init__(self, sec, usec, type, code, value): #: Time in seconds since epoch at which event occurred. self.sec = sec #: Microsecond portion of the timestamp. self.usec = usec #: Event type - one of ``ecodes.EV_*``. self.type = type #: Event code related to the event type. self.code = code #: Event value related to the event type. self.value = value def timestamp(self): '''Return event timestamp as a float.''' return self.sec + (self.usec / 1000000.0) def __str__(s): msg = 'event at {:f}, code {:02d}, type {:02d}, val {:02d}' return msg.format(s.timestamp(), s.code, s.type, s.value) def __repr__(s): msg = '{}({!r}, {!r}, {!r}, {!r}, {!r})' return msg.format(s.__class__.__name__, s.sec, s.usec, s.type, s.code, s.value) class KeyEvent: '''An event generated by a keyboard, button or other key-like devices.''' key_up = 0x0 key_down = 0x1 key_hold = 0x2 __slots__ = 'scancode', 'keycode', 'keystate', 'event' def __init__(self, event, allow_unknown=False): ''' The ``allow_unknown`` argument determines what to do in the event of an event code for which a key code cannot be found. If ``False`` a ``KeyError`` will be raised. If ``True`` the keycode will be set to the hex value of the event code. ''' self.scancode = event.code if event.value == 0: self.keystate = KeyEvent.key_up elif event.value == 2: self.keystate = KeyEvent.key_hold elif event.value == 1: self.keystate = KeyEvent.key_down try: self.keycode = keys[event.code] except KeyError: if allow_unknown: self.keycode = '0x{:02X}'.format(event.code) else: raise #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): try: ks = ('up', 'down', 'hold')[self.keystate] except IndexError: ks = 'unknown' msg = 'key event at {:f}, {} ({}), {}' return msg.format(self.event.timestamp(), self.scancode, self.keycode, ks) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) class RelEvent: '''A relative axis event (e.g moving the mouse 5 units to the left).''' __slots__ = 'event' def __init__(self, event): #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): msg = 'relative axis event at {:f}, {}' return msg.format(self.event.timestamp(), REL[self.event.code]) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) class AbsEvent: '''An absolute axis event (e.g the coordinates of a tap on a touchscreen).''' __slots__ = 'event' def __init__(self, event): #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): msg = 'absolute axis event at {:f}, {}' return msg.format(self.event.timestamp(), ABS[self.event.code]) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) class SynEvent: ''' A synchronization event. Used as markers to separate events. Events may be separated in time or in space, such as with the multitouch protocol. ''' __slots__ = 'event' def __init__(self, event): #: Reference to an :class:`InputEvent` instance. self.event = event def __str__(self): msg = 'synchronization event at {:f}, {}' return msg.format(self.event.timestamp(), SYN[self.event.code]) def __repr__(s): return '{}({!r})'.format(s.__class__.__name__, s.event) #: A mapping of event types to :class:`InputEvent` sub-classes. Used #: by :func:`evdev.util.categorize()` event_factory = { EV_KEY: KeyEvent, EV_REL: RelEvent, EV_ABS: AbsEvent, EV_SYN: SynEvent, } __all__ = ('InputEvent', 'KeyEvent', 'RelEvent', 'SynEvent', 'AbsEvent', 'event_factory')