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