1extern crate framebuffer;
2use embedded_graphics::{pixelcolor::BinaryColor, prelude::*};
3use framebuffer::{Framebuffer, FramebufferError};
4use std::path::PathBuf;
5use std::{fs::File, io::Write};
6use thiserror::Error;
7
8pub struct BeepyDisplay {
9 pub device: PathBuf,
10 fb: Framebuffer,
11 frame: Vec<u8>,
12}
13
14#[derive(Error, Debug)]
15pub enum BeepyDisplayError {
16 #[error(transparent)]
17 FramebufferError(#[from] FramebufferError),
18}
19
20impl BeepyDisplay {
21 pub fn new(device: PathBuf) -> Result<Self, BeepyDisplayError> {
22 let fb = Framebuffer::new(&device)?;
23 let frame = vec![0u8; 400 * 4 * 240 as usize];
24 Ok(Self { device, fb, frame })
27 }
28
29 pub fn flush(&mut self) {
30 self.fb.write_frame(&self.frame);
31 }
32}
33
34impl DrawTarget for BeepyDisplay {
35 type Color = BinaryColor;
36 type Error = core::convert::Infallible;
37
38 fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
39 where
40 I: IntoIterator<Item = Pixel<Self::Color>>,
41 {
42 for Pixel(point, color) in pixels.into_iter() {
43 if let Ok((x @ 0..=399, y @ 0..=239)) = point.try_into() {
44 let index: u32 = x * 4 + y * 1600;
45 let c = if color.is_on() { 255 } else { 0 };
46
47 self.frame[(index + 0) as usize] = c; self.frame[(index + 1) as usize] = c; self.frame[(index + 2) as usize] = c; }
52 }
53
54 Ok(())
55 }
56}
57
58impl OriginDimensions for BeepyDisplay {
59 fn size(&self) -> Size {
60 Size::new(400, 240)
61 }
62}
63
64pub fn unbind_console() -> Result<(), std::io::Error> {
65 let mut file = File::create("/sys/class/vtconsole/vtcon1/bind")?;
66 file.write_all(b"0")
67}
68
69pub fn bind_console() -> Result<(), std::io::Error> {
70 let mut file = File::create("/sys/class/vtconsole/vtcon1/bind")?;
71 file.write_all(b"1")
72}