Reworked the handler adding to be based on input reports. This way multiple
handlers may be added to a single device if it provides more than one report for a kind of device. Should fix #5549 where two mouse reports are present and only the first one was picked up and made available as device. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35796 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -87,6 +87,8 @@ KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport)
|
|||||||
|
|
||||||
TRACE("keyboard device with %lu keys and %lu modifiers\n", fKeyCount,
|
TRACE("keyboard device with %lu keys and %lu modifiers\n", fKeyCount,
|
||||||
fModifierCount);
|
fModifierCount);
|
||||||
|
TRACE("input report: %u; output report: %u\n", inputReport->ID(),
|
||||||
|
outputReport != NULL ? outputReport->ID() : 255);
|
||||||
|
|
||||||
fLastKeys = (uint16 *)malloc(fKeyCount * 2 * sizeof(uint16));
|
fLastKeys = (uint16 *)malloc(fKeyCount * 2 * sizeof(uint16));
|
||||||
fCurrentKeys = &fLastKeys[fKeyCount];
|
fCurrentKeys = &fLastKeys[fKeyCount];
|
||||||
@@ -143,55 +145,46 @@ KeyboardDevice::~KeyboardDevice()
|
|||||||
|
|
||||||
|
|
||||||
ProtocolHandler *
|
ProtocolHandler *
|
||||||
KeyboardDevice::AddHandler(HIDDevice *device)
|
KeyboardDevice::AddHandler(HIDDevice *device, HIDReport *input)
|
||||||
{
|
{
|
||||||
HIDParser *parser = device->Parser();
|
bool mayHaveOutput = false;
|
||||||
|
|
||||||
// try to find the keyboard usage in any input report
|
|
||||||
HIDReport *input = NULL;
|
|
||||||
bool foundKeyboardUsage = false;
|
bool foundKeyboardUsage = false;
|
||||||
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
for (uint32 i = 0; i < input->CountItems(); i++) {
|
||||||
for (uint32 i = 0; i < reportCount; i++) {
|
HIDReportItem *item = input->ItemAt(i);
|
||||||
input = parser->ReportAt(HID_REPORT_TYPE_INPUT, i);
|
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||||
|
|| (item->UsagePage() == HID_USAGE_PAGE_CONSUMER && item->Array())
|
||||||
for (uint32 j = 0; j < input->CountItems(); j++) {
|
|| (item->UsagePage() == HID_USAGE_PAGE_BUTTON && item->Array())) {
|
||||||
HIDReportItem *item = input->ItemAt(j);
|
// found at least one item with a keyboard usage or with
|
||||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
// a consumer/button usage that is handled like a key
|
||||||
|| (item->UsagePage() == HID_USAGE_PAGE_CONSUMER
|
mayHaveOutput = item->UsagePage() == HID_USAGE_PAGE_KEYBOARD;
|
||||||
&& item->Array())
|
foundKeyboardUsage = true;
|
||||||
|| (item->UsagePage() == HID_USAGE_PAGE_BUTTON
|
|
||||||
&& item->Array())) {
|
|
||||||
// found at least one item with a keyboard usage or with
|
|
||||||
// a consumer/button usage that is handled like a key
|
|
||||||
foundKeyboardUsage = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundKeyboardUsage)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundKeyboardUsage)
|
if (!foundKeyboardUsage)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// try to find the led output report
|
|
||||||
HIDReport *output = NULL;
|
HIDReport *output = NULL;
|
||||||
bool foundOutputReport = false;
|
bool foundOutputReport = false;
|
||||||
reportCount = parser->CountReports(HID_REPORT_TYPE_OUTPUT);
|
if (mayHaveOutput) {
|
||||||
for (uint32 i = 0; i < reportCount; i++) {
|
// try to find the led output report
|
||||||
output = parser->ReportAt(HID_REPORT_TYPE_OUTPUT, i);
|
HIDParser *parser = device->Parser();
|
||||||
|
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_OUTPUT);
|
||||||
|
for (uint32 i = 0; i < reportCount; i++) {
|
||||||
|
output = parser->ReportAt(HID_REPORT_TYPE_OUTPUT, i);
|
||||||
|
|
||||||
for (uint32 j = 0; j < output->CountItems(); j++) {
|
for (uint32 j = 0; j < output->CountItems(); j++) {
|
||||||
HIDReportItem *item = output->ItemAt(j);
|
HIDReportItem *item = output->ItemAt(j);
|
||||||
if (item->UsagePage() == HID_USAGE_PAGE_LED) {
|
if (item->UsagePage() == HID_USAGE_PAGE_LED) {
|
||||||
foundOutputReport = true;
|
foundOutputReport = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (foundOutputReport)
|
if (foundOutputReport)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(std::nothrow) KeyboardDevice(input,
|
return new(std::nothrow) KeyboardDevice(input,
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ public:
|
|||||||
HIDReport *outputReport);
|
HIDReport *outputReport);
|
||||||
virtual ~KeyboardDevice();
|
virtual ~KeyboardDevice();
|
||||||
|
|
||||||
static ProtocolHandler * AddHandler(HIDDevice *device);
|
static ProtocolHandler * AddHandler(HIDDevice *device,
|
||||||
|
HIDReport *input);
|
||||||
|
|
||||||
virtual status_t Open(uint32 flags);
|
virtual status_t Open(uint32 flags);
|
||||||
virtual status_t Control(uint32 op, void *buffer, size_t length);
|
virtual status_t Control(uint32 op, void *buffer, size_t length);
|
||||||
|
|||||||
@@ -47,31 +47,25 @@ MouseDevice::MouseDevice(HIDReport *report, HIDReportItem *xAxis,
|
|||||||
|
|
||||||
fWheel = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
fWheel = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||||
HID_USAGE_ID_WHEEL);
|
HID_USAGE_ID_WHEEL);
|
||||||
|
|
||||||
|
TRACE("mouse device with %lu buttons and %swheel\n", buttonCount,
|
||||||
|
fWheel == NULL ? "no " : "");
|
||||||
|
TRACE("report id: %u\n", report->ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ProtocolHandler *
|
ProtocolHandler *
|
||||||
MouseDevice::AddHandler(HIDDevice *device)
|
MouseDevice::AddHandler(HIDDevice *device, HIDReport *report)
|
||||||
{
|
{
|
||||||
HIDParser *parser = device->Parser();
|
|
||||||
|
|
||||||
// try to find at least an x and y axis
|
// try to find at least an x and y axis
|
||||||
HIDReport *report = NULL;
|
HIDReportItem *xAxis = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||||
HIDReportItem *xAxis = NULL;
|
HID_USAGE_ID_X);
|
||||||
HIDReportItem *yAxis = NULL;
|
if (xAxis == NULL)
|
||||||
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
return NULL;
|
||||||
for (uint32 i = 0; i < reportCount; i++) {
|
|
||||||
report = parser->ReportAt(HID_REPORT_TYPE_INPUT, i);
|
|
||||||
xAxis = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
|
||||||
HID_USAGE_ID_X);
|
|
||||||
yAxis = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
|
||||||
HID_USAGE_ID_Y);
|
|
||||||
|
|
||||||
if (xAxis != NULL && yAxis != NULL)
|
HIDReportItem *yAxis = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||||
break;
|
HID_USAGE_ID_Y);
|
||||||
}
|
if (yAxis == NULL)
|
||||||
|
|
||||||
if (xAxis == NULL || yAxis == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return new(std::nothrow) MouseDevice(report, xAxis, yAxis);
|
return new(std::nothrow) MouseDevice(report, xAxis, yAxis);
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public:
|
|||||||
MouseDevice(HIDReport *report,
|
MouseDevice(HIDReport *report,
|
||||||
HIDReportItem *xAxis, HIDReportItem *yAxis);
|
HIDReportItem *xAxis, HIDReportItem *yAxis);
|
||||||
|
|
||||||
static ProtocolHandler * AddHandler(HIDDevice *device);
|
static ProtocolHandler * AddHandler(HIDDevice *device,
|
||||||
|
HIDReport *report);
|
||||||
|
|
||||||
virtual status_t Control(uint32 op, void *buffer, size_t length);
|
virtual status_t Control(uint32 op, void *buffer, size_t length);
|
||||||
|
|
||||||
|
|||||||
@@ -63,36 +63,41 @@ ProtocolHandler::AddHandlers(HIDDevice *device, ProtocolHandler ***handlerList,
|
|||||||
{
|
{
|
||||||
TRACE("adding protocol handlers\n");
|
TRACE("adding protocol handlers\n");
|
||||||
|
|
||||||
uint32 count = 3;
|
HIDParser *parser = device->Parser();
|
||||||
ProtocolHandler *handlers[count];
|
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
||||||
handlers[0] = KeyboardDevice::AddHandler(device);
|
|
||||||
handlers[1] = MouseDevice::AddHandler(device);
|
|
||||||
handlers[2] = NULL; //GenericDevice::AddHandler(device);
|
|
||||||
|
|
||||||
*handlerCount = 0;
|
*handlerCount = 0;
|
||||||
uint32 actualCount = 0;
|
|
||||||
for (uint32 i = 0; i < count; i++) {
|
|
||||||
if (handlers[i] != NULL)
|
|
||||||
actualCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actualCount == 0) {
|
|
||||||
TRACE_ALWAYS("no handlers for hid device\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*handlerList = (ProtocolHandler **)malloc(sizeof(ProtocolHandler *)
|
*handlerList = (ProtocolHandler **)malloc(sizeof(ProtocolHandler *)
|
||||||
* actualCount);
|
* reportCount * 2 /* handler type count */);
|
||||||
if (*handlerList == NULL) {
|
if (*handlerList == NULL) {
|
||||||
TRACE_ALWAYS("out of memory allocating handler list\n");
|
TRACE_ALWAYS("out of memory allocating handler list\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 i = 0; i < count; i++) {
|
uint32 usedCount = 0;
|
||||||
if (handlers[i] != NULL)
|
ProtocolHandler *handler = NULL;
|
||||||
(*handlerList)[(*handlerCount)++] = handlers[i];
|
for (uint32 i = 0; i < reportCount; i++) {
|
||||||
|
HIDReport *report = parser->ReportAt(HID_REPORT_TYPE_INPUT, i);
|
||||||
|
|
||||||
|
handler = KeyboardDevice::AddHandler(device, report);
|
||||||
|
if (handler != NULL)
|
||||||
|
(*handlerList)[usedCount++] = handler;
|
||||||
|
handler = MouseDevice::AddHandler(device, report);
|
||||||
|
if (handler != NULL)
|
||||||
|
(*handlerList)[usedCount++] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usedCount == 0) {
|
||||||
|
TRACE_ALWAYS("no handlers for hid device\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*handlerCount = usedCount;
|
||||||
|
ProtocolHandler **shrunkList = (ProtocolHandler **)realloc(
|
||||||
|
*handlerList, sizeof(ProtocolHandler *) * usedCount);
|
||||||
|
if (shrunkList != NULL)
|
||||||
|
*handlerList = shrunkList;
|
||||||
|
|
||||||
TRACE("added %ld handlers for hid device\n", *handlerCount);
|
TRACE("added %ld handlers for hid device\n", *handlerCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user