term.gfx.drm_display

index · term.gfx

Overview

DRM console display — a placement of a canvas on a DRM/KMS device.

The console twin of term.gfx.display: the same duck-typed contract (update/show/hide/destroy/set_anchor), but each :update() blits the canvas surface into a dumb buffer (term.drm_core) and presents it with a vsynced page flip instead of transmitting it over the Kitty protocol. The canvas is upscaled by the largest INTEGER factor that fits the display mode — nearest-neighbour, centered, black borders — so pixel art stays crisp and uniform.

Presentation is double-buffered with one flip in flight: :update() first waits for the previous flip's completion event (cooperatively, via the LEV loop — the wait yields, so the display is the frame pacer and motion runs at the display's refresh), then blits and queues the next flip. The first :update() has nothing pending, so creating the display needs no running LEV loop; every later update must run under one (term.gfx.loop does).

The display manages the controlling console by default: raw mode (no echoed keystrokes) and a hidden cursor, both restored by :destroy(), which also restores the CRTC the console was scanning out before. There is no alt screen and no Kitty handshake — the device is the screen. Intended to be driven by term.gfx.loop with alt_screen = false and no input handler (input comes from elsewhere, e.g. evdev).

Opening requires DRM master, so the process must run at a plain VT — a running compositor holds master and display() returns a clean error. While the display is live, other VTs cannot repaint (they show a frozen frame until this process exits); the evdev/VT-gate input layer is what mutes input meanwhile.

Functions

NameSignature
layoutlayout(dev_w, dev_h, cw, ch) -> k, dx, dy
displaydisplay(canvas, opts) -> display, err

layout(dev_w, dev_h, cw, ch) -> k, dx, dy

Compute the integer-upscale layout of a canvas on a display mode

Returns the largest integer scale factor k such that cw*k x ch*k fits inside dev_w x dev_h, plus the 0-indexed offsets dx, dy that center the scaled image. Returns nil, err when the mode is smaller than the canvas (k < 1).

display(canvas, opts) -> display, err

Create a DRM console display for a canvas

opts shape:

NameDefaultDescription
path/dev/dri/card0DRM card node
manage_consoletrueraw mode + hidden cursor, restored on destroy

Returns nil, err (console untouched) when the device can't be opened, DRM master is unavailable (a compositor is running), no connected output is found, or the mode is smaller than the canvas.

Methods (the term.gfx.display contract):