diff options
Diffstat (limited to 'tools/iso/kernel.soso/tty.c')
-rw-r--r-- | tools/iso/kernel.soso/tty.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/tools/iso/kernel.soso/tty.c b/tools/iso/kernel.soso/tty.c new file mode 100644 index 00000000..9e53c339 --- /dev/null +++ b/tools/iso/kernel.soso/tty.c @@ -0,0 +1,153 @@ +#include "tty.h" +#include "alloc.h" + +Tty* createTty(uint16 lineCount, uint16 columnCount, TtyFlushScreenFunction flushFunction) { + Tty* tty = kmalloc(sizeof(Tty)); + memset((uint8*)tty, 0, sizeof(Tty)); + + tty->lineCount = lineCount; + tty->columnCount = columnCount; + tty->buffer = kmalloc(tty->lineCount * tty->columnCount * 2); + tty->currentColumn = 0; + tty->currentLine = 0; + tty->color = 0x0A; + + memset(tty->lineBuffer, 0, TTY_LINEBUFFER_SIZE); + tty->lineBufferIndex = 0; + tty->keyBuffer = FifoBuffer_create(64); + tty->flushScreen = flushFunction; + + tty->term.c_cc[VMIN] = 1; + tty->term.c_lflag |= ECHO; + tty->term.c_lflag |= ICANON; + + Tty_Clear(tty); + + return tty; +} + +void destroyTty(Tty* tty) { + FifoBuffer_destroy(tty->keyBuffer); + kfree(tty->buffer); + kfree(tty); +} + +void Tty_Print(Tty* tty, int row, int column, const char* text) { + unsigned char * video = tty->buffer; + + video += (row * tty->columnCount + column) * 2; + while(*text != 0) { + *video++ = *text++; + *video++ = tty->color; + } +} + +//One line +void Tty_ScrollUp(Tty* tty) { + unsigned char * videoLine = tty->buffer; + unsigned char * videoLineNext = tty->buffer; + int line = 0; + int column = 0; + + for (line = 0; line < tty->lineCount - 1; ++line) { + for (column = 0; column < tty->columnCount; ++column) { + videoLine = tty->buffer + (line * tty->columnCount + column) * 2; + videoLineNext = tty->buffer + ((line + 1) * tty->columnCount + column) * 2; + + videoLine[0] = videoLineNext[0]; + videoLine[1] = videoLineNext[1]; + } + } + + //Last line should be empty. + unsigned char * lastLine = tty->buffer + ((tty->lineCount - 1) * tty->columnCount) * 2; + for (int i = 0; i < tty->columnCount * 2; i += 2) { + lastLine[i] = 0; + lastLine[i + 1] = tty->color; + } +} + +void Tty_Clear(Tty* tty) { + unsigned char * video = tty->buffer; + int i = 0; + + for (i = 0; i < tty->lineCount * tty->columnCount; ++i) { + *video++ = 0; + *video++ = tty->color; + } + + tty->currentLine = 0; + tty->currentColumn = 0; +} + +void Tty_PutChar(Tty* tty, char c) { + unsigned char * video = tty->buffer; + + if ('\n' == c || '\r' == c) { + ++tty->currentLine; + tty->currentColumn = 0; + + if (tty->currentLine >= tty->lineCount - 0) { + --tty->currentLine; + Tty_ScrollUp(tty); + } + + Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn); + return; + } + else if ('\b' == c) { + if (tty->currentColumn > 0) { + --tty->currentColumn; + c = '\0'; + video = tty->buffer + (tty->currentLine * tty->columnCount + tty->currentColumn) * 2; + video[0] = c; + video[1] = tty->color; + Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn); + return; + } + else if (tty->currentColumn == 0) { + if (tty->currentLine > 0) { + --tty->currentLine; + tty->currentColumn = tty->columnCount - 1; + c = '\0'; + video = tty->buffer + (tty->currentLine * tty->columnCount + tty->currentColumn) * 2; + video[0] = c; + video[1] = tty->color; + Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn); + return; + } + } + } + + if (tty->currentColumn >= tty->columnCount) { + ++tty->currentLine; + tty->currentColumn = 0; + } + + if (tty->currentLine >= tty->lineCount - 0) { + --tty->currentLine; + Tty_ScrollUp(tty); + } + + video += (tty->currentLine * tty->columnCount + tty->currentColumn) * 2; + + video[0] = c; + video[1] = tty->color; + + ++tty->currentColumn; + + Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn); +} + +void Tty_PutText(Tty* tty, const char* text) { + const char* c = text; + while (*c) { + Tty_PutChar(tty, *c); + ++c; + } +} + +void Tty_MoveCursor(Tty* tty, uint16 line, uint16 column) { + tty->currentLine = line; + tty->currentColumn = column; +} |