Kernel: Rework the whole input system
We now use Device abstraction that will allow us to provide devices to userspace through /dev. Currently Shell reads from first and only device (it being PS/2 Keyboard).
This commit is contained in:
@@ -21,6 +21,65 @@ namespace Kernel
|
||||
uint32_t creator_revision;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct FADT : public SDTHeader
|
||||
{
|
||||
uint32_t firmware_ctrl;
|
||||
uint32_t dsdt;
|
||||
uint8_t __reserved;
|
||||
uint8_t preferred_pm_profile;
|
||||
uint16_t sci_int;
|
||||
uint32_t smi_cmd;
|
||||
uint8_t acpi_enable;
|
||||
uint8_t acpi_disable;
|
||||
uint8_t s4bios_req;
|
||||
uint8_t pstate_cnt;
|
||||
uint32_t pm1a_evt_blk;
|
||||
uint32_t pm1b_evt_blk;
|
||||
uint32_t pm1a_cnt_blk;
|
||||
uint32_t pm1b_cnt_blk;
|
||||
uint32_t pm2_cnt_blk;
|
||||
uint32_t pm_tmr_blk;
|
||||
uint32_t gpe0_blk;
|
||||
uint32_t gpe1_blk;
|
||||
uint8_t pm1_evt_len;
|
||||
uint8_t pm1_cnt_len;
|
||||
uint8_t pm2_cnt_len;
|
||||
uint8_t pm_tmr_len;
|
||||
uint8_t gpe0_blk_len;
|
||||
uint8_t gpe1_blk_len;
|
||||
uint8_t gpe1_base;
|
||||
uint8_t cst_cnt;
|
||||
uint16_t p_lvl2_lat;
|
||||
uint16_t p_lvl3_lat;
|
||||
uint16_t flush_size;
|
||||
uint16_t flush_stride;
|
||||
uint8_t duty_offset;
|
||||
uint8_t duty_width;
|
||||
uint8_t day_alrm;
|
||||
uint8_t mon_alrm;
|
||||
uint8_t century;
|
||||
uint16_t iapc_boot_arch;
|
||||
uint8_t __reserved2;
|
||||
uint32_t flags;
|
||||
uint8_t reset_reg[12];
|
||||
uint8_t reset_value;
|
||||
uint16_t arm_boot_arch;
|
||||
uint8_t fadt_minor_version;
|
||||
uint64_t x_firmware_version;
|
||||
uint64_t x_dsdt;
|
||||
uint8_t x_pm1a_evt_blk[12];
|
||||
uint8_t x_pm1b_evt_blk[12];
|
||||
uint8_t x_pm1a_cnt_blk[12];
|
||||
uint8_t x_pm1b_cnt_blk[12];
|
||||
uint8_t x_pm2_cnt_blk[12];
|
||||
uint8_t x_pm_tmr_blk[12];
|
||||
uint8_t x_gpe0_blk[12];
|
||||
uint8_t x_gpe1_blk[12];
|
||||
uint8_t sleep_control_reg[12];
|
||||
uint8_t sleep_status_reg[12];
|
||||
uint64_t hypervison_vendor_identity;
|
||||
} __attribute__((packed));
|
||||
|
||||
public:
|
||||
static BAN::ErrorOr<void> initialize();
|
||||
static ACPI& get();
|
||||
|
||||
59
kernel/include/kernel/Device.h
Normal file
59
kernel/include/kernel/Device.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
BlockDevice,
|
||||
CharacterDevice,
|
||||
DeviceController
|
||||
};
|
||||
|
||||
virtual ~Device() {}
|
||||
virtual Type type() const = 0;
|
||||
virtual void update() {}
|
||||
};
|
||||
|
||||
class BlockDevice : public Device
|
||||
{
|
||||
public:
|
||||
virtual Type type() const override { return Type::BlockDevice; }
|
||||
};
|
||||
|
||||
class CharacterDevice : public Device
|
||||
{
|
||||
public:
|
||||
virtual Type type() const override { return Type::CharacterDevice; }
|
||||
|
||||
virtual BAN::ErrorOr<void> read(BAN::Span<uint8_t>);
|
||||
};
|
||||
|
||||
class DeviceManager
|
||||
{
|
||||
BAN_NON_COPYABLE(DeviceManager);
|
||||
BAN_NON_MOVABLE(DeviceManager);
|
||||
|
||||
public:
|
||||
static DeviceManager& get();
|
||||
|
||||
void update();
|
||||
void add_device(Device*);
|
||||
|
||||
BAN::Vector<Device*> devices() { return m_devices; }
|
||||
|
||||
private:
|
||||
DeviceManager() = default;
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
BAN::Vector<Device*> m_devices;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Function.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Input
|
||||
{
|
||||
|
||||
enum class Key : uint8_t
|
||||
{
|
||||
INVALID, None,
|
||||
_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_Dot, A_Dots, O_Dots,
|
||||
|
||||
Comma, Colon, Period, Semicolon, Hyphen, Underscore, SingleQuote, Asterix, Caret, Tilde,
|
||||
ExclamationMark, QuestionMark, DoubleQuote, Hashtag, Percent, Ampersand, Slash, BackSlash, Plus, Equals,
|
||||
OpenParen, CloseParen, OpenBracket, CloseBracket, OpenBrace, CloseBrace,
|
||||
Dollar, Pound, Euro, Currency, Enter, Space, Tab, Backspace, LessThan, MoreThan, Tick, BackTick, Section, Half, At, Pipe,
|
||||
End, Home, Insert, Delete, Super, PageUp, PageDown, PrintScreen, Left, Right, Up, Down,
|
||||
|
||||
LeftShift, RightShift, CapsLock, LeftCtrl, RightCtrl, LeftAlt, RightAlt, NumLock, ScrollLock, Escape,
|
||||
|
||||
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
|
||||
NumpadSep, NumpadPlus, NumpadMult, NumpadDiv, NumpadMinus, NumpadEnter,
|
||||
|
||||
Mute, VolumeDown, VolumeUp, Calculator, PlayPause, Stop, PreviousTrack, NextTrack,
|
||||
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
struct KeyEvent
|
||||
{
|
||||
Key key;
|
||||
uint8_t modifiers;
|
||||
bool pressed;
|
||||
};
|
||||
|
||||
enum class MouseButton
|
||||
{
|
||||
Left, Right, Middle,
|
||||
};
|
||||
struct MouseButtonEvent
|
||||
{
|
||||
MouseButton button;
|
||||
};
|
||||
|
||||
struct MouseMoveEvent
|
||||
{
|
||||
int16_t dx;
|
||||
int16_t dy;
|
||||
};
|
||||
|
||||
|
||||
bool initialize();
|
||||
void update();
|
||||
bool is_key_down(Key);
|
||||
|
||||
void register_key_event_callback(const BAN::Function<void(KeyEvent)>&);
|
||||
void register_mouse_button_event_callback(const BAN::Function<void(MouseButtonEvent)>&);
|
||||
void register_mouse_move_event_callback(const BAN::Function<void(MouseMoveEvent)>&);
|
||||
|
||||
const char* key_event_to_utf8(KeyEvent);
|
||||
|
||||
}
|
||||
99
kernel/include/kernel/Input/KeyEvent.h
Normal file
99
kernel/include/kernel/Input/KeyEvent.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
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,
|
||||
OpenBracet, CloseBracet, OpenBrace, CloseBrace, OpenCurlyBrace, CloseCurlyBrace,
|
||||
Equals, QuestionMark, Plus, BackSlash, Acute, BackTick, TwoDots, Backspace, AtSign, Pound, Dollar, Euro,
|
||||
Escape, Tab, CapsLock, LeftShift, LeftCtrl, Super, Alt, AltGr, RightCtrl, RightShift,
|
||||
SingleQuote, Asterix, Caret, Tilde, ArrowUp, ArrowDown, ArrowLeft, ArrowRight,
|
||||
Comma, Semicolon, Period, Colon, Hyphen, Underscore, NumLock, ScrollLock, LessThan, GreaterThan, Pipe,
|
||||
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 class Modifier : uint8_t
|
||||
{
|
||||
Shift = (1 << 0),
|
||||
Ctrl = (1 << 1),
|
||||
Alt = (1 << 2),
|
||||
AltGr = (1 << 3),
|
||||
CapsLock = (1 << 4),
|
||||
NumLock = (1 << 5),
|
||||
ScrollLock = (1 << 6),
|
||||
Released = (1 << 7),
|
||||
};
|
||||
|
||||
bool shift() const { return modifier & (uint8_t)Modifier::Shift; }
|
||||
bool ctrl() const { return modifier & (uint8_t)Modifier::Ctrl; }
|
||||
bool alt() const { return modifier & (uint8_t)Modifier::Alt; }
|
||||
bool altgr() const { return modifier & (uint8_t)Modifier::AltGr; }
|
||||
bool caps_lock() const { return modifier & (uint8_t)Modifier::CapsLock; }
|
||||
bool num_lock() const { return modifier & (uint8_t)Modifier::NumLock; }
|
||||
bool scroll_lock() const { return modifier & (uint8_t)Modifier::ScrollLock; }
|
||||
bool released() const { return modifier & (uint8_t)Modifier::Released; }
|
||||
bool pressed() const { return !released(); }
|
||||
|
||||
uint8_t modifier;
|
||||
Key key;
|
||||
};
|
||||
|
||||
inline const char* key_event_to_utf8(KeyEvent event)
|
||||
{
|
||||
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));
|
||||
|
||||
return (event.shift() ^ event.caps_lock()) ? utf8_upper[(uint8_t)event.key] : utf8_lower[(uint8_t)event.key];
|
||||
}
|
||||
|
||||
}
|
||||
38
kernel/include/kernel/Input/PS2Controller.h
Normal file
38
kernel/include/kernel/Input/PS2Controller.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/Device.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
class PS2Device : public CharacterDevice
|
||||
{
|
||||
public:
|
||||
virtual ~PS2Device() {}
|
||||
virtual void on_byte(uint8_t) = 0;
|
||||
};
|
||||
|
||||
class PS2Controller
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<void> initialize();
|
||||
static PS2Controller& get();
|
||||
|
||||
void send_byte(const PS2Device*, uint8_t);
|
||||
|
||||
private:
|
||||
PS2Controller() = default;
|
||||
BAN::ErrorOr<void> initialize_impl();
|
||||
BAN::ErrorOr<void> initialize_device(uint8_t);
|
||||
|
||||
BAN::ErrorOr<void> reset_device(uint8_t);
|
||||
BAN::ErrorOr<void> set_scanning(uint8_t, bool);
|
||||
|
||||
static void device0_irq();
|
||||
static void device1_irq();
|
||||
|
||||
private:
|
||||
PS2Device* m_devices[2] { nullptr, nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
64
kernel/include/kernel/Input/PS2Keyboard.h
Normal file
64
kernel/include/kernel/Input/PS2Keyboard.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/CircularQueue.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Input/PS2Controller.h>
|
||||
#include <kernel/Input/PS2Keymap.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
class PS2Keyboard final : public PS2Device
|
||||
{
|
||||
private:
|
||||
enum Command : uint8_t
|
||||
{
|
||||
SET_LEDS = 0xED,
|
||||
SCANCODE = 0xF0,
|
||||
ENABLE_SCANNING = 0xF4,
|
||||
DISABLE_SCANNING = 0xF5,
|
||||
};
|
||||
|
||||
enum class State
|
||||
{
|
||||
Normal,
|
||||
WaitingAck,
|
||||
};
|
||||
|
||||
public:
|
||||
static BAN::ErrorOr<PS2Keyboard*> create(PS2Controller&);
|
||||
|
||||
virtual void on_byte(uint8_t) override;
|
||||
virtual void update() override;
|
||||
|
||||
virtual BAN::ErrorOr<void> read(BAN::Span<uint8_t>) override;
|
||||
|
||||
private:
|
||||
PS2Keyboard(PS2Controller& controller)
|
||||
: m_controller(controller)
|
||||
{}
|
||||
BAN::ErrorOr<void> initialize();
|
||||
|
||||
void append_command_queue(uint8_t);
|
||||
void append_command_queue(uint8_t, uint8_t);
|
||||
|
||||
void buffer_has_key();
|
||||
|
||||
void update_leds();
|
||||
|
||||
private:
|
||||
PS2Controller& m_controller;
|
||||
uint8_t m_byte_buffer[10];
|
||||
uint8_t m_byte_index { 0 };
|
||||
|
||||
uint8_t m_modifiers { 0 };
|
||||
|
||||
BAN::CircularQueue<KeyEvent, 10> m_event_queue;
|
||||
BAN::CircularQueue<uint8_t, 10> m_command_queue;
|
||||
|
||||
PS2Keymap m_keymap;
|
||||
|
||||
State m_state { State::Normal };
|
||||
};
|
||||
|
||||
}
|
||||
23
kernel/include/kernel/Input/PS2Keymap.h
Normal file
23
kernel/include/kernel/Input/PS2Keymap.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
class PS2Keymap
|
||||
{
|
||||
public:
|
||||
PS2Keymap();
|
||||
|
||||
Key key_for_scancode_and_modifiers(uint32_t, uint8_t);
|
||||
|
||||
private:
|
||||
BAN::Vector<Key> m_normal_keymap;
|
||||
BAN::Vector<Key> m_shift_keymap;
|
||||
BAN::Vector<Key> m_altgr_keymap;
|
||||
BAN::Vector<Key> m_extended_keymap;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <BAN/String.h>
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/Input.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/TTY.h>
|
||||
|
||||
namespace Kernel
|
||||
|
||||
Reference in New Issue
Block a user