Merge pull request #3719 from chiehw/win-linux

translate mode: support linux in server
This commit is contained in:
RustDesk
2023-03-20 15:55:24 +08:00
committed by GitHub
10 changed files with 167 additions and 14 deletions

View File

@@ -1,3 +1,4 @@
use crate::platform::breakdown_callback;
use hbb_common::log;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use hbb_common::platform::register_breakdown_handler;
@@ -38,7 +39,7 @@ pub fn core_main() -> Option<Vec<String>> {
i += 1;
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
register_breakdown_handler();
register_breakdown_handler(breakdown_callback);
#[cfg(target_os = "linux")]
#[cfg(feature = "flutter")]
{

View File

@@ -3,11 +3,13 @@ use crate::client::get_key_state;
use crate::common::GrabState;
#[cfg(feature = "flutter")]
use crate::flutter::{CUR_SESSION_ID, SESSIONS};
#[cfg(target_os = "windows")]
use crate::platform::windows::get_char_by_vk;
#[cfg(not(any(feature = "flutter", feature = "cli")))]
use crate::ui::CUR_SESSION;
use hbb_common::message_proto::*;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use hbb_common::log;
use hbb_common::message_proto::*;
use rdev::{Event, EventType, Key};
#[cfg(any(target_os = "windows", target_os = "macos"))]
use std::sync::atomic::{AtomicBool, Ordering};
@@ -789,7 +791,17 @@ fn try_fill_unicode(event: &Event, key_event: &KeyEvent, events: &mut Vec<KeyEve
}
}
}
None => {}
None =>
{
#[cfg(target_os = "windows")]
if is_hot_key_modifiers_down() && unsafe { !IS_0X021D_DOWN } {
if let Some(chr) = get_char_by_vk(event.code as u32) {
let mut evt = key_event.clone();
evt.set_seq(chr.to_string());
events.push(evt);
}
}
}
}
}
@@ -857,7 +869,7 @@ pub fn translate_keyboard_mode(peer: &str, event: &Event, key_event: KeyEvent) -
}
#[cfg(target_os = "windows")]
if unsafe { IS_0X021D_DOWN } || !is_hot_key_modifiers_down() {
if matches!(event.event_type, EventType::KeyPress(_)) {
try_fill_unicode(event, &key_event, &mut events);
}

View File

@@ -33,6 +33,11 @@ pub fn is_xfce() -> bool {
}
}
pub fn breakdown_callback() {
#[cfg(target_os = "linux")]
crate::input_service::clear_remapped_keycode()
}
// Android
#[cfg(target_os = "android")]
pub fn get_active_username() -> String {

View File

@@ -10,6 +10,7 @@ use hbb_common::{
sleep, timeout, tokio,
};
use std::io::prelude::*;
use std::ptr::null_mut;
use std::{
ffi::OsString,
fs, io, mem,
@@ -1961,7 +1962,8 @@ mod cert {
RegKey,
};
const ROOT_CERT_STORE_PATH: &str = "SOFTWARE\\Microsoft\\SystemCertificates\\ROOT\\Certificates\\";
const ROOT_CERT_STORE_PATH: &str =
"SOFTWARE\\Microsoft\\SystemCertificates\\ROOT\\Certificates\\";
const THUMBPRINT_ALG: ALG_ID = CALG_SHA1;
const THUMBPRINT_LEN: DWORD = 20;
@@ -1979,7 +1981,10 @@ mod cert {
&mut size,
) == TRUE
{
(thumbprint.to_vec(), hex::encode(thumbprint).to_ascii_uppercase())
(
thumbprint.to_vec(),
hex::encode(thumbprint).to_ascii_uppercase(),
)
} else {
(thumbprint.to_vec(), "".to_owned())
}
@@ -2086,16 +2091,70 @@ mod cert {
}
}
pub fn get_char_by_vk(vk: u32) -> Option<char> {
const BUF_LEN: i32 = 32;
let mut buff = [0_u16; BUF_LEN as usize];
let buff_ptr = buff.as_mut_ptr();
let len = unsafe {
let current_window_thread_id = GetWindowThreadProcessId(GetForegroundWindow(), null_mut());
let layout = GetKeyboardLayout(current_window_thread_id);
// refs: https://github.com/fufesou/rdev/blob/25a99ce71ab42843ad253dd51e6a35e83e87a8a4/src/windows/keyboard.rs#L115
let press_state = 129;
let mut state: [BYTE; 256] = [0; 256];
let shift_left = rdev::get_modifier(rdev::Key::ShiftLeft);
let shift_right = rdev::get_modifier(rdev::Key::ShiftRight);
if shift_left {
state[VK_LSHIFT as usize] = press_state;
}
if shift_right {
state[VK_RSHIFT as usize] = press_state;
}
if shift_left || shift_right {
state[VK_SHIFT as usize] = press_state;
}
ToUnicodeEx(vk, 0x00, &state as _, buff_ptr, BUF_LEN, 0, layout)
};
if len == 1 {
if let Some(chr) = String::from_utf16(&buff[..len as usize])
.ok()?
.chars()
.next()
{
if chr.is_control() {
return None;
} else {
Some(chr)
}
} else {
None
}
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_install_cert() {
println!("install driver cert: {:?}", cert::install_cert("RustDeskIddDriver.cer"));
println!(
"install driver cert: {:?}",
cert::install_cert("RustDeskIddDriver.cer")
);
}
#[test]
fn test_uninstall_cert() {
println!("uninstall driver certs: {:?}", cert::uninstall_certs());
}
#[test]
fn test_get_char_by_vk() {
let chr = get_char_by_vk(0x41); // VK_A
assert_eq!(chr, Some('a'));
let chr = get_char_by_vk(VK_ESCAPE as u32); // VK_ESC
assert_eq!(chr, None)
}
}

View File

@@ -612,6 +612,8 @@ impl Connection {
}
}
}
#[cfg(target_os = "linux")]
clear_remapped_keycode();
log::info!("Input thread exited");
}

View File

@@ -413,6 +413,11 @@ pub fn fix_key_down_timeout_at_exit() {
log::info!("fix_key_down_timeout_at_exit");
}
#[cfg(target_os = "linux")]
pub fn clear_remapped_keycode() {
ENIGO.lock().unwrap().tfc_clear_remapped();
}
#[inline]
fn record_key_is_control_key(record_key: u64) -> bool {
record_key < KEY_CHAR_START
@@ -1130,7 +1135,24 @@ fn translate_process_code(code: u32, down: bool) {
fn translate_keyboard_mode(evt: &KeyEvent) {
match &evt.union {
Some(key_event::Union::Seq(seq)) => {
ENIGO.lock().unwrap().key_sequence(seq);
// Fr -> US
// client: Shift + & => 1(send to remote)
// remote: Shift + 1 => !
//
// Try to release shift first.
// remote: Shift + 1 => 1
let mut en = ENIGO.lock().unwrap();
#[cfg(target_os = "linux")]
{
simulate_(&EventType::KeyRelease(RdevKey::ShiftLeft));
simulate_(&EventType::KeyRelease(RdevKey::ShiftRight));
for chr in seq.chars() {
en.key_click(Key::Layout(chr));
}
}
#[cfg(not(target_os = "linux"))]
en.key_sequence(seq);
}
Some(key_event::Union::Chr(..)) => {
#[cfg(target_os = "windows")]