Files
jsix/src/user/drv.uefi_fb/main.cpp
F in Chat for Tabs 8f529046a9 [project] Lose the battle between tabs & spaces
I'm a tabs guy. I like tabs, it's an elegant way to represent
indentation instead of brute-forcing it. But I have to admit that the
world seems to be going towards spaces, and tooling tends not to play
nice with tabs. So here we go, changing the whole repo to spaces since
I'm getting tired of all the inconsistent formatting.
2021-08-01 17:46:16 -07:00

141 lines
3.4 KiB
C++

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "j6/init.h"
#include "j6/errors.h"
#include "j6/flags.h"
#include "j6/signals.h"
#include "j6/syscalls.h"
#include "j6/types.h"
#include "font.h"
#include "screen.h"
#include "scrollback.h"
extern "C" {
int main(int, const char **);
void _get_init(size_t *initc, struct j6_init_value **initv);
}
extern j6_handle_t __handle_sys;
extern j6_handle_t __handle_self;
struct entry
{
uint8_t bytes;
uint8_t area;
uint8_t severity;
uint8_t sequence;
char message[0];
};
int
main(int argc, const char **argv)
{
j6_system_log("fb driver starting");
size_t initc = 0;
j6_init_value *initv = nullptr;
_get_init(&initc, &initv);
j6_init_framebuffer *fb = nullptr;
for (unsigned i = 0; i < initc; ++i) {
if (initv[i].type == j6_init_desc_framebuffer) {
fb = reinterpret_cast<j6_init_framebuffer*>(initv[i].data);
break;
}
}
if (!fb || fb->addr == 0) {
j6_system_log("fb driver didn't find a framebuffer, exiting");
return 1;
}
j6_handle_t fb_handle = j6_handle_invalid;
uint32_t flags =
j6_vm_flag_write |
j6_vm_flag_write_combine |
j6_vm_flag_mmio;
j6_status_t s = j6_system_map_phys(__handle_sys, &fb_handle, fb->addr, fb->size, flags);
if (s != j6_status_ok) {
return s;
}
s = j6_vma_map(fb_handle, __handle_self, fb->addr);
if (s != j6_status_ok) {
return s;
}
const screen::pixel_order order = (fb->flags & 1) ?
screen::pixel_order::bgr8 : screen::pixel_order::rgb8;
screen scr(
reinterpret_cast<void*>(fb->addr),
fb->horizontal,
fb->vertical,
fb->scanline,
order);
font fnt;
screen::pixel_t fg = scr.color(0xb0, 0xb0, 0xb0);
screen::pixel_t bg = scr.color(49, 79, 128);
scr.fill(bg);
scr.update();
constexpr int margin = 2;
const unsigned xstride = (margin + fnt.width());
const unsigned ystride = (margin + fnt.height());
const unsigned rows = (scr.height() - margin) / ystride;
const unsigned cols = (scr.width() - margin) / xstride;
scrollback scroll(rows, cols);
int pending = 0;
constexpr int pending_threshold = 5;
j6_handle_t sys = __handle_sys;
size_t buffer_size = 0;
void *message_buffer = nullptr;
while (true) {
size_t size = buffer_size;
j6_status_t s = j6_system_get_log(sys, message_buffer, &size);
if (s == j6_err_insufficient) {
free(message_buffer);
message_buffer = malloc(size * 2);
buffer_size = size;
continue;
} else if (s != j6_status_ok) {
j6_system_log("fb driver got error from get_log, quitting");
return s;
}
if (size > 0) {
entry *e = reinterpret_cast<entry*>(message_buffer);
size_t eom = e->bytes - sizeof(entry);
e->message[eom] = 0;
scroll.add_line(e->message, eom);
if (++pending > pending_threshold) {
scroll.render(scr, fnt);
scr.update();
pending = 0;
}
} else {
if (pending) {
scroll.render(scr, fnt);
scr.update();
pending = 0;
}
}
}
j6_system_log("fb driver done, exiting");
return 0;
}