Cocoa: Fix segfault

This fixes a segfault caused by missing input monitoring permissions
for a connected controller / gamepad.
This commit is contained in:
Daniel Hauser 2023-04-18 20:21:58 +02:00
parent 3fa2360720
commit d577f1d0e7

View File

@ -182,84 +182,87 @@ static void matchCallback(void* context,
CFArrayRef elements = CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
for (CFIndex i = 0; i < CFArrayGetCount(elements); i++) if (elements)
{ {
IOHIDElementRef native = (IOHIDElementRef) for (CFIndex i = 0; i < CFArrayGetCount(elements); i++)
CFArrayGetValueAtIndex(elements, i);
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
continue;
const IOHIDElementType type = IOHIDElementGetType(native);
if ((type != kIOHIDElementTypeInput_Axis) &&
(type != kIOHIDElementTypeInput_Button) &&
(type != kIOHIDElementTypeInput_Misc))
{ {
continue; IOHIDElementRef native = (IOHIDElementRef)
} CFArrayGetValueAtIndex(elements, i);
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
continue;
CFMutableArrayRef target = NULL; const IOHIDElementType type = IOHIDElementGetType(native);
if ((type != kIOHIDElementTypeInput_Axis) &&
const uint32_t usage = IOHIDElementGetUsage(native); (type != kIOHIDElementTypeInput_Button) &&
const uint32_t page = IOHIDElementGetUsagePage(native); (type != kIOHIDElementTypeInput_Misc))
if (page == kHIDPage_GenericDesktop)
{
switch (usage)
{ {
case kHIDUsage_GD_X: continue;
case kHIDUsage_GD_Y: }
case kHIDUsage_GD_Z:
case kHIDUsage_GD_Rx: CFMutableArrayRef target = NULL;
case kHIDUsage_GD_Ry:
case kHIDUsage_GD_Rz: const uint32_t usage = IOHIDElementGetUsage(native);
case kHIDUsage_GD_Slider: const uint32_t page = IOHIDElementGetUsagePage(native);
case kHIDUsage_GD_Dial: if (page == kHIDPage_GenericDesktop)
case kHIDUsage_GD_Wheel: {
target = axes; switch (usage)
break; {
case kHIDUsage_GD_Hatswitch: case kHIDUsage_GD_X:
target = hats; case kHIDUsage_GD_Y:
break; case kHIDUsage_GD_Z:
case kHIDUsage_GD_DPadUp: case kHIDUsage_GD_Rx:
case kHIDUsage_GD_DPadRight: case kHIDUsage_GD_Ry:
case kHIDUsage_GD_DPadDown: case kHIDUsage_GD_Rz:
case kHIDUsage_GD_DPadLeft: case kHIDUsage_GD_Slider:
case kHIDUsage_GD_SystemMainMenu: case kHIDUsage_GD_Dial:
case kHIDUsage_GD_Select: case kHIDUsage_GD_Wheel:
case kHIDUsage_GD_Start: target = axes;
target = buttons; break;
break; case kHIDUsage_GD_Hatswitch:
target = hats;
break;
case kHIDUsage_GD_DPadUp:
case kHIDUsage_GD_DPadRight:
case kHIDUsage_GD_DPadDown:
case kHIDUsage_GD_DPadLeft:
case kHIDUsage_GD_SystemMainMenu:
case kHIDUsage_GD_Select:
case kHIDUsage_GD_Start:
target = buttons;
break;
}
}
else if (page == kHIDPage_Simulation)
{
switch (usage)
{
case kHIDUsage_Sim_Accelerator:
case kHIDUsage_Sim_Brake:
case kHIDUsage_Sim_Throttle:
case kHIDUsage_Sim_Rudder:
case kHIDUsage_Sim_Steering:
target = axes;
break;
}
}
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
target = buttons;
if (target)
{
_GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS));
element->native = native;
element->usage = usage;
element->index = (int) CFArrayGetCount(target);
element->minimum = IOHIDElementGetLogicalMin(native);
element->maximum = IOHIDElementGetLogicalMax(native);
CFArrayAppendValue(target, element);
} }
} }
else if (page == kHIDPage_Simulation)
{
switch (usage)
{
case kHIDUsage_Sim_Accelerator:
case kHIDUsage_Sim_Brake:
case kHIDUsage_Sim_Throttle:
case kHIDUsage_Sim_Rudder:
case kHIDUsage_Sim_Steering:
target = axes;
break;
}
}
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
target = buttons;
if (target) CFRelease(elements);
{
_GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS));
element->native = native;
element->usage = usage;
element->index = (int) CFArrayGetCount(target);
element->minimum = IOHIDElementGetLogicalMin(native);
element->maximum = IOHIDElementGetLogicalMax(native);
CFArrayAppendValue(target, element);
}
} }
CFRelease(elements);
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)), CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
compareElements, NULL); compareElements, NULL);
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)), CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),