diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 31f8f8ee2f..cf185ea766 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -97,6 +97,7 @@ set(KERNEL_SOURCES kernel/USB/Device.cpp kernel/USB/HID/HIDDriver.cpp kernel/USB/HID/Keyboard.cpp + kernel/USB/HID/Mouse.cpp kernel/USB/USBManager.cpp kernel/USB/XHCI/Controller.cpp kernel/USB/XHCI/Device.cpp diff --git a/kernel/include/kernel/USB/HID/Mouse.h b/kernel/include/kernel/USB/HID/Mouse.h new file mode 100644 index 0000000000..1950beb469 --- /dev/null +++ b/kernel/include/kernel/USB/HID/Mouse.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +namespace Kernel +{ + + class USBMouse final : public USBHIDDevice + { + BAN_NON_COPYABLE(USBMouse); + BAN_NON_MOVABLE(USBMouse); + + public: + void start_report() override; + void stop_report() override; + + void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override; + void handle_array(uint16_t usage_page, uint16_t usage) override; + + private: + USBMouse() + : USBHIDDevice(InputDevice::Type::Mouse) + {} + ~USBMouse() = default; + + private: + BAN::Array m_button_state { false }; + BAN::Array m_button_state_temp { false }; + int64_t m_pointer_x { 0 }; + int64_t m_pointer_y { 0 }; + int64_t m_wheel { 0 }; + + friend class BAN::RefPtr; + }; + +} diff --git a/kernel/kernel/USB/HID/HIDDriver.cpp b/kernel/kernel/USB/HID/HIDDriver.cpp index fb337f2959..bfa604cdd8 100644 --- a/kernel/kernel/USB/HID/HIDDriver.cpp +++ b/kernel/kernel/USB/HID/HIDDriver.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #define DEBUG_HID 0 @@ -219,6 +220,9 @@ namespace Kernel switch (collection.usage_id) { + case 0x02: + m_hid_device = TRY(BAN::RefPtr::create()); + break; case 0x06: m_hid_device = TRY(BAN::RefPtr::create()); break; diff --git a/kernel/kernel/USB/HID/Mouse.cpp b/kernel/kernel/USB/HID/Mouse.cpp new file mode 100644 index 0000000000..4412299685 --- /dev/null +++ b/kernel/kernel/USB/HID/Mouse.cpp @@ -0,0 +1,99 @@ +#include +#include + +#define DEBUG_MOUSE 0 + +namespace Kernel +{ + + void USBMouse::start_report() + { + for (auto& val : m_button_state_temp) + val = false; + } + + void USBMouse::stop_report() + { + if (m_pointer_x || m_pointer_y) + { + dprintln_if(DEBUG_MOUSE, "Mouse move event {}, {}", m_pointer_x, m_pointer_y); + + LibInput::MouseEvent event; + event.type = LibInput::MouseEventType::MouseMoveEvent; + event.move_event.rel_x = m_pointer_x; + event.move_event.rel_y = -m_pointer_y; + add_event(BAN::ConstByteSpan::from(event)); + + m_pointer_x = 0; + m_pointer_y = 0; + } + + if (m_wheel) + { + dprintln_if(DEBUG_MOUSE, "Mouse scroll event {}", m_wheel); + + LibInput::MouseEvent event; + event.type = LibInput::MouseEventType::MouseScrollEvent; + event.scroll_event.scroll = m_wheel; + add_event(BAN::ConstByteSpan::from(event)); + + m_wheel = 0; + } + + for (size_t i = 0; i < m_button_state.size(); i++) + { + if (m_button_state[i] == m_button_state_temp[i]) + continue; + + const bool pressed = m_button_state_temp[i]; + + dprintln_if(DEBUG_MOUSE, "Mouse button event {}: {}", i, pressed); + + LibInput::MouseEvent event; + event.type = LibInput::MouseEventType::MouseButtonEvent; + event.button_event.pressed = pressed; + event.button_event.button = static_cast(i); + add_event(BAN::ConstByteSpan::from(event)); + + m_button_state[i] = m_button_state_temp[i]; + } + } + + void USBMouse::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) + { + switch (usage_page) + { + case 0x01: // pointer + switch (usage) + { + case 0x30: + m_pointer_x = state; + break; + case 0x31: + m_pointer_y = state; + break; + case 0x38: + m_wheel = state; + break; + default: + dprintln_if(DEBUG_MOUSE, "Unsupported mouse usage {2H} on page {2H}", usage, usage_page); + break; + } + break; + case 0x09: // button + if (usage == 0 || usage >= m_button_state_temp.size()) + break; + m_button_state_temp[usage - 1] = state; + break; + default: + dprintln_if(DEBUG_MOUSE, "Unsupported mouse usage page {2H}", usage_page); + break; + } + } + + void USBMouse::handle_array(uint16_t usage_page, uint16_t usage) + { + dprintln_if(DEBUG_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage); + } + +}