diff --git a/src/kernel/drivers/framebuffer.c b/src/kernel/drivers/framebuffer.c index b2a26d5..a54bb0d 100644 --- a/src/kernel/drivers/framebuffer.c +++ b/src/kernel/drivers/framebuffer.c @@ -2,30 +2,80 @@ #include #include +struct gfx_context { + uint32_t width; + uint32_t height; + uint32_t bpp; + uint32_t pitch; + void *addr; + void *buffer; + size_t size; +}; + +struct gfx_context framebuffer; + +struct gfx_context subcontext; + +#define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b))) + +void putpixel(struct gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr) +{ + if(x >= ctr->width || y >= ctx->height) return; + uint64_t loc = \ + y * ctx->pitch + \ + x * ctx->bpp/8; + uint32_t *fb = incptr(P2V(ctx->addr), loc); + + *fb = clr; +} + +static void draw_border(struct gfx_context *ctx, uint32_t clr) +{ + for(uint64_t x = 0; x < ctx->width; x++) + { + putpixel(ctx, x, 0, clr); + putpixel(ctx, x, ctx->height-1, clr); + } + for(uint64_t y = 0; y < ctx->height; y++) + { + putpixel(ctx, 0, y, clr); + putpixel(ctx, ctx->width-1, y, clr); + } +} + +struct gfx_context *make_subarea(struct gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) +{ + struct gfx_context *out = &subcontext; + uint64_t loc = \ + y * ctx->pitch + \ + x * ctx->bpp/8; + + out->width = width; + out->height = height; + out->bpp = ctx->bpp; + out->pitch = ctx->pitch; + out->addr = incptr(ctx->addr, loc); + out->size = ctx->pitch * (height); + + return out; +} + void framebuffer_init(struct fbinfo *fbinfo) { - size_t fb_size = fbinfo->framebuffer_pitch * (fbinfo->framebuffer_height+1); - uintptr_t fb_end = fbinfo->framebuffer_addr + fb_size; + framebuffer.width = fbinfo->framebuffer_width; + framebuffer.height = fbinfo->framebuffer_height; + framebuffer.bpp = fbinfo->framebuffer_bpp; + framebuffer.pitch = fbinfo->framebuffer_pitch; + framebuffer.addr = (void *)fbinfo->framebuffer_addr; + framebuffer.size = framebuffer.pitch * (framebuffer.height); - for(uintptr_t p = fbinfo->framebuffer_addr; p < fb_end; p += PAGE_SIZE) + for(uintptr_t p = (uintptr_t)framebuffer.addr; p < ((uintptr_t)framebuffer.addr + framebuffer.size); p += PAGE_SIZE) { vmm_set_page(kernel_P4, (uint64_t)P2V(p), p, PAGE_WRITE | PAGE_PRESENT); } - uint8_t *fb = P2V(fbinfo->framebuffer_addr); - - for(uint32_t y = 0; y < 1; y++) - { - for(uint32_t x = 0; x < fbinfo->framebuffer_width; x++) - { - unsigned int bpp = fbinfo->framebuffer_bpp/8; - unsigned int loc = \ - y*fbinfo->framebuffer_pitch + \ - x*(bpp); - fb[loc++] = 0xFF; - fb[loc++] = 0; - fb[loc] = 0xFF; - } - } + draw_border(&framebuffer, RGB(0, 255, 0)); + struct gfx_context *sub = make_subarea(&framebuffer, 256, 192, 256, 192); + draw_border(sub, RGB(255, 0, 0)); } \ No newline at end of file