112 lines
3.1 KiB
Diff
112 lines
3.1 KiB
Diff
|
diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp
|
||
|
index 6df37b4..64ade4a 100644
|
||
|
--- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp
|
||
|
+++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp
|
||
|
@@ -392,6 +392,65 @@ void Init()
|
||
|
StartHotplugThread();
|
||
|
}
|
||
|
|
||
|
+struct joypad_udev_entry
|
||
|
+{
|
||
|
+ const char *devnode;
|
||
|
+ struct udev_device *dev;
|
||
|
+};
|
||
|
+
|
||
|
+int isNumber(const char *s) {
|
||
|
+ int n;
|
||
|
+
|
||
|
+ if(strlen(s) == 0) {
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ for(n=0; n<strlen(s); n++) {
|
||
|
+ if(!(s[n] == '0' || s[n] == '1' || s[n] == '2' || s[n] == '3' || s[n] == '4' ||
|
||
|
+ s[n] == '5' || s[n] == '6' || s[n] == '7' || s[n] == '8' || s[n] == '9'))
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
+// compare /dev/input/eventX and /dev/input/eventY where X and Y are numbers
|
||
|
+int strcmp_events(const char* x, const char* y) {
|
||
|
+
|
||
|
+ // find a common string
|
||
|
+ int n, common, is_number;
|
||
|
+ int a, b;
|
||
|
+
|
||
|
+ n=0;
|
||
|
+ while(x[n] == y[n] && x[n] != '\0' && y[n] != '\0') {
|
||
|
+ n++;
|
||
|
+ }
|
||
|
+ common = n;
|
||
|
+
|
||
|
+ // check if remaining string is a number
|
||
|
+ is_number = 1;
|
||
|
+ if(isNumber(x+common) == 0) is_number = 0;
|
||
|
+ if(isNumber(y+common) == 0) is_number = 0;
|
||
|
+
|
||
|
+ if(is_number == 1) {
|
||
|
+ a = atoi(x+common);
|
||
|
+ b = atoi(y+common);
|
||
|
+
|
||
|
+ if(a == b) return 0;
|
||
|
+ if(a < b) return -1;
|
||
|
+ return 1;
|
||
|
+ } else {
|
||
|
+ return strcmp(x, y);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+/* Used for sorting devnodes to appear in the correct order */
|
||
|
+static int sort_devnodes(const void *a, const void *b)
|
||
|
+{
|
||
|
+ const struct joypad_udev_entry *aa = (const struct joypad_udev_entry *) a;
|
||
|
+ const struct joypad_udev_entry *bb = (const struct joypad_udev_entry *) b;
|
||
|
+ return strcmp_events(aa->devnode, bb->devnode);
|
||
|
+}
|
||
|
+
|
||
|
// Only call this when ControllerInterface::m_devices_population_mutex is locked
|
||
|
void PopulateDevices()
|
||
|
{
|
||
|
@@ -404,6 +463,10 @@ void PopulateDevices()
|
||
|
// We use udev to iterate over all /dev/input/event* devices.
|
||
|
// Note: the Linux kernel is currently limited to just 32 event devices. If
|
||
|
// this ever changes, hopefully udev will take care of this.
|
||
|
+ unsigned sorted_count = 0;
|
||
|
+ struct joypad_udev_entry sorted[64];
|
||
|
+ const char* devnode;
|
||
|
+ int i;
|
||
|
|
||
|
udev* const udev = udev_new();
|
||
|
ASSERT_MSG(CONTROLLERINTERFACE, udev != nullptr, "Couldn't initialize libudev.");
|
||
|
@@ -422,11 +485,25 @@ void PopulateDevices()
|
||
|
|
||
|
udev_device* dev = udev_device_new_from_syspath(udev, path);
|
||
|
|
||
|
- if (const char* devnode = udev_device_get_devnode(dev))
|
||
|
- AddDeviceNode(devnode);
|
||
|
-
|
||
|
- udev_device_unref(dev);
|
||
|
+ devnode = udev_device_get_devnode(dev);
|
||
|
+ if (devnode != NULL && sorted_count < 64) {
|
||
|
+ sorted[sorted_count].devnode = devnode;
|
||
|
+ sorted[sorted_count].dev = dev;
|
||
|
+ sorted_count++;
|
||
|
+ } else {
|
||
|
+ udev_device_unref(dev);
|
||
|
+ }
|
||
|
}
|
||
|
+
|
||
|
+ /* Sort the udev entries by devnode name so that they are
|
||
|
+ * created in the proper order */
|
||
|
+ qsort(sorted, sorted_count, sizeof(struct joypad_udev_entry), sort_devnodes);
|
||
|
+
|
||
|
+ for (i = 0; i < sorted_count; i++) {
|
||
|
+ AddDeviceNode(sorted[i].devnode);
|
||
|
+ udev_device_unref(sorted[i].dev);
|
||
|
+ }
|
||
|
+
|
||
|
udev_enumerate_unref(enumerate);
|
||
|
udev_unref(udev);
|
||
|
}
|