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) {
