use winapi;
use user32;
use std::collections::VecDeque;
pub struct MonitorID {
name: [winapi::WCHAR; 32],
readable_name: String,
flags: winapi::DWORD,
position: (u32, u32),
dimensions: (u32, u32),
}
pub fn get_available_monitors() -> VecDeque<MonitorID> {
use std::{iter, mem, ptr};
let mut result = VecDeque::new();
for id in iter::count(0u32, 1) {
let output = {
let mut output: winapi::DISPLAY_DEVICEW = unsafe { mem::zeroed() };
output.cb = mem::size_of::<winapi::DISPLAY_DEVICEW>() as winapi::DWORD;
if unsafe { user32::EnumDisplayDevicesW(ptr::null(),
id as winapi::DWORD, &mut output, 0) } == 0
{
break;
}
if (output.StateFlags & winapi::DISPLAY_DEVICE_ACTIVE) == 0 ||
(output.StateFlags & winapi::DISPLAY_DEVICE_MIRRORING_DRIVER) != 0
{
continue;
}
output
};
let readable_name = String::from_utf16_lossy(output.DeviceString.as_slice());
let readable_name = readable_name.as_slice().trim_right_matches(0 as char).to_string();
let (position, dimensions) = unsafe {
let mut dev: winapi::DEVMODEW = mem::zeroed();
dev.dmSize = mem::size_of::<winapi::DEVMODEW>() as winapi::WORD;
if user32::EnumDisplaySettingsExW(output.DeviceName.as_ptr(), winapi::ENUM_CURRENT_SETTINGS,
&mut dev, 0) == 0
{
continue;
}
let point: &winapi::POINTL = mem::transmute(&dev.union1);
let position = (point.x as u32, point.y as u32);
let dimensions = (dev.dmPelsWidth as u32, dev.dmPelsHeight as u32);
(position, dimensions)
};
result.push_back(MonitorID {
name: output.DeviceName,
readable_name: readable_name,
flags: output.StateFlags,
position: position,
dimensions: dimensions,
});
}
result
}
pub fn get_primary_monitor() -> MonitorID {
for monitor in get_available_monitors().into_iter() {
if (monitor.flags & winapi::DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 {
return monitor
}
}
panic!("Failed to find the primary monitor")
}
impl MonitorID {
pub fn get_name(&self) -> Option<String> {
Some(self.readable_name.clone())
}
pub fn get_dimensions(&self) -> (u32, u32) {
self.dimensions
}
pub fn get_system_name(&self) -> &[winapi::WCHAR] {
self.name.as_slice()
}
pub fn get_position(&self) -> (u32, u32) {
self.position
}
}