1) Event -> LinuxEvent and Joystick -> LinuxJoystick 2) Rewritten Linux input device detection: introducing LinuxInputManager. It keeps IH_Linux_Event and IH_Linux_Joystick playing nice with each other, and will later be fundamental in hotplugging support.
This commit is contained in:
+2
-1
@@ -293,7 +293,8 @@ if UNIX
|
|||||||
ArchHooks += arch/ArchHooks/ArchHooks_Unix.cpp arch/ArchHooks/ArchHooks_Unix.h
|
ArchHooks += arch/ArchHooks/ArchHooks_Unix.cpp arch/ArchHooks/ArchHooks_Unix.h
|
||||||
|
|
||||||
if LINUX
|
if LINUX
|
||||||
InputHandler += arch/InputHandler/InputHandler_Linux_Joystick.cpp arch/InputHandler/InputHandler_Linux_Joystick.h \
|
InputHandler += arch/InputHandler/LinuxInputManager.cpp arch/InputHandler/LinuxInputManager.h \
|
||||||
|
arch/InputHandler/InputHandler_Linux_Joystick.cpp arch/InputHandler/InputHandler_Linux_Joystick.h \
|
||||||
arch/InputHandler/InputHandler_Linux_Event.cpp arch/InputHandler/InputHandler_Linux_Event.h \
|
arch/InputHandler/InputHandler_Linux_Event.cpp arch/InputHandler/InputHandler_Linux_Event.h \
|
||||||
arch/InputHandler/InputHandler_Linux_PIUIO.cpp arch/InputHandler/InputHandler_Linux_PIUIO.h
|
arch/InputHandler/InputHandler_Linux_PIUIO.cpp arch/InputHandler/InputHandler_Linux_PIUIO.h
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "InputHandler_Linux_Event.h"
|
#include "InputHandler_Linux_Event.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
|
#include "LinuxInputManager.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -11,9 +12,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
|
||||||
REGISTER_INPUT_HANDLER_CLASS2( Event, Linux_Event );
|
REGISTER_INPUT_HANDLER_CLASS2( LinuxEvent, Linux_Event );
|
||||||
|
|
||||||
bool InputHandler_Linux_Event::m_bFoundAnyJoysticks;
|
|
||||||
|
|
||||||
static RString BustypeToString( int iBus )
|
static RString BustypeToString( int iBus )
|
||||||
{
|
{
|
||||||
@@ -94,13 +93,7 @@ bool EventDevice::Open( RString sFile, InputDevice dev )
|
|||||||
m_iFD = open( sFile, O_RDWR );
|
m_iFD = open( sFile, O_RDWR );
|
||||||
if( m_iFD == -1 )
|
if( m_iFD == -1 )
|
||||||
{
|
{
|
||||||
if( errno == ENODEV )
|
// HACK: Let the caller handle errno.
|
||||||
return false;
|
|
||||||
|
|
||||||
if( !EventDeviceExists(m_iFD) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
LOG->Warn( "Error opening %s: %s", sFile.c_str(), strerror(errno) );
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,48 +266,33 @@ EventDevice::~EventDevice()
|
|||||||
|
|
||||||
InputHandler_Linux_Event::InputHandler_Linux_Event()
|
InputHandler_Linux_Event::InputHandler_Linux_Event()
|
||||||
{
|
{
|
||||||
if( InputHandler_Linux_Event::m_bFoundAnyJoysticks )
|
m_NextDevice = DEVICE_JOY1;
|
||||||
{
|
m_bDevicesChanged = false;
|
||||||
LOG->Trace( "InputHandler_Linux_Event disabled (joystick driver already loaded)" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Permission problems are likely. We want to warn about them only if there's actually
|
if(LINUXINPUT == NULL) LINUXINPUT = new LinuxInputManager;
|
||||||
* an underlying device, but if we can't open the device, the only way we can tell if
|
LINUXINPUT->InitDriver(this);
|
||||||
* there'd be anything there is sysfs. That won't always be there. */
|
|
||||||
m_bFoundAnyJoysticks = false;
|
|
||||||
InputDevice NextDevice = DEVICE_JOY1;
|
|
||||||
for( int i = 0; i < 64; ++i )
|
|
||||||
{
|
|
||||||
RString sFile = ssprintf( "/dev/input/event%i", i );
|
|
||||||
|
|
||||||
g_apEventDevices.push_back( new EventDevice );
|
if( ! g_apEventDevices.empty() ) // LinuxInputManager found at least one valid device for us
|
||||||
EventDevice *pDev = g_apEventDevices.back();
|
StartThread();
|
||||||
if( !pDev->Open(sFile, NextDevice) )
|
|
||||||
{
|
|
||||||
delete pDev;
|
|
||||||
g_apEventDevices.pop_back();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NextDevice = enum_add2(NextDevice, 1);
|
|
||||||
m_bFoundAnyJoysticks = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bShutdown = false;
|
|
||||||
|
|
||||||
if( m_bFoundAnyJoysticks )
|
|
||||||
{
|
|
||||||
m_InputThread.SetName( "Event input thread" );
|
|
||||||
m_InputThread.Create( InputThread_Start, this );
|
|
||||||
|
|
||||||
/* We loaded joysticks, so disable joydev. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputHandler_Linux_Event::~InputHandler_Linux_Event()
|
InputHandler_Linux_Event::~InputHandler_Linux_Event()
|
||||||
{
|
{
|
||||||
if( m_InputThread.IsCreated() )
|
if( m_InputThread.IsCreated() ) StopThread();
|
||||||
|
|
||||||
|
for( int i = 0; i < (int) g_apEventDevices.size(); ++i )
|
||||||
|
delete g_apEventDevices[i];
|
||||||
|
g_apEventDevices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHandler_Linux_Event::StartThread()
|
||||||
|
{
|
||||||
|
m_bShutdown = false;
|
||||||
|
m_InputThread.SetName( "Event input thread" );
|
||||||
|
m_InputThread.Create( InputThread_Start, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHandler_Linux_Event::StopThread()
|
||||||
{
|
{
|
||||||
m_bShutdown = true;
|
m_bShutdown = true;
|
||||||
LOG->Trace( "Shutting down joystick thread ..." );
|
LOG->Trace( "Shutting down joystick thread ..." );
|
||||||
@@ -322,9 +300,32 @@ InputHandler_Linux_Event::~InputHandler_Linux_Event()
|
|||||||
LOG->Trace( "Joystick thread shut down." );
|
LOG->Trace( "Joystick thread shut down." );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i = 0; i < (int) g_apEventDevices.size(); ++i )
|
bool InputHandler_Linux_Event::TryDevice(RString devfile)
|
||||||
delete g_apEventDevices[i];
|
{
|
||||||
g_apEventDevices.clear();
|
EventDevice* pDev = new EventDevice;
|
||||||
|
if( pDev->Open(devfile, m_NextDevice) )
|
||||||
|
{
|
||||||
|
bool hotplug = false;
|
||||||
|
if( m_InputThread.IsCreated() ) { StopThread(); hotplug = true; }
|
||||||
|
/* Thread is stopped! DO NOT RETURN */
|
||||||
|
{
|
||||||
|
g_apEventDevices.push_back( pDev );
|
||||||
|
}
|
||||||
|
if( hotplug ) StartThread();
|
||||||
|
|
||||||
|
m_NextDevice = enum_add2(m_NextDevice, 1);
|
||||||
|
m_bDevicesChanged = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete pDev;
|
||||||
|
// This is likely to fail; most systems still forbid ALL eventNN regardless
|
||||||
|
// of their type. Info it anyway, it could be useful for end-user
|
||||||
|
// troubleshooting.
|
||||||
|
LOG->Info("LinuxEvent: Couldn't open %s: %s.", devfile.c_str(), strerror(errno) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int InputHandler_Linux_Event::InputThread_Start( void *p )
|
int InputHandler_Linux_Event::InputThread_Start( void *p )
|
||||||
@@ -419,10 +420,13 @@ void InputHandler_Linux_Event::GetDevicesAndDescriptions( vector<InputDeviceInfo
|
|||||||
EventDevice *pDev = g_apEventDevices[i];
|
EventDevice *pDev = g_apEventDevices[i];
|
||||||
vDevicesOut.push_back( InputDeviceInfo(pDev->m_Dev, pDev->m_sName) );
|
vDevicesOut.push_back( InputDeviceInfo(pDev->m_Dev, pDev->m_sName) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_bDevicesChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2003-2008 Glenn Maynard
|
* (c) 2003-2008 Glenn Maynard
|
||||||
|
* (c) 2013 Ben "root" Anderson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
@@ -13,17 +13,19 @@ public:
|
|||||||
enum { NUM_JOYSTICKS = 4 };
|
enum { NUM_JOYSTICKS = 4 };
|
||||||
InputHandler_Linux_Event();
|
InputHandler_Linux_Event();
|
||||||
~InputHandler_Linux_Event();
|
~InputHandler_Linux_Event();
|
||||||
|
bool TryDevice(RString devfile);
|
||||||
|
bool DevicesChanged() { return m_bDevicesChanged; }
|
||||||
void GetDevicesAndDescriptions( vector<InputDeviceInfo>& vDevicesOut );
|
void GetDevicesAndDescriptions( vector<InputDeviceInfo>& vDevicesOut );
|
||||||
|
|
||||||
/* Shared with InputHandler_Linux_Joystick.cpp: */
|
|
||||||
static bool m_bFoundAnyJoysticks;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void StartThread();
|
||||||
|
void StopThread();
|
||||||
static int InputThread_Start( void *p );
|
static int InputThread_Start( void *p );
|
||||||
void InputThread();
|
void InputThread();
|
||||||
|
|
||||||
RageThread m_InputThread;
|
RageThread m_InputThread;
|
||||||
bool m_bShutdown;
|
InputDevice m_NextDevice;
|
||||||
|
bool m_bShutdown, m_bDevicesChanged;
|
||||||
};
|
};
|
||||||
#define USE_INPUT_HANDLER_LINUX_JOYSTICK
|
#define USE_INPUT_HANDLER_LINUX_JOYSTICK
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "InputHandler_Linux_Joystick.h"
|
#include "InputHandler_Linux_Joystick.h"
|
||||||
#include "InputHandler_Linux_Event.h" // for m_bFoundAnyJoysticks
|
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
|
#include "LinuxInputManager.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
REGISTER_INPUT_HANDLER_CLASS2( Joystick, Linux_Joystick );
|
REGISTER_INPUT_HANDLER_CLASS2( LinuxJoystick, Linux_Joystick );
|
||||||
|
|
||||||
static const char *Paths[InputHandler_Linux_Joystick::NUM_JOYSTICKS] =
|
static const char *Paths[InputHandler_Linux_Joystick::NUM_JOYSTICKS] =
|
||||||
{
|
{
|
||||||
@@ -26,72 +26,43 @@ static const char *Paths[InputHandler_Linux_Joystick::NUM_JOYSTICKS] =
|
|||||||
|
|
||||||
InputHandler_Linux_Joystick::InputHandler_Linux_Joystick()
|
InputHandler_Linux_Joystick::InputHandler_Linux_Joystick()
|
||||||
{
|
{
|
||||||
|
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)
|
for(int i = 0; i < NUM_JOYSTICKS; ++i)
|
||||||
fds[i] = -1;
|
fds[i] = -1;
|
||||||
|
|
||||||
if( InputHandler_Linux_Event::m_bFoundAnyJoysticks )
|
m_iLastFd = 0;
|
||||||
{
|
|
||||||
LOG->Trace( "InputHandler_Linux_Joystick disabled (joystick driver already loaded)" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We check both eg. /dev/js0 and /dev/input/js0. If both exist, they're probably
|
if( LINUXINPUT == NULL ) LINUXINPUT = new LinuxInputManager;
|
||||||
* the same device; keep track of device IDs so we don't open the same joystick
|
LINUXINPUT->InitDriver(this);
|
||||||
* twice. */
|
|
||||||
set< pair<int,int> > devices;
|
|
||||||
bool bFoundAnyJoysticks = false;
|
|
||||||
|
|
||||||
for(int i = 0; i < NUM_JOYSTICKS; ++i)
|
for(int i = 0; i < NUM_JOYSTICKS; ++i)
|
||||||
{
|
{
|
||||||
struct stat st;
|
|
||||||
if( stat( Paths[i], &st ) == -1 )
|
|
||||||
{
|
|
||||||
if( errno != ENOENT )
|
|
||||||
LOG->Warn( "Couldn't stat %s: %s", Paths[i], strerror(errno) );
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !S_ISCHR( st.st_mode ) )
|
if( fds[0] != -1 ) // LinuxInputManager found at least one valid joystick for us
|
||||||
{
|
StartThread();
|
||||||
LOG->Warn( "Ignoring %s: not a character device", Paths[i] );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<int,int> dev( major(st.st_rdev), minor(st.st_rdev) );
|
|
||||||
if( devices.find(dev) != devices.end() )
|
|
||||||
continue; /* dupe */
|
|
||||||
devices.insert( dev );
|
|
||||||
|
|
||||||
fds[i] = open( Paths[i], O_RDONLY );
|
|
||||||
|
|
||||||
if(fds[i] != -1)
|
|
||||||
{
|
|
||||||
char szName[1024];
|
|
||||||
ZERO( szName );
|
|
||||||
if( ioctl(fds[i], JSIOCGNAME(sizeof(szName)), szName) < 0 )
|
|
||||||
m_sDescription[i] = ssprintf( "Unknown joystick at %s", Paths[i] );
|
|
||||||
else
|
|
||||||
m_sDescription[i] = szName;
|
|
||||||
|
|
||||||
LOG->Info("Opened %s", Paths[i]);
|
|
||||||
bFoundAnyJoysticks = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bShutdown = false;
|
|
||||||
|
|
||||||
if( bFoundAnyJoysticks )
|
|
||||||
{
|
|
||||||
m_InputThread.SetName( "Joystick thread" );
|
|
||||||
m_InputThread.Create( InputThread_Start, this );
|
|
||||||
InputHandler_Linux_Event::m_bFoundAnyJoysticks = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputHandler_Linux_Joystick::~InputHandler_Linux_Joystick()
|
InputHandler_Linux_Joystick::~InputHandler_Linux_Joystick()
|
||||||
{
|
{
|
||||||
if( m_InputThread.IsCreated() )
|
if( m_InputThread.IsCreated() )
|
||||||
|
StopThread();
|
||||||
|
|
||||||
|
for(int i = 0; i < NUM_JOYSTICKS; ++i)
|
||||||
|
if(fds[i] != -1) close(fds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHandler_Linux_Joystick::StartThread()
|
||||||
|
{
|
||||||
|
m_bShutdown = false;
|
||||||
|
m_InputThread.SetName( "Joystick thread" );
|
||||||
|
m_InputThread.Create( InputThread_Start, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHandler_Linux_Joystick::StopThread()
|
||||||
{
|
{
|
||||||
m_bShutdown = true;
|
m_bShutdown = true;
|
||||||
LOG->Trace( "Shutting down joystick thread ..." );
|
LOG->Trace( "Shutting down joystick thread ..." );
|
||||||
@@ -99,8 +70,41 @@ InputHandler_Linux_Joystick::~InputHandler_Linux_Joystick()
|
|||||||
LOG->Trace( "Joystick thread shut down." );
|
LOG->Trace( "Joystick thread shut down." );
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < NUM_JOYSTICKS; ++i)
|
bool InputHandler_Linux_Joystick::TryDevice(RString dev)
|
||||||
if(fds[i] != -1) close(fds[i]);
|
{
|
||||||
|
bool hotplug = false;
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if( stat( dev, &st ) == -1 )
|
||||||
|
{ LOG->Warn( "LinuxJoystick: Couldn't stat %s: %s", dev.c_str(), strerror(errno) ); return false; }
|
||||||
|
|
||||||
|
if( !S_ISCHR( st.st_mode ) )
|
||||||
|
{ LOG->Warn( "LinuxJoystick: Ignoring %s: not a character device", dev.c_str() ); return false; }
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
if( m_InputThread.IsCreated() ) { StopThread(); hotplug = true; }
|
||||||
|
/* Thread is stopped! DO NOT RETURN */
|
||||||
|
{
|
||||||
|
fds[m_iLastFd] = open( dev, O_RDONLY );
|
||||||
|
|
||||||
|
if(fds[m_iLastFd] != -1)
|
||||||
|
{
|
||||||
|
char szName[1024];
|
||||||
|
ZERO( szName );
|
||||||
|
if( ioctl(fds[m_iLastFd], JSIOCGNAME(sizeof(szName)), szName) < 0 )
|
||||||
|
m_sDescription[m_iLastFd] = ssprintf( "Unknown joystick at %s", dev.c_str() );
|
||||||
|
else
|
||||||
|
m_sDescription[m_iLastFd] = szName;
|
||||||
|
|
||||||
|
LOG->Info("LinuxJoystick: Opened %s", dev.c_str() );
|
||||||
|
m_iLastFd++;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
else LOG->Warn("LinuxJoystick: Failed to open %s: %s", dev.c_str(), strerror(errno) );
|
||||||
|
}
|
||||||
|
if( hotplug ) StartThread();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InputHandler_Linux_Joystick::InputThread_Start( void *p )
|
int InputHandler_Linux_Joystick::InputThread_Start( void *p )
|
||||||
@@ -197,10 +201,12 @@ void InputHandler_Linux_Joystick::GetDevicesAndDescriptions( vector<InputDeviceI
|
|||||||
|
|
||||||
vDevicesOut.push_back( InputDeviceInfo(InputDevice(DEVICE_JOY1+i), m_sDescription[i]) );
|
vDevicesOut.push_back( InputDeviceInfo(InputDevice(DEVICE_JOY1+i), m_sDescription[i]) );
|
||||||
}
|
}
|
||||||
|
m_bDevicesChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2003-2004 Glenn Maynard
|
* (c) 2003-2004 Glenn Maynard
|
||||||
|
* (c) 2013 Ben "root" Anderson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
@@ -11,16 +11,21 @@ public:
|
|||||||
enum { NUM_JOYSTICKS = 4 };
|
enum { NUM_JOYSTICKS = 4 };
|
||||||
InputHandler_Linux_Joystick();
|
InputHandler_Linux_Joystick();
|
||||||
~InputHandler_Linux_Joystick();
|
~InputHandler_Linux_Joystick();
|
||||||
|
bool TryDevice(RString dev);
|
||||||
|
bool DevicesChanged() { return m_bDevicesChanged; }
|
||||||
void GetDevicesAndDescriptions( vector<InputDeviceInfo>& vDevicesOut );
|
void GetDevicesAndDescriptions( vector<InputDeviceInfo>& vDevicesOut );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void StartThread();
|
||||||
|
void StopThread();
|
||||||
static int InputThread_Start( void *p );
|
static int InputThread_Start( void *p );
|
||||||
void InputThread();
|
void InputThread();
|
||||||
|
|
||||||
int fds[NUM_JOYSTICKS];
|
int fds[NUM_JOYSTICKS];
|
||||||
|
int m_iLastFd;
|
||||||
RString m_sDescription[NUM_JOYSTICKS];
|
RString m_sDescription[NUM_JOYSTICKS];
|
||||||
RageThread m_InputThread;
|
RageThread m_InputThread;
|
||||||
bool m_bShutdown;
|
bool m_bShutdown, m_bDevicesChanged;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
#include "LinuxInputManager.h"
|
||||||
|
|
||||||
|
#include "InputHandler_Linux_Event.h"
|
||||||
|
#include "InputHandler_Linux_Joystick.h"
|
||||||
|
|
||||||
|
#include "RageInput.h" // g_sInputDrivers
|
||||||
|
#include "RageLog.h"
|
||||||
|
#include "Foreach.h"
|
||||||
|
|
||||||
|
#include <string> // std::string::npos
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
RString getDevice(RString inputDir, RString type)
|
||||||
|
{
|
||||||
|
DIR* dir = opendir( inputDir.c_str() );
|
||||||
|
if(dir == NULL)
|
||||||
|
{ LOG->Warn("LinuxInputManager: Couldn't open %s: %s.", inputDir.c_str(), strerror(errno) ); return ""; }
|
||||||
|
|
||||||
|
struct dirent* d;
|
||||||
|
while( ( d = readdir(dir) ) != NULL)
|
||||||
|
if( strncmp( type.c_str(), d->d_name, type.size() ) == 0) break;
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
if( d == NULL ) return "";
|
||||||
|
return RString("/dev/input/") + d->d_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxInputManager::LinuxInputManager()
|
||||||
|
{
|
||||||
|
m_bEventEnabled = g_sInputDrivers.Get().find("LinuxEvent") != std::string::npos;
|
||||||
|
m_bJoystickEnabled = g_sInputDrivers.Get().find("LinuxJoystick") != std::string::npos;
|
||||||
|
// HACK: If empty, assume both are enabled
|
||||||
|
if( g_sInputDrivers.Get() == "" )
|
||||||
|
{ m_bEventEnabled = true; m_bJoystickEnabled = true; }
|
||||||
|
|
||||||
|
m_EventDriver = NULL;
|
||||||
|
m_JoystickDriver = NULL;
|
||||||
|
|
||||||
|
// XXX: Can I use RageFile for this?
|
||||||
|
DIR* sysClassInput = opendir("/sys/class/input");
|
||||||
|
if( sysClassInput == NULL )
|
||||||
|
{
|
||||||
|
// XXX: Probably should throw a Dialog. But Linux doesn't have a DialogDriver yet so eh.
|
||||||
|
LOG->Warn("Couldn't open /sys/class/input: %s. Joysticks will not work!", strerror(errno) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent* d;
|
||||||
|
while( ( d = readdir(sysClassInput) ) != NULL)
|
||||||
|
{
|
||||||
|
if( strncmp( "input", d->d_name, 5) != 0) continue;
|
||||||
|
|
||||||
|
RString dName = RString("/sys/class/input/") + d->d_name;
|
||||||
|
|
||||||
|
bool bEventPresent = getDevice(dName, "event") != "";
|
||||||
|
if( m_bEventEnabled && bEventPresent )
|
||||||
|
{ m_vsPendingEventDevices.push_back(dName); continue; }
|
||||||
|
|
||||||
|
bool bJoystickPresent = getDevice(dName, "js") != "";
|
||||||
|
if( m_bJoystickEnabled && bJoystickPresent )
|
||||||
|
{ m_vsPendingJoystickDevices.push_back(dName); continue; }
|
||||||
|
|
||||||
|
if( !bEventPresent && !bJoystickPresent )
|
||||||
|
LOG->Info("LinuxInputManager: %s seems to have no eventNN or jsNN.", dName.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxInputManager::InitDriver(InputHandler_Linux_Event* driver)
|
||||||
|
{
|
||||||
|
m_EventDriver = driver;
|
||||||
|
|
||||||
|
FOREACH(RString, m_vsPendingEventDevices, dev)
|
||||||
|
{
|
||||||
|
RString devFile = getDevice(*dev, "event");
|
||||||
|
ASSERT( devFile != "" );
|
||||||
|
|
||||||
|
if( ! driver->TryDevice(devFile) && m_bJoystickEnabled && getDevice(*dev, "js") != "" )
|
||||||
|
m_vsPendingJoystickDevices.push_back(*dev);
|
||||||
|
}
|
||||||
|
if( m_JoystickDriver != NULL ) InitDriver(m_JoystickDriver);
|
||||||
|
|
||||||
|
m_vsPendingEventDevices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxInputManager::InitDriver(InputHandler_Linux_Joystick* driver)
|
||||||
|
{
|
||||||
|
m_JoystickDriver = driver;
|
||||||
|
|
||||||
|
FOREACH(RString, m_vsPendingJoystickDevices, dev)
|
||||||
|
{
|
||||||
|
RString devFile = getDevice(*dev, "js");
|
||||||
|
ASSERT( devFile != "" );
|
||||||
|
|
||||||
|
driver->TryDevice(devFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vsPendingJoystickDevices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxInputManager* LINUXINPUT = NULL; // global and accessible anywhere in our program
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (c) 2013 Ben "root" Anderson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||||
|
* whom the Software is furnished to do so, provided that the above
|
||||||
|
* copyright notice(s) and this permission notice appear in all copies of
|
||||||
|
* the Software and that both the above copyright notice(s) and this
|
||||||
|
* permission notice appear in supporting documentation.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||||
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||||
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||||
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef LINUX_INPUT_MANAGER
|
||||||
|
#define LINUX_INPUT_MANAGER 1
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
class InputHandler_Linux_Joystick;
|
||||||
|
class InputHandler_Linux_Event;
|
||||||
|
|
||||||
|
// Enumerates the input devices on the system and dispatches them to
|
||||||
|
// IH_Linux_Event and IH_Linux_Joystick as appropriate.
|
||||||
|
|
||||||
|
class LinuxInputManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LinuxInputManager();
|
||||||
|
void InitDriver(InputHandler_Linux_Joystick* drv);
|
||||||
|
void InitDriver(InputHandler_Linux_Event* drv);
|
||||||
|
~LinuxInputManager();
|
||||||
|
private:
|
||||||
|
bool m_bEventEnabled;
|
||||||
|
InputHandler_Linux_Event* m_EventDriver;
|
||||||
|
vector<RString> m_vsPendingEventDevices;
|
||||||
|
|
||||||
|
bool m_bJoystickEnabled;
|
||||||
|
InputHandler_Linux_Joystick* m_JoystickDriver;
|
||||||
|
vector<RString> m_vsPendingJoystickDevices;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern LinuxInputManager* LINUXINPUT; // global and accessible from anywhere in our program
|
||||||
|
|
||||||
|
#endif // LINUX_INPUT_MANAGER
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (c) 2013 Ben "root" Anderson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||||
|
* whom the Software is furnished to do so, provided that the above
|
||||||
|
* copyright notice(s) and this permission notice appear in all copies of
|
||||||
|
* the Software and that both the above copyright notice(s) and this
|
||||||
|
* permission notice appear in supporting documentation.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||||
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||||
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||||
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
@@ -37,6 +37,8 @@ void MakeInputHandlers( const RString &drivers, vector<InputHandler *> &Add )
|
|||||||
#ifdef USE_INPUT_HANDLER_LINUX_JOYSTICK
|
#ifdef USE_INPUT_HANDLER_LINUX_JOYSTICK
|
||||||
if( !s->CompareNoCase("Joystick") ) ret = new InputHandler_Linux_Joystick;
|
if( !s->CompareNoCase("Joystick") ) ret = new InputHandler_Linux_Joystick;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_INPUT_HANDLER_LINUX_EVENT
|
||||||
|
if !s->CompareNocase("LinuxEvent") ) ret = new InputHandler_Linux_Event;
|
||||||
#ifdef USE_INPUT_HANDLER_LINUX_TTY
|
#ifdef USE_INPUT_HANDLER_LINUX_TTY
|
||||||
if( !s->CompareNoCase("tty") ) ret = new InputHandler_Linux_tty;
|
if( !s->CompareNoCase("tty") ) ret = new InputHandler_Linux_tty;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#include "LoadingWindow/LoadingWindow_Gtk.h"
|
#include "LoadingWindow/LoadingWindow_Gtk.h"
|
||||||
#endif
|
#endif
|
||||||
#if defined(LINUX)
|
#if defined(LINUX)
|
||||||
#define DEFAULT_INPUT_DRIVER_LIST "X11,Event,Joystick"
|
#define DEFAULT_INPUT_DRIVER_LIST "X11,LinuxEvent,LinuxJoystick"
|
||||||
#else
|
#else
|
||||||
#define DEFAULT_INPUT_DRIVER_LIST "X11"
|
#define DEFAULT_INPUT_DRIVER_LIST "X11"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user