]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c
Roll back changes to apply GetBestLanguage() in HiiDataBase. Exact language match...
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMouseDxe / MouseHid.c
CommitLineData
ed838d0c 1/** @file\r
29129ce4 2 Helper functions to parse HID report descriptor and items.\r
bb80e3b2 3\r
4Copyright (c) 2004 - 2008, Intel Corporation\r
ed838d0c 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
ed838d0c 13**/\r
14\r
29129ce4 15#include "UsbMouse.h"\r
ed838d0c 16\r
17\r
ed838d0c 18/**\r
29129ce4 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
ed838d0c 29\r
29129ce4 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
ed838d0c 33\r
29129ce4 34 @return Pointer to end of the HID item returned.\r
35 NULL if no HID item retrieved.\r
ed838d0c 36\r
37**/\r
ed838d0c 38UINT8 *\r
29129ce4 39GetNextHidItem (\r
ed838d0c 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
29129ce4 47 if (EndPos <= StartPos) {\r
ed838d0c 48 return NULL;\r
49 }\r
50\r
51 Temp = *StartPos;\r
52 StartPos++;\r
29129ce4 53\r
ed838d0c 54 //\r
29129ce4 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
ed838d0c 59 //\r
29129ce4 60 HidItem->Type = BitFieldRead8 (Temp, 2, 3);\r
61 HidItem->Tag = BitFieldRead8 (Temp, 4, 7);\r
ed838d0c 62\r
63 if (HidItem->Tag == HID_ITEM_TAG_LONG) {\r
64 //\r
29129ce4 65 // Long Items are not supported, although we try to parse it.\r
ed838d0c 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
29129ce4 81 HidItem->Size = BitFieldRead8 (Temp, 0, 1);\r
ed838d0c 82\r
29129ce4 83 switch (HidItem->Size) {\r
ed838d0c 84 case 0:\r
85 //\r
86 // No data\r
87 //\r
88 return StartPos;\r
89\r
90 case 1:\r
91 //\r
29129ce4 92 // 1-byte data\r
ed838d0c 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
29129ce4 101 // 2-byte data\r
ed838d0c 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
29129ce4 111 // 4-byte data, adjust size\r
ed838d0c 112 //\r
29129ce4 113 HidItem->Size = 4;\r
ed838d0c 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
29129ce4 127 Get data from HID item.\r
ed838d0c 128\r
29129ce4 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
ed838d0c 132\r
29129ce4 133 @param HidItem Pointer to the HID item.\r
134\r
135 @return The data of HID item.\r
ed838d0c 136\r
137**/\r
ed838d0c 138UINT32\r
139GetItemData (\r
140 IN HID_ITEM *HidItem\r
141 )\r
142{\r
143 //\r
29129ce4 144 // Get data from HID item.\r
ed838d0c 145 //\r
146 switch (HidItem->Size) {\r
ed838d0c 147 case 1:\r
148 return HidItem->Data.U8;\r
ed838d0c 149 case 2:\r
150 return HidItem->Data.U16;\r
ed838d0c 151 case 4:\r
152 return HidItem->Data.U32;\r
153 }\r
ed838d0c 154 return 0;\r
155}\r
156\r
ed838d0c 157/**\r
29129ce4 158 Parse HID item from report descriptor.\r
ed838d0c 159\r
29129ce4 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
163 \r
bb80e3b2 164 @param UsbMouse The instance of USB_MOUSE_DEV\r
29129ce4 165 @param HidItem The HID item to parse\r
ed838d0c 166\r
167**/\r
ed838d0c 168VOID\r
29129ce4 169ParseHidItem (\r
ed838d0c 170 IN USB_MOUSE_DEV *UsbMouse,\r
29129ce4 171 IN HID_ITEM *HidItem\r
ed838d0c 172 )\r
173{\r
29129ce4 174 UINT8 Data;\r
ed838d0c 175\r
29129ce4 176 switch (HidItem->Type) {\r
177\r
178 case HID_ITEM_TYPE_MAIN:\r
ed838d0c 179 //\r
29129ce4 180 // we don't care any main items, just skip\r
ed838d0c 181 //\r
29129ce4 182 return;\r
ed838d0c 183\r
29129ce4 184 case HID_ITEM_TYPE_GLOBAL:\r
ed838d0c 185 //\r
29129ce4 186 // For global items, we only care Usage Page tag for Button Page here\r
ed838d0c 187 //\r
29129ce4 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
ed838d0c 198\r
29129ce4 199 case HID_ITEM_TYPE_LOCAL:\r
200 if (HidItem->Size == 0) {\r
201 //\r
202 // No expected data for local item\r
203 //\r
204 return ;\r
ed838d0c 205 }\r
206\r
29129ce4 207 Data = (UINT8) GetItemData (HidItem);\r
ed838d0c 208\r
29129ce4 209 switch (HidItem->Tag) {\r
210 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:\r
ed838d0c 211 if (UsbMouse->PrivateData.ButtonDetected) {\r
29129ce4 212 UsbMouse->PrivateData.ButtonMinIndex = Data;\r
ed838d0c 213 }\r
ed838d0c 214 return ;\r
ed838d0c 215\r
29129ce4 216 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:\r
ed838d0c 217 {\r
29129ce4 218 if (UsbMouse->PrivateData.ButtonDetected) {\r
219 UsbMouse->PrivateData.ButtonMaxIndex = Data;\r
ed838d0c 220 }\r
29129ce4 221 return ;\r
ed838d0c 222 }\r
223\r
29129ce4 224 default:\r
225 return;\r
226 }\r
ed838d0c 227 }\r
228}\r
bb80e3b2 229\r
ed838d0c 230\r
231/**\r
bb80e3b2 232 Parse Mouse Report Descriptor.\r
ed838d0c 233\r
29129ce4 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_DEV.\r
238\r
bb80e3b2 239 @param UsbMouse The instance of USB_MOUSE_DEV\r
ed838d0c 240 @param ReportDescriptor Report descriptor to parse\r
241 @param ReportSize Report descriptor size\r
242\r
29129ce4 243 @retval EFI_SUCCESS Report descriptor successfully parsed.\r
244 @retval EFI_UNSUPPORTED Report descriptor contains long item.\r
ed838d0c 245\r
246**/\r
247EFI_STATUS\r
248ParseMouseReportDescriptor (\r
29129ce4 249 OUT USB_MOUSE_DEV *UsbMouse,\r
ed838d0c 250 IN UINT8 *ReportDescriptor,\r
251 IN UINTN ReportSize\r
252 )\r
253{\r
254 UINT8 *DescriptorEnd;\r
bb80e3b2 255 UINT8 *Ptr;\r
ed838d0c 256 HID_ITEM HidItem;\r
257\r
258 DescriptorEnd = ReportDescriptor + ReportSize;\r
259\r
29129ce4 260 Ptr = GetNextHidItem (ReportDescriptor, DescriptorEnd, &HidItem);\r
bb80e3b2 261 while (Ptr != NULL) {\r
ed838d0c 262 if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {\r
263 //\r
29129ce4 264 // Long Item is not supported at current HID revision\r
ed838d0c 265 //\r
29129ce4 266 return EFI_UNSUPPORTED;\r
ed838d0c 267 }\r
268\r
269 ParseHidItem (UsbMouse, &HidItem);\r
270\r
29129ce4 271 Ptr = GetNextHidItem (Ptr, DescriptorEnd, &HidItem);\r
ed838d0c 272 }\r
273\r
29129ce4 274 UsbMouse->NumberOfButtons = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);\r
275 UsbMouse->XLogicMax = 127;\r
276 UsbMouse->YLogicMax = 127;\r
277 UsbMouse->XLogicMin = -127;\r
278 UsbMouse->YLogicMin = -127;\r
ed838d0c 279\r
280 return EFI_SUCCESS;\r
281}\r