From aa0089a3ec469ad725a8756fcf98e09bb7f3cc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 19 Nov 2022 22:55:08 +0100 Subject: [PATCH] [DXDIAG] Rework display enumeration, to use DirectDrawEnumerateEx We can now get a device GUID by display, which is given to DirectDrawCreate. --- base/applications/dxdiag/display.c | 115 ++++++++++++++++++----------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/base/applications/dxdiag/display.c b/base/applications/dxdiag/display.c index b5f3c561058..8b0171bfcdc 100644 --- a/base/applications/dxdiag/display.c +++ b/base/applications/dxdiag/display.c @@ -305,62 +305,89 @@ InitializeDialog(HWND hwndDlg, PDISPLAY_DEVICEW pDispDevice) return TRUE; } -void InitializeDisplayAdapters(PDXDIAG_CONTEXT pContext) + +static BOOL WINAPI +DDEnumerateCallback( + IN GUID *lpGuid, + IN LPSTR lpDriverName, + IN LPSTR lpDriverDescription, + IN LPVOID lpContext, + IN HMONITOR hMonitor) { DISPLAY_DEVICEW DispDevice; + LPWSTR lpDriverDescriptionW; + PDXDIAG_CONTEXT pContext = lpContext; PDXDIAG_DISPLAY *pDisplayAdapters; PDXDIAG_DISPLAY pDisplayAdapter; HWND hwndDlg; WCHAR szDisplay[20]; WCHAR szText[30]; - DWORD dwOffset = 0; + int len; + BOOL ret; - while(TRUE) + /* Convert lpDriverDescription to WCHAR */ + len = MultiByteToWideChar(CP_ACP, 0, lpDriverDescription, strlen(lpDriverDescription), NULL, 0); + if (!len) + return FALSE; + lpDriverDescriptionW = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); + if (!lpDriverDescriptionW) + return FALSE; + MultiByteToWideChar(CP_ACP, 0, lpDriverDescription, strlen(lpDriverDescription), lpDriverDescriptionW, len); + lpDriverDescriptionW[len] = UNICODE_NULL; + + /* Get associated display device */ + ZeroMemory(&DispDevice, sizeof(DispDevice)); + DispDevice.cb = sizeof(DispDevice); + ret = EnumDisplayDevicesW(lpDriverDescriptionW, 0, &DispDevice, 0); + HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW); + if (!ret) + return TRUE; + + pDisplayAdapter = HeapAlloc(GetProcessHeap(), 0, sizeof(DXDIAG_DISPLAY)); + if (!pDisplayAdapter) + return FALSE; + + if (pContext->NumDisplayAdapter) + pDisplayAdapters = HeapReAlloc(GetProcessHeap(), 0, pContext->DisplayAdapters, (pContext->NumDisplayAdapter + 1) * sizeof(PDXDIAG_DISPLAY)); + else + pDisplayAdapters = HeapAlloc(GetProcessHeap(), 0, (pContext->NumDisplayAdapter + 1) * sizeof(PDXDIAG_DISPLAY)); + + if (!pDisplayAdapters) { - ZeroMemory(&DispDevice, sizeof(DISPLAY_DEVICEW)); - DispDevice.cb = sizeof(DISPLAY_DEVICEW); - if (!EnumDisplayDevicesW(NULL, pContext->NumDisplayAdapter + dwOffset, &DispDevice, 0)) - return; - - /* skip devices not attached to the desktop and mirror drivers */ - if (!(DispDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) || (DispDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) - { - dwOffset++; - continue; - } - if (pContext->NumDisplayAdapter) - pDisplayAdapters = HeapReAlloc(GetProcessHeap(), 0, pContext->DisplayAdapters, (pContext->NumDisplayAdapter + 1) * sizeof(PDXDIAG_DISPLAY)); - else - pDisplayAdapters = HeapAlloc(GetProcessHeap(), 0, sizeof(PDXDIAG_DISPLAY)); - - if (!pDisplayAdapters) - break; - - pDisplayAdapter = HeapAlloc(GetProcessHeap(), 0, sizeof(DXDIAG_DISPLAY)); - if (!pDisplayAdapter) - break; - - pContext->DisplayAdapters = pDisplayAdapters; - hwndDlg = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DISPLAY_DIALOG), pContext->hMainDialog, DisplayPageWndProc, (LPARAM)pDisplayAdapter); EnableDialogTheme(hwndDlg); - if (!hwndDlg) - break; - - /* initialize the dialog */ - InitializeDialog(hwndDlg, &DispDevice); - - szDisplay[0] = L'\0'; - LoadStringW(hInst, IDS_DISPLAY_DIALOG, szDisplay, sizeof(szDisplay)/sizeof(WCHAR)); - szDisplay[(sizeof(szDisplay)/sizeof(WCHAR))-1] = L'\0'; - - wsprintfW (szText, L"%s %u", szDisplay, pContext->NumDisplayAdapter + 1); - InsertTabCtrlItem(GetDlgItem(pContext->hMainDialog, IDC_TAB_CONTROL), pContext->NumDisplayAdapter + 1, szText); - - pDisplayAdapter->hDisplayWnd = hwndDlg; - pDisplayAdapters[pContext->NumDisplayAdapter] = pDisplayAdapter; - pContext->NumDisplayAdapter++; + HeapFree(GetProcessHeap(), 0, pDisplayAdapter); + return FALSE; } + pContext->DisplayAdapters = pDisplayAdapters; + hwndDlg = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DISPLAY_DIALOG), pContext->hMainDialog, DisplayPageWndProc, (LPARAM)pDisplayAdapter); + EnableDialogTheme(hwndDlg); + if (!hwndDlg) + { + HeapFree(GetProcessHeap(), 0, pDisplayAdapter); + return FALSE; + } + /* initialize the dialog */ + InitializeDialog(hwndDlg, &DispDevice); + + szDisplay[0] = UNICODE_NULL; + LoadStringW(hInst, IDS_DISPLAY_DIALOG, szDisplay, ARRAYSIZE(szDisplay)); + szDisplay[ARRAYSIZE(szDisplay) - 1] = UNICODE_NULL; + + wsprintfW(szText, L"%s %u", szDisplay, pContext->NumDisplayAdapter + 1); + InsertTabCtrlItem(GetDlgItem(pContext->hMainDialog, IDC_TAB_CONTROL), pContext->NumDisplayAdapter + 1, szText); + + pDisplayAdapter->hDisplayWnd = hwndDlg; + if (lpGuid) + pDisplayAdapter->guid = *lpGuid; + pContext->DisplayAdapters[pContext->NumDisplayAdapter++] = pDisplayAdapter; + return TRUE; +} + + +void InitializeDisplayAdapters(PDXDIAG_CONTEXT pContext) +{ + DirectDrawEnumerateExA(DDEnumerateCallback, pContext, DDENUM_ATTACHEDSECONDARYDEVICES); }