GameInput devices

Every physical input device that's connected to the system is represented by the IGameInputDevice interface. Like readings, device instances are reference-counted singletons, which means that the interface pointers can be compared for equality. The majority of a typical application's input code only uses device instances in this way, as a sort of device identifier when calling other APIs (for example, as a filter when retrieving readings).

The IGameInputDevice interface methods are typically only called when an application needs to interact directly with a specific device in some way. The most common reason is to send haptic or force feedback commands to the device. However, this interface also exposes device properties and provides access to low-level device I/O, which might be needed by more advanced code.

Device properties

Applications that need to know specific details about a device can call the property getter methods of IGameInputDevice. For example, GetVendorId and GetProductId identify the hardware, GetSupportedInput returns the kinds of input the device produces, GetDisplayName returns a name that can be shown to the user, and GetGamepadInfo describes the layout and labels of a gamepad.

Most device properties don't change for the lifetime of the device. Properties that can change, such as the keyboard layout, haptic information, and XInput index, are signaled by GameInputDeviceEvent values delivered to a device callback. For more information, see Device enumeration.

GameInput v3 and earlier

In GameInput v3 and earlier, device properties are available through the GameInputDeviceInfo structure, which is returned by the GetDeviceInfo method.

Device information can be big—sometimes 10 KB or more. For efficiency reasons, the GameInput API doesn't make a copy of the device data, but instead temporarily grants applications direct access to the data stored internally within GameInput. This approach favors high-performance code by avoiding buffer allocations and large memory transfers, because applications often are interested only in some small portion of the data. This also enables the GameInputDeviceInfo structure to contain nested pointers to other regions within the device info data block where various supporting arrays of information can be found, without adding the complexity of variable-sized output and deep copies.

Device IDs

One important piece of information available for each device is the device's application-local device ID, which is returned by GetDeviceId. This is a special 32-byte value that uniquely identifies the device, even across restarts of the application or reboots of the system. This ID is also stable across disconnects and reconnects of wireless devices, and wired USB devices as long as they are plugged back into the same USB port.

The app-local device ID is most commonly used to identify specific devices beyond the lifetime of the application. For example, a game with an input-mapping UI can use the device ID to ensure the user's input configuration is applied to the same devices each time the app starts. This is especially important for applications that support complex mappings across multiple devices that may otherwise appear identical (for example, a set of homogenous instrument panel devices for a flight simulator).

Device enumeration

While most applications should never need it, GameInput does support explicit enumeration of connected devices. This can be performed via the IGameInput interface's RegisterDeviceCallback method.

HRESULT RegisterDeviceCallback(
    _In_opt_ IGameInputDevice * device,
    _In_ GameInputKind inputKind,
    _In_opt_ void * context,
    _In_ GameInputDeviceCallback callbackFunc,
    _Out_opt_ _Result_zeroonfailure_ GameInputCallbackToken * callbackToken);

This method handles both device enumeration and device notifications by first triggering an initial series of GameInputDeviceEventConnected callbacks for every connected device, and then subsequent callbacks whenever devices are connected, disconnected, or updated. The initial callbacks are always dispatched asynchronously.

In GameInput v3 and earlier, the method takes additional statusFilter and enumerationKind parameters. Applications can use the GameInputEnumerationKind parameter to control whether the function blocks until all the initial callbacks have been dispatched, or whether it returns immediately and the callbacks are dispatched asynchronously.

Filters are available to control which devices are included in the enumeration and trigger callbacks. For more information, see RegisterDeviceCallback. For general information about how callbacks work, see GameInput callbacks.

Reference API documentation

See also

GameInput fundamentals

Advanced GameInput topics

GameInput API reference