From 347add18744358b9d07247bee458f2a4ca17c0f8 Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 8 Feb 2023 09:48:04 +0800 Subject: [PATCH] win, translate mode, to debug Signed-off-by: fufesou --- Cargo.lock | 26 +++++++++- Cargo.toml | 2 +- src/keyboard.rs | 100 ++++++++++++++++++++++++++++++++---- src/server/input_service.rs | 13 ++++- 4 files changed, 128 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 988363019..f5ffa7f9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1556,7 +1556,7 @@ dependencies = [ "log", "objc", "pkg-config", - "rdev", + "rdev 0.5.0-2 (git+https://github.com/fufesou/rdev)", "serde 1.0.149", "serde_derive", "tfc", @@ -4401,6 +4401,28 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rdev" +version = "0.5.0-2" +dependencies = [ + "cocoa", + "core-foundation 0.9.3", + "core-foundation-sys 0.8.3", + "core-graphics 0.22.3", + "enum-map", + "epoll", + "inotify", + "lazy_static", + "libc", + "log", + "mio 0.8.5", + "strum 0.24.1", + "strum_macros 0.24.3", + "widestring 1.0.2", + "winapi 0.3.9", + "x11 2.20.1", +] + [[package]] name = "rdev" version = "0.5.0-2" @@ -4709,7 +4731,7 @@ dependencies = [ "objc", "objc_id", "parity-tokio-ipc", - "rdev", + "rdev 0.5.0-2", "repng", "reqwest", "rpassword 7.2.0", diff --git a/Cargo.toml b/Cargo.toml index 936b9e349..5d75b7a23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ default-net = { git = "https://github.com/Kingtous/default-net" } wol-rs = "0.9.1" flutter_rust_bridge = { version = "1.61.1", optional = true } errno = "0.2.8" -rdev = { git = "https://github.com/fufesou/rdev" } +rdev = { path = "../rdev" } url = { version = "2.1", features = ["serde"] } reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false } diff --git a/src/keyboard.rs b/src/keyboard.rs index fd9514427..492314ab6 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -199,6 +199,9 @@ pub fn update_grab_get_key_name() { }; } +#[cfg(target_os = "windows")] +static mut IS_LAST_0X021D: bool = false; + pub fn start_grab_loop() { #[cfg(any(target_os = "windows", target_os = "macos"))] std::thread::spawn(move || { @@ -210,12 +213,22 @@ pub fn start_grab_loop() { if KEYBOARD_HOOKED.load(Ordering::SeqCst) { let keyboard_mode = client::process_event(&event, None); if keyboard_mode == KeyboardMode::Translate { - // SHIFT(0x2A) RSHIFT(0x36) - if event.scan_code == 0x2A || event.scan_code == 0x36 { - return Some(event); + #[cfg(target_os = "windows")] + match event.scan_code { + 0x2A => rdev::set_modifier(Key::ShiftLeft, is_press), + 0x36 => rdev::set_modifier(Key::ShiftRight, is_press), + 0x38 => rdev::set_modifier(Key::Alt, is_press), + 0xE038 => rdev::set_modifier(Key::AltGr, is_press), + 0xE05B => rdev::set_modifier(Key::MetaLeft, is_press), + 0xE05C => rdev::set_modifier(Key::MetaRight, is_press), + _ => {} + } + #[cfg(target_os = "windows")] + unsafe { + IS_LAST_0X021D = event.scan_code == 0x021D; } } - + if is_press { return None; } else { @@ -352,7 +365,11 @@ fn update_modifiers_state(event: &Event) { }; } -pub fn event_to_key_events(event: &Event, keyboard_mode: KeyboardMode, lock_modes: Option) -> Vec { +pub fn event_to_key_events( + event: &Event, + keyboard_mode: KeyboardMode, + lock_modes: Option, +) -> Vec { let mut key_event = KeyEvent::new(); update_modifiers_state(event); @@ -577,7 +594,10 @@ pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Vec { if s.len() <= 2 { @@ -724,8 +744,7 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option Vec { - let mut events: Vec = Vec::new(); +fn try_fill_unicode(event: &Event, key_event: &KeyEvent, events: &mut Vec) { match &event.unicode { Some(unicode_info) => { if !unicode_info.is_dead { @@ -738,8 +757,71 @@ pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec {} } +} + +#[cfg(target_os = "windows")] +fn is_hot_key_modifiers_down() -> bool { + if rdev::get_modifier(Key::ControlLeft) || rdev::get_modifier(Key::ControlRight) { + return true; + } + if rdev::get_modifier(Key::Alt) || rdev::get_modifier(Key::AltGr) { + return true; + } + if rdev::get_modifier(Key::MetaLeft) || rdev::get_modifier(Key::MetaRight) { + return true; + } + return false; +} + +pub fn translate_virtual_keycode(event: &Event, mut key_event: KeyEvent) -> Option { + match event.event_type { + EventType::KeyPress(..) => { + key_event.down = true; + } + EventType::KeyRelease(..) => { + key_event.down = false; + } + _ => return None, + }; + + let mut peer = get_peer_platform().to_lowercase(); + peer.retain(|c| !c.is_whitespace()); + + // #[cfg(target_os = "windows")] + // let keycode = match peer.as_str() { + // "windows" => event.code, + // "macos" => { + // if hbb_common::config::LocalConfig::get_kb_layout_type() == "ISO" { + // rdev::win_scancode_to_macos_iso_code(event.scan_code)? + // } else { + // rdev::win_scancode_to_macos_code(event.scan_code)? + // } + // } + // _ => rdev::win_scancode_to_linux_code(event.scan_code)?, + // }; + + key_event.set_chr(event.code as _); + Some(key_event) +} + +pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec { + let mut events: Vec = Vec::new(); + #[cfg(target_os = "windows")] + unsafe { + if IS_LAST_0X021D { + if event.scan_code == 0xE038 { + return events; + } + } + } + + #[cfg(target_os = "windows")] + if !is_hot_key_modifiers_down() { + try_fill_unicode(event, &key_event, &mut events); + } + if events.is_empty() { - if let Some(evt) = map_keyboard_mode(event, key_event) { + if let Some(evt) = translate_virtual_keycode(event, key_event) { events.push(evt); } return events; diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 1d7d4773d..133b9a830 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1067,13 +1067,24 @@ fn legacy_keyboard_mode(evt: &KeyEvent) { release_keys(&mut en, &to_release); } +#[cfg(target_os = "windows")] +fn translate_process_virtual_keycode(vk: u32, down: bool) { + let scancode = rdev::vk_to_scancode(vk); + // map mode(1): Send keycode according to the peer platform. + record_pressed_key(scancode as u64 + KEY_CHAR_START, down); + + crate::platform::windows::try_change_desktop(); + sim_rdev_rawkey(scancode, down); +} + fn translate_keyboard_mode(evt: &KeyEvent) { match evt.union { Some(key_event::Union::Unicode(unicode)) => { allow_err!(rdev::simulate_unicode(unicode as _)); }, Some(key_event::Union::Chr(..)) => { - map_keyboard_mode(evt) + #[cfg(target_os = "windows")] + translate_process_virtual_keycode(evt.chr(), evt.down) } _ => { log::debug!("Unreachable. Unexpected key event {:?}", &evt);