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