From 670ebb242c95be16f276f271a64a140298f2b127 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Mon, 17 Apr 2017 19:44:32 +0000 Subject: [PATCH] [WIN32K:ENG] - Split populating the display mode list out from EngpRegisterGraphicsDevice, into its own function, EngpPopulateDeviceModeList. Based on a patch by Ismael Ferreras Morezuelas. CORE-6742 svn path=/trunk/; revision=74359 --- reactos/win32ss/gdi/eng/device.c | 242 +++++++++++++++++-------------- reactos/win32ss/gdi/eng/device.h | 5 + 2 files changed, 136 insertions(+), 111 deletions(-) diff --git a/reactos/win32ss/gdi/eng/device.c b/reactos/win32ss/gdi/eng/device.c index e1d6363e5b0..0123a2713c9 100644 --- a/reactos/win32ss/gdi/eng/device.c +++ b/reactos/win32ss/gdi/eng/device.c @@ -30,6 +30,132 @@ InitDeviceImpl(VOID) return STATUS_SUCCESS; } +BOOLEAN +EngpPopulateDeviceModeList( + _Inout_ PGRAPHICS_DEVICE pGraphicsDevice, + _In_ PDEVMODEW pdmDefault) +{ + PWSTR pwsz; + PLDEVOBJ pldev; + PDEVMODEINFO pdminfo; + PDEVMODEW pdm, pdmEnd; + ULONG i, cModes = 0; + BOOLEAN bModeMatch = FALSE; + + ASSERT(pGraphicsDevice->pdevmodeInfo == NULL); + ASSERT(pGraphicsDevice->pDevModeList == NULL); + + pwsz = pGraphicsDevice->pDiplayDrivers; + + /* Loop through the driver names + * This is a REG_MULTI_SZ string */ + for (; *pwsz; pwsz += wcslen(pwsz) + 1) + { + TRACE("trying driver: %ls\n", pwsz); + /* Try to load the display driver */ + pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY); + if (!pldev) + { + ERR("Could not load driver: '%ls'\n", pwsz); + continue; + } + + /* Get the mode list from the driver */ + pdminfo = LDEVOBJ_pdmiGetModes(pldev, pGraphicsDevice->DeviceObject); + if (!pdminfo) + { + ERR("Could not get mode list for '%ls'\n", pwsz); + continue; + } + + /* Attach the mode info to the device */ + pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo; + pGraphicsDevice->pdevmodeInfo = pdminfo; + + /* Loop all DEVMODEs */ + pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); + for (pdm = pdminfo->adevmode; + (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0); + pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) + { + /* Count this DEVMODE */ + cModes++; + + /* Some drivers like the VBox driver don't fill the dmDeviceName + with the name of the display driver. So fix that here. */ + wcsncpy(pdm->dmDeviceName, pwsz, CCHDEVICENAME); + pdm->dmDeviceName[CCHDEVICENAME - 1] = 0; + } + + // FIXME: release the driver again until it's used? + } + + if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) + { + ERR("No devmodes\n"); + return FALSE; + } + + /* Allocate an index buffer */ + pGraphicsDevice->cDevModes = cModes; + pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool, + cModes * sizeof(DEVMODEENTRY), + GDITAG_GDEVICE); + if (!pGraphicsDevice->pDevModeList) + { + ERR("No devmode list\n"); + return FALSE; + } + + TRACE("Looking for mode %lux%lux%lu(%lu Hz)\n", + pdmDefault->dmPelsWidth, + pdmDefault->dmPelsHeight, + pdmDefault->dmBitsPerPel, + pdmDefault->dmDisplayFrequency); + + /* Loop through all DEVMODEINFOs */ + for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0; + pdminfo; + pdminfo = pdminfo->pdmiNext) + { + /* Calculate End of the DEVMODEs */ + pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); + + /* Loop through the DEVMODEs */ + for (pdm = pdminfo->adevmode; + (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0); + pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) + { + TRACE(" %S has mode %lux%lux%lu(%lu Hz)\n", + pdm->dmDeviceName, + pdm->dmPelsWidth, + pdm->dmPelsHeight, + pdm->dmBitsPerPel, + pdm->dmDisplayFrequency); + /* Compare with the default entry */ + if (!bModeMatch && + pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel && + pdm->dmPelsWidth == pdmDefault->dmPelsWidth && + pdm->dmPelsHeight == pdmDefault->dmPelsHeight) + { + pGraphicsDevice->iDefaultMode = i; + pGraphicsDevice->iCurrentMode = i; + TRACE("Found default entry: %lu '%ls'\n", i, pdm->dmDeviceName); + if (pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency) + { + /* Uh oh, even the display frequency matches. */ + bModeMatch = TRUE; + } + } + + /* Initialize the entry */ + pGraphicsDevice->pDevModeList[i].dwFlags = 0; + pGraphicsDevice->pDevModeList[i].pdm = pdm; + i++; + } + } + return TRUE; +} PGRAPHICS_DEVICE NTAPI @@ -44,13 +170,9 @@ EngpRegisterGraphicsDevice( PFILE_OBJECT pFileObject; NTSTATUS Status; PWSTR pwsz; - ULONG i, cj, cModes = 0; + ULONG cj; SIZE_T cjWritten; BOOL bEnable = TRUE; - PDEVMODEINFO pdminfo; - PDEVMODEW pdm, pdmEnd; - PLDEVOBJ pldev; - BOOLEAN bModeMatch = FALSE; TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName); @@ -124,116 +246,14 @@ EngpRegisterGraphicsDevice( // FIXME: initialize state flags pGraphicsDevice->StateFlags = 0; - /* Loop through the driver names - * This is a REG_MULTI_SZ string */ - for (; *pwsz; pwsz += wcslen(pwsz) + 1) + /* Create the mode list */ + pGraphicsDevice->pDevModeList = NULL; + if (!EngpPopulateDeviceModeList(pGraphicsDevice, pdmDefault)) { - TRACE("trying driver: %ls\n", pwsz); - /* Try to load the display driver */ - pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY); - if (!pldev) - { - ERR("Could not load driver: '%ls'\n", pwsz); - continue; - } - - /* Get the mode list from the driver */ - pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject); - if (!pdminfo) - { - ERR("Could not get mode list for '%ls'\n", pwsz); - continue; - } - - /* Attach the mode info to the device */ - pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo; - pGraphicsDevice->pdevmodeInfo = pdminfo; - - /* Loop all DEVMODEs */ - pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); - for (pdm = pdminfo->adevmode; - (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0); - pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) - { - /* Count this DEVMODE */ - cModes++; - - /* Some drivers like the VBox driver don't fill the dmDeviceName - with the name of the display driver. So fix that here. */ - wcsncpy(pdm->dmDeviceName, pwsz, CCHDEVICENAME); - pdm->dmDeviceName[CCHDEVICENAME - 1] = 0; - } - - // FIXME: release the driver again until it's used? - } - - if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) - { - ERR("No devmodes\n"); ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } - /* Allocate an index buffer */ - pGraphicsDevice->cDevModes = cModes; - pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool, - cModes * sizeof(DEVMODEENTRY), - GDITAG_GDEVICE); - if (!pGraphicsDevice->pDevModeList) - { - ERR("No devmode list\n"); - ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); - return NULL; - } - - TRACE("Looking for mode %lux%lux%lu(%lu Hz)\n", - pdmDefault->dmPelsWidth, - pdmDefault->dmPelsHeight, - pdmDefault->dmBitsPerPel, - pdmDefault->dmDisplayFrequency); - - /* Loop through all DEVMODEINFOs */ - for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0; - pdminfo; - pdminfo = pdminfo->pdmiNext) - { - /* Calculate End of the DEVMODEs */ - pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); - - /* Loop through the DEVMODEs */ - for (pdm = pdminfo->adevmode; - (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0); - pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) - { - TRACE(" %S has mode %lux%lux%lu(%lu Hz)\n", - pdm->dmDeviceName, - pdm->dmPelsWidth, - pdm->dmPelsHeight, - pdm->dmBitsPerPel, - pdm->dmDisplayFrequency); - /* Compare with the default entry */ - if (!bModeMatch && - pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel && - pdm->dmPelsWidth == pdmDefault->dmPelsWidth && - pdm->dmPelsHeight == pdmDefault->dmPelsHeight) - { - pGraphicsDevice->iDefaultMode = i; - pGraphicsDevice->iCurrentMode = i; - TRACE("Found default entry: %lu '%ls'\n", i, pdm->dmDeviceName); - if (pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency) - { - /* Uh oh, even the display frequency matches. */ - bModeMatch = TRUE; - } - } - - /* Initialize the entry */ - pGraphicsDevice->pDevModeList[i].dwFlags = 0; - pGraphicsDevice->pDevModeList[i].pdm = pdm; - i++; - } - } - /* Lock loader */ EngAcquireSemaphore(ghsemGraphicsDeviceList); @@ -250,7 +270,7 @@ EngpRegisterGraphicsDevice( /* Unlock loader */ EngReleaseSemaphore(ghsemGraphicsDeviceList); - TRACE("Prepared %lu modes for %ls\n", cModes, pGraphicsDevice->pwszDescription); + TRACE("Prepared %lu modes for %ls\n", pGraphicsDevice->cDevModes, pGraphicsDevice->pwszDescription); return pGraphicsDevice; } diff --git a/reactos/win32ss/gdi/eng/device.h b/reactos/win32ss/gdi/eng/device.h index e194456544f..35ac63a5f99 100644 --- a/reactos/win32ss/gdi/eng/device.h +++ b/reactos/win32ss/gdi/eng/device.h @@ -29,6 +29,11 @@ EngpRegisterGraphicsDevice( _In_ PUNICODE_STRING pustrDescription, _In_ PDEVMODEW pdmDefault); +BOOLEAN +EngpPopulateDeviceModeList( + _Inout_ PGRAPHICS_DEVICE pGraphicsDevice, + _In_ PDEVMODEW pdmDefault); + INIT_FUNCTION NTSTATUS NTAPI