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 3c4f67b8..c6ba7294 100644 --- a/common/lib/print.s2.c +++ b/common/lib/print.s2.c @@ -222,7 +222,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 82049f0f..1b67fee4 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 0750e17e..eb47437b 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 8a6d609d..84b5c6df 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 98a98547..5bbc4f90 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;