📄 src/physical_monitor/windows.rs
use std::mem;

use bevy::{math::UVec2, window::Monitor};
use windows::{
    Devices::Display::DisplayMonitor,
    Win32::{
        Graphics::Gdi::{DISPLAY_DEVICE_ACTIVE, DISPLAY_DEVICEW, EnumDisplayDevicesW},
        UI::WindowsAndMessaging::EDD_GET_DEVICE_INTERFACE_NAME,
    },
    core::HSTRING,
};

use super::PhysicalMonitor;

impl PhysicalMonitor for Monitor {
    fn physical_size_millimeters(&self) -> Option<UVec2> {
        let name = HSTRING::from(self.name.as_ref()?);
        let id = get_monitor_interface_id(&name)?;
        let monitor = DisplayMonitor::FromInterfaceIdAsync(&id)
            .ok()?
            .join()
            .ok()?;
        let size = monitor.PhysicalSizeInInches().ok()?.Value().ok()?;
        Some(UVec2::new(
            to_millimeters(size.Width),
            to_millimeters(size.Height),
        ))
    }
}

fn get_monitor_interface_id(name: &HSTRING) -> Option<HSTRING> {
    for i in 0.. {
        let mut dd = DISPLAY_DEVICEW {
            cb: mem::size_of::<DISPLAY_DEVICEW>() as u32,
            ..DISPLAY_DEVICEW::default()
        };
        let ok = unsafe { EnumDisplayDevicesW(name, i, &mut dd, EDD_GET_DEVICE_INTERFACE_NAME) };
        if !ok.as_bool() {
            return None;
        }
        if dd.StateFlags.contains(DISPLAY_DEVICE_ACTIVE) {
            let len = dd
                .DeviceID
                .iter()
                .position(|c| *c == 0)
                .unwrap_or(dd.DeviceID.len());
            return Some(HSTRING::from_wide(&dd.DeviceID[..len]));
        }
    }
    None
}

fn to_millimeters(inches: f32) -> u32 {
    (inches * 25.4) as u32
}