Display and input
A virtio GPU in 2D or with virgl 3D, drawn on a canvas with WebGPU or WebGL2, and a keyboard and tablet driven by the user or by QMP.
A display
Add a virtio GPU and the guest gets a graphical console and /dev/dri/card0:
wemu-system-aarch64 ... -device virtio-gpu-pci -device virtio-keyboard-pci -device virtio-tablet-pci| Device | What the guest gets |
|---|---|
virtio-gpu-pci | A 2D display: a framebuffer console, a desktop in software, a hardware cursor. Default 1280×800; set xres and yres. |
virtio-gpu-gl-pci | The same, plus 3D through virgl (see below). |
ramfb | A plain 1024×768 framebuffer, for firmware and kernels without a virtio GPU driver. |
-vga virtio is a shorthand for -device virtio-gpu-pci.
Where the picture goes
The picture reaches your code through the host's display:
- A canvas. Pass an
OffscreenCanvasand Warm64's GPU worker draws on it directly. - Frames. Pass a
frame(width, height, pixels)callback and receive each changed frame, at up torefreshHztimes a second. - Screenshots.
screendumpsaves the screen as PNG or PPM, with or without a display attached.
const canvas = document.querySelector("canvas").transferControlToOffscreen();
const vm = await WEMU.launch("... -device virtio-gpu-gl-pci -device virtio-keyboard-pci", {
...browserWEMUHost(),
display: { canvas },
});In Node there's no window: use frame or screendump.
await vm.qmp("screendump", { filename: "screen.png", format: "png" });When the page resizes, tell the guest, as a resized QEMU window does:
vm.setUIInfo({ width: 1440, height: 900 });3D graphics
virtio-gpu-gl-pci gives the guest virgl: its stock Mesa virgl driver sends OpenGL work to Warm64, which renders it on the host's GPU.
| Host | Renders with |
|---|---|
| A browser with WebGPU | WebGPU |
| A browser with WebGL2 | WebGL2 |
Neither, or -display ...,gl=off | Software |
| Node | Software |
The guest gets OpenGL 2.1 and OpenGL ES 2.0 with GLSL 1.30, enough for desktops, kmscube and glmark2. Compute, geometry and tessellation shaders, multisampling and transform feedback aren't there.
Tip Run glmark2 with --visual-config alpha=0.
Keyboard and pointer
Any one of virtio-keyboard-*, virtio-tablet-* or virtio-mouse-* adds both a keyboard and a tablet, which Linux names warm64 keyboard and warm64 tablet. The pointer is always an absolute tablet, so it follows the user's pointer exactly.
On USB instead, add a controller and the devices:
wemu-system-aarch64 ... -device wemu-xhci -device usb-kbd -device usb-tabletSending input from code
// type Enter
await vm.qmp("send-key", { keys: [{ type: "qcode", data: "ret" }] });
// click in the middle of the screen
await vm.qmp("input-send-event", { events: [
{ type: "abs", data: { axis: "x", value: 16384 } },
{ type: "abs", data: { axis: "y", value: 16384 } },
{ type: "btn", data: { down: true, button: "left" } },
{ type: "btn", data: { down: false, button: "left" } },
] });Pointer positions run from 0 to 32767 across the screen. See send-key and input-send-event.
USB
The xHCI controller (-device wemu-xhci, or -usb) takes a keyboard (usb-kbd), a tablet (usb-tablet; usb-mouse becomes one) and a disk (usb-storage,drive=ID). A USB disk is read into memory and its writes aren't saved.