sdl

SDL2 bindings for Kit - cross-platform windowing, input, and graphics

Files

FileDescription
.editorconfigEditor formatting configuration
.gitignoreGit ignore rules for build artifacts and dependencies
.tool-versionsasdf tool versions (Zig, Kit)
LICENSEMIT license file
README.mdThis file
c/kit_sdl.cC FFI wrapper
c/kit_sdl.hC header for FFI wrapper
examples/animation.kitExample: animation
examples/basic.kitBasic usage example
examples/basic_image/main.kitExample: main
examples/basic_mixer/main.kitExample: main
examples/basic_window/main.kitExample: main
examples/input.kitExample: input
examples/lbm/main.kitExample: main
examples/tvintris/main.kitExample: main
examples/version/main.kitExample: main
examples/versions/main.kitExample: main
kit.tomlPackage manifest with metadata and dependencies
src/sdl.kitSDL - Cross-platform windowing, input, and graphics for Kit
tests/sdl-properties.test.kitTests for sdl-properties
tests/sdl.test.kitTests for sdl

Dependencies

No Kit package dependencies.

Installation

kit add gitlab.com/kit-lang/packages/kit-sdl.git

Usage

import Kit.Sdl

License

MIT License - see LICENSE for details.

Exported Functions & Types

Raw SDL event record returned by the low-level polling APIs.

Event

Typed SDL event normalized from a raw event record.

Variants

Quit
KeyDown {scancode, keycode, mods, repeat?}
KeyUp {scancode, keycode, mods, repeat?}
TextInput {text}
TextEditing {text, start, length}
MouseMotion {x, y, rel-x, rel-y}
MouseButtonDown {x, y, button, clicks}
MouseButtonUp {x, y, button, clicks}
MouseWheel {x, y, direction}
WindowShown
WindowHidden
WindowExposed
WindowMoved {x, y}
WindowResized {width, height}
WindowSizeChanged {width, height}
WindowMinimized
WindowMaximized
WindowRestored
WindowEnter
WindowLeave
WindowFocusGained
WindowFocusLost
WindowClose
WindowDisplayChanged {display-index}
DropFile {path}
DropText {text}
DropBegin
DropComplete
Other {event-type}

Derived window state summary used by UI runtimes.

Platform-specific native window handles used by renderer backends.

The first pass returns a flat record keyed by the SDL window-manager subsystem. Backends can branch on subsystem and read the fields relevant to that platform.

CursorKind

Stable cursor abstraction for UI runtimes.

Variants

Arrow
IBeam
Wait
Crosshair
WaitArrow
SizeNWSE
SizeNESW
SizeWE
SizeNS
SizeAll
No
Hand

init

Initialize SDL with all subsystems (video, audio, timer, joystick, gamecontroller).

Returns:

Result Unit String

match init()
  | Ok _ -> print "SDL initialized"
  | Err err -> print "Failed: ${err}"

init-video

Initialize SDL video subsystem only.

Returns:

Result Unit String

match init-video()
  | Ok _ -> print "Video initialized"
  | Err err -> print "Failed: ${err}"

init-audio

Initialize SDL audio subsystem only.

Returns:

Result Unit String

match init-audio()
  | Ok _ -> print "Audio initialized"
  | Err err -> print "Failed: ${err}"

quit

Shut down SDL and clean up all subsystems.

Returns:

Unit

quit()

get-error

Get the last SDL error message.

Returns:

String

error = get-error()
print "SDL error: ${error}"

create-window

Create a window centered on screen with default flags.

Parameters:

Returns:

String -> Int -> Int -> Result {ptr: Ptr} String

match create-window "My Window" 800 600
  | Ok window ->
    # Use window...
    destroy-window window
  | Err err -> print "Failed: ${err}"

create-window-ex

Create a window with explicit position and flags.

Parameters:

Returns:

NonEmptyString -> Int -> Int -> PositiveInt -> PositiveInt -> Int -> Result {ptr: Ptr} String

flags = window-shown | window-resizable
match create-window-ex "My Window" 100 100 800 600 flags
  | Ok window -> print "Window created"
  | Err err -> print "Failed: ${err}"

destroy-window

Destroy a window and free its resources.

Parameters:

Returns:

{ptr: Ptr} -> Unit

destroy-window window

