/* *------------------------------------------------------------------------------ * * HIDSetUsageValueArray - Set the values for a usage * * Input: * reportType - HIDP_Input, HIDP_Output, HIDP_Feature * usagePage - Page Criteria * iCollection - Collection Criteria or zero * usage - usage Criteria * psBuffer - Pointer to usage Buffer * iByteLength - Length of usage Buffer * ptPreparsedData - Pre-Parsed Data * psReport - An HID Report * iReportLength - The length of the Report * Output: * piValue - Pointer to usage Value * Returns: * *------------------------------------------------------------------------------ */ OSStatus HIDSetUsageValueArray(HIDReportType reportType, HIDUsage usagePage, UInt32 iCollection, HIDUsage usage, UInt8 *psUsageBuffer, UInt32 iByteLength, HIDPreparsedDataRef preparsedDataRef, void *psReport, UInt32 iReportLength) { HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef; HIDCollection *ptCollection; HIDReportItem *ptReportItem; OSStatus iStatus; int i; int iR; long iValue; int iStart; int iReportItem; UInt32 iUsageIndex; UInt32 iCount; int byteCount; Boolean bIncompatibleReport = false; /* * Disallow Null Pointers */ if ((ptPreparsedData == NULL) || (psUsageBuffer == NULL) || (psReport == NULL)) return kHIDNullPointerErr; if (ptPreparsedData->hidTypeIfValid != kHIDOSType) return kHIDInvalidPreparsedDataErr; /* * The Collection must be in range */ if ((iCollection < 0) || (iCollection >= ptPreparsedData->collectionCount)) return kHIDBadParameterErr; /* * Search only the scope of the Collection specified * Go through the ReportItems * Filter on ReportType and usagePage */ ptCollection = &ptPreparsedData->collections[iCollection]; for (iR=0; iR<ptCollection->reportItemCount; iR++) { iReportItem = ptCollection->firstReportItem + iR; ptReportItem = &ptPreparsedData->reportItems[iReportItem]; if (HIDIsVariable(ptReportItem, preparsedDataRef) && HIDHasUsage(preparsedDataRef,ptReportItem,usagePage,usage,&iUsageIndex,&iCount)) { /* * This may be the proper place * Let's check for the proper Report ID, Type, and Length */ iStatus = HIDCheckReport(reportType,preparsedDataRef,ptReportItem, psReport,iReportLength); /* * The Report ID or Type may not match. * This may not be an error (yet) */ if (iStatus == kHIDIncompatibleReportErr) bIncompatibleReport = true; else if (iStatus != kHIDSuccess) return iStatus; else { /* * Disallow single count variables * Count is set by HasUsage */ if (iCount <= 1) return kHIDNotValueArrayErr; /* * Write out the data */ iStart = ptReportItem->startBit + (ptReportItem->globals.reportSize * iUsageIndex); byteCount = (ptReportItem->globals.reportSize * iCount + 7)/8; if (byteCount > iByteLength) byteCount = iByteLength; for (i=0; i<byteCount; i++) { iValue = *psUsageBuffer++; iStatus = HIDPreProcessRIValue (ptReportItem, &iValue); iStatus = HIDPutData(psReport, iReportLength, iStart, 8, iValue); if (iStatus != kHIDSuccess) return iStatus; iStart += 8; } return kHIDSuccess; } } } if (bIncompatibleReport) return kHIDIncompatibleReportErr; return kHIDUsageNotFoundErr; }
/* *------------------------------------------------------------------------------ * * HIDSetScaledUsageValue - Set the value for a usage * * Input: * reportType - HIDP_Input, HIDP_Output, HIDP_Feature * usagePage - Page Criteria or zero * iCollection - Collection Criteria or zero * usage - usage Criteria or zero * iValue - The usage Value * ptPreparsedData - Pre-Parsed Data * psReport - An HID Report * iReportLength - The length of the Report * Output: * piValue - Pointer to usage Value * Returns: * *------------------------------------------------------------------------------ */ OSStatus HIDSetScaledUsageValue(HIDReportType reportType, HIDUsage usagePage, UInt32 iCollection, HIDUsage usage, SInt32 iUsageValue, HIDPreparsedDataRef preparsedDataRef, void *psReport, IOByteCount iReportLength) { HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef; HIDCollection *ptCollection; HIDReportItem *ptReportItem; OSStatus iStatus; int iR; SInt32 data; int iStart; int iReportItem; UInt32 iUsageIndex; Boolean bIncompatibleReport = false; /* * Disallow Null Pointers */ if ((ptPreparsedData == NULL) || (psReport == NULL)) return kHIDNullPointerErr; if (ptPreparsedData->hidTypeIfValid != kHIDOSType) return kHIDInvalidPreparsedDataErr; /* * The Collection must be in range */ if (iCollection >= ptPreparsedData->collectionCount) return kHIDBadParameterErr; /* * Search only the scope of the Collection specified * Go through the ReportItems * Filter on ReportType and usagePage */ ptCollection = &ptPreparsedData->collections[iCollection]; for (iR=0; iR<ptCollection->reportItemCount; iR++) { iReportItem = ptCollection->firstReportItem + iR; ptReportItem = &ptPreparsedData->reportItems[iReportItem]; if ((ptReportItem->reportType == reportType) && HIDIsVariable(ptReportItem, preparsedDataRef) && HIDHasUsage(preparsedDataRef,ptReportItem,usagePage,usage,&iUsageIndex,NULL)) { /* * This may be the proper place to write data * Let's check for the proper Report ID, Type, and Length */ iStatus = HIDCheckReport(reportType,preparsedDataRef,ptReportItem,psReport,iReportLength); /* * The Report ID or Type may not match. * This may not be an error (yet) */ if (iStatus == kHIDIncompatibleReportErr) bIncompatibleReport = true; else if (iStatus != kHIDSuccess) return iStatus; else { iStatus = HIDScaleUsageValueOut(ptReportItem,iUsageValue,&data); if (iStatus != kHIDSuccess) return iStatus; iStart = ptReportItem->startBit + (int)(ptReportItem->globals.reportSize * iUsageIndex); HIDPreProcessRIValue (ptReportItem, &data); // error ignored iStatus = HIDPutData(psReport, iReportLength, iStart, (int)ptReportItem->globals.reportSize, data); if (iStatus != kHIDSuccess) return iStatus; return kHIDSuccess; } } } if (bIncompatibleReport) return kHIDIncompatibleReportErr; return kHIDUsageNotFoundErr; }