Forráskód Böngészése

input: more device support on macOS (incl. SpaceNavigator)

rdb 7 éve
szülő
commit
c1fd2e46de
1 módosított fájl, 77 hozzáadás és 27 törlés
  1. 77 27
      panda/src/device/ioKitInputDevice.cxx

+ 77 - 27
panda/src/device/ioKitInputDevice.cxx

@@ -46,8 +46,15 @@ IOKitInputDevice(IOHIDDeviceRef device) :
 
   CFStringRef name = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
   if (name) {
+    buffer[0] = 0;
     CFStringGetCString(name, buffer, sizeof(buffer), kCFStringEncodingUTF8);
-    _name = buffer;
+
+    // Strip trailing spaces.
+    size_t len = strlen(buffer);
+    while (isspace(buffer[len - 1])) {
+      --len;
+    }
+    _name.assign(buffer, len);
   }
 
   CFStringRef mfg = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDManufacturerKey));
@@ -89,6 +96,18 @@ IOKitInputDevice(IOHIDDeviceRef device) :
   } else if (_vendor_id == 0x044f && _product_id == 0xb108) {
     // T.Flight Hotas X
     _device_class = DC_flight_stick;
+  } else if (_vendor_id == 0x046d &&
+      (_product_id == 0xc623 ||
+       _product_id == 0xc625 ||
+       _product_id == 0xc626 ||
+       _product_id == 0xc627 ||
+       _product_id == 0xc628 ||
+       _product_id == 0xc629 ||
+       _product_id == 0xc62b)) {
+    // 3Dconnexion SpaceNavigator and friends.
+    _device_class = DC_3d_mouse;
+  } else if (_name == "usb gamepad") {
+    _device_class = DC_gamepad;
   }
 
   CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, NULL, 0);
@@ -189,15 +208,25 @@ parse_element(IOHIDElementRef element) {
       case kHIDUsage_GD_Z:
         if (_device_class == DC_gamepad) {
           axis = C_left_trigger;
-        } else {
+        } else if (_device_class == DC_flight_stick) {
           axis = C_throttle;
+        } else {
+          axis = C_z;
         }
         break;
       case kHIDUsage_GD_Rx:
-        axis = C_right_x;
+        if (_device_class == DC_gamepad) {
+          axis = C_right_x;
+        } else {
+          axis = C_pitch;
+        }
         break;
       case kHIDUsage_GD_Ry:
-        axis = C_right_y;
+        if (_device_class == DC_gamepad) {
+          axis = C_right_y;
+        } else {
+          axis = C_roll;
+        }
         break;
       case kHIDUsage_GD_Rz:
         if (_device_class == DC_gamepad) {
@@ -259,7 +288,8 @@ parse_element(IOHIDElementRef element) {
       if (_vendor_id == 0x044f && _product_id == 0xb108 && axis == C_throttle) {
         // T.Flight Hotas X throttle is reversed and can go backwards.
         add_control(axis, max, min, true);
-      } else if (axis == C_yaw || axis == C_left_y || axis == C_right_y) {
+      } else if (axis == C_yaw || axis == C_rudder || axis == C_left_y || axis == C_right_y ||
+                 (_device_class == DC_3d_mouse && (axis == C_y || axis == C_z || axis == C_roll))) {
         // We'd like to reverse the Y axis to match the XInput behavior.
         // We also reverse yaw to obey the right-hand rule.
         add_control(axis, max, min);
@@ -598,28 +628,48 @@ parse_element(IOHIDElementRef element) {
 
     case kHIDPage_Button:
       if (_device_class == DC_gamepad) {
-        // These seem to be the button mappings exposed by the 360Controller
-        // driver I don't know if other drivers do the same thing at all.
-        static const ButtonHandle gamepad_buttons[] = {
-          ButtonHandle::none(),
-          GamepadButton::action_a(),
-          GamepadButton::action_b(),
-          GamepadButton::action_x(),
-          GamepadButton::action_y(),
-          GamepadButton::lshoulder(),
-          GamepadButton::rshoulder(),
-          GamepadButton::lstick(),
-          GamepadButton::rstick(),
-          GamepadButton::start(),
-          GamepadButton::back(),
-          GamepadButton::guide(),
-          GamepadButton::dpad_up(),
-          GamepadButton::dpad_down(),
-          GamepadButton::dpad_left(),
-          GamepadButton::dpad_right(),
-        };
-        if (usage < sizeof(gamepad_buttons) / sizeof(ButtonHandle)) {
-          handle = gamepad_buttons[usage];
+        if (_vendor_id == 0x0810 && _product_id == 0xe501) {
+          // SNES-style USB gamepad
+          static const ButtonHandle gamepad_buttons[] = {
+            ButtonHandle::none(),
+            GamepadButton::action_x(),
+            GamepadButton::action_a(),
+            GamepadButton::action_b(),
+            GamepadButton::action_y(),
+            GamepadButton::lshoulder(),
+            GamepadButton::rshoulder(),
+            ButtonHandle::none(),
+            ButtonHandle::none(),
+            GamepadButton::back(),
+            GamepadButton::start(),
+          };
+          if (usage < sizeof(gamepad_buttons) / sizeof(ButtonHandle)) {
+            handle = gamepad_buttons[usage];
+          }
+        } else {
+          // These seem to be the button mappings exposed by the 360Controller
+          // driver.  I don't know if other drivers do the same thing at all.
+          static const ButtonHandle gamepad_buttons[] = {
+            ButtonHandle::none(),
+            GamepadButton::action_a(),
+            GamepadButton::action_b(),
+            GamepadButton::action_x(),
+            GamepadButton::action_y(),
+            GamepadButton::lshoulder(),
+            GamepadButton::rshoulder(),
+            GamepadButton::lstick(),
+            GamepadButton::rstick(),
+            GamepadButton::start(),
+            GamepadButton::back(),
+            GamepadButton::guide(),
+            GamepadButton::dpad_up(),
+            GamepadButton::dpad_down(),
+            GamepadButton::dpad_left(),
+            GamepadButton::dpad_right(),
+          };
+          if (usage < sizeof(gamepad_buttons) / sizeof(ButtonHandle)) {
+            handle = gamepad_buttons[usage];
+          }
         }
       } else if (_device_class == DC_flight_stick) {
         if (usage > 0) {