set-window-title

{ptr: Ptr} -> NonEmptyString -> Unit

get-window-title

{ptr: Ptr} -> String

set-window-size

{ptr: Ptr} -> PositiveInt -> PositiveInt -> Unit

get-window-width

{ptr: Ptr} -> Int

get-window-height

{ptr: Ptr} -> Int

window-size

Get the logical window size as a record.

{ptr: Ptr} -> {width: Int, height: Int}

set-window-position

{ptr: Ptr} -> Int -> Int -> Unit

get-window-x

{ptr: Ptr} -> Int

get-window-y

{ptr: Ptr} -> Int

window-position

Get the current window position as a record.

{ptr: Ptr} -> {x: Int, y: Int}

get-window-display-index

Get the display index currently hosting the window.

{ptr: Ptr} -> Int

get-native-window-info

Query platform-native window handles for renderer interop.

The first pass exposes the common desktop backends available from SDL_GetWindowWMInfo: Windows, X11, Cocoa, and Wayland.

{ptr: Ptr} -> Result NativeWindowInfo String

get-window-flags

Read the raw SDL window flags bitmask.

{ptr: Ptr} -> Int

has-window-flag?

Check whether a specific SDL window flag is present.

Int -> Int -> Bool

window-state-from-flags

Derive a normalized window-state record from raw SDL flags.

Int -> WindowState

window-state

Derive a normalized window-state record for a live window.

{ptr: Ptr} -> WindowState

is-window-hidden?

{ptr: Ptr} -> Bool

is-window-visible?

{ptr: Ptr} -> Bool

is-window-minimized?

{ptr: Ptr} -> Bool

is-window-maximized?

{ptr: Ptr} -> Bool

has-window-input-focus?

{ptr: Ptr} -> Bool

has-window-mouse-focus?

{ptr: Ptr} -> Bool

show-window

{ptr: Ptr} -> Unit

hide-window

{ptr: Ptr} -> Unit

raise-window

{ptr: Ptr} -> Unit

maximize-window

{ptr: Ptr} -> Unit

minimize-window

{ptr: Ptr} -> Unit

restore-window

{ptr: Ptr} -> Unit

set-fullscreen

{ptr: Ptr} -> Bool -> Unit

is-fullscreen?

{ptr: Ptr} -> Bool

create-renderer

Create a hardware-accelerated renderer for a window.

Parameters:

Returns:

{ptr: Ptr} -> Result {ptr: Ptr} String

match create-renderer window
  | Ok renderer ->
    # Use renderer...
    destroy-renderer renderer
  | Err err -> print "Failed: ${err}"

create-software-renderer

Create a software renderer for a window (slower, no hardware acceleration).

Parameters:

Returns:

{ptr: Ptr} -> Result {ptr: Ptr} String

match create-software-renderer window
  | Ok renderer -> print "Software renderer created"
  | Err err -> print "Failed: ${err}"

destroy-renderer

Destroy a renderer and free its resources.

Parameters:

Returns:

{ptr: Ptr} -> Unit

destroy-renderer renderer

clear

Clear the rendering target with the current draw color.

Parameters:

Returns:

{ptr: Ptr} -> Unit

set-draw-color renderer 0 0 0 255
clear renderer

present

Present the current rendering to the window (swap buffers).

Parameters:

Returns:

{ptr: Ptr} -> Unit

clear renderer
# Draw stuff...
present renderer

set-draw-color

Set the color used for drawing operations.

Parameters:

Returns:

{ptr: Ptr} -> Int -> Int -> Int -> Int -> Unit

set-draw-color renderer 255 0 0 255  # Red

draw-point

Draw a single point at the specified position.

Parameters:

Returns:

{ptr: Ptr} -> Int -> Int -> Unit

set-draw-color renderer 255 255 255 255
draw-point renderer 100 100

draw-line

Draw a line between two points.

Parameters:

Returns:

{ptr: Ptr} -> Int -> Int -> Int -> Int -> Unit

draw-line renderer 0 0 100 100

draw-rect

Draw a rectangle outline.

Parameters:

Returns:

{ptr: Ptr} -> Int -> Int -> Int -> Int -> Unit

draw-rect renderer 50 50 100 100

fill-rect

Draw a filled rectangle.

Parameters:

Returns:

