OsX 中 USB HID API 的回调永远不会被游戏手柄或其他任何东西调用

Posted

技术标签:

【中文标题】OsX 中 USB HID API 的回调永远不会被游戏手柄或其他任何东西调用【英文标题】:Callbacks for USB HID API in OsX are never called for game pad or anything else 【发布时间】:2014-08-12 11:45:40 【问题描述】:

我正在尝试在我的游戏中检测并使用连接到我的 Mac 的游戏手柄。 我为此使用了 IOKit,但没有成功。 当我下载了一个查看所有附加游戏手柄的 Mac 应用程序时,游戏手柄被识别。 它是罗技 F310,我已将其设置为 DirectInput。 我在 awakeFromNib 中调用 setupInput 但没有调用任何回调。 没有抛出错误或异常。 我不知道为什么不调用回调。 我究竟做错了什么? 我在想这可能是运行循环的问题。我尝试了 CFRunLoopGetMain 和 CFRunLoopGetCurrent。

不知道还能做什么。

编辑:根据某人的建议,我尝试将相同的 GamePad 代码放入一个新项目中,并且成功了。 类的结构存在一些差异,但即使我尝试复制这些类,我也无法使其在我的应用程序中工作。 我的应用程序使用 AppDelegate 和 NSOpenGLView。奇怪的是它没有 NSViewController。 最小的应用程序使用 NSOpenGLView 也使用 NSResponder ,当我将游戏手柄代码放在(自定义)NSResponder 类中时,它“工作”(检测游戏手柄并响应输入)。 我试图将该自定义类添加到我的应用程序中,但它“不起作用”。 我错过了什么?

void gamepadWasAdded(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) 
    NSLog(@"Gamepad was plugged in");


void gamepadWasRemoved(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) 
    NSLog(@"Gamepad was unplugged");


void gamepadAction(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef value) 
    NSLog(@"Gamepad talked!");
    IOHIDElementRef element = IOHIDValueGetElement(value);
    NSLog(@"Element: %@", element);
    int elementValue = IOHIDValueGetIntegerValue(value);
    NSLog(@"Element value: %i", elementValue);


-(void) setupInput 
    //get a HID manager reference
    hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
                                                    kIOHIDOptionsTypeNone);

    //define the device to search for, via usage page and usage key
    NSMutableDictionary* criterion = [[NSMutableDictionary alloc] init];
    [criterion setObject: [NSNumber numberWithInt: kHIDPage_GenericDesktop]
                  forKey: (NSString*)CFSTR(kIOHIDDeviceUsagePageKey)];
    [criterion setObject: [NSNumber numberWithInt: kHIDUsage_GD_Joystick]
                  forKey: (NSString*)CFSTR(kIOHIDDeviceUsageKey)];

    //search for the device
    IOHIDManagerSetDeviceMatching(hidManager,
                                  (__bridge CFDictionaryRef)criterion);

    //register our callback functions
    IOHIDManagerRegisterDeviceMatchingCallback(hidManager, gamepadWasAdded,
                                               (__bridge void*)self);
    IOHIDManagerRegisterDeviceRemovalCallback(hidManager, gamepadWasRemoved,
                                              (__bridge void*)self);
    IOHIDManagerRegisterInputValueCallback(hidManager, gamepadAction,
                                           (__bridge void*)self);

    //scedule our HIDManager with the current run loop, so that we
    //are able to recieve events from the hardware.
    IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(),
                                    kCFRunLoopDefaultMode);

    //open the HID manager, so that it can start routing events
    //to our callbacks.
    IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);



// Put our timer in -awakeFromNib, so it can start up right from the beginning
-(void)awakeFromNib

    renderTimer = [NSTimer timerWithTimeInterval:0.001   //a 1ms time interval
                                          target:self
                                        selector:@selector(timerFired:)
                                        userInfo:nil
                                         repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:renderTimer
                                 forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:renderTimer
                                 forMode:NSEventTrackingRunLoopMode]; //Ensure timer fires during resize
    [self setupInput];

【问题讨论】:

【参考方案1】:

好的,我找到了问题。 问题是我的 Mac 应用程序在沙盒中,我没有选中硬件/USB 复选框。 选中此选项后,它可以与原始代码一起使用。

【讨论】:

以上是关于OsX 中 USB HID API 的回调永远不会被游戏手柄或其他任何东西调用的主要内容,如果未能解决你的问题,请参考以下文章

USB-HID的介绍

usb蓝牙转hid

求救!!usb hid设备(模拟键盘)遇到的问题

addEventListener('fetch', callback) 在 ReactJS 中永远不会触发回调

浅析usbhid驱动如何源源不断的获取usb鼠标

浅析USB HID ReportDesc (HID报告描述符)