1/* 2 * @APPLE_LICENSE_HEADER_START@ 3 * 4 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 File: HIDHasUsage.c 25 26 Contains: xxx put contents here xxx 27 28 Version: xxx put version here xxx 29 30 Copyright: � 1999-2000 by Apple Computer, Inc., all rights reserved. 31 32 File Ownership: 33 34 DRI: xxx put dri here xxx 35 36 Other Contact: xxx put other contact here xxx 37 38 Technology: xxx put technology here xxx 39 40 Writers: 41 42 (KH) Keithen Hayenga 43 (BWS) Brent Schorsch 44 45 Change History (most recent first): 46 47 <USB2> 12/12/00 KH range count off by 1. 48 <USB1> 3/5/99 BWS first checked in 49*/ 50 51#include "HIDLib.h" 52 53/* 54 *------------------------------------------------------------------------------ 55 * 56 * HidP_UsageFromIndex 57 * 58 * Input: 59 * ptPreparsedData - The Preparsed Data 60 * ptReportItem - The Report Item 61 * usagePage - The usage Page to find 62 * usage - The usage to find 63 * piIndex(optional) - The usage Index pointer (Can be used to tell 64 * which bits in an array correspond to that usage.) 65 * piCount(optional) - The usage Count pointer (Can be used to tell 66 * how many items will be in a report.) 67 * Output: 68 * piIndex - The usage Index 69 * Returns: 70 * The usage 71 * 72 *------------------------------------------------------------------------------ 73*/ 74Boolean HIDHasUsage (HIDPreparsedDataRef preparsedDataRef, 75 HIDReportItem *ptReportItem, 76 HIDUsage usagePage, HIDUsage usage, 77 UInt32 *piIndex, UInt32 *piCount) 78{ 79 HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef; 80 int iUsageItem; 81 UInt32 iUsageIndex; 82 int iUsages; 83 int i; 84 SInt32 iCountsLeft; 85 HIDP_UsageItem *ptUsageItem; 86 Boolean bOnPage; 87/* 88 * Disallow Null Pointers 89*/ 90 if ((ptPreparsedData == NULL) 91 || (ptReportItem == NULL)) 92 return 0; 93 if (ptPreparsedData->hidTypeIfValid != kHIDOSType) 94 return 0; 95/* 96 * Look through the usage Items for this usage 97*/ 98 iUsageItem = ptReportItem->firstUsageItem; 99 iUsageIndex = 0; 100 for (i=0; i<ptReportItem->usageItemCount; i++) 101 { 102/* 103 * Each usage Item is either a usage or a usage range 104*/ 105 ptUsageItem = &ptPreparsedData->usageItems[iUsageItem++]; 106 bOnPage = ((usagePage == 0) || (usagePage == ptUsageItem->usagePage)); 107 if (ptUsageItem->isRange) 108 { 109/* 110 * For usage Ranges 111 * If the index is in the range 112 * then return the usage 113 * Otherwise adjust the index by the size of the range 114*/ 115 if ((usage >= ptUsageItem->usageMinimum) 116 && (usage <= ptUsageItem->usageMaximum)) 117 { 118 if (piIndex != NULL) 119 *piIndex = iUsageIndex + (ptUsageItem->usageMinimum - usage); 120/* 121 * If this usage is the last one for this ReportItem 122 * then it gets all of the remaining reportCount 123*/ 124 if (piCount != NULL) 125 { 126 // piCount is going to be used to find which element in a button array is 127 // the one that returns the value for that usage. 128 if (((i+1) == ptReportItem->usageItemCount) 129 && (usage == ptUsageItem->usageMaximum)) 130 { 131 // Hmm, the same logic in the non-range case below was wrong. But things 132 // seem to be working for finding buttons, so i am not changing it here. 133 // However, we have made some changes to range calculations that may no 134 // longer require that -1 here either. Heads up! 135 iCountsLeft = ptReportItem->globals.reportCount - iUsageIndex - 1; 136 if (iCountsLeft > 1) 137 *piCount = iCountsLeft; 138 else 139 *piCount = 1; 140 } 141 else 142 *piCount = 1; 143 } 144 if (bOnPage) 145 return true; 146 } 147 iUsages = ptUsageItem->usageMaximum - ptUsageItem->usageMinimum; 148 if (iUsages < 0) 149 iUsages = -iUsages; 150 iUsages++; // Add off by one adjustment AFTER sign correction. 151 iUsageIndex += iUsages; 152 } 153 else 154 { 155/* 156 * For Usages 157 * If the index is zero 158 * then return this usage 159 * Otherwise one less to index through 160*/ 161 if (usage == ptUsageItem->usage) 162 { 163 if (piIndex != NULL) 164 *piIndex = iUsageIndex; 165 if (piCount != NULL) 166 { 167 if ((i+1) == ptReportItem->usageItemCount) 168 { 169 // Keithen does not understand the logic of iCountsLeft. 170 // In Radar #2579612 we come through here for HIDGetUsageValueArray 171 // and HIDGetSpecificValueCaps. In both cases piCount that is returned 172 // should be the reportCount without the -1. 173// iCountsLeft = ptReportItem->globals.reportCount - iUsageIndex - 1; 174 iCountsLeft = ptReportItem->globals.reportCount - iUsageIndex; 175 if (iCountsLeft > 1) 176 *piCount = iCountsLeft; 177 else 178 *piCount = 1; 179 } 180 else 181 *piCount = 1; 182 } 183 if (bOnPage) 184 return true; 185 } 186 iUsageIndex++; 187 } 188 } 189 return false; 190} 191