1 use std::{cell::Cell, fs::File, io::{Seek, SeekFrom, Write}}; 2 3 use crate::base::{color::Color, renderer::{RenderMode, Renderer}}; 4 5 // TODO: 读帧缓冲设备属性 6 /// 屏幕宽度 7 const SCREEN_WIDTH: usize = 1440; 8 /// 屏幕高度 9 #[allow(dead_code)] 10 const SCREEN_HEIGHT: usize = 900; 11 12 #[allow(dead_code)] 13 pub struct Window { 14 /// 窗口左上角的x坐标 15 x: i32, 16 /// 窗口左上角的y坐标 17 y: i32, 18 /// 窗口的宽度 19 w: u32, 20 /// 窗口的高度 21 h: u32, 22 /// 窗口的标题 23 t: String, 24 /// TODO 25 // window_async: bool, 26 /// 窗口是否大小可变 27 resizable: bool, 28 /// 窗口的渲染模式 29 mode: Cell<RenderMode>, 30 // TODO 31 // file_opt: Option<File>, 32 // TODO: 改定长数组 33 // data_opt: Option<& 'static mut [Color]>, 34 /// 窗口的渲染数据 35 data_opt: Option<Box<[Color]>>, 36 } 37 38 impl Renderer for Window { 39 fn width(&self) -> u32 { 40 self.w 41 } 42 43 fn height(&self) -> u32 { 44 self.h 45 } 46 47 fn data(&self) -> &[Color] { 48 self.data_opt.as_ref().unwrap() 49 } 50 51 fn data_mut(&mut self) -> &mut [Color]{ 52 self.data_opt.as_mut().unwrap() 53 } 54 55 /// TODO 56 fn sync(&mut self) -> bool { 57 true 58 } 59 60 fn mode(&self) -> &Cell<RenderMode> { 61 &self.mode 62 } 63 } 64 65 #[allow(dead_code)] 66 impl Window { 67 /// TODO: 接收flags 68 pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Self { 69 Window { 70 x: x, 71 y: y, 72 w: w, 73 h: h, 74 t: title.to_string(), 75 // window_async: false, 76 resizable: false, 77 mode: Cell::new(RenderMode::Blend), 78 // file_opt: None, 79 data_opt: Some(vec!(Color::rgb(0, 0, 0); (w * h) as usize).into_boxed_slice()), 80 } 81 82 // TODO: 与服务器通信 83 } 84 85 /// # 函数功能 86 /// 同步数据至系统帧缓冲 87 pub fn sync(&self) { 88 let mut fb = File::open("/dev/fb0").expect("Unable to open framebuffer"); 89 90 for y in 0..self.height() as i32 { 91 for x in 0..self.width() as i32 { 92 let pixel = self.get_pixel(x, y); 93 let offset = (((y + self.y()) * SCREEN_WIDTH as i32) + x + self.x()) * 4; 94 // 写缓冲区 95 fb.seek(SeekFrom::Start(offset as u64)).expect("Unable to seek framebuffer"); 96 fb.write_all(&pixel.to_rgba_bytes()).expect("Unable to write framebuffer"); 97 } 98 } 99 } 100 101 pub fn x(&self) -> i32 { 102 self.x 103 } 104 105 pub fn y(&self) -> i32 { 106 self.y 107 } 108 109 pub fn title(&self) -> String { 110 self.t.clone() 111 } 112 113 114 }