169 lines
3.9 KiB
C
169 lines
3.9 KiB
C
#include "vxBoot/terminal.h"
|
|
|
|
#include <gint/display.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
//---
|
|
// 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);
|
|
}
|
|
}
|
|
}
|