refactoring

This commit is contained in:
crusader 2020-12-17 00:04:14 +09:00
parent 02355fa511
commit fbf3946f59
3 changed files with 351 additions and 379 deletions

View File

@ -5,13 +5,8 @@ pub use crate::windows::*;
use crate::keyboard::Key; use crate::keyboard::Key;
use crate::mouse::Button; use crate::mouse::Button;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{
collections::hash_map::HashMap,
sync::{Arc, Mutex},
time::SystemTime,
};
pub mod keyboard; pub mod keyboard;
pub mod mouse; pub mod mouse;
@ -31,61 +26,61 @@ pub enum EventType {
MouseMoveTo { x: f64, y: f64 }, MouseMoveTo { x: f64, y: f64 },
} }
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] // #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Event { // pub struct Event {
pub time: SystemTime, // pub time: SystemTime,
pub event_type: EventType, // pub event_type: EventType,
} // }
pub enum BlockInput { // pub enum BlockInput {
Block, // Block,
DontBlock, // DontBlock,
} // }
pub enum Bind { // pub enum Bind {
NormalBind(BindHandler), // NormalBind(BindHandler),
BlockBind(BlockBindHandler), // BlockBind(BlockBindHandler),
BlockableBind(BlockableBindHandler), // BlockableBind(BlockableBindHandler),
} // }
pub type BindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>; // pub type BindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
pub type BlockBindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>; // pub type BlockBindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
pub type BlockableBindHandler = Arc<dyn Fn(Event) -> BlockInput + Send + Sync + 'static>; // pub type BlockableBindHandler = Arc<dyn Fn(Event) -> BlockInput + Send + Sync + 'static>;
pub type EventBindMap = HashMap<EventListenType, Bind>; // pub type EventBindMap = HashMap<EventListenType, Bind>;
pub static EVENT_BINDS: Lazy<Mutex<EventBindMap>> = Lazy::new(|| Mutex::new(EventBindMap::new())); // pub static EVENT_BINDS: Lazy<Mutex<EventBindMap>> = Lazy::new(|| Mutex::new(EventBindMap::new()));
pub struct Robot; pub struct Robot;
impl Robot { // impl Robot {
pub fn bind<F: Fn(Event) + Send + Sync + 'static>(listen_type: EventListenType, callback: F) { // pub fn bind<F: Fn(Event) + Send + Sync + 'static>(listen_type: EventListenType, callback: F) {
EVENT_BINDS // EVENT_BINDS
.lock() // .lock()
.unwrap() // .unwrap()
.insert(listen_type, Bind::NormalBind(Arc::new(callback))); // .insert(listen_type, Bind::NormalBind(Arc::new(callback)));
} // }
pub fn block_bind<F: Fn(Event) + Send + Sync + 'static>( // pub fn block_bind<F: Fn(Event) + Send + Sync + 'static>(
listen_type: EventListenType, // listen_type: EventListenType,
callback: F, // callback: F,
) { // ) {
EVENT_BINDS // EVENT_BINDS
.lock() // .lock()
.unwrap() // .unwrap()
.insert(listen_type, Bind::BlockBind(Arc::new(callback))); // .insert(listen_type, Bind::BlockBind(Arc::new(callback)));
} // }
pub fn blockable_bind<F: Fn(Event) -> BlockInput + Send + Sync + 'static>( // pub fn blockable_bind<F: Fn(Event) -> BlockInput + Send + Sync + 'static>(
listen_type: EventListenType, // listen_type: EventListenType,
callback: F, // callback: F,
) { // ) {
EVENT_BINDS // EVENT_BINDS
.lock() // .lock()
.unwrap() // .unwrap()
.insert(listen_type, Bind::BlockableBind(Arc::new(callback))); // .insert(listen_type, Bind::BlockableBind(Arc::new(callback)));
} // }
pub fn unbind(listen_type: EventListenType) { // pub fn unbind(listen_type: EventListenType) {
EVENT_BINDS.lock().unwrap().remove(&listen_type); // EVENT_BINDS.lock().unwrap().remove(&listen_type);
} // }
} // }

View File

