]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IOHIDSystem/IOHIDDescriptorParser/HIDSetButtons.c
b13e73685f5c15b5f9525f6e3bef6cadf1a74fab
[apple/xnu.git] / iokit / Families / IOHIDSystem / IOHIDDescriptorParser / HIDSetButtons.c
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 File: HIDSetButtons.c
24
25 Contains: xxx put contents here xxx
26
27 Version: xxx put version here xxx
28
29 Copyright: © 1999-2000 by Apple Computer, Inc., all rights reserved.
30
31 File Ownership:
32
33 DRI: xxx put dri here xxx
34
35 Other Contact: xxx put other contact here xxx
36
37 Technology: xxx put technology here xxx
38
39 Writers:
40
41 (KH) Keithen Hayenga
42 (BWS) Brent Schorsch
43
44 Change History (most recent first):
45
46 <USB4> 3/24/00 KH Complex report descriptors could lead to reporting
47 kHIDUsageNotFoundErr's as kHIDIncompatibleReportErr's instead.
48 <USB3> 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 <USB2> 4/7/99 BWS Add support for reversed report items
53 <USB1> 3/5/99 BWS first checked in
54 */
55
56 #include "HIDLib.h"
57
58 /*
59 *------------------------------------------------------------------------------
60 *
61 * HIDSetButton - Set the state of a button for a Page
62 *
63 * Input:
64 * reportType - HIDP_Input, HIDP_Output, HIDP_Feature
65 * usagePage - Page Criteria or zero
66 * iCollection - Collection Criteria or zero
67 * usage - Usages for pressed button
68 * ptPreparsedData - Pre-Parsed Data
69 * psReport - An HID Report
70 * iReportLength - The length of the Report
71 * Output:
72 * Returns:
73 *
74 *------------------------------------------------------------------------------
75 */
76 OSStatus HIDSetButton (HIDReportType reportType,
77 HIDUsage usagePage,
78 UInt32 collection,
79 HIDUsage usage,
80 HIDPreparsedDataRef preparsedDataRef,
81 void * report,
82 ByteCount reportLength)
83 {
84 HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
85 HIDCollection *ptCollection;
86 HIDReportItem *ptReportItem;
87 OSStatus iStatus;
88 int iR, iX;
89 SInt32 data;
90 int iStart;
91 int iReportItem;
92 UInt32 iUsageIndex;
93 Boolean bIncompatibleReport = false;
94 Boolean butNotReally = false;
95 /*
96 * Disallow Null Pointers
97 */
98 if ((ptPreparsedData == NULL)
99 || (report == NULL))
100 return kHIDNullPointerErr;
101 if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
102 return kHIDInvalidPreparsedDataErr;
103 /*
104 * The Collection must be in range
105 */
106 if ((collection < 0) || (collection >= ptPreparsedData->collectionCount))
107 return kHIDBadParameterErr;
108 /*
109 * Search only the scope of the Collection specified
110 * Go through the ReportItems
111 * Filter on ReportType and usagePage
112 */
113 ptCollection = &ptPreparsedData->collections[collection];
114 for (iR=0; iR<ptCollection->reportItemCount; iR++)
115 {
116 iReportItem = ptCollection->firstReportItem + iR;
117 ptReportItem = &ptPreparsedData->reportItems[iReportItem];
118 if (HIDIsButton(ptReportItem, preparsedDataRef)
119 && HIDHasUsage(preparsedDataRef,ptReportItem,usagePage,usage,&iUsageIndex,NULL))
120 {
121 /*
122 * This may be the proper data to get
123 * Let's check for the proper Report ID, Type, and Length
124 */
125 iStatus = HIDCheckReport(reportType,preparsedDataRef,ptReportItem,report,reportLength);
126 /*
127 * The Report ID or Type may not match.
128 * This may not be an error (yet)
129 */
130 if (iStatus == kHIDIncompatibleReportErr)
131 bIncompatibleReport = true;
132 else if (iStatus != kHIDSuccess)
133 return iStatus;
134 else
135 {
136 butNotReally = true;
137 /*
138 * Save Arrays
139 */
140 if ((ptReportItem->dataModes & kHIDDataArrayBit) == kHIDDataArray)
141 {
142 for (iX=0; iX<ptReportItem->globals.reportCount; iX++)
143 {
144 iStart = ptReportItem->startBit + (ptReportItem->globals.reportSize * iX);
145 iStatus = HIDGetData(report, reportLength, iStart,
146 ptReportItem->globals.reportSize, &data, true);
147 if (!iStatus)
148 iStatus = HIDPostProcessRIValue (ptReportItem, &data);
149 if (iStatus != kHIDSuccess)
150 return iStatus;
151 // if not already in the list, add it (is this code right??)
152 if (data == 0)
153 return HIDPutData(report, reportLength, iStart,
154 ptReportItem->globals.reportSize,
155 iUsageIndex + ptReportItem->globals.logicalMinimum);
156 }
157 return kHIDBufferTooSmallErr;
158 }
159 /*
160 * Save Bitmaps
161 */
162 else if (ptReportItem->globals.reportSize == 1)
163 {
164 iStart = ptReportItem->startBit + (ptReportItem->globals.reportSize * iUsageIndex);
165 // should we call HIDPreProcessRIValue here?
166 // we are passing '-1' as trhe value, is this right? Some hack to set the right bit to 1?
167 iStatus = HIDPutData(report, reportLength, iStart, ptReportItem->globals.reportSize, -1);
168 if (iStatus != kHIDSuccess)
169 return iStatus;
170 return kHIDSuccess;
171 }
172 }
173 }
174 }
175 // If any of the report items were not the right type, we have set the bIncompatibleReport flag.
176 // However, if any of the report items really were the correct type, we have done our job of checking
177 // and really didn't find a usage. Don't let the bIncompatibleReport flag wipe out our valid test.
178 if (bIncompatibleReport && !butNotReally)
179 return kHIDIncompatibleReportErr;
180 return kHIDUsageNotFoundErr;
181 }
182
183 /*
184 *------------------------------------------------------------------------------
185 *
186 * HIDSetButtons - Set the state of the buttons for a Page
187 *
188 * Input:
189 * reportType - HIDP_Input, HIDP_Output, HIDP_Feature
190 * usagePage - Page Criteria or zero
191 * collection - Collection Criteria or zero
192 * piUsageList - Usages for pressed buttons
193 * piUsageListLength - Max entries in UsageList
194 * ptPreparsedData - Pre-Parsed Data
195 * report - An HID Report
196 * reportLength - The length of the Report
197 * Output:
198 * piValue - Pointer to usage Value
199 * Returns:
200 *
201 *------------------------------------------------------------------------------
202 */
203 OSStatus
204 HIDSetButtons (HIDReportType reportType,
205 HIDUsage usagePage,
206 UInt32 collection,
207 HIDUsage * usageList,
208 UInt32 * usageListSize,
209 HIDPreparsedDataRef preparsedDataRef,
210 void * report,
211 ByteCount reportLength)
212 {
213 HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
214 OSStatus iStatus;
215 int iUsages;
216 int usage;
217 /*
218 * Disallow Null Pointers
219 */
220 if ((ptPreparsedData == NULL)
221 || (usageList == NULL)
222 || (usageListSize == NULL)
223 || (report == NULL))
224 return kHIDNullPointerErr;
225 if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
226 return kHIDInvalidPreparsedDataErr;
227 /*
228 * Save the usage List Length
229 */
230 iUsages = *usageListSize;
231 /*
232 * Write them out one at a time
233 */
234 for (usage=0; usage<iUsages; usage++)
235 {
236 *usageListSize = usage;
237 iStatus = HIDSetButton(reportType, usagePage, collection,
238 usageList[usage], preparsedDataRef,
239 report, reportLength);
240 if (iStatus != kHIDSuccess)
241 return iStatus;
242 }
243 return kHIDSuccess;
244 }