ReactOS  0.4.13-dev-235-g7373cb3
ps2pp.c
Go to the documentation of this file.
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
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  }
126  DeviceExtension,
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 }
#define IN
Definition: typedefs.h:38
#define MOUSE_WHEEL
Definition: ntddmou.h:56
Definition: arc.h:84
VOID i8042MouHandleButtons(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN USHORT Mask)
Definition: mouse.c:191
ULONG RawButtons
Definition: ntddmou.h:86
#define MOUSE_BUTTON_4_DOWN
Definition: ntddmou.h:52
USHORT ButtonData
Definition: ntddmou.h:83
VOID i8042MouHandlePs2pp(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Input)
Definition: ps2pp.c:19
unsigned char UCHAR
Definition: xmlstorage.h:181
USHORT ButtonFlags
Definition: ntddmou.h:82
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define MOUSE_BUTTON_5_DOWN
Definition: ntddmou.h:54
VOID i8042MouHandle(IN PI8042_MOUSE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: mouse.c:68
#define WARN_(ch,...)
Definition: debug.h:157