refactoring
This commit is contained in:
parent
02355fa511
commit
fbf3946f59
103
src/lib.rs
103
src/lib.rs
|
@ -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);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -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,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user