framebuffer.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. use header::Tag;
  2. use ::Reader;
  3. use core::slice;
  4. #[derive(Debug, PartialEq)]
  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, PartialEq)]
  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, PartialEq)]
  26. pub struct FramebufferField {
  27. pub position: u8,
  28. pub size: u8
  29. }
  30. #[derive(Clone, Copy, Debug, PartialEq)]
  31. #[repr(C, packed)]
  32. pub struct FramebufferColor {
  33. pub red: u8,
  34. pub green: u8,
  35. pub blue: u8
  36. }
  37. pub fn framebuffer_tag<'a>(tag: &'a Tag) -> FramebufferTag<'a> {
  38. let mut reader = Reader::new(tag as *const Tag);
  39. reader.skip(8);
  40. let address = reader.read_u64();
  41. let pitch = reader.read_u32();
  42. let width = reader.read_u32();
  43. let height = reader.read_u32();
  44. let bpp = reader.read_u8();
  45. let type_no = reader.read_u8();
  46. reader.skip(2); // In the multiboot spec, it has this listed as a u8 _NOT_ a u16.
  47. // Reading the GRUB2 source code reveals it is in fact a u16.
  48. let buffer_type = match type_no {
  49. 0 => {
  50. let num_colors = reader.read_u32();
  51. let palette = unsafe {
  52. slice::from_raw_parts(reader.read_u32() as usize as *const FramebufferColor, num_colors as usize)
  53. } as &'a [FramebufferColor];
  54. FramebufferType::Indexed { palette }
  55. },
  56. 1 => {
  57. let red_pos = reader.read_u8(); // These refer to the bit positions of the MSB of each field
  58. let red_mask = reader.read_u8(); // And then the length of the field from MSB to LSB
  59. let green_pos = reader.read_u8();
  60. let green_mask = reader.read_u8();
  61. let blue_pos = reader.read_u8();
  62. let blue_mask = reader.read_u8();
  63. FramebufferType::RGB {
  64. red: FramebufferField { position: red_pos, size: red_mask },
  65. green: FramebufferField { position: green_pos, size: green_mask },
  66. blue: FramebufferField { position: blue_pos, size: blue_mask }
  67. }
  68. },
  69. 2 => FramebufferType::Text,
  70. _ => panic!("Unknown framebuffer type: {}", type_no)
  71. };
  72. FramebufferTag {
  73. address,
  74. pitch,
  75. width,
  76. height,
  77. bpp,
  78. buffer_type
  79. }
  80. }