123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- use core::ptr;
- use core::slice;
- use header::Tag;
- #[derive(Debug)]
- pub struct FramebufferTag<'a> {
- pub address: u64,
- pub pitch: u32,
- pub width: u32,
- pub height: u32,
- pub bpp: u8,
- pub buffer_type: FramebufferType<'a>
- }
- #[derive(Debug)]
- pub enum FramebufferType<'a> {
- Indexed {
- palette: &'a [FramebufferColor]
- },
- RGB {
- red: FramebufferField,
- green: FramebufferField,
- blue: FramebufferField
- },
- Text
- }
- #[derive(Debug)]
- pub struct FramebufferField {
- position: u8,
- size: u8
- }
- #[derive(Debug)]
- #[repr(C, packed)]
- pub struct FramebufferColor {
- red: u8,
- green: u8,
- blue: u8
- }
- struct Reader {
- ptr: *const u8,
- off: usize
- }
- impl Reader {
- fn new<T>(ptr: *const T) -> Reader {
- Reader {
- ptr: ptr as *const u8,
- off: 0
- }
- }
- fn read_u8(&mut self) -> u8 {
- self.off += 1;
- unsafe {
- ptr::read(self.ptr.offset((self.off - 1) as isize))
- }
- }
- fn read_u16(&mut self) -> u16 {
- self.read_u8() as u16 | (self.read_u8() as u16) << 8
- }
- fn read_u32(&mut self) -> u32 {
- self.read_u16() as u32 | (self.read_u16() as u32) << 16
- }
- fn read_u64(&mut self) -> u64 {
- self.read_u32() as u64 | (self.read_u32() as u64) << 32
- }
- fn skip(&mut self, n: usize) {
- self.off += n;
- }
- }
- pub fn framebuffer_tag<'a>(tag: &'a Tag) -> FramebufferTag<'a> {
- let mut reader = Reader::new(tag as *const Tag);
- reader.skip(8);
- let address = reader.read_u64();
- let pitch = reader.read_u32();
- let width = reader.read_u32();
- let height = reader.read_u32();
- let bpp = reader.read_u8();
- let type_no = reader.read_u8();
- reader.skip(2); // In the multiboot spec, it has this listed as a u8 _NOT_ a u16.
- // Reading the GRUB2 source code reveals it is in fact a u16.
- let buffer_type = match type_no {
- 0 => {
- let num_colors = reader.read_u32();
- let palette = unsafe {
- slice::from_raw_parts(reader.ptr.offset(reader.off as isize) as *const FramebufferColor, num_colors as usize)
- } as &'static [FramebufferColor];
- FramebufferType::Indexed { palette }
- },
- 1 => {
- let red_pos = reader.read_u8(); //These refer to the bit positions of the MSB of each field
- let red_mask = reader.read_u8(); //And then the length of the field from MSB to LSB
- let green_pos = reader.read_u8();
- let green_mask = reader.read_u8();
- let blue_pos = reader.read_u8();
- let blue_mask = reader.read_u8();
- FramebufferType::RGB {
- red: FramebufferField { position: red_pos, size: red_mask },
- green: FramebufferField { position: green_pos, size: green_mask },
- blue: FramebufferField { position: blue_pos, size: blue_mask }
- }
- },
- 2 => FramebufferType::Text,
- _ => panic!("Unknown framebuffer type: {}", type_no)
- };
- FramebufferTag {
- address,
- pitch,
- width,
- height,
- bpp,
- buffer_type
- }
- }
|