diff --git a/kernel/Makefile b/kernel/Makefile index 53fba722..22cd222f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -32,8 +32,8 @@ BUILDDIR=$(abspath build) KERNEL_OBJS= \ $(KERNEL_ARCH_OBJS) \ kernel/build_libc.o \ +kernel/Input.o \ kernel/kernel.o \ -kernel/Keyboard.o \ kernel/kmalloc.o \ kernel/PIC.o \ kernel/PIT.o \ diff --git a/kernel/arch/i386/APIC.cpp b/kernel/arch/i386/APIC.cpp index 746d1f6a..c23447e8 100644 --- a/kernel/arch/i386/APIC.cpp +++ b/kernel/arch/i386/APIC.cpp @@ -406,10 +406,10 @@ namespace APIC } } - void EOI() + void EOI(uint8_t irq) { if (s_using_fallback_pic) - return PIC::EOI(0); + return PIC::EOI(irq); WriteLocalAPIC(0xB0, 0); } diff --git a/kernel/arch/i386/IDT.cpp b/kernel/arch/i386/IDT.cpp index d73c2d7a..435170c7 100644 --- a/kernel/arch/i386/IDT.cpp +++ b/kernel/arch/i386/IDT.cpp @@ -144,7 +144,7 @@ found: else Kernel::panic("no handler for irq 0x{2H}\n", irq); - APIC::EOI(); + APIC::EOI(irq); } extern "C" void handle_irq_common(); diff --git a/kernel/include/kernel/APIC.h b/kernel/include/kernel/APIC.h index 59908d71..6c59ca2c 100644 --- a/kernel/include/kernel/APIC.h +++ b/kernel/include/kernel/APIC.h @@ -6,7 +6,7 @@ namespace APIC { void Initialize(bool force_pic = false); - void EOI(); + void EOI(uint8_t irq); void GetISR(uint32_t[8]); void EnableIRQ(uint8_t irq); diff --git a/kernel/include/kernel/Keyboard.h b/kernel/include/kernel/Input.h similarity index 74% rename from kernel/include/kernel/Keyboard.h rename to kernel/include/kernel/Input.h index b42f0880..71a737f3 100644 --- a/kernel/include/kernel/Keyboard.h +++ b/kernel/include/kernel/Input.h @@ -2,7 +2,7 @@ #include -namespace Keyboard +namespace Input { enum class Key : uint8_t @@ -37,13 +37,30 @@ namespace Keyboard bool pressed; }; - bool initialize(); - void update_keyboard(); + enum class MouseButton + { + Left, Right, Middle, + }; + struct MouseButtonEvent + { + MouseButton button; + }; - void register_key_event_callback(void(*callback)(KeyEvent)); + struct MouseMoveEvent + { + int16_t dx; + int16_t dy; + }; + + + bool initialize(); + void update(); + bool is_key_down(Key); + + void register_key_event_callback(void (*callback)(KeyEvent)); + void register_mouse_button_event_callback(void (*callback)(MouseButtonEvent)); + void register_mouse_move_event_callback(void (*callback)(MouseMoveEvent)); const char* key_event_to_utf8(KeyEvent); - void led_disco(); - } \ No newline at end of file diff --git a/kernel/include/kernel/KeyboardLayout/FI.h b/kernel/include/kernel/KeyboardLayout/FI.h index 0dd99442..94ffe843 100644 --- a/kernel/include/kernel/KeyboardLayout/FI.h +++ b/kernel/include/kernel/KeyboardLayout/FI.h @@ -1,8 +1,8 @@ #pragma once -#include +#include -namespace Keyboard +namespace Input { constexpr Key scan_code_to_key_extended[0xFF] diff --git a/kernel/include/kernel/Shell.h b/kernel/include/kernel/Shell.h index 79a6f194..38caddfc 100644 --- a/kernel/include/kernel/Shell.h +++ b/kernel/include/kernel/Shell.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include namespace Kernel @@ -22,7 +22,7 @@ namespace Kernel Shell(); void PrintPrompt(); void ProcessCommand(const BAN::Vector&); - void KeyEventCallback(Keyboard::KeyEvent); + void KeyEventCallback(Input::KeyEvent); private: TTY* m_tty; diff --git a/kernel/kernel/Keyboard.cpp b/kernel/kernel/Input.cpp similarity index 56% rename from kernel/kernel/Keyboard.cpp rename to kernel/kernel/Input.cpp index 644033e4..e9769e67 100644 --- a/kernel/kernel/Keyboard.cpp +++ b/kernel/kernel/Input.cpp @@ -1,8 +1,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -23,12 +23,13 @@ #define I8042_CONFING_IRQ_FIRST (1 << 0) #define I8042_CONFING_IRQ_SECOND (1 << 1) +#define I8042_CONFING_DUAL_CHANNEL (1 << 5) #define I8042_CONFING_TRANSLATION (1 << 6) -#define I8042_ENABLE_FIRST 0xAE -#define I8042_ENABLE_SECOND 0xA8 -#define I8042_DISABLE_FIRST 0xAD -#define I8042_DISABLE_SECOND 0xA7 +#define I8042_ENABLE_FIRST_PORT 0xAE +#define I8042_ENABLE_SECOND_PORT 0xA8 +#define I8042_DISABLE_FIRST_PORT 0xAD +#define I8042_DISABLE_SECOND_PORT 0xA7 #define I8042_TEST_CONTROLLER 0xAA #define I8042_TEST_CONTROLLER_PASS 0x55 @@ -50,7 +51,17 @@ #define I8042_KB_LED_NUM_LOCK (1 << 1) #define I8042_KB_LED_CAPS_LOCK (1 << 2) +#define I8042_MOUSE_ACK 0xFA +#define I8042_MOUSE_RESET 0xFF +#define I8042_MOUSE_SELF_TEST_PASS 0xAA +#define I8042_MOUSE_ENABLE 0xF4 +#define I8042_MOUSE_DISABLE 0xF5 + #define KEYBOARD_IRQ 0x01 +#define MOUSE_IRQ 0x0C + +#define TARGET_KEYBOARD 1 +#define TARGET_MOUSE 2 #define MOD_ALT (1 << 0) #define MOD_CTRL (1 << 1) @@ -58,32 +69,41 @@ #define MOD_ALTGR (1 << 3) #define MOD_CAPS (1 << 4) -namespace Keyboard +namespace Input { static bool s_keyboard_state[0xFF] = {}; struct Command { + uint8_t target = 0; uint8_t command = 0; uint8_t data = 0; bool has_data = false; - bool extra = false; + uint8_t resp_cnt = 0; uint8_t _sent = 0; uint8_t _ack = 0; bool _done = false; }; - static BAN::Queue s_keyboard_command_queue; - static uint8_t s_keyboard_command_extra = 0x00; + static BAN::Queue s_command_queue; + static uint8_t s_command_response[3] = {}; + static uint8_t s_command_response_index = 0; static BAN::Queue s_key_event_queue; static uint8_t s_keyboard_key_buffer[10] = {}; static uint8_t s_keyboard_key_buffer_size = 0; + static BAN::Queue s_mouse_button_event_queue; + static BAN::Queue s_mouse_move_event_queue; + static uint8_t s_mouse_data_buffer[3] = {}; + static uint8_t s_mouse_data_buffer_index = 0; + static uint8_t s_led_states = 0b000; static uint8_t s_modifiers = 0x00; static void (*s_key_event_callback)(KeyEvent) = nullptr; + static void (*s_mouse_button_event_callback)(MouseButtonEvent) = nullptr; + static void (*s_mouse_move_event_callback)(MouseMoveEvent) = nullptr; static const char* s_key_to_utf8_lower[] { @@ -107,7 +127,7 @@ namespace Keyboard nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }; - static_assert(sizeof(s_key_to_utf8_lower) == static_cast(Key::Count) * sizeof(*s_key_to_utf8_lower)); + static_assert(sizeof(s_key_to_utf8_lower) == (int)Key::Count * sizeof(*s_key_to_utf8_lower)); static const char* s_key_to_utf8_upper[] { @@ -131,7 +151,7 @@ namespace Keyboard nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }; - static_assert(sizeof(s_key_to_utf8_upper) == static_cast(Key::Count) * sizeof(*s_key_to_utf8_upper)); + static_assert(sizeof(s_key_to_utf8_upper) == (int)Key::Count * sizeof(*s_key_to_utf8_upper)); static uint8_t wait_and_read() { @@ -153,8 +173,11 @@ namespace Keyboard IO::outb(I8042_DATA_PORT, data); } - static bool i8042_keyboard_command(uint8_t command) + static bool i8042_command(uint8_t target, uint8_t command) { + if (target == TARGET_MOUSE) + IO::outb(I8042_STATUS_REGISTER, 0xD4); + auto timeout = PIT::ms_since_boot() + I8042_KB_TIMEOUT_MS; while (PIT::ms_since_boot() < timeout) @@ -169,40 +192,66 @@ namespace Keyboard return false; } - void update_keyboard() + void update() { - if (!s_keyboard_command_queue.Empty()) + if (!s_command_queue.Empty()) { - auto& command = s_keyboard_command_queue.Front(); + auto& command = s_command_queue.Front(); + if (command.target != TARGET_KEYBOARD && command.target != TARGET_MOUSE) + Kernel::panic("Undefined target for command 0x{2H}", command.command); if (command._sent == 0 && command._ack == 0) { - if (!i8042_keyboard_command(command.command)) - Kernel::panic("oof 1"); + if (!i8042_command(command.target, command.command)) + Kernel::panic("PS/2 command oof {}, 0x{2H}", command.target, command.command); command._sent++; } if (command._sent == 1 && command._ack == 1 && command.has_data) { - if (!i8042_keyboard_command(command.data)) - Kernel::panic("oof 2"); + if (!i8042_command(command.target, command.data)) + Kernel::panic("PS/2 data oof {}, 0x{2H}", command.target, command.data); command._sent++; } if (command._done) { - switch (command.command) + if (command.target == TARGET_KEYBOARD) { - case I8042_KB_RESET: - if (s_keyboard_command_extra != I8042_KB_SELF_TEST_PASS) - Kernel::panic("PS/2 Keyboard self test failed"); - break; - case I8042_KB_SET_SCAN_CODE_SET: - break; - case I8042_KB_SET_LEDS: - break; + switch (command.command) + { + case I8042_KB_RESET: + if (s_command_response[0] != I8042_KB_SELF_TEST_PASS) + Kernel::panic("PS/2 Keyboard self test failed"); + break; + case I8042_KB_SET_SCAN_CODE_SET: + break; + case I8042_KB_SET_LEDS: + break; + default: + Kernel::panic("PS/2 Keyboard unhandled command"); + } } - s_keyboard_command_queue.Pop(); + else if (command.target == TARGET_MOUSE) + { + switch (command.command) + { + case I8042_MOUSE_RESET: + if (s_command_response[0] != I8042_MOUSE_SELF_TEST_PASS) + Kernel::panic("PS/2 Mouse self test failed"); + if (s_command_response[1] != 0x00) + Kernel::panic("PS/2 Mouse invalid byte sent after self test"); + break; + case I8042_MOUSE_ENABLE: + break; + case I8042_MOUSE_DISABLE: + break; + default: + Kernel::panic("PS/2 Mouse unhandled command"); + } + } + s_command_response_index = 0; + s_command_queue.Pop(); } } @@ -212,6 +261,25 @@ namespace Keyboard s_key_event_callback(s_key_event_queue.Front()); s_key_event_queue.Pop(); } + + while (!s_mouse_button_event_queue.Empty()) + { + if (s_mouse_button_event_callback) + s_mouse_button_event_callback(s_mouse_button_event_queue.Front()); + s_mouse_button_event_queue.Pop(); + } + + while (!s_mouse_move_event_queue.Empty()) + { + if (s_mouse_move_event_callback) + s_mouse_move_event_callback(s_mouse_move_event_queue.Front()); + s_mouse_move_event_queue.Pop(); + } + } + + bool is_key_down(Key key) + { + return s_keyboard_state[(int)key]; } static void keyboard_new_key() @@ -265,7 +333,7 @@ namespace Keyboard kprintln("{} {}", ch, extended ? 'E' : ' '); #endif - s_keyboard_state[static_cast(key)] = pressed; + s_keyboard_state[(int)key] = pressed; bool update_leds = false; switch (key) @@ -291,7 +359,7 @@ namespace Keyboard if (update_leds) { - s_keyboard_command_queue.Push({ + s_command_queue.Push({ .command = I8042_KB_SET_LEDS, .data = s_led_states, .has_data = true, @@ -321,54 +389,52 @@ namespace Keyboard memmove(s_keyboard_key_buffer, s_keyboard_key_buffer + index, s_keyboard_key_buffer_size); } - void keyboard_irq_handler() + static void keyboard_irq_handler() { uint8_t raw = IO::inb(I8042_DATA_PORT); - bool command_waiting = false; - if (!s_keyboard_command_queue.Empty()) + bool waiting_response = false; + if (!s_command_queue.Empty()) { - auto& command = s_keyboard_command_queue.Front(); - command_waiting = (command._sent > 0 && !command._done); + auto& command = s_command_queue.Front(); + if (command.target == TARGET_MOUSE) + Kernel::panic("Please no :( (PS/2 Keyboard got irq while Mouse was waiting)"); + waiting_response = (command._sent > 0 && !command._done); } - if (command_waiting) + if (waiting_response) { - auto& command = s_keyboard_command_queue.Front(); + auto& command = s_command_queue.Front(); + if (raw == I8042_KB_RESEND) { dprintln("PS/2 Keyboard: Resend 0x{H}", command._sent == 2 ? command.data : command.command); command._sent--; - return; } - - if (raw == I8042_KB_ACK) + else if (raw == I8042_KB_ACK) { command._ack++; - if (command.extra > 0) - return; - command._done = command.has_data ? (command._ack == 2) : true; - return; + if (command.resp_cnt == 0) + command._done = (command._ack >= (1 + command.has_data)); } - - if (raw == 0x00) + else if (raw == 0x00) { dprintln("\e[33mKey detection error or internal buffer overrun\e[m"); command._sent = 0; command._ack = 0; command._done = false; - return; + s_command_response_index = 0; } - - if (raw == 0xEE && command.command == 0xEE) + else if (raw == 0xEE && command.command == 0xEE) { - s_keyboard_command_queue.Pop(); - return; + s_command_queue.Pop(); + } + else + { + s_command_response[s_command_response_index++] = raw; + if (s_command_response_index >= command.resp_cnt) + command._done = true; } - - s_keyboard_command_extra = raw; - command._done = true; - return; } else { @@ -378,12 +444,118 @@ namespace Keyboard } } + static void mouse_irq_handler() + { + uint8_t raw = IO::inb(I8042_DATA_PORT); + + bool waiting_response = false; + if (!s_command_queue.Empty()) + { + auto& command = s_command_queue.Front(); + if (command.target == TARGET_KEYBOARD) + Kernel::panic("Please no :( (PS/2 Mouse got irq while Keyboard was waiting)"); + waiting_response = (command._sent > 0 && !command._done); + } + + if (waiting_response) + { + auto& command = s_command_queue.Front(); + + if (raw == I8042_MOUSE_ACK) + { + command._ack++; + if (command.resp_cnt == 0) + command._done = (command._ack >= (1 + command.has_data)); + } + else + { + s_command_response[s_command_response_index++] = raw; + if (s_command_response_index >= command.resp_cnt) + command._done = true; + } + } + else + { + s_mouse_data_buffer[s_mouse_data_buffer_index++] = raw; + + if (s_mouse_data_buffer_index >= 3) + { + if (s_mouse_data_buffer[0] & 0x07) + { + bool left = s_mouse_data_buffer[0] & (1 << 0); + bool right = s_mouse_data_buffer[0] & (1 << 1); + bool middle = s_mouse_data_buffer[0] & (1 << 2); + + if (left) s_mouse_button_event_queue.Push({ .button = MouseButton::Left }); + if (right) s_mouse_button_event_queue.Push({ .button = MouseButton::Right }); + if (middle) s_mouse_button_event_queue.Push({ .button = MouseButton::Middle }); + } + + if (s_mouse_data_buffer[1] || s_mouse_data_buffer[2]) + { + int16_t rel_x = (int16_t)s_mouse_data_buffer[1] - ((s_mouse_data_buffer[0] << 4) & 0x100); + int16_t rel_y = (int16_t)s_mouse_data_buffer[2] - ((s_mouse_data_buffer[0] << 3) & 0x100); + + s_mouse_move_event_queue.Push({ .dx = rel_x, .dy = rel_y }); + } + + s_mouse_data_buffer_index = 0; + } + } + } + + static void initialize_keyboard() + { + MUST(s_command_queue.Push({ + .target = TARGET_KEYBOARD, + .command = I8042_KB_RESET, + .resp_cnt = 1, + })); + + // Set scan code set 2 + MUST(s_command_queue.Push({ + .target = TARGET_KEYBOARD, + .command = I8042_KB_SET_SCAN_CODE_SET, + .data = 0x02, + .has_data = true, + })); + + // Turn LEDs off + MUST(s_command_queue.Push({ + .target = TARGET_KEYBOARD, + .command = I8042_KB_SET_LEDS, + .data = s_led_states, + .has_data = true, + })); + + // Register callback and IRQ + IDT::register_irq_handler(KEYBOARD_IRQ, keyboard_irq_handler); + APIC::EnableIRQ(KEYBOARD_IRQ); + } + + static void initialize_mouse() + { + MUST(s_command_queue.Push({ + .target = TARGET_MOUSE, + .command = I8042_MOUSE_RESET, + .resp_cnt = 2, + })); + + // Mouse should be disabled when sending commands + MUST(s_command_queue.Push({ + .target = TARGET_MOUSE, + .command = I8042_MOUSE_ENABLE, + })); + + // Register callback and IRQ + IDT::register_irq_handler(MOUSE_IRQ, mouse_irq_handler); + APIC::EnableIRQ(MOUSE_IRQ); + } + bool initialize() { // https://wiki.osdev.org/%228042%22_PS/2_Controller - // TODO: support dual channel - // Step 1: Initialize USB Controllers // TODO @@ -391,8 +563,8 @@ namespace Keyboard // TODO // Step 3: Disable Devices - i8042_controller_command(I8042_DISABLE_FIRST); - i8042_controller_command(I8042_DISABLE_SECOND); + i8042_controller_command(I8042_DISABLE_FIRST_PORT); + i8042_controller_command(I8042_DISABLE_SECOND_PORT); // Step 4: Flush The Ouput Buffer while ((IO::inb(I8042_STATUS_REGISTER) & I8042_STATUS_OUT_FULL) != 0) @@ -404,6 +576,7 @@ namespace Keyboard config &= ~(I8042_CONFING_IRQ_FIRST | I8042_CONFING_IRQ_SECOND); i8042_controller_command(I8042_WRITE_CONFIG, config); + // Step 6: Perform Controller Self Test i8042_controller_command(I8042_TEST_CONTROLLER); if (wait_and_read() != I8042_TEST_CONTROLLER_PASS) @@ -413,6 +586,16 @@ namespace Keyboard } // Step 7: Determine If There Are 2 Channels + bool dual_channel = config & I8042_CONFING_DUAL_CHANNEL; + if (dual_channel) + { + i8042_controller_command(I8042_ENABLE_SECOND_PORT); + i8042_controller_command(I8042_READ_CONFIG); + if (wait_and_read() & I8042_CONFING_DUAL_CHANNEL) + dual_channel = false; + else + i8042_controller_command(I8042_DISABLE_SECOND_PORT); + } // Step 8: Perform Interface Tests i8042_controller_command(I8042_TEST_FIRST_PORT); @@ -422,73 +605,54 @@ namespace Keyboard return false; } + if (dual_channel) + { + i8042_controller_command(I8042_TEST_SECOND_PORT); + if (wait_and_read() != I8042_TEST_SECOND_PORT_PASS) + { + dwarnln("PS/2 second port test failed. Mouse will be disabled"); + dual_channel = false; + } + } + // Step 9: Enable Devices config |= I8042_CONFING_IRQ_FIRST; + if (dual_channel) + config |= I8042_CONFING_IRQ_SECOND; i8042_controller_command(I8042_WRITE_CONFIG, config); - i8042_controller_command(I8042_ENABLE_FIRST); + i8042_controller_command(I8042_ENABLE_FIRST_PORT); + i8042_controller_command(I8042_ENABLE_SECOND_PORT); // Step 10: Reset Devices - MUST(s_keyboard_command_queue.Push({ - .command = I8042_KB_RESET, - .extra = true, - })); - - // Set scan code set 2 - MUST(s_keyboard_command_queue.Push({ - .command = I8042_KB_SET_SCAN_CODE_SET, - .data = 0x02, - .has_data = true, - })); - - // Turn LEDs off - MUST(s_keyboard_command_queue.Push({ - .command = I8042_KB_SET_LEDS, - .data = s_led_states, - .has_data = true, - })); - - // Register callback and IRQ - IDT::register_irq_handler(KEYBOARD_IRQ, keyboard_irq_handler); - APIC::EnableIRQ(KEYBOARD_IRQ); + initialize_keyboard(); + if (dual_channel) + initialize_mouse(); return true; } - void register_key_event_callback(void(*callback)(KeyEvent)) + void register_key_event_callback(void (*callback)(KeyEvent)) { s_key_event_callback = callback; } + void register_mouse_button_event_callback(void (*callback)(MouseButtonEvent)) + { + s_mouse_button_event_callback = callback; + } + + void register_mouse_move_event_callback(void (*callback)(MouseMoveEvent)) + { + s_mouse_move_event_callback = callback; + } + const char* key_event_to_utf8(KeyEvent event) { bool shift = event.modifiers & MOD_SHIFT; bool caps = event.modifiers & MOD_CAPS; if (shift ^ caps) - return s_key_to_utf8_upper[static_cast(event.key)]; - return s_key_to_utf8_lower[static_cast(event.key)]; - } - - void led_disco() - { - uint64_t time = PIT::ms_since_boot(); - uint64_t freq = 100; - bool state = false; - for(;;) - { - if (PIT::ms_since_boot() > time + freq) - { - time += freq; - state = !state; - - MUST(s_keyboard_command_queue.Push({ - .command = I8042_KB_SET_LEDS, - .data = (uint8_t)(state ? 0b111 : 0b000), - .has_data = true, - })); - } - - update_keyboard(); - } + return s_key_to_utf8_upper[(int)event.key]; + return s_key_to_utf8_lower[(int)event.key]; } } \ No newline at end of file diff --git a/kernel/kernel/Shell.cpp b/kernel/kernel/Shell.cpp index 18ef3df2..da59cd07 100644 --- a/kernel/kernel/Shell.cpp +++ b/kernel/kernel/Shell.cpp @@ -1,12 +1,12 @@ #include #include #include +#include #include -#include #include #include -#include #include +#include #include #define TTY_PRINT(...) BAN::Formatter::print([this](char c) { m_tty->PutChar(c); }, __VA_ARGS__) @@ -26,7 +26,7 @@ namespace Kernel Shell::Shell() { - Keyboard::register_key_event_callback([](Keyboard::KeyEvent event) { Shell::Get().KeyEventCallback(event); }); + Input::register_key_event_callback([](Input::KeyEvent event) { Shell::Get().KeyEventCallback(event); }); m_buffer.Reserve(128); } @@ -46,7 +46,7 @@ namespace Kernel for (;;) { asm volatile("hlt"); - Keyboard::update_keyboard(); + Input::update(); } } @@ -213,14 +213,14 @@ namespace Kernel return 1; } - void Shell::KeyEventCallback(Keyboard::KeyEvent event) + void Shell::KeyEventCallback(Input::KeyEvent event) { if (!event.pressed) return; switch (event.key) { - case Keyboard::Key::Backspace: + case Input::Key::Backspace: { if (!m_buffer.Empty()) { @@ -233,8 +233,8 @@ namespace Kernel break; } - case Keyboard::Key::Enter: - case Keyboard::Key::NumpadEnter: + case Input::Key::Enter: + case Input::Key::NumpadEnter: { TTY_PRINT("\n"); ProcessCommand(MUST(m_buffer.SV().Split(' '))); @@ -243,16 +243,16 @@ namespace Kernel break; } - case Keyboard::Key::Escape: + case Input::Key::Escape: TTY_PRINTLN("time since boot {} ms", PIT::ms_since_boot()); break; - case Keyboard::Key::Tab: + case Input::Key::Tab: break; default: { - const char* utf8 = Keyboard::key_event_to_utf8(event); + const char* utf8 = Input::key_event_to_utf8(event); if (utf8) { TTY_PRINT("{}", utf8); diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index dba79b2e..acb9f3fb 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -1,8 +1,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -86,7 +86,7 @@ extern "C" void kernel_main(multiboot_info_t* mbi, uint32_t magic) TTY* tty1 = new TTY; tty1->SetCursorPosition(0, 2); - if (!Keyboard::initialize()) + if (!Input::initialize()) return; ENABLE_INTERRUPTS();