Rework incoming report handling. We need to notify all reports when one comes in
because all reports schedule transfers on the same endpoint and therefore need to possibly reschedule. Previously if we got a report that we didn't listen on all further reports would stop, because noone would schedule a new transfer. This fixes extra keys not working on my natural keyboard. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32580 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
feff9eba4a
commit
c9c3b32d3b
@ -448,34 +448,34 @@ HIDParser::MaxReportSize()
|
||||
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;
|
||||
if (status != B_OK || length == 0) {
|
||||
if (status == B_OK)
|
||||
status = B_ERROR;
|
||||
|
||||
fReports[i]->SetReport(status, NULL, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
report = NULL;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
HIDReport *target = NULL;
|
||||
if (fUsesReportIDs) {
|
||||
target = FindReport(HID_REPORT_TYPE_INPUT, report[0]);
|
||||
uint8 targetID = 0;
|
||||
if (fUsesReportIDs && status == B_OK) {
|
||||
targetID = report[0];
|
||||
report++;
|
||||
length--;
|
||||
} else
|
||||
target = FindReport(HID_REPORT_TYPE_INPUT, 0);
|
||||
|
||||
if (target == NULL) {
|
||||
TRACE_ALWAYS("got report buffer but found no report to handle it\n");
|
||||
return;
|
||||
}
|
||||
|
||||
target->SetReport(status, report, length);
|
||||
// We need to notify all input reports, as we don't know who has waiting
|
||||
// listeners. Anyone other than the target report also waiting for a
|
||||
// transfer to happen needs to reschedule one now.
|
||||
for (uint32 i = 0; i < fReportCount; i++) {
|
||||
if (fReports[i] == NULL
|
||||
|| fReports[i]->Type() != HID_REPORT_TYPE_INPUT)
|
||||
continue;
|
||||
|
||||
if (fReports[i]->ID() == targetID)
|
||||
fReports[i]->SetReport(status, report, length);
|
||||
else
|
||||
fReports[i]->SetReport(B_INTERRUPTED, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -334,8 +334,10 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (result != B_TIMED_OUT) {
|
||||
// we expect timeouts as we do repeat key handling this way
|
||||
if (result != B_TIMED_OUT && result != B_INTERRUPTED) {
|
||||
// we expect timeouts as we do repeat key handling this way,
|
||||
// interrupts happen when other reports come in on the same
|
||||
// endpoint
|
||||
TRACE_ALWAYS("error waiting for report: %s\n", strerror(result));
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,12 @@ MouseDevice::_ReadReport()
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
TRACE_ALWAYS("error waiting for report: %s\n", strerror(result));
|
||||
if (result != B_INTERRUPTED) {
|
||||
// interrupts happen when other reports come in on the same
|
||||
// input as ours
|
||||
TRACE_ALWAYS("error waiting for report: %s\n", strerror(result));
|
||||
}
|
||||
|
||||
// signal that we simply want to try again
|
||||
return B_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user