windraw2.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,002 行 · 第 1/5 页

CPP
2,002
字号
    
    /* update client area size: */
    lpwd->dwWindowWidth = dwWidth;
    lpwd->dwWindowHeight = dwHeight;
    
    /* ... */
    
    return (LRESULT) 1;
}

/*
* This function handles the WM_CLOSE message:
*/
LRESULT WinDraw2_OnClose (LPWINDRAW lpwd)
{
    /* check parameters: */
    if (lpwd == NULL || lpwd->hWnd == NULL)
        return (LRESULT) 0;
    
    /* hide window before destroying it: */
    ShowWindow (lpwd->hWnd, SW_HIDE);
    
    return TRUE;
}

HRESULT CALLBACK 
DisplayModeEnumeratorCallback(LPDDSURFACEDESC pddsd, LPVOID Context)
{
    CHXSimpleList* pList = (CHXSimpleList*) Context;
    
    CModesDesc* pDesc = new CModesDesc;
    
    pDesc->m_nWidth	= pddsd->dwWidth;
    pDesc->m_nHeight	= pddsd->dwHeight;
    pDesc->m_nBitCount	= pddsd->ddpfPixelFormat.dwRGBBitCount;
    pDesc->m_fourCC	= pddsd->ddpfPixelFormat.dwFourCC;
    
    pList->AddTail(pDesc);
    
    return DDENUMRET_OK;
} 

