0
# evdev
1
2
Python bindings to the Linux input handling subsystem, providing access to input events from devices like keyboards, mice, joysticks, and touchscreens. The package enables both reading input events from existing devices and creating virtual input devices to inject events into the Linux input subsystem.
3
4
## Package Information
5
6
- **Package Name**: evdev
7
- **Language**: Python
8
- **Installation**: `pip install evdev`
9
- **Minimum Python**: 3.8+
10
- **Platform**: Linux (requires kernel with evdev support)
11
12
## Core Imports
13
14
```python
15
import evdev
16
```
17
18
Common patterns:
19
20
```python
21
import os
22
from evdev import InputDevice, UInput, categorize, ecodes
23
```
24
25
For specific functionality:
26
27
```python
28
from evdev import list_devices, resolve_ecodes, resolve_ecodes_dict
29
from evdev.ff import Effect, Rumble, Constant, Periodic, Condition
30
```
31
32
## Basic Usage
33
34
### Reading from Input Devices
35
36
```python
37
from evdev import InputDevice, categorize, ecodes
38
39
# Open an input device
40
device = InputDevice('/dev/input/event0')
41
42
# Read events continuously
43
for event in device.read_loop():
44
if event.type == ecodes.EV_KEY:
45
key_event = categorize(event)
46
print(f'Key {key_event.keycode} {key_event.keystate}')
47
```
48
49
### Creating Virtual Input Devices
50
51
```python
52
from evdev import UInput, ecodes
53
54
# Create a virtual input device
55
ui = UInput()
56
57
# Send a key press
58
ui.write(ecodes.EV_KEY, ecodes.KEY_A, 1) # Press
59
ui.write(ecodes.EV_KEY, ecodes.KEY_A, 0) # Release
60
ui.syn()
61
62
ui.close()
63
```
64
65
### Discovering Available Devices
66
67
```python
68
from evdev import list_devices, InputDevice
69
70
# List all available input devices
71
devices = list_devices()
72
for device_path in devices:
73
device = InputDevice(device_path)
74
print(f'{device.path}: {device.name}')
75
```
76
77
## Architecture
78
79
The evdev package is built around several core components:
80
81
- **InputDevice**: Represents physical input devices for reading events and device information
82
- **UInput**: Creates virtual input devices for event injection
83
- **Event System**: Hierarchical event classes (InputEvent, KeyEvent, etc.) for structured event handling
84
- **Event Codes**: Comprehensive constants mapping (ecodes module) for all Linux input event types
85
- **Utilities**: Helper functions for device discovery, event categorization, and code resolution
86
- **Force Feedback**: Support for haptic feedback effects on compatible devices
87
88
The design closely mirrors the Linux kernel's input subsystem, providing a Pythonic interface to evdev character devices while maintaining full access to low-level capabilities.
89
90
## Capabilities
91
92
### Device Operations
93
94
Core functionality for opening, reading from, and controlling input devices. Includes device discovery, capability querying, event reading, and exclusive device access.
95
96
```python { .api }
97
class InputDevice:
98
def __init__(self, dev: Union[str, bytes, os.PathLike]) -> None: ...
99
def capabilities(self, verbose: bool = False, absinfo: bool = True) -> Dict: ...
100
def read_loop(self) -> Iterator[InputEvent]: ...
101
def read_one(self) -> Union[InputEvent, None]: ...
102
def grab(self) -> None: ...
103
def close(self) -> None: ...
104
105
def list_devices(input_device_dir: Union[str, bytes, os.PathLike] = "/dev/input") -> List[str]: ...
106
```
107
108
[Device Operations](./device-operations.md)
109
110
### Event Processing
111
112
Event classes and utilities for handling, categorizing, and interpreting input events from devices. Includes typed event classes and event processing utilities.
113
114
```python { .api }
115
class InputEvent:
116
def __init__(self, sec: int, usec: int, type: int, code: int, value: int) -> None: ...
117
def timestamp(self) -> float: ...
118
119
class KeyEvent:
120
def __init__(self, event: InputEvent, allow_unknown: bool = False) -> None: ...
121
122
def categorize(event: InputEvent) -> Union[InputEvent, KeyEvent, RelEvent, AbsEvent, SynEvent]: ...
123
```
124
125
[Event Processing](./event-processing.md)
126
127
### Virtual Input Devices
128
129
Creating and managing virtual input devices using UInput to inject events into the Linux input subsystem. Supports creating devices with custom capabilities and sending events programmatically.
130
131
```python { .api }
132
class UInput:
133
def __init__(
134
self,
135
events: Optional[Dict[int, Sequence[int]]] = None,
136
name: str = "py-evdev-uinput",
137
vendor: int = 0x1,
138
product: int = 0x1,
139
version: int = 0x1,
140
bustype: int = 0x3,
141
devnode: str = "/dev/uinput",
142
phys: str = "py-evdev-uinput",
143
input_props=None,
144
max_effects: int = 96
145
) -> None: ...
146
147
def write(self, etype: int, code: int, value: int) -> None: ...
148
def syn(self) -> None: ...
149
def close(self) -> None: ...
150
```
151
152
[Virtual Input Devices](./virtual-devices.md)
153
154
### Event Codes and Constants
155
156
Comprehensive mapping of Linux input subsystem constants and utilities for resolving event codes to human-readable names. Includes all event types, key codes, and constant mappings.
157
158
```python { .api }
159
# Event type constants
160
EV_KEY: int
161
EV_REL: int
162
EV_ABS: int
163
EV_SYN: int
164
165
# Key code dictionaries
166
KEY: Dict[int, str]
167
BTN: Dict[int, str]
168
ABS: Dict[int, str]
169
REL: Dict[int, str]
170
171
def resolve_ecodes(ecode_dict, ecode_list, unknown: str = "?") -> List: ...
172
def resolve_ecodes_dict(typecodemap, unknown: str = "?") -> Iterator: ...
173
def find_ecodes_by_regex(regex) -> Dict[int, List[int]]: ...
174
```
175
176
[Event Codes and Constants](./event-codes.md)
177
178
### Force Feedback
179
180
Support for force feedback effects on compatible devices. Includes effect structures, uploading effects, and controlling haptic feedback.
181
182
```python { .api }
183
class Effect(ctypes.Structure): ...
184
class Rumble(ctypes.Structure): ...
185
class Constant(ctypes.Structure): ...
186
class Periodic(ctypes.Structure): ...
187
```
188
189
[Force Feedback](./force-feedback.md)
190
191
## Async Support
192
193
The evdev package provides async support for non-blocking event reading through the eventio_async module (when available):
194
195
```python { .api }
196
class ReadIterator:
197
"""Async iterator for reading input events"""
198
def __aiter__(self) -> ReadIterator: ...
199
def __anext__(self) -> Awaitable[InputEvent]: ...
200
```
201
202
Async usage:
203
204
```python
205
import asyncio
206
from evdev import InputDevice
207
208
async def read_events():
209
device = InputDevice('/dev/input/event0')
210
211
# Async event reading
212
async for event in device.async_read_loop():
213
print(f'Event: {event.type} {event.code} {event.value}')
214
215
# Single async read
216
event = await device.async_read_one()
217
if event:
218
print(f'Single event: {event}')
219
```
220
221
## Error Handling
222
223
The package defines specific exceptions for different error conditions:
224
225
```python { .api }
226
class EvdevError(Exception):
227
"""Base exception for evdev-related errors"""
228
229
class UInputError(Exception):
230
"""Exception for UInput-specific errors"""
231
```
232
233
Common error scenarios include device access permissions, invalid device paths, and UInput device creation failures.
234
235
## Types
236
237
```python { .api }
238
class AbsInfo(NamedTuple):
239
"""Absolute axis information"""
240
value: int
241
min: int
242
max: int
243
fuzz: int
244
flat: int
245
resolution: int
246
247
class DeviceInfo(NamedTuple):
248
"""Device identification information"""
249
bustype: int
250
vendor: int
251
product: int
252
version: int
253
254
class KbdInfo(NamedTuple):
255
"""Keyboard repeat rate information"""
256
delay: int
257
repeat: int
258
```
259
260
Usage examples:
261
262
```python
263
# Get current repeat settings
264
device = InputDevice('/dev/input/event0')
265
kbd_info = device.repeat
266
print(f"Delay: {kbd_info.delay}ms, Rate: {kbd_info.repeat} chars/sec")
267
268
# Set new repeat settings
269
device.repeat = KbdInfo(500, 30) # 500ms delay, 30 chars/sec
270
```