Implementation Reference
Implementation details extracted from GLFW and winit for our Odin window library.
GLFW Implementation Details
Architecture Patterns
- Global state struct containing all library state (initialized flag, platform vtable, error handling, window/cursor/monitor linked lists)
- Window struct with linked list node (
next pointer), settings/state flags, input state arrays, constraints, callbacks, and platform-specific state via macro embedding
- Monitor struct with name, physical dimensions, video modes array, gamma ramp state
- Opaque handle pattern - public API only sees pointers, never internal struct details
- Intrusive linked lists for windows, cursors, errors -
next pointer embedded in each structure
Platform Abstraction
- Virtual function table -
_GLFWplatform struct contains ~60 function pointers for all platform operations
- Platform state macros -
GLFW_X11_WINDOW_STATE, GLFW_WIN32_WINDOW_STATE etc. embedded in window struct
- Conditional compilation - empty stub macros when platform not compiled, same binary types across platforms
- Platform ID stored in global state for runtime platform identification
Window Management
- Hints system - stateful configuration before creation (
glfwWindowHint(), glfwInitHint())
- Hints persist until explicitly reset or new window created - allows adding new hints without breaking API
- Simple creation -
glfwCreateWindow(width, height, title, monitor, share)
- Monitor parameter - NULL for windowed, valid monitor for fullscreen
- Share parameter - NULL or reference to existing window for OpenGL context sharing
- Constraints - min/max width/height, aspect ratio numerator/denominator
Input Handling
- Key state array -
keys[GLFW_KEY_LAST + 1] stores PRESS/RELEASE/REPEAT
- Mouse state array -
mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]
- Sticky input modes - persistent state capture even when callback missed
- Virtual cursor position - software-tracked cursor for disabled cursor mode
- Raw mouse motion - platform-specific unfiltered motion data
- Callback pointers - 17 callbacks stored directly in window struct (null = no-op)
Event Loop
pollEvents() - non-blocking, processes queue
waitEvents() - blocks until event
waitEventsTimeout(t) - blocks with timeout
postEmptyEvent() - force wake from wait
- Internal event functions -
_glfwInputKey(), _glfwInputMouseClick() etc. called by platform code
API Design
- Error handling - thread-local storage via TLS slots, last error only (not queued)
- Input mode configuration - single function with mode enum (
GLFW_CURSOR, GLFW_STICKY_KEYS, etc.)
- String hints for platform extensions (
GLFW_X11_CLASS_NAME, etc.)
- Callback registration returns previous callback pointer
- User pointer on windows and monitors for application data
Platform Functions Required
- init/terminate
- Cursor: getCursorPos, setCursorPos, setCursorMode, createCursor, createStandardCursor, destroyCursor, setCursor
- Input: getScancodeName, getKeyScancode, setClipboardString, getClipboardString, rawMouseMotionSupported
- Monitor: freeMonitor, getMonitorPos, getMonitorContentScale, getMonitorWorkarea, getVideoModes, getVideoMode, getGammaRamp, setGammaRamp
- Window: createWindow, destroyWindow, setWindowTitle, setWindowIcon, get/setWindowPos, get/setWindowSize, setWindowSizeLimits, setWindowAspectRatio, getFramebufferSize, getWindowFrameSize, getWindowContentScale, iconifyWindow, restoreWindow, maximizeWindow, showWindow, hideWindow, requestWindowAttention, focusWindow, setWindowMonitor
- Window state: windowFocused, windowIconified, windowVisible, windowMaximized, windowHovered, framebufferTransparent, getWindowOpacity, setWindowResizable, setWindowDecorated, setWindowFloating, setWindowOpacity, setWindowMousePassthrough
- Events: pollEvents, waitEvents, waitEventsTimeout, postEmptyEvent
Winit Implementation Details
Architecture Patterns
- Trait-based abstraction -
ActiveEventLoop, Window, ApplicationHandler traits
- Enum-based event system - discriminated unions for events (40+ WindowEvent variants)
- Separate crates per platform - winit-core (shared), winit-x11, winit-wayland, winit-win32, etc.
- Runtime backend selection on Linux - check
WAYLAND_DISPLAY then DISPLAY env vars
- Window IDs - distinct u64 identifiers for multi-window handling
ApplicationHandler Callbacks
can_create_surfaces() - lifecycle point for surface creation (critical for Android)
window_event(event_loop, window_id, event) - per-window events
device_event(event_loop, device_id, event) - raw input events
about_to_wait() - pre-blocking hook
new_events(cause) - start of event batch
proxy_wake_up() - inter-thread signaling
Window Attributes (Builder Pattern)
- surface_size, min_surface_size, max_surface_size, surface_resize_increments
- position
- resizable
- enabled_buttons (bitflags for min/max/close)
- title
- maximized, visible, transparent, blur, decorations
- window_icon
- preferred_theme (Light/Dark)
- content_protected
- window_level (Normal, AlwaysOnTop, AlwaysOnBottom)
- active
- cursor
- parent_window
- fullscreen (Borderless or Exclusive with video mode)
- platform (boxed trait object for platform-specific extensions)
Keyboard Input Hierarchy
- Physical scancode (XKB keycode, Windows scancode)
- Platform-native NativeKeyCode:
Xkb(u32), Windows(u16), MacOS(u16)
- Logical key via NativeKey (keysym, vkcode)
- Named key enum: Enter, Escape, ArrowUp, F1-F24, etc.
Key Modifiers
- Shift, Control, Alt, Super (meta/win/cmd)
- Separate left/right tracking
- CapsLock, NumLock state
Pointer Events
PointerMoved { position, primary, source }
PointerEntered { position, primary, kind }
PointerLeft { position, primary, kind }
PointerButton { state, position, button }
MouseWheel { delta: LineDelta | PixelDelta, phase }
- Primary vs secondary pointer for multi-touch
Event Loop Control Flow
Poll - continuous polling (games)
Wait - block until events (UI apps, most efficient)
WaitUntil(instant) - block with timeout
StartCause (Why event loop woke)
Init - first iteration
Poll - Poll control flow triggered
WaitCancelled { start, requested_resume } - new events interrupted wait
ResumeTimeReached { start, requested_resume } - WaitUntil timeout fired
Window Events (Key Variants)
- SurfaceResized, Moved, CloseRequested, Destroyed
- Focused(bool), Occluded(bool)
- KeyboardInput { device_id, event, is_synthetic }
- ModifiersChanged
- PointerMoved, PointerEntered, PointerLeft, PointerButton
- MouseWheel, AxisMotion
- Touch, TouchpadPressure
- PinchGesture, PanGesture, DoubleTapGesture, RotationGesture
- DragEntered, DragMoved, DragDropped, DragLeft
- ScaleFactorChanged { scale_factor, surface_size_writer }
- ThemeChanged
- Ime(Enabled, Preedit, Commit, Disabled)
- RedrawRequested
Coordinate Systems
- Surface coordinates - relative to drawable area (0,0 at content top-left)
- Window coordinates - relative to window including decorations
- Desktop coordinates - absolute screen position
- Methods:
surface_size(), outer_size(), surface_position(), outer_position()
DPI/Scaling
scale_factor() on Window
ScaleFactorChanged event when DPI changes
- Physical and Logical types that auto-convert
- Fractional scaling support (Wayland)
Monitor API
available_monitors() - iterator of MonitorHandle
primary_monitor() - Option<MonitorHandle>
- MonitorHandle: id, native_id, name, position, scale_factor, video_modes, current_video_mode
Cross-Thread Communication
EventLoopProxy::wake_up() - coalesced (multiple calls = 1 proxy_wake_up event)
- Used for background threads signaling work completion
Raw Window Handles
raw_window_handle() → RawWindowHandle for Vulkan/OpenGL/Metal/DirectX
raw_display_handle() → DisplayHandle for display connection
X11-Specific
- Window types: Desktop, Dock, Toolbar, Menu, Utility, Splash, Dialog, DropdownMenu, PopupMenu, Tooltip, Notification, Combo, Dnd, Normal
- XAtom handling
- Drag & drop (XDND protocol)
- Input method integration
- XSettings for desktop settings
Wayland-Specific
- Client-side decorations (CSD) option
- xdg_toplevel access
- Activation tokens
- Fractional scaling protocol
- Tablet input v2
Current Implementation Status
Core Data Structures
- [x] Global library state (
Platform_Event_Loop in platform_linux.odin)
- [x] Window struct (
Platform_Window with union of X11/Wayland data)
- [x] Monitor struct (
Monitor_Info with id, name, dimensions, modes, position, scale)
- [x] Event enum (discriminated union:
Window_Event, Device_Event, Loop_Event)
Window Management
- [x] Window creation with attributes (
create_window() + Window_Attributes)
- [x] Window destruction (
destroy_window())
- [x] Title (
set_title())
- [ ] Window icon
- [x] Position (
outer_position(), set_outer_position(), set_position(), get_position())
- [x] Size (
surface_size(), request_surface_size(), outer_size(), set_size())
- [x] Min/max size constraints (
set_min_surface_size(), set_max_surface_size())
- [ ] Aspect ratio constraints
- [x] Visible (
set_visible(), is_visible())
- [x] Focused (
focus(), is_focused())
- [x] Maximized (
set_maximized(), is_maximized() - state tracking TODO)
- [x] Minimized (
set_minimized(), is_minimized() - state tracking TODO)
- [x] Fullscreen (
set_fullscreen(), get_fullscreen() - borderless + exclusive)
- [x] Decorations (
set_decorations(), is_decorated() - state tracking TODO)
- [x] Resizable (
set_resizable(), is_resizable() - state tracking TODO)
- [ ] Floating/always-on-top
- [ ] Mouse passthrough
- [ ] Opacity
- [~] Content scale / DPI (
scale_factor() - hardcoded 1.0, detection TODO)
Input Handling
- [x] Keyboard input with scancodes (
Key_Input event, Key_Code enum 126+ keys)
- [ ] Key state array for polling
- [x] Modifier keys tracking (
Modifiers struct: shift, ctrl, alt, super)
- [x] Mouse button input (
Mouse_Button_Input event)
- [x] Cursor position (
Pointer_Moved event with position)
- [x] Scroll wheel (
Mouse_Wheel event with line + pixel deltas)
- [ ] Cursor modes (normal, hidden, disabled/grabbed)
- [ ] Raw mouse motion (relative pointer protocol)
- [ ] Cursor shapes (standard cursors)
- [~] Key repeat detection (TODO in both X11 and Wayland)
Event System
- [x] Poll events (
poll() - non-blocking)
- [x] Wait events (
run() with Wait control flow - blocking)
- [x] Wait events with timeout (
Wait_Until control flow)
- [ ] Post empty event / wake from wait (TODO in code)
- [x] Callback-based design (winit-style
Event_Handler callback)
- [x] Start cause tracking (
Init, Poll, Wait_Cancelled, Resume_Time_Reached)
- [x] Loop events (
New_Events, About_To_Wait, Loop_Exiting)
Monitor/Display
- [x] Enumerate monitors (
get_monitors())
- [x] Primary monitor (
get_primary_monitor())
- [x] Monitor name (
get_monitor_name())
- [x] Monitor position (
get_monitor_position())
- [x] Monitor workarea (
get_monitor_workarea())
- [x] Physical size (
get_monitor_physical_size())
- [x] Content scale (
get_monitor_content_scale())
- [x] Video modes enumeration (
get_video_modes())
- [x] Current video mode (
get_current_video_mode())
- [x] Combined info (
get_monitor_info())
Platform Abstraction
- [x] Platform-specific state embedded in structs (union in
Platform_Window)
- [x] Runtime platform selection (X11 vs Wayland via
select_backend())
- [x] Environment variable checks (
WAYLAND_DISPLAY, ODIN_WINDOW_BACKEND)
- [x] X11 backend (complete)
- [x] Wayland backend (functional - window creation, input, monitors, decorations)
Raw Handle Support
- [x]
raw_window_handle() - X11 window ID or Wayland wl_surface
- [x]
raw_display_handle() - X11 display or Wayland wl_display
API Design (Implemented Choices)
- [x] Distinct handle types (
Window_Id, Device_Id, Monitor_Handle)
- [x] Attributes struct pattern (not hints)
- [x] Callback-based events (winit-style)
- [ ] User pointer on objects
- [x] Error handling via
Error enum return values
- [ ] Thread-local error storage
Not Yet Implemented
Window Features
- Window icon
- Aspect ratio constraints
- Floating/always-on-top window level
- Mouse passthrough
- Window opacity
- Proper DPI detection (currently hardcoded to 1.0)
- State tracking for maximized/minimized/resizable/decorated flags
Input Features
- Key state array for polling (currently event-only)
- Cursor visibility modes (hidden, disabled/grabbed)
- Raw mouse motion (Wayland relative-pointer protocol)
- Standard cursor shapes
- Key repeat detection (marked TODO)
- Event loop wake-up mechanism (marked TODO)
Advanced Features
- Clipboard access (copy/paste)
- Custom cursor images
- Drag & drop
- Input method (IME) integration
- Touch input
- Gamepad/joystick
- Pointer gestures (pinch, pan, rotate)
- Tablet input
Wayland-Specific Incomplete
- Exclusive fullscreen with specific video mode
- Pointer constraints (cursor locking)
- Activation tokens
- Fractional scaling (protocol exists, not wired through)