OpenLogi

0x4531 · multiPlatform

为每个 Easy-Switch 主机槽关联 OS 平台,并将当前槽保持在主机 OS 布局。

MultiPlatform 将主机槽映射到键盘 OS 平台。它上报平台描述符,读取每个主机选择值,并可为主机持久设置选定平台。

**规格:**Logitech HID++ 2.0——multiPlatform(v1)。**交叉核对:**Logi Options+ 2.8(静态分析)、Solaar。用于:键盘功能。

函数参考

MultiPlatformFeature 只能为功能版本 1 创建。

方法

函数HID++ fn签名返回值
get_feature_infos0()MultiPlatformInfo
get_platform_descriptor1(descriptor_index: u8)PlatformDescriptor
get_host_platform2(host: HostIndex)HostPlatform
set_host_platform3(host: HostIndex, platform_index: u8)()

每个方法都是 async 方法,并返回 Result<…, Hidpp20Error>。

类型

MultiPlatformInfo

字段类型说明
capabilitiesMultiPlatformCapabilities功能能力。
platform_countu8平台 ID 数量。
descriptor_countu8描述符行数。
host_countu8主机槽数量。
current_hostHostIndex当前主机槽。
current_host_platformOption<u8>当前槽的平台。0xff 时为 None。

MultiPlatformCapabilities

能力字是 BE u16。

字段值说明
OS_DETECTION1 << 8(0x0100)设备可检测主机 OS。
SET_HOST_PLATFORM1 << 9(0x0200)主机软件可设置平台。

PlatformDescriptor

字段类型说明
platform_indexu8拥有此描述符的平台。
descriptor_indexu8描述符行索引。
os_maskOsMask所覆盖的操作系统。
from_versionu8支持的首个 OS 主版本。
from_revisionu8支持的首个 OS 修订版本。
to_versionu8支持的最后 OS 主版本。
to_revisionu8支持的最后 OS 修订版本。

OsMask

OsMask 是描述符字节 2–3 中的 BE u16。OpenLogi 会保留未命名位。

字段值说明
TIZEN1 << 0(0x0001)Tizen。
WINDOWS1 << 8(0x0100)Microsoft Windows。
WINDOWS_EMBEDDED1 << 9(0x0200)Windows Embedded。
LINUX1 << 10(0x0400)Linux。
CHROME1 << 11(0x0800)ChromeOS。
ANDROID1 << 12(0x1000)Android。
MACOS1 << 13(0x2000)macOS。
IOS1 << 14(0x4000)iOS。
WEBOS1 << 15(0x8000)webOS。

HostPlatform

字段类型说明
host_indexHostIndex设备返回的主机槽。
statusu8原始主机状态字节。
platform_indexOption<u8>已选平台。0xff 时为 None。
sourcePlatformSource选择来源。未知值返回 UnsupportedResponse。
auto_platform_indexOption<u8>自动检测平台。0xff 时为 None。
auto_descriptor_indexOption<u8>自动检测描述符。0xff 时为 None。

PlatformSource

变体值说明
Default0设备默认值。
Auto1设备自动检测。
Manual2在设备上选择。
Software3由主机软件选择。

HostIndex

变体值说明
Current0xff当前由设备选择的主机。
Slot(u8)0..=0xfe从零开始的主机槽索引。

事件

MultiPlatformFeature 没有 listen() 方法。PlatformChange::decode 为库存事件路径解码原始报告。

字段类型说明
host_indexHostIndex平台发生变化的主机。
platform_indexOption<u8>新平台。0xff 时为 None。
sourceOption<PlatformSource>新来源。未知值时为 None。

线格式

每个函数使用 3 字节短请求。OpenLogi 将每个响应规范化为 16 字节,再解码响应。

get_feature_infos(fn 0)

请求:0x00, 0x00, 0x00。

