OpenLogi

0x2201 · adjustableDpi

按传感器调节指针分辨率——枚举支持的 DPI 值,并读取或写入当前 DPI。

0x2201 按传感器控制一个 DPI 值。它报告传感器数量、支持的 DPI 值和当前 DPI。功能版本 1 还会报告默认 DPI 值。

**规格:**Logitech HID++ 2.0 —— x2201 adjustableDpi。**交叉核对:**Logi Options+ 2.8(静态分析)、Solaar。用于:DPI。

函数参考

AdjustableDpiFeature 是 OpenLogi 对 0x2201 的封装。所有方法都是异步方法,并返回 Result<T, Hidpp20Error>。

方法

函数HID++ fn签名返回值
get_sensor_count0()u8
get_sensor_dpi_list1(sensor_index: u8)Vec<u16>
get_sensor_dpi2(sensor_index: u8)u16
set_sensor_dpi3(sensor_index: u8, dpi: u16)()

类型

封装使用 u8 表示传感器索引,使用 u16 表示 DPI。get_sensor_dpi_list 返回按升序排列且不重复的值。

事件

OpenLogi v0.8.15 未定义 0x2201 事件类型。

线格式

函数 0~2 使用 3 字节短载荷。功能版本 0 和 1 的 set_sensor_dpi 也使用此形式。所有多字节 DPI 值均采用 BE 字节序。封装会对回复调用 extend_payload(),因此不要求长回复。

get_sensor_count(fn 0)

请求:[0x00, 0x00, 0x00]。

字节字段说明
0sensor_count运动传感器数量。
1–15/OpenLogi 忽略这些字节。

get_sensor_dpi_list(fn 1)

请求:[sensor_index, 0x00, 0x00]。

字节字段说明
0回显的 sensor_indexOpenLogi 要求该值与请求相同。不同则返回 Hidpp20Error::UnsupportedResponse。
1–14DPI 字最多 7 个 BE u16 字,按顺序解码。
15尾随字节该字节不能构成完整的字。OpenLogi 会忽略它。

0x0000 终止列表。完整列表没有终止符。字面 DPI 字的最高 3 位不是 0b111。最高 3 位为 0b111 的字是范围标记。其低 13 位是正步长。

前一个字面值是范围起点。后一个字面值是范围终点。OpenLogi 展开范围,保留不在步长网格上的终点,再排序和去重。起始范围标记、零步长、缺少终点或递减终点都会返回 Hidpp20Error::UnsupportedResponse。

get_sensor_dpi(fn 2)

请求:[sensor_index, 0x00, 0x00]。

字节字段说明
0回显的 sensor_index协议提供此回显。OpenLogi 在此函数中忽略它。
1–2current_dpiBE u16。OpenLogi 返回此值。
3–4default_dpi功能版本 1 及以后为 BE u16。版本 0 使用零。OpenLogi 忽略这些字节。
5–15/OpenLogi 忽略这些字节。

set_sensor_dpi(fn 3)

字节字段说明
0sensor_index目标传感器。
1–2dpiBE u16。
3dpi_levelLogi Options+ 2.8 的静态分析表明,此字段存在于功能版本 2 及以后。其含义尚未确认。

功能版本低于 2 时,请求在字节 2 后结束。OpenLogi v0.8.15 对所有版本都发送 3 字节形式。它会忽略确认回复的载荷。

OpenLogi 的用法

设备层先解析 0x2201,再解析 0x2202。它只操作传感器 0。设备报告零个传感器时,OpenLogi 会拒绝该设备。对于 0x2201,它读取当前 DPI 和支持的 DPI 列表。

写入前,OpenLogi 检查请求的 DPI 是否完全匹配设备报告的值。否则,它返回 WriteError::DpiUnsupported,且不发送数据包。写入后,它读取 DPI,并重试一次。第二次读到不同值时,它返回 WriteError::DpiNotApplied。读取失败不会撤销已确认的写入。

桌面端会在异步设备写入前保存请求的 DPI。因此,拒绝或未应用的写入可能会让请求值保留在桌面端状态中,直到后续实时读取。传感器设置是易失性的,因此代理会在重连后重新应用保存的 DPI。OpenLogi 退出时不会执行此功能的专用重置。

OpenLogi 不公开 default_dpi 或版本 2 的 dpi_level。面向用户的控制见 DPI 页面。

未确认的细节

Logi Options+ 2.8 会为版本 2 及以后的 0x2201 写入第 4 个 dpi_level 字节。公开规格止于版本 1。静态分析无法确认该字段的含义或硬件支持情况。OpenLogi 对每个版本都发送版本 0/1 形式。

Rust 用法

use hidpp::{
    device::Device,
    feature::adjustable_dpi::AdjustableDpiFeature,
    protocol::v20::Hidpp20Error,
};

async fn set_first_other_dpi(device: &mut Device) -> Result<(), Hidpp20Error> {
    device.enumerate_features().await?;
    if let Some(feature) = device.get_feature::<AdjustableDpiFeature>() {
        let sensor_count = feature.get_sensor_count().await?;
        let supported = feature.get_sensor_dpi_list(0).await?;
        let current = feature.get_sensor_dpi(0).await?;

        println!("sensors: {sensor_count}, current DPI: {current}");
        if let Some(&next) = supported.iter().find(|&&dpi| dpi != current) {
            feature.set_sensor_dpi(0, next).await?;
        }
    }

    Ok(())
}

本页目录