LampArray Basics

This page describes how to register LampArray callbacks and interact with ILampArray and ILampInfo instances.

Please note: As of the March 2023 recovery, the GDK Lighting API only supports the following devices on console. Support for additional devices will be added in future recovery releases.

  • Razer Turret for Xbox One (keyboard and mouse)
  • Razer BlackWidow Tournament Edition Chroma V2

ILampArray and ILampInfo

Each compatible lighting device connected to the system is represented by an ILampArray instance. ILampArray provides information about the device, such as its dimensions, device type, manufacturer, and number of Lamps. It also exposes methods to change the brightness and color values of its Lamps.

An ILampInfo object encapsulates properties of an individual Lamp in the LampArray, including the Lamp's relative position, color support and intended purposes. ILampInfo instances can be retrieved using ILampArray::GetLampInfo.

NOTE: Like the graphics, audio, and GameInput APIs, ILampArray and ILampInfo aren't true COM APIs, even though they expose interfaces that derive from IUnknown. This style of API is sometimes referred to as "COM lite" or "nano-COM." While IUnknown is used for reference counting and reflection, the COM runtime infrastructure isn't used by ILampArray or ILampInfo. Specifically, this means the following:

  • Applications call neither CoInitialize nor CoCreateInstance to obtain object instances.
  • COM features such as aggregation and caller-provided interface implementations aren't supported.
  • There's no cross-process marshaling support, and no apartment/threading model. All objects are agile.
  • Interface pointers can be compared directly for object identity, without going through IUnknown.
  • Methods aren't required to return HRESULT codes, which often leads to simpler function signatures.

LampArray Callbacks

LampArray callbacks are the mechanism for obtaining ILampArray instances and for being notified when LampArrays are attached or removed from the system.

RegisterLampArrayCallback

typedef interface ILampArray ILampArray;

typedef uint64_t LampArrayCallbackToken;

typedef void (CALLBACK * LampArrayCallback)(
    _In_opt_ void * context,
    bool isAttached,
    _In_ ILampArray * lampArray);

HRESULT RegisterLampArrayCallback(
    _In_ LampArrayCallback lampArrayCallback,
    _In_opt_ void* context,
    _Out_ _Result_zeroonfailure_ LampArrayCallbackToken* callbackToken);

Callback Threading

If any LampArray devices are attached at the time a callback is registered, the RegisterLampArrayCallback function will block until that callback is invoked for each attached device (meaning the callback will be invoked on the calling thread).

When the first callback is registered, the LampArray API starts a worker thread to handle ILampArray device attach and removal notifications. These events are infrequent, and the worker thread otherwise remains in a wait state. After the registration call returns, all subsequent LampArrayCallbacks will be invoked sequentially on this worker thread.

Processor affinity for the LampArray worker thread can be controlled using TrySetLampArrayWorkerThreadAffinityMask. This API can be called at most once per process. Any subsequent calls to the API will not take effect.

HRESULT TrySetLampArrayWorkerThreadAffinityMask(
    uint64_t threadAffinityMask);

Unregistering Callbacks

After a callback is successfully registered, the application must guarantee that any resources that are required to execute the callback remain valid. This includes both resources that are consumed by the callback's code, as well as the callback function itself, for example, if the callback function is hosted in a DLL that the application loads and unloads on demand.

To safely reclaim these resources, an application must first unregister the callback by passing the token that was received from the RegisterLampArrayCallback method into the UnregisterLampArrayCallback method. Unregistering a LampArray callback from inside a registered LampArray callback is not supported, and attempting to do so will terminate the process.

bool UnregisterLampArrayCallback(
    LampArrayCallbackToken callbackToken,
    uint64_t timeoutInMicroseconds);

See also

Lighting API Overview
ILampArray Reference
ILampInfo Reference