Annotation of XNU/iokit/Families/IOHIDSystem/IOHIDDescriptorParser/HIDProcessReportItem.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.