about summary refs log blame commit diff stats
path: root/kernel.soso/tty.c
blob: 9e53c339f6ad779baecf09d3cf8fc13fb3d2fe47 (plain) (tree)
1
2
3
4


                  
                                                                                            























                                                                 
                           




                                       
                                                                 


                                                   
                       





                              
                             




                                                

                                                               









                                                                                           
                                                       




                                     
                          


                                        
                                                             







                              
                                    

                                        
                                 


                               
                                                     






                                                                  

                                     







                                                                                                 

                                           











                                                                                                     
                                                 



                               
                                                 













                                                                            
                                              
                         
                




                             
                                                           


                                
#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;
}