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:
parent
b11dde545b
commit
18074c28fa
@ -87,6 +87,8 @@ KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport)
|
||||
|
||||
TRACE("keyboard device with %lu keys and %lu modifiers\n", fKeyCount,
|
||||
fModifierCount);
|
||||
TRACE("input report: %u; output report: %u\n", inputReport->ID(),
|
||||
outputReport != NULL ? outputReport->ID() : 255);
|
||||
|
||||
fLastKeys = (uint16 *)malloc(fKeyCount * 2 * sizeof(uint16));
|
||||
fCurrentKeys = &fLastKeys[fKeyCount];
|
||||
@ -143,55 +145,46 @@ KeyboardDevice::~KeyboardDevice()
|
||||
|
||||
|
||||
ProtocolHandler *
|
||||
KeyboardDevice::AddHandler(HIDDevice *device)
|
||||
KeyboardDevice::AddHandler(HIDDevice *device, HIDReport *input)
|
||||
{
|
||||
HIDParser *parser = device->Parser();
|
||||
|
||||
// try to find the keyboard usage in any input report
|
||||
HIDReport *input = NULL;
|
||||
bool mayHaveOutput = false;
|
||||
bool foundKeyboardUsage = false;
|
||||
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
||||
for (uint32 i = 0; i < reportCount; i++) {
|
||||
input = parser->ReportAt(HID_REPORT_TYPE_INPUT, i);
|
||||
|
||||
for (uint32 j = 0; j < input->CountItems(); j++) {
|
||||
HIDReportItem *item = input->ItemAt(j);
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||
|| (item->UsagePage() == HID_USAGE_PAGE_CONSUMER
|
||||
&& item->Array())
|
||||
|| (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)
|
||||
for (uint32 i = 0; i < input->CountItems(); i++) {
|
||||
HIDReportItem *item = input->ItemAt(i);
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_KEYBOARD
|
||||
|| (item->UsagePage() == HID_USAGE_PAGE_CONSUMER && item->Array())
|
||||
|| (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
|
||||
mayHaveOutput = item->UsagePage() == HID_USAGE_PAGE_KEYBOARD;
|
||||
foundKeyboardUsage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundKeyboardUsage)
|
||||
return NULL;
|
||||
|
||||
// try to find the led output report
|
||||
HIDReport *output = NULL;
|
||||
bool foundOutputReport = false;
|
||||
reportCount = parser->CountReports(HID_REPORT_TYPE_OUTPUT);
|
||||
for (uint32 i = 0; i < reportCount; i++) {
|
||||
output = parser->ReportAt(HID_REPORT_TYPE_OUTPUT, i);
|
||||
if (mayHaveOutput) {
|
||||
// try to find the led output report
|
||||
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++) {
|
||||
HIDReportItem *item = output->ItemAt(j);
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_LED) {
|
||||
foundOutputReport = true;
|
||||
break;
|
||||
for (uint32 j = 0; j < output->CountItems(); j++) {
|
||||
HIDReportItem *item = output->ItemAt(j);
|
||||
if (item->UsagePage() == HID_USAGE_PAGE_LED) {
|
||||
foundOutputReport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundOutputReport)
|
||||
break;
|
||||
if (foundOutputReport)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new(std::nothrow) KeyboardDevice(input,
|
||||
|
@ -19,7 +19,8 @@ public:
|
||||
HIDReport *outputReport);
|
||||
virtual ~KeyboardDevice();
|
||||
|
||||
static ProtocolHandler * AddHandler(HIDDevice *device);
|
||||
static ProtocolHandler * AddHandler(HIDDevice *device,
|
||||
HIDReport *input);
|
||||
|
||||
virtual status_t Open(uint32 flags);
|
||||
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,
|
||||
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 *
|
||||
MouseDevice::AddHandler(HIDDevice *device)
|
||||
MouseDevice::AddHandler(HIDDevice *device, HIDReport *report)
|
||||
{
|
||||
HIDParser *parser = device->Parser();
|
||||
|
||||
// try to find at least an x and y axis
|
||||
HIDReport *report = NULL;
|
||||
HIDReportItem *xAxis = NULL;
|
||||
HIDReportItem *yAxis = NULL;
|
||||
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
||||
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);
|
||||
HIDReportItem *xAxis = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
HID_USAGE_ID_X);
|
||||
if (xAxis == NULL)
|
||||
return NULL;
|
||||
|
||||
if (xAxis != NULL && yAxis != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xAxis == NULL || yAxis == NULL)
|
||||
HIDReportItem *yAxis = report->FindItem(HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
HID_USAGE_ID_Y);
|
||||
if (yAxis == NULL)
|
||||
return NULL;
|
||||
|
||||
return new(std::nothrow) MouseDevice(report, xAxis, yAxis);
|
||||
|
@ -20,7 +20,8 @@ public:
|
||||
MouseDevice(HIDReport *report,
|
||||
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);
|
||||
|
||||
|
@ -63,36 +63,41 @@ ProtocolHandler::AddHandlers(HIDDevice *device, ProtocolHandler ***handlerList,
|
||||
{
|
||||
TRACE("adding protocol handlers\n");
|
||||
|
||||
uint32 count = 3;
|
||||
ProtocolHandler *handlers[count];
|
||||
handlers[0] = KeyboardDevice::AddHandler(device);
|
||||
handlers[1] = MouseDevice::AddHandler(device);
|
||||
handlers[2] = NULL; //GenericDevice::AddHandler(device);
|
||||
HIDParser *parser = device->Parser();
|
||||
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
||||
|
||||
*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 *)
|
||||
* actualCount);
|
||||
* reportCount * 2 /* handler type count */);
|
||||
if (*handlerList == NULL) {
|
||||
TRACE_ALWAYS("out of memory allocating handler list\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
if (handlers[i] != NULL)
|
||||
(*handlerList)[(*handlerCount)++] = handlers[i];
|
||||
uint32 usedCount = 0;
|
||||
ProtocolHandler *handler = NULL;
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user