Skip to content

Commit

Permalink
Implement mouse scrolling.
Browse files Browse the repository at this point in the history
  • Loading branch information
hgaiser committed Jan 25, 2024
1 parent e902ecb commit 5d616f5
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 5 deletions.
30 changes: 27 additions & 3 deletions moonshine/src/session/stream/control/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,18 @@ use tokio::sync::mpsc;

use crate::session::stream::control::input::gamepad::Gamepad;

use self::{mouse::{Mouse, MouseButton, MouseMoveRelative, MouseMoveAbsolute}, keyboard::{Keyboard, Key}, gamepad::{GamepadInfo, GamepadUpdate}};
use self::{
mouse::{
Mouse,
MouseButton,
MouseMoveAbsolute,
MouseMoveRelative,
MouseScrollVertical,
MouseScrollHorizontal,
},
keyboard::{Keyboard, Key},
gamepad::{GamepadInfo, GamepadUpdate}
};

mod keyboard;
mod mouse;
Expand All @@ -15,10 +26,11 @@ enum InputEventType {
KeyDown = 0x00000003,
KeyUp = 0x00000004,
MouseMoveAbsolute = 0x00000005,
// MouseMoveRelative = 0x00000006 (pre gen5)
MouseMoveRelative = 0x00000007,
MouseButtonDown = 0x00000008,
MouseButtonUp = 0x00000009,
MouseScrollVertical = 0x0000000A,
MouseScrollHorizontal = 0x55000001,
GamepadInfo = 0x55000004, // Called ControllerArrival in Moonlight.
GamepadUpdate = 0x0000000C,
}
Expand All @@ -32,6 +44,8 @@ enum InputEvent {
MouseMoveRelative(MouseMoveRelative),
MouseButtonDown(MouseButton),
MouseButtonUp(MouseButton),
MouseScrollVertical(MouseScrollVertical),
MouseScrollHorizontal(MouseScrollHorizontal),
GamepadInfo(GamepadInfo),
GamepadUpdate(GamepadUpdate),
}
Expand All @@ -51,6 +65,8 @@ impl InputEvent {
Some(InputEventType::MouseMoveRelative) => Ok(InputEvent::MouseMoveRelative(MouseMoveRelative::from_bytes(&buffer[4..])?)),
Some(InputEventType::MouseButtonDown) => Ok(InputEvent::MouseButtonDown(MouseButton::from_bytes(&buffer[4..])?)),
Some(InputEventType::MouseButtonUp) => Ok(InputEvent::MouseButtonUp(MouseButton::from_bytes(&buffer[4..])?)),
Some(InputEventType::MouseScrollVertical) => Ok(InputEvent::MouseScrollVertical(MouseScrollVertical::from_bytes(&buffer[4..])?)),
Some(InputEventType::MouseScrollHorizontal) => Ok(InputEvent::MouseScrollHorizontal(MouseScrollHorizontal::from_bytes(&buffer[4..])?)),
Some(InputEventType::GamepadInfo) => Ok(InputEvent::GamepadInfo(GamepadInfo::from_bytes(&buffer[4..])?)),
Some(InputEventType::GamepadUpdate) => Ok(InputEvent::GamepadUpdate(GamepadUpdate::from_bytes(&buffer[4..])?)),
None => {
Expand Down Expand Up @@ -123,8 +139,16 @@ impl InputHandlerInner {
log::trace!("Releasing mouse button: {button:?}");
let _ = self.mouse.button_up(button);
},
InputEvent::MouseScrollVertical(event) => {
log::trace!("Scrolling vertically: {event:?}");
let _ = self.mouse.scroll_vertical(event.amount);
},
InputEvent::MouseScrollHorizontal(event) => {
log::trace!("Scrolling horizontally: {event:?}");
let _ = self.mouse.scroll_horizontal(event.amount);
},
InputEvent::GamepadInfo(gamepad) => {
log::info!("Gamepad info: {gamepad:?}");
log::debug!("Gamepad info: {gamepad:?}");
if let Ok(gamepad) = Gamepad::new(gamepad) {
gamepads.push(gamepad);
}
Expand Down
56 changes: 54 additions & 2 deletions moonshine/src/session/stream/control/input/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,42 @@ impl From<MouseButton> for Key {
}
}

#[derive(Debug)]
pub struct MouseScrollVertical {
pub amount: i16,
}

impl MouseScrollVertical {
pub fn from_bytes(buffer: &[u8]) -> Result<Self, ()> {
if buffer.len() < std::mem::size_of::<Self>() {
log::warn!("Expected at least {} bytes for MouseScrollVertical, got {} bytes.", std::mem::size_of::<Self>(), buffer.len());
return Err(());
}

Ok(Self {
amount: i16::from_be_bytes(buffer[0..2].try_into().unwrap()),
})
}
}

#[derive(Debug)]
pub struct MouseScrollHorizontal {
pub amount: i16,
}

impl MouseScrollHorizontal {
pub fn from_bytes(buffer: &[u8]) -> Result<Self, ()> {
if buffer.len() < std::mem::size_of::<Self>() {
log::warn!("Expected at least {} bytes for MouseScrollHorizontal, got {} bytes.", std::mem::size_of::<Self>(), buffer.len());
return Err(());
}

Ok(Self {
amount: i16::from_be_bytes(buffer[0..2].try_into().unwrap()),
})
}
}

pub struct Mouse {
device: VirtualDevice,
}
Expand All @@ -100,8 +136,8 @@ impl Mouse {
.with_relative_axes(&AttributeSet::from_iter([
RelativeAxisType::REL_X,
RelativeAxisType::REL_Y,
RelativeAxisType::REL_WHEEL,
RelativeAxisType::REL_HWHEEL,
RelativeAxisType::REL_WHEEL_HI_RES,
RelativeAxisType::REL_HWHEEL_HI_RES,
]))
.map_err(|e| log::error!("Failed to enable relative axes for virtual mouse: {e}"))?
.with_absolute_axis(&UinputAbsSetup::new(
Expand Down Expand Up @@ -166,4 +202,20 @@ impl Mouse {
self.device.emit(&[button_event])
.map_err(|e| log::error!("Failed to release mouse button: {e}"))
}

pub fn scroll_vertical(&mut self, amount: i16) -> Result<(), ()> {
let events = [
evdev::InputEvent::new_now(evdev::EventType::RELATIVE, RelativeAxisType::REL_WHEEL_HI_RES.0, amount as i32),
];
self.device.emit(&events)
.map_err(|e| log::error!("Failed to scroll vertically: {e}"))
}

pub fn scroll_horizontal(&mut self, amount: i16) -> Result<(), ()> {
let events = [
evdev::InputEvent::new_now(evdev::EventType::RELATIVE, RelativeAxisType::REL_HWHEEL_HI_RES.0, amount as i32),
];
self.device.emit(&events)
.map_err(|e| log::error!("Failed to scroll horizontally: {e}"))
}
}

0 comments on commit 5d616f5

Please sign in to comment.