|
|
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: HIDProcessReportItem.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: <USB7> 4/7/99 BWS Add support for reversed report items
46: <USB6> 3/20/99 BWS Oops, strict error checking does not work if there is no error.
47: We should only return error if it is not noErr
48: <USB5> 3/17/99 BWS [2314839] Added flags field to HIDPreparsedData which is set in
49: new parameter to HIDOpenReportDescriptor. We check the
50: StrictErrorCheck bit to determine whether we return errors or
51: just try to work around problems we find
52: <USB4> 3/7/99 BWS [2311413] Do not error check min/max ranges for constants
53: <USB3> 3/7/99 BWS [2311412] We need to handle the cases where physical min/max is
54: either (0/0) which is valid according to the spec, and means to
55: use the logical min/max, and the invalid case, that some devices
56: exibit, which has (0/-1) which we will treat the same,
57: <USB2> 3/5/99 BWS [2311359] HIDProcessReportItem does not initialize startBit
58: field of HIDReportItem!
59: <USB1> 3/5/99 BWS first checked in
60: */
61:
62: #include "HIDLib.h"
63:
64: /*
65: *------------------------------------------------------------------------------
66: *
67: * HIDProcessReportItem - Process a Report Item MainItem
68: *
69: * Input:
70: * ptDescriptor - The Descriptor Structure
71: * ptPreparsedData - The PreParsedData Structure
72: * Output:
73: * ptDescriptor - The Descriptor Structure
74: * ptPreparsedData - The PreParsedData Structure
75: * Returns:
76: * kHIDSuccess - Success
77: * kHIDNullPointerErr - Argument, Pointer was Null
78: *
79: *------------------------------------------------------------------------------
80: */
81: OSStatus HIDProcessReportItem(HIDReportDescriptor *ptDescriptor, HIDPreparsedDataPtr ptPreparsedData)
82: {
83: OSStatus error = noErr;
84: HIDReportItem *ptReportItem;
85: HIDReportSizes *ptReport;
86: int iBits;
87: /*
88: * Disallow NULL Pointers
89: */
90:
91: if ((ptDescriptor == NULL) || (ptPreparsedData == NULL))
92: return kHIDNullPointerErr;
93: /*
94: * Begin to initialize the new Report Item structure
95: */
96:
97: ptReportItem = &ptPreparsedData->reportItems[ptPreparsedData->reportItemCount++];
98: ptReportItem->dataModes = ptDescriptor->item.unsignedValue;
99: ptReportItem->globals = ptDescriptor->globals;
100: ptReportItem->flags = 0;
101:
102: /*
103: * Reality Check on the Report Main Item
104: */
105: // Don't check ranges for constants (MS Sidewinder, for one, does not reset)
106: //if (!(ptReportItem->dataModes & kHIDDataConstantBit)) // don't think we need this anymore
107: {
108: if (ptReportItem->globals.logicalMinimum >= (1<<ptReportItem->globals.reportSize))
109: {
110: error = kHIDBadLogicalMinimumErr;
111: ptReportItem->globals.logicalMinimum = 0;
112: }
113: if (ptReportItem->globals.logicalMaximum >= (1<<ptReportItem->globals.reportSize))
114: {
115: if (error == noErr)
116: error = kHIDBadLogicalMaximumErr;
117: ptReportItem->globals.logicalMaximum = (1<<ptReportItem->globals.reportSize);
118: }
119: if (ptReportItem->globals.logicalMinimum > ptReportItem->globals.logicalMaximum)
120: {
121: SInt32 temp;
122: if (error == noErr)
123: error = kHIDInvertedLogicalRangeErr;
124:
125: // mark as a 'reversed' item
126: ptReportItem->flags |= kHIDReportItemFlag_Reversed;
127:
128: temp = ptReportItem->globals.logicalMaximum;
129: ptReportItem->globals.logicalMaximum = ptReportItem->globals.logicalMinimum;
130: ptReportItem->globals.logicalMinimum = temp;
131: }
132: }
133:
134: // check to see if we got half a range (we don't need to fix this, since 'isRange' will be false
135: if ((error == noErr) && (ptDescriptor->haveUsageMin || ptDescriptor->haveUsageMax))
136: error = kHIDUnmatchedUsageRangeErr;
137: if ((error == noErr) && (ptDescriptor->haveStringMin || ptDescriptor->haveStringMax))
138: error = kHIDUnmatchedStringRangeErr;
139: if ((error == noErr) && (ptDescriptor->haveDesigMin || ptDescriptor->haveDesigMax))
140: error = kHIDUnmatchedDesignatorRangeErr;
141:
142: // if the physical min/max are out of wack, use the logical values
143: if (ptReportItem->globals.physicalMinimum >= ptReportItem->globals.physicalMaximum)
144: {
145: // equal to each other is not an error, just means to use the logical values
146: if ((error == noErr) &&
147: (ptReportItem->globals.physicalMinimum > ptReportItem->globals.physicalMaximum))
148: error = kHIDInvertedPhysicalRangeErr;
149:
150: ptReportItem->globals.physicalMinimum = ptReportItem->globals.logicalMinimum;
151: ptReportItem->globals.physicalMaximum = ptReportItem->globals.logicalMaximum;
152: }
153:
154: // if strict error checking is true, return any errors
155: if (error != noErr && ptPreparsedData->flags & kHIDFlag_StrictErrorChecking)
156: return error;
157:
158: /*
159: * Continue to initialize the new Report Item structure
160: */
161:
162: ptReportItem->parent = ptDescriptor->parent;
163: ptReportItem->firstUsageItem = ptDescriptor->firstUsageItem;
164: ptDescriptor->firstUsageItem = ptPreparsedData->usageItemCount;
165: ptReportItem->usageItemCount = ptPreparsedData->usageItemCount - ptReportItem->firstUsageItem;
166: ptReportItem->firstStringItem = ptDescriptor->firstStringItem;
167: ptDescriptor->firstStringItem = ptPreparsedData->stringItemCount;
168: ptReportItem->stringItemCount = ptPreparsedData->stringItemCount - ptReportItem->firstStringItem;
169: ptReportItem->firstDesigItem = ptDescriptor->firstDesigItem;
170: ptDescriptor->firstDesigItem = ptPreparsedData->desigItemCount;
171: ptReportItem->desigItemCount = ptPreparsedData->desigItemCount - ptReportItem->firstDesigItem;
172: /*
173: * Update the Report by the size of this item
174: */
175:
176: ptReport = &ptPreparsedData->reports[ptReportItem->globals.reportIndex];
177: iBits = ptReportItem->globals.reportSize * ptReportItem->globals.reportCount;
178: switch (ptDescriptor->item.tag)
179: {
180: case kHIDTagFeature:
181: ptReportItem->reportType = kHIDFeatureReport;
182: ptReportItem->startBit = ptReport->featureBitCount;
183: ptReport->featureBitCount += iBits;
184: break;
185: case kHIDTagOutput:
186: ptReportItem->reportType = kHIDOutputReport;
187: ptReportItem->startBit = ptReport->outputBitCount;
188: ptReport->outputBitCount += iBits;
189: break;
190: case kHIDTagInput:
191: ptReportItem->reportType = kHIDInputReport;
192: ptReportItem->startBit = ptReport->inputBitCount;
193: ptReport->inputBitCount += iBits;
194: break;
195: default:
196: ptReportItem->reportType = kHIDUnknownReport;
197: ptReportItem->startBit = 0;
198: break;
199: }
200: return kHIDSuccess;
201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.