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) {