# 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 1. Physical scancode (XKB keycode, Windows scancode) 2. Platform-native NativeKeyCode: `Xkb(u32)`, `Windows(u16)`, `MacOS(u16)` 3. Logical key via NativeKey (keysym, vkcode) 4. 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: 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)