0x1C00 · persistentRemappableAction
非易失性控件重映射——按控件和主机槽读写持久化动作配置(按键、鼠标按键、消费者控制码、内部函数),映射存储于设备存储中。
将设备控件持久地重映射到不同的 HID 动作,映射关系写入设备的非易失性存储。控件以与
0x1B04(reprogControls)相同的 ControlId 标识;若设备同时支持两个功能,0x1B04
的实时转发优先于此处的持久重映射。
get_feature_info 报告设备支持哪些 HID 输出类型;get_count 返回可重映射控件数量与
主机槽数量。get_cid_info 枚举控件表;get_persistent_action / set_persistent_action
读取和写入每个控件、每个主机的映射。reset_persistent_action 将单条映射恢复出厂默认;
reset_to_factory_settings 一次性清除指定主机槽的全部映射。
ActionId—— 控件触发时产生的动作类型:SendKeyboard、SendMouseButton、SendXDisplacement、SendYDisplacement、SendVerticalRoller、SendHorizontalRoller、SendConsumerControl、ExecuteInternalFunction、SendPowerKey。RemappableCapabilities—— 标志位,声明设备可产生哪些ActionId类型;由get_feature_info返回。ModifierMask—— 键盘修饰键标志(左/右 Ctrl、Shift、Alt、GUI);仅适用于SendKeyboard动作。HostMask—— 为reset_to_factory_settings选择一个或多个主机槽 (HOST_1–HOST_3)。
规格: Logitech HID++ 2.0 —— persistentRemappableAction。用于:
openlogi-hidpp的类型化封装。
Function reference
The PersistentRemappableActionFeature wrapper (0x1c00) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_feature_info | 0 | () | RemappableCapabilities |
get_count | 1 | () | RemappableInfo |
get_cid_info | 2 | (index: u8, host: HostIndex) | ControlId |
get_persistent_action | 3 | (cid: ControlId, host: HostIndex) | PersistentAction |
set_persistent_action | 4 | (cid: ControlId, host: HostIndex, config: PersistentActionConfig) | () |
reset_persistent_action | 5 | (cid: ControlId, host: HostIndex) | () |
reset_to_factory_settings | 6 | (hosts: HostMask) | () |
All methods are async and return Result<…, Hidpp20Error>.
Types
RemappableCapabilities
Bitflags advertising which HID output categories the device's persistent remapping can produce; returned by get_feature_info.
| Flag | Bit/Value | Description |
|---|---|---|
KEYBOARD_REPORT | 1 << 0 | Can send keyboard/keypad keys. |
MOUSE_BUTTONS | 1 << 1 | Can send mouse buttons. |
X_DISPLACEMENT | 1 << 2 | Can send mouse X displacement. |
Y_DISPLACEMENT | 1 << 3 | Can send mouse Y displacement. |
VERTICAL_ROLLER | 1 << 4 | Can send vertical roller increments. |
HORIZONTAL_ROLLER | 1 << 5 | Can send horizontal roller (AC pan) increments. |
CONSUMER_CONTROL | 1 << 6 | Can send consumer-control codes. |
INTERNAL_FUNCTION | 1 << 7 | Can execute internal functions. |
POWER_KEY | 1 << 8 | Can send power keys. |
RemappableInfo
Control-table sizing returned by get_count.
| Field | Type | Description |
|---|---|---|
count | u8 | Number of control IDs in the table. |
host_count | u8 | Number of hosts the device supports. |
PersistentAction
The action mapped to a control, returned by get_persistent_action.
| Field | Type | Description |
|---|---|---|
cid | ControlId | The control the action belongs to. |
host | HostIndex | The host slot the mapping applies to. |
action_id | ActionId | The action performed when triggered. |
value | u16 | The HID usage code, displacement, or internal-function index sent. |
modifier_mask | ModifierMask | Keyboard modifiers applied (keyboard actions only). |
remapped | bool | Whether the control is remapped away from its default behaviour. |
PersistentActionConfig
The action to assign via set_persistent_action.
| Field | Type | Description |
|---|---|---|
action_id | ActionId | The action to perform when triggered. |
value | u16 | The HID usage code, displacement, or internal-function index to send. |
modifier_mask | ModifierMask | Keyboard modifiers to apply (keyboard actions only). |
ActionId
The action a control performs when triggered.
| Variant | Value | Description |
|---|---|---|
SendKeyboard | 0x01 | Send a keyboard/keypad report (HID usage page 7). |
SendMouseButton | 0x02 | Send a mouse-button report (usage page 9). |
SendXDisplacement | 0x03 | Send mouse X displacement (usage page 1, code 0x30). |
SendYDisplacement | 0x04 | Send mouse Y displacement (usage page 1, code 0x31). |
SendVerticalRoller | 0x05 | Send vertical roller/wheel displacement (usage page 1, code 0x38). |
SendHorizontalRoller | 0x06 | Send horizontal roller / AC pan displacement (usage page 12, code 0x0238). |
SendConsumerControl | 0x07 | Send a consumer-control report (usage page 12). |
ExecuteInternalFunction | 0x08 | Execute an internal function (the value is the function index). |
SendPowerKey | 0x09 | Send a power-key report (usage page 1). |
ModifierMask
Standard keyboard modifier keys for a remapped keyboard action. Modifiers only apply to keyboard reports.
| Flag | Bit/Value | Description |
|---|---|---|
LEFT_CTRL | 1 << 0 | Left Control. |
LEFT_SHIFT | 1 << 1 | Left Shift. |
LEFT_ALT | 1 << 2 | Left Alt. |
LEFT_GUI | 1 << 3 | Left GUI (Win/Command). |
RIGHT_CTRL | 1 << 4 | Right Control. |
RIGHT_SHIFT | 1 << 5 | Right Shift. |
RIGHT_ALT | 1 << 6 | Right Alt. |
RIGHT_GUI | 1 << 7 | Right GUI (Win/Command). |
HostMask
A set of host slots for reset_to_factory_settings.
| Flag | Bit/Value | Description |
|---|---|---|
HOST_1 | 1 << 0 | Host 1. |
HOST_2 | 1 << 1 | Host 2. |
HOST_3 | 1 << 2 | Host 3. |
Wire format
Short getter requests carry a 3-byte zero payload; set_persistent_action uses a 16-byte long-payload request. All responses are read from the 16-byte long payload returned by .extend_payload().
get_feature_info (fn 0)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0–1 | RemappableCapabilities | Big-endian u16 bitfield; see flag table above. |
get_count (fn 1)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | count | Number of control IDs in the table. |
| 1 | host_count | Number of host slots the device supports. |
get_cid_info (fn 2)
Request: [index, host, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0–1 | ControlId | Big-endian u16 control identifier. |
get_persistent_action (fn 3)
Request: [cid_hi, cid_lo, host] — ControlId split into two bytes big-endian, followed by the HostIndex byte.
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0–1 | cid | ControlId as big-endian u16. |
| 2 | host | HostIndex byte. |
| 3 | action_id | ActionId discriminant (0x01–0x09). |
| 4–5 | value | HID usage code, displacement, or function index as big-endian u16. |
| 6 | modifier_mask | ModifierMask bitfield byte. |
| 7 | remapped | Bit 0: 1 = remapped away from factory default. |
set_persistent_action (fn 4)
Uses call_long: a 16-byte request payload; bytes 7–15 are zero-padded.
| Byte | Field | Notes |
|---|---|---|
| 0–1 | cid | ControlId as big-endian u16. |
| 2 | host | HostIndex byte. |
| 3 | action_id | ActionId discriminant. |
| 4–5 | value | HID usage / displacement / function index as big-endian u16. |
| 6 | modifier_mask | ModifierMask bitfield byte. |
| 7–15 | — | Reserved, zero. |
No meaningful response body.
reset_persistent_action (fn 5)
Request: [cid_hi, cid_lo, host] — same layout as get_persistent_action request.
No meaningful response body.
reset_to_factory_settings (fn 6)
Request: [hosts_bits, 0x00, 0x00] — HostMask bitfield in byte 0; bits 0/1/2 select HOST_1/HOST_2/HOST_3.
No meaningful response body.
Usage (Rust)
use hidpp::{
device::Device,
feature::{
hosts_info::HostIndex,
persistent_remappable_action::{
ActionId, ModifierMask, PersistentActionConfig, PersistentRemappableActionFeature,
},
reprog_controls::ControlId,
},
};
// device: &mut Device, already created via Device::new(channel, device_index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<PersistentRemappableActionFeature>() {
// Query device capabilities and table size.
let caps = feat.get_feature_info().await?;
let info = feat.get_count().await?;
println!("caps={caps:?}, controls={}, hosts={}", info.count, info.host_count);
// Read the current mapping for control 0x00c4 on host 0.
let host = HostIndex::from(0u8);
let cid = ControlId::from(0x00c4u16);
let action = feat.get_persistent_action(cid, host).await?;
println!("current action: {:?}", action.action_id);
// Remap the control to send Ctrl+C (usage 0x06 = HID keycode for 'c').
let config = PersistentActionConfig {
action_id: ActionId::SendKeyboard,
value: 0x0006,
modifier_mask: ModifierMask::LEFT_CTRL,
};
feat.set_persistent_action(cid, host, config).await?;
}