Index: win32ss/gdi/eng/device.h =================================================================== --- win32ss/gdi/eng/device.h (revision 65128) +++ win32ss/gdi/eng/device.h (working copy) @@ -43,6 +43,11 @@ PDEVOBJ_pdmMatchDevMode( PPDEVOBJ ppdev, PDEVMODEW pdm); + +VOID +NTAPI +PDEVOBJ_vRefreshModeList( + PPDEVOBJ ppdev); extern PGRAPHICS_DEVICE gpPrimaryGraphicsDevice; extern PGRAPHICS_DEVICE gpVgaGraphicsDevice; Index: win32ss/gdi/eng/pdevobj.c =================================================================== --- win32ss/gdi/eng/pdevobj.c (revision 65128) +++ win32ss/gdi/eng/pdevobj.c (working copy) @@ -7,9 +7,11 @@ */ #include -#define NDEBUG +//#define NDEBUG #include +DBG_DEFAULT_CHANNEL(UserDisplay); + PPDEVOBJ gppdevPrimary = NULL; static PPDEVOBJ gppdevList = NULL; @@ -231,6 +233,76 @@ return ppdev->pSurface; } +VOID +NTAPI +PDEVOBJ_vRefreshModeList( + PPDEVOBJ ppdev) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PDEVMODEINFO pdminfo; + UINT cModes = 0; + UINT j = 0; + + ULONG size = 0; + + /* Lock the PDEV */ + EngAcquireSemaphore(ppdev->hsemDevLock); + + pGraphicsDevice = ppdev->pGraphicsDevice; + + DPRINT("Enter PDEVOBJ_vRefreshModeList('%ws'/'%ws')\n", + pGraphicsDevice->szNtDeviceName, + pGraphicsDevice->szWinDeviceName); + + pdminfo = LDEVOBJ_pdmiGetModes(ppdev->pldev, pGraphicsDevice->DeviceObject); + + if (!pdminfo || pdminfo->cbdevmode == 0) + { + ERR("Could not get an updated mode list for '%ls'\n", pGraphicsDevice->szWinDeviceName); + } + else + { + DPRINT("Bingo! We've just got some (%lu) new modes for '%ls'.\n", pdminfo->cbdevmode/sizeof(DEVMODEW), pGraphicsDevice->szWinDeviceName); + + while(size < pdminfo->cbdevmode && (pdminfo->adevmode[cModes].dmSize != 0)) + { + + DPRINT("mode %lu -- %lux%lux%lu (%lu hz)\n", cModes, pdminfo->adevmode[cModes].dmPelsWidth, + pdminfo->adevmode[cModes].dmPelsHeight, + pdminfo->adevmode[cModes].dmBitsPerPel, + pdminfo->adevmode[cModes].dmDisplayFrequency); + + /* Some drivers like the VBox driver don't fill the dmDeviceName + with the name of the display driver. So fix that here. */ + + wcsncpy(pdminfo->adevmode[cModes].dmDeviceName, pGraphicsDevice->pDiplayDrivers, CCHDEVICENAME); + pdminfo->adevmode[cModes].dmDeviceName[CCHDEVICENAME - 1] = 0; + + cModes++; size += sizeof(DEVMODEW); + } + + /* Attach the mode info to the device */ + pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo; + pGraphicsDevice->pdevmodeInfo = pdminfo; + + /* Allocate an index buffer */ + pGraphicsDevice->cDevModes = cModes; + pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool, + cModes * sizeof(DEVMODEENTRY), + GDITAG_GDEVICE); + + for(j=0;jpDevModeList[j].dwFlags = 0; + pGraphicsDevice->pDevModeList[j].pdm = &pdminfo->adevmode[j]; + } + } + + /* Unlock PDEV */ + EngReleaseSemaphore(ppdev->hsemDevLock); +} + PDEVMODEW NTAPI PDEVOBJ_pdmMatchDevMode( @@ -243,14 +315,33 @@ DWORD dwFields; pGraphicsDevice = ppdev->pGraphicsDevice; + + DPRINT("looking for mode -- %lux%lux%lu (%lu hz) (%ls)\n", pdm->dmPelsWidth, + pdm->dmPelsHeight, + pdm->dmBitsPerPel, + pdm->dmDisplayFrequency, + pdm->dmDeviceName); for (i = 0; i < pGraphicsDevice->cDevModes; i++) { pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm; + DPRINT("mode %lu -- %lux%lux%lu (%lu hz) (%ls)\n", i, pdmCurrent->dmPelsWidth, + pdmCurrent->dmPelsHeight, + pdmCurrent->dmBitsPerPel, + pdmCurrent->dmDisplayFrequency, + pdmCurrent->dmDeviceName); + } + + DPRINT("---\n"); + + for (i = 0; i < pGraphicsDevice->cDevModes; i++) + { + pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm; + /* Compare asked DEVMODE fields * Only compare those that are valid in both DEVMODE structs */ - dwFields = pdmCurrent->dmFields & pdm->dmFields ; + dwFields = pdmCurrent->dmFields & pdm->dmFields; /* For now, we only need those */ if ((dwFields & DM_BITSPERPEL) && @@ -262,6 +353,12 @@ if ((dwFields & DM_DISPLAYFREQUENCY) && (pdmCurrent->dmDisplayFrequency != pdm->dmDisplayFrequency)) continue; + DPRINT("chosen mode %lu -- %lux%lux%lu (%lu hz) (%ls)\n", i, pdmCurrent->dmPelsWidth, + pdmCurrent->dmPelsHeight, + pdmCurrent->dmBitsPerPel, + pdmCurrent->dmDisplayFrequency, + pdmCurrent->dmDeviceName); + /* Match! Return the DEVMODE */ return pdmCurrent; } @@ -333,7 +430,7 @@ ppdev->pGraphicsDevice = pGraphicsDevice; ppdev->hsemDevLock = EngCreateSemaphore(); - // Should we change the ative mode of pGraphicsDevice ? + // Should we change the active mode of pGraphicsDevice ? ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ; /* FIXME! */ Index: win32ss/user/ntuser/display.c =================================================================== --- win32ss/user/ntuser/display.c (revision 65128) +++ win32ss/user/ntuser/display.c (working copy) @@ -7,6 +7,8 @@ */ #include +#include + DBG_DEFAULT_CHANNEL(UserDisplay); BOOL gbBaseVideo = 0; @@ -463,7 +465,7 @@ PDEVMODEENTRY pdmentry; ULONG i, iFoundMode; - TRACE("Enter UserEnumDisplaySettings('%wZ', %lu)\n", + DPRINT("Enter UserEnumDisplaySettings('%wZ', %lu)\n", pustrDevice, iModeNum); /* Ask GDI for the GRAPHICS_DEVICE */ @@ -472,12 +474,21 @@ if (!pGraphicsDevice) { /* No device found */ - ERR("No device found!\n"); + DPRINT("No device found!\n"); return STATUS_UNSUCCESSFUL; } + /* let's politely ask the driver for an updated mode list, + just in case there's something new in there (vbox) */ + + PDEVOBJ_vRefreshModeList(EngpGetPDEV(pustrDevice)); + + /* FIXME: maybe only refresh when iModeNum is bigger than cDevModes? */ if (iModeNum >= pGraphicsDevice->cDevModes) + { + DPRINT("STATUS_NO_MORE_ENTRIES!\n"); return STATUS_NO_MORE_ENTRIES; + } iFoundMode = 0; for (i = 0; i < pGraphicsDevice->cDevModes; i++) @@ -568,7 +579,7 @@ ULONG cbSize, cbExtra; DEVMODEW dmReg, *pdm; - TRACE("Enter NtUserEnumDisplaySettings(%wZ, %lu, %p, 0x%lx)\n", + DPRINT("Enter NtUserEnumDisplaySettings(%wZ, %lu, %p, 0x%lx)\n", pustrDevice, iModeNum, lpDevMode, dwFlags); if (pustrDevice)