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