#include "HIDLib.h"
OSStatus HIDGetSpecificValueCaps(HIDReportType reportType,
HIDUsage usagePage,
UInt32 iCollection,
HIDUsage usage,
HIDValueCapsPtr valueCaps,
UInt32 *piValueCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
HIDCollection *ptCollection;
HIDCollection *ptParent;
HIDReportItem *ptReportItem;
HIDP_UsageItem *ptUsageItem;
HIDStringItem *ptStringItem;
HIDDesignatorItem *ptDesignatorItem;
HIDP_UsageItem *ptFirstCollectionUsageItem;
HIDValueCaps *ptCapability;
int iR, iU;
int parent;
int iReportItem, iUsageItem;
int iMaxCaps;
UInt32 iCount;
UInt32 startBit;
if ((valueCaps == NULL)
|| (piValueCapsLength == NULL)
|| (ptPreparsedData == NULL))
return kHIDNullPointerErr;
if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
return kHIDInvalidPreparsedDataErr;
iMaxCaps = *piValueCapsLength;
*piValueCapsLength = 0;
if (iCollection >= ptPreparsedData->collectionCount)
return kHIDBadParameterErr;
ptCollection = &ptPreparsedData->collections[iCollection];
for (iR=0; iR<ptCollection->reportItemCount; iR++)
{
iReportItem = ptCollection->firstReportItem + iR;
ptReportItem = &ptPreparsedData->reportItems[iReportItem];
if ((ptReportItem->reportType == reportType)
&& ((ptReportItem->globals.usagePage == usagePage)
|| (usagePage == 0))
&& HIDIsVariable(ptReportItem, preparsedDataRef))
{
startBit = ptReportItem->startBit;
for (iU=0; iU<ptReportItem->usageItemCount; iU++)
{
iUsageItem = ptReportItem->firstUsageItem + iU;
ptUsageItem = &ptPreparsedData->usageItems[iUsageItem];
ptStringItem = &ptPreparsedData->stringItems[ptReportItem->firstStringItem + iU];
ptDesignatorItem = &ptPreparsedData->desigItems[ptReportItem->firstDesigItem + iU];
if (HIDUsageInRange(ptUsageItem,usagePage,usage))
{
if (*piValueCapsLength >= (UInt32)iMaxCaps)
return kHIDBufferTooSmallErr;
ptCapability = &valueCaps[(*piValueCapsLength)++];
parent = ptReportItem->parent;
ptParent = &ptPreparsedData->collections[parent];
ptFirstCollectionUsageItem = &ptPreparsedData->usageItems[ptParent->firstUsageItem];
ptCapability->collection = parent;
ptCapability->collectionUsagePage = ptParent->usagePage;
ptCapability->collectionUsage = ptFirstCollectionUsageItem->usage;
ptCapability->bitField = ptReportItem->dataModes;
ptCapability->reportID = ptReportItem->globals.reportID;
ptCapability->usagePage = ptUsageItem->usagePage;
ptCapability->isAbsolute = !(ptReportItem->dataModes & kHIDDataRelative);
ptCapability->isRange = ptUsageItem->isRange;
if (ptUsageItem->isRange)
{
ptCapability->u.range.usageMin = ptUsageItem->usageMinimum;
ptCapability->u.range.usageMax = ptUsageItem->usageMaximum;
}
else
ptCapability->u.notRange.usage = ptUsageItem->usage;
if (iU < ptReportItem->stringItemCount)
{
ptCapability->isStringRange = ptStringItem->isRange;
if (ptStringItem->isRange)
{
ptCapability->u.range.stringMin = ptStringItem->minimum;
ptCapability->u.range.stringMax = ptStringItem->maximum;
}
else
ptCapability->u.notRange.stringIndex = ptStringItem->index;
}
else
{
ptCapability->isStringRange = false;
ptCapability->u.notRange.stringIndex = 0;
}
if (iU < ptReportItem->desigItemCount)
{
ptCapability->isDesignatorRange = ptDesignatorItem->isRange;
if (ptDesignatorItem->isRange)
{
ptCapability->u.range.designatorMin = ptDesignatorItem->minimum;
ptCapability->u.range.designatorMax = ptDesignatorItem->maximum;
}
else
ptCapability->u.notRange.designatorIndex = ptDesignatorItem->index;
}
else
{
ptCapability->isDesignatorRange = false;
ptCapability->u.notRange.designatorIndex = 0;
}
ptCapability->bitSize = (UInt32)ptReportItem->globals.reportSize;
ptCapability->logicalMin = ptReportItem->globals.logicalMinimum;
ptCapability->logicalMax = ptReportItem->globals.logicalMaximum;
ptCapability->physicalMin = ptReportItem->globals.physicalMinimum;
ptCapability->physicalMax = ptReportItem->globals.physicalMaximum;
if (ptUsageItem->isRange)
{
iCount = ptUsageItem->usageMaximum - ptUsageItem->usageMinimum;
iCount++; }
else
HIDHasUsage(preparsedDataRef,ptReportItem,
ptUsageItem->usagePage,ptUsageItem->usage,
NULL,&iCount);
ptCapability->reportCount = iCount;
ptCapability->startBit = startBit;
startBit += (ptCapability->bitSize * ptCapability->reportCount);
}
}
}
}
return kHIDSuccess;
}
OSStatus HIDGetValueCaps(HIDReportType reportType,
HIDValueCapsPtr valueCaps,
UInt32 *piValueCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
return HIDGetSpecificValueCaps(reportType,0,0,0,valueCaps,
piValueCapsLength,preparsedDataRef);
}
OSStatus HIDGetSpecificValueCapabilities(HIDReportType reportType,
HIDUsage usagePage,
UInt32 iCollection,
HIDUsage usage,
HIDValueCapabilitiesPtr valueCaps,
UInt32 *piValueCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
HIDCollection *ptCollection;
HIDCollection *ptParent;
HIDReportItem *ptReportItem;
HIDP_UsageItem *ptUsageItem;
HIDStringItem *ptStringItem;
HIDDesignatorItem *ptDesignatorItem;
HIDP_UsageItem *ptFirstCollectionUsageItem;
HIDValueCapabilities *ptCapability;
int iR, iU;
int parent;
int iReportItem, iUsageItem;
int iMaxCaps;
UInt32 iCount;
UInt32 startBit;
if ((valueCaps == NULL)
|| (piValueCapsLength == NULL)
|| (ptPreparsedData == NULL))
return kHIDNullPointerErr;
if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
return kHIDInvalidPreparsedDataErr;
iMaxCaps = *piValueCapsLength;
*piValueCapsLength = 0;
if (iCollection >= ptPreparsedData->collectionCount)
return kHIDBadParameterErr;
ptCollection = &ptPreparsedData->collections[iCollection];
for (iR=0; iR<ptCollection->reportItemCount; iR++)
{
iReportItem = ptCollection->firstReportItem + iR;
ptReportItem = &ptPreparsedData->reportItems[iReportItem];
if ((ptReportItem->reportType == reportType)
&& ((ptReportItem->globals.usagePage == usagePage)
|| (usagePage == 0))
&& HIDIsVariable(ptReportItem, preparsedDataRef))
{
startBit = ptReportItem->startBit;
for (iU=0; iU<ptReportItem->usageItemCount; iU++)
{
iUsageItem = ptReportItem->firstUsageItem + iU;
ptUsageItem = &ptPreparsedData->usageItems[iUsageItem];
ptStringItem = &ptPreparsedData->stringItems[ptReportItem->firstStringItem + iU];
ptDesignatorItem = &ptPreparsedData->desigItems[ptReportItem->firstDesigItem + iU];
if (HIDUsageInRange(ptUsageItem,usagePage,usage))
{
if (*piValueCapsLength >= (UInt32)iMaxCaps)
return kHIDBufferTooSmallErr;
ptCapability = &valueCaps[(*piValueCapsLength)++];
parent = ptReportItem->parent;
ptParent = &ptPreparsedData->collections[parent];
ptFirstCollectionUsageItem = &ptPreparsedData->usageItems[ptParent->firstUsageItem];
ptCapability->collection = parent;
ptCapability->collectionUsagePage = ptParent->usagePage;
ptCapability->collectionUsage = ptFirstCollectionUsageItem->usage;
ptCapability->bitField = ptReportItem->dataModes;
ptCapability->reportID = ptReportItem->globals.reportID;
ptCapability->usagePage = ptUsageItem->usagePage;
ptCapability->unitExponent = ptReportItem->globals.unitExponent;
ptCapability->units = ptReportItem->globals.units;
ptCapability->startBit = 0; ptCapability->pbVersion = 2;
ptCapability->isAbsolute = !(ptReportItem->dataModes & kHIDDataRelative);
ptCapability->isRange = ptUsageItem->isRange;
if (ptUsageItem->isRange)
{
ptCapability->u.range.usageMin = ptUsageItem->usageMinimum;
ptCapability->u.range.usageMax = ptUsageItem->usageMaximum;
}
else
ptCapability->u.notRange.usage = ptUsageItem->usage;
if (iU < ptReportItem->stringItemCount)
{
ptCapability->isStringRange = ptStringItem->isRange;
if (ptStringItem->isRange)
{
ptCapability->u.range.stringMin = ptStringItem->minimum;
ptCapability->u.range.stringMax = ptStringItem->maximum;
}
else
ptCapability->u.notRange.stringIndex = ptStringItem->index;
}
else
{
ptCapability->isStringRange = false;
ptCapability->u.notRange.stringIndex = 0;
}
if (iU < ptReportItem->desigItemCount)
{
ptCapability->isDesignatorRange = ptDesignatorItem->isRange;
if (ptDesignatorItem->isRange)
{
ptCapability->u.range.designatorMin = ptDesignatorItem->minimum;
ptCapability->u.range.designatorMax = ptDesignatorItem->maximum;
}
else
ptCapability->u.notRange.designatorIndex = ptDesignatorItem->index;
}
else
{
ptCapability->isDesignatorRange = false;
ptCapability->u.notRange.designatorIndex = 0;
}
ptCapability->bitSize = (UInt32)ptReportItem->globals.reportSize;
ptCapability->logicalMin = ptReportItem->globals.logicalMinimum;
ptCapability->logicalMax = ptReportItem->globals.logicalMaximum;
ptCapability->physicalMin = ptReportItem->globals.physicalMinimum;
ptCapability->physicalMax = ptReportItem->globals.physicalMaximum;
if (ptUsageItem->isRange)
{
iCount = ptUsageItem->usageMaximum - ptUsageItem->usageMinimum;
iCount++; }
else
HIDHasUsage(preparsedDataRef,ptReportItem,
ptUsageItem->usagePage,ptUsageItem->usage,
NULL,&iCount);
ptCapability->reportCount = iCount;
ptCapability->startBit = startBit; startBit += (ptCapability->bitSize * ptCapability->reportCount);
}
}
}
}
return kHIDSuccess;
}
OSStatus HIDGetValueCapabilities(HIDReportType reportType,
HIDValueCapabilitiesPtr valueCaps,
UInt32 *piValueCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
return HIDGetSpecificValueCapabilities(reportType,0,0,0,valueCaps,
piValueCapsLength,preparsedDataRef);
}