diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/cons/cons.c | 60 | ||||
-rw-r--r-- | sys/include/dev/cons/cons.h | 9 |
2 files changed, 65 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; diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h index 15a7f59..337b738 100644 --- a/sys/include/dev/cons/cons.h +++ b/sys/include/dev/cons/cons.h @@ -33,6 +33,12 @@ #include <sys/types.h> #include <dev/video/fbdev.h> +struct cons_char { + char c; + uint32_t fg; + uint32_t bg; +}; + struct cons_screen { struct fbdev fbdev; uint32_t fg; @@ -44,6 +50,9 @@ struct cons_screen { uint32_t ncols; uint32_t ch_col; /* Current col */ uint32_t ch_row; /* Current row */ + uint32_t curs_col; /* Cursor col */ + uint32_t curs_row; /* Cursor row */ + struct cons_char last_chr; }; void cons_init(void); |