input: more device support on macOS (incl. SpaceNavigator)
This commit is contained in:
parent
6ada306184
commit
c1fd2e46de
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue