:: commit 0477d34236296b2ee23e67ffda6479d99478b197

VAN BOSSUYT Nicolas <nicolas.van.bossuyt@gmail.com> — 2020-09-24 19:48

parents: 9a9df2b146

The color scheme can be changed using the configuration file.

diff --git a/CONFIG.md b/CONFIG.md
index 5615aea4..91812069 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -22,6 +22,7 @@ Some *local assignments* are shared between entries using any *protocol*, while
 *Globally assignable* keys are:
 * `TIMEOUT` - Specifies the timeout in seconds before the first *entry* is automatically booted.
 * `TEXTMODE` - If set to `on`, do not use graphical VESA framebuffer for the boot menu.
+* `COLORSCHEME_BLACK`, `COLORSCHEME_RED`, `COLORSCHEME_GREEN`, `COLORSCHEME_BROWN`, `COLORSCHEME_BLUE`, `COLORSCHEME_MAGENTA`, `COLORSCHEME_CYAN`, `COLORSCHEME_GREY`, `COLORSCHEME_WHITE` - Specifies the colors used by the terminal (RRGGBB).
 
 *Locally assignable (non protocol specific)* keys are:
 * `PROTOCOL` - The boot protocol that will be used to boot the kernel. Valid protocols are: `linux`, `stivale`, `chainload`.
