use std::any::Any;
use std::sync::mpsc::Sender;
use std::time::{Duration, Instant};
use crate::capability::{Action, Axis, Button, Snapshot};
use crate::error::Result;
use crate::event::{BoxTime, DropSource};
use crate::key::{Key, MediaKey};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Command {
Move(i16, i16),
MoveNow(i16, i16),
Press(Button),
Release(Button),
Click {
button: Button,
hold: Option<Duration>,
},
Wheel(i16),
Pan(i16),
DiscardPendingMoves,
KeyPress(Key),
KeyRelease(Key),
KeyTap {
key: Key,
hold: Option<Duration>,
},
MediaPress(MediaKey),
MediaRelease(MediaKey),
MediaTap {
key: MediaKey,
hold: Option<Duration>,
},
Lock {
slot: LockSlot,
keep: i16,
},
}
pub(crate) const UNLOCKED: i16 = 100;
pub(crate) const LOCKED: i16 = 0;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum LockSlot {
Button(Button),
Key(Key),
Axis(Axis, Sign),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum Sign {
Positive,
Negative,
}
impl LockSlot {
pub(crate) fn action(self, keep: i16) -> Action {
match self {
Self::Button(_) => Action::LockButton,
Self::Key(_) => Action::LockKey,
Self::Axis(..) if keep == LOCKED || keep == UNLOCKED => Action::LockAxis,
Self::Axis(..) => Action::ScaleAxis,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum Usage {
Button(Button),
Key(Key),
Media(MediaKey),
}
impl Usage {
pub(crate) fn press(self) -> Command {
match self {
Self::Button(button) => Command::Press(button),
Self::Key(key) => Command::KeyPress(key),
Self::Media(key) => Command::MediaPress(key),
}
}
pub(crate) fn release(self) -> Command {
match self {
Self::Button(button) => Command::Release(button),
Self::Key(key) => Command::KeyRelease(key),
Self::Media(key) => Command::MediaRelease(key),
}
}
pub(crate) fn tap(self, hold: Option<Duration>) -> Command {
match self {
Self::Button(button) => Command::Click { button, hold },
Self::Key(key) => Command::KeyTap { key, hold },
Self::Media(key) => Command::MediaTap { key, hold },
}
}
}
impl Command {
pub(crate) fn action(self) -> Action {
match self {
Self::Move(..) => Action::Move,
Self::MoveNow(..) => Action::MoveNow,
Self::Press(_) => Action::Press,
Self::Release(_) => Action::Release,
Self::Click { .. } => Action::Click,
Self::Wheel(_) => Action::Wheel,
Self::Pan(_) => Action::Pan,
Self::DiscardPendingMoves => Action::DiscardPendingMoves,
Self::KeyPress(_) => Action::KeyPress,
Self::KeyRelease(_) => Action::KeyRelease,
Self::KeyTap { .. } => Action::KeyTap,
Self::MediaPress(_) => Action::MediaPress,
Self::MediaRelease(_) => Action::MediaRelease,
Self::MediaTap { .. } => Action::MediaTap,
Self::Lock { slot, keep } => slot.action(keep),
}
}
pub(crate) fn holds(self) -> Option<(Usage, bool)> {
match self {
Self::Press(button) => Some((Usage::Button(button), true)),
Self::Release(button) => Some((Usage::Button(button), false)),
Self::KeyPress(key) => Some((Usage::Key(key), true)),
Self::KeyRelease(key) => Some((Usage::Key(key), false)),
Self::MediaPress(key) => Some((Usage::Media(key), true)),
Self::MediaRelease(key) => Some((Usage::Media(key), false)),
Self::Move(..)
| Self::MoveNow(..)
| Self::Click { .. }
| Self::Wheel(_)
| Self::Pan(_)
| Self::DiscardPendingMoves
| Self::KeyTap { .. }
| Self::MediaTap { .. }
| Self::Lock { .. } => None,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub(crate) struct InputKinds {
pub(crate) buttons: bool,
pub(crate) motion: bool,
pub(crate) keys: bool,
pub(crate) media: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum InputKind {
Buttons,
Motion,
Keys,
Media,
}
impl InputKind {
pub(crate) fn kinds(self) -> InputKinds {
let mut kinds = InputKinds::default();
match self {
Self::Buttons => kinds.buttons = true,
Self::Motion => kinds.motion = true,
Self::Keys => kinds.keys = true,
Self::Media => kinds.media = true,
}
kinds
}
}
#[derive(Debug)]
pub(crate) struct StreamFailure {
pub(crate) failed: InputKinds,
pub(crate) error: crate::error::Error,
}
pub(crate) trait Backend: Send + Sync + 'static {
fn send(&self, command: Command) -> Result<()>;
fn set_streams(&self, kinds: InputKinds) -> std::result::Result<(), StreamFailure>;
fn restart_stream(&self, kind: InputKind) -> Result<()>;
fn release_all(&self, held: &[Usage]) -> Result<()>;
fn unlock_all(&self, slots: &[LockSlot]) -> Result<()>;
fn shutdown(&self, deadline: Duration);
fn close(&self, deadline: Duration) -> Result<()> {
self.shutdown(deadline);
Ok(())
}
fn as_any(&self) -> &dyn Any;
}
pub(crate) const WRITE_DEADLINE: Duration = Duration::from_millis(500);
#[derive(Debug)]
pub(crate) enum Input {
Button {
button: Button,
pressed: bool,
},
Motion {
dx: i32,
dy: i32,
wheel: i32,
pan: i32,
},
Key {
key: Key,
pressed: bool,
},
Media {
key: MediaKey,
pressed: bool,
},
}
#[derive(Debug)]
pub(crate) enum Signal {
Input {
input: Input,
arrived: Instant,
box_time: Option<BoxTime>,
read: Option<crate::transport::os::Read>,
},
Dropped(u64, DropSource, Option<InputKind>),
StreamLost(InputKind),
Refused(Action),
SessionReset,
Disconnected,
Reconnected(Box<Snapshot>),
Changed(Box<Snapshot>),
#[cfg(test)]
Barrier(std::sync::mpsc::Sender<()>),
Stop,
}
#[derive(Clone, Debug)]
pub(crate) struct Sink(pub(crate) Sender<Signal>);
impl Sink {
pub(crate) fn input(
&self,
input: Input,
arrived: Instant,
box_time: Option<BoxTime>,
read: Option<crate::transport::os::Read>,
) {
self.send(Signal::Input {
input,
arrived,
box_time,
read,
});
}
pub(crate) fn dropped(&self, count: u64, source: DropSource) {
self.send(Signal::Dropped(count, source, None));
}
pub(crate) fn lost(&self, count: u64, kind: InputKind) {
self.send(Signal::Dropped(count, DropSource::Host, Some(kind)));
}
pub(crate) fn stream_lost(&self, kind: InputKind) {
self.send(Signal::StreamLost(kind));
}
pub(crate) fn refused(&self, action: Action) {
self.send(Signal::Refused(action));
}
pub(crate) fn session_reset(&self) {
self.send(Signal::SessionReset);
}
pub(crate) fn disconnected(&self) {
self.send(Signal::Disconnected);
}
pub(crate) fn reconnected(&self, snapshot: Snapshot) {
self.send(Signal::Reconnected(Box::new(snapshot)));
}
pub(crate) fn changed(&self, snapshot: Snapshot) {
self.send(Signal::Changed(Box::new(snapshot)));
}
fn send(&self, signal: Signal) {
let _ = self.0.send(signal);
}
}