Add console backspace bold and underline support.

Combine textbuffer char and attr concepts while here.
This commit is contained in:
Jonas 'Sortie' Termansen 2015-10-04 18:55:06 +02:00
parent 9297ff2a20
commit 8f233b4a10
9 changed files with 111 additions and 140 deletions

View File

@ -35,6 +35,10 @@
namespace Sortix {
static const uint16_t ATTR_CHAR = 1 << 0;
static const uint16_t ATTR_BOLD = 1 << 1;
static const uint16_t ATTR_UNDERLINE = 1 << 2;
struct TextPos
{
TextPos() { }
@ -47,16 +51,20 @@ struct TextCharPOD
{
wchar_t c;
uint8_t vgacolor; // Format of <sortix/vga.h>
uint16_t attr;
};
struct TextChar
{
TextChar() { }
TextChar(const TextCharPOD& o) : c(o.c), vgacolor(o.vgacolor) { }
TextChar(wchar_t c, uint8_t vgacolor) : c(c), vgacolor(vgacolor) { }
operator TextCharPOD() { return TextCharPOD{c, vgacolor}; }
TextChar(const TextCharPOD& o) :
c(o.c), vgacolor(o.vgacolor), attr(o.attr) { }
TextChar(wchar_t c, uint8_t vgacolor, uint16_t attr) :
c(c), vgacolor(vgacolor), attr(attr) { }
operator TextCharPOD() { return TextCharPOD{c, vgacolor, attr}; }
wchar_t c;
uint8_t vgacolor; // Format of <sortix/vga.h>
uint16_t attr;
};
static inline bool IsTextPosBeforeTextPos(const TextPos& a, const TextPos& b)
@ -77,12 +85,9 @@ public:
virtual size_t Height() const = 0;
virtual TextChar GetChar(TextPos pos) const = 0;
virtual void SetChar(TextPos pos, TextChar c) = 0;
virtual uint16_t GetCharAttr(TextPos pos) const = 0;
virtual void SetCharAttr(TextPos pos, uint16_t attr) = 0;
virtual void Scroll(ssize_t off, TextChar fillwith) = 0;
virtual void Move(TextPos to, TextPos from, size_t numchars) = 0;
virtual void Fill(TextPos from, TextPos to, TextChar fillwith,
uint16_t fillattr) = 0;
virtual void Fill(TextPos from, TextPos to, TextChar fillwith) = 0;
virtual bool GetCursorEnabled() const = 0;
virtual void SetCursorEnabled(bool enablecursor) = 0;
virtual TextPos GetCursorPos() const = 0;

View File

@ -63,7 +63,6 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
uint8_t* backbuf;
uint8_t* font;
TextChar* chars;
uint16_t* attrs;
TextBufferCmd* queue;
LFBTextBuffer* ret;
@ -75,10 +74,8 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
goto cleanup_backbuf;
if ( !(chars = new TextChar[columns * rows]) )
goto cleanup_font;
if ( !(attrs = new uint16_t[columns * rows]) )
goto cleanup_chars;
if ( !(queue = new TextBufferCmd[QUEUE_LENGTH]) )
goto cleanup_attrs;
goto cleanup_chars;
if ( !(ret = new LFBTextBuffer) )
goto cleanup_queue;
@ -108,8 +105,6 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
ret->font = font;
memset(chars, 0, sizeof(chars[0]) * columns * rows);
ret->chars = chars;
memset(attrs, 0, sizeof(attrs[0]) * columns * rows);
ret->attrs = attrs;
for ( size_t i = 0; i < 16UL; i++ )
{
uint8_t r = i & 0b0100 ? (i & 0b1000 ? 255 : 191) : (i & 0b1000 ? 63 : 0);
@ -135,8 +130,6 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
cleanup_queue:
delete[] queue;
cleanup_attrs:
delete[] attrs;
cleanup_chars:
delete[] chars;
cleanup_font:
@ -176,7 +169,6 @@ LFBTextBuffer::~LFBTextBuffer()
delete[] backbuf;
delete[] font;
delete[] chars;
delete[] attrs;
delete[] queue;
}
@ -220,6 +212,8 @@ void LFBTextBuffer::RenderChar(TextChar textchar, size_t posx, size_t posy)
return;
bool drawcursor = cursorenabled && posx == cursorpos.x && posy == cursorpos.y;
uint8_t fgcoloridx = textchar.vgacolor >> 0 & 0x0F;
if ( textchar.attr & ATTR_BOLD )
fgcoloridx |= 0x08;
uint8_t bgcoloridx = textchar.vgacolor >> 4 & 0x0F;
uint32_t fgcolor = colors[fgcoloridx];
uint32_t bgcolor = colors[bgcoloridx];
@ -259,9 +253,10 @@ void LFBTextBuffer::RenderChar(TextChar textchar, size_t posx, size_t posy)
}
}
}
if ( likely(!drawcursor) )
if ( likely(!drawcursor) && !(textchar.attr & ATTR_UNDERLINE) )
return;
for ( size_t y = VGA_FONT_HEIGHT - 2; y < VGA_FONT_HEIGHT; y++ )
size_t underlines = VGA_FONT_HEIGHT - (!drawcursor ? 1 : 0);
for ( size_t y = VGA_FONT_HEIGHT - 2; y < underlines; y++ )
{
size_t pixely = posy * VGA_FONT_HEIGHT + y;
for ( size_t x = 0; x < VGA_FONT_WIDTH+1; x++ )
@ -378,7 +373,7 @@ TextChar LFBTextBuffer::GetChar(TextPos pos) const
((LFBTextBuffer*) this)->ResumeRendering();
return ret;
}
return {0, 0};
return {0, 0, 0};
}
void LFBTextBuffer::SetChar(TextPos pos, TextChar c)
@ -393,30 +388,6 @@ void LFBTextBuffer::SetChar(TextPos pos, TextChar c)
IssueCommand(&cmd);
}
uint16_t LFBTextBuffer::GetCharAttr(TextPos pos) const
{
if ( UsablePosition(pos) )
{
((LFBTextBuffer*) this)->StopRendering();
uint16_t ret = attrs[pos.y * columns + pos.x];
((LFBTextBuffer*) this)->ResumeRendering();
return ret;
}
return 0;
}
void LFBTextBuffer::SetCharAttr(TextPos pos, uint16_t attrval)
{
if ( !UsablePosition(pos) )
return;
TextBufferCmd cmd;
cmd.type = TEXTBUFCMD_ATTR;
cmd.x = pos.x;
cmd.y = pos.y;
cmd.attr = attrval;
IssueCommand(&cmd);
}
bool LFBTextBuffer::GetCursorEnabled() const
{
((LFBTextBuffer*) this)->StopRendering();
@ -485,8 +456,7 @@ void LFBTextBuffer::Move(TextPos to, TextPos from, size_t numchars)
IssueCommand(&cmd);
}
void LFBTextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith,
uint16_t fillattr)
void LFBTextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith)
{
from = CropPosition(from);
to = CropPosition(to);
@ -497,7 +467,6 @@ void LFBTextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith,
cmd.to_x = to.x;
cmd.to_y = to.y;
cmd.c = fillwith;
cmd.attr = fillattr;
IssueCommand(&cmd);
}
@ -513,7 +482,7 @@ void LFBTextBuffer::DoScroll(ssize_t off, TextChar entry)
TextPos fillto = neg ? TextPos{columns-1, rows-1} : TextPos{columns-1, absoff-1};
size_t scrollchars = columns * (rows-absoff);
DoMove(scrollto, scrollfrom, scrollchars);
DoFill(fillfrom, fillto, entry, 0);
DoFill(fillfrom, fillto, entry);
}
void LFBTextBuffer::DoMove(TextPos to, TextPos from, size_t numchars)
@ -522,22 +491,18 @@ void LFBTextBuffer::DoMove(TextPos to, TextPos from, size_t numchars)
size_t src = OffsetOfPos(from);
if ( dest < src )
for ( size_t i = 0; i < numchars; i++ )
chars[dest + i] = chars[src + i],
attrs[dest + i] = attrs[src + i];
chars[dest + i] = chars[src + i];
else if ( src < dest )
for ( size_t i = 0; i < numchars; i++ )
chars[dest + numchars-1 - i] = chars[src + numchars-1 - i],
attrs[dest + numchars-1 - i] = attrs[src + numchars-1 - i];
chars[dest + numchars-1 - i] = chars[src + numchars-1 - i];
}
void LFBTextBuffer::DoFill(TextPos from, TextPos to, TextChar fillwith,
uint16_t fillattr)
void LFBTextBuffer::DoFill(TextPos from, TextPos to, TextChar fillwith)
{
size_t start = OffsetOfPos(from);
size_t end = OffsetOfPos(to);
for ( size_t i = start; i <= end; i++ )
chars[i] = fillwith,
attrs[i] = fillattr;
chars[i] = fillwith;
}
bool LFBTextBuffer::IsCommandIdempotent(const TextBufferCmd* cmd) const
@ -548,7 +513,6 @@ bool LFBTextBuffer::IsCommandIdempotent(const TextBufferCmd* cmd) const
case TEXTBUFCMD_SYNC: return true;
case TEXTBUFCMD_PAUSE: return true;
case TEXTBUFCMD_CHAR: return true;
case TEXTBUFCMD_ATTR: return true;
case TEXTBUFCMD_CURSOR_SET_ENABLED: return true;
case TEXTBUFCMD_CURSOR_MOVE: return true;
case TEXTBUFCMD_MOVE: return false;
@ -586,11 +550,6 @@ void LFBTextBuffer::ExecuteCommand(TextBufferCmd* cmd,
if ( IsTextPosAfterTextPos(pos, render_to) )
render_to = pos;
} break;
case TEXTBUFCMD_ATTR:
{
TextPos pos(cmd->x, cmd->y);
attrs[pos.y * columns + pos.x] = cmd->attr;
} break;
case TEXTBUFCMD_CURSOR_SET_ENABLED:
if ( cmd->b != cursorenabled )
{
@ -633,7 +592,7 @@ void LFBTextBuffer::ExecuteCommand(TextBufferCmd* cmd,
{
TextPos from(cmd->from_x, cmd->from_y);
TextPos to(cmd->to_x, cmd->to_y);
DoFill(from, to, cmd->c, cmd->attr);
DoFill(from, to, cmd->c);
if ( IsTextPosBeforeTextPos(from, render_from) )
render_from = from;
if ( IsTextPosAfterTextPos(to, render_to) )
@ -778,7 +737,7 @@ void LFBTextBuffer::EmergencyReset()
{
// TODO: Reset everything here!
Fill(TextPos{0, 0}, TextPos{columns-1, rows-1}, TextChar{0, 0}, 0);
Fill(TextPos{0, 0}, TextPos{columns-1, rows-1}, TextChar{0, 0, 0});
SetCursorPos(TextPos{0, 0});
}

View File

@ -36,7 +36,6 @@ enum TextBufferCmdType
TEXTBUFCMD_SYNC,
TEXTBUFCMD_PAUSE,
TEXTBUFCMD_CHAR,
TEXTBUFCMD_ATTR,
TEXTBUFCMD_CURSOR_SET_ENABLED,
TEXTBUFCMD_CURSOR_MOVE,
TEXTBUFCMD_MOVE,
@ -55,7 +54,7 @@ struct TextBufferCmd
union
{
bool b;
struct { TextCharPOD c; uint16_t attr; };
TextCharPOD c;
size_t val;
};
};
@ -74,12 +73,9 @@ public:
virtual size_t Height() const;
virtual TextChar GetChar(TextPos pos) const;
virtual void SetChar(TextPos pos, TextChar c);
virtual uint16_t GetCharAttr(TextPos pos) const;
virtual void SetCharAttr(TextPos pos, uint16_t attrval);
virtual void Scroll(ssize_t off, TextChar fillwith);
virtual void Move(TextPos to, TextPos from, size_t numchars);
virtual void Fill(TextPos from, TextPos to, TextChar fillwith,
uint16_t fillattr);
virtual void Fill(TextPos from, TextPos to, TextChar fillwith);
virtual bool GetCursorEnabled() const;
virtual void SetCursorEnabled(bool enablecursor);
virtual TextPos GetCursorPos() const;
@ -104,7 +100,7 @@ private:
TextPos AddToPosition(TextPos pos, size_t count);
void DoScroll(ssize_t off, TextChar entry);
void DoMove(TextPos to, TextPos from, size_t numchars);
void DoFill(TextPos from, TextPos to, TextChar fillwith, uint16_t fillattr);
void DoFill(TextPos from, TextPos to, TextChar fillwith);
void IssueCommand(TextBufferCmd* cmd);
void StopRendering();
void ResumeRendering();
@ -135,7 +131,6 @@ private:
uint8_t* backbuf;
uint8_t* font;
TextChar* chars;
uint16_t* attrs;
size_t columns;
size_t rows;
size_t pixelsx;

View File

@ -176,12 +176,10 @@ void Init(multiboot_info_t* bootinfo)
uint16_t* const VGAFB = (uint16_t*) 0xB8000;
const size_t VGA_WIDTH = 80;
const size_t VGA_HEIGHT = 25;
uint16_t* vga_attr_buffer = new uint16_t[VGA_WIDTH * VGA_HEIGHT];
TextChar* vga_chars_buffer = new TextChar[VGA_WIDTH * VGA_HEIGHT];
if ( !vga_attr_buffer || !vga_chars_buffer )
if ( !vga_chars_buffer )
Panic(oom_msg);
textbuf = new VGATextBuffer(VGAFB, vga_chars_buffer, vga_attr_buffer,
VGA_WIDTH, VGA_HEIGHT);
textbuf = new VGATextBuffer(VGAFB, vga_chars_buffer, VGA_WIDTH, VGA_HEIGHT);
if ( !textbuf )
Panic(oom_msg);
}

View File

@ -228,7 +228,7 @@ void LogTerminal::ProcessKeystroke(int kbkey)
(!wasuni || termmode & TERMMODE_UNICODE) &&
termmode & TERMMODE_ECHO &&
wasuni )
Log::Print("\b");
Log::Print("\b \b");
goto c_w_delete_more;
}
@ -243,7 +243,7 @@ void LogTerminal::ProcessKeystroke(int kbkey)
(!wasuni || termmode & TERMMODE_UNICODE) &&
termmode & TERMMODE_ECHO &&
wasuni )
Log::Print("\b");
Log::Print("\b \b");
}
return;
}
@ -289,7 +289,7 @@ void LogTerminal::QueueUnicode(uint32_t unicode)
if ( waskbkey && !kbkeymode ) { continue; }
if ( wasuni && !unicodemode ) { continue; }
if ( !echomode ) { return; }
if ( wasuni ) { Log::Print("\b"); }
if ( wasuni ) { Log::Print("\b \b"); }
return;
}
@ -308,7 +308,10 @@ void LogTerminal::QueueUnicode(uint32_t unicode)
memset(&ps, 0, sizeof(ps));
char utf8buf[MB_CUR_MAX];
size_t num_bytes = wcrtomb(utf8buf, (wchar_t) unicode, &ps);
Log::PrintData(utf8buf, num_bytes);
if ( num_bytes == 1 && utf8buf[0] == '\b' )
Log::PrintData("\b \b", 3);
else
Log::PrintData(utf8buf, num_bytes);
}
bool commit = !linemode || wasenter;

