📄 winroot.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
#include "hxtypes.h"
#include "hxmtypes.h"
#include "hxwintyp.h"
#include "hxvsurf.h"
#include "hxslist.h"
#include "hxerror.h"
#include "hxstrutl.h"
#include "hxver.h"
//#include "surfroot.h"
//#include "surfwles.h"
//#include "sitewles.h"
#include "winroot.h" // this muyst be included before colormap.h
#include "colormap.h"
#include "hxprefs.h"
#include "hxtick.h"
#include "ddpdb.h"
#include "winsite.h"
#ifndef _WIN32
#error This is the Macintosh platform specific implementation.
#endif
typedef HRESULT (HXEXPORT_PTR FPDIRECTDRAWCREATE)(GUID FAR * lpGUID,
LPDIRECTDRAW FAR * lplpDD, IUnknown FAR * pUnkOuter);
#define _DEBUGGING_WINDOWED_RENDERERS
CWinBaseRootSurface::CWinBaseRootSurface(IUnknown* pContext, CHXBaseSite* pSite) :
CBaseRootSurface(pContext, pSite),
m_bWindrawOpened(FALSE),
m_bWindrawCapsOpened(FALSE),
m_bBltLock(FALSE),
m_pScratchSurface(0),
m_nScratchSurfaceCID(0),
m_bScratchSurfaceCreated(FALSE),
m_bShowingText(FALSE),
m_hBrush(0),
m_hPen(0),
m_textColor(0),
m_nTextBackgroundColor(0),
m_hFont(0),
m_hOldFont(0),
m_hLastClipper(0),
m_pErrMsg(NULL),
m_pYUVScratchBits(NULL)
{
memset( &m_windraw, 0, sizeof( m_windraw) );
memset( &m_windrawCaps, 0, sizeof( m_windrawCaps) );
memset( &m_compositionSurface, 0, sizeof( m_compositionSurface) );
}
CWinBaseRootSurface::~CWinBaseRootSurface()
{
_DestroyCompositionSurface();
#ifdef _WORKAROUND_YUV_RGB_16BIT_HXCOLOR_BUG
DestroyScratchSurface();
#endif /*_WORKAROUND_YUV_RGB_16BIT_HXCOLOR_BUG*/
if (m_bWindrawOpened)
{
m_overlayMgr.RemoveAll();
WinDraw2_Close(&m_windraw);
m_bWindrawOpened = FALSE;
}
if (m_bWindrawCapsOpened)
{
WinDraw2_Close(&m_windrawCaps);
m_bWindrawCapsOpened = FALSE;
}
HX_RELEASE(m_pErrMsg);
}
static void OpenDDPBD()
{
HKEY hKey;
long lSize = _MAX_PATH-1;
char szDBFileName[_MAX_PATH]; /* Flawfinder: ignore */
const char* szKeyName = "Software\\"HXVER_COMMUNITY"\\Preferences\\DT_Plugins";
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szKeyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
/* retrieve path name: */
memset(szDBFileName, 0, _MAX_PATH);
if (RegQueryValue(hKey, "", szDBFileName, &lSize) == ERROR_SUCCESS) {
/* convert it at a string: */
SafeStrCat(szDBFileName, "\\pvdu3260.bin", _MAX_PATH);
/*
* Open Database file to check for buggy video drivers
* If the file has not changed since the last time we read this
* information, this call is basically a NO-OP
*/
DDPDB_Open(szDBFileName);
}
/* close hKey: */
RegCloseKey(hKey);
}
}
HX_RESULT CWinBaseRootSurface::_DebugBlt(UCHAR* /*IN*/ pImageData,
HXBitmapInfoHeader* /*IN*/ pBitmapInfo,
REF(HXxRect) /*IN*/ rDestRect,
REF(HXxRect) /*IN*/ rSrcRect)
{
if (m_pSite)
{
HXxWindow* pWindow = m_pSite->GetWindow();
if (pWindow && pWindow->window)
{
HWND hwnd = (HWND) pWindow->window;
HDC hDC = GetDC(hwnd);
HBRUSH hBrush = CreateSolidBrush(0x00008000);
HPEN hPen = CreatePen(PS_SOLID, 1, 0x00FF0000);
HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
HPEN hOldPen = (HPEN)SelectObject(hDC, hPen);
Rectangle(hDC,rDestRect.left,rDestRect.top,rDestRect.right,rDestRect.bottom);
SelectObject(hDC,hOldBrush);
SelectObject(hDC,hOldPen);
DeleteObject(hBrush);
DeleteObject(hPen);
ReleaseDC(hwnd, hDC);
}
}
return HXR_OK;
}
void CWinBaseRootSurface::_GetYUVScratchWidthHeight(UINT32* pWidth, UINT32* pHeight)
{
*pWidth = m_YUVScratchbmi.bmiHeader.biWidth;
*pHeight = m_YUVScratchbmi.bmiHeader.biHeight;
}
void CWinBaseRootSurface::_CreateYUVScratchSurface(UINT32 width, UINT32 height)
{
HX_VECTOR_DELETE(m_pYUVScratchBits);
m_pYUVScratchBits = NULL;
memset(&m_YUVScratchbmi, 0, sizeof(BITMAPINFO));
if (MakeBitmap(&m_YUVScratchbmi, sizeof(BITMAPINFO), 0, width, height, NULL, NULL))
{
m_pYUVScratchBits = new UCHAR[m_YUVScratchbmi.bmiHeader.biSizeImage];
m_nYUVPitch = GetBitmapPitch(&m_YUVScratchbmi);
}
}
void CWinBaseRootSurface::_GetYUVScratchSurfacePointer(UCHAR** pYUVBits, INT32* YUVPitch)
{
*pYUVBits = m_pYUVScratchBits;
*YUVPitch = m_nYUVPitch;
}
void CWinBaseRootSurface::_BltFromScratchToComposition(REF(HXxRect) rDestRect, REF(HXxRect) rSrcRect)
{
WinDrawSurface_Unlock(&m_windraw, &m_compositionSurface, 0);
WinDrawSurface_BltIndirect(&m_windraw, &m_compositionSurface, &m_scratchSurface, (RECT*)&rDestRect, (RECT*)&rSrcRect);
WinDrawSurface_Lock(&m_windraw, &m_compositionSurface, 0,
(void**) &m_pCompositionSurface, (LONG*)&m_nCompositionPitch);
}
HX_RESULT CWinBaseRootSurface::_LockComposition(UCHAR** pBits, INT32* pPitch)
{
if (NOERROR == WinDrawSurface_Lock(&m_windraw, &m_compositionSurface, 0,
(void**) pBits, (LONG*)pPitch))
{
return HXR_OK;
}
return HXR_FAIL;
}
HX_RESULT CWinBaseRootSurface::OpenWindraw()
{
HX_RESULT retVal = HXR_FAIL;
if (m_bWindrawOpened)
{
return HXR_OK;
}
OpenDDPBD();
if (m_pSite)
{
if (!m_pErrMsg)
m_pContext->QueryInterface(IID_IHXErrorMessages, (void**)&m_pErrMsg);
HXxWindow* pWindow = m_pSite->GetWindow();
if (pWindow && pWindow->window)
{
memset(&m_windraw, 0, sizeof(WINDRAW));
HRESULT failed = TRUE;
if (m_fSurfaceType & HX_ACCELERATION_ON)
{
failed = WinDraw2_Open(&m_windraw, (HWND) pWindow->window, WINDRAW_DIRECTDRAW, NULL, NULL);
// do any required cleanup
if (failed)
{
WinDraw2_Close(&m_windraw);
}
else
{
// Store the accelerated windraw
m_windrawCaps = m_windraw;
m_windraw.pErrMsg = m_pErrMsg;
WinDraw2_GetMonitorProperties(&m_windraw);
}
}
/* go to GDI mode */
if (failed)
{
m_fSurfaceType &= ~HX_ACCELERATION_ON;
m_fSurfaceType &= ~HX_USE_VIDEO_MEMORY;
m_fSurfaceType &= ~HX_USE_SYSTEM_MEMORY;
failed = WinDraw2_Open(&m_windraw, (HWND) pWindow->window, NULL, NULL, NULL);
}
if (!failed)
{
retVal = HXR_OK;
m_bWindrawOpened = TRUE;
}
}
}
return retVal;
}
void CWinBaseRootSurface::_MinimalBlt(HXxRect& src, HXxRect& dst)
{
}
HX_RESULT CWinBaseRootSurface::_CreateCompositionSurface()
{
HX_RESULT retVal = HXR_FAIL;
OpenWindraw();
if (m_bCompositionSurfaceCreated)
{
return HXR_OK;
}
if (!m_bWindrawOpened)
{
return retVal;
}
// Can we restore hw acceleratoin (don't do it during a video surface switch)
if((m_fSurfaceType & HX_ACCELERATION_ON) == HX_ACCELERATION_ON)
{
if(!_IsHardwareAccelerationAvail())
{
_LoseHardwareAcceleration();
return HXR_OK;
}
}
else if( m_bWindrawCapsOpened )
{
if( _IsHardwareAccelerationAvail() )
_AcquireHardwareAcceleration();
return HXR_OK;
}
// get primary surface CID.
BMI primaryBMI;
memset(&primaryBMI, 0, sizeof(BMI));
WinDraw2_GetDisplayFormat(&m_windraw, &primaryBMI);
m_nCompositionSurfaceCID = GetBitmapColor((LPBITMAPINFO)&primaryBMI);
// create a BMI to describe the composition surface
memset(&primaryBMI, 0, sizeof(BMI));
memcpy(&m_compositionSize, &m_pSite->m_size, sizeof(HXxSize)); /* Flawfinder: ignore */
// find out how big we want to allocate.
if (m_pSite->IsFullScreen())
{
m_allocatedCompositionSize.cx = GetSystemMetrics(SM_CXSCREEN);
m_allocatedCompositionSize.cy = GetSystemMetrics(SM_CYSCREEN);
}
else
{
m_allocatedCompositionSize.cx = m_compositionSize.cx;
m_allocatedCompositionSize.cy = m_compositionSize.cy;
}
if (m_compositionSize.cx > m_allocatedCompositionSize.cx || m_compositionSize.cy > m_allocatedCompositionSize.cy)
{
m_allocatedCompositionSize.cx = m_compositionSize.cx;
m_allocatedCompositionSize.cy = m_compositionSize.cy;
}
MakeBitmap((LPBITMAPINFO)&primaryBMI, sizeof(BMI), m_nCompositionSurfaceCID, m_allocatedCompositionSize.cx, m_allocatedCompositionSize.cy, NULL, NULL);
// now attempt to create the surface
memset(&m_compositionSurface, 0, sizeof(WINDRAWSURFACE));
/*
* Now are we in 8 bit color mode? If so we will need to make a palette.
*/
if (m_nCompositionSurfaceCID == CID_RGB8)
{
HDC hDC;
int n = 0;
hDC = GetDC (NULL);
n = GetSystemPaletteEntries (hDC, 0, 256, (LPPALETTEENTRY) primaryBMI.dwPalette);
ReleaseDC (NULL,hDC);
}
if (NOERROR == WinDraw2_CreateSurface(&m_windraw, &m_compositionSurface, &primaryBMI, m_fSurfaceType, 0, 0))
{
retVal = HXR_OK;
m_bCompositionSurfaceCreated = TRUE;
}
primaryBMI.bmiHeader.biWidth = 1;
primaryBMI.bmiHeader.biHeight = 1;
return retVal;
}
HX_RESULT CWinBaseRootSurface::_DestroyCompositionSurface()
{
HX_RESULT retVal = HXR_OK;
if (m_bCompositionSurfaceCreated)
{
if (NOERROR == WinDraw2_ReleaseSurface(&m_windraw, &m_compositionSurface))
{
m_bCompositionSurfaceCreated = FALSE;
retVal = HXR_OK;
}
else
{
retVal = HXR_FAIL;
}
}
return retVal;
}
HX_RESULT CWinBaseRootSurface::_MinimalUnlock(HXxWindow* pWindow)
{
if( m_pSite->IsCompositionLocked() )
{
#if 0
if (m_pUnlockingSite && m_pUnlockingSite->HasFocusRect())
{
DrawFocusRect(&m_compositionSurface,
m_nCompositionSurfaceCID,
&m_allocatedCompositionSize,
m_pCompositionSurface,
m_pUnlockingSite);
}
#endif
WinDrawSurface_Unlock(&m_windraw, &m_compositionSurface, 0);
return HXR_OK;
}
#if 0
if (m_pUnlockingSite && m_pUnlockingSite->HasFocusRect())
{
DrawFocusRect(&m_compositionSurface,
m_nCompositionSurfaceCID,
&m_allocatedCompositionSize,
m_pCompositionSurface,
m_pUnlockingSite);
}
#endif
HX_RESULT retVal = HXR_FAIL;
if (NOERROR == WinDrawSurface_Unlock(&m_windraw, &m_compositionSurface, 0))
{
m_pCompositionSurface = NULL;
if (!m_bBltLock)
{
// Assuming that no windowed renderer uses video services this will work.
// Should fix this so that windowed renderers can use video services.
/*
if (m_hLastClipper != (HWND) pWindow->window)
{
m_hLastClipper = (HWND) pWindow->window;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -