148d97639Syuyi2439 use std::{ 248d97639Syuyi2439 cell::Cell, 348d97639Syuyi2439 fs::File, 448d97639Syuyi2439 io::{Seek, SeekFrom, Write}, 548d97639Syuyi2439 }; 6bee61dcaSR0ronoa 748d97639Syuyi2439 use crate::base::{ 848d97639Syuyi2439 color::Color, 948d97639Syuyi2439 renderer::{RenderMode, Renderer}, 1048d97639Syuyi2439 }; 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 // 写缓冲区 72*1c11e7deSyuyi2439 fb.seek(SeekFrom::Start(offset as u64)) 73*1c11e7deSyuyi2439 .expect("Unable to seek framebuffer"); 74*1c11e7deSyuyi2439 fb.write_all(&pixel.to_bgra_bytes()) 75*1c11e7deSyuyi2439 .expect("Unable to write framebuffer"); 7645e17157SR0ronoa } 7745e17157SR0ronoa } 78bee61dcaSR0ronoa true 79bee61dcaSR0ronoa } 80bee61dcaSR0ronoa 81bee61dcaSR0ronoa fn mode(&self) -> &Cell<RenderMode> { 82bee61dcaSR0ronoa &self.mode 83bee61dcaSR0ronoa } 84bee61dcaSR0ronoa } 85bee61dcaSR0ronoa 86bee61dcaSR0ronoa #[allow(dead_code)] 87bee61dcaSR0ronoa impl Window { 88bee61dcaSR0ronoa /// TODO: 接收flags 89bee61dcaSR0ronoa pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Self { 90bee61dcaSR0ronoa Window { 91bee61dcaSR0ronoa x: x, 92bee61dcaSR0ronoa y: y, 93bee61dcaSR0ronoa w: w, 94bee61dcaSR0ronoa h: h, 9545e17157SR0ronoa title: title.to_string(), 96bee61dcaSR0ronoa // window_async: false, 97bee61dcaSR0ronoa resizable: false, 98bee61dcaSR0ronoa mode: Cell::new(RenderMode::Blend), 99bee61dcaSR0ronoa // file_opt: None, 10048d97639Syuyi2439 data_opt: Some(vec![Color::rgb(0, 0, 0); (w * h) as usize].into_boxed_slice()), 101bee61dcaSR0ronoa } 102bee61dcaSR0ronoa 103bee61dcaSR0ronoa // TODO: 与服务器通信 104bee61dcaSR0ronoa } 105bee61dcaSR0ronoa 10645e17157SR0ronoa /// 返回窗口x坐标 107bee61dcaSR0ronoa pub fn x(&self) -> i32 { 108bee61dcaSR0ronoa self.x 109bee61dcaSR0ronoa } 110bee61dcaSR0ronoa 11145e17157SR0ronoa /// 返回窗口y坐标 112bee61dcaSR0ronoa pub fn y(&self) -> i32 { 113bee61dcaSR0ronoa self.y 114bee61dcaSR0ronoa } 115bee61dcaSR0ronoa 11645e17157SR0ronoa /// 返回窗口标题 117bee61dcaSR0ronoa pub fn title(&self) -> String { 11845e17157SR0ronoa self.title.clone() 119*1c11e7deSyuyi2439 } 120bee61dcaSR0ronoa 12145e17157SR0ronoa /// 改变窗口的位置 12245e17157SR0ronoa pub fn set_pos(&mut self, x: i32, y: i32) { 12345e17157SR0ronoa self.x = x; 12445e17157SR0ronoa self.y = y; 12545e17157SR0ronoa } 126bee61dcaSR0ronoa 12745e17157SR0ronoa /// 改变窗口的大小 12845e17157SR0ronoa pub fn set_size(&mut self, width: u32, height: u32) { 12945e17157SR0ronoa self.w = width; 13045e17157SR0ronoa self.h = height; 13145e17157SR0ronoa } 13245e17157SR0ronoa 13345e17157SR0ronoa /// 改变窗口标题 13445e17157SR0ronoa pub fn set_title(&mut self, title: &str) { 13545e17157SR0ronoa self.title = title.to_string(); 13645e17157SR0ronoa } 137bee61dcaSR0ronoa } 138