#[cfg(any(feature = "alloc", feature = "std"))]
pub type ParseWarning = crate::prelude::Arc<dyn core::error::Error + Send + Sync + 'static>;
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum StereoMode {
#[default]
None,
FieldSequentialRightFirst,
FieldSequentialLeftFirst,
TwoWayInterleavedRightEven,
TwoWayInterleavedLeftEven,
FourWayInterleaved,
SideBySideInterleaved,
}
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SyncDefinition {
AnalogComposite {
serrations: bool,
sync_on_all_rgb: bool,
},
BipolarAnalogComposite {
serrations: bool,
sync_on_all_rgb: bool,
},
DigitalComposite {
serrations: bool,
h_sync_positive: bool,
},
DigitalSeparate {
v_sync_positive: bool,
h_sync_positive: bool,
},
}
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq, Default)]
pub struct VideoMode {
pub width: u16,
pub height: u16,
pub refresh_rate: u8,
pub interlaced: bool,
pub h_front_porch: u16,
pub h_sync_width: u16,
pub v_front_porch: u16,
pub v_sync_width: u16,
pub h_border: u8,
pub v_border: u8,
pub stereo: StereoMode,
pub sync: Option<SyncDefinition>,
pub pixel_clock_khz: Option<u32>,
}
impl VideoMode {
pub fn new(width: u16, height: u16, refresh_rate: u8, interlaced: bool) -> Self {
Self {
width,
height,
refresh_rate,
interlaced,
..Self::default()
}
}
#[allow(clippy::too_many_arguments)]
pub fn with_detailed_timing(
mut self,
pixel_clock_khz: u32,
h_front_porch: u16,
h_sync_width: u16,
v_front_porch: u16,
v_sync_width: u16,
h_border: u8,
v_border: u8,
stereo: StereoMode,
sync: Option<SyncDefinition>,
) -> Self {
self.pixel_clock_khz = Some(pixel_clock_khz);
self.h_front_porch = h_front_porch;
self.h_sync_width = h_sync_width;
self.v_front_porch = v_front_porch;
self.v_sync_width = v_sync_width;
self.h_border = h_border;
self.v_border = v_border;
self.stereo = stereo;
self.sync = sync;
self
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EdidVersion {
pub version: u8,
pub revision: u8,
}
impl core::fmt::Display for EdidVersion {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}.{}", self.version, self.revision)
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
pub trait ExtensionData: core::any::Any + core::fmt::Debug + Send + Sync {
fn as_any(&self) -> &dyn core::any::Any;
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<T: core::any::Any + core::fmt::Debug + Send + Sync> ExtensionData for T {
fn as_any(&self) -> &dyn core::any::Any {
self
}
}
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Default)]
pub struct DisplayCapabilities {
pub manufacturer: Option<crate::manufacture::ManufacturerId>,
pub manufacture_date: Option<crate::manufacture::ManufactureDate>,
pub edid_version: Option<EdidVersion>,
pub product_code: Option<u16>,
pub serial_number: Option<u32>,
pub serial_number_string: Option<crate::manufacture::MonitorString>,
pub display_name: Option<crate::manufacture::MonitorString>,
pub unspecified_text: [Option<crate::manufacture::MonitorString>; 4],
pub white_points: [Option<crate::color::WhitePoint>; 2],
pub digital: bool,
pub color_bit_depth: Option<crate::color::ColorBitDepth>,
pub display_technology: Option<crate::panel::DisplayTechnology>,
pub display_subtype: Option<u8>,
pub operating_mode: Option<crate::panel::OperatingMode>,
pub backlight_type: Option<crate::panel::BacklightType>,
pub data_enable_used: Option<bool>,
pub data_enable_positive: Option<bool>,
pub native_pixels: Option<(u16, u16)>,
pub panel_aspect_ratio_100: Option<u8>,
pub physical_orientation: Option<crate::panel::PhysicalOrientation>,
pub rotation_capability: Option<crate::panel::RotationCapability>,
pub zero_pixel_location: Option<crate::panel::ZeroPixelLocation>,
pub scan_direction: Option<crate::panel::ScanDirection>,
pub subpixel_layout: Option<crate::panel::SubpixelLayout>,
pub pixel_pitch_hundredths_mm: Option<(u8, u8)>,
pub pixel_response_time_ms: Option<u8>,
pub power_sequencing: Option<crate::panel::PowerSequencing>,
#[cfg(any(feature = "alloc", feature = "std"))]
pub transfer_characteristic: Option<crate::transfer::DisplayIdTransferCharacteristic>,
pub display_id_interface: Option<crate::panel::DisplayIdInterface>,
pub stereo_interface: Option<crate::panel::DisplayIdStereoInterface>,
pub tiled_topology: Option<crate::panel::DisplayIdTiledTopology>,
pub chromaticity: crate::color::Chromaticity,
pub gamma: Option<crate::color::DisplayGamma>,
pub display_features: Option<crate::features::DisplayFeatureFlags>,
pub digital_color_encoding: Option<crate::color::DigitalColorEncoding>,
pub analog_color_type: Option<crate::color::AnalogColorType>,
pub video_interface: Option<crate::input::VideoInterface>,
pub analog_sync_level: Option<crate::input::AnalogSyncLevel>,
pub screen_size: Option<crate::screen::ScreenSize>,
pub min_v_rate: Option<u16>,
pub max_v_rate: Option<u16>,
pub min_h_rate_khz: Option<u16>,
pub max_h_rate_khz: Option<u16>,
pub max_pixel_clock_mhz: Option<u16>,
pub preferred_image_size_mm: Option<(u16, u16)>,
pub timing_formula: Option<crate::timing::TimingFormula>,
pub color_management: Option<crate::color::ColorManagementData>,
#[cfg(any(feature = "alloc", feature = "std"))]
pub supported_modes: crate::prelude::Vec<VideoMode>,
#[cfg(any(feature = "alloc", feature = "std"))]
#[cfg_attr(feature = "serde", serde(skip))]
pub warnings: crate::prelude::Vec<ParseWarning>,
#[cfg(any(feature = "alloc", feature = "std"))]
#[cfg_attr(feature = "serde", serde(skip))]
pub extension_data: crate::prelude::Vec<(u8, crate::prelude::Arc<dyn ExtensionData>)>,
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl DisplayCapabilities {
pub fn iter_warnings(&self) -> impl Iterator<Item = &ParseWarning> {
self.warnings.iter()
}
pub fn push_warning(&mut self, w: impl core::error::Error + Send + Sync + 'static) {
self.warnings.push(crate::prelude::Arc::new(w));
}
pub fn set_extension_data<T: ExtensionData>(&mut self, tag: u8, data: T) {
if let Some(entry) = self.extension_data.iter_mut().find(|(t, _)| *t == tag) {
entry.1 = crate::prelude::Arc::new(data);
} else {
self.extension_data
.push((tag, crate::prelude::Arc::new(data)));
}
}
pub fn get_extension_data<T: core::any::Any>(&self, tag: u8) -> Option<&T> {
self.extension_data
.iter()
.find(|(t, _)| *t == tag)
.and_then(|(_, data)| (**data).as_any().downcast_ref::<T>())
}
}