Kernel: TTY now handles keeping terminal buffer
VESA Driver cannot scroll anymore, this is handled by tty
This commit is contained in:
parent
f7eb85babd
commit
2535eb1c4c
|
@ -36,12 +36,8 @@ TTY::TTY()
|
||||||
|
|
||||||
void TTY::Clear()
|
void TTY::Clear()
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < m_width * m_height; i++)
|
for (size_t i = 0; i < m_width * m_height; i++)
|
||||||
{
|
m_buffer[i] = { .foreground = m_foreground, .background = m_background, .character = ' ' };
|
||||||
m_buffer[i].foreground = m_foreground;
|
|
||||||
m_buffer[i].background = m_background;
|
|
||||||
m_buffer[i].character = ' ';
|
|
||||||
}
|
|
||||||
VESA::Clear(m_background);
|
VESA::Clear(m_background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +244,15 @@ void TTY::HandleAnsiEscape(uint16_t ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTY::PutCharAt(uint16_t ch, size_t x, size_t y)
|
||||||
|
{
|
||||||
|
auto& cell = m_buffer[y * m_width + x];
|
||||||
|
cell.character = ch;
|
||||||
|
cell.foreground = m_foreground;
|
||||||
|
cell.background = m_background;
|
||||||
|
VESA::PutEntryAt(ch, x, y, m_foreground, m_background);
|
||||||
|
}
|
||||||
|
|
||||||
void TTY::PutChar(char ch)
|
void TTY::PutChar(char ch)
|
||||||
{
|
{
|
||||||
uint16_t cp = handle_unicode(ch);
|
uint16_t cp = handle_unicode(ch);
|
||||||
|
@ -285,7 +290,7 @@ void TTY::PutChar(char ch)
|
||||||
m_ansi_state.mode = '\1';
|
m_ansi_state.mode = '\1';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
VESA::PutEntryAt(cp, m_column, m_row, m_foreground, m_background);
|
PutCharAt(cp, m_column, m_row);
|
||||||
m_column++;
|
m_column++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -298,9 +303,18 @@ void TTY::PutChar(char ch)
|
||||||
|
|
||||||
while (m_row >= m_height)
|
while (m_row >= m_height)
|
||||||
{
|
{
|
||||||
VESA::Scroll();
|
// Shift buffer one line up
|
||||||
|
for (size_t y = 1; y < m_height; y++)
|
||||||
for (size_t x = 0; x < m_width; x++)
|
for (size_t x = 0; x < m_width; x++)
|
||||||
VESA::PutEntryAt(' ', x, m_height - 1, m_foreground, m_background);
|
m_buffer[(y - 1) * m_width + x] = m_buffer[y * m_width + x];
|
||||||
|
// Clear last line in buffer
|
||||||
|
for (size_t x = 0; x < m_width; x++)
|
||||||
|
m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .character = ' ' };
|
||||||
|
|
||||||
|
// Render the whole buffer to the screen
|
||||||
|
for (size_t y = 0; y < m_height; y++)
|
||||||
|
for (size_t x = 0; x < m_width; x++)
|
||||||
|
RenderFromBuffer(x, y);
|
||||||
|
|
||||||
m_column = 0;
|
m_column = 0;
|
||||||
m_row--;
|
m_row--;
|
||||||
|
@ -332,6 +346,31 @@ void TTY::PutCharCurrent(char ch)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
static size_t x = 0;
|
||||||
|
static size_t y = 0;
|
||||||
|
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
VESA::PutEntryAt(ch, x, y, VESA::Color::BRIGHT_WHITE, VESA::Color::BLACK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++x == VESA::GetTerminalWidth())
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y == VESA::GetTerminalHeight())
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
VESA::Clear(VESA::Color::BLACK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ extern const struct bitmap_font font;
|
||||||
|
|
||||||
namespace VESA
|
namespace VESA
|
||||||
{
|
{
|
||||||
static void* s_buffer = nullptr;
|
|
||||||
static void* s_addr = nullptr;
|
static void* s_addr = nullptr;
|
||||||
static uint8_t s_bpp = 0;
|
static uint8_t s_bpp = 0;
|
||||||
static uint32_t s_pitch = 0;
|
static uint32_t s_pitch = 0;
|
||||||
|
@ -28,11 +28,9 @@ namespace VESA
|
||||||
|
|
||||||
static void GraphicsPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg);
|
static void GraphicsPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg);
|
||||||
static void GraphicsClear(Color color);
|
static void GraphicsClear(Color color);
|
||||||
static void GraphicsScroll();
|
|
||||||
|
|
||||||
static void TextPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg);
|
static void TextPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg);
|
||||||
static void TextClear(Color color);
|
static void TextClear(Color color);
|
||||||
static void TextScroll();
|
|
||||||
|
|
||||||
void PutEntryAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg)
|
void PutEntryAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg)
|
||||||
{
|
{
|
||||||
|
@ -54,14 +52,6 @@ namespace VESA
|
||||||
return TextClear(color);
|
return TextClear(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scroll()
|
|
||||||
{
|
|
||||||
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
|
||||||
return GraphicsScroll();
|
|
||||||
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
|
||||||
return TextScroll();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GetTerminalWidth()
|
uint32_t GetTerminalWidth()
|
||||||
{
|
{
|
||||||
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||||
|
@ -138,24 +128,6 @@ namespace VESA
|
||||||
static void GraphicsSetPixel(uint32_t offset, uint32_t color)
|
static void GraphicsSetPixel(uint32_t offset, uint32_t color)
|
||||||
{
|
{
|
||||||
uint32_t* address = (uint32_t*)((uint32_t)s_addr + offset);
|
uint32_t* address = (uint32_t*)((uint32_t)s_addr + offset);
|
||||||
|
|
||||||
if (s_buffer)
|
|
||||||
{
|
|
||||||
uint32_t* buffer = (uint32_t*)((uint32_t)s_buffer + offset);
|
|
||||||
switch (s_bpp)
|
|
||||||
{
|
|
||||||
case 24:
|
|
||||||
*buffer = (*buffer & 0xFF000000) | (color & 0x00FFFFFF);
|
|
||||||
*address = *buffer;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
*buffer = color;
|
|
||||||
*address = color;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (s_bpp)
|
switch (s_bpp)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
|
@ -166,7 +138,6 @@ namespace VESA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void GraphicsPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg)
|
static void GraphicsPutCharAt(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg)
|
||||||
{
|
{
|
||||||
|
@ -214,10 +185,6 @@ namespace VESA
|
||||||
for (uint32_t y = 0; y < s_height; y++)
|
for (uint32_t y = 0; y < s_height; y++)
|
||||||
for (uint32_t x = 0; x < s_width; x++)
|
for (uint32_t x = 0; x < s_width; x++)
|
||||||
((uint32_t*)s_addr)[y * bytes_per_row + x] = u32_color;
|
((uint32_t*)s_addr)[y * bytes_per_row + x] = u32_color;
|
||||||
if (s_buffer)
|
|
||||||
for (uint32_t y = 0; y < s_height; y++)
|
|
||||||
for (uint32_t x = 0; x < s_width; x++)
|
|
||||||
((uint32_t*)s_buffer)[y * bytes_per_row + x] = u32_color;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,52 +201,6 @@ namespace VESA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GraphicsScroll()
|
|
||||||
{
|
|
||||||
if (s_bpp == 32)
|
|
||||||
{
|
|
||||||
uint32_t bytes_per_row = s_pitch / 4;
|
|
||||||
for (uint32_t y = 0; y < s_height - font.Height; y++)
|
|
||||||
{
|
|
||||||
for (uint32_t x = 0; x < s_width; x++)
|
|
||||||
{
|
|
||||||
if (s_buffer)
|
|
||||||
{
|
|
||||||
((uint32_t*)s_buffer)[y * bytes_per_row + x] = ((uint32_t*)s_buffer)[(y + font.Height) * bytes_per_row + x];
|
|
||||||
((uint32_t*)s_addr )[y * bytes_per_row + x] = ((uint32_t*)s_buffer)[(y + font.Height) * bytes_per_row + x];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
((uint32_t*)s_addr )[y * bytes_per_row + x] = ((uint32_t*)s_addr )[(y + font.Height) * bytes_per_row + x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t row_offset_out = 0;
|
|
||||||
uint32_t row_offset_in = font.Height * s_pitch;
|
|
||||||
|
|
||||||
for (uint32_t y = 0; y < s_height - 1; y++)
|
|
||||||
{
|
|
||||||
if (s_buffer)
|
|
||||||
{
|
|
||||||
memcpy((void*)((uint32_t)s_buffer + row_offset_out), (void*)((uint32_t)s_buffer + row_offset_in), s_width * s_bpp);
|
|
||||||
memcpy((void*)((uint32_t)s_addr + row_offset_out), (void*)((uint32_t)s_buffer + row_offset_in), s_width * s_bpp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy((void*)((uint32_t)s_addr + row_offset_out), (void*)((uint32_t)s_addr + row_offset_in), s_width * s_bpp);
|
|
||||||
}
|
|
||||||
row_offset_out += s_pitch;
|
|
||||||
row_offset_in += s_pitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint8_t TextColor(Color fg, Color bg)
|
static inline uint8_t TextColor(Color fg, Color bg)
|
||||||
{
|
{
|
||||||
return (((uint8_t)bg & 0x0F) << 4) | ((uint8_t)fg & 0x0F);
|
return (((uint8_t)bg & 0x0F) << 4) | ((uint8_t)fg & 0x0F);
|
||||||
|
@ -303,17 +224,4 @@ namespace VESA
|
||||||
TextPutCharAt(' ', x, y, Color::BRIGHT_WHITE, color);
|
TextPutCharAt(' ', x, y, Color::BRIGHT_WHITE, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TextScroll()
|
|
||||||
{
|
|
||||||
for (uint32_t y = 1; y < s_height; y++)
|
|
||||||
{
|
|
||||||
for (uint32_t x = 0; x < s_width; x++)
|
|
||||||
{
|
|
||||||
uint32_t index1 = (y - 0) * s_width + x;
|
|
||||||
uint32_t index2 = (y - 1) * s_width + x;
|
|
||||||
((uint16_t*)s_addr)[index2] = ((uint16_t*)s_addr)[index1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,13 +19,19 @@ private:
|
||||||
void ResetAnsiEscape();
|
void ResetAnsiEscape();
|
||||||
void HandleAnsiSGR();
|
void HandleAnsiSGR();
|
||||||
void HandleAnsiEscape(uint16_t ch);
|
void HandleAnsiEscape(uint16_t ch);
|
||||||
|
void PutCharAt(uint16_t ch, size_t x, size_t y);
|
||||||
|
inline void RenderFromBuffer(size_t x, size_t y)
|
||||||
|
{
|
||||||
|
const auto& cell = m_buffer[y * m_width + x];
|
||||||
|
VESA::PutEntryAt(cell.character, x, y, cell.foreground, cell.background);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Cell
|
struct Cell
|
||||||
{
|
{
|
||||||
VESA::Color foreground = VESA::Color::BRIGHT_WHITE;
|
VESA::Color foreground = VESA::Color::BRIGHT_WHITE;
|
||||||
VESA::Color background = VESA::Color::BLACK;
|
VESA::Color background = VESA::Color::BLACK;
|
||||||
uint8_t character = ' ';
|
uint16_t character = ' ';
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnsiState
|
struct AnsiState
|
||||||
|
|
|
@ -28,7 +28,6 @@ namespace VESA
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
void PutEntryAt(uint16_t, uint32_t, uint32_t, Color, Color);
|
void PutEntryAt(uint16_t, uint32_t, uint32_t, Color, Color);
|
||||||
void Clear(Color);
|
void Clear(Color);
|
||||||
void Scroll();
|
|
||||||
|
|
||||||
uint32_t GetTerminalWidth();
|
uint32_t GetTerminalWidth();
|
||||||
uint32_t GetTerminalHeight();
|
uint32_t GetTerminalHeight();
|
||||||
|
|
Loading…
Reference in New Issue