diff --git a/src/controller/controls/mod.rs b/src/controller/controls/mod.rs index dad577d..7561e10 100644 --- a/src/controller/controls/mod.rs +++ b/src/controller/controls/mod.rs @@ -1,11 +1,11 @@ -mod dpad; mod media; mod null; +mod paddle; mod scroll_zoom; mod volume; -pub use self::dpad::*; pub use self::media::*; pub use self::null::*; +pub use self::paddle::*; pub use self::scroll_zoom::*; pub use self::volume::*; diff --git a/src/controller/controls/dpad.rs b/src/controller/controls/paddle.rs similarity index 70% rename from src/controller/controls/dpad.rs rename to src/controller/controls/paddle.rs index 5a1226e..c01592e 100644 --- a/src/controller/controls/dpad.rs +++ b/src/controller/controls/paddle.rs @@ -10,9 +10,15 @@ use crate::DynResult; use evdev_rs::enums::EV_KEY; +// everything is done in a worker, as we need use `recv_timeout` as a (very) +// poor man's `select!`. + enum Msg { Kill, + ButtonDown, + ButtonUp, Delta(i32), + Enabled(bool), } struct Worker { @@ -24,6 +30,7 @@ struct Worker { cap: i32, deadzone: i32, + enabled: bool, last_delta: i32, velocity: i32, } @@ -40,6 +47,7 @@ impl Worker { cap: 250, deadzone: 10, + enabled: false, last_delta: 0, velocity: 0, } @@ -49,8 +57,26 @@ impl Worker { loop { let falloff = self.velocity.abs() / self.falloff + 1; - match self.msg.recv_timeout(Duration::from_millis(self.timeout)) { + let msg = if self.enabled { + self.msg.recv_timeout(Duration::from_millis(self.timeout)) + } else { + self.msg + .recv() + .map_err(|_| mpsc::RecvTimeoutError::Disconnected) + }; + + match msg { Ok(Msg::Kill) => return, + Ok(Msg::Enabled(enabled)) => { + self.enabled = enabled; + if !enabled { + self.fake_input + .key_release(&[EV_KEY::KEY_SPACE, EV_KEY::KEY_LEFT, EV_KEY::KEY_RIGHT]) + .unwrap() + } + } + Ok(Msg::ButtonDown) => self.fake_input.key_press(&[EV_KEY::KEY_SPACE]).unwrap(), + Ok(Msg::ButtonUp) => self.fake_input.key_release(&[EV_KEY::KEY_SPACE]).unwrap(), Ok(Msg::Delta(delta)) => { // abrupt direction change! if (delta < 0) != (self.last_delta < 0) { @@ -94,35 +120,31 @@ impl Worker { } /// A bit of a misnomer, since it's only left-right. -pub struct DPad { +pub struct Paddle { _worker: JoinHandle<()>, msg: mpsc::Sender, - - fake_input: FakeInput, } -impl Drop for DPad { +impl Drop for Paddle { fn drop(&mut self) { let _ = self.msg.send(Msg::Kill); } } -impl DPad { - pub fn new() -> DPad { +impl Paddle { + pub fn new() -> Paddle { let (msg_tx, msg_rx) = mpsc::channel(); let worker = std::thread::spawn(move || Worker::new(msg_rx).run()); - DPad { + Paddle { _worker: worker, msg: msg_tx, - - fake_input: FakeInput::new(), } } } -impl ControlMode for DPad { +impl ControlMode for Paddle { fn meta(&self) -> ControlModeMeta { ControlModeMeta { name: "Paddle", @@ -132,16 +154,22 @@ impl ControlMode for DPad { fn on_start(&mut self, haptics: &DialHaptics) -> DynResult<()> { haptics.set_mode(false, Some(3600))?; + self.msg.send(Msg::Enabled(true))?; + Ok(()) + } + + fn on_end(&mut self, _haptics: &DialHaptics) -> DynResult<()> { + self.msg.send(Msg::Enabled(false))?; Ok(()) } fn on_btn_press(&mut self, _: &DialHaptics) -> DynResult<()> { - eprintln!("space"); - self.fake_input.key_click(&[EV_KEY::KEY_SPACE])?; + self.msg.send(Msg::ButtonDown)?; Ok(()) } fn on_btn_release(&mut self, _: &DialHaptics) -> DynResult<()> { + self.msg.send(Msg::ButtonUp)?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 8534cfe..72f4cf3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,7 @@ fn true_main() -> DynResult<()> { Box::new(controller::controls::ScrollZoom::new()), Box::new(controller::controls::Volume::new()), Box::new(controller::controls::Media::new()), - Box::new(controller::controls::DPad::new()), + Box::new(controller::controls::Paddle::new()), ], );