Kernel: Move KeyEvent/MouseEvent from kernel to LibInput
This commit is contained in:
@@ -42,8 +42,6 @@ set(KERNEL_SOURCES
|
||||
kernel/FS/VirtualFileSystem.cpp
|
||||
kernel/GDT.cpp
|
||||
kernel/IDT.cpp
|
||||
kernel/Input/KeyboardLayout.cpp
|
||||
kernel/Input/KeyEvent.cpp
|
||||
kernel/Input/PS2/Controller.cpp
|
||||
kernel/Input/PS2/Device.cpp
|
||||
kernel/Input/PS2/Keyboard.cpp
|
||||
@@ -150,12 +148,18 @@ set(LIBELF_SOURCES
|
||||
../LibELF/LibELF/LoadableELF.cpp
|
||||
)
|
||||
|
||||
set(LIBINPUT_SOURCE
|
||||
../LibInput/KeyboardLayout.cpp
|
||||
../LibInput/KeyEvent.cpp
|
||||
)
|
||||
|
||||
set(KERNEL_SOURCES
|
||||
${KERNEL_SOURCES}
|
||||
${LAI_SOURCES}
|
||||
${BAN_SOURCES}
|
||||
${KLIBC_SOURCES}
|
||||
${LIBELF_SOURCES}
|
||||
${LIBINPUT_SOURCE}
|
||||
)
|
||||
|
||||
add_executable(kernel ${KERNEL_SOURCES})
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
/*
|
||||
Key Code:
|
||||
bits 4:0 column (from left)
|
||||
bits 7:5 row (from top)
|
||||
*/
|
||||
|
||||
#define BANAN_CONSTEVAL_STATIC_ASSERT(cond) do { int dummy = 1 / (cond); } while (false)
|
||||
|
||||
consteval uint8_t keycode_function(uint8_t index)
|
||||
{
|
||||
BANAN_CONSTEVAL_STATIC_ASSERT(index <= 0b11111);
|
||||
return index;
|
||||
}
|
||||
|
||||
consteval uint8_t keycode_normal(uint8_t row, uint8_t col)
|
||||
{
|
||||
BANAN_CONSTEVAL_STATIC_ASSERT(row <= 0b111 - 1);
|
||||
BANAN_CONSTEVAL_STATIC_ASSERT(col < 0b11111 - 8);
|
||||
return ((row + 1) << 5) | col;
|
||||
}
|
||||
|
||||
consteval uint8_t keycode_numpad(uint8_t row, uint8_t col)
|
||||
{
|
||||
BANAN_CONSTEVAL_STATIC_ASSERT(row <= 0b111 - 1);
|
||||
BANAN_CONSTEVAL_STATIC_ASSERT(col <= 8);
|
||||
return ((row + 1) << 5) | (col + 0b11111 - 8);
|
||||
}
|
||||
|
||||
enum class Key
|
||||
{
|
||||
Invalid, None,
|
||||
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_Ring, A_Umlaut, O_Umlaut,
|
||||
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9,
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
Insert, PrintScreen, Delete, Home, End, PageUp, PageDown, Enter, Space,
|
||||
ExclamationMark, DoubleQuote, Hashtag, Currency, Percent, Ampersand, Slash, Section, Half,
|
||||
OpenParenthesis, CloseParenthesis, OpenSquareBracket, CloseSquareBracket, OpenCurlyBracket, CloseCurlyBracket,
|
||||
Equals, QuestionMark, Plus, BackSlash, Acute, BackTick, TwoDots, Cedilla, Backspace, AtSign, Pound, Dollar, Euro,
|
||||
Escape, Tab, CapsLock, LeftShift, LeftCtrl, Super, LeftAlt, RightAlt, AltGr = RightAlt, RightCtrl, RightShift,
|
||||
SingleQuote, Asterix, Caret, Tilde, ArrowUp, ArrowDown, ArrowLeft, ArrowRight,
|
||||
Comma, Semicolon, Period, Colon, Hyphen, Underscore, NumLock, ScrollLock, LessThan, GreaterThan, Pipe, Negation, BrokenBar,
|
||||
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
|
||||
NumpadPlus, NumpadMinus, NumpadMultiply, NumpadDivide, NumpadEnter, NumpadDecimal,
|
||||
VolumeMute, VolumeUp, VolumeDown, Calculator, MediaPlayPause, MediaStop, MediaPrevious, MediaNext,
|
||||
Count,
|
||||
};
|
||||
|
||||
struct KeyEvent
|
||||
{
|
||||
enum Modifier : uint16_t
|
||||
{
|
||||
LShift = (1 << 0),
|
||||
RShift = (1 << 1),
|
||||
LCtrl = (1 << 2),
|
||||
RCtrl = (1 << 3),
|
||||
LAlt = (1 << 4),
|
||||
RAlt = (1 << 5),
|
||||
CapsLock = (1 << 6),
|
||||
NumLock = (1 << 7),
|
||||
ScrollLock = (1 << 8),
|
||||
Pressed = (1 << 9),
|
||||
};
|
||||
|
||||
bool lshift() const { return modifier & Modifier::LShift; }
|
||||
bool rshift() const { return modifier & Modifier::RShift; }
|
||||
bool shift() const { return lshift() || rshift(); }
|
||||
|
||||
bool lctrl() const { return modifier & Modifier::LCtrl; }
|
||||
bool rctrl() const { return modifier & Modifier::RCtrl; }
|
||||
bool ctrl() const { return lctrl() || rctrl(); }
|
||||
|
||||
bool lalt() const { return modifier & Modifier::LAlt; }
|
||||
bool ralt() const { return modifier & Modifier::RAlt; }
|
||||
bool alt() const { return lalt() || ralt(); }
|
||||
|
||||
bool caps_lock() const { return modifier & Modifier::CapsLock; }
|
||||
bool num_lock() const { return modifier & Modifier::NumLock; }
|
||||
bool scroll_lock() const { return modifier & Modifier::ScrollLock; }
|
||||
|
||||
bool pressed() const { return modifier & Modifier::Pressed; }
|
||||
bool released() const { return !pressed(); }
|
||||
|
||||
uint16_t modifier;
|
||||
uint8_t keycode;
|
||||
};
|
||||
|
||||
Key key_event_to_key(KeyEvent);
|
||||
const char* key_to_utf8(Key key, uint16_t modifier);
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <BAN/UniqPtr.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
class KeyboardLayout
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<void> initialize();
|
||||
static KeyboardLayout& get();
|
||||
|
||||
Key get_key_from_event(KeyEvent);
|
||||
BAN::ErrorOr<void> load_from_file(BAN::StringView path);
|
||||
|
||||
private:
|
||||
KeyboardLayout();
|
||||
|
||||
private:
|
||||
BAN::Array<Key, 0xFF> m_keycode_to_key_normal;
|
||||
BAN::Array<Key, 0xFF> m_keycode_to_key_shift;
|
||||
BAN::Array<Key, 0xFF> m_keycode_to_key_altgr;
|
||||
SpinLock m_lock;
|
||||
|
||||
friend class BAN::UniqPtr<KeyboardLayout>;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
enum class MouseButton
|
||||
{
|
||||
Left, Right, Middle, Extra1, Extra2
|
||||
};
|
||||
|
||||
struct MouseButtonEvent
|
||||
{
|
||||
MouseButton button;
|
||||
bool pressed;
|
||||
};
|
||||
|
||||
struct MouseMoveEvent
|
||||
{
|
||||
int32_t rel_x;
|
||||
int32_t rel_y;
|
||||
};
|
||||
|
||||
struct MouseScrollEvent
|
||||
{
|
||||
int32_t scroll;
|
||||
};
|
||||
|
||||
enum class MouseEventType
|
||||
{
|
||||
MouseButtonEvent,
|
||||
MouseMoveEvent,
|
||||
MouseScrollEvent,
|
||||
};
|
||||
|
||||
struct MouseEvent
|
||||
{
|
||||
MouseEventType type;
|
||||
union
|
||||
{
|
||||
MouseButtonEvent button_event;
|
||||
MouseMoveEvent move_event;
|
||||
MouseScrollEvent scroll_event;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <BAN/CircularQueue.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Input/PS2/Device.h>
|
||||
#include <kernel/Input/PS2/Keymap.h>
|
||||
#include <kernel/Semaphore.h>
|
||||
#include <LibInput/KeyEvent.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
@@ -40,7 +40,7 @@ namespace Kernel::Input
|
||||
|
||||
uint16_t m_modifiers { 0 };
|
||||
|
||||
BAN::CircularQueue<KeyEvent, 50> m_event_queue;
|
||||
BAN::CircularQueue<LibInput::RawKeyEvent, 50> m_event_queue;
|
||||
SpinLock m_event_lock;
|
||||
|
||||
PS2Keymap m_keymap;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/Input/MouseEvent.h>
|
||||
#include <kernel/Input/PS2/Device.h>
|
||||
#include <kernel/Semaphore.h>
|
||||
#include <LibInput/MouseEvent.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace Kernel::Input
|
||||
uint8_t m_mouse_id { 0x00 };
|
||||
uint8_t m_button_mask { 0x00 };
|
||||
|
||||
BAN::CircularQueue<MouseEvent, 128> m_event_queue;
|
||||
BAN::CircularQueue<LibInput::MouseEvent, 128> m_event_queue;
|
||||
SpinLock m_event_lock;
|
||||
|
||||
Semaphore m_semaphore;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <kernel/Device/Device.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
#include <kernel/Terminal/termios.h>
|
||||
#include <kernel/Semaphore.h>
|
||||
#include <LibInput/KeyEvent.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace Kernel
|
||||
void set_as_current();
|
||||
|
||||
static void initialize_devices();
|
||||
void on_key_event(Input::KeyEvent);
|
||||
void on_key_event(LibInput::KeyEvent);
|
||||
void handle_input_byte(uint8_t);
|
||||
|
||||
virtual bool is_tty() const override { return true; }
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <kernel/Device/Device.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
#include <kernel/Terminal/termios.h>
|
||||
#include <kernel/Terminal/TTY.h>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#include <BAN/Array.h>
|
||||
#include <kernel/Input/KeyboardLayout.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
Key key_event_to_key(KeyEvent event)
|
||||
{
|
||||
return KeyboardLayout::get().get_key_from_event(event);
|
||||
}
|
||||
|
||||
const char* key_to_utf8(Key key, uint16_t modifier)
|
||||
{
|
||||
static constexpr const char* utf8_lower[] = {
|
||||
nullptr, nullptr,
|
||||
"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", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
|
||||
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
|
||||
"(", ")", "[", "]", "{", "}",
|
||||
"=", "?", "+", "\\", "´", "`", "¨", "¸", nullptr, "@", "£", "$", "€",
|
||||
nullptr, "\t", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
"'", "*", "^", "~", nullptr, nullptr, nullptr, nullptr,
|
||||
",", ";", ".", ":", "-", "_", nullptr, nullptr, "<", ">", "|", "¬", "¦",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"+", "-", "*", "/", nullptr, ",",
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
};
|
||||
static_assert((size_t)Key::Count == sizeof(utf8_lower) / sizeof(*utf8_lower));
|
||||
|
||||
static constexpr const char* utf8_upper[] = {
|
||||
nullptr, nullptr,
|
||||
"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", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, " ",
|
||||
"!", "\"", "#", "¤", "%", "&", "/", "§", "½",
|
||||
"(", ")", "[", "]", "{", "}",
|
||||
"=", "?", "+", "\\", "´", "`", "¨", "¸", nullptr, "@", "£", "$", "€",
|
||||
nullptr, "\t", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
"'", "*", "^", "~", nullptr, nullptr, nullptr, nullptr,
|
||||
",", ";", ".", ":", "-", "_", nullptr, nullptr, "<", ">", "|", "¬", "¦",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"+", "-", "*", "/", nullptr, ",",
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
};
|
||||
static_assert((size_t)Key::Count == sizeof(utf8_upper) / sizeof(*utf8_lower));
|
||||
|
||||
KeyEvent event { .modifier = modifier, .keycode = 0x00 };
|
||||
return (event.shift() ^ event.caps_lock()) ? utf8_upper[static_cast<uint8_t>(key)] : utf8_lower[static_cast<uint8_t>(key)];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,438 +0,0 @@
|
||||
#include <BAN/HashMap.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/Input/KeyboardLayout.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
struct StringViewLower
|
||||
{
|
||||
BAN::StringView value;
|
||||
|
||||
StringViewLower(BAN::StringView sv)
|
||||
: value(sv)
|
||||
{ }
|
||||
|
||||
bool operator==(const StringViewLower& other) const
|
||||
{
|
||||
if (value.size() != other.value.size())
|
||||
return false;
|
||||
for (size_t i = 0; i < value.size(); i++)
|
||||
if (tolower(value[i]) != tolower(other.value[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct StringViewLowerHash
|
||||
{
|
||||
BAN::hash_t operator()(const StringViewLower& value) const
|
||||
{
|
||||
constexpr BAN::hash_t FNV_offset_basis = 0x811c9dc5;
|
||||
constexpr BAN::hash_t FNV_prime = 0x01000193;
|
||||
|
||||
BAN::hash_t hash = FNV_offset_basis;
|
||||
for (size_t i = 0; i < value.value.size(); i++)
|
||||
{
|
||||
hash *= FNV_prime;
|
||||
hash ^= (uint8_t)tolower(value.value[i]);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static BAN::UniqPtr<KeyboardLayout> s_instance;
|
||||
|
||||
BAN::ErrorOr<void> KeyboardLayout::initialize()
|
||||
{
|
||||
ASSERT(!s_instance);
|
||||
s_instance = TRY(BAN::UniqPtr<KeyboardLayout>::create());
|
||||
return {};
|
||||
}
|
||||
|
||||
KeyboardLayout& KeyboardLayout::get()
|
||||
{
|
||||
ASSERT(s_instance);
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
KeyboardLayout::KeyboardLayout()
|
||||
{
|
||||
for (auto& key : m_keycode_to_key_normal)
|
||||
key = Key::None;
|
||||
for (auto& key : m_keycode_to_key_shift)
|
||||
key = Key::None;
|
||||
for (auto& key : m_keycode_to_key_altgr)
|
||||
key = Key::None;
|
||||
}
|
||||
|
||||
Key KeyboardLayout::get_key_from_event(KeyEvent event)
|
||||
{
|
||||
SpinLockGuard _(m_lock);
|
||||
if (event.shift())
|
||||
return m_keycode_to_key_shift[event.keycode];
|
||||
if (event.ralt())
|
||||
return m_keycode_to_key_altgr[event.keycode];
|
||||
return m_keycode_to_key_normal[event.keycode];
|
||||
}
|
||||
|
||||
static BAN::Optional<uint8_t> parse_keycode(BAN::StringView str)
|
||||
{
|
||||
if (str.size() > 3)
|
||||
return {};
|
||||
uint16_t keycode = 0;
|
||||
for (char c : str)
|
||||
{
|
||||
if (!isdigit(c))
|
||||
return {};
|
||||
keycode = (keycode * 10) + (c - '0');
|
||||
}
|
||||
if (keycode >= 0xFF)
|
||||
return {};
|
||||
return keycode;
|
||||
}
|
||||
|
||||
static BAN::HashMap<StringViewLower, Key, StringViewLowerHash> s_name_to_key;
|
||||
static BAN::ErrorOr<void> initialize_name_to_key();
|
||||
|
||||
static BAN::Optional<Key> parse_key(BAN::StringView name)
|
||||
{
|
||||
if (s_name_to_key.contains(name))
|
||||
return s_name_to_key[name];
|
||||
return {};
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<BAN::Vector<BAN::String>> load_keymap_lines_and_parse_includes(BAN::StringView path)
|
||||
{
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0));
|
||||
|
||||
BAN::String file_data;
|
||||
TRY(file_data.resize(file.inode->size()));
|
||||
TRY(file.inode->read(0, BAN::ByteSpan { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() }));
|
||||
|
||||
BAN::Vector<BAN::String> result;
|
||||
|
||||
auto lines = TRY(file_data.sv().split('\n'));
|
||||
for (auto line : lines)
|
||||
{
|
||||
auto parts = TRY(line.split([](char c) -> bool { return isspace(c); }));
|
||||
if (parts.empty() || parts.front().front() == '#')
|
||||
continue;
|
||||
|
||||
if (parts.front() == "include"sv)
|
||||
{
|
||||
if (parts.size() != 2)
|
||||
{
|
||||
dprintln("Invalid modifier instruction in keymap '{}'", line);
|
||||
dprintln(" format: include \"PATH\"");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
if (parts[1].size() < 2 || parts[1].front() != '"' || parts[1].back() != '"')
|
||||
{
|
||||
dprintln("Invalid modifier instruction in keymap '{}'", line);
|
||||
dprintln(" format: include \"PATH\"");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
parts[1] = parts[1].substring(1, parts[1].size() - 2);
|
||||
|
||||
BAN::String include_path;
|
||||
TRY(include_path.append(file.canonical_path));
|
||||
ASSERT(include_path.sv().contains('/'));
|
||||
while (include_path.back() != '/')
|
||||
include_path.pop_back();
|
||||
TRY(include_path.append(parts[1]));
|
||||
|
||||
auto new_lines = TRY(load_keymap_lines_and_parse_includes(include_path));
|
||||
TRY(result.reserve(result.size() + new_lines.size()));
|
||||
for (auto& line : new_lines)
|
||||
TRY(result.push_back(BAN::move(line)));
|
||||
}
|
||||
else
|
||||
{
|
||||
BAN::String line_str;
|
||||
TRY(line_str.append(line));
|
||||
TRY(result.push_back(BAN::move(line_str)));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> KeyboardLayout::load_from_file(BAN::StringView path)
|
||||
{
|
||||
if (s_name_to_key.empty())
|
||||
TRY(initialize_name_to_key());
|
||||
|
||||
auto new_layout = TRY(BAN::UniqPtr<KeyboardLayout>::create());
|
||||
|
||||
bool shift_is_mod = false;
|
||||
bool altgr_is_mod = false;
|
||||
|
||||
auto lines = TRY(load_keymap_lines_and_parse_includes(path));
|
||||
for (const auto& line : lines)
|
||||
{
|
||||
auto parts = TRY(line.sv().split([](char c) -> bool { return isspace(c); }));
|
||||
if (parts.empty() || parts.front().front() == '#')
|
||||
continue;
|
||||
|
||||
if (parts.size() == 1)
|
||||
{
|
||||
dprintln("Invalid line in keymap '{}'", line);
|
||||
dprintln(" format: KEYCODE KEY [MODIFIER=KEY]...");
|
||||
dprintln(" format: mod MODIFIER");
|
||||
dprintln(" format: include \"PATH\"");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
if (parts.front() == "mod"sv)
|
||||
{
|
||||
if (parts.size() != 2)
|
||||
{
|
||||
dprintln("Invalid modifier instruction in keymap '{}'", line);
|
||||
dprintln(" format: mod MODIFIER");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
if (parts[1] == "shift"sv)
|
||||
shift_is_mod = true;
|
||||
else if (parts[1] == "altgr"sv)
|
||||
altgr_is_mod = true;
|
||||
else
|
||||
{
|
||||
dprintln("Unrecognized modifier '{}'", parts[1]);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
auto keycode = parse_keycode(parts.front());
|
||||
if (!keycode.has_value())
|
||||
{
|
||||
dprintln("Invalid keycode '{}', keycode must number between [0, 0xFF[", parts.front());
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
auto default_key = parse_key(parts[1]);
|
||||
if (!default_key.has_value())
|
||||
{
|
||||
dprintln("Unrecognized key '{}'", parts[1]);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
new_layout->m_keycode_to_key_normal[*keycode] = *default_key;
|
||||
new_layout->m_keycode_to_key_shift[*keycode] = *default_key;
|
||||
new_layout->m_keycode_to_key_altgr[*keycode] = *default_key;
|
||||
|
||||
for (size_t i = 2; i < parts.size(); i++)
|
||||
{
|
||||
auto pair = TRY(parts[i].split('='));
|
||||
if (pair.size() != 2)
|
||||
{
|
||||
dprintln("Invalid modifier format '{}', modifier format: MODIFIRER=KEY", parts[i]);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
auto key = parse_key(pair.back());
|
||||
if (!key.has_value())
|
||||
{
|
||||
dprintln("Unrecognized key '{}'", pair.back());
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
if (shift_is_mod && pair.front() == "shift"sv)
|
||||
new_layout->m_keycode_to_key_shift[*keycode] = *key;
|
||||
else if (altgr_is_mod && pair.front() == "altgr"sv)
|
||||
new_layout->m_keycode_to_key_altgr[*keycode] = *key;
|
||||
else
|
||||
{
|
||||
dprintln("Unrecognized modifier '{}'", pair.front());
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpinLockGuard _(m_lock);
|
||||
|
||||
for (size_t i = 0; i < new_layout->m_keycode_to_key_normal.size(); i++)
|
||||
if (new_layout->m_keycode_to_key_normal[i] != Key::None)
|
||||
m_keycode_to_key_normal[i] = new_layout->m_keycode_to_key_normal[i];
|
||||
|
||||
for (size_t i = 0; i < new_layout->m_keycode_to_key_shift.size(); i++)
|
||||
if (new_layout->m_keycode_to_key_shift[i] != Key::None)
|
||||
m_keycode_to_key_shift[i] = new_layout->m_keycode_to_key_shift[i];
|
||||
|
||||
for (size_t i = 0; i < new_layout->m_keycode_to_key_altgr.size(); i++)
|
||||
if (new_layout->m_keycode_to_key_altgr[i] != Key::None)
|
||||
m_keycode_to_key_altgr[i] = new_layout->m_keycode_to_key_altgr[i];
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstack-usage="
|
||||
static BAN::ErrorOr<void> initialize_name_to_key()
|
||||
{
|
||||
ASSERT(s_name_to_key.empty());
|
||||
TRY(s_name_to_key.insert("A_Ring"sv, Key::A_Ring));
|
||||
TRY(s_name_to_key.insert("A_Umlaut"sv, Key::A_Umlaut));
|
||||
TRY(s_name_to_key.insert("A"sv, Key::A));
|
||||
TRY(s_name_to_key.insert("Acute"sv, Key::Acute));
|
||||
TRY(s_name_to_key.insert("AltGr"sv, Key::AltGr));
|
||||
TRY(s_name_to_key.insert("Ampersand"sv, Key::Ampersand));
|
||||
TRY(s_name_to_key.insert("ArrowDown"sv, Key::ArrowDown));
|
||||
TRY(s_name_to_key.insert("ArrowLeft"sv, Key::ArrowLeft));
|
||||
TRY(s_name_to_key.insert("ArrowRight"sv, Key::ArrowRight));
|
||||
TRY(s_name_to_key.insert("ArrowUp"sv, Key::ArrowUp));
|
||||
TRY(s_name_to_key.insert("Asterix"sv, Key::Asterix));
|
||||
TRY(s_name_to_key.insert("AtSign"sv, Key::AtSign));
|
||||
TRY(s_name_to_key.insert("B"sv, Key::B));
|
||||
TRY(s_name_to_key.insert("BackSlash"sv, Key::BackSlash));
|
||||
TRY(s_name_to_key.insert("Backspace"sv, Key::Backspace));
|
||||
TRY(s_name_to_key.insert("BackTick"sv, Key::BackTick));
|
||||
TRY(s_name_to_key.insert("BrokenBar"sv, Key::BrokenBar));
|
||||
TRY(s_name_to_key.insert("C"sv, Key::C));
|
||||
TRY(s_name_to_key.insert("Calculator"sv, Key::Calculator));
|
||||
TRY(s_name_to_key.insert("CapsLock"sv, Key::CapsLock));
|
||||
TRY(s_name_to_key.insert("Caret"sv, Key::Caret));
|
||||
TRY(s_name_to_key.insert("Cedilla"sv, Key::Cedilla));
|
||||
TRY(s_name_to_key.insert("CloseCurlyBracket"sv, Key::CloseCurlyBracket));
|
||||
TRY(s_name_to_key.insert("CloseParenthesis"sv, Key::CloseParenthesis));
|
||||
TRY(s_name_to_key.insert("CloseSquareBracket"sv, Key::CloseSquareBracket));
|
||||
TRY(s_name_to_key.insert("Colon"sv, Key::Colon));
|
||||
TRY(s_name_to_key.insert("Comma"sv, Key::Comma));
|
||||
TRY(s_name_to_key.insert("Currency"sv, Key::Currency));
|
||||
TRY(s_name_to_key.insert("D"sv, Key::D));
|
||||
TRY(s_name_to_key.insert("Delete"sv, Key::Delete));
|
||||
TRY(s_name_to_key.insert("Dollar"sv, Key::Dollar));
|
||||
TRY(s_name_to_key.insert("DoubleQuote"sv, Key::DoubleQuote));
|
||||
TRY(s_name_to_key.insert("E"sv, Key::E));
|
||||
TRY(s_name_to_key.insert("End"sv, Key::End));
|
||||
TRY(s_name_to_key.insert("Enter"sv, Key::Enter));
|
||||
TRY(s_name_to_key.insert("Equals"sv, Key::Equals));
|
||||
TRY(s_name_to_key.insert("Escape"sv, Key::Escape));
|
||||
TRY(s_name_to_key.insert("Euro"sv, Key::Euro));
|
||||
TRY(s_name_to_key.insert("Exclamation"sv, Key::ExclamationMark));
|
||||
TRY(s_name_to_key.insert("ExclamationMark"sv, Key::ExclamationMark));
|
||||
TRY(s_name_to_key.insert("F"sv, Key::F));
|
||||
TRY(s_name_to_key.insert("F1"sv, Key::F1));
|
||||
TRY(s_name_to_key.insert("F10"sv, Key::F10));
|
||||
TRY(s_name_to_key.insert("F11"sv, Key::F11));
|
||||
TRY(s_name_to_key.insert("F12"sv, Key::F12));
|
||||
TRY(s_name_to_key.insert("F2"sv, Key::F2));
|
||||
TRY(s_name_to_key.insert("F3"sv, Key::F3));
|
||||
TRY(s_name_to_key.insert("F4"sv, Key::F4));
|
||||
TRY(s_name_to_key.insert("F5"sv, Key::F5));
|
||||
TRY(s_name_to_key.insert("F6"sv, Key::F6));
|
||||
TRY(s_name_to_key.insert("F7"sv, Key::F7));
|
||||
TRY(s_name_to_key.insert("F8"sv, Key::F8));
|
||||
TRY(s_name_to_key.insert("F9"sv, Key::F9));
|
||||
TRY(s_name_to_key.insert("G"sv, Key::G));
|
||||
TRY(s_name_to_key.insert("GreaterThan"sv, Key::GreaterThan));
|
||||
TRY(s_name_to_key.insert("H"sv, Key::H));
|
||||
TRY(s_name_to_key.insert("Half"sv, Key::Half));
|
||||
TRY(s_name_to_key.insert("Hashtag"sv, Key::Hashtag));
|
||||
TRY(s_name_to_key.insert("Home"sv, Key::Home));
|
||||
TRY(s_name_to_key.insert("Hyphen"sv, Key::Hyphen));
|
||||
TRY(s_name_to_key.insert("I"sv, Key::I));
|
||||
TRY(s_name_to_key.insert("Insert"sv, Key::Insert));
|
||||
TRY(s_name_to_key.insert("J"sv, Key::J));
|
||||
TRY(s_name_to_key.insert("K"sv, Key::K));
|
||||
TRY(s_name_to_key.insert("Key0"sv, Key::_0));
|
||||
TRY(s_name_to_key.insert("Key1"sv, Key::_1));
|
||||
TRY(s_name_to_key.insert("Key2"sv, Key::_2));
|
||||
TRY(s_name_to_key.insert("Key3"sv, Key::_3));
|
||||
TRY(s_name_to_key.insert("Key4"sv, Key::_4));
|
||||
TRY(s_name_to_key.insert("Key5"sv, Key::_5));
|
||||
TRY(s_name_to_key.insert("Key6"sv, Key::_6));
|
||||
TRY(s_name_to_key.insert("Key7"sv, Key::_7));
|
||||
TRY(s_name_to_key.insert("Key8"sv, Key::_8));
|
||||
TRY(s_name_to_key.insert("Key9"sv, Key::_9));
|
||||
TRY(s_name_to_key.insert("L"sv, Key::L));
|
||||
TRY(s_name_to_key.insert("LAlt"sv, Key::LeftAlt));
|
||||
TRY(s_name_to_key.insert("LControl"sv, Key::LeftCtrl));
|
||||
TRY(s_name_to_key.insert("LeftAlt"sv, Key::LeftAlt));
|
||||
TRY(s_name_to_key.insert("LeftControl"sv, Key::LeftCtrl));
|
||||
TRY(s_name_to_key.insert("LeftShift"sv, Key::LeftShift));
|
||||
TRY(s_name_to_key.insert("LessThan"sv, Key::LessThan));
|
||||
TRY(s_name_to_key.insert("LShift"sv, Key::LeftShift));
|
||||
TRY(s_name_to_key.insert("M"sv, Key::M));
|
||||
TRY(s_name_to_key.insert("MediaNext"sv, Key::MediaNext));
|
||||
TRY(s_name_to_key.insert("MediaPlayPause"sv, Key::MediaPlayPause));
|
||||
TRY(s_name_to_key.insert("MediaPrevious"sv, Key::MediaPrevious));
|
||||
TRY(s_name_to_key.insert("MediaStop"sv, Key::MediaStop));
|
||||
TRY(s_name_to_key.insert("N"sv, Key::N));
|
||||
TRY(s_name_to_key.insert("Negation"sv, Key::Negation));
|
||||
TRY(s_name_to_key.insert("None"sv, Key::None));
|
||||
TRY(s_name_to_key.insert("NumLock"sv, Key::NumLock));
|
||||
TRY(s_name_to_key.insert("Numpad0"sv, Key::Numpad0));
|
||||
TRY(s_name_to_key.insert("Numpad1"sv, Key::Numpad1));
|
||||
TRY(s_name_to_key.insert("Numpad2"sv, Key::Numpad2));
|
||||
TRY(s_name_to_key.insert("Numpad3"sv, Key::Numpad3));
|
||||
TRY(s_name_to_key.insert("Numpad4"sv, Key::Numpad4));
|
||||
TRY(s_name_to_key.insert("Numpad5"sv, Key::Numpad5));
|
||||
TRY(s_name_to_key.insert("Numpad6"sv, Key::Numpad6));
|
||||
TRY(s_name_to_key.insert("Numpad7"sv, Key::Numpad7));
|
||||
TRY(s_name_to_key.insert("Numpad8"sv, Key::Numpad8));
|
||||
TRY(s_name_to_key.insert("Numpad9"sv, Key::Numpad9));
|
||||
TRY(s_name_to_key.insert("NumpadDecimal"sv, Key::NumpadDecimal));
|
||||
TRY(s_name_to_key.insert("NumpadDivide"sv, Key::NumpadDivide));
|
||||
TRY(s_name_to_key.insert("NumpadEnter"sv, Key::NumpadEnter));
|
||||
TRY(s_name_to_key.insert("NumpadMinus"sv, Key::NumpadMinus));
|
||||
TRY(s_name_to_key.insert("NumpadMultiply"sv, Key::NumpadMultiply));
|
||||
TRY(s_name_to_key.insert("NumpadPlus"sv, Key::NumpadPlus));
|
||||
TRY(s_name_to_key.insert("O_Umlaut"sv, Key::O_Umlaut));
|
||||
TRY(s_name_to_key.insert("O"sv, Key::O));
|
||||
TRY(s_name_to_key.insert("OpenCurlyBracket"sv, Key::OpenCurlyBracket));
|
||||
TRY(s_name_to_key.insert("OpenParenthesis"sv, Key::OpenParenthesis));
|
||||
TRY(s_name_to_key.insert("OpenSquareBracket"sv, Key::OpenSquareBracket));
|
||||
TRY(s_name_to_key.insert("P"sv, Key::P));
|
||||
TRY(s_name_to_key.insert("PageDown"sv, Key::PageDown));
|
||||
TRY(s_name_to_key.insert("PageUp"sv, Key::PageUp));
|
||||
TRY(s_name_to_key.insert("Percent"sv, Key::Percent));
|
||||
TRY(s_name_to_key.insert("Period"sv, Key::Period));
|
||||
TRY(s_name_to_key.insert("Pipe"sv, Key::Pipe));
|
||||
TRY(s_name_to_key.insert("Plus"sv, Key::Plus));
|
||||
TRY(s_name_to_key.insert("Pound"sv, Key::Pound));
|
||||
TRY(s_name_to_key.insert("PrintScreen"sv, Key::PrintScreen));
|
||||
TRY(s_name_to_key.insert("Q"sv, Key::Q));
|
||||
TRY(s_name_to_key.insert("Question"sv, Key::QuestionMark));
|
||||
TRY(s_name_to_key.insert("QuestionMark"sv, Key::QuestionMark));
|
||||
TRY(s_name_to_key.insert("R"sv, Key::R));
|
||||
TRY(s_name_to_key.insert("RAlt"sv, Key::RightAlt));
|
||||
TRY(s_name_to_key.insert("RControl"sv, Key::RightCtrl));
|
||||
TRY(s_name_to_key.insert("RightAlt"sv, Key::RightAlt));
|
||||
TRY(s_name_to_key.insert("RightControl"sv, Key::RightCtrl));
|
||||
TRY(s_name_to_key.insert("RightShift"sv, Key::RightShift));
|
||||
TRY(s_name_to_key.insert("RShift"sv, Key::RightShift));
|
||||
TRY(s_name_to_key.insert("S"sv, Key::S));
|
||||
TRY(s_name_to_key.insert("ScrollLock"sv, Key::ScrollLock));
|
||||
TRY(s_name_to_key.insert("Section"sv, Key::Section));
|
||||
TRY(s_name_to_key.insert("Semicolon"sv, Key::Semicolon));
|
||||
TRY(s_name_to_key.insert("SingleQuote"sv, Key::SingleQuote));
|
||||
TRY(s_name_to_key.insert("Slash"sv, Key::Slash));
|
||||
TRY(s_name_to_key.insert("Space"sv, Key::Space));
|
||||
TRY(s_name_to_key.insert("Super"sv, Key::Super));
|
||||
TRY(s_name_to_key.insert("T"sv, Key::T));
|
||||
TRY(s_name_to_key.insert("Tab"sv, Key::Tab));
|
||||
TRY(s_name_to_key.insert("Tilde"sv, Key::Tilde));
|
||||
TRY(s_name_to_key.insert("TwoDots"sv, Key::TwoDots));
|
||||
TRY(s_name_to_key.insert("U"sv, Key::U));
|
||||
TRY(s_name_to_key.insert("Underscore"sv, Key::Underscore));
|
||||
TRY(s_name_to_key.insert("V"sv, Key::V));
|
||||
TRY(s_name_to_key.insert("VolumeDown"sv, Key::VolumeDown));
|
||||
TRY(s_name_to_key.insert("VolumeMute"sv, Key::VolumeMute));
|
||||
TRY(s_name_to_key.insert("VolumeUp"sv, Key::VolumeUp));
|
||||
TRY(s_name_to_key.insert("W"sv, Key::W));
|
||||
TRY(s_name_to_key.insert("X"sv, Key::X));
|
||||
TRY(s_name_to_key.insert("Y"sv, Key::Y));
|
||||
TRY(s_name_to_key.insert("Z"sv, Key::Z));
|
||||
return {};
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Input/KeyboardLayout.h>
|
||||
#include <kernel/Input/PS2/Config.h>
|
||||
#include <kernel/Input/PS2/Keyboard.h>
|
||||
#include <kernel/Thread.h>
|
||||
#include <LibInput/KeyboardLayout.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
@@ -44,6 +44,10 @@ namespace Kernel::Input
|
||||
|
||||
void PS2Keyboard::handle_byte(uint8_t byte)
|
||||
{
|
||||
using LibInput::Key;
|
||||
using LibInput::RawKeyEvent;
|
||||
using KeyModifier = LibInput::KeyEvent::Modifier;
|
||||
|
||||
if (byte == PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN1 || byte == PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN2)
|
||||
{
|
||||
dwarnln("Key detection error or internal buffer overrun");
|
||||
@@ -123,25 +127,24 @@ namespace Kernel::Input
|
||||
if (!keycode.has_value())
|
||||
return;
|
||||
|
||||
auto key = KeyboardLayout::get().get_key_from_event(KeyEvent { .modifier = 0, .keycode = keycode.value() });
|
||||
|
||||
if (key == Key::F1)
|
||||
auto dummy_event = LibInput::KeyboardLayout::get().key_event_from_raw(RawKeyEvent { .modifier = 0, .keycode = keycode.value() });
|
||||
if (dummy_event.key == Key::F1)
|
||||
panic("OOF");
|
||||
|
||||
uint16_t modifier_mask = 0;
|
||||
uint16_t toggle_mask = 0;
|
||||
switch (key)
|
||||
switch (dummy_event.key)
|
||||
{
|
||||
case Key::LeftShift: modifier_mask = KeyEvent::Modifier::LShift; break;
|
||||
case Key::RightShift: modifier_mask = KeyEvent::Modifier::RShift; break;
|
||||
case Key::LeftCtrl: modifier_mask = KeyEvent::Modifier::LCtrl; break;
|
||||
case Key::RightCtrl: modifier_mask = KeyEvent::Modifier::RCtrl; break;
|
||||
case Key::LeftAlt: modifier_mask = KeyEvent::Modifier::LAlt; break;
|
||||
case Key::RightAlt: modifier_mask = KeyEvent::Modifier::RAlt; break;
|
||||
case Key::LeftShift: modifier_mask = KeyModifier::LShift; break;
|
||||
case Key::RightShift: modifier_mask = KeyModifier::RShift; break;
|
||||
case Key::LeftCtrl: modifier_mask = KeyModifier::LCtrl; break;
|
||||
case Key::RightCtrl: modifier_mask = KeyModifier::RCtrl; break;
|
||||
case Key::LeftAlt: modifier_mask = KeyModifier::LAlt; break;
|
||||
case Key::RightAlt: modifier_mask = KeyModifier::RAlt; break;
|
||||
|
||||
case Key::ScrollLock: toggle_mask = KeyEvent::Modifier::ScrollLock; break;
|
||||
case Key::NumLock: toggle_mask = KeyEvent::Modifier::NumLock; break;
|
||||
case Key::CapsLock: toggle_mask = KeyEvent::Modifier::CapsLock; break;
|
||||
case Key::ScrollLock: toggle_mask = KeyModifier::ScrollLock; break;
|
||||
case Key::NumLock: toggle_mask = KeyModifier::NumLock; break;
|
||||
case Key::CapsLock: toggle_mask = KeyModifier::CapsLock; break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
@@ -160,8 +163,8 @@ namespace Kernel::Input
|
||||
update_leds();
|
||||
}
|
||||
|
||||
KeyEvent event;
|
||||
event.modifier = m_modifiers | (released ? 0 : KeyEvent::Modifier::Pressed);
|
||||
RawKeyEvent event;
|
||||
event.modifier = m_modifiers | (released ? 0 : KeyModifier::Pressed);
|
||||
event.keycode = keycode.value();
|
||||
|
||||
SpinLockGuard _(m_event_lock);
|
||||
@@ -178,19 +181,23 @@ namespace Kernel::Input
|
||||
|
||||
void PS2Keyboard::update_leds()
|
||||
{
|
||||
using KeyModifier = LibInput::KeyEvent::Modifier;
|
||||
|
||||
uint8_t new_leds = 0;
|
||||
if (m_modifiers & +KeyEvent::Modifier::ScrollLock)
|
||||
if (m_modifiers & +KeyModifier::ScrollLock)
|
||||
new_leds |= PS2::KBLeds::SCROLL_LOCK;
|
||||
if (m_modifiers & +KeyEvent::Modifier::NumLock)
|
||||
if (m_modifiers & +KeyModifier::NumLock)
|
||||
new_leds |= PS2::KBLeds::NUM_LOCK;
|
||||
if (m_modifiers & +KeyEvent::Modifier::CapsLock)
|
||||
if (m_modifiers & +KeyModifier::CapsLock)
|
||||
new_leds |= PS2::KBLeds::CAPS_LOCK;
|
||||
append_command_queue(Command::SET_LEDS, new_leds, 0);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, BAN::ByteSpan buffer)
|
||||
{
|
||||
if (buffer.size() < sizeof(KeyEvent))
|
||||
using LibInput::RawKeyEvent;
|
||||
|
||||
if (buffer.size() < sizeof(RawKeyEvent))
|
||||
return BAN::Error::from_errno(ENOBUFS);
|
||||
|
||||
auto state = m_event_lock.lock();
|
||||
@@ -201,12 +208,12 @@ namespace Kernel::Input
|
||||
state = m_event_lock.lock();
|
||||
}
|
||||
|
||||
buffer.as<KeyEvent>() = m_event_queue.front();
|
||||
buffer.as<RawKeyEvent>() = m_event_queue.front();
|
||||
m_event_queue.pop();
|
||||
|
||||
m_event_lock.unlock(state);
|
||||
|
||||
return sizeof(KeyEvent);
|
||||
return sizeof(RawKeyEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Input/PS2/Keymap.h>
|
||||
#include <LibInput/KeyEvent.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
using LibInput::keycode_function;
|
||||
using LibInput::keycode_normal;
|
||||
using LibInput::keycode_numpad;
|
||||
|
||||
void PS2Keymap::initialize(uint8_t scancode_set)
|
||||
{
|
||||
|
||||
@@ -71,6 +71,10 @@ namespace Kernel::Input
|
||||
|
||||
void PS2Mouse::handle_byte(uint8_t byte)
|
||||
{
|
||||
using LibInput::MouseButton;
|
||||
using LibInput::MouseEvent;
|
||||
using LibInput::MouseEventType;
|
||||
|
||||
if (!m_enabled)
|
||||
return initialize_extensions(byte);
|
||||
|
||||
@@ -174,6 +178,8 @@ namespace Kernel::Input
|
||||
|
||||
BAN::ErrorOr<size_t> PS2Mouse::read_impl(off_t, BAN::ByteSpan buffer)
|
||||
{
|
||||
using LibInput::MouseEvent;
|
||||
|
||||
if (buffer.size() < sizeof(MouseEvent))
|
||||
return BAN::Error::from_errno(ENOBUFS);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <kernel/FS/ProcFS/FileSystem.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <kernel/Input/KeyboardLayout.h>
|
||||
#include <kernel/InterruptController.h>
|
||||
#include <kernel/Lock/LockGuard.h>
|
||||
#include <kernel/Memory/FileBackedRegion.h>
|
||||
@@ -17,6 +16,7 @@
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
#include <LibELF/LoadableELF.h>
|
||||
#include <LibInput/KeyboardLayout.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@@ -1460,7 +1460,7 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(EPERM);
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
TRY(Input::KeyboardLayout::get().load_from_file(absolute_path));
|
||||
TRY(LibInput::KeyboardLayout::get().load_from_file(absolute_path));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kernel/Lock/LockGuard.h>
|
||||
#include <kernel/Process.h>
|
||||
#include <kernel/Terminal/TTY.h>
|
||||
#include <LibInput/KeyboardLayout.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
@@ -94,10 +95,11 @@ namespace Kernel
|
||||
while (!TTY::current()->m_tty_ctrl.receive_input)
|
||||
TTY::current()->m_tty_ctrl.semaphore.block_indefinite();
|
||||
|
||||
Input::KeyEvent event;
|
||||
LibInput::RawKeyEvent event;
|
||||
size_t read = MUST(inode->read(0, BAN::ByteSpan::from(event)));
|
||||
ASSERT(read == sizeof(event));
|
||||
TTY::current()->on_key_event(event);
|
||||
|
||||
TTY::current()->on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
|
||||
}
|
||||
}, nullptr
|
||||
);
|
||||
@@ -120,71 +122,70 @@ namespace Kernel
|
||||
return {};
|
||||
}
|
||||
|
||||
void TTY::on_key_event(Input::KeyEvent event)
|
||||
void TTY::on_key_event(LibInput::KeyEvent event)
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
if (event.released())
|
||||
return;
|
||||
|
||||
Input::Key key = Input::key_event_to_key(event);
|
||||
const char* ansi_c_str = Input::key_to_utf8(key, event.modifier);
|
||||
const char* ansi_c_str = LibInput::key_to_utf8(event.key, event.modifier);
|
||||
|
||||
if (event.ctrl())
|
||||
{
|
||||
ansi_c_str = nullptr;
|
||||
switch (key)
|
||||
switch (event.key)
|
||||
{
|
||||
case Input::Key::A: ansi_c_str = "\x01"; break;
|
||||
case Input::Key::B: ansi_c_str = "\x02"; break;
|
||||
case Input::Key::C: ansi_c_str = "\x03"; break;
|
||||
case Input::Key::D: ansi_c_str = "\x04"; break;
|
||||
case Input::Key::E: ansi_c_str = "\x05"; break;
|
||||
case Input::Key::F: ansi_c_str = "\x06"; break;
|
||||
case Input::Key::G: ansi_c_str = "\x07"; break;
|
||||
case Input::Key::H: ansi_c_str = "\x08"; break;
|
||||
case Input::Key::I: ansi_c_str = "\x09"; break;
|
||||
case Input::Key::J: ansi_c_str = "\x0A"; break;
|
||||
case Input::Key::K: ansi_c_str = "\x0B"; break;
|
||||
case Input::Key::L: ansi_c_str = "\x0C"; break;
|
||||
case Input::Key::M: ansi_c_str = "\x0D"; break;
|
||||
case Input::Key::N: ansi_c_str = "\x0E"; break;
|
||||
case Input::Key::O: ansi_c_str = "\x0F"; break;
|
||||
case Input::Key::P: ansi_c_str = "\x10"; break;
|
||||
case Input::Key::Q: ansi_c_str = "\x11"; break;
|
||||
case Input::Key::R: ansi_c_str = "\x12"; break;
|
||||
case Input::Key::S: ansi_c_str = "\x13"; break;
|
||||
case Input::Key::T: ansi_c_str = "\x14"; break;
|
||||
case Input::Key::U: ansi_c_str = "\x15"; break;
|
||||
case Input::Key::V: ansi_c_str = "\x16"; break;
|
||||
case Input::Key::W: ansi_c_str = "\x17"; break;
|
||||
case Input::Key::X: ansi_c_str = "\x18"; break;
|
||||
case Input::Key::Y: ansi_c_str = "\x19"; break;
|
||||
case Input::Key::Z: ansi_c_str = "\x1A"; break;
|
||||
case LibInput::Key::A: ansi_c_str = "\x01"; break;
|
||||
case LibInput::Key::B: ansi_c_str = "\x02"; break;
|
||||
case LibInput::Key::C: ansi_c_str = "\x03"; break;
|
||||
case LibInput::Key::D: ansi_c_str = "\x04"; break;
|
||||
case LibInput::Key::E: ansi_c_str = "\x05"; break;
|
||||
case LibInput::Key::F: ansi_c_str = "\x06"; break;
|
||||
case LibInput::Key::G: ansi_c_str = "\x07"; break;
|
||||
case LibInput::Key::H: ansi_c_str = "\x08"; break;
|
||||
case LibInput::Key::I: ansi_c_str = "\x09"; break;
|
||||
case LibInput::Key::J: ansi_c_str = "\x0A"; break;
|
||||
case LibInput::Key::K: ansi_c_str = "\x0B"; break;
|
||||
case LibInput::Key::L: ansi_c_str = "\x0C"; break;
|
||||
case LibInput::Key::M: ansi_c_str = "\x0D"; break;
|
||||
case LibInput::Key::N: ansi_c_str = "\x0E"; break;
|
||||
case LibInput::Key::O: ansi_c_str = "\x0F"; break;
|
||||
case LibInput::Key::P: ansi_c_str = "\x10"; break;
|
||||
case LibInput::Key::Q: ansi_c_str = "\x11"; break;
|
||||
case LibInput::Key::R: ansi_c_str = "\x12"; break;
|
||||
case LibInput::Key::S: ansi_c_str = "\x13"; break;
|
||||
case LibInput::Key::T: ansi_c_str = "\x14"; break;
|
||||
case LibInput::Key::U: ansi_c_str = "\x15"; break;
|
||||
case LibInput::Key::V: ansi_c_str = "\x16"; break;
|
||||
case LibInput::Key::W: ansi_c_str = "\x17"; break;
|
||||
case LibInput::Key::X: ansi_c_str = "\x18"; break;
|
||||
case LibInput::Key::Y: ansi_c_str = "\x19"; break;
|
||||
case LibInput::Key::Z: ansi_c_str = "\x1A"; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (key)
|
||||
switch (event.key)
|
||||
{
|
||||
case Input::Key::Enter:
|
||||
case Input::Key::NumpadEnter:
|
||||
case LibInput::Key::Enter:
|
||||
case LibInput::Key::NumpadEnter:
|
||||
ansi_c_str = "\n";
|
||||
break;
|
||||
case Input::Key::Backspace:
|
||||
case LibInput::Key::Backspace:
|
||||
ansi_c_str = "\b";
|
||||
break;
|
||||
case Input::Key::ArrowUp:
|
||||
case LibInput::Key::ArrowUp:
|
||||
ansi_c_str = "\e[A";
|
||||
break;
|
||||
case Input::Key::ArrowDown:
|
||||
case LibInput::Key::ArrowDown:
|
||||
ansi_c_str = "\e[B";
|
||||
break;
|
||||
case Input::Key::ArrowRight:
|
||||
case LibInput::Key::ArrowRight:
|
||||
ansi_c_str = "\e[C";
|
||||
break;
|
||||
case Input::Key::ArrowLeft:
|
||||
case LibInput::Key::ArrowLeft:
|
||||
ansi_c_str = "\e[D";
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/GDT.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <kernel/Input/KeyboardLayout.h>
|
||||
#include <kernel/Input/PS2/Controller.h>
|
||||
#include <kernel/InterruptController.h>
|
||||
#include <kernel/kprint.h>
|
||||
@@ -28,6 +27,8 @@
|
||||
#include <kernel/Terminal/VirtualTTY.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
#include <LibInput/KeyboardLayout.h>
|
||||
|
||||
struct ParsedCommandLine
|
||||
{
|
||||
bool force_pic = false;
|
||||
@@ -194,7 +195,7 @@ static void init2(void*)
|
||||
#endif
|
||||
|
||||
// Initialize empty keymap
|
||||
MUST(Input::KeyboardLayout::initialize());
|
||||
MUST(LibInput::KeyboardLayout::initialize());
|
||||
if (auto res = PS2Controller::initialize(); res.is_error())
|
||||
dprintln("{}", res.error());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user