0x2201 · adjustableDpi
Per-sensor pointer resolution — read the sensor count, enumerate supported DPI values, and read or write the active DPI.
Per-sensor pointer resolution. getSensorCount reports how many sensors the
device has; getSensorDpiList returns the supported DPI values (a list or a
range with a step); getSensorDpi / setSensorDpi read and write the active
DPI.
OpenLogi builds its DPI presets on top of this feature, and exposes Cycle DPI and Set preset as bindable actions.
Spec: Logitech HID++ 2.0 — x2201 adjustableDpi. See also x2202 extendedAdjustableDpi. Used by: DPI presets.
Function reference
The AdjustableDpiFeature wrapper (0x2201) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_sensor_count | 0 | () | u8 |
get_sensor_dpi_list | 1 | (sensor_index: u8) | Vec<u16> |
get_sensor_dpi | 2 | (sensor_index: u8) | u16 |
set_sensor_dpi | 3 | (sensor_index: u8, dpi: u16) | () |
All methods are async and return Result<…, Hidpp20Error>.
Wire format
All four functions use a 3-byte short request payload and receive a 16-byte long response payload (extend_payload()).
get_sensor_count (fn 0)
Request: [0x00, 0x00, 0x00] (no parameters)
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | sensor_count | Number of sensors on the device |
get_sensor_dpi_list (fn 1)
Request: [sensor_index, 0x00, 0x00]
Response (bytes → field): byte 0 is the echoed sensor_index. Bytes 1–15 carry up to seven big-endian u16 values, terminated by 0x0000 (terminator may be absent when values fill the payload).
Each u16 value is either:
- An explicit DPI value (top 3 bits are not
0b111). - A range marker (
value >> 13 == 0b111): the low 13 bits are the step (value & 0x1fff). The preceding explicit value is the range start; the next explicit value (bytesoffset+2..=offset+3) is the range end. The crate expands the range into individual DPI steps and always includes the end value.
| Bytes | Field | Notes |
|---|---|---|
| 0 | echoed sensor_index | Skipped by the crate |
| 1–2, 3–4, … | DPI entry (big-endian u16) | Explicit value or range marker |
| next 2 | 0x0000 | Terminator (absent if payload is full) |
get_sensor_dpi (fn 2)
Request: [sensor_index, 0x00, 0x00]
Response (bytes → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | echoed sensor_index | Ignored by the crate |
| 1 | DPI high byte | Combined as u16::from_be_bytes([payload[1], payload[2]]) |
| 2 | DPI low byte |
set_sensor_dpi (fn 3)
Request: [sensor_index, dpi_hi, dpi_lo] — dpi split as dpi.to_be_bytes().
Response: acknowledged; return value is () (response payload ignored).
Usage (Rust)
use hidpp::{device::Device, feature::adjustable_dpi::AdjustableDpiFeature};
// device: &mut Device, already created via Device::new(channel, index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<AdjustableDpiFeature>() {
let sensor_count = feat.get_sensor_count().await?;
println!("sensors: {sensor_count}");
// Query supported DPI values for sensor 0
let dpi_list = feat.get_sensor_dpi_list(0).await?;
println!("supported DPI: {dpi_list:?}");
// Read and then raise the active DPI
let current = feat.get_sensor_dpi(0).await?;
println!("current DPI: {current}");
feat.set_sensor_dpi(0, 1600).await?;
}0x2200 · mousePointer
Read optical-sensor resolution and pointer-tuning hints — acceleration curve, OS-ballistics preference, and vertical-tuning suggestion.
0x2202 · extendedAdjustableDpi
Extended per-sensor DPI control — independent X/Y resolution, lift-off distance, DPI-status LED, and firmware or host-side calibration.