aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-02-25 23:16:05 -0500
committerIan Moffett <ian@osmora.org>2024-02-25 23:16:05 -0500
commitcc595a73cf45ee8b0f0444b844b10bc021d02572 (patch)
tree36fe8c084d1eec983dcdbddec4dffe83f4e0d92a
parent042899885e610554e28cb673a1b0b10cc8b93ea7 (diff)
kernel: vcons: Add cursor support
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/dev/vcons/vcons.c78
-rw-r--r--sys/dev/vcons/vcons_io.c8
-rw-r--r--sys/include/dev/vcons/vcons.h1
3 files changed, 75 insertions, 12 deletions
diff --git a/sys/dev/vcons/vcons.c b/sys/dev/vcons/vcons.c
index 4858110..1c69cf3 100644
--- a/sys/dev/vcons/vcons.c
+++ b/sys/dev/vcons/vcons.c
@@ -39,12 +39,33 @@ __KERNEL_META("$Hyra$: kern_vcons.c, Ian Marco Moffett, "
"Hyra video console code");
/* Get x or y values in pixels */
-#define PIX_CPY_X(scrptr) (scr->cpy_x * FONT_WIDTH)
-#define PIX_CPY_Y(scrptr) (scr->cpy_y * FONT_HEIGHT)
+#define PIX_CPY_X(scrptr) ((scrptr)->cpy_x * FONT_WIDTH)
+#define PIX_CPY_Y(scrptr) ((scrptr)->cpy_y * FONT_HEIGHT)
static struct vcons_screen *screen = NULL;
static void
+vcons_draw_cursor(struct vcons_screen *scr, uint32_t color)
+{
+ struct vcons_cursor *cursor = &scr->cursor;
+ struct fbdev fbdev = scr->fbdev;
+
+ uint32_t *fbdev_mem = fbdev.mem;
+ uint32_t fbdev_idx = 0;
+ uint32_t cx, cy;
+
+ for (size_t y = VCONS_CURSOR_HEIGHT; y > 0; --y) {
+ for (size_t x = VCONS_CURSOR_WIDTH; x > 0; --x) {
+ cx = cursor->old_xpos + x;
+ cy = cursor->old_ypos + y;
+
+ fbdev_idx = fbdev_get_index(&fbdev, cx, cy);
+ fbdev_mem[fbdev_idx] = color;
+ }
+ }
+}
+
+static void
vcons_clear_scr(struct vcons_screen *scr)
{
struct fbdev fbdev = scr->fbdev;
@@ -52,6 +73,7 @@ vcons_clear_scr(struct vcons_screen *scr)
scr->cpy_x = 0, scr->cpy_y = 0;
memset(scr->fbdev_mem, scr->bg, (fbdev.pitch * fbdev.height));
+ vcons_update_cursor(scr);
}
/*
@@ -80,11 +102,35 @@ vcons_draw_char(struct vcons_screen *scr, char c, uint32_t x, uint32_t y)
}
}
+void
+vcons_update_cursor(struct vcons_screen *scr)
+{
+ struct vcons_cursor *cursor = &scr->cursor;
+
+ cursor->is_drawing = true;
+
+ if (cursor->is_drawn) {
+ /* Clear old cursor */
+ vcons_draw_cursor(scr, scr->bg);
+ }
+
+ cursor->old_xpos = cursor->xpos;
+ cursor->old_ypos = cursor->ypos;
+ vcons_draw_cursor(scr, scr->fg);
+
+ cursor->is_drawn = true;
+ cursor->is_drawing = false;
+}
+
int
vcons_putch(struct vcons_screen *scr, char c)
{
uint32_t x = PIX_CPY_X(scr);
uint32_t y = PIX_CPY_Y(scr);
+ struct vcons_cursor *cursor = &scr->cursor;
+ bool cursor_newline = false;
+
+ while (cursor->is_drawing);
if (scr == NULL) {
return 1;
@@ -95,25 +141,35 @@ vcons_putch(struct vcons_screen *scr, char c)
return 0;
}
- /*
- * Check text bounds
- *
- * We must subtract ncols,nrows by FONT_WIDTH,FONT_HEIGHT
- * as each char is of that width,height and we need to account for
- * that.
- */
- if (x >= (scr->ncols - FONT_WIDTH)) {
+ /* Check cursor bounds */
+ if (cursor->xpos >= PIX_BOUNDS_MAX_X(scr)) {
+ cursor->xpos = FONT_WIDTH;
+ cursor->ypos += FONT_HEIGHT;
+ cursor_newline = true;
+ }
+ if (cursor->ypos >= PIX_BOUNDS_MAX_Y(scr)) {
+ cursor->xpos = FONT_WIDTH;
+ cursor->ypos = 0;
+ }
+
+ /* Check text bounds */
+ if (x >= PIX_BOUNDS_MAX_X(scr)) {
/* Wrap to the next row */
++scr->cpy_y, scr->cpy_x = 0;
x = PIX_CPY_X(scr), y = PIX_CPY_Y(scr);
}
- if (y >= (scr->nrows - FONT_HEIGHT)) {
+ if (y >= PIX_BOUNDS_MAX_Y(scr)) {
scr->cpy_y = 0;
scr->cpy_x = 0;
vcons_clear_scr(scr);
x = PIX_CPY_X(scr), y = PIX_CPY_Y(scr);
}
+ if (!cursor_newline) {
+ cursor->xpos += FONT_WIDTH;
+ }
+
+ vcons_update_cursor(scr);
vcons_draw_char(scr, c, x, y);
++scr->cpy_x;
return 0;
diff --git a/sys/dev/vcons/vcons_io.c b/sys/dev/vcons/vcons_io.c
index 569cce6..a3d6042 100644
--- a/sys/dev/vcons/vcons_io.c
+++ b/sys/dev/vcons/vcons_io.c
@@ -53,15 +53,20 @@ int
vcons_process_output(struct vcons_screen *scr, int c)
{
struct termios termios = scr->termios;
+ struct vcons_cursor *cursor = &scr->cursor;
switch (c) {
case ASCII_LF:
- if (__TEST(termios.c_oflag, OCRNL))
+ if (__TEST(termios.c_oflag, OCRNL)) {
scr->cpy_x = 0;
+ cursor->xpos = 0;
+ }
scr->cpy_y++;
+ cursor->ypos += FONT_HEIGHT;
break;
case ASCII_CR:
scr->cpy_x = 0;
+ cursor->xpos = 0;
break;
case ASCII_HT:
vcons_expand_tab(scr);
@@ -70,5 +75,6 @@ vcons_process_output(struct vcons_screen *scr, int c)
return -1;
}
+ vcons_update_cursor(scr);
return c;
}
diff --git a/sys/include/dev/vcons/vcons.h b/sys/include/dev/vcons/vcons.h
index fc59f6e..737651f 100644
--- a/sys/include/dev/vcons/vcons.h
+++ b/sys/include/dev/vcons/vcons.h
@@ -67,5 +67,6 @@ struct vcons_screen {
void vcons_attach(struct vcons_screen *scr);
int vcons_putch(struct vcons_screen *scr, char c);
+void vcons_update_cursor(struct vcons_screen *scr);
#endif /* !_DEV_VCONS_H_ */