@ -1,25 +1,15 @@
use crate::windows; use crate::{Key, Robot};
use crate::{Bind, BlockInput, Event, EventListenType, EventType, Key, Robot, EVENT_BINDS};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{ use std::{
collections::HashMap, collections::HashMap,
mem::{size_of, transmute_copy}, mem::{size_of, transmute_copy},
ptr::null_mut,
sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
thread::spawn,
time::SystemTime,
}; };
use winapi::ctypes::c_int; use winapi::ctypes::c_int;
use winapi::shared::minwindef::{LPARAM, LRESULT, WORD, WPARAM}; use winapi::shared::minwindef::WORD;
use winapi::shared::windef::HHOOK__;
use winapi::um::winuser::{ use winapi::um::winuser::{
CallNextHookEx, GetAsyncKeyState, GetKeyState, MapVirtualKeyW, SendInput, HC_ACTION, INPUT, GetAsyncKeyState, GetKeyState, MapVirtualKeyW, SendInput, INPUT, INPUT_KEYBOARD, KEYBDINPUT,
INPUT_KEYBOARD, KBDLLHOOKSTRUCT, KEYBDINPUT, KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE, LPINPUT, KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE, LPINPUT,
WH_KEYBOARD_LL, WM_KEYDOWN, WM_KEYUP,
}; };
static KEY_2_VK_MAP: Lazy<HashMap<Key, WORD>> = Lazy::new(|| { static KEY_2_VK_MAP: Lazy<HashMap<Key, WORD>> = Lazy::new(|| {
@ -144,151 +134,151 @@ static KEY_2_VK_MAP: Lazy<HashMap<Key, WORD>> = Lazy::new(|| {
m m
}); });
static VK_2_KEY_MAP: Lazy<HashMap<WORD, Key>> = Lazy::new(|| { // static VK_2_KEY_MAP: Lazy<HashMap<WORD, Key>> = Lazy::new(|| {
let mut m = HashMap::new(); // let mut m = HashMap::new();
m.insert(0x30, Key::Digit0); // m.insert(0x30, Key::Digit0);
m.insert(0x31, Key::Digit1); // m.insert(0x31, Key::Digit1);
m.insert(0x32, Key::Digit2); // m.insert(0x32, Key::Digit2);
m.insert(0x33, Key::Digit3); // m.insert(0x33, Key::Digit3);
m.insert(0x34, Key::Digit4); // m.insert(0x34, Key::Digit4);
m.insert(0x35, Key::Digit5); // m.insert(0x35, Key::Digit5);
m.insert(0x36, Key::Digit6); // m.insert(0x36, Key::Digit6);
m.insert(0x37, Key::Digit7); // m.insert(0x37, Key::Digit7);
m.insert(0x38, Key::Digit8); // m.insert(0x38, Key::Digit8);
m.insert(0x39, Key::Digit9); // m.insert(0x39, Key::Digit9);
m.insert(0x41, Key::KeyA); // m.insert(0x41, Key::KeyA);
m.insert(0x42, Key::KeyB); // m.insert(0x42, Key::KeyB);
m.insert(0x43, Key::KeyC); // m.insert(0x43, Key::KeyC);
m.insert(0x44, Key::KeyD); // m.insert(0x44, Key::KeyD);
m.insert(0x45, Key::KeyE); // m.insert(0x45, Key::KeyE);
m.insert(0x46, Key::KeyF); // m.insert(0x46, Key::KeyF);
m.insert(0x47, Key::KeyG); // m.insert(0x47, Key::KeyG);
m.insert(0x48, Key::KeyH); // m.insert(0x48, Key::KeyH);
m.insert(0x49, Key::KeyI); // m.insert(0x49, Key::KeyI);
m.insert(0x4A, Key::KeyJ); // m.insert(0x4A, Key::KeyJ);
m.insert(0x4B, Key::KeyK); // m.insert(0x4B, Key::KeyK);
m.insert(0x4C, Key::KeyL); // m.insert(0x4C, Key::KeyL);
m.insert(0x4D, Key::KeyM); // m.insert(0x4D, Key::KeyM);
m.insert(0x4E, Key::KeyN); // m.insert(0x4E, Key::KeyN);
m.insert(0x4F, Key::KeyO); // m.insert(0x4F, Key::KeyO);
m.insert(0x50, Key::KeyP); // m.insert(0x50, Key::KeyP);
m.insert(0x51, Key::KeyQ); // m.insert(0x51, Key::KeyQ);
m.insert(0x52, Key::KeyR); // m.insert(0x52, Key::KeyR);
m.insert(0x53, Key::KeyS); // m.insert(0x53, Key::KeyS);
m.insert(0x54, Key::KeyT); // m.insert(0x54, Key::KeyT);
m.insert(0x55, Key::KeyU); // m.insert(0x55, Key::KeyU);
m.insert(0x56, Key::KeyV); // m.insert(0x56, Key::KeyV);
m.insert(0x57, Key::KeyW); // m.insert(0x57, Key::KeyW);
m.insert(0x58, Key::KeyX); // m.insert(0x58, Key::KeyX);
m.insert(0x59, Key::KeyY); // m.insert(0x59, Key::KeyY);
m.insert(0x5A, Key::KeyZ); // m.insert(0x5A, Key::KeyZ);
m.insert(0x70, Key::F1); // m.insert(0x70, Key::F1);
m.insert(0x71, Key::F2); // m.insert(0x71, Key::F2);
m.insert(0x72, Key::F3); // m.insert(0x72, Key::F3);
m.insert(0x73, Key::F4); // m.insert(0x73, Key::F4);
m.insert(0x74, Key::F5); // m.insert(0x74, Key::F5);
m.insert(0x75, Key::F6); // m.insert(0x75, Key::F6);
m.insert(0x76, Key::F7); // m.insert(0x76, Key::F7);
m.insert(0x77, Key::F8); // m.insert(0x77, Key::F8);
m.insert(0x78, Key::F9); // m.insert(0x78, Key::F9);
m.insert(0x79, Key::F10); // m.insert(0x79, Key::F10);
m.insert(0x7A, Key::F11); // m.insert(0x7A, Key::F11);
m.insert(0x7B, Key::F12); // m.insert(0x7B, Key::F12);
m.insert(0x7C, Key::F13); // m.insert(0x7C, Key::F13);
m.insert(0x7D, Key::F14); // m.insert(0x7D, Key::F14);
m.insert(0x7E, Key::F15); // m.insert(0x7E, Key::F15);
m.insert(0x7F, Key::F16); // m.insert(0x7F, Key::F16);
m.insert(0x80, Key::F17); // m.insert(0x80, Key::F17);
m.insert(0x81, Key::F18); // m.insert(0x81, Key::F18);
m.insert(0x82, Key::F19); // m.insert(0x82, Key::F19);
m.insert(0x83, Key::F20); // m.insert(0x83, Key::F20);
m.insert(0x84, Key::F21); // m.insert(0x84, Key::F21);
m.insert(0x85, Key::F22); // m.insert(0x85, Key::F22);
m.insert(0x86, Key::F23); // m.insert(0x86, Key::F23);
m.insert(0x87, Key::F24); // m.insert(0x87, Key::F24);
m.insert(0x60, Key::Numpad0); // m.insert(0x60, Key::Numpad0);
m.insert(0x61, Key::Numpad1); // m.insert(0x61, Key::Numpad1);
m.insert(0x62, Key::Numpad2); // m.insert(0x62, Key::Numpad2);
m.insert(0x63, Key::Numpad3); // m.insert(0x63, Key::Numpad3);
m.insert(0x64, Key::Numpad4); // m.insert(0x64, Key::Numpad4);
m.insert(0x65, Key::Numpad5); // m.insert(0x65, Key::Numpad5);
m.insert(0x66, Key::Numpad6); // m.insert(0x66, Key::Numpad6);
m.insert(0x67, Key::Numpad7); // m.insert(0x67, Key::Numpad7);
m.insert(0x68, Key::Numpad8); // m.insert(0x68, Key::Numpad8);
m.insert(0x69, Key::Numpad9); // m.insert(0x69, Key::Numpad9);
m.insert(0x6B, Key::NumpadAdd); // Add // m.insert(0x6B, Key::NumpadAdd); // Add
m.insert(0x6D, Key::NumpadSubtract); // Subtract // m.insert(0x6D, Key::NumpadSubtract); // Subtract
m.insert(0x6A, Key::NumpadMultiply); // Multiply // m.insert(0x6A, Key::NumpadMultiply); // Multiply
m.insert(0x6F, Key::NumpadDivide); // Divide // m.insert(0x6F, Key::NumpadDivide); // Divide
m.insert(0x6E, Key::NumpadDecimal); // Decimal // m.insert(0x6E, Key::NumpadDecimal); // Decimal
m.insert(0x0D, Key::NumpadEnter); // m.insert(0x0D, Key::NumpadEnter);
m.insert(0x90, Key::NumLock); // m.insert(0x90, Key::NumLock);
m.insert('-' as u16, Key::Minus); // m.insert('-' as u16, Key::Minus);
m.insert('=' as u16, Key::Equal); // m.insert('=' as u16, Key::Equal);
m.insert('{' as u16, Key::BracketLeft); // m.insert('{' as u16, Key::BracketLeft);
m.insert('}' as u16, Key::BracketRight); // m.insert('}' as u16, Key::BracketRight);
m.insert(';' as u16, Key::Semicolon); // m.insert(';' as u16, Key::Semicolon);
m.insert('\'' as u16, Key::Quote); // m.insert('\'' as u16, Key::Quote);
m.insert('`' as u16, Key::Backquote); // m.insert('`' as u16, Key::Backquote);
m.insert('\\' as u16, Key::Backslash); // m.insert('\\' as u16, Key::Backslash);
m.insert(',' as u16, Key::Comma); // m.insert(',' as u16, Key::Comma);
m.insert('~' as u16, Key::Period); // m.insert('~' as u16, Key::Period);
m.insert('/' as u16, Key::Slash); // m.insert('/' as u16, Key::Slash);
m.insert(0x1B, Key::Escape); // m.insert(0x1B, Key::Escape);
m.insert(0x0D, Key::Enter); // m.insert(0x0D, Key::Enter);
m.insert(0x08, Key::Backspace); // m.insert(0x08, Key::Backspace);
m.insert(0x09, Key::Tab); // m.insert(0x09, Key::Tab);
m.insert(0x20, Key::Space); // m.insert(0x20, Key::Space);
m.insert(0x14, Key::CapsLock); // m.insert(0x14, Key::CapsLock);
m.insert(0xA0, Key::ShiftLeft); // m.insert(0xA0, Key::ShiftLeft);
m.insert(0xA1, Key::ShiftRight); // m.insert(0xA1, Key::ShiftRight);
m.insert(0xA2, Key::ControlLeft); // m.insert(0xA2, Key::ControlLeft);
m.insert(0xA3, Key::ControlRight); // m.insert(0xA3, Key::ControlRight);
m.insert(0xA4, Key::AltLeft); // m.insert(0xA4, Key::AltLeft);
m.insert(0xA5, Key::AltRight); // m.insert(0xA5, Key::AltRight);
m.insert(0x13, Key::Pause); // m.insert(0x13, Key::Pause);
m.insert(0x91, Key::ScrollLock); // m.insert(0x91, Key::ScrollLock);
m.insert(0x2C, Key::PrintScreen); // m.insert(0x2C, Key::PrintScreen);
m.insert(0x25, Key::ArrowLeft); // m.insert(0x25, Key::ArrowLeft);
m.insert(0x26, Key::ArrowUp); // m.insert(0x26, Key::ArrowUp);
m.insert(0x27, Key::ArrowRight); // m.insert(0x27, Key::ArrowRight);
m.insert(0x28, Key::ArrowDown); // m.insert(0x28, Key::ArrowDown);
m.insert(0x21, Key::PageUp); // m.insert(0x21, Key::PageUp);
m.insert(0x22, Key::PageDown); // m.insert(0x22, Key::PageDown);
m.insert(0x24, Key::Home); // m.insert(0x24, Key::Home);
m.insert(0x23, Key::End); // m.insert(0x23, Key::End);
m.insert(0x2D, Key::Insert); // m.insert(0x2D, Key::Insert);
m.insert(0x2E, Key::Delete); // m.insert(0x2E, Key::Delete);
m.insert(0x5B, Key::MetaLeft); // m.insert(0x5B, Key::MetaLeft);
m.insert(0x5C, Key::MetaRight); // m.insert(0x5C, Key::MetaRight);
m // m
}); // });
static KEYBOARD_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default); // static KEYBOARD_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
impl Robot { impl Robot {
pub unsafe fn key_listen() -> Result<(), windows::HookError> { // pub unsafe fn key_listen() -> Result<(), windows::HookError> {
if KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() { // if KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::hook(WH_KEYBOARD_LL, &*KEYBOARD_HHOOK, Self::key_raw_callback); // let r = windows::hook(WH_KEYBOARD_LL, &*KEYBOARD_HHOOK, Self::key_raw_callback);
if r.is_err() { // if r.is_err() {
return Err(windows::HookError::Keyboard(r.err().unwrap())); // return Err(windows::HookError::Keyboard(r.err().unwrap()));
} // }
} // }
Ok(()) // Ok(())
} // }
pub unsafe fn key_unlisten() -> Result<(), windows::HookError> { // pub unsafe fn key_unlisten() -> Result<(), windows::HookError> {
if !KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() { // if !KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::unhook(&*KEYBOARD_HHOOK); // let r = windows::unhook(&*KEYBOARD_HHOOK);
if r.is_err() { // if r.is_err() {
return Err(windows::HookError::Keyboard(r.err().unwrap())); // return Err(windows::HookError::Keyboard(r.err().unwrap()));
} // }
} // }
Ok(()) // Ok(())
} // }
pub fn key_press(key: Key) { pub fn key_press(key: Key) {
let dw_flags = KEYEVENTF_SCANCODE; let dw_flags = KEYEVENTF_SCANCODE;
@ -339,63 +329,63 @@ impl Robot {
} }
} }
unsafe fn get_virtual_key(lpdata: isize) -> u32 { // unsafe fn get_virtual_key(lpdata: isize) -> u32 {
let kb = *(lpdata as *const KBDLLHOOKSTRUCT); // let kb = *(lpdata as *const KBDLLHOOKSTRUCT);
kb.vkCode // kb.vkCode
} // }
unsafe extern "system" fn key_raw_callback( // unsafe extern "system" fn key_raw_callback(
code: c_int, // code: c_int,
w_param: WPARAM, // w_param: WPARAM,
l_param: LPARAM, // l_param: LPARAM,
) -> LRESULT { // ) -> LRESULT {
if code == HC_ACTION { // if code == HC_ACTION {
let opt = match w_param as u32 { // let opt = match w_param as u32 {
WM_KEYDOWN => { // WM_KEYDOWN => {
let code = Self::get_virtual_key(l_param); // let code = Self::get_virtual_key(l_param);
match Self::virtual_key_2_key(code as u16) { // match Self::virtual_key_2_key(code as u16) {
Some(k) => Some(EventType::KeyPress(k)), // Some(k) => Some(EventType::KeyPress(k)),
None => None, // None => None,
} // }
} // }
WM_KEYUP => { // WM_KEYUP => {
let code = Self::get_virtual_key(l_param); // let code = Self::get_virtual_key(l_param);
match Self::virtual_key_2_key(code as u16) { // match Self::virtual_key_2_key(code as u16) {
Some(k) => Some(EventType::KeyRelease(k)), // Some(k) => Some(EventType::KeyRelease(k)),
None => None, // None => None,
} // }
} // }
_ => None, // _ => None,
}; // };
if let Some(event_type) = opt { // if let Some(event_type) = opt {
let event = Event { // let event = Event {
event_type, // event_type,
time: SystemTime::now(), // time: SystemTime::now(),
}; // };
if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) { // if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
match bind { // match bind {
Bind::NormalBind(cb) => { // Bind::NormalBind(cb) => {
let cb = Arc::clone(cb); // let cb = Arc::clone(cb);
spawn(move || cb(event)); // spawn(move || cb(event));
} // }
Bind::BlockBind(cb) => { // Bind::BlockBind(cb) => {
let cb = Arc::clone(cb); // let cb = Arc::clone(cb);
spawn(move || cb(event)); // spawn(move || cb(event));
return 1; // return 1;
} // }
Bind::BlockableBind(cb) => { // Bind::BlockableBind(cb) => {
if let BlockInput::Block = cb(event) { // if let BlockInput::Block = cb(event) {
return 1; // return 1;
} // }
} // }
} // }
} // }
} // }
} // }
CallNextHookEx(null_mut(), code, w_param, l_param) // CallNextHookEx(null_mut(), code, w_param, l_param)
} // }
fn key_2_virtual_key(key: Key) -> Option<WORD> { fn key_2_virtual_key(key: Key) -> Option<WORD> {
match KEY_2_VK_MAP.get(&key) { match KEY_2_VK_MAP.get(&key) {
@ -404,10 +394,10 @@ impl Robot {
} }
} }
fn virtual_key_2_key(virtual_key: WORD) -> Option<Key> { // fn virtual_key_2_key(virtual_key: WORD) -> Option<Key> {
match VK_2_KEY_MAP.get(&virtual_key) { // match VK_2_KEY_MAP.get(&virtual_key) {
Some(v) => Some(*v), // Some(v) => Some(*v),
None => None, // None => None,
} // }
} // }
} }

