:: commit dc3b45a9a90159476422c075e2676aa62f8d70a7

mintsuki <mintsuki@protonmail.com> — 2021-05-22 22:19

parents: 4d7a48eca7

term: General terminal improvements

diff --git a/stage23/lib/term.s2.c b/stage23/lib/term.s2.c
index 0f7bfb3b..5701d2a0 100644
--- a/stage23/lib/term.s2.c
+++ b/stage23/lib/term.s2.c
@@ -7,7 +7,11 @@
 #include <lib/blib.h>
 #include <drivers/vga_textmode.h>
 
+// Tries to implement this standard for terminfo
+// https://man7.org/linux/man-pages/man4/console_codes.4.html
+
 #define TERM_TABSIZE (8)
+#define MAX_ESC_VALUES (256)
 
 int current_video_mode = -1;
 
@@ -74,125 +78,118 @@ static int get_cursor_pos_y(void) {
     return y;
 }
 
-static void escape_parse(uint8_t c);
+static bool control_sequence = false;
+static bool escape = false;
+static bool rrr = false;
+static int esc_values[MAX_ESC_VALUES];
+static int esc_values_i = 0;
+static int saved_cursor_x = 0, saved_cursor_y = 0;
 
-static int escape = 0;
-static int esc_value0 = 0;
-static int esc_value1 = 0;
-static int *esc_value = &esc_value0;
-static int esc_default0 = 1;
-static int esc_default1 = 1;
-static int *esc_default = &esc_default0;
+static void sgr(void) {
+    int i = 0;
 
-static void term_putchar(uint8_t c) {
-    if (escape) {
-        escape_parse(c);
-        return;
-    }
-    switch (c) {
-        case 0x00:
-            break;
-        case '\e':
-            escape = 1;
-            return;
-        case '\t':
-            if ((get_cursor_pos_x() / TERM_TABSIZE + 1) >= term_cols)
-                break;
-            set_cursor_pos((get_cursor_pos_x() / TERM_TABSIZE + 1) * TERM_TABSIZE, get_cursor_pos_y());
-            break;
-        default:
-            raw_putchar(c);
-            break;
-    }
-}
+    if (!esc_values_i)
+        goto def;
 
-static void sgr(void) {
-    if (esc_value0 == 0){
-        set_text_bg(8);
-        set_text_fg(9);
-        return;
-    }
+    for (; i < esc_values_i; i++) {
+        if (!esc_values[i]) {
+def:
+            set_text_bg(8);
+            set_text_fg(9);
+            continue;
+        }
 
-    if (esc_value0 >= 30 && esc_value0 <= 37) {
-        set_text_fg(esc_value0 - 30);
-        return;
-    }
+        if (esc_values[i] >= 30 && esc_values[i] <= 37) {
+            set_text_fg(esc_values[i] - 30);
+            continue;
+        }
 
-    if (esc_value0 >= 40 && esc_value0 <= 47) {
-        set_text_bg(esc_value0 - 40);
-        return;
+        if (esc_values[i] >= 40 && esc_values[i] <= 47) {
+            set_text_bg(esc_values[i] - 40);
+            continue;
+        }
     }
 }
 
-static void escape_parse(uint8_t c) {
+static void control_sequence_parse(uint8_t c) {
     if (c >= '0' && c <= '9') {
-        *esc_value *= 10;
-        *esc_value += c - '0';
-        *esc_default = 0;
+        rrr = true;
+        esc_values[esc_values_i] *= 10;
+        esc_values[esc_values_i] += c - '0';
         return;
+    } else {
+        if (rrr == true) {
+            esc_values_i++;
+            rrr = false;
+            if (c == ';')
+                return;
+        } else if (c == ';') {
+            esc_values[esc_values_i] = 1;
+            esc_values_i++;
+            return;
+        }
     }
 
+    // default rest to 1
+    for (int i = esc_values_i; i < MAX_ESC_VALUES; i++)
+        esc_values[i] = 1;
+
     switch (c) {
-        case 0x1b:
-            escape = 0;
-            raw_putchar(0x1b);
-            return;
-        case '[':
-            return;
-        case ';':
-            esc_value = &esc_value1;
-            esc_default = &esc_default1;
-            return;
         case 'A':
-            if (esc_default0)
-                esc_value0 = 1;
-            if (esc_value0 > get_cursor_pos_y())
-                esc_value0 = get_cursor_pos_y();
-            set_cursor_pos(get_cursor_pos_x(),
-                                get_cursor_pos_y() - esc_value0);
+            if (esc_values[0] > get_cursor_pos_y())
+                esc_values[0] = get_cursor_pos_y();
+            set_cursor_pos(get_cursor_pos_x(), get_cursor_pos_y() - esc_values[0]);
             break;
         case 'B':
-            if (esc_default0)
-                esc_value0 = 1;
-            if ((get_cursor_pos_y() + esc_value0) > (term_rows - 1))
-                esc_value0 = (term_rows - 1) - get_cursor_pos_y();
-            set_cursor_pos(get_cursor_pos_x(),
-                                get_cursor_pos_y() + esc_value0);
+            if ((get_cursor_pos_y() + esc_values[0]) > (term_rows - 1))
+                esc_values[0] = (term_rows - 1) - get_cursor_pos_y();
+            set_cursor_pos(get_cursor_pos_x(), get_cursor_pos_y() + esc_values[0]);
             break;
         case 'C':
-            if (esc_default0)
-                esc_value0 = 1;
-            if ((get_cursor_pos_x() + esc_value0) > (term_cols - 1))
-                esc_value0 = (term_cols - 1) - get_cursor_pos_x();
-            set_cursor_pos(get_cursor_pos_x() + esc_value0,
-                                get_cursor_pos_y());
+            if ((get_cursor_pos_x() + esc_values[0]) > (term_cols - 1))
+                esc_values[0] = (term_cols - 1) - get_cursor_pos_x();
+            set_cursor_pos(get_cursor_pos_x() + esc_values[0], get_cursor_pos_y());
             break;
         case 'D':
-            if (esc_default0)
-                esc_value0 = 1;
-            if (esc_value0 > get_cursor_pos_x())
-                esc_value0 = get_cursor_pos_x();
-            set_cursor_pos(get_cursor_pos_x() - esc_value0,
-                                get_cursor_pos_y());
+            if (esc_values[0] > get_cursor_pos_x())
+                esc_values[0] = get_cursor_pos_x();
+            set_cursor_pos(get_cursor_pos_x() - esc_values[0], get_cursor_pos_y());
             break;
-        case 'H':
-            esc_value0--;
-            esc_value1--;
-            if (esc_default0)
-                esc_value0 = 0;
-            if (esc_default1)
-                esc_value1 = 0;
-            if (esc_value1 >= term_cols)
-                esc_value1 = term_cols - 1;
-            if (esc_value0 >= term_rows)
-                esc_value0 = term_rows - 1;
-            set_cursor_pos(esc_value1, esc_value0);
+        case 'E':
+            if (get_cursor_pos_y() + esc_values[0] >= term_rows)
+                set_cursor_pos(0, term_rows - 1);
+            else
+                set_cursor_pos(0, get_cursor_pos_y() + esc_values[0]);
             break;
-        case 'm':
-            sgr();
+        case 'F':
+            if (get_cursor_pos_y() - esc_values[0] < 0)
+                set_cursor_pos(0, 0);
+            else
+                set_cursor_pos(0, get_cursor_pos_y() - esc_values[0]);
+            break;
+        case 'd':
+            if (esc_values[0] >= term_rows)
+                break;
+            set_cursor_pos(get_cursor_pos_x(), esc_values[0]);
+            break;
+        case 'G':
+        case '`':
+            if (esc_values[0] >= term_cols)
+                break;
+            set_cursor_pos(esc_values[0], get_cursor_pos_y());
+            break;
+        case 'H':
+        case 'f':
+            esc_values[0] -= 1;
+            esc_values[1] -= 1;
+            if (esc_values[1] >= term_cols)
+                esc_values[1] = term_cols - 1;
+            if (esc_values[0] >= term_rows)
+                esc_values[0] = term_rows - 1;
+            set_cursor_pos(esc_values[1], esc_values[0]);
             break;
         case 'J':
-            switch (esc_value0) {
+            switch (esc_values[0]) {
                 case 2:
                     clear(false);
                     break;
@@ -200,11 +197,20 @@ static void escape_parse(uint8_t c) {
                     break;
             }
             break;
+        case 'm':
+            sgr();
+            break;
+        case 's':
+            get_cursor_pos(&saved_cursor_x, &saved_cursor_y);
+            break;
+        case 'u':
+            set_cursor_pos(saved_cursor_x, saved_cursor_y);
+            break;
         case 'K':
-            switch (esc_value0) {
+            switch (esc_values[0]) {
                 case 2: {
-                    int x = get_cursor_pos_x();
-                    int y = get_cursor_pos_y();
+                    int x, y;
+                    get_cursor_pos(&x, &y);
                     set_cursor_pos(0, y);
                     for (int i = 0; i < term_cols; i++)
                         raw_putchar(' ');
@@ -212,18 +218,53 @@ static void escape_parse(uint8_t c) {
                     break;
                 }
             }
+        default:
+            break;
+    }
+
+    control_sequence = false;
+    escape = false;
+}
+
+static void escape_parse(uint8_t c) {
+    if (control_sequence == true) {
+        control_sequence_parse(c);
+        return;
+    }
+
+    switch (c) {
+        case '[':
+            for (int i = 0; i < MAX_ESC_VALUES; i++)
+                esc_values[i] = 0;
+            esc_values_i = 0;
+            rrr = false;
+            control_sequence = true;
             break;
         default:
-            escape = 0;
-            raw_putchar('?');
+            escape = false;
             break;
     }
+}
+
+static void term_putchar(uint8_t c) {
+    if (escape == true) {
+        escape_parse(c);
+        return;
+    }
 
-    esc_value = &esc_value0;
-    esc_value0 = 0;
-    esc_value1 = 0;
-    esc_default = &esc_default0;
-    esc_default0 = 1;
-    esc_default1 = 1;
-    escape = 0;
+    switch (c) {
+        case '\0':
+            break;
+        case '\e':
+            escape = 1;
+            return;
+        case '\t':
+            if ((get_cursor_pos_x() / TERM_TABSIZE + 1) >= term_cols)
+                break;
+            set_cursor_pos((get_cursor_pos_x() / TERM_TABSIZE + 1) * TERM_TABSIZE, get_cursor_pos_y());
+            break;
+        default:
+            raw_putchar(c);
+            break;
+    }
 }
diff --git a/stage23/menu.c b/stage23/menu.c
index f30fc181..29716268 100644
--- a/stage23/menu.c
+++ b/stage23/menu.c
@@ -416,11 +416,12 @@ refresh:
     if (skip_timeout == false) {
         print("\n\n");
         for (int i = timeout; i; i--) {
-            print("\rBooting automatically in %u, press any key to stop the countdown...", i);
+            print("\e[2K\rBooting automatically in %u, press any key to stop the countdown...", i);
             term_double_buffer_flush();
             if ((c = pit_sleep_and_quit_on_keypress(1))) {
                 skip_timeout = true;
                 print("\e[2K\r\e[2A");
+                term_double_buffer_flush();
                 goto timeout_aborted;
             }
         }
tab: 248 wrap: offon