1#![allow(dead_code)]
2use crate::types::{keys::Keys, Point};
3use libloading::Library;
4use winapi::shared::windef::POINT;
5
6const MOUSEEVENTF_ABSOLUTE: i32 = 0x8000;
7const MOUSEEVENTF_MOVE: i32 = 0x1;
8const MOUSEEVENTF_WHEEL: i32 = 0x800;
9const MOUSEEVENTF_HWHEEL: i32 = 0x1000;
10const MOUSEEVENTF_LEFTDOWN: i32 = 0x2;
11const MOUSEEVENTF_LEFTUP: i32 = 0x4;
12const MOUSEEVENTF_RIGHTDOWN: i32 = 0x8;
13const MOUSEEVENTF_RIGHTUP: i32 = 0x10;
14const MOUSEEVENTF_MIDDLEDOWN: i32 = 0x20;
15const MOUSEEVENTF_MIDDLEUP: i32 = 0x40;
16const MOUSEEVENTF_XDOWN: i32 = 0x0080;
17const MOUSEEVENTF_XUP: i32 = 0x0100;
18
19fn win_translate_key(key: (&Keys, &Keys)) -> i32 {
20 match key {
21 (Keys::WHEEL, Keys::HORIZONTAL) => MOUSEEVENTF_HWHEEL,
22 (Keys::WHEEL, Keys::VERTICAL) => MOUSEEVENTF_WHEEL,
23
24 (Keys::DOWN, Keys::LEFT) => MOUSEEVENTF_LEFTDOWN,
25 (Keys::UP, Keys::LEFT) => MOUSEEVENTF_LEFTUP,
26
27 (Keys::DOWN, Keys::RIGHT) => MOUSEEVENTF_RIGHTDOWN,
28 (Keys::UP, Keys::RIGHT) => MOUSEEVENTF_RIGHTUP,
29
30 (Keys::DOWN, Keys::MIDDLE) => MOUSEEVENTF_MIDDLEDOWN,
31 (Keys::UP, Keys::MIDDLE) => MOUSEEVENTF_MIDDLEUP,
32
33 (Keys::DOWN, Keys::WHEEL) => MOUSEEVENTF_MIDDLEDOWN,
34 (Keys::UP, Keys::WHEEL) => MOUSEEVENTF_MIDDLEUP,
35
36 (Keys::DOWN, Keys::X) => MOUSEEVENTF_XDOWN,
37 (Keys::UP, Keys::X) => MOUSEEVENTF_XUP,
38 _ => panic!("Invalid parameter passed, please use constants from types::keys"),
39 }
40}
41
42impl From<POINT> for Point {
43 fn from(other: POINT) -> Point {
44 Point {
45 x: other.x as _,
46 y: other.y as _,
47 }
48 }
49}
50
51pub struct Mouse {
52 user32: Library,
53}
54
55#[allow(unreachable_code, unused_variables)]
56impl Mouse {
57 fn translate_button(button: &Keys) -> (&Keys, i32) {
58 return match button {
59 Keys::X => (&Keys::X, 0x10000),
60 Keys::X2 => (&Keys::X2, 0x20000),
61 _ => (button, 0),
62 };
63 }
64
65 fn mouse_event(
66 &self,
67 dw_flags: i32,
68 dx: i32,
69 dy: i32,
70 dw_data: i32,
71 dw_extra_info: i32,
72 ) -> Result<(), Box<dyn std::error::Error>> {
73 unsafe {
74 let mouse_event: libloading::Symbol<
75 unsafe extern "C" fn(
76 dw_flags: i32,
77 dx: i32,
78 dy: i32,
79 dw_data: i32,
80 dw_extra_info: i32,
81 ),
82 > = self.user32.get(b"mouse_event")?;
83 Ok(mouse_event(dw_flags, dx, dy, dw_data, dw_extra_info))
84 }
85 }
86
87 pub fn new() -> Mouse {
88 Mouse {
89 user32: libloading::Library::new("user32").unwrap(),
90 }
91 }
92
93 pub fn move_to(&self, x: i32, y: i32) -> Result<(), Box<dyn std::error::Error>> {
94 unsafe {
95 let set_cursor_pos: libloading::Symbol<unsafe extern "C" fn(x: i32, y: i32)> =
96 self.user32.get(b"SetCursorPos")?;
97 Ok(set_cursor_pos(x, y))
98 }
99 }
100
101 pub fn press(&self, button: &Keys) -> Result<(), Box<dyn std::error::Error>> {
102 let (button, data) = Mouse::translate_button(button);
103 let code = win_translate_key((&Keys::DOWN, button));
104 self.mouse_event(code, 0, 0, data, 0)
105 }
106
107 pub fn release(&self, button: &Keys) -> Result<(), Box<dyn std::error::Error>> {
108 let (button, data) = Mouse::translate_button(button);
109 let code = win_translate_key((&Keys::UP, button));
110 self.mouse_event(code, 0, 0, data, 0)
111 }
112
113 pub fn get_position(&self) -> Result<Point, Box<dyn std::error::Error>> {
114 let mut pos: POINT = POINT { x: 0, y: 0 };
115 unsafe {
116 let get_cursor_pos: libloading::Symbol<unsafe extern "C" fn(lp_point: &POINT) -> bool> =
117 self.user32.get(b"GetCursorPos")?;
118 get_cursor_pos(&mut pos);
119 Ok(pos.into())
120 }
121 }
122
123 pub fn wheel(&self, delta: i32) -> Result<(), Box<dyn std::error::Error>> {
124 let code = win_translate_key((&Keys::WHEEL, &Keys::VERTICAL));
125 self.mouse_event(code, 0, 0, delta * 120, 0)
126 }
127}