Kernel: Implement unified input files for device hot-plugging support

/dev/keyboard and /dev/mouse can be read for events from any attached
keyboard or mouse respectively. This makes device hot-plugging support
pretty much automatic for TTY, GUI, and whatever takes input.
This commit is contained in:
2024-07-15 22:11:15 +03:00
parent 9d7f97ccd5
commit a5cb4057f9
7 changed files with 216 additions and 19 deletions

View File

@@ -7,7 +7,7 @@
namespace Kernel
{
class InputDevice : public CharacterDevice
class InputDevice : public CharacterDevice, public BAN::Weakable<InputDevice>
{
public:
enum class Type
@@ -19,6 +19,9 @@ namespace Kernel
public:
InputDevice(Type type);
BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; }
protected:
void add_event(BAN::ConstByteSpan);
@@ -28,8 +31,9 @@ namespace Kernel
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
virtual BAN::StringView name() const final override { return m_name; }
virtual dev_t rdev() const final override { return m_rdev; }
private:
BAN::ErrorOr<size_t> read_non_block(BAN::ByteSpan);
private:
const dev_t m_rdev;
@@ -47,6 +51,63 @@ namespace Kernel
size_t m_event_tail { 0 };
size_t m_event_head { 0 };
size_t m_event_count { 0 };
friend class KeyboardDevice;
friend class MouseDevice;
};
class KeyboardDevice : public CharacterDevice
{
public:
static BAN::ErrorOr<BAN::RefPtr<KeyboardDevice>> create(mode_t mode, uid_t uid, gid_t gid);
void notify() { m_semaphore.unblock(); }
private:
KeyboardDevice(mode_t mode, uid_t uid, gid_t gid);
BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
bool can_read_impl() const override;
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; }
private:
const dev_t m_rdev;
const BAN::StringView m_name;
Semaphore m_semaphore;
friend class BAN::RefPtr<KeyboardDevice>;
};
class MouseDevice : public CharacterDevice
{
public:
static BAN::ErrorOr<BAN::RefPtr<MouseDevice>> create(mode_t mode, uid_t uid, gid_t gid);
void notify() { m_semaphore.unblock(); }
private:
MouseDevice(mode_t mode, uid_t uid, gid_t gid);
BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
bool can_read_impl() const override;
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; }
private:
const dev_t m_rdev;
const BAN::StringView m_name;
Semaphore m_semaphore;
friend class BAN::RefPtr<MouseDevice>;
};
}