From 5ddb10366e5fe0c66187a44a45f07e43e1dfa0d9 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 13 Oct 2022 06:34:50 -0700 Subject: [PATCH] wayland: fix enigo crash & mid commit Signed-off-by: fufesou --- build.py | 1 + res/DEBIAN/postinst | 2 +- src/common.rs | 25 ++++-------------------- src/server/connection.rs | 1 - src/server/input_service.rs | 3 ++- src/server/video_service.rs | 26 ++++++++++++++++++++++--- src/server/wayland.rs | 39 ++++++++++++++++++++++++++++++++----- 7 files changed, 65 insertions(+), 32 deletions(-) diff --git a/build.py b/build.py index 7780ecfd0..dbc4f6255 100755 --- a/build.py +++ b/build.py @@ -342,6 +342,7 @@ def main(): os.system('cp -a res/DEBIAN/* tmpdeb/DEBIAN/') os.system('strip tmpdeb/usr/bin/rustdesk') os.system('mkdir -p tmpdeb/usr/lib/rustdesk') + os.system('mv tmpdeb/usr/bin/rustdesk tmpdeb/usr/lib/rustdesk/') os.system('cp libsciter-gtk.so tmpdeb/usr/lib/rustdesk/') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service.user') diff --git a/res/DEBIAN/postinst b/res/DEBIAN/postinst index 44cb88c33..95222564d 100755 --- a/res/DEBIAN/postinst +++ b/res/DEBIAN/postinst @@ -14,7 +14,7 @@ if [ "$1" = configure ]; then fi version=$(python3 -V 2>&1 | grep -Po '(?<=Python )(.+)') parsedVersion=$(echo "${version//./}") - mkdir -p /usr/lib/systemd/system/ + mkdir -p /usr/lib/systemd/system/ cp /usr/share/rustdesk/files/systemd/rustdesk.service /usr/lib/systemd/system/rustdesk.service systemctl daemon-reload systemctl enable rustdesk diff --git a/src/common.rs b/src/common.rs index 9beed2e90..26903eacf 100644 --- a/src/common.rs +++ b/src/common.rs @@ -34,34 +34,17 @@ lazy_static::lazy_static! { pub static ref DEVICE_NAME: Arc> = Default::default(); } -lazy_static::lazy_static! { - static ref GLOBAL_INIT_FUNCS: Mutex bool>> = Default::default(); - static ref GLOBAL_CLEAN_FUNCS: Mutex> = 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; + #[cfg(target_os = "linux")] + { + if !scrap::is_x11() { + crate::server::wayland::set_wayland_scrap_map_err(); } } true } pub fn global_clean() { - for (k, f) in GLOBAL_CLEAN_FUNCS.lock().unwrap().iter() { - println!("Clean {}", k); - f(); - } } #[inline] diff --git a/src/server/connection.rs b/src/server/connection.rs index 8e3f80bb9..c451d5a1c 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -666,7 +666,6 @@ impl Connection { #[allow(unused_mut)] let mut username = crate::platform::get_active_username(); let mut res = LoginResponse::new(); - let mut pi = PeerInfo { username: username.clone(), conn_id: self.inner.id, diff --git a/src/server/input_service.rs b/src/server/input_service.rs index f36f2c50e..7dbba0e05 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -190,7 +190,8 @@ pub async fn set_uinput() -> ResultType<()> { let mouse = super::uinput::client::UInputMouse::new().await?; log::info!("UInput mouse created"); - let mut en = ENIGO.lock().unwrap(); + let xxx = ENIGO.lock(); + let mut en = xxx.unwrap(); en.set_uinput_keyboard(Some(Box::new(keyboard))); en.set_uinput_mouse(Some(Box::new(mouse))); Ok(()) diff --git a/src/server/video_service.rs b/src/server/video_service.rs index fad66ffb4..2b94077be 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -379,6 +379,10 @@ fn run(sp: GenericService) -> ResultType<()> { #[cfg(windows)] ensure_close_virtual_device()?; + // ensure_inited() is needed because release_resouce() may be called. + #[cfg(target_os = "linux")] + super::wayland::ensure_inited()?; + let mut c = get_capturer(true)?; let mut video_qos = VIDEO_QOS.lock().unwrap(); @@ -458,6 +462,8 @@ fn run(sp: GenericService) -> ResultType<()> { #[cfg(windows)] start_uac_elevation_check(); + let mut would_block_count = 0u32; + while sp.ok() { #[cfg(windows)] check_uac_switch(c.privacy_mode_id, c._captuerer_privacy_mode_id)?; @@ -547,8 +553,7 @@ fn run(sp: GenericService) -> ResultType<()> { }; match res { - Err(ref e) if e.kind() == WouldBlock => - { + Err(ref e) if e.kind() == WouldBlock => { #[cfg(windows)] if try_gdi > 0 && !c.is_gdi() { if try_gdi > 3 { @@ -558,6 +563,19 @@ fn run(sp: GenericService) -> ResultType<()> { } try_gdi += 1; } + + would_block_count += 1; + #[cfg(target_os = "linux")] + { + if !scrap::is_x11() { + if would_block_count >= 100 { + // For now, the user should choose and agree screen sharing agiain. + // to-do: Remember choice, attendless... + super::wayland::release_resouce(); + bail!("Wayland capturer none 100 times, try restart captuere"); + } + } + } } Err(err) => { if check_display_changed(c.ndisplay, c.current, c.width, c.height) { @@ -575,7 +593,9 @@ fn run(sp: GenericService) -> ResultType<()> { return Err(err.into()); } - _ => {} + _ => { + would_block_count = 0; + } } let mut fetched_conn_ids = HashSet::new(); diff --git a/src/server/wayland.rs b/src/server/wayland.rs index c12d1e8da..6d4a85399 100644 --- a/src/server/wayland.rs +++ b/src/server/wayland.rs @@ -12,13 +12,22 @@ pub const SCRAP_X11_REF_URL: &str = "https://rustdesk.com/docs/en/manual/linux/# lazy_static::lazy_static! { static ref CAP_DISPLAY_INFO: RwLock = RwLock::new(0); static ref LOG_SCRAP_COUNT: Mutex = 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 { +pub fn set_wayland_scrap_map_err() { + set_map_err(map_err_scrap); +} + +fn map_err_scrap(err: String) -> io::Error { + // REMOVE ME ===================================== uncomment to handle error + // // to-do: Handle error better, do not restart server + // if err.starts_with("Did not receive a reply") { + // log::error!("Fatal pipewire error, {}", &err); + // std::process::exit(-1); + // } + + log::error!("REMOVE ME ===================================== wayland scrap error {}", &err); + 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) @@ -79,6 +88,11 @@ struct CapDisplayInfo { capturer: CapturerPtr, } +#[tokio::main(flavor = "current_thread")] +pub(super) async fn ensure_inited() -> ResultType<()> { + check_init().await +} + async fn check_init() -> ResultType<()> { if !scrap::is_x11() { let mut minx = 0; @@ -205,6 +219,21 @@ pub(super) fn get_display_num() -> ResultType { } } +pub(super) fn release_resouce() { + if scrap::is_x11() { + return; + } + let mut write_lock = CAP_DISPLAY_INFO.write().unwrap(); + if *write_lock != 0 { + let cap_display_info: *mut CapDisplayInfo = *write_lock as _; + unsafe { + let box_capturer = Box::from_raw((*cap_display_info).capturer.0); + let box_cap_display_info = Box::from_raw(cap_display_info); + *write_lock = 0; + } + } +} + pub(super) fn get_capturer() -> ResultType { if scrap::is_x11() { bail!("Do not call this function if not wayland");