【问题标题】:How to read the home key on an iOS keyboard using IOHIDManager or Bluetooth?如何使用 IOHIDManager 或蓝牙读取 iOS 键盘上的 home 键?
【发布时间】:2019-06-11 02:55:51
【问题描述】:

我正在尝试将 iOS 键盘上的主页键用于Esc 键。我可以使用IOHIDManager 读取键盘上的键,iOS 主页键除外。

我的理解是,将NULL 传递给IOHIDManagerSetDeviceMatching 应该匹配IOHIDUsageTables 中的所有类型,如下所示:

// clang -framework coreFoundation -framework IOKit ./HID.c -o hid
// sudo ./hid

#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDValue.h>

void myHIDKeyboardCallback(void* context, IOReturn result, void* sender, IOHIDValueRef value)
{
    IOHIDElementRef elem = IOHIDValueGetElement(value);
    uint32_t scancode = IOHIDElementGetUsage(elem);
    long pressed = IOHIDValueGetIntegerValue(value);
    printf("scancode: %d, pressed: %ld\n", scancode, pressed);
}

int main(void)
{
    IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
    IOHIDManagerSetDeviceMatching(hidManager, NULL);
    IOHIDManagerRegisterInputValueCallback(hidManager, myHIDKeyboardCallback, NULL);
    IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
    IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
    CFRunLoopRun();
}

使用PacketLogger.app(来自Apple 的Hardware IO Tools)我可以记录以下内容,其中第一个按键是主页键,然后是波形键。

[Jan 16 18:31:06.631]  [HII receive]  HID Interrupt: [A1] Unknown [03] Event Data [ 01 00 00 ]
[Jan 16 18:31:06.730]  [HII receive]  HID Interrupt: [A1] Unknown [03] Event Data [ 00 00 00 ]
[Jan 16 18:31:07.805]  [HII receive]  HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 35 00 00 00 00 00 ]
[Jan 16 18:31:07.905]  [HII receive]  HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 00 00 00 00 00 00 ]

可能是因为Unknown事件,它不能通过IOHIDManager获得。

也可以选择创建内核扩展并直接从蓝牙读取,这是上面的扩展日志:

[Jan 16 18:31:06.631]  [HII receive]  HID Interrupt: [A1] Unknown [03] Event Data [ 01 00 00 ]
               HID Interrupt: [A1] Unknown [03] Event Data [ 01 00 00 ]
[Jan 16 18:31:06.631]  [L2CAP RECEIVE]  Channel ID: 0x0041  Length: 0x0005 (05) [ A1 03 01 00 00 ]
               Channel ID: 0x0041  Length: 0x0005 (05) [ A1 03 01 00 00 ]
               00000000: 0500 4100 a103 0100 00                   ..A......
[Jan 16 18:31:06.631]  [ACL RECEIVE]  Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
               Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
               Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
               Broadcast Flags: [00] 0x00 - Point-to-point
               Data (0x0009 bytes)
[Jan 16 18:31:06.631]  [ACL RECEIVE]  00000000: 0b20 0900 0500 4100 a103 0100 00         . ....A......
               00000000: 0b20 0900 0500 4100 a103 0100 00         . ....A......
[Jan 16 18:31:06.730]  [HII receive]  HID Interrupt: [A1] Unknown [03] Event Data [ 00 00 00 ]
               HID Interrupt: [A1] Unknown [03] Event Data [ 00 00 00 ]
[Jan 16 18:31:06.730]  [L2CAP RECEIVE]  Channel ID: 0x0041  Length: 0x0005 (05) [ A1 03 00 00 00 ]
               Channel ID: 0x0041  Length: 0x0005 (05) [ A1 03 00 00 00 ]
               00000000: 0500 4100 a103 0000 00                   ..A......
[Jan 16 18:31:06.730]  [ACL RECEIVE]  Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
               Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
               Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
               Broadcast Flags: [00] 0x00 - Point-to-point
               Data (0x0009 bytes)
[Jan 16 18:31:06.730]  [ACL RECEIVE]  00000000: 0b20 0900 0500 4100 a103 0000 00         . ....A......
               00000000: 0b20 0900 0500 4100 a103 0000 00         . ....A......
