hidpp/feature/mode_status/
mod.rs1use std::sync::Arc;
4
5use crate::{
6 channel::HidppChannel,
7 feature::{CreatableFeature, Feature, FeatureEndpoint},
8 protocol::v20::Hidpp20Error,
9};
10
11bitflags::bitflags! {
12 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
14 #[cfg_attr(feature = "serde", derive(serde::Serialize))]
15 pub struct ModeStatus0: u8 {
16 const PERFORMANCE = 1 << 0;
18 }
19}
20
21bitflags::bitflags! {
22 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
24 #[cfg_attr(feature = "serde", derive(serde::Serialize))]
25 pub struct ModeStatusCapabilities: u16 {
26 const HARDWARE_SWITCH = 1 << 0;
28 const SOFTWARE_SWITCH = 1 << 1;
30 }
31}
32
33#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize))]
36#[non_exhaustive]
37pub struct ModeStatus {
38 pub status0: ModeStatus0,
40 pub status1: u8,
42}
43
44#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize))]
47pub struct ModeStatusChange {
48 pub status0: ModeStatus0,
50 pub status1: u8,
52 pub changed_mask0: ModeStatus0,
54 pub changed_mask1: u8,
56}
57
58#[derive(Clone)]
60pub struct ModeStatusFeature {
61 endpoint: FeatureEndpoint,
63}
64
65impl CreatableFeature for ModeStatusFeature {
66 const ID: u16 = 0x8090;
67 const STARTING_VERSION: u8 = 1;
68
69 fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self {
70 Self {
71 endpoint: FeatureEndpoint::new(chan, device_index, feature_index),
72 }
73 }
74}
75
76impl Feature for ModeStatusFeature {}
77
78impl ModeStatusFeature {
79 pub async fn get_mode_status(&self) -> Result<ModeStatus, Hidpp20Error> {
81 let payload = self.endpoint.call(0, [0; 3]).await?.extend_payload();
82 Ok(ModeStatus {
83 status0: ModeStatus0::from_bits_retain(payload[0]),
84 status1: payload[1],
85 })
86 }
87
88 pub async fn set_mode_status(&self, change: ModeStatusChange) -> Result<(), Hidpp20Error> {
90 let mut args = [0; 16];
91 args[0] = change.status0.bits();
92 args[1] = change.status1;
93 args[2] = change.changed_mask0.bits();
94 args[3] = change.changed_mask1;
95
96 self.endpoint.call_long(1, args).await?;
97 Ok(())
98 }
99
100 pub async fn set_performance_mode(&self, enabled: bool) -> Result<(), Hidpp20Error> {
102 let status0 = if enabled {
103 ModeStatus0::PERFORMANCE
104 } else {
105 ModeStatus0::empty()
106 };
107 self.set_mode_status(ModeStatusChange {
108 status0,
109 status1: 0,
110 changed_mask0: ModeStatus0::PERFORMANCE,
111 changed_mask1: 0,
112 })
113 .await
114 }
115
116 pub async fn get_device_config(&self) -> Result<ModeStatusCapabilities, Hidpp20Error> {
118 let payload = self.endpoint.call(2, [0; 3]).await?.extend_payload();
119 Ok(ModeStatusCapabilities::from_bits_retain(
120 u16::from_be_bytes([payload[0], payload[1]]),
121 ))
122 }
123}