mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-29 14:14:45 +03: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
Notes:
sideshowbarker
2024-07-17 06:51:40 +09:00
Author: https://github.com/supercomputer7 Commit: https://github.com/SerenityOS/serenity/commit/8a0a3638f0 Pull-request: https://github.com/SerenityOS/serenity/pull/21357 Reviewed-by: https://github.com/ADKaster ✅
@ -70,6 +70,7 @@ set(KERNEL_SOURCES
|
||||
Devices/KCOVInstance.cpp
|
||||
Devices/PCISerialDevice.cpp
|
||||
Devices/SerialDevice.cpp
|
||||
Devices/HID/AllMiceDevice.cpp
|
||||
Devices/HID/KeyboardDevice.cpp
|
||||
Devices/HID/Management.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
|
||||
|
||||
void HIDManagement::enqueue_mouse_packet(Badge<MouseDevice>, MousePacket packet)
|
||||
{
|
||||
m_all_mice_device->enqueue_mouse_packet(packet);
|
||||
}
|
||||
|
||||
void HIDManagement::set_client(KeyboardClient* client)
|
||||
{
|
||||
SpinlockLocker locker(m_client_lock);
|
||||
@ -103,6 +108,7 @@ UNMAP_AFTER_INIT HIDManagement::KeymapData::KeymapData()
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT HIDManagement::HIDManagement()
|
||||
: m_all_mice_device(AllMiceDevice::must_create())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/API/KeyCode.h>
|
||||
#include <Kernel/Bus/SerialIO/Controller.h>
|
||||
#include <Kernel/Devices/HID/AllMiceDevice.h>
|
||||
#include <Kernel/Devices/HID/Device.h>
|
||||
#include <Kernel/Locking/Spinlock.h>
|
||||
#include <Kernel/Locking/SpinlockProtected.h>
|
||||
@ -32,6 +33,7 @@ class KeyboardClient;
|
||||
class HIDManagement {
|
||||
friend class KeyboardDevice;
|
||||
friend class MouseDevice;
|
||||
friend class AllMiceDevice;
|
||||
|
||||
public:
|
||||
HIDManagement();
|
||||
@ -56,6 +58,8 @@ public:
|
||||
void attach_standalone_hid_device(HIDDevice&);
|
||||
void detach_standalone_hid_device(HIDDevice&);
|
||||
|
||||
void enqueue_mouse_packet(Badge<MouseDevice>, MousePacket);
|
||||
|
||||
private:
|
||||
size_t generate_minor_device_number_for_mouse();
|
||||
size_t generate_minor_device_number_for_keyboard();
|
||||
@ -65,6 +69,8 @@ private:
|
||||
size_t m_keyboard_minor_number { 0 };
|
||||
KeyboardClient* m_client { nullptr };
|
||||
|
||||
NonnullRefPtr<AllMiceDevice> m_all_mice_device;
|
||||
|
||||
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
|
||||
// (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)
|
||||
{
|
||||
m_entropy_source.add_random_event(packet);
|
||||
HIDManagement::the().enqueue_mouse_packet({}, packet);
|
||||
{
|
||||
SpinlockLocker lock(m_queue_lock);
|
||||
m_queue.enqueue(packet);
|
||||
|
Loading…
Reference in New Issue
Block a user