gpt4 book ai didi

macos - 使用 IOHIDManager 获取修饰符键事件

转载 作者:行者123 更新时间:2023-12-04 05:57:15 37 4
gpt4 key购买 nike

我正在尝试使用 IOHIDManager 来获取修饰键事件,因为缺少 Cocoa flagsChanged 事件(很难区分按下/释放、左/右是否都按下等)这是我创建管理器并注册回调的代码.

IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
if (CFGetTypeID(hidManager) != IOHIDManagerGetTypeID())
return 1;

CFMutableDictionaryRef capsLock =
myCreateDeviceMatchingDictionary(0x07, 0x39);
CFMutableDictionaryRef lctrl =
myCreateDeviceMatchingDictionary(0x07, 0xE0);
CFMutableDictionaryRef lshift =
myCreateDeviceMatchingDictionary(0x07, 0xE1);
CFMutableDictionaryRef lalt =
myCreateDeviceMatchingDictionary(0x07, 0xE2);
CFMutableDictionaryRef lsuper =
myCreateDeviceMatchingDictionary(0x07, 0xE3);
CFMutableDictionaryRef rctrl =
myCreateDeviceMatchingDictionary(0x07, 0xE4);
CFMutableDictionaryRef rshift =
myCreateDeviceMatchingDictionary(0x07, 0xE5);
CFMutableDictionaryRef ralt =
myCreateDeviceMatchingDictionary(0x07, 0xE6);
CFMutableDictionaryRef rsuper =
myCreateDeviceMatchingDictionary(0x07, 0xE7);

CFMutableDictionaryRef matchesList[] = {
capsLock,
lctrl,
lshift,
lalt,
lsuper,
rctrl,
rshift,
ralt,
rsuper
};
CFArrayRef matches = CFArrayCreate(kCFAllocatorDefault,
(const void **)matchesList, 9, NULL);
IOHIDManagerSetDeviceMatchingMultiple(hidManager, matches);

IOHIDManagerRegisterInputValueCallback(hidManager,
myHandleModifiersCallback, NULL);

IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(),
kCFRunLoopDefaultMode);

IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);

但是,回调永远不会运行。我错过了什么吗?

我不完全了解 HID 使用页面,所以我不知道是否使用带有键盘使用 ID (06) 的通用桌面页面 (0x01) 或带有个人使用 ID 的键盘/键盘页面 (0x07)键。也许这与它有关?

最佳答案

我想到了。这样做的方法是使用通用桌面页面 (0x01) 键盘 (06)(和键盘 (07) 以确保完整性)与 IOHIDManagerSetDeviceMatchingMultiple 一起使用,然后输入值回调获取键盘/键盘使用页面 (0x07) 的东西。

例如,要为所有键盘/小键盘设置一个 HIDManager,可以执行以下操作:

IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);

CFMutableDictionaryRef keyboard =
myCreateDeviceMatchingDictionary(0x01, 6);
CFMutableDictionaryRef keypad =
myCreateDeviceMatchingDictionary(0x01, 7);

CFMutableDictionaryRef matchesList[] = {
keyboard,
keypad,
};
CFArrayRef matches = CFArrayCreate(kCFAllocatorDefault,
(const void **)matchesList, 2, NULL);
IOHIDManagerSetDeviceMatchingMultiple(hidManager, matches);

IOHIDManagerRegisterInputValueCallback(hidManager,
myHIDKeyboardCallback, NULL);

IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(),
kCFRunLoopDefaultMode);

IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);

其中 myCreateDeviceMatchingDictionary 类似于:
CFMutableDictionaryRef myCreateDeviceMatchingDictionary(UInt32 usagePage,
UInt32 usage) {
CFMutableDictionaryRef ret = CFDictionaryCreateMutable(kCFAllocatorDefault,
0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (!ret)
return NULL;

CFNumberRef pageNumberRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberIntType, &usagePage );
if (!pageNumberRef) {
CFRelease(ret);
return NULL;
}

CFDictionarySetValue(ret, CFSTR(kIOHIDDeviceUsagePageKey), pageNumberRef);
CFRelease(pageNumberRef);

CFNumberRef usageNumberRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberIntType, &usage);
if (!usageNumberRef) {
CFRelease(ret);
return NULL;
}

CFDictionarySetValue(ret, CFSTR(kIOHIDDeviceUsageKey), usageNumberRef);
CFRelease(usageNumberRef);

return ret;
}

myHIDKeyboardCallback 类似于:
void myHIDKeyboardCallback(void *context, IOReturn result, void *sender,
IOHIDValueRef value) {
IOHIDElementRef elem = IOHIDValueGetElement(value);
if (IOHIDElementGetUsagePage(elem) != 0x07)
return;
uint32_t scancode = IOHIDElementGetUsage(elem);
if (scancode < 4 || scancode > 231)
return;
long pressed = IOHIDValueGetIntegerValue(value);
// ... Do something ...
}

请注意,每次按下或释放似乎都会多次调用回调,但使用 ID 超出正常范围,这就是“if (scancode < 4 || scancode > 231)”的用途。

关于macos - 使用 IOHIDManager 获取修饰符键事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7190852/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com