use std::{
ffi::c_void,
ptr::null_mut,
sync::{
Once,
atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering},
},
};
use windows::Win32::UI::HiDpi::{
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, SetProcessDpiAwarenessContext,
};
pub static IS_CORE_RUNNING: AtomicBool = AtomicBool::new(false);
pub static IS_LISTEN_RUNNING: AtomicBool = AtomicBool::new(false);
pub static IS_GRAB_RUNNING: AtomicBool = AtomicBool::new(false);
pub static GLOBAL_HWND: AtomicPtr<c_void> = AtomicPtr::new(null_mut());
pub static LISTEN_FLAG: AtomicU32 = AtomicU32::new(0);
pub const LISTEN_MOUSE_MOVE: u32 = 1 << 0;
pub const LISTEN_MOUSE_BUTTON: u32 = 1 << 1;
pub const LISTEN_MOUSE_WHEEL: u32 = 1 << 2;
pub const LISTEN_KEYBOARD: u32 = 1 << 3;
#[rustfmt::skip]
pub const LISTENS_ALL: u32 = LISTEN_MOUSE_MOVE | LISTEN_MOUSE_BUTTON | LISTEN_MOUSE_WHEEL | LISTEN_KEYBOARD;
pub static GRAB_FLAG: AtomicU32 = AtomicU32::new(0);
pub const GRAB_MOUSE_MOVE: u32 = 1 << 0; pub const GRAB_MOUSE_BUTTON: u32 = 1 << 1; pub const GRAB_MOUSE_WHEEL: u32 = 1 << 2; pub const GRAB_KEYBOARD: u32 = 1 << 3; pub const GRAB_ALL: u32 = GRAB_MOUSE_MOVE | GRAB_MOUSE_BUTTON | GRAB_MOUSE_WHEEL | GRAB_KEYBOARD;
pub fn update_state(atomic: &AtomicU32, bit: u32, enable: bool) {
let mut current = atomic.load(Ordering::SeqCst);
loop {
let next = if enable {
current | bit } else {
current & !bit };
match atomic.compare_exchange(current, next, Ordering::SeqCst, Ordering::SeqCst) {
Ok(_) => break,
Err(actual) => current = actual, }
}
}
static DPI_INIT: Once = Once::new();
pub fn initialize_dpi_awareness() {
DPI_INIT.call_once(|| unsafe {
let _ = SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
});
}
pub mod utils {
use windows::Win32::UI::{
Input::KeyboardAndMouse::VK_PACKET,
WindowsAndMessaging::{KBDLLHOOKSTRUCT, KBDLLHOOKSTRUCT_FLAGS},
};
#[inline]
pub fn hiword(l: u32) -> u16 {
((l >> 16) & 0xffff) as u16
}
#[allow(dead_code)]
#[inline]
pub(crate) fn loword(l: u32) -> u16 {
(l & 0xffff) as u16
}
#[allow(dead_code)]
#[inline]
pub(crate) fn hibyte(w: u16) -> u8 {
((w >> 8) & 0xff) as u8
}
#[allow(dead_code)]
#[inline]
pub(crate) fn lobyte(w: u16) -> u8 {
(w & 0xff) as u8
}
pub(crate) fn get_code(kb: &KBDLLHOOKSTRUCT) -> u32 {
if kb.vkCode == VK_PACKET.0 as u32 {
kb.scanCode
} else {
kb.vkCode
}
}
#[allow(dead_code)]
pub(crate) fn get_scan_code(kb: &KBDLLHOOKSTRUCT) -> u32 {
match kb.scanCode {
0x36 | 0x45 => kb.scanCode,
_ => {
if (kb.flags & KBDLLHOOKSTRUCT_FLAGS(0x01)) == KBDLLHOOKSTRUCT_FLAGS(0x01) {
0xE0 << 8 | kb.scanCode
} else {
kb.scanCode
}
}
}
}
}