2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 File: HIDGetButtonsOnPage.c
25 Contains: xxx put contents here xxx
27 Version: xxx put version here xxx
29 Copyright: © 1999 by Apple Computer, Inc., all rights reserved.
33 DRI: xxx put dri here xxx
35 Other Contact: xxx put other contact here xxx
37 Technology: xxx put technology here xxx
44 Change History (most recent first):
46 <USB5> 3/24/00 KH Complex report descriptors could lead to reporting
47 kHIDUsageNotFoundErr's as kHIDIncompatibleReportErr's instead.
48 <USB4> 11/1/99 BWS [2405720] We need a better check for 'bit padding' items,
49 rather than just is constant. We will check to make sure the
50 item is constant, and has no usage, or zero usage. This means we
51 need to pass an additional parameter to some internal functions
52 <USB3> 5/26/99 BWS We are not checking the usage page for bitmapped buttons! This
53 caused the Wingman Extreme to get the tilt button on the user
54 page confused with the first button on the button page.
55 <USB2> 4/7/99 BWS Add support for reversed report items
56 <USB1> 3/5/99 BWS first checked in
62 *------------------------------------------------------------------------------
64 * HIDGetButtonsOnPage - Get the state of the buttons for a Page
67 * reportType - HIDP_Input, HIDP_Output, HIDP_Feature
68 * usagePage - Page Criteria or zero
69 * iCollection - Collection Criteria or zero
70 * piUsageList - Usages for pressed buttons
71 * piUsageListLength - Max entries in UsageList
72 * ptPreparsedData - Pre-Parsed Data
73 * psReport - An HID Report
74 * iReportLength - The length of the Report
76 * piValue - Pointer to usage Value
79 *------------------------------------------------------------------------------
81 OSStatus
HIDGetButtonsOnPage(HIDReportType reportType
,
84 HIDUsage
*piUsageList
,
85 UInt32
*piUsageListLength
,
86 HIDPreparsedDataRef preparsedDataRef
,
90 HIDPreparsedDataPtr ptPreparsedData
= (HIDPreparsedDataPtr
) preparsedDataRef
;
91 HIDUsageAndPage tUsageAndPage
;
92 HIDCollection
*ptCollection
;
93 HIDReportItem
*ptReportItem
;
100 Boolean bIncompatibleReport
= false;
101 Boolean butNotReally
= false;
103 * Disallow Null Pointers
105 if ((ptPreparsedData
== NULL
)
106 || (piUsageList
== NULL
)
107 || (piUsageListLength
== NULL
)
108 || (psReport
== NULL
))
109 return kHIDNullPointerErr
;
110 if (ptPreparsedData
->hidTypeIfValid
!= kHIDOSType
)
111 return kHIDInvalidPreparsedDataErr
;
113 * The Collection must be in range
115 if ((iCollection
< 0) || (iCollection
>= ptPreparsedData
->collectionCount
))
116 return kHIDBadParameterErr
;
118 * Save the size of the list
120 iMaxUsages
= *piUsageListLength
;
121 *piUsageListLength
= 0;
123 * Search only the scope of the Collection specified
124 * Go through the ReportItems
125 * Filter on ReportType and usagePage
127 ptCollection
= &ptPreparsedData
->collections
[iCollection
];
128 for (iR
=0; iR
<ptCollection
->reportItemCount
; iR
++)
130 iReportItem
= ptCollection
->firstReportItem
+ iR
;
131 ptReportItem
= &ptPreparsedData
->reportItems
[iReportItem
];
132 if (HIDIsButton(ptReportItem
, preparsedDataRef
))
135 * This may be the proper data to get
136 * Let's check for the proper Report ID, Type, and Length
138 iStatus
= HIDCheckReport(reportType
,preparsedDataRef
,ptReportItem
,
139 psReport
,iReportLength
);
141 * The Report ID or Type may not match.
142 * This may not be an error (yet)
144 if (iStatus
== kHIDIncompatibleReportErr
)
145 bIncompatibleReport
= true;
146 else if (iStatus
!= kHIDSuccess
)
154 iStart
= ptReportItem
->startBit
;
155 for (iE
=0; iE
<ptReportItem
->globals
.reportCount
; iE
++)
157 if ((ptReportItem
->dataModes
& kHIDDataArrayBit
) == kHIDDataArray
)
159 iStatus
= HIDGetData(psReport
, iReportLength
, iStart
,
160 ptReportItem
->globals
.reportSize
,
163 iStatus
= HIDPostProcessRIValue (ptReportItem
, &iValue
);
164 HIDUsageAndPageFromIndex(preparsedDataRef
,
166 iValue
-ptReportItem
->globals
.logicalMinimum
,
168 iStart
+= ptReportItem
->globals
.reportSize
;
169 if (usagePage
== tUsageAndPage
.usagePage
)
171 if (*piUsageListLength
>= iMaxUsages
)
172 return kHIDBufferTooSmallErr
;
173 piUsageList
[(*piUsageListLength
)++] = iValue
;
177 * Save Bitmapped Buttons
181 iStatus
= HIDGetData(psReport
, iReportLength
, iStart
, 1, &iValue
, false);
183 iStatus
= HIDPostProcessRIValue (ptReportItem
, &iValue
);
185 if (!iStatus
&& iValue
!= 0)
187 HIDUsageAndPageFromIndex(preparsedDataRef
,ptReportItem
,iE
,&tUsageAndPage
);
188 if (usagePage
== tUsageAndPage
.usagePage
)
190 if (*piUsageListLength
>= iMaxUsages
)
191 return kHIDBufferTooSmallErr
;
192 piUsageList
[(*piUsageListLength
)++] = tUsageAndPage
.usage
;
201 * If nothing was returned then change the status
203 if (*piUsageListLength
== 0)
205 // If any of the report items were not the right type, we have set the bIncompatibleReport flag.
206 // However, if any of the report items really were the correct type, we have done our job of checking
207 // and really didn't find a usage. Don't let the bIncompatibleReport flag wipe out our valid test.
208 if (bIncompatibleReport
&& !butNotReally
)
209 return kHIDIncompatibleReportErr
;
210 return kHIDUsageNotFoundErr
;