Skip to main content

automata_windows/
mouse.rs

1/// Type of mouse click to perform.
2#[derive(Debug, Clone, Copy)]
3pub enum ClickType {
4    Left,
5    Double,
6    Triple,
7    Right,
8    Middle,
9}
10
11/// Direction for a scroll wheel event.
12#[derive(Debug, Clone, Copy)]
13pub enum ScrollAxis {
14    Vertical,
15    Horizontal,
16}
17
18/// Move the mouse cursor to the given screen coordinates.
19/// Returns `false` if the system call failed (e.g. out of bounds).
20#[cfg(target_os = "windows")]
21pub fn move_cursor(x: i32, y: i32) -> bool {
22    use windows::Win32::UI::WindowsAndMessaging::SetCursorPos;
23    unsafe { SetCursorPos(x, y) }.is_ok()
24}
25
26#[cfg(not(target_os = "windows"))]
27pub fn move_cursor(_x: i32, _y: i32) -> bool {
28    false
29}
30
31/// Return the current screen coordinates of the mouse cursor.
32#[cfg(target_os = "windows")]
33pub fn get_cursor_pos() -> Option<(i32, i32)> {
34    use windows::Win32::Foundation::POINT;
35    use windows::Win32::UI::WindowsAndMessaging::GetCursorPos;
36    let mut pt = POINT { x: 0, y: 0 };
37    unsafe { GetCursorPos(&mut pt) }.ok().map(|_| (pt.x, pt.y))
38}
39
40#[cfg(not(target_os = "windows"))]
41pub fn get_cursor_pos() -> Option<(i32, i32)> {
42    None
43}
44
45/// Send a single scroll wheel tick via `SendInput`.
46///
47/// `clicks` is the number of wheel detents: positive scrolls up/left,
48/// negative scrolls down/right. Each detent is one `WHEEL_DELTA` (120 units).
49#[cfg(target_os = "windows")]
50pub fn scroll_wheel(axis: ScrollAxis, clicks: i32) {
51    use std::mem::size_of;
52    use windows::Win32::UI::Input::KeyboardAndMouse::{
53        INPUT, INPUT_0, INPUT_MOUSE, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_WHEEL, MOUSEINPUT, SendInput,
54    };
55
56    let flags = match axis {
57        ScrollAxis::Vertical => MOUSEEVENTF_WHEEL,
58        ScrollAxis::Horizontal => MOUSEEVENTF_HWHEEL,
59    };
60    let input = INPUT {
61        r#type: INPUT_MOUSE,
62        Anonymous: INPUT_0 {
63            mi: MOUSEINPUT {
64                dx: 0,
65                dy: 0,
66                mouseData: (clicks * 120) as u32,
67                dwFlags: flags,
68                time: 0,
69                dwExtraInfo: 0,
70            },
71        },
72    };
73    unsafe { SendInput(&[input], size_of::<INPUT>() as i32) };
74}
75
76#[cfg(not(target_os = "windows"))]
77pub fn scroll_wheel(_axis: ScrollAxis, _clicks: i32) {}