* Integrate reports/items some more.
* Reorganize how items are added to collections. * Make collections useful for enumeration through that. * Added printing out of collections, reports and report items for easier verification of report parsing. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30821 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -5,9 +5,11 @@
|
|||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "HIDCollection.h"
|
#include "HIDCollection.h"
|
||||||
|
#include "HIDReportItem.h"
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
HIDCollection::HIDCollection(HIDCollection *parent, uint8 type,
|
HIDCollection::HIDCollection(HIDCollection *parent, uint8 type,
|
||||||
@@ -17,7 +19,10 @@ HIDCollection::HIDCollection(HIDCollection *parent, uint8 type,
|
|||||||
fStringID(localState.string_index),
|
fStringID(localState.string_index),
|
||||||
fPhysicalID(localState.designator_index),
|
fPhysicalID(localState.designator_index),
|
||||||
fChildCount(0),
|
fChildCount(0),
|
||||||
fChildren(NULL)
|
fChildren(NULL),
|
||||||
|
fItemCount(0),
|
||||||
|
fItemsAllocated(0),
|
||||||
|
fItems(NULL)
|
||||||
{
|
{
|
||||||
usage_value usageValue;
|
usage_value usageValue;
|
||||||
usageValue.u.s.usage_page = globalState.usage_page;
|
usageValue.u.s.usage_page = globalState.usage_page;
|
||||||
@@ -42,6 +47,7 @@ HIDCollection::~HIDCollection()
|
|||||||
for (uint32 i = 0; i < fChildCount; i++)
|
for (uint32 i = 0; i < fChildCount; i++)
|
||||||
delete fChildren[i];
|
delete fChildren[i];
|
||||||
free(fChildren);
|
free(fChildren);
|
||||||
|
free(fItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,8 +78,84 @@ HIDCollection::ChildAt(uint32 index)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HIDCollection::AddMainItem(global_item_state &globalState,
|
HIDCollection::AddItem(HIDReportItem *item)
|
||||||
local_item_state &localState, main_item_data &mainData)
|
|
||||||
{
|
{
|
||||||
// TODO: implement
|
if (fItemCount >= fItemsAllocated) {
|
||||||
|
fItemsAllocated += 10;
|
||||||
|
HIDReportItem **newItems = (HIDReportItem **)realloc(fItems,
|
||||||
|
fItemsAllocated * sizeof(HIDReportItem *));
|
||||||
|
if (newItems == NULL) {
|
||||||
|
TRACE_ALWAYS("no memory when trying to resize collection items\n");
|
||||||
|
fItemsAllocated -= 10;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fItems = newItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
fItems[fItemCount++] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HIDReportItem *
|
||||||
|
HIDCollection::ItemAt(uint32 index)
|
||||||
|
{
|
||||||
|
if (index >= fItemCount)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return fItems[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HIDCollection::PrintToStream(uint32 indentLevel)
|
||||||
|
{
|
||||||
|
char indent[indentLevel + 1];
|
||||||
|
memset(indent, '\t', indentLevel);
|
||||||
|
indent[indentLevel] = 0;
|
||||||
|
|
||||||
|
const char *typeName = "unknown";
|
||||||
|
switch (fType) {
|
||||||
|
case COLLECTION_PHYSICAL:
|
||||||
|
typeName = "physical";
|
||||||
|
break;
|
||||||
|
case COLLECTION_APPLICATION:
|
||||||
|
typeName = "application";
|
||||||
|
break;
|
||||||
|
case COLLECTION_LOGICAL:
|
||||||
|
typeName = "logical";
|
||||||
|
break;
|
||||||
|
case COLLECTION_REPORT:
|
||||||
|
typeName = "report";
|
||||||
|
break;
|
||||||
|
case COLLECTION_NAMED_ARRAY:
|
||||||
|
typeName = "named array";
|
||||||
|
break;
|
||||||
|
case COLLECTION_USAGE_SWITCH:
|
||||||
|
typeName = "usage switch";
|
||||||
|
break;
|
||||||
|
case COLLECTION_USAGE_MODIFIER:
|
||||||
|
typeName = "usage modifier";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_ALWAYS("%sHIDCollection %p\n", indent, this);
|
||||||
|
TRACE_ALWAYS("%s\ttype: %u %s\n", indent, fType, typeName);
|
||||||
|
TRACE_ALWAYS("%s\tusage: 0x%08lx\n", indent, fUsage);
|
||||||
|
TRACE_ALWAYS("%s\tstring id: %u\n", indent, fStringID);
|
||||||
|
TRACE_ALWAYS("%s\tphysical id: %u\n", indent, fPhysicalID);
|
||||||
|
|
||||||
|
TRACE_ALWAYS("%s\titem count: %lu\n", indent, fItemCount);
|
||||||
|
for (uint32 i = 0; i < fItemCount; i++) {
|
||||||
|
HIDReportItem *item = fItems[i];
|
||||||
|
if (item != NULL)
|
||||||
|
item->PrintToStream(indentLevel + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_ALWAYS("%s\tchild count: %lu\n", indent, fChildCount);
|
||||||
|
for (uint32 i = 0; i < fChildCount; i++) {
|
||||||
|
HIDCollection *child = fChildren[i];
|
||||||
|
if (child != NULL)
|
||||||
|
child->PrintToStream(indentLevel + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "HIDParser.h"
|
#include "HIDParser.h"
|
||||||
|
|
||||||
|
class HIDReportItem;
|
||||||
|
|
||||||
class HIDCollection {
|
class HIDCollection {
|
||||||
public:
|
public:
|
||||||
HIDCollection(HIDCollection *parent,
|
HIDCollection(HIDCollection *parent,
|
||||||
@@ -20,9 +22,11 @@ public:
|
|||||||
uint32 CountChildren() { return fChildCount; };
|
uint32 CountChildren() { return fChildCount; };
|
||||||
HIDCollection * ChildAt(uint32 index);
|
HIDCollection * ChildAt(uint32 index);
|
||||||
|
|
||||||
void AddMainItem(global_item_state &globalState,
|
void AddItem(HIDReportItem *item);
|
||||||
local_item_state &localState,
|
uint32 CountItems() { return fItemCount; };
|
||||||
main_item_data &mainData);
|
HIDReportItem * ItemAt(uint32 index);
|
||||||
|
|
||||||
|
void PrintToStream(uint32 indentLevel = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HIDCollection * fParent;
|
HIDCollection * fParent;
|
||||||
@@ -34,6 +38,10 @@ private:
|
|||||||
|
|
||||||
uint32 fChildCount;
|
uint32 fChildCount;
|
||||||
HIDCollection ** fChildren;
|
HIDCollection ** fChildren;
|
||||||
|
|
||||||
|
uint32 fItemCount;
|
||||||
|
uint32 fItemsAllocated;
|
||||||
|
HIDReportItem ** fItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HID_COLLECTION_H
|
#endif // HID_COLLECTION_H
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ typedef struct usage_value {
|
|||||||
} u;
|
} u;
|
||||||
|
|
||||||
bool is_extended;
|
bool is_extended;
|
||||||
|
|
||||||
|
usage_value()
|
||||||
|
{
|
||||||
|
u.extended = 0;
|
||||||
|
is_extended = false;
|
||||||
|
}
|
||||||
} usage_value;
|
} usage_value;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ static int8 sUnitExponent[16] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HIDParser::HIDParser()
|
HIDParser::HIDParser(HIDDevice *device)
|
||||||
: fReportCount(0),
|
: fDevice(device),
|
||||||
|
fReportCount(0),
|
||||||
fReports(NULL),
|
fReports(NULL),
|
||||||
fRootCollection(NULL)
|
fRootCollection(NULL)
|
||||||
{
|
{
|
||||||
@@ -35,7 +36,7 @@ HIDParser::~HIDParser()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
HIDParser::ParseReportDescriptor(uint8 *reportDescriptor,
|
HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
|
||||||
size_t descriptorLength)
|
size_t descriptorLength)
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
@@ -56,11 +57,11 @@ HIDParser::ParseReportDescriptor(uint8 *reportDescriptor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
HIDCollection *collection = NULL;
|
HIDCollection *collection = NULL;
|
||||||
uint8 *pointer = reportDescriptor;
|
const uint8 *pointer = reportDescriptor;
|
||||||
uint8 *end = pointer + descriptorLength;
|
const uint8 *end = pointer + descriptorLength;
|
||||||
|
|
||||||
while (pointer < end) {
|
while (pointer < end) {
|
||||||
item_prefix *item = (item_prefix *)pointer;
|
const item_prefix *item = (item_prefix *)pointer;
|
||||||
size_t itemSize = sItemSize[item->size];
|
size_t itemSize = sItemSize[item->size];
|
||||||
uint32 data = 0;
|
uint32 data = 0;
|
||||||
|
|
||||||
@@ -179,12 +180,8 @@ HIDParser::ParseReportDescriptor(uint8 *reportDescriptor,
|
|||||||
if (!localState.string_index_set)
|
if (!localState.string_index_set)
|
||||||
localState.string_index = localState.string_minimum;
|
localState.string_index = localState.string_minimum;
|
||||||
|
|
||||||
target->AddMainItem(globalState, localState, *mainData);
|
target->AddMainItem(globalState, localState, *mainData,
|
||||||
if (collection != NULL) {
|
collection);
|
||||||
collection->AddMainItem(globalState, localState,
|
|
||||||
*mainData);
|
|
||||||
} else
|
|
||||||
TRACE_ALWAYS("main item not part of a collection\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the local item state
|
// reset the local item state
|
||||||
@@ -428,9 +425,40 @@ HIDParser::ReportAt(uint8 type, uint8 index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
size_t
|
||||||
HIDParser::SetReport(uint8 *report, size_t length)
|
HIDParser::MaxReportSize()
|
||||||
{
|
{
|
||||||
|
size_t maxSize = 0;
|
||||||
|
for (uint32 i = 0; i < fReportCount; i++) {
|
||||||
|
HIDReport *report = fReports[i];
|
||||||
|
if (report == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (report->ReportSize() > maxSize)
|
||||||
|
maxSize = report->ReportSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HIDParser::SetReport(status_t status, uint8 *report, size_t length)
|
||||||
|
{
|
||||||
|
if (status != B_OK) {
|
||||||
|
// in case of error we need to notify all input reports, as we don't
|
||||||
|
// know who has waiting listeners.
|
||||||
|
for (uint32 i = 0; i < fReportCount; i++) {
|
||||||
|
if (fReports[i] == NULL
|
||||||
|
|| fReports[i]->Type() != HID_REPORT_TYPE_INPUT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fReports[i]->SetReport(status, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HIDReport *target = fReports[0];
|
HIDReport *target = fReports[0];
|
||||||
if (fUsesReportIDs) {
|
if (fUsesReportIDs) {
|
||||||
target = FindReport(HID_REPORT_TYPE_INPUT, report[0]);
|
target = FindReport(HID_REPORT_TYPE_INPUT, report[0]);
|
||||||
@@ -440,10 +468,10 @@ HIDParser::SetReport(uint8 *report, size_t length)
|
|||||||
|
|
||||||
if (target == NULL) {
|
if (target == NULL) {
|
||||||
TRACE_ALWAYS("got report buffer but found no report to handle it\n");
|
TRACE_ALWAYS("got report buffer but found no report to handle it\n");
|
||||||
return B_ENTRY_NOT_FOUND;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return target->SetReport(report, length);
|
target->SetReport(status, report, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,19 @@
|
|||||||
|
|
||||||
#include "HIDDataTypes.h"
|
#include "HIDDataTypes.h"
|
||||||
|
|
||||||
class HIDReport;
|
|
||||||
class HIDCollection;
|
class HIDCollection;
|
||||||
|
class HIDDevice;
|
||||||
|
class HIDReport;
|
||||||
|
|
||||||
class HIDParser {
|
class HIDParser {
|
||||||
public:
|
public:
|
||||||
HIDParser();
|
HIDParser(HIDDevice *device);
|
||||||
~HIDParser();
|
~HIDParser();
|
||||||
|
|
||||||
status_t ParseReportDescriptor(uint8 *reportDescriptor,
|
HIDDevice * Device() { return fDevice; };
|
||||||
|
|
||||||
|
status_t ParseReportDescriptor(
|
||||||
|
const uint8 *reportDescriptor,
|
||||||
size_t descriptorLength);
|
size_t descriptorLength);
|
||||||
|
|
||||||
bool UsesReportIDs() { return fUsesReportIDs; };
|
bool UsesReportIDs() { return fUsesReportIDs; };
|
||||||
@@ -23,16 +27,19 @@ public:
|
|||||||
HIDReport * FindReport(uint8 type, uint8 id);
|
HIDReport * FindReport(uint8 type, uint8 id);
|
||||||
uint8 CountReports(uint8 type);
|
uint8 CountReports(uint8 type);
|
||||||
HIDReport * ReportAt(uint8 type, uint8 index);
|
HIDReport * ReportAt(uint8 type, uint8 index);
|
||||||
|
size_t MaxReportSize();
|
||||||
|
|
||||||
HIDCollection * RootCollection() { return fRootCollection; };
|
HIDCollection * RootCollection() { return fRootCollection; };
|
||||||
|
|
||||||
status_t SetReport(uint8 *report, size_t length);
|
void SetReport(status_t status, uint8 *report,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HIDReport * _FindOrCreateReport(uint8 type, uint8 id);
|
HIDReport * _FindOrCreateReport(uint8 type, uint8 id);
|
||||||
float _CalculateResolution(global_item_state *state);
|
float _CalculateResolution(global_item_state *state);
|
||||||
void _Reset();
|
void _Reset();
|
||||||
|
|
||||||
|
HIDDevice * fDevice;
|
||||||
bool fUsesReportIDs;
|
bool fUsesReportIDs;
|
||||||
uint8 fReportCount;
|
uint8 fReportCount;
|
||||||
HIDReport ** fReports;
|
HIDReport ** fReports;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
|
#include "HIDCollection.h"
|
||||||
|
#include "HIDDevice.h"
|
||||||
#include "HIDReport.h"
|
#include "HIDReport.h"
|
||||||
#include "HIDReportItem.h"
|
#include "HIDReportItem.h"
|
||||||
|
|
||||||
@@ -19,6 +21,7 @@ HIDReport::HIDReport(HIDParser *parser, uint8 type, uint8 id)
|
|||||||
fItemsUsed(0),
|
fItemsUsed(0),
|
||||||
fItemsAllocated(0),
|
fItemsAllocated(0),
|
||||||
fItems(NULL),
|
fItems(NULL),
|
||||||
|
fReportStatus(B_NO_INIT),
|
||||||
fCurrentReport(NULL),
|
fCurrentReport(NULL),
|
||||||
fBusyCount(0)
|
fBusyCount(0)
|
||||||
{
|
{
|
||||||
@@ -34,7 +37,8 @@ HIDReport::~HIDReport()
|
|||||||
|
|
||||||
void
|
void
|
||||||
HIDReport::AddMainItem(global_item_state &globalState,
|
HIDReport::AddMainItem(global_item_state &globalState,
|
||||||
local_item_state &localState, main_item_data &mainData)
|
local_item_state &localState, main_item_data &mainData,
|
||||||
|
HIDCollection *collection)
|
||||||
{
|
{
|
||||||
TRACE("adding main item to report of type 0x%02x with id 0x%02x\n",
|
TRACE("adding main item to report of type 0x%02x with id 0x%02x\n",
|
||||||
fType, fReportID);
|
fType, fReportID);
|
||||||
@@ -121,31 +125,36 @@ HIDReport::AddMainItem(global_item_state &globalState,
|
|||||||
usageMinimum = usageMaximum = usage.u.extended;
|
usageMinimum = usageMaximum = usage.u.extended;
|
||||||
}
|
}
|
||||||
|
|
||||||
fItems[fItemsUsed++] = new(std::nothrow) HIDReportItem(this,
|
fItems[fItemsUsed] = new(std::nothrow) HIDReportItem(this,
|
||||||
fReportSize, globalState.report_size, mainData.data_constant == 0,
|
fReportSize, globalState.report_size, mainData.data_constant == 0,
|
||||||
mainData.array_variable == 0, mainData.relative != 0,
|
mainData.array_variable == 0, mainData.relative != 0,
|
||||||
logicalMinimum, logicalMaximum, usageMinimum, usageMaximum);
|
logicalMinimum, logicalMaximum, usageMinimum, usageMaximum);
|
||||||
|
if (fItems[fItemsUsed] == NULL)
|
||||||
|
TRACE_ALWAYS("no memory when creating report item\n");
|
||||||
|
|
||||||
|
if (collection != NULL)
|
||||||
|
collection->AddItem(fItems[fItemsUsed]);
|
||||||
|
else
|
||||||
|
TRACE_ALWAYS("main item not part of a collection\n");
|
||||||
|
|
||||||
|
fReportSize += globalState.report_size;
|
||||||
|
fItemsUsed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
HIDReport::SetReport(uint8 *report, size_t length)
|
HIDReport::SetReport(status_t status, uint8 *report, size_t length)
|
||||||
{
|
{
|
||||||
if (report == NULL) {
|
fReportStatus = status;
|
||||||
fCurrentReport = NULL;
|
fCurrentReport = report;
|
||||||
return B_OK;
|
if (status == B_OK && length * 8 < fReportSize) {
|
||||||
}
|
|
||||||
|
|
||||||
if (length * 8 < fReportSize) {
|
|
||||||
TRACE_ALWAYS("report of %lu bits too small, expected %lu bits\n",
|
TRACE_ALWAYS("report of %lu bits too small, expected %lu bits\n",
|
||||||
length * 8, fReportSize);
|
length * 8, fReportSize);
|
||||||
return B_ERROR;
|
fReportStatus = B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fConditionVariable.NotifyAll();
|
fConditionVariable.NotifyAll();
|
||||||
fCurrentReport = report;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -164,18 +173,24 @@ HIDReport::WaitForReport(bigtime_t timeout)
|
|||||||
while (atomic_or(&fBusyCount, 0) != 0)
|
while (atomic_or(&fBusyCount, 0) != 0)
|
||||||
snooze(1000);
|
snooze(1000);
|
||||||
|
|
||||||
|
#ifndef TEST_MODE
|
||||||
ConditionVariableEntry conditionVariableEntry;
|
ConditionVariableEntry conditionVariableEntry;
|
||||||
fConditionVariable.Add(&conditionVariableEntry);
|
fConditionVariable.Add(&conditionVariableEntry);
|
||||||
//status_t result = fParser->Device()->MaybeScheduleTransfer();
|
status_t result = fParser->Device()->MaybeScheduleTransfer();
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
conditionVariableEntry.Wait(B_RELATIVE_TIMEOUT, 0);
|
conditionVariableEntry.Wait(B_RELATIVE_TIMEOUT, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = conditionVariableEntry.Wait(B_RELATIVE_TIMEOUT, timeout);
|
result = conditionVariableEntry.Wait(B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT,
|
||||||
|
timeout);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
if (fReportStatus != B_OK)
|
||||||
|
return fReportStatus;
|
||||||
|
#endif
|
||||||
|
|
||||||
atomic_add(&fBusyCount, 1);
|
atomic_add(&fBusyCount, 1);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -188,6 +203,38 @@ HIDReport::DoneProcessing()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HIDReport::PrintToStream()
|
||||||
|
{
|
||||||
|
TRACE_ALWAYS("HIDReport %p\n", this);
|
||||||
|
|
||||||
|
const char *typeName = "unknown";
|
||||||
|
switch (fType) {
|
||||||
|
case HID_REPORT_TYPE_INPUT:
|
||||||
|
typeName = "input";
|
||||||
|
break;
|
||||||
|
case HID_REPORT_TYPE_OUTPUT:
|
||||||
|
typeName = "output";
|
||||||
|
break;
|
||||||
|
case HID_REPORT_TYPE_FEATURE:
|
||||||
|
typeName = "feature";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_ALWAYS("\ttype: %u %s\n", fType, typeName);
|
||||||
|
TRACE_ALWAYS("\treport id: %u\n", fReportID);
|
||||||
|
TRACE_ALWAYS("\treport size: %lu bits = %lu bytes\n", fReportSize,
|
||||||
|
(fReportSize + 7) / 8);
|
||||||
|
|
||||||
|
TRACE_ALWAYS("\titem count: %lu\n", fItemsUsed);
|
||||||
|
for (uint32 i = 0; i < fItemsUsed; i++) {
|
||||||
|
HIDReportItem *item = fItems[i];
|
||||||
|
if (item != NULL)
|
||||||
|
item->PrintToStream(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HIDReport::_SignExtend(uint32 &minimum, uint32 &maximum)
|
HIDReport::_SignExtend(uint32 &minimum, uint32 &maximum)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#define HID_REPORT_TYPE_FEATURE 0x04
|
#define HID_REPORT_TYPE_FEATURE 0x04
|
||||||
#define HID_REPORT_TYPE_ANY 0x07
|
#define HID_REPORT_TYPE_ANY 0x07
|
||||||
|
|
||||||
|
class HIDCollection;
|
||||||
class HIDReportItem;
|
class HIDReportItem;
|
||||||
|
|
||||||
class HIDReport {
|
class HIDReport {
|
||||||
@@ -24,12 +25,18 @@ public:
|
|||||||
|
|
||||||
uint8 Type() { return fType; };
|
uint8 Type() { return fType; };
|
||||||
uint8 ID() { return fReportID; };
|
uint8 ID() { return fReportID; };
|
||||||
|
size_t ReportSize() { return (fReportSize + 7) / 8; };
|
||||||
|
|
||||||
|
HIDParser * Parser() { return fParser; };
|
||||||
|
HIDDevice * Device() { return fParser->Device(); };
|
||||||
|
|
||||||
void AddMainItem(global_item_state &globalState,
|
void AddMainItem(global_item_state &globalState,
|
||||||
local_item_state &localState,
|
local_item_state &localState,
|
||||||
main_item_data &mainData);
|
main_item_data &mainData,
|
||||||
|
HIDCollection *collection);
|
||||||
|
|
||||||
status_t SetReport(uint8 *report, size_t length);
|
void SetReport(status_t status, uint8 *report,
|
||||||
|
size_t length);
|
||||||
uint8 * CurrentReport() { return fCurrentReport; };
|
uint8 * CurrentReport() { return fCurrentReport; };
|
||||||
|
|
||||||
uint32 CountItems() { return fItemsUsed; };
|
uint32 CountItems() { return fItemsUsed; };
|
||||||
@@ -38,6 +45,8 @@ public:
|
|||||||
status_t WaitForReport(bigtime_t timeout);
|
status_t WaitForReport(bigtime_t timeout);
|
||||||
void DoneProcessing();
|
void DoneProcessing();
|
||||||
|
|
||||||
|
void PrintToStream();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _SignExtend(uint32 &minimum, uint32 &maximum);
|
void _SignExtend(uint32 &minimum, uint32 &maximum);
|
||||||
|
|
||||||
@@ -51,6 +60,7 @@ private:
|
|||||||
uint32 fItemsAllocated;
|
uint32 fItemsAllocated;
|
||||||
HIDReportItem ** fItems;
|
HIDReportItem ** fItems;
|
||||||
|
|
||||||
|
status_t fReportStatus;
|
||||||
uint8 * fCurrentReport;
|
uint8 * fCurrentReport;
|
||||||
int32 fBusyCount;
|
int32 fBusyCount;
|
||||||
ConditionVariable fConditionVariable;
|
ConditionVariable fConditionVariable;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Driver.h"
|
||||||
|
|
||||||
#include "HIDReportItem.h"
|
#include "HIDReportItem.h"
|
||||||
#include "HIDReport.h"
|
#include "HIDReport.h"
|
||||||
|
|
||||||
@@ -28,6 +30,15 @@ HIDReportItem::HIDReportItem(HIDReport *report, uint32 bitOffset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16
|
||||||
|
HIDReportItem::UsagePage()
|
||||||
|
{
|
||||||
|
usage_value value;
|
||||||
|
value.u.extended = fUsageMinimum;
|
||||||
|
return value.u.s.usage_page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
HIDReportItem::Extract()
|
HIDReportItem::Extract()
|
||||||
{
|
{
|
||||||
@@ -54,3 +65,24 @@ HIDReportItem::Extract()
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
HIDReportItem::PrintToStream(uint32 indentLevel)
|
||||||
|
{
|
||||||
|
char indent[indentLevel + 1];
|
||||||
|
memset(indent, '\t', indentLevel);
|
||||||
|
indent[indentLevel] = 0;
|
||||||
|
|
||||||
|
TRACE_ALWAYS("%sHIDReportItem %p\n", indent, this);
|
||||||
|
TRACE_ALWAYS("%s\tbyte offset: %lu\n", indent, fByteOffset);
|
||||||
|
TRACE_ALWAYS("%s\tshift: %u\n", indent, fShift);
|
||||||
|
TRACE_ALWAYS("%s\tmask: 0x%08lx\n", indent, fMask);
|
||||||
|
TRACE_ALWAYS("%s\thas data: %s\n", indent, fHasData ? "yes" : "no");
|
||||||
|
TRACE_ALWAYS("%s\tarray: %s\n", indent, fArray ? "yes" : "no");
|
||||||
|
TRACE_ALWAYS("%s\trelative: %s\n", indent, fRelative ? "yes" : "no");
|
||||||
|
TRACE_ALWAYS("%s\tminimum: %lu\n", indent, fMinimum);
|
||||||
|
TRACE_ALWAYS("%s\tmaximum: %lu\n", indent, fMaximum);
|
||||||
|
TRACE_ALWAYS("%s\tusage minimum: 0x%08lx\n", indent, fUsageMinimum);
|
||||||
|
TRACE_ALWAYS("%s\tusage maximum: 0x%08lx\n", indent, fUsageMaximum);
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
bool Array() { return fArray; };
|
bool Array() { return fArray; };
|
||||||
bool Signed() { return fMinimum > fMaximum; };
|
bool Signed() { return fMinimum > fMaximum; };
|
||||||
|
|
||||||
|
uint16 UsagePage();
|
||||||
uint32 UsageMinimum() { return fUsageMinimum; };
|
uint32 UsageMinimum() { return fUsageMinimum; };
|
||||||
uint32 UsageMaximum() { return fUsageMaximum; };
|
uint32 UsageMaximum() { return fUsageMaximum; };
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ public:
|
|||||||
bool Valid() { return fValid; };
|
bool Valid() { return fValid; };
|
||||||
uint32 Data() { return fData; };
|
uint32 Data() { return fData; };
|
||||||
|
|
||||||
|
void PrintToStream(uint32 indentLevel = 0);
|
||||||
private:
|
private:
|
||||||
HIDReport * fReport;
|
HIDReport * fReport;
|
||||||
uint32 fByteOffset;
|
uint32 fByteOffset;
|
||||||
|
|||||||
Reference in New Issue
Block a user