From 6ff4b38d6378f36dc11acd6bee4c676f41462cc1 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Tue, 9 Jul 2024 02:09:07 -0400 Subject: kernel: cons: Improve char handling and add cursor Signed-off-by: Ian Moffett --- sys/dev/cons/cons.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) (limited to 'sys/dev/cons/cons.c') diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c index 4c83c62..bf03469 100644 --- a/sys/dev/cons/cons.c +++ b/sys/dev/cons/cons.c @@ -33,10 +33,30 @@ #include #include #include +#include #include struct cons_screen g_root_scr = {0}; +/* + * Create a chracter descriptor for drawing + * characters. + * + * @c: Character. + * @fg: Foreground. + * @bg: Background. + */ +static inline struct cons_char +cons_make_char(char c, uint32_t fg, uint32_t bg) +{ + struct cons_char ch; + + ch.fg = fg; + ch.bg = bg; + ch.c = c; + return ch; +} + /* * Render a character onto the screen. * @@ -46,8 +66,10 @@ struct cons_screen g_root_scr = {0}; * @y: Y position of char. */ static void -cons_render_char(struct cons_screen *scr, char c, uint32_t x, uint32_t y) +cons_render_char(struct cons_screen *scr, struct cons_char ch, + uint32_t x, uint32_t y) { + char c = ch.c; size_t idx; const uint8_t *glyph; @@ -59,11 +81,32 @@ cons_render_char(struct cons_screen *scr, char c, uint32_t x, uint32_t y) for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) { for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) { idx = fbdev_get_index(&scr->fbdev, x+FONT_WIDTH-cx, y+cy); - scr->fb_mem[idx] = ISSET(glyph[cy], BIT(cx)) ? scr->fg : scr->bg; + scr->fb_mem[idx] = ISSET(glyph[cy], BIT(cx)) ? ch.fg : ch.bg; } } } +static void +cons_draw_cursor(struct cons_screen *scr, uint32_t color) +{ + struct cons_char cursor_chr; + + cursor_chr.fg = scr->fg; + cursor_chr.bg = color; + cursor_chr.c = ' '; + cons_render_char(scr, cursor_chr, scr->curs_col * FONT_WIDTH, + scr->curs_row * FONT_HEIGHT); +} + +static void +cons_move_cursor(struct cons_screen *scr, uint32_t col, uint32_t row) +{ + cons_draw_cursor(scr, scr->bg); + scr->curs_col = col; + scr->curs_row = row; + cons_draw_cursor(scr, scr->last_chr.fg); +} + /* * Clear the screen. * @@ -96,6 +139,7 @@ cons_handle_special(struct cons_screen *scr, char c) /* Make a newline */ scr->ch_col = 0; ++scr->ch_row; + cons_move_cursor(scr, 0, scr->curs_row + 1); return 0; } @@ -112,17 +156,20 @@ cons_handle_special(struct cons_screen *scr, char c) int cons_putch(struct cons_screen *scr, char c) { + struct cons_char cons_chr; + if (scr->ch_col > scr->ncols) { /* Make a newline as we past the max col */ scr->ch_col = 0; ++scr->ch_row; } - if (scr->ch_row > scr->nrows) { + if (scr->curs_row >= scr->nrows) { /* Went over the screen size */ scr->ch_col = 0; scr->ch_row = 0; cons_clear_scr(scr, scr->bg); + cons_move_cursor(scr, 0, 0); } /* @@ -133,7 +180,12 @@ cons_putch(struct cons_screen *scr, char c) return 0; } - cons_render_char(scr, c, scr->ch_col * FONT_WIDTH, + cons_chr = cons_make_char(c, scr->fg, scr->bg); + scr->last_chr = cons_chr; + + /* Draw cursor and character */ + cons_move_cursor(scr, scr->curs_col + 1, scr->curs_row); + cons_render_char(scr, cons_chr, scr->ch_col * FONT_WIDTH, scr->ch_row * FONT_HEIGHT); ++scr->ch_col; -- cgit v1.2.3