PyInput is an API that abstracts away some of the low-level details of the Linux
input subsystem. It allows read/write access to the devices /dev/input/event*
and the uninput device through object streams.
An object stream is like a normal stream, except it produces objects instead of bytes or strings. This means that many of the usual Python interfaces are modified to take the type that is supposed to be read from the stream. They must implement my struct interface (see The struct Interface).
Also provided is the pile of constants, structures, and macros defined in the
headers linux/input.h
and linux/uinput.h
. This is generated by SWIG, so
it should be complete.
WARNING: There are several major bugs and lapses in functionality that currently make this module less than usable. See `issues <https://github.com/astronouth7303/pyinput/issues>`_ for a list of issues.
The struct
interface is implemented on all structures defined in this
module and is used by the object streams.
struct(**props)
- The initializer takes the initial properties as arguments.
inst.pack()
- Returns a binary string containing the the data packed for the input subsystem. This is just a copy of the C struct as in memory.
struct.unpack(str)
- A class method. Reverses
pack()
. Takes the packed C struct as a string and returns an instance. struct.size()
- Returns the size of the struct, or the size of the string of the string
returned by
pack()
, or the size of the string expected byunpack()
. (These are all the same value.)
This is where everything is (not just stuff related to uinput). In addition to the macros, structures, and constants, the following is available. See pydoc for full information.
FindUinput(*others)
- Attempts to find the uinput device by checking a pre-defined list of options.
You can pass in more options in
others
. EvdevStream
The object stream for reading from
/dev/input/event*
. It defines both stream reading methods and convenience methods for getting information about the device.The stream interface is:
write(obj)
read(type)
ioctl(op, ...)
close()
flush()
iter(type)
(Read the docs on this; the iterator has extra options)- The context manager interface
These are the convenience methods. Most of them use
ioctl()
for their data.dev_id()
-- Returns theinput_id
structure for the devicedev_version()
-- Returns the device version as an integerdev_name()
-- Returns the device name as a stringdev_bits()
-- Returns what events the device will create, as a dictionary of listsdev_ranges()
-- Returns the ranges of the absolute axis, as a dict
UinputStream
Inherits from
EvdevStream
, but most of the methods will probably fail. It also keeps track of the state of the device (namely if it's created).The context manager interface is implemented somewhat unusually. It is meant to be nested. To demonstrate:
with UinputStream() as us: # Open the file, make sure it gets closed us.events = ... # Declare the events you're using with us.create(): # Create the device and make sure it gets destroyed. # The return value of create() isn't meant to be used outside of this. us.event(t, c, v) # Actually feed an event
The first
with
is the one for the file, managing the open/close life cycle. The innerwith
is for the virtual device, managing the create/destroy life cycle.Note that
UinputStream
doesn't abstract away anything to do with the events themselves or the declarations. It just makes interfacing with the input subsystem easier. You still need to pass a reset event and declare the events you'll be creating.create()
-- Creates the device, ie call theUI_DEV_CREATE
ioctl, and returns a context manager to destroy itdestroy()
-- Destroys the device, ie call theUI_DEV_DESTROY
ioctlevent(type, code, value)
-- Creates and feeds aninput_event