#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct TouchPoint {
pub contact_type: u8,
pub contact_status: u8,
pub x: u16,
pub y: u16,
pub finger_id: u8,
pub z: u8,
pub area: u8,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct DualXyData {
pub timestamp: u16,
pub touch1: TouchPoint,
pub touch2: TouchPoint,
pub button: bool,
pub end_of_frame: bool,
pub finger_count: u8,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum TouchpadRawEvent {
DualXy(DualXyData),
}
fn coord14(high: u8, low: u8) -> u16 {
(u16::from(high & 0x3f) << 8) | u16::from(low)
}
pub(super) fn decode_event(sub_id: u8, payload: &[u8; 16]) -> Option<TouchpadRawEvent> {
match sub_id {
0 => Some(TouchpadRawEvent::DualXy(DualXyData {
timestamp: u16::from_be_bytes([payload[0], payload[1]]),
touch1: TouchPoint {
contact_type: payload[2] >> 6,
contact_status: payload[4] >> 6,
x: coord14(payload[2], payload[3]),
y: coord14(payload[4], payload[5]),
finger_id: payload[8] >> 4,
z: payload[6],
area: payload[7],
},
touch2: TouchPoint {
contact_type: payload[9] >> 6,
contact_status: payload[11] >> 6,
x: coord14(payload[9], payload[10]),
y: coord14(payload[11], payload[12]),
finger_id: payload[15] >> 4,
z: payload[13],
area: payload[14],
},
button: payload[8] & (1 << 2) != 0,
end_of_frame: payload[8] & 1 != 0,
finger_count: payload[15] & 0x0f,
})),
_ => None,
}
}