* Changed the way how devices are enumerated and protocol handlers are added to
handle the different device classes. Handlers are now added based on the application collections that the HID descriptor describes instead of by enumerating the different report items inside the reports. This means that a device is now logically treated as a mouse when it comes with an application collection that designates it as a mouse, instead of when there is a report that contains an X and a Y axis. This resolves the conflicts that gamepads and joysticks were added as mice due to them containing such elements. This therefore fixes #4499 and opens up the way to properly handle other device types like joysticks (#7429), gamepads, tablets (#7354, #5989 and #7481) and so on. I'll work on gamepads/joysticks next and see where we stand for tablets later. * Added a few enumeration functions to HIDCollection to support the above. * Fix the root collection handling. A device doesn't describe a single root collection and then adds everything as a child. Instead it just has multiple collections on level 0. We account for that now by always creating an empty logical collection as the root collection where all the collections of the descriptor get added. * Rename the {Mouse|Keyboard}Device.{cpp|h} to {Mouse|Keyboard}ProtocolHandler.{cpp|h} as that more clearly describes their purpose. These classes are protocol handlers, i.e. they handle the ioctl based mouse and keyboard protocol between the driver and the input_server add-ons. * Change a lot of stuff to use references instead of pointers where it makes sense (not necessarily complete yet). I've tested this successfully on a keyboard with extended keys, a combo device with a keyboard with extended keys and a mouse, a mouse and a gamepad (that now doesn't do anything anymore) and found no regressions. However, since there are a lot of very varied ways how to describe such functions with HID, it's not too unlikely that some more curiously described devices will now stop working. These have to be handled case by case and their usages have to be added to the added to the appropriate handlers (or new handlers have to be written). Please test and create bug reports (preferrably including the report descriptor that is written out to /tmp). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41794 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3035edeb39
commit
305aff3f78
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "HIDCollection.h"
|
||||
#include "HIDReport.h"
|
||||
#include "HIDReportItem.h"
|
||||
|
||||
#include <new>
|
||||
@ -36,7 +37,10 @@ HIDCollection::HIDCollection(HIDCollection *parent, uint8 type,
|
||||
usageValue.u.extended = localState.usage_minimum.u.extended;
|
||||
else if (localState.usage_maximum_set)
|
||||
usageValue.u.extended = localState.usage_maximum.u.extended;
|
||||
else {
|
||||
else if (type == COLLECTION_LOGICAL) {
|
||||
// this is just a logical grouping collection
|
||||
usageValue.u.extended = 0;
|
||||
} else {
|
||||
TRACE_ALWAYS("non of the possible usages for the collection are set\n");
|
||||
}
|
||||
|
||||
@ -53,6 +57,24 @@ HIDCollection::~HIDCollection()
|
||||
}
|
||||
|
||||
|
||||
uint16
|
||||
HIDCollection::UsagePage()
|
||||
{
|
||||
usage_value value;
|
||||
value.u.extended = fUsage;
|
||||
return value.u.s.usage_page;
|
||||
}
|
||||
|
||||
|
||||
uint16
|
||||
HIDCollection::UsageID()
|
||||
{
|
||||
usage_value value;
|
||||
value.u.extended = fUsage;
|
||||
return value.u.s.usage_id;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
HIDCollection::AddChild(HIDCollection *child)
|
||||
{
|
||||
@ -79,6 +101,32 @@ HIDCollection::ChildAt(uint32 index)
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
HIDCollection::CountChildrenFlat(uint8 type)
|
||||
{
|
||||
uint32 count = 0;
|
||||
if (type == COLLECTION_ALL || fType == type)
|
||||
count++;
|
||||
|
||||
for (uint32 i = 0; i < fChildCount; i++) {
|
||||
HIDCollection *child = fChildren[i];
|
||||
if (child == NULL)
|
||||
continue;
|
||||
|
||||
count += child->CountChildrenFlat(type);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
HIDCollection *
|
||||
HIDCollection::ChildAtFlat(uint8 type, uint32 index)
|
||||
{
|
||||
return _ChildAtFlat(type, index);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HIDCollection::AddItem(HIDReportItem *item)
|
||||
{
|
||||
@ -109,6 +157,28 @@ HIDCollection::ItemAt(uint32 index)
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
HIDCollection::CountItemsFlat()
|
||||
{
|
||||
uint32 count = fItemCount;
|
||||
|
||||
for (uint32 i = 0; i < fChildCount; i++) {
|
||||
HIDCollection *child = fChildren[i];
|
||||
if (child != NULL)
|
||||
count += child->CountItemsFlat();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
HIDReportItem *
|
||||
HIDCollection::ItemAtFlat(uint32 index)
|
||||
{
|
||||
return _ItemAtFlat(index);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HIDCollection::PrintToStream(uint32 indentLevel)
|
||||
{
|
||||
@ -161,3 +231,87 @@ HIDCollection::PrintToStream(uint32 indentLevel)
|
||||
child->PrintToStream(indentLevel + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HIDCollection *
|
||||
HIDCollection::_ChildAtFlat(uint8 type, uint32 &index)
|
||||
{
|
||||
if (type == COLLECTION_ALL || fType == type) {
|
||||
if (index == 0)
|
||||
return this;
|
||||
|
||||
index--;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < fChildCount; i++) {
|
||||
HIDCollection *child = fChildren[i];
|
||||
if (child == NULL)
|
||||
continue;
|
||||
|
||||
HIDCollection *result = child->_ChildAtFlat(type, index);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HIDReportItem *
|
||||
HIDCollection::_ItemAtFlat(uint32 &index)
|
||||
{
|
||||
if (index < fItemCount)
|
||||
return fItems[index];
|
||||
|
||||
index -= fItemCount;
|
||||
|
||||
for (uint32 i = 0; i < fChildCount; i++) {
|
||||
HIDCollection *child = fChildren[i];
|
||||
if (child == NULL)
|
||||
continue;
|
||||
|
||||
HIDReportItem *result = child->_ItemAtFlat(index);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HIDCollection::BuildReportList(uint8 reportType,
|
||||
HIDReport **reportList, uint32 &reportCount)
|
||||
{
|
||||
|
||||
for (uint32 i = 0; i < fItemCount; i++) {
|
||||
HIDReportItem *item = fItems[i];
|
||||
if (item == NULL)
|
||||
continue;
|
||||
|
||||
HIDReport *report = item->Report();
|
||||
if (reportType != HID_REPORT_TYPE_ANY && report->Type() != reportType)
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
for (uint32 j = 0; j < reportCount; j++) {
|
||||
if (reportList[j] == report) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
reportList[reportCount++] = report;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < fChildCount; i++) {
|
||||
HIDCollection *child = fChildren[i];
|
||||
if (child == NULL)
|
||||
continue;
|
||||
|
||||
child->BuildReportList(reportType, reportList, reportCount);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef HID_COLLECTION_H
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "HIDParser.h"
|
||||
|
||||
class HIDReport;
|
||||
class HIDReportItem;
|
||||
|
||||
class HIDCollection {
|
||||
@ -15,19 +16,37 @@ public:
|
||||
uint8 type, local_item_state &localState);
|
||||
~HIDCollection();
|
||||
|
||||
uint8 Type() { return fType; };
|
||||
|
||||
uint16 UsagePage();
|
||||
uint16 UsageID();
|
||||
|
||||
HIDCollection * Parent() { return fParent; };
|
||||
|
||||
status_t AddChild(HIDCollection *child);
|
||||
uint32 CountChildren() { return fChildCount; };
|
||||
HIDCollection * ChildAt(uint32 index);
|
||||
|
||||
uint32 CountChildrenFlat(uint8 type);
|
||||
HIDCollection * ChildAtFlat(uint8 type, uint32 index);
|
||||
|
||||
void AddItem(HIDReportItem *item);
|
||||
uint32 CountItems() { return fItemCount; };
|
||||
HIDReportItem * ItemAt(uint32 index);
|
||||
|
||||
uint32 CountItemsFlat();
|
||||
HIDReportItem * ItemAtFlat(uint32 index);
|
||||
|
||||
void BuildReportList(uint8 reportType,
|
||||
HIDReport **reportList,
|
||||
uint32 &reportCount);
|
||||
|
||||
void PrintToStream(uint32 indentLevel = 0);
|
||||
|
||||
private:
|
||||
HIDCollection * _ChildAtFlat(uint8 type, uint32 &index);
|
||||
HIDReportItem * _ItemAtFlat(uint32 &index);
|
||||
|
||||
HIDCollection * fParent;
|
||||
|
||||
uint8 fType;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef HID_DATA_TYPES_H
|
||||
@ -51,6 +51,7 @@
|
||||
#define COLLECTION_NAMED_ARRAY 0x04
|
||||
#define COLLECTION_USAGE_SWITCH 0x05
|
||||
#define COLLECTION_USAGE_MODIFIER 0x06
|
||||
#define COLLECTION_ALL 0xff
|
||||
|
||||
#define UNIT_SYSTEM 0x0
|
||||
#define UNIT_LENGTH 0x1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Copyright 2008-2011, Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
@ -35,7 +35,7 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
||||
fRemoved(false),
|
||||
fParser(this),
|
||||
fProtocolHandlerCount(0),
|
||||
fProtocolHandlers(NULL)
|
||||
fProtocolHandlerList(NULL)
|
||||
{
|
||||
uint8 *reportDescriptor = NULL;
|
||||
size_t descriptorLength = 0;
|
||||
@ -166,18 +166,21 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
||||
return;
|
||||
}
|
||||
|
||||
ProtocolHandler::AddHandlers(this, &fProtocolHandlers,
|
||||
&fProtocolHandlerCount);
|
||||
ProtocolHandler::AddHandlers(*this, fProtocolHandlerList,
|
||||
fProtocolHandlerCount);
|
||||
fStatus = B_OK;
|
||||
}
|
||||
|
||||
|
||||
HIDDevice::~HIDDevice()
|
||||
{
|
||||
for (uint32 i = 0; i < fProtocolHandlerCount; i++)
|
||||
delete fProtocolHandlers[i];
|
||||
ProtocolHandler *handler = fProtocolHandlerList;
|
||||
while (handler != NULL) {
|
||||
ProtocolHandler *next = handler->NextHandler();
|
||||
delete handler;
|
||||
handler = next;
|
||||
}
|
||||
|
||||
free(fProtocolHandlers);
|
||||
free(fTransferBuffer);
|
||||
}
|
||||
|
||||
@ -250,9 +253,16 @@ HIDDevice::SendReport(HIDReport *report)
|
||||
ProtocolHandler *
|
||||
HIDDevice::ProtocolHandlerAt(uint32 index) const
|
||||
{
|
||||
if (index >= fProtocolHandlerCount)
|
||||
return NULL;
|
||||
return fProtocolHandlers[index];
|
||||
ProtocolHandler *handler = fProtocolHandlerList;
|
||||
while (handler != NULL) {
|
||||
if (index == 0)
|
||||
return handler;
|
||||
|
||||
handler = handler->NextHandler();
|
||||
index--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Copyright 2008-2011, Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef USB_HID_DEVICE_H
|
||||
@ -38,7 +38,7 @@ public:
|
||||
|
||||
status_t SendReport(HIDReport *report);
|
||||
|
||||
HIDParser * Parser() { return &fParser; }
|
||||
HIDParser & Parser() { return fParser; }
|
||||
ProtocolHandler * ProtocolHandlerAt(uint32 index) const;
|
||||
|
||||
// only to be used for the kernel debugger information
|
||||
@ -66,7 +66,7 @@ private:
|
||||
HIDParser fParser;
|
||||
|
||||
uint32 fProtocolHandlerCount;
|
||||
ProtocolHandler ** fProtocolHandlers;
|
||||
ProtocolHandler * fProtocolHandlerList;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -62,7 +62,14 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
HIDCollection *collection = NULL;
|
||||
fRootCollection = new(std::nothrow) HIDCollection(NULL, COLLECTION_LOGICAL,
|
||||
localState);
|
||||
if (fRootCollection == NULL) {
|
||||
TRACE_ALWAYS("no memory to allocate root collection\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
HIDCollection *collection = fRootCollection;
|
||||
const uint8 *pointer = reportDescriptor;
|
||||
const uint8 *end = pointer + descriptorLength;
|
||||
|
||||
@ -138,14 +145,10 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
|
||||
break;
|
||||
}
|
||||
|
||||
if (collection == NULL)
|
||||
fRootCollection = newCollection;
|
||||
else
|
||||
collection->AddChild(newCollection);
|
||||
|
||||
collection->AddChild(newCollection);
|
||||
collection = newCollection;
|
||||
} else if (item->tag == ITEM_TAG_MAIN_END_COLLECTION) {
|
||||
if (collection == NULL) {
|
||||
if (collection == fRootCollection) {
|
||||
TRACE_ALWAYS("end collection with no open one\n");
|
||||
break;
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ public:
|
||||
uint32 minimum, uint32 maximum,
|
||||
uint32 usageMinimum, uint32 usageMaximum);
|
||||
|
||||
HIDReport * Report() { return fReport; };
|
||||
|
||||
bool HasData() { return fHasData; };
|
||||
bool Relative() { return fRelative; };
|
||||
bool Array() { return fArray; };
|
||||
|
@ -10,12 +10,13 @@ KernelAddon usb_hid :
|
||||
DeviceList.cpp
|
||||
Driver.cpp
|
||||
HIDDevice.cpp
|
||||
KeyboardDevice.cpp
|
||||
MouseDevice.cpp
|
||||
ProtocolHandler.cpp
|
||||
|
||||
HIDCollection.cpp
|
||||
HIDParser.cpp
|
||||
HIDReport.cpp
|
||||
HIDReportItem.cpp
|
||||
|
||||
ProtocolHandler.cpp
|
||||
KeyboardProtocolHandler.cpp
|
||||
MouseProtocolHandler.cpp
|
||||
;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Copyright 2008-2011 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
@ -14,8 +14,9 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include "Driver.h"
|
||||
#include "KeyboardDevice.h"
|
||||
#include "KeyboardProtocolHandler.h"
|
||||
|
||||
#include "HIDCollection.h"
|
||||
#include "HIDDevice.h"
|
||||
#include "HIDReport.h"
|
||||
#include "HIDReportItem.h"
|
||||
@ -48,9 +49,10 @@ debug_get_keyboard_config(int argc, char **argv)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport)
|
||||
KeyboardProtocolHandler::KeyboardProtocolHandler(HIDReport &inputReport,
|
||||
HIDReport *outputReport)
|
||||
:
|
||||
ProtocolHandler(inputReport->Device(), "input/keyboard/usb/", 512),
|
||||
ProtocolHandler(inputReport.Device(), "input/keyboard/usb/", 512),
|
||||
fInputReport(inputReport),
|
||||
fOutputReport(outputReport),
|
||||
fRepeatDelay(300000),
|
||||
@ -68,8 +70,8 @@ KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport)
|
||||
mutex_init(&fLock, "usb keyboard");
|
||||
|
||||
// find modifiers and keys
|
||||
for (uint32 i = 0; i < inputReport->CountItems(); i++) {
|
||||
HIDReportItem *item = inputReport->ItemAt(i);
|
||||
for (uint32 i = 0; i < inputReport.CountItems(); i++) {
|
||||
HIDReportItem *item = inputReport.ItemAt(i);
|
||||
if (!item->HasData())
|
||||
continue;
|
||||
|
||||
@ -96,7 +98,7 @@ 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(),
|
||||
TRACE("input report: %u; output report: %u\n", inputReport.ID(),
|
||||
outputReport != NULL ? outputReport->ID() : 255);
|
||||
|
||||
fLastKeys = (uint16 *)malloc(fKeyCount * 2 * sizeof(uint16));
|
||||
@ -142,7 +144,7 @@ KeyboardDevice::KeyboardDevice(HIDReport *inputReport, HIDReport *outputReport)
|
||||
}
|
||||
|
||||
|
||||
KeyboardDevice::~KeyboardDevice()
|
||||
KeyboardProtocolHandler::~KeyboardProtocolHandler()
|
||||
{
|
||||
free(fLastKeys);
|
||||
|
||||
@ -155,59 +157,122 @@ KeyboardDevice::~KeyboardDevice()
|
||||
}
|
||||
|
||||
|
||||
ProtocolHandler *
|
||||
KeyboardDevice::AddHandler(HIDDevice *device, HIDReport *input)
|
||||
void
|
||||
KeyboardProtocolHandler::AddHandlers(HIDDevice &device,
|
||||
HIDCollection &collection, ProtocolHandler *&handlerList)
|
||||
{
|
||||
bool mayHaveOutput = false;
|
||||
bool foundKeyboardUsage = false;
|
||||
for (uint32 i = 0; i < input->CountItems(); i++) {
|
||||
HIDReportItem *item = input->ItemAt(i);
|
||||
if (!item->HasData())
|
||||
continue;
|
||||
bool handled = false;
|
||||
switch (collection.UsagePage()) {
|
||||
case B_HID_USAGE_PAGE_GENERIC_DESKTOP:
|
||||
{
|
||||
switch (collection.UsageID()) {
|
||||
case B_HID_UID_GD_KEYBOARD:
|
||||
case B_HID_UID_GD_KEYPAD:
|
||||
case B_HID_UID_GD_SYSTEM_CONTROL:
|
||||
handled = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case B_HID_USAGE_PAGE_CONSUMER:
|
||||
{
|
||||
switch (collection.UsageID()) {
|
||||
case B_HID_UID_CON_CONSUMER_CONTROL:
|
||||
handled = true;
|
||||
}
|
||||
|
||||
if (item->UsagePage() == B_HID_USAGE_PAGE_KEYBOARD
|
||||
|| (item->UsagePage() == B_HID_USAGE_PAGE_CONSUMER && item->Array())
|
||||
|| (item->UsagePage() == B_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() == B_HID_USAGE_PAGE_KEYBOARD;
|
||||
foundKeyboardUsage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundKeyboardUsage)
|
||||
return NULL;
|
||||
|
||||
HIDReport *output = NULL;
|
||||
bool foundOutputReport = false;
|
||||
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() == B_HID_USAGE_PAGE_LED) {
|
||||
foundOutputReport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundOutputReport)
|
||||
break;
|
||||
}
|
||||
if (!handled) {
|
||||
TRACE("collection not a supported keyboard subset\n");
|
||||
return;
|
||||
}
|
||||
|
||||
return new(std::nothrow) KeyboardDevice(input,
|
||||
foundOutputReport ? output : NULL);
|
||||
HIDParser &parser = device.Parser();
|
||||
uint32 maxReportCount = parser.CountReports(HID_REPORT_TYPE_INPUT);
|
||||
if (maxReportCount == 0)
|
||||
return;
|
||||
|
||||
uint32 inputReportCount = 0;
|
||||
HIDReport *inputReports[maxReportCount];
|
||||
collection.BuildReportList(HID_REPORT_TYPE_INPUT, inputReports,
|
||||
inputReportCount);
|
||||
|
||||
TRACE("input report count: %lu\n", inputReportCount);
|
||||
|
||||
for (uint32 i = 0; i < inputReportCount; i++) {
|
||||
HIDReport *inputReport = inputReports[i];
|
||||
|
||||
bool mayHaveOutput = false;
|
||||
bool foundKeyboardUsage = false;
|
||||
for (uint32 j = 0; j < inputReport->CountItems(); j++) {
|
||||
HIDReportItem *item = inputReport->ItemAt(j);
|
||||
if (!item->HasData())
|
||||
continue;
|
||||
|
||||
if (item->UsagePage() == B_HID_USAGE_PAGE_KEYBOARD
|
||||
|| (item->UsagePage() == B_HID_USAGE_PAGE_CONSUMER
|
||||
&& item->Array())
|
||||
|| (item->UsagePage() == B_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() == B_HID_USAGE_PAGE_KEYBOARD;
|
||||
foundKeyboardUsage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundKeyboardUsage)
|
||||
continue;
|
||||
|
||||
bool foundOutputReport = false;
|
||||
HIDReport *outputReport = NULL;
|
||||
do {
|
||||
// try to find the led output report
|
||||
maxReportCount = parser.CountReports(HID_REPORT_TYPE_OUTPUT);
|
||||
if (maxReportCount == 0)
|
||||
break;
|
||||
|
||||
uint32 outputReportCount = 0;
|
||||
HIDReport *outputReports[maxReportCount];
|
||||
collection.BuildReportList(HID_REPORT_TYPE_OUTPUT,
|
||||
outputReports, outputReportCount);
|
||||
|
||||
for (uint32 j = 0; j < outputReportCount; j++) {
|
||||
outputReport = outputReports[j];
|
||||
|
||||
for (uint32 k = 0; k < outputReport->CountItems(); k++) {
|
||||
HIDReportItem *item = outputReport->ItemAt(k);
|
||||
if (item->UsagePage() == B_HID_USAGE_PAGE_LED) {
|
||||
foundOutputReport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundOutputReport)
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
ProtocolHandler *newHandler = new(std::nothrow) KeyboardProtocolHandler(
|
||||
*inputReport, foundOutputReport ? outputReport : NULL);
|
||||
if (newHandler == NULL) {
|
||||
TRACE("failed to allocated keyboard protocol handler\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
newHandler->SetNextHandler(handlerList);
|
||||
handlerList = newHandler;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::Open(uint32 flags, uint32 *cookie)
|
||||
KeyboardProtocolHandler::Open(uint32 flags, uint32 *cookie)
|
||||
{
|
||||
status_t status = ProtocolHandler::Open(flags, cookie);
|
||||
if (status != B_OK) {
|
||||
@ -226,7 +291,7 @@ KeyboardDevice::Open(uint32 flags, uint32 *cookie)
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::Close(uint32 *cookie)
|
||||
KeyboardProtocolHandler::Close(uint32 *cookie)
|
||||
{
|
||||
if ((*cookie & KEYBOARD_FLAG_DEBUGGER) != 0)
|
||||
fHasDebugReader = false;
|
||||
@ -238,7 +303,8 @@ KeyboardDevice::Close(uint32 *cookie)
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
|
||||
KeyboardProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
|
||||
size_t length)
|
||||
{
|
||||
switch (op) {
|
||||
case KB_READ:
|
||||
@ -347,7 +413,7 @@ KeyboardDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
|
||||
|
||||
|
||||
void
|
||||
KeyboardDevice::_WriteKey(uint32 key, bool down)
|
||||
KeyboardProtocolHandler::_WriteKey(uint32 key, bool down)
|
||||
{
|
||||
raw_key_info info;
|
||||
info.keycode = key;
|
||||
@ -358,7 +424,7 @@ KeyboardDevice::_WriteKey(uint32 key, bool down)
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::_SetLEDs(uint8 *data)
|
||||
KeyboardProtocolHandler::_SetLEDs(uint8 *data)
|
||||
{
|
||||
if (fOutputReport == NULL || fOutputReport->Device()->IsRemoved())
|
||||
return B_ERROR;
|
||||
@ -375,11 +441,11 @@ KeyboardDevice::_SetLEDs(uint8 *data)
|
||||
|
||||
|
||||
status_t
|
||||
KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
KeyboardProtocolHandler::_ReadReport(bigtime_t timeout)
|
||||
{
|
||||
status_t result = fInputReport->WaitForReport(timeout);
|
||||
status_t result = fInputReport.WaitForReport(timeout);
|
||||
if (result != B_OK) {
|
||||
if (fInputReport->Device()->IsRemoved()) {
|
||||
if (fInputReport.Device()->IsRemoved()) {
|
||||
TRACE("device has been removed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -420,7 +486,7 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
fCurrentKeys[i] = 0;
|
||||
}
|
||||
|
||||
fInputReport->DoneProcessing();
|
||||
fInputReport.DoneProcessing();
|
||||
|
||||
static const uint32 kModifierTable[] = {
|
||||
KEY_ControlL,
|
||||
@ -643,9 +709,9 @@ KeyboardDevice::_ReadReport(bigtime_t timeout)
|
||||
&& (fLastModifiers & ALT_KEYS) != 0) {
|
||||
// Alt-SysReq+letter was pressed
|
||||
sDebugKeyboardPipe
|
||||
= fInputReport->Device()->InterruptPipe();
|
||||
= fInputReport.Device()->InterruptPipe();
|
||||
sDebugKeyboardReportSize
|
||||
= fInputReport->Parser()->MaxReportSize();
|
||||
= fInputReport.Parser()->MaxReportSize();
|
||||
|
||||
char letter = current[i] - 4 + 'a';
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Copyright 2008-2011 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef USB_KEYBOARD_DEVICE_H
|
||||
#define USB_KEYBOARD_DEVICE_H
|
||||
#ifndef USB_KEYBOARD_PROTOCOL_HANDLER_H
|
||||
#define USB_KEYBOARD_PROTOCOL_HANDLER_H
|
||||
|
||||
|
||||
#include "ProtocolHandler.h"
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
|
||||
class HIDReportItem;
|
||||
class HIDCollection;
|
||||
|
||||
|
||||
#define MAX_MODIFIERS 16
|
||||
@ -19,14 +20,15 @@ class HIDReportItem;
|
||||
#define MAX_LEDS 3
|
||||
|
||||
|
||||
class KeyboardDevice : public ProtocolHandler {
|
||||
class KeyboardProtocolHandler : public ProtocolHandler {
|
||||
public:
|
||||
KeyboardDevice(HIDReport *inputReport,
|
||||
KeyboardProtocolHandler(HIDReport &inputReport,
|
||||
HIDReport *outputReport);
|
||||
virtual ~KeyboardDevice();
|
||||
virtual ~KeyboardProtocolHandler();
|
||||
|
||||
static ProtocolHandler * AddHandler(HIDDevice *device,
|
||||
HIDReport *input);
|
||||
static void AddHandlers(HIDDevice &device,
|
||||
HIDCollection &collection,
|
||||
ProtocolHandler *&handlerList);
|
||||
|
||||
virtual status_t Open(uint32 flags, uint32 *cookie);
|
||||
virtual status_t Close(uint32 *cookie);
|
||||
@ -42,7 +44,7 @@ private:
|
||||
private:
|
||||
mutex fLock;
|
||||
|
||||
HIDReport * fInputReport;
|
||||
HIDReport & fInputReport;
|
||||
HIDReport * fOutputReport;
|
||||
|
||||
HIDReportItem * fModifiers[MAX_MODIFIERS];
|
||||
@ -66,4 +68,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // USB_KEYBOARD_DEVICE_H
|
||||
#endif // USB_KEYBOARD_PROTOCOL_HANDLER_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Copyright 2008-2011 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
@ -8,8 +8,9 @@
|
||||
|
||||
|
||||
#include "Driver.h"
|
||||
#include "MouseDevice.h"
|
||||
#include "MouseProtocolHandler.h"
|
||||
|
||||
#include "HIDCollection.h"
|
||||
#include "HIDDevice.h"
|
||||
#include "HIDReport.h"
|
||||
#include "HIDReportItem.h"
|
||||
@ -21,10 +22,10 @@
|
||||
#include <keyboard_mouse_driver.h>
|
||||
|
||||
|
||||
MouseDevice::MouseDevice(HIDReport *report, HIDReportItem *xAxis,
|
||||
HIDReportItem *yAxis)
|
||||
MouseProtocolHandler::MouseProtocolHandler(HIDReport &report,
|
||||
HIDReportItem &xAxis, HIDReportItem &yAxis)
|
||||
:
|
||||
ProtocolHandler(report->Device(), "input/mouse/usb/", 512),
|
||||
ProtocolHandler(report.Device(), "input/mouse/usb/", 512),
|
||||
fReport(report),
|
||||
fXAxis(xAxis),
|
||||
fYAxis(yAxis),
|
||||
@ -35,47 +36,77 @@ MouseDevice::MouseDevice(HIDReport *report, HIDReportItem *xAxis,
|
||||
fClickSpeed(250000)
|
||||
{
|
||||
uint32 buttonCount = 0;
|
||||
for (uint32 i = 0; i < report->CountItems(); i++) {
|
||||
HIDReportItem *item = report->ItemAt(i);
|
||||
for (uint32 i = 0; i < report.CountItems(); i++) {
|
||||
HIDReportItem *item = report.ItemAt(i);
|
||||
if (!item->HasData())
|
||||
continue;
|
||||
|
||||
if (item->UsagePage() == B_HID_USAGE_PAGE_BUTTON
|
||||
&& item->UsageID() - 1 < B_MAX_MOUSE_BUTTONS)
|
||||
&& item->UsageID() - 1 < B_MAX_MOUSE_BUTTONS) {
|
||||
fButtons[buttonCount++] = item;
|
||||
}
|
||||
}
|
||||
|
||||
fButtons[buttonCount] = NULL;
|
||||
|
||||
fWheel = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
fWheel = report.FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
B_HID_UID_GD_WHEEL);
|
||||
|
||||
TRACE("mouse device with %lu buttons and %swheel\n", buttonCount,
|
||||
fWheel == NULL ? "no " : "");
|
||||
TRACE("report id: %u\n", report->ID());
|
||||
TRACE("report id: %u\n", report.ID());
|
||||
}
|
||||
|
||||
|
||||
ProtocolHandler *
|
||||
MouseDevice::AddHandler(HIDDevice *device, HIDReport *report)
|
||||
void
|
||||
MouseProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection,
|
||||
ProtocolHandler *&handlerList)
|
||||
{
|
||||
// try to find at least an x and y axis
|
||||
HIDReportItem *xAxis = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
B_HID_UID_GD_X);
|
||||
if (xAxis == NULL)
|
||||
return NULL;
|
||||
if (collection.UsagePage() != B_HID_USAGE_PAGE_GENERIC_DESKTOP
|
||||
|| collection.UsageID() != B_HID_UID_GD_MOUSE) {
|
||||
TRACE("collection not a mouse\n");
|
||||
return;
|
||||
}
|
||||
|
||||
HIDReportItem *yAxis = report->FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
B_HID_UID_GD_Y);
|
||||
if (yAxis == NULL)
|
||||
return NULL;
|
||||
HIDParser &parser = device.Parser();
|
||||
uint32 maxReportCount = parser.CountReports(HID_REPORT_TYPE_INPUT);
|
||||
if (maxReportCount == 0)
|
||||
return;
|
||||
|
||||
return new(std::nothrow) MouseDevice(report, xAxis, yAxis);
|
||||
uint32 inputReportCount = 0;
|
||||
HIDReport *inputReports[maxReportCount];
|
||||
collection.BuildReportList(HID_REPORT_TYPE_INPUT, inputReports,
|
||||
inputReportCount);
|
||||
|
||||
for (uint32 i = 0; i < inputReportCount; i++) {
|
||||
HIDReport *inputReport = inputReports[i];
|
||||
|
||||
// try to find at least an x and y axis
|
||||
HIDReportItem *xAxis = inputReport->FindItem(
|
||||
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X);
|
||||
if (xAxis == NULL)
|
||||
continue;
|
||||
|
||||
HIDReportItem *yAxis = inputReport->FindItem(
|
||||
B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y);
|
||||
if (yAxis == NULL)
|
||||
continue;
|
||||
|
||||
ProtocolHandler *newHandler = new(std::nothrow) MouseProtocolHandler(
|
||||
*inputReport, *xAxis, *yAxis);
|
||||
if (newHandler == NULL) {
|
||||
TRACE("failed to allocated mouse protocol handler\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
newHandler->SetNextHandler(handlerList);
|
||||
handlerList = newHandler;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MouseDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
|
||||
MouseProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
|
||||
{
|
||||
switch (op) {
|
||||
case MS_READ:
|
||||
@ -90,7 +121,7 @@ MouseDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
|
||||
case MS_NUM_EVENTS:
|
||||
{
|
||||
int32 count = RingBufferReadable() / sizeof(mouse_movement);
|
||||
if (count == 0 && fReport->Device()->IsRemoved())
|
||||
if (count == 0 && fReport.Device()->IsRemoved())
|
||||
return B_DEV_NOT_READY;
|
||||
return count;
|
||||
}
|
||||
@ -109,11 +140,11 @@ MouseDevice::Control(uint32 *cookie, uint32 op, void *buffer, size_t length)
|
||||
|
||||
|
||||
status_t
|
||||
MouseDevice::_ReadReport()
|
||||
MouseProtocolHandler::_ReadReport()
|
||||
{
|
||||
status_t result = fReport->WaitForReport(B_INFINITE_TIMEOUT);
|
||||
status_t result = fReport.WaitForReport(B_INFINITE_TIMEOUT);
|
||||
if (result != B_OK) {
|
||||
if (fReport->Device()->IsRemoved()) {
|
||||
if (fReport.Device()->IsRemoved()) {
|
||||
TRACE("device has been removed\n");
|
||||
return B_DEV_NOT_READY;
|
||||
}
|
||||
@ -131,10 +162,10 @@ MouseDevice::_ReadReport()
|
||||
mouse_movement info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (fXAxis->Extract() == B_OK && fXAxis->Valid())
|
||||
info.xdelta = fXAxis->Data();
|
||||
if (fYAxis->Extract() == B_OK && fYAxis->Valid())
|
||||
info.ydelta = -fYAxis->Data();
|
||||
if (fXAxis.Extract() == B_OK && fXAxis.Valid())
|
||||
info.xdelta = fXAxis.Data();
|
||||
if (fYAxis.Extract() == B_OK && fYAxis.Valid())
|
||||
info.ydelta = -fYAxis.Data();
|
||||
|
||||
if (fWheel != NULL && fWheel->Extract() == B_OK && fWheel->Valid())
|
||||
info.wheel_ydelta = -fWheel->Data();
|
||||
@ -148,7 +179,7 @@ MouseDevice::_ReadReport()
|
||||
info.buttons |= (button->Data() & 1) << (button->UsageID() - 1);
|
||||
}
|
||||
|
||||
fReport->DoneProcessing();
|
||||
fReport.DoneProcessing();
|
||||
TRACE("got mouse report\n");
|
||||
|
||||
bigtime_t timestamp = system_time();
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Copyright 2008-2011 Michael Lotz <mmlr@mlotz.ch>
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef USB_MOUSE_DEVICE_H
|
||||
#define USB_MOUSE_DEVICE_H
|
||||
#ifndef USB_MOUSE_PROTOCOL_HANDLER_H
|
||||
#define USB_MOUSE_PROTOCOL_HANDLER_H
|
||||
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
@ -11,6 +11,7 @@
|
||||
#include "ProtocolHandler.h"
|
||||
|
||||
|
||||
class HIDCollection;
|
||||
class HIDReportItem;
|
||||
|
||||
|
||||
@ -19,13 +20,14 @@ class HIDReportItem;
|
||||
#endif
|
||||
|
||||
|
||||
class MouseDevice : public ProtocolHandler {
|
||||
class MouseProtocolHandler : public ProtocolHandler {
|
||||
public:
|
||||
MouseDevice(HIDReport *report,
|
||||
HIDReportItem *xAxis, HIDReportItem *yAxis);
|
||||
MouseProtocolHandler(HIDReport &report,
|
||||
HIDReportItem &xAxis, HIDReportItem &yAxis);
|
||||
|
||||
static ProtocolHandler * AddHandler(HIDDevice *device,
|
||||
HIDReport *report);
|
||||
static void AddHandlers(HIDDevice &device,
|
||||
HIDCollection &collection,
|
||||
ProtocolHandler *&handlerList);
|
||||
|
||||
virtual status_t Control(uint32 *cookie, uint32 op, void *buffer,
|
||||
size_t length);
|
||||
@ -34,10 +36,10 @@ private:
|
||||
status_t _ReadReport();
|
||||
|
||||
private:
|
||||
HIDReport * fReport;
|
||||
HIDReport & fReport;
|
||||
|
||||
HIDReportItem * fXAxis;
|
||||
HIDReportItem * fYAxis;
|
||||
HIDReportItem & fXAxis;
|
||||
HIDReportItem & fYAxis;
|
||||
HIDReportItem * fWheel;
|
||||
HIDReportItem * fButtons[B_MAX_MOUSE_BUTTONS];
|
||||
|
||||
@ -47,4 +49,4 @@ private:
|
||||
bigtime_t fClickSpeed;
|
||||
};
|
||||
|
||||
#endif // USB_MOUSE_DEVICE_H
|
||||
#endif // USB_MOUSE_PROTOCOL_HANDLER_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -8,14 +8,15 @@
|
||||
#include <ring_buffer.h>
|
||||
|
||||
#include "Driver.h"
|
||||
#include "HIDCollection.h"
|
||||
#include "HIDDevice.h"
|
||||
#include "HIDReport.h"
|
||||
#include "ProtocolHandler.h"
|
||||
|
||||
// includes for the different protocol handlers
|
||||
#include "KeyboardDevice.h"
|
||||
#include "MouseDevice.h"
|
||||
//#include "GenericDevice.h"
|
||||
#include "KeyboardProtocolHandler.h"
|
||||
#include "MouseProtocolHandler.h"
|
||||
//#include "JoystickProtocolHandler.h"
|
||||
|
||||
|
||||
ProtocolHandler::ProtocolHandler(HIDDevice *device, const char *basePath,
|
||||
@ -24,7 +25,8 @@ ProtocolHandler::ProtocolHandler(HIDDevice *device, const char *basePath,
|
||||
fDevice(device),
|
||||
fBasePath(basePath),
|
||||
fPublishPath(NULL),
|
||||
fRingBuffer(NULL)
|
||||
fRingBuffer(NULL),
|
||||
fNextHandler(NULL)
|
||||
{
|
||||
if (ringBufferSize > 0) {
|
||||
fRingBuffer = create_ring_buffer(ringBufferSize);
|
||||
@ -59,47 +61,48 @@ ProtocolHandler::SetPublishPath(char *publishPath)
|
||||
|
||||
|
||||
void
|
||||
ProtocolHandler::AddHandlers(HIDDevice *device, ProtocolHandler ***handlerList,
|
||||
uint32 *handlerCount)
|
||||
ProtocolHandler::AddHandlers(HIDDevice &device, ProtocolHandler *&handlerList,
|
||||
uint32 &handlerCount)
|
||||
{
|
||||
TRACE("adding protocol handlers\n");
|
||||
|
||||
HIDParser *parser = device->Parser();
|
||||
uint32 reportCount = parser->CountReports(HID_REPORT_TYPE_INPUT);
|
||||
|
||||
*handlerCount = 0;
|
||||
*handlerList = (ProtocolHandler **)malloc(sizeof(ProtocolHandler *)
|
||||
* reportCount * 2 /* handler type count */);
|
||||
if (*handlerList == NULL) {
|
||||
TRACE_ALWAYS("out of memory allocating handler list\n");
|
||||
HIDParser &parser = device.Parser();
|
||||
HIDCollection *rootCollection = parser.RootCollection();
|
||||
if (rootCollection == NULL)
|
||||
return;
|
||||
|
||||
uint32 appCollectionCount = rootCollection->CountChildrenFlat(
|
||||
COLLECTION_APPLICATION);
|
||||
TRACE("root collection holds %lu application collection%s\n",
|
||||
appCollectionCount, appCollectionCount != 1 ? "s" : "");
|
||||
|
||||
handlerCount = 0;
|
||||
for (uint32 i = 0; i < appCollectionCount; i++) {
|
||||
HIDCollection *collection = rootCollection->ChildAtFlat(
|
||||
COLLECTION_APPLICATION, i);
|
||||
if (collection == NULL)
|
||||
continue;
|
||||
|
||||
TRACE("collection usage page %u usage id %u\n",
|
||||
collection->UsagePage(), collection->UsageID());
|
||||
|
||||
KeyboardProtocolHandler::AddHandlers(device, *collection, handlerList);
|
||||
MouseProtocolHandler::AddHandlers(device, *collection, handlerList);
|
||||
//JoystickProtocolHandler::AddHandlers(device, *collection, handlerList);
|
||||
}
|
||||
|
||||
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;
|
||||
ProtocolHandler *handler = handlerList;
|
||||
while (handler != NULL) {
|
||||
handler = handler->NextHandler();
|
||||
handlerCount++;
|
||||
}
|
||||
|
||||
if (usedCount == 0) {
|
||||
if (handlerCount == 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);
|
||||
}
|
||||
|
||||
|
||||
@ -146,3 +149,10 @@ ProtocolHandler::RingBufferWrite(const void *buffer, size_t length)
|
||||
ring_buffer_write(fRingBuffer, (const uint8 *)buffer, length);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProtocolHandler::SetNextHandler(ProtocolHandler *nextHandler)
|
||||
{
|
||||
fNextHandler = nextHandler;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Copyright 2009-2011, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PROTOCOL_HANDLER_H
|
||||
@ -28,9 +28,9 @@ public:
|
||||
void SetPublishPath(char *publishPath);
|
||||
const char * PublishPath() { return fPublishPath; }
|
||||
|
||||
static void AddHandlers(HIDDevice *device,
|
||||
ProtocolHandler ***handlerList,
|
||||
uint32 *handlerCount);
|
||||
static void AddHandlers(HIDDevice &device,
|
||||
ProtocolHandler *&handlerList,
|
||||
uint32 &handlerCount);
|
||||
|
||||
virtual status_t Open(uint32 flags, uint32 *cookie);
|
||||
virtual status_t Close(uint32 *cookie);
|
||||
@ -43,6 +43,9 @@ public:
|
||||
status_t RingBufferWrite(const void *buffer,
|
||||
size_t length);
|
||||
|
||||
void SetNextHandler(ProtocolHandler *next);
|
||||
ProtocolHandler * NextHandler() { return fNextHandler; };
|
||||
|
||||
protected:
|
||||
status_t fStatus;
|
||||
|
||||
@ -51,6 +54,8 @@ private:
|
||||
const char * fBasePath;
|
||||
char * fPublishPath;
|
||||
struct ring_buffer *fRingBuffer;
|
||||
|
||||
ProtocolHandler * fNextHandler;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user