/*
* Initialize WinDraw engine.
* Use:
*  HRESULT WinDraw2_Open (LPWINDRAW lpwd, HWND hWnd, DWORD fMode,
*      LPSTR lpszDisplay, LPBMI lpbiDisplayFormat);
* Input:
*  lpwd - pointer to a WINDRAW structure to initialize
*  hWnd - a window handle to use
*  fMode - WinDraw mode to set (e.g. WINDRAW_FULLSCREEN)
*  lpszDisplay - monitor to use (NULL or zero string = use all monitors)
*  lpbiDisplayFormat - preferred display mode in full screen
* Returns:
*  NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
*/
HRESULT WinDraw2_Open (LPWINDRAW lpwd, HWND hWnd, DWORD fMode,
		       LPSTR lpszDisplay, LPBMI lpbiDisplayFormat)
{
    /* check parameters: */
    if (lpwd == NULL || hWnd == NULL || (lpwd->fMode & WINDRAW_OPENED))
        return E_INVALIDARG;
    
    HRESULT hrFail = E_FAIL;

    if (!g_ehandlerMutexCnt)
    {
        InitializeCriticalSection(&g_ehandlerMutex);
    }
    InterlockedIncrement(&g_ehandlerMutexCnt);
    
    z_hHxColor = LoadLibrary("colorcvt.dll");
    if (!z_hHxColor)
         z_hHxColor = LoadLibrary("hxltcolor.dll");

    if (z_hHxColor)
    {
	pfInitColorConverter = (INITCOLORCONVERTERFN) GetProcAddress(z_hHxColor,"InitColorConverter");
	pfSetRGB8Palette = (SETRGB8PALETTEFN) GetProcAddress(z_hHxColor,"SetRGB8Palette");
    }
    
    /* initialize WinDraw structure: */
    memset (lpwd, 0, sizeof (WINDRAW));
    lpwd->hWnd = hWnd;
    lpwd->m_pModesList	    = new CHXSimpleList;
    lpwd->m_pSurfaceList    = new CHXSimpleList;
    lpwd->nSchedulerResolution = 0;
    
    InitializeCriticalSection(&lpwd->csPrimary);
	
    /* check if want to use DirectDraw: */
    if (fMode & WINDRAW_DIRECTDRAW) 
    {
        lpwd->fMode |= WINDRAW_DIRECTDRAW;
	
        /* initialize DirectDraw objects: */
	
	LPDIRECTDRAW pDirectDraw = NULL;
	
        try
        {

        if (LoadDirectDraw (lpszDisplay, &pDirectDraw, & (lpwd->dd.hDD)) != NOERROR)
            goto dd_fail;

        }
        catch (...)
        {
            DumpDDInfo(lpwd, NULL, "WinDraw2_Open");
            goto dd_fail;
        }
	
        pDirectDraw->QueryInterface(IID_IDirectDraw2, (void**)&lpwd->dd.lpDD2);
	pDirectDraw->Release();
	pDirectDraw = 0;
	
	/* 
	* DirectX 1.0 installed (e.g. boxes with the original (Aug 95) release of Win95).
	* don't support that!
	*/
	if (!lpwd->dd.lpDD2)
	{
	    goto dd_fail;
	}
	
        /* initialize our color conversion engine: */
	if (pfInitColorConverter)
	    (*pfInitColorConverter)();
	
        /* get display format: */
        lpwd->lpszDisplayDevice = lpszDisplay;
        lpwd->cidDisplayColor = CID_UNKNOWN;
        if (GetDisplayFormat (&lpwd->bmiDisplayFormat, lpwd->lpszDisplayDevice) != NOERROR ||
            (lpwd->cidDisplayColor = GetBitmapColor ((LPBITMAPINFO)&lpwd->bmiDisplayFormat)) == CID_UNKNOWN) 
	{
	    
            /* this is very bad... */
            #ifdef _DEBUG
            OutputDebugString ("WinDraw: cannot obtain display pixel format.\n");
            #endif

            goto dd_fail;
        }
	
	/* find out what FourCC codes are supported */
	
	lpwd->dd.lpDD2->GetFourCCCodes(&(lpwd->numCodes), lpwd->lpCodes);
	
	if (lpwd->numCodes)
	{
	    lpwd->lpCodes	= (LPDWORD) malloc (lpwd->numCodes*4);
	    lpwd->lpCID	= (LPDWORD) malloc (lpwd->numCodes*4);
	    
	    lpwd->dd.lpDD2->GetFourCCCodes(&(lpwd->numCodes), lpwd->lpCodes);
	    
	    for(unsigned int i = 0; i<lpwd->numCodes; i++)
	    {
		lpwd->lpCID[i] = MapFourCCtoCID(lpwd->lpCodes[i]);
	    }
	}
	
	/* Get the device caps */
	memset(&lpwd->dd.m_caps, 0, sizeof(DDCAPS));
	lpwd->dd.m_caps.dwSize = sizeof(DDCAPS_DX3);
	lpwd->dd.lpDD2->GetCaps(&(lpwd->dd.m_caps), 0);

	/*
	*  If we have neither overlay nor streatching then we will use DibEngine (good call? time will tell)
	*/
	
        if (! ( (lpwd->dd.m_caps.dwCaps & DDCAPS_OVERLAY) || (lpwd->dd.m_caps.dwCaps &  DDCAPS_BLTSTRETCH) ))
	{
	    goto dd_fail;
	}
	
	/* set normal cooperative level  */
        if (DD_OK != lpwd->dd.lpDD2->SetCooperativeLevel(lpwd->hWnd, DDSCL_NORMAL)) 
	{
	    goto dd_fail;
        }
	
        try
        {

        if (DD_OK == WindrawSurface_CreatePrimarySurface(lpwd))
	{
            /* DirectDraw profile/mode masks: */
            DWORD dwOverlayMask, dwBltMask;
            DDPIXELFORMAT ddpf;
	    /* color formats: */
	    int cidOut = CID_UNKNOWN;
	    
            /* get pixel format of the primary surface: */
            memset (&ddpf, 0, sizeof (DDPIXELFORMAT));
            ddpf.dwSize = sizeof (DDPIXELFORMAT);
            ddpf.dwFlags = DDPF_RGB | DDPF_FOURCC;
            if (lpwd->dd.lpDDSPrimary->GetPixelFormat(&ddpf) != DD_OK)
                goto dd_fail;
	    
            /* convert it to our color ID: */
            cidOut = GetDirectDrawColor (&ddpf);
            if (cidOut < CID_RGB32 || cidOut > CID_RGB8)
                goto dd_fail;
	    
            /* check if DirectDraw profile needs to be loaded: */
            if (!lpddprofDirectDrawProfile || DDPDB_IsNewProfile ()) {
		
                /* get DirectDraw device profile: */
		lpwd->dd.lpDD2->QueryInterface(IID_IDirectDraw, (void**)&pDirectDraw);
		HX_ASSERT(pDirectDraw);
		lpddprofDirectDrawProfile = DDPDB_GetDeviceProfile(pDirectDraw);
		pDirectDraw->Release();
		pDirectDraw = 0;
            }
	    
            /* get mode masks: */
            dwOverlayMask = lpddprofDirectDrawProfile->fOverlays [cidOut-CID_RGB32];
            dwBltMask = lpddprofDirectDrawProfile->fBlts [cidOut-CID_RGB32];
	    
	    //            if (dwOverlayMask == 0 || dwBltMask == 0)
	    /* We currently disable DirectDraw if bltMask is 0.
	    * Need to add support for selecting DirectDraw features based on
	    * the info in the database.
	    */
            if (dwOverlayMask == 0)
                goto dd_fail;
	    
	    /* Enum the display modes  */
	    zm_DisplaySettings.GetSettings(lpwd->m_pModesList);
	    
	    /*
	    *  For SOME reason EnumDisplayModes is causing a number of cards to go CRAZY.
	    *	So we now we call a function which calls enum display modes early and caches 
	    *	the results. For some reason this does not cause things to go INSANE. Who knows why.
	    */
	    
	    //	    lpwd->dd.lpDD2->EnumDisplayModes(0, NULL, lpwd->m_pModesList, DisplayModeEnumeratorCallback); 	    
	}
	else
	{
            goto dd_fail;
	}
	
        }
        catch(...)
        {
            DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_Open");
            goto dd_fail;
        }
        
        goto success;
	
dd_fail:
	
        /* release DirectDraw library, if loaded: */
        if (lpwd->dd.lpDD2 != NULL && lpwd->dd.hDD != NULL)
            ReleaseDirectDraw(&(lpwd->dd.lpDD), &(lpwd->dd.lpDD2), & (lpwd->dd.hDD));
	
        /* exit with error: */
        return hrFail;
	
    } else { /* use GDI: */

        /* grab DCs: */
	
	if ((lpwd->gdi.hDC = GetDC (lpwd->hWnd)) == NULL ||
	    (lpwd->gdi.hMemoryDC = CreateCompatibleDC (lpwd->gdi.hDC)) == NULL ||
	    (lpwd->gdi.hMemoryDC2 = CreateCompatibleDC (lpwd->gdi.hDC)) == NULL)
            goto gdi_fail;
	
        /* set default StretchBlt () mode: */
	SetStretchBltMode (lpwd->gdi.hDC, COLORONCOLOR);
        SetStretchBltMode (lpwd->gdi.hMemoryDC,COLORONCOLOR);
        SetStretchBltMode (lpwd->gdi.hMemoryDC2,COLORONCOLOR);
	
        /* get display format: */
        lpwd->lpszDisplayDevice = lpszDisplay;
        lpwd->cidDisplayColor = CID_UNKNOWN;
        if (GetDisplayFormat (&lpwd->bmiDisplayFormat, lpwd->lpszDisplayDevice) != NOERROR ||
            (lpwd->cidDisplayColor = GetBitmapColor ((LPBITMAPINFO)&lpwd->bmiDisplayFormat)) == CID_UNKNOWN) {
	    
            /* this is very bad... */
            #ifdef _DEBUG
            OutputDebugString ("WinDraw: cannot obtain display pixel format.\n");
            #endif

            goto gdi_fail;
        }
	
        /* initialize our color conversion engine: */
	if (pfInitColorConverter)
	    (*pfInitColorConverter)();
	
        goto success;
	
        /* something really bad has happened... */
gdi_fail:
	
        /* delete palette: */
        if (lpwd->gdi.hPalette) {
            DeleteObject (lpwd->gdi.hPalette);
	    lpwd->gdi.hPalette = NULL;
	}
	
	
	
	/* release DCs, if taken: */   
	if (lpwd->gdi.hDC != NULL) 
	{   
	    ReleaseDC (lpwd->hWnd, lpwd->gdi.hDC);   
	    lpwd->gdi.hDC = NULL;   
	} 
        
	if (lpwd->gdi.hMemoryDC != NULL) {
            DeleteDC (lpwd->gdi.hMemoryDC);
	    lpwd->gdi.hMemoryDC = NULL;
	}
        if (lpwd->gdi.hMemoryDC2 != NULL) {
            DeleteDC (lpwd->gdi.hMemoryDC2);
	    lpwd->gdi.hMemoryDC2 = NULL;
	}
	
        /* exit with error: */
        return E_FAIL;
    }
    
success:
    
    /* activate WinDraw & exit: */
    lpwd->fMode |= WINDRAW_OPENED;
    WinDraw2_OnPaletteChange(lpwd, lpwd->hWnd, WM_PALETTECHANGED);

    return NOERROR;
}

