Skip to main content

hidpp/feature/
disable_keys.rs

1//! Implements the `DisableKeys` feature (ID `0x4521`) that disables a fixed set
2//! of lock / system keys.
3//!
4//! For disabling arbitrary keys by HID usage, see
5//! [`DisableKeysByUsage`](super::disable_keys_by_usage) (`0x4522`).
6
7use openlogi_hidpp_derive::Feature;
8
9use crate::{feature::FeatureEndpoint, protocol::v20::Hidpp20Error};
10
11bitflags::bitflags! {
12    /// The set of keys a [`DisableKeysFeature`] device can disable.
13    ///
14    /// Used both for the device's capabilities and for the currently disabled
15    /// keys.
16    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
17    #[cfg_attr(feature = "serde", derive(serde::Serialize))]
18    pub struct DisableableKeys: u8 {
19        /// The Caps Lock key.
20        const CAPS_LOCK = 1 << 0;
21        /// The Num Lock key.
22        const NUM_LOCK = 1 << 1;
23        /// The Scroll Lock key.
24        const SCROLL_LOCK = 1 << 2;
25        /// The Insert key.
26        const INSERT = 1 << 3;
27        /// The Windows / Start key.
28        const WINDOWS = 1 << 4;
29    }
30}
31
32/// Implements the `DisableKeys` / `0x4521` feature.
33#[derive(Clone, Feature)]
34#[creatable(id = 0x4521, version = 0)]
35pub struct DisableKeysFeature {
36    /// The endpoint this feature talks to.
37    endpoint: FeatureEndpoint,
38}
39
40impl DisableKeysFeature {
41    /// Retrieves the set of keys the device allows software to disable.
42    pub async fn get_capabilities(&self) -> Result<DisableableKeys, Hidpp20Error> {
43        let payload = self.endpoint.call(0, [0; 3]).await?.extend_payload();
44        Ok(DisableableKeys::from_bits_retain(payload[0]))
45    }
46
47    /// Retrieves the set of keys currently disabled.
48    pub async fn get_disabled_keys(&self) -> Result<DisableableKeys, Hidpp20Error> {
49        let payload = self.endpoint.call(1, [0; 3]).await?.extend_payload();
50        Ok(DisableableKeys::from_bits_retain(payload[0]))
51    }
52
53    /// Replaces the set of disabled keys and returns the device's echo.
54    ///
55    /// This replaces the whole set, so passing [`DisableableKeys::empty`]
56    /// re-enables every key. The device rejects keys it cannot disable.
57    pub async fn set_disabled_keys(
58        &self,
59        keys: DisableableKeys,
60    ) -> Result<DisableableKeys, Hidpp20Error> {
61        let payload = self
62            .endpoint
63            .call(2, [keys.bits(), 0, 0])
64            .await?
65            .extend_payload();
66        Ok(DisableableKeys::from_bits_retain(payload[0]))
67    }
68}