compatibility with the latest version

This commit is contained in:
2026-02-22 17:49:19 +01:00
parent 3b23ca266a
commit e705b3e839
6 changed files with 68 additions and 24 deletions

View File

@@ -38,22 +38,22 @@ impl Iterator for OtdIpc {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let mut raw_header = [0; size_of::<Header>()]; let mut raw_header = [0; size_of::<Header>()];
self.stream.read_exact(&mut raw_header).ok()?; self.stream.read_exact(&mut raw_header).unwrap();
let header: Header = raw_header[..].try_into().ok()?; let header: Header = raw_header[..].try_into().unwrap();
let mut raw_buffer = vec![0; (header.size as usize) - size_of::<Header>()]; let mut raw_buffer = vec![0; (header.size as usize) - size_of::<Header>()];
self.stream.read_exact(&mut raw_buffer).ok()?; self.stream.read_exact(&mut raw_buffer).unwrap();
match header.message_type { match header.message_type {
messages::MessageType::None => None, messages::MessageType::None => None,
messages::MessageType::DeviceInfo => Some(Message::DeviceInfo(Box::new( messages::MessageType::DeviceInfo => Some(Message::DeviceInfo(Box::new(
DeviceInfo::try_from(&raw_buffer[..]).ok()?, DeviceInfo::try_from(&raw_buffer[..]).unwrap(),
))), ))),
messages::MessageType::State => { messages::MessageType::State => {
Some(Message::State(State::try_from(&raw_buffer[..]).ok()?)) Some(Message::State(State::try_from(&raw_buffer[..]).unwrap()))
} }
messages::MessageType::Ping => { messages::MessageType::Ping => {
Some(Message::Ping(Ping::try_from(&raw_buffer[..]).ok()?)) Some(Message::Ping(Ping::try_from(&raw_buffer[..]).unwrap()))
} }
messages::MessageType::DebugMessage => { messages::MessageType::DebugMessage => {
Some(Message::DebugMessage(DebugMessage::from(&raw_buffer[..]))) Some(Message::DebugMessage(DebugMessage::from(&raw_buffer[..])))
@@ -62,8 +62,7 @@ impl Iterator for OtdIpc {
Some(Message::Experimental(Experimental::from(&raw_buffer[..]))) Some(Message::Experimental(Experimental::from(&raw_buffer[..])))
} }
messages::MessageType::Hello => { messages::MessageType::Hello => {
// Some(Message::Hello(Hello::from(&raw_buffer[..]))) Some(Message::Hello(Hello::try_from(&raw_buffer[..]).unwrap()))
None
} }
} }
} }

View File

