1use std::{convert::TryFrom, error::Error as StdError, fmt, path::Path};
2
3use event_source::EventSourceError;
4
5mod event_source;
6mod raw_event;
7
8use {event_source::EventSource, raw_event::RawEvent};
9
10#[derive(Debug)]
11pub enum Error {
12 UnfinishedEvent(ToolKind, &'static str),
15
16 UnknownEventRead(UnknownEvent),
19
20 Io(std::io::Error),
21}
22
23impl fmt::Display for Error {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 match self {
26 Self::UnfinishedEvent(kind, missing) => {
27 write!(f, "Unfinished {} event. Missing {}", kind, missing)
28 }
29 Self::UnknownEventRead(err) => write!(f, "Read Unknown event: {}", err),
30
31 Self::Io(err) => write!(f, "Io error: {}", err),
32 }
33 }
34}
35
36impl StdError for Error {
37 fn source(&self) -> Option<&(dyn StdError + 'static)> {
38 match self {
39 Self::Io(ref inner) => inner.source(),
40 _ => None,
41 }
42 }
43}
44
45impl From<EventSourceError<UnknownEvent>> for Error {
46 fn from(err: EventSourceError<UnknownEvent>) -> Self {
47 match err {
48 EventSourceError::Io(io_err) => Self::Io(io_err),
49 EventSourceError::Parse(ev_err) => Self::UnknownEventRead(ev_err),
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
55pub enum ToolEvent {
56 Update(Tool),
57 Removed(ToolKind),
58}
59pub struct ToolEventSource {
63 event_source: EventSource<Event>,
64 state: Option<ToolBuilder>,
65}
66
67impl ToolEventSource {
68 pub async fn open(path: impl AsRef<Path>) -> Result<Self, Error> {
69 let event_source = event_source::EventSource::open(path)
70 .await
71 .map_err(Error::Io)?;
72
73 Ok(Self {
74 event_source,
75 state: None,
76 })
77 }
78
79 pub async fn next(&mut self) -> Result<ToolEvent, Error> {
80 let state = if let Some(ref mut state) = self.state {
89 state
90 } else {
91 loop {
93 match self.event_source.next().await? {
94 Event::ToolAdded(ToolKind::Pen) => {
95 let new_state = ToolBuilder::new(ToolKind::Pen);
96 break self.state.insert(new_state);
97 }
98
99 Event::ToolAdded(_kind) => {
100
101 }
103
104 _ev => {
105 }
107 }
108 }
109 };
110 loop {
111 match self.event_source.next().await? {
112 Event::Movement(mv) => match state {
113 ToolBuilder::Building(unfinished) => unfinished.apply_movement(mv),
114 ToolBuilder::Built(tool) => tool.apply_movement(mv),
115 },
116
117 Event::Sync => match state {
118 ToolBuilder::Building(unfinished) => {
119 let tool = unfinished.finish().expect("Could not finish tool");
120 *state = ToolBuilder::Built(tool);
121 return Ok(ToolEvent::Update(tool));
122 }
123
124 ToolBuilder::Built(tool) => {
125 return Ok(ToolEvent::Update(*tool));
126 }
127 },
128 Event::ToolRemoved(ToolKind::Pen) => {
129 self.state = None;
130 return Ok(ToolEvent::Removed(ToolKind::Pen));
131 }
132
133 Event::ToolRemoved(kind) => {
134 eprintln!("Ignoring non Pen ToolRemoved({:?})", kind);
136 }
137
138 Event::ToolAdded(kind) => {
139 eprintln!("Ignoring ToolAdded({:?})", kind);
140 }
141 }
142 }
143 }
144}
145
146enum ToolBuilder {
147 Built(Tool),
148 Building(UnfinishedTool),
149}
150
151impl ToolBuilder {
152 fn new(kind: ToolKind) -> Self {
153 Self::Building(UnfinishedTool::kind(kind))
154 }
155}
156
157struct UnfinishedTool {
158 kind: ToolKind,
159 x: Option<u32>,
160 y: Option<u32>,
161 tilt_x: Option<u32>,
162 tilt_y: Option<u32>,
163 pressure: Option<u32>,
164 distance: Option<u32>,
165}
166
167impl UnfinishedTool {
168 fn kind(kind: ToolKind) -> Self {
169 Self {
170 kind,
171 x: None,
172 y: None,
173 tilt_x: None,
174 tilt_y: None,
175 pressure: None,
176 distance: None,
177 }
178 }
179
180 fn apply_movement(&mut self, mv: Movement) {
181 match mv {
182 Movement::X(n) => self.x.replace(n),
183 Movement::Y(n) => self.y.replace(n),
184 Movement::TiltX(n) => self.tilt_x.replace(n),
185 Movement::TiltY(n) => self.tilt_y.replace(n),
186 Movement::Pressure(n) => self.pressure.replace(n),
187 Movement::Distance(n) => self.distance.replace(n),
188 };
189 }
190
191 fn finish(&mut self) -> Result<Tool, &'static str> {
193 let x = self.x.take().ok_or("X")?;
194 let y = self.y.take().ok_or("Y")?;
195
196 let height = match (self.pressure.take(), self.distance.take()) {
197 (Some(pressure), Some(distance)) => {
198 if distance < 10 && 700 < pressure {
199 Height::Touching(pressure)
200 } else {
201 Height::Distance(distance)
202 }
203 }
204 (Some(pressure), None) => Height::Touching(pressure),
205 (None, Some(distance)) => Height::Distance(distance),
206 (None, None) => Height::Missing,
207 };
208
209 Ok(Tool {
210 kind: self.kind,
211 point: Point(x, y),
212 tilt_x: self.tilt_x.take(),
213 tilt_y: self.tilt_y.take(),
214 height,
215 })
216 }
217}
218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
220pub struct Tool {
221 kind: ToolKind,
222 point: Point,
223 tilt_x: Option<u32>,
224 tilt_y: Option<u32>,
225 height: Height,
226}
227
228impl Tool {
229 fn apply_movement(&mut self, ev: Movement) {
230 match ev {
231 Movement::X(n) => self.point.0 = n,
232 Movement::Y(n) => self.point.1 = n,
233 Movement::TiltX(n) => self.tilt_x = Some(n),
234 Movement::TiltY(n) => self.tilt_y = Some(n),
235 Movement::Pressure(n) => self.height = Height::Touching(n),
236 Movement::Distance(n) => self.height = Height::Distance(n),
237 }
238 }
239}
240
241impl fmt::Display for Tool {
242 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
243 write!(
244 f,
245 "Tool at {}. tilt x{:?} y{:?}. {}",
246 self.point, self.tilt_x, self.tilt_y, self.height
247 )
248 }
249}
250
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
252pub enum Height {
253 Missing,
254 Distance(u32),
255 Touching(u32),
256}
257
258impl fmt::Display for Height {
259 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
260 match self {
261 Self::Missing => f.write_str("distance missing"),
262 Self::Distance(n) => write!(f, "distance{}", n),
263 Self::Touching(n) => write!(f, "touching{}", n),
264 }
265 }
266}
267
268#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
269pub struct Point(u32, u32);
270
271impl fmt::Display for Point {
272 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273 write!(f, "{},{}", self.0, self.1)
274 }
275}
276
277#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
278pub enum ToolKind {
279 Pen,
280 Rubber,
281 Touch,
282 Stylus,
283 Stylus2,
284}
285
286impl fmt::Display for ToolKind {
287 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288 match *self {
289 Self::Pen => f.write_str("Pen"),
290 Self::Rubber => f.write_str("Rubber"),
291 Self::Touch => f.write_str("Touch"),
292 Self::Stylus => f.write_str("Stylus"),
293 Self::Stylus2 => f.write_str("Stylus2"),
294 }
295 }
296}
297
298impl ToolKind {
299 fn from_code(code: u16) -> Option<ToolKind> {
300 match code {
301 320 => Some(Self::Pen),
302 321 => Some(Self::Rubber),
303 330 => Some(Self::Touch),
304 331 => Some(Self::Stylus),
305 332 => Some(Self::Stylus2),
306 _ => None,
307 }
308 }
309}
310
311#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
312pub enum Movement {
313 X(u32),
314 Y(u32),
315 TiltX(u32),
316 TiltY(u32),
317 Pressure(u32),
318 Distance(u32),
319}
320
321#[derive(Debug, Clone, Copy, PartialEq, Eq)]
340enum Event {
342 Sync,
343 ToolAdded(ToolKind),
344 ToolRemoved(ToolKind),
345 Movement(Movement),
346}
347
348impl TryFrom<RawEvent> for Event {
349 type Error = UnknownEvent;
350
351 fn try_from(ev: RawEvent) -> std::result::Result<Self, Self::Error> {
352 match (ev.typ, ev.code) {
353 (0, _) => Ok(Event::Sync),
354 (1, code) => {
355 let tool = ToolKind::from_code(code).ok_or(UnknownEvent::ToolCode(code))?;
359 match ev.value {
360 0 => Ok(Event::ToolRemoved(tool)),
361 1 => Ok(Event::ToolAdded(tool)),
362 v => Err(UnknownEvent::ToolValue(v)),
363 }
364 }
365
366 (3, 0) => Ok(Event::Movement(Movement::X(ev.value))),
367 (3, 1) => Ok(Event::Movement(Movement::Y(ev.value))),
368 (3, 24) => Ok(Event::Movement(Movement::Pressure(ev.value))),
369 (3, 25) => Ok(Event::Movement(Movement::Distance(ev.value))),
370 (3, 26) => Ok(Event::Movement(Movement::TiltX(ev.value))),
371 (3, 27) => Ok(Event::Movement(Movement::TiltY(ev.value))),
372
373 (3, _) => Err(UnknownEvent::MovementCode(ev.code)),
374
375 _ => Err(UnknownEvent::Type(ev)),
376 }
377 }
378}
379
380#[derive(Debug, Clone, Copy, PartialEq, Eq)]
383pub enum UnknownEvent {
384 ToolCode(u16),
385 ToolValue(u32),
386 MovementCode(u16),
387
388 Type(RawEvent),
389}
390
391impl std::error::Error for UnknownEvent {
392 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
393 None
394 }
395}
396
397impl fmt::Display for UnknownEvent {
398 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399 match self {
400 Self::ToolCode(code) => write!(f, "Unknown tool code`{:#04x}`", code),
401 Self::ToolValue(value) => write!(
402 f,
403 "Unexpected value for Tool event. Should be 0 or 1. Was:`{:#04x}`",
404 value
405 ),
406 Self::MovementCode(code) => write!(f, "Unknown movement code `{:#04x}`", code),
407 Self::Type(ev) => write!(
408 f,
409 "Unknown type: `{:#02x}`, code: `{:#04x}`, value: `{:#08x}`, ",
410 ev.typ, ev.code, ev.value
411 ),
412 }
413 }
414}