Kernel: Add support for absolute position mouse
This commit is contained in:
parent
a0d1a9ad67
commit
2c65590134
|
@ -58,8 +58,9 @@ namespace Kernel
|
||||||
virtual void start_report() = 0;
|
virtual void start_report() = 0;
|
||||||
virtual void stop_report() = 0;
|
virtual void stop_report() = 0;
|
||||||
|
|
||||||
virtual void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) = 0;
|
|
||||||
virtual void handle_array(uint16_t usage_page, uint16_t usage) = 0;
|
virtual void handle_array(uint16_t usage_page, uint16_t usage) = 0;
|
||||||
|
virtual void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) = 0;
|
||||||
|
virtual void handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class USBHIDDriver final : public USBClassDriver
|
class USBHIDDriver final : public USBClassDriver
|
||||||
|
|
|
@ -14,8 +14,9 @@ namespace Kernel
|
||||||
void start_report() override;
|
void start_report() override;
|
||||||
void stop_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;
|
void handle_array(uint16_t usage_page, uint16_t usage) override;
|
||||||
|
void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override;
|
||||||
|
void handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max) override;
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,9 @@ namespace Kernel
|
||||||
void start_report() override;
|
void start_report() override;
|
||||||
void stop_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;
|
void handle_array(uint16_t usage_page, uint16_t usage) override;
|
||||||
|
void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override;
|
||||||
|
void handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USBMouse()
|
USBMouse()
|
||||||
|
@ -23,13 +24,25 @@ namespace Kernel
|
||||||
{}
|
{}
|
||||||
~USBMouse() = default;
|
~USBMouse() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct AbsInfo
|
||||||
|
{
|
||||||
|
int64_t val { -1 };
|
||||||
|
int64_t min { 0 };
|
||||||
|
int64_t max { 0 };
|
||||||
|
bool valid() const { return min <= val && val <= max; }
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::Array<bool, 5> m_button_state { false };
|
BAN::Array<bool, 5> m_button_state { false };
|
||||||
BAN::Array<bool, 5> m_button_state_temp { false };
|
BAN::Array<bool, 5> m_button_state_temp { false };
|
||||||
int64_t m_pointer_x { 0 };
|
int64_t m_rel_x { 0 };
|
||||||
int64_t m_pointer_y { 0 };
|
int64_t m_rel_y { 0 };
|
||||||
int64_t m_wheel { 0 };
|
int64_t m_wheel { 0 };
|
||||||
|
|
||||||
|
AbsInfo m_abs_x;
|
||||||
|
AbsInfo m_abs_y;
|
||||||
|
|
||||||
friend class BAN::RefPtr<USBMouse>;
|
friend class BAN::RefPtr<USBMouse>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -376,17 +376,26 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int64_t physical =
|
|
||||||
(input.physical_maximum - input.physical_minimum) *
|
|
||||||
(logical - input.logical_minimum) /
|
|
||||||
(input.logical_maximum - input.logical_minimum) +
|
|
||||||
input.physical_minimum;
|
|
||||||
|
|
||||||
const uint32_t usage_base = input.usage_id ? input.usage_id : input.usage_minimum;
|
const uint32_t usage_base = input.usage_id ? input.usage_id : input.usage_minimum;
|
||||||
if (input.flags & 0x02)
|
|
||||||
device_input.device->handle_variable(input.usage_page, usage_base + i, physical);
|
const bool relative = !!(input.flags & 0x04);
|
||||||
|
const bool variable = !!(input.flags & 0x02);
|
||||||
|
|
||||||
|
if (!variable)
|
||||||
|
device_input.device->handle_array(input.usage_page, usage_base + logical);
|
||||||
else
|
else
|
||||||
device_input.device->handle_array(input.usage_page, usage_base + physical);
|
{
|
||||||
|
const int64_t physical =
|
||||||
|
(input.physical_maximum - input.physical_minimum) *
|
||||||
|
(logical - input.logical_minimum) /
|
||||||
|
(input.logical_maximum - input.logical_minimum) +
|
||||||
|
input.physical_minimum;
|
||||||
|
|
||||||
|
if (relative)
|
||||||
|
device_input.device->handle_variable(input.usage_page, usage_base + i, physical);
|
||||||
|
else
|
||||||
|
device_input.device->handle_variable_absolute(input.usage_page, usage_base + i, physical, input.physical_minimum, input.physical_maximum);
|
||||||
|
}
|
||||||
|
|
||||||
bit_offset += input.report_size;
|
bit_offset += input.report_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,21 +102,6 @@ namespace Kernel
|
||||||
m_keyboard_lock.unlock(m_lock_state);
|
m_keyboard_lock.unlock(m_lock_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBKeyboard::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
|
|
||||||
{
|
|
||||||
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
|
||||||
|
|
||||||
if (usage_page != 0x07)
|
|
||||||
{
|
|
||||||
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!state)
|
|
||||||
return;
|
|
||||||
if (usage >= 4 && usage < m_keyboard_state_temp.size())
|
|
||||||
m_keyboard_state_temp[usage] = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBKeyboard::handle_array(uint16_t usage_page, uint16_t usage)
|
void USBKeyboard::handle_array(uint16_t usage_page, uint16_t usage)
|
||||||
{
|
{
|
||||||
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
||||||
|
@ -130,6 +115,31 @@ namespace Kernel
|
||||||
m_keyboard_state_temp[usage] = true;
|
m_keyboard_state_temp[usage] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBKeyboard::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
|
||||||
|
{
|
||||||
|
(void)usage_page;
|
||||||
|
(void)usage;
|
||||||
|
(void)state;
|
||||||
|
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard relative usage page {2H}", usage_page);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBKeyboard::handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max)
|
||||||
|
{
|
||||||
|
(void)min; (void)max;
|
||||||
|
|
||||||
|
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
||||||
|
|
||||||
|
if (usage_page != 0x07)
|
||||||
|
{
|
||||||
|
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!state)
|
||||||
|
return;
|
||||||
|
if (usage >= 4 && usage < m_keyboard_state_temp.size())
|
||||||
|
m_keyboard_state_temp[usage] = state;
|
||||||
|
}
|
||||||
|
|
||||||
void USBKeyboard::update()
|
void USBKeyboard::update()
|
||||||
{
|
{
|
||||||
using KeyModifier = LibInput::KeyEvent::Modifier;
|
using KeyModifier = LibInput::KeyEvent::Modifier;
|
||||||
|
|
|
@ -6,24 +6,43 @@ namespace Kernel
|
||||||
|
|
||||||
void USBMouse::start_report()
|
void USBMouse::start_report()
|
||||||
{
|
{
|
||||||
|
m_wheel = 0;
|
||||||
|
m_rel_x = 0;
|
||||||
|
m_rel_y = 0;
|
||||||
|
|
||||||
|
m_abs_x = {};
|
||||||
|
m_abs_y = {};
|
||||||
|
|
||||||
for (auto& val : m_button_state_temp)
|
for (auto& val : m_button_state_temp)
|
||||||
val = false;
|
val = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBMouse::stop_report()
|
void USBMouse::stop_report()
|
||||||
{
|
{
|
||||||
if (m_pointer_x || m_pointer_y)
|
if (m_abs_x.valid() && m_abs_y.valid())
|
||||||
{
|
{
|
||||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse move event {}, {}", m_pointer_x, m_pointer_y);
|
dprintln_if(DEBUG_USB_MOUSE, "Mouse move absolute event {}, {}", m_abs_x.val, m_abs_y.val);
|
||||||
|
|
||||||
|
LibInput::MouseEvent event;
|
||||||
|
event.type = LibInput::MouseEventType::MouseMoveAbsEvent;
|
||||||
|
event.move_abs_event.abs_x = m_abs_x.val;
|
||||||
|
event.move_abs_event.min_x = m_abs_x.min;
|
||||||
|
event.move_abs_event.max_x = m_abs_x.max;
|
||||||
|
event.move_abs_event.abs_y = m_abs_y.val;
|
||||||
|
event.move_abs_event.min_y = m_abs_y.min;
|
||||||
|
event.move_abs_event.max_y = m_abs_y.max;
|
||||||
|
add_event(BAN::ConstByteSpan::from(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rel_x || m_rel_y)
|
||||||
|
{
|
||||||
|
dprintln_if(DEBUG_USB_MOUSE, "Mouse move event {}, {}", m_rel_x, m_rel_y);
|
||||||
|
|
||||||
LibInput::MouseEvent event;
|
LibInput::MouseEvent event;
|
||||||
event.type = LibInput::MouseEventType::MouseMoveEvent;
|
event.type = LibInput::MouseEventType::MouseMoveEvent;
|
||||||
event.move_event.rel_x = m_pointer_x;
|
event.move_event.rel_x = m_rel_x;
|
||||||
event.move_event.rel_y = -m_pointer_y;
|
event.move_event.rel_y = -m_rel_y;
|
||||||
add_event(BAN::ConstByteSpan::from(event));
|
add_event(BAN::ConstByteSpan::from(event));
|
||||||
|
|
||||||
m_pointer_x = 0;
|
|
||||||
m_pointer_y = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_wheel)
|
if (m_wheel)
|
||||||
|
@ -34,8 +53,6 @@ namespace Kernel
|
||||||
event.type = LibInput::MouseEventType::MouseScrollEvent;
|
event.type = LibInput::MouseEventType::MouseScrollEvent;
|
||||||
event.scroll_event.scroll = m_wheel;
|
event.scroll_event.scroll = m_wheel;
|
||||||
add_event(BAN::ConstByteSpan::from(event));
|
add_event(BAN::ConstByteSpan::from(event));
|
||||||
|
|
||||||
m_wheel = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < m_button_state.size(); i++)
|
for (size_t i = 0; i < m_button_state.size(); i++)
|
||||||
|
@ -57,6 +74,11 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBMouse::handle_array(uint16_t usage_page, uint16_t usage)
|
||||||
|
{
|
||||||
|
dprintln_if(DEBUG_USB_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage);
|
||||||
|
}
|
||||||
|
|
||||||
void USBMouse::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
|
void USBMouse::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
|
||||||
{
|
{
|
||||||
switch (usage_page)
|
switch (usage_page)
|
||||||
|
@ -65,16 +87,50 @@ namespace Kernel
|
||||||
switch (usage)
|
switch (usage)
|
||||||
{
|
{
|
||||||
case 0x30:
|
case 0x30:
|
||||||
m_pointer_x = state;
|
m_rel_x = state;
|
||||||
break;
|
break;
|
||||||
case 0x31:
|
case 0x31:
|
||||||
m_pointer_y = state;
|
m_rel_y = state;
|
||||||
break;
|
break;
|
||||||
case 0x38:
|
case 0x38:
|
||||||
m_wheel = state;
|
m_wheel = state;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported mouse usage {2H} on page {2H}", usage, usage_page);
|
dprintln_if(DEBUG_USB_MOUSE, "Unsupported relative mouse usage {2H} on page {2H}", usage, usage_page);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintln_if(DEBUG_USB_MOUSE, "Unsupported relative mouse usage page {2H}", usage_page);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBMouse::handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max)
|
||||||
|
{
|
||||||
|
(void)min; (void)max;
|
||||||
|
|
||||||
|
switch (usage_page)
|
||||||
|
{
|
||||||
|
case 0x01: // pointer
|
||||||
|
switch (usage)
|
||||||
|
{
|
||||||
|
case 0x30:
|
||||||
|
m_abs_x = {
|
||||||
|
.val = state,
|
||||||
|
.min = min,
|
||||||
|
.max = max,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
m_abs_y = {
|
||||||
|
.val = state,
|
||||||
|
.min = min,
|
||||||
|
.max = max,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintln_if(DEBUG_USB_MOUSE, "Unsupported absolute mouse usage {2H} on page {2H}", usage, usage_page);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -84,14 +140,9 @@ namespace Kernel
|
||||||
m_button_state_temp[usage - 1] = state;
|
m_button_state_temp[usage - 1] = state;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported mouse usage page {2H}", usage_page);
|
dprintln_if(DEBUG_USB_MOUSE, "Unsupported absolute mouse usage page {2H}", usage_page);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBMouse::handle_array(uint16_t usage_page, uint16_t usage)
|
|
||||||
{
|
|
||||||
dprintln_if(DEBUG_USB_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,16 @@ namespace LibInput
|
||||||
int32_t rel_y;
|
int32_t rel_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MouseMoveAbsEvent
|
||||||
|
{
|
||||||
|
int32_t abs_x;
|
||||||
|
int32_t abs_y;
|
||||||
|
int32_t min_x;
|
||||||
|
int32_t min_y;
|
||||||
|
int32_t max_x;
|
||||||
|
int32_t max_y;
|
||||||
|
};
|
||||||
|
|
||||||
struct MouseScrollEvent
|
struct MouseScrollEvent
|
||||||
{
|
{
|
||||||
int32_t scroll;
|
int32_t scroll;
|
||||||
|
@ -31,6 +41,7 @@ namespace LibInput
|
||||||
{
|
{
|
||||||
MouseButtonEvent,
|
MouseButtonEvent,
|
||||||
MouseMoveEvent,
|
MouseMoveEvent,
|
||||||
|
MouseMoveAbsEvent,
|
||||||
MouseScrollEvent,
|
MouseScrollEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,6 +52,7 @@ namespace LibInput
|
||||||
{
|
{
|
||||||
MouseButtonEvent button_event;
|
MouseButtonEvent button_event;
|
||||||
MouseMoveEvent move_event;
|
MouseMoveEvent move_event;
|
||||||
|
MouseMoveAbsEvent move_abs_event;
|
||||||
MouseScrollEvent scroll_event;
|
MouseScrollEvent scroll_event;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue