use drm::control::{connector, property, Device as ControlDevice, ResourceHandles};
use std::collections::HashMap;
use std::fs::File;
use std::os::unix::io::AsRawFd;
use super::displmgr_drm_sys::{DrmPropertyCache, DrmResourceIds};
use crate::error::{DisplayError, DisplayResult};
use crate::types::{
AdapterId, ConnectorId, DisplayId, DisplayIdentity, DisplayRotation, Extent2D, HdrMode,
HdrState, OutputState, Point2D, Rect,
};
pub fn probe_drm_hardware(
device: &File,
) -> DisplayResult<(
Vec<OutputState>,
HashMap<DisplayId, DrmResourceIds>,
DrmPropertyCache,
)> {
let fd = device.as_raw_fd();
let resources = ResourceHandles::acquire(fd).map_err(|e| DisplayError::ConnectionFailed)?;
let mut outputs = Vec::new();
let mut resource_map = HashMap::new();
let mut property_cache = DrmPropertyCache::default();
for conn_handle in resources.connectors() {
if let Ok(conn_info) = connector::Info::load(fd, *conn_handle) {
if conn_info.connection_state() != connector::State::Connected {
continue;
}
if let Some(encoder_handle) = conn_info.current_encoder() {
if let Ok(enc_info) = drm::control::encoder::Info::load(fd, encoder_handle) {
if let Some(crtc_handle) = enc_info.current_crtc() {
let display_str = format!("DRM-KMS-{}", conn_info.interface().as_str());
let display_id = DisplayId(display_str.clone());
let res_ids = DrmResourceIds {
connector_id: *conn_handle,
crtc_id: crtc_handle,
primary_plane_id: drm::control::plane::Handle::from(conn_info.id()),
};
let size = if let Some(mode) = conn_info.modes().first() {
Extent2D {
width: mode.size().0 as u32,
height: mode.size().1 as u32,
}
} else {
Extent2D {
width: 1920,
height: 1080,
}
};
if let Ok(props) = ControlDevice::get_properties(fd, *conn_handle) {
let mut inner_map = HashMap::new();
for (p_handle, _) in props.iter() {
if let Ok(p_info) = property::Info::load(fd, *p_handle) {
inner_map.insert(
p_info.name().to_string_lossy().into_owned(),
*p_handle,
);
}
}
property_cache.props.insert(*conn_handle, inner_map);
}
outputs.push(OutputState {
identity: DisplayIdentity {
id: display_id.clone(),
connector_id: ConnectorId(format!(
"DRM-Port-{}",
conn_info.interface_id()
)),
adapter_id: AdapterId("/dev/dri/card0".to_string()),
hardware_uuid: None, monitor_name: display_str,
},
geometry: Rect {
origin: Point2D { x: 0, y: 0 },
size,
},
refresh_rate: 60000, rotation: DisplayRotation::Rotate0,
hdr_state: HdrState::Disabled,
hdr_mode: HdrMode::Default,
scale: 1.0,
native_resolution: Some(size),
supported_modes: Vec::new(),
});
resource_map.insert(display_id, res_ids);
}
}
}
}
}
Ok((outputs, resource_map, property_cache))
}