1/* 2 * 3 * @APPLE_LICENSE_HEADER_START@ 4 * 5 * Copyright (c) 1999-2012 Apple Computer, Inc. All Rights Reserved. 6 * 7 * This file contains Original Code and/or Modifications of Original Code 8 * as defined in and that are subject to the Apple Public Source License 9 * Version 2.0 (the 'License'). You may not use this file except in 10 * compliance with the License. Please obtain a copy of the License at 11 * http://www.opensource.apple.com/apsl/ and read it before using this 12 * file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 * Please see the License for the specific language governing rights and 20 * limitations under the License. 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/* 25 File: HIDGetNextUsageValueInfo.c 26 27 Contains: HIDGetNextUsageValueInfo call for HID Library 28 29 Version: 1.0d1 30 31 Copyright: � 2000 by Apple Computer, Inc., all rights reserved. 32 33 File Ownership: 34 35 DRI: David Ferguson 36 37 Other Contact: Keithen Hayenga 38 39 Technology: technologies, usb 40 41 Writers: 42 43 (KH) Keithen Hayenga 44 45 Change History (most recent first): 46 47 <USB1> 2/14/00 KH first checked in 48*/ 49 50#include "HIDLib.h" 51 52/* 53 *------------------------------------------------------------------------------ 54 * 55 * HIDGetNextUsageValueInfo - Get report id and collection for a usage. In keeping 56 * with USBGetNextInterface, we find the usage in the 57 * next collection, so that you can find usages that 58 * have the same usage and usage page. 59 * 60 * Input: 61 * reportType - HIDP_Input, HIDP_Output, HIDP_Feature 62 * usagePage - Page Criteria or zero 63 * usage - The usage to get the information for 64 * collection - Starting Collection Criteria or zero 65 * preparsedDataRef - Pre-Parsed Data 66 * Output: 67 * collection - Final Collection Criteria or no change 68 * reportID - Report ID or no change 69 * Returns: 70 * kHIDBadParameterErr when there are no more collections to search. 71 * 72 *------------------------------------------------------------------------------ 73*/ 74OSStatus HIDGetNextUsageValueInfo 75 (HIDReportType reportType, 76 HIDUsage usagePage, 77 HIDUsage usage, 78 UInt32 * collection, 79 UInt8 * reportID, 80 HIDPreparsedDataRef preparsedDataRef) 81{ 82 HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr)preparsedDataRef; 83 HIDReportItem *ptReportItem; 84 UInt32 iCollection; 85 UInt32 newCollection = 0xFFFFFFFF; 86 int iR; 87 UInt8 newReportID = 0; 88 OSStatus iStatus = kHIDUsageNotFoundErr; 89 90 //Disallow Null Pointers 91 92 if ((ptPreparsedData == NULL) || (collection == NULL) || (reportID == NULL)) 93 return kHIDNullPointerErr; 94 if (ptPreparsedData->hidTypeIfValid != kHIDOSType) 95 return kHIDInvalidPreparsedDataErr; 96 97 // The Collection must be in range 98 99 iCollection = *collection; 100 if (iCollection >= ptPreparsedData->collectionCount) 101 return kHIDBadParameterErr; 102 103 // HIDGetNextUsageValueInfo is different from HIDGetUsageValue in how it treats 104 // the collection parameter. HIDGetUsageValue will only look at report items that 105 // are within the collection and can therefore limit it's searches to starting at 106 // ptPreparsedData->collections[iCollection]->firstReportItem and only check 107 // ptPreparsedData->collections[iCollection]->reportItemCount. Since we want to 108 // find the NEXT collection as well, we need to cycle through all of the reports. 109 110 for (iR = 0; iR < ptPreparsedData->reportItemCount; iR++) 111 { 112 SInt32 minUsage; 113 SInt32 maxUsage; 114 HIDP_UsageItem thisUsage; 115 116 ptReportItem = &ptPreparsedData->reportItems[iR]; 117 118 thisUsage = ptPreparsedData->usageItems[ptReportItem->firstUsageItem]; 119 120 if (thisUsage.isRange) 121 { 122 minUsage = thisUsage.usageMinimum; 123 maxUsage = thisUsage.usageMaximum; 124 } 125 else 126 { 127 minUsage = thisUsage.usage; 128 maxUsage = thisUsage.usage; 129 } 130 131 if (ptReportItem->reportType == reportType && 132 (usagePage == 0 || ptReportItem->globals.usagePage == usagePage) && 133 (usage >= minUsage && usage <= maxUsage) && 134 ptReportItem->parent > iCollection && 135 HIDIsVariable(ptReportItem, preparsedDataRef)) 136 { 137 if (ptReportItem->parent < newCollection) 138 { 139 newCollection = ptReportItem->parent; 140 newReportID = iR; 141 iStatus = 0; 142 } 143 } 144 } 145 146 if (!iStatus) 147 { 148 *reportID = newReportID; 149 *collection = newCollection; 150 } 151 152 return iStatus; 153} 154 155