Remove limit of 4 joysticks in InputHandler_Linux_Joystick

This commit is contained in:
Gareth Francis
2024-04-10 20:17:11 -07:00
committed by teejusb
parent 7009a16dea
commit ef86cbbda3
2 changed files with 39 additions and 38 deletions
@@ -28,15 +28,11 @@ InputHandler_Linux_Joystick::InputHandler_Linux_Joystick()
m_bDevicesChanged = false; m_bDevicesChanged = false;
LOG->Trace( "InputHandler_Linux_Joystick::InputHandler_Linux_Joystick" ); LOG->Trace( "InputHandler_Linux_Joystick::InputHandler_Linux_Joystick" );
for(int i = 0; i < NUM_JOYSTICKS; ++i)
fds[i] = -1;
m_iLastFd = 0;
if( LINUXINPUT == nullptr ) LINUXINPUT = new LinuxInputManager; if( LINUXINPUT == nullptr ) LINUXINPUT = new LinuxInputManager;
LINUXINPUT->InitDriver(this); LINUXINPUT->InitDriver(this);
if( fds[0] != -1 ) // LinuxInputManager found at least one valid joystick for us if( !m_files.empty() ) // LinuxInputManager found at least one valid joystick for us
StartThread(); StartThread();
} }
@@ -45,8 +41,10 @@ InputHandler_Linux_Joystick::~InputHandler_Linux_Joystick()
if( m_InputThread.IsCreated() ) if( m_InputThread.IsCreated() )
StopThread(); StopThread();
for(int i = 0; i < NUM_JOYSTICKS; ++i) for( auto& f : m_files ) {
if(fds[i] != -1) close(fds[i]); if( f.file != -1 ) close(f.file);
}
m_files.clear();
} }
void InputHandler_Linux_Joystick::StartThread() void InputHandler_Linux_Joystick::StartThread()
@@ -78,21 +76,22 @@ bool InputHandler_Linux_Joystick::TryDevice(RString dev)
if( m_InputThread.IsCreated() ) { StopThread(); hotplug = true; } if( m_InputThread.IsCreated() ) { StopThread(); hotplug = true; }
/* Thread is stopped! DO NOT RETURN */ /* Thread is stopped! DO NOT RETURN */
{ {
fds[m_iLastFd] = open( dev, O_RDONLY ); FileDescriptor f;
f.file = open( dev, O_RDONLY );
if(fds[m_iLastFd] != -1) if(f.file != -1)
{ {
char szName[1024]; char szName[1024];
ZERO( szName ); ZERO( szName );
if( ioctl(fds[m_iLastFd], JSIOCGNAME(sizeof(szName)), szName) < 0 ) if( ioctl(f.file, JSIOCGNAME(sizeof(szName)), szName) < 0 )
m_sDescription[m_iLastFd] = ssprintf( "Unknown joystick at %s", dev.c_str() ); f.description = ssprintf( "Unknown joystick at %s", dev.c_str() );
else else
m_sDescription[m_iLastFd] = szName; f.description = szName;
LOG->Info("LinuxJoystick: Opened %s", dev.c_str() ); LOG->Info("LinuxJoystick: Opened %s", dev.c_str() );
m_iLastFd++;
m_bDevicesChanged = true; m_bDevicesChanged = true;
ret = true; ret = true;
m_files.push_back(f);
} }
else LOG->Warn("LinuxJoystick: Failed to open %s: %s", dev.c_str(), strerror(errno) ); else LOG->Warn("LinuxJoystick: Failed to open %s: %s", dev.c_str(), strerror(errno) );
} }
@@ -115,13 +114,13 @@ void InputHandler_Linux_Joystick::InputThread()
FD_ZERO(&fdset); FD_ZERO(&fdset);
int max_fd = -1; int max_fd = -1;
for(int i = 0; i < NUM_JOYSTICKS; ++i) for(int i = 0; i < m_files.size(); ++i)
{ {
if (fds[i] < 0) if (m_files[i].file < 0)
continue; continue;
FD_SET(fds[i], &fdset); FD_SET(m_files[i].file, &fdset);
max_fd = std::max(max_fd, fds[i]); max_fd = std::max(max_fd, m_files[i].file);
} }
if(max_fd == -1) if(max_fd == -1)
@@ -132,30 +131,30 @@ void InputHandler_Linux_Joystick::InputThread()
continue; continue;
RageTimer now; RageTimer now;
for(int i = 0; i < NUM_JOYSTICKS; ++i) for(int i = 0; i < m_files.size(); ++i)
{ {
if( fds[i] == -1 ) if( m_files[i].file == -1 )
continue; continue;
if(!FD_ISSET(fds[i], &fdset)) if(!FD_ISSET(m_files[i].file, &fdset))
continue; continue;
js_event event; js_event event;
int ret = read(fds[i], &event, sizeof(event)); int ret = read(m_files[i].file, &event, sizeof(event));
if(ret == -1) if(ret == -1)
{ {
LOG->Warn("Error reading from joystick %i: %s; disabled", i, strerror(errno)); LOG->Warn("Error reading from joystick %i: %s; disabled", i, strerror(errno));
close(fds[i]); close(m_files[i].file);
fds[i] = -1; m_files[i].file = -1;
continue; continue;
} }
if(ret != sizeof(event)) if(ret != sizeof(event))
{ {
LOG->Warn("Unexpected packet (size %i != %i) from joystick %i; disabled", ret, (int)sizeof(event), i); LOG->Warn("Unexpected packet (size %i != %i) from joystick %i; disabled", ret, (int)sizeof(event), i);
close(fds[i]); close(m_files[i].file);
fds[i] = -1; m_files[i].file = -1;
continue; continue;
} }
@@ -183,8 +182,8 @@ void InputHandler_Linux_Joystick::InputThread()
default: default:
LOG->Warn("Unexpected packet (type %i) from joystick %i; disabled", event.type, i); LOG->Warn("Unexpected packet (type %i) from joystick %i; disabled", event.type, i);
close(fds[i]); close(m_files[i].file);
fds[i] = -1; m_files[i].file = -1;
continue; continue;
} }
@@ -200,14 +199,14 @@ void InputHandler_Linux_Joystick::GetDevicesAndDescriptions( std::vector<InputDe
// HACK: If IH_Linux_Joystick is constructed before IH_Linux_Event, our thread won't be started // HACK: If IH_Linux_Joystick is constructed before IH_Linux_Event, our thread won't be started
// as part of the constructor. This isn't called until all InputHandlers have been constructed, // as part of the constructor. This isn't called until all InputHandlers have been constructed,
// and is (hopefully) in the same thread as TryDevice... so doublecheck our thread now. // and is (hopefully) in the same thread as TryDevice... so doublecheck our thread now.
if( fds[0] != -1 && !m_InputThread.IsCreated() ) StartThread(); if( m_files.empty() && !m_InputThread.IsCreated() ) StartThread();
for(int i = 0; i < NUM_JOYSTICKS; ++i) for(int i = 0; i < m_files.size(); ++i)
{ {
if (fds[i] < 0) if (m_files[i].file < 0)
continue; continue;
vDevicesOut.push_back( InputDeviceInfo(InputDevice(DEVICE_JOY1+i), m_sDescription[i]) ); vDevicesOut.push_back( InputDeviceInfo(InputDevice(DEVICE_JOY1+i), m_files[i].description) );
} }
m_bDevicesChanged = false; m_bDevicesChanged = false;
} }
@@ -6,11 +6,9 @@
#include <vector> #include <vector>
class InputHandler_Linux_Joystick: public InputHandler class InputHandler_Linux_Joystick: public InputHandler
{ {
public: public:
enum { NUM_JOYSTICKS = 4 };
InputHandler_Linux_Joystick(); InputHandler_Linux_Joystick();
~InputHandler_Linux_Joystick(); ~InputHandler_Linux_Joystick();
bool TryDevice(RString dev); bool TryDevice(RString dev);
@@ -23,11 +21,15 @@ private:
static int InputThread_Start( void *p ); static int InputThread_Start( void *p );
void InputThread(); void InputThread();
int fds[NUM_JOYSTICKS]; struct FileDescriptor {
int m_iLastFd; int file = -1;
RString m_sDescription[NUM_JOYSTICKS]; RString description = "";
};
std::vector<FileDescriptor> m_files;
RageThread m_InputThread; RageThread m_InputThread;
bool m_bShutdown, m_bDevicesChanged; bool m_bShutdown = false;
bool m_bDevicesChanged = false;
}; };
#endif #endif