:: commit dc47b83c16788bb437093c3d3ce887ac2bc547af

mintsuki <mintsuki@protonmail.com> — 2021-06-07 22:06

parents: abf1d90515

term: Fix various cursor-related issues

diff --git a/stage23/drivers/vga_textmode.h b/stage23/drivers/vga_textmode.h
index cf22d936..5c5d98ff 100644
--- a/stage23/drivers/vga_textmode.h
+++ b/stage23/drivers/vga_textmode.h
@@ -8,7 +8,7 @@ void init_vga_textmode(int *rows, int *cols, bool managed);
 void text_putchar(uint8_t c);
 void text_clear(bool move);
 void text_enable_cursor(void);
-void text_disable_cursor(void);
+bool text_disable_cursor(void);
 void text_set_cursor_pos(int x, int y);
 void text_get_cursor_pos(int *x, int *y);
 void text_set_text_fg(int fg);
diff --git a/stage23/drivers/vga_textmode.s2.c b/stage23/drivers/vga_textmode.s2.c
index a359961d..e002d4b4 100644
--- a/stage23/drivers/vga_textmode.s2.c
+++ b/stage23/drivers/vga_textmode.s2.c
@@ -67,10 +67,11 @@ void text_enable_cursor(void) {
     return;
 }
 
-void text_disable_cursor(void) {
+bool text_disable_cursor(void) {
+    bool ret = cursor_status != 0;
     cursor_status = 0;
     clear_cursor();
-    return;
+    return ret;
 }
 
 void init_vga_textmode(int *_rows, int *_cols, bool managed) {
diff --git a/stage23/lib/gterm.c b/stage23/lib/gterm.c
index e68b19db..254d0216 100644
--- a/stage23/lib/gterm.c
+++ b/stage23/lib/gterm.c
@@ -173,6 +173,20 @@ void gterm_plot_char(struct gterm_char *c, int x, int y) {
     }
 }
 
+static void plot_char_grid_force(struct gterm_char *c, int x, int y) {
+    uint32_t new_char[VGA_FONT_WIDTH * VGA_FONT_HEIGHT];
+    plot_char_mem(new_char, c,
+                  x * VGA_FONT_WIDTH + frame_width, y * VGA_FONT_HEIGHT + frame_height);
+
+    for (int i = 0; i < VGA_FONT_HEIGHT; i++) {
+        for (int j = 0; j < VGA_FONT_WIDTH; j++) {
+            gterm_plot_px(x * VGA_FONT_WIDTH + frame_width + j,
+                          y * VGA_FONT_HEIGHT + frame_height + i,
+                          new_char[i * VGA_FONT_WIDTH + j]);
+        }
+    }
+}
+
 static void plot_char_grid(struct gterm_char *c, int x, int y) {
     uint32_t old_char[VGA_FONT_WIDTH * VGA_FONT_HEIGHT];
     uint32_t new_char[VGA_FONT_WIDTH * VGA_FONT_HEIGHT];
@@ -197,10 +211,10 @@ static void plot_char_grid(struct gterm_char *c, int x, int y) {
 }
 
 static void clear_cursor(void) {
-    struct gterm_char c = grid[cursor_x + cursor_y * cols];
-    c.fg = 9;
-    c.bg = 8;
-    plot_char_grid(&c, cursor_x, cursor_y);
+    if (cursor_status) {
+        struct gterm_char c = grid[cursor_x + cursor_y * cols];
+        plot_char_grid_force(&c, cursor_x, cursor_y);
+    }
 }
 
 static void draw_cursor(void) {
@@ -208,7 +222,7 @@ static void draw_cursor(void) {
         struct gterm_char c = grid[cursor_x + cursor_y * cols];
         c.fg = 0;
         c.bg = 7;
-        plot_char_grid(&c, cursor_x, cursor_y);
+        plot_char_grid_force(&c, cursor_x, cursor_y);
     }
 }
 
@@ -261,9 +275,11 @@ void gterm_enable_cursor(void) {
     draw_cursor();
 }
 
-void gterm_disable_cursor(void) {
+bool gterm_disable_cursor(void) {
+    bool ret = cursor_status;
     clear_cursor();
     cursor_status = false;
+    return ret;
 }
 
 void gterm_set_cursor_pos(int x, int y) {
@@ -301,6 +317,8 @@ void gterm_double_buffer_flush(void) {
         gterm_plot_char(&grid[i], x * VGA_FONT_WIDTH + frame_width,
                                 y * VGA_FONT_HEIGHT + frame_height);
     }
+
+    draw_cursor();
 }
 
 void gterm_double_buffer(bool state) {
@@ -310,12 +328,8 @@ void gterm_double_buffer(bool state) {
         gterm_clear(true);
         gterm_double_buffer_flush();
     } else {
-        bool pcs = cursor_status;
-        cursor_status = false;
         gterm_clear(true);
         gterm_double_buffer_flush();
-        cursor_status = pcs;
-        draw_cursor();
         double_buffer_enabled = false;
     }
 }
diff --git a/stage23/lib/gterm.h b/stage23/lib/gterm.h
index 5ccfc8e2..9e8f7311 100644
--- a/stage23/lib/gterm.h
+++ b/stage23/lib/gterm.h
@@ -13,7 +13,7 @@ bool gterm_init(int *_rows, int *_cols, int width, int height);
 void gterm_putchar(uint8_t c);
 void gterm_clear(bool move);
 void gterm_enable_cursor(void);
-void gterm_disable_cursor(void);
+bool gterm_disable_cursor(void);
 void gterm_set_cursor_pos(int x, int y);
 void gterm_get_cursor_pos(int *x, int *y);
 void gterm_set_text_fg(int fg);
diff --git a/stage23/lib/term.h b/stage23/lib/term.h
index b1a2a9ac..6b0b19ec 100644
--- a/stage23/lib/term.h
+++ b/stage23/lib/term.h
@@ -8,7 +8,7 @@
 extern void (*raw_putchar)(uint8_t c);
 extern void (*clear)(bool move);
 extern void (*enable_cursor)(void);
-extern void (*disable_cursor)(void);
+extern bool (*disable_cursor)(void);
 extern void (*set_cursor_pos)(int x, int y);
 extern void (*get_cursor_pos)(int *x, int *y);
 extern void (*set_text_fg)(int fg);
diff --git a/stage23/lib/term.s2.c b/stage23/lib/term.s2.c
index 5701d2a0..64311f2b 100644
--- a/stage23/lib/term.s2.c
+++ b/stage23/lib/term.s2.c
@@ -20,7 +20,7 @@ int term_backend = NOT_READY;
 void (*raw_putchar)(uint8_t c);
 void (*clear)(bool move);
 void (*enable_cursor)(void);
-void (*disable_cursor)(void);
+bool (*disable_cursor)(void);
 void (*set_cursor_pos)(int x, int y);
 void (*get_cursor_pos)(int *x, int *y);
 void (*set_text_fg)(int fg);
@@ -62,8 +62,11 @@ static void term_putchar(uint8_t c);
 void term_write(const char *buf, size_t count) {
     if (term_backend == NOT_READY)
         return;
+    bool old_cur_stat = disable_cursor();
     for (size_t i = 0; i < count; i++)
         term_putchar(buf[i]);
+    if (old_cur_stat)
+        enable_cursor();
 }
 
 static int get_cursor_pos_x(void) {
tab: 248 wrap: offon