Browse Source

device: Work around FreeBSD kernel bug for querying gamepad axes

This is to support older kernels, which always returned 0 from successful ioctl, rather than the number of bits.  This was fixed in the FreeBSD kernel trunk.
rdb 4 years ago
parent
commit
51a6923008
1 changed files with 16 additions and 1 deletions
  1. 16 1
      panda/src/device/evdevInputDevice.cxx

+ 16 - 1
panda/src/device/evdevInputDevice.cxx

@@ -328,7 +328,22 @@ init_device() {
   uint8_t axes[(ABS_MAX + 8) >> 3] = {0};
   uint8_t axes[(ABS_MAX + 8) >> 3] = {0};
   if (test_bit(EV_ABS, evtypes)) {
   if (test_bit(EV_ABS, evtypes)) {
     // Check which axes are on the device.
     // Check which axes are on the device.
-    num_bits = ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(axes)), axes) << 3;
+    int result = ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(axes)), axes);
+#ifdef __FreeBSD__
+    // Older kernels had a bug where this would always return 0, see D28218
+    if (result == 0) {
+      for (int i = ABS_MAX; i >= 0; --i) {
+        if (test_bit(i, axes)) {
+          num_bits = i + 1;
+          break;
+        }
+      }
+    }
+    else
+#endif
+    if (result > 0) {
+      num_bits = result << 3;
+    }
     has_axes = true;
     has_axes = true;
   }
   }