framebuffer.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. use core::ptr;
  2. use core::slice;
  3. use header::Tag;
  4. #[derive(Debug)]
  5. pub struct FramebufferTag<'a> {
  6. pub address: u64,
  7. pub pitch: u32,
  8. pub width: u32,
  9. pub height: u32,
  10. pub bpp: u8,
  11. pub buffer_type: FramebufferType<'a>
  12. }
  13. #[derive(Debug)]
  14. pub enum FramebufferType<'a> {
  15. Indexed {
  16. palette: &'a [FramebufferColor]
  17. },
  18. RGB {
  19. red: FramebufferField,
  20. green: FramebufferField,
  21. blue: FramebufferField
  22. },
  23. Text
  24. }
  25. #[derive(Debug)]
  26. pub struct FramebufferField {
  27. position: u8,
  28. size: u8
  29. }
  30. #[derive(Debug)]
  31. #[repr(C, packed)]
  32. pub struct FramebufferColor {
  33. red: u8,
  34. green: u8,
  35. blue: u8
  36. }
  37. struct Reader {
  38. ptr: *const u8,
  39. off: usize
  40. }
  41. impl Reader {
  42. fn new<T>(ptr: *const T) -> Reader {
  43. Reader {
  44. ptr: ptr as *const u8,
  45. off: 0
  46. }
  47. }
  48. fn read_u8(&mut self) -> u8 {
  49. self.off += 1;
  50. unsafe {
  51. ptr::read(self.ptr.offset((self.off - 1) as isize))
  52. }
  53. }
  54. fn read_u16(&mut self) -> u16 {
  55. self.read_u8() as u16 | (self.read_u8() as u16) << 8
  56. }
  57. fn read_u32(&mut self) -> u32 {
  58. self.read_u16() as u32 | (self.read_u16() as u32) << 16
  59. }
  60. fn read_u64(&mut self) -> u64 {
  61. self.read_u32() as u64 | (self.read_u32() as u64) << 32
  62. }
  63. fn skip(&mut self, n: usize) {
  64. self.off += n;
  65. }
  66. }
  67. pub fn framebuffer_tag<'a>(tag: &'a Tag) -> FramebufferTag<'a> {
  68. let mut reader = Reader::new(tag as *const Tag);
  69. reader.skip(8);
  70. let address = reader.read_u64();
  71. let pitch = reader.read_u32();
  72. let width = reader.read_u32();
  73. let height = reader.read_u32();
  74. let bpp = reader.read_u8();
  75. let type_no = reader.read_u8();
  76. reader.skip(2); // In the multiboot spec, it has this listed as a u8 _NOT_ a u16.
  77. // Reading the GRUB2 source code reveals it is in fact a u16.
  78. let buffer_type = match type_no {
  79. 0 => {
  80. let num_colors = reader.read_u32();
  81. let palette = unsafe {
  82. slice::from_raw_parts(reader.ptr.offset(reader.off as isize) as *const FramebufferColor, num_colors as usize)
  83. } as &'static [FramebufferColor];
  84. FramebufferType::Indexed { palette }
  85. },
  86. 1 => {
  87. let red_pos = reader.read_u8(); //These refer to the bit positions of the MSB of each field
  88. let red_mask = reader.read_u8(); //And then the length of the field from MSB to LSB
  89. let green_pos = reader.read_u8();
  90. let green_mask = reader.read_u8();
  91. let blue_pos = reader.read_u8();
  92. let blue_mask = reader.read_u8();
  93. FramebufferType::RGB {
  94. red: FramebufferField { position: red_pos, size: red_mask },
  95. green: FramebufferField { position: green_pos, size: green_mask },
  96. blue: FramebufferField { position: blue_pos, size: blue_mask }
  97. }
  98. },
  99. 2 => FramebufferType::Text,
  100. _ => panic!("Unknown framebuffer type: {}", type_no)
  101. };
  102. FramebufferTag {
  103. address,
  104. pitch,
  105. width,
  106. height,
  107. bpp,
  108. buffer_type
  109. }
  110. }