CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pysdl2

Pure Python wrapper around SDL2 libraries for cross-platform multimedia development

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

events-input.mddocs/

Event Handling and Input

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.

Capabilities

Core Event System

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."""

Event Types

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 = 0x655

Keyboard Input

Keyboard 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 Input

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."""

Mouse Button Constants

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 = 0

Joystick and Game Controller Input

Functions 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."""

High-Level Event Utilities

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
    """

Types

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."""

Usage Examples

Basic Event Loop

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()

Keyboard Input Handling

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()

Mouse Input Handling

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()

Game Controller Input

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

docs

audio.md

events-input.md

file-io.md

fonts-text.md

graphics-rendering.md

image-processing.md

index.md

joystick-input.md

sprites-animation.md

system-utils.md

timer.md

window-display.md

tile.json