mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 00:34:39 +00:00
4f0b8d3db0
svn path=/branches/ntvdm/; revision=59241
138 lines
4.1 KiB
C
138 lines
4.1 KiB
C
/*
|
|
* PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: drivers/input/i8042prt/ps2pp.c
|
|
* PURPOSE: ps2pp protocol handling
|
|
* PROGRAMMERS: Copyright Martijn Vernooij (o112w8r02@sneakemail.com)
|
|
* Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ****************************************************************/
|
|
|
|
#include "i8042prt.h"
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
VOID
|
|
i8042MouHandlePs2pp(
|
|
IN PI8042_MOUSE_EXTENSION DeviceExtension,
|
|
IN UCHAR Input)
|
|
{
|
|
UCHAR PktType;
|
|
PMOUSE_INPUT_DATA MouseInput;
|
|
|
|
MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
|
|
|
|
/* First, collect 3 bytes for a packet
|
|
* We can detect out-of-sync only by checking
|
|
* the whole packet anyway.
|
|
*
|
|
* If bit 7 and 8 of the first byte are 0, its
|
|
* a normal packet.
|
|
*
|
|
* Otherwise, the packet is different, like this:
|
|
* 1: E 1 b3 b2 1 x x x
|
|
* 2: x x b1 b0 x1 x0 1 0
|
|
* 3: x x x x x x x1 x0
|
|
*
|
|
* b3-0 form a code that specifies the packet type:
|
|
*
|
|
* 0 Device Type
|
|
* 1 Rollers and buttons
|
|
* 2 Reserved
|
|
* 3 Reserved
|
|
* 4 Device ID
|
|
* 5 Channel & Battery
|
|
* 6 Wireless notifications
|
|
* 7 Reserved
|
|
* 8 ShortID LSB (ShortID is a number that is supposed to differentiate
|
|
* 9 ShortID MSB between your mouse and your neighbours')
|
|
* 10 Reserved
|
|
* 11 Mouse capabilities
|
|
* 12 Remote control LSB
|
|
* 13 Remote control MSB
|
|
* 14 Reserved
|
|
* 15 Extended packet
|
|
*/
|
|
|
|
switch (DeviceExtension->MouseState)
|
|
{
|
|
case MouseIdle:
|
|
case XMovement:
|
|
DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input;
|
|
DeviceExtension->MouseState++;
|
|
break;
|
|
|
|
case YMovement:
|
|
DeviceExtension->MouseLogiBuffer[2] = Input;
|
|
DeviceExtension->MouseState = MouseIdle;
|
|
|
|
/* first check if it's a normal packet */
|
|
|
|
if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0))
|
|
{
|
|
DeviceExtension->MouseState = MouseIdle;
|
|
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]);
|
|
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]);
|
|
i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]);
|
|
/* We could care about wether MouseState really
|
|
* advances, but we don't need to because we're
|
|
* only doing three bytes anyway, so the packet
|
|
* will never complete if it's broken.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
/* sanity check */
|
|
if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) ||
|
|
(((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) !=
|
|
(DeviceExtension->MouseLogiBuffer[2] & 0x03)))
|
|
{
|
|
WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n");
|
|
return;
|
|
}
|
|
|
|
/* Now get the packet type */
|
|
PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 2) |
|
|
((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 4);
|
|
|
|
switch (PktType)
|
|
{
|
|
case 0:
|
|
/* The packet contains the device ID, but we
|
|
* already read that in the initialization
|
|
* sequence. Ignore it.
|
|
*/
|
|
return;
|
|
case 1:
|
|
RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA));
|
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x10)
|
|
MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
|
|
|
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x20)
|
|
MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
|
|
|
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x0F)
|
|
{
|
|
MouseInput->ButtonFlags |= MOUSE_WHEEL;
|
|
if (DeviceExtension->MouseLogiBuffer[2] & 0x08)
|
|
MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8;
|
|
else
|
|
MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07;
|
|
}
|
|
i8042MouHandleButtons(
|
|
DeviceExtension,
|
|
MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN);
|
|
DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
|
|
return;
|
|
default:
|
|
/* These are for things that would probably
|
|
* be handled by logitechs own driver.
|
|
*/
|
|
return;
|
|
}
|
|
|
|
default:
|
|
WARN_(I8042PRT, "Unexpected input state for ps2pp!\n");
|
|
}
|
|
}
|