Kernel: Add unicode support
This commit is contained in:
@@ -85,30 +85,53 @@ namespace Keyboard
|
||||
|
||||
static void (*s_key_event_callback)(KeyEvent) = nullptr;
|
||||
|
||||
static char s_key_to_char[]
|
||||
static const char* s_key_to_utf8_lower[]
|
||||
{
|
||||
'\0', '\0',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'A', 'A', 'O',
|
||||
nullptr, nullptr,
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
||||
"å", "ä", "ö",
|
||||
|
||||
',', ':', '.', ';', '-', '_', '\'', '*', '^', '~',
|
||||
'!', '?', '"', '#', '%', '&', '/', '\\', '+', '=',
|
||||
'(', ')', '[', ']', '{', '}',
|
||||
'$', '\0', '\0', '\0', '\n', ' ', '\t', '\b', '<', '>', '\0', '`', '\0', '\0', '@', '|',
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
",", ":", ".", ";", "-", "_", "'", "*", "^", "~",
|
||||
"!", "?", "\"", "#", "%", "&", "/", "\\", "+", "=",
|
||||
"(", ")", "[", "]", "{", "}",
|
||||
"$", "£", "€", "¤", "\n", " ", "\t", nullptr, "<", ">", "´", "`", "§", "½", "@", "|",
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
',', '+', '*', '/', '-', '\n',
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
",", "+", "*", "/", "-", "\n",
|
||||
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
};
|
||||
static_assert(sizeof(s_key_to_char) == static_cast<int>(Key::Count));
|
||||
static_assert(sizeof(s_key_to_utf8_lower) == static_cast<int>(Key::Count) * sizeof(*s_key_to_utf8_lower));
|
||||
|
||||
static const char* s_key_to_utf8_upper[]
|
||||
{
|
||||
nullptr, nullptr,
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
|
||||
"Å", "Ä", "Ö",
|
||||
|
||||
",", ":", ".", ";", "-", "_", "'", "*", "^", "~",
|
||||
"!", "?", "\"", "#", "%", "&", "/", "\\", "+", "=",
|
||||
"(", ")", "[", "]", "{", "}",
|
||||
"$", "£", "€", "¤", "\n", " ", "\t", nullptr, "<", ">", "´", "`", "§", "½", "@", "|",
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
",", "+", "*", "/", "-", "\n",
|
||||
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
};
|
||||
static_assert(sizeof(s_key_to_utf8_upper) == static_cast<int>(Key::Count) * sizeof(*s_key_to_utf8_upper));
|
||||
|
||||
static uint8_t wait_and_read()
|
||||
{
|
||||
@@ -436,15 +459,13 @@ namespace Keyboard
|
||||
s_key_event_callback = callback;
|
||||
}
|
||||
|
||||
char key_event_to_ascii(KeyEvent event)
|
||||
const char* key_event_to_utf8(KeyEvent event)
|
||||
{
|
||||
char res = s_key_to_char[static_cast<uint8_t>(event.key)];
|
||||
|
||||
if (!(event.modifiers & (MOD_SHIFT | MOD_CAPS)))
|
||||
if (res >= 'A' && res <= 'Z')
|
||||
res = res - 'A' + 'a';
|
||||
|
||||
return res;
|
||||
bool shift = event.modifiers & MOD_SHIFT;
|
||||
bool caps = event.modifiers & MOD_CAPS;
|
||||
if (shift ^ caps)
|
||||
return s_key_to_utf8_upper[static_cast<uint8_t>(event.key)];
|
||||
return s_key_to_utf8_lower[static_cast<uint8_t>(event.key)];
|
||||
}
|
||||
|
||||
void led_disco()
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <kernel/PIT.h>
|
||||
#include <kernel/RTC.h>
|
||||
#include <kernel/Shell.h>
|
||||
#include <kernel/Serial.h>
|
||||
#include <kernel/tty.h>
|
||||
|
||||
namespace Kernel
|
||||
@@ -172,6 +173,47 @@ namespace Kernel
|
||||
kprintln("unrecognized command '{}'", arguments.Front());
|
||||
}
|
||||
|
||||
static uint8_t GetLastLength(const BAN::String& string)
|
||||
{
|
||||
if (string.Empty())
|
||||
return 0;
|
||||
|
||||
if (!(string[string.Size() - 1] & 0x80))
|
||||
return 1;
|
||||
|
||||
if (string.Size() < 2)
|
||||
return 1;
|
||||
|
||||
if (((uint8_t)string[string.Size() - 2] >> 5) == 0b110 &&
|
||||
((uint8_t)string[string.Size() - 1] >> 6) == 0b10)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (string.Size() < 3)
|
||||
return 1;
|
||||
|
||||
if (((uint8_t)string[string.Size() - 3] >> 4) == 0b1110 &&
|
||||
((uint8_t)string[string.Size() - 2] >> 6) == 0b10 &&
|
||||
((uint8_t)string[string.Size() - 1] >> 6) == 0b10)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (string.Size() < 4)
|
||||
return 1;
|
||||
|
||||
if ((string[string.Size() - 4] >> 3) == 0b11110 &&
|
||||
(string[string.Size() - 3] >> 6) == 0b10 &&
|
||||
(string[string.Size() - 2] >> 6) == 0b10 &&
|
||||
(string[string.Size() - 1] >> 6) == 0b10)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Shell::KeyEventCallback(Keyboard::KeyEvent event)
|
||||
{
|
||||
if (!event.pressed)
|
||||
@@ -184,7 +226,10 @@ namespace Kernel
|
||||
if (!m_buffer.Empty())
|
||||
{
|
||||
kprint("\b \b", 3);
|
||||
m_buffer.PopBack();
|
||||
|
||||
uint8_t last_len = GetLastLength(m_buffer);
|
||||
for (uint8_t i = 0; i < last_len; i++)
|
||||
m_buffer.PopBack();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -200,21 +245,19 @@ namespace Kernel
|
||||
}
|
||||
|
||||
case Keyboard::Key::Tab:
|
||||
event.key = Keyboard::Key::Space;
|
||||
// fall through
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char ascii = Keyboard::key_event_to_ascii(event);
|
||||
if (ascii)
|
||||
const char* utf8 = Keyboard::key_event_to_utf8(event);
|
||||
if (utf8)
|
||||
{
|
||||
kprint("{}", ascii);
|
||||
m_buffer.PushBack(ascii);
|
||||
kprint("{}", utf8);
|
||||
m_buffer.Append(utf8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user