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