# encoding: utf-8
import os
import stat
import time
from evdev import _uinput
from evdev import ecodes, util, device
class UInputError(Exception):
pass
class UInput(object):
'''
A userland input device and that can inject input events into the
linux input subsystem.
'''
__slots__ = (
'name', 'vendor', 'product', 'version', 'bustype',
'events', 'devnode', 'fd', 'device',
)
def __init__(self,
events=None,
name='py-evdev-uinput',
vendor=0x1, product=0x1, version=0x1, bustype=0x3,
devnode='/dev/uinput'):
'''
:param events: the event types and codes that the uinput
device will be able to inject - defaults to all
key codes.
:type events: dictionary of event types mapping to lists of
event codes.
:param name: the name of the input device.
:param vendor: vendor identifier.
:param product: product identifier.
:param version: version identifier.
:param bustype: bustype identifier.
.. note:: If you do not specify any events, the uinput device
will be able to inject only ``KEY_*`` and ``BTN_*``
event codes.
'''
self.name = name #: Uinput device name.
self.vendor = vendor #: Device vendor identifier.
self.product = product #: Device product identifier.
self.version = version #: Device version identifier.
self.bustype = bustype #: Device bustype - eg. ``BUS_USB``.
self.devnode = devnode #: Uinput device node - eg. ``/dev/uinput/``.
if not events:
events = {ecodes.EV_KEY: ecodes.keys.keys()}
# the min, max, fuzz and flat values for the absolute axis for
# a given code
absinfo = []
self._verify()
#: Write-only, non-blocking file descriptor to the uinput device node.
self.fd = _uinput.open(devnode)
# set device capabilities
for etype, codes in events.items():
for code in codes:
# handle max, min, fuzz, flat
if isinstance(code, (tuple, list, device.AbsInfo)):
# flatten (ABS_Y, (0, 255, 0, 0)) to (ABS_Y, 0, 255, 0, 0)
f = [code[0]]; f += code[1]
absinfo.append(f)
code = code[0]
#:todo: a lot of unnecessary packing/unpacking
_uinput.enable(self.fd, etype, code)
# create uinput device
_uinput.create(self.fd, name, vendor, product, version, bustype, absinfo)
#: An :class:`InputDevice