From 26e8355528d91e186a6d48de8dfbcbb1a947b2af Mon Sep 17 00:00:00 2001 From: fufesou Date: Fri, 18 Nov 2022 13:33:54 +0800 Subject: [PATCH] dynamic library - win virtual display Signed-off-by: fufesou --- Cargo.lock | 2 +- Cargo.toml | 2 +- build.py | 6 ++++ libs/clipboard/build.rs | 2 +- libs/virtual_display/Cargo.toml | 4 +++ libs/virtual_display/build.rs | 4 +-- libs/virtual_display/src/lib.rs | 9 +++++ src/server.rs | 2 ++ src/server/video_service.rs | 2 +- src/server/virtual_display.rs | 64 +++++++++++++++++++++++++++++++++ 10 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/server/virtual_display.rs diff --git a/Cargo.lock b/Cargo.lock index 49fcc3dce..0e892aa31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4391,6 +4391,7 @@ dependencies = [ "lazy_static", "libappindicator", "libc", + "libloading", "libpulse-binding", "libpulse-simple-binding", "mac_address", @@ -4424,7 +4425,6 @@ dependencies = [ "trayicon", "url", "uuid", - "virtual_display", "whoami", "winapi 0.3.9", "windows-service", diff --git a/Cargo.toml b/Cargo.toml index 836bd07d4..a3758c861 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ flutter_rust_bridge = { git = "https://github.com/SoLongAndThanksForAllThePizza/ errno = "0.2.8" rdev = { git = "https://github.com/asur4s/rdev" } url = { version = "2.1", features = ["serde"] } +libloading = "0.7" reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false } chrono = "0.4.23" @@ -91,7 +92,6 @@ winit = "0.26" winapi = { version = "0.3", features = ["winuser"] } winreg = "0.10" windows-service = "0.4" -virtual_display = { path = "libs/virtual_display" } impersonate_system = { git = "https://github.com/21pages/impersonate-system" } shared_memory = "0.12.4" shutdown_hooks = "0.1.0" diff --git a/build.py b/build.py index c907334ce..48eaf1bc0 100755 --- a/build.py +++ b/build.py @@ -280,6 +280,7 @@ def build_flutter_windows(version, features): exit(-1) os.chdir('flutter') os.system('flutter build windows --release') + shutil.copy2('target/release/deps/virtual_display.dll', flutter_win_target_dir) os.chdir('..') os.chdir('libs/portable') os.system('pip3 install -r requirements.txt') @@ -316,6 +317,11 @@ def main(): os.system('python3 res/inline-sciter.py') portable = args.portable if windows: + # build virtual display dynamic library + os.chdir('libs/virtual_display') + os.system('cargo build --release') + os.chdir('../..') + if flutter: build_flutter_windows(version, features) return diff --git a/libs/clipboard/build.rs b/libs/clipboard/build.rs index b5c547637..7eb52c75b 100644 --- a/libs/clipboard/build.rs +++ b/libs/clipboard/build.rs @@ -18,7 +18,7 @@ fn build_c_impl() { if build.get_compiler().is_like_msvc() { build.define("WIN32", ""); // build.define("_AMD64_", ""); - build.flag("-Zi"); + build.flag("-Z7"); build.flag("-GR-"); // build.flag("-std:c++11"); } else { diff --git a/libs/virtual_display/Cargo.toml b/libs/virtual_display/Cargo.toml index 8d0b65171..d0b63b454 100644 --- a/libs/virtual_display/Cargo.toml +++ b/libs/virtual_display/Cargo.toml @@ -3,6 +3,10 @@ name = "virtual_display" version = "0.1.0" edition = "2021" +[lib] +name = "virtual_display" +crate-type = ["cdylib", "staticlib", "rlib"] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] diff --git a/libs/virtual_display/build.rs b/libs/virtual_display/build.rs index 177d92371..29c3dd5d4 100644 --- a/libs/virtual_display/build.rs +++ b/libs/virtual_display/build.rs @@ -13,7 +13,7 @@ fn build_c_impl() { if build.get_compiler().is_like_msvc() { build.define("WIN32", ""); - build.flag("-Zi"); + build.flag("-Z7"); build.flag("-GR-"); // build.flag("-std:c++11"); } else { @@ -24,7 +24,7 @@ fn build_c_impl() { } #[cfg(target_os = "windows")] - build.compile("xxx"); + build.compile("win_virtual_display"); #[cfg(target_os = "windows")] println!("cargo:rerun-if-changed=src/win10/IddController.c"); diff --git a/libs/virtual_display/src/lib.rs b/libs/virtual_display/src/lib.rs index 9f71fd6da..7ffcc679f 100644 --- a/libs/virtual_display/src/lib.rs +++ b/libs/virtual_display/src/lib.rs @@ -11,6 +11,7 @@ lazy_static::lazy_static! { static ref MONITOR_PLUGIN: Mutex> = Mutex::new(Vec::new()); } +#[no_mangle] pub fn download_driver() -> ResultType<()> { #[cfg(windows)] let _download_url = win10::DRIVER_DOWNLOAD_URL; @@ -22,6 +23,7 @@ pub fn download_driver() -> ResultType<()> { Ok(()) } +#[no_mangle] pub fn install_update_driver(_reboot_required: &mut bool) -> ResultType<()> { #[cfg(windows)] let install_path = win10::DRIVER_INSTALL_PATH; @@ -62,6 +64,7 @@ pub fn install_update_driver(_reboot_required: &mut bool) -> ResultType<()> { Ok(()) } +#[no_mangle] pub fn uninstall_driver(_reboot_required: &mut bool) -> ResultType<()> { #[cfg(windows)] let install_path = win10::DRIVER_INSTALL_PATH; @@ -96,6 +99,7 @@ pub fn uninstall_driver(_reboot_required: &mut bool) -> ResultType<()> { Ok(()) } +#[no_mangle] pub fn is_device_created() -> bool { #[cfg(windows)] return *H_SW_DEVICE.lock().unwrap() != 0; @@ -103,6 +107,7 @@ pub fn is_device_created() -> bool { return false; } +#[no_mangle] pub fn create_device() -> ResultType<()> { if is_device_created() { return Ok(()); @@ -120,6 +125,7 @@ pub fn create_device() -> ResultType<()> { Ok(()) } +#[no_mangle] pub fn close_device() { #[cfg(windows)] unsafe { @@ -129,6 +135,7 @@ pub fn close_device() { } } +#[no_mangle] pub fn plug_in_monitor() -> ResultType<()> { #[cfg(windows)] unsafe { @@ -149,6 +156,7 @@ pub fn plug_in_monitor() -> ResultType<()> { Ok(()) } +#[no_mangle] pub fn plug_out_monitor() -> ResultType<()> { #[cfg(windows)] unsafe { @@ -169,6 +177,7 @@ pub fn plug_out_monitor() -> ResultType<()> { Ok(()) } +#[no_mangle] pub fn update_monitor_modes() -> ResultType<()> { #[cfg(windows)] unsafe { diff --git a/src/server.rs b/src/server.rs index 7e00532fe..bf81468ce 100644 --- a/src/server.rs +++ b/src/server.rs @@ -53,6 +53,8 @@ mod connection; pub mod portable_service; mod service; mod video_qos; +#[cfg(windows)] +mod virtual_display; pub mod video_service; use hbb_common::tcp::new_listener; diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 3ccc3af39..0597ac956 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -42,7 +42,7 @@ use std::{ time::{self, Duration, Instant}, }; #[cfg(windows)] -use virtual_display; +use super::virtual_display; pub const SCRAP_UBUNTU_HIGHER_REQUIRED: &str = "Wayland requires Ubuntu 21.04 or higher version."; pub const SCRAP_OTHER_VERSION_OR_X11_REQUIRED: &str = diff --git a/src/server/virtual_display.rs b/src/server/virtual_display.rs new file mode 100644 index 000000000..23071326b --- /dev/null +++ b/src/server/virtual_display.rs @@ -0,0 +1,64 @@ +#![allow(dead_code)] + +use hbb_common::{bail, ResultType}; +use std::sync::{Arc, Mutex}; + +const LIB_NAME_VIRTUAL_DISPLAY: &str = "virtual_display"; + +lazy_static::lazy_static! { + static ref LIB_VIRTUAL_DISPLAY: Arc>> = { + #[cfg(target_os = "windows")] + let libname = format!("{}.dll", LIB_NAME_VIRTUAL_DISPLAY); + #[cfg(target_os = "linux")] + let libname = format!("lib{}.so", LIB_NAME_VIRTUAL_DISPLAY); + #[cfg(target_os = "macos")] + let libname = format!("lib{}.dylib", LIB_NAME_VIRTUAL_DISPLAY); + Arc::new(Mutex::new(unsafe { libloading::Library::new(libname) })) + }; +} + +pub(super) fn is_device_created() -> bool { + match &*LIB_VIRTUAL_DISPLAY.lock().unwrap() { + Ok(lib) => unsafe { + match lib.get:: bool>>(b"is_device_created") { + Ok(func) => func(), + Err(..) => false, + } + }, + Err(..) => false, + } +} + +macro_rules! def_func_result { + ($func:ident, $name: tt) => { + pub(super) fn $func() -> ResultType<()> { + match &*LIB_VIRTUAL_DISPLAY.lock().unwrap() { + Ok(lib) => unsafe { + match lib.get:: ResultType<()>>>($name.as_bytes()) { + Ok(func) => func(), + Err(..) => bail!("Failed to load func {}", $name), + } + }, + Err(e) => bail!("Failed to load library {}, {}", LIB_NAME_VIRTUAL_DISPLAY, e), + } + } + }; +} + +def_func_result!(create_device, "create_device"); + +pub(super) fn close_device() { + match &*LIB_VIRTUAL_DISPLAY.lock().unwrap() { + Ok(lib) => unsafe { + match lib.get::>(b"close_device") { + Ok(func) => func(), + Err(..) => {}, + } + }, + Err(..) => {}, + } +} + +def_func_result!(plug_in_monitor, "plug_in_monitor"); +def_func_result!(plug_out_monitor, "plug_out_monitor"); +def_func_result!(update_monitor_modes, "update_monitor_modes");