#include "vxBoot/terminal.h" #include #include //--- // Update the internal buffer //--- /* terminal_buffer_insert() : insert string anywhere in the output buffer */ void terminal_buffer_insert(char *buffer, size_t nb) { size_t dump; void *start; /* calculate the "real" number of byte to dump into the buffer */ dump = nb; start = &buffer[0]; if (dump > terminal.buffer.size) { dump -= terminal.buffer.size; start = &buffer[nb - dump]; } /* dump the buffer (be carful with the circular effect) */ if (terminal.buffer.cursor + dump > terminal.buffer.size) { memcpy( &terminal.buffer.data[terminal.buffer.cursor], start, terminal.buffer.size - terminal.buffer.cursor ); dump -= terminal.buffer.size - terminal.buffer.cursor; terminal.buffer.cursor = 0; } memcpy(&terminal.buffer.data[terminal.buffer.cursor], start, dump); terminal.buffer.cursor += dump; } //--- // Display the internal buffer //--- /* terminal_vertical_update() - Update vertical cursor */ static void terminal_vertical_update(void) { if (terminal.cursor.y + 1 < terminal.winsize.ws_col) { terminal.cursor.y = terminal.cursor.y + 1; return; } } /* earlyterm_horizontal_update() - Update horizotal cursor */ static int terminal_horizontal_update(void) { terminal.cursor.x = terminal.cursor.x + 1; if (terminal.cursor.x >= terminal.winsize.ws_col) { terminal_vertical_update(); terminal.cursor.x = 0; return (1); } return (0); } /* line_discipline() - Check "special" char */ static int terminal_line_discipline(char n) { int offset; switch (n) { case '\0': return (1); case '\n': terminal.cursor.x = 0; terminal_vertical_update(); return (1); case '\b': if (terminal.cursor.x > 0) terminal.cursor.x = terminal.cursor.x - 1; return (1); case '\v': terminal_vertical_update(); return (1); case '\r': terminal.cursor.x = 0; return (1); case '\t': /* Check if we need a new line or not. */ offset = terminal.cursor.x - ((terminal.cursor.x / 5) * 5); offset = 5 - offset; while (--offset >= 0) terminal_horizontal_update(); return (1); default: return (0); } } /* terminal_buffer_write() : display the buffer on screen */ void terminal_buffer_display(void) { uint8_t *buffer; uint16_t tmp; int cursor; int x; int y; int i; /* Due to potential special char, we sould find the "real" starting index for the internal buffer */ terminal.cursor.x = 0; terminal.cursor.y = 0; i = terminal.buffer.cursor - 1; buffer = &terminal.buffer.data[0]; while (1) { /* decrease the cursor and avoid circular effect */ if (--i < 0) i = terminal.buffer.size - 1; /* check loop condition */ if (i == (int)terminal.buffer.cursor) break; /* check EOL */ if (buffer[i] == '\0') { break; } /* handle the character (only to force update cursors) */ if (terminal_line_discipline(buffer[i] & 0x7f) == 0) terminal_horizontal_update(); if (terminal.cursor.y >= terminal.winsize.ws_row) break; } /* Display character per character because we need to check special behaviour (like cariege return, line feed, ...) */ terminal.cursor.x = 0; terminal.cursor.y = 0; while (1) { /* update the index */ if (++i >= (int)terminal.buffer.size) i = 0; if (i == (int)terminal.buffer.cursor) break; /* get the cursor and remove the potential cursor marker */ cursor = ((buffer[i] & 0x80) != 0); buffer[i] &= 0x7f; /* display part (character + cursor if needed) */ x = terminal.cursor.x * terminal.winsize.ft_xpixel; y = terminal.cursor.y * terminal.winsize.ft_ypixel; if (terminal_line_discipline(buffer[i]) == 0) { tmp = buffer[i] << 8; dtext(x, y, terminal.private.color.fg, (void*)&tmp); terminal_horizontal_update(); } if (cursor != 0) { dline(x, y + terminal.winsize.ft_ypixel, x + terminal.winsize.ft_xpixel - 2, y + terminal.winsize.ft_ypixel, terminal.private.color.fg); } } }