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,