|
@@ -24,8 +24,9 @@
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* 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 IRQ_MOUSE 12
|
|
#define I8042_BUFFER 0x60
|
|
#define I8042_BUFFER 0x60
|
|
@@ -47,6 +48,14 @@
|
|
#define PS2MOUSE_RESEND 0xFE
|
|
#define PS2MOUSE_RESEND 0xFE
|
|
#define PS2MOUSE_RESET 0xFF
|
|
#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_INTELLIMOUSE_ID 0x03
|
|
|
|
|
|
//#define PS2MOUSE_DEBUG
|
|
//#define PS2MOUSE_DEBUG
|
|
@@ -70,8 +79,68 @@ PS2MouseDevice& PS2MouseDevice::the()
|
|
return *s_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()
|
|
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 (;;) {
|
|
for (;;) {
|
|
u8 status = IO::in8(I8042_STATUS);
|
|
u8 status = IO::in8(I8042_STATUS);
|
|
if (!(((status & I8042_WHICH_BUFFER) == I8042_MOUSE_BUFFER) && (status & I8042_BUFFER_FULL)))
|
|
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.y = y;
|
|
packet.z = z;
|
|
packet.z = z;
|
|
packet.buttons = m_data[0] & 0x07;
|
|
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);
|
|
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))
|
|
if ((size - nread) < (ssize_t)sizeof(MousePacket))
|
|
break;
|
|
break;
|
|
auto packet = m_queue.dequeue();
|
|
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));
|
|
memcpy(buffer, &packet, sizeof(MousePacket));
|
|
nread += sizeof(MousePacket);
|
|
nread += sizeof(MousePacket);
|
|
}
|
|
}
|