@@ -16,7 +16,7 @@ impl TryFrom<&[u8]> for DeviceInfo {
type Error = &'static str; type Error = &'static str;
fn try_from(mut bytes: &[u8]) -> Result<Self, Self::Error> { fn try_from(mut bytes: &[u8]) -> Result<Self, Self::Error> {
if bytes.len() < 16 + 256 + 256 { if bytes.len() < 12 + 256 + 256 {
return Err("buffer too small"); return Err("buffer too small");
} }
@@ -24,9 +24,6 @@ impl TryFrom<&[u8]> for DeviceInfo {
let max_y = f32::from_le_bytes(take::<4>(&mut bytes)?); let max_y = f32::from_le_bytes(take::<4>(&mut bytes)?);
let max_pressure = u32::from_le_bytes(take::<4>(&mut bytes)?); let max_pressure = u32::from_le_bytes(take::<4>(&mut bytes)?);
// skip ignored field
let _ = take::<4>(&mut bytes)?;
let (id_bytes, name_bytes) = bytes.split_at(256); let (id_bytes, name_bytes) = bytes.split_at(256);
let persistent_id = String::from_utf8_lossy(id_bytes) let persistent_id = String::from_utf8_lossy(id_bytes)
.trim_end_matches('\0') .trim_end_matches('\0')

View File

@@ -2,9 +2,11 @@ use std::fmt::Debug;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::take;
use super::MessageType; use super::MessageType;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct Hello { pub struct Hello {
pub protocol_version: u64, pub protocol_version: u64,
pub human_readable_name: String, pub human_readable_name: String,
@@ -13,6 +15,18 @@ pub struct Hello {
pub compatibility_version: u8, pub compatibility_version: u8,
} }
impl Debug for Hello {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Hello")
.field("protocol_version", &format!("{:x}", &self.protocol_version))
.field("human_readable_name", &self.human_readable_name)
.field("human_readable_version", &self.human_readable_version)
.field("implementation_id", &self.implementation_id)
.field("compatibility_version", &self.compatibility_version)
.finish()
}
}
impl Hello { impl Hello {
pub fn new( pub fn new(
protocol_version: u64, protocol_version: u64,
@@ -35,13 +49,13 @@ impl From<Hello> for Vec<u8> {
fn from(value: Hello) -> Self { fn from(value: Hello) -> Self {
let mut output = Vec::with_capacity(std::mem::size_of::<Hello>()); let mut output = Vec::with_capacity(std::mem::size_of::<Hello>());
// Header
output.extend_from_slice(&(MessageType::Hello as u32).to_le_bytes()); output.extend_from_slice(&(MessageType::Hello as u32).to_le_bytes());
output.extend_from_slice(&(std::mem::size_of::<Hello>() as u32).to_le_bytes()); output.extend_from_slice(&(std::mem::size_of::<Hello>() as u32).to_le_bytes());
output.push(0u8); // non_persistent_tablet_id output.push(0u8); // non_persistent_tablet_id
// Hello
output.extend_from_slice(&value.protocol_version.to_le_bytes()); output.extend_from_slice(&value.protocol_version.to_le_bytes());
output.extend_from_slice(&str_to_fixed(&value.human_readable_name).unwrap()); output.extend_from_slice(&str_to_fixed(&value.human_readable_name).unwrap());
output.extend_from_slice(&str_to_fixed(&value.human_readable_version).unwrap()); output.extend_from_slice(&str_to_fixed(&value.human_readable_version).unwrap());
output.extend_from_slice(&str_to_fixed(&value.implementation_id).unwrap()); output.extend_from_slice(&str_to_fixed(&value.implementation_id).unwrap());
@@ -52,6 +66,33 @@ impl From<Hello> for Vec<u8> {
} }
} }
impl TryFrom<&[u8]> for Hello {
type Error = &'static str;
fn try_from(mut bytes: &[u8]) -> Result<Self, Self::Error> {
if bytes.len() < 8 + 256 + 256 + 256 + 1 {
return Err("buffer too small");
}
// random 4 bytes are here now, wtf?
let _ = take::<4>(&mut bytes);
Ok(Self {
protocol_version: u64::from_le_bytes(take::<8>(&mut bytes)?),
human_readable_name: String::from_utf8_lossy(&take::<256>(&mut bytes)?)
.trim_end_matches('\0')
.to_string(),
human_readable_version: String::from_utf8_lossy(&take::<256>(&mut bytes)?)
.trim_end_matches('\0')
.to_string(),
implementation_id: String::from_utf8_lossy(&take::<256>(&mut bytes)?)
.trim_end_matches('\0')
.to_string(),
compatibility_version: u8::from_le_bytes(take::<1>(&mut bytes)?),
})
}
}
fn str_to_fixed(input: &str) -> Result<[u8; 256], String> { fn str_to_fixed(input: &str) -> Result<[u8; 256], String> {
let bytes = input.as_bytes(); let bytes = input.as_bytes();

View File

@@ -23,7 +23,7 @@ pub enum Message {
Ping(Ping), Ping(Ping),
DebugMessage(DebugMessage), DebugMessage(DebugMessage),
Experimental(Experimental), Experimental(Experimental),
// Hello(Hello), Hello(Hello),
} }
// helper to read fixed-size chunks // helper to read fixed-size chunks

View File

@@ -71,6 +71,7 @@ pub struct State {
impl State { impl State {
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
if !self.valid_bits.has(ValidMask::POSITION_X) { if !self.valid_bits.has(ValidMask::POSITION_X) {
eprintln!("X Pos not valid");
return 0.0; return 0.0;
} }
@@ -79,6 +80,7 @@ impl State {
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
if !self.valid_bits.has(ValidMask::POSITION_Y) { if !self.valid_bits.has(ValidMask::POSITION_Y) {
eprintln!("Y Pos not valid");
return 0.0; return 0.0;
} }
@@ -87,6 +89,7 @@ impl State {
pub fn pressure(&self) -> u32 { pub fn pressure(&self) -> u32 {
if !self.valid_bits.has(ValidMask::PRESSURE) { if !self.valid_bits.has(ValidMask::PRESSURE) {
eprintln!("Pressure not valid");
return 0; return 0;
} }
@@ -94,6 +97,7 @@ impl State {
} }
pub fn pen_buttons(&self) -> u32 { pub fn pen_buttons(&self) -> u32 {
if !self.valid_bits.has(ValidMask::PEN_BUTTONS) { if !self.valid_bits.has(ValidMask::PEN_BUTTONS) {
eprintln!("Pen buttons not valid");
return 0; return 0;
} }
@@ -101,6 +105,7 @@ impl State {
} }
pub fn aux_buttons(&self) -> u32 { pub fn aux_buttons(&self) -> u32 {
if !self.valid_bits.has(ValidMask::AUX_BUTTONS) { if !self.valid_bits.has(ValidMask::AUX_BUTTONS) {
eprintln!("Aux buttons not valid");
return 0; return 0;
} }
@@ -108,6 +113,7 @@ impl State {
} }
pub fn hover_distance(&self) -> u32 { pub fn hover_distance(&self) -> u32 {
if !self.valid_bits.has(ValidMask::HOVER_DISTANCE) { if !self.valid_bits.has(ValidMask::HOVER_DISTANCE) {
eprintln!("Hover distance not valid");
return 0; return 0;
} }
@@ -116,6 +122,7 @@ impl State {
pub fn pen_is_near_surface(&self) -> bool { pub fn pen_is_near_surface(&self) -> bool {
if !self.valid_bits.has(ValidMask::PEN_IS_NEAR_SURFACE) { if !self.valid_bits.has(ValidMask::PEN_IS_NEAR_SURFACE) {
eprintln!("Pen is near surface not valid");
return true; return true;
} }

View File

@@ -4,11 +4,11 @@ use std::{collections::HashMap, fs::read_to_string, path::PathBuf};
#[allow(unused)] #[allow(unused)]
pub(crate) struct OtdIpcMetadata { pub(crate) struct OtdIpcMetadata {
pub id: String, pub id: String,
pub name: String,
pub semver: String,
pub debug_version: String,
pub homepage: String,
pub socket: PathBuf, pub socket: PathBuf,
pub human_readable_name: String,
pub human_readable_version: String,
pub homepage: String,
pub compatibility_version: String,
} }
impl OtdIpcMetadata { impl OtdIpcMetadata {
@@ -43,11 +43,11 @@ impl OtdIpcMetadata {
Ok(Self { Ok(Self {
id: data["ID"].clone(), id: data["ID"].clone(),
name: data["NAME"].clone(),
semver: data["SEMVER"].clone(),
debug_version: data["DEBUG_VERSION"].clone(),
homepage: data["HOMEPAGE"].clone(),
socket: data["SOCKET"].clone().into(), socket: data["SOCKET"].clone().into(),
human_readable_name: data["HUMAN_READABLE_NAME"].clone(),
human_readable_version: data["HUMAN_READABLE_VERSION"].clone(),
homepage: data["HOMEPAGE"].clone(),
compatibility_version: data["COMPATIBILITY_VERSION"].clone(),
}) })
} }
} }