mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
multi remote instances 0.5
This commit is contained in:
@@ -28,7 +28,7 @@ pub trait FileManager: Interface {
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel_job(&mut self, id: i32) {
|
||||
fn cancel_job(&self, id: i32) {
|
||||
self.send(Data::CancelJob(id));
|
||||
}
|
||||
|
||||
@@ -44,23 +44,23 @@ pub trait FileManager: Interface {
|
||||
self.send(Data::Message(msg_out));
|
||||
}
|
||||
|
||||
fn remove_file(&mut self, id: i32, path: String, file_num: i32, is_remote: bool) {
|
||||
fn remove_file(&self, id: i32, path: String, file_num: i32, is_remote: bool) {
|
||||
self.send(Data::RemoveFile((id, path, file_num, is_remote)));
|
||||
}
|
||||
|
||||
fn remove_dir_all(&mut self, id: i32, path: String, is_remote: bool) {
|
||||
fn remove_dir_all(&self, id: i32, path: String, is_remote: bool) {
|
||||
self.send(Data::RemoveDirAll((id, path, is_remote)));
|
||||
}
|
||||
|
||||
fn confirm_delete_files(&mut self, id: i32, file_num: i32) {
|
||||
fn confirm_delete_files(&self, id: i32, file_num: i32) {
|
||||
self.send(Data::ConfirmDeleteFiles((id, file_num)));
|
||||
}
|
||||
|
||||
fn set_no_confirm(&mut self, id: i32) {
|
||||
fn set_no_confirm(&self, id: i32) {
|
||||
self.send(Data::SetNoConfirm(id));
|
||||
}
|
||||
|
||||
fn remove_dir(&mut self, id: i32, path: String, is_remote: bool) {
|
||||
fn remove_dir(&self, id: i32, path: String, is_remote: bool) {
|
||||
if is_remote {
|
||||
self.send(Data::RemoveDir((id, path)));
|
||||
} else {
|
||||
@@ -68,7 +68,7 @@ pub trait FileManager: Interface {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_dir(&mut self, id: i32, path: String, is_remote: bool) {
|
||||
fn create_dir(&self, id: i32, path: String, is_remote: bool) {
|
||||
self.send(Data::CreateDir((id, path, is_remote)));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::client::*;
|
||||
use crate::{client::*, flutter_ffi::EventToUI};
|
||||
use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer};
|
||||
use hbb_common::{
|
||||
allow_err,
|
||||
@@ -28,8 +28,7 @@ use std::{
|
||||
lazy_static::lazy_static! {
|
||||
// static ref SESSION: Arc<RwLock<Option<Session>>> = Default::default();
|
||||
pub static ref SESSIONS: RwLock<HashMap<String,Session>> = Default::default();
|
||||
pub static ref EVENT_STREAM: RwLock<Option<StreamSink<String>>> = Default::default(); // rust to dart event channel
|
||||
pub static ref RGBA_STREAM: RwLock<Option<StreamSink<ZeroCopyBuffer<Vec<u8>>>>> = Default::default(); // rust to dart rgba (big u8 list) channel
|
||||
pub static ref GLOBAL_EVENT_STREAM: RwLock<Option<StreamSink<String>>> = Default::default(); // rust to dart event channel
|
||||
}
|
||||
|
||||
// pub fn get_session<'a>(id: &str) -> Option<&'a Session> {
|
||||
@@ -41,7 +40,7 @@ pub struct Session {
|
||||
id: String,
|
||||
sender: Arc<RwLock<Option<mpsc::UnboundedSender<Data>>>>, // UI to rust
|
||||
lc: Arc<RwLock<LoginConfigHandler>>,
|
||||
events2ui: Arc<RwLock<StreamSink<String>>>,
|
||||
events2ui: Arc<RwLock<StreamSink<EventToUI>>>,
|
||||
}
|
||||
|
||||
impl Session {
|
||||
@@ -51,7 +50,7 @@ impl Session {
|
||||
///
|
||||
/// * `id` - The id of the remote session.
|
||||
/// * `is_file_transfer` - If the session is used for file transfer.
|
||||
pub fn start(id: &str, is_file_transfer: bool, events2ui: StreamSink<String>) {
|
||||
pub fn start(id: &str, is_file_transfer: bool, events2ui: StreamSink<EventToUI>) {
|
||||
LocalConfig::set_remote_id(&id);
|
||||
// TODO check same id
|
||||
// TODO close
|
||||
@@ -284,11 +283,8 @@ impl Session {
|
||||
let mut h: HashMap<&str, &str> = event.iter().cloned().collect();
|
||||
assert!(h.get("name").is_none());
|
||||
h.insert("name", name);
|
||||
|
||||
self.events2ui
|
||||
.read()
|
||||
.unwrap()
|
||||
.add(serde_json::ser::to_string(&h).unwrap_or("".to_owned()));
|
||||
let out = serde_json::ser::to_string(&h).unwrap_or("".to_owned());
|
||||
self.events2ui.read().unwrap().add(EventToUI::Event(out));
|
||||
}
|
||||
|
||||
/// Get platform of peer.
|
||||
@@ -676,11 +672,11 @@ impl Connection {
|
||||
if !self.first_frame {
|
||||
self.first_frame = true;
|
||||
}
|
||||
if let (Ok(true), Some(s)) = (
|
||||
self.video_handler.handle_frame(vf),
|
||||
RGBA_STREAM.read().unwrap().as_ref(),
|
||||
) {
|
||||
s.add(ZeroCopyBuffer(self.video_handler.rgb.clone()));
|
||||
if let Ok(true) = self.video_handler.handle_frame(vf) {
|
||||
let stream = self.session.events2ui.read().unwrap();
|
||||
stream.add(EventToUI::Rgba(ZeroCopyBuffer(
|
||||
self.video_handler.rgb.clone(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
Some(message::Union::hash(hash)) => {
|
||||
@@ -1274,7 +1270,7 @@ pub mod connection_manager {
|
||||
use scrap::android::call_main_service_set_by_name;
|
||||
use serde_derive::Serialize;
|
||||
|
||||
use super::EVENT_STREAM;
|
||||
use super::GLOBAL_EVENT_STREAM;
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
struct Client {
|
||||
@@ -1382,7 +1378,7 @@ pub mod connection_manager {
|
||||
assert!(h.get("name").is_none());
|
||||
h.insert("name", name);
|
||||
|
||||
if let Some(s) = EVENT_STREAM.read().unwrap().as_ref() {
|
||||
if let Some(s) = GLOBAL_EVENT_STREAM.read().unwrap().as_ref() {
|
||||
s.add(serde_json::ser::to_string(&h).unwrap_or("".to_owned()));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -59,18 +59,18 @@ pub extern "C" fn rustdesk_core_main() -> bool {
|
||||
crate::core_main::core_main()
|
||||
}
|
||||
|
||||
pub fn start_event_stream(s: StreamSink<String>) -> ResultType<()> {
|
||||
let _ = flutter::EVENT_STREAM.write().unwrap().insert(s);
|
||||
Ok(())
|
||||
pub enum EventToUI {
|
||||
Event(String),
|
||||
Rgba(ZeroCopyBuffer<Vec<u8>>),
|
||||
}
|
||||
|
||||
pub fn start_rgba_stream(s: StreamSink<ZeroCopyBuffer<Vec<u8>>>) -> ResultType<()> {
|
||||
let _ = flutter::RGBA_STREAM.write().unwrap().insert(s);
|
||||
pub fn start_global_event_stream(s: StreamSink<String>) -> ResultType<()> {
|
||||
let _ = flutter::GLOBAL_EVENT_STREAM.write().unwrap().insert(s);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn session_connect(
|
||||
events2ui: StreamSink<String>,
|
||||
events2ui: StreamSink<EventToUI>,
|
||||
id: String,
|
||||
is_file_transfer: bool,
|
||||
) -> ResultType<()> {
|
||||
@@ -86,6 +86,7 @@ pub fn get_session_remember(id: String) -> Option<bool> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO sync
|
||||
pub fn get_session_toggle_option(id: String, arg: String) -> Option<bool> {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||
Some(session.get_toggle_option(&arg))
|
||||
@@ -94,11 +95,20 @@ pub fn get_session_toggle_option(id: String, arg: String) -> Option<bool> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_session_image_quality(id: String) -> SyncReturn<Option<String>> {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||
SyncReturn(Some(session.get_image_quality()))
|
||||
pub fn get_session_toggle_option_sync(id: String, arg: String) -> SyncReturn<Vec<u8>> {
|
||||
let res = if get_session_toggle_option(id, arg) == Some(true) {
|
||||
1
|
||||
} else {
|
||||
SyncReturn(None)
|
||||
0
|
||||
};
|
||||
SyncReturn(vec![res])
|
||||
}
|
||||
|
||||
pub fn get_session_image_quality(id: String) -> Option<String> {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
|
||||
Some(session.get_image_quality())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,40 +527,49 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) {
|
||||
// "chat_client_mode" => {
|
||||
// Session::send_chat(value.to_owned());
|
||||
// }
|
||||
// "send_mouse" => {
|
||||
// if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
// let alt = m.get("alt").is_some();
|
||||
// let ctrl = m.get("ctrl").is_some();
|
||||
// let shift = m.get("shift").is_some();
|
||||
// let command = m.get("command").is_some();
|
||||
// let x = m
|
||||
// .get("x")
|
||||
// .map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
// .unwrap_or(0);
|
||||
// let y = m
|
||||
// .get("y")
|
||||
// .map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
// .unwrap_or(0);
|
||||
// let mut mask = 0;
|
||||
// if let Some(_type) = m.get("type") {
|
||||
// mask = match _type.as_str() {
|
||||
// "down" => 1,
|
||||
// "up" => 2,
|
||||
// "wheel" => 3,
|
||||
// _ => 0,
|
||||
// };
|
||||
// }
|
||||
// if let Some(buttons) = m.get("buttons") {
|
||||
// mask |= match buttons.as_str() {
|
||||
// "left" => 1,
|
||||
// "right" => 2,
|
||||
// "wheel" => 4,
|
||||
// _ => 0,
|
||||
// } << 3;
|
||||
// }
|
||||
// Session::send_mouse(mask, x, y, alt, ctrl, shift, command);
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO
|
||||
"send_mouse" => {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
let id = m.get("id");
|
||||
if id.is_none() {
|
||||
return;
|
||||
}
|
||||
let id = id.unwrap();
|
||||
let alt = m.get("alt").is_some();
|
||||
let ctrl = m.get("ctrl").is_some();
|
||||
let shift = m.get("shift").is_some();
|
||||
let command = m.get("command").is_some();
|
||||
let x = m
|
||||
.get("x")
|
||||
.map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
let y = m
|
||||
.get("y")
|
||||
.map(|x| x.parse::<i32>().unwrap_or(0))
|
||||
.unwrap_or(0);
|
||||
let mut mask = 0;
|
||||
if let Some(_type) = m.get("type") {
|
||||
mask = match _type.as_str() {
|
||||
"down" => 1,
|
||||
"up" => 2,
|
||||
"wheel" => 3,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
if let Some(buttons) = m.get("buttons") {
|
||||
mask |= match buttons.as_str() {
|
||||
"left" => 1,
|
||||
"right" => 2,
|
||||
"wheel" => 4,
|
||||
_ => 0,
|
||||
} << 3;
|
||||
}
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(id) {
|
||||
session.send_mouse(mask, x, y, alt, ctrl, shift, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
"option" => {
|
||||
if let Ok(m) = serde_json::from_str::<HashMap<String, String>>(value) {
|
||||
if let Some(name) = m.get("name") {
|
||||
|
||||
Reference in New Issue
Block a user