or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

device-operations.mdevent-codes.mdevent-processing.mdforce-feedback.mdindex.mdvirtual-devices.md

event-processing.mddocs/

0

# Event Processing

1

2

Event classes and utilities for handling input events from Linux input devices. This includes the core event representation, specialized event types, and utilities for event categorization and processing.

3

4

## Capabilities

5

6

### Core Event Representation

7

8

The fundamental InputEvent class represents all input events from the Linux kernel.

9

10

```python { .api }

11

class InputEvent:

12

def __init__(self, sec: int, usec: int, type: int, code: int, value: int) -> None:

13

"""

14

Initialize an input event.

15

16

Parameters:

17

- sec: Seconds since epoch when event occurred

18

- usec: Microsecond portion of timestamp

19

- type: Event type (EV_KEY, EV_REL, EV_ABS, etc.)

20

- code: Event code specific to the event type

21

- value: Event value

22

"""

23

24

def timestamp(self) -> float:

25

"""

26

Return event timestamp as float seconds since epoch.

27

28

Returns:

29

Combined sec + usec as floating point timestamp

30

"""

31

32

# Attributes

33

sec: int # Seconds since epoch

34

usec: int # Microseconds portion

35

type: int # Event type (EV_*)

36

code: int # Event code

37

value: int # Event value

38

```

39

40

### Key Events

41

42

Specialized class for keyboard and button events with enhanced key state information.

43

44

```python { .api }

45

class KeyEvent:

46

# Class constants for key states

47

key_up: int = 0x0 # Key released

48

key_down: int = 0x1 # Key pressed

49

key_hold: int = 0x2 # Key held (repeat)

50

51

def __init__(self, event: InputEvent, allow_unknown: bool = False) -> None:

52

"""

53

Create KeyEvent from InputEvent.

54

55

Parameters:

56

- event: InputEvent with type EV_KEY

57

- allow_unknown: If False, raise KeyError for unknown key codes.

58

If True, use hex value for unknown keys.

59

60

Raises:

61

- KeyError: If key code is unknown and allow_unknown=False

62

"""

63

64

# Attributes

65

scancode: int # Raw scan code from event.code

66

keycode: str # Human-readable key name (e.g., "KEY_A", "BTN_LEFT")

67

keystate: int # Key state (key_up, key_down, or key_hold)

68

event: InputEvent # Reference to original InputEvent

69

```

70

71

### Relative Events

72

73

Events for relative positioning devices like mice and trackballs.

74

75

```python { .api }

76

class RelEvent:

77

def __init__(self, event: InputEvent) -> None:

78

"""

79

Create RelEvent from InputEvent with type EV_REL.

80

81

Parameters:

82

- event: InputEvent with type EV_REL

83

"""

84

85

# Attributes

86

event: InputEvent # Reference to original InputEvent

87

```

88

89

### Absolute Events

90

91

Events for absolute positioning devices like touchscreens and joysticks.

92

93

```python { .api }

94

class AbsEvent:

95

def __init__(self, event: InputEvent) -> None:

96

"""

97

Create AbsEvent from InputEvent with type EV_ABS.

98

99

Parameters:

100

- event: InputEvent with type EV_ABS

101

"""

102

103

# Attributes

104

event: InputEvent # Reference to original InputEvent

105

```

106

107

### Synchronization Events

108

109

Events that mark boundaries between logical input events.

110

111

```python { .api }

112

class SynEvent:

113

def __init__(self, event: InputEvent) -> None:

114

"""

115

Create SynEvent from InputEvent with type EV_SYN.

116

117

Parameters:

118

- event: InputEvent with type EV_SYN

119

"""

120

121

# Attributes

122

event: InputEvent # Reference to original InputEvent

123

```

124

125

### Event Factory

126

127

Dictionary mapping event types to their corresponding event classes.

128

129

```python { .api }

130

event_factory: Dict[int, Type] = {

131

# Maps event type codes to event classes

132

# EV_KEY -> KeyEvent

133

# EV_REL -> RelEvent

134

# EV_ABS -> AbsEvent

135

# EV_SYN -> SynEvent

136

}

137

```

138

139

### Event Categorization

140

141

Utilities for converting generic InputEvent objects to specialized event types.

142

143

```python { .api }

144

def categorize(event: InputEvent) -> Union[InputEvent, KeyEvent, RelEvent, AbsEvent, SynEvent]:

145

"""

146

Categorize InputEvent according to its type.

147

148

Uses event_factory dictionary to map event types to specialized classes.

149

If event type is not found in factory, returns original InputEvent unchanged.

150

151

Parameters:

152

- event: InputEvent to categorize

153

154

Returns:

155

Specialized event object (KeyEvent, RelEvent, etc.) or original InputEvent

156

"""

157

```

158

159

## Usage Examples

160

161

### Basic Event Processing

162

163

