pub mod event;
#[cfg(test)]
mod tests;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use openlogi_hidpp_derive::Feature;
pub use event::{TouchMousePoint, TouchMouseRawEvent, TouchMouseStatus};
use crate::{
feature::{EventSource, FeatureEndpoint},
protocol::v20::Hidpp20Error,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum Origin {
LowerLeft = 1,
LowerRight = 2,
UpperLeft = 3,
UpperRight = 4,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum RawMode {
NativeGestures = 0,
RawFiltered = 1,
RawUnfilteredAndGestures = 2,
RawUnfilteredAlways = 3,
RawUnfilteredWithZ = 4,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct TouchMouseInfo {
pub x_max_count: u16,
pub y_max_count: u16,
pub resolution_dpi: u16,
pub origin: Origin,
pub max_finger_count: u8,
pub width_height_data_range: u8,
}
impl TouchMouseInfo {
fn from_payload(payload: &[u8; 16]) -> Result<Self, Hidpp20Error> {
Ok(Self {
x_max_count: u16::from_be_bytes([payload[0], payload[1]]),
y_max_count: u16::from_be_bytes([payload[2], payload[3]]),
resolution_dpi: u16::from_be_bytes([payload[4], payload[5]]),
origin: Origin::try_from(payload[6]).map_err(|_| Hidpp20Error::UnsupportedResponse)?,
max_finger_count: payload[7],
width_height_data_range: payload[8],
})
}
}
#[derive(Feature)]
#[creatable(id = 0x6110, version = 0)]
pub struct TouchMouseRawFeature {
endpoint: FeatureEndpoint,
events: EventSource<TouchMouseRawEvent>,
}
impl TouchMouseRawFeature {
pub async fn get_touchpad_info(&self) -> Result<TouchMouseInfo, Hidpp20Error> {
let payload = self.endpoint.call(0, [0; 3]).await?.extend_payload();
TouchMouseInfo::from_payload(&payload)
}
pub async fn get_raw_mode(&self) -> Result<RawMode, Hidpp20Error> {
let payload = self.endpoint.call(1, [0; 3]).await?.extend_payload();
RawMode::try_from(payload[0]).map_err(|_| Hidpp20Error::UnsupportedResponse)
}
pub async fn set_raw_mode(&self, mode: RawMode) -> Result<(), Hidpp20Error> {
self.endpoint.call(2, [mode.into(), 0, 0]).await?;
Ok(())
}
}