Remove limit of 4 joysticks in InputHandler_Linux_Joystick
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user