Implement mouse packet timeout. Fixes right-click menu appearing
incorrectly on qemu if debuggins is used. Patch by Tinus
Modified: trunk/reactos/drivers/input/i8042prt/i8042prt.h
Modified: trunk/reactos/drivers/input/i8042prt/mouse.c
_____
Modified: trunk/reactos/drivers/input/i8042prt/i8042prt.h
--- trunk/reactos/drivers/input/i8042prt/i8042prt.h 2005-05-17
20:43:27 UTC (rev 15388)
+++ trunk/reactos/drivers/input/i8042prt/i8042prt.h 2005-05-17
20:51:39 UTC (rev 15389)
@@ -86,7 +86,7 @@
DWORD OverrideKeyboardType;
DWORD OverrideKeyboardSubtype;
DWORD MouseResendStallTime;
- DWORD MouseSynchIn100ns;
+ DWORD MouseSynchIn100ns; /* done */
DWORD MouseResolution; /* done */
DWORD NumberOfButtons;
DWORD EnableWheelDetection;
@@ -169,6 +169,7 @@
MOUSE_INPUT_DATA *MouseBuffer;
ULONG MouseInBuffer;
USHORT MouseButtonState;
+ ULARGE_INTEGER MousePacketStartTime;
UCHAR MouseLogiBuffer[3];
UCHAR MouseLogitechID;
_____
Modified: trunk/reactos/drivers/input/i8042prt/mouse.c
--- trunk/reactos/drivers/input/i8042prt/mouse.c 2005-05-17
20:43:27 UTC (rev 15388)
+++ trunk/reactos/drivers/input/i8042prt/mouse.c 2005-05-17
20:51:39 UTC (rev 15389)
@@ -45,6 +45,39 @@
WaitForAck);
}
+/* Test if packets are taking too long to come in. If they do, we
+ * might have gotten out of sync and should just drop what we have.
+ *
+ * If we want to be totally right, we'd also have to keep a count of
+ * errors, and totally reset the mouse after too much of them (can
+ * happen if the user is using a KVM switch and an OS on another port
+ * resets the mouse, or if the user hotplugs the mouse, or if we're
just
+ * generally unlucky). Also note the input parsing routine where we
+ * drop invalid input packets.
+ */
+static VOID STDCALL I8042MouseInputTestTimeout(PDEVICE_EXTENSION
DevExt)
+{
+ ULARGE_INTEGER Now;
+
+ if (DevExt->MouseState == MouseExpectingACK ||
+ DevExt->MouseState == MouseResetting)
+ return;
+
+ Now.QuadPart = KeQueryInterruptTime();
+
+ if (DevExt->MouseState != MouseIdle) {
+ /* Check if the last byte came too long ago */
+ if (Now.QuadPart - DevExt->MousePacketStartTime.QuadPart
+
DevExt->Settings.MouseSynchIn100ns) {
+ DPRINT1("Mouse input packet timeout\n");
+ DevExt->MouseState = MouseIdle;
+ }
+ }
+
+ if (DevExt->MouseState == MouseIdle)
+ DevExt->MousePacketStartTime.QuadPart = Now.QuadPart;
+}
+
/*
* Call the customization hook. The Ret2 parameter is about wether
* we should go on with the interrupt. The return value is what
@@ -517,6 +550,8 @@
return TRUE;
}
+ I8042MouseInputTestTimeout(DevExt);
+
if (I8042MouseResetIsr(DevExt, PortStatus, &Output)) {
DPRINT("Handled by ResetIsr or hooked Isr\n");
if (NoChange != DevExt->MouseTimeoutState) {