Skip to main content

denise_fbdev/
error.rs

1//! Failures from the fbdev backend.
2
3use std::fmt;
4use std::io;
5use std::path::PathBuf;
6
7use denise::SurfaceError;
8
9use crate::info::FbInfoError;
10
11/// Something went wrong driving `/dev/fbN`.
12#[derive(Debug)]
13#[non_exhaustive]
14pub enum FbdevError {
15    /// No `/dev/fb*` node exists.
16    ///
17    /// Expected on a modern kernel: fbdev is optional, and where it does exist it
18    /// is usually DRM's emulation layer rather than a driver of its own.
19    NoDevice,
20
21    /// The device node could not be opened.
22    ///
23    /// Writing to a framebuffer needs the `video` group, or root.
24    Open {
25        /// The device that failed.
26        path: PathBuf,
27        /// The underlying failure.
28        source: io::Error,
29    },
30
31    /// A sysfs attribute could not be read.
32    Sysfs {
33        /// The attribute that failed.
34        path: PathBuf,
35        /// The underlying failure.
36        source: io::Error,
37    },
38
39    /// The geometry could not be understood.
40    Geometry(FbInfoError),
41
42    /// The framebuffer could not be mapped into this process.
43    Map(io::Error),
44
45    /// The mapping is smaller than the reported geometry needs.
46    TooSmall {
47        /// Bytes the geometry requires.
48        required: usize,
49        /// Bytes actually mapped.
50        actual: usize,
51    },
52}
53
54impl fmt::Display for FbdevError {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        match self {
57            Self::NoDevice => f.write_str("no framebuffer device found"),
58            Self::Open { path, .. } => write!(f, "opening {}", path.display()),
59            Self::Sysfs { path, .. } => write!(f, "reading {}", path.display()),
60            Self::Geometry(err) => core::fmt::Display::fmt(err, f),
61            Self::Map(_) => f.write_str("mapping the framebuffer"),
62            Self::TooSmall { required, actual } => write!(
63                f,
64                "framebuffer is {actual} bytes but the geometry needs {required}"
65            ),
66        }
67    }
68}
69
70impl std::error::Error for FbdevError {
71    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
72        match self {
73            Self::Open { source, .. } | Self::Sysfs { source, .. } | Self::Map(source) => {
74                Some(source)
75            }
76            Self::NoDevice | Self::Geometry(_) | Self::TooSmall { .. } => None,
77        }
78    }
79}
80
81impl From<FbInfoError> for FbdevError {
82    fn from(err: FbInfoError) -> Self {
83        Self::Geometry(err)
84    }
85}
86
87impl From<FbdevError> for SurfaceError {
88    fn from(err: FbdevError) -> Self {
89        SurfaceError::backend(err)
90    }
91}