@@ -110,22 +110,28 @@ IDDCX_XOR_CURSOR_SUPPORT XorCursorSupportLevel = IDDCX_XOR_CURSOR_SUPPORT_FULL;
110110IDDCX_BITS_PER_COMPONENT SDRCOLOUR = IDDCX_BITS_PER_COMPONENT_8;
111111IDDCX_BITS_PER_COMPONENT HDRCOLOUR = IDDCX_BITS_PER_COMPONENT_10;
112112
113+ wstring ColourFormat = L" RGB" ;
114+
113115std::map<std::wstring, std::pair<std::wstring, std::wstring>> SettingsQueryMap = {
114116 {L" LoggingEnabled" , {L" LOGS" , L" logging" }},
115117 {L" DebugLoggingEnabled" , {L" DEBUGLOGS" , L" debuglogging" }},
116- {L" HDRPlusEnabled" , {L" HDRPLUS" , L" HDRPlus" }},
117- {L" SDR10Enabled" , {L" SDR10BIT" , L" SDR10bit" }},
118118 {L" CustomEdidEnabled" , {L" CUSTOMEDID" , L" CustomEdid" }},
119- { L" HardwareCursorEnabled " , { L" HARDWARECURSOR " , L" HardwareCursor " }},
119+
120120 {L" PreventMonitorSpoof" , {L" PREVENTMONITORSPOOF" , L" PreventSpoof" }},
121121 {L" EdidCeaOverride" , {L" EDIDCEAOVERRIDE" , L" EdidCeaOverride" }},
122122 {L" SendLogsThroughPipe" , {L" SENDLOGSTHROUGHPIPE" , L" SendLogsThroughPipe" }},
123- // Cursor
123+ // Cursor Begin
124+ {L" HardwareCursorEnabled" , {L" HARDWARECURSOR" , L" HardwareCursor" }},
124125 {L" AlphaCursorSupport" , {L" ALPHACURSORSUPPORT" , L" AlphaCursorSupport" }},
125126 {L" CursorMaxX" , {L" CURSORMAXX" , L" CursorMaxX" }},
126127 {L" CursorMaxY" , {L" CURSORMAXY" , L" CursorMaxY" }},
127128 {L" XorCursorSupportLevel" , {L" XORCURSORSUPPORTLEVEL" , L" XorCursorSupportLevel" }},
128-
129+ // /Cursor End
130+ // Colour Begin
131+ {L" HDRPlusEnabled" , {L" HDRPLUS" , L" HDRPlus" }},
132+ {L" SDR10Enabled" , {L" SDR10BIT" , L" SDR10bit" }},
133+ {L" ColourFormat" , {L" COLOURFORMAT" , L" ColourFormat" }},
134+ // Colour End
129135};
130136
131137const char * XorCursorSupportLevelToString (IDDCX_XOR_CURSOR_SUPPORT level) {
@@ -167,6 +173,14 @@ void LogQueries(const char* severity, const std::wstring& xmlName) {
167173 }
168174}
169175
176+ string WStringToString (const wstring& wstr) { // basically just a function for converting strings since codecvt is depricated in c++ 17
177+ if (wstr.empty ()) return " " ;
178+
179+ int size_needed = WideCharToMultiByte (CP_UTF8, 0 , wstr.c_str (), (int )wstr.size (), NULL , 0 , NULL , NULL );
180+ string str (size_needed, 0 );
181+ WideCharToMultiByte (CP_UTF8, 0 , wstr.c_str (), (int )wstr.size (), &str[0 ], size_needed, NULL , NULL );
182+ return str;
183+ }
170184
171185bool EnabledQuery (const std::wstring& settingKey) {
172186 auto it = SettingsQueryMap.find (settingKey);
@@ -351,16 +365,79 @@ int GetIntegerSetting(const std::wstring& settingKey) {
351365 return xmlLoggingValue;
352366}
353367
368+ std::wstring GetStringSetting (const std::wstring& settingKey) {
369+ auto it = SettingsQueryMap.find (settingKey);
370+ if (it == SettingsQueryMap.end ()) {
371+ vddlog (" e" , " requested data not found in xml, consider updating xml!" );
372+ return L" " ;
373+ }
354374
355- string WStringToString ( const wstring& wstr) { // basically just a function for converting strings since codecvt is depricated in c++ 17
356- if (wstr. empty ()) return " " ;
375+ std:: wstring regName = it-> second . first ;
376+ std::wstring xmlName = it-> second . second ;
357377
358- int size_needed = WideCharToMultiByte (CP_UTF8, 0 , wstr.c_str (), (int )wstr.size (), NULL , 0 , NULL , NULL );
359- string str (size_needed, 0 );
360- WideCharToMultiByte (CP_UTF8, 0 , wstr.c_str (), (int )wstr.size (), &str[0 ], size_needed, NULL , NULL );
361- return str;
378+ std::wstring settingsname = confpath + L" \\ vdd_settings.xml" ;
379+ HKEY hKey;
380+ DWORD dwBufferSize = MAX_PATH;
381+ wchar_t buffer[MAX_PATH];
382+
383+ LONG lResult = RegOpenKeyExW (HKEY_LOCAL_MACHINE, L" SOFTWARE\\ MikeTheTech\\ VirtualDisplayDriver" , 0 , KEY_READ, &hKey);
384+ if (lResult == ERROR_SUCCESS) {
385+ lResult = RegQueryValueExW (hKey, regName.c_str (), NULL , NULL , (LPBYTE)buffer, &dwBufferSize);
386+ RegCloseKey (hKey);
387+
388+ if (lResult == ERROR_SUCCESS) {
389+ LogQueries (" d" , xmlName + L" - Retrieved string value from registry: " + buffer);
390+ return std::wstring (buffer);
391+ }
392+ else {
393+ LogQueries (" d" , xmlName + L" - Failed to retrieve string value from registry. Attempting to read as XML." );
394+ }
395+ }
396+
397+ CComPtr<IStream> pFileStream;
398+ HRESULT hr = SHCreateStreamOnFileEx (settingsname.c_str (), STGM_READ, FILE_ATTRIBUTE_NORMAL, FALSE , nullptr , &pFileStream);
399+ if (FAILED (hr)) {
400+ LogQueries (" d" , xmlName + L" - Failed to create file stream for XML settings." );
401+ return L" " ;
402+ }
403+
404+ CComPtr<IXmlReader> pReader;
405+ hr = CreateXmlReader (__uuidof (IXmlReader), (void **)&pReader, nullptr );
406+ if (FAILED (hr)) {
407+ LogQueries (" d" , xmlName + L" - Failed to create XML reader." );
408+ return L" " ;
409+ }
410+
411+ hr = pReader->SetInput (pFileStream);
412+ if (FAILED (hr)) {
413+ LogQueries (" d" , xmlName + L" - Failed to set input for XML reader." );
414+ return L" " ;
415+ }
416+
417+ XmlNodeType nodeType;
418+ const wchar_t * pwszLocalName;
419+ std::wstring xmlLoggingValue = L" " ;
420+
421+ while (S_OK == pReader->Read (&nodeType)) {
422+ if (nodeType == XmlNodeType_Element) {
423+ pReader->GetLocalName (&pwszLocalName, nullptr );
424+ if (wcscmp (pwszLocalName, xmlName.c_str ()) == 0 ) {
425+ pReader->Read (&nodeType);
426+ if (nodeType == XmlNodeType_Text) {
427+ const wchar_t * pwszValue;
428+ pReader->GetValue (&pwszValue, nullptr );
429+ xmlLoggingValue = pwszValue;
430+ LogQueries (" i" , xmlName + L" - Retrieved from XML: " + xmlLoggingValue);
431+ break ;
432+ }
433+ }
434+ }
435+ }
436+
437+ return xmlLoggingValue;
362438}
363439
440+
364441int gcd (int a, int b) {
365442 while (b != 0 ) {
366443 int temp = b;
@@ -1346,16 +1423,20 @@ extern "C" NTSTATUS DriverEntry(
13461423 initpath ();
13471424 logsEnabled = EnabledQuery (L" LoggingEnabled" );
13481425 debugLogs = EnabledQuery (L" DebugLoggingEnabled" );
1349- HDRPlus = EnabledQuery (L" HDRPlusEnabled" );
1350- SDR10 = EnabledQuery (L" SDR10Enabled" );
1351- HDRCOLOUR = HDRPlus ? IDDCX_BITS_PER_COMPONENT_12 : IDDCX_BITS_PER_COMPONENT_10;
1352- SDRCOLOUR = SDR10 ? IDDCX_BITS_PER_COMPONENT_10 : IDDCX_BITS_PER_COMPONENT_8;
13531426
13541427 customEdid = EnabledQuery (L" CustomEdidEnabled" );
13551428 preventManufacturerSpoof = EnabledQuery (L" PreventMonitorSpoof" );
13561429 edidCeaOverride = EnabledQuery (L" EdidCeaOverride" );
13571430 sendLogsThroughPipe = EnabledQuery (L" SendLogsThroughPipe" );
13581431
1432+
1433+ // colour
1434+ HDRPlus = EnabledQuery (L" HDRPlusEnabled" );
1435+ SDR10 = EnabledQuery (L" SDR10Enabled" );
1436+ HDRCOLOUR = HDRPlus ? IDDCX_BITS_PER_COMPONENT_12 : IDDCX_BITS_PER_COMPONENT_10;
1437+ SDRCOLOUR = SDR10 ? IDDCX_BITS_PER_COMPONENT_10 : IDDCX_BITS_PER_COMPONENT_8;
1438+ ColourFormat = GetStringSetting (L" ColourFormat" );
1439+
13591440 // Cursor
13601441 hardwareCursor = EnabledQuery (L" HardwareCursorEnabled" );
13611442 alphaCursorSupport = EnabledQuery (L" AlphaCursorSupport" );
@@ -2820,14 +2901,31 @@ void CreateTargetMode2(IDDCX_TARGET_MODE2& Mode, UINT Width, UINT Height, UINT V
28202901 vddlog (" d" , logStream.str ().c_str ());
28212902
28222903 Mode.Size = sizeof (Mode);
2823- Mode.BitsPerComponent .Rgb = SDRCOLOUR | HDRCOLOUR;
2904+
2905+
2906+ if (ColourFormat == L" RGB" ) {
2907+ Mode.BitsPerComponent .Rgb = SDRCOLOUR | HDRCOLOUR;
2908+ }
2909+ else if (ColourFormat == L" YCbCr444" ) {
2910+ Mode.BitsPerComponent .YCbCr444 = SDRCOLOUR | HDRCOLOUR;
2911+ }
2912+ else if (ColourFormat == L" YCbCr422" ) {
2913+ Mode.BitsPerComponent .YCbCr422 = SDRCOLOUR | HDRCOLOUR;
2914+ }
2915+ else if (ColourFormat == L" YCbCr420" ) {
2916+ Mode.BitsPerComponent .YCbCr420 = SDRCOLOUR | HDRCOLOUR;
2917+ }
2918+ else {
2919+ Mode.BitsPerComponent .Rgb = SDRCOLOUR | HDRCOLOUR; // Default to RGB
2920+ }
28242921
28252922
28262923 logStream.str (" " );
28272924 logStream << " IDDCX_TARGET_MODE2 configured with Size: " << Mode.Size
2828- << " and BitsPerComponent.Rgb: " << Mode. BitsPerComponent . Rgb ;
2925+ << " and colour format " << WStringToString (ColourFormat) ;
28292926 vddlog (" d" , logStream.str ().c_str ());
28302927
2928+
28312929 CreateTargetMode (Mode.TargetVideoSignalInfo .targetVideoSignalInfo , Width, Height, VSyncNum, VSyncDen);
28322930}
28332931
@@ -2920,11 +3018,26 @@ NTSTATUS VirtualDisplayDriverEvtIddCxAdapterQueryTargetInfo(
29203018 UNREFERENCED_PARAMETER (pInArgs);
29213019
29223020 pOutArgs->TargetCaps = IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE | IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE;
2923- pOutArgs->DitheringSupport .Rgb = HDRCOLOUR;
3021+
3022+ if (ColourFormat == L" RGB" ) {
3023+ pOutArgs->DitheringSupport .Rgb = SDRCOLOUR | HDRCOLOUR;
3024+ }
3025+ else if (ColourFormat == L" YCbCr444" ) {
3026+ pOutArgs->DitheringSupport .YCbCr444 = SDRCOLOUR | HDRCOLOUR;
3027+ }
3028+ else if (ColourFormat == L" YCbCr422" ) {
3029+ pOutArgs->DitheringSupport .YCbCr422 = SDRCOLOUR | HDRCOLOUR;
3030+ }
3031+ else if (ColourFormat == L" YCbCr420" ) {
3032+ pOutArgs->DitheringSupport .YCbCr420 = SDRCOLOUR | HDRCOLOUR;
3033+ }
3034+ else {
3035+ pOutArgs->DitheringSupport .Rgb = SDRCOLOUR | HDRCOLOUR; // Default to RGB
3036+ }
29243037
29253038 logStream.str (" " );
29263039 logStream << " Target capabilities set to: " << pOutArgs->TargetCaps
2927- << " \n Dithering support set to: " << pOutArgs-> DitheringSupport . Rgb ;
3040+ << " \n Dithering support colour format set to: " << WStringToString (ColourFormat) ;
29283041 vddlog (" d" , logStream.str ().c_str ());
29293042
29303043 return STATUS_SUCCESS;
@@ -2995,13 +3108,30 @@ NTSTATUS VirtualDisplayDriverEvtIddCxParseMonitorDescription2(
29953108 pInArgs->pMonitorModes [ModeIndex].Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
29963109 pInArgs->pMonitorModes [ModeIndex].MonitorVideoSignalInfo = s_KnownMonitorModes2[ModeIndex];
29973110
2998- pInArgs->pMonitorModes [ModeIndex].BitsPerComponent .Rgb = SDRCOLOUR | HDRCOLOUR;
3111+
3112+ if (ColourFormat == L" RGB" ) {
3113+ pInArgs->pMonitorModes [ModeIndex].BitsPerComponent .Rgb = SDRCOLOUR | HDRCOLOUR;
3114+
3115+ }
3116+ else if (ColourFormat == L" YCbCr444" ) {
3117+ pInArgs->pMonitorModes [ModeIndex].BitsPerComponent .YCbCr444 = SDRCOLOUR | HDRCOLOUR;
3118+ }
3119+ else if (ColourFormat == L" YCbCr422" ) {
3120+ pInArgs->pMonitorModes [ModeIndex].BitsPerComponent .YCbCr422 = SDRCOLOUR | HDRCOLOUR;
3121+ }
3122+ else if (ColourFormat == L" YCbCr420" ) {
3123+ pInArgs->pMonitorModes [ModeIndex].BitsPerComponent .YCbCr420 = SDRCOLOUR | HDRCOLOUR;
3124+ }
3125+ else {
3126+ pInArgs->pMonitorModes [ModeIndex].BitsPerComponent .Rgb = SDRCOLOUR | HDRCOLOUR; // Default to RGB
3127+ }
3128+
29993129
30003130
30013131 logStream << " \n ModeIndex: " << ModeIndex
30023132 << " \n Size: " << pInArgs->pMonitorModes [ModeIndex].Size
30033133 << " \n Origin: " << pInArgs->pMonitorModes [ModeIndex].Origin
3004- << " \n BitsPerComponent.Rgb : " << pInArgs-> pMonitorModes [ModeIndex]. BitsPerComponent . Rgb ;
3134+ << " \n Colour Format : " << WStringToString (ColourFormat) ;
30053135 }
30063136
30073137 vddlog (" d" , logStream.str ().c_str ());
@@ -3062,7 +3192,7 @@ NTSTATUS VirtualDisplayDriverEvtIddCxMonitorQueryTargetModes2(
30623192 {
30633193 logStream << " \n TargetModeIndex: " << i
30643194 << " \n Size: " << TargetModes[i].Size
3065- << " \n BitsPerComponent.Rgb : " << TargetModes[i]. BitsPerComponent . Rgb ;
3195+ << " \n ColourFormat : " << WStringToString (ColourFormat) ;
30663196 }
30673197 vddlog (" d" , logStream.str ().c_str ());
30683198 }
0 commit comments