Compare commits
10 Commits
40f55be587
...
51214ea1bf
Author | SHA1 | Date |
---|---|---|
Bananymous | 51214ea1bf | |
Bananymous | 8f89519bcf | |
Bananymous | e6d42e5c45 | |
Bananymous | 961ab9768a | |
Bananymous | e4f48cbc73 | |
Bananymous | e8f853a197 | |
Bananymous | d760239748 | |
Bananymous | 2fec718590 | |
Bananymous | f0cf54e194 | |
Bananymous | 41ae05dd6e |
Binary file not shown.
|
@ -13,12 +13,10 @@
|
|||
|
||||
.global stage1_main
|
||||
stage1_main:
|
||||
# setup segments
|
||||
movw $0, %ax
|
||||
# setup segments and stack
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
|
||||
# setup stack
|
||||
movw %ax, %ss
|
||||
movl $0x7C00, %esp
|
||||
|
||||
|
@ -53,6 +51,8 @@ stage2_main:
|
|||
movw $hello_msg, %si
|
||||
call puts; call print_newline
|
||||
|
||||
lgdt gdtr
|
||||
|
||||
call enter_unreal_mode
|
||||
movw $unreal_enter_msg, %si
|
||||
call puts; call print_newline
|
||||
|
@ -86,32 +86,32 @@ stage2_main:
|
|||
|
||||
cli
|
||||
|
||||
# kernel entry point
|
||||
movl %eax, %ecx
|
||||
|
||||
# setup kernel parameters
|
||||
movl $0xD3C60CFF, %eax
|
||||
movl $banan_boot_info, %ebx
|
||||
|
||||
# setup protected mode
|
||||
movl %cr0, %ebx
|
||||
orb $1, %bl
|
||||
movl %ebx, %cr0
|
||||
movl %cr0, %edx
|
||||
orb $1, %dl
|
||||
movl %edx, %cr0
|
||||
|
||||
# jump to kernel in protected mode
|
||||
# jump to protected mode
|
||||
ljmpl $0x18, $protected_mode
|
||||
|
||||
|
||||
.code32
|
||||
protected_mode:
|
||||
movw $0x10, %bx
|
||||
movw %bx, %ds
|
||||
movw %bx, %es
|
||||
movw %bx, %fs
|
||||
movw %bx, %gs
|
||||
movw %bx, %ss
|
||||
|
||||
movl %eax, %ecx
|
||||
|
||||
movl $0xD3C60CFF, %eax
|
||||
movl $banan_boot_info, %ebx
|
||||
xorl %edx, %edx
|
||||
xorl %esi, %esi
|
||||
xorl %edi, %edi
|
||||
# setup protected mode segments
|
||||
movw $0x10, %dx
|
||||
movw %dx, %ds
|
||||
movw %dx, %es
|
||||
movw %dx, %fs
|
||||
movw %dx, %gs
|
||||
movw %dx, %ss
|
||||
|
||||
# jump to kernel entry
|
||||
jmp *%ecx
|
||||
|
||||
|
||||
|
@ -120,8 +120,6 @@ enter_unreal_mode:
|
|||
cli
|
||||
pushw %ds
|
||||
|
||||
lgdt gdtr
|
||||
|
||||
movl %cr0, %eax
|
||||
orb $1, %al
|
||||
movl %eax, %cr0
|
||||
|
@ -152,9 +150,9 @@ start_kernel_load_msg:
|
|||
|
||||
gdt:
|
||||
.quad 0x0000000000000000
|
||||
.quad 0x00009A000000FFFF
|
||||
.quad 0x00CF92000000FFFF
|
||||
.quad 0x00CF9A000000FFFF
|
||||
.quad 0x008F9A000000FFFF # 16-bit code
|
||||
.quad 0x00CF92000000FFFF # 32-bit data
|
||||
.quad 0x00CF9A000000FFFF # 32-bit code
|
||||
gdtr:
|
||||
.short . - gdt - 1
|
||||
.quad gdt
|
||||
|
|
|
@ -32,6 +32,8 @@ set(KERNEL_SOURCES
|
|||
kernel/FS/TmpFS/FileSystem.cpp
|
||||
kernel/FS/TmpFS/Inode.cpp
|
||||
kernel/FS/VirtualFileSystem.cpp
|
||||
kernel/Input/KeyboardLayout.cpp
|
||||
kernel/Input/KeyEvent.cpp
|
||||
kernel/Input/PS2/Controller.cpp
|
||||
kernel/Input/PS2/Device.cpp
|
||||
kernel/Input/PS2/Keyboard.cpp
|
||||
|
|
|
@ -11,10 +11,6 @@ namespace Kernel
|
|||
ACPI_NoRootSDT,
|
||||
ACPI_NoSuchHeader,
|
||||
ACPI_RootInvalid,
|
||||
PS2_Timeout,
|
||||
PS2_SelfTest,
|
||||
PS2_Reset,
|
||||
PS2_UnsupportedDevice,
|
||||
Ext2_Invalid,
|
||||
Ext2_Corrupted,
|
||||
Ext2_NoInodes,
|
||||
|
|
|
@ -5,6 +5,47 @@
|
|||
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 ModifierKeycode
|
||||
{
|
||||
CapsLock = keycode_normal(2, 0),
|
||||
NumLock = keycode_numpad(0, 0),
|
||||
ScrollLock = keycode_function(20),
|
||||
LShift = keycode_normal(3, 0),
|
||||
RShift = keycode_normal(3, 12),
|
||||
LCtrl = keycode_normal(4, 0),
|
||||
RCtrl = keycode_normal(4, 5),
|
||||
LAlt = keycode_normal(4, 2),
|
||||
RAlt = keycode_normal(4, 4),
|
||||
};
|
||||
|
||||
enum class Key
|
||||
{
|
||||
Invalid, None,
|
||||
|
@ -14,9 +55,9 @@ namespace Kernel::Input
|
|||
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,
|
||||
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,
|
||||
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
|
||||
|
@ -27,73 +68,44 @@ namespace Kernel::Input
|
|||
|
||||
struct KeyEvent
|
||||
{
|
||||
enum class Modifier : uint8_t
|
||||
enum Modifier : uint16_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),
|
||||
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 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(); }
|
||||
bool lshift() const { return modifier & Modifier::LShift; }
|
||||
bool rshift() const { return modifier & Modifier::RShift; }
|
||||
bool shift() const { return lshift() || rshift(); }
|
||||
|
||||
uint8_t modifier;
|
||||
Key key;
|
||||
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;
|
||||
};
|
||||
|
||||
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];
|
||||
}
|
||||
Key key_event_to_key(KeyEvent);
|
||||
const char* key_to_utf8(Key key, uint16_t modifier);
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <BAN/UniqPtr.h>
|
||||
#include <kernel/Input/KeyEvent.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;
|
||||
|
||||
friend class BAN::UniqPtr<KeyboardLayout>;
|
||||
};
|
||||
|
||||
}
|
|
@ -14,8 +14,8 @@ namespace Kernel::Input::PS2
|
|||
|
||||
enum Status : uint8_t
|
||||
{
|
||||
OUTPUT_FULL = (1 << 0),
|
||||
INPUT_FULL = (1 << 1),
|
||||
OUTPUT_STATUS = (1 << 0),
|
||||
INPUT_STATUS = (1 << 1),
|
||||
SYSTEM = (1 << 2),
|
||||
DEVICE_OR_CONTROLLER = (1 << 3),
|
||||
TIMEOUT_ERROR = (1 << 6),
|
||||
|
@ -78,13 +78,6 @@ namespace Kernel::Input::PS2
|
|||
KEY_ERROR_OR_BUFFER_OVERRUN2 = 0xFF,
|
||||
};
|
||||
|
||||
enum KBScancode : uint8_t
|
||||
{
|
||||
SET_SCANCODE_SET1 = 1,
|
||||
SET_SCANCODE_SET2 = 2,
|
||||
SET_SCANCODE_SET3 = 3,
|
||||
};
|
||||
|
||||
enum KBLeds : uint8_t
|
||||
{
|
||||
SCROLL_LOCK = (1 << 0),
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/CircularQueue.h>
|
||||
#include <BAN/UniqPtr.h>
|
||||
#include <kernel/Device/Device.h>
|
||||
#include <kernel/Input/PS2/Config.h>
|
||||
#include <kernel/InterruptController.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
@ -15,18 +18,50 @@ namespace Kernel::Input
|
|||
static BAN::ErrorOr<void> initialize();
|
||||
static PS2Controller& get();
|
||||
|
||||
void send_byte(const PS2Device*, uint8_t);
|
||||
bool append_command_queue(PS2Device*, uint8_t command, uint8_t response_size);
|
||||
bool append_command_queue(PS2Device*, uint8_t command, uint8_t data, uint8_t response_size);
|
||||
void update_command_queue();
|
||||
// Returns true, if byte is used as command, if returns false, byte is meant to device
|
||||
bool handle_command_byte(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);
|
||||
BAN::ErrorOr<uint8_t> read_byte();
|
||||
BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte);
|
||||
|
||||
BAN::ErrorOr<void> send_command(PS2::Command command);
|
||||
BAN::ErrorOr<void> send_command(PS2::Command command, uint8_t data);
|
||||
|
||||
BAN::ErrorOr<void> device_send_byte(uint8_t device_index, uint8_t byte);
|
||||
BAN::ErrorOr<void> device_send_byte_and_wait_ack(uint8_t device_index, uint8_t byte);
|
||||
|
||||
private:
|
||||
PS2Device* m_devices[2] { nullptr, nullptr };
|
||||
struct Command
|
||||
{
|
||||
enum class State : uint8_t
|
||||
{
|
||||
NotSent,
|
||||
Sending,
|
||||
WaitingAck,
|
||||
WaitingResponse,
|
||||
};
|
||||
State state;
|
||||
uint8_t device_index;
|
||||
uint8_t out_data[2];
|
||||
uint8_t out_count;
|
||||
uint8_t in_count;
|
||||
uint8_t send_index;
|
||||
};
|
||||
|
||||
private:
|
||||
BAN::RefPtr<PS2Device> m_devices[2];
|
||||
RecursiveSpinLock m_lock;
|
||||
|
||||
BAN::CircularQueue<Command, 128> m_command_queue;
|
||||
uint64_t m_command_send_time { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <kernel/Input/PS2/Controller.h>
|
||||
#include <kernel/InterruptController.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
@ -13,33 +14,23 @@ namespace Kernel::Input
|
|||
|
||||
virtual void send_initialize() = 0;
|
||||
|
||||
bool append_command_queue(uint8_t command);
|
||||
bool append_command_queue(uint8_t command, uint8_t data);
|
||||
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) = 0;
|
||||
|
||||
bool append_command_queue(uint8_t command, uint8_t response_size);
|
||||
bool append_command_queue(uint8_t command, uint8_t data, uint8_t response_size);
|
||||
virtual void handle_irq() final override;
|
||||
|
||||
virtual void handle_byte(uint8_t) = 0;
|
||||
virtual void handle_device_command_response(uint8_t) = 0;
|
||||
|
||||
virtual BAN::StringView name() const final override { return m_name; }
|
||||
virtual dev_t rdev() const final override { return m_rdev; }
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
||||
private:
|
||||
enum class State
|
||||
{
|
||||
Normal,
|
||||
WaitingAck,
|
||||
};
|
||||
virtual void update() final override { m_controller.update_command_queue(); }
|
||||
|
||||
private:
|
||||
const BAN::String m_name;
|
||||
const dev_t m_rdev;
|
||||
|
||||
PS2Controller& m_controller;
|
||||
State m_state = State::Normal;
|
||||
BAN::CircularQueue<uint8_t, 10> m_command_queue;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#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>
|
||||
|
@ -14,15 +16,16 @@ namespace Kernel::Input
|
|||
enum Command : uint8_t
|
||||
{
|
||||
SET_LEDS = 0xED,
|
||||
SCANCODE = 0xF0
|
||||
CONFIG_SCANCODE_SET = 0xF0
|
||||
};
|
||||
|
||||
public:
|
||||
static BAN::ErrorOr<PS2Keyboard*> create(PS2Controller&);
|
||||
virtual void send_initialize() override;
|
||||
|
||||
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) final override;
|
||||
|
||||
virtual void handle_byte(uint8_t) final override;
|
||||
virtual void handle_device_command_response(uint8_t) final override;
|
||||
|
||||
private:
|
||||
PS2Keyboard(PS2Controller& controller);
|
||||
|
@ -30,12 +33,14 @@ namespace Kernel::Input
|
|||
void update_leds();
|
||||
|
||||
private:
|
||||
uint8_t m_byte_buffer[10];
|
||||
BAN::Array<uint8_t, 3> m_byte_buffer;
|
||||
uint8_t m_byte_index { 0 };
|
||||
|
||||
uint8_t m_modifiers { 0 };
|
||||
uint8_t m_scancode_set { 0xFF };
|
||||
|
||||
BAN::CircularQueue<KeyEvent, 10> m_event_queue;
|
||||
uint16_t m_modifiers { 0 };
|
||||
|
||||
BAN::CircularQueue<KeyEvent, 50> m_event_queue;
|
||||
|
||||
PS2Keymap m_keymap;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <BAN/Array.h>
|
||||
#include <BAN/Optional.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
@ -9,15 +9,18 @@ namespace Kernel::Input
|
|||
class PS2Keymap
|
||||
{
|
||||
public:
|
||||
PS2Keymap();
|
||||
void initialize(uint8_t scancode_set);
|
||||
|
||||
Key key_for_scancode_and_modifiers(uint32_t, uint8_t);
|
||||
BAN::Optional<uint8_t> get_keycode(uint8_t scancode, bool extended) const;
|
||||
|
||||
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;
|
||||
void initialize_scancode_set1();
|
||||
void initialize_scancode_set2();
|
||||
void initialize_scancode_set3();
|
||||
|
||||
private:
|
||||
BAN::Array<uint8_t, 0xFF> m_scancode_to_keycode_normal;
|
||||
BAN::Array<uint8_t, 0xFF> m_scancode_to_keycode_extended;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -19,8 +19,9 @@ namespace Kernel::Input
|
|||
static BAN::ErrorOr<PS2Mouse*> create(PS2Controller&);
|
||||
virtual void send_initialize() override;
|
||||
|
||||
virtual void command_timedout(uint8_t* command_data, uint8_t command_size) final override {}
|
||||
|
||||
virtual void handle_byte(uint8_t) final override;
|
||||
virtual void handle_device_command_response(uint8_t) final override;
|
||||
|
||||
private:
|
||||
PS2Mouse(PS2Controller& controller);
|
||||
|
@ -35,7 +36,7 @@ namespace Kernel::Input
|
|||
uint8_t m_mouse_id { 0x00 };
|
||||
uint8_t m_button_mask { 0x00 };
|
||||
|
||||
BAN::CircularQueue<MouseEvent, 25> m_event_queue;
|
||||
BAN::CircularQueue<MouseEvent, 128> m_event_queue;
|
||||
|
||||
Semaphore m_semaphore;
|
||||
|
||||
|
|
|
@ -146,6 +146,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*);
|
||||
|
||||
BAN::ErrorOr<long> sys_load_keymap(const char* path);
|
||||
|
||||
TTY& tty() { ASSERT(m_controlling_terminal); return *m_controlling_terminal; }
|
||||
|
||||
static Process& current() { return Thread::current().process(); }
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Kernel
|
|||
bool add_signal(int signal);
|
||||
|
||||
// blocks semaphore and returns either on unblock, eintr or spuriously
|
||||
[[nodiscard]] bool block_or_eintr(Semaphore&);
|
||||
BAN::ErrorOr<void> block_or_eintr(Semaphore&);
|
||||
|
||||
void set_return_rsp(uintptr_t& rsp) { m_return_rsp = &rsp; }
|
||||
void set_return_rip(uintptr_t& rip) { m_return_rip = &rip; }
|
||||
|
|
|
@ -8,10 +8,6 @@ namespace Kernel
|
|||
"ACPI could not find root SDT header"sv,
|
||||
"ACPI no such header"sv,
|
||||
"ACPI root invalid",
|
||||
"PS/2 device timeout"sv,
|
||||
"PS/2 controller self test failed"sv,
|
||||
"PS/2 reset failed"sv,
|
||||
"PS/2 unsupported device"sv,
|
||||
"Invalid ext2 filesystem"sv,
|
||||
"Ext2 filesystem corrupted"sv,
|
||||
"Ext2 filesystem out of inodes"sv,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <kernel/FS/TmpFS/Inode.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Process.h>
|
||||
#include <kernel/Scheduler.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
|
@ -48,8 +49,7 @@ namespace Kernel
|
|||
}
|
||||
);
|
||||
s_instance->m_device_lock.unlock();
|
||||
|
||||
Kernel::SystemTimer::get().sleep(1);
|
||||
Scheduler::get().reschedule();
|
||||
}
|
||||
}, nullptr
|
||||
);
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#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)];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,346 @@
|
|||
#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)
|
||||
{
|
||||
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 {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> KeyboardLayout::load_from_file(BAN::StringView path)
|
||||
{
|
||||
if (s_name_to_key.empty())
|
||||
TRY(initialize_name_to_key());
|
||||
|
||||
auto inode = TRY(VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0)).inode;
|
||||
|
||||
BAN::String file_data;
|
||||
TRY(file_data.resize(inode->size()));
|
||||
TRY(inode->read(0, { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() }));
|
||||
|
||||
auto new_layout = TRY(BAN::UniqPtr<KeyboardLayout>::create());
|
||||
|
||||
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.size() == 1)
|
||||
{
|
||||
dprintln("Invalid line in keymap '{}'", line);
|
||||
dprintln(" format: KEYCODE KEY [MODIFIER=KEY]...");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto keycode = parse_keycode(parts.front());
|
||||
if (!keycode.has_value())
|
||||
{
|
||||
dprintln("Invalid keycode '{}', keycode must number between [0, 0xFF[", parts.front());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto default_key = parse_key(parts[1]);
|
||||
if (!default_key.has_value())
|
||||
{
|
||||
dprintln("Unrecognized key '{}'", parts[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
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]);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto key = parse_key(pair.back());
|
||||
if (!key.has_value())
|
||||
{
|
||||
dprintln("Unrecognized key '{}'", pair.back());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pair.front() == "shift"sv)
|
||||
new_layout->m_keycode_to_key_shift[*keycode] = *key;
|
||||
else if (pair.front() == "altgr"sv)
|
||||
new_layout->m_keycode_to_key_altgr[*keycode] = *key;
|
||||
else
|
||||
{
|
||||
dprintln("Unrecognized modifier '{}'", pair.front());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_keycode_to_key_normal = new_layout->m_keycode_to_key_normal;
|
||||
m_keycode_to_key_shift = new_layout->m_keycode_to_key_shift;
|
||||
m_keycode_to_key_altgr = new_layout->m_keycode_to_key_altgr;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
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("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("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 {};
|
||||
}
|
||||
|
||||
}
|
|
@ -10,65 +10,212 @@
|
|||
#include <kernel/IO.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
#define DEBUG_PS2 1
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
static constexpr uint64_t s_device_timeout_ms = 100;
|
||||
|
||||
static void controller_send_command(PS2::Command command)
|
||||
{
|
||||
IO::outb(PS2::IOPort::COMMAND, command);
|
||||
}
|
||||
|
||||
static void controller_send_command(PS2::Command command, uint8_t data)
|
||||
{
|
||||
IO::outb(PS2::IOPort::COMMAND, command);
|
||||
while (IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_FULL)
|
||||
continue;
|
||||
IO::outb(PS2::IOPort::DATA, data);
|
||||
}
|
||||
|
||||
static uint8_t wait_and_read()
|
||||
{
|
||||
while (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_FULL))
|
||||
continue;
|
||||
return IO::inb(PS2::IOPort::DATA);
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<void> device_send_byte(uint8_t device, uint8_t byte)
|
||||
{
|
||||
if (device == 1)
|
||||
IO::outb(PS2::IOPort::COMMAND, PS2::Command::WRITE_TO_SECOND_PORT);
|
||||
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_device_timeout_ms;
|
||||
while (SystemTimer::get().ms_since_boot() < timeout)
|
||||
{
|
||||
if (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_FULL))
|
||||
{
|
||||
IO::outb(PS2::IOPort::DATA, byte);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return BAN::Error::from_error_code(ErrorCode::PS2_Timeout);
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<uint8_t> device_read_byte()
|
||||
{
|
||||
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_device_timeout_ms;
|
||||
while (SystemTimer::get().ms_since_boot() < timeout)
|
||||
if (IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_FULL)
|
||||
return IO::inb(PS2::IOPort::DATA);
|
||||
return BAN::Error::from_error_code(ErrorCode::PS2_Timeout);
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<void> device_wait_ack()
|
||||
{
|
||||
while (TRY(device_read_byte()) != PS2::Response::ACK)
|
||||
continue;;
|
||||
return {};
|
||||
}
|
||||
static constexpr uint64_t s_ps2_timeout_ms = 100;
|
||||
|
||||
static PS2Controller* s_instance = nullptr;
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::send_byte(uint16_t port, uint8_t byte)
|
||||
{
|
||||
ASSERT(interrupts_enabled());
|
||||
LockGuard _(m_lock);
|
||||
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_ps2_timeout_ms;
|
||||
while (SystemTimer::get().ms_since_boot() < timeout)
|
||||
{
|
||||
if (IO::inb(PS2::IOPort::STATUS) & PS2::Status::INPUT_STATUS)
|
||||
continue;
|
||||
IO::outb(port, byte);
|
||||
return {};
|
||||
}
|
||||
return BAN::Error::from_errno(ETIMEDOUT);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<uint8_t> PS2Controller::read_byte()
|
||||
{
|
||||
ASSERT(interrupts_enabled());
|
||||
LockGuard _(m_lock);
|
||||
uint64_t timeout = SystemTimer::get().ms_since_boot() + s_ps2_timeout_ms;
|
||||
while (SystemTimer::get().ms_since_boot() < timeout)
|
||||
{
|
||||
if (!(IO::inb(PS2::IOPort::STATUS) & PS2::Status::OUTPUT_STATUS))
|
||||
continue;
|
||||
return IO::inb(PS2::IOPort::DATA);
|
||||
}
|
||||
return BAN::Error::from_errno(ETIMEDOUT);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::send_command(PS2::Command command)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
TRY(send_byte(PS2::IOPort::COMMAND, command));
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::send_command(PS2::Command command, uint8_t data)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
TRY(send_byte(PS2::IOPort::COMMAND, command));
|
||||
TRY(send_byte(PS2::IOPort::DATA, data));
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::device_send_byte(uint8_t device_index, uint8_t byte)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
if (device_index == 1)
|
||||
TRY(send_byte(PS2::IOPort::COMMAND, PS2::Command::WRITE_TO_SECOND_PORT));
|
||||
TRY(send_byte(PS2::IOPort::DATA, byte));
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::device_send_byte_and_wait_ack(uint8_t device_index, uint8_t byte)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
for (;;)
|
||||
{
|
||||
TRY(device_send_byte(device_index, byte));
|
||||
uint8_t response = TRY(read_byte());
|
||||
if (response == PS2::Response::RESEND)
|
||||
continue;
|
||||
if (response == PS2::Response::ACK)
|
||||
break;
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 device on port {} did not respond with expected ACK, got {2H}", device_index, byte);
|
||||
return BAN::Error::from_errno(EBADMSG);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool PS2Controller::append_command_queue(PS2Device* device, uint8_t command, uint8_t response_size)
|
||||
{
|
||||
// NOTE: command queue push/pop must be done without interrupts
|
||||
CriticalScope _;
|
||||
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
|
||||
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
|
||||
{
|
||||
dprintln("PS/2 command queue full");
|
||||
return false;
|
||||
}
|
||||
m_command_queue.push(Command {
|
||||
.state = Command::State::NotSent,
|
||||
.device_index = (device == m_devices[0].ptr()) ? uint8_t(0) : uint8_t(1),
|
||||
.out_data = { command, 0x00 },
|
||||
.out_count = 1,
|
||||
.in_count = response_size,
|
||||
.send_index = 0
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PS2Controller::append_command_queue(PS2Device* device, uint8_t command, uint8_t data, uint8_t response_size)
|
||||
{
|
||||
// NOTE: command queue push/pop must be done without interrupts
|
||||
CriticalScope _;
|
||||
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
|
||||
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
|
||||
{
|
||||
dprintln("PS/2 command queue full");
|
||||
return false;
|
||||
}
|
||||
m_command_queue.push(Command {
|
||||
.state = Command::State::NotSent,
|
||||
.device_index = (device == m_devices[0].ptr()) ? uint8_t(0) : uint8_t(1),
|
||||
.out_data = { command, data },
|
||||
.out_count = 2,
|
||||
.in_count = response_size,
|
||||
.send_index = 0
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void PS2Controller::update_command_queue()
|
||||
{
|
||||
ASSERT(interrupts_enabled());
|
||||
|
||||
if (m_command_queue.empty())
|
||||
return;
|
||||
auto& command = m_command_queue.front();
|
||||
if (command.state == Command::State::WaitingResponse || command.state == Command::State::WaitingAck)
|
||||
{
|
||||
if (SystemTimer::get().ms_since_boot() >= m_command_send_time + s_ps2_timeout_ms)
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "Command timedout");
|
||||
m_devices[command.device_index]->command_timedout(command.out_data, command.out_count);
|
||||
m_command_queue.pop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
ASSERT(command.send_index < command.out_count);
|
||||
command.state = Command::State::WaitingAck;
|
||||
m_command_send_time = SystemTimer::get().ms_since_boot();
|
||||
if (auto ret = device_send_byte(command.device_index, command.out_data[command.send_index]); ret.is_error())
|
||||
{
|
||||
command.state = Command::State::Sending;
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 send command byte: {}", ret.error());
|
||||
}
|
||||
}
|
||||
|
||||
bool PS2Controller::handle_command_byte(PS2Device* device, uint8_t byte)
|
||||
{
|
||||
// NOTE: command queue push/pop must be done without interrupts
|
||||
ASSERT(!interrupts_enabled());
|
||||
|
||||
if (m_command_queue.empty())
|
||||
return false;
|
||||
auto& command = m_command_queue.front();
|
||||
|
||||
ASSERT(device && (device == m_devices[0].ptr() || device == m_devices[1].ptr()));
|
||||
if (command.device_index != (device == m_devices[0].ptr()) ? 0 : 1)
|
||||
return false;
|
||||
|
||||
switch (command.state)
|
||||
{
|
||||
case Command::State::NotSent:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case Command::State::Sending:
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 device sent byte while middle of command send");
|
||||
return false;
|
||||
}
|
||||
case Command::State::WaitingResponse:
|
||||
{
|
||||
if (--command.in_count <= 0)
|
||||
m_command_queue.pop();
|
||||
return false;
|
||||
}
|
||||
case Command::State::WaitingAck:
|
||||
{
|
||||
switch (byte)
|
||||
{
|
||||
case PS2::Response::ACK:
|
||||
{
|
||||
if (++command.send_index < command.out_count)
|
||||
command.state = Command::State::Sending;
|
||||
else if (command.in_count > 0)
|
||||
command.state = Command::State::WaitingResponse;
|
||||
else
|
||||
m_command_queue.pop();
|
||||
return true;
|
||||
}
|
||||
case PS2::Response::RESEND:
|
||||
command.state = Command::State::Sending;
|
||||
return true;
|
||||
default:
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 expected ACK got {2H}", byte);
|
||||
command.state = Command::State::Sending;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::initialize()
|
||||
{
|
||||
ASSERT(s_instance == nullptr);
|
||||
|
@ -89,88 +236,96 @@ namespace Kernel::Input
|
|||
|
||||
BAN::ErrorOr<void> PS2Controller::initialize_impl()
|
||||
{
|
||||
// Step 1: Initialise USB Controllers
|
||||
// FIXME
|
||||
// FIXME: Initialise USB Controllers
|
||||
|
||||
// Step 2: Determine if the PS/2 Controller Exists
|
||||
// FIXME
|
||||
// Determine if the PS/2 Controller Exists
|
||||
auto* fadt = static_cast<const ACPI::FADT*>(ACPI::get().get_header("FACP"sv, 0));
|
||||
if (fadt && fadt->revision > 1 && !(fadt->iapc_boot_arch & (1 << 1)))
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "No PS/2 available");
|
||||
return {};
|
||||
}
|
||||
|
||||
// Step 3: Disable Devices
|
||||
controller_send_command(PS2::Command::DISABLE_FIRST_PORT);
|
||||
controller_send_command(PS2::Command::DISABLE_SECOND_PORT);
|
||||
// Disable Devices
|
||||
TRY(send_command(PS2::Command::DISABLE_FIRST_PORT));
|
||||
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT));
|
||||
|
||||
// Step 4: Flush The Output Buffer
|
||||
IO::inb(PS2::IOPort::DATA);
|
||||
// Flush The Output Buffer
|
||||
while (!read_byte().is_error())
|
||||
continue;
|
||||
|
||||
// Step 5: Set the Controller Configuration Byte
|
||||
controller_send_command(PS2::Command::READ_CONFIG);
|
||||
uint8_t config = wait_and_read();
|
||||
// Set the Controller Configuration Byte
|
||||
TRY(send_command(PS2::Command::READ_CONFIG));
|
||||
uint8_t config = TRY(read_byte());
|
||||
config &= ~PS2::Config::INTERRUPT_FIRST_PORT;
|
||||
config &= ~PS2::Config::INTERRUPT_SECOND_PORT;
|
||||
config &= ~PS2::Config::TRANSLATION_FIRST_PORT;
|
||||
controller_send_command(PS2::Command::WRITE_CONFIG, config);
|
||||
TRY(send_command(PS2::Command::WRITE_CONFIG, config));
|
||||
|
||||
// Step 6: Perform Controller Self Test
|
||||
controller_send_command(PS2::Command::TEST_CONTROLLER);
|
||||
if (wait_and_read() != PS2::Response::TEST_CONTROLLER_PASS)
|
||||
return BAN::Error::from_error_code(ErrorCode::PS2_SelfTest);
|
||||
// Perform Controller Self Test
|
||||
TRY(send_command(PS2::Command::TEST_CONTROLLER));
|
||||
if (TRY(read_byte()) != PS2::Response::TEST_CONTROLLER_PASS)
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 Controller test failed");
|
||||
return BAN::Error::from_errno(ENODEV);
|
||||
}
|
||||
// NOTE: self test might reset the device so we set the config byte again
|
||||
controller_send_command(PS2::Command::WRITE_CONFIG, config);
|
||||
TRY(send_command(PS2::Command::WRITE_CONFIG, config));
|
||||
|
||||
// Step 7: Determine If There Are 2 Channels
|
||||
// Determine If There Are 2 Channels
|
||||
bool valid_ports[2] { true, false };
|
||||
if (config & PS2::Config::CLOCK_SECOND_PORT)
|
||||
{
|
||||
controller_send_command(PS2::Command::ENABLE_SECOND_PORT);
|
||||
controller_send_command(PS2::Command::READ_CONFIG);
|
||||
if (!(wait_and_read() & PS2::Config::CLOCK_SECOND_PORT))
|
||||
TRY(send_command(PS2::Command::ENABLE_SECOND_PORT));
|
||||
TRY(send_command(PS2::Command::READ_CONFIG));
|
||||
if (!(TRY(read_byte()) & PS2::Config::CLOCK_SECOND_PORT))
|
||||
{
|
||||
valid_ports[1] = true;
|
||||
controller_send_command(PS2::Command::DISABLE_SECOND_PORT);
|
||||
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 8: Perform Interface Tests
|
||||
controller_send_command(PS2::Command::TEST_FIRST_PORT);
|
||||
if (wait_and_read() != PS2::Response::TEST_FIRST_PORT_PASS)
|
||||
// Perform Interface Tests
|
||||
TRY(send_command(PS2::Command::TEST_FIRST_PORT));
|
||||
if (TRY(read_byte()) != PS2::Response::TEST_FIRST_PORT_PASS)
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 first port test failed");
|
||||
valid_ports[0] = false;
|
||||
}
|
||||
if (valid_ports[1])
|
||||
{
|
||||
controller_send_command(PS2::Command::TEST_SECOND_PORT);
|
||||
if (wait_and_read() != PS2::Response::TEST_SECOND_PORT_PASS)
|
||||
TRY(send_command(PS2::Command::TEST_SECOND_PORT));
|
||||
if (TRY(read_byte()) != PS2::Response::TEST_SECOND_PORT_PASS)
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 second port test failed");
|
||||
valid_ports[1] = false;
|
||||
}
|
||||
}
|
||||
if (!valid_ports[0] && !valid_ports[1])
|
||||
return {};
|
||||
|
||||
// Step 9: Enable Devices (and disable scanning)
|
||||
// Initialize devices
|
||||
for (uint8_t device = 0; device < 2; device++)
|
||||
{
|
||||
if (!valid_ports[device])
|
||||
continue;
|
||||
controller_send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT);
|
||||
if (set_scanning(device, false).is_error())
|
||||
valid_ports[device] = false;
|
||||
if (auto ret = send_command(device == 0 ? PS2::Command::ENABLE_FIRST_PORT : PS2::Command::ENABLE_SECOND_PORT); ret.is_error())
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 device enable failed: {}", ret.error());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Step 10: Reset Devices
|
||||
for (uint8_t device = 0; device < 2; device++)
|
||||
{
|
||||
if (!valid_ports[device])
|
||||
continue;
|
||||
if (reset_device(device).is_error())
|
||||
valid_ports[device] = false;
|
||||
if (set_scanning(device, false).is_error())
|
||||
valid_ports[device] = false;
|
||||
}
|
||||
|
||||
// Step 11: Initialize Device Drivers
|
||||
for (uint8_t device = 0; device < 2; device++)
|
||||
{
|
||||
if (!valid_ports[device])
|
||||
continue;
|
||||
if (auto res = initialize_device(device); res.is_error())
|
||||
dprintln("{}", res.error());
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 device initialization failed: {}", res.error());
|
||||
(void)send_command(device == 0 ? PS2::Command::DISABLE_FIRST_PORT : PS2::Command::DISABLE_SECOND_PORT);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_devices[0] && !m_devices[1])
|
||||
return {};
|
||||
|
||||
// Enable irqs on valid devices
|
||||
if (m_devices[0])
|
||||
{
|
||||
m_devices[0]->set_irq(PS2::IRQ::DEVICE0);
|
||||
|
@ -184,11 +339,12 @@ namespace Kernel::Input
|
|||
config |= PS2::Config::INTERRUPT_SECOND_PORT;
|
||||
}
|
||||
|
||||
controller_send_command(PS2::Command::WRITE_CONFIG, config);
|
||||
TRY(send_command(PS2::Command::WRITE_CONFIG, config));
|
||||
|
||||
// Send device initialization sequence after interrupts are enabled
|
||||
for (uint8_t device = 0; device < 2; device++)
|
||||
{
|
||||
if (m_devices[device] == nullptr)
|
||||
if (!m_devices[device])
|
||||
continue;
|
||||
m_devices[device]->send_initialize();
|
||||
DevFileSystem::get().add_device(m_devices[device]);
|
||||
|
@ -199,14 +355,30 @@ namespace Kernel::Input
|
|||
|
||||
BAN::ErrorOr<void> PS2Controller::initialize_device(uint8_t device)
|
||||
{
|
||||
TRY(device_send_byte(device, PS2::DeviceCommand::IDENTIFY));
|
||||
TRY(device_wait_ack());
|
||||
// Reset device
|
||||
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::RESET));
|
||||
if (TRY(read_byte()) != PS2::Response::SELF_TEST_PASS)
|
||||
{
|
||||
dwarnln_if(DEBUG_PS2, "PS/2 device self test failed");
|
||||
return BAN::Error::from_errno(ENODEV);
|
||||
}
|
||||
while (!read_byte().is_error())
|
||||
continue;
|
||||
|
||||
// Disable scanning and flush buffer
|
||||
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::DISABLE_SCANNING));
|
||||
while (!read_byte().is_error())
|
||||
continue;
|
||||
|
||||
// Identify device
|
||||
TRY(device_send_byte_and_wait_ack(device, PS2::DeviceCommand::IDENTIFY));
|
||||
|
||||
// Read up to 2 identification bytes
|
||||
uint8_t bytes[2] {};
|
||||
uint8_t index = 0;
|
||||
for (uint8_t i = 0; i < 2; i++)
|
||||
{
|
||||
auto res = device_read_byte();
|
||||
auto res = read_byte();
|
||||
if (res.is_error())
|
||||
break;
|
||||
bytes[index++] = res.value();
|
||||
|
@ -214,38 +386,22 @@ namespace Kernel::Input
|
|||
|
||||
// Standard PS/2 Mouse
|
||||
if (index == 1 && (bytes[0] == 0x00))
|
||||
{
|
||||
dprintln_if(DEBUG_PS2, "PS/2 found mouse");
|
||||
m_devices[device] = TRY(PS2Mouse::create(*this));
|
||||
return {};
|
||||
}
|
||||
|
||||
// MF2 Keyboard
|
||||
else if (index == 2 && (bytes[0] == 0xAB && bytes[1] == 0x83))
|
||||
if (index == 2 && (bytes[0] == 0xAB && (bytes[1] == 0x83 || bytes[1] == 0x41)))
|
||||
{
|
||||
dprintln_if(DEBUG_PS2, "PS/2 found keyboard");
|
||||
m_devices[device] = TRY(PS2Keyboard::create(*this));
|
||||
|
||||
if (m_devices[device])
|
||||
return {};
|
||||
|
||||
return BAN::Error::from_error_code(ErrorCode::PS2_UnsupportedDevice);
|
||||
}
|
||||
|
||||
void PS2Controller::send_byte(const PS2Device* device, uint8_t byte)
|
||||
{
|
||||
ASSERT(device != nullptr && (device == m_devices[0] || device == m_devices[1]));
|
||||
uint8_t device_index = (device == m_devices[0]) ? 0 : 1;
|
||||
MUST(device_send_byte(device_index, byte));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::reset_device(uint8_t device)
|
||||
{
|
||||
TRY(device_send_byte(device, PS2::DeviceCommand::RESET));
|
||||
TRY(device_wait_ack());
|
||||
if (TRY(device_read_byte()) != PS2::Response::SELF_TEST_PASS)
|
||||
return BAN::Error::from_error_code(ErrorCode::PS2_Reset);
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> PS2Controller::set_scanning(uint8_t device, bool enabled)
|
||||
{
|
||||
TRY(device_send_byte(device, enabled ? PS2::DeviceCommand::ENABLE_SCANNING : PS2::DeviceCommand::DISABLE_SCANNING));
|
||||
TRY(device_wait_ack());
|
||||
return {};
|
||||
dprintln_if(DEBUG_PS2, "PS/2 unsupported device {2H} {2H} ({} bytes) on port {}", bytes[0], bytes[1], index, device);
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,74 +15,21 @@ namespace Kernel::Input
|
|||
, m_controller(controller)
|
||||
{ }
|
||||
|
||||
bool PS2Device::append_command_queue(uint8_t command)
|
||||
bool PS2Device::append_command_queue(uint8_t command, uint8_t response_size)
|
||||
{
|
||||
if (m_command_queue.size() + 1 >= m_command_queue.capacity())
|
||||
{
|
||||
dprintln("PS/2 command queue full");
|
||||
return false;
|
||||
}
|
||||
m_command_queue.push(command);
|
||||
update();
|
||||
return true;
|
||||
return m_controller.append_command_queue(this, command, response_size);
|
||||
}
|
||||
|
||||
bool PS2Device::append_command_queue(uint8_t command, uint8_t data)
|
||||
bool PS2Device::append_command_queue(uint8_t command, uint8_t data, uint8_t response_size)
|
||||
{
|
||||
if (m_command_queue.size() + 2 >= m_command_queue.capacity())
|
||||
{
|
||||
dprintln("PS/2 command queue full");
|
||||
return false;
|
||||
}
|
||||
m_command_queue.push(command);
|
||||
m_command_queue.push(data);
|
||||
update();
|
||||
return true;
|
||||
return m_controller.append_command_queue(this, command, data, response_size);
|
||||
}
|
||||
|
||||
void PS2Device::handle_irq()
|
||||
{
|
||||
uint8_t byte = IO::inb(PS2::IOPort::DATA);
|
||||
|
||||
// NOTE: This implementation does not allow using commands
|
||||
// that respond with more bytes than ACK
|
||||
switch (m_state)
|
||||
{
|
||||
case State::WaitingAck:
|
||||
{
|
||||
switch (byte)
|
||||
{
|
||||
case PS2::Response::ACK:
|
||||
m_command_queue.pop();
|
||||
m_state = State::Normal;
|
||||
break;
|
||||
case PS2::Response::RESEND:
|
||||
m_state = State::Normal;
|
||||
break;
|
||||
default:
|
||||
handle_device_command_response(byte);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case State::Normal:
|
||||
{
|
||||
if (!m_controller.handle_command_byte(this, byte))
|
||||
handle_byte(byte);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void PS2Device::update()
|
||||
{
|
||||
if (m_state == State::WaitingAck)
|
||||
return;
|
||||
if (m_command_queue.empty())
|
||||
return;
|
||||
m_state = State::WaitingAck;
|
||||
m_controller.send_byte(this, m_command_queue.front());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Input/PS2/Config.h>
|
||||
#include <kernel/Input/PS2/Keyboard.h>
|
||||
#include <kernel/Thread.h>
|
||||
|
||||
#define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask)))
|
||||
#define TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
|
||||
|
@ -24,90 +25,121 @@ namespace Kernel::Input
|
|||
|
||||
void PS2Keyboard::send_initialize()
|
||||
{
|
||||
append_command_queue(Command::SET_LEDS, 0x00);
|
||||
append_command_queue(Command::SCANCODE, PS2::KBScancode::SET_SCANCODE_SET2);
|
||||
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING);
|
||||
constexpr uint8_t wanted_scancode_set = 3;
|
||||
append_command_queue(Command::SET_LEDS, 0x00, 0);
|
||||
append_command_queue(Command::CONFIG_SCANCODE_SET, wanted_scancode_set, 0);
|
||||
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1);
|
||||
}
|
||||
|
||||
void PS2Keyboard::handle_device_command_response(uint8_t byte)
|
||||
void PS2Keyboard::command_timedout(uint8_t* command_data, uint8_t command_size)
|
||||
{
|
||||
switch (byte)
|
||||
if (command_size == 0)
|
||||
return;
|
||||
|
||||
if (command_data[0] == Command::CONFIG_SCANCODE_SET && m_scancode_set >= 0xFE)
|
||||
{
|
||||
case PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN1:
|
||||
case PS2::KBResponse::KEY_ERROR_OR_BUFFER_OVERRUN2:
|
||||
dwarnln("Key detection error or internal buffer overrun");
|
||||
break;
|
||||
default:
|
||||
dwarnln("Unhandeled byte {2H}", byte);
|
||||
break;
|
||||
dwarnln("Could not detect scancode set, assuming 1");
|
||||
m_scancode_set = 1;
|
||||
m_keymap.initialize(m_scancode_set);
|
||||
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PS2Keyboard::handle_byte(uint8_t byte)
|
||||
{
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_scancode_set == 0xFF)
|
||||
{
|
||||
append_command_queue(Command::CONFIG_SCANCODE_SET, 0, 1);
|
||||
m_scancode_set = 0xFE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_scancode_set == 0xFE)
|
||||
{
|
||||
if (1 <= byte && byte <= 3)
|
||||
{
|
||||
m_scancode_set = byte;
|
||||
dprintln("Using scancode set {}", m_scancode_set);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwarnln("Could not detect scancode set, assuming 1");
|
||||
m_scancode_set = 1;
|
||||
}
|
||||
m_keymap.initialize(m_scancode_set);
|
||||
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_byte_index >= 3)
|
||||
{
|
||||
dwarnln("PS/2 corrupted key packet");
|
||||
m_byte_index = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
m_byte_buffer[m_byte_index++] = byte;
|
||||
if (byte == 0xE0 || byte == 0xF0)
|
||||
if (byte == 0xE0)
|
||||
return;
|
||||
if ((m_scancode_set == 2 || m_scancode_set == 3) && byte == 0xF0)
|
||||
return;
|
||||
|
||||
uint32_t scancode = 0;
|
||||
bool extended = false;
|
||||
bool released = false;
|
||||
|
||||
for (uint8_t i = 0; i < m_byte_index; i++)
|
||||
uint8_t index = 0;
|
||||
// in all scancode sets, extended scancode is indicated by byte 0xE0
|
||||
if (index < m_byte_index && m_byte_buffer[index] == 0xE0)
|
||||
{
|
||||
if (m_byte_buffer[i] == 0xE0)
|
||||
extended = true;
|
||||
else if (m_byte_buffer[i] == 0xF0)
|
||||
index++;
|
||||
}
|
||||
// in scancode set 1, released key is indicated by bit 7 set
|
||||
if (m_scancode_set == 1 && (m_byte_buffer[index] & 0x80))
|
||||
{
|
||||
released = true;
|
||||
else
|
||||
scancode = (scancode << 8) | m_byte_buffer[i];
|
||||
m_byte_buffer[index] &= 0x7F;
|
||||
}
|
||||
// in scancode set 2 and 3, released key is indicated by byte 0xF0
|
||||
if ((m_scancode_set == 2 || m_scancode_set == 3) && m_byte_buffer[index] == 0xF0)
|
||||
{
|
||||
released = true;
|
||||
index++;
|
||||
}
|
||||
|
||||
if (extended)
|
||||
scancode |= 0x80000000;
|
||||
|
||||
bool corrupted = (index + 1 != m_byte_index);
|
||||
m_byte_index = 0;
|
||||
|
||||
Key key = m_keymap.key_for_scancode_and_modifiers(scancode, m_modifiers);
|
||||
|
||||
if (key == Key::None)
|
||||
return;
|
||||
|
||||
if (key == Input::Key::Invalid)
|
||||
if (corrupted)
|
||||
{
|
||||
dprintln("unknown key for scancode {2H} {}", scancode & 0x7FFFFFFF, extended ? 'E' : ' ');
|
||||
dwarnln("PS/2 corrupted key packet");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t modifier_mask = 0;
|
||||
uint8_t toggle_mask = 0;
|
||||
switch (key)
|
||||
auto keycode = m_keymap.get_keycode(m_byte_buffer[index], extended);
|
||||
if (!keycode.has_value())
|
||||
return;
|
||||
|
||||
uint16_t modifier_mask = 0;
|
||||
uint16_t toggle_mask = 0;
|
||||
switch (keycode.value())
|
||||
{
|
||||
case Input::Key::LeftShift:
|
||||
case Input::Key::RightShift:
|
||||
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Shift;
|
||||
break;
|
||||
case Input::Key::LeftCtrl:
|
||||
case Input::Key::RightCtrl:
|
||||
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Ctrl;
|
||||
break;
|
||||
case Input::Key::Alt:
|
||||
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::Alt;
|
||||
break;
|
||||
case Input::Key::AltGr:
|
||||
modifier_mask = (uint8_t)Input::KeyEvent::Modifier::AltGr;
|
||||
break;;
|
||||
case Input::Key::ScrollLock:
|
||||
toggle_mask = (uint8_t)Input::KeyEvent::Modifier::ScrollLock;
|
||||
break;
|
||||
case Input::Key::NumLock:
|
||||
toggle_mask = (uint8_t)Input::KeyEvent::Modifier::NumLock;
|
||||
break;
|
||||
case Input::Key::CapsLock:
|
||||
toggle_mask = (uint8_t)Input::KeyEvent::Modifier::CapsLock;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case ModifierKeycode::LShift: modifier_mask = KeyEvent::Modifier::LShift; break;
|
||||
case ModifierKeycode::RShift: modifier_mask = KeyEvent::Modifier::RShift; break;
|
||||
case ModifierKeycode::LCtrl: modifier_mask = KeyEvent::Modifier::LCtrl; break;
|
||||
case ModifierKeycode::RCtrl: modifier_mask = KeyEvent::Modifier::RCtrl; break;
|
||||
case ModifierKeycode::LAlt: modifier_mask = KeyEvent::Modifier::LAlt; break;
|
||||
case ModifierKeycode::RAlt: modifier_mask = KeyEvent::Modifier::RAlt; break;
|
||||
|
||||
case ModifierKeycode::ScrollLock: toggle_mask = KeyEvent::Modifier::ScrollLock; break;
|
||||
case ModifierKeycode::NumLock: toggle_mask = KeyEvent::Modifier::NumLock; break;
|
||||
case ModifierKeycode::CapsLock: toggle_mask = KeyEvent::Modifier::CapsLock; break;
|
||||
}
|
||||
|
||||
if (modifier_mask)
|
||||
|
@ -118,15 +150,15 @@ namespace Kernel::Input
|
|||
m_modifiers |= modifier_mask;
|
||||
}
|
||||
|
||||
if (toggle_mask && !released)
|
||||
if (toggle_mask)
|
||||
{
|
||||
m_modifiers ^= toggle_mask;
|
||||
update_leds();
|
||||
}
|
||||
|
||||
Input::KeyEvent event;
|
||||
event.modifier = m_modifiers | (released ? (uint8_t)Input::KeyEvent::Modifier::Released : 0);
|
||||
event.key = key;
|
||||
KeyEvent event;
|
||||
event.modifier = m_modifiers | (released ? 0 : KeyEvent::Modifier::Pressed);
|
||||
event.keycode = keycode.value();
|
||||
|
||||
if (m_event_queue.full())
|
||||
{
|
||||
|
@ -141,13 +173,13 @@ namespace Kernel::Input
|
|||
void PS2Keyboard::update_leds()
|
||||
{
|
||||
uint8_t new_leds = 0;
|
||||
if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::ScrollLock)
|
||||
if (m_modifiers & +Input::KeyEvent::Modifier::ScrollLock)
|
||||
new_leds |= PS2::KBLeds::SCROLL_LOCK;
|
||||
if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::NumLock)
|
||||
if (m_modifiers & +Input::KeyEvent::Modifier::NumLock)
|
||||
new_leds |= PS2::KBLeds::NUM_LOCK;
|
||||
if (m_modifiers & (uint8_t)Input::KeyEvent::Modifier::CapsLock)
|
||||
if (m_modifiers & +Input::KeyEvent::Modifier::CapsLock)
|
||||
new_leds |= PS2::KBLeds::CAPS_LOCK;
|
||||
append_command_queue(Command::SET_LEDS, new_leds);
|
||||
append_command_queue(Command::SET_LEDS, new_leds, 0);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, BAN::ByteSpan buffer)
|
||||
|
@ -158,7 +190,7 @@ namespace Kernel::Input
|
|||
while (true)
|
||||
{
|
||||
if (m_event_queue.empty())
|
||||
m_semaphore.block();
|
||||
TRY(Thread::current().block_or_eintr(m_semaphore));
|
||||
|
||||
CriticalScope _;
|
||||
if (m_event_queue.empty())
|
||||
|
|
|
@ -1,360 +1,361 @@
|
|||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/Input/PS2/Keymap.h>
|
||||
|
||||
namespace Kernel::Input
|
||||
{
|
||||
|
||||
PS2Keymap::PS2Keymap()
|
||||
void PS2Keymap::initialize(uint8_t scancode_set)
|
||||
{
|
||||
MUST(m_normal_keymap.resize(0xFF, Key::Invalid));
|
||||
m_normal_keymap[0x01] = Key::F9;
|
||||
m_normal_keymap[0x03] = Key::F5;
|
||||
m_normal_keymap[0x04] = Key::F3;
|
||||
m_normal_keymap[0x05] = Key::F1;
|
||||
m_normal_keymap[0x06] = Key::F2;
|
||||
m_normal_keymap[0x07] = Key::F11;
|
||||
m_normal_keymap[0x09] = Key::F10;
|
||||
m_normal_keymap[0x0A] = Key::F8;
|
||||
m_normal_keymap[0x0B] = Key::F6;
|
||||
m_normal_keymap[0x0C] = Key::F4;
|
||||
m_normal_keymap[0x0D] = Key::Tab;
|
||||
m_normal_keymap[0x0E] = Key::Section;
|
||||
m_normal_keymap[0x11] = Key::Alt;
|
||||
m_normal_keymap[0x12] = Key::LeftShift;
|
||||
m_normal_keymap[0x14] = Key::LeftCtrl;
|
||||
m_normal_keymap[0x15] = Key::Q;
|
||||
m_normal_keymap[0x16] = Key::_1;
|
||||
m_normal_keymap[0x1A] = Key::Z;
|
||||
m_normal_keymap[0x1B] = Key::S;
|
||||
m_normal_keymap[0x1C] = Key::A;
|
||||
m_normal_keymap[0x1D] = Key::W;
|
||||
m_normal_keymap[0x1E] = Key::_2;
|
||||
m_normal_keymap[0x21] = Key::C;
|
||||
m_normal_keymap[0x22] = Key::X;
|
||||
m_normal_keymap[0x23] = Key::D;
|
||||
m_normal_keymap[0x24] = Key::E;
|
||||
m_normal_keymap[0x25] = Key::_4;
|
||||
m_normal_keymap[0x26] = Key::_3;
|
||||
m_normal_keymap[0x29] = Key::Space;
|
||||
m_normal_keymap[0x2A] = Key::V;
|
||||
m_normal_keymap[0x2B] = Key::F;
|
||||
m_normal_keymap[0x2C] = Key::T;
|
||||
m_normal_keymap[0x2D] = Key::R;
|
||||
m_normal_keymap[0x2E] = Key::_5;
|
||||
m_normal_keymap[0x31] = Key::N;
|
||||
m_normal_keymap[0x32] = Key::B;
|
||||
m_normal_keymap[0x33] = Key::H;
|
||||
m_normal_keymap[0x34] = Key::G;
|
||||
m_normal_keymap[0x35] = Key::Y;
|
||||
m_normal_keymap[0x36] = Key::_6;
|
||||
m_normal_keymap[0x3A] = Key::M;
|
||||
m_normal_keymap[0x3B] = Key::J;
|
||||
m_normal_keymap[0x3C] = Key::U;
|
||||
m_normal_keymap[0x3D] = Key::_7;
|
||||
m_normal_keymap[0x3E] = Key::_8;
|
||||
m_normal_keymap[0x41] = Key::Comma;
|
||||
m_normal_keymap[0x42] = Key::K;
|
||||
m_normal_keymap[0x43] = Key::I;
|
||||
m_normal_keymap[0x44] = Key::O;
|
||||
m_normal_keymap[0x45] = Key::_0;
|
||||
m_normal_keymap[0x46] = Key::_9;
|
||||
m_normal_keymap[0x49] = Key::Period;
|
||||
m_normal_keymap[0x4A] = Key::Hyphen;
|
||||
m_normal_keymap[0x4B] = Key::L;
|
||||
m_normal_keymap[0x4C] = Key::O_Umlaut;
|
||||
m_normal_keymap[0x4D] = Key::P;
|
||||
m_normal_keymap[0x4E] = Key::Plus;
|
||||
m_normal_keymap[0x52] = Key::A_Umlaut;
|
||||
m_normal_keymap[0x54] = Key::A_Ring;
|
||||
m_normal_keymap[0x55] = Key::Acute;
|
||||
m_normal_keymap[0x58] = Key::CapsLock;
|
||||
m_normal_keymap[0x59] = Key::RightShift;
|
||||
m_normal_keymap[0x59] = Key::RightShift;
|
||||
m_normal_keymap[0x5A] = Key::Enter;
|
||||
m_normal_keymap[0x5B] = Key::TwoDots;
|
||||
m_normal_keymap[0x5D] = Key::SingleQuote;
|
||||
m_normal_keymap[0x61] = Key::LessThan;
|
||||
m_normal_keymap[0x66] = Key::Backspace;
|
||||
m_normal_keymap[0x69] = Key::Numpad1;
|
||||
m_normal_keymap[0x6B] = Key::Numpad4;
|
||||
m_normal_keymap[0x6C] = Key::Numpad7;
|
||||
m_normal_keymap[0x70] = Key::Numpad0;
|
||||
m_normal_keymap[0x71] = Key::NumpadDecimal;
|
||||
m_normal_keymap[0x72] = Key::Numpad2;
|
||||
m_normal_keymap[0x73] = Key::Numpad5;
|
||||
m_normal_keymap[0x74] = Key::Numpad6;
|
||||
m_normal_keymap[0x75] = Key::Numpad8;
|
||||
m_normal_keymap[0x76] = Key::Escape;
|
||||
m_normal_keymap[0x77] = Key::NumLock;
|
||||
m_normal_keymap[0x78] = Key::F11;
|
||||
m_normal_keymap[0x79] = Key::NumpadPlus;
|
||||
m_normal_keymap[0x7A] = Key::Numpad3;
|
||||
m_normal_keymap[0x7B] = Key::NumpadMinus;
|
||||
m_normal_keymap[0x7C] = Key::NumpadMultiply;
|
||||
m_normal_keymap[0x7D] = Key::Numpad9;
|
||||
m_normal_keymap[0x83] = Key::F7;
|
||||
|
||||
MUST(m_shift_keymap.resize(0xFF, Key::Invalid));
|
||||
m_shift_keymap[0x01] = Key::F9;
|
||||
m_shift_keymap[0x03] = Key::F5;
|
||||
m_shift_keymap[0x04] = Key::F3;
|
||||
m_shift_keymap[0x05] = Key::F1;
|
||||
m_shift_keymap[0x06] = Key::F2;
|
||||
m_shift_keymap[0x07] = Key::F11;
|
||||
m_shift_keymap[0x09] = Key::F10;
|
||||
m_shift_keymap[0x0A] = Key::F8;
|
||||
m_shift_keymap[0x0B] = Key::F6;
|
||||
m_shift_keymap[0x0C] = Key::F4;
|
||||
m_shift_keymap[0x0D] = Key::Tab;
|
||||
m_shift_keymap[0x0E] = Key::Half;
|
||||
m_shift_keymap[0x11] = Key::Alt;
|
||||
m_shift_keymap[0x12] = Key::LeftShift;
|
||||
m_shift_keymap[0x14] = Key::LeftCtrl;
|
||||
m_shift_keymap[0x15] = Key::Q;
|
||||
m_shift_keymap[0x16] = Key::ExclamationMark;
|
||||
m_shift_keymap[0x1A] = Key::Z;
|
||||
m_shift_keymap[0x1B] = Key::S;
|
||||
m_shift_keymap[0x1C] = Key::A;
|
||||
m_shift_keymap[0x1D] = Key::W;
|
||||
m_shift_keymap[0x1E] = Key::DoubleQuote;
|
||||
m_shift_keymap[0x21] = Key::C;
|
||||
m_shift_keymap[0x22] = Key::X;
|
||||
m_shift_keymap[0x23] = Key::D;
|
||||
m_shift_keymap[0x24] = Key::E;
|
||||
m_shift_keymap[0x25] = Key::Currency;
|
||||
m_shift_keymap[0x26] = Key::Hashtag;
|
||||
m_shift_keymap[0x29] = Key::Space;
|
||||
m_shift_keymap[0x2A] = Key::V;
|
||||
m_shift_keymap[0x2B] = Key::F;
|
||||
m_shift_keymap[0x2C] = Key::T;
|
||||
m_shift_keymap[0x2D] = Key::R;
|
||||
m_shift_keymap[0x2E] = Key::Percent;
|
||||
m_shift_keymap[0x31] = Key::N;
|
||||
m_shift_keymap[0x32] = Key::B;
|
||||
m_shift_keymap[0x33] = Key::H;
|
||||
m_shift_keymap[0x34] = Key::G;
|
||||
m_shift_keymap[0x35] = Key::Y;
|
||||
m_shift_keymap[0x36] = Key::Ampersand;
|
||||
m_shift_keymap[0x3A] = Key::M;
|
||||
m_shift_keymap[0x3B] = Key::J;
|
||||
m_shift_keymap[0x3C] = Key::U;
|
||||
m_shift_keymap[0x3D] = Key::Slash;
|
||||
m_shift_keymap[0x3E] = Key::OpenBracet;
|
||||
m_shift_keymap[0x41] = Key::Semicolon;
|
||||
m_shift_keymap[0x42] = Key::K;
|
||||
m_shift_keymap[0x43] = Key::I;
|
||||
m_shift_keymap[0x44] = Key::O;
|
||||
m_shift_keymap[0x45] = Key::Equals;
|
||||
m_shift_keymap[0x46] = Key::CloseBracet;
|
||||
m_shift_keymap[0x49] = Key::Colon;
|
||||
m_shift_keymap[0x4A] = Key::Underscore;
|
||||
m_shift_keymap[0x4B] = Key::L;
|
||||
m_shift_keymap[0x4C] = Key::O_Umlaut;
|
||||
m_shift_keymap[0x4D] = Key::P;
|
||||
m_shift_keymap[0x4E] = Key::QuestionMark;
|
||||
m_shift_keymap[0x52] = Key::A_Umlaut;
|
||||
m_shift_keymap[0x54] = Key::A_Ring;
|
||||
m_shift_keymap[0x55] = Key::BackTick;
|
||||
m_shift_keymap[0x58] = Key::CapsLock;
|
||||
m_shift_keymap[0x59] = Key::RightShift;
|
||||
m_shift_keymap[0x59] = Key::RightShift;
|
||||
m_shift_keymap[0x5A] = Key::Enter;
|
||||
m_shift_keymap[0x5B] = Key::Caret;
|
||||
m_shift_keymap[0x5D] = Key::Asterix;
|
||||
m_shift_keymap[0x61] = Key::GreaterThan;
|
||||
m_shift_keymap[0x66] = Key::Backspace;
|
||||
m_shift_keymap[0x69] = Key::Numpad1;
|
||||
m_shift_keymap[0x6B] = Key::Numpad4;
|
||||
m_shift_keymap[0x6C] = Key::Numpad7;
|
||||
m_shift_keymap[0x70] = Key::Numpad0;
|
||||
m_shift_keymap[0x71] = Key::NumpadDecimal;
|
||||
m_shift_keymap[0x72] = Key::Numpad2;
|
||||
m_shift_keymap[0x73] = Key::Numpad5;
|
||||
m_shift_keymap[0x74] = Key::Numpad6;
|
||||
m_shift_keymap[0x75] = Key::Numpad8;
|
||||
m_shift_keymap[0x76] = Key::Escape;
|
||||
m_shift_keymap[0x77] = Key::NumLock;
|
||||
m_shift_keymap[0x78] = Key::F11;
|
||||
m_shift_keymap[0x79] = Key::NumpadPlus;
|
||||
m_shift_keymap[0x7A] = Key::Numpad3;
|
||||
m_shift_keymap[0x7B] = Key::NumpadMinus;
|
||||
m_shift_keymap[0x7C] = Key::NumpadMultiply;
|
||||
m_shift_keymap[0x7D] = Key::Numpad9;
|
||||
m_shift_keymap[0x83] = Key::F7;
|
||||
|
||||
MUST(m_altgr_keymap.resize(0xFF, Key::Invalid));
|
||||
m_altgr_keymap[0x01] = Key::F9;
|
||||
m_altgr_keymap[0x03] = Key::F5;
|
||||
m_altgr_keymap[0x04] = Key::F3;
|
||||
m_altgr_keymap[0x05] = Key::F1;
|
||||
m_altgr_keymap[0x06] = Key::F2;
|
||||
m_altgr_keymap[0x07] = Key::F11;
|
||||
m_altgr_keymap[0x09] = Key::F10;
|
||||
m_altgr_keymap[0x0A] = Key::F8;
|
||||
m_altgr_keymap[0x0B] = Key::F6;
|
||||
m_altgr_keymap[0x0C] = Key::F4;
|
||||
m_altgr_keymap[0x0D] = Key::Tab;
|
||||
m_altgr_keymap[0x0E] = Key::None;
|
||||
m_altgr_keymap[0x11] = Key::Alt;
|
||||
m_altgr_keymap[0x12] = Key::LeftShift;
|
||||
m_altgr_keymap[0x14] = Key::LeftCtrl;
|
||||
m_altgr_keymap[0x15] = Key::Q;
|
||||
m_altgr_keymap[0x16] = Key::None;
|
||||
m_altgr_keymap[0x1A] = Key::Z;
|
||||
m_altgr_keymap[0x1B] = Key::S;
|
||||
m_altgr_keymap[0x1C] = Key::A;
|
||||
m_altgr_keymap[0x1D] = Key::W;
|
||||
m_altgr_keymap[0x1E] = Key::AtSign;
|
||||
m_altgr_keymap[0x21] = Key::C;
|
||||
m_altgr_keymap[0x22] = Key::X;
|
||||
m_altgr_keymap[0x23] = Key::D;
|
||||
m_altgr_keymap[0x24] = Key::Euro;
|
||||
m_altgr_keymap[0x25] = Key::Dollar;
|
||||
m_altgr_keymap[0x26] = Key::Pound;
|
||||
m_altgr_keymap[0x29] = Key::Space;
|
||||
m_altgr_keymap[0x2A] = Key::V;
|
||||
m_altgr_keymap[0x2B] = Key::F;
|
||||
m_altgr_keymap[0x2C] = Key::T;
|
||||
m_altgr_keymap[0x2D] = Key::R;
|
||||
m_altgr_keymap[0x2E] = Key::None;
|
||||
m_altgr_keymap[0x31] = Key::N;
|
||||
m_altgr_keymap[0x32] = Key::B;
|
||||
m_altgr_keymap[0x33] = Key::H;
|
||||
m_altgr_keymap[0x34] = Key::G;
|
||||
m_altgr_keymap[0x35] = Key::Y;
|
||||
m_altgr_keymap[0x36] = Key::None;
|
||||
m_altgr_keymap[0x3A] = Key::M;
|
||||
m_altgr_keymap[0x3B] = Key::J;
|
||||
m_altgr_keymap[0x3C] = Key::U;
|
||||
m_altgr_keymap[0x3D] = Key::OpenCurlyBrace;
|
||||
m_altgr_keymap[0x3E] = Key::OpenBrace;
|
||||
m_altgr_keymap[0x41] = Key::None;
|
||||
m_altgr_keymap[0x42] = Key::K;
|
||||
m_altgr_keymap[0x43] = Key::I;
|
||||
m_altgr_keymap[0x44] = Key::O;
|
||||
m_altgr_keymap[0x45] = Key::CloseCurlyBrace;
|
||||
m_altgr_keymap[0x46] = Key::CloseBrace;
|
||||
m_altgr_keymap[0x49] = Key::None;
|
||||
m_altgr_keymap[0x4A] = Key::None;
|
||||
m_altgr_keymap[0x4B] = Key::L;
|
||||
m_altgr_keymap[0x4C] = Key::O_Umlaut;
|
||||
m_altgr_keymap[0x4D] = Key::P;
|
||||
m_altgr_keymap[0x4E] = Key::BackSlash;
|
||||
m_altgr_keymap[0x52] = Key::A_Umlaut;
|
||||
m_altgr_keymap[0x54] = Key::A_Ring;
|
||||
m_altgr_keymap[0x55] = Key::None;
|
||||
m_altgr_keymap[0x58] = Key::CapsLock;
|
||||
m_altgr_keymap[0x59] = Key::RightShift;
|
||||
m_altgr_keymap[0x59] = Key::RightShift;
|
||||
m_altgr_keymap[0x5A] = Key::Enter;
|
||||
m_altgr_keymap[0x5B] = Key::Tilde;
|
||||
m_altgr_keymap[0x5D] = Key::None;
|
||||
m_altgr_keymap[0x61] = Key::Pipe;
|
||||
m_altgr_keymap[0x66] = Key::Backspace;
|
||||
m_altgr_keymap[0x69] = Key::Numpad1;
|
||||
m_altgr_keymap[0x6B] = Key::Numpad4;
|
||||
m_altgr_keymap[0x6C] = Key::Numpad7;
|
||||
m_altgr_keymap[0x70] = Key::Numpad0;
|
||||
m_altgr_keymap[0x71] = Key::NumpadDecimal;
|
||||
m_altgr_keymap[0x72] = Key::Numpad2;
|
||||
m_altgr_keymap[0x73] = Key::Numpad5;
|
||||
m_altgr_keymap[0x74] = Key::Numpad6;
|
||||
m_altgr_keymap[0x75] = Key::Numpad8;
|
||||
m_altgr_keymap[0x76] = Key::Escape;
|
||||
m_altgr_keymap[0x77] = Key::NumLock;
|
||||
m_altgr_keymap[0x78] = Key::F11;
|
||||
m_altgr_keymap[0x79] = Key::NumpadPlus;
|
||||
m_altgr_keymap[0x7A] = Key::Numpad3;
|
||||
m_altgr_keymap[0x7B] = Key::NumpadMinus;
|
||||
m_altgr_keymap[0x7C] = Key::NumpadMultiply;
|
||||
m_altgr_keymap[0x7D] = Key::Numpad9;
|
||||
m_altgr_keymap[0x83] = Key::F7;
|
||||
|
||||
MUST(m_extended_keymap.resize(0xFF, Key::Invalid));
|
||||
m_extended_keymap[0x11] = Key::AltGr;
|
||||
m_extended_keymap[0x14] = Key::RightCtrl;
|
||||
m_extended_keymap[0x15] = Key::MediaPrevious;
|
||||
m_extended_keymap[0x1F] = Key::Super;
|
||||
m_extended_keymap[0x21] = Key::VolumeUp;
|
||||
m_extended_keymap[0x23] = Key::VolumeMute;
|
||||
m_extended_keymap[0x2B] = Key::Calculator;
|
||||
m_extended_keymap[0x32] = Key::VolumeDown;
|
||||
m_extended_keymap[0x34] = Key::MediaPlayPause;
|
||||
m_extended_keymap[0x3B] = Key::MediaStop;
|
||||
m_extended_keymap[0x4A] = Key::NumpadDivide;
|
||||
m_extended_keymap[0x4D] = Key::MediaNext;
|
||||
m_extended_keymap[0x5A] = Key::NumpadEnter;
|
||||
m_extended_keymap[0x69] = Key::End;
|
||||
m_extended_keymap[0x6B] = Key::ArrowLeft;
|
||||
m_extended_keymap[0x6C] = Key::Home;
|
||||
m_extended_keymap[0x70] = Key::Insert;
|
||||
m_extended_keymap[0x71] = Key::Delete;
|
||||
m_extended_keymap[0x72] = Key::ArrowDown;
|
||||
m_extended_keymap[0x74] = Key::ArrowRight;
|
||||
m_extended_keymap[0x75] = Key::ArrowUp;
|
||||
m_extended_keymap[0x7A] = Key::PageUp;
|
||||
m_extended_keymap[0x7D] = Key::PageDown;
|
||||
memset(m_scancode_to_keycode_normal.data(), 0xFF, m_scancode_to_keycode_normal.size());
|
||||
memset(m_scancode_to_keycode_extended.data(), 0xFF, m_scancode_to_keycode_extended.size());
|
||||
if (scancode_set == 1)
|
||||
return initialize_scancode_set1();
|
||||
if (scancode_set == 2)
|
||||
return initialize_scancode_set2();
|
||||
if (scancode_set == 3)
|
||||
return initialize_scancode_set3();
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
Key PS2Keymap::key_for_scancode_and_modifiers(uint32_t scancode, uint8_t modifiers)
|
||||
BAN::Optional<uint8_t> PS2Keymap::get_keycode(uint8_t scancode, bool extended) const
|
||||
{
|
||||
bool extended = scancode & 0x80000000;
|
||||
scancode &= 0x7FFFFFFF;
|
||||
|
||||
KeyEvent dummy;
|
||||
dummy.modifier = modifiers;
|
||||
auto& keymap = extended ? m_extended_keymap :
|
||||
dummy.shift() ? m_shift_keymap :
|
||||
dummy.altgr() ? m_altgr_keymap :
|
||||
m_normal_keymap;
|
||||
|
||||
if (scancode >= keymap.size())
|
||||
return Key::Invalid;
|
||||
|
||||
Key key = keymap[scancode];
|
||||
|
||||
if (!dummy.num_lock() || dummy.shift() || dummy.ctrl() || dummy.alt())
|
||||
uint8_t keycode = extended ? m_scancode_to_keycode_extended[scancode] : m_scancode_to_keycode_normal[scancode];
|
||||
if (keycode == 0xFF)
|
||||
{
|
||||
switch (key)
|
||||
dprintln("unknown {2H} {}", scancode, extended ? 'E' : ' ');
|
||||
return {};
|
||||
}
|
||||
return keycode;
|
||||
}
|
||||
|
||||
void PS2Keymap::initialize_scancode_set1()
|
||||
{
|
||||
case Key::Numpad0:
|
||||
key = Key::Insert;
|
||||
break;
|
||||
case Key::Numpad1:
|
||||
key = Key::End;
|
||||
break;
|
||||
case Key::Numpad2:
|
||||
key = Key::ArrowDown;
|
||||
break;
|
||||
case Key::Numpad3:
|
||||
key = Key::PageDown;
|
||||
break;
|
||||
case Key::Numpad4:
|
||||
key = Key::ArrowLeft;
|
||||
break;
|
||||
case Key::Numpad5:
|
||||
key = Key::None;
|
||||
break;
|
||||
case Key::Numpad6:
|
||||
key = Key::ArrowRight;
|
||||
break;
|
||||
case Key::Numpad7:
|
||||
key = Key::Home;
|
||||
break;
|
||||
case Key::Numpad8:
|
||||
key = Key::ArrowUp;
|
||||
break;
|
||||
case Key::Numpad9:
|
||||
key = Key::PageUp;
|
||||
break;
|
||||
case Key::NumpadDecimal:
|
||||
key = Key::Delete;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_scancode_to_keycode_normal[0x29] = keycode_normal(0, 0);
|
||||
m_scancode_to_keycode_normal[0x02] = keycode_normal(0, 1);
|
||||
m_scancode_to_keycode_normal[0x03] = keycode_normal(0, 2);
|
||||
m_scancode_to_keycode_normal[0x04] = keycode_normal(0, 3);
|
||||
m_scancode_to_keycode_normal[0x05] = keycode_normal(0, 4);
|
||||
m_scancode_to_keycode_normal[0x06] = keycode_normal(0, 5);
|
||||
m_scancode_to_keycode_normal[0x07] = keycode_normal(0, 6);
|
||||
m_scancode_to_keycode_normal[0x08] = keycode_normal(0, 7);
|
||||
m_scancode_to_keycode_normal[0x09] = keycode_normal(0, 8);
|
||||
m_scancode_to_keycode_normal[0x0A] = keycode_normal(0, 9);
|
||||
m_scancode_to_keycode_normal[0x0B] = keycode_normal(0, 10);
|
||||
m_scancode_to_keycode_normal[0x0C] = keycode_normal(0, 11);
|
||||
m_scancode_to_keycode_normal[0x0D] = keycode_normal(0, 12);
|
||||
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 13);
|
||||
m_scancode_to_keycode_normal[0x0F] = keycode_normal(1, 0);
|
||||
m_scancode_to_keycode_normal[0x10] = keycode_normal(1, 1);
|
||||
m_scancode_to_keycode_normal[0x11] = keycode_normal(1, 2);
|
||||
m_scancode_to_keycode_normal[0x12] = keycode_normal(1, 3);
|
||||
m_scancode_to_keycode_normal[0x13] = keycode_normal(1, 4);
|
||||
m_scancode_to_keycode_normal[0x14] = keycode_normal(1, 5);
|
||||
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 6);
|
||||
m_scancode_to_keycode_normal[0x16] = keycode_normal(1, 7);
|
||||
m_scancode_to_keycode_normal[0x17] = keycode_normal(1, 8);
|
||||
m_scancode_to_keycode_normal[0x18] = keycode_normal(1, 9);
|
||||
m_scancode_to_keycode_normal[0x19] = keycode_normal(1, 10);
|
||||
m_scancode_to_keycode_normal[0x1A] = keycode_normal(1, 11);
|
||||
m_scancode_to_keycode_normal[0x1B] = keycode_normal(1, 12);
|
||||
m_scancode_to_keycode_normal[0x3A] = keycode_normal(2, 0);
|
||||
m_scancode_to_keycode_normal[0x1E] = keycode_normal(2, 1);
|
||||
m_scancode_to_keycode_normal[0x1F] = keycode_normal(2, 2);
|
||||
m_scancode_to_keycode_normal[0x20] = keycode_normal(2, 3);
|
||||
m_scancode_to_keycode_normal[0x21] = keycode_normal(2, 4);
|
||||
m_scancode_to_keycode_normal[0x22] = keycode_normal(2, 5);
|
||||
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 6);
|
||||
m_scancode_to_keycode_normal[0x24] = keycode_normal(2, 7);
|
||||
m_scancode_to_keycode_normal[0x25] = keycode_normal(2, 8);
|
||||
m_scancode_to_keycode_normal[0x26] = keycode_normal(2, 9);
|
||||
m_scancode_to_keycode_normal[0x27] = keycode_normal(2, 10);
|
||||
m_scancode_to_keycode_normal[0x28] = keycode_normal(2, 11);
|
||||
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 12);
|
||||
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 13);
|
||||
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 0);
|
||||
m_scancode_to_keycode_normal[0x56] = keycode_normal(3, 1);
|
||||
m_scancode_to_keycode_normal[0x2C] = keycode_normal(3, 2);
|
||||
m_scancode_to_keycode_normal[0x2D] = keycode_normal(3, 3);
|
||||
m_scancode_to_keycode_normal[0x2E] = keycode_normal(3, 4);
|
||||
m_scancode_to_keycode_normal[0x2F] = keycode_normal(3, 5);
|
||||
m_scancode_to_keycode_normal[0x30] = keycode_normal(3, 6);
|
||||
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
|
||||
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 8);
|
||||
m_scancode_to_keycode_normal[0x33] = keycode_normal(3, 9);
|
||||
m_scancode_to_keycode_normal[0x34] = keycode_normal(3, 10);
|
||||
m_scancode_to_keycode_normal[0x35] = keycode_normal(3, 11);
|
||||
m_scancode_to_keycode_normal[0x36] = keycode_normal(3, 12);
|
||||
m_scancode_to_keycode_normal[0x1D] = keycode_normal(4, 0);
|
||||
m_scancode_to_keycode_extended[0x5B] = keycode_normal(4, 1);
|
||||
m_scancode_to_keycode_normal[0x38] = keycode_normal(4, 2);
|
||||
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 3);
|
||||
m_scancode_to_keycode_extended[0x38] = keycode_normal(4, 4);
|
||||
m_scancode_to_keycode_extended[0x1D] = keycode_normal(4, 5);
|
||||
|
||||
m_scancode_to_keycode_normal[0x45] = keycode_numpad(0, 0);
|
||||
m_scancode_to_keycode_extended[0x35] = keycode_numpad(0, 1);
|
||||
m_scancode_to_keycode_normal[0x37] = keycode_numpad(0, 2);
|
||||
m_scancode_to_keycode_normal[0x4A] = keycode_numpad(0, 3);
|
||||
m_scancode_to_keycode_normal[0x47] = keycode_numpad(1, 0);
|
||||
m_scancode_to_keycode_normal[0x48] = keycode_numpad(1, 1);
|
||||
m_scancode_to_keycode_normal[0x49] = keycode_numpad(1, 2);
|
||||
m_scancode_to_keycode_normal[0x4E] = keycode_numpad(1, 3);
|
||||
m_scancode_to_keycode_normal[0x4B] = keycode_numpad(2, 0);
|
||||
m_scancode_to_keycode_normal[0x4C] = keycode_numpad(2, 1);
|
||||
m_scancode_to_keycode_normal[0x4D] = keycode_numpad(2, 2);
|
||||
m_scancode_to_keycode_normal[0x4F] = keycode_numpad(3, 0);
|
||||
m_scancode_to_keycode_normal[0x50] = keycode_numpad(3, 1);
|
||||
m_scancode_to_keycode_normal[0x51] = keycode_numpad(3, 2);
|
||||
m_scancode_to_keycode_extended[0x1C] = keycode_numpad(3, 3);
|
||||
m_scancode_to_keycode_normal[0x52] = keycode_numpad(4, 0);
|
||||
m_scancode_to_keycode_normal[0x53] = keycode_numpad(4, 1);
|
||||
|
||||
m_scancode_to_keycode_normal[0x01] = keycode_function( 0);
|
||||
m_scancode_to_keycode_normal[0x3B] = keycode_function( 1);
|
||||
m_scancode_to_keycode_normal[0x3C] = keycode_function( 2);
|
||||
m_scancode_to_keycode_normal[0x3D] = keycode_function( 3);
|
||||
m_scancode_to_keycode_normal[0x3E] = keycode_function( 4);
|
||||
m_scancode_to_keycode_normal[0x3F] = keycode_function( 5);
|
||||
m_scancode_to_keycode_normal[0x40] = keycode_function( 6);
|
||||
m_scancode_to_keycode_normal[0x41] = keycode_function( 7);
|
||||
m_scancode_to_keycode_normal[0x42] = keycode_function( 8);
|
||||
m_scancode_to_keycode_normal[0x43] = keycode_function( 9);
|
||||
m_scancode_to_keycode_normal[0x44] = keycode_function(10);
|
||||
m_scancode_to_keycode_normal[0x57] = keycode_function(11);
|
||||
m_scancode_to_keycode_normal[0x58] = keycode_function(12);
|
||||
m_scancode_to_keycode_extended[0x52] = keycode_function(13);
|
||||
//m_scancode_to_keycode_normal[0x] = keycode_function(14);
|
||||
m_scancode_to_keycode_extended[0x53] = keycode_function(15);
|
||||
m_scancode_to_keycode_extended[0x47] = keycode_function(16);
|
||||
m_scancode_to_keycode_extended[0x4F] = keycode_function(17);
|
||||
m_scancode_to_keycode_extended[0x49] = keycode_function(18);
|
||||
m_scancode_to_keycode_extended[0x51] = keycode_function(19);
|
||||
m_scancode_to_keycode_normal[0x46] = keycode_function(20);
|
||||
|
||||
// Arrow keys
|
||||
m_scancode_to_keycode_extended[0x48] = keycode_normal(5, 0);
|
||||
m_scancode_to_keycode_extended[0x4B] = keycode_normal(5, 1);
|
||||
m_scancode_to_keycode_extended[0x50] = keycode_normal(5, 2);
|
||||
m_scancode_to_keycode_extended[0x4D] = keycode_normal(5, 3);
|
||||
}
|
||||
|
||||
return key;
|
||||
void PS2Keymap::initialize_scancode_set2()
|
||||
{
|
||||
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0);
|
||||
m_scancode_to_keycode_normal[0x16] = keycode_normal(0, 1);
|
||||
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2);
|
||||
m_scancode_to_keycode_normal[0x26] = keycode_normal(0, 3);
|
||||
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4);
|
||||
m_scancode_to_keycode_normal[0x2E] = keycode_normal(0, 5);
|
||||
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6);
|
||||
m_scancode_to_keycode_normal[0x3D] = keycode_normal(0, 7);
|
||||
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8);
|
||||
m_scancode_to_keycode_normal[0x46] = keycode_normal(0, 9);
|
||||
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10);
|
||||
m_scancode_to_keycode_normal[0x4E] = keycode_normal(0, 11);
|
||||
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12);
|
||||
m_scancode_to_keycode_normal[0x66] = keycode_normal(0, 13);
|
||||
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0);
|
||||
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 1);
|
||||
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2);
|
||||
m_scancode_to_keycode_normal[0x24] = keycode_normal(1, 3);
|
||||
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4);
|
||||
m_scancode_to_keycode_normal[0x2C] = keycode_normal(1, 5);
|
||||
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6);
|
||||
m_scancode_to_keycode_normal[0x3C] = keycode_normal(1, 7);
|
||||
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8);
|
||||
m_scancode_to_keycode_normal[0x44] = keycode_normal(1, 9);
|
||||
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10);
|
||||
m_scancode_to_keycode_normal[0x54] = keycode_normal(1, 11);
|
||||
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12);
|
||||
m_scancode_to_keycode_normal[0x58] = keycode_normal(2, 0);
|
||||
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1);
|
||||
m_scancode_to_keycode_normal[0x1B] = keycode_normal(2, 2);
|
||||
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3);
|
||||
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 4);
|
||||
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5);
|
||||
m_scancode_to_keycode_normal[0x33] = keycode_normal(2, 6);
|
||||
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7);
|
||||
m_scancode_to_keycode_normal[0x42] = keycode_normal(2, 8);
|
||||
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9);
|
||||
m_scancode_to_keycode_normal[0x4C] = keycode_normal(2, 10);
|
||||
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11);
|
||||
m_scancode_to_keycode_normal[0x5D] = keycode_normal(2, 12);
|
||||
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13);
|
||||
m_scancode_to_keycode_normal[0x12] = keycode_normal(3, 0);
|
||||
m_scancode_to_keycode_normal[0x61] = keycode_normal(3, 1);
|
||||
m_scancode_to_keycode_normal[0x1A] = keycode_normal(3, 2);
|
||||
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3);
|
||||
m_scancode_to_keycode_normal[0x21] = keycode_normal(3, 4);
|
||||
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5);
|
||||
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 6);
|
||||
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
|
||||
m_scancode_to_keycode_normal[0x3A] = keycode_normal(3, 8);
|
||||
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9);
|
||||
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
|
||||
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
|
||||
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
|
||||
m_scancode_to_keycode_normal[0x14] = keycode_normal(4, 1);
|
||||
m_scancode_to_keycode_extended[0x1F] = keycode_normal(4, 2);
|
||||
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 3);
|
||||
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 4);
|
||||
m_scancode_to_keycode_extended[0x11] = keycode_normal(4, 5);
|
||||
m_scancode_to_keycode_extended[0x14] = keycode_normal(4, 6);
|
||||
|
||||
m_scancode_to_keycode_normal[0x77] = keycode_numpad(0, 0);
|
||||
m_scancode_to_keycode_extended[0x4A] = keycode_numpad(0, 1);
|
||||
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(0, 2);
|
||||
m_scancode_to_keycode_normal[0x7B] = keycode_numpad(0, 3);
|
||||
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 0);
|
||||
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 1);
|
||||
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 2);
|
||||
m_scancode_to_keycode_normal[0x79] = keycode_numpad(1, 3);
|
||||
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 0);
|
||||
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 1);
|
||||
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 2);
|
||||
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 0);
|
||||
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 1);
|
||||
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 2);
|
||||
m_scancode_to_keycode_extended[0x5A] = keycode_numpad(3, 3);
|
||||
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 0);
|
||||
m_scancode_to_keycode_normal[0x71] = keycode_numpad(4, 1);
|
||||
|
||||
m_scancode_to_keycode_normal[0x76] = keycode_function( 0);
|
||||
m_scancode_to_keycode_normal[0x05] = keycode_function( 1);
|
||||
m_scancode_to_keycode_normal[0x06] = keycode_function( 2);
|
||||
m_scancode_to_keycode_normal[0x04] = keycode_function( 3);
|
||||
m_scancode_to_keycode_normal[0x0C] = keycode_function( 4);
|
||||
m_scancode_to_keycode_normal[0x03] = keycode_function( 5);
|
||||
m_scancode_to_keycode_normal[0x0B] = keycode_function( 6);
|
||||
m_scancode_to_keycode_normal[0x83] = keycode_function( 7);
|
||||
m_scancode_to_keycode_normal[0x0A] = keycode_function( 8);
|
||||
m_scancode_to_keycode_normal[0x01] = keycode_function( 9);
|
||||
m_scancode_to_keycode_normal[0x09] = keycode_function(10);
|
||||
m_scancode_to_keycode_normal[0x78] = keycode_function(11);
|
||||
m_scancode_to_keycode_normal[0x07] = keycode_function(12);
|
||||
m_scancode_to_keycode_extended[0x70] = keycode_function(13);
|
||||
//m_scancode_to_keycode_normal[0x] = keycode_function(14);
|
||||
m_scancode_to_keycode_extended[0x71] = keycode_function(15);
|
||||
m_scancode_to_keycode_extended[0x6C] = keycode_function(16);
|
||||
m_scancode_to_keycode_extended[0x69] = keycode_function(17);
|
||||
m_scancode_to_keycode_extended[0x7D] = keycode_function(18);
|
||||
m_scancode_to_keycode_extended[0x7A] = keycode_function(19);
|
||||
m_scancode_to_keycode_normal[0x7E] = keycode_function(20);
|
||||
|
||||
// Arrow keys
|
||||
m_scancode_to_keycode_extended[0x75] = keycode_normal(5, 0);
|
||||
m_scancode_to_keycode_extended[0x6B] = keycode_normal(5, 1);
|
||||
m_scancode_to_keycode_extended[0x72] = keycode_normal(5, 2);
|
||||
m_scancode_to_keycode_extended[0x74] = keycode_normal(5, 3);
|
||||
}
|
||||
|
||||
void PS2Keymap::initialize_scancode_set3()
|
||||
{
|
||||
m_scancode_to_keycode_normal[0x0E] = keycode_normal(0, 0);
|
||||
m_scancode_to_keycode_normal[0x16] = keycode_normal(0, 1);
|
||||
m_scancode_to_keycode_normal[0x1E] = keycode_normal(0, 2);
|
||||
m_scancode_to_keycode_normal[0x26] = keycode_normal(0, 3);
|
||||
m_scancode_to_keycode_normal[0x25] = keycode_normal(0, 4);
|
||||
m_scancode_to_keycode_normal[0x2E] = keycode_normal(0, 5);
|
||||
m_scancode_to_keycode_normal[0x36] = keycode_normal(0, 6);
|
||||
m_scancode_to_keycode_normal[0x3D] = keycode_normal(0, 7);
|
||||
m_scancode_to_keycode_normal[0x3E] = keycode_normal(0, 8);
|
||||
m_scancode_to_keycode_normal[0x46] = keycode_normal(0, 9);
|
||||
m_scancode_to_keycode_normal[0x45] = keycode_normal(0, 10);
|
||||
m_scancode_to_keycode_normal[0x4E] = keycode_normal(0, 11);
|
||||
m_scancode_to_keycode_normal[0x55] = keycode_normal(0, 12);
|
||||
m_scancode_to_keycode_normal[0x66] = keycode_normal(0, 13);
|
||||
m_scancode_to_keycode_normal[0x0D] = keycode_normal(1, 0);
|
||||
m_scancode_to_keycode_normal[0x15] = keycode_normal(1, 1);
|
||||
m_scancode_to_keycode_normal[0x1D] = keycode_normal(1, 2);
|
||||
m_scancode_to_keycode_normal[0x24] = keycode_normal(1, 3);
|
||||
m_scancode_to_keycode_normal[0x2D] = keycode_normal(1, 4);
|
||||
m_scancode_to_keycode_normal[0x2C] = keycode_normal(1, 5);
|
||||
m_scancode_to_keycode_normal[0x35] = keycode_normal(1, 6);
|
||||
m_scancode_to_keycode_normal[0x3C] = keycode_normal(1, 7);
|
||||
m_scancode_to_keycode_normal[0x43] = keycode_normal(1, 8);
|
||||
m_scancode_to_keycode_normal[0x44] = keycode_normal(1, 9);
|
||||
m_scancode_to_keycode_normal[0x4D] = keycode_normal(1, 10);
|
||||
m_scancode_to_keycode_normal[0x54] = keycode_normal(1, 11);
|
||||
m_scancode_to_keycode_normal[0x5B] = keycode_normal(1, 12);
|
||||
m_scancode_to_keycode_normal[0x14] = keycode_normal(2, 0);
|
||||
m_scancode_to_keycode_normal[0x1C] = keycode_normal(2, 1);
|
||||
m_scancode_to_keycode_normal[0x1B] = keycode_normal(2, 2);
|
||||
m_scancode_to_keycode_normal[0x23] = keycode_normal(2, 3);
|
||||
m_scancode_to_keycode_normal[0x2B] = keycode_normal(2, 4);
|
||||
m_scancode_to_keycode_normal[0x34] = keycode_normal(2, 5);
|
||||
m_scancode_to_keycode_normal[0x33] = keycode_normal(2, 6);
|
||||
m_scancode_to_keycode_normal[0x3B] = keycode_normal(2, 7);
|
||||
m_scancode_to_keycode_normal[0x42] = keycode_normal(2, 8);
|
||||
m_scancode_to_keycode_normal[0x4B] = keycode_normal(2, 9);
|
||||
m_scancode_to_keycode_normal[0x4C] = keycode_normal(2, 10);
|
||||
m_scancode_to_keycode_normal[0x52] = keycode_normal(2, 11);
|
||||
m_scancode_to_keycode_normal[0x5C] = keycode_normal(2, 12);
|
||||
m_scancode_to_keycode_normal[0x5A] = keycode_normal(2, 13);
|
||||
m_scancode_to_keycode_normal[0x12] = keycode_normal(3, 0);
|
||||
m_scancode_to_keycode_normal[0x13] = keycode_normal(3, 1);
|
||||
m_scancode_to_keycode_normal[0x1A] = keycode_normal(3, 2);
|
||||
m_scancode_to_keycode_normal[0x22] = keycode_normal(3, 3);
|
||||
m_scancode_to_keycode_normal[0x21] = keycode_normal(3, 4);
|
||||
m_scancode_to_keycode_normal[0x2A] = keycode_normal(3, 5);
|
||||
m_scancode_to_keycode_normal[0x32] = keycode_normal(3, 6);
|
||||
m_scancode_to_keycode_normal[0x31] = keycode_normal(3, 7);
|
||||
m_scancode_to_keycode_normal[0x3A] = keycode_normal(3, 8);
|
||||
m_scancode_to_keycode_normal[0x41] = keycode_normal(3, 9);
|
||||
m_scancode_to_keycode_normal[0x49] = keycode_normal(3, 10);
|
||||
m_scancode_to_keycode_normal[0x4A] = keycode_normal(3, 11);
|
||||
m_scancode_to_keycode_normal[0x59] = keycode_normal(3, 12);
|
||||
m_scancode_to_keycode_normal[0x11] = keycode_normal(4, 0);
|
||||
m_scancode_to_keycode_normal[0x8B] = keycode_normal(4, 1);
|
||||
m_scancode_to_keycode_normal[0x19] = keycode_normal(4, 2);
|
||||
m_scancode_to_keycode_normal[0x29] = keycode_normal(4, 3);
|
||||
m_scancode_to_keycode_normal[0x39] = keycode_normal(4, 4);
|
||||
m_scancode_to_keycode_normal[0x58] = keycode_normal(4, 5);
|
||||
|
||||
m_scancode_to_keycode_normal[0x76] = keycode_numpad(0, 0);
|
||||
//m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 1);
|
||||
m_scancode_to_keycode_normal[0x7E] = keycode_numpad(0, 2);
|
||||
//m_scancode_to_keycode_normal[0x] = keycode_numpad(0, 3);
|
||||
m_scancode_to_keycode_normal[0x6C] = keycode_numpad(1, 1);
|
||||
m_scancode_to_keycode_normal[0x75] = keycode_numpad(1, 2);
|
||||
m_scancode_to_keycode_normal[0x7D] = keycode_numpad(1, 3);
|
||||
m_scancode_to_keycode_normal[0x7C] = keycode_numpad(1, 4);
|
||||
m_scancode_to_keycode_normal[0x6B] = keycode_numpad(2, 1);
|
||||
m_scancode_to_keycode_normal[0x73] = keycode_numpad(2, 2);
|
||||
m_scancode_to_keycode_normal[0x74] = keycode_numpad(2, 3);
|
||||
m_scancode_to_keycode_normal[0x69] = keycode_numpad(3, 1);
|
||||
m_scancode_to_keycode_normal[0x72] = keycode_numpad(3, 2);
|
||||
m_scancode_to_keycode_normal[0x7A] = keycode_numpad(3, 3);
|
||||
m_scancode_to_keycode_normal[0x79] = keycode_numpad(3, 4);
|
||||
m_scancode_to_keycode_normal[0x70] = keycode_numpad(4, 1);
|
||||
m_scancode_to_keycode_normal[0x71] = keycode_numpad(4, 2);
|
||||
|
||||
m_scancode_to_keycode_normal[0x08] = keycode_function(0);
|
||||
m_scancode_to_keycode_normal[0x07] = keycode_function(1);
|
||||
m_scancode_to_keycode_normal[0x0F] = keycode_function(2);
|
||||
m_scancode_to_keycode_normal[0x17] = keycode_function(3);
|
||||
m_scancode_to_keycode_normal[0x1F] = keycode_function(4);
|
||||
m_scancode_to_keycode_normal[0x27] = keycode_function(5);
|
||||
m_scancode_to_keycode_normal[0x2F] = keycode_function(6);
|
||||
m_scancode_to_keycode_normal[0x37] = keycode_function(7);
|
||||
m_scancode_to_keycode_normal[0x3F] = keycode_function(8);
|
||||
m_scancode_to_keycode_normal[0x47] = keycode_function(9);
|
||||
m_scancode_to_keycode_normal[0x4F] = keycode_function(10);
|
||||
m_scancode_to_keycode_normal[0x56] = keycode_function(11);
|
||||
m_scancode_to_keycode_normal[0x5E] = keycode_function(12);
|
||||
m_scancode_to_keycode_normal[0x67] = keycode_function(13);
|
||||
m_scancode_to_keycode_normal[0x57] = keycode_function(14);
|
||||
m_scancode_to_keycode_normal[0x64] = keycode_function(15);
|
||||
m_scancode_to_keycode_normal[0x6E] = keycode_function(16);
|
||||
m_scancode_to_keycode_normal[0x65] = keycode_function(17);
|
||||
m_scancode_to_keycode_normal[0x6F] = keycode_function(18);
|
||||
m_scancode_to_keycode_normal[0x6D] = keycode_function(19);
|
||||
m_scancode_to_keycode_normal[0x5F] = keycode_function(20);
|
||||
|
||||
// Arrow keys
|
||||
m_scancode_to_keycode_normal[0x63] = keycode_normal(5, 0);
|
||||
m_scancode_to_keycode_normal[0x61] = keycode_normal(5, 1);
|
||||
m_scancode_to_keycode_normal[0x60] = keycode_normal(5, 2);
|
||||
m_scancode_to_keycode_normal[0x6A] = keycode_normal(5, 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Input/PS2/Config.h>
|
||||
#include <kernel/Input/PS2/Mouse.h>
|
||||
#include <kernel/Thread.h>
|
||||
|
||||
#define SET_MASK(byte, mask, on_off) ((on_off) ? ((byte) | (mask)) : ((byte) & ~(mask)))
|
||||
#define TOGGLE_MASK(byte, mask) ((byte) ^ (mask))
|
||||
|
@ -25,10 +26,10 @@ namespace Kernel::Input
|
|||
void PS2Mouse::send_initialize()
|
||||
{
|
||||
// Query extensions
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 200);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 100);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 80);
|
||||
append_command_queue(PS2::DeviceCommand::IDENTIFY);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 100, 0);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 80, 0);
|
||||
append_command_queue(PS2::DeviceCommand::IDENTIFY, 1);
|
||||
}
|
||||
|
||||
void PS2Mouse::initialize_extensions(uint8_t byte)
|
||||
|
@ -47,10 +48,10 @@ namespace Kernel::Input
|
|||
else
|
||||
{
|
||||
m_mouse_id = 0x03;
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 200);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 200);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 80);
|
||||
append_command_queue(PS2::DeviceCommand::IDENTIFY);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 200, 0);
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 80, 0);
|
||||
append_command_queue(PS2::DeviceCommand::IDENTIFY, 1);
|
||||
}
|
||||
break;
|
||||
case 0x04:
|
||||
|
@ -64,18 +65,8 @@ namespace Kernel::Input
|
|||
|
||||
if (m_enabled)
|
||||
{
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 100);
|
||||
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING);
|
||||
}
|
||||
}
|
||||
|
||||
void PS2Mouse::handle_device_command_response(uint8_t byte)
|
||||
{
|
||||
switch (byte)
|
||||
{
|
||||
default:
|
||||
dwarnln("Unhandeled byte {2H}", byte);
|
||||
break;
|
||||
append_command_queue(Command::SET_SAMPLE_RATE, 100, 0);
|
||||
append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +179,7 @@ namespace Kernel::Input
|
|||
while (true)
|
||||
{
|
||||
if (m_event_queue.empty())
|
||||
m_semaphore.block();
|
||||
TRY(Thread::current().block_or_eintr(m_semaphore));
|
||||
|
||||
CriticalScope _;
|
||||
if (m_event_queue.empty())
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#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/LockGuard.h>
|
||||
#include <kernel/Memory/FileBackedRegion.h>
|
||||
|
@ -1253,6 +1254,17 @@ namespace Kernel
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_load_keymap(const char* path)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto absolute_path = TRY(absolute_path_of(path));
|
||||
TRY(Input::KeyboardLayout::get().load_from_file(absolute_path));
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_signal(int signal, void (*handler)(int))
|
||||
{
|
||||
if (signal < _SIGMIN || signal > _SIGMAX)
|
||||
|
|
|
@ -210,6 +210,9 @@ namespace Kernel
|
|||
case SYS_CHOWN:
|
||||
ret = Process::current().sys_chown((const char*)arg1, (uid_t)arg2, (gid_t)arg3);
|
||||
break;
|
||||
case SYS_LOAD_KEYMAP:
|
||||
ret = Process::current().sys_load_keymap((const char*)arg1);
|
||||
break;
|
||||
default:
|
||||
dwarnln("Unknown syscall {}", syscall);
|
||||
break;
|
||||
|
|
|
@ -127,12 +127,13 @@ namespace Kernel
|
|||
if (event.released())
|
||||
return;
|
||||
|
||||
const char* ansi_c_str = Input::key_event_to_utf8(event);
|
||||
Input::Key key = Input::key_event_to_key(event);
|
||||
const char* ansi_c_str = Input::key_to_utf8(key, event.modifier);
|
||||
|
||||
if (event.ctrl())
|
||||
{
|
||||
ansi_c_str = nullptr;
|
||||
switch (event.key)
|
||||
switch (key)
|
||||
{
|
||||
case Input::Key::A: ansi_c_str = "\x01"; break;
|
||||
case Input::Key::B: ansi_c_str = "\x02"; break;
|
||||
|
@ -165,7 +166,7 @@ namespace Kernel
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (event.key)
|
||||
switch (key)
|
||||
{
|
||||
case Input::Key::Enter:
|
||||
case Input::Key::NumpadEnter:
|
||||
|
@ -322,11 +323,11 @@ namespace Kernel
|
|||
uint32_t depth = m_lock.lock_depth();
|
||||
for (uint32_t i = 0; i < depth; i++)
|
||||
m_lock.unlock();
|
||||
bool eintr = Thread::current().block_or_eintr(m_output.semaphore);
|
||||
auto eintr = Thread::current().block_or_eintr(m_output.semaphore);
|
||||
for (uint32_t i = 0; i < depth; i++)
|
||||
m_lock.lock();
|
||||
if (eintr)
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
if (eintr.is_error())
|
||||
return eintr.release_error();
|
||||
}
|
||||
|
||||
if (m_output.bytes == 0)
|
||||
|
|
|
@ -343,12 +343,14 @@ namespace Kernel
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Thread::block_or_eintr(Semaphore& semaphore)
|
||||
BAN::ErrorOr<void> Thread::block_or_eintr(Semaphore& semaphore)
|
||||
{
|
||||
if (is_interrupted_by_signal())
|
||||
return true;
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
semaphore.block();
|
||||
return is_interrupted_by_signal();
|
||||
if (is_interrupted_by_signal())
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
return {};
|
||||
}
|
||||
|
||||
void Thread::validate_stack() const
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#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>
|
||||
|
@ -176,12 +177,19 @@ static void init2(void*)
|
|||
|
||||
DevFileSystem::get().initialize_device_updater();
|
||||
|
||||
#if 0
|
||||
dprintln("sleeping for 5 seconds");
|
||||
SystemTimer::get().sleep(5000);
|
||||
#endif
|
||||
|
||||
PCI::PCIManager::initialize();
|
||||
dprintln("PCI initialized");
|
||||
|
||||
VirtualFileSystem::initialize(cmdline.root);
|
||||
dprintln("VFS initialized");
|
||||
|
||||
// Initialize empty keymap
|
||||
MUST(Input::KeyboardLayout::initialize());
|
||||
if (auto res = PS2Controller::initialize(); res.is_error())
|
||||
dprintln("{}", res.error());
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ return value: 0 on success, -1 on failure and errno set to the error
|
|||
int tty_ctrl(int fildes, int command, int flags);
|
||||
int poweroff(int command);
|
||||
|
||||
int load_keymap(const char* path);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,7 @@ __BEGIN_DECLS
|
|||
#define SYS_MSYNC 61
|
||||
#define SYS_PREAD 62
|
||||
#define SYS_CHOWN 63
|
||||
#define SYS_LOAD_KEYMAP 64
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -11,3 +11,8 @@ int poweroff(int command)
|
|||
{
|
||||
return syscall(SYS_POWEROFF, command);
|
||||
}
|
||||
|
||||
int load_keymap(const char* path)
|
||||
{
|
||||
return syscall(SYS_LOAD_KEYMAP, path);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/banan-os.h>
|
||||
#include <termios.h>
|
||||
|
||||
void initialize_stdio()
|
||||
|
@ -25,6 +26,9 @@ int main()
|
|||
if (signal(SIGINT, [](int) {}) == SIG_ERR)
|
||||
perror("signal");
|
||||
|
||||
if (load_keymap("/usr/share/keymaps/fi.keymap") == -1)
|
||||
perror("load_keymap");
|
||||
|
||||
bool first = true;
|
||||
|
||||
termios termios;
|
||||
|
|
Loading…
Reference in New Issue