diff --git a/win32ss/gdi/eng/pdevobj.c b/win32ss/gdi/eng/pdevobj.c index 64d18320872..85098a58437 100644 --- a/win32ss/gdi/eng/pdevobj.c +++ b/win32ss/gdi/eng/pdevobj.c @@ -522,10 +522,10 @@ PDEVOBJ_bSwitchMode( // Lookup the GraphicsDevice + select DEVMODE // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm); - /* 1. Temporarily disable the current PDEV */ + /* 1. Temporarily disable the current PDEV and reset video to its default mode */ if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE)) { - DPRINT1("DrvAssertMode failed\n"); + DPRINT1("DrvAssertMode(FALSE) failed\n"); goto leave; } @@ -535,7 +535,7 @@ PDEVOBJ_bSwitchMode( if (!ppdevTmp) { DPRINT1("Failed to create a new PDEV\n"); - goto leave; + goto leave2; } /* 3. Create a new surface */ @@ -543,7 +543,8 @@ PDEVOBJ_bSwitchMode( if (!pSurface) { DPRINT1("PDEVOBJ_pSurface failed\n"); - goto leave; + PDEVOBJ_vRelease(ppdevTmp); + goto leave2; } /* 4. Get DirectDraw information */ @@ -565,10 +566,19 @@ PDEVOBJ_bSwitchMode( /* Success! */ retval = TRUE; + +leave2: + /* Set the new video mode, or restore the original one in case of failure */ + if (!ppdev->pfn.AssertMode(ppdev->dhpdev, TRUE)) + { + DPRINT1("DrvAssertMode(TRUE) failed\n"); + } + leave: - /* Unlock PDEV */ - EngReleaseSemaphore(ppdev->hsemDevLock); + /* Unlock everything else */ EngReleaseSemaphore(ghsemPDEV); + /* Unlock the PDEV */ + EngReleaseSemaphore(ppdev->hsemDevLock); DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface); diff --git a/win32ss/user/ntuser/display.c b/win32ss/user/ntuser/display.c index 8ef37c9c4b9..6abe5c84a5c 100644 --- a/win32ss/user/ntuser/display.c +++ b/win32ss/user/ntuser/display.c @@ -800,38 +800,53 @@ UserChangeDisplaySettings( pvOldCursor = UserSetCursor(pvOldCursor, TRUE); ASSERT(pvOldCursor == NULL); - /* Check for failure */ + /* Check for success or failure */ if (!ulResult) { + /* Setting mode failed */ ERR("Failed to set mode\n"); - lResult = (lResult == DISP_CHANGE_NOTUPDATED) ? - DISP_CHANGE_FAILED : DISP_CHANGE_RESTART; - goto leave; - } - - UserUpdateFullscreen(flags); - - /* Update the system metrics */ - InitMetrics(); - - /* Set new size of the monitor */ - UserUpdateMonitorSize((HDEV)ppdev); - - /* Update the SERVERINFO */ - gpsi->dmLogPixels = ppdev->gdiinfo.ulLogPixelsY; - gpsi->Planes = ppdev->gdiinfo.cPlanes; - gpsi->BitsPixel = ppdev->gdiinfo.cBitsPixel; - gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel; - if (ppdev->gdiinfo.flRaster & RC_PALETTE) - { - gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY; + /* Set the correct return value */ + if ((flags & CDS_UPDATEREGISTRY) && (lResult != DISP_CHANGE_NOTUPDATED)) + lResult = DISP_CHANGE_RESTART; + else + lResult = DISP_CHANGE_FAILED; } else - gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY; - // Font is realized and this dc was previously set to internal DC_ATTR. - gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar); - gpsi->tmSysFont = tmw; + { + /* Setting mode succeeded */ + lResult = DISP_CHANGE_SUCCESSFUL; + + UserUpdateFullscreen(flags); + + /* Update the system metrics */ + InitMetrics(); + + /* Set new size of the monitor */ + UserUpdateMonitorSize((HDEV)ppdev); + + /* Update the SERVERINFO */ + gpsi->dmLogPixels = ppdev->gdiinfo.ulLogPixelsY; + gpsi->Planes = ppdev->gdiinfo.cPlanes; + gpsi->BitsPixel = ppdev->gdiinfo.cBitsPixel; + gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel; + if (ppdev->gdiinfo.flRaster & RC_PALETTE) + { + gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY; + } + else + { + gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY; + } + // Font is realized and this dc was previously set to internal DC_ATTR. + gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar); + gpsi->tmSysFont = tmw; + } + + /* + * Refresh the display on success and even on failure, + * since the display may have been messed up. + */ /* Remove all cursor clipping */ UserClipCursor(NULL);