diff --git a/sdk/include/reactos/drivers/directx/dxeng.h b/sdk/include/reactos/drivers/directx/dxeng.h index 8a349ce6507..fa2f248e7cf 100644 --- a/sdk/include/reactos/drivers/directx/dxeng.h +++ b/sdk/include/reactos/drivers/directx/dxeng.h @@ -57,7 +57,7 @@ typedef enum _DXEGSHDEVDATA DxEGShDevData_DrvFuncs, DxEGShDevData_dhpdev, DxEGShDevData_eddg, - DxEGShDevData_dd_nCount, + DxEGShDevData_dd_locks, DxEGShDevData_dd_flags, DxEGShDevData_disable, DxEGShDevData_metadev, diff --git a/sdk/include/reactos/drivers/directx/dxg.h b/sdk/include/reactos/drivers/directx/dxg.h index 33a815a2a61..470597ad1de 100644 --- a/sdk/include/reactos/drivers/directx/dxg.h +++ b/sdk/include/reactos/drivers/directx/dxg.h @@ -197,7 +197,7 @@ typedef DWORD (NTAPI *PGD_DXGENERICTRUNK)(ULONG_PTR, ULONG_PTR, SIZE_T*, PVOID, //typedef x (NTAPI *PGD_DxDdHeapVidMemAllocAligned)( //typedef x (NTAPI *PGD_DxDdHeapVidMemFree)( typedef BOOLEAN (NTAPI *PGD_DXDDENABLEDIRECTDRAW)(PVOID, BOOLEAN); -//typedef x (NTAPI *PGD_DxDdDisableDirectDraw)( +typedef VOID (NTAPI *PGD_DXDDDISABLEDIRECTDRAW)(PVOID, BOOLEAN); //typedef x (NTAPI *PGD_DxDdSuspendDirectDraw)( //typedef x (NTAPI *PGD_DxDdResumeDirectDraw)( //typedef x (NTAPI *PGD_DxDdDynamicModeChange)( diff --git a/win32ss/gdi/eng/pdevobj.c b/win32ss/gdi/eng/pdevobj.c index c8af5c7e9c3..ed6fc630e76 100644 --- a/win32ss/gdi/eng/pdevobj.c +++ b/win32ss/gdi/eng/pdevobj.c @@ -3,7 +3,8 @@ * PROJECT: ReactOS kernel * PURPOSE: Support for physical devices * FILE: win32ss/gdi/eng/pdevobj.c - * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) + * PROGRAMERS: Timo Kreuzer (timo.kreuzer@reactos.org) + * Oleg Dubinskiy (oleg.dubinskij30@gmail.com) */ #include @@ -336,6 +337,55 @@ PDEVOBJ_pSurface( return ppdev->pSurface; } +BOOL +PDEVOBJ_bEnableDirectDraw( + _Inout_ PPDEVOBJ ppdev) +{ + PGD_DXDDENABLEDIRECTDRAW pfnDdEnableDirectDraw = (PGD_DXDDENABLEDIRECTDRAW)gpDxFuncs[DXG_INDEX_DxDdEnableDirectDraw].pfn; + BOOL Success; + + /* Enable DirectDraw */ + TRACE("DxDdEnableDirectDraw(ppdev %p)\n", ppdev); + Success = pfnDdEnableDirectDraw((HDEV)ppdev, TRUE); + TRACE("DxDdEnableDirectDraw(ppdev %p) => %d\n", ppdev, Success); + + return Success; +} + +VOID +PDEVOBJ_vResumeDirectDraw( + _Inout_ PPDEVOBJ ppdev) +{ + PGD_DXDDRESUMEDIRECTDRAW pfnDdResumeDirectDraw = (PGD_DXDDRESUMEDIRECTDRAW)gpDxFuncs[DXG_INDEX_DxDdResumeDirectDraw].pfn; + + /* Resume DirectDraw after mode change */ + TRACE("DxDdResumeDirectDraw(ppdev %p)\n", ppdev); + pfnDdResumeDirectDraw((HDEV)ppdev, 0); +} + +VOID +PDEVOBJ_vSuspendDirectDraw( + _Inout_ PPDEVOBJ ppdev) +{ + PGD_DXDDSUSPENDDIRECTDRAW pfnDdSuspendDirectDraw = (PGD_DXDDSUSPENDDIRECTDRAW)gpDxFuncs[DXG_INDEX_DxDdSuspendDirectDraw].pfn; + + /* Suspend DirectDraw for mode change */ + TRACE("DxDdSuspendDirectDraw(ppdev %p)\n", ppdev); + pfnDdSuspendDirectDraw((HDEV)ppdev, 0); +} + +VOID +PDEVOBJ_vSwitchDirectDraw( + _Inout_ PPDEVOBJ ppdev, + _Inout_ PPDEVOBJ ppdev2) +{ + PGD_DXDDDYNAMICMODECHANGE pfnDdDynamicModeChange = (PGD_DXDDDYNAMICMODECHANGE)gpDxFuncs[DXG_INDEX_DxDdDynamicModeChange].pfn; + + /* Switch DirectDraw instances between the PDEVs */ + TRACE("DxDdDynamicModeChange(ppdev %p, ppdev2 %p)\n", ppdev, ppdev2); + pfnDdDynamicModeChange((HDEV)ppdev, (HDEV)ppdev2, 0); +} + VOID PDEVOBJ_vEnableDisplay( _Inout_ PPDEVOBJ ppdev) @@ -365,6 +415,8 @@ PDEVOBJ_bDisableDisplay( if (ppdev->flFlags & PDEV_DISABLED) return TRUE; + PDEVOBJ_vSuspendDirectDraw(ppdev); + TRACE("DrvAssertMode(dhpdev %p, FALSE)\n", ppdev->dhpdev); assertVal = ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE); TRACE("DrvAssertMode(dhpdev %p, FALSE) => %d\n", ppdev->dhpdev, assertVal); @@ -548,6 +600,15 @@ PDEVOBJ_Create( return NULL; } + /* Enable DirectDraw */ + if (!PDEVOBJ_bEnableDirectDraw(ppdev)) + { + ERR("Failed to enable DirectDraw\n"); + PDEVOBJ_vRelease(ppdev); + EngUnloadImage(pldev); + return NULL; + } + /* Remove some acceleration capabilities from driver */ PDEVOBJ_vFilterDriverHooks(ppdev); @@ -631,6 +692,9 @@ PDEVOBJ_bDynamicModeChange( ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev); ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2); + /* Switch DirectDraw mode */ + PDEVOBJ_vSwitchDirectDraw(ppdev, ppdev2); + return TRUE; } @@ -660,6 +724,8 @@ PDEVOBJ_bSwitchMode( if (!PDEVOBJ_bDisableDisplay(ppdev)) { DPRINT1("PDEVOBJ_bDisableDisplay() failed\n"); + /* Resume DirectDraw in case of failure */ + PDEVOBJ_vResumeDirectDraw(ppdev); goto leave; } @@ -680,11 +746,11 @@ PDEVOBJ_bSwitchMode( goto leave2; } - /* 4. Get DirectDraw information */ - /* 5. Enable DirectDraw Not traced */ - /* 6. Copy old PDEV state to new PDEV instance */ + /* 4. Temporarily suspend DirectDraw for mode change */ + PDEVOBJ_vSuspendDirectDraw(ppdev); + PDEVOBJ_vSuspendDirectDraw(ppdevTmp); - /* 7. Switch the PDEVs */ + /* 5. Switch the PDEVs */ if (!PDEVOBJ_bDynamicModeChange(ppdev, ppdevTmp)) { DPRINT1("PDEVOBJ_bDynamicModeChange() failed\n"); @@ -692,10 +758,17 @@ PDEVOBJ_bSwitchMode( goto leave2; } - /* 8. Disable DirectDraw */ + /* 6. Resume DirectDraw */ + PDEVOBJ_vResumeDirectDraw(ppdev); + PDEVOBJ_vResumeDirectDraw(ppdevTmp); + /* Release temp PDEV */ PDEVOBJ_vRelease(ppdevTmp); + /* Re-initialize DirectDraw data */ + ppdev->pEDDgpl->hDev = (HDEV)ppdev; + ppdev->pEDDgpl->dhpdev = ppdev->dhpdev; + /* Update primary display capabilities */ if (ppdev == gpmdev->ppdevGlobal) { diff --git a/win32ss/gdi/eng/pdevobj.h b/win32ss/gdi/eng/pdevobj.h index b9d439d3dda..a58eb1aa2ab 100644 --- a/win32ss/gdi/eng/pdevobj.h +++ b/win32ss/gdi/eng/pdevobj.h @@ -101,7 +101,7 @@ typedef struct _PDEVOBJ // RFONT * prfntInactive; // ULONG cInactive; // BYTE ajbo[0x5C]; -// ULONG cDirectDrawDisableLocks; + ULONG cDirectDrawDisableLocks; // PVOID TypeOneInfo; PVOID pvGammaRamp; /* Gamma ramp pointer. */ PVOID RemoteTypeOne; @@ -140,7 +140,6 @@ typedef struct _PDEVOBJ }; /* ros specific */ - ULONG DxDd_nCount; GDIPOINTER Pointer; /* Stuff to keep track of software cursors; win32k gdi part */ UINT SafetyRemoveLevel; /* at what level was the cursor removed? diff --git a/win32ss/reactx/dxg/ddraw.c b/win32ss/reactx/dxg/ddraw.c index 1a639a39ef1..12ed339367d 100644 --- a/win32ss/reactx/dxg/ddraw.c +++ b/win32ss/reactx/dxg/ddraw.c @@ -563,7 +563,7 @@ DxDdReenableDirectDrawObject( gpEngFuncs.DxEngGetDCState(hDC, 2) != 1 && !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_OpenRefs)) && !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_disable)) && - !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_nCount)) && + !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_locks)) && gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_DitherFmt) >= BMF_8BPP) { // reset acceleration and suspend flags diff --git a/win32ss/reactx/ntddraw/dxeng.c b/win32ss/reactx/ntddraw/dxeng.c index a096bf5f350..bcd0db67e26 100644 --- a/win32ss/reactx/ntddraw/dxeng.c +++ b/win32ss/reactx/ntddraw/dxeng.c @@ -324,9 +324,9 @@ DxEngGetHdevData(HDEV hDev, DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_eddg\n"); retVal = (DWORD_PTR) PDev->pEDDgpl; break; - case DxEGShDevData_dd_nCount: - DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_dd_nCount\n"); - retVal = (DWORD_PTR) PDev->DxDd_nCount; + case DxEGShDevData_dd_locks: + DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_dd_locks\n"); + retVal = (DWORD_PTR) PDev->cDirectDrawDisableLocks; break; case DxEGShDevData_dd_flags: DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_dd_flags\n"); @@ -413,9 +413,10 @@ DxEngSetHdevData(HDEV hDev, DPRINT1("ReactX Calling : DxEngSetHdevData DXEGSHDEVDATA : %ld\n", Type); - if ( Type == DxEGShDevData_dd_nCount ) + if (Type == DxEGShDevData_dd_locks) { - ((PPDEVOBJ)hDev)->DxDd_nCount = Data; + DPRINT1("Assigning value %d\n", Data); + ((PPDEVOBJ)hDev)->cDirectDrawDisableLocks = Data; retVal = TRUE; // Set } return retVal; diff --git a/win32ss/reactx/ntddraw/intddraw.h b/win32ss/reactx/ntddraw/intddraw.h index c1ab8c945b0..5dcf1d28774 100644 --- a/win32ss/reactx/ntddraw/intddraw.h +++ b/win32ss/reactx/ntddraw/intddraw.h @@ -108,6 +108,11 @@ typedef VOID (APIENTRY *PGD_ENGFREEPRIVATEUSERMEM)(PDD_SURFACE_LOCAL, PVOID); typedef PDD_SURFACE_LOCAL (APIENTRY *PGD_ENGLOCKDIRECTDRAWSURFACE)(HANDLE); typedef BOOL (APIENTRY *PGD_ENGUNLOCKDIRECTDRAWSURFACE)(PDD_SURFACE_LOCAL); +/* Other internal functions */ +typedef VOID (APIENTRY *PGD_DXDDDYNAMICMODECHANGE)(HDEV, HDEV, ULONG_PTR); +typedef VOID (APIENTRY *PGD_DXDDRESUMEDIRECTDRAW)(HDEV, ULONG_PTR); +typedef VOID (APIENTRY *PGD_DXDDSUSPENDDIRECTDRAW)(HDEV, ULONG_PTR); + /* Gammaramp internal prototype */ BOOL FASTCALL IntGetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp); BOOL FASTCALL IntSetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp, BOOL);