字节字段说明
0–1capabilitiesBE u16。
2platform_count平台 ID 数量。
3descriptor_count描述符行数。
4host_count主机槽数量。
5current_hostHostIndex;0xff 是 Current。
6current_host_platform0xff 是 None。
7–15—OpenLogi 忽略这些字节。

get_platform_descriptor(fn 1)

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

字节字段说明
0platform_index拥有此描述符的平台。
1descriptor_index描述符行索引。
2–3os_maskBE u16。
4from_version支持的首个 OS 主版本。
5from_revision支持的首个 OS 修订版本。
6to_version支持的最后 OS 主版本。
7to_revision支持的最后 OS 修订版本。
8–15—OpenLogi 忽略这些字节。

get_host_platform(fn 2)

请求:[u8::from(host), 0x00, 0x00]。

字节字段说明
0host_index设备返回的 HostIndex。
1status原始状态字节。
2platform_index0xff 是 None。
3source0 = Default,1 = Auto,2 = Manual,3 = Software。
4auto_platform_index0xff 是 None。
5auto_descriptor_index0xff 是 None。
6–15—OpenLogi 忽略这些字节。

set_host_platform(fn 3)

请求:[u8::from(host), platform_index, 0x00]。

OpenLogi 等待 HID++ 响应,但不会解析响应字节。调用 get_host_platform,可以确认持久选择值。

PlatformChange 事件

公开 v1 规格将此事件列为 0。Logi Options+ 和 OpenLogi 的库存路径会在功能索引与软件 ID 检查后,接受此功能的任意非请求函数。

字节字段说明
0host_indexHostIndex。
1platform_index0xff 会变为 None。
2source未知值会变为 None。
3–15—PlatformChange::decode 忽略这些字节。

OpenLogi 的用法

从 v0.8.14 起,保持 OS 布局设置使用此功能。键盘声明 SET_HOST_PLATFORM 时,此设置默认开启。

OpenLogi 读取功能信息,并要求当前主机是 host_count 范围内的编号槽。它读取全部描述符,选择覆盖主机 OS 的平台,并拒绝超出 platform_count 的索引。

OpenLogi 会在写入前读取当前槽。仅当选定平台不同时,OpenLogi 才会写入。之后,OpenLogi 会再次读取该槽,并将不匹配报告为错误。

主机 OS 可以是 macOS、Windows 或 Linux。无法取得 OS 版本时,OpenLogi 只接受没有上限版本的描述符。

库存路径会识别软件 ID 为 0 的平台变化报告,增加 settings_revision 并请求重新协调。如果保持 OS 布局仍开启,代理会在设备端变化后重新检查并恢复主机布局。

此选择会持久保存。OpenLogi 不会在退出时恢复旧平台。关闭设置会停止后续写入,但不会还原当前选择。

未确认的细节

v1 规格将事件标识为 0,而 Options+ 接受任意函数的报告。OpenLogi 的库存路径使用 Options+ 的宽松规则。

尚无硬件抓包可以确定键盘是否发送非零函数报告。OpenLogi 将每个有效的 3 字节报告视为变化提示,并重新读取权威状态。

Rust 用法

use hidpp::{
    device::Device,
    feature::{
        hosts_info::HostIndex,
        multi_platform::{MultiPlatformCapabilities, MultiPlatformFeature},
    },
};

// `device` is a discovered HID++ device.
device.enumerate_features().await?;
if let Some(feature) = device.get_feature::<MultiPlatformFeature>() {
    let info = feature.get_feature_infos().await?;
    let host = HostIndex::Current;
    let before = feature.get_host_platform(host).await?;

    if info
        .capabilities
        .contains(MultiPlatformCapabilities::SET_HOST_PLATFORM)
    {
        // The caller must obtain this index from a compatible descriptor.
        feature.set_host_platform(host, 0).await?;
        let after = feature.get_host_platform(host).await?;
        println!("{before:?} -> {after:?}");
    }
}

本页目录