{ptr: Ptr} -> Int -> Int -> Int -> Int -> Unit

set-draw-color renderer 0 255 0 255
fill-rect renderer 50 50 100 100

set-viewport

{ptr: Ptr} -> Int -> Int -> Int -> Int -> Unit

reset-viewport

{ptr: Ptr} -> Unit

load-texture

{ptr: Ptr} -> NonEmptyString -> Result {ptr: Ptr} String

destroy-texture

{ptr: Ptr} -> Unit

texture-width

{ptr: Ptr} -> Int

texture-height

{ptr: Ptr} -> Int

draw-texture

{ptr: Ptr} -> {ptr: Ptr} -> Int -> Int -> Unit

draw-texture-sized

{ptr: Ptr} -> {ptr: Ptr} -> Int -> Int -> Int -> Int -> Unit

draw-texture-ex

{ptr: Ptr} -> {ptr: Ptr} -> Int -> Int -> Int -> Int -> Float -> Bool -> Bool -> Unit

set-texture-alpha

{ptr: Ptr} -> Int -> Unit

set-texture-color

{ptr: Ptr} -> Int -> Int -> Int -> Unit

poll-event

Poll for pending events without blocking.

Returns:

Option RawEvent

match poll-event()
  | Some event ->
    if event.event-type == event-quit then
      print "Quit requested"
    else if event.event-type == event-keydown then
      print "Key pressed: ${Int.to-string event.key-scancode}"
  | None -> ()  # No events

wait-event

Wait indefinitely for an event (blocks until event arrives).

Returns:

Option RawEvent

match wait-event()
  | Some event -> print "Got event: ${Int.to-string event.event-type}"
  | None -> print "Error waiting for event"

wait-event-timeout

Wait for an event with timeout.

Parameters:

Returns:

NonNegativeInt -> Option RawEvent

match wait-event-timeout 1000
  | Some event -> print "Got event within 1 second"
  | None -> print "Timeout or no events"

event-from-raw

Normalize a raw SDL event record into a typed Event variant.

Common UI-relevant events are promoted to specific variants. Any event not yet normalized remains available as Other.

RawEvent -> Event

poll-event-typed

Poll for pending events without blocking and normalize them to typed variants.

Option Event

wait-event-typed

Wait indefinitely for an event and normalize it to a typed variant.

Option Event

wait-event-timeout-typed

Wait for an event with timeout and normalize it to a typed variant.

NonNegativeInt -> Option Event

is-key-pressed?

Int -> Bool

get-mod-state

Int

is-shift-pressed?

Bool

is-ctrl-pressed?

Bool

is-alt-pressed?

Bool

get-mouse-x

Int

get-mouse-y

Int

get-mouse-buttons

Int

is-mouse-button-pressed?

Int -> Bool

warp-mouse

{ptr: Ptr} -> Int -> Int -> Unit

set-relative-mouse-mode

Bool -> Unit

is-relative-mouse-mode?

Bool

show-cursor

Unit

hide-cursor

Unit

is-cursor-visible?

Bool

get-ticks

Get milliseconds since SDL initialization.

Returns:

Int

start = get-ticks()
# Do work...
elapsed = get-ticks() - start
print "Took ${Int.to-string elapsed}ms"

delay

Delay execution for specified milliseconds.

Parameters:

Returns:

Int -> Unit

print "Waiting..."
delay 1000  # Wait 1 second
print "Done!"

get-performance-counter

Get high-precision performance counter value.

Returns:

Int

start = get-performance-counter()
# Do work...
end = get-performance-counter()
freq = get-performance-frequency()
seconds = (end - start) / freq

get-performance-frequency

Get performance counter frequency (ticks per second).

Returns:

Int

freq = get-performance-frequency()
print "Timer frequency: ${Int.to-string freq} Hz"

get-clipboard-text

Option String

set-clipboard-text

String -> Unit

has-clipboard-text?

Bool

get-num-displays

Int

get-display-width

Int -> Int

get-display-height

Int -> Int

get-display-refresh-rate

Int -> Int

get-display-name

Int -> String

get-display-dpi

Get DPI metrics for a display as a record.

Int -> {diagonal: Float, horizontal: Float, vertical: Float}

show-info

NonEmptyString -> String -> Unit

show-warning

