//! The scanout wire protocol — what the compositor says to a native scanout driver (e.g.
//! virtio-gpu) over its well-known `.scanout` endpoint to put a composited frame on screen.
//! The driver owns the panel and the shared scanout surface it handed the compositor (via the
//! display service's `attach_scanout`); the compositor composites into that surface, then asks
//! the driver to present a damaged rectangle. Tiny by design — one present request. Separate
//! from the display protocol because the directions differ: clients call the compositor over
//! `.display`; the compositor calls the driver over `.scanout`. See docs/display-v2.md.

const std = @import("std");

pub const Operation = enum(u32) {
    /// present(x, y, width, height): put the given rectangle of the shared scanout surface on
    /// the panel (on virtio-gpu: transfer-to-host of the region, then a fenced resource flush).
    present = 0,
    /// get_modes() -> ModesReply: the display modes this scanout can switch to (V5).
    get_modes = 1,
    /// set_mode(width, height): change the scanout resolution — the shared surface is sized to
    /// the largest mode, so this just re-points the scanout rectangle; the surface is unchanged.
    set_mode = 2,
};

pub const Request = extern struct {
    operation: u32,
    x: u32 = 0,
    y: u32 = 0,
    width: u32 = 0,
    height: u32 = 0,
};

pub const Reply = extern struct {
    status: i32, // 0 on success, negative on failure
    reserved: u32 = 0,
};

/// One offered display mode.
pub const Mode = extern struct { width: u32, height: u32 };
pub const max_modes = 4;

/// The reply to `get_modes`: a small fixed list of modes.
pub const ModesReply = extern struct {
    status: i32,
    count: u32,
    modes: [max_modes]Mode,
};

pub const message_maximum: usize = 64;
pub const request_size: usize = @sizeOf(Request);
pub const reply_size: usize = @sizeOf(Reply);
pub const modes_reply_size: usize = @sizeOf(ModesReply);
