OSX监听全局键盘按下事件并捕获事件源的硬件接口位置
2017-09-16 15:18
746 查看
在OSX系统全局监听键盘的按下事件,并可以捕获事件源的硬件的接口位置,用于区分是哪个键盘产生的事件。下面的代码只是以键盘为例子,其实是可以适用于其他输入外设的。如有需要可搜索相关外设的匹配字典的创建代码。
设备匹配字典
CFMutableDictionaryRef myCreateDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage ) { CFMutableDictionaryRef dict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0 , & kCFTypeDictionaryKeyCallBacks , & kCFTypeDictionaryValueCallBacks ); if ( ! dict ) return NULL; CFNumberRef pageNumberRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, & usagePage ); if ( ! pageNumberRef ) { CFRelease( dict ); return NULL; } CFDictionarySetValue( dict, CFSTR(kIOHIDDeviceUsagePageKey), pageNumberRef ); CFRelease( pageNumberRef ); CFNumberRef usageNumberRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, & usage ); if ( ! usageNumberRef ) { CFRelease( dict ); return NULL; } CFDictionarySetValue( dict, CFSTR(kIOHIDDeviceUsageKey), usageNumberRef ); CFRelease( usageNumberRef ); return dict; }
事件的回调函数
void myHIDKeyboardCallback(void* context, IOReturn result, void* sender, IOHIDValueRef value ) { //get device product id and vendor id IOHIDDeviceRef device = sender; // int32_t pid = 1; // CFNumberGetValue(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)), kCFNumberSInt32Type, &pid); // int32_t vendorID = 0; // CFNumberGetValue(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)), kCFNumberSInt32Type, &vendorID); // NSLog(@"vendor:%d product:%d", vendorID, pid); IOHIDElementRef elem = IOHIDValueGetElement( value ); // if (IOHIDElementGetUsagePage(elem) != 0x07) // return; uint32_t scancode = IOHIDElementGetUsage( elem ); if (scancode < 3 || scancode > 231) return; int32_t locationID = 0; CFNumberGetValue(IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey)), kCFNumberSInt32Type, &locationID); NSLog(@"location:%d", locationID); long pressed = IOHIDValueGetIntegerValue( value ); uint64_t timestamp = IOHIDValueGetTimeStamp(value); printf( "scancode: %3d, %s timestamp:%llu \n", scancode, pressed?"keydown":"keyup ", timestamp); //send the keyboard event NSDictionary* userInfo = [[NSDictionary alloc]initWithObjectsAndKeys: [NSNumber numberWithInt:scancode], NOTIFICATION_KEY_ScanCode, [NSNumber numberWithInt:locationID], NOTIFICATION_KEY_Location, [NSNumber numberWithLong:pressed], NOTIFICATION_KEY_IsKeyDown, [NSNumber numberWithLong:timestamp], NOTIFICATION_KEY_Timestamp, nil]; NSNotification* notification = [NSNotification notificationWithName:NOTIFICATION_KeyBoardEvent object:nil userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotification:notification]; UsbSignalController* controller = (__bridge UsbSignalController*)context; [controller onKeyEvent:scancode Location:locationID IsDown:pressed Timestamp:timestamp]; }
注册键盘钩子
-(void)registerKeyboardHook { IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone ); CFMutableDictionaryRef keyboard = myCreateDeviceMatchingDictionary( 0x01, 6 ); CFArrayRef matches; { //CFMutableDictionaryRef keypad = myCreateDeviceMatchingDictionary( 0x01, 7 ); CFMutableDictionaryRef matchesList[] = { keyboard/*, keypad*/ }; matches = CFArrayCreate( kCFAllocatorDefault, (const void **)matchesList, 1/*2*/, NULL ); } IOHIDManagerSetDeviceMatchingMultiple(hidManager, matches ); CFRelease(matches); CFRelease(keyboard ); IOHIDManagerRegisterInputValueCallback(hidManager, myHIDKeyboardCallback, (__bridge void*)self); IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode ); IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone ); }
相关文章推荐
- Flex编程注意之自动获取焦点、监听全局键盘事件
- [Flex]Flex编程注意之自动获取焦点、监听全局键盘事件
- [Flex]Flex编程注意之自动获取焦点、监听全局键盘事件
- QT如何捕获全局的键盘事件?
- Flex 自动获取焦点 监听全局键盘事件
- osx获取全局键盘/鼠标事件
- c# WinForm 全局键盘事件怎么监听
- .NET使用钩子捕获全局鼠标和键盘事件
- c# WinForm 全局键盘事件怎么监听
- Java监听键盘鼠标全局事件
- Java监听键盘鼠标全局事件
- 键盘管理-监听键盘事件及键盘出现或者隐藏时改变view的位置
- Flex 自动获取焦点 监听全局键盘事件
- QT如何捕获全局的键盘事件?
- Flex编程注意之自动获取焦点、监听全局键盘事件
- 在全局中监听键盘事件
- Flex 自动获取焦点 监听全局键盘事件
- 全局钩子监听键盘鼠标事件
- Flex 自动获取焦点 监听全局键盘事件
- Flex编程注意之自动获取焦点、监听全局键盘事件