Skip to content

Commit

Permalink
windows: impl back and forward mouse buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
feschber committed Apr 12, 2024
1 parent ccb201e commit 633d2c3
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
27 changes: 24 additions & 3 deletions src/capture/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ use windows::Win32::UI::WindowsAndMessaging::{
LLKHF_EXTENDED, MSG, MSLLHOOKSTRUCT, WH_KEYBOARD_LL, WH_MOUSE_LL, WINDOW_STYLE,
WM_DISPLAYCHANGE, WM_KEYDOWN, WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN,
WM_MBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SYSKEYDOWN,
WM_SYSKEYUP, WM_USER, WNDCLASSW, WNDPROC,
WM_SYSKEYUP, WM_USER, WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSW, WNDPROC,
};

use crate::client::Position;
use crate::event::{KeyboardEvent, PointerEvent, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT};
use crate::event::{
KeyboardEvent, PointerEvent, BTN_BACK, BTN_FORWARD, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
};
use crate::scancode::Linux;
use crate::{
capture::InputCapture,
Expand Down Expand Up @@ -142,7 +144,26 @@ fn to_mouse_event(wparam: WPARAM, lparam: LPARAM) -> Option<PointerEvent> {
axis: 0,
value: -(mouse_low_level.mouseData as i32) as f64,
}),
_ => None,
WPARAM(p) if p == WM_XBUTTONDOWN as usize || p == WM_XBUTTONUP as usize => {
let hb = mouse_low_level.mouseData >> 16;
let button = match hb {
1 => BTN_BACK,
2 => BTN_FORWARD,
_ => {
log::warn!("unknown mouse button");
return None;
}
};
Some(PointerEvent::Button {
time: 0,
button,
state: if p == WM_XBUTTONDOWN as usize { 1 } else { 0 },
})
}
w => {
log::warn!("unknown mouse event: {w:?}");
None
}
}
}

Expand Down
29 changes: 21 additions & 8 deletions src/emulate/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ use async_trait::async_trait;
use std::ops::BitOrAssign;
use std::time::Duration;
use tokio::task::AbortHandle;
use windows::Win32::UI::Input::KeyboardAndMouse::{SendInput, INPUT_0, KEYEVENTF_EXTENDEDKEY};
use windows::Win32::UI::Input::KeyboardAndMouse::{
SendInput, INPUT_0, KEYEVENTF_EXTENDEDKEY, MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP,
};
use windows::Win32::UI::Input::KeyboardAndMouse::{
INPUT, INPUT_KEYBOARD, INPUT_MOUSE, KEYBDINPUT, KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE,
MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEDOWN,
MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_MOVE, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP,
MOUSEEVENTF_WHEEL, MOUSEINPUT,
};
use windows::Win32::UI::WindowsAndMessaging::{XBUTTON1, XBUTTON2};

use crate::event::{BTN_BACK, BTN_FORWARD, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT};
use crate::{
client::{ClientEvent, ClientHandle},
event::Event,
Expand Down Expand Up @@ -145,23 +149,32 @@ fn rel_mouse(dx: i32, dy: i32) {
fn mouse_button(button: u32, state: u32) {
let dw_flags = match state {
0 => match button {
0x110 => MOUSEEVENTF_LEFTUP,
0x111 => MOUSEEVENTF_RIGHTUP,
0x112 => MOUSEEVENTF_MIDDLEUP,
BTN_LEFT => MOUSEEVENTF_LEFTUP,
BTN_RIGHT => MOUSEEVENTF_RIGHTUP,
BTN_MIDDLE => MOUSEEVENTF_MIDDLEUP,
BTN_BACK => MOUSEEVENTF_XUP,
BTN_FORWARD => MOUSEEVENTF_XUP,
_ => return,
},
1 => match button {
0x110 => MOUSEEVENTF_LEFTDOWN,
0x111 => MOUSEEVENTF_RIGHTDOWN,
0x112 => MOUSEEVENTF_MIDDLEDOWN,
BTN_LEFT => MOUSEEVENTF_LEFTDOWN,
BTN_RIGHT => MOUSEEVENTF_RIGHTDOWN,
BTN_MIDDLE => MOUSEEVENTF_MIDDLEDOWN,
BTN_BACK => MOUSEEVENTF_XDOWN,
BTN_FORWARD => MOUSEEVENTF_XDOWN,
_ => return,
},
_ => return,
};
let mouse_data = match button {
BTN_BACK => XBUTTON1 as u32,
BTN_FORWARD => XBUTTON2 as u32,
_ => 0,
};
let mi = MOUSEINPUT {
dx: 0,
dy: 0, // no movement
mouseData: 0,
mouseData: mouse_data,
dwFlags: dw_flags,
time: 0,
dwExtraInfo: 0,
Expand Down
16 changes: 15 additions & 1 deletion src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,21 @@ impl Display for PointerEvent {
time: _,
button,
state,
} => write!(f, "button({button}, {state})"),
} => {
let str = match *button {
BTN_LEFT => Some("left"),
BTN_RIGHT => Some("right"),
BTN_MIDDLE => Some("middle"),
BTN_FORWARD => Some("forward"),
BTN_BACK => Some("back"),
_ => None,
};
if let Some(button) = str {
write!(f, "button({button}, {state})")
} else {
write!(f, "button({button}, {state}")
}
}
PointerEvent::Axis {
time: _,
axis,
Expand Down
2 changes: 1 addition & 1 deletion src/server/emulation_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ async fn handle_udp_rx(
if !ignore_event {
// consume event
emulate.consume(event, handle).await;
log::trace!("{event:?} => emulate");
log::trace!("{event} => emulate");
}
}
State::AwaitingLeave => {
Expand Down

0 comments on commit 633d2c3

Please sign in to comment.