void DeleteDisplayModes(LPWINDRAW lpwd)
{
    CHXSimpleList::Iterator i;
    
    if (!lpwd->m_pModesList || !lpwd->m_pModesList->GetCount())
        return;

    for(i=lpwd->m_pModesList->Begin(); i!= lpwd->m_pModesList->End(); ++i)
    {
	CModesDesc* pDesc = (CModesDesc*) *i;
	HX_DELETE(pDesc);
    }
    lpwd->m_pModesList->RemoveAll();
}

/*
* Close WinDraw library.
* Use:
*  HRESULT WinDrawClose (LPWINDRAW lpwd);
* Input:
*  lpwd - pointer to a WINDRAW engine to deactivate
* Returns:
*  NOERROR if OK, or E_FAIL.
*/
HRESULT WinDraw2_Close (LPWINDRAW lpwd)
{
    /* check parameters: */
    if (lpwd == NULL || !(lpwd->fMode & WINDRAW_OPENED))
        //	return E_INVALIDARG;
        goto cleanup;

    if (z_hHxColor)
    {
        FreeLibrary(z_hHxColor);
        z_hHxColor = 0;

        pfInitColorConverter = 0;
        pfSetRGB8Palette = 0;
    }

    /* check mode: */
    if (lpwd->fMode & WINDRAW_DIRECTDRAW)
    {
        free(lpwd->lpCodes);
        free(lpwd->lpCID);

       /* 
        * Release the Primary Surface
        */

        if (lpwd->dd.lpDDSPrimary)
        {
            int rel = lpwd->dd.lpDDSPrimary->Release();
            lpwd->dd.lpDDSPrimary = NULL;
        }

        /* release DirectDraw library, if loaded: */
        if (lpwd->dd.lpDD2 != NULL && lpwd->dd.hDD != NULL)
        ReleaseDirectDraw (&(lpwd->dd.lpDD), &(lpwd->dd.lpDD2), &(lpwd->dd.hDD));


    }
    else
    { /* GDI: */
        /* delete palette: */
        if (lpwd->gdi.hPalette)

⌨️ 快捷键说明

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