1use std::fmt;
4use std::io;
5use std::path::PathBuf;
6
7use denise::SurfaceError;
8
9use crate::mode::SelectionError;
10
11#[derive(Debug)]
13#[non_exhaustive]
14pub enum DrmError {
15 NoDevice,
17
18 Open {
20 path: PathBuf,
22 source: io::Error,
24 },
25
26 NoDisplayCapableDevice,
31
32 NotMaster(io::Error),
37
38 Resources(io::Error),
40
41 Selection(SelectionError),
43
44 NoCrtc {
46 connector: u32,
48 },
49
50 Allocate {
52 width: u32,
54 height: u32,
56 source: io::Error,
58 },
59
60 Map(io::Error),
62
63 UnalignedPitch {
68 pitch: u32,
70 },
71
72 AddFramebuffer(io::Error),
74
75 SetMode {
77 mode: String,
79 crtc: u32,
81 source: io::Error,
83 },
84
85 PageFlip(io::Error),
87
88 WaitVblank(io::Error),
90}
91
92impl fmt::Display for DrmError {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 match self {
95 Self::NoDevice => f.write_str("no DRM device found under /dev/dri"),
96 Self::Open { path, .. } => write!(f, "opening {}", path.display()),
97 Self::NoDisplayCapableDevice => f.write_str("no DRM device has a display output"),
98 Self::NotMaster(_) => f.write_str(
99 "cannot become DRM master — another process (a compositor, or another \
100 instance of this program) already holds it, or this process lacks the rights",
101 ),
102 Self::Resources(_) => f.write_str("reading DRM resources"),
103 Self::Selection(err) => core::fmt::Display::fmt(err, f),
104 Self::NoCrtc { connector } => write!(f, "no CRTC can drive connector {connector}"),
105 Self::Allocate { width, height, .. } => {
106 write!(f, "allocating a {width}x{height} dumb buffer")
107 }
108 Self::Map(_) => f.write_str("mapping a dumb buffer"),
109 Self::UnalignedPitch { pitch } => write!(
110 f,
111 "dumb buffer pitch {pitch} is not a whole number of 32-bit pixels"
112 ),
113 Self::AddFramebuffer(_) => f.write_str("registering a framebuffer"),
114 Self::SetMode { mode, crtc, .. } => write!(f, "setting mode {mode} on CRTC {crtc}"),
115 Self::PageFlip(_) => f.write_str("queueing a page flip"),
116 Self::WaitVblank(_) => f.write_str("waiting for vblank"),
117 }
118 }
119}
120
121impl std::error::Error for DrmError {
122 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
123 match self {
124 Self::Open { source, .. }
125 | Self::Allocate { source, .. }
126 | Self::SetMode { source, .. }
127 | Self::NotMaster(source)
128 | Self::Resources(source)
129 | Self::Map(source)
130 | Self::AddFramebuffer(source)
131 | Self::PageFlip(source)
132 | Self::WaitVblank(source) => Some(source),
133 Self::NoDevice
134 | Self::NoDisplayCapableDevice
135 | Self::Selection(_)
136 | Self::NoCrtc { .. }
137 | Self::UnalignedPitch { .. } => None,
138 }
139 }
140}
141
142impl From<SelectionError> for DrmError {
143 fn from(err: SelectionError) -> Self {
144 Self::Selection(err)
145 }
146}
147
148impl From<DrmError> for SurfaceError {
149 fn from(err: DrmError) -> Self {
150 SurfaceError::backend(err)
151 }
152}