From dc11b9f837602277a1d293e8b2371e4ef6dd1fa1 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 19 Apr 2014 20:28:54 +0200 Subject: [PATCH] Add unicode support to kernel terminal and console. --- kernel/include/sortix/kernel/textbuffer.h | 15 +- kernel/kernel.cpp | 4 +- kernel/lfbtextbuffer.cpp | 48 ++--- kernel/lfbtextbuffer.h | 12 +- kernel/textterminal.cpp | 54 ++++-- kernel/textterminal.h | 5 +- kernel/vga.h | 218 +++++++++++++++++++++- kernel/vgatextbuffer.cpp | 28 +-- kernel/vgatextbuffer.h | 5 +- 9 files changed, 312 insertions(+), 77 deletions(-) diff --git a/kernel/include/sortix/kernel/textbuffer.h b/kernel/include/sortix/kernel/textbuffer.h index b2f0b560..3e99ecde 100644 --- a/kernel/include/sortix/kernel/textbuffer.h +++ b/kernel/include/sortix/kernel/textbuffer.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014. This file is part of Sortix. @@ -27,6 +27,7 @@ #include +#include #include #include @@ -42,11 +43,19 @@ struct TextPos size_t y; }; +struct TextCharPOD +{ + wchar_t c; + uint8_t vgacolor; // Format of +}; + struct TextChar { TextChar() { } - TextChar(char c, uint8_t vgacolor) : c(c), vgacolor(vgacolor) { } - char c; + 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}; } + wchar_t c; uint8_t vgacolor; // Format of }; diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 6e61364e..9b4d017d 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -209,7 +209,9 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) const size_t VGA_WIDTH = 80; const size_t VGA_HEIGHT = 25; static uint16_t vga_attr_buffer[VGA_WIDTH*VGA_HEIGHT]; - VGATextBuffer textbuf(VGAFB, vga_attr_buffer, VGA_WIDTH, VGA_HEIGHT); + static struct TextCharPOD vga_chars_pod_buffer[VGA_WIDTH*VGA_HEIGHT]; + TextChar* vga_chars_buffer = (TextChar*) vga_chars_pod_buffer; + VGATextBuffer textbuf(VGAFB, vga_chars_buffer, vga_attr_buffer, VGA_WIDTH, VGA_HEIGHT); TextBufferHandle textbufhandlestack(NULL, false, &textbuf, false); textbufhandle = Ref(&textbufhandlestack); diff --git a/kernel/lfbtextbuffer.cpp b/kernel/lfbtextbuffer.cpp index 321ff5f3..209f0dc3 100644 --- a/kernel/lfbtextbuffer.cpp +++ b/kernel/lfbtextbuffer.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014. This file is part of Sortix. @@ -62,7 +62,7 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat, size_t fontsize = VGA_FONT_CHARSIZE * VGA_FONT_NUMCHARS; uint8_t* backbuf; uint8_t* font; - uint16_t* chars; + TextChar* chars; uint16_t* attrs; TextBufferCmd* queue; LFBTextBuffer* ret; @@ -73,7 +73,7 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat, goto cleanup_done; if ( !(font = new uint8_t[fontsize]) ) goto cleanup_backbuf; - if ( !(chars = new uint16_t[columns * rows]) ) + if ( !(chars = new TextChar[columns * rows]) ) goto cleanup_font; if ( !(attrs = new uint16_t[columns * rows]) ) goto cleanup_chars; @@ -106,9 +106,9 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat, ret->columns = columns; ret->rows = rows; ret->font = font; - memset(chars, 0, sizeof(uint16_t) * columns * rows); + memset(chars, 0, sizeof(chars[0]) * columns * rows); ret->chars = chars; - memset(attrs, 0, sizeof(uint16_t) * columns * rows); + memset(attrs, 0, sizeof(attrs[0]) * columns * rows); ret->attrs = attrs; for ( size_t i = 0; i < 16UL; i++ ) { @@ -147,21 +147,6 @@ cleanup_done: return NULL; } -// TODO: Those are also in vgatextbuffer.cpp. Move them to a shared location and -// give them better names. -static TextChar EntryToTextChar(uint16_t entry) -{ - char c = entry & 0x00FF; - uint8_t vgacolor = entry >> 8U; - return TextChar{c, vgacolor}; -} - -static uint16_t CharToTextEntry(TextChar c) -{ - unsigned char uc = c.c; - return (uint16_t) uc | (uint16_t) c.vgacolor << 8U; -} - LFBTextBuffer::LFBTextBuffer() { } @@ -216,7 +201,7 @@ TextPos LFBTextBuffer::AddToPosition(TextPos pos, size_t count) return CropPosition(ret); } -void LFBTextBuffer::RenderChar(uint16_t vgachar, size_t posx, size_t posy) +void LFBTextBuffer::RenderChar(TextChar textchar, size_t posx, size_t posy) { if ( columns <= posx || rows <= posy ) return; @@ -224,15 +209,15 @@ void LFBTextBuffer::RenderChar(uint16_t vgachar, size_t posx, size_t posy) if ( lfbformat != 32 || VGA_FONT_WIDTH != 8UL ) return; bool drawcursor = cursorenabled && posx == cursorpos.x && posy == cursorpos.y; - uint8_t c = vgachar >> 0 & 0xFF; - uint8_t fgcoloridx = vgachar >> 8 & 0x0F; - uint8_t bgcoloridx = vgachar >> 12 & 0x0F; + uint8_t fgcoloridx = textchar.vgacolor >> 0 & 0x0F; + uint8_t bgcoloridx = textchar.vgacolor >> 4 & 0x0F; uint32_t fgcolor = colors[fgcoloridx]; uint32_t bgcolor = colors[bgcoloridx]; + const uint8_t* charfont = VGA::GetCharacterFont(font, textchar.c); for ( size_t y = 0; y < VGA_FONT_HEIGHT; y++ ) { size_t pixely = posy * VGA_FONT_HEIGHT + y; - uint8_t linebitmap = font[c * VGA_FONT_CHARSIZE + y]; + uint8_t linebitmap = charfont[y]; for ( size_t x = 0; x < VGA_FONT_WIDTH+1; x++ ) { uint32_t* line = (uint32_t*) (lfb + pixely * scansize); @@ -354,7 +339,7 @@ TextChar LFBTextBuffer::GetChar(TextPos pos) const if ( UsablePosition(pos) ) { ((LFBTextBuffer*) this)->StopRendering(); - TextChar ret = EntryToTextChar(chars[pos.y * columns + pos.x]); + TextChar ret = chars[pos.y * columns + pos.x]; ((LFBTextBuffer*) this)->ResumeRendering(); return ret; } @@ -365,12 +350,11 @@ void LFBTextBuffer::SetChar(TextPos pos, TextChar c) { if ( !UsablePosition(pos) ) return; - uint16_t entry = CharToTextEntry(c); TextBufferCmd cmd; cmd.type = TEXTBUFCMD_CHAR; cmd.x = pos.x; cmd.y = pos.y; - cmd.c = entry; + cmd.c = c; IssueCommand(&cmd); } @@ -443,7 +427,7 @@ void LFBTextBuffer::Scroll(ssize_t off, TextChar fillwith) TextBufferCmd cmd; cmd.type = TEXTBUFCMD_SCROLL; cmd.scroll_offset = off; - cmd.c = CharToTextEntry(fillwith); + cmd.c = fillwith; IssueCommand(&cmd); } @@ -472,12 +456,12 @@ void LFBTextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith, cmd.from_y = from.y; cmd.to_x = to.x; cmd.to_y = to.y; - cmd.c = CharToTextEntry(fillwith); + cmd.c = fillwith; cmd.attr = fillattr; IssueCommand(&cmd); } -void LFBTextBuffer::DoScroll(ssize_t off, uint16_t entry) +void LFBTextBuffer::DoScroll(ssize_t off, TextChar entry) { bool neg = 0 < off; size_t absoff = off < 0 ? -off : off; @@ -506,7 +490,7 @@ void LFBTextBuffer::DoMove(TextPos to, TextPos from, size_t numchars) attrs[dest + numchars-1 - i] = attrs[src + numchars-1 - i]; } -void LFBTextBuffer::DoFill(TextPos from, TextPos to, uint16_t fillwith, +void LFBTextBuffer::DoFill(TextPos from, TextPos to, TextChar fillwith, uint16_t fillattr) { size_t start = OffsetOfPos(from); diff --git a/kernel/lfbtextbuffer.h b/kernel/lfbtextbuffer.h index 9fd44404..2cadece7 100644 --- a/kernel/lfbtextbuffer.h +++ b/kernel/lfbtextbuffer.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014. This file is part of Sortix. @@ -54,7 +54,7 @@ struct TextBufferCmd union { bool b; - struct { uint16_t c; uint16_t attr; }; + struct { TextCharPOD c; uint16_t attr; }; size_t val; }; }; @@ -91,7 +91,7 @@ public: virtual void RenderThread(); private: - void RenderChar(uint16_t vgachar, size_t posx, size_t posy); + void RenderChar(TextChar textchar, size_t posx, size_t posy); void RenderCharAt(TextPos pos); void RenderRegion(size_t c1, size_t r1, size_t c2, size_t r2); void RenderRange(TextPos from, TextPos to); @@ -99,9 +99,9 @@ private: size_t OffsetOfPos(TextPos pos) const; TextPos CropPosition(TextPos pos) const; TextPos AddToPosition(TextPos pos, size_t count); - void DoScroll(ssize_t off, uint16_t entry); + void DoScroll(ssize_t off, TextChar entry); void DoMove(TextPos to, TextPos from, size_t numchars); - void DoFill(TextPos from, TextPos to, uint16_t fillwith, uint16_t fillattr); + void DoFill(TextPos from, TextPos to, TextChar fillwith, uint16_t fillattr); void IssueCommand(TextBufferCmd* cmd); void StopRendering(); void ResumeRendering(); @@ -131,7 +131,7 @@ private: uint8_t* lfb; uint8_t* backbuf; uint8_t* font; - uint16_t* chars; + TextChar* chars; uint16_t* attrs; size_t columns; size_t rows; diff --git a/kernel/textterminal.cpp b/kernel/textterminal.cpp index f435fbe0..d21bf59a 100644 --- a/kernel/textterminal.cpp +++ b/kernel/textterminal.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. This file is part of Sortix. @@ -22,6 +22,10 @@ *******************************************************************************/ +#include +#include +#include + #include #include @@ -37,6 +41,7 @@ const uint16_t ATTR_CHAR = 1U << 0U; TextTerminal::TextTerminal(Ref textbufhandle) { + memset(&ps, 0, sizeof(ps)); this->textbufhandle = textbufhandle; this->termlock = KTHREAD_MUTEX_INITIALIZER; Reset(); @@ -233,24 +238,39 @@ bool TextTerminal::EmergencySync() void TextTerminal::PutChar(TextBuffer* textbuf, char c) { if ( ansimode ) - PutAnsiEscaped(textbuf, c); - else switch ( c ) + return PutAnsiEscaped(textbuf, c); + + if ( mbsinit(&ps) ) { - case '\n': Newline(textbuf); break; - case '\r': column = 0; break; - case '\b': Backspace(textbuf); break; - case '\t': Tab(textbuf); break; - case '\e': AnsiReset(); break; - default: - { - if ( textbuf->Width() <= column ) - Newline(textbuf); - TextPos pos(column++, line); - TextChar tc(c, vgacolor); - textbuf->SetChar(pos, tc); - textbuf->SetCharAttr(pos, ATTR_CHAR); - } break; + switch ( c ) + { + case '\n': Newline(textbuf); return; + case '\r': column = 0; return; + case '\b': Backspace(textbuf); return; + case '\t': Tab(textbuf); return; + case '\e': AnsiReset(); return; + default: break; + } } + + wchar_t wc; + size_t result = mbrtowc(&wc, &c, 1, &ps); + if ( result == (size_t) -2 ) + return; + if ( result == (size_t) -1 ) + { + memset(&ps, 0, sizeof(ps)); + wc = L'�'; + } + if ( result == (size_t) 0 ) + wc = L' '; + + if ( textbuf->Width() <= column ) + Newline(textbuf); + TextPos pos(column++, line); + TextChar tc(wc, vgacolor); + textbuf->SetChar(pos, tc); + textbuf->SetCharAttr(pos, ATTR_CHAR); } void TextTerminal::UpdateCursor(TextBuffer* textbuf) diff --git a/kernel/textterminal.h b/kernel/textterminal.h index 00d01df4..05768335 100644 --- a/kernel/textterminal.h +++ b/kernel/textterminal.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014. This file is part of Sortix. @@ -25,6 +25,8 @@ #ifndef SORTIX_TEXTTERMINAL_H #define SORTIX_TEXTTERMINAL_H +#include + #include #include @@ -63,6 +65,7 @@ private: void Reset(); private: + mbstate_t ps; mutable Ref textbufhandle; mutable kthread_mutex_t termlock; uint8_t vgacolor; diff --git a/kernel/vga.h b/kernel/vga.h index dd044e07..804172fa 100644 --- a/kernel/vga.h +++ b/kernel/vga.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014. This file is part of Sortix. @@ -25,6 +25,8 @@ #ifndef SORTIX_VGA_H #define SORTIX_VGA_H +#include + #include namespace Sortix { @@ -38,6 +40,220 @@ const size_t VGA_FONT_CHARSIZE = VGA_FONT_WIDTH * VGA_FONT_HEIGHT / 8UL; namespace VGA { +// https://en.wikipedia.org/wiki/Code_page_437 +__attribute__((unused)) +static inline int MapWideToVGAFont(wchar_t c) +{ + if ( 32 <= c && c < 127 ) + return (int) c; + switch ( c ) + { + case L'☺': return 1; + case L'☻': return 2; + case L'♥': return 3; + case L'♦': return 4; + case L'♣': return 5; + case L'♠': return 6; + case L'•': return 7; + case L'◘': return 8; + case L'○': return 9; + case L'◙': return 10; + case L'♂': return 11; + case L'♀': return 12; + case L'♪': return 13; + case L'♬': return 14; + case L'☼': return 15; + case L'►': return 16; + case L'◄': return 17; + case L'↕': return 18; + case L'‼': return 19; + case L'¶': return 20; + case L'§': return 21; + case L'▬': return 22; + case L'↨': return 23; + case L'↑': return 24; + case L'↓': return 25; + case L'→': return 26; + case L'←': return 27; + case L'∟': return 28; + case L'↔': return 29; + case L'▲': return 30; + case L'▼': return 31; + case L'⌂': return 127; + case L'Ç': return 128; + case L'ü': return 129; + case L'é': return 130; + case L'â': return 131; + case L'ä': return 132; + case L'à': return 133; + case L'å': return 134; + case L'ç': return 135; + case L'ê': return 136; + case L'ë': return 137; + case L'è': return 138; + case L'ï': return 139; + case L'î': return 140; + case L'ì': return 141; + case L'Ä': return 142; + case L'Å': return 143; + case L'É': return 144; + case L'æ': return 145; + case L'Æ': return 146; + case L'ô': return 147; + case L'ö': return 148; + case L'ò': return 149; + case L'û': return 150; + case L'ù': return 151; + case L'ÿ': return 152; + case L'Ö': return 153; + case L'Ü': return 154; + case L'¢': return 155; + case L'£': return 156; + case L'¥': return 157; + case L'₧': return 158; + case L'ƒ': return 159; + case L'á': return 160; + case L'í': return 161; + case L'ó': return 162; + case L'ú': return 163; + case L'ñ': return 164; + case L'Ñ': return 165; + case L'ª': return 166; + case L'º': return 167; + case L'¿': return 168; + case L'⌐': return 169; + case L'¬': return 170; + case L'½': return 171; + case L'¼': return 172; + case L'¡': return 173; + case L'«': return 174; + case L'»': return 175; + case L'░': return 176; + case L'▒': return 177; + case L'▓': return 178; + case L'│': return 179; + case L'┤': return 180; + case L'╡': return 181; + case L'╢': return 182; + case L'╖': return 183; + case L'╕': return 184; + case L'╣': return 185; + case L'║': return 186; + case L'╗': return 187; + case L'╝': return 188; + case L'╜': return 189; + case L'╛': return 190; + case L'┐': return 191; + case L'└': return 192; + case L'┴': return 193; + case L'┬': return 194; + case L'├': return 195; + case L'─': return 196; + case L'┼': return 197; + case L'╞': return 198; + case L'╟': return 199; + case L'╚': return 200; + case L'╔': return 201; + case L'╩': return 202; + case L'╦': return 203; + case L'╠': return 204; + case L'═': return 205; + case L'╬': return 206; + case L'╧': return 207; + case L'╨': return 208; + case L'╤': return 209; + case L'╥': return 210; + case L'╙': return 211; + case L'╘': return 212; + case L'╒': return 213; + case L'╓': return 214; + case L'╫': return 215; + case L'╪': return 216; + case L'┘': return 217; + case L'┌': return 218; + case L'█': return 219; + case L'▄': return 220; + case L'▌': return 221; + case L'▐': return 222; + case L'▀': return 223; + case L'α': return 224; + case L'ß': return 225; /* German sharp S U+00DF */ + case L'β': return 225; /* Greek lowercase beta U+03B2 */ + case L'Γ': return 226; + case L'π': return 227; + case L'Σ': return 228; /* Greek uppercase sigma U+03A3 */ + case L'∑': return 228; /* n-ary summation sign U+2211 (replacement) */ + case L'σ': return 229; + case L'µ': return 230; + case L'τ': return 231; + case L'Φ': return 232; + case L'Θ': return 233; + case L'Ω': return 234; + case L'δ': return 235; /* Greek lowercase delta U+03B4 */ + case L'ð': return 235; /* Icelandic lowercase eth U+00F0 (replacement) */ + case L'∂': return 235; /* Partial derivative sign U+2202 (replacement) */ + case L'∞': return 236; + case L'φ': return 237; /* Greek lowercase phi U+03C6 */ + case L'∅': return 237; /* Empty set sign U+2205 (replacement) */ + case L'ϕ': return 237; /* Greek phi symbol in italics U+03D5 (replacement) */ + case L'⌀': return 237; /* Diameter sign U+2300 (replacement) */ + case L'ø': return 237; /* Latin lowercase O with stroke U+00F8 (replacement) */ + case L'Ø': return 237; /* Latin uppercase O with stroke U+00D8 (replacement) */ + case L'ε': return 238; /* Greek lowercase epsilon U+03B5 */ + case L'∈': return 238; /* Element-of sign U+2208 */ + case L'€': return 238; /* Euro sign U+20AC */ + case L'∩': return 239; + case L'≡': return 240; + case L'±': return 241; + case L'≥': return 242; + case L'≤': return 243; + case L'⌠': return 244; + case L'⌡': return 245; + case L'÷': return 246; + case L'≈': return 247; + case L'°': return 248; + case L'∙': return 249; + case L'·': return 250; + case L'√': return 251; + case L'ⁿ': return 252; + case L'²': return 253; + case L'■': return 254; + default: return 0 <= c && c < 256 ? c : -1; + } +} + +__attribute__((unused)) +static const uint8_t font_replacement_character[16] = +{ + 0b00000000, + 0b00010000, + 0b00111000, + 0b01000100, + 0b10111010, + 0b10111010, + 0b11110110, + 0b11101110, + 0b11101110, + 0b11111110, + 0b01101100, + 0b00101000, + 0b00010000, + 0b00000000, + 0b00000000, + 0b00000000, +}; + +__attribute__((unused)) +static inline const uint8_t* GetCharacterFont(const uint8_t* font, wchar_t wc) +{ + if ( wc == L'�' ) + return font_replacement_character; + int remap = MapWideToVGAFont(wc); + if ( remap < 0 ) + return font_replacement_character; + return font + 16 * remap; +} + void Init(const char* devpath, Ref slashdev); void SetCursor(unsigned x, unsigned y); const uint8_t* GetFont(); diff --git a/kernel/vgatextbuffer.cpp b/kernel/vgatextbuffer.cpp index b693e168..6515fe27 100644 --- a/kernel/vgatextbuffer.cpp +++ b/kernel/vgatextbuffer.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014. This file is part of Sortix. @@ -34,10 +34,11 @@ namespace Sortix { -VGATextBuffer::VGATextBuffer(uint16_t* vga, uint16_t* attr, +VGATextBuffer::VGATextBuffer(uint16_t* vga, TextChar* chars, uint16_t* attr, size_t width, size_t height) { this->vga = vga; + this->chars = chars; this->attr = attr; this->width = width; this->height = height; @@ -50,17 +51,12 @@ VGATextBuffer::~VGATextBuffer() { } -static TextChar EntryToTextChar(uint16_t entry) -{ - char c = entry & 0x00FF; - uint8_t vgacolor = entry >> 8U; - return TextChar{c, vgacolor}; -} - static uint16_t CharToTextEntry(TextChar c) { - unsigned char uc = c.c; - return (uint16_t) uc | (uint16_t) c.vgacolor << 8U; + int remap = VGA::MapWideToVGAFont(c.c); + if ( remap < 0 ) + return (uint16_t) '?' | (uint16_t) COLOR8_RED << 8U; + return (uint16_t) remap | (uint16_t) c.vgacolor << 8U; } bool VGATextBuffer::UsablePosition(TextPos pos) const @@ -95,13 +91,14 @@ size_t VGATextBuffer::Height() const TextChar VGATextBuffer::GetChar(TextPos pos) const { if ( UsablePosition(pos) ) - return EntryToTextChar(vga[OffsetOfPos(pos)]); + return chars[OffsetOfPos(pos)]; return {0, 0}; } void VGATextBuffer::SetChar(TextPos pos, TextChar c) { if ( UsablePosition(pos) ) + chars[OffsetOfPos(pos)] = c, vga[OffsetOfPos(pos)] = CharToTextEntry(c); } @@ -141,11 +138,13 @@ void VGATextBuffer::Move(TextPos to, TextPos from, size_t numchars) size_t src = OffsetOfPos(CropPosition(from)); if ( dest < src ) for ( size_t i = 0; i < numchars; i++ ) - vga[dest + i] = vga[src + i], + chars[dest + i] = chars[src + i], + vga[dest + i] = CharToTextEntry(chars[dest + i]), attr[dest + i] = attr[src + i]; else if ( src < dest ) for ( size_t i = 0; i < numchars; i++ ) - vga[dest + numchars-1 - i] = vga[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]), attr[dest + numchars-1 - i] = attr[src + numchars-1 - i]; } @@ -158,6 +157,7 @@ void VGATextBuffer::Fill(TextPos from, TextPos to, TextChar fillwith, size_t end = OffsetOfPos(to); size_t entry = CharToTextEntry(fillwith); for ( size_t i = start; i <= end; i++ ) + chars[i] = fillwith, vga[i] = entry, attr[i] = fillattr; } diff --git a/kernel/vgatextbuffer.h b/kernel/vgatextbuffer.h index 7410b81b..0196d9bf 100644 --- a/kernel/vgatextbuffer.h +++ b/kernel/vgatextbuffer.h @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. + Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014. This file is part of Sortix. @@ -32,7 +32,7 @@ namespace Sortix { class VGATextBuffer : public TextBuffer { public: - VGATextBuffer(uint16_t* vga, uint16_t* attr, size_t width, size_t height); + VGATextBuffer(uint16_t* vga, TextChar* chars, uint16_t* attr, size_t width, size_t height); virtual ~VGATextBuffer(); virtual size_t Width() const; virtual size_t Height() const; @@ -60,6 +60,7 @@ private: private: uint16_t* vga; + TextChar* chars; uint16_t* attr; size_t width; size_t height;