Kernel: Add horizontal mouse scroll support

This commit is contained in:
Dmitry Petrov 2021-12-13 23:12:01 +01:00 committed by Andreas Kling
parent 1afb6d5eca
commit d61cc47055
Notes: sideshowbarker 2024-07-17 20:34:55 +09:00
5 changed files with 30 additions and 5 deletions

View file

@ -12,6 +12,7 @@ struct MousePacket {
int x { 0 }; int x { 0 };
int y { 0 }; int y { 0 };
int z { 0 }; int z { 0 };
int w { 0 };
enum Button { enum Button {
LeftButton = 0x01, LeftButton = 0x01,

View file

@ -35,7 +35,7 @@ ErrorOr<size_t> MouseDevice::read(OpenFileDescription&, u64, UserOrKernelBuffer&
lock.unlock(); lock.unlock();
dbgln_if(MOUSE_DEBUG, "Mouse Read: Buttons {:x}", packet.buttons); dbgln_if(MOUSE_DEBUG, "Mouse Read: Buttons {:x}", packet.buttons);
dbgln_if(MOUSE_DEBUG, "PS2 Mouse: X {}, Y {}, Z {}, Relative {}", packet.x, packet.y, packet.z, packet.buttons); dbgln_if(MOUSE_DEBUG, "PS2 Mouse: X {}, Y {}, Z {}, W {}, Relative {}", packet.x, packet.y, packet.z, packet.w, packet.buttons);
dbgln_if(MOUSE_DEBUG, "PS2 Mouse Read: Filter packets"); dbgln_if(MOUSE_DEBUG, "PS2 Mouse Read: Filter packets");
size_t bytes_read_from_packet = min(remaining_space_in_buffer, sizeof(MousePacket)); size_t bytes_read_from_packet = min(remaining_space_in_buffer, sizeof(MousePacket));

View file

@ -89,6 +89,7 @@ MousePacket PS2MouseDevice::parse_data_packet(const RawPacket& raw_packet)
int x = raw_packet.bytes[1]; int x = raw_packet.bytes[1];
int y = raw_packet.bytes[2]; int y = raw_packet.bytes[2];
int z = 0; int z = 0;
int w = 0;
if (m_has_wheel) { if (m_has_wheel) {
// FIXME: For non-Intellimouse, this is a full byte. // FIXME: For non-Intellimouse, this is a full byte.
// However, for now, m_has_wheel is only set for Intellimouse. // However, for now, m_has_wheel is only set for Intellimouse.
@ -97,6 +98,14 @@ MousePacket PS2MouseDevice::parse_data_packet(const RawPacket& raw_packet)
// -1 in 4 bits // -1 in 4 bits
if (z == 15) if (z == 15)
z = -1; z = -1;
if ((raw_packet.bytes[3] & 0xc0) == 0x40) {
// FIXME: Scroll only functions correctly when the sign is flipped there
w = -z;
z = 0;
} else {
w = 0;
}
} }
bool x_overflow = raw_packet.bytes[0] & 0x40; bool x_overflow = raw_packet.bytes[0] & 0x40;
bool y_overflow = raw_packet.bytes[0] & 0x80; bool y_overflow = raw_packet.bytes[0] & 0x80;
@ -114,6 +123,7 @@ MousePacket PS2MouseDevice::parse_data_packet(const RawPacket& raw_packet)
packet.x = x; packet.x = x;
packet.y = y; packet.y = y;
packet.z = z; packet.z = z;
packet.w = w;
packet.buttons = raw_packet.bytes[0] & 0x07; packet.buttons = raw_packet.bytes[0] & 0x07;
if (m_has_five_buttons) { if (m_has_five_buttons) {
@ -125,7 +135,7 @@ MousePacket PS2MouseDevice::parse_data_packet(const RawPacket& raw_packet)
packet.is_relative = true; packet.is_relative = true;
dbgln_if(PS2MOUSE_DEBUG, "PS2 Relative Mouse: Buttons {:x}", packet.buttons); dbgln_if(PS2MOUSE_DEBUG, "PS2 Relative Mouse: Buttons {:x}", packet.buttons);
dbgln_if(PS2MOUSE_DEBUG, "Mouse: X {}, Y {}, Z {}", packet.x, packet.y, packet.z); dbgln_if(PS2MOUSE_DEBUG, "Mouse: X {}, Y {}, Z {}, W {}", packet.x, packet.y, packet.z, packet.w);
return packet; return packet;
} }

View file

@ -211,16 +211,28 @@ MousePacket VMWareBackdoor::receive_mouse_packet()
int x = command.bx; int x = command.bx;
int y = command.cx; int y = command.cx;
int z = static_cast<i8>(command.dx); // signed 8 bit value only! int z = static_cast<i8>(command.dx); // signed 8 bit value only!
int w = 0;
// horizontal scroll is reported as +-2 by qemu
// FIXME: Scroll only functions correctly when the sign is flipped there
if (z == 2) {
w = -1;
z = 0;
} else if (z == -2) {
w = 1;
z = 0;
}
if constexpr (PS2MOUSE_DEBUG) { if constexpr (PS2MOUSE_DEBUG) {
dbgln("Absolute Mouse: Buttons {:x}", buttons); dbgln("Absolute Mouse: Buttons {:x}", buttons);
dbgln("Mouse: x={}, y={}, z={}", x, y, z); dbgln("Mouse: x={}, y={}, z={}, w={}", x, y, z, w);
} }
MousePacket packet; MousePacket packet;
packet.x = x; packet.x = x;
packet.y = y; packet.y = y;
packet.z = z; packet.z = z;
packet.w = w;
if (buttons & VMMOUSE_LEFT_CLICK) if (buttons & VMMOUSE_LEFT_CLICK)
packet.buttons |= MousePacket::LeftButton; packet.buttons |= MousePacket::LeftButton;
if (buttons & VMMOUSE_RIGHT_CLICK) if (buttons & VMMOUSE_RIGHT_CLICK)

View file

@ -64,7 +64,7 @@ void EventLoop::drain_mouse()
bool state_is_sent = false; bool state_is_sent = false;
for (size_t i = 0; i < npackets; ++i) { for (size_t i = 0; i < npackets; ++i) {
auto& packet = packets[i]; auto& packet = packets[i];
dbgln_if(WSMESSAGELOOP_DEBUG, "EventLoop: Mouse X {}, Y {}, Z {}, relative={}", packet.x, packet.y, packet.z, packet.is_relative); dbgln_if(WSMESSAGELOOP_DEBUG, "EventLoop: Mouse X {}, Y {}, Z {}, W {}, relative={}", packet.x, packet.y, packet.z, packet.w, packet.is_relative);
state.is_relative = packet.is_relative; state.is_relative = packet.is_relative;
if (packet.is_relative) { if (packet.is_relative) {
@ -75,6 +75,7 @@ void EventLoop::drain_mouse()
state.y = packet.y; state.y = packet.y;
} }
state.z += packet.z; state.z += packet.z;
state.w += packet.w;
state_is_sent = false; state_is_sent = false;
if (packet.buttons != state.buttons) { if (packet.buttons != state.buttons) {
@ -100,12 +101,13 @@ void EventLoop::drain_mouse()
state.x = 0; state.x = 0;
state.y = 0; state.y = 0;
state.z = 0; state.z = 0;
state.w = 0;
} }
} }
} }
if (state_is_sent) if (state_is_sent)
return; return;
if (state.is_relative && (state.x || state.y || state.z)) if (state.is_relative && (state.x || state.y || state.z || state.w))
screen_input.on_receive_mouse_data(state); screen_input.on_receive_mouse_data(state);
if (!state.is_relative) if (!state.is_relative)
screen_input.on_receive_mouse_data(state); screen_input.on_receive_mouse_data(state);