diff options
author | Ian Moffett <ian@osmora.org> | 2024-02-25 22:28:09 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-02-25 22:30:15 -0500 |
commit | d4372855f00cb47ccfa60db79c5ee35c17f96707 (patch) | |
tree | 6efffc5617fc4c66a38d2e41a7990ddd7534c922 /sys | |
parent | 752ae0d0c23d1edf9b2ce563c4e82283dffd273a (diff) |
kernel: Move video console code
This commit introduces a video console driver to Hyra and replaces
that weird tty.c file used only for video console logic
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/vcons/vcons.c | 133 | ||||
-rw-r--r-- | sys/dev/vcons/vcons_io.c | 74 | ||||
-rw-r--r-- | sys/include/dev/vcons/vcons.h | 71 | ||||
-rw-r--r-- | sys/include/dev/vcons/vcons_io.h (renamed from sys/kern/subr_tty.c) | 30 | ||||
-rw-r--r-- | sys/include/lib/sysfont.h (renamed from sys/include/lib/tty_font.h) | 0 | ||||
-rw-r--r-- | sys/include/sys/tty.h | 121 | ||||
-rw-r--r-- | sys/kern/kern_syslog.c | 27 | ||||
-rw-r--r-- | sys/kern/tty.c | 382 | ||||
-rw-r--r-- | sys/lib/sysfont.c (renamed from sys/lib/tty_font.c) | 2 |
9 files changed, 297 insertions, 543 deletions
diff --git a/sys/dev/vcons/vcons.c b/sys/dev/vcons/vcons.c new file mode 100644 index 0000000..622c7ae --- /dev/null +++ b/sys/dev/vcons/vcons.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <dev/vcons/vcons.h> +#include <dev/vcons/vcons_io.h> +#include <dev/video/fbdev.h> +#include <sys/syslog.h> +#include <sys/cdefs.h> +#include <string.h> + +__MODULE_NAME("kern_vcons"); +__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) + +static struct vcons_screen *screen = NULL; + +static void +vcons_clear_scr(struct vcons_screen *scr) +{ + struct fbdev fbdev = scr->fbdev; + + scr->cpy_x = 0, scr->cpy_y = 0; + + memset(scr->fbdev_mem, scr->bg, (fbdev.pitch * fbdev.height)); +} + +/* + * Renders a char onto the screen specified by `scr`. + * + * @x,y: In chars + */ +static void +vcons_draw_char(struct vcons_screen *scr, char c, uint32_t x, uint32_t y) +{ + uint32_t *fb_ptr; + size_t idx; + const uint8_t *glyph; + + /* Get a pointer to framebuffer memory */ + fb_ptr = scr->fbdev_mem; + + /* Get the specific glyph of `c` */ + glyph = &DEFAULT_FONT_DATA[(int)c*16]; + + 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); + fb_ptr[idx] = __TEST(glyph[cy], __BIT(cx)) ? scr->fg : scr->bg; + } + } +} + +int +vcons_putch(struct vcons_screen *scr, char c) +{ + uint32_t x = PIX_CPY_X(scr); + uint32_t y = PIX_CPY_Y(scr); + + if (scr == NULL) { + return 1; + } + + if (vcons_process_output(scr, c) >= 0) { + /* No need to do anything */ + return 0; + } + + /* + * Check text bounds + * + * We must subtract ncols,nrows by FONT_WIDTH,FONT_HEIGHT + * as each char is of that width and we need to account for + * that. + */ + if (x >= (scr->ncols - FONT_WIDTH)) { + /* 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)) { + scr->cpy_y = 0; + scr->cpy_x = 0; + vcons_clear_scr(scr); + x = PIX_CPY_X(scr), y = PIX_CPY_Y(scr); + } + + vcons_draw_char(scr, c, x, y); + ++scr->cpy_x; + return 0; +} + +void +vcons_attach(struct vcons_screen *scr) +{ + scr->fbdev = fbdev_get_front(); + scr->fbdev_mem = scr->fbdev.mem; + + scr->nrows = scr->fbdev.height; + scr->ncols = scr->fbdev.width; + + screen = scr; + vcons_clear_scr(scr); +} diff --git a/sys/dev/vcons/vcons_io.c b/sys/dev/vcons/vcons_io.c new file mode 100644 index 0000000..569cce6 --- /dev/null +++ b/sys/dev/vcons/vcons_io.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <dev/vcons/vcons_io.h> +#include <dev/vcons/vcons.h> +#include <sys/cdefs.h> +#include <sys/ascii.h> + +static void +vcons_expand_tab(struct vcons_screen *scr) +{ + for (size_t i = 0; i < VCONS_TAB_WIDTH; ++i) { + vcons_putch(scr, ' '); + } +} + +/* + * This routine tries to process the output `c'. + * + * Returns < 0 value on failure. Values >= 0 + * is `c' which may differ from the original. + * + * This routine also may modify the screen state + * if `c' is a control character. + */ +int +vcons_process_output(struct vcons_screen *scr, int c) +{ + struct termios termios = scr->termios; + + switch (c) { + case ASCII_LF: + if (__TEST(termios.c_oflag, OCRNL)) + scr->cpy_x = 0; + scr->cpy_y++; + break; + case ASCII_CR: + scr->cpy_x = 0; + break; + case ASCII_HT: + vcons_expand_tab(scr); + break; + default: + return -1; + } + + return c; +} diff --git a/sys/include/dev/vcons/vcons.h b/sys/include/dev/vcons/vcons.h new file mode 100644 index 0000000..fc59f6e --- /dev/null +++ b/sys/include/dev/vcons/vcons.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _DEV_VCONS_H_ +#define _DEV_VCONS_H_ + +#include <sys/types.h> +#include <sys/termios.h> +#include <dev/video/fbdev.h> +#include <sysfont.h> + +#define VCONS_TAB_WIDTH 4 +#define VCONS_CURSOR_WIDTH FONT_WIDTH +#define VCONS_CURSOR_HEIGHT FONT_HEIGHT + +struct vcons_cursor { + size_t xpos, ypos; + uint32_t rgb; + + /* Internal */ + uint32_t old_xpos, old_ypos; + volatile bool is_drawing; + volatile bool is_drawn; /* If it has been drawn before */ +}; + +struct vcons_screen { + size_t nrows, ncols; + size_t cpy_x, cpy_y; /* In chars */ + size_t cpy_len; + + uint32_t bg; + uint32_t fg; + void *fbdev_mem; + + struct fbdev fbdev; + struct vcons_cursor cursor; + struct termios termios; +}; + +#define is_cursor_drawing(screenptr) (screenptr)->cursor.is_drawing + +void vcons_attach(struct vcons_screen *scr); +int vcons_putch(struct vcons_screen *scr, char c); + +#endif /* !_DEV_VCONS_H_ */ diff --git a/sys/kern/subr_tty.c b/sys/include/dev/vcons/vcons_io.h index 43a02bb..a75d811 100644 --- a/sys/kern/subr_tty.c +++ b/sys/include/dev/vcons/vcons_io.h @@ -27,31 +27,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/tty.h> +#ifndef _VCONS_IO_H_ +#define _VCONS_IO_H_ -/* - * Pushes a char to the TTY - * ring buffer. - * - * Call with TTY locked. - */ -void -tty_push_char(struct tty *tty, int c) -{ - struct tty_ring *ring; - - ring = &tty->ring; +#include <dev/vcons/vcons.h> - /* - * If our ring is full, it should - * be flushed as soon as possible. - * - * XXX: ring->len will be reset by tty_flush() - * so there is no need to do it here. - */ - if (ring->len >= LINE_RING_SIZE) { - tty_flush(tty); - } +int vcons_process_output(struct vcons_screen *scr, int c); - ring->buf[ring->len++] = c; -} +#endif /* !_VCONS_IO_H_ */ diff --git a/sys/include/lib/tty_font.h b/sys/include/lib/sysfont.h index 62b4ec0..62b4ec0 100644 --- a/sys/include/lib/tty_font.h +++ b/sys/include/lib/sysfont.h diff --git a/sys/include/sys/tty.h b/sys/include/sys/tty.h deleted file mode 100644 index f245966..0000000 --- a/sys/include/sys/tty.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SYS_TTY_H_ -#define _SYS_TTY_H_ - -#include <sys/types.h> -#include <sys/termios.h> -#include <sys/queue.h> -#include <sys/cdefs.h> -#include <sys/spinlock.h> -#include <dev/video/fbdev.h> - -/* - * Max chars an entire line can hold: - * 2^9 => 512 bytes - */ -#define LINE_RING_SIZE __POW2(9) - -/* Default TTY tab width */ -#define DEFAULT_TAB_WIDTH 4 - -/* - * Describes the size - * of a TTY window. - */ -struct winsize { - uint16_t ws_row; /* Rows, in chars */ - uint16_t ws_col; /* Columns, in chars */ - uint16_t ws_xpixel; /* Horizontal size, in pixels */ - uint16_t ws_ypixel; /* Vertical size, in pixels */ -}; - -/* - * TTY ring buffer. - */ -struct tty_ring { - char buf[LINE_RING_SIZE]; /* Actual buffer */ - size_t len; -}; - -/* - * Describes a TTY. Each TTY - * shall be described by a - * `struct tty`. - */ -struct tty { - uint32_t chpos_x; /* Next char X position */ - uint32_t chpos_y; /* Next char Y position */ - uint32_t curspos_x; /* Cursor X position */ - uint32_t curspos_y; /* Cursor Y position */ - uint32_t fg; /* Foreground (hex color) */ - uint32_t bg; /* Background (hex color) */ - uint8_t tab_width; /* Width of a tab (in chars) */ - struct fbdev fbdev; /* Framebuffer device */ - struct termios termios; /* Termios state */ - struct winsize winsize; /* Window size */ - struct tty_ring ring; /* Ring buffer */ - struct spinlock lock; /* Protects TTY */ - TAILQ_ENTRY(tty) link; /* TTY list link */ -}; - -/* - * Some helper macros to facilitate - * locking/unlocking a TTY. - */ -#define TTY_LOCK(tty_ptr) spinlock_acquire(&(tty_ptr)->lock) -#define TTY_UNLOCK(tty_ptr) spinlock_release(&(tty_ptr)->lock) - -/* - * Macros to allow easy access for - * termios and winsize flags, e.g usage: - * - * struct tty *tty = ... - * tty->t_cflag = ... - */ -#define t_cflag termios.c_cflag -#define t_iflag termios.c_iflag -#define t_lflag termios.c_lflag -#define t_oflag termios.c_oflag -#define t_ispeed termios.c_ispeed -#define t_ospeed termios.c_ospeed -#define t_ws_row winsize.ws_row -#define t_ws_col winsize.ws_col -#define t_ws_xpixel winsize.ws_xpixel -#define t_ws_ypixel winsize.ws_ypixel - -void tty_push_char(struct tty *tty, int c); -void tty_flush(struct tty *tty); -ssize_t tty_write(struct tty *tty, const char *buf, size_t len); -void tty_set_defaults(struct tty *tty); -void tty_attach(struct tty *tty); -void tty_init(void); - -#endif /* !_SYS_TTY_H_ */ diff --git a/sys/kern/kern_syslog.c b/sys/kern/kern_syslog.c index 52bdcca..d8880a9 100644 --- a/sys/kern/kern_syslog.c +++ b/sys/kern/kern_syslog.c @@ -28,29 +28,23 @@ */ #include <sys/syslog.h> -#include <sys/tty.h> #include <sys/machdep.h> +#include <dev/vcons/vcons.h> #include <string.h> -static struct tty syslog_tty; - -/* False if we don't log to a console */ -static bool is_conlog_init = false; +static struct vcons_screen syslog_screen = {0}; static void syslog_write(const char *s, size_t len) { -#if defined(__SERIAL_DEBUG) size_t tmp_len = len; const char *tmp_s = s; while (tmp_len--) { - serial_dbgch(*tmp_s++); - } +#if defined(__SERIAL_DEBUG) + serial_dbgch(*tmp_s); #endif /* defined(__SERIAL_DEBUG) */ - - if (is_conlog_init) { - tty_write(&syslog_tty, s, len); + vcons_putch(&syslog_screen, *tmp_s++); } } @@ -131,8 +125,13 @@ kprintf(const char *fmt, ...) void syslog_init(void) { - is_conlog_init = true; + struct termios termios = {0}; + + termios.c_oflag |= OCRNL; /* Map CR to NL by default */ + + syslog_screen.bg = 0x000000; + syslog_screen.fg = 0x808080; + syslog_screen.termios = termios; - tty_set_defaults(&syslog_tty); - tty_attach(&syslog_tty); + vcons_attach(&syslog_screen); } diff --git a/sys/kern/tty.c b/sys/kern/tty.c deleted file mode 100644 index 3a959a9..0000000 --- a/sys/kern/tty.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/tty.h> -#include <sys/cdefs.h> -#include <sys/errno.h> -#include <sys/ascii.h> -#include <string.h> -#include <tty_font.h> - -/* - * Default cursor color. - * - * TODO: The cursor color should - * be the invert of the color - * of whatever it is on top of. - */ -#define DEFAULT_CURSOR_BG 0x808080 - -#define CURSOR_WIDTH FONT_WIDTH -#define CURSOR_HEIGHT FONT_HEIGHT - -__KERNEL_META("$Hyra$: tty.c, Ian Marco Moffett, " - "Core TTY implementation"); - -/* List of attached TTYs */ -static TAILQ_HEAD(, tty) tty_list; - -/* - * Renders a char onto the TTY specified by `tty`. - */ -static void -tty_draw_char(struct tty *tty, char c, uint32_t fg, uint32_t bg) -{ - uint32_t *fb_ptr; - uint32_t x, y; - size_t idx; - const uint8_t *glyph; - - /* Get a pointer to framebuffer memory */ - fb_ptr = tty->fbdev.mem; - - /* Get the specific glyph of `c` */ - glyph = &DEFAULT_FONT_DATA[(int)c*16]; - - x = tty->chpos_x; - y = tty->chpos_y; - - for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) { - for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) { - idx = fbdev_get_index(&tty->fbdev, x+FONT_WIDTH-cx, y+cy); - fb_ptr[idx] = __TEST(glyph[cy], __BIT(cx)) ? fg : bg; - } - } -} - -/* - * Draws a cursor onto the screen. - * - * Call with TTY locked. - */ -static void -tty_draw_cursor(struct tty *tty, bool hide) -{ - uint32_t x, y, idx; - uint32_t *fb_ptr; - uint32_t color; - - fb_ptr = tty->fbdev.mem; - color = hide ? tty->bg : DEFAULT_CURSOR_BG; - - for (size_t cy = 0; cy < CURSOR_HEIGHT; ++cy) { - for (size_t cx = 0; cx < CURSOR_WIDTH; ++cx) { - x = tty->curspos_x + cx; - y = tty->curspos_y + cy; - idx = fbdev_get_index(&tty->fbdev, x, y); - fb_ptr[idx] = color; - } - } -} - -static void -tty_scroll_single(struct tty *tty) -{ - uint32_t *fb_ptr; - size_t line_size, dest_idx, src_idx; - - fb_ptr = tty->fbdev.mem; - line_size = tty->fbdev.pitch/4; - - /* Copy each line up */ - for (size_t y = FONT_HEIGHT; y < tty->t_ws_ypixel; y += FONT_HEIGHT) { - dest_idx = fbdev_get_index(&tty->fbdev, 0, y - FONT_HEIGHT); - src_idx = fbdev_get_index(&tty->fbdev, 0, y); - memcpy32(&fb_ptr[dest_idx], &fb_ptr[src_idx], FONT_HEIGHT*line_size); - } - - /* - * Ensure we start at X position 0 - * after we scrolled down. - */ - tty->chpos_x = 0; - tty->curspos_x = 0; -} - -/* - * Handles a newline. - * - * Call with TTY locked. - */ -static inline void -tty_newline(struct tty *tty) -{ - uint32_t ypos; - const uint32_t MAX_YPOS = tty->t_ws_ypixel - (CURSOR_HEIGHT*2); - - /* Hide the cursor */ - tty_draw_cursor(tty, true); - - /* Reset X positions */ - tty->chpos_x = 0; - tty->curspos_x = 0; - - /* - * Get the value closest to end - * of the screen. - */ - ypos = __MAX(tty->chpos_y, tty->curspos_y); - - /* - * Check if we need to scroll - * instead of incrementing - * Y positions. - */ - if (ypos < MAX_YPOS) { - tty->chpos_y += FONT_HEIGHT; - tty->curspos_y += FONT_HEIGHT; - } else { - tty_scroll_single(tty); - } - - /* Redraw the cursor */ - tty_draw_cursor(tty, false); -} - -/* - * Appends a character to the TTY specified - * by `tty` as well as incrementing tty->chpos_x - * and making newlines as needed. - * - * Call with TTY locked. - */ -static inline void -tty_append_char(struct tty *tty, int c) -{ - const uint32_t MAX_XPOS = tty->t_ws_xpixel - FONT_WIDTH; - - /* Hide the cursor */ - tty_draw_cursor(tty, true); - - tty_draw_char(tty, c, tty->fg, tty->bg); - tty->chpos_x += FONT_WIDTH; - tty->curspos_x += FONT_WIDTH; - - if (tty->chpos_x >= MAX_XPOS) { - tty_newline(tty); - } - - /* Redraw the cursor */ - tty_draw_cursor(tty, false); -} - -/* - * Writes out a tab as `tty->tab_width` - * spaces. - * - * Call with TTY locked. - */ -static void -tty_expand_tab(struct tty *tty) -{ - for (size_t i = 0; i < tty->tab_width; ++i) { - tty_append_char(tty, ' '); - } -} - -/* - * Writes a char to the TTY. - * - * Returns 0 on success; non-zero value - * is a character to be resent. - * - * Call with TTY locked. - */ -static int -tty_putch(struct tty *tty, int c) -{ - if (!__TEST(tty->t_oflag, OPOST)) { - /* - * Just write out the char with - * no processing. - */ - tty_append_char(tty, c); - return 0; - } - - switch (c) { - case ASCII_HT: - /* Tab */ - tty_expand_tab(tty); - break; - case ASCII_LF: - /* Line feed ('\n') */ - tty_newline(tty); - break; - default: - tty_append_char(tty, c); - break; - } - - return 0; -} - -/* - * Flushes a TTY specified by `tty`. - * - * Call with TTY locked. - */ -void -tty_flush(struct tty *tty) -{ - struct tty_ring *ring; - - ring = &tty->ring; - - /* - * Write each byte from the buffer - * to the screen with output processing - * if possible. - * - * XXX: Perhaps there could be a faster - * way of doing this instead of - * byte by byte? - */ - for (size_t i = 0; i < ring->len; ++i) { - tty_putch(tty, ring->buf[i]); - } - - ring->len = 0; -} - -/* - * Writes to a TTY specified by `tty`. - * - * @buf: Buffer to write. - * @len: Length of buffer. - * - * Returns number of bytes written, and - * EXIT_FAILURE on error. - */ -ssize_t -tty_write(struct tty *tty, const char *buf, size_t len) -{ - if (len == 0) { - /* Bad value, don't even try */ - return EXIT_FAILURE; - } - - TTY_LOCK(tty); - for (size_t i = 0; i < len; ++i) { - tty_push_char(tty, buf[i]); - /* - * If we have a newline and we are - * buffering bytes, flush the ring. - */ - if (buf[i] == '\n' && __TEST(tty->t_oflag, ORBUF)) { - tty_flush(tty); - } - } - - /* - * If we aren't buffering bytes, don't - * keep the bytes within the ring and - * flush it right away per `tty_write()` - * call. - */ - if (!__TEST(tty->t_oflag, ORBUF)) { - tty_flush(tty); - } - - TTY_UNLOCK(tty); - return len; -} - -/* - * Sets TTY fields to their defaults. - */ -void -tty_set_defaults(struct tty *tty) -{ - /* Ensure everything is initially zero */ - memset(tty, 0, sizeof(*tty)); - - /* - * Now, initialize everything to their defaults. - * - * Some notes about the default framebuffer device: - * ------------------------------------------------ - * The default framebuffer device should be the - * front buffer. Later on during boot, all attached - * TTYs shall have their fbdev swapped out with a - * backbuffer to improve performace as reading directly - * from video memory is going to be slow. - * - * XXX: At some point we should be allocating a backbuffer - * instead when it's time for *all* TTYs to have them. - * - * A good idea would be to only allocate a backbuffer - * *if* we switched to some TTY and deallocate - * that backbuffer when switching away from that TTY. - * - * The first thing that comes to mind when thinking - * about this idea is loosing our text when we switch - * back out. To rectify this, we could buffer chars - * which would take less memory than keeping the whole - * backbuffer (holds pixels i.e uint32_t). - * - * This can perhaps be done by some internal flag which - * indicates that kmalloc() is usable and chars can - * be buffered. Once we switch back, just allocate - * a new backbuffer and copy the chars back. - */ - tty->fbdev = fbdev_get_front(); - tty->t_oflag = (OPOST | ORBUF); - tty->tab_width = DEFAULT_TAB_WIDTH; - tty->fg = 0x808080; - tty->bg = 0x000000; - tty->t_ws_xpixel = tty->fbdev.width; - tty->t_ws_ypixel = tty->fbdev.height; - tty->t_ws_row = tty->fbdev.height / FONT_HEIGHT; - tty->t_ws_col = tty->fbdev.width / FONT_WIDTH; - -} - -void -tty_attach(struct tty *tty) -{ - TAILQ_INSERT_TAIL(&tty_list, tty, link); - tty_draw_cursor(tty, false); -} - -void -tty_init(void) -{ - TAILQ_INIT(&tty_list); /* Ensure the TTY list is usable */ -} diff --git a/sys/lib/tty_font.c b/sys/lib/sysfont.c index a5a8c89..e5ae2aa 100644 --- a/sys/lib/tty_font.c +++ b/sys/lib/sysfont.c @@ -27,7 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <lib/tty_font.h> +#include <lib/sysfont.h> const uint8_t DEFAULT_FONT_DATA[] = { |