From a04f8e62fe68974fbf349591fd9ee5fa7414c9ab Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 17 May 2005 20:51:39 +0000 Subject: [PATCH] Implement mouse packet timeout. Fixes right-click menu appearing incorrectly on qemu if debuggins is used. Patch by Tinus svn path=/trunk/; revision=15389 --- reactos/drivers/input/i8042prt/i8042prt.h | 3 +- reactos/drivers/input/i8042prt/mouse.c | 35 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/input/i8042prt/i8042prt.h b/reactos/drivers/input/i8042prt/i8042prt.h index 3c1f6d57494..fb9df9a1afa 100644 --- a/reactos/drivers/input/i8042prt/i8042prt.h +++ b/reactos/drivers/input/i8042prt/i8042prt.h @@ -86,7 +86,7 @@ typedef struct _I8042_SETTINGS DWORD OverrideKeyboardType; DWORD OverrideKeyboardSubtype; DWORD MouseResendStallTime; - DWORD MouseSynchIn100ns; + DWORD MouseSynchIn100ns; /* done */ DWORD MouseResolution; /* done */ DWORD NumberOfButtons; DWORD EnableWheelDetection; @@ -169,6 +169,7 @@ typedef struct _DEVICE_EXTENSION MOUSE_INPUT_DATA *MouseBuffer; ULONG MouseInBuffer; USHORT MouseButtonState; + ULARGE_INTEGER MousePacketStartTime; UCHAR MouseLogiBuffer[3]; UCHAR MouseLogitechID; diff --git a/reactos/drivers/input/i8042prt/mouse.c b/reactos/drivers/input/i8042prt/mouse.c index f2f82fd3ca4..c52a92610c1 100644 --- a/reactos/drivers/input/i8042prt/mouse.c +++ b/reactos/drivers/input/i8042prt/mouse.c @@ -45,6 +45,39 @@ NTSTATUS STDCALL I8042SynchWritePortMouse(PVOID Context, 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 @@ BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, return TRUE; } + I8042MouseInputTestTimeout(DevExt); + if (I8042MouseResetIsr(DevExt, PortStatus, &Output)) { DPRINT("Handled by ResetIsr or hooked Isr\n"); if (NoChange != DevExt->MouseTimeoutState) {