8 #include <CoreFoundation/CoreFoundation.h>
9 #include <IOKit/hid/IOHIDUsageTables.h>
14 using namespace swift::misc::input;
16 namespace swift::input
18 CJoystickDevice::CJoystickDevice(QObject *parent) :
22 CJoystickDevice::~CJoystickDevice()
33 CFTypeRef
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
34 m_deviceName = QString::fromCFString(
static_cast<CFStringRef
>(property));
38 CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device,
nullptr, kIOHIDOptionsTypeNone);
40 for (
int i = 0; i < CFArrayGetCount(elements); i++)
42 IOHIDElementRef elementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
43 if (CFGetTypeID(elementRef) != IOHIDElementGetTypeID()) {
continue; }
45 const IOHIDElementType type = IOHIDElementGetType(elementRef);
46 if (type != kIOHIDElementTypeInput_Button) {
continue; }
48 const uint32_t page = IOHIDElementGetUsagePage(elementRef);
50 if (page == kHIDPage_Button)
54 int number = m_joystickDeviceInputs.size();
55 m_joystickDeviceInputs.insert(elementRef, { m_deviceName, number });
56 IOHIDDeviceRegisterInputValueCallback(device, valueCallback,
this);
62 if (m_joystickDeviceInputs.isEmpty()) {
return false; }
64 CLogMessage(
this).
info(u
"Created joystick device '%1' with %2 buttons") << m_deviceName << m_joystickDeviceInputs.size();
73 void CJoystickDevice::processButtonEvent(IOHIDValueRef value)
75 IOHIDElementRef element = IOHIDValueGetElement(value);
79 bool isPressed = IOHIDValueGetIntegerValue(value) == 1;
85 void CJoystickDevice::valueCallback(
void *context, IOReturn result,
void *sender, IOHIDValueRef value)
90 obj->processButtonEvent(value);
102 m_joystickDevices.clear();
106 IOHIDManagerClose(m_hidManager, kIOHIDOptionsTypeNone);
107 CFRelease(m_hidManager);
116 availableButtons.
push_back(device->getDeviceButtons());
118 return availableButtons;
123 m_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
125 CFMutableArrayRef matchingArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
135 CFArrayAppendValue(matchingArray, matchingDict);
136 CFRelease(matchingDict);
142 CFArrayAppendValue(matchingArray, matchingDict);
143 CFRelease(matchingDict);
149 CFArrayAppendValue(matchingArray, matchingDict);
150 CFRelease(matchingDict);
153 IOHIDManagerSetDeviceMatchingMultiple(m_hidManager, matchingArray);
154 CFRelease(matchingArray);
156 IOHIDManagerRegisterDeviceMatchingCallback(m_hidManager, matchCallback,
this);
157 IOHIDManagerRegisterDeviceRemovalCallback(m_hidManager, removeCallback,
this);
158 IOHIDManagerScheduleWithRunLoop(m_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
159 return IOHIDManagerOpen(m_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess;
162 void CJoystickMacOS::addJoystickDevice(
const IOHIDDeviceRef device)
166 if (d->getNativeDevice() == device) {
return; }
169 CJoystickDevice *joystickDevice =
new CJoystickDevice(
this);
170 bool success = joystickDevice->init(device);
174 m_joystickDevices.push_back(joystickDevice);
178 delete joystickDevice;
182 void CJoystickMacOS::removeJoystickDevice(
const IOHIDDeviceRef device)
184 for (
auto it = m_joystickDevices.begin(); it != m_joystickDevices.end();)
186 CJoystickDevice *d = *it;
187 if (d->getNativeDevice() == device)
190 it = m_joystickDevices.erase(it);
199 void CJoystickMacOS::joystickButtonChanged(
const CJoystickButton &joystickButton,
bool isPressed)
205 if (oldCombination != m_buttonCombination)
211 void CJoystickMacOS::matchCallback(
void *context, IOReturn result,
void *sender, IOHIDDeviceRef device)
216 obj->addJoystickDevice(device);
219 void CJoystickMacOS::removeCallback(
void *context, IOReturn result,
void *sender, IOHIDDeviceRef device)
224 obj->removeJoystickDevice(device);
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & debug()
Set the severity to debug.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
void push_back(const T &value)
Appends an element at the end of the sequence.
Free functions in swift::misc.