From cf121bdf47550df9725b604e340e1fa4491cafd4 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 2 Feb 2023 22:27:11 +0800 Subject: [PATCH] win, translate mode, not debug yet Signed-off-by: fufesou --- Cargo.lock | 26 ++++++++- Cargo.toml | 2 +- src/keyboard.rs | 105 ++++++++++++++++++++++++++++-------- src/server/input_service.rs | 17 +++++- src/ui_session_interface.rs | 21 ++++++++ 5 files changed, 144 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e15641363..4ac2720be 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 054a39580..bcb0650ac 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -92,7 +92,8 @@ pub mod client { if is_long_press(&event) { return; } - if let Some(key_event) = event_to_key_event(&event, lock_modes) { + + for key_event in event_to_key_events(&event, lock_modes) { send_key_event(&key_event); } } @@ -341,7 +342,7 @@ fn update_modifiers_state(event: &Event) { }; } -pub fn event_to_key_event(event: &Event, lock_modes: Option) -> Option { +pub fn event_to_key_events(event: &Event, lock_modes: Option) -> Vec { let mut key_event = KeyEvent::new(); update_modifiers_state(event); @@ -357,28 +358,38 @@ pub fn event_to_key_event(event: &Event, lock_modes: Option) -> Option map_keyboard_mode(event, key_event)?, - KeyboardMode::Translate => translate_keyboard_mode(event, key_event)?, + let mut key_events = match keyboard_mode { + KeyboardMode::Map => match map_keyboard_mode(event, key_event) { + Some(event) => [event].to_vec(), + None => Vec::new(), + }, + KeyboardMode::Translate => translate_keyboard_mode(event, key_event), _ => { #[cfg(not(any(target_os = "android", target_os = "ios")))] { - legacy_keyboard_mode(event, key_event)? + legacy_keyboard_mode(event, key_event) } #[cfg(any(target_os = "android", target_os = "ios"))] { - None? + Vec::new() } } }; - #[cfg(not(any(target_os = "android", target_os = "ios")))] - if let Some(lock_modes) = lock_modes { - add_numlock_capslock_with_lock_modes(&mut key_event, lock_modes); - } else { - add_numlock_capslock_status(&mut key_event); + + if keyboard_mode != KeyboardMode::Translate { + for key_event in &mut key_events { + #[cfg(not(any(target_os = "android", target_os = "ios")))] + if let Some(lock_modes) = lock_modes { + add_numlock_capslock_with_lock_modes(key_event, lock_modes); + } else { + add_numlock_capslock_status(key_event); + } + } } - return Some(key_event); + println!("REMOVE ME ========================= key_events {:?}", &key_events); + + key_events } pub fn event_type_to_event(event_type: EventType) -> Event { @@ -386,6 +397,7 @@ pub fn event_type_to_event(event_type: EventType) -> Event { event_type, time: SystemTime::now(), name: None, + unicode: Vec::new(), code: 0, scan_code: 0, } @@ -423,13 +435,14 @@ pub fn get_peer_platform() -> String { } #[cfg(not(any(target_os = "android", target_os = "ios")))] -pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option { +pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Vec { + let mut events = Vec::new(); // legacy mode(0): Generate characters locally, look for keycode on other side. let (mut key, down_or_up) = match event.event_type { EventType::KeyPress(key) => (key, true), EventType::KeyRelease(key) => (key, false), _ => { - return None; + return events; } }; @@ -475,7 +488,7 @@ pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option Option { if is_win && ctrl && alt { client::ctrl_alt_del(); - return None; + return events; } Some(ControlKey::Delete) } @@ -545,7 +558,7 @@ pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option Some(ControlKey::Subtract), Key::KpPlus => Some(ControlKey::Add), Key::CapsLock | Key::NumLock | Key::ScrollLock => { - return None; + return events; } Key::Home => Some(ControlKey::Home), Key::End => Some(ControlKey::End), @@ -628,12 +641,12 @@ pub fn legacy_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option Option Option { @@ -703,6 +717,51 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option Option { - None +#[cfg(target_os = "windows")] +fn is_modifier_code(scan_code: u32) -> bool { + match scan_code { + // Alt | AltGr | ControlLeft | ControlRight | ShiftLeft | ShiftRight | MetaLeft | MetaRight + 0x38 | 0xE038 | 0x1D | 0xE01D | 0x2A | 0x36 | 0xE05B | 0xE05C => true, + _ => false, + } +} + +#[cfg(target_os = "linux")] +fn is_modifier_code(key_code: u32) -> bool { + match scan_code { + 64 | 108 | 37 | 105 | 50 | 62 | 133 | 134 => true, + _ => false, + } +} + +#[cfg(target_os = "macos")] +fn is_modifier_code(key_code: u32) -> bool { + match scan_code { + 0x3A | 0x3D | 0x3B | 0x3E | 0x38 | 0x3C | 0x37 | 0x36 => true, + _ => false, + } +} + +pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec { + #[cfg(target_os = "windows")] + let is_modifier = is_modifier_code(event.scan_code); + #[cfg(target_os = "linux")] + let is_modifier = is_modifier_code(event.key_code); + #[cfg(target_os = "macos")] + let is_modifier = is_modifier_code(event.key_code); + + let mut events: Vec = Vec::new(); + if is_modifier { + if let Some(evt) = map_keyboard_mode(event, key_event) { + events.push(evt); + } + return events; + } + + for unicode in &event.unicode { + let mut evt = key_event.clone(); + evt.set_unicode(*unicode as _); + events.push(evt); + } + events } diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 2715a2643..072ef53fb 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1067,6 +1067,21 @@ fn legacy_keyboard_mode(evt: &KeyEvent) { release_keys(&mut en, &to_release); } +fn translate_keyboard_mode(evt: &KeyEvent) { + match evt.union { + Some(key_event::Union::Unicode(unicode)) => { + println!("REMOVE ME ========================= simulate_unicode {}", unicode); + allow_err!(rdev::simulate_unicode(unicode as _)); + }, + Some(key_event::Union::Chr(..)) => { + map_keyboard_mode(evt) + } + _ => { + log::debug!("Unreachable. Unexpected key event {:?}", &evt); + } + } +} + pub fn handle_key_(evt: &KeyEvent) { if EXITING.load(Ordering::SeqCst) { return; @@ -1080,7 +1095,7 @@ pub fn handle_key_(evt: &KeyEvent) { map_keyboard_mode(evt); } KeyboardMode::Translate => { - legacy_keyboard_mode(evt); + translate_keyboard_mode(evt); } _ => { legacy_keyboard_mode(evt); diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 4fc5db743..95b8cdbd0 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -361,11 +361,31 @@ impl Session { } pub fn enter(&self) { + #[cfg(target_os = "windows")] + { + match &self.lc.read().unwrap().keyboard_mode as _ { + "legacy" => { + println!("REMOVE ME =========================== enter legacy "); + rdev::set_get_key_name(true); + } + "translate" => { + println!("REMOVE ME =========================== enter translate "); + rdev::set_get_key_name(true); + } + _ => {} + } + } + IS_IN.store(true, Ordering::SeqCst); keyboard::client::change_grab_status(GrabState::Run); } pub fn leave(&self) { + #[cfg(target_os = "windows")] + { + println!("REMOVE ME =========================== leave "); + rdev::set_get_key_name(false); + } IS_IN.store(false, Ordering::SeqCst); keyboard::client::change_grab_status(GrabState::Wait); } @@ -429,6 +449,7 @@ impl Session { let event = Event { time: std::time::SystemTime::now(), name: Option::Some(name.to_owned()), + unicode: Vec::new(), code: keycode as _, scan_code: scancode as _, event_type: event_type,