Implement mouse packet timeout. Fixes right-click menu appearing incorrectly on qemu if debuggins is used. Patch by Tinus

svn path=/trunk/; revision=15389
This commit is contained in:
Alex Ionescu 2005-05-17 20:51:39 +00:00
parent e3757a0fb1
commit a04f8e62fe
2 changed files with 37 additions and 1 deletions

View file

@ -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;

View file

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