⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddraw.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:        See COPYING in the top level directory
 * PROJECT:          ReactOS kernel
 * PURPOSE:          Native DirectDraw implementation
 * FILE:             subsys/win32k/ntddraw/ddraw.c
 * PROGRAMER:        Peter Bajusz (hyp-x@stormregion.com)
 * REVISION HISTORY:
 *       25-10-2003  PB  Created
 */

#include <w32k.h>

//#define NDEBUG
#include <debug.h>
GDIDEVICE IntGetPrimarySurface(VOID);

/* swtich this off to get rid of all dx debug msg */
#define DX_DEBUG

#define DdHandleTable GdiHandleTable




/************************************************************************/
/* DIRECT DRAW OBJECT                                                   */
/************************************************************************/

BOOL INTERNAL_CALL
DD_Cleanup(PVOID ObjectBody)
{
    PDD_DIRECTDRAW pDirectDraw = (PDD_DIRECTDRAW) ObjectBody;

    DPRINT1("DD_Cleanup\n");

    if (!pDirectDraw)
    {
        return FALSE;
    }

    if (pDirectDraw->Global.dhpdev == NULL)
    {
        return FALSE;
    }

    if (pDirectDraw->DrvDisableDirectDraw == NULL)
    {
        return FALSE;
    }

    //if (pDirectDraw->pvmList != NULL)
    //{
    //    ExFreePool(pDirectDraw->pvmList);
    //}
    //
    //if (pDirectDraw->pdwFourCC != NULL)
    //{
    //    ExFreePool(pDirectDraw->pdwFourCC);
    //}

    pDirectDraw->DrvDisableDirectDraw(pDirectDraw->Global.dhpdev);
    return TRUE;
}

