Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

856 lines
29 KiB

/******************************Module*Header**********************************\
*
* **************************
* * DirectDraw SAMPLE CODE *
* **************************
*
* Module Name: ddenable.c
*
* Content: Windows 2000 only DirectDraw/D3D enabling functions
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "glint.h"
#if WNT_DDRAW
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// __DDE_BuildPixelFormat
//
// generate a pixel format structure based on the mode
// This example works only with RGB surfaces
//
//-----------------------------------------------------------------------------
void
__DDE_BuildPixelFormat(
P3_THUNKEDDATA* pThisDisplay,
LPGLINTINFO pGLInfo,
LPDDPIXELFORMAT pdpf )
{
PPDEV ppdev;
ppdev = pThisDisplay->ppdev;
pdpf->dwSize = sizeof( DDPIXELFORMAT );
pdpf->dwFourCC = 0;
pdpf->dwFlags = DDPF_RGB;
if( pGLInfo->dwBpp == 8 )
{
pdpf->dwFlags |= DDPF_PALETTEINDEXED8;
}
pdpf->dwRGBBitCount = pGLInfo->dwBpp;
pdpf->dwRBitMask = ppdev->flRed;
pdpf->dwGBitMask = ppdev->flGreen;
pdpf->dwBBitMask = ppdev->flBlue;
// Calculate the alpha channel as it isn't in the ppdev
switch (pGLInfo->dwBpp)
{
case 8:
DISPDBG((DBGLVL, "Format is 8 bits"));
pdpf->dwRGBAlphaBitMask = 0;
break;
case 16:
DISPDBG((DBGLVL, "Format is 16 bits"));
switch(ppdev->flRed)
{
case 0x7C00:
pdpf->dwRGBAlphaBitMask = 0x8000L;
pdpf->dwFlags |= DDPF_ALPHAPIXELS;
break;
default:
pdpf->dwRGBAlphaBitMask = 0x0L;
}
break;
case 24:
DISPDBG((DBGLVL, "Format is 24 bits"));
pdpf->dwRGBAlphaBitMask = 0x00000000L;
break;
case 32:
DISPDBG((DBGLVL, "Desktop is 32 bits"));
pdpf->dwRGBAlphaBitMask = 0xff000000L;
pdpf->dwFlags |= DDPF_ALPHAPIXELS;
break;
}
} // __DDE_BuildPixelFormat
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// __DDE_bSetupDDStructs
//
// This fills in the data that would have been setup on Win9X in the
// 16 bit side
//
//-----------------------------------------------------------------------------
BOOL
__DDE_bSetupDDStructs(
P3_THUNKEDDATA* pThisDisplay,
BOOL reset )
{
DWORD dwRegistryValue;
BOOL bSuccess;
LPGLINTINFO pGLInfo;
PPDEV ppdev;
void *fbPtr; // Framebuffer pointer
void *lbPtr; // Localbuffer pointer
DWORD fbSizeInBytes; // Size of framebuffer
DWORD lbSizeInBytes; // Size of localbuffer
DWORD fbOffsetInBytes; // Offset to 1st 'free' byte in framebuffer
DWORD dwMemStart, dwMemEnd;
// reset == TRUE if there has been a mode change.
pThisDisplay->bResetMode = reset;
#if DBG
if (pThisDisplay->bResetMode)
{
DISPDBG((DBGLVL,"Resetting due to mode change"));
}
else
{
DISPDBG((DBGLVL, "Creating for the first time"));
}
#endif
// Setup pThisDisplay->pGLInfo from PPDEV
pGLInfo = pThisDisplay->pGLInfo;
ppdev = pThisDisplay->ppdev;
GetFBLBInfoForDDraw (ppdev,
&fbPtr, // Framebuffer pointer
&lbPtr, // Localbuffer pointer,
// (*** This is NULL***)
&fbSizeInBytes, // Size of framebuffer
&lbSizeInBytes, // Size of localbuffer
&fbOffsetInBytes, // Offset to 1st 'free' byte
// in framebuffer
&pGLInfo->bDRAMBoard);// TRUE if SDRAM vidmem,
// FALSE if SGRAM
// (i.e. hw writemask) vidmem
DISPDBG((DBGLVL, "__DDE_bSetupDDStructs: fbPtr 0x%lx, fbOff 0x%x",
fbPtr, fbOffsetInBytes));
// If VBlankStatusPtr is non-NULL then we know that the NT miniport
// will set the VBlankStatusPtr for us.
if (pThisDisplay->VBlankStatusPtr)
pGLInfo->dwFlags = GMVF_VBLANK_ENABLED;// Say that we are using VBLANKs
else
pGLInfo->dwFlags = 0;
pGLInfo->bPixelToBytesShift = (unsigned char)ppdev->cPelSize;
pGLInfo->ddFBSize = fbSizeInBytes;
pGLInfo->dwScreenBase = 0;
pGLInfo->dwOffscreenBase = fbOffsetInBytes;
pGLInfo->dwScreenWidth = ppdev->cxScreen; // Driver info
pGLInfo->dwScreenHeight = ppdev->cyScreen;
pGLInfo->dwVideoWidth = ppdev->cxMemory;
pGLInfo->dwVideoHeight = ppdev->cyMemory;
bSuccess = GET_REGISTRY_ULONG_FROM_STRING(
"HardwareInformation.CurrentPixelClockSpeed",
&dwRegistryValue);
if(!bSuccess)
{
DISPDBG((ERRLVL,"Error - can't determine pixel clock"));
dwRegistryValue = 0;
}
DISPDBG((DBGLVL,"Pixel clock frequency is %dHz", dwRegistryValue));
pGLInfo->PixelClockFrequency = dwRegistryValue;
bSuccess = GET_REGISTRY_ULONG_FROM_STRING(
"HardwareInformation.CurrentMemClockSpeed",
&dwRegistryValue);
if(!bSuccess)
{
DISPDBG((ERRLVL,"Error - can't determine memory clock"));
dwRegistryValue = 0;
}
DISPDBG((DBGLVL,"Memory clock frequency is %dHz", dwRegistryValue));
pGLInfo->MClkFrequency = dwRegistryValue;
if (ppdev->iBitmapFormat == BMF_8BPP)
{
DISPDBG((DBGLVL, "Desktop is 8 bits"));
pGLInfo->dwBpp = 8;
}
else if (ppdev->iBitmapFormat == BMF_16BPP)
{
DISPDBG((DBGLVL, "Desktop is 16 bits"));
pGLInfo->dwBpp = 16;
}
else if (ppdev->iBitmapFormat == BMF_24BPP)
{
DISPDBG((DBGLVL, "Desktop is 24 bits"));
pGLInfo->dwBpp = 24;
}
else
{
DISPDBG((DBGLVL, "Desktop is 32 bits"));
pGLInfo->dwBpp = 32;
}
pGLInfo->dwScreenWidthBytes = ppdev->lDelta;
if (pGLInfo->pRegs == 0)
{
DISPDBG ((WRNLVL, "__DDE_bSetupDDStructs: NULL register set"));
return (FALSE);
}
// Setup the information that is shared with the 32 bit side
// Control points to the RAMDAC
// pGLInfo is a pointer to the DisplayDriver state.
pThisDisplay->pGLInfo = pGLInfo;
pThisDisplay->control = (FLATPTR) pGLInfo->pRegs;
// NT uses offsets for its memory addresses
pThisDisplay->dwScreenFlatAddr = 0;
pThisDisplay->dwLocalBuffer = 0;
__DDE_BuildPixelFormat( pThisDisplay,
(LPGLINTINFO) pThisDisplay->pGLInfo,
&pThisDisplay->ddpfDisplay );
// Setup the display size information
// dwScreenWidth, dwScreenHeight = current resolution
// cxMemory = Pixels across for one scanline
// (not necessarily the same as the screen width)
// cyMemory = Scanline height of the memory
// dwScreenStart = First visible line of display
pThisDisplay->dwScreenWidth = pGLInfo->dwScreenWidth;
pThisDisplay->dwScreenHeight = pGLInfo->dwScreenHeight;
pThisDisplay->cxMemory = pGLInfo->dwScreenWidth;
pThisDisplay->dwScreenStart = pThisDisplay->dwScreenFlatAddr +
pGLInfo->dwScreenBase;
// Usefull constants used during blits.
if (pThisDisplay->ddpfDisplay.dwRGBBitCount == 24)
{
// The driver will detect these strange values and handle appropriately
pThisDisplay->bPixShift = 4;
pThisDisplay->bBppShift = 4;
pThisDisplay->dwBppMask = 4;
pThisDisplay->cyMemory = pGLInfo->ddFBSize /
(pThisDisplay->dwScreenWidth * 3);
}
else
{
// = 2,1,0 for 32,16,8 depth. Shifts needed to calculate bytes/pixel
pThisDisplay->bPixShift =
(BYTE)pThisDisplay->ddpfDisplay.dwRGBBitCount >> 4;
// = 0,1,2 for 32/16/8.
pThisDisplay->bBppShift = 2 - pThisDisplay->bPixShift;
// = 3,1,0 for 8,16,32 bpp
pThisDisplay->dwBppMask = 3 >> pThisDisplay->bPixShift;
pThisDisplay->cyMemory =
pGLInfo->ddFBSize /
(pThisDisplay->dwScreenWidth <<
(pThisDisplay->ddpfDisplay.dwRGBBitCount >> 4));
}
// On Windows NT, we manage a region of memory starting from 0
//(all pointers are offsets from the start of the mapped memory)
dwMemStart = pGLInfo->dwOffscreenBase;
dwMemEnd = pGLInfo->ddFBSize - 1;
// Round up the start pointer and round down the end pointer
dwMemStart = (dwMemStart + 3) & ~3;
dwMemEnd = dwMemEnd & ~3;
// Now make the end pointer inclusive
dwMemEnd -= 1;
DISPDBG((DBGLVL,"Heap Attributes:"));
DISPDBG((DBGLVL," Start of Heap Memory: 0x%lx",
pThisDisplay->LocalVideoHeap0Info.dwMemStart));
DISPDBG((DBGLVL," End of Heap Memory: 0x%lx",
pThisDisplay->LocalVideoHeap0Info.dwMemEnd));
// If we already have a heap setup and the mode has changed
// we free the Heap manager
if (pThisDisplay->bDDHeapManager)
{
if (pThisDisplay->bResetMode)
{
// The mode has been changed.
// We need to free the allocator and re-create it
_DX_LIN_UnInitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info);
// Start the allocator off again.
_DX_LIN_InitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info,
dwMemStart,
dwMemEnd);
}
}
else
{
// This must be the first instance of a created driver,
// so create the Heap and remember that it is created.
_DX_LIN_InitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info,
dwMemStart,
dwMemEnd);
pThisDisplay->bDDHeapManager = TRUE;
}
if(ppdev->flStatus & ENABLE_LINEAR_HEAP)
{
// save away the heap info we really need, we won't actually
// enable the DX managed heap until we get a
// DrvNotify(DN_DRAWING_BEGIN)
ppdev->heap.pvmLinearHeap = &pThisDisplay->LocalVideoHeap0Info;
ppdev->heap.cLinearHeaps = 1;
}
return TRUE;
} // __DDE_bSetupDDStructs
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// __DDE_bDestroyDDStructs
//
// Disable the linear allocator.
//
//-----------------------------------------------------------------------------
BOOL
__DDE_bDestroyDDStructs (
P3_THUNKEDDATA* pThisDisplay )
{
// Release the linear allocator
if (pThisDisplay->bDDHeapManager)
{
_DX_LIN_UnInitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info);
}
// 3D Heap manager not available.
pThisDisplay->bDDHeapManager = FALSE;
// Reset the driver version to 0 so it will be filled in again.
pThisDisplay->dwDXVersion = 0;
return TRUE;
} // __DDE_bDestroyDDStructs
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// _DD_DDE_CreatePPDEV
//
// These functions are called in sync with the creation/destruction of the pDev
//
//-----------------------------------------------------------------------------
BOOL
_DD_DDE_CreatePPDEV(
PDEV* ppdev)
{
P3_THUNKEDDATA* pThisDisplay;
DISPDBG((DBGLVL,"*** In _DD_DDE_CreatePPDEV"));
ASSERTDD(ppdev->thunkData == NULL,
"ERROR: thunkData already created for this pDev??");
// initialize the DX context which will be used by the display driver
// context switcher. We need a reference count because there is a case
// when a second, temporary, context would otherwise be created (when
// enabling the second adapter in a m-monitor system), first scrubbing
// out the old context ID, then invalidating the new one when it is
// deleted!
ppdev->DDContextID = -1;
ppdev->DDContextRefCount = 0;
// Allocate our ppdev
ppdev->thunkData = (PVOID)HEAP_ALLOC(HEAP_ZERO_MEMORY,
sizeof(P3_THUNKEDDATA),
ALLOC_TAG_DX(D));
if (ppdev->thunkData == NULL)
{
DISPDBG((ERRLVL, "_DD_DDE_CreatePPDEV: thunkdata alloc failed"));
return (FALSE);
}
// Our ppdev is called pThisDisplay
pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
pThisDisplay->ppdev = ppdev;
pThisDisplay->pGLInfo = (PVOID)HEAP_ALLOC(HEAP_ZERO_MEMORY,
sizeof(GlintInfo),
ALLOC_TAG_DX(E));
if (pThisDisplay->pGLInfo == NULL)
{
DISPDBG((ERRLVL, "_DD_DDE_CreatePPDEV: pGLInfo alloc failed"));
EngFreeMem (pThisDisplay);
ppdev->thunkData = NULL;
return (FALSE);
}
//@@BEGIN_DDKSPLIT
// W9X DX version is setup in the display driver.
//@@END_DDKSPLIT
// On Windows W2000 DX is always at least DX7
pThisDisplay->dwDXVersion = DX7_RUNTIME;
GetChipInfoForDDraw(ppdev,
&pThisDisplay->pGLInfo->dwRenderChipID,
&pThisDisplay->pGLInfo->dwRenderChipRev,
&pThisDisplay->pGLInfo->dwRenderFamily,
&pThisDisplay->pGLInfo->dwGammaRev);
DISPDBG((DBGLVL,"RenderChip: 0x%x, RenderFamily: 0x%x",
pThisDisplay->pGLInfo->dwRenderChipID,
pThisDisplay->pGLInfo->dwRenderFamily));
return TRUE;
} // _DD_DDE_CreatePPDEV
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// _DD_DDE_ResetPPDEV
//
//-----------------------------------------------------------------------------
void _DD_DDE_ResetPPDEV(PDEV* ppdevOld, PDEV* ppdevNew)
{
P3_THUNKEDDATA* pThisDisplayOld = (P3_THUNKEDDATA*)ppdevOld->thunkData;
P3_THUNKEDDATA* pThisDisplayNew = (P3_THUNKEDDATA*)ppdevNew->thunkData;
DISPDBG((DBGLVL,"_DD_DDE_ResetPPDEV: "
"pThisDispayOld: 0x%x, pThisDisplayNew: 0x%x",
pThisDisplayOld, pThisDisplayNew));
} // _DD_DDE_ResetPPDEV
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// _DD_DDE_DestroyPPDEV
//
//-----------------------------------------------------------------------------
void _DD_DDE_DestroyPPDEV(PDEV* ppdev)
{
P3_THUNKEDDATA* pThisDisplay = (P3_THUNKEDDATA*)ppdev->thunkData;
#if DBG
g_pThisTemp = NULL;
#endif
if (pThisDisplay)
{
// The 32 bit side will have allocated memory for use as global
// D3D/DD Driver data. Free it if it is there
if (pThisDisplay->pD3DHALCallbacks16)
{
SHARED_HEAP_FREE(&pThisDisplay->pD3DHALCallbacks16,
&pThisDisplay->pD3DHALCallbacks32,
TRUE);
DISPDBG((DBGLVL,"Freed pThisDisplay->pD3DHALCallbacks32"));
}
if (pThisDisplay->pD3DDriverData16)
{
SHARED_HEAP_FREE(&pThisDisplay->pD3DDriverData16,
&pThisDisplay->pD3DDriverData32,
TRUE);
DISPDBG((DBGLVL,"Freed pThisDisplay->pD3DDriverData32"));
}
pThisDisplay->lpD3DGlobalDriverData = 0;
pThisDisplay->lpD3DHALCallbacks = 0;
if (pThisDisplay->pGLInfo)
{
EngFreeMem (pThisDisplay->pGLInfo);
pThisDisplay->pGLInfo = NULL;
DISPDBG((DBGLVL,"Freed pThisDisplay->pGLInfo"));
}
EngFreeMem (pThisDisplay);
pThisDisplay = NULL;
DISPDBG((DBGLVL,"Freed pThisDisplay"));
}
// Clear the pointer
ppdev->thunkData = NULL;
} // _DD_DDE_DestroyPPDEV
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// _DD_DDE_vAssertModeDirectDraw
//
// This function is called by enable.c when entering or leaving the
// DOS full-screen character mode.
//
//-----------------------------------------------------------------------------
VOID
_DD_DDE_vAssertModeDirectDraw(
PDEV* ppdev,
BOOL bEnabled)
{
P3_THUNKEDDATA* pThisDisplay = (P3_THUNKEDDATA*)ppdev->thunkData;
DISPDBG((DBGLVL, "_DD_DDE_vAssertModeDirectDraw: enter"));
#if DX7_TEXMANAGEMENT
// Mark all managed surfaces as dirty as we've lost
// everything living in the videomemory
_DD_TM_EvictAllManagedTextures(pThisDisplay);
#endif
} // _DD_DDE_vAssertModeDirectDraw
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// _DD_DDE_bEnableDirectDraw
//
// This function is called by enable.c when the mode is first initialized,
// right after the miniport does the mode-set.
//
//-----------------------------------------------------------------------------
BOOL _DD_DDE_bEnableDirectDraw(
PDEV* ppdev)
{
DISPDBG((DBGLVL, "_DD_DDE_bEnableDirectDraw: enter"));
// DirectDraw is all set to be used on this card:
ppdev->flStatus |= STAT_DIRECTDRAW;
return(TRUE);
} // _DD_DDE_bEnableDirectDraw
//-----------------------------------------------------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// _DD_DDE_vDisableDirectDraw
//
// This function is called by enable.c when the driver is shutting down.
//
//-----------------------------------------------------------------------------
VOID _DD_DDE_vDisableDirectDraw(
PDEV* ppdev)
{
DISPDBG((DBGLVL, "_DD_DDE_vDisableDirectDraw: enter"));
} // _DD_DDE_vDisableDirectDraw
//-----------------------------Public Routine----------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// DrvEnableDirectDraw
//
// Enables hardware for DirectDraw use.
//
// GDI calls DrvEnableDirectDraw to obtain pointers to the DirectDraw callbacks
// that the driver supports. The driver should set the function pointer members
// of DD_CALLBACKS, DD_SURFACECALLBACKS, and DD_PALETTECALLBACKS to point to
// those functions that it implements. A driver should also set the
// corresponding bit fields in the dwFlags members of these structures for all
// supported callbacks.
//
// A driver's DrvEnableDirectDraw implementation can also dedicate hardware
// resources such as display memory for use by DirectDraw only.
//
// DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE
//
// Parameters
//
// dhpdev
// Handle to the PDEV returned by the driver's DrvEnablePDEV routine.
// pCallBacks
// Points to the DD_CALLBACKS structure to be initialized by the
// driver.
// pSurfaceCallBacks
// Points to the DD_SURFACECALLBACKS structure to be initialized by
// the driver.
// pPaletteCallBacks
// Points to the DD_PALETTECALLBACKS structure to be initialized by
// the driver.
//
//-----------------------------------------------------------------------------
BOOL DrvEnableDirectDraw(
DHPDEV dhpdev,
DD_CALLBACKS* pCallBacks,
DD_SURFACECALLBACKS* pSurfaceCallBacks,
DD_PALETTECALLBACKS* pPaletteCallBacks)
{
PDEV* ppdev;
BOOL bRet;
DWORD dwResult;
P3_THUNKEDDATA* pThisDisplay;
DWORD *theVBlankThing, *bOverlayEnabled;
DWORD *VBLANKUpdateOverlay;
DWORD *VBLANKUpdateOverlayWidth;
DWORD *VBLANKUpdateOverlayHeight;
DWORD Buffers;
ppdev = (PDEV*) dhpdev;
pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
if (!bSetupOffscreenForDDraw (FALSE,
ppdev,
&theVBlankThing,
&bOverlayEnabled,
&VBLANKUpdateOverlay,
&VBLANKUpdateOverlayWidth,
&VBLANKUpdateOverlayHeight))
{
DISPDBG((ERRLVL, "DrvEnableDirectDraw: "
"bSetupOffscreenForDDraw failed, but continuing"));
//return (FALSE);
}
pThisDisplay->VBlankStatusPtr = theVBlankThing;
pThisDisplay->bOverlayEnabled = bOverlayEnabled;
pThisDisplay->bVBLANKUpdateOverlay = VBLANKUpdateOverlay;
pThisDisplay->VBLANKUpdateOverlayWidth = VBLANKUpdateOverlayWidth;
pThisDisplay->VBLANKUpdateOverlayHeight = VBLANKUpdateOverlayHeight;
#if DBG
// Read in the registry variable for the debug level
{
// Get the Debuglevel for DirectX
bRet = GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.Debug", &dwResult);
if (bRet == TRUE)
{
P3R3DX_DebugLevel = (LONG)dwResult;
}
else
{
P3R3DX_DebugLevel = 0;
}
DISPDBG((WRNLVL,"Setting DebugLevel to 0x%x", P3R3DX_DebugLevel));
}
#endif
// Create context with >2 sub-buffers for Interupt driven DMA.
bRet =GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.SubBuffers", &dwResult);
if ((dwResult == 0) || (bRet == FALSE))
{
// Default
Buffers = DEFAULT_SUBBUFFERS;
}
else
{
if (dwResult > MAX_SUBBUFFERS)
{
Buffers = MAX_SUBBUFFERS;
}
else
{
Buffers = dwResult;
}
if (Buffers < 2)
{
Buffers = 2;
}
}
pThisDisplay->pGLInfo->dw3DDMABufferSize = 0;
pThisDisplay->pGLInfo->dw3DDMABufferPhys = 0;
pThisDisplay->pGLInfo->dw3DDMABufferVirt = 0;
// Allocate a DMA Buffer on Win2K
DDGetFreeDMABuffer(&pThisDisplay->pGLInfo->dw3DDMABufferPhys,
&pThisDisplay->pGLInfo->dw3DDMABufferVirt,
&pThisDisplay->pGLInfo->dw3DDMABufferSize);
if (pThisDisplay->pGLInfo->dw3DDMABufferSize != 0)
{
DISPDBG((DBGLVL,"Allocated DMA Buffer:- "
"Phys:0x%x, Virt:0x%x, Size:0x%x",
pThisDisplay->pGLInfo->dw3DDMABufferPhys,
pThisDisplay->pGLInfo->dw3DDMABufferVirt,
pThisDisplay->pGLInfo->dw3DDMABufferSize));
}
else
{
DISPDBG((WRNLVL,"Failed to allocate DMA Buffer!"));
}
if(ppdev->DDContextID == -1)
{
// we don't have a DDraw context: create one now
ppdev->DDContextID = GlintAllocateNewContext(ppdev,
NULL,
0,
Buffers,
NULL,
ContextType_None);
if(ppdev->DDContextID != -1)
{
++ppdev->DDContextRefCount;
DISPDBG((DBGLVL, "<%13s, %4d>: DrvEnableDirectDraw: "
"Created DDraw context, current DX context "
"count = %d for ppdev %p",
__FILE__, __LINE__,
ppdev->DDContextRefCount, ppdev));
}
}
if (ppdev->DDContextID < 0)
{
DISPDBG((ERRLVL, "ERROR: failed to allocate DDRAW context"));
return(FALSE);
}
DISPDBG((DBGLVL," Created DD Register context: 0x%x",
ppdev->DDContextID));
if (!__DDE_bSetupDDStructs (pThisDisplay, TRUE))
{
vGlintFreeContext (ppdev, ppdev->DDContextID);
DISPDBG((ERRLVL, "ERROR: DrvEnableDirectDraw: "
"__DDE_bSetupDDStructs failed"));
return (FALSE);
}
if (!_DD_InitDDHAL32Bit (pThisDisplay))
{
vGlintFreeContext (ppdev, ppdev->DDContextID);
DISPDBG((ERRLVL, "ERROR: DrvEnableDirectDraw: "
"_DD_InitDDHAL32Bit failed"));
return (FALSE);
}
// Set the flag that says we have to handle a mode change.
// This will cause the chip to be initialised properly at the
// right time.
pThisDisplay->bResetMode = TRUE;
pThisDisplay->bStartOfDay = TRUE;
pThisDisplay->pGLInfo->dwDirectXState = DIRECTX_LASTOP_UNKNOWN;
// Fill in the function pointers at start of day. We copy these from
// the Initialisation done in _DD_InitDDHAL32Bit. It's OK to do this
// because on a Windows NT compile the structures should match
memcpy(pCallBacks,
&pThisDisplay->DDHALCallbacks,
sizeof(DD_CALLBACKS));
memcpy(pSurfaceCallBacks,
&pThisDisplay->DDSurfCallbacks,
sizeof(DD_SURFACECALLBACKS));
// Note that we don't call 'vGetDisplayDuration' here, for a couple of
// reasons:
//
// o Because the system is already running, it would be disconcerting
// to pause the graphics for a good portion of a second just to read
// the refresh rate;
// o More importantly, we may not be in graphics mode right now.
//
// For both reasons, we always measure the refresh rate when we switch
// to a new mode.
return(TRUE);
} // DrvEnableDirectDraw
//-----------------------------Public Routine----------------------------------
//
// ***************************WIN NT ONLY**********************************
//
// DrvDisableDirectDraw
//
// Disables hardware for DirectDraw use.
//
// GDI calls DrvDisableDirectDraw when the last DirectDraw application has
// finished running. A driver's DrvDisableDirectDraw implementation should
// clean up any software resources and reclaim any hardware resources that
// the driver dedicated to DirectDraw in DrvEnableDirectDraw.
//
// Parameters
// dhpdev
// Handle to the PDEV that was returned by the driver's
// DrvEnablePDEV routine.
//
//-----------------------------------------------------------------------------
VOID
DrvDisableDirectDraw(
DHPDEV dhpdev)
{
PDEV* ppdev;
P3_THUNKEDDATA* pThisDisplay;
ppdev = (PDEV*) dhpdev;
pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
// Only do all this stuff if we have not already been disabled.
// Note that when running NT4 without SP3, this function can be called
// more times than DrvEnableDirectDraw.
if (pThisDisplay != NULL)
{
// Re-enable GDI off-screen bitmaps
(void) bSetupOffscreenForDDraw (TRUE,
ppdev,
NULL,
NULL,
NULL,
NULL,
NULL);
// Free all memory
(void) __DDE_bDestroyDDStructs (pThisDisplay);
if(ppdev->DDContextRefCount > 0)
{
if(--ppdev->DDContextRefCount == 0)
{
vGlintFreeContext (ppdev, ppdev->DDContextID);
DISPDBG((DBGLVL,"Freed DDraw context: 0x%x",
ppdev->DDContextID));
ppdev->DDContextID = -1;
DISPDBG((DBGLVL, "<%13s, %4d>: DrvDisableDirectDraw:"
" Deleted DDraw context, current DX context"
" count = %d for ppdev %p",
__FILE__, __LINE__,
ppdev->DDContextRefCount, ppdev));
}
}
DDFreeDMABuffer((void*)(ULONG_PTR)pThisDisplay->pGLInfo->dw3DDMABufferPhys);
}
} // DrvDisableDirectDraw
#endif // WNT_DDRAW