#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Hash)]
pub enum ConnectorType {
#[default]
Unknown = 0,
VGA = 1,
DVII = 2,
DVID = 3,
DVIA = 4,
Composite = 5,
SVideo = 6,
LVDS = 7,
Component = 8,
DisplayPort = 9,
HDMIA = 10,
HDMIB = 11,
TV = 12,
EDP = 13,
Virtual = 14,
DSI = 15,
USBC = 16,
}
impl ConnectorType {
#[inline]
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Self::Unknown),
1 => Some(Self::VGA),
2 => Some(Self::DVII),
3 => Some(Self::DVID),
4 => Some(Self::DVIA),
5 => Some(Self::Composite),
6 => Some(Self::SVideo),
7 => Some(Self::LVDS),
8 => Some(Self::Component),
9 => Some(Self::DisplayPort),
10 => Some(Self::HDMIA),
11 => Some(Self::HDMIB),
12 => Some(Self::TV),
13 => Some(Self::EDP),
14 => Some(Self::Virtual),
15 => Some(Self::DSI),
16 => Some(Self::USBC),
_ => None,
}
}
#[inline]
pub const fn name(&self) -> &'static str {
match self {
Self::Unknown => "Unknown",
Self::VGA => "VGA",
Self::DVII => "DVI-I",
Self::DVID => "DVI-D",
Self::DVIA => "DVI-A",
Self::Composite => "Composite",
Self::SVideo => "S-Video",
Self::LVDS => "LVDS",
Self::Component => "Component",
Self::DisplayPort => "DisplayPort",
Self::HDMIA => "HDMI-A",
Self::HDMIB => "HDMI-B",
Self::TV => "TV",
Self::EDP => "eDP",
Self::Virtual => "Virtual",
Self::DSI => "DSI",
Self::USBC => "USB-C",
}
}
#[inline]
pub const fn is_digital(&self) -> bool {
matches!(
self,
Self::DVID
| Self::DisplayPort
| Self::HDMIA
| Self::HDMIB
| Self::EDP
| Self::DSI
| Self::USBC
)
}
#[inline]
pub const fn supports_audio(&self) -> bool {
matches!(
self,
Self::HDMIA | Self::HDMIB | Self::DisplayPort | Self::EDP | Self::USBC
)
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct OutputInfo {
pub id: u32,
pub connector: ConnectorType,
pub connected: bool,
pub width_mm: u32,
pub height_mm: u32,
}
impl OutputInfo {
#[inline]
pub fn dpi_x(&self, width_px: u32) -> Option<f32> {
if self.width_mm > 0 {
Some(width_px as f32 / (self.width_mm as f32 / 25.4))
} else {
None
}
}
#[inline]
pub fn dpi_y(&self, height_px: u32) -> Option<f32> {
if self.height_mm > 0 {
Some(height_px as f32 / (self.height_mm as f32 / 25.4))
} else {
None
}
}
#[inline]
pub fn dpi(&self, width_px: u32, height_px: u32) -> Option<f32> {
match (self.dpi_x(width_px), self.dpi_y(height_px)) {
(Some(x), Some(y)) => Some((x + y) / 2.0),
(Some(x), None) => Some(x),
(None, Some(y)) => Some(y),
(None, None) => None,
}
}
}