brightwheel 0.1.0

Windows tray utility for DDC/CI monitor brightness and HDR control
# BrightWheel

Small Windows CLI for controlling external monitor brightness over DDC/CI.
It talks directly to the Windows monitor configuration API in `dxva2.dll` and
does not depend on ASUS DisplayWidget or its service.

The project also builds `brightwheel.exe`, a tray-only Windows application:

- hover the tray icon and turn the mouse wheel to change primary-monitor
  brightness; continuous scrolling accelerates dynamically from precise 2%
  steps up to 10% per notch;
- moving the pointer away from the tray icon cancels wheel input that has not
  reached the monitor yet, so a long burst does not keep running in the
  background;
- double-click the tray icon to toggle HDR on the primary monitor;
- right-click to toggle `Start with Windows` or exit;
- startup is enabled automatically on the first run and can then be disabled
  from that menu;
- only one instance can run at a time;
- the MSVC runtime is linked statically, so the release executable only uses
  DLLs included with Windows.

`brightwheel.exe` is self-contained and does not ship an ASUS library. The
brightness control works with external monitors that expose MCCS VCP `0x10`
through Windows DDC/CI; DDC/CI must be enabled in the monitor's on-screen menu.
HDR toggling additionally requires a Windows version and primary monitor that
support the advanced-color display configuration API.

## ASUS XG49V findings

The locally installed ASUS DisplayWidget `3.4.0.041` from Portrait Displays
imports these Windows APIs directly from `dxva2.dll`:

- `GetPhysicalMonitorsFromHMONITOR`
- `GetVCPFeatureAndVCPFeatureReply`
- `SetVCPFeature`
- `DestroyPhysicalMonitors`

Its UI binds brightness to `ddc.vcp16`. Decimal `16` is MCCS VCP code `0x10`
(luminance/brightness); the control range is `0..100`. Contrast is exposed as
`ddc.vcp18`, which maps to VCP `0x12`.

The monitor's own capabilities reply identifies it as `LCDXG49V`, declares
MCCS `2.2`, and includes VCP `10` and `12`. Windows uses the standard Microsoft
`monitor.inf`; there is no ASUS monitor driver in this path.

The app also has a LocalSystem service and named pipes for privileged helper
operations, but the brightness path does not require them. Direct VCP read and
write both work on the connected `ASUS XG49V` (`DISPLAY\AUS49A1`) while
DisplayWidget is running.

DDC/CI is a relatively slow serial protocol. The implementation waits briefly
after writes and retries transient failures, which also reduces collisions with
DisplayWidget's background polling.

## Build

Install directly from crates.io on Windows:

```powershell
cargo install brightwheel --locked
```

Build from a Windows shell:

```powershell
cargo build --release
```

Building the tray executable requires the Windows SDK resource compiler
(`rc.exe`) so Cargo can embed `assets\brightwheel.ico`. The resulting executable
loads the tray icon from its own resources; the image files are not needed at
runtime.

The repository can live on the WSL filesystem and be built by invoking
`cargo.exe` from WSL. Incremental compilation is disabled for development and
test profiles because Windows file locking is not supported for incremental
caches accessed through `\\wsl.localhost`.

The executables are `target\release\bright.exe` and
`target\release\brightwheel.exe`.

## Commands

```text
bright list
bright get [MONITOR]
bright set PERCENT [MONITOR]
bright change DELTA [MONITOR]
bright capabilities [MONITOR]
bright hdr
bright hdr-toggle
```

Examples:

```powershell
bright.exe get
bright.exe set 65
bright.exe change -5
```

`get`, `set`, and `change` print only the resulting percentage, which makes the
binary easy to call from a taskbar widget, AutoHotkey, PowerToys, or a tray UI.

## API references

- [GetVCPFeatureAndVCPFeatureReply]https://learn.microsoft.com/en-us/windows/win32/api/lowlevelmonitorconfigurationapi/nf-lowlevelmonitorconfigurationapi-getvcpfeatureandvcpfeaturereply
- [SetVCPFeature]https://learn.microsoft.com/en-us/windows/win32/api/lowlevelmonitorconfigurationapi/nf-lowlevelmonitorconfigurationapi-setvcpfeature
- [GetPhysicalMonitorsFromHMONITOR]https://learn.microsoft.com/en-us/windows/win32/api/physicalmonitorenumerationapi/nf-physicalmonitorenumerationapi-getphysicalmonitorsfromhmonitor