#![warn(missing_docs)]
extern crate core;
extern crate drm_ffi;
extern crate drm_fourcc;
extern crate nix;
pub(crate) mod util;
pub mod buffer;
pub mod control;
use std::os::unix::io::AsRawFd;
pub use drm_ffi::result::SystemError;
use util::*;
pub trait Device: AsRawFd {
fn acquire_master_lock(&self) -> Result<(), SystemError> {
drm_ffi::auth::acquire_master(self.as_raw_fd())?;
Ok(())
}
fn release_master_lock(&self) -> Result<(), SystemError> {
drm_ffi::auth::release_master(self.as_raw_fd())?;
Ok(())
}
#[deprecated(note = "Consider opening a render node instead.")]
fn generate_auth_token(&self) -> Result<AuthToken, SystemError> {
let token = drm_ffi::auth::get_magic_token(self.as_raw_fd())?;
Ok(AuthToken(token.magic))
}
fn authenticate_auth_token(&self, token: AuthToken) -> Result<(), SystemError> {
drm_ffi::auth::auth_magic_token(self.as_raw_fd(), token.0)?;
Ok(())
}
fn set_client_capability(
&self,
cap: ClientCapability,
enable: bool,
) -> Result<(), SystemError> {
drm_ffi::set_capability(self.as_raw_fd(), cap as u64, enable)?;
Ok(())
}
fn get_bus_id(&self) -> Result<BusID, SystemError> {
let mut buffer = [0u8; 32];
let buffer_len;
let _busid = {
let mut slice = &mut buffer[..];
let busid = drm_ffi::get_bus_id(self.as_raw_fd(), Some(&mut slice))?;
buffer_len = slice.len();
busid
};
let bus_id = BusID(SmallOsString::from_u8_buffer(buffer, buffer_len));
Ok(bus_id)
}
fn authenticated(&self) -> Result<bool, SystemError> {
let client = drm_ffi::get_client(self.as_raw_fd(), 0)?;
Ok(client.auth == 1)
}
fn get_driver_capability(&self, cap: DriverCapability) -> Result<u64, SystemError> {
let cap = drm_ffi::get_capability(self.as_raw_fd(), cap as u64)?;
Ok(cap.value)
}
#[allow(missing_docs)]
fn get_driver(&self) -> Result<Driver, SystemError> {
let mut name = [0i8; 32];
let mut date = [0i8; 32];
let mut desc = [0i8; 32];
let name_len;
let date_len;
let desc_len;
let _version = {
let mut name_slice = &mut name[..];
let mut date_slice = &mut date[..];
let mut desc_slice = &mut desc[..];
let version = drm_ffi::get_version(
self.as_raw_fd(),
Some(&mut name_slice),
Some(&mut date_slice),
Some(&mut desc_slice),
)?;
name_len = name_slice.len();
date_len = date_slice.len();
desc_len = desc_slice.len();
version
};
let name = SmallOsString::from_i8_buffer(name, name_len);
let date = SmallOsString::from_i8_buffer(date, date_len);
let desc = SmallOsString::from_i8_buffer(desc, desc_len);
let driver = Driver { name, date, desc };
Ok(driver)
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct AuthToken(u32);
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct BusID(SmallOsString);
impl AsRef<OsStr> for BusID {
fn as_ref(&self) -> &OsStr {
self.0.as_ref()
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Driver {
name: SmallOsString,
date: SmallOsString,
desc: SmallOsString,
}
impl Driver {
pub fn name(&self) -> &OsStr {
self.name.as_ref()
}
pub fn date(&self) -> &OsStr {
self.date.as_ref()
}
pub fn description(&self) -> &OsStr {
self.desc.as_ref()
}
}
#[allow(clippy::upper_case_acronyms)]
#[repr(u64)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum DriverCapability {
DumbBuffer = drm_ffi::DRM_CAP_DUMB_BUFFER as u64,
VBlankHighCRTC = drm_ffi::DRM_CAP_VBLANK_HIGH_CRTC as u64,
DumbPreferredDepth = drm_ffi::DRM_CAP_DUMB_PREFERRED_DEPTH as u64,
DumbPreferShadow = drm_ffi::DRM_CAP_DUMB_PREFER_SHADOW as u64,
Prime = drm_ffi::DRM_CAP_PRIME as u64,
MonotonicTimestamp = drm_ffi::DRM_CAP_TIMESTAMP_MONOTONIC as u64,
ASyncPageFlip = drm_ffi::DRM_CAP_ASYNC_PAGE_FLIP as u64,
CursorWidth = drm_ffi::DRM_CAP_CURSOR_WIDTH as u64,
CursorHeight = drm_ffi::DRM_CAP_CURSOR_HEIGHT as u64,
AddFB2Modifiers = drm_ffi::DRM_CAP_ADDFB2_MODIFIERS as u64,
PageFlipTarget = drm_ffi::DRM_CAP_PAGE_FLIP_TARGET as u64,
CRTCInVBlankEvent = drm_ffi::DRM_CAP_CRTC_IN_VBLANK_EVENT as u64,
SyncObj = drm_ffi::DRM_CAP_SYNCOBJ as u64,
}
#[repr(u64)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum ClientCapability {
Stereo3D = drm_ffi::DRM_CLIENT_CAP_STEREO_3D as u64,
UniversalPlanes = drm_ffi::DRM_CLIENT_CAP_UNIVERSAL_PLANES as u64,
Atomic = drm_ffi::DRM_CLIENT_CAP_ATOMIC as u64,
}