我正在尝试接收鼠标的输入报告(用包裹IOHIDDeviceRef),但是对于我来说,我似乎无法在macOS 10.12上使用它。相同的代码在10.11和10.10中都可以正常工作,并且对所有其他类型的HID输入设备(键盘,游戏手柄和操纵杆)都适用。
我已经尝试了多种方法,但是无论如何,我只是没有收到任何输入事件。我试过了:
IOHIDDeviceRegisterInputReportCallback和IOHIDDeviceRegisterInputValueCallback(),因为它们是接收日期的最直接的方法。另外,我尝试创建一个添加IOHIDQueueRef了所有IOHIDElement鼠标的的。
这些方法都不能解决问题。如前所述,该代码确实适用于其他输入设备,因此我确定自己正确设置了99.999%。我打开通过IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone)它返回的设备kIOReturnSuccess。我将设备安排在具有kCFRunLoopCommonModes模式的主运行循环中。在IOHIDQueueRefI 的情况下,我还将那个注册到运行循环并调用IOHIDQueueStart()。同样值得注意的是:该代码曾经在10.10和10.11上运行,只是停止了10.12的工作。
我在这里做错了,还是macOS 10.12不再支持此功能?
这是一个最小的repro示例(为样板鳕鱼道歉),它将与键盘和鼠标设备匹配并随后打开。但是,它只会为键盘产生输入值,鼠标不会在10.12上报告任何内容:
#include <iostream>
#include <IOKit/hid/IOHIDLib.h>
void HIDDeviceValueReceived(__unused void *context, __unused IOReturn result, void *sender, __unused IOHIDValueRef value)
{
std::cout << "Received IOHIDValue from " << sender << std::endl;
}
void HIDDeviceMatched(__unused void *context, __unused IOReturn result, __unused void *sender, IOHIDDeviceRef deviceRef)
{
CFNumberRef usagePageValue = (CFNumberRef)IOHIDDeviceGetProperty(deviceRef, CFSTR(kIOHIDPrimaryUsagePageKey));
CFNumberRef usageValue = (CFNumberRef)IOHIDDeviceGetProperty(deviceRef, CFSTR(kIOHIDPrimaryUsageKey));
if(!usagePageValue || !usageValue)
{
IOHIDDeviceClose(deviceRef, kIOHIDOptionsTypeNone);
return;
}
int32_t usagePage;
int32_t usage;
CFNumberGetValue(usagePageValue, kCFNumberSInt32Type, &usagePage);
CFNumberGetValue(usageValue, kCFNumberSInt32Type, &usage);
switch(usagePage)
{
case kHIDPage_GenericDesktop:
{
switch(usage)
{
case kHIDUsage_GD_Keyboard:
case kHIDUsage_GD_Keypad:
{
std::cout << "Found keyboard device " << (void *)deviceRef << std::endl;
if(IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone) != kIOReturnSuccess)
std::cerr << "Couldn't open keyboard device";
IOHIDDeviceRegisterInputValueCallback(deviceRef, &HIDDeviceValueReceived, nullptr);
IOHIDDeviceScheduleWithRunLoop(deviceRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
break;
}
case kHIDUsage_GD_Mouse:
case kHIDUsage_GD_Pointer:
{
std::cout << "Found mouse device " << (void *)deviceRef << std::endl;
if(IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone) != kIOReturnSuccess)
std::cerr << "Couldn't open mouse device";
IOHIDDeviceRegisterInputValueCallback(deviceRef, &HIDDeviceValueReceived, nullptr);
IOHIDDeviceScheduleWithRunLoop(deviceRef, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
break;
}
default:
break;
}
break;
}
default:
break;
}
}
int main()
{
// Find all HID Devices
IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
IOHIDManagerSetDeviceMatching(hidManager, nullptr);
IOHIDManagerRegisterDeviceMatchingCallback(hidManager, &HIDDeviceMatched, nullptr);
IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
// Run the run loop
CFRunLoopRun();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:CGEventTaps仍然可以正常工作,所以我认为这不是安全的事情。我想我会就此向苹果提交错误报告。
| 归档时间: |
|
| 查看次数: |
229 次 |
| 最近记录: |