From 18074c28fa91f22f504aaf9ab5a18a7d499f3d1f Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 10 Mar 2010 01:06:14 +0000 Subject: [PATCH] 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 --- .../drivers/input/usb_hid/KeyboardDevice.cpp | 65 +++++++++---------- .../drivers/input/usb_hid/KeyboardDevice.h | 3 +- .../drivers/input/usb_hid/MouseDevice.cpp | 30 ++++----- .../drivers/input/usb_hid/MouseDevice.h | 3 +- .../drivers/input/usb_hid/ProtocolHandler.cpp | 45 +++++++------ 5 files changed, 70 insertions(+), 76 deletions(-) diff --git a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp index c7ce65017c..c759383b98 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp @@ -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, diff --git a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h index 88a0af4251..0e8e113976 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.h @@ -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); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp index 2f12407309..a38c4f2c08 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp @@ -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); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h index f66c10025d..66e621ddc6 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h +++ b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.h @@ -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); diff --git a/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp b/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp index ce7382b6f4..3be535cb09 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/ProtocolHandler.cpp @@ -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); }