Crate evdi[][src]

High-level bindings to evdi, a library for managing virtual displays on linux.

Tracing and logging

This library emits many tracing events. Logs by libevdi are converted to INFO-level tracing events.

Not thread safe

Evdi is not thread safe, and you cannot block the thread it runs for too long as your real and virtual devices will not receive events.

Alpha quality

This library is alpha quality. If your display starts behaving weirdly, rebooting may help.

Basic usage

const AWAIT_MODE_TIMEOUT: Duration = Duration::from_millis(250);
const UPDATE_BUFFER_TIMEOUT: Duration = Duration::from_millis(20);

// If get returns None you need to call DeviceNode::add with superuser permissions or setup the
// kernel module to create a device on module load.
let device = DeviceNode::get().unwrap();

// Replace this with the details of the display you want to emulate
let device_config = DeviceConfig::sample();

let unconnected_handle =;
let mut handle = unconnected_handle.connect(&device_config);

// For simplicity don't handle the mode changing after we start
let mode =;

// For simplicity, we only use one buffer. You may want to use more than one buffer so that you
// can send the contents of one buffer while updating another.
let buffer_id = handle.new_buffer(&mode);

loop {
    handle.request_update(buffer_id, UPDATE_BUFFER_TIMEOUT).await?;
    let buf = handle.get_buffer(buffer_id).expect("Buffer exists");
    // Do something with the bytes
    let _bytes = buf.bytes();

Managing device nodes

Creating and removing device nodes requires superuser permissions.

I include the helper binaries evdi_device_add and evdi_device_remove_all that do nothing but call DeviceNode::add and DeviceNode::remove_all so that you can easily manage devices while testing.

For example:

> # (while in the checked out source code of this library)
> cargo build --bin evdi_device_add
> sudo target/debug/evdi_device_add

You will probably want to create your own seperate binaries that manage device nodes so that your users don’t need to run your main binary with superuser permissions.

Another alternative is [configuring the kernel module] to create devices when it loads.


  • serde: Derive feat_serde::Serialize and feat_serde::Deserialize for types where it makes sense.


pub use evdi_sys as ffi;



Buffer to receive virtual screen pixels


Config of virtual output display


Device node (/dev/dri/card*)


Performs most operations


Simplify importing



Version of kernel evdi module


Version of the userspace evdi library


Wraps some u32 that isn’t a DRM fourcc we recognize



Status of the evdi kernel module



Check the status of the evdi kernel module for compatibility with this library version.