0
# Event Handling and Input
1
2
Comprehensive event system for keyboard, mouse, joystick, and system events. PySDL2 provides both polling and event-driven approaches through direct SDL2 bindings and simplified extension utilities.
3
4
## Capabilities
5
6
### Core Event System
7
8
Low-level event polling and handling functions.
9
10
```python { .api }
11
def SDL_PollEvent(event: SDL_Event) -> int:
12
"""
13
Poll for currently pending events.
14
15
Parameters:
16
- event: SDL_Event structure to fill with event data
17
18
Returns:
19
1 if there are pending events, 0 if no events available
20
"""
21
22
def SDL_WaitEvent(event: SDL_Event) -> int:
23
"""Wait indefinitely for the next available event."""
24
25
def SDL_WaitEventTimeout(event: SDL_Event, timeout: int) -> int:
26
"""Wait up to timeout milliseconds for the next available event."""
27
28
def SDL_PushEvent(event: SDL_Event) -> int:
29
"""Add an event to the event queue."""
30
31
def SDL_FlushEvent(type: int) -> None:
32
"""Clear events of specific type from the event queue."""
33
34
def SDL_FlushEvents(minType: int, maxType: int) -> None:
35
"""Clear events in specified type range from the event queue."""
36
37
def SDL_HasEvent(type: int) -> bool:
38
"""Check if events of specific type are available."""
39
40
def SDL_HasEvents(minType: int, maxType: int) -> bool:
41
"""Check if events in type range are available."""
42
```
43
44
### Event Types
45
46
Constants defining the various event types.
47
48
```python { .api }
49
# Application events
50
SDL_QUIT: int = 0x100
51
SDL_APP_TERMINATING: int = 0x101
52
SDL_APP_LOWMEMORY: int = 0x102
53
SDL_APP_WILLENTERBACKGROUND: int = 0x103
54
SDL_APP_DIDENTERBACKGROUND: int = 0x104
55
SDL_APP_WILLENTERFOREGROUND: int = 0x105
56
SDL_APP_DIDENTERFOREGROUND: int = 0x106
57
58
# Display events
59
SDL_DISPLAYEVENT: int = 0x150
60
61
# Window events
62
SDL_WINDOWEVENT: int = 0x200
63
SDL_SYSWMEVENT: int = 0x201
64
65
# Keyboard events
66
SDL_KEYDOWN: int = 0x300
67
SDL_KEYUP: int = 0x301
68
SDL_TEXTEDITING: int = 0x302
69
SDL_TEXTINPUT: int = 0x303
70
SDL_KEYMAPCHANGED: int = 0x304
71
SDL_TEXTEDITING_EXT: int = 0x305
72
73
# Mouse events
74
SDL_MOUSEMOTION: int = 0x400
75
SDL_MOUSEBUTTONDOWN: int = 0x401
76
SDL_MOUSEBUTTONUP: int = 0x402
77
SDL_MOUSEWHEEL: int = 0x403
78
79
# Joystick events
80
SDL_JOYAXISMOTION: int = 0x600
81
SDL_JOYBALLMOTION: int = 0x601
82
SDL_JOYHATMOTION: int = 0x602
83
SDL_JOYBUTTONDOWN: int = 0x603
84
SDL_JOYBUTTONUP: int = 0x604
85
SDL_JOYDEVICEADDED: int = 0x605
86
SDL_JOYDEVICEREMOVED: int = 0x606
87
SDL_JOYBATTERYUPDATED: int = 0x607
88
89
# Game controller events
90
SDL_CONTROLLERAXISMOTION: int = 0x650
91
SDL_CONTROLLERBUTTONDOWN: int = 0x651
92
SDL_CONTROLLERBUTTONUP: int = 0x652
93
SDL_CONTROLLERDEVICEADDED: int = 0x653
94
SDL_CONTROLLERDEVICEREMOVED: int = 0x654
95
SDL_CONTROLLERDEVICEREMAPPED: int = 0x655
96
```
97
98
### Keyboard Input
99
100
Keyboard state and input handling functions.
101
102
```python { .api }
103
def SDL_GetKeyboardState(numkeys: ctypes.POINTER(ctypes.c_int)) -> ctypes.POINTER(ctypes.c_uint8):
104
"""
105
Get snapshot of current keyboard state.
106
107
Returns:
108
Pointer to array of key states (1=pressed, 0=released)
109
"""
110
111
def SDL_GetModState() -> int:
112
"""Get current key modifier state."""
113
114
def SDL_SetModState(modstate: int) -> None:
115
"""Set current key modifier state."""
116
117
def SDL_GetKeyFromScancode(scancode: int) -> int:
118
"""Get key code corresponding to scancode."""
119
120
def SDL_GetScancodeFromKey(key: int) -> int:
121
"""Get scancode corresponding to key code."""
122
123
def SDL_GetScancodeName(scancode: int) -> bytes:
124
"""Get human-readable name for scancode."""
125
126
def SDL_GetKeyName(key: int) -> bytes:
127
"""Get human-readable name for key."""
128
129
def SDL_StartTextInput() -> None:
130
"""Start accepting Unicode text input events."""
131
132
def SDL_StopTextInput() -> None:
133
"""Stop receiving Unicode text input events."""
134
135
def SDL_IsTextInputActive() -> bool:
136
"""Check if Unicode text input events are enabled."""
137
```
138
139
### Mouse Input
140
141
Mouse state, cursor, and input handling functions.
142
143
```python { .api }
144
def SDL_GetMouseState(x: ctypes.POINTER(ctypes.c_int), y: ctypes.POINTER(ctypes.c_int)) -> int:
145
"""
146
Get current mouse state.
147
148
Parameters:
149
- x, y: pointers to store mouse coordinates
150
151
Returns:
152
Button state bitmask (SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT, etc.)
153
"""
154
155
def SDL_GetRelativeMouseState(x: ctypes.POINTER(ctypes.c_int), y: ctypes.POINTER(ctypes.c_int)) -> int:
156
"""Get relative mouse state since last call."""
157
158
def SDL_WarpMouseInWindow(window: SDL_Window, x: int, y: int) -> None:
159
"""Move mouse cursor to given coordinates in window."""
160
161
def SDL_SetRelativeMouseMode(enabled: bool) -> int:
162
"""Enable/disable relative mouse mode."""
163
164
def SDL_GetRelativeMouseMode() -> bool:
165
"""Check if relative mouse mode is enabled."""
166
167
def SDL_CreateCursor(data: ctypes.POINTER(ctypes.c_uint8), mask: ctypes.POINTER(ctypes.c_uint8),
168
w: int, h: int, hot_x: int, hot_y: int) -> SDL_Cursor:
169
"""Create a cursor from bitmap data."""
170
171
def SDL_CreateColorCursor(surface: SDL_Surface, hot_x: int, hot_y: int) -> SDL_Cursor:
172
"""Create a color cursor from surface."""
173
174
def SDL_CreateSystemCursor(id: int) -> SDL_Cursor:
175
"""Create a system cursor."""
176
177
def SDL_SetCursor(cursor: SDL_Cursor) -> None:
178
"""Set active cursor."""
179
180
def SDL_GetCursor() -> SDL_Cursor:
181
"""Get active cursor."""
182
183
def SDL_FreeCursor(cursor: SDL_Cursor) -> None:
184
"""Free cursor resources."""
185
186
def SDL_ShowCursor(toggle: int) -> int:
187
"""Show/hide cursor."""
188
```
189
190
### Mouse Button Constants
191
192
```python { .api }
193
SDL_BUTTON_LEFT: int = 1
194
SDL_BUTTON_MIDDLE: int = 2
195
SDL_BUTTON_RIGHT: int = 3
196
SDL_BUTTON_X1: int = 4
197
SDL_BUTTON_X2: int = 5
198
199
# Mouse button state constants
200
SDL_PRESSED: int = 1
201
SDL_RELEASED: int = 0
202
```
203
204
### Joystick and Game Controller Input
205
206
Functions for joystick and game controller support.
207
208
```python { .api }
209
def SDL_NumJoysticks() -> int:
210
"""Get number of joysticks attached to system."""
211
212
def SDL_JoystickOpen(device_index: int) -> SDL_Joystick:
213
"""Open joystick for use."""
214
215
def SDL_JoystickClose(joystick: SDL_Joystick) -> None:
216
"""Close joystick."""
217
218
def SDL_JoystickName(joystick: SDL_Joystick) -> bytes:
219
"""Get joystick name."""
220
221
def SDL_JoystickNumAxes(joystick: SDL_Joystick) -> int:
222
"""Get number of axes on joystick."""
223
224
def SDL_JoystickNumButtons(joystick: SDL_Joystick) -> int:
225
"""Get number of buttons on joystick."""
226
227
def SDL_JoystickGetAxis(joystick: SDL_Joystick, axis: int) -> int:
228
"""Get current state of axis."""
229
230
def SDL_JoystickGetButton(joystick: SDL_Joystick, button: int) -> int:
231
"""Get current state of button."""
232
233
def SDL_IsGameController(joystick_index: int) -> bool:
234
"""Check if joystick is supported by game controller interface."""
235
236
def SDL_GameControllerOpen(joystick_index: int) -> SDL_GameController:
237
"""Open game controller for use."""
238
239
def SDL_GameControllerClose(gamecontroller: SDL_GameController) -> None:
240
"""Close game controller."""
241
242
def SDL_GameControllerGetButton(gamecontroller: SDL_GameController, button: int) -> int:
243
"""Get state of game controller button."""
244
245
def SDL_GameControllerGetAxis(gamecontroller: SDL_GameController, axis: int) -> int:
246
"""Get state of game controller axis."""
247
```
248
249
### High-Level Event Utilities
250
251
Extension module functions for simplified event handling.
252
253
```python { .api }
254
def get_events() -> list[SDL_Event]:
255
"""
256
Get all pending events as a list.
257
258
Returns:
259
List of SDL_Event objects
260
"""
261
262
def key_pressed(key: int) -> bool:
263
"""
264
Check if specific key is currently pressed.
265
266
Parameters:
267
- key: SDL key constant (e.g., sdl2.SDLK_SPACE)
268
269
Returns:
270
True if key is pressed, False otherwise
271
"""
272
273
def get_key_state() -> dict[int, bool]:
274
"""
275
Get state of all keys.
276
277
Returns:
278
Dictionary mapping key codes to pressed state
279
"""
280
281
def mouse_clicked() -> bool:
282
"""
283
Check if any mouse button was clicked this frame.
284
285
Returns:
286
True if mouse was clicked, False otherwise
287
"""
288
289
def get_clicks() -> list[tuple[int, int, int]]:
290
"""
291
Get all mouse clicks this frame.
292
293
Returns:
294
List of (button, x, y) tuples for each click
295
"""
296
297
def mouse_coords() -> tuple[int, int]:
298
"""
299
Get current mouse coordinates.
300
301
Returns:
302
(x, y) tuple of mouse position
303
"""
304
305
def get_text_input() -> str:
306
"""
307
Get text input from this frame.
308
309
Returns:
310
String of text entered this frame
311
"""
312
```
313
314
## Types
315
316
```python { .api }
317
class SDL_Event:
318
"""Union structure for all event types."""
319
type: int # Event type constant
320
321
class SDL_KeyboardEvent:
322
"""Keyboard event structure."""
323
type: int # SDL_KEYDOWN or SDL_KEYUP
324
timestamp: int # Event timestamp
325
windowID: int # Associated window ID
326
state: int # SDL_PRESSED or SDL_RELEASED
327
repeat: int # Non-zero if key repeat
328
keysym: SDL_Keysym # Key information
329
330
class SDL_MouseButtonEvent:
331
"""Mouse button event structure."""
332
type: int # SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
333
timestamp: int # Event timestamp
334
windowID: int # Associated window ID
335
which: int # Mouse instance ID
336
button: int # Mouse button (SDL_BUTTON_LEFT, etc.)
337
state: int # SDL_PRESSED or SDL_RELEASED
338
clicks: int # Number of clicks (1=single, 2=double, etc.)
339
x: int # X coordinate relative to window
340
y: int # Y coordinate relative to window
341
342
class SDL_MouseMotionEvent:
343
"""Mouse motion event structure."""
344
type: int # SDL_MOUSEMOTION
345
timestamp: int # Event timestamp
346
windowID: int # Associated window ID
347
which: int # Mouse instance ID
348
state: int # Current button state
349
x: int # X coordinate relative to window
350
y: int # Y coordinate relative to window
351
xrel: int # Relative motion in X direction
352
yrel: int # Relative motion in Y direction
353
354
class SDL_Keysym:
355
"""Key symbol structure."""
356
scancode: int # SDL physical key code
357
sym: int # SDL virtual key code
358
mod: int # Current key modifiers
359
unicode: int # Deprecated (use text events)
360
361
class SDL_Joystick:
362
"""Opaque joystick structure."""
363
364
class SDL_GameController:
365
"""Opaque game controller structure."""
366
367
class SDL_Cursor:
368
"""Opaque cursor structure."""
369
```
370
371
## Usage Examples
372
373
### Basic Event Loop
374
375
```python
376
import sdl2
377
import sdl2.ext
378
379
# Initialize and create window
380
sdl2.ext.init()
381
window = sdl2.ext.Window("Event Example", size=(800, 600))
382
window.show()
383
384
# Main event loop
385
running = True
386
while running:
387
# Get all events this frame
388
events = sdl2.ext.get_events()
389
390
for event in events:
391
if event.type == sdl2.SDL_QUIT:
392
running = False
393
elif event.type == sdl2.SDL_KEYDOWN:
394
if event.key.keysym.sym == sdl2.SDLK_ESCAPE:
395
running = False
396
elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
397
print(f"Mouse clicked at ({event.button.x}, {event.button.y})")
398
399
sdl2.ext.quit()
400
```
401
402
### Keyboard Input Handling
403
404
```python
405
import sdl2
406
import sdl2.ext
407
408
sdl2.ext.init()
409
window = sdl2.ext.Window("Keyboard Input", size=(800, 600))
410
window.show()
411
412
running = True
413
while running:
414
events = sdl2.ext.get_events()
415
416
for event in events:
417
if event.type == sdl2.SDL_QUIT:
418
running = False
419
elif event.type == sdl2.SDL_KEYDOWN:
420
key = event.key.keysym.sym
421
if key == sdl2.SDLK_SPACE:
422
print("Space key pressed!")
423
elif key == sdl2.SDLK_w:
424
print("W key pressed!")
425
426
# Check continuous key states
427
if sdl2.ext.key_pressed(sdl2.SDLK_LEFT):
428
print("Left arrow held")
429
if sdl2.ext.key_pressed(sdl2.SDLK_RIGHT):
430
print("Right arrow held")
431
432
sdl2.ext.quit()
433
```
434
435
### Mouse Input Handling
436
437
```python
438
import sdl2
439
import sdl2.ext
440
441
sdl2.ext.init()
442
window = sdl2.ext.Window("Mouse Input", size=(800, 600))
443
window.show()
444
445
running = True
446
while running:
447
events = sdl2.ext.get_events()
448
449
for event in events:
450
if event.type == sdl2.SDL_QUIT:
451
running = False
452
elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
453
button = event.button.button
454
if button == sdl2.SDL_BUTTON_LEFT:
455
print(f"Left click at ({event.button.x}, {event.button.y})")
456
elif button == sdl2.SDL_BUTTON_RIGHT:
457
print(f"Right click at ({event.button.x}, {event.button.y})")
458
elif event.type == sdl2.SDL_MOUSEWHEEL:
459
print(f"Mouse wheel: {event.wheel.y}")
460
461
# Get current mouse position
462
mouse_x, mouse_y = sdl2.ext.mouse_coords()
463
464
sdl2.ext.quit()
465
```
466
467
### Game Controller Input
468
469
```python
470
import sdl2
471
472
# Initialize SDL with joystick support
473
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO | sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_GAMECONTROLLER)
474
475
# Check for controllers
476
num_joysticks = sdl2.SDL_NumJoysticks()
477
print(f"Found {num_joysticks} joysticks")
478
479
controller = None
480
for i in range(num_joysticks):
481
if sdl2.SDL_IsGameController(i):
482
controller = sdl2.SDL_GameControllerOpen(i)
483
if controller:
484
print(f"Opened controller: {sdl2.SDL_GameControllerName(controller)}")
485
break
486
487
# Event loop with controller input
488
if controller:
489
running = True
490
event = sdl2.SDL_Event()
491
492
while running:
493
while sdl2.SDL_PollEvent(event):
494
if event.type == sdl2.SDL_QUIT:
495
running = False
496
elif event.type == sdl2.SDL_CONTROLLERBUTTONDOWN:
497
button = event.cbutton.button
498
if button == sdl2.SDL_CONTROLLER_BUTTON_A:
499
print("A button pressed!")
500
elif event.type == sdl2.SDL_CONTROLLERAXISMOTION:
501
axis = event.caxis.axis
502
value = event.caxis.value
503
if axis == sdl2.SDL_CONTROLLER_AXIS_LEFTX:
504
print(f"Left stick X: {value}")
505
506
sdl2.SDL_GameControllerClose(controller)
507
508
sdl2.SDL_Quit()
509
```