Skip to main content

Crate displays_physical_linux_sys

Crate displays_physical_linux_sys 

Source
Expand description

displays_physical_linux_sys is a small Rust library for querying and updating Linux brightness devices exposed through sysfs.

It is also the lowest-level Linux physical brightness backend used by the higher-level displays crate.

Start with the displays crate unless you need direct sysfs access.

It currently works with devices under:

  • /sys/class/backlight
  • /sys/class/leds

The API is intentionally manager-oriented and library-focused. It exposes typed device metadata and brightness update operations instead of mirroring a CLI.

§How this maps to Linux

On Linux, brightness for many devices is exposed through the kernel’s sysfs interface. Sysfs presents kernel objects as files and directories, usually under /sys.

For this crate, the important directories are:

  • /sys/class/backlight for laptop panels and other backlight-style devices
  • /sys/class/leds for LED-style brightness devices, including some keyboard backlights and indicator LEDs

Each device normally appears as a directory such as:

  • /sys/class/backlight/intel_backlight
  • /sys/class/leds/asus::kbd_backlight

Inside that directory, Linux commonly exposes:

  • brightness: the current raw brightness value that can be written
  • max_brightness: the maximum allowed raw value
  • actual_brightness: the effective brightness actually being applied, when the driver exposes it

This crate reads those files directly. That is why the API exposes raw values as first-class data instead of hiding everything behind percentages.

§Understanding raw values

Linux brightness values are device-specific integers, not universal units.

For example:

  • one device may use a range of 0..=255
  • another may use 0..=937
  • another may use 0..=3

So BrightnessUpdate::Raw(100) does not mean the same thing across devices. When you need a cross-device notion of brightness, use percentages.

The crate therefore exposes both:

  • raw values, which match Linux directly
  • brightness_percent, which is derived from brightness / max_brightness

§Reading versus actual brightness

Some drivers expose both brightness and actual_brightness.

  • brightness is the configured target value
  • actual_brightness is the effective value reported by the driver

They are often equal, but they do not have to be. For example, hardware or driver behavior may temporarily clamp or lag behind the configured value.

If actual_brightness is not present, the device is still fully usable through this crate.

§Permissions and writes

Reading sysfs brightness files is commonly allowed for regular users, but writing is often restricted.

In practice, successful writes usually require one of these:

  • root privileges
  • udev rules that grant write access to the relevant brightness file
  • a system policy that changes device permissions outside the crate

This first version performs direct sysfs writes only. It does not currently use logind or another privileged mediation path.

§Why both backlight and leds are included

Linux does not have a single unified “brightness device” abstraction. Similar controls can show up in different sysfs classes depending on the driver and the hardware.

This crate includes both backlight and leds so callers can work with the kernel’s available brightness-capable devices through one API.

§Features

  • Enumerate backlight and LED brightness devices
  • Read current, maximum, and optional actual brightness values
  • Match devices by class, id, and path
  • Apply brightness updates using raw values, percentages, and deltas
  • Validate updates without writing to sysfs
  • Use a custom sysfs root for tests and fixtures

§Usage

use std::collections::BTreeSet;

use displays_physical_linux_sys::{
    BrightnessUpdate, DeviceClass, DeviceIdentifier, DeviceUpdate,
    PhysicalDisplayManagerLinuxSys,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let manager = PhysicalDisplayManagerLinuxSys::new();

    for device in manager.list()? {
        println!(
            "{} {}: {}/{} ({}%)",
            match device.metadata.class {
                DeviceClass::Backlight => "backlight",
                DeviceClass::Leds => "leds",
            },
            device.metadata.id,
            device.state.brightness_raw,
            device.state.max_brightness_raw,
            device.state.brightness_percent,
        );
    }

    let remaining = manager.update(vec![DeviceUpdate {
        id: DeviceIdentifier {
            class: Some(DeviceClass::Backlight),
            id: Some("intel_backlight".to_string()),
            path: None,
        },
        brightness: Some(BrightnessUpdate::Percent(50)),
    }])?;

    assert!(remaining.is_empty());
    Ok(())
}

§Matching

DeviceIdentifier uses subset matching:

  • class restricts matching to one sysfs class
  • id matches the device directory name
  • path matches the full device path exactly

Any field left as None is ignored during matching.

§Update semantics

The crate currently supports these update types:

  • BrightnessUpdate::Raw(u32)
  • BrightnessUpdate::Percent(u8)
  • BrightnessUpdate::RawDelta(i32)
  • BrightnessUpdate::PercentDelta(i32)

All writes are clamped to the device’s valid raw range 0..=max_brightness.

§Linux behavior

The crate reads the same sysfs brightness values that Linux exposes directly. That means raw values are first-class API data rather than being hidden behind a percent-only abstraction.

If an actual_brightness file exists, it is exposed as DeviceState::actual_brightness_raw. It is not required for a device to be usable.

§Current scope

This first version uses direct sysfs reads and writes only.

It does not currently include:

  • logind-based write fallback
  • hotplug monitoring
  • non-sysfs backends

§Further reading

Kernel documentation:

Man pages to check locally on a Linux system:

  • man 5 sysfs
  • man 7 udev
  • man 8 udevadm

Those references are useful if you want to understand where these files come from, why device permissions differ between systems, or how a particular driver maps hardware brightness into sysfs.

§License

MIT

Structs§

Device
A Linux brightness-capable device and its current state.
DeviceIdentifier
A user-facing identifier used to match one or more Linux brightness devices.
DeviceMetadata
Stable metadata describing a Linux brightness device.
DeviceState
The current state of a Linux brightness device.
DeviceUpdate
A request to update one or more Linux brightness devices.
PhysicalDisplayManagerLinuxSys
High-level entry point for querying and updating Linux brightness devices.

Enums§

ApplyError
Errors that can occur while applying Linux brightness updates.
BrightnessUpdate
Supported brightness update operations.
DeviceClass
Supported Linux sysfs device classes.
QueryError
Errors that can occur while querying Linux brightness devices.

Functions§

normalize_brightness_update
Normalizes a brightness update into the raw value expected by Linux sysfs.