libdisplaydevice v2026.322.2407
C++ library to modify display devices.
display_device::WinApiLayerInterface Class Referenceabstract

Lowest level Windows API wrapper for easy mocking. More...

#include <src/windows/include/display_device/windows/win_api_layer_interface.h>

Inheritance diagram for display_device::WinApiLayerInterface:
[legend]

Public Member Functions

virtual std::string getDeviceId (const DISPLAYCONFIG_PATH_INFO &path) const =0
 Get a stable and persistent device id for the path.
 
virtual std::string getDisplayName (const DISPLAYCONFIG_PATH_INFO &path) const =0
 Get the logical display name for the path.
 
virtual std::optional< RationalgetDisplayScale (const std::string &display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const =0
 Get the scaling value for the display.
 
virtual std::vector< std::byte > getEdid (const DISPLAYCONFIG_PATH_INFO &path) const =0
 Get EDID byte array for the path.
 
virtual std::string getErrorString (LONG error_code) const =0
 Stringify the error code from Windows API.
 
virtual std::string getFriendlyName (const DISPLAYCONFIG_PATH_INFO &path) const =0
 Get the user-friendly name for the path.
 
virtual std::optional< HdrStategetHdrState (const DISPLAYCONFIG_PATH_INFO &path) const =0
 Get the HDR state the path.
 
virtual std::string getMonitorDevicePath (const DISPLAYCONFIG_PATH_INFO &path) const =0
 Get a string that represents a path from the adapter to the display target.
 
virtual std::optional< PathAndModeDataqueryDisplayConfig (QueryType type) const =0
 Query Windows for the device paths and associated modes.
 
virtual LONG setDisplayConfig (std::vector< DISPLAYCONFIG_PATH_INFO > paths, std::vector< DISPLAYCONFIG_MODE_INFO > modes, UINT32 flags)=0
 Direct wrapper around the SetDisplayConfig WinAPI.
 
virtual bool setHdrState (const DISPLAYCONFIG_PATH_INFO &path, HdrState state)=0
 Set the HDR state for the path.
 
virtual ~WinApiLayerInterface ()=default
 Default virtual destructor.
 

Detailed Description

Lowest level Windows API wrapper for easy mocking.

Member Function Documentation

◆ getDeviceId()

virtual std::string display_device::WinApiLayerInterface::getDeviceId ( const DISPLAYCONFIG_PATH_INFO & path) const
nodiscardpure virtual

Get a stable and persistent device id for the path.

This function tries to generate a unique id for the path that is persistent between driver re-installs and physical unplugging and replugging of the device.

The best candidate for it could have been a "ContainerID" from the registry, however it was found to be unstable for the virtual display (probably because it uses the EDID for the id generation and the current virtual displays have incomplete EDID information). The "ContainerID" also does not change if the physical device is plugged into a different port (which does not satisfy the "device id for the path" part) and is unstable for virtual displays, therefore other solution was used.

The accepted solution was to use the "InstanceID" and EDID (just to be on the safe side). "InstanceID" is semi-stable, it has some parts that change between driver re-installs, and it has a part that changes based on the GPU port that the display is connected to. It is most likely to be unique, but since the MS documentation is lacking we are also hashing EDID information (contains serial ids, timestamps, etc. that should guarantee that identical displays are differentiated like with the "ContainerID"). Most importantly this information is stable for the virtual displays.

After we remove the unstable parts from the "InstanceID" and hash everything together, we get an id that changes only when you connect the display to a different GPU port which seems to be acceptable.

As a fallback we are using a hashed device path, in case the "InstanceID" or EDID is not available. At least if you don't do driver re-installs often and change the GPU ports, it will be stable for a while.

Parameters
pathPath to get the device id for.
Returns
Device id, or an empty string if it could not be generated.
See also
queryDisplayConfig on how to get paths from the system.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
const WinApiLayerInterface* iface = getIface(...);
const std::string device_path = iface->getDeviceId(path);
Lowest level Windows API wrapper for easy mocking.
Definition win_api_layer_interface.h:14
virtual std::string getDeviceId(const DISPLAYCONFIG_PATH_INFO &path) const =0
Get a stable and persistent device id for the path.

Implemented in display_device::WinApiLayer.

◆ getDisplayName()

virtual std::string display_device::WinApiLayerInterface::getDisplayName ( const DISPLAYCONFIG_PATH_INFO & path) const
nodiscardpure virtual

Get the logical display name for the path.

These are the "\\\\.\\DISPLAY1", "\\\\.\\DISPLAY2" and etc. display names that can change whenever Windows wants to change them.

Parameters
pathPath to get user display name for.
Returns
Display name for the path if available, empty string otherwise.
See also
queryDisplayConfig on how to get paths from the system.
Note
Inactive paths can have these names already assigned to them, even though they are not even in use! There can also be duplicates.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
const WinApiLayerInterface* iface = getIface(...);
const std::string display_name = iface->getDisplayName(path);
virtual std::string getDisplayName(const DISPLAYCONFIG_PATH_INFO &path) const =0
Get the logical display name for the path.

Implemented in display_device::WinApiLayer.

◆ getDisplayScale()

virtual std::optional< Rational > display_device::WinApiLayerInterface::getDisplayScale ( const std::string & display_name,
const DISPLAYCONFIG_SOURCE_MODE & source_mode ) const
nodiscardpure virtual

Get the scaling value for the display.

Parameters
display_nameDisplay to get the scaling for.
source_modeSource mode to get the scaling for.
Returns
Current display scale value or null optional in case of error or if the value could not be retrieved.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
DISPLAYCONFIG_SOURCE_MODE source_mode;
const WinApiLayerInterface* iface = getIface(...);
const auto scale = iface->getDisplayScale(iface->getDisplayName(path), source_mode);
virtual std::optional< Rational > getDisplayScale(const std::string &display_name, const DISPLAYCONFIG_SOURCE_MODE &source_mode) const =0
Get the scaling value for the display.

Implemented in display_device::WinApiLayer.

◆ getEdid()

virtual std::vector< std::byte > display_device::WinApiLayerInterface::getEdid ( const DISPLAYCONFIG_PATH_INFO & path) const
nodiscardpure virtual

Get EDID byte array for the path.

Parameters
pathPath to get the EDID for.
Returns
EDID byte array, or an empty array if error has occurred.

Implemented in display_device::WinApiLayer.

◆ getErrorString()

virtual std::string display_device::WinApiLayerInterface::getErrorString ( LONG error_code) const
nodiscardpure virtual

Stringify the error code from Windows API.

Parameters
error_codeError code to stringify.
Returns
String containing the error code in a readable format + a system message describing the code.

*Examples**

const WinApiLayerInterface* iface = getIface(...);
const std::string error_message = iface->getErrorString(ERROR_NOT_SUPPORTED);
virtual std::string getErrorString(LONG error_code) const =0
Stringify the error code from Windows API.

Implemented in display_device::WinApiLayer.

◆ getFriendlyName()

virtual std::string display_device::WinApiLayerInterface::getFriendlyName ( const DISPLAYCONFIG_PATH_INFO & path) const
nodiscardpure virtual

Get the user-friendly name for the path.

Parameters
pathPath to get user-friendly name for.
Returns
User-friendly name for the path if available, empty string otherwise.
See also
queryDisplayConfig on how to get paths from the system.
Note
This is usually a monitor name (like "ROG PG279Q") and is most likely taken from EDID.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
const WinApiLayerInterface* iface = getIface(...);
const std::string friendly_name = iface->getFriendlyName(path);
virtual std::string getFriendlyName(const DISPLAYCONFIG_PATH_INFO &path) const =0
Get the user-friendly name for the path.

Implemented in display_device::WinApiLayer.

◆ getHdrState()

virtual std::optional< HdrState > display_device::WinApiLayerInterface::getHdrState ( const DISPLAYCONFIG_PATH_INFO & path) const
nodiscardpure virtual

Get the HDR state the path.

Parameters
pathPath to get HDR state for.
Returns
std::nullopt if the state could not be retrieved, or other enum values describing the state otherwise.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
const WinApiLayerInterface* iface = getIface(...);
const auto hdr_state = iface->getHdrState(path);
virtual std::optional< HdrState > getHdrState(const DISPLAYCONFIG_PATH_INFO &path) const =0
Get the HDR state the path.

Implemented in display_device::WinApiLayer.

◆ getMonitorDevicePath()

virtual std::string display_device::WinApiLayerInterface::getMonitorDevicePath ( const DISPLAYCONFIG_PATH_INFO & path) const
nodiscardpure virtual

Get a string that represents a path from the adapter to the display target.

Parameters
pathPath to get the string for.
Returns
String representation, or an empty string if it's not available.
See also
queryDisplayConfig on how to get paths from the system.
Note
In the rest of the code we refer to this string representation simply as the "device path". It is used as a simple way of grouping related path objects together and removing "bad" paths that don't have such string representation.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
const WinApiLayerInterface* iface = getIface(...);
const std::string device_path = iface->getMonitorDevicePath(path);
virtual std::string getMonitorDevicePath(const DISPLAYCONFIG_PATH_INFO &path) const =0
Get a string that represents a path from the adapter to the display target.

Implemented in display_device::WinApiLayer.

◆ queryDisplayConfig()

virtual std::optional< PathAndModeData > display_device::WinApiLayerInterface::queryDisplayConfig ( QueryType type) const
nodiscardpure virtual

Query Windows for the device paths and associated modes.

Parameters
typeSpecify device type to query for.
Returns
Data containing paths and modes, empty optional if we have failed to query.

*Examples**

const WinApiLayerInterface* iface = getIface(...);
const auto display_data = iface->queryDisplayConfig(QueryType::Active);
virtual std::optional< PathAndModeData > queryDisplayConfig(QueryType type) const =0
Query Windows for the device paths and associated modes.

Implemented in display_device::WinApiLayer.

◆ setDisplayConfig()

virtual LONG display_device::WinApiLayerInterface::setDisplayConfig ( std::vector< DISPLAYCONFIG_PATH_INFO > paths,
std::vector< DISPLAYCONFIG_MODE_INFO > modes,
UINT32 flags )
nodiscardpure virtual

Direct wrapper around the SetDisplayConfig WinAPI.

It implements no additional logic, just a direct pass-trough.

Parameters
pathsList of paths to pass.
modesList of modes to pass.
flagsFlags to pass.
Returns
The return error code of the API.

*Examples**

std::vector<DISPLAYCONFIG_PATH_INFO> paths;
WinApiLayerInterface* iface = getIface(...);
const auto result = iface->setDisplayConfig(paths, {}, 0);
virtual LONG setDisplayConfig(std::vector< DISPLAYCONFIG_PATH_INFO > paths, std::vector< DISPLAYCONFIG_MODE_INFO > modes, UINT32 flags)=0
Direct wrapper around the SetDisplayConfig WinAPI.

Implemented in display_device::WinApiLayer.

◆ setHdrState()

virtual bool display_device::WinApiLayerInterface::setHdrState ( const DISPLAYCONFIG_PATH_INFO & path,
HdrState state )
nodiscardpure virtual

Set the HDR state for the path.

Parameters
pathPath to set HDR state for.
stateSpecify new HDR state.
Returns
True if the device is in the new state, false otherwise.

*Examples**

DISPLAYCONFIG_PATH_INFO path;
WinApiLayerInterface* iface = getIface(...);
const bool success = iface->setHdrState(path, HdrState::Enabled);
virtual bool setHdrState(const DISPLAYCONFIG_PATH_INFO &path, HdrState state)=0
Set the HDR state for the path.

Implemented in display_device::WinApiLayer.


The documentation for this class was generated from the following file: