aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/cons/cons.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cons/cons.c')
-rw-r--r--sys/dev/cons/cons.c60
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;