Pure Python wrapper around SDL2 libraries for cross-platform multimedia development
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Low-level event polling and handling functions.
def SDL_PollEvent(event: SDL_Event) -> int:
"""
Poll for currently pending events.
Parameters:
- event: SDL_Event structure to fill with event data
Returns:
1 if there are pending events, 0 if no events available
"""
def SDL_WaitEvent(event: SDL_Event) -> int:
"""Wait indefinitely for the next available event."""
def SDL_WaitEventTimeout(event: SDL_Event, timeout: int) -> int:
"""Wait up to timeout milliseconds for the next available event."""
def SDL_PushEvent(event: SDL_Event) -> int:
"""Add an event to the event queue."""
def SDL_FlushEvent(type: int) -> None:
"""Clear events of specific type from the event queue."""
def SDL_FlushEvents(minType: int, maxType: int) -> None:
"""Clear events in specified type range from the event queue."""
def SDL_HasEvent(type: int) -> bool:
"""Check if events of specific type are available."""
def SDL_HasEvents(minType: int, maxType: int) -> bool:
"""Check if events in type range are available."""Constants defining the various event types.
# Application events
SDL_QUIT: int = 0x100
SDL_APP_TERMINATING: int = 0x101
SDL_APP_LOWMEMORY: int = 0x102
SDL_APP_WILLENTERBACKGROUND: int = 0x103
SDL_APP_DIDENTERBACKGROUND: int = 0x104
SDL_APP_WILLENTERFOREGROUND: int = 0x105
SDL_APP_DIDENTERFOREGROUND: int = 0x106
# Display events
SDL_DISPLAYEVENT: int = 0x150
# Window events
SDL_WINDOWEVENT: int = 0x200
SDL_SYSWMEVENT: int = 0x201
# Keyboard events
SDL_KEYDOWN: int = 0x300
SDL_KEYUP: int = 0x301
SDL_TEXTEDITING: int = 0x302
SDL_TEXTINPUT: int = 0x303
SDL_KEYMAPCHANGED: int = 0x304
SDL_TEXTEDITING_EXT: int = 0x305
# Mouse events
SDL_MOUSEMOTION: int = 0x400
SDL_MOUSEBUTTONDOWN: int = 0x401
SDL_MOUSEBUTTONUP: int = 0x402
SDL_MOUSEWHEEL: int = 0x403
# Joystick events
SDL_JOYAXISMOTION: int = 0x600
SDL_JOYBALLMOTION: int = 0x601
SDL_JOYHATMOTION: int = 0x602
SDL_JOYBUTTONDOWN: int = 0x603
SDL_JOYBUTTONUP: int = 0x604
SDL_JOYDEVICEADDED: int = 0x605
SDL_JOYDEVICEREMOVED: int = 0x606
SDL_JOYBATTERYUPDATED: int = 0x607
# Game controller events
SDL_CONTROLLERAXISMOTION: int = 0x650
SDL_CONTROLLERBUTTONDOWN: int = 0x651
SDL_CONTROLLERBUTTONUP: int = 0x652
SDL_CONTROLLERDEVICEADDED: int = 0x653
SDL_CONTROLLERDEVICEREMOVED: int = 0x654
SDL_CONTROLLERDEVICEREMAPPED: int = 0x655Keyboard state and input handling functions.
def SDL_GetKeyboardState(numkeys: ctypes.POINTER(ctypes.c_int)) -> ctypes.POINTER(ctypes.c_uint8):
"""
Get snapshot of current keyboard state.
Returns:
Pointer to array of key states (1=pressed, 0=released)
"""
def SDL_GetModState() -> int:
"""Get current key modifier state."""
def SDL_SetModState(modstate: int) -> None:
"""Set current key modifier state."""
def SDL_GetKeyFromScancode(scancode: int) -> int:
"""Get key code corresponding to scancode."""
def SDL_GetScancodeFromKey(key: int) -> int:
"""Get scancode corresponding to key code."""
def SDL_GetScancodeName(scancode: int) -> bytes:
"""Get human-readable name for scancode."""
def SDL_GetKeyName(key: int) -> bytes:
"""Get human-readable name for key."""
def SDL_StartTextInput() -> None:
"""Start accepting Unicode text input events."""
def SDL_StopTextInput() -> None:
"""Stop receiving Unicode text input events."""
def SDL_IsTextInputActive() -> bool:
"""Check if Unicode text input events are enabled."""Mouse state, cursor, and input handling functions.
def SDL_GetMouseState(x: ctypes.POINTER(ctypes.c_int), y: ctypes.POINTER(ctypes.c_int)) -> int:
"""
Get current mouse state.
Parameters:
- x, y: pointers to store mouse coordinates
Returns:
Button state bitmask (SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT, etc.)
"""
def SDL_GetRelativeMouseState(x: ctypes.POINTER(ctypes.c_int), y: ctypes.POINTER(ctypes.c_int)) -> int:
"""Get relative mouse state since last call."""
def SDL_WarpMouseInWindow(window: SDL_Window, x: int, y: int) -> None:
"""Move mouse cursor to given coordinates in window."""
def SDL_SetRelativeMouseMode(enabled: bool) -> int:
"""Enable/disable relative mouse mode."""
def SDL_GetRelativeMouseMode() -> bool:
"""Check if relative mouse mode is enabled."""
def SDL_CreateCursor(data: ctypes.POINTER(ctypes.c_uint8), mask: ctypes.POINTER(ctypes.c_uint8),
w: int, h: int, hot_x: int, hot_y: int) -> SDL_Cursor:
"""Create a cursor from bitmap data."""
def SDL_CreateColorCursor(surface: SDL_Surface, hot_x: int, hot_y: int) -> SDL_Cursor:
"""Create a color cursor from surface."""
def SDL_CreateSystemCursor(id: int) -> SDL_Cursor:
"""Create a system cursor."""
def SDL_SetCursor(cursor: SDL_Cursor) -> None:
"""Set active cursor."""
def SDL_GetCursor() -> SDL_Cursor:
"""Get active cursor."""
def SDL_FreeCursor(cursor: SDL_Cursor) -> None:
"""Free cursor resources."""
def SDL_ShowCursor(toggle: int) -> int:
"""Show/hide cursor."""SDL_BUTTON_LEFT: int = 1
SDL_BUTTON_MIDDLE: int = 2
SDL_BUTTON_RIGHT: int = 3
SDL_BUTTON_X1: int = 4
SDL_BUTTON_X2: int = 5
# Mouse button state constants
SDL_PRESSED: int = 1
SDL_RELEASED: int = 0Functions for joystick and game controller support.
def SDL_NumJoysticks() -> int:
"""Get number of joysticks attached to system."""
def SDL_JoystickOpen(device_index: int) -> SDL_Joystick:
"""Open joystick for use."""
def SDL_JoystickClose(joystick: SDL_Joystick) -> None:
"""Close joystick."""
def SDL_JoystickName(joystick: SDL_Joystick) -> bytes:
"""Get joystick name."""
def SDL_JoystickNumAxes(joystick: SDL_Joystick) -> int:
"""Get number of axes on joystick."""
def SDL_JoystickNumButtons(joystick: SDL_Joystick) -> int:
"""Get number of buttons on joystick."""
def SDL_JoystickGetAxis(joystick: SDL_Joystick, axis: int) -> int:
"""Get current state of axis."""
def SDL_JoystickGetButton(joystick: SDL_Joystick, button: int) -> int:
"""Get current state of button."""
def SDL_IsGameController(joystick_index: int) -> bool:
"""Check if joystick is supported by game controller interface."""
def SDL_GameControllerOpen(joystick_index: int) -> SDL_GameController:
"""Open game controller for use."""
def SDL_GameControllerClose(gamecontroller: SDL_GameController) -> None:
"""Close game controller."""
def SDL_GameControllerGetButton(gamecontroller: SDL_GameController, button: int) -> int:
"""Get state of game controller button."""
def SDL_GameControllerGetAxis(gamecontroller: SDL_GameController, axis: int) -> int:
"""Get state of game controller axis."""Extension module functions for simplified event handling.
def get_events() -> list[SDL_Event]:
"""
Get all pending events as a list.
Returns:
List of SDL_Event objects
"""
def key_pressed(key: int) -> bool:
"""
Check if specific key is currently pressed.
Parameters:
- key: SDL key constant (e.g., sdl2.SDLK_SPACE)
Returns:
True if key is pressed, False otherwise
"""
def get_key_state() -> dict[int, bool]:
"""
Get state of all keys.
Returns:
Dictionary mapping key codes to pressed state
"""
def mouse_clicked() -> bool:
"""
Check if any mouse button was clicked this frame.
Returns:
True if mouse was clicked, False otherwise
"""
def get_clicks() -> list[tuple[int, int, int]]:
"""
Get all mouse clicks this frame.
Returns:
List of (button, x, y) tuples for each click
"""
def mouse_coords() -> tuple[int, int]:
"""
Get current mouse coordinates.
Returns:
(x, y) tuple of mouse position
"""
def get_text_input() -> str:
"""
Get text input from this frame.
Returns:
String of text entered this frame
"""class SDL_Event:
"""Union structure for all event types."""
type: int # Event type constant
class SDL_KeyboardEvent:
"""Keyboard event structure."""
type: int # SDL_KEYDOWN or SDL_KEYUP
timestamp: int # Event timestamp
windowID: int # Associated window ID
state: int # SDL_PRESSED or SDL_RELEASED
repeat: int # Non-zero if key repeat
keysym: SDL_Keysym # Key information
class SDL_MouseButtonEvent:
"""Mouse button event structure."""
type: int # SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
timestamp: int # Event timestamp
windowID: int # Associated window ID
which: int # Mouse instance ID
button: int # Mouse button (SDL_BUTTON_LEFT, etc.)
state: int # SDL_PRESSED or SDL_RELEASED
clicks: int # Number of clicks (1=single, 2=double, etc.)
x: int # X coordinate relative to window
y: int # Y coordinate relative to window
class SDL_MouseMotionEvent:
"""Mouse motion event structure."""
type: int # SDL_MOUSEMOTION
timestamp: int # Event timestamp
windowID: int # Associated window ID
which: int # Mouse instance ID
state: int # Current button state
x: int # X coordinate relative to window
y: int # Y coordinate relative to window
xrel: int # Relative motion in X direction
yrel: int # Relative motion in Y direction
class SDL_Keysym:
"""Key symbol structure."""
scancode: int # SDL physical key code
sym: int # SDL virtual key code
mod: int # Current key modifiers
unicode: int # Deprecated (use text events)
class SDL_Joystick:
"""Opaque joystick structure."""
class SDL_GameController:
"""Opaque game controller structure."""
class SDL_Cursor:
"""Opaque cursor structure."""import sdl2
import sdl2.ext
# Initialize and create window
sdl2.ext.init()
window = sdl2.ext.Window("Event Example", size=(800, 600))
window.show()
# Main event loop
running = True
while running:
# Get all events this frame
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
elif event.type == sdl2.SDL_KEYDOWN:
if event.key.keysym.sym == sdl2.SDLK_ESCAPE:
running = False
elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
print(f"Mouse clicked at ({event.button.x}, {event.button.y})")
sdl2.ext.quit()import sdl2
import sdl2.ext
sdl2.ext.init()
window = sdl2.ext.Window("Keyboard Input", size=(800, 600))
window.show()
running = True
while running:
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
elif event.type == sdl2.SDL_KEYDOWN:
key = event.key.keysym.sym
if key == sdl2.SDLK_SPACE:
print("Space key pressed!")
elif key == sdl2.SDLK_w:
print("W key pressed!")
# Check continuous key states
if sdl2.ext.key_pressed(sdl2.SDLK_LEFT):
print("Left arrow held")
if sdl2.ext.key_pressed(sdl2.SDLK_RIGHT):
print("Right arrow held")
sdl2.ext.quit()import sdl2
import sdl2.ext
sdl2.ext.init()
window = sdl2.ext.Window("Mouse Input", size=(800, 600))
window.show()
running = True
while running:
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
button = event.button.button
if button == sdl2.SDL_BUTTON_LEFT:
print(f"Left click at ({event.button.x}, {event.button.y})")
elif button == sdl2.SDL_BUTTON_RIGHT:
print(f"Right click at ({event.button.x}, {event.button.y})")
elif event.type == sdl2.SDL_MOUSEWHEEL:
print(f"Mouse wheel: {event.wheel.y}")
# Get current mouse position
mouse_x, mouse_y = sdl2.ext.mouse_coords()
sdl2.ext.quit()import sdl2
# Initialize SDL with joystick support
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO | sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_GAMECONTROLLER)
# Check for controllers
num_joysticks = sdl2.SDL_NumJoysticks()
print(f"Found {num_joysticks} joysticks")
controller = None
for i in range(num_joysticks):
if sdl2.SDL_IsGameController(i):
controller = sdl2.SDL_GameControllerOpen(i)
if controller:
print(f"Opened controller: {sdl2.SDL_GameControllerName(controller)}")
break
# Event loop with controller input
if controller:
running = True
event = sdl2.SDL_Event()
while running:
while sdl2.SDL_PollEvent(event):
if event.type == sdl2.SDL_QUIT:
running = False
elif event.type == sdl2.SDL_CONTROLLERBUTTONDOWN:
button = event.cbutton.button
if button == sdl2.SDL_CONTROLLER_BUTTON_A:
print("A button pressed!")
elif event.type == sdl2.SDL_CONTROLLERAXISMOTION:
axis = event.caxis.axis
value = event.caxis.value
if axis == sdl2.SDL_CONTROLLER_AXIS_LEFTX:
print(f"Left stick X: {value}")
sdl2.SDL_GameControllerClose(controller)
sdl2.SDL_Quit()Install with Tessl CLI
npx tessl i tessl/pypi-pysdl2