[NTFS] - Add some fixes and improvements to attribute.c from CR-123:
[reactos.git] / drivers / input / i8042prt / ps2pp.c
1 /*
2 * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/i8042prt/ps2pp.c
5 * PURPOSE: ps2pp protocol handling
6 * PROGRAMMERS: Copyright Martijn Vernooij (o112w8r02@sneakemail.com)
7 * Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
8 */
9
10 /* INCLUDES ****************************************************************/
11
12 #include "i8042prt.h"
13
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 VOID
19 i8042MouHandlePs2pp(
20 IN PI8042_MOUSE_EXTENSION DeviceExtension,
21 IN UCHAR Input)
22 {
23 UCHAR PktType;
24 PMOUSE_INPUT_DATA MouseInput;
25
26 MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
27
28 /* First, collect 3 bytes for a packet
29 * We can detect out-of-sync only by checking
30 * the whole packet anyway.
31 *
32 * If bit 7 and 8 of the first byte are 0, its
33 * a normal packet.
34 *
35 * Otherwise, the packet is different, like this:
36 * 1: E 1 b3 b2 1 x x x
37 * 2: x x b1 b0 x1 x0 1 0
38 * 3: x x x x x x x1 x0
39 *
40 * b3-0 form a code that specifies the packet type:
41 *
42 * 0 Device Type
43 * 1 Rollers and buttons
44 * 2 Reserved
45 * 3 Reserved
46 * 4 Device ID
47 * 5 Channel & Battery
48 * 6 Wireless notifications
49 * 7 Reserved
50 * 8 ShortID LSB (ShortID is a number that is supposed to differentiate
51 * 9 ShortID MSB between your mouse and your neighbours')
52 * 10 Reserved
53 * 11 Mouse capabilities
54 * 12 Remote control LSB
55 * 13 Remote control MSB
56 * 14 Reserved
57 * 15 Extended packet
58 */
59
60 switch (DeviceExtension->MouseState)
61 {
62 case MouseIdle:
63 case XMovement:
64 DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input;
65 DeviceExtension->MouseState++;
66 break;
67
68 case YMovement:
69 DeviceExtension->MouseLogiBuffer[2] = Input;
70 DeviceExtension->MouseState = MouseIdle;
71
72 /* first check if it's a normal packet */
73
74 if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0))
75 {
76 DeviceExtension->MouseState = MouseIdle;
77 i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]);
78 i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]);
79 i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]);
80 /* We could care about wether MouseState really
81 * advances, but we don't need to because we're
82 * only doing three bytes anyway, so the packet
83 * will never complete if it's broken.
84 */
85 return;
86 }
87
88 /* sanity check */
89 if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) ||
90 (((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) !=
91 (DeviceExtension->MouseLogiBuffer[2] & 0x03)))
92 {
93 WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n");
94 return;
95 }
96
97 /* Now get the packet type */
98 PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 2) |
99 ((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 4);
100
101 switch (PktType)
102 {
103 case 0:
104 /* The packet contains the device ID, but we
105 * already read that in the initialization
106 * sequence. Ignore it.
107 */
108 return;
109 case 1:
110 RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA));
111 if (DeviceExtension->MouseLogiBuffer[2] & 0x10)
112 MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
113
114 if (DeviceExtension->MouseLogiBuffer[2] & 0x20)
115 MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
116
117 if (DeviceExtension->MouseLogiBuffer[2] & 0x0F)
118 {
119 MouseInput->ButtonFlags |= MOUSE_WHEEL;
120 if (DeviceExtension->MouseLogiBuffer[2] & 0x08)
121 MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8;
122 else
123 MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07;
124 }
125 i8042MouHandleButtons(
126 DeviceExtension,
127 MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN);
128 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
129 return;
130 default:
131 /* These are for things that would probably
132 * be handled by logitechs own driver.
133 */
134 return;
135 }
136
137 default:
138 WARN_(I8042PRT, "Unexpected input state for ps2pp!\n");
139 }
140 }