mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
remember resolution, mid commit
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
@@ -56,6 +56,10 @@ use windows_service::{
|
||||
use winreg::enums::*;
|
||||
use winreg::RegKey;
|
||||
|
||||
// This string is defined here.
|
||||
// https://github.com/fufesou/RustDeskIddDriver/blob/b370aad3f50028b039aad211df60c8051c4a64d6/RustDeskIddDriver/RustDeskIddDriver.inf#LL73C1-L73C40
|
||||
const IDD_DEVICE_STRING: &'static str = "RustDeskIddDriver Device\0";
|
||||
|
||||
pub fn get_cursor_pos() -> Option<(i32, i32)> {
|
||||
unsafe {
|
||||
#[allow(invalid_value)]
|
||||
@@ -1831,21 +1835,25 @@ pub fn set_path_permission(dir: &PathBuf, permission: &str) -> ResultType<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn str_to_device_name(name: &str) -> [u16; 32] {
|
||||
let mut device_name: Vec<u16> = wide_string(name);
|
||||
if device_name.len() < 32 {
|
||||
device_name.resize(32, 0);
|
||||
}
|
||||
let mut result = [0; 32];
|
||||
result.copy_from_slice(&device_name[..32]);
|
||||
result
|
||||
}
|
||||
|
||||
pub fn resolutions(name: &str) -> Vec<Resolution> {
|
||||
unsafe {
|
||||
let mut dm: DEVMODEW = std::mem::zeroed();
|
||||
let wname = wide_string(name);
|
||||
let len = if wname.len() <= dm.dmDeviceName.len() {
|
||||
wname.len()
|
||||
} else {
|
||||
dm.dmDeviceName.len()
|
||||
};
|
||||
std::ptr::copy_nonoverlapping(wname.as_ptr(), dm.dmDeviceName.as_mut_ptr(), len);
|
||||
dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
||||
let mut v = vec![];
|
||||
let mut num = 0;
|
||||
let device_name = str_to_device_name(name);
|
||||
loop {
|
||||
if EnumDisplaySettingsW(NULL as _, num, &mut dm) == 0 {
|
||||
if EnumDisplaySettingsW(device_name.as_ptr(), num, &mut dm) == 0 {
|
||||
break;
|
||||
}
|
||||
let r = Resolution {
|
||||
@@ -1866,8 +1874,8 @@ pub fn current_resolution(name: &str) -> ResultType<Resolution> {
|
||||
unsafe {
|
||||
let mut dm: DEVMODEW = std::mem::zeroed();
|
||||
dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
||||
let wname = wide_string(name);
|
||||
if EnumDisplaySettingsW(wname.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) == 0 {
|
||||
let device_name = str_to_device_name(name);
|
||||
if EnumDisplaySettingsW(device_name.as_ptr(), ENUM_CURRENT_SETTINGS, &mut dm) == 0 {
|
||||
bail!(
|
||||
"failed to get currrent resolution, errno={}",
|
||||
GetLastError()
|
||||
@@ -1882,29 +1890,46 @@ pub fn current_resolution(name: &str) -> ResultType<Resolution> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_virtual_display(name: &str) -> ResultType<bool> {
|
||||
let device_name = str_to_device_name(name);
|
||||
let mut dd: DISPLAY_DEVICEW = unsafe { std::mem::zeroed() };
|
||||
dd.cb = std::mem::size_of::<DISPLAY_DEVICEW>() as _;
|
||||
let ok = unsafe { EnumDisplayDevicesW(device_name.as_ptr(), 0, &mut dd as _, 0) };
|
||||
if ok == FALSE {
|
||||
bail!(
|
||||
"enumerate display devices with device name '{}', errno {}",
|
||||
name,
|
||||
unsafe { GetLastError() }
|
||||
);
|
||||
}
|
||||
match std::string::String::from_utf16(&dd.DeviceString) {
|
||||
Ok(s) => Ok(&s[..IDD_DEVICE_STRING.len()] == IDD_DEVICE_STRING),
|
||||
Err(e) => bail!(
|
||||
"convert the device string of '{}' to string: {}",
|
||||
name,
|
||||
e
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_resolution(name: &str, width: usize, height: usize) -> ResultType<()> {
|
||||
let device_name = str_to_device_name(name);
|
||||
unsafe {
|
||||
let mut dm: DEVMODEW = std::mem::zeroed();
|
||||
if FALSE == EnumDisplaySettingsW(NULL as _, ENUM_CURRENT_SETTINGS, &mut dm) {
|
||||
if FALSE == EnumDisplaySettingsW(device_name.as_ptr() as _, ENUM_CURRENT_SETTINGS, &mut dm)
|
||||
{
|
||||
bail!("EnumDisplaySettingsW failed, errno={}", GetLastError());
|
||||
}
|
||||
|
||||
// to-do: check if need change
|
||||
println!("REMOVE ME ========================== dm ({},{}) to ({},{})", dm.dmPelsWidth, dm.dmPelsHeight, width, height);
|
||||
|
||||
let wname = wide_string(name);
|
||||
let len = if wname.len() <= dm.dmDeviceName.len() {
|
||||
wname.len()
|
||||
} else {
|
||||
dm.dmDeviceName.len()
|
||||
};
|
||||
std::ptr::copy_nonoverlapping(wname.as_ptr(), dm.dmDeviceName.as_mut_ptr(), len);
|
||||
dm.dmSize = std::mem::size_of::<DEVMODEW>() as _;
|
||||
// dmPelsWidth and dmPelsHeight is the same to width and height
|
||||
// Because this process is running in dpi awareness mode.
|
||||
if dm.dmPelsWidth == width as u32 && dm.dmPelsHeight == height as u32 {
|
||||
return Ok(());
|
||||
}
|
||||
dm.dmPelsWidth = width as _;
|
||||
dm.dmPelsHeight = height as _;
|
||||
dm.dmFields = DM_PELSHEIGHT | DM_PELSWIDTH;
|
||||
let res = ChangeDisplaySettingsExW(
|
||||
wname.as_ptr(),
|
||||
device_name.as_ptr(),
|
||||
&mut dm,
|
||||
NULL as _,
|
||||
CDS_UPDATEREGISTRY | CDS_GLOBAL | CDS_RESET,
|
||||
|
||||
@@ -25,9 +25,12 @@ use crate::virtual_display_manager;
|
||||
use crate::{platform::windows::is_process_consent_running, privacy_win_mag};
|
||||
#[cfg(windows)]
|
||||
use hbb_common::get_version_number;
|
||||
use hbb_common::tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
use hbb_common::{
|
||||
protobuf::MessageField,
|
||||
tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||
Mutex as TokioMutex,
|
||||
},
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
use scrap::Capturer;
|
||||
@@ -65,8 +68,9 @@ lazy_static::lazy_static! {
|
||||
static ref ORIGINAL_RESOLUTIONS: Arc<RwLock<HashMap<String, (i32, i32)>>> = Default::default();
|
||||
}
|
||||
|
||||
// Not virtual display
|
||||
#[inline]
|
||||
pub fn set_original_resolution(display_name: &str, wh: (i32, i32)) -> (i32, i32) {
|
||||
fn set_original_resolution_(display_name: &str, wh: (i32, i32)) -> (i32, i32) {
|
||||
let mut original_resolutions = ORIGINAL_RESOLUTIONS.write().unwrap();
|
||||
match original_resolutions.get(display_name) {
|
||||
Some(r) => r.clone(),
|
||||
@@ -77,8 +81,9 @@ pub fn set_original_resolution(display_name: &str, wh: (i32, i32)) -> (i32, i32)
|
||||
}
|
||||
}
|
||||
|
||||
// Not virtual display
|
||||
#[inline]
|
||||
fn get_original_resolution(display_name: &str) -> Option<(i32, i32)> {
|
||||
fn get_original_resolution_(display_name: &str) -> Option<(i32, i32)> {
|
||||
ORIGINAL_RESOLUTIONS
|
||||
.read()
|
||||
.unwrap()
|
||||
@@ -86,13 +91,25 @@ fn get_original_resolution(display_name: &str) -> Option<(i32, i32)> {
|
||||
.map(|r| r.clone())
|
||||
}
|
||||
|
||||
// Not virtual display
|
||||
#[inline]
|
||||
fn get_or_set_original_resolution(display_name: &str, wh: (i32, i32)) -> (i32, i32) {
|
||||
let r = get_original_resolution(display_name);
|
||||
fn get_or_set_original_resolution_(display_name: &str, wh: (i32, i32)) -> (i32, i32) {
|
||||
let r = get_original_resolution_(display_name);
|
||||
if let Some(r) = r {
|
||||
return r;
|
||||
}
|
||||
set_original_resolution(display_name, wh)
|
||||
set_original_resolution_(display_name, wh)
|
||||
}
|
||||
|
||||
// Not virtual display
|
||||
#[inline]
|
||||
fn update_get_original_resolution_(display_name: &str, w: usize, h: usize) -> Resolution {
|
||||
let wh = get_or_set_original_resolution_(display_name, (w as _, h as _));
|
||||
Resolution {
|
||||
width: wh.0,
|
||||
height: wh.1,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -543,10 +560,13 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
if *SWITCH.lock().unwrap() {
|
||||
log::debug!("Broadcasting display switch");
|
||||
let mut misc = Misc::new();
|
||||
let display_name = get_current_display_name();
|
||||
|
||||
// to-do: check if is virtual display
|
||||
|
||||
let display_name = get_current_display_name().unwrap_or_default();
|
||||
println!(
|
||||
"REMOVE ME ============================ display_name: {:?}, is_virtual: {}",
|
||||
display_name,
|
||||
is_virtual_display(&display_name)
|
||||
);
|
||||
let original_resolution = get_original_resolution(&display_name, c.width, c.height);
|
||||
misc.set_switch_display(SwitchDisplay {
|
||||
display: c.current as _,
|
||||
x: c.origin.0 as _,
|
||||
@@ -556,19 +576,15 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
cursor_embedded: capture_cursor_embedded(),
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
resolutions: Some(SupportedResolutions {
|
||||
resolutions: display_name
|
||||
.as_ref()
|
||||
.map(|name| crate::platform::resolutions(name))
|
||||
.unwrap_or(vec![]),
|
||||
resolutions: if display_name.is_empty() {
|
||||
vec![]
|
||||
} else {
|
||||
crate::platform::resolutions(&display_name)
|
||||
},
|
||||
..SupportedResolutions::default()
|
||||
})
|
||||
.into(),
|
||||
original_resolution: Some(update_get_original_resolution(
|
||||
&display_name.unwrap_or_default(),
|
||||
c.width,
|
||||
c.height,
|
||||
))
|
||||
.into(),
|
||||
original_resolution,
|
||||
..Default::default()
|
||||
});
|
||||
let mut msg_out = Message::new();
|
||||
@@ -884,15 +900,37 @@ pub fn handle_one_frame_encoded(
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn update_get_original_resolution(display_name: &str, w: usize, h: usize) -> Resolution {
|
||||
let wh = get_or_set_original_resolution(display_name, (w as _, h as _));
|
||||
Resolution {
|
||||
width: wh.0,
|
||||
height: wh.1,
|
||||
..Default::default()
|
||||
fn get_original_resolution(display_name: &str, w: usize, h: usize) -> MessageField<Resolution> {
|
||||
Some(if is_virtual_display(&display_name) {
|
||||
Resolution {
|
||||
width: 0,
|
||||
height: 0,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
update_get_original_resolution_(&display_name, w, h)
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_os = "windows")]
|
||||
fn is_virtual_display(name: &str) -> bool {
|
||||
match crate::platform::windows::is_virtual_display(&name) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Failed to check is virtual display for '{}': {}", &name, e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn is_virtual_display(_name: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub(super) fn get_displays_2(all: &Vec<Display>) -> (usize, Vec<DisplayInfo>) {
|
||||
let mut displays = Vec::new();
|
||||
let mut primary = 0;
|
||||
@@ -900,20 +938,17 @@ pub(super) fn get_displays_2(all: &Vec<Display>) -> (usize, Vec<DisplayInfo>) {
|
||||
if d.is_primary() {
|
||||
primary = i;
|
||||
}
|
||||
let display_name = d.name();
|
||||
let original_resolution = get_original_resolution(&display_name, d.width(), d.height());
|
||||
displays.push(DisplayInfo {
|
||||
x: d.origin().0 as _,
|
||||
y: d.origin().1 as _,
|
||||
width: d.width() as _,
|
||||
height: d.height() as _,
|
||||
name: d.name(),
|
||||
name: display_name,
|
||||
online: d.is_online(),
|
||||
cursor_embedded: false,
|
||||
original_resolution: Some(update_get_original_resolution(
|
||||
&d.name(),
|
||||
d.width(),
|
||||
d.height(),
|
||||
))
|
||||
.into(),
|
||||
original_resolution,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user