dxcapture/
displays.rs

1/// author: Robert Mikhayelyan <rob.mikh@outlook.com>
2
3use winapi::{
4    shared::{
5        minwindef::{BOOL, LPARAM},
6        windef::{HDC, HMONITOR, LPRECT},
7    },
8    um::winuser::{EnumDisplayMonitors, GetMonitorInfoW, MONITORINFOEXW},
9};
10
11/// Display informations.
12#[derive(Debug, Clone)]
13pub struct DisplayInfo {
14    pub handle: HMONITOR,
15    pub display_name: String,
16}
17
18extern "system" fn enum_monitor(handle: HMONITOR, _: HDC, _: LPRECT, lparam: LPARAM) -> BOOL {
19    let mut monitor_info = MONITORINFOEXW::default();
20    monitor_info.cbSize = std::mem::size_of::<MONITORINFOEXW>() as u32;
21
22    let result = unsafe { GetMonitorInfoW(handle, &mut monitor_info as *mut _ as *mut _) };
23    if result == 0 {
24        panic!("GetMonitorInfoW failed!");
25        // TODO: GetLastError
26        // TODO: ErrorCode conversion
27    }
28
29    let display_name = String::from_utf16_lossy(&monitor_info.szDevice)
30        .trim_matches(char::from(0))
31        .to_string();
32
33    let info = DisplayInfo {
34        handle: handle,
35        display_name: display_name,
36    };
37
38    unsafe {
39        let list = std::mem::transmute::<LPARAM, *mut Vec<DisplayInfo>>(lparam);
40        (*list).push(info);
41    };
42
43    return 1;
44}
45
46/// Get all displays and returns them as a Vec<[`DisplayInfo`]>.
47pub fn enumerate_displays() -> Vec<DisplayInfo> {
48    let mut displays: Vec<DisplayInfo> = Vec::new();
49    let result = unsafe {
50        EnumDisplayMonitors(
51            std::ptr::null_mut(),
52            std::ptr::null_mut(),
53            Some(enum_monitor),
54            &mut displays as *mut _ as _,
55        )
56    };
57    if result == 0 {
58        panic!("EnumDisplayMonitors failed!");
59        // TODO: GetLastError
60        // TODO: ErrorCode conversion
61    }
62    displays
63}