use std::fmt;
use std::io;
use std::path::PathBuf;
use denise::SurfaceError;
use crate::mode::SelectionError;
#[derive(Debug)]
#[non_exhaustive]
pub enum DrmError {
NoDevice,
Open {
path: PathBuf,
source: io::Error,
},
NoDisplayCapableDevice,
NotMaster(io::Error),
Resources(io::Error),
Selection(SelectionError),
NoCrtc {
connector: u32,
},
Allocate {
width: u32,
height: u32,
source: io::Error,
},
Map(io::Error),
UnalignedPitch {
pitch: u32,
},
AddFramebuffer(io::Error),
SetMode {
mode: String,
crtc: u32,
source: io::Error,
},
PageFlip(io::Error),
WaitVblank(io::Error),
}
impl fmt::Display for DrmError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NoDevice => f.write_str("no DRM device found under /dev/dri"),
Self::Open { path, .. } => write!(f, "opening {}", path.display()),
Self::NoDisplayCapableDevice => f.write_str("no DRM device has a display output"),
Self::NotMaster(_) => f.write_str(
"cannot become DRM master — another process (a compositor, or another \
instance of this program) already holds it, or this process lacks the rights",
),
Self::Resources(_) => f.write_str("reading DRM resources"),
Self::Selection(err) => core::fmt::Display::fmt(err, f),
Self::NoCrtc { connector } => write!(f, "no CRTC can drive connector {connector}"),
Self::Allocate { width, height, .. } => {
write!(f, "allocating a {width}x{height} dumb buffer")
}
Self::Map(_) => f.write_str("mapping a dumb buffer"),
Self::UnalignedPitch { pitch } => write!(
f,
"dumb buffer pitch {pitch} is not a whole number of 32-bit pixels"
),
Self::AddFramebuffer(_) => f.write_str("registering a framebuffer"),
Self::SetMode { mode, crtc, .. } => write!(f, "setting mode {mode} on CRTC {crtc}"),
Self::PageFlip(_) => f.write_str("queueing a page flip"),
Self::WaitVblank(_) => f.write_str("waiting for vblank"),
}
}
}
impl std::error::Error for DrmError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Open { source, .. }
| Self::Allocate { source, .. }
| Self::SetMode { source, .. }
| Self::NotMaster(source)
| Self::Resources(source)
| Self::Map(source)
| Self::AddFramebuffer(source)
| Self::PageFlip(source)
| Self::WaitVblank(source) => Some(source),
Self::NoDevice
| Self::NoDisplayCapableDevice
| Self::Selection(_)
| Self::NoCrtc { .. }
| Self::UnalignedPitch { .. } => None,
}
}
}
impl From<SelectionError> for DrmError {
fn from(err: SelectionError) -> Self {
Self::Selection(err)
}
}
impl From<DrmError> for SurfaceError {
fn from(err: DrmError) -> Self {
SurfaceError::backend(err)
}
}