diff options
Diffstat (limited to 'src/win32/monitor.rs')
-rw-r--r-- | src/win32/monitor.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/win32/monitor.rs b/src/win32/monitor.rs new file mode 100644 index 0000000..d53577e --- /dev/null +++ b/src/win32/monitor.rs @@ -0,0 +1,79 @@ +use super::ffi; + +pub struct MonitorID { + name: [ffi::WCHAR, ..32], + readable_name: String, + flags: ffi::DWORD, + position: (uint, uint), +} + +pub fn get_available_monitors() -> Vec<MonitorID> { + use std::{iter, mem, ptr}; + + let mut result = Vec::new(); + + for id in iter::count(0u, 1) { + let mut output: ffi::DISPLAY_DEVICEW = unsafe { mem::zeroed() }; + output.cb = mem::size_of::<ffi::DISPLAY_DEVICEW>() as ffi::DWORD; + + if unsafe { ffi::EnumDisplayDevicesW(ptr::null(), id as ffi::DWORD, &mut output, 0) } == 0 { + break + } + + if (output.StateFlags & ffi::DISPLAY_DEVICE_ACTIVE) == 0 || + (output.StateFlags & ffi::DISPLAY_DEVICE_MIRRORING_DRIVER) != 0 + { + continue + } + + let readable_name = String::from_utf16_lossy(output.DeviceString.as_slice()); + let readable_name = readable_name.as_slice().trim_right_chars(0 as char).to_string(); + + let position = unsafe { + let mut dev: ffi::DEVMODE = mem::zeroed(); + dev.dmSize = mem::size_of::<ffi::DEVMODE>() as ffi::WORD; + + if ffi::EnumDisplaySettingsExW(output.DeviceName.as_ptr(), ffi::ENUM_CURRENT_SETTINGS, + &mut dev, 0) == 0 + { + continue + } + + let point: &ffi::POINTL = mem::transmute(&dev.union1); + (point.x as uint, point.y as uint) + }; + + result.push(MonitorID { + name: output.DeviceName, + readable_name: readable_name, + flags: output.StateFlags, + position: position, + }); + } + + result +} + +pub fn get_primary_monitor() -> MonitorID { + for monitor in get_available_monitors().move_iter() { + if (monitor.flags & ffi::DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 { + return monitor + } + } + + fail!("Failed to find the primary monitor") +} + +impl MonitorID { + pub fn get_name(&self) -> Option<String> { + Some(self.readable_name.clone()) + } + + pub fn get_system_name(&self) -> &[ffi::WCHAR] { + self.name.as_slice() + } + + pub fn get_position(&self) -> (uint, uint) { + self.position + } +} |