-
Notifications
You must be signed in to change notification settings - Fork 186
cargo-release changes and migrate to windows-sys #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| /target | ||
| Cargo.lock | ||
|
|
||
| /.idea | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ categories = ["development-tools::testing", "api-bindings", "hardware-support"] | |
| license = "MIT" | ||
|
|
||
| [dependencies] | ||
| serde = {version = "1.0", features = ["derive"], optional=true} | ||
| serde = { version = "1.0", features = ["derive"], optional = true } | ||
| lazy_static = "1.4" | ||
|
|
||
| [features] | ||
|
|
@@ -23,28 +23,34 @@ unstable_grab = ["evdev-rs", "epoll", "inotify"] | |
|
|
||
| [target.'cfg(target_os = "macos")'.dependencies] | ||
| cocoa = "0.22" | ||
| core-graphics = {version = "0.19.0", features = ["highsierra"]} | ||
| core-foundation = {version = "0.7"} | ||
| core-foundation-sys = {version = "0.7"} | ||
| core-graphics = { version = "0.19.0", features = ["highsierra"] } | ||
| core-foundation = { version = "0.7" } | ||
| core-foundation-sys = { version = "0.7" } | ||
|
|
||
|
|
||
| [target.'cfg(target_os = "linux")'.dependencies] | ||
| libc = "0.2" | ||
| x11 = {version = "2.18", features = ["xlib", "xrecord", "xinput"]} | ||
| evdev-rs = {version = "0.4.0", optional=true} | ||
| epoll = {version = "4.1.0", optional=true} | ||
| inotify = {version = "0.8.2", default-features=false, optional=true} | ||
| x11 = { version = "2.18", features = ["xlib", "xrecord", "xinput"] } | ||
| evdev-rs = { version = "0.4.0", optional = true } | ||
| epoll = { version = "4.1.0", optional = true } | ||
| inotify = { version = "0.8.2", default-features = false, optional = true } | ||
|
|
||
| [target.'cfg(target_os = "windows")'.dependencies] | ||
| winapi = { version = "0.3", features = ["winuser", "errhandlingapi", "processthreadsapi"] } | ||
| windows-sys = { version = "0.45.0", features = [ | ||
| "Win32_UI_WindowsAndMessaging", | ||
| "Win32_Foundation", | ||
| "Win32_System_Threading", | ||
| "Win32_UI_Input_KeyboardAndMouse", | ||
| "Win32_UI_TextServices" | ||
| ] } | ||
|
|
||
| [dev-dependencies] | ||
| serde_json = "1.0" | ||
| # Some tests interact with the real OS. We can't hit the OS in parallel | ||
| # because that leads to unexpected behavior and flaky tests, so we need | ||
| # to run thoses tests in sequence instead. | ||
| serial_test = "0.4" | ||
| tokio = {version = "1.5", features=["sync", "macros", "rt-multi-thread"]} | ||
| tokio = { version = "1.5", features = ["sync", "macros", "rt-multi-thread"] } | ||
|
|
||
| [[example]] | ||
| name = "serialize" | ||
|
|
@@ -62,3 +68,8 @@ required-features = ["unstable_grab"] | |
| name = "grab" | ||
| path = "tests/grab.rs" | ||
| required-features = ["unstable_grab"] | ||
|
|
||
| [profile.release] | ||
| lto = true | ||
| codegen-units = 1 | ||
| opt-level = 3 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still no. This is really not the job of the lib. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,14 +9,14 @@ fn main() { | |
| listen(move |event| { | ||
| schan | ||
| .send(event) | ||
| .unwrap_or_else(|e| println!("Could not send event {:?}", e)); | ||
| .unwrap_or_else(|e| println!("Could not send event {e:?}")); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove all these changes and put them in a separate PR please. While being nice, they pollute the PR by adding a lot of meaningless changes.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see it's a new clippy lint. Let's still move it to another PR. |
||
| }) | ||
| .expect("Could not listen"); | ||
| }); | ||
|
|
||
| let mut events = Vec::new(); | ||
| for event in rchan.iter() { | ||
| println!("Received {:?}", event); | ||
| println!("Received {event:?}"); | ||
| events.push(event); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,13 +4,12 @@ use crate::windows::keycodes::key_from_code; | |
| use lazy_static::lazy_static; | ||
| use std::convert::TryInto; | ||
| use std::os::raw::{c_int, c_short}; | ||
| use std::ptr::null_mut; | ||
|
|
||
| use std::sync::Mutex; | ||
| use winapi::shared::minwindef::{DWORD, HIWORD, LPARAM, LRESULT, WORD, WPARAM}; | ||
| use winapi::shared::ntdef::LONG; | ||
| use winapi::shared::windef::HHOOK; | ||
| use winapi::um::errhandlingapi::GetLastError; | ||
| use winapi::um::winuser::{ | ||
| use windows_sys::Win32::Foundation::GetLastError; | ||
| use windows_sys::Win32::Foundation::{LPARAM, LRESULT}; | ||
| use windows_sys::Win32::UI::WindowsAndMessaging::HHOOK; | ||
| use windows_sys::Win32::UI::WindowsAndMessaging::{ | ||
| SetWindowsHookExA, KBDLLHOOKSTRUCT, MSLLHOOKSTRUCT, WHEEL_DELTA, WH_KEYBOARD_LL, WH_MOUSE_LL, | ||
| WM_KEYDOWN, WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, | ||
| WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SYSKEYDOWN, | ||
|
|
@@ -19,36 +18,41 @@ use winapi::um::winuser::{ | |
| pub const TRUE: i32 = 1; | ||
| pub const FALSE: i32 = 0; | ||
|
|
||
| pub static mut HOOK: HHOOK = null_mut(); | ||
| #[inline] | ||
| pub fn hiword(l: u32) -> u16 { | ||
| ((l >> 16) & 0xffff) as u16 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels broken to me. Classic Microsoft thing. |
||
| } | ||
|
|
||
| pub static mut HOOK: HHOOK = 0; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this |
||
| lazy_static! { | ||
| pub(crate) static ref KEYBOARD: Mutex<Keyboard> = Mutex::new(Keyboard::new().unwrap()); | ||
| } | ||
|
|
||
| pub unsafe fn get_code(lpdata: LPARAM) -> DWORD { | ||
| pub unsafe fn get_code(lpdata: LPARAM) -> u32 { | ||
| let kb = *(lpdata as *const KBDLLHOOKSTRUCT); | ||
| kb.vkCode | ||
| } | ||
| pub unsafe fn get_scan_code(lpdata: LPARAM) -> DWORD { | ||
| pub unsafe fn get_scan_code(lpdata: LPARAM) -> u32 { | ||
| let kb = *(lpdata as *const KBDLLHOOKSTRUCT); | ||
| kb.scanCode | ||
| } | ||
| pub unsafe fn get_point(lpdata: LPARAM) -> (LONG, LONG) { | ||
| pub unsafe fn get_point(lpdata: LPARAM) -> (i32, i32) { | ||
| let mouse = *(lpdata as *const MSLLHOOKSTRUCT); | ||
| (mouse.pt.x, mouse.pt.y) | ||
| } | ||
| // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644986(v=vs.85) | ||
| /// confusingly, this function returns a WORD (unsigned), but may be | ||
| /// confusingly, this function returns a u16 (unsigned), but may be | ||
| /// interpreted as either signed or unsigned depending on context | ||
| pub unsafe fn get_delta(lpdata: LPARAM) -> WORD { | ||
| pub unsafe fn get_delta(lpdata: LPARAM) -> u16 { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All these conversions are broken we need to revert (and it's ok to maybe alias everything at the beginning of the file).
|
||
| let mouse = *(lpdata as *const MSLLHOOKSTRUCT); | ||
| HIWORD(mouse.mouseData) | ||
| hiword(mouse.mouseData) | ||
| } | ||
| pub unsafe fn get_button_code(lpdata: LPARAM) -> WORD { | ||
| pub unsafe fn get_button_code(lpdata: LPARAM) -> u16 { | ||
| let mouse = *(lpdata as *const MSLLHOOKSTRUCT); | ||
| HIWORD(mouse.mouseData) | ||
| hiword(mouse.mouseData) | ||
| } | ||
|
|
||
| pub unsafe fn convert(param: WPARAM, lpdata: LPARAM) -> Option<EventType> { | ||
| pub unsafe fn convert(param: usize, lpdata: LPARAM) -> Option<EventType> { | ||
| match param.try_into() { | ||
| Ok(WM_KEYDOWN) | Ok(WM_SYSKEYDOWN) => { | ||
| let code = get_code(lpdata); | ||
|
|
@@ -85,30 +89,30 @@ pub unsafe fn convert(param: WPARAM, lpdata: LPARAM) -> Option<EventType> { | |
| let delta = get_delta(lpdata) as c_short; | ||
| Some(EventType::Wheel { | ||
| delta_x: 0, | ||
| delta_y: (delta / WHEEL_DELTA) as i64, | ||
| delta_y: (delta as u32 / WHEEL_DELTA) as i64, | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No we need to change the other line which casts a Also how is window-rs changing this type ??? https://rust-lang.github.io/libc/i686-pc-windows-msvc/doc/libc/type.c_short.html https://docs.rs/winapi/latest/winapi/um/winuser/constant.WHEEL_DELTA.html One of them is wrong... |
||
| }) | ||
| } | ||
| Ok(WM_MOUSEHWHEEL) => { | ||
| let delta = get_delta(lpdata) as c_short; | ||
| Some(EventType::Wheel { | ||
| delta_x: (delta / WHEEL_DELTA) as i64, | ||
| delta_x: (delta as u32 / WHEEL_DELTA) as i64, | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||
| delta_y: 0, | ||
| }) | ||
| } | ||
| _ => None, | ||
| } | ||
| } | ||
|
|
||
| type RawCallback = unsafe extern "system" fn(code: c_int, param: WPARAM, lpdata: LPARAM) -> LRESULT; | ||
| type RawCallback = unsafe extern "system" fn(code: c_int, param: usize, lpdata: LPARAM) -> LRESULT; | ||
| pub enum HookError { | ||
| Mouse(DWORD), | ||
| Key(DWORD), | ||
| Mouse(u32), | ||
| Key(u32), | ||
| } | ||
|
|
||
| pub unsafe fn set_key_hook(callback: RawCallback) -> Result<(), HookError> { | ||
| let hook = SetWindowsHookExA(WH_KEYBOARD_LL, Some(callback), null_mut(), 0); | ||
| let hook = SetWindowsHookExA(WH_KEYBOARD_LL, Some(callback), 0, 0); | ||
|
|
||
| if hook.is_null() { | ||
| if hook == 0 { | ||
| let error = GetLastError(); | ||
| return Err(HookError::Key(error)); | ||
| } | ||
|
|
@@ -117,8 +121,8 @@ pub unsafe fn set_key_hook(callback: RawCallback) -> Result<(), HookError> { | |
| } | ||
|
|
||
| pub unsafe fn set_mouse_hook(callback: RawCallback) -> Result<(), HookError> { | ||
| let hook = SetWindowsHookExA(WH_MOUSE_LL, Some(callback), null_mut(), 0); | ||
| if hook.is_null() { | ||
| let hook = SetWindowsHookExA(WH_MOUSE_LL, Some(callback), 0, 0); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| if hook == 0 { | ||
| let error = GetLastError(); | ||
| return Err(HookError::Mouse(error)); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,12 +2,12 @@ use crate::rdev::{Event, EventType, GrabError}; | |
| use crate::windows::common::{convert, set_key_hook, set_mouse_hook, HookError, HOOK, KEYBOARD}; | ||
| use std::ptr::null_mut; | ||
| use std::time::SystemTime; | ||
| use winapi::um::winuser::{CallNextHookEx, GetMessageA, HC_ACTION}; | ||
| use windows_sys::Win32::UI::WindowsAndMessaging::{CallNextHookEx, GetMessageA, HC_ACTION}; | ||
|
|
||
| static mut GLOBAL_CALLBACK: Option<Box<dyn FnMut(Event) -> Option<Event>>> = None; | ||
|
|
||
| unsafe extern "system" fn raw_callback(code: i32, param: usize, lpdata: isize) -> isize { | ||
| if code == HC_ACTION { | ||
| if code == HC_ACTION as i32 { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| let opt = convert(param, lpdata); | ||
| if let Some(event_type) = opt { | ||
| let name = match &event_type { | ||
|
|
@@ -53,7 +53,7 @@ where | |
| set_key_hook(raw_callback)?; | ||
| set_mouse_hook(raw_callback)?; | ||
|
|
||
| GetMessageA(null_mut(), null_mut(), 0, 0); | ||
| GetMessageA(null_mut(), 0, 0, 0); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| Ok(()) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,13 +2,15 @@ use crate::rdev::{EventType, Key, KeyboardState}; | |
| use crate::windows::common::{get_code, get_scan_code, FALSE, TRUE}; | ||
| use crate::windows::keycodes::code_from_key; | ||
| use std::ptr::null_mut; | ||
| use winapi::shared::minwindef::{BYTE, HKL, LPARAM, UINT}; | ||
| use winapi::um::processthreadsapi::GetCurrentThreadId; | ||
| use winapi::um::winuser; | ||
| use winapi::um::winuser::{ | ||
| GetForegroundWindow, GetKeyState, GetKeyboardLayout, GetKeyboardState, | ||
| GetWindowThreadProcessId, ToUnicodeEx, VK_CAPITAL, VK_LSHIFT, VK_RSHIFT, VK_SHIFT, | ||
| use windows_sys::Win32::Foundation::LPARAM; | ||
| use windows_sys::Win32::System::Threading::{AttachThreadInput, GetCurrentThreadId}; | ||
| use windows_sys::Win32::UI::Input::KeyboardAndMouse::{ | ||
| GetKeyState, GetKeyboardLayout, GetKeyboardState, ToUnicodeEx, VK_CAPITAL, VK_LSHIFT, | ||
| VK_RSHIFT, VK_SHIFT, | ||
| }; | ||
| use windows_sys::Win32::UI::TextServices::HKL; | ||
|
|
||
| use windows_sys::Win32::UI::WindowsAndMessaging::{GetForegroundWindow, GetWindowThreadProcessId}; | ||
|
|
||
| const VK_SHIFT_: usize = VK_SHIFT as usize; | ||
| const VK_CAPITAL_: usize = VK_CAPITAL as usize; | ||
|
|
@@ -17,9 +19,9 @@ const VK_RSHIFT_: usize = VK_RSHIFT as usize; | |
| const HIGHBIT: u8 = 0x80; | ||
|
|
||
| pub struct Keyboard { | ||
| last_code: UINT, | ||
| last_scan_code: UINT, | ||
| last_state: [BYTE; 256], | ||
| last_code: u32, | ||
| last_scan_code: u32, | ||
| last_state: [u8; 256], | ||
| last_is_dead: bool, | ||
| } | ||
|
|
||
|
|
@@ -47,16 +49,16 @@ impl Keyboard { | |
| let mut state = [0_u8; 256]; | ||
| let state_ptr = state.as_mut_ptr(); | ||
|
|
||
| let _shift = GetKeyState(VK_SHIFT); | ||
| let _shift = GetKeyState(VK_SHIFT as i32); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| let current_window_thread_id = GetWindowThreadProcessId(GetForegroundWindow(), null_mut()); | ||
| let thread_id = GetCurrentThreadId(); | ||
| // Attach to active thread so we can get that keyboard state | ||
| let status = if winuser::AttachThreadInput(thread_id, current_window_thread_id, TRUE) == 1 { | ||
| let status = if AttachThreadInput(thread_id, current_window_thread_id, TRUE) == 1 { | ||
| // Current state of the modifiers in keyboard | ||
| let status = GetKeyboardState(state_ptr); | ||
|
|
||
| // Detach | ||
| winuser::AttachThreadInput(thread_id, current_window_thread_id, FALSE); | ||
| AttachThreadInput(thread_id, current_window_thread_id, FALSE); | ||
| status | ||
| } else { | ||
| // Could not attach, perhaps it is this process? | ||
|
|
@@ -70,7 +72,7 @@ impl Keyboard { | |
| Some(()) | ||
| } | ||
|
|
||
| pub(crate) unsafe fn get_code_name(&mut self, code: UINT, scan_code: UINT) -> Option<String> { | ||
| pub(crate) unsafe fn get_code_name(&mut self, code: u32, scan_code: u32) -> Option<String> { | ||
| let current_window_thread_id = GetWindowThreadProcessId(GetForegroundWindow(), null_mut()); | ||
| let state_ptr = self.last_state.as_mut_ptr(); | ||
| const BUF_LEN: i32 = 32; | ||
|
|
@@ -113,7 +115,7 @@ impl Keyboard { | |
| result | ||
| } | ||
|
|
||
| unsafe fn clear_keyboard_buffer(&self, code: UINT, scan_code: UINT, layout: HKL) { | ||
| unsafe fn clear_keyboard_buffer(&self, code: u32, scan_code: u32, layout: HKL) { | ||
| const BUF_LEN: i32 = 32; | ||
| let mut buff = [0_u16; BUF_LEN as usize]; | ||
| let buff_ptr = buff.as_mut_ptr(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Use your own
.gitignorefor that. https://sebastiandedeyne.com/setting-up-a-global-gitignore-file/