HidHide on MacOS

I was wondering if there's a method on MacOS to have my application hide a hid device such as a game controller and instead have the receiving game/application see my app's virtual controller? Is this possible via DriverKit or some other form of kernel level coding?

On Windows we have a tool known as HidHide that hids a game controller from all other applications. Is it possible to implement such behavior into an app or is that system level?

Answered by DTS Engineer in 885211022

I was wondering if there's a method on macOS to have my application hide a hid device such as a game controller and instead have the receiving game/application see my app's virtual controller? Is this possible via DriverKit or some other form of kernel-level coding?

Yes, and it doesn't require DriverKit or any kernel-level code. The basic flow here is:

  • Your app discovers the device using CoreHID.

  • You use seizeDevice() to take control of the accessory. Strictly speaking, the device would still be visible to other apps, but they can't receive events from it or otherwise interact.

  • Your app then emits events to the system, either by using CoreHID to create a virtual HID device or by using CGEventTap to directly submit higher-level events to the system.

Expanding on that last point, the choice here depends on what you're actually trying to do. Using virtual HID allows you to emulate a specific accessory, but that assumes that some other app/process is "looking" for that accessory and is ready to interpret that HID device. On the other hand, CGEvent is the entry point into the system event system, which makes it much easier to ensure you're generating exactly what the rest of the system is "expecting".

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

The architecture stack should be like this if possible: Game Controller -> My App -> Game/Application and Game/Application -> My App -> Game Controller. Cause currently the inputs are doubled.

Accepted Answer

I was wondering if there's a method on macOS to have my application hide a hid device such as a game controller and instead have the receiving game/application see my app's virtual controller? Is this possible via DriverKit or some other form of kernel-level coding?

Yes, and it doesn't require DriverKit or any kernel-level code. The basic flow here is:

  • Your app discovers the device using CoreHID.

  • You use seizeDevice() to take control of the accessory. Strictly speaking, the device would still be visible to other apps, but they can't receive events from it or otherwise interact.

  • Your app then emits events to the system, either by using CoreHID to create a virtual HID device or by using CGEventTap to directly submit higher-level events to the system.

Expanding on that last point, the choice here depends on what you're actually trying to do. Using virtual HID allows you to emulate a specific accessory, but that assumes that some other app/process is "looking" for that accessory and is ready to interpret that HID device. On the other hand, CGEvent is the entry point into the system event system, which makes it much easier to ensure you're generating exactly what the rest of the system is "expecting".

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Specifically I'm doing this for controller management. Meaning I want my app to process the input and output of the controller. And so I would need to virtualize a controller with the outputs.

Specifically I'm doing this for controller management. Meaning I want my app to process the input and output of the controller. And so I would need to virtualize a controller with the outputs.

OK. What I outlined above should work fine for that. Do you have any other questions or concerns?

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Does this apply for games as well that use the Game Controller Framework? I don’t know how low level it is can I hide the events from the framework and virtualize ones? Can I say spoof/virtualize a DualSense controller?

Does this apply for games as well that use the Game Controller Framework?

I haven't actually tried or experimented with this, but yes, I think it would work depending on exactly what you're trying to do.

I don’t know how low level it is. Can I hide the events from the framework and virtualize ones?

At a technical level, how CoreHID's virtual device support actually works is that your app is sending data/commands to a kernel driver, which is then presenting a HID device that the rest of the system handles "normally". As far as the larger system is concerned, it's a HID device just like any other.

Can I say spoof/virtualize a DualSense controller?

Generally speaking, yes, I think you could; however, that comes with a few different issues/qualifications:

  1. I don't know whether you'll be able to "claim" a controller that the GameController has already claimed, as it depends on how they opened the HID interface and whether or not they allow you to claim it. I expect that you will be able to claim it, but I don't know for certain.

  2. In terms of emulating an existing controller, the main issue here is that the GameController.framework controller-specific support is quite detailed, so things may not work properly unless you exactly replicate the configuration and behavior of whatever controller you're trying to emulate.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

HidHide on MacOS
 
 
Q