View File

@ -36,8 +36,7 @@
namespace Sortix {
const uint16_t DEFAULT_COLOR = COLOR8_LIGHT_GREY << 0U | COLOR8_BLACK << 4U;
const uint16_t ATTR_CHAR = 1U << 0U;
static const uint16_t DEFAULT_COLOR = COLOR8_LIGHT_GREY | COLOR8_BLACK << 4;
TextTerminal::TextTerminal(TextBufferHandle* textbufhandle)
{
@ -53,6 +52,7 @@ TextTerminal::~TextTerminal()
void TextTerminal::Reset()
{
next_attr = 0;
vgacolor = DEFAULT_COLOR;
column = line = 0;
ansisavedposx = ansisavedposy = 0;
@ -60,8 +60,8 @@ void TextTerminal::Reset()
TextBuffer* textbuf = textbufhandle->Acquire();
TextPos fillfrom(0, 0);
TextPos fillto(textbuf->Width()-1, textbuf->Height()-1);
TextChar fillwith(' ', vgacolor);
textbuf->Fill(fillfrom, fillto, fillwith, 0);
TextChar fillwith(' ', vgacolor, 0);
textbuf->Fill(fillfrom, fillto, fillwith);
textbuf->SetCursorEnabled(true);
UpdateCursor(textbuf);
textbufhandle->Release(textbuf);
@ -278,9 +278,9 @@ void TextTerminal::PutChar(TextBuffer* textbuf, char c)
if ( textbuf->Width() <= column )
Newline(textbuf);
TextPos pos(column++, line);
TextChar tc(wc, vgacolor);
TextChar tc(wc, vgacolor, ATTR_CHAR | next_attr);
textbuf->SetChar(pos, tc);
textbuf->SetCharAttr(pos, ATTR_CHAR);
next_attr = 0;
}
void TextTerminal::UpdateCursor(TextBuffer* textbuf)
@ -290,13 +290,21 @@ void TextTerminal::UpdateCursor(TextBuffer* textbuf)
void TextTerminal::Newline(TextBuffer* textbuf)
{
textbuf->SetCharAttr(TextPos(column, line), ATTR_CHAR);
TextPos pos(column, line);
TextChar tc = textbuf->GetChar(pos);
if ( !(tc.attr & ATTR_CHAR) )
{
tc.attr |= ATTR_CHAR;
textbuf->SetChar(pos, tc);
}
column = 0;
if ( line < textbuf->Height()-1 )
line++;
else
textbuf->Scroll(1, TextChar(' ', vgacolor)),
{
textbuf->Scroll(1, TextChar(' ', vgacolor, 0));
line = textbuf->Height()-1;
}
}
static TextPos DecrementTextPos(TextBuffer* textbuf, TextPos pos)
@ -314,10 +322,16 @@ void TextTerminal::Backspace(TextBuffer* textbuf)
while ( pos.x || pos.y )
{
pos = DecrementTextPos(textbuf, pos);
uint16_t attr = textbuf->GetCharAttr(pos);
textbuf->SetChar(pos, TextChar(' ', vgacolor));
textbuf->SetCharAttr(pos, attr & ~ATTR_CHAR);
if ( attr & ATTR_CHAR )
TextChar tc = textbuf->GetChar(pos);
next_attr = tc.attr & (ATTR_BOLD | ATTR_UNDERLINE);
if ( tc.c == L'_' )
next_attr |= ATTR_UNDERLINE;
else if ( tc.c == L' ' )
next_attr &= ~(ATTR_BOLD | ATTR_CHAR);
else
next_attr |= ATTR_BOLD;
textbuf->SetChar(pos, TextChar(' ', vgacolor, 0));
if ( tc.attr & ATTR_CHAR )
break;
}
column = pos.x;
@ -328,17 +342,21 @@ void TextTerminal::Tab(TextBuffer* textbuf)
{
if ( column == textbuf->Width() )
Newline(textbuf);
// TODO: This does not work correctly if the text buffer width is not a
// multiple of four and the column is near the edge.
unsigned until = 8 - (column % 8);
textbuf->SetCharAttr(TextPos(column, line), ATTR_CHAR);
while ( (until--) != 0 )
textbuf->SetChar(TextPos(column++, line), TextChar(' ', vgacolor));
unsigned int count = 8 - (column % 8);
for ( unsigned int i = 0; i < count; i++ )
{
if ( column == textbuf->Width() )
break;
TextPos pos(column++, line);
TextChar tc(' ', vgacolor, i == 0 ? ATTR_CHAR : 0);
textbuf->SetChar(pos, tc);
}
}
// TODO: This implementation of the 'Ansi Escape Codes' is incomplete and hacky.
void TextTerminal::AnsiReset()
{
next_attr = 0;
ansiusedparams = 0;
currentparamindex = 0;
ansiparams[0] = 0;
@ -501,7 +519,7 @@ void TextTerminal::RunAnsiCommand(TextBuffer* textbuf, char c)
from = TextPos{0, 0},
to = TextPos{width-1, height-1};
textbuf->Fill(from, to, TextChar(' ', vgacolor), 0);
textbuf->Fill(from, to, TextChar(' ', vgacolor, 0));
} break;
case 'K': // Erase parts of the current line.
{
@ -521,16 +539,16 @@ void TextTerminal::RunAnsiCommand(TextBuffer* textbuf, char c)
from = TextPos{0, line},
to = TextPos{width-1, line};
textbuf->Fill(from, to, TextChar(' ', vgacolor), 0);
textbuf->Fill(from, to, TextChar(' ', vgacolor, 0));
} break;
case 'S': // Scroll a line up and place a new line at the buttom.
{
textbuf->Scroll(1, TextChar(' ', vgacolor));
textbuf->Scroll(1, TextChar(' ', vgacolor, 0));
line = height-1;
} break;
case 'T': // Scroll a line up and place a new line at the top.
{
textbuf->Scroll(-1, TextChar(' ', vgacolor));
textbuf->Scroll(-1, TextChar(' ', vgacolor, 0));
line = 0;
} break;
case 'm': // Change how the text is rendered.

View File

@ -69,6 +69,7 @@ private:
mbstate_t ps;
mutable TextBufferHandle* textbufhandle;
mutable kthread_mutex_t termlock;
uint16_t next_attr;
uint8_t vgacolor;
unsigned column;
unsigned line;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -34,12 +34,11 @@
namespace Sortix {
VGATextBuffer::VGATextBuffer(uint16_t* vga, TextChar* chars, uint16_t* attr,
VGATextBuffer::VGATextBuffer(uint16_t* vga, TextChar* chars,
size_t width, size_t height)
{
this->vga = vga;
this->chars = chars;
this->attr = attr;
this->width = width;
this->height = height;
cursorpos = {0, 0};
@ -56,6 +55,8 @@ static uint16_t CharToTextEntry(TextChar c)
int remap = VGA::MapWideToVGAFont(c.c);
if ( remap < 0 )
remap = 0 /* replacement character */;
if ( c.attr & ATTR_BOLD )
c.vgacolor |= 0x08;
return (uint16_t) remap | (uint16_t) c.vgacolor << 8U;
}
@ -92,27 +93,16 @@ TextChar VGATextBuffer::GetChar(TextPos pos) const
{
if ( UsablePosition(pos) )
return chars[OffsetOfPos(pos)];
return {0, 0};
return {0, 0, 0};
}
void VGATextBuffer::SetChar(TextPos pos, TextChar c)
{
if ( UsablePosition(pos) )
chars[OffsetOfPos(pos)] = c,
{
chars[OffsetOfPos(pos)] = c;
vga[OffsetOfPos(pos)] = CharToTextEntry(c);
}
uint16_t VGATextBuffer::GetCharAttr(TextPos pos) const
{
if ( UsablePosition(pos) )
return attr[OffsetOfPos(pos)];
return 0;
}
void VGATextBuffer::SetCharAttr(TextPos pos, uint16_t attrval)
{
if ( UsablePosition(pos) )
attr[OffsetOfPos(pos)] = attrval;
}
}
void VGATextBuffer::Scroll(ssize_t off, TextChar fillwith)
@ -129,7 +119,7 @@ void VGATextBuffer::Scroll(ssize_t off, TextChar fillwith)
TextPos fillto = neg ? TextPos{width-1, height-1} : TextPos{width-1, absoff-1};
size_t scrollchars = width * (height-absoff);
Move(scrollto, scrollfrom, scrollchars);
Fill(fillfrom, fillto, fillwith, 0);
Fill(fillfrom, fillto, fillwith);
}
void VGATextBuffer::Move(TextPos to, TextPos from, size_t numchars)
@ -137,29 +127,35 @@ void VGATextBuffer::Move(TextPos to, TextPos from, size_t numchars)
size_t dest = OffsetOfPos(CropPosition(to));
size_t src = OffsetOfPos(CropPosition(from));
if ( dest < src )
{
for ( size_t i = 0; i < numchars; i++ )
chars[dest + i] = chars[src + i],
vga[dest + i] = CharToTextEntry(chars[dest + i]),
attr[dest + i] = attr[src + i];
{
chars[dest + i] = chars[src + i];
vga[dest + i] = CharToTextEntry(chars[dest + i]);
}
}
else if ( src < dest )
{
for ( size_t i = 0; i < numchars; i++ )
chars[dest + numchars-1 - i] = chars[src + numchars-1 - i],
vga[dest + numchars-1 - i] = CharToTextEntry(chars[dest + numchars-1 - i]),
attr[dest + numchars-1 - i] = attr[src + numchars-1 - i];
{
chars[dest + numchars-1 - i] = chars[src + numchars-1 - i];
vga[dest + numchars-1 - i] = CharToTextEntry(chars[dest + numchars-1 - i]);
}
}
}
void VGATextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith,
uint16_t fillattr)
void VGATextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith)
{
from = CropPosition(from);
to = CropPosition(to);
size_t start = OffsetOfPos(from);
size_t end = OffsetOfPos(to);
size_t entry = CharToTextEntry(fillwith);
uint16_t entry = CharToTextEntry(fillwith);
for ( size_t i = start; i <= end; i++ )
chars[i] = fillwith,
vga[i] = entry,
attr[i] = fillattr;
{
chars[i] = fillwith;
vga[i] = entry;
}
}
bool VGATextBuffer::GetCursorEnabled() const
@ -212,7 +208,7 @@ bool VGATextBuffer::EmergencyRecoup()
void VGATextBuffer::EmergencyReset()
{
Fill(TextPos{0, 0}, TextPos{width-1, height-1}, TextChar{0, 0}, 0);
Fill(TextPos{0, 0}, TextPos{width-1, height-1}, TextChar{0, 0, 0});
SetCursorPos(TextPos{0, 0});
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -32,18 +32,15 @@ namespace Sortix {
class VGATextBuffer : public TextBuffer
{
public:
VGATextBuffer(uint16_t* vga, TextChar* chars, uint16_t* attr, size_t width, size_t height);
VGATextBuffer(uint16_t* vga, TextChar* chars, size_t width, size_t height);
virtual ~VGATextBuffer();
virtual size_t Width() const;
virtual size_t Height() const;
virtual TextChar GetChar(TextPos pos) const;
virtual void SetChar(TextPos pos, TextChar c);
virtual uint16_t GetCharAttr(TextPos pos) const ;
virtual void SetCharAttr(TextPos pos, uint16_t attrval);
virtual void Scroll(ssize_t off, TextChar fillwith);
virtual void Move(TextPos to, TextPos from, size_t numchars);
virtual void Fill(TextPos from, TextPos to, TextChar fillwith,
uint16_t fillattr);
virtual void Fill(TextPos from, TextPos to, TextChar fillwith);
virtual bool GetCursorEnabled() const;
virtual void SetCursorEnabled(bool enablecursor);
virtual TextPos GetCursorPos() const;
@ -63,7 +60,6 @@ private:
private:
uint16_t* vga;
TextChar* chars;
uint16_t* attr;
size_t width;
size_t height;
TextPos cursorpos;