xref: /StarryEngine/starry_client/src/window.rs (revision bee61dca287acb4b9fd6d747ba3f687aebacab90)
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 }