1/*
2 * @APPLE_LICENSE_HEADER_START@
3 *
4 * Copyright (c) 1999-2012 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:		HIDGetButtons.c
25
26	Contains:	xxx put contents here xxx
27
28	Version:	xxx put version here xxx
29
30	Copyright:	� 1999 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		(BWS)	Brent Schorsch
43
44	Change History (most recent first):
45
46	  <USB4>	 11/1/99	BWS		[2405720]  We need a better check for 'bit padding' items,
47									rather than just is constant. We will check to make sure the
48									item is constant, and has no usage, or zero usage. This means we
49									need to pass an additional parameter to some internal functions
50	  <USB3>	  4/7/99	BWS		Add support for reversed report items
51	  <USB2>	  3/5/99	BWS		[2311349]  iteration broken, passing wrong value
52	  <USB1>	  3/5/99	BWS		first checked in
53*/
54
55#include "HIDLib.h"
56
57/*
58 *------------------------------------------------------------------------------
59 *
60 * HIDGetButtons - Get the state of the buttons for a Page
61 *
62 *	 Input:
63 *			  reportType		   - HIDP_Input, HIDP_Output, HIDP_Feature
64 *			  usagePage			   - Page Criteria or zero
65 *			  iCollection			- Collection Criteria or zero
66 *			  piUsageList			- Usages for pressed buttons
67 *			  piUsageListLength		- Max entries in UsageList
68 *			  ptPreparsedData		- Pre-Parsed Data
69 *			  psReport				- An HID Report
70 *			  iReportLength			- The length of the Report
71 *	 Output:
72 *			  piValue				- Pointer to usage Value
73 *	 Returns:
74 *
75 *------------------------------------------------------------------------------
76*/
77OSStatus
78HIDGetButtons  (HIDReportType			reportType,
79				UInt32					iCollection,
80				HIDUsageAndPagePtr		ptUsageList,
81				UInt32 *				piUsageListLength,
82				HIDPreparsedDataRef 	preparsedDataRef,
83				void *					psReport,
84				IOByteCount             iReportLength)
85{
86	HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
87	HIDCollection *ptCollection;
88	HIDReportItem *ptReportItem;
89	int iR, iE;
90	SInt32 iValue;
91	int iStart;
92	int iReportItem;
93	int iMaxUsages;
94	HIDUsageAndPage tUsageAndPage;
95
96/*
97 *	Disallow Null Pointers
98*/
99	if ((ptPreparsedData == NULL)
100	 || (ptUsageList == NULL)
101	 || (piUsageListLength == NULL)
102	 || (psReport == NULL))
103		return kHIDNullPointerErr;
104	if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
105		return kHIDInvalidPreparsedDataErr;
106/*
107 *	Save the UsageList size
108*/
109	iMaxUsages = *piUsageListLength;
110	*piUsageListLength = 0;
111/*
112 *	Search only the scope of the Collection specified
113 *	Go through the ReportItems
114 *	Filter on ReportType
115*/
116	ptCollection = &ptPreparsedData->collections[iCollection];
117	for (iR=0; iR<ptCollection->reportItemCount; iR++)
118	{
119		iReportItem = ptCollection->firstReportItem + iR;
120		ptReportItem = &ptPreparsedData->reportItems[iReportItem];
121		if ((ptReportItem->reportType == reportType)
122		 && HIDIsButton(ptReportItem, preparsedDataRef))
123		{
124/*
125 *			Save Arrays and Bitmaps
126*/
127			iStart = ptReportItem->startBit;
128			for (iE=0; iE<ptReportItem->globals.reportCount; iE++)
129			{
130				OSStatus status = 0;
131				iValue = 0;
132
133				if ((ptReportItem->dataModes & kHIDDataArrayBit) == kHIDDataArray)
134				{
135					status = HIDGetData(psReport, iReportLength, iStart, ptReportItem->globals.reportSize, &iValue, false);
136					if (!status)
137						status = HIDPostProcessRIValue (ptReportItem, &iValue);
138					if (status) return status;
139
140					iStart += ptReportItem->globals.reportSize;
141					HIDUsageAndPageFromIndex(preparsedDataRef,ptReportItem,ptReportItem->globals.logicalMinimum+iE,&tUsageAndPage);
142					if (*piUsageListLength >= iMaxUsages)
143						return kHIDBufferTooSmallErr;
144					ptUsageList[(*piUsageListLength)++] = tUsageAndPage;
145				}
146				else
147				{
148					status = HIDGetData(psReport, iReportLength, iStart, 1, &iValue, false);
149					if (!status)
150						status = HIDPostProcessRIValue (ptReportItem, &iValue);
151					if (status) return status;
152
153					iStart++;
154					if (iValue != 0)
155					{
156						HIDUsageAndPageFromIndex(preparsedDataRef,ptReportItem,ptReportItem->globals.logicalMinimum+iE,&tUsageAndPage);
157						if (*piUsageListLength >= iMaxUsages)
158							return kHIDBufferTooSmallErr;
159						ptUsageList[(*piUsageListLength)++] = tUsageAndPage;
160					}
161				}
162			}
163		}
164	}
165	return kHIDSuccess;
166}
167