.\" Man page generated from reStructuredText. . .TH "PYTHON-EVDEV" "7" "Jun 02, 2021" "1.4.0" "python-evdev" .SH NAME python-evdev \- python-evdev Documentation . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .sp This package provides bindings to the generic input event interface in Linux. The \fIevdev\fP interface serves the purpose of passing events generated in the kernel directly to userspace through character devices that are typically located in \fB/dev/input/\fP\&. .sp This package also comes with bindings to \fIuinput\fP, the userspace input subsystem. \fIUinput\fP allows userspace programs to create and handle input devices that can inject events directly into the input subsystem. .sp In other words, \fIpython\-evdev\fP allows you to read and write input events on Linux. An event can be a key or button press, a mouse movement or a tap on a touchscreen. .SH FROM A BINARY PACKAGE .sp Python\-evdev has been packaged for the following GNU/Linux distributions: .sp Consult the documentation of your OS package manager for installation instructions. .SH FROM SOURCE .sp The latest stable version of \fIpython\-evdev\fP can be installed from \fI\%pypi\fP, provided that you have gcc/clang, \fI\%pip\fP and the Python and Linux development headers installed on your system. Installing them is distribution specific and typically falls in one of the following categories: .sp On a Debian compatible OS: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ apt\-get install python\-dev python\-pip gcc $ apt\-get install linux\-headers\-$(uname \-r) .ft P .fi .UNINDENT .UNINDENT .sp On a Redhat compatible OS: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ yum install python\-devel python\-pip gcc $ yum install kernel\-headers\-$(uname \-r) .ft P .fi .UNINDENT .UNINDENT .sp On Arch Linux and derivatives: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ pacman \-S core/linux\-api\-headers python\-pip gcc .ft P .fi .UNINDENT .UNINDENT .sp Once all dependencies are available, you may install \fIpython\-evdev\fP using \fI\%pip\fP: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ sudo pip install evdev # available globally $ pip install \-\-user evdev # available to the current user .ft P .fi .UNINDENT .UNINDENT .SH SPECIFYING HEADER LOCATIONS .sp By default, the setup script will look for the \fBinput.h\fP and \fBinput\-event\-codes.h\fP [1] header files \fB/usr/include/linux\fP\&. .sp You may use the \fB\-\-evdev\-headers\fP option to the \fBbuild_ext\fP setuptools command to specify the location of these header files. It accepts one or more colon\-separated paths. For example: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ python setup.py build_ext \e \-\-evdev\-headers buildroot/input.h:buildroot/input\-event\-codes.h \e \-\-include\-dirs buildroot/ \e install # or any other command (e.g. develop, bdist, bdist_wheel) .ft P .fi .UNINDENT .UNINDENT .IP [1] 5 \fBinput\-event\-codes.h\fP is found only in more recent kernel versions. .SH QUICK START .SS Listing accessible event devices .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> import evdev >>> devices = [evdev.InputDevice(path) for path in evdev.list_devices()] >>> for device in devices: \&... print(device.path, device.name, device.phys) /dev/input/event1 USB Keyboard usb\-0000:00:12.1\-2/input0 /dev/input/event0 USB Optical Mouse usb\-0000:00:12.0\-2/input0 .ft P .fi .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 If you do not see any devices, ensure that your user is in the correct group (typically \fBinput\fP) to have read/write access. .UNINDENT .UNINDENT .SS Reading events from a device .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> import evdev >>> device = evdev.InputDevice(\(aq/dev/input/event1\(aq) >>> print(device) device /dev/input/event1, name "USB Keyboard", phys "usb\-0000:00:12.1\-2/input0" >>> for event in device.read_loop(): \&... if event.type == evdev.ecodes.EV_KEY: \&... print(evdev.categorize(event)) \&... # pressing \(aqa\(aq and holding \(aqspace\(aq key event at 1337016188.396030, 30 (KEY_A), down key event at 1337016188.492033, 30 (KEY_A), up key event at 1337016189.772129, 57 (KEY_SPACE), down key event at 1337016190.275396, 57 (KEY_SPACE), hold key event at 1337016190.284160, 57 (KEY_SPACE), up .ft P .fi .UNINDENT .UNINDENT .SS Accessing event codes .sp The \fBevdev.ecodes\fP module provides reverse and forward mappings between the names and values of the event subsystem constants. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import ecodes >>> ecodes.KEY_A \&... 30 >>> ecodes.ecodes[\(aqKEY_A\(aq] \&... 30 >>> ecodes.KEY[30] \&... \(aqKEY_A\(aq >>> ecodes.bytype[ecodes.EV_KEY][30] \&... \(aqKEY_A\(aq # A single value may correspond to multiple event codes. >>> ecodes.KEY[152] \&... [\(aqKEY_COFFEE\(aq, \(aqKEY_SCREENLOCK\(aq] .ft P .fi .UNINDENT .UNINDENT .SS Listing and monitoring input devices .sp The \fIpython\-evdev\fP package also comes with a small command\-line program for listing and monitoring input devices: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C $ python \-m evdev.evtest .ft P .fi .UNINDENT .UNINDENT .SH TUTORIAL .SS Listing accessible event devices .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> import evdev >>> devices = [evdev.InputDevice(path) for path in evdev.list_devices()] >>> for device in devices: >>> print(device.path, device.name, device.phys) /dev/input/event1 Dell Dell USB Keyboard usb\-0000:00:12.1\-2/input0 /dev/input/event0 Dell USB Optical Mouse usb\-0000:00:12.0\-2/input0 .ft P .fi .UNINDENT .UNINDENT .SS Listing device capabilities .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> import evdev >>> device = evdev.InputDevice(\(aq/dev/input/event0\(aq) >>> print(device) device /dev/input/event0, name "Dell USB Optical Mouse", phys "usb\-0000:00:12.0\-2/input0" >>> device.capabilities() \&... { 0: [0, 1, 2], 1: [272, 273, 274, 275], 2: [0, 1, 6, 8], 4: [4] } >>> device.capabilities(verbose=True) \&... { (\(aqEV_SYN\(aq, 0): [(\(aqSYN_REPORT\(aq, 0), (\(aqSYN_CONFIG\(aq, 1), (\(aqSYN_MT_REPORT\(aq, 2)], \&... (\(aqEV_KEY\(aq, 1): [(\(aqBTN_MOUSE\(aq, 272), (\(aqBTN_RIGHT\(aq, 273), (\(aqBTN_MIDDLE\(aq, 274), (\(aqBTN_SIDE\(aq, 275)], ... .ft P .fi .UNINDENT .UNINDENT .SS Listing device capabilities (devices with absolute axes) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> import evdev >>> device = evdev.InputDevice(\(aq/dev/input/event7\(aq) >>> print(device) device /dev/input/event7, name "Wacom Bamboo 2FG 4x5 Finger", phys "" >>> device.capabilities() \&... { 1: [272, 273, 277, 278, 325, 330, 333] , \&... 3: [(0, AbsInfo(min=0, max=15360, fuzz=128, flat=0)), \&... (1, AbsInfo(min=0, max=10240, fuzz=128, flat=0))] } >>> device.capabilities(verbose=True) \&... { (\(aqEV_KEY\(aq, 1): [(\(aqBTN_MOUSE\(aq, 272), (\(aqBTN_RIGHT\(aq, 273), ...], \&... (\(aqEV_ABS\(aq, 3): [((\(aqABS_X\(aq, 0), AbsInfo(min=0, max=15360, fuzz=128, flat=0)), \&... ((\(aqABS_Y\(aq, 1), AbsInfo(min=0, max=10240, fuzz=128, flat=0)),] } >>> device.capabilities(absinfo=False) \&... { 1: [272, 273, 277, 278, 325, 330, 333], \&... 3: [0, 1, 47, 53, 54, 57] } .ft P .fi .UNINDENT .UNINDENT .SS Getting and setting LED states .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> dev.leds(verbose=True) \&... [(\(aqLED_NUML\(aq, 0), (\(aqLED_CAPSL\(aq, 1)] >>> dev.leds() \&... [0, 1] >>> dev.set_led(ecodes.LED_NUML, 1) # enable numlock >>> dev.set_led(ecodes.LED_NUML, 0) # disable numlock .ft P .fi .UNINDENT .UNINDENT .SS Getting currently active keys .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> dev.active_keys(verbose=True) \&... [(\(aqKEY_3\(aq, 4), (\(aqKEY_LEFTSHIFT\(aq, 42)] >>> dev.active_keys() \&... [4, 42] .ft P .fi .UNINDENT .UNINDENT .SS Reading events .sp Reading events from a single device in an endless loop. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import InputDevice, categorize, ecodes >>> dev = InputDevice(\(aq/dev/input/event1\(aq) >>> print(dev) device /dev/input/event1, name "Dell Dell USB Keyboard", phys "usb\-0000:00:12.1\-2/input0" >>> for event in dev.read_loop(): \&... if event.type == ecodes.EV_KEY: \&... print(categorize(event)) \&... # pressing \(aqa\(aq and holding \(aqspace\(aq key event at 1337016188.396030, 30 (KEY_A), down key event at 1337016188.492033, 30 (KEY_A), up key event at 1337016189.772129, 57 (KEY_SPACE), down key event at 1337016190.275396, 57 (KEY_SPACE), hold key event at 1337016190.284160, 57 (KEY_SPACE), up .ft P .fi .UNINDENT .UNINDENT .SS Reading events (using \fBasyncio\fP) .sp \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 This requires Python 3.5+ for the async/await keywords. .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> import asyncio >>> from evdev import InputDevice, categorize, ecodes >>> dev = InputDevice(\(aq/dev/input/event1\(aq) >>> async def helper(dev): \&... async for ev in dev.async_read_loop(): \&... print(repr(ev)) >>> loop = asyncio.get_event_loop() >>> loop.run_until_complete(helper(dev)) InputEvent(1527363738, 348740, 4, 4, 458792) InputEvent(1527363738, 348740, 1, 28, 0) InputEvent(1527363738, 348740, 0, 0, 0) .ft P .fi .UNINDENT .UNINDENT .SS Reading events from multiple devices (using \fBselect\fP) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import InputDevice >>> from select import select # A mapping of file descriptors (integers) to InputDevice instances. >>> devices = map(InputDevice, (\(aq/dev/input/event1\(aq, \(aq/dev/input/event2\(aq)) >>> devices = {dev.fd: dev for dev in devices} >>> for dev in devices.values(): print(dev) device /dev/input/event1, name "Dell Dell USB Keyboard", phys "usb\-0000:00:12.1\-2/input0" device /dev/input/event2, name "Logitech USB Laser Mouse", phys "usb\-0000:00:12.0\-2/input0" >>> while True: \&... r, w, x = select(devices, [], []) \&... for fd in r: \&... for event in devices[fd].read(): \&... print(event) event at 1351116708.002230, code 01, type 02, val 01 event at 1351116708.002234, code 00, type 00, val 00 event at 1351116708.782231, code 04, type 04, val 458782 event at 1351116708.782237, code 02, type 01, val 01 .ft P .fi .UNINDENT .UNINDENT .SS Reading events from multiple devices (using \fBselectors\fP) .sp This can also be achieved using the \fBselectors\fP module in Python 3.4: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C from evdev import InputDevice from selectors import DefaultSelector, EVENT_READ selector = selectors.DefaultSelector() mouse = evdev.InputDevice(\(aq/dev/input/event1\(aq) keybd = evdev.InputDevice(\(aq/dev/input/event2\(aq) # This works because InputDevice has a \(gafileno()\(ga method. selector.register(mouse, selectors.EVENT_READ) selector.register(keybd, selectors.EVENT_READ) while True: for key, mask in selector.select(): device = key.fileobj for event in device.read(): print(event) .ft P .fi .UNINDENT .UNINDENT .SS Reading events from multiple devices (using \fBasyncio\fP) .sp Yet another possibility is the \fBasyncio\fP module from Python 3.4: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C import asyncio, evdev @asyncio.coroutine def print_events(device): while True: events = yield from device.async_read() for event in events: print(device.path, evdev.categorize(event), sep=\(aq: \(aq) mouse = evdev.InputDevice(\(aq/dev/input/eventX\(aq) keybd = evdev.InputDevice(\(aq/dev/input/eventY\(aq) for device in mouse, keybd: asyncio.async(print_events(device)) loop = asyncio.get_event_loop() loop.run_forever() .ft P .fi .UNINDENT .UNINDENT .sp Since Python 3.5, the \fI\%async/await\fP syntax makes this even simpler: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C import asyncio, evdev mouse = evdev.InputDevice(\(aq/dev/input/event4\(aq) keybd = evdev.InputDevice(\(aq/dev/input/event5\(aq) async def print_events(device): async for event in device.async_read_loop(): print(device.path, evdev.categorize(event), sep=\(aq: \(aq) for device in mouse, keybd: asyncio.ensure_future(print_events(device)) loop = asyncio.get_event_loop() loop.run_forever() .ft P .fi .UNINDENT .UNINDENT .SS Accessing evdev constants .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import ecodes >>> ecodes.KEY_A, ecodes.ecodes[\(aqKEY_A\(aq] \&... (30, 30) >>> ecodes.KEY[30] \&... \(aqKEY_A\(aq >>> ecodes.bytype[ecodes.EV_KEY][30] \&... \(aqKEY_A\(aq >>> ecodes.KEY[152] # a single value may correspond to multiple codes \&... [\(aqKEY_COFFEE\(aq, \(aqKEY_SCREENLOCK\(aq] .ft P .fi .UNINDENT .UNINDENT .SS Searching event codes by regex .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import util >>> res = util.find_ecodes_by_regex(r\(aq(ABS|KEY)_BR(AKE|EAK)\(aq) >>> res \&... {1: [411], 3: [10]} >>> util.resolve_ecodes_dict(res) \&... {(\(aqEV_KEY\(aq, 1): [(\(aqKEY_BREAK\(aq, 411)], (\(aqEV_ABS\(aq, 3): [(\(aqABS_BRAKE\(aq, 10)]} .ft P .fi .UNINDENT .UNINDENT .SS Getting exclusive access to a device .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> dev.grab() # become the sole recipient of all incoming input events >>> dev.ungrab() .ft P .fi .UNINDENT .UNINDENT .sp This functionality is also available as a context manager. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> with dev.grab_context(): \&... pass .ft P .fi .UNINDENT .UNINDENT .SS Associating classes with event types .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import categorize, event_factory, ecodes >>> class SynEvent(object): \&... def __init__(self, event): \&... ... >>> event_factory[ecodes.EV_SYN] = SynEvent .ft P .fi .UNINDENT .UNINDENT .sp See \fBevents\fP for more information. .SS Injecting input .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import UInput, ecodes as e >>> ui = UInput() >>> # accepts only KEY_* events by default >>> ui.write(e.EV_KEY, e.KEY_A, 1) # KEY_A down >>> ui.write(e.EV_KEY, e.KEY_A, 0) # KEY_A up >>> ui.syn() >>> ui.close() .ft P .fi .UNINDENT .UNINDENT .SS Injecting events (using a context manager) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> ev = InputEvent(1334414993, 274296, ecodes.EV_KEY, ecodes.KEY_A, 1) >>> with UInput() as ui: \&... ui.write_event(ev) \&... ui.syn() .ft P .fi .UNINDENT .UNINDENT .SS Specifying \fBuinput\fP device options .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import UInput, AbsInfo, ecodes as e >>> cap = { \&... e.EV_KEY : [e.KEY_A, e.KEY_B], \&... e.EV_ABS : [ \&... (e.ABS_X, AbsInfo(value=0, min=0, max=255, \&... fuzz=0, flat=0, resolution=0)), \&... (e.ABS_Y, AbsInfo(0, 0, 255, 0, 0, 0)), \&... (e.ABS_MT_POSITION_X, (0, 128, 255, 0)) ] \&... } >>> ui = UInput(cap, name=\(aqexample\-device\(aq, version=0x3) >>> print(ui) name "example\-device", bus "BUS_USB", vendor "0001", product "0001", version "0003" event types: EV_KEY EV_ABS EV_SYN >>> print(ui.capabilities()) {0: [0, 1, 3], 1: [30, 48], 3: [(0, AbsInfo(value=0, min=0, max=0, fuzz=255, flat=0, resolution=0)), (1, AbsInfo(value=0, min=0, max=0, fuzz=255, flat=0, resolution=0)), (53, AbsInfo(value=0, min=0, max=255, fuzz=128, flat=0, resolution=0))]} >>> # move mouse cursor >>> ui.write(e.EV_ABS, e.ABS_X, 20) >>> ui.write(e.EV_ABS, e.ABS_Y, 20) >>> ui.syn() .ft P .fi .UNINDENT .UNINDENT .SS Create \fBuinput\fP device with capabilities of another device .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C >>> from evdev import UInput, InputDevice >>> mouse = InputDevice(\(aq/dev/input/event1\(aq) >>> keybd = \(aq/dev/input/event2\(aq >>> ui = UInput.from_device(mouse, keybd, name=\(aqkeyboard\-mouse\-device\(aq) >>> ui.capabilities(verbose=True).keys() dict_keys([(\(aqEV_LED\(aq, 17), (\(aqEV_KEY\(aq, 1), (\(aqEV_SYN\(aq, 0), (\(aqEV_REL\(aq, 2), (\(aqEV_MSC\(aq, 4)]) .ft P .fi .UNINDENT .UNINDENT .SS Create \fBuinput\fP device capable of receiving FF\-effects .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C import asyncio from evdev import UInput, categorize, ecodes cap = { ecodes.EV_FF: [ecodes.FF_RUMBLE ], ecodes.EV_KEY: [ecodes.KEY_A, ecodes.KEY_B] } ui = UInput(cap, name=\(aqtest\-controller\(aq, version=0x3) async def print_events(device): async for event in device.async_read_loop(): print(categorize(event)) # Wait for an EV_UINPUT event that will signal us that an # effect upload/erase operation is in progress. if event.type != ecodes.EV_UINPUT: continue if event.code == ecodes.UI_FF_UPLOAD: upload = device.begin_upload(event.value) upload.retval = 0 print(f\(aq[upload] effect_id: {upload.effect.id}, type: {upload.effect.type}\(aq) device.end_upload(upload) elif event.code == ecodes.UI_FF_ERASE: erase = device.begin_erase(event.value) print(f\(aq[erase] effect_id {erase.effect_id}\(aq) erase.retval = 0 device.end_erase(erase) asyncio.ensure_future(print_events(ui)) loop = asyncio.get_event_loop() loop.run_forever() .ft P .fi .UNINDENT .UNINDENT .SS Injecting an FF\-event into first FF\-capable device found .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C from evdev import ecodes, InputDevice, ff # Find first EV_FF capable event device (that we have permissions to use). for name in evdev.list_devices(): dev = InputDevice(name) if ecodes.EV_FF in dev.capabilities(): break rumble = ff.Rumble(strong_magnitude=0x0000, weak_magnitude=0xffff) effect_type = ff.EffectType(ff_rumble_effect=rumble) duration_ms = 1000 effect = ff.Effect( ecodes.FF_RUMBLE, \-1, 0, ff.Trigger(0, 0), ff.Replay(duration_ms, 0), ff.EffectType(ff_rumble_effect=rumble) ) repeat_count = 1 effect_id = dev.upload_effect(effect) dev.write(e.EV_FF, effect_id, repeat_count) dev.erase_effect(effect_id) .ft P .fi .UNINDENT .UNINDENT .SH API REFERENCE .SS \fBevents\fP .SS \fBeventio\fP .SS \fBeventio_async\fP .SS \fBdevice\fP .SS \fBuinput\fP .SS \fButil\fP .SS \fBecodes\fP .SH SCOPE AND STATUS .sp Python\-evdev exposes most of the more common interfaces defined in the evdev subsystem. Reading and injecting events is well supported and has been tested with nearly all event types. .sp The basic functionality for reading and uploading force\-feedback events is there, but it has not been exercised sufficiently. A major shortcoming of the uinput wrapper is that it does not support force\-feedback devices at all (see issue \fI\%#23\fP). .sp Some characters, such as \fB:\fP (colon), cannot be easily injected (see issue \fI\%#7\fP), Translating them into UInput events would require knowing the kernel keyboard translation table, which is beyond the scope of python\-evdev. Please look into the following projects if you need more complete or convenient input injection support. .INDENT 0.0 .IP \(bu 2 \fI\%python\-uinput\fP .IP \(bu 2 \fI\%uinput\-mapper\fP .IP \(bu 2 \fI\%pynput\fP .IP \(bu 2 \fI\%pygame\fP (cross\-platform) .UNINDENT .SH CHANGELOG .SS 1.4.0 (Jan 16, 2021) .INDENT 0.0 .IP \(bu 2 Fix \fBInputDevice.set_absinfo\fP to allow setting parameters to zero. .IP \(bu 2 Fix off\-by\-one in \fBioctl_EVIOCG_bits\fP, which causes value at the end of the list to not be reported back (\fI\%#131\fP). .IP \(bu 2 Fix \fBset_absinfo\fP to allow setting parameters to zero (\fI\%#128\fP). .IP \(bu 2 Fix leak when returning \fBBlockingIOError\fP from a read (\fI\%#143\fP). .IP \(bu 2 Fix "There is no current event loop in thread" error for non asyncio code (\fI\%#146\fP). .IP \(bu 2 Prevent \fBInputDevice\fP destructor from blocking (\fI\%#145\fP). .IP \(bu 2 Add missing return codes to \fBos.strerror()\fP calls and fix force feedback example in docs (\fI\%#138\fP). .IP \(bu 2 Add the \fButil.find_ecodes_by_regex()\fP helper function. .UNINDENT .SS 1.3.0 (Jan 12, 2020) .INDENT 0.0 .IP \(bu 2 Fix build on 32bit arches with 64bit time_t .IP \(bu 2 Add functionality to query device properties. See \fBInputDevice.input_props\fP and the \fBinput_props\fP argument to \fBUinput\fP\&. .IP \(bu 2 \fBKeyEvent\fP received an \fBallow_unknown\fP constructor argument, which determines what will happen when an event code cannot be mapped to a keycode. The default and behavior so far has been to raise \fBKeyError\fP\&. If set to \fBTrue\fP, the keycode will be set to the event code formatted as a hex number. .IP \(bu 2 Add \fBInputDevice.set_absinfo()\fP and \fBInputDevice.absinfo()\fP\&. .IP \(bu 2 Instruct the asyncio event loop to stop monitoring the fd of the input device when the device is closed. .UNINDENT .SS 1.2.0 (Apr 7, 2019) .INDENT 0.0 .IP \(bu 2 Add UInput support for the resolution parameter in AbsInfo. This brings support for the new method of uinput device setup, which was \fI\%introduced in Linux 4.5\fP (thanks to \fI\%@LinusCDE\fP). .IP \(bu 2 Vendor and product identifiers can be greater or equal to \fI0x8000\fP (thanks \fI\%@ivaradi\fP). .UNINDENT .SS 1.1.2 (Sep 1, 2018) .INDENT 0.0 .IP \(bu 2 Fix installation on kernels <= 4.4. .IP \(bu 2 Fix uinput creation ignoring absinfo settings. .UNINDENT .SS 1.1.0 (Aug 27, 2018) .INDENT 0.0 .IP \(bu 2 Add support for handling force\-feedback effect uploads (many thanks to \fI\%@ndreys\fP). .IP \(bu 2 Fix typo preventing ff effects that need left coefficients from working. .UNINDENT .SS 1.0.0 (Jun 02, 2018) .INDENT 0.0 .IP \(bu 2 Prevent \fBUinput\fP device creation raising \fBObjects/longobject.c:415: bad argument to internal function\fP when a non\-complete \fBAbsInfo\fP structure is passed. All missing \fBAbsInfo\fP fields are set to 0. .IP \(bu 2 Fix \fBUinput\fP device creation raising \fBKeyError\fP when a capability filtered by default is not present. .IP \(bu 2 The \fBInputDevice.fn\fP attribute was deprecated in favor of \fBInputDevice.path\fP\&. Using the former will show a \fBDeprecationWarning\fP, but would otherwise continue working as before. .IP \(bu 2 Fix \fBInputDevice\fP comparison raising \fBAttributeError\fP due to a non\-existant \fBpath\fP attribute. .IP \(bu 2 Fix asyncio support in Python 3.5+. .IP \(bu 2 Uploading FF effect now works both on Python 2.7 and Python 3+. .IP \(bu 2 Remove the \fBasyncore\fP example from the tutorial. .UNINDENT .SS 0.8.1 (Mar 24, 2018) .INDENT 0.0 .IP \(bu 2 Fix Python 2 compatibility issue in with \fBUinput.from_device\fP\&. .IP \(bu 2 Fix minor \fIevdev.evtest\fP formatting issue. .UNINDENT .SS 0.8.0 (Mar 22, 2018) .INDENT 0.0 .IP \(bu 2 Fix \fBInputDevice\fP comparison on Python 2. .IP \(bu 2 The device path is now considered when comparing two devices. .IP \(bu 2 Fix \fBUInput.from_device\fP not correctly merging the capabilities of selected devices. .IP \(bu 2 The list of excluded event types in \fBUInput.from_device\fP is now configurable. For example: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C UInput.from_device(dev, filtered_types=(EV_SYN, EV_FF)) .ft P .fi .UNINDENT .UNINDENT .sp In addition, \fBecodes.EV_FF\fP is now excluded by default. .IP \(bu 2 Add a context manager for grabbing access to a device \- \fBInputDevice.grab_context\fP\&. For example: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C with dev.grab_context(): pass .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 Add the \fBInputDevice.uniq\fP attribute, which contains the unique identifier of the device. As with \fBphys\fP, this attribute may be empty (i.e. \fI\(aq\(aq\fP). .UNINDENT .SS 0.7.0 (Jun 16, 2017) .INDENT 0.0 .IP \(bu 2 \fBInputDevice\fP now accepts objects that support the path protocol. For example: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C pth = pathlib.Path(\(aq/dev/input/event0\(aq) dev = evdev.InputDevice(pth) .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 Support path protocol in \fBInputDevice\fP\&. This means that \fBInputDevice\fP instances can be passed to callers that expect a \fBos.PathLike\fP object. .IP \(bu 2 Exceptions raised during \fBInputDevice.async_read()\fP (and similar) are now handled properly (i.e. an exception is set on the returned future instead of leaking that exception into the event loop) (Fixes \fI\%#67\fP). .UNINDENT .SS 0.6.4 (Oct 07, 2016) .INDENT 0.0 .IP \(bu 2 Exclude \fBecodes.c\fP from source distribution (Fixes \fI\%#63\fP). .UNINDENT .SS 0.6.3 (Oct 06, 2016) .INDENT 0.0 .IP \(bu 2 Add the \fBUInput.from_device\fP class method, which allows uinput device to be created with the capabiltiies of one or more existing input devices: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C ui = UInput.from_device(\(aq/dev/input1\(aq, \(aq/dev/input2\(aq, **constructor_kwargs) .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 Add the \fBbuild_ecodes\fP distutils command, which generates the \fBecodes.c\fP extension module. The new way of overwriting the evdev header locations is: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C python setup.py build \e build_ecodes \-\-evdev\-headers path/input.h:path/input\-event\-codes.h \e build_ext \-\-include\-dirs path/ \e install .ft P .fi .UNINDENT .UNINDENT .sp The \fBbuild*\fP and \fBinstall\fP commands no longer have to be part of the same command\-line (i.e. running \fBinstall\fP will reuse the outputs of the last \fBbuild\fP). .UNINDENT .SS 0.6.1 (Jun 04, 2016) .INDENT 0.0 .IP \(bu 2 Disable tty echoing while evtest is running. .IP \(bu 2 Allow evtest to listen to more than one devices. .IP \(bu 2 The setup.py script now allows the location of the input header files to be overwritten. For example: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C python setup.py build_ext \e \-\-evdev\-headers path/input.h:path/input\-event\-codes.h \e \-\-include\-dirs path/ \e install .ft P .fi .UNINDENT .UNINDENT .UNINDENT .SS 0.6.0 (Feb 14, 2016) .INDENT 0.0 .IP \(bu 2 Asyncio and async/await support (many thanks to \fI\%@paulo\-raca\fP). .IP \(bu 2 Add the ability to set the \fIphys\fP property of uinput devices (thanks \fI\%@paulo\-raca\fP). .IP \(bu 2 Add a generic \fBInputDevice.set()\fP method (thanks \fI\%@paulo\-raca\fP). .IP \(bu 2 Distribute the evtest script along with evdev. .IP \(bu 2 Fix issue with generating \fBecodes.c\fP in recent kernels (\fB>= 4.4.0\fP). .IP \(bu 2 Fix absinfo item indexes in \fBUInput.uinput_create()\fP (thanks \fI\%@forsenonlhaimaisentito\fP). .IP \(bu 2 More robust comparison of \fBInputDevice\fP objects (thanks \fI\%@isia\fP). .UNINDENT .SS 0.5.0 (Jun 16, 2015) .INDENT 0.0 .IP \(bu 2 Write access to the input device is no longer mandatory. Evdev will first try to open the device for reading and writing and fallback to read\-only. Methods that require write access (e.g. \fBset_led()\fP) will raise \fBEvdevError\fP if the device is open only for reading. .UNINDENT .SS 0.4.7 (Oct 07, 2014) .INDENT 0.0 .IP \(bu 2 Fallback to distutils if setuptools is not available. .UNINDENT .SS 0.4.6 (Oct 07, 2014) .INDENT 0.0 .IP \(bu 2 Rework documentation and docstrings once more. .IP \(bu 2 Fix install on Python 3.4 (works around \fI\%issue21121\fP). .IP \(bu 2 Fix \fBioctl()\fP requested buffer size (thanks Jakub Wojciech Klama). .UNINDENT .SS 0.4.5 (Jul 06, 2014) .INDENT 0.0 .IP \(bu 2 Add method for returning a list of the currently active keys \- \fBInputDevice.active_keys()\fP (thanks \fI\%@spasche\fP). .IP \(bu 2 Fix a potential buffer overflow in \fBioctl_capabilities()\fP (thanks \fI\%@spasche\fP). .UNINDENT .SS 0.4.4 (Jun 04, 2014) .INDENT 0.0 .IP \(bu 2 Calling \fBInputDevice.read_one()\fP should always return \fBNone\fP, when there is nothing to be read, even in case of a \fBEAGAIN\fP errno (thanks JPP). .UNINDENT .SS 0.4.3 (Dec 19, 2013) .INDENT 0.0 .IP \(bu 2 Silence \fBOSError\fP in destructor (thanks \fI\%@polyphemus\fP). .IP \(bu 2 Make \fBInputDevice.close()\fP work in cases in which stdin (fd 0) has been closed (thanks \fI\%@polyphemus\fP). .UNINDENT .SS 0.4.2 (Dec 13, 2013) .INDENT 0.0 .IP \(bu 2 Rework documentation and docstrings. .IP \(bu 2 Call \fBInputDevice.close()\fP from \fBInputDevice.__del__()\fP\&. .UNINDENT .SS 0.4.1 (Jul 24, 2013) .INDENT 0.0 .IP \(bu 2 Fix reference counting in \fBInputDevice.device_read()\fP, \fBInputDevice.device_read_many()\fP and \fBioctl_capabilities()\fP\&. .UNINDENT .SS 0.4.0 (Jul 01, 2013) .INDENT 0.0 .IP \(bu 2 Add \fBFF_*\fP and \fBFF_STATUS\fP codes to \fBecodes()\fP (thanks \fI\%@bgilbert\fP). .IP \(bu 2 Reverse event code mappings (\fBecodes.{KEY,FF,REL,ABS}\fP and etc.) will now map to a list of codes, whenever a value corresponds to multiple codes: .INDENT 2.0 .INDENT 3.5 .sp .nf .ft C >>> ecodes.KEY[152] \&... [\(aqKEY_COFFEE\(aq, \(aqKEY_SCREENLOCK\(aq] >>> ecodes.KEY[30] \&... \(aqKEY_A\(aq .ft P .fi .UNINDENT .UNINDENT .IP \(bu 2 Set the state of a LED through \fBInputDevice.set_led()\fP (thanks \fI\%@accek\fP). .IP \(bu 2 Open \fBInputDevice.fd\fP in \fBO_RDWR\fP mode from now on. .IP \(bu 2 Fix segfault in \fBInputDevice.device_read_many()\fP (thanks \fI\%@bgilbert\fP). .UNINDENT .SS 0.3.3 (May 29, 2013) .INDENT 0.0 .IP \(bu 2 Raise \fBIOError\fP from \fBInputDevice.device_read()\fP and \fBInputDevice.device_read_many()\fP when \fBInputDevice.read()\fP fails. .IP \(bu 2 Several stability and style changes (thank you debian code reviewers). .UNINDENT .SS 0.3.2 (Apr 05, 2013) .INDENT 0.0 .IP \(bu 2 Fix vendor id and product id order in \fBDeviceInfo()\fP (thanks \fI\%@kived\fP). .UNINDENT .SS 0.3.1 (Nov 23, 2012) .INDENT 0.0 .IP \(bu 2 \fBInputDevice.read()\fP will return an empty tuple if the device has nothing to offer (instead of segfaulting). .IP \(bu 2 Exclude unnecessary package data in sdist and bdist. .UNINDENT .SS 0.3.0 (Nov 06, 2012) .INDENT 0.0 .IP \(bu 2 Add ability to set/get auto\-repeat settings with \fBEVIOC{SG}REP\fP\&. .IP \(bu 2 Add \fBInputDevice.version()\fP \- the value of \fBEVIOCGVERSION\fP\&. .IP \(bu 2 Add \fBInputDevice.read_loop()\fP\&. .IP \(bu 2 Add \fBInputDevice.grab()\fP and \fBInputDevice.ungrab()\fP \- exposes \fBEVIOCGRAB\fP\&. .IP \(bu 2 Add \fBInputDevice.leds()\fP \- exposes \fBEVIOCGLED\fP\&. .IP \(bu 2 Replace \fBDeviceInfo\fP class with a namedtuple. .IP \(bu 2 Prevent \fBInputDevice.read_one()\fP from skipping events. .IP \(bu 2 Rename \fBAbsData\fP to \fBAbsInfo\fP (as in \fBstruct input_absinfo\fP). .UNINDENT .SS 0.2.0 (Aug 22, 2012) .INDENT 0.0 .IP \(bu 2 Add the ability to set arbitrary device capabilities on uinput devices (defaults to all \fBEV_KEY\fP ecodes). .IP \(bu 2 Add \fBUInput.device\fP which is an open \fBInputDevice\fP to the input device that uinput \(aqspawns\(aq. .IP \(bu 2 Add \fBUInput.capabilities()\fP which is just a shortcut to \fBUInput.device.capabilities()\fP\&. .IP \(bu 2 Rename \fBUInput.write()\fP to \fBUInput.write_event()\fP\&. .IP \(bu 2 Add a simpler \fBUInput.write(type, code, value)()\fP method. .IP \(bu 2 Make all \fBUInput()\fP constructor arguments optional (default device name is now \fBpy\-evdev\-uinput\fP). .IP \(bu 2 Add the ability to set \fBabsmin\fP, \fBabsmax\fP, \fBabsfuzz\fP and \fBabsflat\fP when specifying the uinput device\(aqs capabilities. .IP \(bu 2 Remove the \fBnophys\fP argument \- if a device fails the \fBEVIOCGPHYS\fP ioctl, phys will equal the empty string. .IP \(bu 2 Make \fBInputDevice.capabilities()\fP perform a \fBEVIOCGABS\fP ioctl for devices that support \fBEV_ABS\fP and return that info wrapped in an \fBAbsData\fP namedtuple. .IP \(bu 2 Split \fBioctl_devinfo\fP into \fBioctl_devinfo\fP and \fBioctl_capabilities\fP\&. .IP \(bu 2 Split \fBUInput.uinput_open()\fP to \fBUInput.uinput_open()\fP and \fBUInput.uinput_create()\fP .IP \(bu 2 Add more uinput usage examples and documentation. .IP \(bu 2 Rewrite uinput tests. .IP \(bu 2 Remove \fBmouserel\fP and \fBmouseabs\fP from \fBUInput\fP\&. .IP \(bu 2 Tie the sphinx version and release to the distutils version. .IP \(bu 2 Set \(aqmethods\-before\-attributes\(aq sorting in the docs. .IP \(bu 2 Remove \fBKEY_CNT\fP and \fBKEY_MAX\fP from \fBecodes.keys()\fP\&. .UNINDENT .SS 0.1.1 (May 18, 2012) .INDENT 0.0 .IP \(bu 2 Add \fBevents.keys\fP, which is a combination of all \fBBTN_\fP and \fBKEY_\fP event codes. .IP \(bu 2 \fBecodes.c\fP was not generated when installing through \fBpip\fP\&. .UNINDENT .SS 0.1.0 (May 17, 2012) .sp \fIInitial Release\fP .sp This package is released under the terms of the \fI\%Revised BSD License\fP\&. .SH AUTHOR Georgi Valkov .SH COPYRIGHT 2012-2021, Georgi Valkov .\" Generated by docutils manpage writer. .