2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 File: HIDProcessLocalItem.c
25 Contains: xxx put contents here xxx
27 Version: xxx put version here xxx
29 Copyright: © 1999 by Apple Computer, Inc., all rights reserved.
33 DRI: xxx put dri here xxx
35 Other Contact: xxx put other contact here xxx
37 Technology: xxx put technology here xxx
43 Change History (most recent first):
45 <USB1> 3/5/99 BWS first checked in
51 *------------------------------------------------------------------------------
53 * HIDProcessLocalItem - Process a LocalItem
56 * ptDescriptor - The Descriptor Structure
57 * ptPreparsedData - The PreParsedData Structure
59 * ptPreparsedData - The PreParsedData Structure
61 * kHIDSuccess - Success
62 * kHIDNullPointerErr - Argument, Pointer was Null
64 *------------------------------------------------------------------------------
66 OSStatus
HIDProcessLocalItem(HIDReportDescriptor
*ptDescriptor
,
67 HIDPreparsedDataPtr ptPreparsedData
)
69 HIDDesignatorItem
*ptDesignatorItem
;
70 HIDStringItem
*ptStringItem
;
71 HIDP_UsageItem
*ptUsageItem
;
74 * Disallow NULL Pointers
76 if ((ptDescriptor
== NULL
) || (ptPreparsedData
== NULL
))
77 return kHIDNullPointerErr
;
79 * Process the LocalItem by tag
81 ptItem
= &ptDescriptor
->item
;
85 * Note that Tag = usage Item may represent either
86 * a UsagePair with the usagePage implied, or
87 * a UsagePair defined by an extended usage
88 * If a Tag = usage Item has 1 or 2 bytes of data
89 * then the current usagePage is used
90 * If a Tag = usage Item has 4 bytes of data
91 * then the high order bytes are the usagePage
93 * Note that the Microsoft HID Parser uses the last
94 * usagePage defined before the MainItem with which
95 * the usage is associated rather than the current
96 * usagePage. The method used here is more generic
97 * although multiple UsagePages for a MainItem are
98 * unlikely due to the MS limitation.
101 ptUsageItem
= &ptPreparsedData
->usageItems
[ptPreparsedData
->usageItemCount
++];
102 ptUsageItem
->isRange
= false;
103 if (ptItem
->byteCount
== 4)
105 ptUsageItem
->usagePage
= ptItem
->unsignedValue
>>16;
106 ptUsageItem
->usage
= ptItem
->unsignedValue
&0xFFFFL
;
110 ptUsageItem
->usagePage
= ptDescriptor
->globals
.usagePage
;
111 ptUsageItem
->usage
= ptItem
->unsignedValue
;
115 * Note that Tag = usage Minimum Item may represent either
116 * a UsagePair with the usagePage implied, or
117 * a UsagePair defined by an extended usage
118 * If a Tag = usage Item has 1 or 2 bytes of data
119 * then the current usagePage is used
120 * If a Tag = usage Item has 4 bytes of data
121 * then the high order bytes are the usagePage
123 case kHIDTagUsageMinimum
:
124 if (ptDescriptor
->haveUsageMax
)
126 ptUsageItem
= &ptPreparsedData
->usageItems
[ptPreparsedData
->usageItemCount
++];
127 ptUsageItem
->isRange
= true;
128 if (ptItem
->byteCount
== 4)
130 ptUsageItem
->usagePage
= ptItem
->unsignedValue
>>16;
131 ptUsageItem
->usageMinimum
= ptItem
->unsignedValue
&0xFFFFL
;
135 ptUsageItem
->usagePage
= ptDescriptor
->globals
.usagePage
;
136 ptUsageItem
->usageMinimum
= ptItem
->unsignedValue
;
138 if (ptUsageItem
->usagePage
!= ptDescriptor
->rangeUsagePage
)
139 return kHIDInvalidRangePageErr
;
140 ptUsageItem
->usageMaximum
= ptDescriptor
->usageMaximum
;
141 if (ptUsageItem
->usageMaximum
< ptUsageItem
->usageMinimum
)
142 return kHIDInvertedUsageRangeErr
;
143 ptDescriptor
->haveUsageMax
= false;
144 ptDescriptor
->haveUsageMin
= false;
148 if (ptItem
->byteCount
== 4)
150 ptDescriptor
->rangeUsagePage
= ptItem
->unsignedValue
>>16;
151 ptDescriptor
->usageMinimum
= ptItem
->unsignedValue
&0xFFFFL
;
155 ptDescriptor
->rangeUsagePage
= ptDescriptor
->globals
.usagePage
;
156 ptDescriptor
->usageMinimum
= ptItem
->unsignedValue
;
158 ptDescriptor
->haveUsageMin
= true;
162 * Note that Tag = usage Maximum Item may represent either
163 * a UsagePair with the usagePage implied, or
164 * a UsagePair defined by an extended usage
165 * If a Tag = usage Item has 1 or 2 bytes of data
166 * then the current usagePage is used
167 * If a Tag = usage Item has 4 bytes of data
168 * then the high order bytes are the usagePage
170 case kHIDTagUsageMaximum
:
171 if (ptDescriptor
->haveUsageMin
)
173 ptUsageItem
= &ptPreparsedData
->usageItems
[ptPreparsedData
->usageItemCount
++];
174 ptUsageItem
->isRange
= true;
175 if (ptItem
->byteCount
== 4)
177 ptUsageItem
->usagePage
= ptItem
->unsignedValue
>>16;
178 ptUsageItem
->usageMaximum
= ptItem
->unsignedValue
&0xFFFFL
;
182 ptUsageItem
->usagePage
= ptDescriptor
->globals
.usagePage
;
183 ptUsageItem
->usageMaximum
= ptItem
->unsignedValue
;
185 if (ptUsageItem
->usagePage
!= ptDescriptor
->rangeUsagePage
)
186 return kHIDInvalidRangePageErr
;
187 ptUsageItem
->usageMinimum
= ptDescriptor
->usageMinimum
;
188 if (ptUsageItem
->usageMaximum
< ptUsageItem
->usageMinimum
)
189 return kHIDInvertedUsageRangeErr
;
190 ptDescriptor
->haveUsageMax
= false;
191 ptDescriptor
->haveUsageMin
= false;
195 if (ptItem
->byteCount
== 4)
197 ptDescriptor
->rangeUsagePage
= ptItem
->unsignedValue
>>16;
198 ptDescriptor
->usageMaximum
= ptItem
->unsignedValue
&0xFFFFL
;
202 ptDescriptor
->rangeUsagePage
= ptDescriptor
->globals
.usagePage
;
203 ptDescriptor
->usageMaximum
= ptItem
->unsignedValue
;
205 ptDescriptor
->haveUsageMax
= true;
211 case kHIDTagDesignatorIndex
:
212 ptDesignatorItem
= &ptPreparsedData
->desigItems
[ptPreparsedData
->desigItemCount
++];
213 ptDesignatorItem
->isRange
= false;
214 ptDesignatorItem
->index
= ptItem
->unsignedValue
;
216 case kHIDTagDesignatorMinimum
:
217 if (ptDescriptor
->haveDesigMax
)
219 ptDesignatorItem
= &ptPreparsedData
->desigItems
[ptPreparsedData
->desigItemCount
++];
220 ptDesignatorItem
->isRange
= true;
221 ptDesignatorItem
->minimum
= ptItem
->unsignedValue
;
222 ptDesignatorItem
->maximum
= ptDescriptor
->desigMaximum
;
223 ptDescriptor
->haveDesigMin
= false;
224 ptDescriptor
->haveDesigMax
= false;
228 ptDescriptor
->desigMinimum
= ptItem
->unsignedValue
;
229 ptDescriptor
->haveDesigMin
= true;
232 case kHIDTagDesignatorMaximum
:
233 if (ptDescriptor
->haveDesigMin
)
235 ptDesignatorItem
= &ptPreparsedData
->desigItems
[ptPreparsedData
->desigItemCount
++];
236 ptDesignatorItem
->isRange
= true;
237 ptDesignatorItem
->maximum
= ptItem
->unsignedValue
;
238 ptDesignatorItem
->minimum
= ptDescriptor
->desigMinimum
;
239 ptDescriptor
->haveDesigMin
= false;
240 ptDescriptor
->haveDesigMax
= false;
244 ptDescriptor
->desigMaximum
= ptItem
->unsignedValue
;
245 ptDescriptor
->haveDesigMax
= true;
251 case kHIDTagStringIndex
:
252 ptStringItem
= &ptPreparsedData
->stringItems
[ptPreparsedData
->stringItemCount
++];
253 ptStringItem
->isRange
= false;
254 ptStringItem
->index
= ptItem
->unsignedValue
;
256 case kHIDTagStringMinimum
:
257 if (ptDescriptor
->haveStringMax
)
259 ptStringItem
= &ptPreparsedData
->stringItems
[ptPreparsedData
->stringItemCount
++];
260 ptStringItem
->isRange
= true;
261 ptStringItem
->minimum
= ptItem
->unsignedValue
;
262 ptStringItem
->maximum
= ptDescriptor
->stringMaximum
;
263 ptDescriptor
->haveStringMin
= false;
264 ptDescriptor
->haveStringMax
= false;
268 ptDescriptor
->stringMinimum
= ptItem
->unsignedValue
;
269 ptDescriptor
->haveStringMin
= true;
272 case kHIDTagStringMaximum
:
273 if (ptDescriptor
->haveStringMin
)
275 ptStringItem
= &ptPreparsedData
->stringItems
[ptPreparsedData
->stringItemCount
++];
276 ptStringItem
->isRange
= true;
277 ptStringItem
->maximum
= ptItem
->unsignedValue
;
278 ptStringItem
->minimum
= ptDescriptor
->stringMinimum
;
279 ptDescriptor
->haveStringMin
= false;
280 ptDescriptor
->haveStringMax
= false;
284 ptDescriptor
->stringMaximum
= ptItem
->unsignedValue
;
285 ptDescriptor
->haveStringMax
= true;
289 * Delimiters (are not processed)
291 case kHIDTagSetDelimiter
: