📄 windraw2.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 ***** */
/* for MS VC++ 6.0, pntypes needs to be included before windows include files */
#include "hxtypes.h"
#include "hxcom.h"
#include "hxwintyp.h"
#include "hxvsurf.h"
#include "hxassert.h"
#include "hxthread.h"
#include "hxtick.h"
#include "dllpath.h"
#include "hxerror.h"
#include "hxstrutl.h"
/* Windows include files: */
#include <windows.h>
#include "ddraw.h"
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>
/* standard libraries: */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include "hxcom.h"
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
/* our stuff:*/
#include "hxcolor.h"
#include "colormap.h"
#include "windraw2.h"
#include "ddpdb.h" /* DirectDraw profiles database */
/* DirectDraw profile: */
static LPDDDEVICEPROFILE lpddprofDirectDrawProfile = NULL;
//#define _CHECK_PERFORMANCE
//#define _REMOVE_WINDRAW_CLIPPER
// Exception handler mutex
static CRITICAL_SECTION g_ehandlerMutex;
static INT32 g_ehandlerMutexCnt = 0;
static INT32 g_ehandlerSilent = 1;
static INT32 g_ehandlerCount = 0;
#include "hxmap.h"
typedef void (HXEXPORT_PTR INITCOLORCONVERTERFN)();
typedef int (HXEXPORT_PTR SETRGB8PALETTEFN) (int,UINT32*,int*);
INITCOLORCONVERTERFN pfInitColorConverter = 0;
SETRGB8PALETTEFN pfSetRGB8Palette = 0;
HMODULE z_hHxColor = 0;
struct CEnumDisplaySetting
{
CEnumDisplaySetting();
~CEnumDisplaySetting();
CHXMapStringToOb m_Settings;
void GetSettings(CHXSimpleList* pList);
};
CEnumDisplaySetting::CEnumDisplaySetting()
{
DEVMODE modeDesc;
DWORD index = 0;
char buffer[64]; /* Flawfinder: ignore */
while(EnumDisplaySettings(0, index, &modeDesc))
{
sprintf(buffer, "%dx%dx%d", modeDesc.dmPelsWidth, modeDesc.dmPelsHeight, modeDesc.dmBitsPerPel); /* Flawfinder: ignore */
void* ptemp;
if (!m_Settings.Lookup(buffer, ptemp))
{
CModesDesc* pDesc = new CModesDesc;
pDesc->m_nWidth = modeDesc.dmPelsWidth;
pDesc->m_nHeight = modeDesc.dmPelsHeight;
pDesc->m_nBitCount = modeDesc.dmBitsPerPel;
m_Settings.SetAt(buffer, pDesc);
}
index++;
}
}
CEnumDisplaySetting::~CEnumDisplaySetting()
{
CHXMapStringToOb::Iterator ndx = m_Settings.Begin();
for(; ndx != m_Settings.End(); ++ndx)
{
CModesDesc* pDesc = (CModesDesc*) (*ndx);
delete pDesc;
}
m_Settings.RemoveAll();
}
void CEnumDisplaySetting::GetSettings(CHXSimpleList* pList)
{
CHXMapStringToOb::Iterator i;
i = m_Settings.Begin();
for(; i!= m_Settings.End(); ++i)
{
CModesDesc* pOldDesc = (CModesDesc*) *i;
CModesDesc* pNewDesc = new CModesDesc;
pNewDesc->m_nWidth = pOldDesc->m_nWidth;
pNewDesc->m_nHeight = pOldDesc->m_nHeight;
pNewDesc->m_nBitCount = pOldDesc->m_nBitCount;
pList->AddTail(pNewDesc);
}
}
CEnumDisplaySetting zm_DisplaySettings;
/***************************************
*
* Routines for using DirectDraw on a multimonitor system
*
*/
/* DDRAW.H might not include these: */
#ifndef DDENUM_ATTACHEDSECONDARYDEVICES
#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001L
#endif
#if DIRECTDRAW_VERSION <= 0x0500
typedef BOOL (FAR PASCAL * LPDDENUMCALLBACKEXA) (GUID FAR *, LPSTR, LPSTR, LPVOID, HANDLE);
typedef HRESULT (WINAPI * LPDIRECTDRAWENUMERATEEXA) ( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
#define HMONITOR HANDLE
#endif
typedef HRESULT (*PDRAWCREATE) (IID *,LPDIRECTDRAW *,LPUNKNOWN);
typedef HRESULT (*PDRAWENUM) (LPDDENUMCALLBACKA, LPVOID);
/*
* FindDeviceCallback functions:
*/
typedef struct
{
LPSTR lpszDevice;
GUID* lpGUID;
GUID GUID;
BOOL fFound;
} FINDDEVICEDATA;
static BOOL CALLBACK FindDeviceCallback (GUID* lpGUID, LPSTR lpszName,
LPSTR lpszDevice, LPVOID lParam)
{
FINDDEVICEDATA *p = (FINDDEVICEDATA*) lParam;
if (lstrcmpiA (p->lpszDevice, lpszDevice) == 0) {
if (lpGUID) {
p->GUID = *lpGUID;
p->lpGUID = &p->GUID;
} else
p->lpGUID = NULL;
p->fFound = TRUE;
return FALSE;
}
return TRUE;
}
static BOOL CALLBACK FindDeviceCallbackEx (GUID* lpGUID, LPSTR lpszName,
LPSTR lpszDevice, LPVOID lParam, HMONITOR hMonitor)
{
FINDDEVICEDATA *p = (FINDDEVICEDATA*) lParam;
if (lstrcmpiA (p->lpszDevice, lpszDevice) == 0) {
if (lpGUID) {
p->GUID = *lpGUID;
p->lpGUID = &p->GUID;
} else
p->lpGUID = NULL;
p->fFound = TRUE;
return FALSE;
}
return TRUE;
}
HRESULT WINAPI EnumSurfacesCallback(LPDIRECTDRAWSURFACE lpDDSurface,
LPDDSURFACEDESC lpDDSurfaceDesc,
LPVOID pSurface)
{
LPDIRECTDRAWSURFACE *lpSurf = (LPDIRECTDRAWSURFACE*)pSurface;
if (lpDDSurface)
{
*lpSurf = lpDDSurface;
lpDDSurface->Release();
}
return DDENUMRET_OK;
}
/*
* DirectDrawCreateFromDevice
*
* create a DirectDraw object for a particular device
*/
static IDirectDraw * DirectDrawCreateFromDevice (LPSTR lpszDevice,
PDRAWCREATE DirectDrawCreateP, PDRAWENUM DirectDrawEnumerateP)
{
IDirectDraw *pdd = NULL;
/* check if device name is specified: */
if (lpszDevice != NULL) {
/* try to find device with a given name: */
FINDDEVICEDATA find;
find.lpszDevice = lpszDevice;
find.fFound = FALSE;
DirectDrawEnumerateP (FindDeviceCallback, (LPVOID)&find);
/* check if found: */
if (find.fFound) {
/* In 4bpp mode the following DDraw call causes a
* message box to be popped up by DDraw (!?!).
* It's DDraw's fault, but we don't like it.
* So we make sure it doesn't happen. */
UINT ErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS);
DirectDrawCreateP (find.lpGUID, &pdd, NULL);
SetErrorMode (ErrorMode);
}
} else
DirectDrawCreateP (NULL, &pdd, NULL);
/* return whatever we have found: */
return pdd;
}
/*
* DirectDrawCreateFromDeviceEx
*
* create a DirectDraw object for a particular device
*/
static IDirectDraw * DirectDrawCreateFromDeviceEx (LPSTR lpszDevice, PDRAWCREATE DirectDrawCreateP, LPDIRECTDRAWENUMERATEEXA DirectDrawEnumerateExP)
{
IDirectDraw *pdd = NULL;
/* check if device name is specified: */
if (lpszDevice != NULL) {
/* try to find device with a given name: */
FINDDEVICEDATA find;
find.lpszDevice = lpszDevice;
find.fFound = FALSE;
DirectDrawEnumerateExP (FindDeviceCallbackEx, (LPVOID)&find, DDENUM_ATTACHEDSECONDARYDEVICES);
/* check if found: */
if (find.fFound) {
/* In 4bpp mode the following DDraw call causes a
* message box to be popped up by DDraw (!?!).
* It's DDraw's fault, but we don't like it.
* So we make sure it doesn't happen. */
UINT ErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS);
DirectDrawCreateP (find.lpGUID, &pdd, NULL);
SetErrorMode (ErrorMode);
}
} else
DirectDrawCreateP (NULL, &pdd, NULL);
/* return whatever we have found: */
return pdd;
}
/***************************************
*
* Routines for dynamic loading and unloading of the DirectDraw library.
*
*/
typedef DWORD (WINAPI *PGETFILEVERSIONINFOSIZE) (LPTSTR,LPDWORD);
typedef BOOL (WINAPI *PGETFILEVERSIONINFO) (LPTSTR,DWORD,DWORD,LPVOID);
typedef BOOL (WINAPI *PVERQUERYVALUE) (LPVOID,LPTSTR,LPVOID,PUINT);
/* forward prototypes: */
HRESULT LockSurface(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, DDSURFACEDESC *pddsd, BOOL bBlock=TRUE);
HRESULT IsFlipDone(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds, ENUMSURFACE* lpSurfEnum, BOOL bBlock=TRUE);
HRESULT IsFrontBuffer(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds, ENUMSURFACE* lpSurfEnum, BOOL bBlock=TRUE);
HRESULT RestoreSurfaces(LPWINDRAW lpwd, LPWINDRAWSURFACE lpSurface);
HRESULT LoadDirectDraw (LPSTR lpszDevice, LPDIRECTDRAW *ppDirectDraw, HINSTANCE *phDirectDraw);
void ReleaseDirectDraw (LPDIRECTDRAW *ppDirectDraw, LPDIRECTDRAW2 *ppDirectDraw2, HINSTANCE *phDirectDraw);
void DumpDDInfo(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, char *pFunction);
/*
* We can't be sure that DirectDraw is always available
* so we can't statically link to the library.
* Therefore we load the library, get the function entry
* point addresses and call them to create the driver objects.
* We return S_OK if we manage to load DirectDraw correctly
* otherwise we return E_NOINTERFACE
* We initialise a DirectDraw instance by explicitely loading
* the library and calling GetProcAddress on the DirectDrawCreate
* entry point that it exports
*
* On a multi monitor system, we can get the DirectDraw object
* for any monitor (device) with the optional lpszDevice parameter
*/
static HRESULT LoadDirectDraw (LPSTR lpszDevice,
LPDIRECTDRAW *ppDirectDraw, HINSTANCE *phDirectDraw)
{
UINT ErrorMode;
PDRAWCREATE pDrawCreate;
PDRAWENUM pDrawEnum;
LPDIRECTDRAWENUMERATEEXA pDrawEnumEx;
HRESULT hr = NOERROR;
/*
* Check the display mode if it is less than 8 bits do not call into direct draw.
*/
HDC hdc = GetDC(0);
int bpp = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(0, hdc);
if (bpp < 8)
{
*ppDirectDraw = 0;
return E_NOINTERFACE; /* whatever */
}
/* is DirectDraw already loaded? */
if (*ppDirectDraw) {
/* ... */
return NOERROR;
}
/* make sure the library is available: */
ErrorMode = SetErrorMode (SEM_NOOPENFILEERRORBOX);
*phDirectDraw = LoadLibrary (TEXT ("DDRAW.DLL"));
SetErrorMode (ErrorMode);
if (*phDirectDraw == NULL) {
/* ... */
return E_NOINTERFACE;
}
/* get the DLL address for the creator function: */
pDrawCreate = (PDRAWCREATE) GetProcAddress (*phDirectDraw, "DirectDrawCreate");
/* force ANSI, we assume it: */
pDrawEnum = (PDRAWENUM) GetProcAddress (*phDirectDraw, "DirectDrawEnumerateA");
pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress (*phDirectDraw, "DirectDrawEnumerateExA");
/* we don't need DirectDrawEnumerateEx, that's just for multimon stuff: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -