Kernel: Fix TTY reading one keyevent after disabling input handling

This commit is contained in:
Bananymous 2024-09-22 17:13:10 +03:00
parent 1280528e4e
commit d59463d11b
3 changed files with 39 additions and 24 deletions

View File

@ -160,6 +160,7 @@ namespace Kernel
BAN::WeakPtr<SharedFileData> m_shared_region;
friend class FileBackedRegion;
friend class SharedFileData;
friend class TTY;
};
}

View File

@ -28,6 +28,7 @@ namespace Kernel
static BAN::RefPtr<TTY> current();
void set_as_current();
static void keyboard_task(void*);
static void initialize_devices();
void on_key_event(LibInput::KeyEvent);
void handle_input_byte(uint8_t);

View File

@ -8,6 +8,7 @@
#include <kernel/Lock/LockGuard.h>
#include <kernel/Process.h>
#include <kernel/Terminal/TTY.h>
#include <kernel/Timer/Timer.h>
#include <LibInput/KeyboardLayout.h>
#include <fcntl.h>
@ -95,35 +96,47 @@ namespace Kernel
return {};
}
void TTY::keyboard_task(void*)
{
BAN::RefPtr<Inode> keyboard_inode;
if (auto ret = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY); !ret.is_error())
keyboard_inode = ret.value().inode;
else
{
dprintln("could not open keyboard device: {}", ret.error());
return;
}
while (true)
{
while (!TTY::current()->m_tty_ctrl.receive_input)
TTY::current()->m_tty_ctrl.thread_blocker.block_indefinite();
while (TTY::current()->m_tty_ctrl.receive_input)
{
LockGuard _(keyboard_inode->m_mutex);
if (!keyboard_inode->can_read())
{
SystemTimer::get().sleep_ms(1);
continue;
}
LibInput::RawKeyEvent event;
[[maybe_unused]] const size_t read = MUST(keyboard_inode->read(0, BAN::ByteSpan::from(event)));
ASSERT(read == sizeof(event));
TTY::current()->on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
}
}
}
void TTY::initialize_devices()
{
static bool initialized = false;
ASSERT(!initialized);
Process::create_kernel(
[](void*)
{
auto file_or_error = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY);
if (file_or_error.is_error())
{
dprintln("no keyboard found");
return;
}
auto inode = file_or_error.value().inode;
while (true)
{
while (!TTY::current()->m_tty_ctrl.receive_input)
TTY::current()->m_tty_ctrl.thread_blocker.block_indefinite();
LibInput::RawKeyEvent event;
size_t read = MUST(inode->read(0, BAN::ByteSpan::from(event)));
ASSERT(read == sizeof(event));
TTY::current()->on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
}
}, nullptr
);
auto* thread = MUST(Thread::create_kernel(&TTY::keyboard_task, nullptr, nullptr));
MUST(Processor::scheduler().add_thread(thread));
initialized = true;
}