Examples¶
The examples included here available in the examples/ directory of the git source.
Printing the capabilities of a device and its events¶
#!/usr/bin/env python3
import sys
import libevdev
def print_capabilities(l):
v = l.driver_version
print("Input driver version is {}.{}.{}".format(v >> 16, (v >> 8) & 0xff, v & 0xff))
id = l.id
print("Input device ID: bus {:#x} vendor {:#x} product {:#x} version {:#x}".format(
id["bustype"],
id["vendor"],
id["product"],
id["version"],
))
print("Input device name: {}".format(l.name))
print("Supported events:")
for t, cs in l.evbits.items():
print(" Event type {} ({})".format(t.value, t.name))
for c in cs:
if t in [libevdev.EV_LED, libevdev.EV_SND, libevdev.EV_SW]:
v = l.value[c]
print(" Event code {} ({}) state {}".format(c.value, c.name, v))
else:
print(" Event code {} ({})".format(c.value, c.name))
if t == libevdev.EV_ABS:
a = l.absinfo[c]
print(" {:10s} {:6d}".format('Value', a.value))
print(" {:10s} {:6d}".format('Minimum', a.minimum))
print(" {:10s} {:6d}".format('Maximum', a.maximum))
print(" {:10s} {:6d}".format('Fuzz', a.fuzz))
print(" {:10s} {:6d}".format('Flat', a.flat))
print(" {:10s} {:6d}".format('Resolution', a.resolution))
print("Properties:")
for p in l.properties:
print(" Property type {} ({})".format(p.value, p.name))
def print_event(e):
print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='')
if e.matches(libevdev.EV_SYN):
if e.matches(libevdev.EV_SYN.SYN_MT_REPORT):
print("++++++++++++++ {} ++++++++++++".format(e.code.name))
elif e.matches(libevdev.EV_SYN.SYN_DROPPED):
print(">>>>>>>>>>>>>> {} >>>>>>>>>>>>".format(e.code.name))
else:
print("-------------- {} ------------".format(e.code.name))
else:
print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value))
def main(args):
path = args[1]
try:
with open(path, "rb") as fd:
dev = libevdev.Device(fd)
print_capabilities(dev)
print("################################\n"
"# Waiting for events #\n"
"################################")
while True:
try:
for e in dev.events():
print_event(e)
except libevdev.EventsDroppedException:
for e in dev.sync():
print_event(e)
except KeyboardInterrupt:
pass
except IOError as e:
import errno
if e.errno == errno.EACCES:
print("Insufficient permissions to access {}".format(path))
elif e.errno == errno.ENOENT:
print("Device {} does not exist".format(path))
else:
raise e
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: {} /dev/input/eventX".format(sys.argv[0]))
sys.exit(1)
main(sys.argv)
Creating a uinput device and sending events¶
#!/usr/bin/env python3
import sys
import libevdev
from libevdev import InputEvent
import time
def main(args):
dev = libevdev.Device()
dev.name = "test device"
dev.enable(libevdev.EV_REL.REL_X)
dev.enable(libevdev.EV_REL.REL_Y)
dev.enable(libevdev.EV_KEY.BTN_LEFT)
dev.enable(libevdev.EV_KEY.BTN_RIGHT)
try:
uinput = dev.create_uinput_device()
print("New device at {} ({})".format(uinput.devnode, uinput.syspath))
# Sleep for a bit so udev, libinput, Xorg, Wayland, ... all have had
# a chance to see the device and initialize it. Otherwise the event
# will be sent by the kernel but nothing is ready to listen to the
# device yet.
time.sleep(1)
for _ in range(5):
events = [InputEvent(libevdev.EV_REL.REL_X, -1),
InputEvent(libevdev.EV_REL.REL_Y, 1),
InputEvent(libevdev.EV_SYN.SYN_REPORT, 0)]
time.sleep(0.012)
uinput.send_events(events)
except OSError as e:
print(e)
if __name__ == "__main__":
main(sys.argv)
Filtering and re-routing events from a device¶
#!/usr/bin/env python3
#
# This example shows how to 'filter' device events from a device node.
# While real filtering is not possible, we can duplicate the input device as
# a new virtual input device and replay all events of the input events on
# our virtual one.
import sys
import libevdev
def main(args):
path = args[1]
code_from = libevdev.evbit(args[2])
code_to = libevdev.evbit(args[3])
print('Remapping {} to {}'.format(code_from, code_to))
fd = open(path, 'rb')
d = libevdev.Device(fd)
d.grab()
# create a duplicate of our input device
d.enable(code_to) # make sure the code we map to is available
uidev = d.create_uinput_device()
print('Device is at {}'.format(uidev.devnode))
while True:
for e in d.events():
# change any event with our event code to
# the one we want to map to, but pass all other events
# through
if e.code == code_from:
e = libevdev.InputEvent(code_to, e.value)
uidev.send_events([e])
if __name__ == "__main__":
if len(sys.argv) < 4:
print("Usage: {} /dev/input/eventX <from> <to>".format(sys.argv[0]))
print(" where <from> and <to> are event codes, e.g. REL_X")
sys.exit(1)
main(sys.argv)
Updating the kernel device’s axis ranges¶
#!/usr/bin/env python3
#
# This example shows how to update a kernel device's axis range
# This can be useful to e.g. change the resolution on a touchpad.
# Note that this is an example only, there are a lot of race conditions to
# be considered when using this as a proper solution.
import sys
import libevdev
def main(args):
path = args[1]
axis = args[2]
field = args[3]
value = int(args[4])
assert field in ['minimum', 'maximum', 'resolution']
axis = libevdev.evbit(axis)
assert axis is not None
fd = open(path, 'rb')
d = libevdev.Device(fd)
if not d.has(axis):
print('Device does not have axis {}'.format(axis))
sys.exit(1)
a = d.absinfo[axis]
setattr(a, field, value)
d.absinfo[axis] = a
d.sync_absinfo_to_kernel(axis)
if __name__ == "__main__":
if len(sys.argv) < 5:
print("Usage: {} /dev/input/eventX <axis> <field> <value>".format(sys.argv[0]))
print(" <axis> ... an EV_ABS event code, e.g. ABS_X")
print(" <field> .. one of 'minimum', 'maximum', 'resolution'")
print(" <value> .. the numeric value to set the axis field to")
sys.exit(1)
main(sys.argv)