NonEmptyString -> String -> Unit

show-error

NonEmptyString -> String -> Unit

num-joysticks

Int

open-joystick

Int -> Result {ptr: Ptr} String

close-joystick

{ptr: Ptr} -> Unit

joystick-name

{ptr: Ptr} -> String

joystick-num-axes

{ptr: Ptr} -> Int

joystick-num-buttons

{ptr: Ptr} -> Int

joystick-get-axis

{ptr: Ptr} -> Int -> Int

is-joystick-button-pressed?

{ptr: Ptr} -> Int -> Bool

is-game-controller?

Int -> Bool

open-game-controller

Int -> Result {ptr: Ptr} String

close-game-controller

{ptr: Ptr} -> Unit

game-controller-name

{ptr: Ptr} -> String

game-controller-get-axis

{ptr: Ptr} -> Int -> Int

is-controller-button-pressed?

{ptr: Ptr} -> Int -> Bool

game-controller-update

Unit

game-controller-name-for-index

Int -> String

game-controller-is-attached?

{ptr: Ptr} -> Bool

game-controller-get-joystick

{ptr: Ptr} -> Result {ptr: Ptr} String

game-controller-get-type

{ptr: Ptr} -> Int

game-controller-has-axis?

{ptr: Ptr} -> Int -> Bool

game-controller-has-button?

{ptr: Ptr} -> Int -> Bool

game-controller-rumble

{ptr: Ptr} -> Int -> Int -> Int -> Unit

game-controller-has-rumble?

{ptr: Ptr} -> Bool

game-controller-set-led

{ptr: Ptr} -> Int -> Int -> Int -> Unit

game-controller-has-led?

{ptr: Ptr} -> Bool

get-version

{major: Int, minor: Int, patch: Int}

get-revision

String

get-platform

String

get-base-path

String

get-pref-path

String -> String -> String

prepare-macos-gui-app

Perform the package's macOS AppKit bootstrap path. This is a no-op on non-macOS platforms.

Unit

is-main-thread?

Returns true when the current call is running on the macOS process main thread. Always returns true on non-macOS platforms.

Bool

get-macos-screen-count

Returns the AppKit NSScreen.screens.count value on macOS. Returns -1 on non-macOS platforms or when AppKit screen enumeration is unavailable.

Int

get-core-graphics-display-count

Returns the CoreGraphics online display count on macOS. Returns -1 on non-macOS platforms or when display enumeration fails.

Int

get-num-video-drivers

Returns the number of compiled-in SDL video drivers.

Int

get-video-driver

Returns the SDL video driver name at the given index.

Int -> String

get-current-video-driver

Returns the currently active SDL video driver, or an empty string if video is not initialized.

String

init-video-driver

Initialize the SDL video subsystem using an explicit driver name.

String -> Result Unit String

video-quit

Shut down just the SDL video subsystem.

Unit

get-power-info

{state: Int, seconds: Int, percent: Int}

is-on-battery?

Bool

is-charging?

Bool

is-charged?

Bool

set-hint

NonEmptyString -> String -> Unit

get-hint

NonEmptyString -> String

is-hint-boolean?

NonEmptyString -> Bool -> Bool

clear-hints

Unit

get-num-audio-drivers

Int

get-audio-driver

Int -> String

get-current-audio-driver

String

get-num-audio-devices

Bool -> Int

get-audio-device-name

NonNegativeInt -> Bool -> String

open-audio-device

Int -> Int -> Int -> Int -> Result Int String

close-audio-device

Int -> Unit

pause-audio-device

Int -> Bool -> Unit

play-audio-device

Int -> Unit

get-audio-device-status

Int -> Int

is-audio-playing?

Int -> Bool

get-queued-audio-size

Int -> Int

clear-queued-audio

Int -> Unit

load-wav

NonEmptyString -> Result {buffer: Ptr, length: Int, freq: Int, format: Int, channels: Int} String

free-wav

Unit

num-haptics

Int

haptic-name

Int -> String

open-haptic

Int -> Result {ptr: Ptr} String

open-haptic-from-joystick

{ptr: Ptr} -> Result {ptr: Ptr} String

close-haptic

{ptr: Ptr} -> Unit

haptic-rumble-init

{ptr: Ptr} -> Unit

haptic-rumble-play

