add global init and update wayland error map

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2022-10-11 20:36:19 -07:00
parent 244c07e50e
commit 2da5401fd4
9 changed files with 151 additions and 12 deletions

View File

@ -1,5 +1,31 @@
use crate::ResultType; use crate::ResultType;
lazy_static::lazy_static! {
pub static ref DISTRO: Disto = Disto::new();
}
pub struct Disto {
pub name: String,
pub version_id: String,
}
impl Disto {
fn new() -> Self {
let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release".to_owned())
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
let version_id =
run_cmds("awk -F'=' '/^VERSION_ID=/ {print $2}' /etc/os-release".to_owned())
.unwrap_or_default()
.trim()
.trim_matches('"')
.to_string();
Self { name, version_id }
}
}
pub fn get_display_server() -> String { pub fn get_display_server() -> String {
let session = get_value_of_seat0(0); let session = get_value_of_seat0(0);
get_display_server_of_session(&session) get_display_server_of_session(&session)
@ -81,8 +107,9 @@ pub fn get_value_of_seat0(i: usize) -> String {
} }
// loginctl has not given the expected output. try something else. // loginctl has not given the expected output. try something else.
if let Ok(sid) = std::env::var("XDG_SESSION_ID") { // could also execute "cat /proc/self/sessionid" if let Ok(sid) = std::env::var("XDG_SESSION_ID") {
return sid.to_owned(); // could also execute "cat /proc/self/sessionid"
return sid.to_owned();
} }
return "".to_owned(); return "".to_owned();

View File

