|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: File: HIDProcessLocalItem.c
24:
25: Contains: xxx put contents here xxx
26:
27: Version: xxx put version here xxx
28:
29: Copyright: � 1999 by Apple Computer, Inc., all rights reserved.
30:
31: File Ownership:
32:
33: DRI: xxx put dri here xxx
34:
35: Other Contact: xxx put other contact here xxx
36:
37: Technology: xxx put technology here xxx
38:
39: Writers:
40:
41: (BWS) Brent Schorsch
42:
43: Change History (most recent first):
44:
45: <USB1> 3/5/99 BWS first checked in
46: */
47:
48: #include "HIDLib.h"
49:
50: /*
51: *------------------------------------------------------------------------------
52: *
53: * HIDProcessLocalItem - Process a LocalItem
54: *
55: * Input:
56: * ptDescriptor - The Descriptor Structure
57: * ptPreparsedData - The PreParsedData Structure
58: * Output:
59: * ptPreparsedData - The PreParsedData Structure
60: * Returns:
61: * kHIDSuccess - Success
62: * kHIDNullPointerErr - Argument, Pointer was Null
63: *
64: *------------------------------------------------------------------------------
65: */
66: OSStatus HIDProcessLocalItem(HIDReportDescriptor *ptDescriptor,
67: HIDPreparsedDataPtr ptPreparsedData)
68: {
69: HIDDesignatorItem *ptDesignatorItem;
70: HIDStringItem *ptStringItem;
71: HIDP_UsageItem *ptUsageItem;
72: HIDItem *ptItem;
73: /*
74: * Disallow NULL Pointers
75: */
76: if ((ptDescriptor == NULL) || (ptPreparsedData == NULL))
77: return kHIDNullPointerErr;
78: /*
79: * Process the LocalItem by tag
80: */
81: ptItem = &ptDescriptor->item;
82: switch (ptItem->tag)
83: {
84: /*
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
92: *
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.
99: */
100: case kHIDTagUsage:
101: ptUsageItem = &ptPreparsedData->usageItems[ptPreparsedData->usageItemCount++];
102: ptUsageItem->isRange = false;
103: if (ptItem->byteCount == 4)
104: {
105: ptUsageItem->usagePage = ptItem->unsignedValue>>16;
106: ptUsageItem->usage = ptItem->unsignedValue&0xFFFFL;
107: }
108: else
109: {
110: ptUsageItem->usagePage = ptDescriptor->globals.usagePage;
111: ptUsageItem->usage = ptItem->unsignedValue;
112: }
113: break;
114: /*
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
122: */
123: case kHIDTagUsageMinimum:
124: if (ptDescriptor->haveUsageMax)
125: {
126: ptUsageItem = &ptPreparsedData->usageItems[ptPreparsedData->usageItemCount++];
127: ptUsageItem->isRange = true;
128: if (ptItem->byteCount == 4)
129: {
130: ptUsageItem->usagePage = ptItem->unsignedValue>>16;
131: ptUsageItem->usageMinimum = ptItem->unsignedValue&0xFFFFL;
132: }
133: else
134: {
135: ptUsageItem->usagePage = ptDescriptor->globals.usagePage;
136: ptUsageItem->usageMinimum = ptItem->unsignedValue;
137: }
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;
145: }
146: else
147: {
148: if (ptItem->byteCount == 4)
149: {
150: ptDescriptor->rangeUsagePage = ptItem->unsignedValue>>16;
151: ptDescriptor->usageMinimum = ptItem->unsignedValue&0xFFFFL;
152: }
153: else
154: {
155: ptDescriptor->rangeUsagePage = ptDescriptor->globals.usagePage;
156: ptDescriptor->usageMinimum = ptItem->unsignedValue;
157: }
158: ptDescriptor->haveUsageMin = true;
159: }
160: break;
161: /*
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
169: */
170: case kHIDTagUsageMaximum:
171: if (ptDescriptor->haveUsageMin)
172: {
173: ptUsageItem = &ptPreparsedData->usageItems[ptPreparsedData->usageItemCount++];
174: ptUsageItem->isRange = true;
175: if (ptItem->byteCount == 4)
176: {
177: ptUsageItem->usagePage = ptItem->unsignedValue>>16;
178: ptUsageItem->usageMaximum = ptItem->unsignedValue&0xFFFFL;
179: }
180: else
181: {
182: ptUsageItem->usagePage = ptDescriptor->globals.usagePage;
183: ptUsageItem->usageMaximum = ptItem->unsignedValue;
184: }
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;
192: }
193: else
194: {
195: if (ptItem->byteCount == 4)
196: {
197: ptDescriptor->rangeUsagePage = ptItem->unsignedValue>>16;
198: ptDescriptor->usageMaximum = ptItem->unsignedValue&0xFFFFL;
199: }
200: else
201: {
202: ptDescriptor->rangeUsagePage = ptDescriptor->globals.usagePage;
203: ptDescriptor->usageMaximum = ptItem->unsignedValue;
204: }
205: ptDescriptor->haveUsageMax = true;
206: }
207: break;
208: /*
209: * Designators
210: */
211: case kHIDTagDesignatorIndex:
212: ptDesignatorItem = &ptPreparsedData->desigItems[ptPreparsedData->desigItemCount++];
213: ptDesignatorItem->isRange = false;
214: ptDesignatorItem->index = ptItem->unsignedValue;
215: break;
216: case kHIDTagDesignatorMinimum:
217: if (ptDescriptor->haveDesigMax)
218: {
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;
225: }
226: else
227: {
228: ptDescriptor->desigMinimum = ptItem->unsignedValue;
229: ptDescriptor->haveDesigMin = true;
230: }
231: break;
232: case kHIDTagDesignatorMaximum:
233: if (ptDescriptor->haveDesigMin)
234: {
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;
241: }
242: else
243: {
244: ptDescriptor->desigMaximum = ptItem->unsignedValue;
245: ptDescriptor->haveDesigMax = true;
246: }
247: break;
248: /*
249: * Strings
250: */
251: case kHIDTagStringIndex:
252: ptStringItem = &ptPreparsedData->stringItems[ptPreparsedData->stringItemCount++];
253: ptStringItem->isRange = false;
254: ptStringItem->index = ptItem->unsignedValue;
255: break;
256: case kHIDTagStringMinimum:
257: if (ptDescriptor->haveStringMax)
258: {
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;
265: }
266: else
267: {
268: ptDescriptor->stringMinimum = ptItem->unsignedValue;
269: ptDescriptor->haveStringMin = true;
270: }
271: break;
272: case kHIDTagStringMaximum:
273: if (ptDescriptor->haveStringMin)
274: {
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;
281: }
282: else
283: {
284: ptDescriptor->stringMaximum = ptItem->unsignedValue;
285: ptDescriptor->haveStringMax = true;
286: }
287: break;
288: /*
289: * Delimiters (are not processed)
290: */
291: case kHIDTagSetDelimiter:
292: break;
293: }
294: return kHIDSuccess;
295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.