Shc*_*ova 2 macos iokit hid mfi gamecontroller
我正在开发支持游戏控制器的 OS X 应用程序。它必须支持源自 IOKit HID 和 GameController.framework 的控制器。我面临的问题是大多数 MFi GameController.framework 兼容控制器也是隐藏设备。因此,MFi 控制器在控制器列表中出现了两次,分别是 GCController 和 IOHIDDevice。有没有办法在它们之间建立连接,忽略 HID 设备?
GCController 对象拥有私有属性deviceRef,指向底层 hid 设备,使得在 HID 层识别和忽略设备成为可能。问题是这deviceRef是一个私有财产,所以我不能在 App Store 应用程序中使用它。
理想的解决方案是识别 IOHIDDeviceRef 是 MFi 设备的一种方法,因此我可以在我的 HID 层中完全跳过它。
我正在尝试使用 GCController 并最终找到了一个 hacky 解决方案。这可能是区分使用 GameController 框架的控制器和使用 IOKit 的控制器的唯一方法:
每当新的控制器连接到 Mac 时,IOKit 和 GameController 的连接回调将分别调用 IOHIDDeviceRef 和 GCController 实例。
获取 IOHIDDeviceRef 的供应商 ID 和产品 ID:
CFNumberRef vendor = static_cast<CFNumberRef>(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
if (vendor) CFNumberGetValue(vendor, kCFNumberSInt32Type, &vendorId);
CFNumberRef product = static_cast<CFNumberRef>(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)));
if (product) CFNumberGetValue(product, kCFNumberSInt32Type, &productId);Run Code Online (Sandbox Code Playgroud)
typedef struct CF_BRIDGED_TYPE(id) __IOHIDServiceClient * IOHIDServiceClientRef;
extern "C" CFTypeRef _Nullable IOHIDServiceClientCopyProperty(IOHIDServiceClientRef service, CFStringRef key);Run Code Online (Sandbox Code Playgroud)
if (class_respondsToSelector(object_getClass(controller), sel_getUid("hidServices")))
{
NSArray* hidServices = reinterpret_cast<NSArray* (*)(id, SEL)>(objc_msgSend)(controller, sel_getUid("hidServices"));
if (hidServices && [hidServices count] > 0)
{
IOHIDServiceClientRef service = reinterpret_cast<IOHIDServiceClientRef (*)(id, SEL)>(objc_msgSend)([hidServices firstObject], sel_getUid("service"));
CFNumberRef vendor = static_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(service, CFSTR(kIOHIDVendorIDKey)));
if (vendor)
{
CFNumberGetValue(vendor, kCFNumberSInt32Type, &vendorId);
CFRelease(vendor);
}
CFNumberRef product = static_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(service, CFSTR(kIOHIDProductIDKey)));
if (product)
{
CFNumberGetValue(product, kCFNumberSInt32Type, &productId);
CFRelease(product);
}
}
}Run Code Online (Sandbox Code Playgroud)
您可以在Ouzel 引擎中查看上述完整代码。
| 归档时间: |
|
| 查看次数: |
1115 次 |
| 最近记录: |