1use std::borrow::Cow;
2use std::collections::{HashMap, HashSet};
3use std::fmt;
4use std::sync::mpsc::{self, Receiver, Sender};
5use std::sync::{Arc, Mutex, MutexGuard, PoisonError, RwLock, Weak};
6use std::thread::{self, JoinHandle};
7use std::time::{Duration, Instant};
8
9use crate::backend::{
10 Backend, Command, Input, InputKinds, LOCKED, LockSlot, Sign, Signal, UNLOCKED, Usage,
11};
12use crate::capability::{Action, Axis, Button, Direction, Execution, Quirk, Snapshot};
13use crate::click::{Click, ClickTiming, Holds, Timing};
14use crate::error::{Error, Result};
15use crate::event::{
16 DropSource, Event, EventKinds, Events, Listeners, QUEUE_CAPACITY, Queue, Stamp,
17};
18use crate::key::{Key, MediaKey};
19
20const SHUTDOWN_DEADLINE: Duration = Duration::from_secs(1);
22
23pub struct Device {
26 core: Arc<Core>,
27 link: Mutex<Option<(JoinHandle<()>, Receiver<()>)>>,
28 closed: Mutex<bool>,
30}
31
32struct Core {
33 backend: Box<dyn Backend>,
34 snapshot: RwLock<Arc<Snapshot>>,
35 output: Mutex<Output>,
36 receivers: Mutex<Receivers>,
37 click_timing: ClickTiming,
38 holds: Mutex<Holds>,
39 opened: Instant,
40 signals: Sender<Signal>,
41 port: String,
42 refused: Mutex<HashMap<Action, Instant>>,
44}
45
46struct Output {
48 held: HashSet<Usage>,
49 unsure: HashSet<Usage>,
53 locked: HashMap<LockSlot, i16>,
56 link_up: bool,
57 closing: bool,
59 session: u64,
62}
63
64struct Receivers {
65 next_id: u64,
66 entries: Vec<Entry>,
67}
68
69struct Entry {
71 id: u64,
72 kinds: EventKinds,
73 queue: Weak<Queue>,
74}
75
76impl Receivers {
77 fn union(&self) -> EventKinds {
79 self.entries
80 .iter()
81 .fold(EventKinds::NONE, |all, entry| all | entry.kinds)
82 }
83}
84
85pub(crate) struct Start {
86 pub(crate) backend: Box<dyn Backend>,
87 pub(crate) snapshot: Snapshot,
88 pub(crate) signals: Sender<Signal>,
89 pub(crate) incoming: Receiver<Signal>,
90 pub(crate) click_timing: ClickTiming,
91 pub(crate) holds: Holds,
92 pub(crate) port: String,
93}
94
95impl Device {
96 pub(crate) fn start(start: Start) -> Result<Self> {
97 let core = Arc::new(Core {
98 snapshot: RwLock::new(prepare(start.snapshot, start.click_timing, &start.port)),
99 backend: start.backend,
100 output: Mutex::new(Output {
101 held: HashSet::new(),
102 locked: HashMap::new(),
103 unsure: HashSet::new(),
104 link_up: true,
105 closing: false,
106 session: 0,
107 }),
108 receivers: Mutex::new(Receivers {
109 next_id: 0,
110 entries: Vec::new(),
111 }),
112 click_timing: start.click_timing,
113 holds: Mutex::new(start.holds),
114 opened: Instant::now(),
115 signals: start.signals,
116 port: start.port.clone(),
117 refused: Mutex::new(HashMap::new()),
118 });
119 let link = spawn_link(Arc::downgrade(&core), start.incoming)?;
120 Ok(Self {
121 core,
122 link: Mutex::new(Some(link)),
123 closed: Mutex::new(false),
124 })
125 }
126
127 pub fn snapshot(&self) -> Arc<Snapshot> {
130 self.core.snapshot()
131 }
132
133 pub fn move_by(&self, dx: i16, dy: i16) -> Result<()> {
135 self.core
136 .run(Action::Move, Timing::Any, Command::Move(dx, dy))
137 }
138
139 pub fn move_now(&self, dx: i16, dy: i16) -> Result<()> {
141 self.core
142 .run(Action::MoveNow, Timing::Any, Command::MoveNow(dx, dy))
143 }
144
145 pub fn press(&self, button: Button) -> Result<()> {
146 self.core
147 .run(Action::Press, Timing::Any, Command::Press(button))
148 }
149
150 pub fn release(&self, button: Button) -> Result<()> {
151 self.core
152 .run(Action::Release, Timing::Any, Command::Release(button))
153 }
154
155 pub fn click(&self, button: Button) -> Result<()> {
157 self.click_with(button, Click::default())
158 }
159
160 pub fn click_with(&self, button: Button, click: Click) -> Result<()> {
161 self.core.tap(Usage::Button(button), click)
162 }
163
164 pub fn press_key(&self, key: Key) -> Result<()> {
166 self.core
167 .run(Action::KeyPress, Timing::Any, Command::KeyPress(key))
168 }
169
170 pub fn release_key(&self, key: Key) -> Result<()> {
171 self.core
172 .run(Action::KeyRelease, Timing::Any, Command::KeyRelease(key))
173 }
174
175 pub fn tap_key(&self, key: Key) -> Result<()> {
177 self.tap_key_with(key, Click::default())
178 }
179
180 pub fn tap_key_with(&self, key: Key, tap: Click) -> Result<()> {
181 self.core.tap(Usage::Key(key), tap)
182 }
183
184 pub fn press_media(&self, key: MediaKey) -> Result<()> {
186 self.core
187 .run(Action::MediaPress, Timing::Any, Command::MediaPress(key))
188 }
189
190 pub fn release_media(&self, key: MediaKey) -> Result<()> {
191 self.core.run(
192 Action::MediaRelease,
193 Timing::Any,
194 Command::MediaRelease(key),
195 )
196 }
197
198 pub fn tap_media(&self, key: MediaKey) -> Result<()> {
199 self.tap_media_with(key, Click::default())
200 }
201
202 pub fn tap_media_with(&self, key: MediaKey, tap: Click) -> Result<()> {
203 self.core.tap(Usage::Media(key), tap)
204 }
205
206 pub fn lock_button(&self, button: Button) -> Result<()> {
209 self.core
210 .lock(Action::LockButton, &[LockSlot::Button(button)], LOCKED)
211 }
212
213 pub fn unlock_button(&self, button: Button) -> Result<()> {
214 self.core
215 .lock(Action::LockButton, &[LockSlot::Button(button)], UNLOCKED)
216 }
217
218 pub fn lock_key(&self, key: Key) -> Result<()> {
220 self.core
221 .lock(Action::LockKey, &[LockSlot::Key(key)], LOCKED)
222 }
223
224 pub fn unlock_key(&self, key: Key) -> Result<()> {
225 self.core
226 .lock(Action::LockKey, &[LockSlot::Key(key)], UNLOCKED)
227 }
228
229 pub fn lock_axis(&self, axis: Axis, direction: Direction) -> Result<()> {
232 self.core
233 .lock(Action::LockAxis, &slots(axis, direction), LOCKED)
234 }
235
236 pub fn unlock_axis(&self, axis: Axis, direction: Direction) -> Result<()> {
238 self.core
239 .lock(Action::LockAxis, &slots(axis, direction), UNLOCKED)
240 }
241
242 pub fn scale_axis(&self, axis: Axis, direction: Direction, percent: i16) -> Result<()> {
245 self.core
246 .lock(Action::ScaleAxis, &slots(axis, direction), percent)
247 }
248
249 pub fn wheel(&self, notches: i16) -> Result<()> {
250 self.core
251 .run(Action::Wheel, Timing::Any, Command::Wheel(notches))
252 }
253
254 pub fn pan(&self, notches: i16) -> Result<()> {
256 self.core
257 .run(Action::Pan, Timing::Any, Command::Pan(notches))
258 }
259
260 pub fn discard_pending_moves(&self) -> Result<()> {
263 self.core.run(
264 Action::DiscardPendingMoves,
265 Timing::Any,
266 Command::DiscardPendingMoves,
267 )
268 }
269
270 pub fn events(&self) -> Events {
274 self.receiver(EventKinds::ALL, false)
275 }
276
277 pub fn events_of(&self, kinds: EventKinds) -> Events {
282 self.receiver(kinds, !kinds.contains(EventKinds::ALL))
284 }
285
286 fn receiver(&self, kinds: EventKinds, report_unsupported: bool) -> Events {
287 let listeners: Weak<dyn Listeners> = Arc::downgrade(&self.core) as Weak<Core>;
288 let (queue, id) = self.core.add_receiver(kinds, report_unsupported);
289 Events::new(queue, listeners, id)
290 }
291
292 #[cfg(feature = "medius")]
307 pub fn medius(&self) -> Option<medius::Device> {
308 if lock(&self.core.output).closing {
309 return None;
310 }
311 self.core
312 .backend
313 .as_any()
314 .downcast_ref::<crate::family::medius::MediusBackend>()
315 .and_then(crate::family::medius::MediusBackend::device)
316 }
317
318 pub fn close(&self) -> Result<()> {
324 let mut closed = lock(&self.closed);
325 if *closed {
326 return Err(Error::Closed);
327 }
328 *closed = true;
329 self.shutdown()
330 }
331
332 fn shutdown(&self) -> Result<()> {
333 let released = self.core.release_everything();
334 self.core.backend.shutdown(SHUTDOWN_DEADLINE);
335 let _ = self.core.signals.send(Signal::Stop);
336 if let Some((handle, done)) = lock(&self.link).take() {
337 if done.recv_timeout(SHUTDOWN_DEADLINE).is_ok() {
339 let _ = handle.join();
340 }
341 }
342 self.core.close_receivers();
343 released
344 }
345}
346
347impl Drop for Device {
348 fn drop(&mut self) {
349 let mut closed = lock(&self.closed);
350 if !*closed {
351 *closed = true;
352 let _ = self.shutdown();
353 }
354 }
355}
356
357impl fmt::Debug for Device {
358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359 f.debug_struct("Device")
360 .field("info", &self.snapshot().info)
361 .finish_non_exhaustive()
362 }
363}
364
365fn prepare(snapshot: Snapshot, click_timing: ClickTiming, port: &str) -> Arc<Snapshot> {
366 let Snapshot {
367 mut info,
368 capabilities,
369 } = snapshot;
370 info.port = port.to_owned();
372 Arc::new(Snapshot::new(
373 info,
374 capabilities.with_host_taps(click_timing),
375 ))
376}
377
378fn keeps_locked(snapshot: &Snapshot) -> bool {
379 [Action::LockButton, Action::LockAxis, Action::LockKey]
380 .into_iter()
381 .any(|lock| {
382 snapshot
383 .capabilities
384 .get(lock)
385 .quirks
386 .contains(&Quirk::KeepsLocked)
387 })
388}
389
390fn slots(axis: Axis, direction: Direction) -> Vec<LockSlot> {
392 let signs: &[Sign] = match direction {
393 Direction::Both => &[Sign::Positive, Sign::Negative],
394 Direction::Positive => &[Sign::Positive],
395 Direction::Negative => &[Sign::Negative],
396 };
397 signs
398 .iter()
399 .map(|&sign| LockSlot::Axis(axis, sign))
400 .collect()
401}
402
403fn keeps_held(snapshot: &Snapshot) -> bool {
405 [Action::Press, Action::KeyPress, Action::MediaPress]
406 .into_iter()
407 .any(|press| {
408 snapshot
409 .capabilities
410 .get(press)
411 .quirks
412 .contains(&Quirk::KeepsHeld)
413 })
414}
415
416fn max_keys_held(snapshot: &Snapshot) -> Option<u8> {
417 snapshot
418 .capabilities
419 .get(Action::KeyPress)
420 .quirks
421 .iter()
422 .find_map(|quirk| match quirk {
423 Quirk::MaxKeysHeld(max) => Some(*max),
424 _ => None,
425 })
426}
427
428fn tap_actions(usage: Usage) -> (Action, Action, Action) {
430 match usage {
431 Usage::Button(_) => (Action::Click, Action::Press, Action::Release),
432 Usage::Key(_) => (Action::KeyTap, Action::KeyPress, Action::KeyRelease),
433 Usage::Media(_) => (Action::MediaTap, Action::MediaPress, Action::MediaRelease),
434 }
435}
436
437fn lock<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
438 mutex.lock().unwrap_or_else(PoisonError::into_inner)
439}
440
441fn stream_kinds(snapshot: &Snapshot) -> InputKinds {
442 let capabilities = &snapshot.capabilities;
443 InputKinds {
444 buttons: capabilities.get(Action::ButtonEvents).is_supported(),
445 motion: capabilities.get(Action::MotionEvents).is_supported(),
446 keys: capabilities.get(Action::KeyEvents).is_supported(),
447 media: capabilities.get(Action::MediaEvents).is_supported(),
448 }
449}
450
451impl Core {
452 fn snapshot(&self) -> Arc<Snapshot> {
453 self.snapshot
454 .read()
455 .unwrap_or_else(PoisonError::into_inner)
456 .clone()
457 }
458
459 fn unsupported(
460 snapshot: &Snapshot,
461 action: Action,
462 reason: impl Into<Cow<'static, str>>,
463 ) -> Error {
464 Error::Unsupported {
465 action,
466 family: snapshot.info.family,
467 reason: reason.into(),
468 }
469 }
470
471 fn gate(snapshot: &Snapshot, action: Action, timing: Timing, command: Command) -> Result<()> {
474 let capability = snapshot.capabilities.get(action);
475 match &capability.execution {
476 Execution::Unsupported { reason } => {
477 return Err(Self::unsupported(snapshot, action, reason.clone()));
478 }
479 Execution::Host if timing == Timing::NativeOnly => {
480 return Err(Self::unsupported(
481 snapshot,
482 action,
483 "the box can't do it by itself and you asked for native timing only",
484 ));
485 }
486 _ => {}
487 }
488 match command {
489 Command::Press(button) | Command::Release(button) | Command::Click { button, .. }
490 if !snapshot.capabilities.buttons().contains(&button) =>
491 {
492 Err(Error::InvalidArgument {
493 action,
494 detail: format!("the box has no {button} button").into(),
495 })
496 }
497 Command::KeyPress(key) | Command::KeyRelease(key) | Command::KeyTap { key, .. }
498 if !key.is_valid() =>
499 {
500 Err(Error::InvalidArgument {
501 action,
502 detail: format!("{key} isn't a key, keys go from 0x04 to 0xE7").into(),
503 })
504 }
505 Command::MediaPress(key)
506 | Command::MediaRelease(key)
507 | Command::MediaTap { key, .. }
508 if key.0 == 0 =>
509 {
510 Err(Error::InvalidArgument {
511 action,
512 detail: "media key 0 isn't a key".into(),
513 })
514 }
515 Command::Click {
516 hold: Some(hold), ..
517 }
518 | Command::KeyTap {
519 hold: Some(hold), ..
520 }
521 | Command::MediaTap {
522 hold: Some(hold), ..
523 } => {
524 for quirk in &capability.quirks {
525 match quirk {
526 Quirk::FixedClickTiming => {
527 return Err(Self::unsupported(
528 snapshot,
529 action,
530 "it has its own timing and doesn't take a hold, so press and release it yourself if you need one",
531 ));
532 }
533 Quirk::MaxHold(max) if hold > *max => {
534 return Err(Error::InvalidArgument {
535 action,
536 detail: format!("the box holds it down for at most {max:?}").into(),
537 });
538 }
539 _ => {}
540 }
541 }
542 Ok(())
543 }
544 Command::Wheel(notches) => {
545 for quirk in &capability.quirks {
546 if let Quirk::NotchesPerCommand(max) = quirk
547 && notches.unsigned_abs() > *max
548 {
549 return Err(Self::unsupported(
550 snapshot,
551 action,
552 match max {
553 1 => {
554 "it takes one wheel notch per command, send them one at a time"
555 .into()
556 }
557 _ => format!(
558 "it takes at most {max} wheel notches per command, so split it up"
559 ),
560 },
561 ));
562 }
563 }
564 Ok(())
565 }
566 Command::Lock { slot, keep } => {
567 let detail = match slot {
568 LockSlot::Button(button)
569 if !snapshot.capabilities.buttons().contains(&button) =>
570 {
571 Some(format!("the box has no {button} button"))
572 }
573 LockSlot::Key(key) if !key.is_valid() => {
574 Some(format!("{key} isn't a key, keys go from 0x04 to 0xE7"))
575 }
576 LockSlot::Axis(axis, _) if !snapshot.capabilities.axes().contains(&axis) => {
577 Some(format!("the box can't lock the {axis} axis"))
578 }
579 LockSlot::Button(_) | LockSlot::Key(_) | LockSlot::Axis(..)
580 if !(-255..=255).contains(&keep) =>
581 {
582 Some(format!(
583 "{keep} is out of range, a scale goes from -255 to 255"
584 ))
585 }
586 LockSlot::Button(_) | LockSlot::Key(_) | LockSlot::Axis(..) => None,
587 };
588 match detail {
589 Some(detail) => Err(Error::InvalidArgument {
590 action,
591 detail: detail.into(),
592 }),
593 None => Ok(()),
594 }
595 }
596 Command::Move(..)
597 | Command::MoveNow(..)
598 | Command::Press(_)
599 | Command::Release(_)
600 | Command::Click { hold: None, .. }
601 | Command::Pan(_)
602 | Command::DiscardPendingMoves
603 | Command::KeyPress(_)
604 | Command::KeyRelease(_)
605 | Command::KeyTap { hold: None, .. }
606 | Command::MediaPress(_)
607 | Command::MediaRelease(_)
608 | Command::MediaTap { hold: None, .. } => Ok(()),
609 }
610 }
611
612 fn check_rollover(
614 output: &Output,
615 snapshot: &Snapshot,
616 action: Action,
617 command: Command,
618 ) -> Result<()> {
619 let (Command::KeyPress(key) | Command::KeyTap { key, .. }) = command else {
620 return Ok(());
621 };
622 let Some(max) = max_keys_held(snapshot) else {
623 return Ok(());
624 };
625 if key.is_modifier() || output.held.contains(&Usage::Key(key)) {
626 return Ok(());
627 }
628 let held = output
629 .held
630 .iter()
631 .filter(|usage| matches!(usage, Usage::Key(held) if !held.is_modifier()))
632 .count();
633 if held >= usize::from(max) {
634 return Err(Self::unsupported(
635 snapshot,
636 action,
637 format!("this box holds at most {max} keys at once, let one go first"),
638 ));
639 }
640 Ok(())
641 }
642
643 fn open_output(&self) -> Result<(MutexGuard<'_, Output>, Arc<Snapshot>)> {
644 let output = lock(&self.output);
645 if output.closing {
646 return Err(Error::Closed);
647 }
648 if !output.link_up {
649 return Err(Error::Disconnected);
650 }
651 let snapshot = self.snapshot();
652 Ok((output, snapshot))
653 }
654
655 fn send_locked(
656 &self,
657 output: &mut Output,
658 snapshot: &Snapshot,
659 action: Action,
660 timing: Timing,
661 command: Command,
662 ) -> Result<()> {
663 let held = command.holds();
664 let releasing_held = matches!(held, Some((usage, false)) if output.held.contains(&usage));
667 if !releasing_held {
668 Self::gate(snapshot, action, timing, command)?;
669 }
670 Self::check_rollover(output, snapshot, action, command)?;
671 let sent = self.backend.send(command);
672 match (held, &sent) {
673 (Some((usage, true)), Ok(())) => {
676 output.held.insert(usage);
677 output.unsure.remove(&usage);
678 }
679 (Some((usage, true)), Err(Error::Disconnected)) => {
680 output.held.insert(usage);
681 output.unsure.insert(usage);
682 }
683 (Some((usage, false)), Ok(())) => {
684 output.held.remove(&usage);
685 output.unsure.remove(&usage);
686 }
687 _ => {}
688 }
689 sent
690 }
691
692 fn run(&self, action: Action, timing: Timing, command: Command) -> Result<()> {
693 let (mut output, snapshot) = self.open_output()?;
694 self.send_locked(&mut output, &snapshot, action, timing, command)
695 }
696
697 fn lock(&self, action: Action, slots: &[LockSlot], keep: i16) -> Result<()> {
700 let (mut output, snapshot) = self.open_output()?;
701 for &slot in slots {
702 let unlocking_held = keep == UNLOCKED && output.locked.contains_key(&slot);
703 if !unlocking_held {
704 Self::gate(&snapshot, action, Timing::Any, Command::Lock { slot, keep })?;
705 }
706 }
707 let mut first = Ok(());
708 for &slot in slots {
709 let sent = self.backend.send(Command::Lock { slot, keep });
710 if keep == UNLOCKED {
711 if sent.is_ok() {
712 output.locked.remove(&slot);
713 }
714 } else if matches!(sent, Ok(()) | Err(Error::Disconnected)) {
715 output.locked.insert(slot, keep);
718 }
719 if first.is_ok() {
720 first = sent;
721 }
722 }
723 first
724 }
725
726 fn tap(&self, usage: Usage, tap: Click) -> Result<()> {
729 let (action, press, release) = tap_actions(usage);
730 let (mut output, snapshot) = self.open_output()?;
731 if snapshot.capabilities.get(action).execution != Execution::Host {
732 return self.send_locked(
733 &mut output,
734 &snapshot,
735 action,
736 tap.timing,
737 usage.tap(tap.hold),
738 );
739 }
740 if tap.timing == Timing::NativeOnly {
741 return Err(Self::unsupported(
742 &snapshot,
743 action,
744 "the box can't time it by itself and you asked for native timing only",
745 ));
746 }
747 let hold = match tap.hold {
748 Some(hold) => hold,
749 None => lock(&self.holds).pick(self.click_timing).ok_or_else(|| {
750 Self::unsupported(
751 &snapshot,
752 action,
753 "the box can't time it by itself and ClickTiming is off, so give it a hold",
754 )
755 })?,
756 };
757 Self::gate(&snapshot, action, tap.timing, usage.tap(None))?;
759 Self::check_rollover(&output, &snapshot, action, usage.press())?;
760 self.send_locked(&mut output, &snapshot, press, Timing::Any, usage.press())?;
761 let session = output.session;
762 drop(output);
763 thread::sleep(hold);
764 let (mut output, snapshot) = match self.open_output() {
765 Ok(open) => open,
766 Err(error) => {
767 lock(&self.output).unsure.insert(usage);
768 return Err(error);
769 }
770 };
771 if output.session != session && !keeps_held(&snapshot) {
772 return Err(Error::Interrupted { action });
775 }
776 let released = self.send_locked(
777 &mut output,
778 &snapshot,
779 release,
780 Timing::Any,
781 usage.release(),
782 );
783 if released.is_err() {
784 output.unsure.insert(usage);
785 }
786 released
787 }
788
789 fn add_receiver(&self, kinds: EventKinds, report_unsupported: bool) -> (Arc<Queue>, u64) {
790 let output = lock(&self.output);
791 let queue = Arc::new(Queue::new(QUEUE_CAPACITY));
792 let id = {
793 let mut receivers = lock(&self.receivers);
794 let id = receivers.next_id;
795 receivers.next_id += 1;
796 if output.closing {
797 queue.close();
798 return (queue, id);
799 }
800 receivers.entries.push(Entry {
801 id,
802 kinds,
803 queue: Arc::downgrade(&queue),
804 });
805 id
806 };
807 let snapshot = self.snapshot();
808 if report_unsupported {
809 let streamable = EventKinds::from_input(stream_kinds(&snapshot));
810 for (_, action) in (kinds & !streamable).each() {
811 queue.push(Event::Rejected { action, count: 1 });
812 }
813 }
814 let refused = self.apply_streams(&output, &snapshot);
815 drop(output);
816 self.publish_all(refused);
817 (queue, id)
818 }
819
820 fn publish(&self, event: Event) {
822 if let Event::Rejected { action, .. } = &event
826 && EventKinds::of_action(*action).is_some()
827 {
828 let now = Instant::now();
829 let mut refused = lock(&self.refused);
830 if refused
831 .get(action)
832 .is_some_and(|at| now.duration_since(*at) < Duration::from_secs(1))
833 {
834 return;
835 }
836 refused.insert(*action, now);
837 }
838 let kind = EventKinds::of(&event);
839 let mut receivers = lock(&self.receivers);
840 receivers
841 .entries
842 .retain(|entry| match entry.queue.upgrade() {
843 Some(queue) => {
844 if kind.is_none_or(|kind| !(entry.kinds & kind).is_empty()) {
845 queue.push(event.clone());
846 }
847 true
848 }
849 None => false,
850 });
851 }
852
853 fn publish_all(&self, events: Vec<Event>) {
854 for event in events {
855 self.publish(event);
856 }
857 }
858
859 fn publish_to(&self, kinds: EventKinds, event: Event) {
861 let receivers = lock(&self.receivers);
862 for entry in &receivers.entries {
863 if !(entry.kinds & kinds).is_empty()
864 && let Some(queue) = entry.queue.upgrade()
865 {
866 queue.push(event.clone());
867 }
868 }
869 }
870
871 fn close_receivers(&self) {
872 for entry in lock(&self.receivers).entries.drain(..) {
873 if let Some(queue) = entry.queue.upgrade() {
874 queue.close();
875 }
876 }
877 }
878
879 fn apply_streams(&self, output: &Output, snapshot: &Snapshot) -> Vec<Event> {
884 if output.closing || !output.link_up {
885 return Vec::new();
886 }
887 let union = lock(&self.receivers).union();
888 let wanted = union & EventKinds::from_input(stream_kinds(snapshot));
889 match self.backend.set_streams(wanted.to_input()) {
890 Err(failure) if !matches!(failure.error, Error::Disconnected) => {
891 (EventKinds::from_input(failure.failed) & wanted)
892 .each()
893 .map(|(_, action)| Event::Rejected { action, count: 1 })
894 .collect()
895 }
896 _ => Vec::new(),
897 }
898 }
899
900 fn release_held(&self, output: &mut Output, snapshot: &Snapshot) -> bool {
904 let usages = if keeps_held(snapshot) {
905 &output.unsure
906 } else {
907 &output.held
908 };
909 let usages: Vec<Usage> = usages.iter().copied().collect();
910 let mut all_released = true;
911 for usage in usages {
912 if self.backend.send(usage.release()).is_ok() {
913 output.held.remove(&usage);
914 output.unsure.remove(&usage);
915 } else {
916 all_released = false;
917 }
918 }
919 all_released
920 }
921
922 fn release_everything(&self) -> Result<()> {
923 let mut output = lock(&self.output);
924 output.closing = true;
925 output.link_up = false;
926 output.unsure.clear();
927 let held: Vec<Usage> = output.held.drain().collect();
928 let released = if held.is_empty() {
929 Ok(())
930 } else {
931 self.backend.release_all(&held)
932 };
933 let locked: Vec<LockSlot> = output.locked.drain().map(|(slot, _)| slot).collect();
934 let unlocked = if locked.is_empty() {
935 Ok(())
936 } else {
937 self.backend.unlock_all(&locked)
938 };
939 released.and(unlocked)
940 }
941
942 fn relock(&self, output: &Output, snapshot: &Snapshot) {
945 if keeps_locked(snapshot) {
946 return;
947 }
948 for (&slot, &keep) in &output.locked {
949 let command = Command::Lock { slot, keep };
950 if Self::gate(snapshot, command.action(), Timing::Any, command).is_ok() {
951 let _ = self.backend.send(command);
952 }
953 }
954 }
955
956 fn handle(&self, signal: Signal) {
957 match signal {
958 Signal::Input {
959 input,
960 arrived,
961 box_time,
962 read,
963 } => {
964 let mut at = Stamp::new(arrived, arrived.saturating_duration_since(self.opened));
965 at.box_time = box_time;
966 if let Some(read) = read {
967 at.received = read.at;
968 at.received_since_open = read.at.saturating_duration_since(self.opened);
969 at.received_qpc = read.qpc;
970 }
971 self.publish(match input {
972 Input::Button { button, pressed } => Event::Button {
973 button,
974 pressed,
975 at,
976 },
977 Input::Motion { dx, dy, wheel, pan } => Event::Motion {
978 dx,
979 dy,
980 wheel,
981 pan,
982 at,
983 },
984 Input::Key { key, pressed } => Event::Key { key, pressed, at },
985 Input::Media { key, pressed } => Event::Media { key, pressed, at },
986 });
987 }
988 Signal::Dropped(count, source, kind) => match kind {
989 Some(kind) => self.publish_to(
990 EventKinds::from_input(kind.kinds()),
991 Event::Dropped { count, source },
992 ),
993 None => self.publish(Event::Dropped { count, source }),
994 },
995 Signal::StreamLost(kind) => {
996 let output = lock(&self.output);
997 if output.closing {
998 return;
999 }
1000 let lost = EventKinds::from_input(kind.kinds());
1001 self.publish_to(
1004 lost,
1005 Event::Dropped {
1006 count: 1,
1007 source: DropSource::Device,
1008 },
1009 );
1010 if output.link_up && lock(&self.receivers).union().contains(lost) {
1013 let restarted = self.backend.restart_stream(kind);
1014 drop(output);
1015 if let Err(error) = restarted
1016 && !matches!(error, Error::Disconnected)
1017 {
1018 for (_, action) in lost.each() {
1019 self.publish(Event::Rejected { action, count: 1 });
1020 }
1021 }
1022 }
1023 }
1024 Signal::Refused(action) => self.publish(Event::Rejected { action, count: 1 }),
1025 Signal::Disconnected => {
1026 let mut output = lock(&self.output);
1027 if output.closing {
1028 return;
1029 }
1030 output.link_up = false;
1031 output.session += 1;
1032 drop(output);
1033 self.publish(Event::Disconnected);
1034 }
1035 Signal::Reconnected(snapshot) => {
1036 let mut output = lock(&self.output);
1037 if output.closing {
1038 return;
1039 }
1040 output.session += 1;
1041 let snapshot = prepare(*snapshot, self.click_timing, &self.port);
1042 *self
1043 .snapshot
1044 .write()
1045 .unwrap_or_else(PoisonError::into_inner) = snapshot.clone();
1046 if !self.release_held(&mut output, &snapshot) {
1047 let was_up = output.link_up;
1050 output.link_up = false;
1051 drop(output);
1052 if was_up {
1053 self.publish(Event::Disconnected);
1054 }
1055 return;
1056 }
1057 self.relock(&output, &snapshot);
1058 output.link_up = true;
1059 let refused = self.apply_streams(&output, &snapshot);
1060 drop(output);
1061 self.publish(Event::Reconnected);
1062 self.publish_all(refused);
1063 }
1064 Signal::Changed(snapshot) => {
1065 let output = lock(&self.output);
1066 if output.closing {
1067 return;
1068 }
1069 *self
1070 .snapshot
1071 .write()
1072 .unwrap_or_else(PoisonError::into_inner) =
1073 prepare(*snapshot, self.click_timing, &self.port);
1074 drop(output);
1075 }
1076 Signal::SessionReset => {
1077 let mut output = lock(&self.output);
1078 if output.closing {
1079 return;
1080 }
1081 output.session += 1;
1082 let snapshot = self.snapshot();
1083 self.release_held(&mut output, &snapshot);
1084 self.relock(&output, &snapshot);
1085 let refused = self.apply_streams(&output, &snapshot);
1086 drop(output);
1087 self.publish(Event::SessionReset);
1088 self.publish_all(refused);
1089 }
1090 #[cfg(test)]
1091 Signal::Barrier(done) => {
1092 let _ = done.send(());
1093 }
1094 Signal::Stop => {}
1095 }
1096 }
1097}
1098
1099impl Listeners for Core {
1100 fn receiver_dropped(&self, id: u64) {
1101 let output = lock(&self.output);
1102 lock(&self.receivers).entries.retain(|entry| entry.id != id);
1103 let refused = self.apply_streams(&output, &self.snapshot());
1104 drop(output);
1105 self.publish_all(refused);
1106 }
1107}
1108
1109fn spawn_link(
1110 core: Weak<Core>,
1111 incoming: Receiver<Signal>,
1112) -> Result<(JoinHandle<()>, Receiver<()>)> {
1113 let (done, finished) = mpsc::channel();
1114 let handle = thread::Builder::new()
1115 .name("anybox-link".into())
1116 .spawn(move || {
1117 while let Ok(signal) = incoming.recv() {
1118 if matches!(signal, Signal::Stop) {
1119 break;
1120 }
1121 match core.upgrade() {
1122 Some(core) => core.handle(signal),
1123 None => break,
1124 }
1125 }
1126 let _ = done.send(());
1127 })?;
1128 Ok((handle, finished))
1129}
1130
1131#[cfg(test)]
1132impl Device {
1133 pub(crate) fn start_closing(&self) {
1135 let _ = self.core.release_everything();
1136 }
1137
1138 pub(crate) fn backend_for_tests(&self) -> &dyn std::any::Any {
1139 self.core.backend.as_any()
1140 }
1141
1142 pub(crate) fn held(&self) -> HashSet<Usage> {
1143 lock(&self.core.output).held.clone()
1144 }
1145
1146 pub(crate) fn settle(&self) {
1148 let (done, wait) = mpsc::channel();
1149 let _ = self.core.signals.send(Signal::Barrier(done));
1150 let _ = wait.recv_timeout(Duration::from_secs(5));
1151 }
1152}
1153
1154#[cfg(test)]
1155mod tests;