mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:57:35 +00:00
Kernel/HID: Introduce the all-mice device
This device will be used by userspace to read mouse packets from all mouse devices that are attached to the machine. This change is a preparation before we can enable seamless hotplug capabilities in WindowServer for mouse devices, without any major change on the userspace side.
This commit is contained in:
parent
75183402fd
commit
8a0a3638f0
6 changed files with 111 additions and 0 deletions
|
@ -70,6 +70,7 @@ set(KERNEL_SOURCES
|
||||||
Devices/KCOVInstance.cpp
|
Devices/KCOVInstance.cpp
|
||||||
Devices/PCISerialDevice.cpp
|
Devices/PCISerialDevice.cpp
|
||||||
Devices/SerialDevice.cpp
|
Devices/SerialDevice.cpp
|
||||||
|
Devices/HID/AllMiceDevice.cpp
|
||||||
Devices/HID/KeyboardDevice.cpp
|
Devices/HID/KeyboardDevice.cpp
|
||||||
Devices/HID/Management.cpp
|
Devices/HID/Management.cpp
|
||||||
Devices/HID/MouseDevice.cpp
|
Devices/HID/MouseDevice.cpp
|
||||||
|
|
57
Kernel/Devices/HID/AllMiceDevice.cpp
Normal file
57
Kernel/Devices/HID/AllMiceDevice.cpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kernel/Devices/DeviceManagement.h>
|
||||||
|
#include <Kernel/Devices/HID/AllMiceDevice.h>
|
||||||
|
#include <Kernel/Devices/HID/Management.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
NonnullRefPtr<AllMiceDevice> AllMiceDevice::must_create()
|
||||||
|
{
|
||||||
|
return *MUST(DeviceManagement::try_create_device<AllMiceDevice>());
|
||||||
|
}
|
||||||
|
|
||||||
|
AllMiceDevice::AllMiceDevice()
|
||||||
|
: CharacterDevice(12, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AllMiceDevice::enqueue_mouse_packet(MousePacket packet)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
SpinlockLocker lock(m_queue_lock);
|
||||||
|
m_queue.enqueue(packet);
|
||||||
|
}
|
||||||
|
evaluate_block_conditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
AllMiceDevice::~AllMiceDevice() = default;
|
||||||
|
|
||||||
|
bool AllMiceDevice::can_read(OpenFileDescription const&, u64) const
|
||||||
|
{
|
||||||
|
SpinlockLocker lock(m_queue_lock);
|
||||||
|
return !m_queue.is_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<size_t> AllMiceDevice::read(OpenFileDescription&, u64, UserOrKernelBuffer& buffer, size_t size)
|
||||||
|
{
|
||||||
|
VERIFY(size > 0);
|
||||||
|
size_t nread = 0;
|
||||||
|
size_t remaining_space_in_buffer = static_cast<size_t>(size) - nread;
|
||||||
|
SpinlockLocker lock(m_queue_lock);
|
||||||
|
while (!m_queue.is_empty() && remaining_space_in_buffer) {
|
||||||
|
auto packet = m_queue.dequeue();
|
||||||
|
|
||||||
|
size_t bytes_read_from_packet = min(remaining_space_in_buffer, sizeof(MousePacket));
|
||||||
|
TRY(buffer.write(&packet, nread, bytes_read_from_packet));
|
||||||
|
nread += bytes_read_from_packet;
|
||||||
|
remaining_space_in_buffer -= bytes_read_from_packet;
|
||||||
|
}
|
||||||
|
return nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
Kernel/Devices/HID/AllMiceDevice.h
Normal file
40
Kernel/Devices/HID/AllMiceDevice.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/CircularQueue.h>
|
||||||
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/API/MousePacket.h>
|
||||||
|
#include <Kernel/Devices/CharacterDevice.h>
|
||||||
|
#include <Kernel/Security/Random.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
class AllMiceDevice final : public CharacterDevice {
|
||||||
|
friend class DeviceManagement;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static NonnullRefPtr<AllMiceDevice> must_create();
|
||||||
|
|
||||||
|
virtual ~AllMiceDevice() override;
|
||||||
|
|
||||||
|
void enqueue_mouse_packet(MousePacket packet);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AllMiceDevice();
|
||||||
|
|
||||||
|
// ^CharacterDevice
|
||||||
|
virtual StringView class_name() const override { return "AllMiceDevice"sv; }
|
||||||
|
virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override;
|
||||||
|
virtual bool can_read(OpenFileDescription const&, u64) const override;
|
||||||
|
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override { return EINVAL; }
|
||||||
|
virtual bool can_write(OpenFileDescription const&, u64) const override { return true; }
|
||||||
|
|
||||||
|
mutable Spinlock<LockRank::None> m_queue_lock {};
|
||||||
|
CircularQueue<MousePacket, 1000> m_queue;
|
||||||
|
};
|
||||||
|
}
|
|
@ -79,6 +79,11 @@ static constexpr Keyboard::CharacterMapData DEFAULT_CHARACTER_MAP =
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
void HIDManagement::enqueue_mouse_packet(Badge<MouseDevice>, MousePacket packet)
|
||||||
|
{
|
||||||
|
m_all_mice_device->enqueue_mouse_packet(packet);
|
||||||
|
}
|
||||||
|
|
||||||
void HIDManagement::set_client(KeyboardClient* client)
|
void HIDManagement::set_client(KeyboardClient* client)
|
||||||
{
|
{
|
||||||
SpinlockLocker locker(m_client_lock);
|
SpinlockLocker locker(m_client_lock);
|
||||||
|
@ -103,6 +108,7 @@ UNMAP_AFTER_INIT HIDManagement::KeymapData::KeymapData()
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT HIDManagement::HIDManagement()
|
UNMAP_AFTER_INIT HIDManagement::HIDManagement()
|
||||||
|
: m_all_mice_device(AllMiceDevice::must_create())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/API/KeyCode.h>
|
#include <Kernel/API/KeyCode.h>
|
||||||
#include <Kernel/Bus/SerialIO/Controller.h>
|
#include <Kernel/Bus/SerialIO/Controller.h>
|
||||||
|
#include <Kernel/Devices/HID/AllMiceDevice.h>
|
||||||
#include <Kernel/Devices/HID/Device.h>
|
#include <Kernel/Devices/HID/Device.h>
|
||||||
#include <Kernel/Locking/Spinlock.h>
|
#include <Kernel/Locking/Spinlock.h>
|
||||||
#include <Kernel/Locking/SpinlockProtected.h>
|
#include <Kernel/Locking/SpinlockProtected.h>
|
||||||
|
@ -32,6 +33,7 @@ class KeyboardClient;
|
||||||
class HIDManagement {
|
class HIDManagement {
|
||||||
friend class KeyboardDevice;
|
friend class KeyboardDevice;
|
||||||
friend class MouseDevice;
|
friend class MouseDevice;
|
||||||
|
friend class AllMiceDevice;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HIDManagement();
|
HIDManagement();
|
||||||
|
@ -56,6 +58,8 @@ public:
|
||||||
void attach_standalone_hid_device(HIDDevice&);
|
void attach_standalone_hid_device(HIDDevice&);
|
||||||
void detach_standalone_hid_device(HIDDevice&);
|
void detach_standalone_hid_device(HIDDevice&);
|
||||||
|
|
||||||
|
void enqueue_mouse_packet(Badge<MouseDevice>, MousePacket);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t generate_minor_device_number_for_mouse();
|
size_t generate_minor_device_number_for_mouse();
|
||||||
size_t generate_minor_device_number_for_keyboard();
|
size_t generate_minor_device_number_for_keyboard();
|
||||||
|
@ -65,6 +69,8 @@ private:
|
||||||
size_t m_keyboard_minor_number { 0 };
|
size_t m_keyboard_minor_number { 0 };
|
||||||
KeyboardClient* m_client { nullptr };
|
KeyboardClient* m_client { nullptr };
|
||||||
|
|
||||||
|
NonnullRefPtr<AllMiceDevice> m_all_mice_device;
|
||||||
|
|
||||||
SpinlockProtected<IntrusiveList<&SerialIOController::m_list_node>, LockRank::None> m_hid_serial_io_controllers;
|
SpinlockProtected<IntrusiveList<&SerialIOController::m_list_node>, LockRank::None> m_hid_serial_io_controllers;
|
||||||
// NOTE: This list is used for standalone devices, like USB HID devices
|
// NOTE: This list is used for standalone devices, like USB HID devices
|
||||||
// (which are not attached via a SerialIO controller in the sense that
|
// (which are not attached via a SerialIO controller in the sense that
|
||||||
|
|
|
@ -23,6 +23,7 @@ MouseDevice::MouseDevice()
|
||||||
void MouseDevice::handle_mouse_packet_input_event(MousePacket packet)
|
void MouseDevice::handle_mouse_packet_input_event(MousePacket packet)
|
||||||
{
|
{
|
||||||
m_entropy_source.add_random_event(packet);
|
m_entropy_source.add_random_event(packet);
|
||||||
|
HIDManagement::the().enqueue_mouse_packet({}, packet);
|
||||||
{
|
{
|
||||||
SpinlockLocker lock(m_queue_lock);
|
SpinlockLocker lock(m_queue_lock);
|
||||||
m_queue.enqueue(packet);
|
m_queue.enqueue(packet);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue