HID-input: don’t crash when open fails
Important since hidraw devices need special permissions on Linux.
This commit is contained in:
parent
2538ab717a
commit
01f0f27c84
6 changed files with 50 additions and 20 deletions
|
@ -410,8 +410,12 @@ unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
|
|||
inputDevice->Configure( deviceNode );
|
||||
|
||||
try {
|
||||
inputDevice->Open();
|
||||
bool ok = inputDevice->Open();
|
||||
if (ok) {
|
||||
input_devices[ deviceNode->getIndex() ] = inputDevice;
|
||||
} else {
|
||||
throw sg_exception("Opening input device failed");
|
||||
}
|
||||
}
|
||||
catch( ... ) {
|
||||
delete inputDevice;
|
||||
|
|
|
@ -223,7 +223,7 @@ public:
|
|||
|
||||
virtual ~FGInputDevice();
|
||||
|
||||
virtual void Open() = 0;
|
||||
virtual bool Open() = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual void Send( const char * eventName, double value ) = 0;
|
||||
|
|
|
@ -219,7 +219,7 @@ public:
|
|||
|
||||
virtual ~FGHIDDevice();
|
||||
|
||||
void Open() override;
|
||||
bool Open() override;
|
||||
void Close() override;
|
||||
|
||||
void update(double dt) override;
|
||||
|
@ -322,15 +322,17 @@ FGHIDDevice::FGHIDDevice(hid_device_info *devInfo, FGHIDEventInput *)
|
|||
|
||||
FGHIDDevice::~FGHIDDevice()
|
||||
{
|
||||
|
||||
if (_device) {
|
||||
hid_close(_device);
|
||||
}
|
||||
}
|
||||
|
||||
void FGHIDDevice::Open()
|
||||
bool FGHIDDevice::Open()
|
||||
{
|
||||
_device = hid_open_path(_hidPath.c_str());
|
||||
if (_device == 0) {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "Failed to open:" << _hidPath);
|
||||
return;
|
||||
if (_device == nullptr) {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "HID: Failed to open:" << _hidPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char reportDescriptor[1024];
|
||||
|
@ -354,6 +356,8 @@ void FGHIDDevice::Open()
|
|||
// SG_LOG(SG_INPUT, SG_INFO, "found item for event:" << v.first);
|
||||
reportItem.second->event = event;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FGHIDDevice::scanCollection(hid_item* c)
|
||||
|
@ -475,11 +479,18 @@ void FGHIDDevice::scanItem(hid_item* item)
|
|||
|
||||
void FGHIDDevice::Close()
|
||||
{
|
||||
if (_device) {
|
||||
hid_close(_device);
|
||||
_device = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FGHIDDevice::update(double dt)
|
||||
{
|
||||
if (!_device) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t reportBuf[65];
|
||||
int readCount = 0;
|
||||
while (true) {
|
||||
|
@ -528,6 +539,10 @@ void writeBits(uint8_t* bytes, size_t bitOffset, size_t bitSize, int value)
|
|||
|
||||
void FGHIDDevice::sendReport(Report* report) const
|
||||
{
|
||||
if (!_device) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t reportBytes[65];
|
||||
size_t reportLength = 0;
|
||||
memset(reportBytes, 0, sizeof(reportBytes));
|
||||
|
@ -632,6 +647,10 @@ void FGHIDDevice::processInputReport(Report* report, unsigned char* data,
|
|||
|
||||
void FGHIDDevice::SendFeatureReport(unsigned int reportId, const std::string& data)
|
||||
{
|
||||
if (!_device) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buf[65];
|
||||
size_t len = std::min(data.length() + 1, sizeof(buf));
|
||||
buf[0] = reportId;
|
||||
|
|
|
@ -286,9 +286,9 @@ static inline bool bitSet( unsigned char * buf, unsigned bit )
|
|||
return (buf[bit/sizeof(unsigned char)/8] >> (bit%(sizeof(unsigned char)*8))) & 1;
|
||||
}
|
||||
|
||||
void FGLinuxInputDevice::Open()
|
||||
bool FGLinuxInputDevice::Open()
|
||||
{
|
||||
if( fd != -1 ) return;
|
||||
if( fd != -1 ) return true;
|
||||
if( (fd = ::open( devname.c_str(), O_RDWR )) == -1 ) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
@ -371,6 +371,8 @@ void FGLinuxInputDevice::Open()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double FGLinuxInputDevice::Normalize( struct input_event & event )
|
||||
|
|
|
@ -45,10 +45,10 @@ public:
|
|||
FGLinuxInputDevice( std::string name, std::string devname, std::string aSerial );
|
||||
virtual ~FGLinuxInputDevice();
|
||||
|
||||
virtual void Open();
|
||||
virtual void Close();
|
||||
virtual void Send( const char * eventName, double value );
|
||||
virtual const char * TranslateEventName( FGEventData & eventData );
|
||||
bool Open() override;
|
||||
void Close() override;
|
||||
void Send( const char * eventName, double value ) override;
|
||||
const char * TranslateEventName( FGEventData & eventData ) override;
|
||||
|
||||
void SetDevname( const std::string & name );
|
||||
std::string GetDevname() const { return devname; }
|
||||
|
|
|
@ -153,7 +153,7 @@ public:
|
|||
|
||||
virtual ~FGMacOSXInputDevice();
|
||||
|
||||
void Open() override;
|
||||
bool Open() override;
|
||||
void Close() override;
|
||||
|
||||
virtual void update(double dt);
|
||||
|
@ -344,16 +344,21 @@ FGMacOSXInputDevice::~FGMacOSXInputDevice()
|
|||
CFRelease(_hid);
|
||||
}
|
||||
|
||||
void FGMacOSXInputDevice::Open()
|
||||
bool FGMacOSXInputDevice::Open()
|
||||
{
|
||||
IOReturn result = IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
|
||||
if (result != kIOReturnSuccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
|
||||
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
|
||||
|
||||
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDQueueStart(_queue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FGMacOSXInputDevice::buildElementNameDictionary()
|
||||
|
|
Loading…
Reference in a new issue