@ -12,6 +12,7 @@ cfg_if! {
mod x11; mod x11;
pub use self::linux::*; pub use self::linux::*;
pub use self::x11::Frame; pub use self::x11::Frame;
pub use self::wayland::set_map_err;
} else { } else {
mod x11; mod x11;
pub use self::x11::*; pub use self::x11::*;

View File

@ -1,11 +1,23 @@
use crate::common::{x11::Frame, TraitCapturer}; use crate::common::{x11::Frame, TraitCapturer};
use crate::wayland::{capturable::*, *}; use crate::wayland::{capturable::*, *};
use std::{io, time::Duration}; use std::{io, sync::RwLock, time::Duration};
pub struct Capturer(Display, Box<dyn Recorder>, bool, Vec<u8>); pub struct Capturer(Display, Box<dyn Recorder>, bool, Vec<u8>);
lazy_static::lazy_static! {
static ref MAP_ERR: RwLock<Option<fn(err: String)-> io::Error>> = Default::default();
}
pub fn set_map_err(f: fn(err: String) -> io::Error) {
*MAP_ERR.write().unwrap() = Some(f);
}
fn map_err<E: ToString>(err: E) -> io::Error { fn map_err<E: ToString>(err: E) -> io::Error {
io::Error::new(io::ErrorKind::Other, err.to_string()) if let Some(f) = *MAP_ERR.read().unwrap() {
f(err.to_string())
} else {
io::Error::new(io::ErrorKind::Other, err.to_string())
}
} }
impl Capturer { impl Capturer {

View File

@ -1,4 +1,7 @@
use std::sync::{Arc, Mutex}; use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub use arboard::Clipboard as ClipboardContext; pub use arboard::Clipboard as ClipboardContext;
@ -31,6 +34,36 @@ lazy_static::lazy_static! {
pub static ref DEVICE_NAME: Arc<Mutex<String>> = Default::default(); pub static ref DEVICE_NAME: Arc<Mutex<String>> = Default::default();
} }
lazy_static::lazy_static! {
static ref GLOBAL_INIT_FUNCS: Mutex<HashMap<String, fn() -> bool>> = Default::default();
static ref GLOBAL_CLEAN_FUNCS: Mutex<HashMap<String, fn()>> = Default::default();
}
pub fn reg_global_init(key: String, f: fn() -> bool) {
GLOBAL_INIT_FUNCS.lock().unwrap().insert(key, f);
}
pub fn reg_global_clean(key: String, f: fn()) {
GLOBAL_CLEAN_FUNCS.lock().unwrap().insert(key, f);
}
pub fn global_init() -> bool {
for (k, f) in GLOBAL_INIT_FUNCS.lock().unwrap().iter() {
println!("Init {}", k);
if !f() {
return false;
}
}
true
}
pub fn global_clean() {
for (k, f) in GLOBAL_CLEAN_FUNCS.lock().unwrap().iter() {
println!("Clean {}", k);
f();
}
}
#[inline] #[inline]
pub fn valid_for_numlock(evt: &KeyEvent) -> bool { pub fn valid_for_numlock(evt: &KeyEvent) -> bool {
if let Some(key_event::Union::ControlKey(ck)) = evt.union { if let Some(key_event::Union::ControlKey(ck)) = evt.union {

View File

@ -6,21 +6,32 @@ use librustdesk::*;
#[cfg(any(target_os = "android", target_os = "ios"))] #[cfg(any(target_os = "android", target_os = "ios"))]
fn main() { fn main() {
if !common::global_init() {
return;
}
common::test_rendezvous_server(); common::test_rendezvous_server();
common::test_nat_type(); common::test_nat_type();
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
crate::common::check_software_update(); crate::common::check_software_update();
common::global_clean();
} }
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
fn main() { fn main() {
if !common::global_init() {
return;
}
if let Some(args) = crate::core_main::core_main().as_mut() { if let Some(args) = crate::core_main::core_main().as_mut() {
ui::start(args); ui::start(args);
} }
common::global_clean();
} }
#[cfg(feature = "cli")] #[cfg(feature = "cli")]
fn main() { fn main() {
if !common::global_init() {
return;
}
use hbb_common::log; use hbb_common::log;
use clap::App; use clap::App;
let args = format!( let args = format!(
@ -64,4 +75,5 @@ fn main() {
let token = LocalConfig::get_option("access_token"); let token = LocalConfig::get_option("access_token");
cli::start_one_port_forward(options[0].clone(), port, remote_host, remote_port, key, token); cli::start_one_port_forward(options[0].clone(), port, remote_host, remote_port, key, token);
} }
common::global_clean();
} }

View File

@ -27,7 +27,7 @@ cfg_if::cfg_if! {
if #[cfg(not(any(target_os = "android", target_os = "ios")))] { if #[cfg(not(any(target_os = "android", target_os = "ios")))] {
mod clipboard_service; mod clipboard_service;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
mod wayland; pub(crate) mod wayland;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub mod uinput; pub mod uinput;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]

View File

@ -745,7 +745,7 @@ impl Connection {
try_activate_screen(); try_activate_screen();
match super::video_service::get_displays().await { match super::video_service::get_displays().await {
Err(err) => { Err(err) => {
res.set_error(format!("X11 error: {}", err)); res.set_error(format!("Error: {}", err));
} }
Ok((current, displays)) => { Ok((current, displays)) => {
pi.displays = displays.into(); pi.displays = displays.into();

View File

@ -1,10 +1,53 @@
use super::*; use super::*;
use hbb_common::allow_err; use hbb_common::{allow_err, platform::linux::DISTRO};
use scrap::{Capturer, Display, Frame, TraitCapturer}; use scrap::{set_map_err, Capturer, Display, Frame, TraitCapturer};
use std::io::Result; use std::io;
pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version.";
pub const SCRAP_OTHER_VERSION_OR_X11_REQUIRED: &str =
"Wayland requires higher version of linux distro. Please try X11 desktop or change your OS.";
pub const SCRAP_X11_REQUIRED: &str = "X11 is required";
pub const SCRAP_X11_REF_URL: &str = "https://rustdesk.com/docs/en/manual/linux/#x11-required";
lazy_static::lazy_static! { lazy_static::lazy_static! {
static ref CAP_DISPLAY_INFO: RwLock<u64> = RwLock::new(0); static ref CAP_DISPLAY_INFO: RwLock<u64> = RwLock::new(0);
static ref LOG_SCRAP_COUNT: Mutex<u32> = Mutex::new(0);
static ref GLOBAL_INIT_REG_HELPER: u8 = {
set_map_err(map_err_scrap);
0u8
};
}
pub fn map_err_scrap(err: String) -> io::Error {
if DISTRO.name.to_uppercase() == "Ubuntu".to_uppercase() {
if DISTRO.version_id < "21".to_owned() {
io::Error::new(io::ErrorKind::Other, SCRAP_UBUNTU_HIGHER_REQUIRED)
} else {
try_log(&err);
io::Error::new(io::ErrorKind::Other, err)
}
} else {
try_log(&err);
if err.contains("org.freedesktop.portal")
|| err.contains("pipewire")
|| err.contains("dbus")
{
io::Error::new(io::ErrorKind::Other, SCRAP_OTHER_VERSION_OR_X11_REQUIRED)
} else {
io::Error::new(io::ErrorKind::Other, SCRAP_X11_REQUIRED)
}
}
}
fn try_log(err: &String) {
let mut lock_count = LOG_SCRAP_COUNT.lock().unwrap();
if *lock_count >= 1000000 {
return;
}
if *lock_count % 10000 == 0 {
log::error!("Failed scrap {}", err);
}
*lock_count += 1;
} }
struct CapturerPtr(*mut Capturer); struct CapturerPtr(*mut Capturer);
@ -16,7 +59,7 @@ impl Clone for CapturerPtr {
} }
impl TraitCapturer for CapturerPtr { impl TraitCapturer for CapturerPtr {
fn frame<'a>(&'a mut self, timeout: Duration) -> Result<Frame<'a>> { fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result<Frame<'a>> {
unsafe { (*self.0).frame(timeout) } unsafe { (*self.0).frame(timeout) }
} }
@ -187,3 +230,14 @@ pub(super) fn get_capturer() -> ResultType<super::video_service::CapturerInfo> {
bail!("Failed to get capturer display info"); bail!("Failed to get capturer display info");
} }
} }
pub fn common_get_error() -> String {
if DISTRO.name.to_uppercase() == "Ubuntu".to_uppercase() {
if DISTRO.version_id < "21".to_owned() {
return "".to_owned();
}
} else {
// to-do: check other distros
}
return "".to_owned();
}

View File

@ -547,7 +547,7 @@ pub fn get_error() -> String {
{ {
let dtype = crate::platform::linux::get_display_server(); let dtype = crate::platform::linux::get_display_server();
if "wayland" == dtype { if "wayland" == dtype {
return "".to_owned(); return crate::server::wayland::common_get_error();
} }
if dtype != "x11" { if dtype != "x11" {
return format!( return format!(