1use std::collections::VecDeque;
2use std::fmt;
3use std::sync::atomic::{AtomicBool, Ordering};
4use std::sync::{Arc, Condvar, Mutex, MutexGuard, OnceLock, PoisonError, Weak};
5use std::time::{Duration, Instant};
6
7use crate::capability::{Action, Button};
8use crate::key::{Key, MediaKey};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum Event {
13 #[non_exhaustive]
15 Button {
16 button: Button,
17 pressed: bool,
18 at: Stamp,
19 },
20 #[non_exhaustive]
23 Key {
24 key: Key,
25 pressed: bool,
26 at: Stamp,
27 },
28 #[non_exhaustive]
30 Media {
31 key: MediaKey,
32 pressed: bool,
33 at: Stamp,
34 },
35 #[non_exhaustive]
37 Motion {
38 dx: i32,
39 dy: i32,
40 wheel: i32,
41 pan: i32,
42 at: Stamp,
43 },
44 #[non_exhaustive]
50 Dropped {
51 count: u64,
52 source: DropSource,
53 },
54 SessionReset,
58 #[non_exhaustive]
62 Rejected {
63 action: Action,
64 count: u64,
65 },
66 Disconnected,
67 Reconnected,
72 Changed,
78}
79
80impl Event {
83 pub fn button(button: Button, pressed: bool, at: Stamp) -> Self {
84 Self::Button {
85 button,
86 pressed,
87 at,
88 }
89 }
90
91 pub fn key(key: Key, pressed: bool, at: Stamp) -> Self {
92 Self::Key { key, pressed, at }
93 }
94
95 pub fn media(key: MediaKey, pressed: bool, at: Stamp) -> Self {
96 Self::Media { key, pressed, at }
97 }
98
99 pub fn motion(dx: i32, dy: i32, wheel: i32, pan: i32, at: Stamp) -> Self {
100 Self::Motion {
101 dx,
102 dy,
103 wheel,
104 pan,
105 at,
106 }
107 }
108
109 pub fn dropped(count: u64, source: DropSource) -> Self {
110 Self::Dropped { count, source }
111 }
112
113 pub fn rejected(action: Action, count: u64) -> Self {
114 Self::Rejected { action, count }
115 }
116}
117
118#[cfg(feature = "mock")]
119impl Event {
120 pub fn examples(at: Stamp) -> Vec<Event> {
123 let stamped = at.with_box_time(BoxTime::new(4_000_000_000, Clock::MediusDeviceChip));
124 vec![
125 Event::button(Button::Side2, true, stamped),
126 Event::key(Key::LEFT_SHIFT, false, stamped),
127 Event::media(MediaKey::VOLUME_DOWN, true, stamped),
128 Event::motion(-3, 7, -1, 2, stamped),
129 Event::dropped(12, DropSource::Device),
130 Event::dropped(3, DropSource::Host),
131 Event::SessionReset,
132 Event::rejected(Action::Move, 4),
133 Event::Disconnected,
134 Event::Reconnected,
135 Event::Changed,
136 ]
137 }
138}
139
140#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
143pub struct EventKinds {
144 buttons: bool,
145 motion: bool,
146 keys: bool,
147 media: bool,
148}
149
150impl EventKinds {
151 pub const NONE: Self = Self {
152 buttons: false,
153 motion: false,
154 keys: false,
155 media: false,
156 };
157 pub const BUTTONS: Self = Self {
158 buttons: true,
159 ..Self::NONE
160 };
161 pub const MOTION: Self = Self {
162 motion: true,
163 ..Self::NONE
164 };
165 pub const KEYS: Self = Self {
166 keys: true,
167 ..Self::NONE
168 };
169 pub const MEDIA: Self = Self {
170 media: true,
171 ..Self::NONE
172 };
173 pub const ALL: Self = Self {
175 buttons: true,
176 motion: true,
177 keys: true,
178 media: true,
179 };
180
181 pub fn contains(self, other: Self) -> bool {
182 self & other == other
183 }
184
185 pub fn is_empty(self) -> bool {
186 self == Self::NONE
187 }
188
189 pub(crate) fn of(event: &Event) -> Option<Self> {
191 match event {
192 Event::Button { .. } => Some(Self::BUTTONS),
193 Event::Motion { .. } => Some(Self::MOTION),
194 Event::Key { .. } => Some(Self::KEYS),
195 Event::Media { .. } => Some(Self::MEDIA),
196 Event::Rejected { action, .. } => Self::of_action(*action),
197 _ => None,
198 }
199 }
200
201 pub(crate) fn of_action(action: Action) -> Option<Self> {
203 match action {
204 Action::ButtonEvents => Some(Self::BUTTONS),
205 Action::MotionEvents => Some(Self::MOTION),
206 Action::KeyEvents => Some(Self::KEYS),
207 Action::MediaEvents => Some(Self::MEDIA),
208 _ => None,
209 }
210 }
211
212 pub(crate) fn to_input(self) -> crate::backend::InputKinds {
213 crate::backend::InputKinds {
214 buttons: self.buttons,
215 motion: self.motion,
216 keys: self.keys,
217 media: self.media,
218 }
219 }
220
221 pub(crate) fn from_input(kinds: crate::backend::InputKinds) -> Self {
222 Self {
223 buttons: kinds.buttons,
224 motion: kinds.motion,
225 keys: kinds.keys,
226 media: kinds.media,
227 }
228 }
229
230 pub(crate) fn each(self) -> impl Iterator<Item = (Self, Action)> {
232 [
233 (Self::BUTTONS, Action::ButtonEvents),
234 (Self::MOTION, Action::MotionEvents),
235 (Self::KEYS, Action::KeyEvents),
236 (Self::MEDIA, Action::MediaEvents),
237 ]
238 .into_iter()
239 .filter(move |(kind, _)| self.contains(*kind))
240 }
241}
242
243impl std::ops::BitOr for EventKinds {
244 type Output = Self;
245
246 fn bitor(self, other: Self) -> Self {
247 Self {
248 buttons: self.buttons || other.buttons,
249 motion: self.motion || other.motion,
250 keys: self.keys || other.keys,
251 media: self.media || other.media,
252 }
253 }
254}
255
256impl std::ops::BitAnd for EventKinds {
257 type Output = Self;
258
259 fn bitand(self, other: Self) -> Self {
260 Self {
261 buttons: self.buttons && other.buttons,
262 motion: self.motion && other.motion,
263 keys: self.keys && other.keys,
264 media: self.media && other.media,
265 }
266 }
267}
268
269#[derive(Clone, Copy, Debug, PartialEq, Eq)]
270#[non_exhaustive]
271pub enum DropSource {
272 Device,
274 Host,
276}
277
278#[derive(Clone, Copy, Debug, PartialEq, Eq)]
279#[non_exhaustive]
280pub struct Stamp {
281 pub arrived: Instant,
285 pub since_open: Duration,
287 pub box_time: Option<BoxTime>,
288 pub received: Instant,
293 pub received_since_open: Duration,
295 pub received_qpc: Option<i64>,
298}
299
300impl Stamp {
301 pub fn new(arrived: Instant, since_open: Duration) -> Self {
304 Self {
305 arrived,
306 since_open,
307 box_time: None,
308 received: arrived,
309 received_since_open: since_open,
310 received_qpc: None,
311 }
312 }
313
314 pub fn with_box_time(mut self, box_time: BoxTime) -> Self {
315 self.box_time = Some(box_time);
316 self
317 }
318
319 pub fn arrived_ns(&self) -> u64 {
322 instant_ns(self.arrived)
323 }
324
325 pub fn received_ns(&self) -> u64 {
327 instant_ns(self.received)
328 }
329
330 pub fn with_received(mut self, received: Instant, qpc: Option<i64>) -> Self {
332 self.received = received;
333 self.received_since_open = if received >= self.arrived {
334 self.since_open
335 .saturating_add(received.duration_since(self.arrived))
336 } else {
337 self.since_open
338 .saturating_sub(self.arrived.duration_since(received))
339 };
340 self.received_qpc = qpc;
341 self
342 }
343}
344
345pub fn monotonic_ns() -> u64 {
349 crate::transport::monotonic_ns()
350}
351
352fn instant_ns(at: Instant) -> u64 {
355 let (anchor, anchor_ns) = anchor();
356 if at >= anchor {
357 anchor_ns.saturating_add(nanos(at.duration_since(anchor)))
358 } else {
359 anchor_ns.saturating_sub(nanos(anchor.duration_since(at)))
360 }
361}
362
363fn anchor() -> (Instant, u64) {
365 static ANCHOR: OnceLock<(Instant, u64)> = OnceLock::new();
366 *ANCHOR.get_or_init(|| {
367 let mut best = (u64::MAX, Instant::now(), 0);
368 for _ in 0..16 {
369 let before = monotonic_ns();
370 let at = Instant::now();
371 let after = monotonic_ns();
372 let bracket = after.saturating_sub(before);
373 if bracket < best.0 {
374 best = (bracket, at, before + bracket / 2);
375 }
376 }
377 (best.1, best.2)
378 })
379}
380
381fn nanos(duration: Duration) -> u64 {
382 u64::try_from(duration.as_nanos()).unwrap_or(u64::MAX)
383}
384
385#[derive(Clone, Copy, Debug, PartialEq, Eq)]
386#[non_exhaustive]
387pub struct BoxTime {
388 pub micros: u32,
389 pub clock: Clock,
390}
391
392impl BoxTime {
393 pub fn new(micros: u32, clock: Clock) -> Self {
394 Self { micros, clock }
395 }
396}
397
398#[derive(Clone, Copy, Debug, PartialEq, Eq)]
400#[non_exhaustive]
401pub enum Clock {
402 MediusHostChip,
403 MediusDeviceChip,
404}
405
406impl Clock {
407 pub fn wraps_after(self) -> Duration {
409 Duration::from_micros(u64::from(u32::MAX) + 1)
410 }
411}
412
413#[derive(Clone, Copy, Debug, PartialEq, Eq)]
414pub struct Closed;
415
416impl fmt::Display for Closed {
417 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
418 f.write_str("the device is gone, no more events will come")
419 }
420}
421
422impl std::error::Error for Closed {}
423
424#[derive(Clone, Copy, Debug, PartialEq, Eq)]
425pub enum RecvTimeoutError {
426 Timeout,
427 Closed,
428}
429
430impl fmt::Display for RecvTimeoutError {
431 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
432 match self {
433 Self::Timeout => f.write_str("no event came in time"),
434 Self::Closed => Closed.fmt(f),
435 }
436 }
437}
438
439impl std::error::Error for RecvTimeoutError {}
440
441#[derive(Clone, Copy, Debug, PartialEq, Eq)]
442pub enum TryRecvError {
443 Empty,
444 Closed,
445}
446
447impl fmt::Display for TryRecvError {
448 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
449 match self {
450 Self::Empty => f.write_str("no event is waiting"),
451 Self::Closed => Closed.fmt(f),
452 }
453 }
454}
455
456impl std::error::Error for TryRecvError {}
457
458pub(crate) const QUEUE_CAPACITY: usize = 1024;
459
460#[derive(Debug)]
461struct State {
462 events: VecDeque<Event>,
463 closed: bool,
464}
465
466#[derive(Debug)]
470pub(crate) struct Queue {
471 state: Mutex<State>,
472 ready: Condvar,
473 capacity: usize,
474}
475
476impl Queue {
477 pub(crate) fn new(capacity: usize) -> Self {
478 Self {
479 state: Mutex::new(State {
480 events: VecDeque::new(),
481 closed: false,
482 }),
483 ready: Condvar::new(),
484 capacity: capacity.max(2),
485 }
486 }
487
488 fn lock(&self) -> MutexGuard<'_, State> {
489 self.state.lock().unwrap_or_else(PoisonError::into_inner)
490 }
491
492 pub(crate) fn push(&self, event: Event) {
493 let mut state = self.lock();
494 if state.closed {
495 return;
496 }
497 let events = &mut state.events;
498 if matches!(event, Event::Changed) && events.iter().any(|e| matches!(e, Event::Changed)) {
500 return;
501 }
502 if let Event::Rejected { action, count } = event {
503 let unread = events.iter_mut().find_map(|queued| match queued {
505 Event::Rejected {
506 action: queued_action,
507 count: queued_count,
508 } if *queued_action == action => Some(queued_count),
509 _ => None,
510 });
511 if let Some(queued_count) = unread {
512 *queued_count += count;
513 return;
514 }
515 }
516 if events.len() >= self.capacity {
517 let counted = matches!(
518 events.front(),
519 Some(Event::Dropped {
520 source: DropSource::Host,
521 ..
522 })
523 );
524 if !counted {
525 events.push_front(Event::Dropped {
526 count: 0,
527 source: DropSource::Host,
528 });
529 }
530 let motion_queued = events.iter().any(|e| matches!(e, Event::Motion { .. }));
531 if matches!(event, Event::Motion { .. }) && !motion_queued {
532 let mut lost = 1;
536 if events.len() > self.capacity
537 && let Some(oldest) = events.iter().skip(1).position(|e| {
538 matches!(
539 e,
540 Event::Button { .. } | Event::Key { .. } | Event::Media { .. }
541 )
542 })
543 {
544 events.remove(oldest + 1);
545 lost += 1;
546 }
547 if let Some(Event::Dropped { count, .. }) = events.front_mut() {
548 *count += lost;
549 }
550 drop(state);
551 self.ready.notify_all();
552 return;
553 }
554 while events.len() >= self.capacity {
555 let motion = events
558 .iter()
559 .skip(1)
560 .position(|e| matches!(e, Event::Motion { .. }));
561 let edge = || {
562 events.iter().skip(1).position(|e| {
563 matches!(
564 e,
565 Event::Button { .. } | Event::Key { .. } | Event::Media { .. }
566 )
567 })
568 };
569 let Some(oldest) = motion.or_else(edge) else {
570 break;
571 };
572 events.remove(oldest + 1);
573 if let Some(Event::Dropped { count, .. }) = events.front_mut() {
574 *count += 1;
575 }
576 }
577 }
578 events.push_back(event);
579 drop(state);
580 self.ready.notify_all();
581 }
582
583 pub(crate) fn close(&self) {
584 self.lock().closed = true;
585 self.ready.notify_all();
586 }
587
588 fn close_now(&self) {
590 let mut state = self.lock();
591 state.events.clear();
592 state.closed = true;
593 drop(state);
594 self.ready.notify_all();
595 }
596
597 fn try_pop(state: &mut State) -> Result<Event, TryRecvError> {
598 match state.events.pop_front() {
599 Some(event) => Ok(event),
600 None if state.closed => Err(TryRecvError::Closed),
601 None => Err(TryRecvError::Empty),
602 }
603 }
604}
605
606pub(crate) trait Listeners: Send + Sync {
608 fn receiver_dropped(&self, id: u64);
609}
610
611pub struct Events {
614 queue: Arc<Queue>,
615 listeners: Weak<dyn Listeners>,
616 id: u64,
617 gone: AtomicBool,
619}
620
621impl Events {
622 pub(crate) fn new(queue: Arc<Queue>, listeners: Weak<dyn Listeners>, id: u64) -> Self {
623 Self {
624 queue,
625 listeners,
626 id,
627 gone: AtomicBool::new(false),
628 }
629 }
630
631 pub fn close(&self) {
635 self.queue.close_now();
637 self.leave();
638 }
639
640 fn leave(&self) {
641 if !self.gone.swap(true, Ordering::AcqRel)
642 && let Some(listeners) = self.listeners.upgrade()
643 {
644 listeners.receiver_dropped(self.id);
645 }
646 }
647
648 pub fn recv(&self) -> Result<Event, Closed> {
649 let mut state = self.queue.lock();
650 loop {
651 match Queue::try_pop(&mut state) {
652 Ok(event) => return Ok(event),
653 Err(TryRecvError::Closed) => return Err(Closed),
654 Err(TryRecvError::Empty) => {
655 state = self
656 .queue
657 .ready
658 .wait(state)
659 .unwrap_or_else(PoisonError::into_inner);
660 }
661 }
662 }
663 }
664
665 pub fn recv_timeout(&self, timeout: Duration) -> Result<Event, RecvTimeoutError> {
666 let Some(deadline) = Instant::now().checked_add(timeout) else {
668 return self.recv().map_err(|Closed| RecvTimeoutError::Closed);
669 };
670 let mut state = self.queue.lock();
671 loop {
672 match Queue::try_pop(&mut state) {
673 Ok(event) => return Ok(event),
674 Err(TryRecvError::Closed) => return Err(RecvTimeoutError::Closed),
675 Err(TryRecvError::Empty) => {
676 let left = deadline.saturating_duration_since(Instant::now());
677 if left.is_zero() {
678 return Err(RecvTimeoutError::Timeout);
679 }
680 state = self
681 .queue
682 .ready
683 .wait_timeout(state, left)
684 .unwrap_or_else(PoisonError::into_inner)
685 .0;
686 }
687 }
688 }
689 }
690
691 pub fn try_recv(&self) -> Result<Event, TryRecvError> {
692 Queue::try_pop(&mut self.queue.lock())
693 }
694}
695
696impl Iterator for Events {
697 type Item = Event;
698
699 fn next(&mut self) -> Option<Event> {
700 self.recv().ok()
701 }
702}
703
704impl Drop for Events {
705 fn drop(&mut self) {
706 self.leave();
707 }
708}
709
710impl fmt::Debug for Events {
711 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
712 f.debug_struct("Events").finish_non_exhaustive()
713 }
714}
715
716impl std::ops::Not for EventKinds {
717 type Output = Self;
718
719 fn not(self) -> Self {
720 Self {
721 buttons: !self.buttons,
722 motion: !self.motion,
723 keys: !self.keys,
724 media: !self.media,
725 }
726 }
727}
728
729#[cfg(test)]
730mod tests;