Merge remote-tracking branch 'rd/master' into feat/x11/clipboard-file/init

Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
This commit is contained in:
ClSlaid
2023-10-28 19:56:19 +08:00
56 changed files with 450 additions and 136 deletions

View File

@@ -53,9 +53,10 @@ use std::{
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use system_shutdown;
#[cfg(all(windows, feature = "virtual_display_driver"))]
use crate::virtual_display_manager;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use std::collections::HashSet;
pub type Sender = mpsc::UnboundedSender<(Instant, Arc<Message>)>;
lazy_static::lazy_static! {
@@ -1031,9 +1032,10 @@ impl Connection {
pi.hostname = DEVICE_NAME.lock().unwrap().clone();
pi.platform = "Android".into();
}
#[cfg(any(target_os = "linux", target_os = "windows"))]
let mut platform_additions = serde_json::Map::new();
#[cfg(target_os = "linux")]
{
let mut platform_additions = serde_json::Map::new();
if crate::platform::current_is_wayland() {
platform_additions.insert("is_wayland".into(), json!(true));
}
@@ -1044,12 +1046,27 @@ impl Connection {
platform_additions.insert("headless".into(), json!(true));
}
}
if !platform_additions.is_empty() {
pi.platform_additions =
serde_json::to_string(&platform_additions).unwrap_or("".into());
}
#[cfg(target_os = "windows")]
{
platform_additions.insert(
"is_installed".into(),
json!(crate::platform::is_installed()),
);
#[cfg(feature = "virtual_display_driver")]
if crate::platform::is_installed() {
let virtual_displays = virtual_display_manager::get_virtual_displays();
if !virtual_displays.is_empty() {
platform_additions.insert("virtual_displays".into(), json!(&virtual_displays));
}
}
}
#[cfg(any(target_os = "linux", target_os = "windows"))]
if !platform_additions.is_empty() {
pi.platform_additions = serde_json::to_string(&platform_additions).unwrap_or("".into());
}
pi.encoding = Some(scrap::codec::Encoder::supported_encoding()).into();
if self.port_forward_socket.is_some() {
@@ -1963,6 +1980,10 @@ impl Connection {
let set = displays.set.iter().map(|d| *d as usize).collect::<Vec<_>>();
self.capture_displays(&add, &sub, &set).await;
}
#[cfg(all(windows, feature = "virtual_display_driver"))]
Some(misc::Union::ToggleVirtualDisplay(t)) => {
self.toggle_virtual_display(t).await;
}
Some(misc::Union::ChatMessage(c)) => {
self.send_to_cm(ipc::Data::ChatMessage { text: c.text });
self.chat_unanswered = true;
@@ -2215,6 +2236,25 @@ impl Connection {
}
}
#[cfg(all(windows, feature = "virtual_display_driver"))]
async fn toggle_virtual_display(&mut self, t: ToggleVirtualDisplay) {
if t.on {
if let Err(e) = virtual_display_manager::plug_in_index_modes(t.display as _, Vec::new())
{
log::error!("Failed to plug in virtual display: {}", e);
}
} else {
let indices = if t.display == -1 {
virtual_display_manager::get_virtual_displays()
} else {
vec![t.display as _]
};
if let Err(e) = virtual_display_manager::plug_out_peer_request(&indices) {
log::error!("Failed to plug out virtual display {:?}: {}", &indices, e);
}
}
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
fn change_resolution(&mut self, r: &Resolution) {
if self.keyboard {
@@ -2223,7 +2263,7 @@ impl Connection {
let name = display.name();
#[cfg(all(windows, feature = "virtual_display_driver"))]
if let Some(_ok) =
crate::virtual_display_manager::change_resolution_if_is_virtual_display(
virtual_display_manager::change_resolution_if_is_virtual_display(
&name,
r.width as _,
r.height as _,
@@ -2919,7 +2959,7 @@ mod raii {
}
#[cfg(all(windows, feature = "virtual_display_driver"))]
if active_conns_lock.is_empty() {
display_service::try_plug_out_virtual_display();
let _ = virtual_display_manager::reset_all();
}
#[cfg(all(windows))]
if active_conns_lock.is_empty() {

View File

@@ -12,6 +12,8 @@ use scrap::Display;
pub const NAME: &'static str = "display";
const DUMMY_DISPLAY_SIDE_MAX_SIZE: usize = 1024;
struct ChangedResolution {
original: (i32, i32),
changed: (i32, i32),
@@ -154,6 +156,20 @@ fn displays_to_msg(displays: Vec<DisplayInfo>) -> Message {
..Default::default()
};
pi.displays = displays.clone();
#[cfg(all(windows, feature = "virtual_display_driver"))]
if crate::platform::is_installed() {
let virtual_displays = crate::virtual_display_manager::get_virtual_displays();
if !virtual_displays.is_empty() {
let mut platform_additions = serde_json::Map::new();
platform_additions.insert(
"virtual_displays".into(),
serde_json::json!(&virtual_displays),
);
pi.platform_additions = serde_json::to_string(&platform_additions).unwrap_or("".into());
}
}
// current_display should not be used in server.
// It is set to 0 for compatibility with old clients.
pi.current_display = 0;
@@ -168,11 +184,6 @@ fn check_get_displays_changed_msg() -> Option<Message> {
Some(displays_to_msg(displays))
}
#[cfg(all(windows, feature = "virtual_display_driver"))]
pub fn try_plug_out_virtual_display() {
let _res = virtual_display_manager::plug_out_headless();
}
fn run(sp: EmptyExtraFieldService) -> ResultType<()> {
while sp.ok() {
sp.snapshot(|sps| {
@@ -312,9 +323,18 @@ fn no_displays(displays: &Vec<Display>) -> bool {
true
} else if display_len == 1 {
let display = &displays[0];
let dummy_display_side_max_size = 800;
display.width() <= dummy_display_side_max_size
&& display.height() <= dummy_display_side_max_size
if display.width() > DUMMY_DISPLAY_SIDE_MAX_SIZE
|| display.height() > DUMMY_DISPLAY_SIDE_MAX_SIZE
{
return false;
}
let any_real = crate::platform::resolutions(&display.name())
.iter()
.any(|r| {
(r.height as usize) > DUMMY_DISPLAY_SIDE_MAX_SIZE
|| (r.width as usize) > DUMMY_DISPLAY_SIDE_MAX_SIZE
});
!any_real
} else {
false
}

View File

@@ -255,7 +255,7 @@ pub fn test_create_capturer(
) -> String {
let test_begin = Instant::now();
loop {
let err = match try_get_displays() {
let err = match Display::all() {
Ok(mut displays) => {
if displays.len() <= display_idx {
anyhow!(
@@ -271,7 +271,7 @@ pub fn test_create_capturer(
}
}
}
Err(e) => e,
Err(e) => e.into(),
};
if test_begin.elapsed().as_millis() >= timeout_millis as _ {
return err.to_string();
@@ -332,7 +332,7 @@ fn get_capturer(
}
}
let mut displays = try_get_displays()?;
let mut displays = Display::all()?;
let ndisplay = displays.len();
if ndisplay <= current {
bail!(
@@ -761,52 +761,6 @@ pub fn refresh() {
Display::refresh_size();
}
#[inline]
#[cfg(not(all(windows, feature = "virtual_display_driver")))]
fn try_get_displays() -> ResultType<Vec<Display>> {
Ok(Display::all()?)
}
#[inline]
#[cfg(all(windows, feature = "virtual_display_driver"))]
fn no_displays(displays: &Vec<Display>) -> bool {
let display_len = displays.len();
if display_len == 0 {
true
} else if display_len == 1 {
let display = &displays[0];
let dummy_display_side_max_size = 800;
if display.width() > dummy_display_side_max_size
|| display.height() > dummy_display_side_max_size
{
return false;
}
let any_real = crate::platform::resolutions(&display.name())
.iter()
.any(|r| {
(r.height as usize) > dummy_display_side_max_size
|| (r.width as usize) > dummy_display_side_max_size
});
!any_real
} else {
false
}
}
#[cfg(all(windows, feature = "virtual_display_driver"))]
fn try_get_displays() -> ResultType<Vec<Display>> {
// let mut displays = Display::all()?;
// if no_displays(&displays) {
// log::debug!("no displays, create virtual display");
// if let Err(e) = virtual_display_manager::plug_in_headless() {
// log::error!("plug in headless failed {}", e);
// } else {
// displays = Display::all()?;
// }
// }
Ok(Display::all()?)
}
#[cfg(windows)]
fn start_uac_elevation_check() {
static START: Once = Once::new();