From 8bedd52e2b15666e53c90c97a04e70622f25783e Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 1 Apr 2020 16:32:21 +0100 Subject: [PATCH] HID: allow raw-descriptor parsing in the XML Also fix deadband computation (do it after min-max ranging) --- src/Input/FGEventInput.cxx | 6 ++--- src/Input/FGHIDEventInput.cxx | 45 +++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/Input/FGEventInput.cxx b/src/Input/FGEventInput.cxx index 4b0a17aea..08c455f0b 100644 --- a/src/Input/FGEventInput.cxx +++ b/src/Input/FGEventInput.cxx @@ -176,12 +176,12 @@ void FGAxisEvent::fire( FGEventData & eventData ) // We need a copy of the FGEventData struct to set the new value and to avoid side effects FGEventData ed = eventData; - if( fabs(ed.value) < deadband ) - ed.value = 0.0; - if( minRange != maxRange ) ed.value = 2.0*(eventData.value-minRange)/(maxRange-minRange)-1.0; + if( fabs(ed.value) < deadband ) + ed.value = 0.0; + if (interpolater) { if ((ed.value < 0.0) && mirrorInterpolater) { // mirror the positive interpolation for negative values diff --git a/src/Input/FGHIDEventInput.cxx b/src/Input/FGHIDEventInput.cxx index 4422a73ea..65f50a631 100644 --- a/src/Input/FGHIDEventInput.cxx +++ b/src/Input/FGHIDEventInput.cxx @@ -318,6 +318,9 @@ private: /// is inaccessible, or devices with broken descriptors bool _haveLocalDescriptor = false; + /// allow specifying the descriptor as hex bytes in XML + std::vector_rawXMLDescriptor; + // all sets which will be send on the next update() call. std::set _dirtyReports; }; @@ -384,6 +387,13 @@ void FGHIDDevice::Configure(SGPropertyNode_ptr node) defineReport(report); } } + + if (node->hasChild("hid-raw-descriptor")) { + _rawXMLDescriptor = simgear::strutils::decodeHex(node->getStringValue("hid-raw-descriptor")); + if (debugEvents) { + SG_LOG(SG_INPUT, SG_INFO, GetUniqueName() << " will configure using XML-defined raw HID descriptor"); + } + } } bool FGHIDDevice::Open() @@ -395,6 +405,19 @@ bool FGHIDDevice::Open() return false; } +#if !defined(SG_WINDOWS) + if (_rawXMLDescriptor.empty()) { + _rawXMLDescriptor.resize(2048); + int descriptorSize = hid_get_descriptor(_device, _rawXMLDescriptor.data(), _rawXMLDescriptor.size()); + if (descriptorSize <= 0) { + SG_LOG(SG_INPUT, SG_WARN, "HID: " << GetUniqueName() << " failed to read HID descriptor"); + return false; + } + + _rawXMLDescriptor.resize(descriptorSize); + } +#endif + if (!_haveLocalDescriptor) { bool ok = parseUSBHIDDescriptor(); if (!ok) @@ -422,26 +445,22 @@ bool FGHIDDevice::Open() bool FGHIDDevice::parseUSBHIDDescriptor() { #if defined(SG_WINDOWS) - SG_LOG(SG_INPUT, SG_ALERT, GetUniqueName() << ": on Windows, there is no way to extract the UDB-HID report descriptor. " - << "\nPlease supply the report descriptor in the device XML configuration."); - return false; -#endif - - unsigned char reportDescriptor[1024]; - int descriptorSize = hid_get_descriptor(_device, reportDescriptor, 1024); - if (descriptorSize <= 0) { - SG_LOG(SG_INPUT, SG_WARN, "HID: " << GetUniqueName() << " failed to read HID descriptor"); + if (_rawXMLDescriptor.empty()) { + SG_LOG(SG_INPUT, SG_ALERT, GetUniqueName() << ": on Windows, there is no way to extract the UDB-HID report descriptor. " + << "\nPlease supply the report descriptor in the device XML configuration."); + SG_LOG(SG_INPUT, SG_ALERT, "See this page:<> for information on extracting the report descriptor on Windows"); return false; } +#endif if (debugEvents) { SG_LOG(SG_INPUT, SG_INFO, "\nHID: descriptor for:" << GetUniqueName()); { std::ostringstream byteString; - for (int i=0; i> 4]; - byteString << hexTable[reportDescriptor[i] & 0x0f]; + for (auto i=0; i<_rawXMLDescriptor.size(); ++i) { + byteString << hexTable[_rawXMLDescriptor[i] >> 4]; + byteString << hexTable[_rawXMLDescriptor[i] & 0x0f]; byteString << " "; } SG_LOG(SG_INPUT, SG_INFO, "\tbytes: " << byteString.str()); @@ -449,7 +468,7 @@ bool FGHIDDevice::parseUSBHIDDescriptor() } hid_item* rootItem = nullptr; - hid_parse_reportdesc(reportDescriptor, descriptorSize, &rootItem); + hid_parse_reportdesc(_rawXMLDescriptor.data(), _rawXMLDescriptor.size(), &rootItem); if (debugEvents) { SG_LOG(SG_INPUT, SG_INFO, "\nHID: scan for:" << GetUniqueName()); }