{ptr: Ptr} -> Float -> Int -> Unit

haptic-rumble-stop

{ptr: Ptr} -> Unit

is-haptic-rumble-supported?

{ptr: Ptr} -> Bool

haptic-set-gain

{ptr: Ptr} -> Int -> Unit

haptic-pause

{ptr: Ptr} -> Unit

haptic-unpause

{ptr: Ptr} -> Unit

haptic-stop-all

{ptr: Ptr} -> Unit

joystick-is-haptic?

{ptr: Ptr} -> Bool

mouse-is-haptic?

Bool

get-num-touch-devices

Int

get-touch-device

Int -> Int

get-touch-device-type

Int -> Int

get-num-touch-fingers

Int -> Int

get-touch-finger

Int -> Int -> {id: Int, x: Float, y: Float, pressure: Float}

num-sensors

Int

sensor-get-device-name

Int -> String

sensor-get-device-type

Int -> Int

open-sensor

Int -> Result {ptr: Ptr} String

close-sensor

{ptr: Ptr} -> Unit

sensor-get-name

{ptr: Ptr} -> String

sensor-get-type

{ptr: Ptr} -> Int

sensor-update

Unit

gl-set-attribute

Int -> Int -> Unit

gl-get-attribute

Int -> Int

gl-create-context

{ptr: Ptr} -> Result {ptr: Ptr} String

gl-delete-context

{ptr: Ptr} -> Unit

gl-make-current

{ptr: Ptr} -> {ptr: Ptr} -> Unit

gl-swap-window

{ptr: Ptr} -> Unit

gl-set-swap-interval

Int -> Unit

gl-get-swap-interval

Int

gl-extension-supported?

String -> Bool

gl-reset-attributes

Unit

gl-get-drawable-size

{ptr: Ptr} -> {width: Int, height: Int}

drawable-size

Get the drawable pixel size for the window.

The current implementation delegates to the existing GL-backed drawable size query exposed by SDL. This is useful as an immediate high-DPI helper while the package moves toward backend-neutral surface integration.

{ptr: Ptr} -> {width: Int, height: Int}

drawable-scale-from-sizes

Compute per-axis drawable scale factors from logical and drawable sizes.

{width: Int, height: Int} -> {width: Int, height: Int} -> {x: Float, y: Float}

drawable-scale

Compute the drawable scale factors for a window.

{ptr: Ptr} -> {x: Float, y: Float}

display-scale

Compute the effective display scale for a window.

This prefers the larger axis scale so slightly mismatched dimensions still produce a scale factor large enough for crisp rendering.

{ptr: Ptr} -> Float

start-text-input

Unit

stop-text-input

Unit

is-text-input-active?

Bool

set-text-input-rect

Int -> Int -> Int -> Int -> Unit

has-screen-keyboard-support?

Bool

is-screen-keyboard-shown?

{ptr: Ptr} -> Bool

system-cursor-type

Map a typed cursor kind to the SDL system cursor constant.

CursorKind -> Int

create-system-cursor

Int -> Result {ptr: Ptr} String

create-system-cursor-kind

Create a system cursor from the stable typed cursor kind.

CursorKind -> Result {ptr: Ptr} String

get-cursor

Unit -> {ptr: Ptr}

get-default-cursor

Unit -> {ptr: Ptr}

set-cursor

{ptr: Ptr} -> Unit

reset-cursor

Restore SDL's default cursor for the current window.

Unit

free-cursor

{ptr: Ptr} -> Unit

joystick-update

Unit

joystick-name-for-index

Int -> String

joystick-num-hats

{ptr: Ptr} -> Int

joystick-num-balls

{ptr: Ptr} -> Int

joystick-get-hat

{ptr: Ptr} -> Int -> Int

joystick-is-attached?

{ptr: Ptr} -> Bool

joystick-instance-id

{ptr: Ptr} -> Int

joystick-current-power-level

{ptr: Ptr} -> Int

joystick-rumble

{ptr: Ptr} -> Int -> Int -> Int -> Unit

joystick-has-rumble?

{ptr: Ptr} -> Bool

joystick-set-led

{ptr: Ptr} -> Int -> Int -> Int -> Unit

joystick-has-led?

{ptr: Ptr} -> Bool

joystick-get-type

{ptr: Ptr} -> Int