diff --git a/Cargo.lock b/Cargo.lock index 672ed401..9eea32d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1258,7 +1258,7 @@ dependencies = [ "wayland-protocols", "wayland-protocols-misc", "wayland-protocols-wlr", - "winapi", + "windows", "x11", ] @@ -2309,6 +2309,35 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-result" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" +dependencies = [ + "windows-targets 0.52.4", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 84291d93..89be667c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ reis = { version = "0.2", features = [ "tokio" ], optional = true } core-graphics = { version = "0.23", features = ["highsierra"] } [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.9", features = ["winuser"] } +windows = { version = "0.54.0", features = [ "Win32_UI_Input_KeyboardAndMouse" ] } [build-dependencies] glib-build-tools = "0.19.0" diff --git a/src/emulate/windows.rs b/src/emulate/windows.rs index d21ace18..b01e15ba 100644 --- a/src/emulate/windows.rs +++ b/src/emulate/windows.rs @@ -5,17 +5,15 @@ use crate::{ }; use anyhow::Result; use async_trait::async_trait; +use std::ops::BitOrAssign; use std::time::Duration; use tokio::task::AbortHandle; -use winapi::um::winuser::{SendInput, KEYEVENTF_EXTENDEDKEY}; -use winapi::{ - self, - um::winuser::{ - INPUT, INPUT_KEYBOARD, INPUT_MOUSE, KEYBDINPUT, KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE, - LPINPUT, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, - MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_MOVE, MOUSEEVENTF_RIGHTDOWN, - MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_WHEEL, MOUSEINPUT, - }, +use windows::Win32::UI::Input::KeyboardAndMouse::{SendInput, INPUT_0, KEYEVENTF_EXTENDEDKEY}; +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 crate::{ @@ -108,21 +106,30 @@ impl WindowsEmulation { } } -fn send_mouse_input(mi: MOUSEINPUT) { +fn send_input_safe(input: INPUT) { unsafe { - let mut input = INPUT { - type_: INPUT_MOUSE, - u: std::mem::transmute(mi), - }; - - SendInput( - 1_u32, - &mut input as LPINPUT, - std::mem::size_of::() as i32, - ); + loop { + /* retval = number of successfully submitted events */ + if SendInput(&[input], std::mem::size_of::() as i32) > 0 { + break; + } + } } } +fn send_mouse_input(mi: MOUSEINPUT) { + send_input_safe(INPUT { + r#type: INPUT_MOUSE, + Anonymous: INPUT_0 { mi }, + }); +} + +fn send_keyboard_input(ki: KEYBDINPUT) { + send_input_safe(INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { ki }, + }); +} fn rel_mouse(dx: i32, dy: i32) { let mi = MOUSEINPUT { dx, @@ -186,33 +193,23 @@ fn key_event(key: u32, state: u8) { }; let extended = scancode > 0xff; let scancode = scancode & 0xff; + let mut flags = KEYEVENTF_SCANCODE; + if extended { + flags.bitor_assign(KEYEVENTF_EXTENDEDKEY); + } + if state == 0 { + flags.bitor_assign(KEYEVENTF_KEYUP); + } let ki = KEYBDINPUT { - wVk: 0, + wVk: Default::default(), wScan: scancode, - dwFlags: KEYEVENTF_SCANCODE - | if extended { KEYEVENTF_EXTENDEDKEY } else { 0 } - | match state { - 0 => KEYEVENTF_KEYUP, - 1 => 0u32, - _ => return, - }, + dwFlags: flags, time: 0, dwExtraInfo: 0, }; send_keyboard_input(ki); } -fn send_keyboard_input(ki: KEYBDINPUT) { - unsafe { - let mut input = INPUT { - type_: INPUT_KEYBOARD, - u: std::mem::zeroed(), - }; - *input.u.ki_mut() = ki; - SendInput(1_u32, &mut input, std::mem::size_of::() as i32); - } -} - fn linux_keycode_to_windows_scancode(linux_keycode: u32) -> Option { let linux_scancode = match scancode::Linux::try_from(linux_keycode) { Ok(s) => s,