How to tap/hook keyboard events in OSX and record which keyboard fires each event

前端 未结 2 1012
轻奢々
轻奢々 2021-01-18 09:13

I\'ve now discovered how to hook/tap keyboard events on OS X at a low level: How to tap (hook) F7 through F12 and Power/Eject on a MacBook keyboard

Printing out the

相关标签:
2条回答
  • 2021-01-18 09:31

    If you register the callback on each device of interest individually with IOHIDDeviceRegisterInputValueCallback then the sender argument will be a IOHIDDeviceRef indicating the device. (instead of using IOHIDManagerRegisterInputValueCallback where the sender will be the HID manager reference)

    The only downside for this is that you'll need to register for and handle notification of hotplugging events for matching devices. (register whenever a new device appears, and deregister when a device disappears)

    You can get HID device references using IOHIDDeviceCreate() - this takes an io_service_t as an argument. This in turn means you need to use the standard IOKit IOService matching functions to obtain and watch your list of devices, but you do indeed get an explicit list of individual devices, which you can query for names to show to the user, etc. The key function for this is IOServiceAddMatchingNotification.

    0 讨论(0)
  • 2021-01-18 09:35

    I was working on this problem, and finally got the solution. OP's code is correct, if you'd like the product ID of the keyboard/pad, add lines to the myHIDKeyboardCallback() function:

    void myHIDKeyboardCallback(void* context,  IOReturn result,  void* sender,  IOHIDValueRef value){
    
        IOHIDElementRef elem = IOHIDValueGetElement(value);
        if (IOHIDElementGetUsagePage(elem) != 0x07)
            return;
    
        IOHIDDeviceRef device = sender;
        int32_t pid = 1;
        CFNumberGetValue(IOHIDDeviceGetProperty(device, CFSTR("idProduct")), kCFNumberSInt32Type, &pid);
    
        uint32_t scancode = IOHIDElementGetUsage(elem);
    
        if (scancode < 4 || scancode > 231)
            return;
    
        long pressed = IOHIDValueGetIntegerValue(value);
    
        printf("scancode: %d, pressed: %ld, keyboardId=%d\n", scancode, pressed, pid);
    }
    

    As @pmdj said you can use IOHIDDeviceRegisterInputValueCallback(), I was having trouble with this, and found that sender argument provided keyboard product id anyways.

    0 讨论(0)
提交回复
热议问题