OpenLogi
Features

0x2121 · hiResWheel

High-resolution scroll wheel — read capabilities, get or set the wheel mode (resolution, ratchet vs. free-spin, event routing), and listen for diverted scroll and ratchet-switch events.

High-resolution scrolling. The wheel can report fine-grained motion, switch between ratchet and free-spin, and route its events either as standard HID or as HID++ notifications. Functions cover reading the wheel capability, getting/setting the current mode, and inverting direction.

Spec: Logitech HID++ 2.0 — x2121 hiResWheel (v1).

Function reference

The HiResWheelFeature wrapper (0x2121) exposes:

Methods

FunctionHID++ fnSignatureReturns
get_wheel_capabilities0()WheelCapabilities
get_wheel_mode1()WheelMode
set_wheel_mode2(target: WheelEventTarget, resolution: WheelResolution, inverted: bool)WheelMode
get_ratchet_switch_state3()WheelRatchetState
listenevent()Receiver<HiResWheelEvent>

All request methods are async and return Result<…, Hidpp20Error>. listen is synchronous and returns an async_channel::Receiver<HiResWheelEvent> directly. The analytics functions are intentionally not wrapped — their data structure is undocumented.

Types

WheelCapabilities

Wheel and feature capabilities, returned by get_wheel_capabilities.

FieldTypeDescription
multiplieru8Hi-res report multiplier: reports produced per ratchet distance in hi-res mode.
has_invertboolDevice can invert scroll direction in native HID mode (never in diverted mode).
has_switchboolDevice has a physical switch for the ratchet mode.
ratches_per_rotationu8Ratchets generated by one full wheel rotation.
wheel_diameteru8Nominal wheel diameter in millimeters.

WheelMode

Current wheel mode, returned by get_wheel_mode / set_wheel_mode.

FieldTypeDescription
invertedboolScroll direction inverted (native HID mode only).
resolutionWheelResolutionCurrent scrolling resolution.
targetWheelEventTargetWhere wheel reports are routed.

WheelResolution

VariantValueDescription
Low0Low-resolution wheel reporting.
High1High-resolution wheel reporting.

WheelEventTarget

VariantValueDescription
Native0Wheel reports go to the native HID path.
Diverted1Wheel reports are diverted to HID++ events.

WheelRatchetState

VariantValueDescription
Freespin0Wheel is in free-spin mode.
Ratchet1Wheel is in ratchet mode.

Events

HiResWheelEvent

VariantPayloadDescription
WheelMovementWheelMovementDataEmitted on wheel movement in diverted HID++ mode.
RatchetSwitchWheelRatchetStateEmitted when the ratchet mode changes. Always enabled.

WheelMovementData

FieldTypeDescription
resolutionWheelResolutionCurrent wheel resolution.
periodsU4Number of sampling periods for this event; U4 is a 4-bit unsigned integer (nibble), range 0–15.
delta_verticali16Vertical movement delta; moving away from the user is positive.

Wire format

All request payloads are 3 bytes. Responses are read from the 16-byte long payload returned by the HID++ 2.0 frame (extend_payload()). Event payloads are also parsed from that same 16-byte area.

get_wheel_capabilities (fn 0)

Request: [0x00, 0x00, 0x00]

Response (byte → field):

ByteFieldNotes
0multiplierHi-res report multiplier (u8).
1 bit 3has_invertpayload[1] & (1 << 3) != 0
1 bit 2has_switchpayload[1] & (1 << 2) != 0
2ratches_per_rotationRatchets per full rotation (u8).
3wheel_diameterNominal diameter in mm (u8).

get_wheel_mode (fn 1)

Request: [0x00, 0x00, 0x00]

Response (byte → field):

ByteFieldNotes
0 bit 2invertedpayload[0] & (1 << 2) != 0
0 bit 1resolution(payload[0] & (1 << 1)) >> 1WheelResolution
0 bit 0targetpayload[0] & 1WheelEventTarget

set_wheel_mode (fn 2)

Request: [mode_byte, 0x00, 0x00]

mode_byte is assembled as:

BitParameterNotes
2invertedSet when inverted == true
1resolutionu8::from(resolution) << 1
0targetu8::from(target)

Response: same byte layout as get_wheel_mode.

get_ratchet_switch_state (fn 3)

Request: [0x00, 0x00, 0x00]

Response (byte → field):

ByteFieldNotes
0 bit 0ratchet statepayload[0] & 1WheelRatchetState

Events

WheelMovement (event fn 0)

ByteFieldNotes
0 bit 4resolution(payload[0] & (1 << 4)) >> 4WheelResolution
0 bits 3–0periodsU4::from_lo(payload[0]) — lower nibble, range 0–15
1–2delta_verticali16::from_be_bytes([payload[1], payload[2]])

RatchetSwitch (event fn 1)

ByteFieldNotes
0 bit 0ratchet statepayload[0] & 1WheelRatchetState

Usage (Rust)

use hidpp::{device::Device, feature::hires_wheel::{HiResWheelFeature, WheelEventTarget, WheelResolution}};

// mut device: Device, obtained via Device::new(channel, index).await?
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<HiResWheelFeature>() {
    let caps = feat.get_wheel_capabilities().await?;
    println!("multiplier={}, ratchets/rot={}", caps.multiplier, caps.ratches_per_rotation);

    // Enable hi-res diverted mode (scroll events arrive as HID++ notifications)
    feat.set_wheel_mode(WheelEventTarget::Diverted, WheelResolution::High, false).await?;

    // Listen for wheel movement and ratchet-switch events
    let rx = feat.listen();
    while let Ok(event) = rx.recv().await {
        println!("{event:?}");
    }
}

On this page