/* code for enable and reanble the drv */
BOOL
intEnableDriver(PDD_DIRECTDRAW pDirectDraw)
{
     BOOL success;
     DD_HALINFO HalInfo;

    /*clean up some of the cache entry */
    RtlZeroMemory(&pDirectDraw->DD,   sizeof(DD_CALLBACKS));
    RtlZeroMemory(&pDirectDraw->Surf, sizeof(DD_SURFACECALLBACKS));
    RtlZeroMemory(&pDirectDraw->Pal,  sizeof(DD_PALETTECALLBACKS));
    RtlZeroMemory(&pDirectDraw->Hal,  sizeof(DD_HALINFO));
    RtlZeroMemory(&HalInfo,  sizeof(DD_HALINFO));
    pDirectDraw->dwNumHeaps =0;
    pDirectDraw->dwNumFourCC = 0;
    pDirectDraw->pdwFourCC = NULL;
    pDirectDraw->pvmList = NULL;

    /* Get DirectDraw infomations form the driver 
     * DDK say pvmList, pdwFourCC is always NULL in frist call here 
     * but we get back how many pvmList it whant we should alloc, same 
     * with pdwFourCC.
     */
    success = pDirectDraw->DrvGetDirectDrawInfo( pDirectDraw->Global.dhpdev, 
                                                 &HalInfo,
                                                 &pDirectDraw->dwNumHeaps,
                                                 NULL,
                                                 &pDirectDraw->dwNumFourCC,
                                                 NULL);
    if (!success)
    {
        DPRINT1("DrvGetDirectDrawInfo  frist call fail\n");
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }



    /* The driver are not respnose to alloc the memory for pvmList
     * but it is win32k responsible todo, Windows 9x it is gdi32.dll
     */
    if (pDirectDraw->dwNumHeaps != 0)
    {
        pDirectDraw->pvmList = (PVIDEOMEMORY) ExAllocatePoolWithTag(PagedPool, pDirectDraw->dwNumHeaps * sizeof(VIDEOMEMORY), TAG_DXPVMLIST);
        if (pDirectDraw->pvmList == NULL)
        {
            return FALSE;
        }
    }

     /* The driver are not respnose to alloc the memory for pdwFourCC
      * but it is win32k responsible todo, Windows 9x it is gdi32.dll
      */

     if (pDirectDraw->dwNumFourCC != 0)
        {
            pDirectDraw->pdwFourCC = (LPDWORD) ExAllocatePoolWithTag(PagedPool, pDirectDraw->dwNumFourCC * sizeof(DWORD), TAG_DXFOURCC);

            if (pDirectDraw->pdwFourCC == NULL)
            {
                return FALSE;
            }
        }

      success = pDirectDraw->DrvGetDirectDrawInfo( pDirectDraw->Global.dhpdev, 
                                                   &HalInfo,
                                                   &pDirectDraw->dwNumHeaps,
                                                   pDirectDraw->pvmList,
                                                   &pDirectDraw->dwNumFourCC,
                                                   pDirectDraw->pdwFourCC);
    if (!success)
    {
        DPRINT1("DrvGetDirectDrawInfo  second call fail\n");
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }


    /* We need now convert the DD_HALINFO we got, it can be NT4 driver we 
     * loading ReactOS supporting NT4 and higher to be loading.so we make
     * the HALInfo compatible here so we can easy pass it to gdi32.dll 
     * without converting it later 
     */

    if ((HalInfo.dwSize != sizeof(DD_HALINFO)) && 
        (HalInfo.dwSize != sizeof(DD_HALINFO_V4)))
    {
         DPRINT1(" Fail not vaild driver DD_HALINFO struct found\n");
         GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
         return FALSE;
    }

    if (HalInfo.dwSize != sizeof(DD_HALINFO))
    {
        if (HalInfo.dwSize == sizeof(DD_HALINFO_V4))
        {
            /* NT4 Compatible */
            DPRINT1("Got DD_HALINFO_V4 sturct we convert it to DD_HALINFO \n");
            HalInfo.dwSize = sizeof(DD_HALINFO);
            HalInfo.lpD3DGlobalDriverData = NULL;
            HalInfo.lpD3DHALCallbacks = NULL;
            HalInfo.lpD3DBufCallbacks = NULL;
        }
        else
        {
            /* Unknown version found */
            DPRINT1(" Fail : did not get DD_HALINFO size \n");

            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return FALSE;
        }

        /* Copy it to user mode pointer the data */
        RtlCopyMemory(&pDirectDraw->Hal, &HalInfo, sizeof(DD_HALINFO));
    }
    
    success = pDirectDraw->EnableDirectDraw( pDirectDraw->Global.dhpdev, 
                                             &pDirectDraw->DD, 
                                             &pDirectDraw->Surf, 
                                             &pDirectDraw->Pal);

    if (!success)
    {
        DPRINT1("EnableDirectDraw call fail\n");
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return FALSE;
    }

    return TRUE;
}


HANDLE STDCALL 
NtGdiDdCreateDirectDrawObject(HDC hdc)
{
    DC *pDC;
    HANDLE hDirectDraw;
    PDD_DIRECTDRAW pDirectDraw;

    DPRINT1("NtGdiDdCreateDirectDrawObject\n");

    /* Create a hdc if we do not have one */
    if (hdc == NULL)
    {
       return NULL;
    }
    
    /* Look the hdc to gain the internal struct */
    pDC = DC_LockDc(hdc);
    if (!pDC)
    {
        return NULL;
    }

    /* test see if drv got a dx interface or not */
    if  (( pDC->DriverFunctions.GetDirectDrawInfo == NULL) ||
         ( pDC->DriverFunctions.DisableDirectDraw == NULL) ||
         ( pDC->DriverFunctions.EnableDirectDraw == NULL))
    {
        DC_UnlockDc(pDC);
        return NULL;
    }

    /* alloc and lock  the stucrt */
    hDirectDraw = GDIOBJ_AllocObj(DdHandleTable, GDI_OBJECT_TYPE_DIRECTDRAW);
    if (!hDirectDraw)
    {
        /* No more memmory */
        DC_UnlockDc(pDC);
        return NULL;
    }

    pDirectDraw = GDIOBJ_LockObj(DdHandleTable, hDirectDraw, GDI_OBJECT_TYPE_DIRECTDRAW);
    if (!pDirectDraw)
    {
        /* invalid handle */
        DC_UnlockDc(pDC);
        return NULL;
    }

    /* setup the internal stuff */
    pDirectDraw->Global.dhpdev = pDC->PDev;
    pDirectDraw->Local.lpGbl = &pDirectDraw->Global;

    pDirectDraw->DrvGetDirectDrawInfo = pDC->DriverFunctions.GetDirectDrawInfo;
    pDirectDraw->DrvDisableDirectDraw = pDC->DriverFunctions.DisableDirectDraw;
    pDirectDraw->EnableDirectDraw = pDC->DriverFunctions.EnableDirectDraw;

    if (intEnableDriver(pDirectDraw) == FALSE)
    {
        /* FIXME delete the pDirectDraw and the handle */
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        DC_UnlockDc(pDC);
        return NULL;
    }

    GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
    DC_UnlockDc(pDC);
    DPRINT1("DirectDraw return handler 0x%x\n",hDirectDraw); 

    return hDirectDraw;
}

