From 2c44255bb25dc8d4f4a5f83de287af9480d66b90 Mon Sep 17 00:00:00 2001 From: jathoms Date: Tue, 16 Sep 2025 23:28:45 +0100 Subject: [PATCH] add dwExtraInfo to Event struct in windows implementation update grab to use new eventtype make extra_info field windows-only --- src/rdev.rs | 2 + src/windows/common.rs | 97 +++++++++++++++++++++++++++++++++---------- src/windows/grab.rs | 3 +- src/windows/listen.rs | 3 +- 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/src/rdev.rs b/src/rdev.rs index 5009995..cbbdf6b 100644 --- a/src/rdev.rs +++ b/src/rdev.rs @@ -283,6 +283,8 @@ pub struct Event { pub time: SystemTime, pub name: Option, pub event_type: EventType, + #[cfg(target_os = "windows")] + pub extra_info: u32, } /// We can define a dummy Keyboard, that we will use to detect diff --git a/src/windows/common.rs b/src/windows/common.rs index e61240b..c621f64 100644 --- a/src/windows/common.rs +++ b/src/windows/common.rs @@ -36,6 +36,18 @@ pub unsafe fn get_scan_code(lpdata: LPARAM) -> DWORD { kb.scanCode } } +pub unsafe fn get_key_extra_info(lpdata: LPARAM) -> DWORD { + unsafe { + let kb = *(lpdata as *const KBDLLHOOKSTRUCT); + kb.dwExtraInfo as u32 + } +} +pub unsafe fn get_mouse_extra_info(lpdata: LPARAM) -> DWORD { + unsafe { + let mouse = *(lpdata as *const MSLLHOOKSTRUCT); + mouse.dwExtraInfo as u32 + } +} pub unsafe fn get_point(lpdata: LPARAM) -> (LONG, LONG) { unsafe { let mouse = *(lpdata as *const MSLLHOOKSTRUCT); @@ -58,54 +70,93 @@ pub unsafe fn get_button_code(lpdata: LPARAM) -> WORD { } } -pub unsafe fn convert(param: WPARAM, lpdata: LPARAM) -> Option { +pub unsafe fn convert(param: WPARAM, lpdata: LPARAM) -> Option<(EventType, u32)> { unsafe { match param.try_into() { Ok(WM_KEYDOWN) | Ok(WM_SYSKEYDOWN) => { let code = get_code(lpdata); let key = key_from_code(code as u16); - Some(EventType::KeyPress(key)) + let extra = get_key_extra_info(lpdata); + Some((EventType::KeyPress(key), extra)) } Ok(WM_KEYUP) | Ok(WM_SYSKEYUP) => { let code = get_code(lpdata); let key = key_from_code(code as u16); - Some(EventType::KeyRelease(key)) + let extra = get_key_extra_info(lpdata); + Some((EventType::KeyRelease(key), extra)) } - Ok(WM_LBUTTONDOWN) => Some(EventType::ButtonPress(Button::Left)), - Ok(WM_LBUTTONUP) => Some(EventType::ButtonRelease(Button::Left)), - Ok(WM_MBUTTONDOWN) => Some(EventType::ButtonPress(Button::Middle)), - Ok(WM_MBUTTONUP) => Some(EventType::ButtonRelease(Button::Middle)), - Ok(WM_RBUTTONDOWN) => Some(EventType::ButtonPress(Button::Right)), - Ok(WM_RBUTTONUP) => Some(EventType::ButtonRelease(Button::Right)), + + Ok(WM_LBUTTONDOWN) => Some(( + EventType::ButtonPress(Button::Left), + get_mouse_extra_info(lpdata), + )), + Ok(WM_LBUTTONUP) => Some(( + EventType::ButtonRelease(Button::Left), + get_mouse_extra_info(lpdata), + )), + Ok(WM_MBUTTONDOWN) => Some(( + EventType::ButtonPress(Button::Middle), + get_mouse_extra_info(lpdata), + )), + Ok(WM_MBUTTONUP) => Some(( + EventType::ButtonRelease(Button::Middle), + get_mouse_extra_info(lpdata), + )), + Ok(WM_RBUTTONDOWN) => Some(( + EventType::ButtonPress(Button::Right), + get_mouse_extra_info(lpdata), + )), + Ok(WM_RBUTTONUP) => Some(( + EventType::ButtonRelease(Button::Right), + get_mouse_extra_info(lpdata), + )), + Ok(WM_XBUTTONDOWN) => { let code = get_button_code(lpdata) as u8; - Some(EventType::ButtonPress(Button::Unknown(code))) + Some(( + EventType::ButtonPress(Button::Unknown(code)), + get_mouse_extra_info(lpdata), + )) } Ok(WM_XBUTTONUP) => { let code = get_button_code(lpdata) as u8; - Some(EventType::ButtonRelease(Button::Unknown(code))) + Some(( + EventType::ButtonRelease(Button::Unknown(code)), + get_mouse_extra_info(lpdata), + )) } + Ok(WM_MOUSEMOVE) => { let (x, y) = get_point(lpdata); - Some(EventType::MouseMove { - x: x as f64, - y: y as f64, - }) + Some(( + EventType::MouseMove { + x: x as f64, + y: y as f64, + }, + get_mouse_extra_info(lpdata), + )) } Ok(WM_MOUSEWHEEL) => { let delta = get_delta(lpdata) as c_short; - Some(EventType::Wheel { - delta_x: 0, - delta_y: (delta / WHEEL_DELTA) as i64, - }) + Some(( + EventType::Wheel { + delta_x: 0, + delta_y: (delta / WHEEL_DELTA) as i64, + }, + get_mouse_extra_info(lpdata), + )) } Ok(WM_MOUSEHWHEEL) => { let delta = get_delta(lpdata) as c_short; - Some(EventType::Wheel { - delta_x: (delta / WHEEL_DELTA) as i64, - delta_y: 0, - }) + Some(( + EventType::Wheel { + delta_x: (delta / WHEEL_DELTA) as i64, + delta_y: 0, + }, + get_mouse_extra_info(lpdata), + )) } + _ => None, } } diff --git a/src/windows/grab.rs b/src/windows/grab.rs index 45a5664..4e58870 100644 --- a/src/windows/grab.rs +++ b/src/windows/grab.rs @@ -10,7 +10,7 @@ unsafe extern "system" fn raw_callback(code: i32, param: usize, lpdata: isize) - unsafe { if code == HC_ACTION { let opt = convert(param, lpdata); - if let Some(event_type) = opt { + if let Some((event_type, extra_info)) = opt { let name = match &event_type { EventType::KeyPress(_key) => match (*KEYBOARD).lock() { Ok(mut keyboard) => keyboard.get_name(lpdata), @@ -22,6 +22,7 @@ unsafe extern "system" fn raw_callback(code: i32, param: usize, lpdata: isize) - event_type, time: SystemTime::now(), name, + extra_info, }; let ptr = &raw mut GLOBAL_CALLBACK; if let Some(callback) = &mut *ptr { diff --git a/src/windows/listen.rs b/src/windows/listen.rs index f5c2e73..8f7e591 100644 --- a/src/windows/listen.rs +++ b/src/windows/listen.rs @@ -21,7 +21,7 @@ unsafe extern "system" fn raw_callback(code: c_int, param: WPARAM, lpdata: LPARA unsafe { if code == HC_ACTION { let opt = convert(param, lpdata); - if let Some(event_type) = opt { + if let Some((event_type, extra_info)) = opt { let name = match &event_type { EventType::KeyPress(_key) => match (*KEYBOARD).lock() { Ok(mut keyboard) => keyboard.get_name(lpdata), @@ -33,6 +33,7 @@ unsafe extern "system" fn raw_callback(code: c_int, param: WPARAM, lpdata: LPARA event_type, time: SystemTime::now(), name, + extra_info, }; let ptr = &raw mut GLOBAL_CALLBACK; if let Some(callback) = &mut *ptr {