[Jan 16 18:31:07.805]  [HII receive]  HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 35 00 00 00 00 00 ]
               HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 35 00 00 00 00 00 ]
               Modifier keys 00
                        NUM_LOCK    [FALSE]
                        CAPS_LOCK   [FALSE]
                        SCROLL_LOCK [FALSE]
                        COMPOSE     [FALSE]
                        KANA        [FALSE]
               Reserved      00
               Keycode 1 35 Keycode 2 00 Keycode 3 00 Keycode 4 00 Keycode 5 00 Keycode 6 00 
[Jan 16 18:31:07.805]  [L2CAP RECEIVE]  Channel ID: 0x0041  Length: 0x000A (10) [ A1 01 00 00 35 00 00 00 00 00 ]
               Channel ID: 0x0041  Length: 0x000A (10) [ A1 01 00 00 35 00 00 00 00 00 ]
               00000000: 0a00 4100 a101 0000 3500 0000 0000       ..A.....5.....
[Jan 16 18:31:07.805]  [ACL RECEIVE]  Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
               Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
               Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
               Broadcast Flags: [00] 0x00 - Point-to-point
               Data (0x000e bytes)
[Jan 16 18:31:07.805]  [ACL RECEIVE]  00000000: 0b20 0e00 0a00 4100 a101 0000 3500 0000  . ....A.....5...
               00000000: 0b20 0e00 0a00 4100 a101 0000 3500 0000  . ....A.....5...
               00000010: 0000                                     ..
[Jan 16 18:31:07.905]  [HII receive]  HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 00 00 00 00 00 00 ]
               HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 00 00 00 00 00 00 ]
               Modifier keys 00
                        NUM_LOCK    [FALSE]
                        CAPS_LOCK   [FALSE]
                        SCROLL_LOCK [FALSE]
                        COMPOSE     [FALSE]
                        KANA        [FALSE]
               Reserved      00
               Keycode 1 00 Keycode 2 00 Keycode 3 00 Keycode 4 00 Keycode 5 00 Keycode 6 00 
[Jan 16 18:31:07.905]  [L2CAP RECEIVE]  Channel ID: 0x0041  Length: 0x000A (10) [ A1 01 00 00 00 00 00 00 00 00 ]
               Channel ID: 0x0041  Length: 0x000A (10) [ A1 01 00 00 00 00 00 00 00 00 ]
               00000000: 0a00 4100 a101 0000 0000 0000 0000       ..A...........
[Jan 16 18:31:07.905]  [ACL RECEIVE]  Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
               Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
               Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
               Broadcast Flags: [00] 0x00 - Point-to-point
               Data (0x000e bytes)
[Jan 16 18:31:07.905]  [ACL RECEIVE]  00000000: 0b20 0e00 0a00 4100 a101 0000 0000 0000  . ....A.........
               00000000: 0b20 0e00 0a00 4100 a101 0000 0000 0000  . ....A.........
               00000010: 0000                                     ..

【问题讨论】:

  • 使用IOHIDManager,您是否尝试使用IOHIDManagerRegisterInputReportCallback 并自己解码报告?我想知道IOHIDManagerRegisterInputValueCallback 是否不支持解码“未知”表中的值。不幸的是,我手边没有这些键盘,所以我无法自己测试。
  • 不幸的是,回调也没有使用IOHIDManagerRegisterInputReportCallback触发。
  • 我发现原始代码确实有效,但在 99% 的情况下都无效。我能够确定密钥是kHIDUsage_Csmr_ACHome。不过,每次运行 sudo packetlogger | grep 'A1.*03.*01 00 00' 都有效。
  • 很奇怪,我想它归结为通过内核的相关位跟踪事件,以便弄清楚发生了什么以及事件被丢弃的确切位置。
  • 如果我断开键盘并按 Home 键重新连接,则会发送一个 kHIDUsage_Csmr_ACHome 事件,但看起来蓝牙控制了。以前,当我能够获得一致的读数时,我也在运行多个 packetlogger 实例,所以这可能会破坏蓝牙控制。

标签: macos bluetooth keyboard hid iokit


【解决方案1】:

原来Karabiner 正在控制输入并丢弃 home 键,具有讽刺意味的是,我安装它是为了重新映射 home 键以逃避。卸载它解决了这个问题。

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 2013-10-14
    • 1970-01-01
    • 2017-05-09
    • 2021-09-06
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多