summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface
diff options
context:
space:
mode:
authorspycrab <spycrab@users.noreply.github.com>2019-03-21 16:57:17 +0100
committerspycrab <spycrab@users.noreply.github.com>2019-03-22 14:04:30 +0100
commit80fd01c3c36e7925fea1016c7f166b02cabdac74 (patch)
treeb1cb55be50845641db23669ead126807cd170e5a /Source/Core/InputCommon/ControllerInterface
parent8713a752f30f1b1ca972948f4d2c7898ff32db1a (diff)
InputCommon/OSX: Refactor IOKit controller interface
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h4
-rw-r--r--Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm132
2 files changed, 89 insertions, 47 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h
index dbe6a725c1..d3393218c6 100644
--- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h
+++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h
@@ -4,6 +4,8 @@
#pragma once
+#include <set>
+
#include <IOKit/hid/IOHIDLib.h>
#include "InputCommon/ControllerInterface/Device.h"
@@ -84,6 +86,8 @@ private:
const IOHIDDeviceRef m_device;
const std::string m_device_name;
+ void AddElements(CFArrayRef elements, std::set<IOHIDElementCookie>& cookies);
+
ForceFeedback::FFDeviceAdapterReference m_ff_device;
};
}
diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm
index bfe2f27505..e2c08707c5 100644
--- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm
+++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm
@@ -2,75 +2,68 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
+#include "InputCommon/ControllerInterface/OSX/OSXJoystick.h"
+
#include <algorithm>
#include <sstream>
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
+#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
-#include "InputCommon/ControllerInterface/OSX/OSXJoystick.h"
namespace ciface
{
namespace OSX
{
-Joystick::Joystick(IOHIDDeviceRef device, std::string name)
- : m_device(device), m_device_name(name), m_ff_device(nullptr)
+void Joystick::AddElements(CFArrayRef elements, std::set<IOHIDElementCookie>& cookies)
{
- // Buttons
- NSDictionary* buttonDict = @{
- @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Button),
- @kIOHIDElementUsagePageKey : @(kHIDPage_Button)
- };
+ for (int i = 0; i < CFArrayGetCount(elements); i++)
+ {
+ IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
- CFArrayRef buttons =
- IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone);
+ const uint32_t type = IOHIDElementGetType(e);
- if (buttons)
- {
- for (int i = 0; i < CFArrayGetCount(buttons); i++)
+ switch (type)
{
- IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i);
- // DeviceElementDebugPrint(e, nullptr);
-
- AddInput(new Button(e, m_device));
+ case kIOHIDElementTypeCollection:
+ AddElements(IOHIDElementGetChildren(e), cookies);
+ continue;
+ case kIOHIDElementTypeOutput:
+ continue;
}
- CFRelease(buttons);
- }
- // Axes
- NSDictionary* axisDict = @{
- @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Misc),
- @kIOHIDElementUsagePageKey : @(kHIDPage_GenericDesktop)
- };
+ IOHIDElementCookie cookie = IOHIDElementGetCookie(e);
- CFArrayRef axes =
- IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone);
+ // Check for any existing elements with the same cookie
+ if (cookies.count(cookie) > 0)
+ continue;
- if (axes)
- {
- std::vector<IOHIDElementRef> elems;
- for (int i = 0; i < CFArrayGetCount(axes); i++)
- {
- IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i);
- // DeviceElementDebugPrint(e, nullptr);
- uint32_t usage = IOHIDElementGetUsage(e);
-
- // Check for any existing elements with the same usage
- auto it = std::find_if(elems.begin(), elems.end(), [usage](const auto& ref) {
- return usage == IOHIDElementGetUsage(ref);
- });
+ cookies.insert(cookie);
- if (it == elems.end())
- elems.push_back(e);
- else
- *it = e;
- }
+ const uint32_t usage = IOHIDElementGetUsage(e);
- for (auto e : elems)
+ switch (usage)
{
- if (IOHIDElementGetUsage(e) == kHIDUsage_GD_Hatswitch)
+ // Axis
+ case kHIDUsage_GD_X:
+ case kHIDUsage_GD_Y:
+ case kHIDUsage_GD_Z:
+ case kHIDUsage_GD_Rx:
+ case kHIDUsage_GD_Ry:
+ case kHIDUsage_GD_Rz:
+ case kHIDUsage_GD_Slider:
+ case kHIDUsage_GD_Dial:
+ case kHIDUsage_GD_Wheel:
+ case kHIDUsage_GD_Hatswitch:
+ // Simulator
+ case kHIDUsage_Sim_Accelerator:
+ case kHIDUsage_Sim_Brake:
+ case kHIDUsage_Sim_Rudder:
+ case kHIDUsage_Sim_Throttle:
+ {
+ if (usage == kHIDUsage_GD_Hatswitch)
{
AddInput(new Hat(e, m_device, Hat::up));
AddInput(new Hat(e, m_device, Hat::right));
@@ -82,10 +75,55 @@ Joystick::Joystick(IOHIDDeviceRef device, std::string name)
AddAnalogInputs(new Axis(e, m_device, Axis::negative),
new Axis(e, m_device, Axis::positive));
}
+ break;
}
+ // Buttons
+ case kHIDUsage_GD_DPadUp:
+ case kHIDUsage_GD_DPadDown:
+ case kHIDUsage_GD_DPadRight:
+ case kHIDUsage_GD_DPadLeft:
+ case kHIDUsage_GD_Start:
+ case kHIDUsage_GD_Select:
+ case kHIDUsage_GD_SystemMainMenu:
+ AddInput(new Button(e, m_device));
+ break;
- CFRelease(axes);
+ default:
+ // Catch any easily identifiable axis and buttons that slipped through
+ if (type == kIOHIDElementTypeInput_Button)
+ {
+ AddInput(new Button(e, m_device));
+ break;
+ }
+
+ const uint32_t usage_page = IOHIDElementGetUsagePage(e);
+
+ if (usage_page == kHIDPage_Button || usage_page == kHIDPage_Consumer)
+ {
+ AddInput(new Button(e, m_device));
+ break;
+ }
+
+ if (type == kIOHIDElementTypeInput_Axis)
+ {
+ AddAnalogInputs(new Axis(e, m_device, Axis::negative),
+ new Axis(e, m_device, Axis::positive));
+ break;
+ }
+
+ NOTICE_LOG(SERIALINTERFACE, "Unknown IOHIDElement, ignoring (Usage: %x, Type: %x)\n", usage,
+ IOHIDElementGetType(e));
+
+ break;
+ }
}
+}
+Joystick::Joystick(IOHIDDeviceRef device, std::string name)
+ : m_device(device), m_device_name(name), m_ff_device(nullptr)
+{
+ CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device, nullptr, kIOHIDOptionsTypeNone);
+ std::set<IOHIDElementCookie> known_cookies;
+ AddElements(elements, known_cookies);
// Force Feedback
FFCAPABILITIES ff_caps;