window.rs 3.1 KB

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