mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:07:34 +00:00
LibVT: Implement G0..G3 and VT100 translation table
This commit is contained in:
parent
aaa1382bd6
commit
49ccda5d97
3 changed files with 106 additions and 1 deletions
59
Userland/Libraries/LibVT/CharacterSet.h
Normal file
59
Userland/Libraries/LibVT/CharacterSet.h
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -998,6 +998,9 @@ void Terminal::on_input(u8 byte)
|
||||||
|
|
||||||
void Terminal::emit_code_point(u32 code_point)
|
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;
|
auto new_column = cursor_column() + 1;
|
||||||
if (new_column < columns()) {
|
if (new_column < columns()) {
|
||||||
put_character_at(cursor_row(), cursor_column(), code_point);
|
put_character_at(cursor_row(), cursor_column(), code_point);
|
||||||
|
@ -1099,7 +1102,13 @@ void Terminal::execute_escape_sequence(Intermediates intermediates, bool ignore,
|
||||||
DECPNM();
|
DECPNM();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (intermediates[0] == '#') {
|
unimplemented_escape_sequence(intermediates, last_byte);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char intermediate = intermediates[0];
|
||||||
|
switch (intermediate) {
|
||||||
|
case '#':
|
||||||
switch (last_byte) {
|
switch (last_byte) {
|
||||||
case '8':
|
case '8':
|
||||||
// Confidence Test - Fill screen with E's
|
// Confidence Test - Fill screen with E's
|
||||||
|
@ -1110,7 +1119,39 @@ void Terminal::execute_escape_sequence(Intermediates intermediates, bool ignore,
|
||||||
}
|
}
|
||||||
return;
|
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);
|
unimplemented_escape_sequence(intermediates, last_byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <Kernel/API/KeyCode.h>
|
#include <Kernel/API/KeyCode.h>
|
||||||
|
#include <LibVT/CharacterSet.h>
|
||||||
#include <LibVT/EscapeSequenceParser.h>
|
#include <LibVT/EscapeSequenceParser.h>
|
||||||
#include <LibVT/Position.h>
|
#include <LibVT/Position.h>
|
||||||
|
|
||||||
|
@ -443,6 +444,10 @@ protected:
|
||||||
Optional<u16> m_column_before_carriage_return;
|
Optional<u16> m_column_before_carriage_return;
|
||||||
bool m_controls_are_logically_generated { false };
|
bool m_controls_are_logically_generated { false };
|
||||||
CursorKeysMode m_cursor_keys_mode { Cursor };
|
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 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue