From 633d2c346e2b30ef0cb1448d471aa8aec14efaf9 Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Fri, 12 Apr 2024 15:28:05 +0200 Subject: [PATCH] windows: impl back and forward mouse buttons --- src/capture/windows.rs | 27 ++++++++++++++++++++++++--- src/emulate/windows.rs | 29 +++++++++++++++++++++-------- src/event.rs | 16 +++++++++++++++- src/server/emulation_task.rs | 2 +- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/capture/windows.rs b/src/capture/windows.rs index 2ace4c0..ae4f9ea 100644 --- a/src/capture/windows.rs +++ b/src/capture/windows.rs @@ -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, @@ -142,7 +144,26 @@ fn to_mouse_event(wparam: WPARAM, lparam: LPARAM) -> Option { 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 + } } } diff --git a/src/emulate/windows.rs b/src/emulate/windows.rs index b01e15b..f71a298 100644 --- a/src/emulate/windows.rs +++ b/src/emulate/windows.rs @@ -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, @@ -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, diff --git a/src/event.rs b/src/event.rs index e785587..fea25c3 100644 --- a/src/event.rs +++ b/src/event.rs @@ -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, diff --git a/src/server/emulation_task.rs b/src/server/emulation_task.rs index ee30d68..6ac7c38 100644 --- a/src/server/emulation_task.rs +++ b/src/server/emulation_task.rs @@ -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 => {