View File

@ -1,55 +1,42 @@
use crate::windows; use crate::{Button, EventType, Robot};
use crate::{Bind, BlockInput, Button, Event, EventListenType, EventType, Robot, EVENT_BINDS}; use std::mem::{size_of, transmute};
use once_cell::sync::Lazy;
use std::{
mem::{size_of, transmute},
ptr::null_mut,
sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
thread::spawn,
time::SystemTime,
};
use winapi::ctypes::c_int; use winapi::ctypes::c_int;
use winapi::shared::minwindef::{DWORD, HIWORD, LPARAM, LRESULT, WPARAM}; use winapi::shared::minwindef::DWORD;
use winapi::shared::windef::{HHOOK__, POINT}; use winapi::shared::windef::POINT;
use winapi::um::winuser::{ use winapi::um::winuser::{
CallNextHookEx, GetAsyncKeyState, GetCursorPos, GetSystemMetrics, SendInput, HC_ACTION, INPUT, GetAsyncKeyState, GetCursorPos, GetSystemMetrics, SendInput, INPUT, INPUT_MOUSE, LPINPUT,
INPUT_MOUSE, LPINPUT, MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP,
MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_MOVE, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_MOVE, MOUSEEVENTF_RIGHTDOWN,
MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_VIRTUALDESK, MOUSEEVENTF_WHEEL, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_VIRTUALDESK, MOUSEEVENTF_WHEEL, MOUSEINPUT, SM_CXVIRTUALSCREEN,
MOUSEINPUT, MSLLHOOKSTRUCT, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, VK_LBUTTON, VK_MBUTTON, VK_RBUTTON,
SM_YVIRTUALSCREEN, VK_LBUTTON, VK_MBUTTON, VK_RBUTTON, VK_XBUTTON1, VK_XBUTTON2, WH_MOUSE_LL, VK_XBUTTON1, VK_XBUTTON2,
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEMOVE, WM_RBUTTONDOWN,
WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
}; };
static MOUSE_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default); // static MOUSE_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
impl Robot { impl Robot {
pub unsafe fn mouse_listen() -> Result<(), windows::HookError> { // pub unsafe fn mouse_listen() -> Result<(), windows::HookError> {
if MOUSE_HHOOK.load(Ordering::Relaxed).is_null() { // if MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::hook(WH_MOUSE_LL, &*MOUSE_HHOOK, Self::mouse_raw_callback); // let r = windows::hook(WH_MOUSE_LL, &*MOUSE_HHOOK, Self::mouse_raw_callback);
if r.is_err() { // if r.is_err() {
return Err(windows::HookError::Mouse(r.err().unwrap())); // return Err(windows::HookError::Mouse(r.err().unwrap()));
} // }
} // }
Ok(()) // Ok(())
} // }
pub unsafe fn mouse_unlisten() -> Result<(), windows::HookError> { // pub unsafe fn mouse_unlisten() -> Result<(), windows::HookError> {
if !MOUSE_HHOOK.load(Ordering::Relaxed).is_null() { // if !MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::unhook(&*MOUSE_HHOOK); // let r = windows::unhook(&*MOUSE_HHOOK);
if r.is_err() { // if r.is_err() {
return Err(windows::HookError::Mouse(r.err().unwrap())); // return Err(windows::HookError::Mouse(r.err().unwrap()));
} // }
} // }
Ok(()) // Ok(())
} // }
pub fn mouse_location() -> (i32, i32) { pub fn mouse_location() -> (i32, i32) {
let mut point = POINT { x: 0, y: 0 }; let mut point = POINT { x: 0, y: 0 };
@ -169,79 +156,79 @@ impl Robot {
} }
} }
unsafe fn get_mouse_point(lpdata: isize) -> (i32, i32) { // unsafe fn get_mouse_point(lpdata: isize) -> (i32, i32) {
let mouse = *(lpdata as *const MSLLHOOKSTRUCT); // let mouse = *(lpdata as *const MSLLHOOKSTRUCT);
(mouse.pt.x, mouse.pt.y) // (mouse.pt.x, mouse.pt.y)
} // }
#[allow(non_snake_case)] // #[allow(non_snake_case)]
unsafe extern "system" fn mouse_raw_callback( // unsafe extern "system" fn mouse_raw_callback(
code: c_int, // code: c_int,
w_param: WPARAM, // w_param: WPARAM,
l_param: LPARAM, // l_param: LPARAM,
) -> LRESULT { // ) -> LRESULT {
if code == HC_ACTION { // if code == HC_ACTION {
let opt = match w_param as u32 { // let opt = match w_param as u32 {
WM_LBUTTONDOWN => Some(EventType::MousePress(Button::Left)), // WM_LBUTTONDOWN => Some(EventType::MousePress(Button::Left)),
WM_LBUTTONUP => Some(EventType::MouseRelease(Button::Left)), // WM_LBUTTONUP => Some(EventType::MouseRelease(Button::Left)),
WM_MBUTTONDOWN => Some(EventType::MousePress(Button::Middle)), // WM_MBUTTONDOWN => Some(EventType::MousePress(Button::Middle)),
WM_MBUTTONUP => Some(EventType::MouseRelease(Button::Middle)), // WM_MBUTTONUP => Some(EventType::MouseRelease(Button::Middle)),
WM_RBUTTONDOWN => Some(EventType::MousePress(Button::Right)), // WM_RBUTTONDOWN => Some(EventType::MousePress(Button::Right)),
WM_RBUTTONUP => Some(EventType::MouseRelease(Button::Right)), // WM_RBUTTONUP => Some(EventType::MouseRelease(Button::Right)),
WM_XBUTTONDOWN => { // WM_XBUTTONDOWN => {
let llhs = &*(l_param as *const MSLLHOOKSTRUCT); // let llhs = &*(l_param as *const MSLLHOOKSTRUCT);
match HIWORD(llhs.mouseData) { // match HIWORD(llhs.mouseData) {
XBUTTON1 => Some(EventType::MousePress(Button::X1)), // XBUTTON1 => Some(EventType::MousePress(Button::X1)),
XBUTTON2 => Some(EventType::MousePress(Button::X2)), // XBUTTON2 => Some(EventType::MousePress(Button::X2)),
_ => None, // _ => None,
} // }
} // }
WM_XBUTTONUP => { // WM_XBUTTONUP => {
let llhs = &*(l_param as *const MSLLHOOKSTRUCT); // let llhs = &*(l_param as *const MSLLHOOKSTRUCT);
match HIWORD(llhs.mouseData) { // match HIWORD(llhs.mouseData) {
XBUTTON1 => Some(EventType::MouseRelease(Button::X1)), // XBUTTON1 => Some(EventType::MouseRelease(Button::X1)),
XBUTTON2 => Some(EventType::MouseRelease(Button::X2)), // XBUTTON2 => Some(EventType::MouseRelease(Button::X2)),
_ => None, // _ => None,
} // }
} // }
WM_MOUSEMOVE => { // WM_MOUSEMOVE => {
let (x, y) = Self::get_mouse_point(l_param); // let (x, y) = Self::get_mouse_point(l_param);
Some(EventType::MouseMoveTo { // Some(EventType::MouseMoveTo {
x: x as f64, // x: x as f64,
y: y as f64, // y: y as f64,
}) // })
} // }
_ => None, // _ => None,
}; // };
if let Some(event_type) = opt { // if let Some(event_type) = opt {
let event = Event { // let event = Event {
event_type, // event_type,
time: SystemTime::now(), // time: SystemTime::now(),
}; // };
if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) { // if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
match bind { // match bind {
Bind::NormalBind(cb) => { // Bind::NormalBind(cb) => {
let cb = Arc::clone(cb); // let cb = Arc::clone(cb);
spawn(move || cb(event)); // spawn(move || cb(event));
} // }
Bind::BlockBind(cb) => { // Bind::BlockBind(cb) => {
let cb = Arc::clone(cb); // let cb = Arc::clone(cb);
spawn(move || cb(event)); // spawn(move || cb(event));
return 1; // return 1;
} // }
Bind::BlockableBind(cb) => { // Bind::BlockableBind(cb) => {
if let BlockInput::Block = cb(event) { // if let BlockInput::Block = cb(event) {
return 1; // return 1;
} // }
} // }
} // }
} // }
} // }
} // }
CallNextHookEx(null_mut(), code, w_param, l_param) // CallNextHookEx(null_mut(), code, w_param, l_param)
} // }
} }