/* * 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" #include /* 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"); } }