BOOL STDCALL 
NtGdiDdDeleteDirectDrawObject( HANDLE hDirectDrawLocal)
{
    DPRINT1("NtGdiDdDeleteDirectDrawObject\n");
    return GDIOBJ_FreeObj(DdHandleTable, hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
}


BOOL STDCALL 
NtGdiDdQueryDirectDrawObject(
    HANDLE hDirectDrawLocal,
    DD_HALINFO  *pHalInfo,
    DWORD *pCallBackFlags,
    LPD3DNTHAL_CALLBACKS puD3dCallbacks,
    LPD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData,
    PDD_D3DBUFCALLBACKS puD3dBufferCallbacks,
    LPDDSURFACEDESC puD3dTextureFormats,
    DWORD *puNumHeaps,
    VIDEOMEMORY *puvmList,
    DWORD *puNumFourCC,
    DWORD *puFourCC
)
{
    PDD_DIRECTDRAW pDirectDraw;
    NTSTATUS Status = FALSE;
    BOOL Ret=FALSE;

    /* FIXME the workaround for 0.3.1 pseh bugs 
     * we should not need todo if (pHalInfo != NULL)
     * so on
     */

    DPRINT1("NtGdiDdQueryDirectDrawObject\n");
    if (hDirectDrawLocal == NULL)
    {
       return Ret;
    }

    pDirectDraw = GDIOBJ_LockObj(DdHandleTable, hDirectDrawLocal,
                                 GDI_OBJECT_TYPE_DIRECTDRAW);

    if (!pDirectDraw)
    {
        return Ret;
    }

    /*
     * Get pHalInfo 
     */
    if (pHalInfo != NULL)
    {
        DPRINT1("copy &pDirectDraw->Hal to pHalInfo\n");
        _SEH_TRY
        {
            ProbeForWrite(pHalInfo,  sizeof(DD_HALINFO), 1);
            RtlCopyMemory(pHalInfo,&pDirectDraw->Hal, sizeof(DD_HALINFO));
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            DPRINT1("GDIOBJ_UnlockObjByPtr and SetLastNtError\n");
            SetLastNtError(Status);
            GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
            return Ret;
        }
    }
    else
    {
        DPRINT1("GDIOBJ_UnlockObjByPtr\n");
        GDIOBJ_UnlockObjByPtr(DdHandleTable, pDirectDraw);
        return Ret;
    }


    /*
     * Get pCallBackFlags
     */
    if (pCallBackFlags != NULL)
    {
        DPRINT1("copy &CallBackFlags to pCallBackFlags\n");
        _SEH_TRY
        {
            ProbeForWrite(pCallBackFlags,  sizeof(DWORD)*3, 1);
            pCallBackFlags[0]=pDirectDraw->DD.dwFlags;
            pCallBackFlags[1]=pDirectDraw->Surf.dwFlags;
            pCallBackFlags[2]=pDirectDraw->Pal.dwFlags;
        }
        _SEH_HANDLE
        {
            Status = _SEH_GetExceptionCode();
        }
        _SEH_END;
        if(!NT_SUCCESS(Status))
        {
            DPRINT1("GDIOBJ_UnlockObjByPtr and SetLastNtError\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -