0x2205 · PointerMotionScaling
以无符号 8.8 定点格式读取或写入设备专用的指针移动缩放系数。
PointerMotionScaling 为指针移动应用设备专用的乘数。原始值是无符号 8.8 定点数。0x0100 表示 1×。0x0180 表示 1.5×。
规格: Logitech HID++ 2.0 —— x2205 PointerMotionScaling。交叉核对: Logi Options+ 2.8(静态分析)。用于:
openlogi diag pointer-speed;回报率。
函数参考
PointerMotionScalingFeature 封装器(0x2205,版本 0+)读写一个标量值。
方法
| 函数 | HID++ fn | 签名 | 返回值 |
|---|---|---|---|
get_pointer_scaling | 0 | () | PointerScaling |
set_pointer_scaling | 1 | (scaling: PointerScaling) | PointerScaling |
所有方法均为 async,并返回 Result<…, Hidpp20Error>。
类型
PointerScaling 是非零原始 u16 值。原始值为零时,from_raw 返回 None。线上的零值响应会返回 Hidpp20Error::UnsupportedResponse。
| API | 签名或值 | 返回值 | 说明 |
|---|---|---|---|
PointerScaling::ONE | 0x0100 | PointerScaling | 未缩放的 1× 值。 |
PointerScaling::from_raw | (raw: u16) | Option<PointerScaling> | 当 raw 非零时构造值。 |
PointerScaling::raw | (self) | u16 | 返回原始无符号 8.8 值。 |
PointerScaling::multiplier | (self) | f32 | 返回 raw / 256.0。 |
事件
PointerMotionScalingFeature 未提供事件类型。
线格式
两个函数都发送 3 字节短请求。OpenLogi 将每个响应读取为 16 字节扩展载荷。
get_pointer_scaling(fn 0)
请求:[0x00, 0x00, 0x00]。3 个字节都是填充。
| 字节 | 字段 | 备注 |
|---|---|---|
| 0~1 | PointerScaling 原始值 | 无符号 8.8 值,使用 BE 字节序。0x0100 表示 1×。 |
| 2~15 | 保留 | OpenLogi 忽略这些字节。 |
set_pointer_scaling(fn 1)
| 请求字节 | 字段 | 备注 |
|---|---|---|
| 0~1 | 请求的原始值 | scaling.raw().to_be_bytes(),使用 BE 字节序。 |
| 2 | 填充 | OpenLogi 写入 0x00。 |
| 响应字节 | 字段 | 备注 |
|---|---|---|
| 0~1 | 回显的原始值 | 无符号 8.8 值,使用 BE 字节序。OpenLogi 将其返回为 PointerScaling。 |
| 2~15 | 保留 | OpenLogi 忽略这些字节。 |
OpenLogi 的用法
设备层在选定的路由上打开 0x2205,以供 get_pointer_scaling 和 set_pointer_scaling 调用。写入没有其他字段需要保留。OpenLogi 写入标量后会独立读取,并返回实际应用的值。
v0.8.15 中,openlogi diag pointer-speed 是唯一的产品调用方。该命令读取原值,并跳过相同的目标值。它总会先尝试恢复,再判断测试写入。它还会验证恢复值是否等于原值。
诊断命令接受任意非零原始 u16 值。此功能没有 GUI、代理配置或 IPC 设置。回报率页面说明了这一差别。
未确认的细节
HID++ 规范推荐 0x0010 至 0x1000,并说明固件会裁剪范围外的写入。已观察到的 MX Ergo 固件 MPM06.03_B0022 会原样存储 0x0001 和 0xffff。因此,OpenLogi 不假定固件会裁剪。未来的产品控件需要定义用户可见的范围。
Rust 用法
use hidpp::{
device::Device,
feature::pointer_motion_scaling::{PointerMotionScalingFeature, PointerScaling},
protocol::v20::Hidpp20Error,
};
async fn set_scaling(device: &mut Device) -> Result<(), Hidpp20Error> {
device.enumerate_features().await?;
if let Some(feature) = device.get_feature::<PointerMotionScalingFeature>() {
let requested = PointerScaling::from_raw(0x0180).expect("value is nonzero");
let applied = feature.set_pointer_scaling(requested).await?;
println!("Applied multiplier: {:.2}×", applied.multiplier());
}
Ok(())
}