window.rs 3.2 KB

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