1use std::collections::VecDeque;
2use std::fmt;
3use std::sync::{Arc, Condvar, Mutex, MutexGuard, PoisonError, Weak};
4use std::time::{Duration, Instant};
5
6use crate::capability::{Action, Button};
7use crate::key::{Key, MediaKey};
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10#[non_exhaustive]
11pub enum Event {
12 #[non_exhaustive]
14 Button {
15 button: Button,
16 pressed: bool,
17 at: Stamp,
18 },
19 #[non_exhaustive]
22 Key {
23 key: Key,
24 pressed: bool,
25 at: Stamp,
26 },
27 #[non_exhaustive]
29 Media {
30 key: MediaKey,
31 pressed: bool,
32 at: Stamp,
33 },
34 #[non_exhaustive]
36 Motion {
37 dx: i32,
38 dy: i32,
39 wheel: i32,
40 pan: i32,
41 at: Stamp,
42 },
43 #[non_exhaustive]
49 Dropped {
50 count: u64,
51 source: DropSource,
52 },
53 SessionReset,
57 #[non_exhaustive]
61 Rejected {
62 action: Action,
63 count: u64,
64 },
65 Disconnected,
66 Reconnected,
71}
72
73impl Event {
76 pub fn button(button: Button, pressed: bool, at: Stamp) -> Self {
77 Self::Button {
78 button,
79 pressed,
80 at,
81 }
82 }
83
84 pub fn key(key: Key, pressed: bool, at: Stamp) -> Self {
85 Self::Key { key, pressed, at }
86 }
87
88 pub fn media(key: MediaKey, pressed: bool, at: Stamp) -> Self {
89 Self::Media { key, pressed, at }
90 }
91
92 pub fn motion(dx: i32, dy: i32, wheel: i32, pan: i32, at: Stamp) -> Self {
93 Self::Motion {
94 dx,
95 dy,
96 wheel,
97 pan,
98 at,
99 }
100 }
101
102 pub fn dropped(count: u64, source: DropSource) -> Self {
103 Self::Dropped { count, source }
104 }
105
106 pub fn rejected(action: Action, count: u64) -> Self {
107 Self::Rejected { action, count }
108 }
109}
110
111#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
114pub struct EventKinds {
115 buttons: bool,
116 motion: bool,
117 keys: bool,
118 media: bool,
119}
120
121impl EventKinds {
122 pub const NONE: Self = Self {
123 buttons: false,
124 motion: false,
125 keys: false,
126 media: false,
127 };
128 pub const BUTTONS: Self = Self {
129 buttons: true,
130 ..Self::NONE
131 };
132 pub const MOTION: Self = Self {
133 motion: true,
134 ..Self::NONE
135 };
136 pub const KEYS: Self = Self {
137 keys: true,
138 ..Self::NONE
139 };
140 pub const MEDIA: Self = Self {
141 media: true,
142 ..Self::NONE
143 };
144 pub const ALL: Self = Self {
146 buttons: true,
147 motion: true,
148 keys: true,
149 media: true,
150 };
151
152 pub fn contains(self, other: Self) -> bool {
153 self & other == other
154 }
155
156 pub fn is_empty(self) -> bool {
157 self == Self::NONE
158 }
159
160 pub(crate) fn of(event: &Event) -> Option<Self> {
162 match event {
163 Event::Button { .. } => Some(Self::BUTTONS),
164 Event::Motion { .. } => Some(Self::MOTION),
165 Event::Key { .. } => Some(Self::KEYS),
166 Event::Media { .. } => Some(Self::MEDIA),
167 Event::Rejected { action, .. } => Self::of_action(*action),
168 _ => None,
169 }
170 }
171
172 pub(crate) fn of_action(action: Action) -> Option<Self> {
174 match action {
175 Action::ButtonEvents => Some(Self::BUTTONS),
176 Action::MotionEvents => Some(Self::MOTION),
177 Action::KeyEvents => Some(Self::KEYS),
178 Action::MediaEvents => Some(Self::MEDIA),
179 _ => None,
180 }
181 }
182
183 pub(crate) fn to_input(self) -> crate::backend::InputKinds {
184 crate::backend::InputKinds {
185 buttons: self.buttons,
186 motion: self.motion,
187 keys: self.keys,
188 media: self.media,
189 }
190 }
191
192 pub(crate) fn from_input(kinds: crate::backend::InputKinds) -> Self {
193 Self {
194 buttons: kinds.buttons,
195 motion: kinds.motion,
196 keys: kinds.keys,
197 media: kinds.media,
198 }
199 }
200
201 pub(crate) fn each(self) -> impl Iterator<Item = (Self, Action)> {
203 [
204 (Self::BUTTONS, Action::ButtonEvents),
205 (Self::MOTION, Action::MotionEvents),
206 (Self::KEYS, Action::KeyEvents),
207 (Self::MEDIA, Action::MediaEvents),
208 ]
209 .into_iter()
210 .filter(move |(kind, _)| self.contains(*kind))
211 }
212}
213
214impl std::ops::BitOr for EventKinds {
215 type Output = Self;
216
217 fn bitor(self, other: Self) -> Self {
218 Self {
219 buttons: self.buttons || other.buttons,
220 motion: self.motion || other.motion,
221 keys: self.keys || other.keys,
222 media: self.media || other.media,
223 }
224 }
225}
226
227impl std::ops::BitAnd for EventKinds {
228 type Output = Self;
229
230 fn bitand(self, other: Self) -> Self {
231 Self {
232 buttons: self.buttons && other.buttons,
233 motion: self.motion && other.motion,
234 keys: self.keys && other.keys,
235 media: self.media && other.media,
236 }
237 }
238}
239
240#[derive(Clone, Copy, Debug, PartialEq, Eq)]
241#[non_exhaustive]
242pub enum DropSource {
243 Device,
245 Host,
247}
248
249#[derive(Clone, Copy, Debug, PartialEq, Eq)]
250#[non_exhaustive]
251pub struct Stamp {
252 pub arrived: Instant,
256 pub since_open: Duration,
258 pub box_time: Option<BoxTime>,
259 pub received: Instant,
264 pub received_since_open: Duration,
266 pub received_qpc: Option<i64>,
269}
270
271impl Stamp {
272 pub fn new(arrived: Instant, since_open: Duration) -> Self {
275 Self {
276 arrived,
277 since_open,
278 box_time: None,
279 received: arrived,
280 received_since_open: since_open,
281 received_qpc: None,
282 }
283 }
284
285 pub fn with_box_time(mut self, box_time: BoxTime) -> Self {
286 self.box_time = Some(box_time);
287 self
288 }
289
290 pub fn with_received(mut self, received: Instant, qpc: Option<i64>) -> Self {
292 self.received = received;
293 self.received_since_open = if received >= self.arrived {
294 self.since_open + received.duration_since(self.arrived)
295 } else {
296 self.since_open
297 .saturating_sub(self.arrived.duration_since(received))
298 };
299 self.received_qpc = qpc;
300 self
301 }
302}
303
304#[derive(Clone, Copy, Debug, PartialEq, Eq)]
305#[non_exhaustive]
306pub struct BoxTime {
307 pub micros: u32,
308 pub clock: Clock,
309}
310
311impl BoxTime {
312 pub fn new(micros: u32, clock: Clock) -> Self {
313 Self { micros, clock }
314 }
315}
316
317#[derive(Clone, Copy, Debug, PartialEq, Eq)]
319#[non_exhaustive]
320pub enum Clock {
321 MediusHostChip,
322 MediusDeviceChip,
323}
324
325impl Clock {
326 pub fn wraps_after(self) -> Duration {
328 Duration::from_micros(u64::from(u32::MAX) + 1)
329 }
330}
331
332#[derive(Clone, Copy, Debug, PartialEq, Eq)]
333pub struct Closed;
334
335impl fmt::Display for Closed {
336 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337 f.write_str("the device is gone, no more events will come")
338 }
339}
340
341impl std::error::Error for Closed {}
342
343#[derive(Clone, Copy, Debug, PartialEq, Eq)]
344pub enum RecvTimeoutError {
345 Timeout,
346 Closed,
347}
348
349impl fmt::Display for RecvTimeoutError {
350 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
351 match self {
352 Self::Timeout => f.write_str("no event came in time"),
353 Self::Closed => Closed.fmt(f),
354 }
355 }
356}
357
358impl std::error::Error for RecvTimeoutError {}
359
360#[derive(Clone, Copy, Debug, PartialEq, Eq)]
361pub enum TryRecvError {
362 Empty,
363 Closed,
364}
365
366impl fmt::Display for TryRecvError {
367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
368 match self {
369 Self::Empty => f.write_str("no event is waiting"),
370 Self::Closed => Closed.fmt(f),
371 }
372 }
373}
374
375impl std::error::Error for TryRecvError {}
376
377pub(crate) const QUEUE_CAPACITY: usize = 1024;
378
379#[derive(Debug)]
380struct State {
381 events: VecDeque<Event>,
382 closed: bool,
383}
384
385#[derive(Debug)]
389pub(crate) struct Queue {
390 state: Mutex<State>,
391 ready: Condvar,
392 capacity: usize,
393}
394
395impl Queue {
396 pub(crate) fn new(capacity: usize) -> Self {
397 Self {
398 state: Mutex::new(State {
399 events: VecDeque::new(),
400 closed: false,
401 }),
402 ready: Condvar::new(),
403 capacity: capacity.max(2),
404 }
405 }
406
407 fn lock(&self) -> MutexGuard<'_, State> {
408 self.state.lock().unwrap_or_else(PoisonError::into_inner)
409 }
410
411 pub(crate) fn push(&self, event: Event) {
412 let mut state = self.lock();
413 if state.closed {
414 return;
415 }
416 let events = &mut state.events;
417 if let Event::Rejected { action, count } = event {
418 let unread = events.iter_mut().find_map(|queued| match queued {
420 Event::Rejected {
421 action: queued_action,
422 count: queued_count,
423 } if *queued_action == action => Some(queued_count),
424 _ => None,
425 });
426 if let Some(queued_count) = unread {
427 *queued_count += count;
428 return;
429 }
430 }
431 if events.len() >= self.capacity {
432 let counted = matches!(
433 events.front(),
434 Some(Event::Dropped {
435 source: DropSource::Host,
436 ..
437 })
438 );
439 if !counted {
440 events.push_front(Event::Dropped {
441 count: 0,
442 source: DropSource::Host,
443 });
444 }
445 let motion_queued = events.iter().any(|e| matches!(e, Event::Motion { .. }));
446 if matches!(event, Event::Motion { .. }) && !motion_queued {
447 let mut lost = 1;
451 if events.len() > self.capacity
452 && let Some(oldest) = events.iter().skip(1).position(|e| {
453 matches!(
454 e,
455 Event::Button { .. } | Event::Key { .. } | Event::Media { .. }
456 )
457 })
458 {
459 events.remove(oldest + 1);
460 lost += 1;
461 }
462 if let Some(Event::Dropped { count, .. }) = events.front_mut() {
463 *count += lost;
464 }
465 drop(state);
466 self.ready.notify_all();
467 return;
468 }
469 while events.len() >= self.capacity {
470 let motion = events
473 .iter()
474 .skip(1)
475 .position(|e| matches!(e, Event::Motion { .. }));
476 let edge = || {
477 events.iter().skip(1).position(|e| {
478 matches!(
479 e,
480 Event::Button { .. } | Event::Key { .. } | Event::Media { .. }
481 )
482 })
483 };
484 let Some(oldest) = motion.or_else(edge) else {
485 break;
486 };
487 events.remove(oldest + 1);
488 if let Some(Event::Dropped { count, .. }) = events.front_mut() {
489 *count += 1;
490 }
491 }
492 }
493 events.push_back(event);
494 drop(state);
495 self.ready.notify_all();
496 }
497
498 pub(crate) fn close(&self) {
499 self.lock().closed = true;
500 self.ready.notify_all();
501 }
502
503 fn try_pop(state: &mut State) -> Result<Event, TryRecvError> {
504 match state.events.pop_front() {
505 Some(event) => Ok(event),
506 None if state.closed => Err(TryRecvError::Closed),
507 None => Err(TryRecvError::Empty),
508 }
509 }
510}
511
512pub(crate) trait Listeners: Send + Sync {
514 fn receiver_dropped(&self, id: u64);
515}
516
517pub struct Events {
519 queue: Arc<Queue>,
520 listeners: Weak<dyn Listeners>,
521 id: u64,
522}
523
524impl Events {
525 pub(crate) fn new(queue: Arc<Queue>, listeners: Weak<dyn Listeners>, id: u64) -> Self {
526 Self {
527 queue,
528 listeners,
529 id,
530 }
531 }
532
533 pub fn recv(&self) -> Result<Event, Closed> {
534 let mut state = self.queue.lock();
535 loop {
536 match Queue::try_pop(&mut state) {
537 Ok(event) => return Ok(event),
538 Err(TryRecvError::Closed) => return Err(Closed),
539 Err(TryRecvError::Empty) => {
540 state = self
541 .queue
542 .ready
543 .wait(state)
544 .unwrap_or_else(PoisonError::into_inner);
545 }
546 }
547 }
548 }
549
550 pub fn recv_timeout(&self, timeout: Duration) -> Result<Event, RecvTimeoutError> {
551 let deadline = Instant::now() + timeout;
552 let mut state = self.queue.lock();
553 loop {
554 match Queue::try_pop(&mut state) {
555 Ok(event) => return Ok(event),
556 Err(TryRecvError::Closed) => return Err(RecvTimeoutError::Closed),
557 Err(TryRecvError::Empty) => {
558 let left = deadline.saturating_duration_since(Instant::now());
559 if left.is_zero() {
560 return Err(RecvTimeoutError::Timeout);
561 }
562 state = self
563 .queue
564 .ready
565 .wait_timeout(state, left)
566 .unwrap_or_else(PoisonError::into_inner)
567 .0;
568 }
569 }
570 }
571 }
572
573 pub fn try_recv(&self) -> Result<Event, TryRecvError> {
574 Queue::try_pop(&mut self.queue.lock())
575 }
576}
577
578impl Iterator for Events {
579 type Item = Event;
580
581 fn next(&mut self) -> Option<Event> {
582 self.recv().ok()
583 }
584}
585
586impl Drop for Events {
587 fn drop(&mut self) {
588 if let Some(listeners) = self.listeners.upgrade() {
589 listeners.receiver_dropped(self.id);
590 }
591 }
592}
593
594impl fmt::Debug for Events {
595 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
596 f.debug_struct("Events").finish_non_exhaustive()
597 }
598}
599
600impl std::ops::Not for EventKinds {
601 type Output = Self;
602
603 fn not(self) -> Self {
604 Self {
605 buttons: !self.buttons,
606 motion: !self.motion,
607 keys: !self.keys,
608 media: !self.media,
609 }
610 }
611}
612
613#[cfg(test)]
614mod tests;