diff --git a/limine.bin b/limine.bin
index 183bba7a..fa3ac124 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/drivers/vbe.c b/stage2/drivers/vbe.c
index 81484175..5cad14bf 100644
--- a/stage2/drivers/vbe.c
+++ b/stage2/drivers/vbe.c
@@ -174,7 +174,8 @@ static uint32_t ansi_colours[] = {
     0x000000aa,              // blue
     0x00aa00aa,              // magenta
     0x0000aaaa,              // cyan
-    0x00aaaaaa               // grey
+    0x00aaaaaa,              // grey
+    0x00ffffff               // white
 };
 
 void vbe_set_text_fg(int fg) {
@@ -185,6 +186,12 @@ void vbe_set_text_bg(int bg) {
     text_bg = ansi_colours[bg];
 }
 
+void vge_set_colors(uint32_t *colors){
+    memcpy(ansi_colours, colors, sizeof(ansi_colours));
+    text_bg = colors[0];
+    text_fg = colors[7];
+}
+
 void vbe_putchar(char c) {
     switch (c) {
         case '\b':
@@ -234,8 +241,8 @@ void vbe_putchar(char c) {
 void vbe_tty_init(int *_rows, int *_cols, struct image *_background) {
     init_vbe(&vbe_framebuffer, &vbe_pitch, &vbe_width, &vbe_height, &vbe_bpp);
     vga_font_retrieve();
-    *_cols = cols = 80;
-    *_rows = rows = 25;
+    *_cols = cols = (vbe_width - 128) / VGA_FONT_WIDTH;
+    *_rows = rows = (vbe_height - 128) / VGA_FONT_HEIGHT;
     grid = ext_mem_alloc(rows * cols * sizeof(struct vbe_char));
     background = _background;
 
diff --git a/stage2/drivers/vbe.h b/stage2/drivers/vbe.h
index e1682df1..5c53d430 100644
--- a/stage2/drivers/vbe.h
+++ b/stage2/drivers/vbe.h
@@ -17,5 +17,6 @@ void vbe_set_cursor_pos(int x, int y);
 void vbe_get_cursor_pos(int *x, int *y);
 void vbe_set_text_fg(int fg);
 void vbe_set_text_bg(int bg);
+void vge_set_colors(uint32_t *colors);
 
 #endif
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index a11f8c62..94296e7b 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -46,10 +46,31 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
     }
 }
 
+static int char_value(char c) {
+    if (c >= 'a' && c <= 'z') {
+        return (c - 'a') + 10;
+    }
+    if (c >= 'A' && c <= 'Z') {
+        return (c - 'A') + 10;
+    }
+    if (c >= '0' && c <= '9'){
+        return c - '0';
+    }
+
+    return 0;
+}
+
 uint64_t strtoui(const char *s) {
     uint64_t n = 0;
     while (*s)
-        n = n * 10 + ((*(s++)) - '0');
+        n = n * 10 + char_value(*(s++));
+    return n;
+}
+
+uint64_t strtoui16(const char *s) {
+    uint64_t n = 0;
+    while (*s)
+        n = n * 16 + char_value(*(s++));
     return n;
 }
 
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index 67d34891..015d5839 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -21,6 +21,7 @@ int pit_sleep_and_quit_on_keypress(uint32_t pit_ticks);
 int getchar(void);
 void gets(const char *orig_str, char *buf, size_t limit);
 uint64_t strtoui(const char *s);
+uint64_t strtoui16(const char *s);
 
 #define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b))
 
diff --git a/stage2/lib/term.c b/stage2/lib/term.c
index cf08ba44..5ceacfd5 100644
--- a/stage2/lib/term.c
+++ b/stage2/lib/term.c
@@ -113,6 +113,12 @@ static void term_putchar(char c) {
 }
 
 static void sgr(void) {
+    if (esc_value0 == 0){
+        set_text_bg(0);
+        set_text_fg(7);
+        return;
+    }
+
     if (esc_value0 >= 30 && esc_value0 <= 37) {
         set_text_fg(esc_value0 - 30);
         return;
diff --git a/stage2/menu.c b/stage2/menu.c
index 4b5d2e3e..bc2f7200 100644
--- a/stage2/menu.c
+++ b/stage2/menu.c
@@ -9,12 +9,67 @@
 #include <lib/config.h>
 #include <lib/term.h>
 #include <mm/pmm.h>
+#include <drivers/vbe.h>
 
 static char *cmdline;
 #define CMDLINE_MAX 1024
 
 static char config_entry_name[1024];
 
+void load_color_from_config(void) {
+    char buf[16];
+
+    uint32_t colorsheme[9] = {
+        0x00191919, // black
+        0x00aa0000, // red
+        0x0000aa00, // green
+        0x00aa5500, // brown
+        0x000000aa, // blue
+        0x009076DE, // magenta
+        0x0000aaaa, // cyan
+        0x00aaaaaa, // grey
+        0x00ffffff, // white
+    };
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_BLACK")) {
+        colorsheme[0] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_RED")) {
+        colorsheme[1] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_GREEN")) {
+        colorsheme[2] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_BROWN")) {
+        colorsheme[3] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_BLUE")) {
+        colorsheme[4] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_MAGENTA")) {
+        colorsheme[5] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_CYAN")) {
+        colorsheme[6] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_GREY")) {
+        colorsheme[7] = (int)strtoui16(buf);
+    }
+
+    if (config_get_value(buf, 0, 16, "COLORSCHEME_WHITE")) {
+        colorsheme[8] = (int)strtoui16(buf);
+    }
+
+    vge_set_colors(colorsheme);
+}
+
 char *menu(int boot_drive) {
     cmdline = conv_mem_alloc(CMDLINE_MAX);
 
@@ -22,6 +77,8 @@ char *menu(int boot_drive) {
 
     // If there is no TEXTMODE config key or the value is not "on", enable graphics
     if (config_get_value(buf, 0, 16, "TEXTMODE") == NULL || strcmp(buf, "on")) {
+        load_color_from_config();
+
         int bg_drive;
         if (!config_get_value(buf, 0, 16, "BACKGROUND_DRIVE")) {
             bg_drive = boot_drive;
diff --git a/test/limine.cfg b/test/limine.cfg
index 775a29a4..369e19ec 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -1,5 +1,15 @@
 TIMEOUT=3
 
+COLORSCHEME_BLACK=073642
+COLORSCHEME_RED=aa0000
+COLORSCHEME_GREEN=00aaff
+COLORSCHEME_BROWN=aa5500
+COLORSCHEME_BLUE=0000aa
+COLORSCHEME_MAGENTA=aa00aa
+COLORSCHEME_CYAN=00aaaa
+COLORSCHEME_GREY=aaaaaa
+COLORSCHEME_WHITE=fdf6e3
+
 BACKGROUND_PARTITION=0
 BACKGROUND_PATH=bg.bmp
 
tab: 248 wrap: offon