term: Misc fixes and improvements
diff --git a/common/drivers/vga_textmode.c b/common/drivers/vga_textmode.c
index 852d82ee..501d9006 100644
--- a/common/drivers/vga_textmode.c
+++ b/common/drivers/vga_textmode.c
@@ -252,6 +252,8 @@ static void text_deinit(struct term_context *_ctx, void (*_free)(void *, size_t)
}
}
+static struct textmode_context term_local_struct;
+
void vga_textmode_init(bool managed) {
if (quiet || allocations_disallowed) {
return;
@@ -265,7 +267,13 @@ void vga_textmode_init(bool managed) {
current_video_mode = 0x3;
}
- struct textmode_context *ctx = (void *)term;
+ if (term != NULL) {
+ term->deinit(term, pmm_free);
+ term = NULL;
+ }
+
+ struct textmode_context *ctx = &term_local_struct;
+ term = &term_local_struct.term;
if (ctx->back_buffer == NULL) {
ctx->back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
diff --git a/common/lib/gterm.c b/common/lib/gterm.c
index 1d9d50d4..6b9165c5 100644
--- a/common/lib/gterm.c
+++ b/common/lib/gterm.c
@@ -497,7 +497,7 @@ static void loop_external(size_t xstart, size_t xend, size_t ystart, size_t yend
static void loop_margin(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_margin); }
static void loop_internal(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_internal); }
-static void *generate_canvas(void) {
+static void generate_canvas(void) {
if (background) {
bg_canvas_size = fbinfo.framebuffer_width * fbinfo.framebuffer_height * sizeof(uint32_t);
bg_canvas = ext_mem_alloc(bg_canvas_size);
@@ -527,21 +527,15 @@ static void *generate_canvas(void) {
}
loop_internal(margin, gradient_stop_x, margin, gradient_stop_y);
-
- return bg_canvas;
+ } else {
+ bg_canvas = NULL;
}
-
- return NULL;
}
static bool last_serial = false;
static char *last_config = NULL;
bool gterm_init(char *config, size_t width, size_t height) {
- if (term_backend != GTERM) {
- term->deinit(term, pmm_free);
- }
-
if (quiet || allocations_disallowed) {
return false;
}
@@ -573,9 +567,15 @@ bool gterm_init(char *config, size_t width, size_t height) {
return true;
}
+ if (term != NULL) {
+ term->deinit(term, pmm_free);
+ term = NULL;
+ }
+
// We force bpp to 32
- if (!fb_init(&fbinfo, width, height, 32))
+ if (!fb_init(&fbinfo, width, height, 32)) {
return false;
+ }
// Ensure this is xRGB8888, we only support that for the menu
if (fbinfo.red_mask_size != 8
@@ -583,8 +583,9 @@ bool gterm_init(char *config, size_t width, size_t height) {
|| fbinfo.green_mask_size != 8
|| fbinfo.green_mask_shift != 8
|| fbinfo.blue_mask_size != 8
- || fbinfo.blue_mask_shift != 0)
+ || fbinfo.blue_mask_shift != 0) {
return false;
+ }
last_serial = serial;
last_config = config;
@@ -762,14 +763,12 @@ no_load_font:;
}
}
- uint32_t *canvas = generate_canvas();
-
- term->deinit(term, pmm_free);
+ generate_canvas();
term = fbterm_init(ext_mem_alloc,
(void *)(uintptr_t)fbinfo.framebuffer_addr,
fbinfo.framebuffer_width, fbinfo.framebuffer_height, fbinfo.framebuffer_pitch,
- canvas,
+ bg_canvas,
ansi_colours, ansi_bright_colours,
&default_bg, &default_fg,
font, font_width, font_height, font_spacing,
@@ -777,6 +776,9 @@ no_load_font:;
margin);
pmm_free(font, FONT_MAX);
+ if (bg_canvas != NULL) {
+ pmm_free(bg_canvas, bg_canvas_size);
+ }
if (serial) {
term->cols = term->cols > 80 ? 80 : term->cols;
diff --git a/common/lib/print.s2.c b/common/lib/print.s2.c
index 8dffdc3d..b64cab9c 100644
--- a/common/lib/print.s2.c
+++ b/common/lib/print.s2.c
@@ -203,7 +203,9 @@ out:
#if defined (BIOS)
if (stage3_loaded) {
#endif
- term_write(term, print_buf, print_buf_i);
+ if (term != NULL) {
+ term_write(term, print_buf, print_buf_i);
+ }
#if defined (BIOS)
} else {
s2_print(print_buf, print_buf_i);
diff --git a/common/lib/term.c b/common/lib/term.c
index b7aa454f..8b0acef0 100644
--- a/common/lib/term.c
+++ b/common/lib/term.c
@@ -3,10 +3,7 @@
#include <stdbool.h>
#include <lib/term.h>
#include <lib/real.h>
-#include <lib/image.h>
#include <lib/misc.h>
-#include <lib/gterm.h>
-#include <drivers/vga_textmode.h>
#include <lib/print.h>
#include <mm/pmm.h>
@@ -15,7 +12,7 @@ int term_backend = _NOT_READY;
struct term_context *term;
-static struct textmode_context term_local_struct;
+static struct term_context term_local_struct;
// --- notready ---
@@ -63,9 +60,10 @@ static void notready_deinit(struct term_context *ctx, void (*_free)(void *, size
void term_notready(void) {
if (term != NULL) {
term->deinit(term, pmm_free);
+ term = NULL;
}
- term = &term_local_struct.term;
+ term = &term_local_struct;
term->raw_putchar = notready_raw_putchar;
term->clear = notready_clear;
diff --git a/common/protos/chainload.c b/common/protos/chainload.c
index e097f6f0..2221c458 100644
--- a/common/protos/chainload.c
+++ b/common/protos/chainload.c
@@ -217,6 +217,7 @@ noreturn void efi_chainload_file(char *config, struct file_handle *image) {
fclose(image);
term->deinit(term, pmm_free);
+ term = NULL;
size_t req_width = 0, req_height = 0, req_bpp = 0;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index a7466947..659f2579 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -736,6 +736,7 @@ FEAT_START
FEAT_END
term->deinit(term, pmm_free);
+ term = NULL;
if (!fb_init(&fb, req_width, req_height, req_bpp)) {
panic(true, "limine: Could not acquire framebuffer");
diff --git a/common/protos/linux.c b/common/protos/linux.c
index d181ee85..a9fa4a89 100644
--- a/common/protos/linux.c
+++ b/common/protos/linux.c
@@ -496,6 +496,7 @@ noreturn void linux_load(char *config, char *cmdline) {
///////////////////////////////////////
term->deinit(term, pmm_free);
+ term = NULL;
struct screen_info *screen_info = &boot_params->screen_info;
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 74347a8a..0f4a92ef 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -303,6 +303,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
multiboot1_info->flags |= (1 << 9);
term->deinit(term, pmm_free);
+ term = NULL;
if (header.flags & (1 << 2)) {
size_t req_width = header.fb_width;
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 8e587417..ab8625b2 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -506,6 +506,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
tag->common.size = sizeof(struct multiboot_tag_framebuffer);
term->deinit(term, pmm_free);
+ term = NULL;
if (fbtag) {
size_t req_width = fbtag->width;
