fix: win, virtual display (#9023)

1. Default resolution 1920x1080.
2. Restore on conn & disconn.

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2024-08-11 19:26:41 +08:00
committed by GitHub
parent ce56be6507
commit 6625aca994
8 changed files with 229 additions and 144 deletions

View File

@@ -2595,3 +2595,107 @@ pub fn try_set_window_foreground(window: HWND) {
}
}
}
pub mod reg_display_settings {
use hbb_common::ResultType;
use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
use winreg::{enums::*, RegValue};
const REG_GRAPHICS_DRIVERS_PATH: &str = "SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers";
const REG_CONNECTIVITY_PATH: &str = "Connectivity";
#[derive(Serialize, Deserialize, Debug)]
pub struct RegRecovery {
path: String,
key: String,
old: (Vec<u8>, isize),
new: (Vec<u8>, isize),
}
pub fn read_reg_connectivity() -> ResultType<HashMap<String, HashMap<String, RegValue>>>
{
let hklm = winreg::RegKey::predef(HKEY_LOCAL_MACHINE);
let reg_connectivity = hklm.open_subkey_with_flags(
format!("{}\\{}", REG_GRAPHICS_DRIVERS_PATH, REG_CONNECTIVITY_PATH),
KEY_READ,
)?;
let mut map_connectivity = HashMap::new();
for key in reg_connectivity.enum_keys() {
let key = key?;
let mut map_item = HashMap::new();
let reg_item = reg_connectivity.open_subkey_with_flags(&key, KEY_READ)?;
for value in reg_item.enum_values() {
let (name, value) = value?;
map_item.insert(name, value);
}
map_connectivity.insert(key, map_item);
}
Ok(map_connectivity)
}
pub fn diff_recent_connectivity(
map1: HashMap<String, HashMap<String, RegValue>>,
map2: HashMap<String, HashMap<String, RegValue>>,
) -> Option<RegRecovery> {
for (subkey, map_item2) in map2 {
if let Some(map_item1) = map1.get(&subkey) {
let key = "Recent";
if let Some(value1) = map_item1.get(key) {
if let Some(value2) = map_item2.get(key) {
if value1 != value2 {
return Some(RegRecovery {
path: format!(
"{}\\{}\\{}",
REG_GRAPHICS_DRIVERS_PATH, REG_CONNECTIVITY_PATH, subkey
),
key: key.to_owned(),
old: (value1.bytes.clone(), value1.vtype.clone() as isize),
new: (value2.bytes.clone(), value2.vtype.clone() as isize),
});
}
}
}
}
}
None
}
pub fn restore_reg_connectivity(reg_recovery: RegRecovery) -> ResultType<()> {
let hklm = winreg::RegKey::predef(HKEY_LOCAL_MACHINE);
let reg_item = hklm.open_subkey_with_flags(&reg_recovery.path, KEY_READ | KEY_WRITE)?;
let cur_reg_value = reg_item.get_raw_value(&reg_recovery.key)?;
let new_reg_value = RegValue {
bytes: reg_recovery.new.0,
vtype: isize_to_reg_type(reg_recovery.new.1),
};
if cur_reg_value != new_reg_value {
return Ok(());
}
let reg_value = RegValue {
bytes: reg_recovery.old.0,
vtype: isize_to_reg_type(reg_recovery.old.1),
};
reg_item.set_raw_value(&reg_recovery.key, &reg_value)?;
Ok(())
}
#[inline]
fn isize_to_reg_type(i: isize) -> RegType {
match i {
0 => RegType::REG_NONE,
1 => RegType::REG_SZ,
2 => RegType::REG_EXPAND_SZ,
3 => RegType::REG_BINARY,
4 => RegType::REG_DWORD,
5 => RegType::REG_DWORD_BIG_ENDIAN,
6 => RegType::REG_LINK,
7 => RegType::REG_MULTI_SZ,
8 => RegType::REG_RESOURCE_LIST,
9 => RegType::REG_FULL_RESOURCE_DESCRIPTOR,
10 => RegType::REG_RESOURCE_REQUIREMENTS_LIST,
11 => RegType::REG_QWORD,
_ => RegType::REG_NONE,
}
}
}