# How to Set DPI for Logitech Mouse with OpenLogi: A Complete HID++ Protocol Guide

> Learn to set DPI for your Logitech mouse using OpenLogi and the HID++ protocol. Discover how to adjust settings and optimize your mouse performance with this comprehensive guide.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: how-to-guide
- Published: 2026-09-10

---

**OpenLogi controls Logitech mouse DPI through the HID++ protocol by detecting either feature `0x2201` (AdjustableDpi) or `0x2202` (ExtendedAdjustableDpi), then writing values via the `set_dpi()` function while verifying the change against supported sensor capabilities.**

OpenLogi provides a Rust-based interface for configuring Logitech peripherals at the firmware level. When you need to change your mouse sensitivity programmatically, the library negotiates with the device using Logitech's proprietary HID++ feature set to ensure compatibility across different sensor architectures.

## Understanding the HID++ DPI Feature Detection

OpenLogi automatically probes for two distinct DPI management features when initializing a device connection. This detection logic, implemented in [`crates/openlogi-device/src/write/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/dpi.rs) within the `DpiFeature::open` method, determines which protocol version your specific mouse model supports.

**`0x2201` (AdjustableDpi)** represents the preferred implementation. This feature exposes DPI values as a flat list where each entry corresponds to a single sensor sensitivity setting. OpenLogi attempts to open this feature first because it offers broader compatibility with existing Logitech hardware.

**`0x2202` (ExtendedAdjustableDpi)** serves as the fallback protocol. This extended feature supports independent X/Y axis DPI configurations and includes lift-off distance parameters. The library only uses this feature when `0x2201` is unavailable on the target device.

## The DPI Control Workflow

Once `DpiFeature::open` establishes the correct feature handle, OpenLogi executes a three-phase workflow to manage sensitivity settings. Each phase maps to specific methods in the DPI module that handle the low-level HID++ communication.

### Reading Current DPI Values

The `DpiFeature::current_dpi()` method retrieves the active sensitivity setting from the device. Depending on which feature was detected during initialization, this calls either `get_sensor_dpi` (for `0x2201`) or `get_sensor_dpi_parameters` (for `0x2202`) to read the hardware registers.

### Querying Supported DPI Ranges

Before writing new values, `DpiFeature::supported_dpi()` obtains the complete list of valid DPI settings for your specific mouse model. For devices using the extended feature (`0x2202`), this method processes stepped ranges through the `expand_dpi_ranges` helper function to generate a flattened list of acceptable values.

### Writing and Verifying New DPI

The `DpiFeature::set_dpi()` method handles the actual configuration change through the following sequence:

1. Transmits the new DPI value using `set_sensor_dpi` (adjustable feature) or `set_sensor_dpi_parameters` (extended feature)
2. Immediately reads the DPI back from the device to confirm the write succeeded
3. Logs a warning if the reported value differs from the requested value, indicating the device clamped the input to the nearest supported step

## Public API Methods

OpenLogi exposes DPI control through two primary async functions that abstract the feature detection and error handling logic.

**`set_dpi(backend, route, dpi)`** manages the complete write operation. This function opens a HID++ channel to the specified device, selects the appropriate feature (`0x2201` or `0x2202`), transmits the new `Dpi` value, and performs the verification read. The `backend` parameter implements the `HidBackend` trait, while `route` specifies the `DeviceRoute` targeting your specific mouse.

**`get_dpi_info(backend, route)`** returns comprehensive sensor capabilities. This function provides both the current active DPI and a `DpiCapabilities` structure containing the full vector of supported values, allowing applications to validate user input against hardware limits before attempting writes.

## Practical Implementation Examples

You can interact with OpenLogi's DPI control either programmatically through the Rust library or via the bundled command-line interface.

### Rust Library Integration

For custom applications or agents, import the DPI module and use the async API directly:

```rust
use openlogi_device::write::dpi::{set_dpi, get_dpi_info};
use openlogi_core::hid::dpi::Dpi;
use openlogi_agent_core::backend::HidBackend;
use openlogi_ipc::DeviceRoute;

async fn change_mouse_dpi(
    backend: &dyn HidBackend, 
    route: &DeviceRoute, 
    new_dpi: u16
) -> Result<(), WriteError> {
    // Convert raw value to the library's Dpi type
    let dpi = Dpi::new(new_dpi);
    
    // Write the DPI setting
    set_dpi(backend, route, dpi).await?;
    
    // Verify capabilities and confirm the change
    let info = get_dpi_info(backend, route).await?;
    println!("Current DPI: {}, supported values: {:?}", 
        info.current, info.capabilities.values());
    
    Ok(())
}

```

The `Dpi` type constructor in [`crates/openlogi-core/src/hid/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-core/src/hid/dpi.rs) handles validation, while the `DpiInfo` structure returned by `get_dpi_info` contains both the current value and the capabilities object.

### Command-Line Interface

For end-user workflows, use the `openlogi` CLI commands without writing Rust code:

```bash

# List connected devices to find your mouse index

openlogi list

# Set device 0 to 1200 DPI

openlogi set-dpi --device 0 --value 1200

# Verify the configuration with diagnostic output

openlogi diag dpi --device 0

```

The `set-dpi` command in [`crates/openlogi-cli/src/cmd/mod.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-cli/src/cmd/mod.rs) forwards your request to the `set_dpi` function, while `diag dpi`—implemented in [`crates/openlogi-cli/src/cmd/diag/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-cli/src/cmd/diag/dpi.rs)—demonstrates the full read-write-read round-trip to confirm the device accepted the new sensitivity value.

## Summary

- OpenLogi automatically detects DPI features `0x2201` (preferred) or `0x2202` (extended fallback) in [`openlogi-device/src/write/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/openlogi-device/src/write/dpi.rs)
- The `DpiFeature::set_dpi()` method writes values and verifies the device report matches the requested sensitivity
- Use **`set_dpi()`** to change settings and **`get_dpi_info()`** to retrieve current values and supported ranges
- The CLI provides `openlogi set-dpi` and `openlogi diag dpi` commands for non-programmatic access
- All DPI types (`Dpi`, `DpiCapabilities`, `DpiInfo`) are defined in [`openlogi-core/src/hid/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/openlogi-core/src/hid/dpi.rs)

## Frequently Asked Questions

### What is the difference between AdjustableDpi and ExtendedAdjustableDpi features?

The **`0x2201` (AdjustableDpi)** feature provides a simple flat list of DPI values per sensor, while **`0x2202` (ExtendedAdjustableDpi)** adds independent X/Y axis control and lift-off distance configuration using stepped ranges. OpenLogi attempts to use `0x2201` first for maximum compatibility, falling back to `0x2202` only when necessary.

### Why does OpenLogi read the DPI back after writing it?

The library performs a verification read to ensure the hardware actually accepted the requested value. Some Logitech mice automatically clamp out-of-range values to the nearest supported step. If the read-back value differs from the write request, OpenLogi logs a warning indicating the device modified the input to match its supported capabilities.

### Can I set different DPI values for X and Y axes?

Only mice exposing the **`0x2202` (ExtendedAdjustableDpi)** feature support independent X/Y axis configuration. When this feature is active, the `set_sensor_dpi_parameters` function accepts separate values for horizontal and vertical sensitivity. The standard `0x2201` feature applies a single value to both axes.

### What happens if I request a DPI value my mouse doesn't support?

The device firmware will automatically adjust your request to the nearest valid value within its hardware limits. OpenLogi's verification step detects this discrepancy and reports it via logging or CLI output, allowing you to query the exact supported range using `get_dpi_info()` or `openlogi diag dpi` before attempting further modifications.