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