diff options
Diffstat (limited to 'boot/limine/framebuffer.c')
| -rw-r--r-- | boot/limine/framebuffer.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/boot/limine/framebuffer.c b/boot/limine/framebuffer.c new file mode 100644 index 0000000..b4330bb --- /dev/null +++ b/boot/limine/framebuffer.c @@ -0,0 +1,79 @@ +#include "arch/x86_64/hal/obj.h" +#include "jove.h" +#include "lib/printf.h" +#include "limine.h" +#include "init.h" +#include "hal/framebuffer.h" + +extern struct limine_framebuffer_response *_limine_framebuffers; + +#define CHECK_IF_FB(obj) \ + if(obj_gettype(obj) != JOVE_OBJ_FRAMEBUFFER) { \ + reterr(EBADOBJ); \ + } + +size_t +fb_width(jove_owned_obj_t *obj) +{ + CHECK_IF_FB(obj); + struct limine_framebuffer *fb = obj_deref(obj); + return fb->width; +} + +size_t +fb_height(jove_owned_obj_t *obj) +{ + CHECK_IF_FB(obj); + struct limine_framebuffer *fb = obj_deref(obj); + return fb->height; +} + +int +fb_blit(jove_owned_obj_t *obj, + uint32_t *data, + size_t x, size_t y, + size_t width, size_t height) +{ + CHECK_IF_FB(obj); + struct limine_framebuffer *fb = obj_deref(obj); + + uint32_t *fb_address = fb->address; + for(size_t oline = 0; oline < height; oline++) { + size_t line = oline + y; + uint32_t *line_data = &data[oline * width]; + for(size_t ocol = 0; ocol < width; ocol++) { + size_t col = ocol + x; + fb_address[line * (fb->pitch >> 2) + col] = line_data[ocol]; + } + } + return 0; +} + +void +fb_init() +{ + if(_limine_framebuffers->framebuffer_count == 0) { + return; + } + struct limine_framebuffer *fb = _limine_framebuffers->framebuffers[0]; + size_t fb_bytes = fb->width * fb->height * (fb->bpp / 8); + void *fb_virt = fb_remap((uintptr_t)fb->address, fb_bytes); + if(fb_virt == NULL) { + kprintf("Unable to remap framebuffer.\n"); + return; + } + + kprintf("framebuffer: phys address %p\n", (uintptr_t)fb->address); + kprintf("framebuffer: virt address %p\n", fb_virt); + kprintf("framebuffer: width %ipx\n", fb->width); + kprintf("framebuffer: height %ipx\n", fb->height); + kprintf("framebuffer: %i bpp\n", fb->bpp); + + fb->address = fb_virt; + { + jove_owned_obj_t *fb_obj = obj_take(objdir_getlocal(_rootdir_obj, ROOTDIR_FRAMEBUFFER_I)); + obj_settype(fb_obj, JOVE_OBJ_FRAMEBUFFER); + obj_setvalue(fb_obj, (uintptr_t)fb); + obj_release(fb_obj); + } +} |
