diff options
-rw-r--r-- | Userland/Libraries/LibVT/CharacterSet.h | 59 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.cpp | 43 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.h | 5 |
3 files changed, 106 insertions, 1 deletions
diff --git a/Userland/Libraries/LibVT/CharacterSet.h b/Userland/Libraries/LibVT/CharacterSet.h new file mode 100644 index 0000000000..3268a3f0e0 --- /dev/null +++ b/Userland/Libraries/LibVT/CharacterSet.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, The SerenityOS Developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace VT { + +enum CharacterSet { + Iso_8859_1, + Null, + UserDefined, + VT100, +}; + +class CharacterSetTranslator { +public: + u32 translate_code_point(CharacterSet active_set, u32 code_point) + { + // Only translate 0x7F and lower + if (code_point > 127) + return code_point; + + // FIXME: implement other character sets + if (active_set != CharacterSet::VT100) + return code_point; + + // VT100 translation table - https://en.wikipedia.org/wiki/Box-drawing_character#Unix,_CP/M,_BBS + switch (code_point) { + case 0x6A: + return 0x2518; + case 0x6B: + return 0x2510; + case 0x6C: + return 0x250C; + case 0x6D: + return 0x2514; + case 0x6E: + return 0x253C; + case 0x71: + return 0x2500; + case 0x74: + return 0x251C; + case 0x75: + return 0x2524; + case 0x76: + return 0x2534; + case 0x77: + return 0x252C; + case 0x78: + return 0x2502; + } + return code_point; + } +}; + +} diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp index 916e7b33b7..7b52dbd0b6 100644 --- a/Userland/Libraries/LibVT/Terminal.cpp +++ b/Userland/Libraries/LibVT/Terminal.cpp @@ -998,6 +998,9 @@ void Terminal::on_input(u8 byte) void Terminal::emit_code_point(u32 code_point) { + auto working_set = m_working_sets[m_active_working_set_index]; + code_point = m_character_set_translator.translate_code_point(working_set, code_point); + auto new_column = cursor_column() + 1; if (new_column < columns()) { put_character_at(cursor_row(), cursor_column(), code_point); @@ -1099,7 +1102,13 @@ void Terminal::execute_escape_sequence(Intermediates intermediates, bool ignore, DECPNM(); return; } - } else if (intermediates[0] == '#') { + unimplemented_escape_sequence(intermediates, last_byte); + return; + } + + char intermediate = intermediates[0]; + switch (intermediate) { + case '#': switch (last_byte) { case '8': // Confidence Test - Fill screen with E's @@ -1110,7 +1119,39 @@ void Terminal::execute_escape_sequence(Intermediates intermediates, bool ignore, } return; } + break; + case '(': + case ')': + case '*': + case '+': + // Determine G0..G3 index + size_t working_set_index = intermediate - '('; + + CharacterSet new_set; + switch (last_byte) { + case 'B': + new_set = CharacterSet::Iso_8859_1; + break; + case '0': + new_set = CharacterSet::VT100; + break; + case 'U': + new_set = CharacterSet::Null; + break; + case 'K': + new_set = CharacterSet::UserDefined; + break; + default: + unimplemented_escape_sequence(intermediates, last_byte); + return; + } + + dbgln_if(TERMINAL_DEBUG, "Setting G{} working set to character set {}", working_set_index, to_underlying(new_set)); + VERIFY(working_set_index <= 3); + m_working_sets[working_set_index] = new_set; + return; } + unimplemented_escape_sequence(intermediates, last_byte); } diff --git a/Userland/Libraries/LibVT/Terminal.h b/Userland/Libraries/LibVT/Terminal.h index 745aabf7a9..6b78c2ef67 100644 --- a/Userland/Libraries/LibVT/Terminal.h +++ b/Userland/Libraries/LibVT/Terminal.h @@ -12,6 +12,7 @@ #include <AK/String.h> #include <AK/Vector.h> #include <Kernel/API/KeyCode.h> +#include <LibVT/CharacterSet.h> #include <LibVT/EscapeSequenceParser.h> #include <LibVT/Position.h> @@ -443,6 +444,10 @@ protected: Optional<u16> m_column_before_carriage_return; bool m_controls_are_logically_generated { false }; CursorKeysMode m_cursor_keys_mode { Cursor }; + + CharacterSetTranslator m_character_set_translator {}; + size_t m_active_working_set_index { 0 }; + CharacterSet m_working_sets[4] { Iso_8859_1 }; }; } |