```python

164

from evdev import InputDevice, categorize, ecodes

165

166

device = InputDevice('/dev/input/event0')

167

168

for event in device.read_loop():

169

# Categorize event based on type

170

categorized_event = categorize(event)

171

172

if isinstance(categorized_event, KeyEvent):

173

print(f"Key event: {categorized_event.keycode} -> {categorized_event.keystate}")

174

elif isinstance(categorized_event, RelEvent):

175

print(f"Relative event: code={event.code}, value={event.value}")

176

elif isinstance(categorized_event, AbsEvent):

177

print(f"Absolute event: code={event.code}, value={event.value}")

178

else:

179

print(f"Other event: {event}")

180

```

181

182

### Key State Processing

183

184

```python

185

from evdev import InputDevice, categorize, ecodes, KeyEvent

186

187

device = InputDevice('/dev/input/event0')

188

189

for event in device.read_loop():

190

if event.type == ecodes.EV_KEY:

191

key_event = categorize(event)

192

193

if key_event.keystate == KeyEvent.key_down:

194

print(f"Key pressed: {key_event.keycode}")

195

elif key_event.keystate == KeyEvent.key_up:

196

print(f"Key released: {key_event.keycode}")

197

elif key_event.keystate == KeyEvent.key_hold:

198

print(f"Key held: {key_event.keycode}")

199

```

200

201

### Event Filtering by Type

202

203

```python

204

from evdev import InputDevice, categorize, ecodes

205

206

device = InputDevice('/dev/input/event0')

207

208

def process_events():

209

for event in device.read_loop():

210

if event.type == ecodes.EV_KEY:

211

# Process keyboard/button events

212

key_event = categorize(event)

213

handle_key_event(key_event)

214

215

elif event.type == ecodes.EV_REL:

216

# Process mouse movement events

217

rel_event = categorize(event)

218

handle_mouse_movement(rel_event)

219

220

elif event.type == ecodes.EV_ABS:

221

# Process absolute positioning events

222

abs_event = categorize(event)

223

handle_absolute_positioning(abs_event)

224

225

elif event.type == ecodes.EV_SYN:

226

# Synchronization event - marks end of event sequence

227

handle_sync_event(event)

228

229

def handle_key_event(key_event):

230

print(f"Key: {key_event.keycode}, State: {key_event.keystate}")

231

232

def handle_mouse_movement(rel_event):

233

event = rel_event.event

234

if event.code == ecodes.REL_X:

235

print(f"Mouse X movement: {event.value}")

236

elif event.code == ecodes.REL_Y:

237

print(f"Mouse Y movement: {event.value}")

238

239

def handle_absolute_positioning(abs_event):

240

event = abs_event.event

241

if event.code == ecodes.ABS_X:

242

print(f"Touch X position: {event.value}")

243

elif event.code == ecodes.ABS_Y:

244

print(f"Touch Y position: {event.value}")

245

246

def handle_sync_event(event):

247

if event.code == ecodes.SYN_REPORT:

248

print("End of event sequence")

249

250

process_events()

251

```

252

253

### Event Timestamp Processing

254

255

```python

256

from evdev import InputDevice, categorize

257

import time

258

259

device = InputDevice('/dev/input/event0')

260

start_time = time.time()

261

262

for event in device.read_loop():

263

# Get event timestamp

264

event_time = event.timestamp()

265

relative_time = event_time - start_time

266

267

categorized = categorize(event)

268

print(f"[{relative_time:.3f}s] {categorized}")

269

270

# Alternative: access timestamp components directly

271

print(f"Event at {event.sec}.{event.usec:06d}")

272

```

273

274

### Handling Unknown Key Codes

275

276

```python

277

from evdev import InputDevice, categorize, ecodes, KeyEvent

278

279

device = InputDevice('/dev/input/event0')

280

281

for event in device.read_loop():

282

if event.type == ecodes.EV_KEY:

283

try:

284

# Default behavior - raises KeyError for unknown keys

285

key_event = KeyEvent(event)

286

print(f"Known key: {key_event.keycode}")

287

except KeyError:

288

# Handle unknown key codes

289

key_event = KeyEvent(event, allow_unknown=True)

290

print(f"Unknown key: {key_event.keycode} (code: {key_event.scancode})")

291

```

292

293

### Event Stream Buffering

294

295

```python

296

from evdev import InputDevice, categorize

297

from collections import deque

298

299

device = InputDevice('/dev/input/event0')

300

event_buffer = deque(maxlen=100) # Keep last 100 events

301

302

def process_buffered_events():

303

while True:

304

# Read all available events

305

events = device.read()

306

307

# Add to buffer and categorize

308

for event in events:

309

categorized = categorize(event)

310

event_buffer.append(categorized)

311

312

# Process buffer

313

while event_buffer:

314

event = event_buffer.popleft()

315

handle_event(event)

316

317

def handle_event(event):

318

if isinstance(event, KeyEvent):

319

print(f"Buffered key event: {event.keycode}")

320

else:

321

print(f"Buffered event: {event}")

322

323

process_buffered_events()

324

```