mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Merge remote-tracking branch 'github/master' into sigma
This commit is contained in:
@@ -25,7 +25,7 @@ use hbb_common::{allow_err, get_time, message_proto::*, sleep};
|
||||
use hbb_common::{fs, log, Stream};
|
||||
|
||||
use crate::client::{
|
||||
new_voice_call_request, Client, CodecFormat, LoginConfigHandler, MediaData, MediaSender,
|
||||
new_voice_call_request, Client, CodecFormat, MediaData, MediaSender,
|
||||
QualityStatus, MILLI1, SEC30, SERVER_CLIPBOARD_ENABLED, SERVER_FILE_TRANSFER_ENABLED,
|
||||
SERVER_KEYBOARD_ENABLED,
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ use hbb_common::{
|
||||
// #[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
|
||||
use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all};
|
||||
|
||||
use crate::ui_interface::{set_option, get_option};
|
||||
use crate::ui_interface::{get_option, set_option};
|
||||
|
||||
pub type NotifyMessageBox = fn(String, String, String, String) -> dyn Future<Output = ()>;
|
||||
|
||||
@@ -762,8 +762,3 @@ pub fn make_fd_to_json(id: i32, path: String, entries: &Vec<FileEntry>) -> Strin
|
||||
fd_json.insert("entries".into(), json!(entries_out));
|
||||
serde_json::to_string(&fd_json).unwrap_or("".into())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_common {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use std::future::Future;
|
||||
|
||||
use hbb_common::{log, ResultType};
|
||||
use hbb_common::log;
|
||||
|
||||
/// shared by flutter and sciter main function
|
||||
///
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use std::{collections::HashMap, ffi::{CStr, CString}, os::raw::c_char, thread};
|
||||
use std::{collections::HashMap, ffi::{CStr, CString}, os::raw::c_char};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "android"))]
|
||||
use std::thread;
|
||||
|
||||
use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer};
|
||||
use serde_json::json;
|
||||
|
||||
@@ -928,7 +931,7 @@ pub fn main_start_dbus_server() {
|
||||
{
|
||||
use crate::dbus::start_dbus_server;
|
||||
// spawn new thread to start dbus server
|
||||
std::thread::spawn(|| {
|
||||
thread::spawn(|| {
|
||||
let _ = start_dbus_server();
|
||||
});
|
||||
}
|
||||
@@ -1275,7 +1278,7 @@ pub fn main_is_login_wayland() -> SyncReturn<bool> {
|
||||
|
||||
pub fn main_start_pa() {
|
||||
#[cfg(target_os = "linux")]
|
||||
std::thread::spawn(crate::ipc::start_pa);
|
||||
thread::spawn(crate::ipc::start_pa);
|
||||
}
|
||||
|
||||
pub fn main_hide_docker() -> SyncReturn<bool> {
|
||||
@@ -1302,9 +1305,9 @@ pub fn main_start_ipc_url_server() {
|
||||
///
|
||||
/// * macOS only
|
||||
#[allow(unused_variables)]
|
||||
pub fn send_url_scheme(url: String) {
|
||||
pub fn send_url_scheme(_url: String) {
|
||||
#[cfg(target_os = "macos")]
|
||||
thread::spawn(move || crate::ui::macos::handle_url_scheme(url));
|
||||
thread::spawn(move || crate::ui::macos::handle_url_scheme(_url));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
@@ -1324,7 +1327,7 @@ pub mod server_side {
|
||||
_class: JClass,
|
||||
) {
|
||||
log::debug!("startServer from java");
|
||||
std::thread::spawn(move || start_server(true));
|
||||
thread::spawn(move || start_server(true));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
28
src/ipc.rs
28
src/ipc.rs
@@ -16,10 +16,10 @@ use hbb_common::{
|
||||
config::{self, Config, Config2},
|
||||
futures::StreamExt as _,
|
||||
futures_util::sink::SinkExt,
|
||||
log, password_security as password, ResultType, timeout,
|
||||
tokio,
|
||||
log, password_security as password, timeout, tokio,
|
||||
tokio::io::{AsyncRead, AsyncWrite},
|
||||
tokio_util::codec::Framed,
|
||||
ResultType,
|
||||
};
|
||||
|
||||
use crate::rendezvous_mediator::RendezvousMediator;
|
||||
@@ -190,7 +190,7 @@ pub enum Data {
|
||||
Socks(Option<config::Socks5Server>),
|
||||
FS(FS),
|
||||
Test,
|
||||
SyncConfig(Option<(Config, Config2)>),
|
||||
SyncConfig(Option<Box<(Config, Config2)>>),
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
ClipboardFile(ClipboardFile),
|
||||
ClipboardFileEnabled(bool),
|
||||
@@ -419,7 +419,8 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
let t = Config::get_nat_type();
|
||||
allow_err!(stream.send(&Data::NatType(Some(t))).await);
|
||||
}
|
||||
Data::SyncConfig(Some((config, config2))) => {
|
||||
Data::SyncConfig(Some(configs)) => {
|
||||
let (config, config2) = *configs;
|
||||
let _chk = CheckIfRestart::new();
|
||||
Config::set(config);
|
||||
Config2::set(config2);
|
||||
@@ -428,7 +429,9 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
Data::SyncConfig(None) => {
|
||||
allow_err!(
|
||||
stream
|
||||
.send(&Data::SyncConfig(Some((Config::get(), Config2::get()))))
|
||||
.send(&Data::SyncConfig(Some(
|
||||
(Config::get(), Config2::get()).into()
|
||||
)))
|
||||
.await
|
||||
);
|
||||
}
|
||||
@@ -840,6 +843,19 @@ pub async fn test_rendezvous_server() -> ResultType<()> {
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn send_url_scheme(url: String) -> ResultType<()> {
|
||||
connect(1_000, "_url").await?.send(&Data::UrlLink(url)).await?;
|
||||
connect(1_000, "_url")
|
||||
.await?
|
||||
.send(&Data::UrlLink(url))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn verify_ffi_enum_data_size() {
|
||||
println!("{}", std::mem::size_of::<Data>());
|
||||
assert!(std::mem::size_of::<Data>() < 96);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,8 +193,8 @@ pub mod client {
|
||||
#[cfg(windows)]
|
||||
pub fn update_grab_get_key_name() {
|
||||
match get_keyboard_mode_enum() {
|
||||
KeyboardMode::Map => rdev::set_get_key_name(false),
|
||||
KeyboardMode::Translate => rdev::set_get_key_name(true),
|
||||
KeyboardMode::Map => rdev::set_get_key_unicode(false),
|
||||
KeyboardMode::Translate => rdev::set_get_key_unicode(true),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
@@ -259,7 +259,7 @@ pub fn start_grab_loop() {
|
||||
|
||||
|
||||
let mut _keyboard_mode = KeyboardMode::Map;
|
||||
let scan_code = event.scan_code;
|
||||
let _scan_code = event.scan_code;
|
||||
let res = if KEYBOARD_HOOKED.load(Ordering::SeqCst) {
|
||||
_keyboard_mode = client::process_event(&event, None);
|
||||
if is_press {
|
||||
@@ -272,7 +272,7 @@ pub fn start_grab_loop() {
|
||||
};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
match scan_code {
|
||||
match _scan_code {
|
||||
0x1D | 0x021D => rdev::set_modifier(Key::ControlLeft, is_press),
|
||||
0xE01D => rdev::set_modifier(Key::ControlRight, is_press),
|
||||
0x2A => rdev::set_modifier(Key::ShiftLeft, is_press),
|
||||
@@ -288,7 +288,7 @@ pub fn start_grab_loop() {
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe {
|
||||
// AltGr
|
||||
if scan_code == 0x021D {
|
||||
if _scan_code == 0x021D {
|
||||
IS_0X021D_DOWN = is_press;
|
||||
}
|
||||
}
|
||||
@@ -303,6 +303,8 @@ pub fn start_grab_loop() {
|
||||
if let Err(error) = rdev::grab(func) {
|
||||
log::error!("rdev Error: {:?}", error)
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
rdev::set_event_popup(false);
|
||||
});
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -804,12 +806,10 @@ pub fn map_keyboard_mode(event: &Event, mut key_event: KeyEvent) -> Option<KeyEv
|
||||
fn try_fill_unicode(event: &Event, key_event: &KeyEvent, events: &mut Vec<KeyEvent>) {
|
||||
match &event.unicode {
|
||||
Some(unicode_info) => {
|
||||
if !unicode_info.is_dead {
|
||||
for code in &unicode_info.unicode {
|
||||
let mut evt = key_event.clone();
|
||||
evt.set_unicode(*code as _);
|
||||
events.push(evt);
|
||||
}
|
||||
for code in &unicode_info.unicode {
|
||||
let mut evt = key_event.clone();
|
||||
evt.set_unicode(*code as _);
|
||||
events.push(evt);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
@@ -863,6 +863,12 @@ pub fn translate_virtual_keycode(event: &Event, mut key_event: KeyEvent) -> Opti
|
||||
|
||||
pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec<KeyEvent> {
|
||||
let mut events: Vec<KeyEvent> = Vec::new();
|
||||
if let Some(unicode_info) = &event.unicode {
|
||||
if unicode_info.is_dead {
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe {
|
||||
if event.scan_code == 0x021D {
|
||||
@@ -881,6 +887,13 @@ pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec<KeyEve
|
||||
try_fill_unicode(event, &key_event, &mut events);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe {
|
||||
if IS_0X021D_DOWN {
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
try_fill_unicode(event, &key_event, &mut events);
|
||||
|
||||
@@ -888,7 +901,6 @@ pub fn translate_keyboard_mode(event: &Event, key_event: KeyEvent) -> Vec<KeyEve
|
||||
if let Some(evt) = translate_virtual_keycode(event, key_event) {
|
||||
events.push(evt);
|
||||
}
|
||||
return events;
|
||||
}
|
||||
events
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("or", "oder"),
|
||||
("Continue with", "Fortfahren mit"),
|
||||
("Elevate", "Erheben"),
|
||||
("Zoom cursor", "Cursor zoomen"),
|
||||
("Zoom cursor", "Cursor vergrößern"),
|
||||
("Accept sessions via password", "Sitzung mit Passwort bestätigen"),
|
||||
("Accept sessions via click", "Sitzung mit einem Klick bestätigen"),
|
||||
("Accept sessions via both", "Sitzung mit Klick und Passwort bestätigen"),
|
||||
@@ -414,8 +414,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Select local keyboard type", "Lokalen Tastaturtyp auswählen"),
|
||||
("software_render_tip", "Wenn Sie eine Nvidia-Grafikkarte haben und sich das entfernte Fenster sofort nach dem Herstellen der Verbindung schließt, kann es helfen, den Nouveau-Treiber zu installieren und Software-Rendering zu verwenden. Ein Neustart der Software ist erforderlich."),
|
||||
("Always use software rendering", "Software-Rendering immer verwenden"),
|
||||
("config_input", "Um den entfernten Desktop mit der Tastatur steuern zu können, müssen Sie RustDesk \"Input Monitoring\"-Rechte erteilen."),
|
||||
("config_microphone", ""),
|
||||
("config_input", "Um den entfernten Desktop mit der Tastatur steuern zu können, müssen Sie RustDesk die Berechtigung \"Input Monitoring\" erteilen."),
|
||||
("config_microphone", "Um aus der Ferne sprechen zu können, müssen Sie RustDesk die Berechtigung \"Audio aufzeichnen\" erteilen."),
|
||||
("request_elevation_tip", "Sie können auch erhöhte Rechte anfordern, wenn sich jemand auf der Gegenseite befindet."),
|
||||
("Wait", "Warten"),
|
||||
("Elevation Error", "Berechtigungsfehler"),
|
||||
@@ -445,9 +445,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Bitrate", "Bitrate"),
|
||||
("FPS", "fps"),
|
||||
("Auto", "Automatisch"),
|
||||
("Other Default Options", "Weitere Standardoptionen"),
|
||||
("Voice call", ""),
|
||||
("Text chat", ""),
|
||||
("Stop voice call", ""),
|
||||
("Other Default Options", "Weitere Standardeinstellungen"),
|
||||
("Voice call", "Sprachanruf"),
|
||||
("Text chat", "Text-Chat"),
|
||||
("Stop voice call", "Sprachanruf beenden"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -446,8 +446,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("FPS", "FPS"),
|
||||
("Auto", "Auto"),
|
||||
("Other Default Options", "Altre Opzioni Predefinite"),
|
||||
("Voice call", ""),
|
||||
("Text chat", ""),
|
||||
("Stop voice call", ""),
|
||||
("Voice call", "Chiamata vocale"),
|
||||
("Text chat", "Chat testuale"),
|
||||
("Stop voice call", "Interrompi la chiamata vocale"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ use std::{
|
||||
use bytes::Bytes;
|
||||
|
||||
pub use connection::*;
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use hbb_common::config::Config2;
|
||||
use hbb_common::tcp::new_listener;
|
||||
use hbb_common::{
|
||||
allow_err,
|
||||
anyhow::{anyhow, Context},
|
||||
@@ -17,18 +20,15 @@ use hbb_common::{
|
||||
message_proto::*,
|
||||
protobuf::{Enum, Message as _},
|
||||
rendezvous_proto::*,
|
||||
ResultType,
|
||||
socket_client,
|
||||
sodiumoxide::crypto::{box_, secretbox, sign}, Stream, timeout, tokio,
|
||||
sodiumoxide::crypto::{box_, secretbox, sign},
|
||||
timeout, tokio, ResultType, Stream,
|
||||
};
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use hbb_common::config::Config2;
|
||||
use hbb_common::tcp::new_listener;
|
||||
use service::{GenericService, Service, Subscriber};
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use service::ServiceTmpl;
|
||||
use service::{GenericService, Service, Subscriber};
|
||||
|
||||
use crate::ipc::{connect, Data};
|
||||
use crate::ipc::Data;
|
||||
|
||||
pub mod audio_service;
|
||||
cfg_if::cfg_if! {
|
||||
@@ -65,7 +65,7 @@ type ConnMap = HashMap<i32, ConnInner>;
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref CHILD_PROCESS: Childs = Default::default();
|
||||
pub static ref CONN_COUNT: Arc<Mutex<usize>> = Default::default();
|
||||
// A client server used to provide local services(audio, video, clipboard, etc.)
|
||||
// A client server used to provide local services(audio, video, clipboard, etc.)
|
||||
// for all initiative connections.
|
||||
//
|
||||
// [Note]
|
||||
@@ -420,7 +420,8 @@ pub async fn start_server(is_server: bool) {
|
||||
if conn.send(&Data::SyncConfig(None)).await.is_ok() {
|
||||
if let Ok(Some(data)) = conn.next_timeout(1000).await {
|
||||
match data {
|
||||
Data::SyncConfig(Some((config, config2))) => {
|
||||
Data::SyncConfig(Some(configs)) => {
|
||||
let (config, config2) = *configs;
|
||||
if Config::set(config) {
|
||||
log::info!("config synced");
|
||||
}
|
||||
@@ -450,28 +451,26 @@ pub async fn start_ipc_url_server() {
|
||||
while let Some(Ok(conn)) = incoming.next().await {
|
||||
let mut conn = crate::ipc::Connection::new(conn);
|
||||
match conn.next_timeout(1000).await {
|
||||
Ok(Some(data)) => {
|
||||
match data {
|
||||
Data::UrlLink(url) => {
|
||||
#[cfg(feature = "flutter")]
|
||||
{
|
||||
if let Some(stream) = crate::flutter::GLOBAL_EVENT_STREAM.read().unwrap().get(
|
||||
crate::flutter::APP_TYPE_MAIN
|
||||
) {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("name", "on_url_scheme_received");
|
||||
m.insert("url", url.as_str());
|
||||
stream.add(serde_json::to_string(&m).unwrap());
|
||||
} else {
|
||||
log::warn!("No main window app found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
log::warn!("An unexpected data was sent to the ipc url server.")
|
||||
Ok(Some(data)) => match data {
|
||||
#[cfg(feature = "flutter")]
|
||||
Data::UrlLink(url) => {
|
||||
if let Some(stream) = crate::flutter::GLOBAL_EVENT_STREAM
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(crate::flutter::APP_TYPE_MAIN)
|
||||
{
|
||||
let mut m = HashMap::new();
|
||||
m.insert("name", "on_url_scheme_received");
|
||||
m.insert("url", url.as_str());
|
||||
stream.add(serde_json::to_string(&m).unwrap());
|
||||
} else {
|
||||
log::warn!("No main window app found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
log::warn!("An unexpected data was sent to the ipc url server.")
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
log::error!("{}", err);
|
||||
}
|
||||
@@ -509,7 +508,8 @@ async fn sync_and_watch_config_dir() {
|
||||
if conn.send(&Data::SyncConfig(None)).await.is_ok() {
|
||||
if let Ok(Some(data)) = conn.next_timeout(1000).await {
|
||||
match data {
|
||||
Data::SyncConfig(Some((config, config2))) => {
|
||||
Data::SyncConfig(Some(configs)) => {
|
||||
let (config, config2) = *configs;
|
||||
let _chk = crate::ipc::CheckIfRestart::new();
|
||||
if cfg0.0 != config {
|
||||
cfg0.0 = config.clone();
|
||||
@@ -534,7 +534,7 @@ async fn sync_and_watch_config_dir() {
|
||||
let cfg = (Config::get(), Config2::get());
|
||||
if cfg != cfg0 {
|
||||
log::info!("config updated, sync to root");
|
||||
match conn.send(&Data::SyncConfig(Some(cfg.clone()))).await {
|
||||
match conn.send(&Data::SyncConfig(Some(cfg.clone().into()))).await {
|
||||
Err(e) => {
|
||||
log::error!("sync config to root failed: {}", e);
|
||||
break;
|
||||
|
||||
@@ -14,12 +14,9 @@ use objc::{
|
||||
sel, sel_impl,
|
||||
};
|
||||
use objc::runtime::Class;
|
||||
use objc_id::WeakId;
|
||||
use sciter::{Host, make_args};
|
||||
|
||||
use hbb_common::{log, tokio};
|
||||
|
||||
use crate::ui_cm_interface::start_ipc;
|
||||
use hbb_common::log;
|
||||
|
||||
static APP_HANDLER_IVAR: &str = "GoDeskAppHandler";
|
||||
|
||||
@@ -141,7 +138,7 @@ extern "C" fn application_should_handle_open_untitled_file(
|
||||
if !LAUNCHED {
|
||||
return YES;
|
||||
}
|
||||
hbb_common::log::debug!("icon clicked on finder");
|
||||
log::debug!("icon clicked on finder");
|
||||
if std::env::args().nth(1) == Some("--server".to_owned()) {
|
||||
crate::platform::macos::check_main_window();
|
||||
}
|
||||
@@ -267,4 +264,4 @@ pub fn make_tray() {
|
||||
set_delegate(None);
|
||||
}
|
||||
crate::tray::make_tray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,6 +845,7 @@ pub fn elevate_portable(_id: i32) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))]
|
||||
#[inline]
|
||||
pub fn handle_incoming_voice_call(id: i32, accept: bool) {
|
||||
if let Some(client) = CLIENTS.write().unwrap().get_mut(&id) {
|
||||
@@ -852,9 +853,10 @@ pub fn handle_incoming_voice_call(id: i32, accept: bool) {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))]
|
||||
#[inline]
|
||||
pub fn close_voice_call(id: i32) {
|
||||
if let Some(client) = CLIENTS.write().unwrap().get_mut(&id) {
|
||||
allow_err!(client.tx.send(Data::CloseVoiceCall("".to_owned())));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,8 +369,8 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
match &self.lc.read().unwrap().keyboard_mode as _ {
|
||||
"legacy" => rdev::set_get_key_name(true),
|
||||
"translate" => rdev::set_get_key_name(true),
|
||||
"legacy" => rdev::set_get_key_unicode(true),
|
||||
"translate" => rdev::set_get_key_unicode(true),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
pub fn leave(&self) {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
rdev::set_get_key_name(false);
|
||||
rdev::set_get_key_unicode(false);
|
||||
}
|
||||
IS_IN.store(false, Ordering::SeqCst);
|
||||
keyboard::client::change_grab_status(GrabState::Wait);
|
||||
|
||||
Reference in New Issue
Block a user