Skip to content

Display Protocol

Apps render to the screen by writing VYOMA_DRAW: commands to stdout. The supervisor intercepts these commands and renders them to the DRM/virtio-gpu framebuffer.

Each command is a single line written to stdout:

VYOMA_DRAW:<command>:<parameters>

Commands are processed in order. Nothing appears on screen until flush is called.

Fill a rectangle with a solid color.

VYOMA_DRAW:fill_rect:<x>,<y>,<width>,<height>,<rgba>
ParameterTypeDescription
xintegerLeft edge (pixels)
yintegerTop edge (pixels)
widthintegerWidth (pixels)
heightintegerHeight (pixels)
rgbau32Color as (R<<24)|(G<<16)|(B<<8)|A printed as decimal

Draw a single line of text.

VYOMA_DRAW:draw_text:<x>,<y>,<rgba>,<size>,<text>
ParameterTypeDescription
xintegerLeft edge (pixels)
yintegerTop edge (pixels)
rgbau32Text color
sizechars = 4x8, m = 8x16, l = 16x32
textstringText content (rest of line)

Draw text with automatic word wrapping.

VYOMA_DRAW:draw_text_wrap:<x>,<y>,<max_width>,<rgba>,<size>,<text>
ParameterTypeDescription
xintegerLeft edge (pixels)
yintegerTop edge (pixels)
max_widthintegerMaximum width before wrapping (pixels)
rgbau32Text color
sizechars, m, or l
textstringText content

Commit the current frame to the framebuffer. Nothing is visible until this is called.

VYOMA_DRAW:flush

Colors are packed as a u32 in RGBA format:

(Red << 24) | (Green << 16) | (Blue << 8) | Alpha

Printed as a decimal integer in the protocol string.

ColorDecimalHex
White42949672950xFFFFFFFF
Black2550x000000FF
Red42781903350xFF0000FF
Green167447030x00FF00FF
Blue655350x0000FFFF
Catppuccin BG5052904950x1E1E2EFF

In Rust, define colors as constants:

const WHITE: u32 = 0xFFFFFFFF;
const BG: u32 = 0x1E1E2EFF;
const RED: u32 = 0xFF0000FF;
Size codePixel dimensionsUse case
s4x8Fine detail, status bars
m8x16Default body text
l16x32Headers, titles
const WHITE: u32 = 0xFFFFFFFF;
const BG: u32 = 0x1E1E2EFF;
const PURPLE: u32 = 0x7C3AEDFF;
const GRAY: u32 = 0x64748BFF;
fn draw_frame() {
// Clear background
println!("VYOMA_DRAW:fill_rect:0,0,960,700,{BG}");
// Header bar
println!("VYOMA_DRAW:fill_rect:0,0,960,40,{PURPLE}");
println!("VYOMA_DRAW:draw_text:10,12,{WHITE},m,My Application");
// Body text
println!("VYOMA_DRAW:draw_text:10,60,{WHITE},m,Welcome to VyomaOS!");
println!("VYOMA_DRAW:draw_text:10,80,{GRAY},s,Press any key to continue...");
// Commit to screen
println!("VYOMA_DRAW:flush");
}

The supervisor automatically adds window chrome around each app’s drawing area:

  • Title bar with app name and deterministic accent color
  • Focus border (2px) around the active window
  • Status strip showing app name and uptime

Apps don’t need to account for chrome in their coordinates — the supervisor handles offsetting.

The supervisor tracks per-app flush rate and logs FPS every 5 seconds. To maintain smooth rendering, apps should aim for consistent flush intervals rather than flooding with draw commands.