mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 23:28:58 +00:00
![Oleg Dubinskiy](/assets/img/avatar_default.png)
CORE-17932 [ENG] Implement DirectDraw management in switch display mode functions (e.g. resolution change, color depth, display frequency etc.): - Switch DirectDraw instances between the two PDEVs (the current one and the new one allocated by ourselves) by calling dxg!DxDdDynamicModeChange function. - Suspend them before and resume after the display mode switch, by calling dxg!DxDdsuspendDirectDraw and dxg!DxDdResumeDirectDraw appropriately. We currently don't have these functions implemented, but MS DXG has, so it allows to properly manage DirectDraw PDEVs using this driver, similarly to Windows. My analysis confirms that these functions are always called in XP/2k3 on display mode switch, even when there is no any DirectX app running at the moment. Analyzing their prototypes show that my guesses are correct. - Initialize hDev and dhpdev members for EDD_DIRECTDRAW_GLOBAL for newly created surfaces, switch them during mode change and re-initialize after it also. They are commonly used by DirectDraw stack. In addition, enable DirectDraw for old and new PDEVs, by calling dxg!DxDdEnableDirectDraw function. [NTDDRAW] Additionally, fix usage of DirectDraw lock count in the PDEVOBJ structure. - Enable cDirectDrawDisableLocks member for storing its value, instead of DxDd_nCount, which is marked as ROS-specific. - Use it in win32k!DxEngGet/SetHdevData for getting/setting DirectDraw count appropriately. My analysis also shows that in Windows, the PDEVOBJ::cDirectDrawDisableLocks method calls DxEngGetHdevData with type 8, which corresponds to our DxDd_nCount. So there are no doubts that this member is used there. - Rename DxEngGetHdevData_dd_count alias of type 8 to DxEngGetHdevData_dd_locks, to match more accurately an actual member name. Update the enumeration and fix all code parts appropriately. All these changes allow to properly change display mode during executing DirectDraw applications, when they try to switch in full-screen mode. At least a bugcheck that happened before my changes, does no longer appear. There are still some games that don't run correctly, as if there is no 3D acceleration (which actually exists). This requires further investigations.
677 lines
22 KiB
C
677 lines
22 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* PURPOSE: Native driver for dxg implementation
|
|
* FILE: win32ss/reactx/dxg/eng.c
|
|
* PROGRAMER: Magnus olsen (magnus@greatlord.com)
|
|
* Sebastian Gasiorek (sebastian.gasiorek@reactos.org)
|
|
* REVISION HISTORY:
|
|
* 30/12-2007 Magnus Olsen
|
|
*/
|
|
|
|
#include <dxg_int.h>
|
|
|
|
/*++
|
|
* @name intDdGetDriverInfo
|
|
* @implemented
|
|
*
|
|
* The function intDdGetDriverInfo is used internally in dxg.sys
|
|
* It retrieves driver information structures
|
|
*
|
|
* @param PEDD_DIRECTDRAW_GLOBAL peDdGl
|
|
* DirectDraw global structure
|
|
*
|
|
* @param GUID guid
|
|
* GUID of InfoData to read
|
|
*
|
|
* @param PVOID callbackStruct
|
|
* Callback structure pointer
|
|
*
|
|
* @param ULONG callbackSize
|
|
* Size of allocated callback structure
|
|
*
|
|
* @param ULONG *returnSize
|
|
* Desired structure size returned by driver
|
|
*
|
|
* @return
|
|
* Returns true on successful execution, false when error.
|
|
*
|
|
* @remarks.
|
|
* Only used internally in dxg.sys
|
|
*--*/
|
|
BOOL intDdGetDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl, GUID guid, PVOID callbackStruct, ULONG callbackSize, ULONG *returnSize)
|
|
{
|
|
DD_GETDRIVERINFODATA ddGetDriverInfoData;
|
|
|
|
if (peDdGl->ddHalInfo.dwFlags & DDHALINFO_GETDRIVERINFOSET && peDdGl->ddHalInfo.GetDriverInfo)
|
|
{
|
|
memset(&ddGetDriverInfoData, 0, sizeof(DD_GETDRIVERINFODATA));
|
|
ddGetDriverInfoData.dwSize = sizeof(DD_GETDRIVERINFODATA);
|
|
ddGetDriverInfoData.dhpdev = peDdGl->dhpdev;
|
|
memcpy(&ddGetDriverInfoData.guidInfo, &guid, sizeof(GUID));
|
|
ddGetDriverInfoData.dwExpectedSize = callbackSize;
|
|
ddGetDriverInfoData.lpvData = callbackStruct;
|
|
ddGetDriverInfoData.ddRVal = DDERR_CURRENTLYNOTAVAIL;
|
|
if (peDdGl->ddHalInfo.GetDriverInfo(&ddGetDriverInfoData) && !ddGetDriverInfoData.ddRVal)
|
|
{
|
|
if (returnSize)
|
|
*returnSize = ddGetDriverInfoData.dwActualSize;
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
/* cleanup on error */
|
|
memset(callbackStruct, 0, callbackSize);
|
|
if (returnSize)
|
|
*returnSize = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
* @name intDdGetAllDriverInfo
|
|
* @implemented
|
|
*
|
|
* The function intDdGetAllDriverInfo is used internally in dxg.sys
|
|
* It retrieves all possible driver information structures
|
|
*
|
|
* @param PEDD_DIRECTDRAW_GLOBAL peDdGl
|
|
* Pointer to destination DirectDrawGlobal structure
|
|
*
|
|
* @remarks.
|
|
* Only used internally in dxg.sys
|
|
* Missing some callbacks (VideoPort, DxApi, AGP)
|
|
*--*/
|
|
VOID intDdGetAllDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl)
|
|
{
|
|
if (peDdGl->ddHalInfo.GetDriverInfo && peDdGl->ddHalInfo.dwFlags & DDHALINFO_GETDRIVERINFOSET)
|
|
{
|
|
intDdGetDriverInfo(peDdGl, GUID_KernelCaps, &peDdGl->ddKernelCaps, sizeof(peDdGl->ddKernelCaps), 0);
|
|
intDdGetDriverInfo(peDdGl, GUID_KernelCallbacks, &peDdGl->ddKernelCallbacks, sizeof(peDdGl->ddKernelCallbacks), 0);
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_D3DCallbacks3, &peDdGl->d3dNtHalCallbacks3, sizeof(peDdGl->d3dNtHalCallbacks3), 0))
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_D3DCALLBACKS3;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_ColorControlCallbacks, &peDdGl->ddColorControlCallbacks, sizeof(peDdGl->ddColorControlCallbacks), 0))
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_COLORCONTROLCALLBACKS;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_MiscellaneousCallbacks, &peDdGl->ddMiscellanousCallbacks, sizeof(peDdGl->ddMiscellanousCallbacks), 0))
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_MISCCALLBACKS;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_Miscellaneous2Callbacks, &peDdGl->ddMiscellanous2Callbacks, sizeof(peDdGl->ddMiscellanous2Callbacks), 0))
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_MISC2CALLBACKS;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_NTCallbacks, &peDdGl->ddNtCallbacks, sizeof(peDdGl->ddNtCallbacks), 0) )
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_NTCALLBACKS;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_DDMoreCaps, &peDdGl->ddMoreCaps, sizeof(peDdGl->ddMoreCaps), 0) )
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_DDMORECAPS;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_NTPrivateDriverCaps, &peDdGl->ddNtPrivateDriverCaps, sizeof(peDdGl->ddNtPrivateDriverCaps), 0) )
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_PRIVATEDRIVERCAPS;
|
|
|
|
if (intDdGetDriverInfo(peDdGl, GUID_MotionCompCallbacks, &peDdGl->ddMotionCompCallbacks, sizeof(peDdGl->ddMotionCompCallbacks), 0) )
|
|
peDdGl->dwCallbackFlags |= EDDDGBL_MOTIONCOMPCALLBACKS;
|
|
}
|
|
}
|
|
|
|
/*++
|
|
* @name intDdEnableDriver
|
|
* @implemented
|
|
*
|
|
* The function intDdEnableDriver is used internally in dxg.sys
|
|
* Fills in all EDD_DIRECTDRAW_GLOBAL structures and enables DirectDraw acceleration when possible
|
|
*
|
|
* @param PEDD_DIRECTDRAW_GLOBAL peDdGl
|
|
* Pointer to destination DirectDrawGlobal structure
|
|
*
|
|
* @remarks.
|
|
* Only used internally in dxg.sys
|
|
*--*/
|
|
VOID intDdEnableDriver(PEDD_DIRECTDRAW_GLOBAL peDdGl)
|
|
{
|
|
PDRIVER_FUNCTIONS DriverFunctions;
|
|
LPD3DNTHAL_GLOBALDRIVERDATA GlobalDriverData;
|
|
LPD3DNTHAL_CALLBACKS HalCallbacks;
|
|
PDD_D3DBUFCALLBACKS D3DBufCallbacks;
|
|
|
|
|
|
gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
|
|
DriverFunctions = (PDRIVER_FUNCTIONS)gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_DrvFuncs);
|
|
|
|
// check if driver has DirectDraw functions
|
|
if ((!DriverFunctions->GetDirectDrawInfo)||(!DriverFunctions->EnableDirectDraw)||(!DriverFunctions->DisableDirectDraw))
|
|
peDdGl->dhpdev = 0;
|
|
|
|
|
|
// reset acceleration flag
|
|
peDdGl->fl = peDdGl->fl & 0xFFFFFFFE;
|
|
|
|
// ask for structure sizes
|
|
if ((peDdGl->dhpdev)&&(DriverFunctions->GetDirectDrawInfo(peDdGl->dhpdev, &peDdGl->ddHalInfo, &peDdGl->dwNumHeaps, NULL, &peDdGl->dwNumFourCC, NULL)))
|
|
{
|
|
// allocate memory for DX data
|
|
if (peDdGl->dwNumHeaps)
|
|
peDdGl->pvmList = EngAllocMem(FL_ZERO_MEMORY, peDdGl->dwNumHeaps*sizeof(VIDEOMEMORY), TAG_GDDV);
|
|
if (peDdGl->dwNumFourCC)
|
|
peDdGl->pdwFourCC = EngAllocMem(FL_ZERO_MEMORY, peDdGl->dwNumFourCC * 4, TAG_GDDF);
|
|
|
|
// get data from driver
|
|
if (!DriverFunctions->GetDirectDrawInfo(peDdGl->dhpdev, &peDdGl->ddHalInfo, &peDdGl->dwNumHeaps, peDdGl->pvmList, &peDdGl->dwNumFourCC, peDdGl->pdwFourCC))
|
|
{
|
|
// failed - cleanup and exit
|
|
if (peDdGl->pvmList)
|
|
EngFreeMem(peDdGl->pvmList);
|
|
if (peDdGl->pdwFourCC)
|
|
EngFreeMem(peDdGl->pdwFourCC);
|
|
gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
|
|
return;
|
|
}
|
|
|
|
// check if we can enable DirectDraw acceleration
|
|
if ((peDdGl->ddHalInfo.vmiData.pvPrimary) &&
|
|
(DriverFunctions->EnableDirectDraw(peDdGl->dhpdev, &peDdGl->ddCallbacks, &peDdGl->ddSurfaceCallbacks, &peDdGl->ddPaletteCallbacks))&&
|
|
!(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_flags) & CapOver_DisableD3DAccel)&&
|
|
(peDdGl->ddHalInfo.dwSize == sizeof(DD_HALINFO)))
|
|
{
|
|
GlobalDriverData = peDdGl->ddHalInfo.lpD3DGlobalDriverData;
|
|
HalCallbacks = peDdGl->ddHalInfo.lpD3DHALCallbacks;
|
|
D3DBufCallbacks = peDdGl->ddHalInfo.lpD3DHALCallbacks;
|
|
|
|
if (GlobalDriverData && GlobalDriverData->dwSize == sizeof(D3DNTHAL_GLOBALDRIVERDATA))
|
|
memcpy(&peDdGl->d3dNtGlobalDriverData, GlobalDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
|
|
|
|
if (HalCallbacks && HalCallbacks->dwSize == sizeof(D3DNTHAL_CALLBACKS))
|
|
memcpy(&peDdGl->d3dNtHalCallbacks, HalCallbacks, sizeof(D3DNTHAL_CALLBACKS));
|
|
|
|
if (D3DBufCallbacks && D3DBufCallbacks->dwSize == sizeof(DD_D3DBUFCALLBACKS))
|
|
memcpy(&peDdGl->d3dBufCallbacks, D3DBufCallbacks, sizeof(DD_D3DBUFCALLBACKS));
|
|
|
|
intDdGetAllDriverInfo(peDdGl);
|
|
|
|
// enable DirectDraw acceleration
|
|
peDdGl->fl |= 1;
|
|
}
|
|
else
|
|
{
|
|
// failed - cleanup and exit
|
|
if (peDdGl->pvmList)
|
|
EngFreeMem(peDdGl->pvmList);
|
|
if (peDdGl->pdwFourCC)
|
|
EngFreeMem(peDdGl->pdwFourCC);
|
|
}
|
|
}
|
|
|
|
gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
|
|
}
|
|
|
|
PVOID
|
|
FASTCALL
|
|
intDdCreateDirectDrawLocal(HDEV hDev)
|
|
{
|
|
PEDD_DIRECTDRAW_GLOBAL peDdGl = NULL;
|
|
PEDD_DIRECTDRAW_LOCAL peDdL = NULL;
|
|
PDD_ENTRY AllocRet;
|
|
|
|
peDdGl = (PEDD_DIRECTDRAW_GLOBAL)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_eddg);
|
|
|
|
AllocRet = DdHmgAlloc(sizeof(EDD_DIRECTDRAW_LOCAL), ObjType_DDLOCAL_TYPE, TRUE);
|
|
if (!AllocRet)
|
|
return NULL;
|
|
|
|
peDdL = (PEDD_DIRECTDRAW_LOCAL)AllocRet->pobj;
|
|
|
|
/* initialize DIRECTDRAW_LOCAL */
|
|
peDdL->peDirectDrawLocal_prev = peDdGl->peDirectDrawLocalList;
|
|
peDdL->hCreatorProcess = PsGetCurrentThreadProcessId();
|
|
peDdL->Process = PsGetCurrentProcess();
|
|
|
|
// link DirectDrawGlobal and DirectDrawLocal
|
|
peDdGl->peDirectDrawLocalList = peDdL;
|
|
peDdL->peDirectDrawGlobal = peDdGl;
|
|
peDdL->peDirectDrawGlobal2 = peDdGl;
|
|
|
|
gpEngFuncs.DxEngReferenceHdev(hDev);
|
|
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
|
|
return peDdL->pobj.hHmgr;
|
|
}
|
|
|
|
/*++
|
|
* @name DxDdCreateDirectDrawObject
|
|
* @implemented
|
|
*
|
|
* Function creates new DirectDraw object
|
|
*
|
|
* @param HDC hDC
|
|
* Device context handle
|
|
*
|
|
* @return
|
|
* Newly created DirectDraw object handle.
|
|
*
|
|
* @remarks.
|
|
* Missing all AGP stuff
|
|
*--*/
|
|
DWORD
|
|
NTAPI
|
|
DxDdCreateDirectDrawObject(
|
|
HDC hDC)
|
|
{
|
|
PDC pDC = NULL;
|
|
HDEV hDev = NULL;
|
|
DWORD_PTR retVal = 0;
|
|
|
|
pDC = gpEngFuncs.DxEngLockDC(hDC);
|
|
if (!pDC)
|
|
return 0;
|
|
|
|
// get driver hDev from DC
|
|
hDev = (HDEV)gpEngFuncs.DxEngGetDCState(hDC, 3);
|
|
if (!hDev) {
|
|
gpEngFuncs.DxEngUnlockDC(pDC);
|
|
return 0;
|
|
}
|
|
|
|
// is this primary display?
|
|
if (!gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_display))
|
|
{
|
|
gpEngFuncs.DxEngUnlockDC(pDC);
|
|
return 0;
|
|
}
|
|
|
|
gpEngFuncs.DxEngLockHdev(hDev);
|
|
|
|
// create object only for 8BPP and more
|
|
if (gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_DitherFmt) >= BMF_8BPP)
|
|
retVal = (DWORD_PTR)intDdCreateDirectDrawLocal(hDev);
|
|
|
|
gpEngFuncs.DxEngUnlockHdev(hDev);
|
|
gpEngFuncs.DxEngUnlockDC(pDC);
|
|
return retVal;
|
|
}
|
|
|
|
|
|
/*++
|
|
* @name DxDdGetDriverInfo
|
|
* @implemented
|
|
*
|
|
* Function queries the driver for DirectDraw and Direct3D functionality
|
|
*
|
|
* @param HANDLE DdHandle
|
|
* Handle to DirectDraw object
|
|
*
|
|
* @param PDD_GETDRIVERINFODATA drvInfoData
|
|
* Pointer to in/out driver info data structure
|
|
*--*/
|
|
DWORD
|
|
NTAPI
|
|
DxDdGetDriverInfo(HANDLE DdHandle, PDD_GETDRIVERINFODATA drvInfoData)
|
|
{
|
|
PEDD_DIRECTDRAW_LOCAL peDdL;
|
|
PEDD_DIRECTDRAW_GLOBAL peDdGl;
|
|
PVOID pInfo = NULL;
|
|
DWORD dwInfoSize = 0;
|
|
BYTE callbackStruct[1024];
|
|
DWORD RetVal = FALSE;
|
|
|
|
peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(DdHandle, ObjType_DDLOCAL_TYPE, FALSE);
|
|
if (!peDdL)
|
|
return RetVal;
|
|
|
|
peDdGl = peDdL->peDirectDrawGlobal2;
|
|
|
|
// check VideoPort related callbacks
|
|
if (peDdGl->dwCallbackFlags & EDDDGBL_VIDEOPORTCALLBACKS)
|
|
{
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_VideoPortCallbacks))
|
|
{
|
|
dwInfoSize = sizeof(DD_VIDEOPORTCALLBACKS);
|
|
pInfo = (VOID*)&peDdGl->ddVideoPortCallback;
|
|
}
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_VideoPortCaps))
|
|
{
|
|
pInfo = (VOID*)peDdGl->lpDDVideoPortCaps;
|
|
dwInfoSize = 72 * peDdGl->ddHalInfo.ddCaps.dwMaxVideoPorts;
|
|
}
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_D3DCallbacks3))
|
|
{
|
|
dwInfoSize = sizeof(D3DNTHAL_CALLBACKS3);
|
|
pInfo = (VOID*)&peDdGl->d3dNtHalCallbacks3;
|
|
}
|
|
}
|
|
|
|
// check ColorControl related callbacks
|
|
if (peDdGl->dwCallbackFlags & EDDDGBL_COLORCONTROLCALLBACKS)
|
|
{
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_ColorControlCallbacks))
|
|
{
|
|
dwInfoSize = sizeof(DD_COLORCONTROLCALLBACKS);
|
|
pInfo = (VOID*)&peDdGl->ddColorControlCallbacks;
|
|
}
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_NTCallbacks))
|
|
{
|
|
dwInfoSize = sizeof(DD_NTCALLBACKS);
|
|
pInfo = (VOID*)&peDdGl->ddNtCallbacks;
|
|
}
|
|
}
|
|
|
|
// check Miscellaneous callbacks
|
|
if (peDdGl->dwCallbackFlags & EDDDGBL_MISCCALLBACKS)
|
|
{
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_MiscellaneousCallbacks))
|
|
{
|
|
dwInfoSize = sizeof(DD_MISCELLANEOUSCALLBACKS);
|
|
pInfo = (VOID*)&peDdGl->ddMiscellanousCallbacks;
|
|
}
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_DDMoreCaps))
|
|
{
|
|
dwInfoSize = sizeof(DD_MORECAPS);
|
|
pInfo = &peDdGl->ddMoreCaps;
|
|
}
|
|
}
|
|
|
|
if (peDdGl->dwCallbackFlags & EDDDGBL_MISC2CALLBACKS &&
|
|
InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_Miscellaneous2Callbacks))
|
|
{
|
|
dwInfoSize = sizeof(DD_MISCELLANEOUS2CALLBACKS);
|
|
pInfo = (VOID*)&peDdGl->ddMiscellanous2Callbacks;
|
|
}
|
|
|
|
if (peDdGl->dwCallbackFlags & EDDDGBL_MOTIONCOMPCALLBACKS &&
|
|
InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_MotionCompCallbacks))
|
|
{
|
|
dwInfoSize = sizeof(DD_MOTIONCOMPCALLBACKS);
|
|
pInfo = (VOID*)&peDdGl->ddMotionCompCallbacks;
|
|
}
|
|
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_KernelCaps) )
|
|
{
|
|
dwInfoSize = sizeof(DD_KERNELCALLBACKS);
|
|
pInfo = &peDdGl->ddKernelCaps;
|
|
}
|
|
|
|
if (InlineIsEqualGUID(&drvInfoData->guidInfo, &GUID_DDMoreSurfaceCaps))
|
|
{
|
|
dwInfoSize = sizeof(DDMORESURFACECAPS);
|
|
pInfo = &peDdGl->ddMoreSurfaceCaps;
|
|
}
|
|
|
|
if (dwInfoSize && pInfo)
|
|
{
|
|
gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
|
|
intDdGetDriverInfo(peDdGl, drvInfoData->guidInfo, &callbackStruct, dwInfoSize, &dwInfoSize);
|
|
gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
|
|
memcpy(drvInfoData->lpvData, callbackStruct, dwInfoSize);
|
|
}
|
|
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
* @name DxDdQueryDirectDrawObject
|
|
* @implemented
|
|
*
|
|
* Function queries the DirectDraw object for its functionality
|
|
*
|
|
* @return
|
|
* TRUE on success.
|
|
*--*/
|
|
BOOL
|
|
NTAPI
|
|
DxDdQueryDirectDrawObject(
|
|
HANDLE DdHandle,
|
|
DD_HALINFO* pDdHalInfo,
|
|
DWORD* pCallBackFlags,
|
|
LPD3DNTHAL_CALLBACKS pd3dNtHalCallbacks,
|
|
LPD3DNTHAL_GLOBALDRIVERDATA pd3dNtGlobalDriverData,
|
|
PDD_D3DBUFCALLBACKS pd3dBufCallbacks,
|
|
LPDDSURFACEDESC pTextureFormats,
|
|
DWORD* p8,
|
|
VIDEOMEMORY* p9,
|
|
DWORD* pdwNumFourCC,
|
|
DWORD* pdwFourCC)
|
|
{
|
|
PEDD_DIRECTDRAW_LOCAL peDdL;
|
|
PEDD_DIRECTDRAW_GLOBAL peDdGl;
|
|
BOOL RetVal = FALSE;
|
|
|
|
if (!DdHandle)
|
|
return RetVal;
|
|
|
|
if (!pDdHalInfo)
|
|
return RetVal;
|
|
|
|
if (!gpEngFuncs.DxEngScreenAccessCheck())
|
|
return RetVal;
|
|
|
|
peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(DdHandle, ObjType_DDLOCAL_TYPE, FALSE);
|
|
if (peDdL)
|
|
{
|
|
peDdGl = peDdL->peDirectDrawGlobal2;
|
|
gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
|
|
|
|
memcpy(pDdHalInfo, &peDdGl->ddHalInfo, sizeof(DD_HALINFO));
|
|
|
|
if (pCallBackFlags)
|
|
{
|
|
*(DWORD*)pCallBackFlags = peDdGl->ddCallbacks.dwFlags;
|
|
*(DWORD*)((ULONG_PTR)pCallBackFlags + 4) = peDdGl->ddSurfaceCallbacks.dwFlags;
|
|
*(DWORD*)((ULONG_PTR)pCallBackFlags + 8) = peDdGl->ddPaletteCallbacks.dwFlags;
|
|
}
|
|
|
|
if (pd3dNtHalCallbacks)
|
|
memcpy(pd3dNtHalCallbacks, &peDdGl->d3dNtHalCallbacks, sizeof(peDdGl->d3dNtHalCallbacks));
|
|
|
|
if (pd3dNtGlobalDriverData)
|
|
memcpy(pd3dNtGlobalDriverData, &peDdGl->d3dNtGlobalDriverData, sizeof(peDdGl->d3dNtGlobalDriverData));
|
|
|
|
if (pd3dBufCallbacks)
|
|
memcpy(pd3dBufCallbacks, &peDdGl->d3dBufCallbacks, sizeof(peDdGl->d3dBufCallbacks));
|
|
|
|
if (pTextureFormats)
|
|
memcpy(pTextureFormats, &peDdGl->d3dNtGlobalDriverData.lpTextureFormats, peDdGl->d3dNtGlobalDriverData.dwNumTextureFormats * sizeof(DDSURFACEDESC2));
|
|
|
|
if (pdwNumFourCC)
|
|
*pdwNumFourCC = peDdGl->dwNumFourCC;
|
|
|
|
if (pdwFourCC)
|
|
memcpy(pdwFourCC, &peDdGl->pdwFourCC, 4 * peDdGl->dwNumFourCC);
|
|
|
|
RetVal = TRUE;
|
|
|
|
gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
|
|
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
}
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
/*++
|
|
* @name DxDdEnableDirectDraw
|
|
* @implemented
|
|
*
|
|
* Function enables DirectDraw
|
|
*
|
|
* @param PEDD_DIRECTDRAW_GLOBAL peDdGl
|
|
* Pointer to destination DirectDrawGlobal structure
|
|
*--*/
|
|
BOOL
|
|
NTAPI
|
|
DxDdEnableDirectDraw(HANDLE hDev, BOOL arg2/*What for?*/)
|
|
{
|
|
PEDD_DIRECTDRAW_GLOBAL peDdGl = NULL;
|
|
|
|
if (gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_display))
|
|
{
|
|
peDdGl = (PEDD_DIRECTDRAW_GLOBAL)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_eddg);
|
|
peDdGl->hDev = hDev;
|
|
peDdGl->bSuspended = FALSE;
|
|
peDdGl->dhpdev = (PVOID)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_dhpdev);
|
|
intDdEnableDriver(peDdGl);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
* @name DxDdReenableDirectDrawObject
|
|
* @implemented
|
|
*
|
|
* Function re-enables DirectDraw object after mode switch
|
|
*
|
|
* @param HANDLE DdHandle
|
|
* DirectDraw object handle
|
|
*
|
|
* @param PVOID p2
|
|
* ???
|
|
*
|
|
* @return
|
|
* TRUE on success.
|
|
*
|
|
* @remarks
|
|
* Missing all AGP stuff and second parameter handling
|
|
*--*/
|
|
DWORD
|
|
NTAPI
|
|
DxDdReenableDirectDrawObject(
|
|
HANDLE DdHandle,
|
|
PVOID p2)
|
|
{
|
|
PEDD_DIRECTDRAW_LOCAL peDdL;
|
|
PEDD_DIRECTDRAW_GLOBAL peDdGl;
|
|
HDC hDC;
|
|
DWORD RetVal = FALSE;
|
|
|
|
peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(DdHandle, ObjType_DDLOCAL_TYPE, FALSE);
|
|
|
|
if (!peDdL)
|
|
return RetVal;
|
|
|
|
peDdGl = peDdL->peDirectDrawGlobal2;
|
|
|
|
hDC = gpEngFuncs.DxEngGetDesktopDC(0, FALSE, FALSE);
|
|
|
|
gpEngFuncs.DxEngLockShareSem();
|
|
gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
|
|
|
|
if (peDdGl->fl & 1 &&
|
|
gpEngFuncs.DxEngGetDCState(hDC, 2) != 1 &&
|
|
!(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_OpenRefs)) &&
|
|
!(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_disable)) &&
|
|
!(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_locks)) &&
|
|
gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_DitherFmt) >= BMF_8BPP)
|
|
{
|
|
// reset acceleration and suspend flags
|
|
peDdGl->fl &= 0xFFFFFFFD;
|
|
peDdGl->bSuspended = 0;
|
|
peDdGl->dhpdev = (PVOID)gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dhpdev);
|
|
|
|
RetVal = TRUE;
|
|
// FIXME AGP Stuff
|
|
}
|
|
|
|
gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
|
|
gpEngFuncs.DxEngUnlockShareSem();
|
|
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
PEDD_SURFACE
|
|
NTAPI
|
|
intDdCreateNewSurfaceObject(PEDD_DIRECTDRAW_LOCAL peDdL, HANDLE hDirectDrawLocal, PDD_SURFACE_GLOBAL pDdSurfGlob, PDD_SURFACE_LOCAL pDdSurfLoc, PDD_SURFACE_MORE pDdSurfMore)
|
|
{
|
|
PEDD_SURFACE pSurface = NULL;
|
|
|
|
// first check if we can assign it from current ddHandle
|
|
if (hDirectDrawLocal)
|
|
{
|
|
pSurface = (PEDD_SURFACE)DdHmgLock(hDirectDrawLocal, ObjType_DDSURFACE_TYPE, FALSE);
|
|
// check if surface is locked and belongs to correct DirectDrawLocal
|
|
if ((pSurface)&&((pSurface->peDirectDrawLocal != peDdL)||(!pSurface->hSecure)))
|
|
{
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// if surface not found from ddHandle or ddHandle not provided
|
|
if (!pSurface)
|
|
{
|
|
// create new surface object
|
|
pSurface = (PEDD_SURFACE)DdHmgAlloc(sizeof(EDD_SURFACE), ObjType_DDSURFACE_TYPE, TRUE);
|
|
if (pSurface)
|
|
{
|
|
pSurface->ddsSurfaceLocal.lpGbl = &pSurface->ddsSurfaceGlobal;
|
|
pSurface->ddsSurfaceLocal.lpSurfMore = &pSurface->ddsSurfaceMore;
|
|
pSurface->ddsSurfaceInt.lpLcl = &pSurface->ddsSurfaceLocal;
|
|
pSurface->peDirectDrawLocal = peDdL;
|
|
pSurface->peDirectDrawGlobalNext = peDdL->peDirectDrawGlobal2;
|
|
pSurface->ldev = gpEngFuncs.DxEngGetHdevData(pSurface->peDirectDrawGlobalNext->hDev, DxEGShDevData_ldev);
|
|
pSurface->gdev = gpEngFuncs.DxEngGetHdevData(pSurface->peDirectDrawGlobalNext->hDev, DxEGShDevData_GDev);
|
|
pSurface->hSecure = (VOID*)1;
|
|
}
|
|
}
|
|
|
|
if (pSurface)
|
|
{
|
|
pSurface->ddsSurfaceGlobal.fpVidMem = pDdSurfGlob->fpVidMem;
|
|
pSurface->ddsSurfaceGlobal.lPitch = pDdSurfGlob->lPitch;
|
|
pSurface->ddsSurfaceGlobal.wWidth = pDdSurfGlob->wWidth;
|
|
pSurface->ddsSurfaceGlobal.wHeight = pDdSurfGlob->wHeight;
|
|
pSurface->wWidth = pDdSurfGlob->wWidth;
|
|
pSurface->wHeight = pDdSurfGlob->wHeight;
|
|
memcpy(&pSurface->ddsSurfaceGlobal.ddpfSurface, &pDdSurfGlob->ddpfSurface, sizeof(pSurface->ddsSurfaceGlobal.ddpfSurface));
|
|
pSurface->ddsSurfaceLocal.ddsCaps.dwCaps = pDdSurfLoc->ddsCaps.dwCaps;
|
|
pSurface->ddsSurfaceMore.ddsCapsEx.dwCaps2 = pDdSurfMore->ddsCapsEx.dwCaps2;
|
|
pSurface->ddsSurfaceMore.ddsCapsEx.dwCaps3 = pDdSurfMore->ddsCapsEx.dwCaps3;
|
|
pSurface->ddsSurfaceMore.ddsCapsEx.dwCaps4 = pDdSurfMore->ddsCapsEx.dwCaps4;
|
|
pSurface->ddsSurfaceMore.dwSurfaceHandle = pDdSurfMore->dwSurfaceHandle;
|
|
pSurface->hSecure = (VOID*)1;
|
|
|
|
peDdL->peSurface_DdList = pSurface;
|
|
peDdL->hSurface = (ULONG_PTR)pSurface->pobj.hHmgr;
|
|
}
|
|
|
|
return pSurface;
|
|
}
|
|
|
|
HANDLE
|
|
NTAPI
|
|
DxDdCreateSurfaceObject(HANDLE hDirectDrawLocal,
|
|
HANDLE hSurface,
|
|
PDD_SURFACE_LOCAL puSurfaceLocal,
|
|
PDD_SURFACE_MORE puSurfaceMore,
|
|
PDD_SURFACE_GLOBAL puSurfaceGlobal,
|
|
BOOL bComplete)
|
|
{
|
|
HANDLE RetVal = FALSE;
|
|
PEDD_DIRECTDRAW_LOCAL peDdL = NULL;
|
|
PEDD_SURFACE pDdSurface = NULL;
|
|
|
|
peDdL = (PEDD_DIRECTDRAW_LOCAL)DdHmgLock(hDirectDrawLocal, ObjType_DDLOCAL_TYPE, FALSE);
|
|
|
|
if (!peDdL)
|
|
return RetVal;
|
|
|
|
pDdSurface = intDdCreateNewSurfaceObject(peDdL, hSurface, puSurfaceGlobal, puSurfaceLocal, puSurfaceMore);
|
|
if (!pDdSurface)
|
|
{
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
return RetVal;
|
|
}
|
|
|
|
RetVal = pDdSurface->pobj.hHmgr;
|
|
|
|
InterlockedDecrement((VOID*)&pDdSurface->pobj.cExclusiveLock);
|
|
InterlockedDecrement((VOID*)&peDdL->pobj.cExclusiveLock);
|
|
|
|
return RetVal;
|
|
}
|