mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:27:45 +00:00
Kernel: Add support for vmmouse
We add this feature together with the VMWareBackdoor class. VMWareBackdoor class is responsible for enabling the vmmouse, and then controlling it from the PS2 mouse IRQ handler.
This commit is contained in:
parent
44ddfd2bf5
commit
47978a5828
8 changed files with 328 additions and 3 deletions
|
@ -24,8 +24,9 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "PS2MouseDevice.h"
|
||||
#include "IO.h"
|
||||
#include <Kernel/Devices/PS2MouseDevice.h>
|
||||
#include <Kernel/Devices/VMWareBackdoor.h>
|
||||
#include <Kernel/IO.h>
|
||||
|
||||
#define IRQ_MOUSE 12
|
||||
#define I8042_BUFFER 0x60
|
||||
|
@ -47,6 +48,14 @@
|
|||
#define PS2MOUSE_RESEND 0xFE
|
||||
#define PS2MOUSE_RESET 0xFF
|
||||
|
||||
#define PS2MOUSE_LEFT_CLICK 0x01
|
||||
#define PS2MOUSE_RIGHT_CLICK 0x02
|
||||
#define PS2MOUSE_MIDDLE_CLICK 0x04
|
||||
|
||||
#define VMMOUSE_LEFT_CLICK 0x20
|
||||
#define VMMOUSE_RIGHT_CLICK 0x10
|
||||
#define VMMOUSE_MIDDLE_CLICK 0x08
|
||||
|
||||
#define PS2MOUSE_INTELLIMOUSE_ID 0x03
|
||||
|
||||
//#define PS2MOUSE_DEBUG
|
||||
|
@ -70,8 +79,68 @@ PS2MouseDevice& PS2MouseDevice::the()
|
|||
return *s_the;
|
||||
}
|
||||
|
||||
void PS2MouseDevice::handle_vmmouse_absolute_pointer()
|
||||
{
|
||||
VMWareCommand command;
|
||||
command.bx = 0;
|
||||
command.command = VMMOUSE_STATUS;
|
||||
VMWareBackdoor::the().send(command);
|
||||
if (command.ax == 0xFFFF0000) {
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("Reset vmmouse.\n");
|
||||
#endif
|
||||
VMWareBackdoor::the().disable_absolute_vmmouse();
|
||||
VMWareBackdoor::the().enable_absolute_vmmouse();
|
||||
return;
|
||||
}
|
||||
int words = command.ax & 0xFFFF;
|
||||
|
||||
if (!words || words % 4)
|
||||
return;
|
||||
command.size = 4;
|
||||
command.command = VMMOUSE_DATA;
|
||||
VMWareBackdoor::the().send(command);
|
||||
|
||||
int buttons = (command.ax & 0xFFFF);
|
||||
int x = (command.bx);
|
||||
int y = (command.cx);
|
||||
int z = (command.dx);
|
||||
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("Absolute Mouse: Buttons %x\n", buttons);
|
||||
dbgprintf("Mouse: X %d, Y %d, Z %d\n", x, y, z);
|
||||
#endif
|
||||
MousePacket packet;
|
||||
packet.x = x;
|
||||
packet.y = y;
|
||||
packet.z = z;
|
||||
if (buttons & VMMOUSE_LEFT_CLICK) {
|
||||
packet.buttons |= PS2MOUSE_LEFT_CLICK;
|
||||
}
|
||||
if (buttons & VMMOUSE_RIGHT_CLICK) {
|
||||
packet.buttons |= PS2MOUSE_RIGHT_CLICK;
|
||||
}
|
||||
if (buttons & VMMOUSE_MIDDLE_CLICK) {
|
||||
packet.buttons |= PS2MOUSE_MIDDLE_CLICK;
|
||||
}
|
||||
packet.is_relative = false;
|
||||
m_queue.enqueue(packet);
|
||||
}
|
||||
|
||||
void PS2MouseDevice::handle_irq()
|
||||
{
|
||||
|
||||
if (VMWareBackdoor::the().vmmouse_is_absolute()) {
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("Handling PS2 vmmouse.\n");
|
||||
#endif
|
||||
IO::in8(I8042_BUFFER);
|
||||
handle_vmmouse_absolute_pointer();
|
||||
return;
|
||||
}
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("Handling classical PS2 mouse.\n");
|
||||
#endif
|
||||
for (;;) {
|
||||
u8 status = IO::in8(I8042_STATUS);
|
||||
if (!(((status & I8042_WHICH_BUFFER) == I8042_MOUSE_BUFFER) && (status & I8042_BUFFER_FULL)))
|
||||
|
@ -143,7 +212,11 @@ void PS2MouseDevice::parse_data_packet()
|
|||
packet.y = y;
|
||||
packet.z = z;
|
||||
packet.buttons = m_data[0] & 0x07;
|
||||
|
||||
packet.is_relative = true;
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("PS2 Relative Mouse: Buttons %x\n", packet.buttons);
|
||||
dbgprintf("Mouse: X %d, Y %d, Z %d\n", packet.x, packet.y, packet.z);
|
||||
#endif
|
||||
m_queue.enqueue(packet);
|
||||
}
|
||||
|
||||
|
@ -296,6 +369,11 @@ ssize_t PS2MouseDevice::read(FileDescription&, u8* buffer, ssize_t size)
|
|||
if ((size - nread) < (ssize_t)sizeof(MousePacket))
|
||||
break;
|
||||
auto packet = m_queue.dequeue();
|
||||
#ifdef PS2MOUSE_DEBUG
|
||||
dbgprintf("PS2 Mouse Read: Buttons %x\n", packet.buttons);
|
||||
dbgprintf("PS2 Mouse Read: X %d, Y %d, Z %d, Relative %d\n", packet.x, packet.y, packet.z, packet.buttons);
|
||||
dbgprintf("PS2 Mouse Read: Filter packets\n");
|
||||
#endif
|
||||
memcpy(buffer, &packet, sizeof(MousePacket));
|
||||
nread += sizeof(MousePacket);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue