sort by location

This commit is contained in:
din
2025-03-01 23:25:47 -08:00
committed by teejusb
parent 4d8d22d223
commit f0394b721e
2 changed files with 101 additions and 23 deletions
+71 -3
View File
@@ -13,8 +13,16 @@
#include <dirent.h>
#endif
#if defined(HAVE_FCNTL_H)
#include <fcntl.h>
#endif
#include <linux/input.h>
#include <errno.h>
Preference<bool> g_bInputLinuxOrderByLocation( "InputLinuxOrderByLocation", false );
RString getDevice(RString inputDir, RString type)
{
RString result = "";
@@ -78,13 +86,73 @@ LinuxInputManager::LinuxInputManager()
LOG->Info("LinuxInputManager: %s seems to have no eventNN or jsNN.", dName.c_str() );
}
// Sort devices for more consistent numbering.
std::sort(m_vsPendingEventDevices.begin(), m_vsPendingEventDevices.end(), cmpDevices);
std::sort(m_vsPendingJoystickDevices.begin(), m_vsPendingJoystickDevices.end(), cmpDevices);
if(g_bInputLinuxOrderByLocation)
{
// use Presort to sort the devices by unique location (like USB port/hub number.)
PresortPhysical(m_vsPendingEventDevices, "event");
PresortPhysical(m_vsPendingJoystickDevices, "js");
}
else
{
// Sort devices for more consistent numbering.
std::sort(m_vsPendingEventDevices.begin(), m_vsPendingEventDevices.end(), cmpDevices);
std::sort(m_vsPendingJoystickDevices.begin(), m_vsPendingJoystickDevices.end(), cmpDevices);
}
closedir(sysClassInput);
}
static bool presort_cmpDevices(LinuxInputSort a, LinuxInputSort b)
{
return a.UniqueString < b.UniqueString;
}
void LinuxInputManager::PresortPhysical(std::vector<RString>& sortingArray, RString sortBy)
{
m_vPreSort.clear();
for (RString &dev : sortingArray)
{
LinuxInputSort entry;
entry.DeviceName = dev;
entry.UniqueString = "";
int m_iFD = open(getDevice(dev, sortBy.c_str()).c_str(), O_RDWR);
if(m_iFD >= 0)
{
char szLocation[1024];
// EVIOCGPHYS can return values like "usb-0000:0d:00.3-4"
// telling us where the device is located physically on the computer.
if(ioctl(m_iFD, EVIOCGPHYS(sizeof(szLocation)), szLocation) != -1)
{
entry.UniqueString += szLocation;
}
close(m_iFD);
}
// in the event we didn't get a unique location from ioctl
// default to the name so that sorting by number still works as intended.
entry.UniqueString += entry.DeviceName;
m_vPreSort.push_back(entry);
}
std::sort(m_vPreSort.begin(), m_vPreSort.end(), presort_cmpDevices);
sortingArray.clear();
for (LinuxInputSort &dev : m_vPreSort)
{
// LOG->Info("%s -> %s", dev.DeviceName.c_str(), dev.UniqueString.c_str());
sortingArray.push_back(dev.DeviceName);
}
}
void LinuxInputManager::InitDriver(InputHandler_Linux_Event* driver)
{
m_EventDriver = driver;
+10
View File
@@ -10,6 +10,13 @@ class InputHandler_Linux_Event;
// Enumerates the input devices on the system and dispatches them to
// IH_Linux_Event and IH_Linux_Joystick as appropriate.
// Helper struct for keeping track of inputs.
struct LinuxInputSort
{
RString DeviceName;
RString UniqueString;
};
class LinuxInputManager
{
public:
@@ -18,6 +25,9 @@ public:
void InitDriver(InputHandler_Linux_Event* drv);
~LinuxInputManager();
private:
std::vector<LinuxInputSort> m_vPreSort;
void PresortPhysical(std::vector<RString>& sortingArray, RString sortBy);
bool m_bEventEnabled;
InputHandler_Linux_Event* m_EventDriver;
std::vector<RString> m_vsPendingEventDevices;