diff options
author | Ian Moffett <ian@osmora.org> | 2024-07-09 02:09:07 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-07-09 02:09:07 -0400 |
commit | 6ff4b38d6378f36dc11acd6bee4c676f41462cc1 (patch) | |
tree | 116cd973bb315146cb927e5975422e3b2af24561 /sys/dev/cons/cons.c | |
parent | 54c9c5246e28a8a3d586a5f7346e38648ef2b3f9 (diff) |
kernel: cons: Improve char handling and add cursor
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/dev/cons/cons.c')
-rw-r--r-- | sys/dev/cons/cons.c | 60 |
1 files changed, 56 insertions, 4 deletions
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,11 +33,31 @@ #include <dev/video/fbdev.h> #include <dev/cons/font.h> #include <dev/cons/cons.h> +#include <vm/dynalloc.h> #include <string.h> 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. * * @scr: Screen to render to. @@ -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; |