On Windows, avoid panic in video_modes()
This commit is contained in:
parent
73718c9f2f
commit
b863283c38
1 changed files with 36 additions and 28 deletions
|
|
@ -230,37 +230,45 @@ impl MonitorHandle {
|
||||||
// EnumDisplaySettingsExW can return duplicate values (or some of the
|
// EnumDisplaySettingsExW can return duplicate values (or some of the
|
||||||
// fields are probably changing, but we aren't looking at those fields
|
// fields are probably changing, but we aren't looking at those fields
|
||||||
// anyway), so we're using a BTreeSet deduplicate
|
// anyway), so we're using a BTreeSet deduplicate
|
||||||
let mut modes = BTreeSet::new();
|
let mut modes = BTreeSet::<RootVideoMode>::new();
|
||||||
let mut i = 0;
|
let mod_map = |mode: RootVideoMode| mode.video_mode;
|
||||||
|
|
||||||
loop {
|
let monitor_info = match get_monitor_info(self.0) {
|
||||||
unsafe {
|
Ok(monitor_info) => monitor_info,
|
||||||
let monitor_info = get_monitor_info(self.0).unwrap();
|
Err(error) => {
|
||||||
let device_name = monitor_info.szDevice.as_ptr();
|
log::warn!("Error from get_monitor_info: {error}");
|
||||||
let mut mode: DEVMODEW = mem::zeroed();
|
return modes.into_iter().map(mod_map);
|
||||||
mode.dmSize = mem::size_of_val(&mode) as u16;
|
|
||||||
if EnumDisplaySettingsExW(device_name, i, &mut mode, 0) == false.into() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
|
|
||||||
const REQUIRED_FIELDS: u32 =
|
|
||||||
DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
|
|
||||||
assert!(has_flag(mode.dmFields, REQUIRED_FIELDS));
|
|
||||||
|
|
||||||
// Use Ord impl of RootVideoMode
|
|
||||||
modes.insert(RootVideoMode {
|
|
||||||
video_mode: VideoMode {
|
|
||||||
size: (mode.dmPelsWidth, mode.dmPelsHeight),
|
|
||||||
bit_depth: mode.dmBitsPerPel as u16,
|
|
||||||
refresh_rate_millihertz: mode.dmDisplayFrequency * 1000,
|
|
||||||
monitor: self.clone(),
|
|
||||||
native_video_mode: Box::new(mode),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let device_name = monitor_info.szDevice.as_ptr();
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
loop {
|
||||||
|
let mut mode: DEVMODEW = unsafe { mem::zeroed() };
|
||||||
|
mode.dmSize = mem::size_of_val(&mode) as u16;
|
||||||
|
if unsafe { EnumDisplaySettingsExW(device_name, i, &mut mode, 0) } == false.into() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const REQUIRED_FIELDS: u32 =
|
||||||
|
DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
|
||||||
|
assert!(has_flag(mode.dmFields, REQUIRED_FIELDS));
|
||||||
|
|
||||||
|
// Use Ord impl of RootVideoMode
|
||||||
|
modes.insert(RootVideoMode {
|
||||||
|
video_mode: VideoMode {
|
||||||
|
size: (mode.dmPelsWidth, mode.dmPelsHeight),
|
||||||
|
bit_depth: mode.dmBitsPerPel as u16,
|
||||||
|
refresh_rate_millihertz: mode.dmDisplayFrequency * 1000,
|
||||||
|
monitor: self.clone(),
|
||||||
|
native_video_mode: Box::new(mode),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
modes.into_iter().map(|mode| mode.video_mode)
|
modes.into_iter().map(mod_map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue