use std::collections::HashMap; use drm_sys::drm_mode_modeinfo; use syscall::{Error, Result, EINVAL}; use crate::GraphicsAdapter; pub struct DrmObjects { next_id: DrmObjectId, objects: HashMap>, } impl DrmObjects { pub(crate) fn new() -> Self { DrmObjects { next_id: DrmObjectId(1), objects: HashMap::new(), } } pub fn add_connector(&mut self, connector: DrmConnector) -> DrmObjectId { let connector_id = self.next_id; self.objects.insert( connector_id, DrmObject { kind: DrmObjectKind::Connector(connector), }, ); self.next_id.0 += 1; let encoder_id = self.next_id; self.objects.insert( encoder_id, DrmObject { kind: DrmObjectKind::Encoder(DrmEncoder { crtc_id: DrmObjectId::INVALID, possible_crtcs: 0, possible_clones: 0, }), }, ); self.next_id.0 += 1; // Attach encoder to connector self.get_connector_mut(connector_id).unwrap().encoder_id = encoder_id; connector_id } pub fn connector_ids(&self) -> impl Iterator + use<'_, T> { self.objects .iter() .filter_map(|(&id, object)| match object.kind { DrmObjectKind::Connector(_) => Some(id), _ => None, }) } pub fn connectors(&self) -> impl Iterator> + use<'_, T> { self.objects .values() .filter_map(|object| match &object.kind { DrmObjectKind::Connector(connector) => Some(connector), _ => None, }) } pub fn connectors_mut(&mut self) -> impl Iterator> + use<'_, T> { self.objects .values_mut() .filter_map(|object| match &mut object.kind { DrmObjectKind::Connector(connector) => Some(connector), _ => None, }) } pub fn get_connector(&self, id: DrmObjectId) -> Result<&DrmConnector> { let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?; match &object.kind { DrmObjectKind::Connector(drm_connector) => Ok(drm_connector), _ => Err(Error::new(EINVAL)), } } pub fn get_connector_mut(&mut self, id: DrmObjectId) -> Result<&mut DrmConnector> { let object = self.objects.get_mut(&id).ok_or(Error::new(EINVAL))?; match &mut object.kind { DrmObjectKind::Connector(drm_connector) => Ok(drm_connector), _ => Err(Error::new(EINVAL)), } } pub fn encoder_ids(&self) -> impl Iterator + use<'_, T> { self.objects .iter() .filter_map(|(&id, object)| match object.kind { DrmObjectKind::Encoder(_) => Some(id), _ => None, }) } pub fn get_encoder(&self, id: DrmObjectId) -> Result<&DrmEncoder> { let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?; match &object.kind { DrmObjectKind::Encoder(drm_encoder) => Ok(drm_encoder), _ => Err(Error::new(EINVAL)), } } pub fn get_encoder_mut(&mut self, id: DrmObjectId) -> Result<&mut DrmEncoder> { let object = self.objects.get_mut(&id).ok_or(Error::new(EINVAL))?; match &mut object.kind { DrmObjectKind::Encoder(drm_encoder) => Ok(drm_encoder), _ => Err(Error::new(EINVAL)), } } } #[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct DrmObjectId(pub(crate) u32); impl DrmObjectId { pub const INVALID: DrmObjectId = DrmObjectId(0); } struct DrmObject { kind: DrmObjectKind, } enum DrmObjectKind { Connector(DrmConnector), Encoder(DrmEncoder), } pub struct DrmConnector { pub modes: Vec, pub encoder_id: DrmObjectId, pub connector_type: u32, pub connector_type_id: u32, pub connection: DrmConnectorStatus, pub mm_width: u32, pub mm_height: u32, pub subpixel: DrmSubpixelOrder, pub driver_data: T::Connector, } #[derive(Copy, Clone)] #[repr(u32)] pub enum DrmConnectorStatus { Disconnected = 0, Connected = 1, Unknown = 2, } #[derive(Copy, Clone)] #[repr(u32)] pub enum DrmSubpixelOrder { Unknown = 0, HorizontalRGB, HorizontalBGR, VerticalRGB, VerticalBGR, None, } // FIXME can we represent connector and encoder using a single struct? pub struct DrmEncoder { pub crtc_id: DrmObjectId, pub possible_crtcs: u32, pub possible_clones: u32, }