hidpp/feature/
mode_status.rs1use openlogi_hidpp_derive::Feature;
4
5use crate::{feature::FeatureEndpoint, protocol::v20::Hidpp20Error};
6
7bitflags::bitflags! {
8 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10 #[cfg_attr(feature = "serde", derive(serde::Serialize))]
11 pub struct ModeStatus0: u8 {
12 const PERFORMANCE = 1 << 0;
14 }
15}
16
17bitflags::bitflags! {
18 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
20 #[cfg_attr(feature = "serde", derive(serde::Serialize))]
21 pub struct ModeStatusCapabilities: u16 {
22 const HARDWARE_SWITCH = 1 << 0;
24 const SOFTWARE_SWITCH = 1 << 1;
26 }
27}
28
29#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize))]
32#[non_exhaustive]
33pub struct ModeStatus {
34 pub status0: ModeStatus0,
36 pub status1: u8,
38}
39
40#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize))]
43pub struct ModeStatusChange {
44 pub status0: ModeStatus0,
46 pub status1: u8,
48 pub changed_mask0: ModeStatus0,
50 pub changed_mask1: u8,
52}
53
54#[derive(Clone, Feature)]
56#[creatable(id = 0x8090, version = 1)]
57pub struct ModeStatusFeature {
58 endpoint: FeatureEndpoint,
60}
61
62impl ModeStatusFeature {
63 pub async fn get_mode_status(&self) -> Result<ModeStatus, Hidpp20Error> {
65 let payload = self.endpoint.call(0, [0; 3]).await?.extend_payload();
66 Ok(ModeStatus {
67 status0: ModeStatus0::from_bits_retain(payload[0]),
68 status1: payload[1],
69 })
70 }
71
72 pub async fn set_mode_status(&self, change: ModeStatusChange) -> Result<(), Hidpp20Error> {
74 let mut args = [0; 16];
75 args[0] = change.status0.bits();
76 args[1] = change.status1;
77 args[2] = change.changed_mask0.bits();
78 args[3] = change.changed_mask1;
79
80 self.endpoint.call_long(1, args).await?;
81 Ok(())
82 }
83
84 pub async fn set_performance_mode(&self, enabled: bool) -> Result<(), Hidpp20Error> {
86 let status0 = if enabled {
87 ModeStatus0::PERFORMANCE
88 } else {
89 ModeStatus0::empty()
90 };
91 self.set_mode_status(ModeStatusChange {
92 status0,
93 status1: 0,
94 changed_mask0: ModeStatus0::PERFORMANCE,
95 changed_mask1: 0,
96 })
97 .await
98 }
99
100 pub async fn get_device_config(&self) -> Result<ModeStatusCapabilities, Hidpp20Error> {
102 let payload = self.endpoint.call(2, [0; 3]).await?.extend_payload();
103 Ok(ModeStatusCapabilities::from_bits_retain(
104 u16::from_be_bytes([payload[0], payload[1]]),
105 ))
106 }
107}