[WIN32K:ENG] In PDEVOBJ_vRefreshModeList, find a proper match for the current display...
[reactos.git] / win32ss / gdi / eng / pdevobj.c
index cc72471..19c2fee 100644 (file)
@@ -67,6 +67,11 @@ PDEVOBJ_AllocPDEV(VOID)
         return NULL;
     }
 
+    /* Allocate EDD_DIRECTDRAW_GLOBAL for our ReactX driver */
+    ppdev->pEDDgpl = ExAllocatePoolWithTag(PagedPool, sizeof(EDD_DIRECTDRAW_GLOBAL), GDITAG_PDEV);
+    if (ppdev->pEDDgpl)
+        RtlZeroMemory(ppdev->pEDDgpl, sizeof(EDD_DIRECTDRAW_GLOBAL));
+
     ppdev->cPdevRefs = 1;
 
     return ppdev;
@@ -78,6 +83,8 @@ PDEVOBJ_vDeletePDEV(
     PPDEVOBJ ppdev)
 {
     EngDeleteSemaphore(ppdev->hsemDevLock);
+    if (ppdev->pEDDgpl)
+        ExFreePoolWithTag(ppdev->pEDDgpl, GDITAG_PDEV);
     ExFreePoolWithTag(ppdev, GDITAG_PDEV);
 }
 
@@ -235,7 +242,7 @@ PDEVOBJ_pSurface(
         hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev);
         if (hsurf== NULL)
         {
-            DPRINT1("Failed to create PDEV surface!");
+            DPRINT1("Failed to create PDEV surface!\n");
             return NULL;
         }
 
@@ -251,6 +258,49 @@ PDEVOBJ_pSurface(
     return ppdev->pSurface;
 }
 
+VOID
+NTAPI
+PDEVOBJ_vRefreshModeList(
+    PPDEVOBJ ppdev)
+{
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    PDEVMODEINFO pdminfo, pdmiNext;
+    DEVMODEW dmDefault;
+    DEVMODEW dmCurrent;
+
+    /* Lock the PDEV */
+    EngAcquireSemaphore(ppdev->hsemDevLock);
+
+    pGraphicsDevice = ppdev->pGraphicsDevice;
+
+    /* Remember our default mode */
+    dmDefault = *pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
+    dmCurrent = *ppdev->pdmwDev;
+
+    /* Clear out the modes */
+    for (pdminfo = pGraphicsDevice->pdevmodeInfo;
+         pdminfo;
+         pdminfo = pdmiNext)
+    {
+        pdmiNext = pdminfo->pdmiNext;
+        ExFreePoolWithTag(pdminfo, GDITAG_DEVMODE);
+    }
+    pGraphicsDevice->pdevmodeInfo = NULL;
+    ExFreePoolWithTag(pGraphicsDevice->pDevModeList, GDITAG_GDEVICE);
+    pGraphicsDevice->pDevModeList = NULL;
+
+    /* Now re-populate the list */
+    if (!EngpPopulateDeviceModeList(pGraphicsDevice, &dmDefault))
+    {
+        DPRINT1("FIXME: EngpPopulateDeviceModeList failed, we just destroyed a perfectly good mode list\n");
+    }
+
+    ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, &dmCurrent);
+
+    /* Unlock PDEV */
+    EngReleaseSemaphore(ppdev->hsemDevLock);
+}
+
 PDEVMODEW
 NTAPI
 PDEVOBJ_pdmMatchDevMode(
@@ -352,6 +402,10 @@ EngpCreatePDEV(
         ppdev->pfnMovePointer = EngMovePointer;
 
     ppdev->pGraphicsDevice = pGraphicsDevice;
+
+    // DxEngGetHdevData asks for Graphics DeviceObject in hSpooler field
+    ppdev->hSpooler = ppdev->pGraphicsDevice->DeviceObject;
+
     // Should we change the ative mode of pGraphicsDevice ?
     ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ;
 
@@ -470,10 +524,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;
     }
 
@@ -483,7 +537,7 @@ PDEVOBJ_bSwitchMode(
     if (!ppdevTmp)
     {
         DPRINT1("Failed to create a new PDEV\n");
-        goto leave;
+        goto leave2;
     }
 
     /* 3. Create a new surface */
@@ -491,7 +545,8 @@ PDEVOBJ_bSwitchMode(
     if (!pSurface)
     {
         DPRINT1("PDEVOBJ_pSurface failed\n");
-        goto leave;
+        PDEVOBJ_vRelease(ppdevTmp);
+        goto leave2;
     }
 
     /* 4. Get DirectDraw information */
@@ -513,10 +568,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);