HIDGetButtonCaps.c [plain text]
#include "HIDLib.h"
OSStatus HIDGetSpecificButtonCaps(HIDReportType reportType,
HIDUsage usagePage,
UInt32 iCollection,
HIDUsage usage,
HIDButtonCapsPtr buttonCaps,
UInt32 *piButtonCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
HIDCollection *ptCollection;
HIDCollection *ptParent;
HIDReportItem *ptReportItem;
HIDP_UsageItem *ptUsageItem;
HIDStringItem *ptStringItem;
HIDDesignatorItem *ptDesignatorItem;
HIDP_UsageItem *ptFirstCollectionUsageItem;
HIDButtonCaps *ptCapability;
int iR, iU;
int parent;
int iReportItem, iUsageItem;
int iMaxCaps;
UInt32 startBit;
if ((buttonCaps == NULL)
|| (piButtonCapsLength == NULL)
|| (ptPreparsedData == NULL))
return kHIDNullPointerErr;
if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
return kHIDInvalidPreparsedDataErr;
iMaxCaps = *piButtonCapsLength;
*piButtonCapsLength = 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)
&& HIDIsButton(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 (*piButtonCapsLength >= (UInt32)iMaxCaps)
return kHIDBufferTooSmallErr;
ptCapability = &buttonCaps[(*piButtonCapsLength)++];
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->isStringRange = false; ptCapability->isDesignatorRange = false; 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->startBit = startBit;
}
if ((ptReportItem->dataModes & kHIDDataVariableBit) == kHIDDataVariable)
{
startBit += ptReportItem->globals.reportSize;
}
}
}
}
return kHIDSuccess;
}
OSStatus HIDGetButtonCaps(HIDReportType reportType,
HIDButtonCapsPtr buttonCaps,
UInt32 *piButtonCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
return HIDGetSpecificButtonCaps(reportType,0,0,0,buttonCaps,
piButtonCapsLength,preparsedDataRef);
}
OSStatus HIDGetSpecificButtonCapabilities(HIDReportType reportType,
HIDUsage usagePage,
UInt32 iCollection,
HIDUsage usage,
HIDButtonCapabilitiesPtr buttonCaps,
UInt32 *piButtonCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
HIDPreparsedDataPtr ptPreparsedData = (HIDPreparsedDataPtr) preparsedDataRef;
HIDCollection *ptCollection;
HIDCollection *ptParent;
HIDReportItem *ptReportItem;
HIDP_UsageItem *ptUsageItem;
HIDStringItem *ptStringItem;
HIDDesignatorItem *ptDesignatorItem;
HIDP_UsageItem *ptFirstCollectionUsageItem;
HIDButtonCapabilities *ptCapability;
int iR, iU;
int parent;
int iReportItem, iUsageItem;
int iMaxCaps;
UInt32 startBit;
if ((buttonCaps == NULL)
|| (piButtonCapsLength == NULL)
|| (ptPreparsedData == NULL))
return kHIDNullPointerErr;
if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
return kHIDInvalidPreparsedDataErr;
iMaxCaps = *piButtonCapsLength;
*piButtonCapsLength = 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)
&& HIDIsButton(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 (*piButtonCapsLength >= (UInt32)iMaxCaps)
return kHIDBufferTooSmallErr;
ptCapability = &buttonCaps[(*piButtonCapsLength)++];
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;
if ((ptReportItem->dataModes & kHIDDataArrayBit) == kHIDDataArray)
{
ptCapability->unitExponent = (SInt32)ptReportItem->globals.reportSize;
ptCapability->units = ptReportItem->globals.reportCount;
if (ptReportItem->flags & kHIDReportItemFlag_Reversed)
{
ptCapability->u.notRange.reserved2 = ptReportItem->globals.logicalMaximum;
ptCapability->u.notRange.reserved3 = ptReportItem->globals.logicalMinimum;
}
else
{
ptCapability->u.notRange.reserved2 = ptReportItem->globals.logicalMinimum;
ptCapability->u.notRange.reserved3 = ptReportItem->globals.logicalMaximum;
}
}
else
{
ptCapability->unitExponent = ptReportItem->globals.unitExponent;
ptCapability->units = ptReportItem->globals.units;
}
ptCapability->startBit = 0; ptCapability->pbVersion = 2;
ptCapability->isStringRange = false; ptCapability->isDesignatorRange = false; 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->startBit = startBit;
}
if ((ptReportItem->dataModes & kHIDDataVariableBit) == kHIDDataVariable)
{
startBit += ptReportItem->globals.reportSize;
}
}
}
}
return kHIDSuccess;
}
OSStatus HIDGetButtonCapabilities(HIDReportType reportType,
HIDButtonCapabilitiesPtr buttonCaps,
UInt32 *piButtonCapsLength,
HIDPreparsedDataRef preparsedDataRef)
{
return HIDGetSpecificButtonCapabilities(reportType,0,0,0,buttonCaps,
piButtonCapsLength,preparsedDataRef);
}