diff --git a/src/Input/FGEventInput.cxx b/src/Input/FGEventInput.cxx index ad0e71cfa..9281ad6b1 100644 --- a/src/Input/FGEventInput.cxx +++ b/src/Input/FGEventInput.cxx @@ -241,11 +241,12 @@ void FGInputDevice::Configure( SGPropertyNode_ptr aDeviceNode ) { deviceNode = aDeviceNode; - nasalModule = string("__event:") + GetName(); + // use _uniqueName here so each loaded device gets its own Nasal module + nasalModule = string("__event:") + _uniqueName; - PropertyList eventNodes = deviceNode->getChildren( "event" ); - for( PropertyList::iterator it = eventNodes.begin(); it != eventNodes.end(); ++it ) - AddHandledEvent( FGInputEvent::NewObject( this, *it ) ); + for (auto ev : deviceNode->getChildren( "event" )) { + AddHandledEvent( FGInputEvent::NewObject( this, ev) ); + } debugEvents = deviceNode->getBoolValue("debug-events", debugEvents ); grab = deviceNode->getBoolValue("grab", grab ); @@ -300,7 +301,7 @@ void FGInputDevice::HandleEvent( FGEventData & eventData ) { string eventName = TranslateEventName( eventData ); if( debugEvents ) { - SG_LOG(SG_INPUT, SG_INFO, GetName() << " has event " << + SG_LOG(SG_INPUT, SG_INFO, GetUniqueName() << " has event " << eventName << " modifiers=" << eventData.modifiers << " value=" << eventData.value); } @@ -314,6 +315,11 @@ void FGInputDevice::SetName( string name ) this->name = name; } +void FGInputDevice::SetUniqueName(const std::string &name) +{ + _uniqueName = name; +} + void FGInputDevice::SetSerialNumber( std::string serial ) { serialNumber = serial; @@ -393,12 +399,13 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice ) configNode = configMap.configurationForDeviceName(nameWithSerial); SG_LOG(SG_INPUT, SG_INFO, "using instance-specific configuration for device " << nameWithSerial << " : " << configNode->getStringValue("source")); + inputDevice->SetUniqueName(nameWithSerial); } } // try instanced (counted) name + const auto nameWithIndex = computeDeviceIndexName(inputDevice); if (configNode == nullptr) { - const auto nameWithIndex = computeDeviceIndexName(inputDevice); if (configMap.hasConfiguration(nameWithIndex)) { configNode = configMap.configurationForDeviceName(nameWithIndex); SG_LOG(SG_INPUT, SG_INFO, "using instance-specific configuration for device " @@ -406,7 +413,7 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice ) } } - // otherwise try the unmodifed name for the device + // otherwise try the unmodifed name for the device if (configNode == nullptr) { if (!configMap.hasConfiguration(deviceName)) { SG_LOG(SG_INPUT, SG_DEBUG, "No configuration found for device " << deviceName); @@ -416,8 +423,13 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice ) configNode = configMap.configurationForDeviceName(deviceName); } - // found - copy to /input/event/device[n] + // if we didn't generate a name based on the serial number, + // use the name with the index suffix _0, _1, etc + if (inputDevice->GetUniqueName().empty()) { + inputDevice->SetUniqueName(nameWithIndex); + } + // found - copy to /input/event/device[n] // find a free index unsigned int index; for ( index = 0; index < MAX_DEVICES; index++ ) { @@ -426,7 +438,7 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice ) } if (index == MAX_DEVICES) { - SG_LOG(SG_INPUT, SG_WARN, "To many event devices - ignoring " << inputDevice->GetName() ); + SG_LOG(SG_INPUT, SG_WARN, "To many event devices - ignoring " << inputDevice->GetUniqueName() ); delete inputDevice; return INVALID_DEVICE_INDEX; } @@ -449,11 +461,11 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice ) } catch( ... ) { delete inputDevice; - SG_LOG(SG_INPUT, SG_ALERT, "can't open InputDevice " << inputDevice->GetName() ); + SG_LOG(SG_INPUT, SG_ALERT, "can't open InputDevice " << inputDevice->GetUniqueName() ); return INVALID_DEVICE_INDEX; } - SG_LOG(SG_INPUT, SG_DEBUG, "using InputDevice " << inputDevice->GetName() ); + SG_LOG(SG_INPUT, SG_DEBUG, "using InputDevice " << inputDevice->GetUniqueName() ); return deviceNode->getIndex(); } diff --git a/src/Input/FGEventInput.hxx b/src/Input/FGEventInput.hxx index 9417807dd..6034b2321 100644 --- a/src/Input/FGEventInput.hxx +++ b/src/Input/FGEventInput.hxx @@ -240,6 +240,10 @@ public: void SetName( std::string name ); std::string & GetName() { return name; } + void SetUniqueName(const std::string& name); + const std::string GetUniqueName() const + { return _uniqueName; } + void SetSerialNumber( std::string serial ); std::string& GetSerialNumber() { return serialNumber; } @@ -280,6 +284,11 @@ protected: std::string nasalModule; report_setting_list_t reportSettings; + + /// name, but with suffix / serial appended. This is important + /// when loading the device multiple times, to ensure the Nasal + /// module is unique + std::string _uniqueName; }; typedef SGSharedPtr FGInputDevice_ptr; diff --git a/src/Input/FGHIDEventInput.cxx b/src/Input/FGHIDEventInput.cxx index 2b1e2bc4a..4375e2675 100644 --- a/src/Input/FGHIDEventInput.cxx +++ b/src/Input/FGHIDEventInput.cxx @@ -315,28 +315,20 @@ FGHIDDevice::FGHIDDevice(hid_device_info *devInfo, FGHIDEventInput *) { _hidPath = devInfo->path; - std::wstring manufactuerName, + std::wstring manufacturerName, productName = std::wstring(devInfo->product_string); if (devInfo->manufacturer_string) { - manufactuerName = std::wstring(devInfo->manufacturer_string); - SetName(simgear::strutils::convertWStringToUtf8(manufactuerName) + " " + + manufacturerName = std::wstring(devInfo->manufacturer_string); + SetName(simgear::strutils::convertWStringToUtf8(manufacturerName) + " " + simgear::strutils::convertWStringToUtf8(productName)); } else { SetName(simgear::strutils::convertWStringToUtf8(productName)); } const auto serial = devInfo->serial_number; - // every device so far encountered returns a blank serial number, so we - // fall back to the device path to disambiguate. std::string path(devInfo->path); - if ((serial == nullptr) || std::wcslen(serial) == 0) { - // use device path to disambiguate - if (!path.empty()) { - SG_LOG(SG_INPUT, SG_INFO, "Missing serial on device '" << - simgear::strutils::convertWStringToUtf8(productName) << "', using path: " << path); - SetSerialNumber(path); - } - } else { + // most devices rreturnturn an empty serial number, unfortunately + if ((serial != nullptr) && std::wcslen(serial) > 0) { SetSerialNumber(simgear::strutils::convertWStringToUtf8(serial)); } } @@ -488,11 +480,11 @@ void FGHIDDevice::scanItem(hid_item* item) auto report = getReport(ty, item->report_id, true /* create */); uint32_t bitOffset = report->currentBitSize(); - SG_LOG(SG_INPUT, SG_INFO, "adding item:" << name); + // SG_LOG(SG_INPUT, SG_INFO, "adding item:" << name); Item* itemObject = new Item{name, bitOffset, item->report_size}; itemObject->isRelative = hid_parse_is_relative(item); - SG_LOG(SG_INPUT, SG_INFO, "\t logical min-max:" << item->logical_min << " / " << item->logical_max); + // SG_LOG(SG_INPUT, SG_INFO, "\t logical min-max:" << item->logical_min << " / " << item->logical_max); itemObject->doSignExtend = (item->logical_min < 0) || (item->logical_max < 0); report->items.push_back(itemObject);