]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/mousehid.c
Code Scrub for USB Mouse Absolute Pointer Driver.
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMouseAbsolutePointerDxe / mousehid.c
CommitLineData
09f72ae8 1/** @file\r
67b8a9ce 2 Helper functions to parse HID report descriptor and items.\r
09f72ae8 3\r
67b8a9ce 4Copyright (c) 2004 - 2008, Intel Corporation\r
09f72ae8 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
09f72ae8 13**/\r
14\r
67b8a9ce 15#include "UsbMouseAbsolutePointer.h"\r
09f72ae8 16\r
09f72ae8 17\r
18/**\r
67b8a9ce 19 Get next HID item from report descriptor.\r
20\r
21 This function retrieves next HID item from report descriptor, according to\r
22 the start position.\r
23 According to USB HID Specification, An item is piece of information\r
24 about the device. All items have a one-byte prefix that contains\r
25 the item tag, item type, and item size.\r
26 There are two basic types of items: short items and long items.\r
27 If the item is a short item, its optional data size may be 0, 1, 2, or 4 bytes.\r
28 Only short item is supported here.\r
09f72ae8 29\r
67b8a9ce 30 @param StartPos Start position of the HID item to get.\r
31 @param EndPos End position of the range to get the the next HID item.\r
32 @param HidItem Buffer for the HID Item to return.\r
09f72ae8 33\r
67b8a9ce 34 @return Pointer to end of the HID item returned.\r
35 NULL if no HID item retrieved.\r
09f72ae8 36\r
37**/\r
09f72ae8 38UINT8 *\r
67b8a9ce 39GetNextHidItem (\r
09f72ae8 40 IN UINT8 *StartPos,\r
41 IN UINT8 *EndPos,\r
42 OUT HID_ITEM *HidItem\r
43 )\r
44{\r
45 UINT8 Temp;\r
46\r
67b8a9ce 47 if (EndPos <= StartPos) {\r
09f72ae8 48 return NULL;\r
49 }\r
50\r
51 Temp = *StartPos;\r
52 StartPos++;\r
67b8a9ce 53\r
09f72ae8 54 //\r
67b8a9ce 55 // Bit format of prefix byte:\r
56 // Bits 0-1: Size\r
57 // Bits 2-3: Type\r
58 // Bits 4-7: Tag\r
09f72ae8 59 //\r
67b8a9ce 60 HidItem->Type = BitFieldRead8 (Temp, 2, 3);\r
61 HidItem->Tag = BitFieldRead8 (Temp, 4, 7);\r
09f72ae8 62\r
63 if (HidItem->Tag == HID_ITEM_TAG_LONG) {\r
64 //\r
67b8a9ce 65 // Long Items are not supported, although we try to parse it.\r
09f72ae8 66 //\r
67 HidItem->Format = HID_ITEM_FORMAT_LONG;\r
68\r
69 if ((EndPos - StartPos) >= 2) {\r
70 HidItem->Size = *StartPos++;\r
71 HidItem->Tag = *StartPos++;\r
72\r
73 if ((EndPos - StartPos) >= HidItem->Size) {\r
74 HidItem->Data.LongData = StartPos;\r
75 StartPos += HidItem->Size;\r
76 return StartPos;\r
77 }\r
78 }\r
79 } else {\r
80 HidItem->Format = HID_ITEM_FORMAT_SHORT;\r
67b8a9ce 81 HidItem->Size = BitFieldRead8 (Temp, 0, 1);\r
09f72ae8 82\r
67b8a9ce 83 switch (HidItem->Size) {\r
09f72ae8 84 case 0:\r
85 //\r
86 // No data\r
87 //\r
88 return StartPos;\r
89\r
90 case 1:\r
91 //\r
67b8a9ce 92 // 1-byte data\r
09f72ae8 93 //\r
94 if ((EndPos - StartPos) >= 1) {\r
95 HidItem->Data.U8 = *StartPos++;\r
96 return StartPos;\r
97 }\r
98\r
99 case 2:\r
100 //\r
67b8a9ce 101 // 2-byte data\r
09f72ae8 102 //\r
103 if ((EndPos - StartPos) >= 2) {\r
104 CopyMem (&HidItem->Data.U16, StartPos, sizeof (UINT16));\r
105 StartPos += 2;\r
106 return StartPos;\r
107 }\r
108\r
109 case 3:\r
110 //\r
67b8a9ce 111 // 4-byte data, adjust size\r
09f72ae8 112 //\r
67b8a9ce 113 HidItem->Size = 4;\r
09f72ae8 114 if ((EndPos - StartPos) >= 4) {\r
115 CopyMem (&HidItem->Data.U32, StartPos, sizeof (UINT32));\r
116 StartPos += 4;\r
117 return StartPos;\r
118 }\r
119 }\r
120 }\r
121\r
122 return NULL;\r
123}\r
124\r
125\r
126/**\r
67b8a9ce 127 Get data from HID item.\r
128\r
129 This function retrieves data from HID item.\r
130 It only supports short items, which has 4 types of data:\r
131 0, 1, 2, or 4 bytes.\r
09f72ae8 132\r
67b8a9ce 133 @param HidItem Pointer to the HID item.\r
09f72ae8 134\r
67b8a9ce 135 @return The data of HID item.\r
09f72ae8 136\r
137**/\r
09f72ae8 138UINT32\r
139GetItemData (\r
140 IN HID_ITEM *HidItem\r
141 )\r
142{\r
143 //\r
67b8a9ce 144 // Get data from HID item.\r
09f72ae8 145 //\r
146 switch (HidItem->Size) {\r
09f72ae8 147 case 1:\r
148 return HidItem->Data.U8;\r
09f72ae8 149 case 2:\r
150 return HidItem->Data.U16;\r
09f72ae8 151 case 4:\r
152 return HidItem->Data.U32;\r
153 }\r
09f72ae8 154 return 0;\r
155}\r
156\r
09f72ae8 157/**\r
67b8a9ce 158 Parse HID item from report descriptor.\r
09f72ae8 159\r
67b8a9ce 160 There are three item types: Main, Global, and Local.\r
161 This function parses these types of HID items according\r
162 to tag info.\r
09f72ae8 163\r
67b8a9ce 164 @param UsbMouse The instance of USB_MOUSE_ABSOLUTE_POINTER_DEV\r
165 @param HidItem The HID item to parse\r
09f72ae8 166\r
167**/\r
09f72ae8 168VOID\r
67b8a9ce 169ParseHidItem (\r
170 IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouse,\r
171 IN HID_ITEM *HidItem\r
09f72ae8 172 )\r
173{\r
67b8a9ce 174 UINT8 Data;\r
09f72ae8 175\r
67b8a9ce 176 switch (HidItem->Type) {\r
177\r
178 case HID_ITEM_TYPE_MAIN:\r
09f72ae8 179 //\r
67b8a9ce 180 // we don't care any main items, just skip\r
09f72ae8 181 //\r
182 return ;\r
09f72ae8 183\r
67b8a9ce 184 case HID_ITEM_TYPE_GLOBAL:\r
185 //\r
186 // For global items, we only care Usage Page tag for Button Page here\r
187 //\r
188 if (HidItem->Tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE) {\r
189 Data = (UINT8) GetItemData (HidItem);\r
190 if (Data == 0x09) {\r
191 //\r
192 // Button Page\r
193 //\r
194 UsbMouse->PrivateData.ButtonDetected = TRUE;\r
195 }\r
196 }\r
197 return;\r
09f72ae8 198\r
67b8a9ce 199 case HID_ITEM_TYPE_LOCAL:\r
200 if (HidItem->Size == 0) {\r
09f72ae8 201 //\r
67b8a9ce 202 // No expected data for local item\r
09f72ae8 203 //\r
204 return ;\r
67b8a9ce 205 }\r
09f72ae8 206\r
67b8a9ce 207 Data = (UINT8) GetItemData (HidItem);\r
09f72ae8 208\r
67b8a9ce 209 switch (HidItem->Tag) {\r
210 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:\r
211 if (UsbMouse->PrivateData.ButtonDetected) {\r
212 UsbMouse->PrivateData.ButtonMinIndex = Data;\r
09f72ae8 213 }\r
09f72ae8 214 return ;\r
215\r
67b8a9ce 216 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:\r
09f72ae8 217 {\r
67b8a9ce 218 if (UsbMouse->PrivateData.ButtonDetected) {\r
219 UsbMouse->PrivateData.ButtonMaxIndex = Data;\r
09f72ae8 220 }\r
09f72ae8 221 return ;\r
222 }\r
09f72ae8 223\r
67b8a9ce 224 default:\r
09f72ae8 225 return ;\r
226 }\r
09f72ae8 227 }\r
228}\r
229\r
230\r
09f72ae8 231/**\r
67b8a9ce 232 Parse Mouse Report Descriptor.\r
09f72ae8 233\r
67b8a9ce 234 According to USB HID Specification, report descriptors are\r
235 composed of pieces of information. Each piece of information\r
236 is called an Item. This function retrieves each item from\r
237 the report descriptor and updates USB_MOUSE_ABSOLUTE_POINTER_DEV.\r
09f72ae8 238\r
67b8a9ce 239 @param UsbMouseAbsolutePointer The instance of USB_MOUSE_ABSOLUTE_POINTER_DEV\r
240 @param ReportDescriptor Report descriptor to parse\r
241 @param ReportSize Report descriptor size\r
09f72ae8 242\r
67b8a9ce 243 @retval EFI_SUCCESS Report descriptor successfully parsed.\r
244 @retval EFI_UNSUPPORTED Report descriptor contains long item.\r
09f72ae8 245\r
246**/\r
247EFI_STATUS\r
248ParseMouseReportDescriptor (\r
67b8a9ce 249 OUT USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointer,\r
250 IN UINT8 *ReportDescriptor,\r
251 IN UINTN ReportSize\r
09f72ae8 252 )\r
253{\r
254 UINT8 *DescriptorEnd;\r
67b8a9ce 255 UINT8 *Ptr;\r
09f72ae8 256 HID_ITEM HidItem;\r
257\r
258 DescriptorEnd = ReportDescriptor + ReportSize;\r
259\r
67b8a9ce 260 Ptr = GetNextHidItem (ReportDescriptor, DescriptorEnd, &HidItem);\r
261 while (Ptr != NULL) {\r
09f72ae8 262 if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {\r
263 //\r
67b8a9ce 264 // Long Item is not supported at current HID revision\r
09f72ae8 265 //\r
67b8a9ce 266 return EFI_UNSUPPORTED;\r
09f72ae8 267 }\r
268\r
269 ParseHidItem (UsbMouseAbsolutePointer, &HidItem);\r
270\r
67b8a9ce 271 Ptr = GetNextHidItem (Ptr, DescriptorEnd, &HidItem);\r
09f72ae8 272 }\r
273\r
67b8a9ce 274 UsbMouseAbsolutePointer->NumberOfButtons = (UINT8) (UsbMouseAbsolutePointer->PrivateData.ButtonMaxIndex - UsbMouseAbsolutePointer->PrivateData.ButtonMinIndex + 1);\r
275 UsbMouseAbsolutePointer->XLogicMax = 1023;\r
276 UsbMouseAbsolutePointer->YLogicMax = 1023;\r
277 UsbMouseAbsolutePointer->XLogicMin = -1023;\r
278 UsbMouseAbsolutePointer->YLogicMin = -1023;\r
09f72ae8 279\r
280 return EFI_SUCCESS;\r
281}\r