denise 0.9.1

Direct-rendering UI toolkit for embedded Linux and systems without a desktop environment.
Documentation

denise

crates.io docs.rs Licence

The platform-agnostic core of Denise — a direct-rendering UI toolkit in Rust for embedded Linux and systems without a desktop environment: kiosks, digital signage, industrial HMIs, Raspberry Pi panels.

This crate is the contract every other one is written against: geometry, colour, the pixel buffer, input events, damage tracking, theming and the cursor sprite. It contains no platform code, #![forbid(unsafe_code)], and builds no_std + alloc. Backends are separate crates chosen at build time, so an embedded target never compiles desktop code.

The two traits a backend implements

use denise::{DamageTracker, Rect, Surface};

# fn demo(surface: &mut impl Surface, tracker: &mut DamageTracker) -> Result<(), denise::SurfaceError> {
let mut frame = surface.acquire()?;
// The buffer just acquired may be several frames old; widen the damage to match.
let damage: &[Rect] = tracker.resolve(frame.age());
// ... draw, clipped to `damage` ...
drop(frame);
surface.present(damage)?;
tracker.end_frame();
# Ok(())
# }

Surface hands out a Frame and presents damaged regions; InputSource drains platform input into InputEvents. Getting the sequence above wrong is the classic double-buffering bug — repaint only the current frame's damage and every second frame shows stale content, which is why BufferAge is part of the contract rather than a backend's private business.

Theming, and why contrast is checked

Colours are named by role, never by value: Primary, Base100, Error, and a *Content partner for each. Theme::pair returns a surface and a foreground that are guaranteed to contrast, and Theme::validate proves it for a custom theme rather than leaving it to be discovered on a panel in daylight. The role vocabulary is borrowed from DaisyUI; the contrast arithmetic is WCAG relative luminance in integers, so it is identical on x86 and ARM.

Features

Feature Default What it does
std std::error::Error for the error types. Turn it off for no_std + alloc.

Where this sits

Crate Role
denise This crate — the contract
denise-render Software rasteriser writing into a Frame
denise-ui Scene graph, widgets, compositor
denise-drm · denise-winit · denise-fbdev Surface implementations
denise-evdev InputSource implementation

Status

M5 complete, M6 in progress. Everything through M5 has run on real hardware — a Raspberry Pi on DRM/KMS, Windows 11 on ARM64, macOS — not only in CI. The roadmap, the design notes and what was tried and abandoned are in the repository README and docs/design.md.

MIT licensed.