Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
windraw2.cpp
Package: 142_61_thumb_advanced.rar [view]
Upload User: dangjiwu
Upload Date: 2013-07-19
Package Size: 42019k
Code Size: 169k
Category:
Symbian
Development Platform:
Visual C++
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: windraw2.cpp,v 1.19.10.1 2004/07/09 01:59:19 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (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.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * 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: */
- if (pDrawCreate == NULL || pDrawEnum == NULL) {
- /* ... */
- ReleaseDirectDraw (ppDirectDraw, NULL, phDirectDraw);
- return E_NOINTERFACE;
- }
- /* create a DirectDraw display provider for this device,
- * using the fancy multimon-aware version, if it exists: */
- if (pDrawEnumEx)
- *ppDirectDraw = DirectDrawCreateFromDeviceEx (lpszDevice, pDrawCreate, pDrawEnumEx);
- else
- *ppDirectDraw = DirectDrawCreateFromDevice (lpszDevice, pDrawCreate, pDrawEnum);
- if (*ppDirectDraw == NULL)
- {
- ReleaseDirectDraw (ppDirectDraw, NULL, phDirectDraw);
- return E_NOINTERFACE;
- }
- return NOERROR;
- }
- /*
- * Called to release any DirectDraw provider we previously loaded.
- * We may be called at any time especially when something goes
- * horribly wrong and when we need to clean up before returning
- * so we can't guarantee that all state variables are consistent
- * so free only those really allocated. This should only be called
- * once all the reference counts have been released.
- */
- void ReleaseDirectDraw (LPDIRECTDRAW *ppDirectDraw, LPDIRECTDRAW2 *ppDirectDraw2, HINSTANCE *phDirectDraw)
- {
- /* release any DirectDraw provider interface: */
- if (ppDirectDraw && *ppDirectDraw) {
- IDirectDraw_Release (*ppDirectDraw);
- *ppDirectDraw = NULL;
- }
- if (ppDirectDraw2 && *ppDirectDraw2)
- {
- (*ppDirectDraw2)->Release();
- *ppDirectDraw2 = NULL;
- }
- /* decrement module load count: */
- if (*phDirectDraw) {
- FreeLibrary (*phDirectDraw);
- *phDirectDraw = NULL;
- }
- }
- #if 0
- /*
- * Are we running on Direct Draw version 1? We need to find out as
- * we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
- * find out, we simply see if it supports IDirectDraw2. Only version 2 and
- * higher support this.
- */
- BOOL IsDirectDrawVersion1 (LPDIRECTDRAW pDirectDraw)
- {
- IDirectDraw2 *p;
- HRESULT hr;
- /* check if DirectDraw is available: */
- if (pDirectDraw == NULL)
- return FALSE;
- /* query and release interface: */
- p = NULL;
- hr = IDirectDraw_QueryInterface(pDirectDraw, IID_IDirectDraw2, (void *)&p);
- if (p)
- IDirectDraw2_Release (p);
- /* returns TRUE, if !IDrectDraw2; FALSE otherwise */
- return hr != NOERROR;
- }
- #endif
- /***************************************
- *
- * Routines for using GDI on a multimonitor system
- *
- */
- /*
- * Get display DC.
- * Use:
- * HDC GetDisplayDC (LPSTR lpszDevice)
- * Input:
- * lpszDevice - device name to use (in a multimonitor system)
- * Returns:
- * NULL, if error; !NULL - display device DC.
- */
- static HDC GetDisplayDC (LPSTR lpszDevice)
- {
- HDC hdcDisplay;
- /* get a DC on the right monitor - it's ugly, but this is the way
- * you have to do it */
- if (lpszDevice == NULL || lstrcmpiA (lpszDevice, "DISPLAY") == 0)
- hdcDisplay = CreateDCA ("DISPLAY", NULL, NULL, NULL);
- else
- hdcDisplay = CreateDCA (NULL, lpszDevice, NULL, NULL);
- return hdcDisplay;
- }
- /*
- * Get pixel format for a given device context.
- * Use:
- * HRESULT GetDeviceFormat (HDC hDC, LPBMI lpbmi);
- * Input:
- * hDC - device context to query
- * lpbmi - pointer to a bitmapinfo structure to initialize
- * Returns:
- * NOERROR, if success, E_FAIL otherwise.
- */
- static HRESULT GetDeviceFormat (HDC hDC, LPBMI lpbmi)
- {
- HBITMAP hBM;
- /* initialize the bitmapinfo structure: */
- memset (lpbmi, 0, sizeof (BMI));
- lpbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
- lpbmi->bmiHeader.biBitCount = 0;
- /* retrieve display format parameters: */
- hBM = CreateCompatibleBitmap (hDC,1,1);
- GetDIBits (hDC,hBM,0,1,NULL, (BITMAPINFO *)& (lpbmi->bmiHeader),DIB_RGB_COLORS);
- /* this call will get the color table or the proper bitfields */
- GetDIBits (hDC,hBM,0,1,NULL, (BITMAPINFO *)& (lpbmi->bmiHeader),DIB_RGB_COLORS);
- DeleteObject (hBM);
- /* check the validity of the format & exit: */
- return CheckBitmap ((BITMAPINFO *)& (lpbmi->bmiHeader))? NOERROR: E_FAIL;
- }
- /*
- * Retrieves display pixel format. This is normally called
- * when we receive WM_DEVMODECHANGED device change messages.
- *
- * The optional szDevice parameter tells us which monitor we are interested
- * in for a multi monitor system.
- *
- * The calling program mush use global syncronization objects to prevent
- * re-entering this code.
- */
- static HRESULT GetDisplayFormat (LPBMI lpbmi, LPSTR lpszDevice)
- {
- HDC hdcDisplay;
- HRESULT hr;
- /* get a DC of a given monitor: */
- if ((hdcDisplay = GetDisplayDC (lpszDevice)) == NULL)
- return E_FAIL;
- /* retrieve display format parameters: */
- hr = GetDeviceFormat (hdcDisplay, lpbmi);
- /* delete hdcDisplay & exit: */
- DeleteDC (hdcDisplay);
- return hr;
- }
- /*
- * Generates the "standard" WinDraw palette.
- * Since we will have to deal with multiple datatypes, each having
- * its own combination of colors, what we really need is some "uniform"
- * palette, we could use to render all these objects with minimum loss
- * of quality.
- * This function generates so-called 6x6x6-color palette that contains
- * all possible combinations of 6 uniformly-displaced values for each
- * color component (R, G, and B). To avoid interference with Windows
- * system palette (first and last 10 entries in the palette), we will
- * insert our colors in 10..225 range, and mark them as non-collapsable
- * in hope to boost the performance (ideally, this should prevent GDI
- * from compressing the palette, and eliminate extra mapping).
- */
- static HRESULT CreateDefaultPalette (LPPALETTEENTRY lppe,
- int *pnLoColor, int *pnHiColor, LPSTR lpszDevice)
- {
- HDC hdc;
- HRESULT hr = E_FAIL;
- unsigned int i, r, g, b;
- /* get a DC of a given monitor: */
- if ((hdc = GetDisplayDC (lpszDevice)) != NULL) {
- /* apparently some displays have odd numbers of system colors: */
- if (GetDeviceCaps (hdc, NUMRESERVED) == 20) {
- /* retrieve system colors: */
- memset (lppe, 0, 256 * sizeof (RGBQUAD));
- GetSystemPaletteEntries (hdc, 0, 10, lppe);
- GetSystemPaletteEntries (hdc, 246, 10, lppe + 246);
- /* generate 6x6x6 (~2.58 bits/channel) palette: */
- i = 10;
- for (b = 0; b <= 0xFF; b += 0x33)
- for (g = 0; g <= 0xFF; g += 0x33)
- for (r = 0; r <= 0xFF; r += 0x33) {
- /* create a palette entry: */
- lppe [i].peGreen = g;
- lppe [i].peBlue = b;
- lppe [i].peRed = r;
- lppe [i].peFlags = PC_NOCOLLAPSE; /* !!! */
- i ++;
- }
- /* store the range of our colors: */
- *pnLoColor = 10;
- *pnHiColor = i;
- hr = NOERROR;
- }
- DeleteDC (hdc);
- }
- return hr;
- }
- char*
- CollectDDInfo(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, char *pFunction, char* pSeparator)
- {
- char* pszDDInfo = NULL;
- CHXString pDDInfo;
- char szTemp[MAX_DISPLAY_NAME]; /* Flawfinder: ignore */
- char szTmp[MAX_DISPLAY_NAME]; /* Flawfinder: ignore */
- // write date and time of log
- SYSTEMTIME time;
- memset(&time, 0, sizeof(time));
- GetSystemTime(&time);
- GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &time, "ddd',' MMM dd yyyy, ", szTmp, sizeof(szTmp));
- SafeSprintf(szTemp, MAX_DISPLAY_NAME, "nLog Entry: %s", szTmp);
- pDDInfo = szTemp;
- GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &time, "hh:mm:ss tt", szTmp, sizeof(szTmp));
- SafeSprintf(szTemp, MAX_DISPLAY_NAME, "%s%s", szTmp, pSeparator);
- pDDInfo += szTemp;
- // write systime members
- SafeSprintf(szTemp, MAX_DISPLAY_NAME, "Systime: %d %d %d %d %d %d %d %d%s",
- time.wYear, time.wMonth, time.wDayOfWeek, time.wDay,
- time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, pSeparator);
- pDDInfo += szTemp;
- // write function that caused fault
- SafeSprintf(szTemp, MAX_DISPLAY_NAME, "Function: %s%s", pFunction, pSeparator);
- pDDInfo += szTemp;
- // write OS version
- OSVERSIONINFO ver;
- memset(&ver, 0, sizeof(ver));
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- SafeSprintf(szTemp, MAX_DISPLAY_NAME,
- "OS MajorVersion: %ld MinorVersion: %ld BuildNum: %ld PlatformId: %ld Build: %s%s",
- ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, ver.dwPlatformId, ver.szCSDVersion, pSeparator);
- pDDInfo += szTemp;
- // write processor info
- SYSTEM_INFO sysinfo;
- memset(&sysinfo, 0, sizeof(sysinfo));
- GetSystemInfo(&sysinfo);
- SafeSprintf(szTemp, MAX_DISPLAY_NAME, "Processor Type: %ld Level: %ld Revision: %ld Count: %ld%s",
- sysinfo.dwProcessorType,
- sysinfo.wProcessorLevel,
- sysinfo.wProcessorRevision,
- sysinfo.dwNumberOfProcessors,
- pSeparator);
- pDDInfo += szTemp;
- // write DD version
- TCHAR szVersion[256] = __TEXT(""); /* Flawfinder: ignore */
- HKEY hKey = 0;
- RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- __TEXT("Software\Microsoft\DirectX"),
- 0, KEY_READ, &hKey);
- if (hKey)
- {
- DWORD dwType = REG_SZ;
- DWORD dwSize = sizeof(szVersion);
- RegQueryValueEx(hKey, __TEXT("Version"), NULL, &dwType, (BYTE*)szVersion, &dwSize);
- RegCloseKey(hKey);
- }
- SafeSprintf(szTemp, MAX_DISPLAY_NAME, "DirectDraw Version %s%s", szVersion, pSeparator);
- pDDInfo += szTemp;
- if (lpSurface)
- {
- // Get DD4* from the surface
- void* pVoid = NULL;
- IDirectDrawSurface2* lpSurface2 = NULL;
- #if DIRECTDRAW_VERSION > 0x0500
- IDirectDraw4* pDD4 = NULL;
- IDirectDraw* pDD = NULL;
- #endif //DIRECTDRAW_VERSION > 0x0500
- DDDEVICEIDENTIFIER ddID;
- memset(&ddID, 0, sizeof(ddID));
- lpSurface->QueryInterface(IID_IDirectDrawSurface2, (void**)&lpSurface2);
- if (lpSurface2)
- {
- lpSurface2->GetDDInterface(&pVoid);
- lpSurface2->Release();
- }
- #if DIRECTDRAW_VERSION > 0x0500
- if (pVoid)
- ((IUnknown*)pVoid)->QueryInterface(IID_IDirectDraw, (void**)&pDD);
- if (pDD)
- {
- pDD->QueryInterface(IID_IDirectDraw4, (void **)&pDD4);
- pDD->Release();
- }
- // Query for the driver descripton
- if (pDD4)
- {
- pDD4->GetDeviceIdentifier(&ddID, DDGDI_GETHOSTIDENTIFIER);
- pDD4->Release();
- }
- // DD4 not supportted (probably NT4)...use more drastic measures
- else
- #endif //DIRECTDRAW_VERSION > 0x0500
- {
- // Check if we are runnning NT
- OSVERSIONINFO osVersion;
- memset(&osVersion,0, sizeof(OSVERSIONINFO));
- osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (GetVersionEx(&osVersion) && osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- char szChipType[MAXCHIPTYPE]; /* Flawfinder: ignore */
- // Try to get WinNT device information
- GetWinNTDeviceID (&ddID, szChipType);
- }
- }
- // write DD driver
- unsigned short data4 = ddID.guidDeviceIdentifier.Data4[0]<<8 |
- ddID.guidDeviceIdentifier.Data4[1];
- unsigned long data5 = ddID.guidDeviceIdentifier.Data4[2]<<24 |
- ddID.guidDeviceIdentifier.Data4[3]<<16 |
- ddID.guidDeviceIdentifier.Data4[4]<<8 |
- ddID.guidDeviceIdentifier.Data4[5];
- unsigned short data6 = ddID.guidDeviceIdentifier.Data4[6]<<8 |
- ddID.guidDeviceIdentifier.Data4[7];
- SafeSprintf(szTemp, MAX_DISPLAY_NAME,
- "DirectDraw Driver: %s VendorID: %ld GUID {""%lx-%x-%x-%x-%lx%x""}%s",
- ddID.szDescription,
- ddID.dwVendorId,
- ddID.guidDeviceIdentifier.Data1,
- ddID.guidDeviceIdentifier.Data2,
- ddID.guidDeviceIdentifier.Data3,
- data4,
- data5,
- data6,
- pSeparator);
- pDDInfo += szTemp;
- // write display properties
- DDSURFACEDESC ddsd;
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- lpSurface->GetSurfaceDesc(&ddsd);
- char fourCC[5] = {(char)(ddsd.ddpfPixelFormat.dwFourCC & 0x000000FF), /* Flawfinder: ignore */
- ((char)(ddsd.ddpfPixelFormat.dwFourCC & 0x0000FF00)>>8),
- ((char)(ddsd.ddpfPixelFormat.dwFourCC & 0x00FF0000)>>16),
- (char)(ddsd.ddpfPixelFormat.dwFourCC>>24),
- ''};
- SafeSprintf(szTemp, MAX_DISPLAY_NAME,
- "DisplayMode: %s %s BackBuffers: %ld Width: %ld Height: %ld%s",
- (ddsd.ddsCaps.dwCaps & DDSCAPS_OVERLAY) ? "Overlay" : "Offscreen",
- fourCC,
- (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) ? ddsd.dwBackBufferCount : 0,
- ddsd.dwWidth,
- ddsd.dwHeight,
- pSeparator);
- pDDInfo += szTemp;
- }
- BMI bmi;
- memset(&bmi, 0, sizeof(bmi));
- GetDisplayFormat(&bmi, NULL);
- // write monitor properties
- SafeSprintf(szTemp, MAX_DISPLAY_NAME,
- "Screen Width %ld Height %ld BPP: %ld%s",
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- bmi.bmiHeader.biBitCount,
- pSeparator);
- pDDInfo += szTemp;
- pszDDInfo = new char[pDDInfo.GetLength()+1];
- if (pszDDInfo)
- {
- strncpy(pszDDInfo, pDDInfo, pDDInfo.GetLength()+1);
- }
- return pszDDInfo;
- }
- void DumpDDInfo(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, char *pFunction)
- {
- // A DirectDraw exception occured...bad bad bad
- //HX_ASSERT(0);
- // Serialize access to ddinfo.txt
- if (g_ehandlerMutexCnt)
- EnterCriticalSection(&g_ehandlerMutex);
- // Write a file in the plugins dir
- char szPath[256]; /* Flawfinder: ignore */
- char szFilePerm[] = "r+";
- int nEntries = 1;
- char szTmp[MAX_DISPLAY_NAME]; /* Flawfinder: ignore */
- char* pszDDInfo = NULL;
- const char* pPath = NULL;
- pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
- SafeStrCpy(szPath, pPath, 256);
- SafeStrCat(szPath, "ddinfo.txt", 256);
- FILE *fp = fopen(szPath, "r"); /* Flawfinder: ignore */
- if (fp)
- {
- const int nMaxChars = 2048;
- int nMaxEntries = 50;
- // check log entry count
- fscanf(fp, "%s %d", szTmp, &nEntries);
- // Limit log file entries to nMaxEntries
- if (++nEntries > nMaxEntries)
- {
- char *pTime = NULL;
- SYSTEMTIME time;
- double dTime = 0;
- double dOldTime = 3000*8760; // 3000 A.D. in hours
- int nOldestOffset = 0;
- int nLoc = 0;
- char pBuffer[nMaxChars]; /* Flawfinder: ignore */
- memset(&time, 0, sizeof(time));
- // read first <cr>
- fgets(pBuffer, nMaxChars, fp);
- // Find the oldest entry if the file
- while (!feof(fp))
- {
- nLoc = ftell(fp);
- fgets(pBuffer, nMaxChars, fp);
- // Find start of date
- pTime = strstr(pBuffer, "Systime: ");
- if (pTime)
- {
- // Read systime values for this log entry
- pTime += 9;
- sscanf(pTime, "%d %d %d %d %d %d %d %d",
- &time.wYear, &time.wMonth, &time.wDayOfWeek,
- &time.wDay, &time.wHour, &time.wMinute,
- &time.wSecond, &time.wMilliseconds);
- // Change date to hours for comparison
- dTime = time.wYear*8760 +
- time.wMonth*720 +
- time.wDay*24 +
- time.wHour +
- time.wSecond/60.0 +
- time.wMilliseconds/60000.0;
- // Compare with the current oldest entry
- if (dTime < dOldTime)
- {
- dOldTime = dTime;
- nOldestOffset = nLoc;
- }
- }
- }
- // Remove oldest log entry: move contents of ddinfo to a temp file,
- // delete ddinfo.txt, ren. temp file to ddinfo.txt.
- pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN);
- SafeStrCpy(szTmp, pPath, 256);
- SafeStrCat(szTmp, "ddtemp.txt", 256);
- FILE *fpTemp = fopen(szTmp, "w"); /* Flawfinder: ignore */
- if (fpTemp)
- {
- fseek(fp, 0, SEEK_SET);
- while (!feof(fp))
- {
- nLoc = ftell(fp);
- if (fgets(pBuffer, nMaxChars, fp))
- {
- // Skip oldest entry
- if (nLoc != nOldestOffset)
- fputs(pBuffer, fpTemp);
- }
- }
- }
- fclose(fp);
- if (fpTemp)
- {
- fclose(fpTemp);
- DeleteFile(szPath);
- rename(szTmp, szPath);
- }
- nEntries = nMaxEntries;
- }
- else
- fclose(fp);
- }
- else
- {
- szFilePerm[0] = 'w';
- szFilePerm[1] = '';
- }
- fp = fopen(szPath, szFilePerm); /* Flawfinder: ignore */
- if (fp)
- {
- fseek(fp, 0, SEEK_SET);
- fprintf(fp, "%s%dt ", "Entries ", nEntries);
- fseek(fp, -1, SEEK_END);
- pszDDInfo = CollectDDInfo(lpwd, lpSurface, pFunction, "t");
- if (pszDDInfo)
- {
- fprintf(fp, "%s", pszDDInfo);
- }
- HX_VECTOR_DELETE(pszDDInfo);
- fclose(fp);
- }
- if (g_ehandlerCount < g_ehandlerSilent)
- {
- // Need to throw error
- if (lpwd && lpwd->pErrMsg)
- {
- lpwd->pErrMsg->Report(HXLOG_INFO, HXR_WINDRAW_EXCEPTION, 0,
- szPath, NULL);
- }
- }
- if (lpwd && lpwd->pErrMsg)
- InterlockedIncrement(&g_ehandlerCount);
- if (g_ehandlerMutexCnt)
- LeaveCriticalSection(&g_ehandlerMutex);
- }
- /*
- * Load system and/or bitmap palette.
- */
- static int nSystemColors = 0; /* !0 when system palette is loaded */
- static PALETTEENTRY SystemPalette [256];
- static RGBQUAD SystemPaletteRGB[256];
- static int SystemPaletteIndices [256];
- static int LoadPalette (LPWINDRAW lpwd)
- {
- HDC hDC;
- int i, n = 0;
- /* get system palette first: */
- if ((hDC = GetDC (NULL)) != NULL)
- {
- n = GetSystemPaletteEntries (hDC, 0, 256, SystemPalette);
- ReleaseDC (NULL,hDC);
- }
- /* check if system palette is loaded: */
- /* generate palette index: */
- for (i=0; i<n; i++)
- {
- SystemPaletteIndices[i] = i;
- SystemPaletteRGB[i].rgbBlue = SystemPalette[i].peBlue;
- SystemPaletteRGB[i].rgbGreen = SystemPalette[i].peGreen;
- SystemPaletteRGB[i].rgbRed = SystemPalette[i].peRed;
- SystemPaletteRGB[i].rgbReserved = 0;
- }
- /* update color conversion tables: */
- if (pfSetRGB8Palette)
- {
- (*pfSetRGB8Palette)(n, (unsigned long *)SystemPalette, SystemPaletteIndices);
- }
- /* indicate that palette is set: */
- nSystemColors = n;
- /* return # of colors loaded: */
- return n;
- }
- HRESULT CreateDirectDrawPalette (LPWINDRAW pwd, LPDIRECTDRAWSURFACE pSurface)
- {
- HRESULT ddrval = E_FAIL;
- if (!pSurface || !pwd)
- {
- return ddrval;
- }
- try
- {
- /* load system palette if necessary: */
- if (nSystemColors) {
- /* create DirectDraw palette object: */
- if ((ddrval = IDirectDraw_CreatePalette (pwd->dd.lpDD2, DDPCAPS_8BIT, SystemPalette, &(pwd->dd.lpDDPal), NULL)) == DD_OK)
- {
- /* check if we can attach palette to a primary surface: */
- if ((ddrval = IDirectDrawSurface_SetPalette (pSurface, pwd->dd.lpDDPal)) != DD_OK)
- {
- /* release it and return error code: */
- IDirectDrawPalette_Release (pwd->dd.lpDDPal);
- }
- }
- }
- }
- catch (...)
- {
- DumpDDInfo(pwd, pSurface, "CreateDirectDrawPalette");
- ddrval = E_FAIL;
- }
- return ddrval;
- }
- /*
- * Instructs color converters to use new destination palette:
- */
- static void SetColorConverterPalette (PALETTEENTRY *pPalette, int l, int h)
- {
- int i, palIdx [256];
- /* Instruct the color conversion library to use set of our
- * "standard" colors ( [l,h] range) from the logical palette: */
- for (i=l; i<h; i++) palIdx [i] = i;
- if (pfSetRGB8Palette)
- {
- (*pfSetRGB8Palette)(h-l, (ULONG32*) (pPalette + l), palIdx + l);
- }
- }
- /*
- * Checks if system palette contains our colors.
- */
- static BOOL HasPaletteChanged (LPWINDRAW lpwd)
- {
- PALETTEENTRY lppe [256], *lppe2;
- register int i;
- /* clear memory: */
- memset(lppe, 0, sizeof(lppe));
- /* retrive system palette: */
- if ((lpwd->fMode & WINDRAW_DIRECTDRAW) && lpwd->dd.lpDDPal != NULL &&
- /* use DirectDraw: */
- IDirectDrawPalette_GetEntries (lpwd->dd.lpDDPal, 0, lpwd->loColor,
- lpwd->hiColor - lpwd->loColor, lppe + lpwd->loColor) == DD_OK) {
- ; /* we're all done here */
- } else {
- /* use GDI: */
- HDC hdc = GetDisplayDC (lpwd->lpszDisplayDevice);
- GetSystemPaletteEntries (hdc, lpwd->loColor, lpwd->hiColor, lppe);
- DeleteDC (hdc);
- }
- /* check if our colors are still there: */
- lppe2 = lpwd->lgplDefaultPalette.palPalEntry;
- for (i=lpwd->loColor; i<lpwd->hiColor; i++)
- if (lppe [i].peGreen != lppe2 [i].peGreen ||
- lppe [i].peBlue != lppe2 [i].peBlue ||
- lppe [i].peRed != lppe2 [i].peRed) {
- break;
- }
- return i == lpwd->hiColor;
- }
- /*
- * Handles Windows palette change messages.
- * Use:
- * LRESULT WinDraw2_OnPaletteChange (LPWINDRAW lpwd, HWND hwnd, UINT Message);
- * Input:
- * lpwd - pointer to a WINDRAW structure we work with
- * hwnd - with WM_PALETTECHANGED: identifies a window that CAUSED the
- * palette to change; window that received a message otherwise
- * Message - either WM_QUERYNEWPALETTE or WM_PALETTECHANGED
- * Returns:
- * TRUE, if we do realise our palette; FALSE, otherwise.
- * Notes:
- * If our window is foreground application then we should get first
- * choice of colors in the system palette entries.
- * We get best performance when our logical palette includes the
- * standard VGA colors (at the beginning and end) otherwise GDI may have
- * to map from our palette to the device palette while drawing.
- */
- LRESULT WinDraw2_OnPaletteChange (LPWINDRAW lpwd, HWND hwnd, UINT Message)
- {
- if (lpwd && (lpwd->fMode & WINDRAW_OPENED) && hwnd == lpwd->hWnd &&
- (Message == WM_QUERYNEWPALETTE || Message == WM_PALETTECHANGED))
- {
- if (LoadPalette(lpwd))
- {
- /* check if we are using DirectDraw: */
- if (lpwd->fMode & WINDRAW_DIRECTDRAW)
- {
- if (FAILED(CreateDirectDrawPalette(lpwd, lpwd->dd.lpDDSPrimary)))
- return 0;
- }
- if (lpwd->m_pSurfaceList)
- {
- for(CHXSimpleList::Iterator i = lpwd->m_pSurfaceList->Begin(); i!= lpwd->m_pSurfaceList->End(); ++i)
- {
- LPWINDRAWSURFACE lpwds = (LPWINDRAWSURFACE) *i;
- if (lpwds)
- {
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- CreateDirectDrawPalette(lpwd, lpwds->dd.lpDDSurface);
- CreateDirectDrawPalette(lpwd, lpwds->dd.lpDDBackBuffer);
- }
- else
- {
- HBITMAP hOldBitmap;
- for(int i = 0; i<(int)lpwds->dwBackBufferCount; i++)
- {
- if (lpwds->gdi.lpGDIBackBuffer[i])
- {
- hOldBitmap = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC, lpwds->gdi.lpGDIBackBuffer[i]->hBitMap);
- SetDIBColorTable(lpwd->gdi.hMemoryDC, 0, nSystemColors, SystemPaletteRGB);
- SelectObject(lpwd->gdi.hMemoryDC, hOldBitmap);
- }
- }
- }
- }
- }
- return (LRESULT) 1;
- }
- }
- }
- return 0;
- }
- /*
- * When the window size changes we adjust our WINDRAW variables that
- * contain the dimensions of the client rectangle for our window so
- * that we come to render an image we will know whether to stretch.
- */
- LRESULT WinDraw2_OnSize (LPWINDRAW lpwd, DWORD dwWidth, DWORD dwHeight)
- {
- /* check parameters: */
- if (lpwd == NULL)
- return (LRESULT) 0;
- /* 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)
- {
- 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;
- }
- }
- cleanup:
- /* deactivate WinDraw & exit: */
- lpwd->fMode = 0;
- /* remove display mode data */
- DeleteDisplayModes(lpwd);
- HX_DELETE(lpwd->m_pModesList);
- HX_DELETE(lpwd->m_pSurfaceList);
- DeleteCriticalSection(&lpwd->csPrimary);
- InterlockedDecrement(&g_ehandlerMutexCnt);
- if (!g_ehandlerMutexCnt)
- {
- DeleteCriticalSection(&g_ehandlerMutex);
- }
- return NOERROR;
- }
- /*
- * Get display/primary surface format.
- * Use:
- * HRESULT WinDraw2_GetDisplayFormat (LPWINDRAW lpwd, LPBMI lpbiDisplayFormat);
- * Input:
- * lpwd - pointer to a WINDRAW structure to initialize
- * lpbiDisplayFormat - a structure to contain display format
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDraw2_GetDisplayFormat (LPWINDRAW lpwd, LPBMI lpbiDisplayFormat)
- {
- int sz;
- /* check parameters: */
- if (lpwd == NULL || !(lpwd->fMode & WINDRAW_OPENED) ||
- lpbiDisplayFormat == NULL)
- return E_INVALIDARG;
- /* check the size of BITMAPINFO structure to copy: */
- sz = lpbiDisplayFormat->bmiHeader.biSize;
- if (sz < (int)sizeof(BITMAPINFOHEADER) || sz > (int)lpwd->bmiDisplayFormat.bmiHeader.biSize)
- sz = lpwd->bmiDisplayFormat.bmiHeader.biSize;
- /* copy bitmap info: */
- /* Since it seems that our convention was to set biSize to the sizeof
- * BITMAPINFOHEADER instead of the actual size of the structure (which
- * causes us to lose the color table of bit fields) we will use the size
- * of the structure.
- */
- // memcpy(lpbiDisplayFormat, &(lpwd->bmiDisplayFormat), sz);
- GetDisplayFormat(&lpwd->bmiDisplayFormat, lpwd->lpszDisplayDevice);
- memcpy(lpbiDisplayFormat, &(lpwd->bmiDisplayFormat), sizeof(BMI) ); /* Flawfinder: ignore */
- return NOERROR;
- }
- /*
- * GDISURFACE functions:
- */
- #define hMEMORY ((HANDLE) 0xFFFFFFFF) /* says to open as memory file */
- /*
- * This function allocates a shared memory block for use by the source filter
- * generating DIBs for us to render. The memory block is created in shared
- * memory so that GDI doesn't have to copy the memory when we do a BitBlt
- */
- static LPGDISURFACE GDISurface_Alloc (LPBITMAPINFO pbmi)
- {
- LPGDISURFACE lpGDISurface; /* pointer to a new GDISURFACE */
- HANDLE hMapping; /* handle to mapped object */
- HBITMAP hBitmap; /* DIB section bitmap handle */
- BYTE *pBase; /* pointer to the actual image */
- /* allocate a new GDISURFACE structure to use: */
- lpGDISurface = (LPGDISURFACE)malloc (sizeof (GDISURFACE));
- if (lpGDISurface != NULL) {
- /* create a file mapping object and map into our address space: */
- hMapping = CreateFileMapping (hMEMORY, NULL, PAGE_READWRITE, (DWORD) 0, pbmi->bmiHeader.biSizeImage, NULL);
- if (hMapping != NULL) {
- /* create a DIB section using given image format */
- hBitmap = CreateDIBSection ((HDC) NULL, pbmi, DIB_RGB_COLORS, (VOID **) &pBase, hMapping, (DWORD) 0);
- if (hBitmap != NULL && pBase != NULL) {
- /* initialise the GDISURFACE structure: */
- lpGDISurface->hBitMap = hBitmap;
- lpGDISurface->hMapping = hMapping;
- lpGDISurface->lpBase = pBase;
- lpGDISurface->lpAlphaSurface = NULL;
- lpGDISurface->hEmpty = CreateEvent(NULL, TRUE, TRUE, NULL);
- /* lpGDISurface->PaletteVersion = PALETTE_VERSION; */
- GetObject (hBitmap, sizeof (DIBSECTION), (VOID *)& (lpGDISurface->DibSection));
- /* success: */
- return lpGDISurface;
- }
- /* close file mapping... */
- CloseHandle (hMapping);
- }
- /* free buffer: */
- free (lpGDISurface);
- }
- return NULL;
- }
- /*
- * Releases previously allocated GDI buffer.
- * Main application should consider calling GdiFlush ();
- * before releasing these buffers.
- */
- static void GDISurface_Free (LPGDISURFACE lpGDISurface)
- {
- /* check pointer to a buffer structure to use: */
- if (lpGDISurface != NULL) {
- /* close dibsection: */
- DeleteObject (lpGDISurface->hBitMap);
- /* close file mapping: */
- CloseHandle (lpGDISurface->hMapping);
- /* close alpha channel */
- free(lpGDISurface->lpAlphaSurface);
- /* close event */
- CloseHandle(lpGDISurface->hEmpty);
- /* free buffer: */
- free (lpGDISurface);
- }
- }
- static BOOL GDISurface_AlphaBltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurfaceDest,
- LPGDISURFACE lpGDISurfaceSrc, LPRECT lpDestRect, LPRECT lpSrcRect)
- {
- #if 0
- INT32 destX, destY;
- INT32 destStride, srcStride, alphaStride;
- UINT32 *srcBuf, *destBuf;
- UCHAR *alphaBuf;
- UCHAR alpha, invalpha;
- UCHAR *pSrc, *pDest;
- int destCID = GetBitmapColor((LPBITMAPINFO) &lpGDISurfaceDest->DibSection.dsBmih);
- int srcCID = GetBitmapColor((LPBITMAPINFO) &lpGDISurfaceSrc->DibSection.dsBmih);
- assert(destCID == srcCID); // not supported
- switch (destCID)
- {
- case CID_RGB565:
- case CID_RGB555:
- destStride = (lpGDISurfaceDest->DibSection.dsBmih.biWidth - (lpDestRect->right - lpDestRect->left)) * 2;
- srcStride = (lpGDISurfaceSrc->DibSection.dsBmih.biWidth - (lpSrcRect->right - lpSrcRect->left)) * 2;
- srcBuf = (UINT32*)(lpGDISurfaceSrc->lpBase + ( (lpSrcRect->right - lpSrcRect->left) * lpSrcRect->top
- + lpSrcRect->left ) * 2);
- destBuf = (UINT32*)(lpGDISurfaceDest->lpBase + ( (lpDestRect->right - lpDestRect->left) * lpDestRect->top
- + lpDestRect->left) *2);
- break;
- case CID_RGB32:
- destStride = (lpGDISurfaceDest->DibSection.dsBmih.biWidth - (lpDestRect->right - lpDestRect->left)) * 4;
- srcStride = (lpGDISurfaceSrc->DibSection.dsBmih.biWidth - (lpSrcRect->right - lpSrcRect->left)) * 4;
- srcBuf = (UINT32*)(lpGDISurfaceSrc->lpBase + ( (lpSrcRect->right - lpSrcRect->left) * lpSrcRect->top
- + lpSrcRect->left ) *4);
- destBuf = (UINT32*)(lpGDISurfaceDest->lpBase + ( (lpDestRect->right - lpDestRect->left) * lpDestRect->top
- + lpDestRect->left ) *4);
- break;
- case CID_RGB24:
- break;
- default:
- assert(CID_NOTSUPPORTED);
- }
- alphaBuf = lpGDISurfaceSrc->lpAlphaSurface;
- alphaStride = lpGDISurfaceDest->DibSection.dsBmih.biWidth - (lpSrcRect->right - lpSrcRect->left);
- switch (destCID)
- {
- case CID_RGB32:
- {
- for (destY = lpDestRect->top; destY < lpDestRect->bottom; destY++ )
- {
- for (destX = lpDestRect->left;destX < lpDestRect->right;destX++, srcBuf++, destBuf++, alphaBuf++)
- {
- alpha = *alphaBuf>128 ? *alphaBuf + 1 : *alphaBuf;
- invalpha = 256 - alpha;
- *destBuf =
- ((((*srcBuf & 0x00ff0000) * alpha) >> 8 ) & 0x00ff0000) +
- ((((*destBuf & 0x00ff0000) * invalpha) >> 8 ) & 0x00ff0000) +
- ((((*srcBuf & 0x0000ff00) * alpha) >> 8 ) & 0x0000ff00) +
- ((((*destBuf & 0x0000ff00) * invalpha) >> 8 ) & 0x0000ff00) +
- ((((*srcBuf & 0x000000ff) * alpha) >> 8 ) & 0x000000ff) +
- ((((*destBuf & 0x000000ff) * invalpha) >> 8 ) & 0x000000ff);
- }
- destBuf += destStride;
- srcBuf += srcStride;
- alphaBuf += alphaStride;
- }
- break;
- }
- case CID_RGB24:
- {
- pSrc = lpGDISurfaceSrc->lpBase;
- pDest = lpGDISurfaceDest->lpBase;
- pDest += (lpGDISurfaceDest->DibSection.dsBmih.biWidth * (lpGDISurfaceDest->DibSection.dsBmih.biHeight - lpDestRect->top) + lpDestRect->left)* 3;
- pSrc += (lpGDISurfaceSrc->DibSection.dsBmih.biWidth * (lpGDISurfaceSrc->DibSection.dsBmih.biHeight - lpSrcRect->top) + lpSrcRect->left)* 3;
- for (destY = lpDestRect->top; destY < lpDestRect->bottom; destY++ )
- {
- for (destX = lpDestRect->left;destX < lpDestRect->right;destX++, alphaBuf++)
- {
- // alpha = *alphaBuf;
- alpha = 128;
- invalpha = 256 - alpha;
- *pDest = (*pSrc * alpha) >> 8 + (*pDest * invalpha) >> 8;
- pDest++; pSrc++;
- *pDest = (*pSrc * alpha) >> 8 + (*pDest * invalpha) >> 8;
- pDest++; pSrc++;
- *pDest = (*pSrc * alpha) >> 8 + (*pDest * invalpha) >> 8;
- pDest++; pSrc++;
- }
- pDest -= (lpGDISurfaceDest->DibSection.dsBmih.biWidth + (lpDestRect->right - lpDestRect->left))*3;
- pSrc -= (lpGDISurfaceSrc->DibSection.dsBmih.biWidth + (lpSrcRect->right - lpSrcRect->left))*3;
- alphaBuf +=alphaStride;
- }
- break;
- }
- case CID_RGB565:
- case CID_RGB555:
- {
- /*
- * The following bugs are plain (and all stem from the same problem)
- *
- * 1. If the dest/src rects are not both even.
- * 2. If the width of the blt is not even
- *
- */
- for (destY = lpDestRect->top; destY < lpDestRect->bottom; destY++ )
- {
- for (destX = lpDestRect->left;destX < lpDestRect->right;destX+=2, srcBuf++, destBuf++, alphaBuf++)
- {
- alpha = *alphaBuf>128 ? *alphaBuf + 1 : *alphaBuf;
- invalpha = 256 - alpha;
- *destBuf =
- ((((*srcBuf & 0xf8000000) * alpha) >> 8 ) & 0xf8000000) +
- ((((*destBuf & 0xf8000000) * invalpha) >> 8 ) & 0xf8000000) +
- ((((*srcBuf & 0x07e00000) * alpha) >> 8 ) & 0x07e00000) +
- ((((*destBuf & 0x07e00000) * invalpha) >> 8 ) & 0x07e00000) +
- ((((*srcBuf & 0x001f0000) * alpha) >> 8 ) & 0x001f0000) +
- ((((*destBuf & 0x001f0000) * invalpha) >> 8 ) & 0x001f0000) +
- ((((*srcBuf & 0x0000f800) * alpha) >> 8 ) & 0x0000f800) +
- ((((*destBuf & 0x0000f800) * invalpha) >> 8 ) & 0x0000f800) +
- ((((*srcBuf & 0x000007e0) * alpha) >> 8 ) & 0x000007e0) +
- ((((*destBuf & 0x000007e0) * invalpha) >> 8 ) & 0x000007e0) +
- ((((*srcBuf & 0x0000001f) * alpha) >> 8 ) & 0x0000001f) +
- ((((*destBuf & 0x0000001f) * invalpha) >> 8 ) & 0x0000001f);
- }
- destBuf += destStride;
- srcBuf += srcStride;
- alphaBuf += alphaStride;
- }
- break;
- }
- }
- #endif
- return NOERROR;
- }
- /*
- * Blits image data into the window.
- * Use:
- * BOOL DDSurface_BltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurface,
- * LPRECT lpSourceRect, LPRECT lpTargetRect)
- * Input:
- * lpwd - pointer to the WINDRAW structure
- * lpDDSurfaceSrc - a structure containing DIBSECTION of image to blit
- * lpDDSurfaceDst - a
- * lpSrcRect - a source image region to blit
- * lpDstRect - a target window region to fill with image
- * Returns:
- * TRUE, if success; FALSE, otherwise.
- */
- static BOOL DDSurface_BltIndirect(
- LPWINDRAW lpwd,
- LPDIRECTDRAWSURFACE lpDDSurfaceDst,
- LPDIRECTDRAWSURFACE lpDDSurfaceSrc,
- LPRECT lpDstRect,
- LPRECT lpSrcRect
- )
- {
- /*
- * this will currently only work if the two color formats are
- * the same.
- */
- /* set update mode: */
- DWORD dwFlags = DDBLT_WAIT | DDBLT_ROP;
- /* set effects: */
- DDBLTFX ddBltFx;
- ZeroMemory(&ddBltFx, sizeof(DDBLTFX));
- ddBltFx.dwSize = sizeof (DDBLTFX);
- ddBltFx.dwROP = SRCCOPY;
- /* try to blit data from an offscreen surface: */
- HRESULT retVal;
- try
- {
- retVal = lpDDSurfaceDst->Blt(lpDstRect, lpDDSurfaceSrc, lpSrcRect, dwFlags, &ddBltFx);
- }
- catch(...)
- {
- char szTmp[256]; /* Flawfinder: ignore */
- sprintf(szTmp, "DDSurface_BltIndirect srcRect %ld %ld %ld %ld dstRc %ld %ld %ld %ld", /* Flawfinder: ignore */
- lpSrcRect->left, lpSrcRect->top, lpSrcRect->right, lpSrcRect->bottom,
- lpDstRect->left, lpDstRect->top, lpDstRect->right, lpDstRect->bottom);
- DumpDDInfo(lpwd, lpDDSurfaceDst, "DDSurface_BltIndirect");
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- /*
- * Blits image data into the window.
- * Use:
- * BOOL GDISurface_BltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurface,
- * LPRECT lpSourceRect, LPRECT lpTargetRect)
- * Input:
- * lpwd - pointer to the WINDRAW structure
- * lpGDISurface - a structure containing DIBSECTION of image to blit
- * lpSourceRect - a source image region to blit
- * lpTargetRect - a target window region to fill with image
- * Returns:
- * TRUE, if success; FALSE, otherwise.
- */
- static BOOL GDISurface_BltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurfaceDest,
- LPGDISURFACE lpGDISurfaceSrc, LPRECT lpSourceRect, LPRECT lpTargetRect)
- {
- BOOL bResult; /* return value */
- /* get sizes of source/destination rectangles: */
- LONG lTargetWidth = lpTargetRect->right - lpTargetRect->left;
- LONG lTargetHeight = lpTargetRect->bottom - lpTargetRect->top;
- LONG lSourceWidth = lpSourceRect->right - lpSourceRect->left;
- LONG lSourceHeight = lpSourceRect->bottom - lpSourceRect->top;
- /* select bitmap to blit: */
- HBITMAP hOldBitmap = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC, lpGDISurfaceDest->hBitMap);
- HBITMAP hOldBitmap2 = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC2, lpGDISurfaceSrc->hBitMap);
- if (lpGDISurfaceSrc->lpAlphaSurface)
- {
- return GDISurface_AlphaBltIndirect(lpwd, lpGDISurfaceDest, lpGDISurfaceSrc, lpTargetRect, lpSourceRect);
- }
- /* is the window the same size as the video: */
- if (lTargetWidth == lSourceWidth && lTargetHeight == lSourceHeight)
- {
- /* put the image straight into the destination: */
- bResult = BitBlt (
- lpwd->gdi.hMemoryDC, /* target device HDC */
- lpTargetRect->left, /* x sink position */
- lpTargetRect->top, /* y sink position */
- lTargetWidth, /* destination width */
- lTargetHeight, /* destination height */
- lpwd->gdi.hMemoryDC2, /* source device context */
- lpSourceRect->left, /* x source position */
- lpSourceRect->top, /* y source position */
- SRCCOPY); /* simple copy */
- }
- else
- {
- /* stretch the image when copying to the destination: */
- bResult = StretchBlt (
- lpwd->gdi.hMemoryDC, /* target device HDC */
- lpTargetRect->left, /* x sink position */
- lpTargetRect->top, /* y sink position */
- lTargetWidth, /* destination width */
- lTargetHeight, /* destination height */
- lpwd->gdi.hMemoryDC2, /* source device HDC */
- lpSourceRect->left, /* x source position */
- lpSourceRect->top, /* y source position */
- lSourceWidth, /* source width */
- lSourceHeight, /* source height */
- SRCCOPY); /* simple copy */
- }
- /* put the old bitmap back into the device context so we don't leak */
- SelectObject (lpwd->gdi.hMemoryDC, hOldBitmap);
- SelectObject (lpwd->gdi.hMemoryDC2, hOldBitmap2);
- /* pass the result of Bit/StretchBlt: */
- return bResult;
- }
- /*
- * Blits image data into the window.
- * Use:
- * BOOL DDSurface_Blt(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpDDSurface,
- * LPRECT lpSourceRect, LPRECT lpTargetRect)
- * Input:
- * lpwd - pointer to the WINDRAW structure
- * lpDDSurface - a structure containing DIBSECTION of image to blit
- * lpSourceRect - a source image region to blit
- * lpTargetRect - a target window region to fill with image
- * Returns:
- * TRUE, if success; FALSE, otherwise.
- */
- BOOL DDSurface_Blt(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpDDSurface,
- LPRECT lpSourceRect, LPRECT lpTargetRect)
- {
- /*
- * this will currently only work if the two color formats are
- * the same.
- */
- /* set update mode: */
- DWORD dwFlags = DDBLT_WAIT;
- /* set effects: */
- DDBLTFX ddBltFx;
- ZeroMemory(&ddBltFx, sizeof(DDBLTFX));
- ddBltFx.dwSize = sizeof (DDBLTFX);
- ddBltFx.dwDDFX = DDBLTFX_NOTEARING;
- //ddBltFx.dwROP = SRCCOPY;
- /* try to blit data from an offscreen surface: */
- RECT rect, destRect;
- GetWindowRect(lpwd->hWnd, &rect);
- destRect.left = lpTargetRect->left + rect.left;
- destRect.right = lpTargetRect->right + rect.left;
- destRect.top = lpTargetRect->top + rect.top;
- destRect.bottom = lpTargetRect->bottom + rect.top;
- /* handle monitor spanning blts */
- RECT srcRect = *lpSourceRect;
- double ratio;
- UINT32 uHorzRes = xGetSystemMetrics(SM_CXVIRTUALSCREEN);
- UINT32 uVertRes = xGetSystemMetrics(SM_CYVIRTUALSCREEN);
- if (destRect.left < 0)
- {
- ratio = ((double)abs(destRect.left)) / (double)(destRect.right - destRect.left);
- destRect.left = 0;
- srcRect.left = (int) (((double) (lpSourceRect->right-lpSourceRect->left)) * ratio);
- }
- if (destRect.right> uHorzRes)
- {
- ratio = ((double)(destRect.right - uHorzRes)) / (double)(destRect.right - destRect.left);
- destRect.right = uHorzRes;
- srcRect.right = (int) (((double) (lpSourceRect->right-lpSourceRect->left)) * (1.0 - ratio));
- }
- if (destRect.top < 0)
- {
- ratio = ((double)abs(destRect.top)) / (double)(destRect.bottom - destRect.top);
- destRect.top = 0;
- srcRect.top = (int) (((double) (lpSourceRect->bottom-lpSourceRect->top)) * ratio);
- }
- if (destRect.bottom > uVertRes)
- {
- ratio = ((double)(destRect.bottom - uVertRes)) / (double)(destRect.bottom - destRect.top);
- destRect.bottom = uVertRes;
- srcRect.bottom = (int) (((double) (lpSourceRect->bottom-lpSourceRect->top)) * (1.0 - ratio));
- }
- #ifdef _CHECK_PERFORMANCE
- static LARGE_INTEGER QueryPerformanceCounterResult = {0,0};
- static LARGE_INTEGER QueryPerformanceFrequencyResult = {0,0};
- QueryPerformanceFrequency(&QueryPerformanceFrequencyResult);
- double frequency = ((double)QueryPerformanceFrequencyResult.LowPart + 4294967296.0*QueryPerformanceFrequencyResult.HighPart);
- QueryPerformanceCounter(&QueryPerformanceCounterResult);
- double startTime = ((double)QueryPerformanceCounterResult.LowPart + 4294967296.0*QueryPerformanceCounterResult.HighPart)/frequency;
- #endif
- #ifdef _CHECK_PERFORMANCE
- FILE* f1 = fopen("c:\status.txt", "a+"); /* Flawfinder: ignore */
- fprintf(f1, "DDSurface_Blt: (%d, %d, %d, %d) -> (%d, %d, %d, %d)n", lpSourceRect->left, lpSourceRect->top, lpSourceRect->right, lpSourceRect->bottom , lpTargetRect->left, lpTargetRect->top, lpTargetRect->right, lpTargetRect->bottom);
- fclose(f1);
- #endif
- HRESULT retVal = E_FAIL;
- EnterCriticalSection(&lpwd->csPrimary);
- if (!lpwd->dd.lpDDSPrimary)
- {
- WindrawSurface_CreatePrimarySurface(lpwd);
- }
- if (lpwd->dd.lpDDSPrimary)
- {
- try
- {
- retVal = lpwd->dd.lpDDSPrimary->Blt(&destRect, lpDDSurface, &srcRect, dwFlags, &ddBltFx);
- if (retVal != DD_OK)
- {
- lpDDSurface->Restore();
- lpwd->dd.lpDDSPrimary->Restore();
- retVal = lpwd->dd.lpDDSPrimary->Blt(&destRect, lpDDSurface, &srcRect, dwFlags, &ddBltFx);
- }
- }
- catch (...)
- {
- char szTmp[256]; /* Flawfinder: ignore */
- sprintf(szTmp, "DDSurface_Blt srcRect %ld %ld %ld %ld dstRc %ld %ld %ld %ld", /* Flawfinder: ignore */
- lpSourceRect->left, lpSourceRect->top, lpSourceRect->right, lpSourceRect->bottom,
- lpTargetRect->left, lpTargetRect->top, lpTargetRect->right, lpTargetRect->bottom);
- DumpDDInfo(lpwd, lpDDSurface, szTmp);
- retVal = HXR_FAIL;
- }
- }
- LeaveCriticalSection(&lpwd->csPrimary);
- #ifdef _CHECK_PERFORMANCE
- QueryPerformanceCounter(&QueryPerformanceCounterResult);
- double endTime = ((double)QueryPerformanceCounterResult.LowPart + 4294967296.0*QueryPerformanceCounterResult.HighPart)/frequency;
- static UINT32 z_nANumTimes = 0;
- static double z_fATotalTime;
- static double z_fAAverageTime;
- z_nANumTimes++;
- z_fATotalTime += endTime - startTime;
- z_fAAverageTime = z_fATotalTime / (double) z_nANumTimes;
- if (! (z_nANumTimes % 25))
- {
- FILE* f1 = ::fopen("c:\performance.txt", "a+"); /* Flawfinder: ignore */
- ::fprintf(f1, "WINDRAW2 - ACTUAL BLT TIME: %d blts. Total CPU time: %f, CPU/Blt: %f -- Blt/s Second Max: %fn", z_nANumTimes, z_fATotalTime, z_fAAverageTime, 1.0/z_fAAverageTime);
- fclose(f1);
- }
- #endif
- return retVal;
- }
- /*
- * Blits image data into the window.
- * Use:
- * BOOL GDISurface_Blt (LPWINDRAW lpwd, LPGDISURFACE lpGDISurface,
- * LPRECT lpSourceRect, LPRECT lpTargetRect)
- * Input:
- * lpwd - pointer to the WINDRAW structure
- * lpGDISurface - a structure containing DIBSECTION of image to blit
- * lpSourceRect - a source image region to blit
- * lpTargetRect - a target window region to fill with image
- * Returns:
- * TRUE, if success; FALSE, otherwise.
- */
- static BOOL GDISurface_Blt (LPWINDRAW lpwd, LPGDISURFACE lpGDISurface,
- LPRECT lpSourceRect, LPRECT lpTargetRect)
- {
- BOOL bResult; /* return value */
- HBITMAP hOldBitmap; /* store the old bitmap */
- /* get sizes of source/destination rectangles: */
- LONG lTargetWidth = lpTargetRect->right - lpTargetRect->left;
- LONG lTargetHeight = lpTargetRect->bottom - lpTargetRect->top;
- LONG lSourceWidth = lpSourceRect->right - lpSourceRect->left;
- LONG lSourceHeight = lpSourceRect->bottom - lpSourceRect->top;
- /* select bitmap to blit: */
- hOldBitmap = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC, lpGDISurface->hBitMap);
- if (lpGDISurface->DibSection.dsBmih.biBitCount <= 8)
- {
- SetDIBColorTable(lpwd->gdi.hMemoryDC, 0, nSystemColors, SystemPaletteRGB);
- }
- /* is the window the same size as the video: */
- if (lTargetWidth == lSourceWidth && lTargetHeight == lSourceHeight) {
- /* put the image straight into the window: */
- bResult = BitBlt (
- lpwd->gdi.hDC, /* target device HDC */
- lpTargetRect->left, /* x sink position */
- lpTargetRect->top, /* y sink position */
- lTargetWidth, /* destination width */
- lTargetHeight, /* destination height */
- lpwd->gdi.hMemoryDC, /* source device context */
- lpSourceRect->left, /* x source position */
- lpSourceRect->top, /* y source position */
- SRCCOPY); /* simple copy */
- } else {
- /* stretch the image when copying to the window: */
- bResult = StretchBlt (
- lpwd->gdi.hDC, /* target device HDC */
- lpTargetRect->left, /* x sink position */
- lpTargetRect->top, /* y sink position */
- lTargetWidth, /* destination width */
- lTargetHeight, /* destination height */
- lpwd->gdi.hMemoryDC, /* source device HDC */
- lpSourceRect->left, /* x source position */
- lpSourceRect->top, /* y source position */
- lSourceWidth, /* source width */
- lSourceHeight, /* source height */
- SRCCOPY); /* simple copy */
- }
- /* put the old bitmap back into the device context so we don't leak */
- SelectObject (lpwd->gdi.hMemoryDC, hOldBitmap);
- /* pass the result of Bit/StretchBlt: */
- return bResult;
- }
- /*
- * Creates a new DD surface to be used for image data.
- * Use:
- * HRESULT WinDraw2_CreateDDSurface(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * LPBMI lpImageFormat, DWORD fSurfaceType, int nBackBuffers, DWORD dwCKey);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to initialize
- * lpImageFormat - pointer to BITMAPINFO structure describing image format
- * fSurfaceType - combination of desired properties for a surface
- * nBackBuffers - number of flippable backbuffers to allocate for this surface
- * dwCKey - a color key to use (if transparent surface)
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDraw2_CreateDDSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- LPBMI lpImageFormat, DWORD fSurfaceType, int nBackBuffers, DWORD dwCKey)
- {
- /*
- * Are we in windraw Mode?
- */
- if (!(lpwd->fMode & WINDRAW_DIRECTDRAW))
- return E_INVALIDARG;
- /* Is the color format supported by direct draw? */
- unsigned int surfaceCID = GetBitmapColor((LPBITMAPINFO) lpImageFormat);
- int directDrawSupported = 0;
- for(unsigned int i = 0; i<lpwd->numCodes; i++)
- {
- if (surfaceCID == lpwd->lpCID[i])
- {
- directDrawSupported = 1;
- break;
- }
- }
- /*
- if (!IsGDI(lpwds->cidSurfaceColor) && !directDrawSupported)
- return E_FAIL;
- */
- /* Create the surface */
- DDSURFACEDESC ddsd;
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof (DDSURFACEDESC);
- ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
- ddsd.dwWidth = lpImageFormat->bmiHeader.biWidth;
- ddsd.dwHeight = lpImageFormat->bmiHeader.biHeight;
- if (IsYUV(surfaceCID))
- {
- ddsd.dwFlags |= DDSD_PIXELFORMAT;
- ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- SetDirectDrawColor(&ddsd.ddpfPixelFormat, surfaceCID);
- }
- /*
- * Which type of surface was requested?
- */
- if (fSurfaceType & WINDRAWSURFACE_OVERLAY)
- {
- ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
- if (nBackBuffers)
- {
- ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
- ddsd.dwBackBufferCount = nBackBuffers;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
- }
- }
- else
- {
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- }
- /*
- * Which type of memory do you want?
- */
- if (fSurfaceType & WINDRAWSURFACE_VIDEOMEMORY)
- {
- ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
- }
- else if (fSurfaceType & WINDRAWSURFACE_NONLOCALVIDMEM)
- {
- ddsd.ddsCaps.dwCaps |= DDSCAPS_NONLOCALVIDMEM;
- }
- // do not specify memory type for WINDRAWSURFACE_DEFAULTMEMORY
- else if (!(fSurfaceType & WINDRAWSURFACE_DEFAULTMEMORY))
- {
- ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
- }
- int res;
- try
- {
- res = lpwd->dd.lpDD2->CreateSurface(&ddsd, &lpwds->dd.lpDDSurface, NULL);
- }
- catch (...)
- {
- char szTmp[256]; /* Flawfinder: ignore */
- sprintf(szTmp, "WinDraw2_CreateDDSurface w %ld h %ld cid %ld bb %ld caps %lx", /* Flawfinder: ignore */
- ddsd.dwWidth, ddsd.dwHeight, surfaceCID, nBackBuffers, ddsd.ddsCaps.dwCaps);
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, szTmp);
- res = HXR_FAIL;
- }
- if (DD_OK != res)
- {
- lpwds->dd.lpDDSurface = NULL;
- return E_FAIL;
- }
- lpwds->dwBackBufferCount = nBackBuffers;
- lpwds->fMode = WINDRAWSURFACE_OPENED | fSurfaceType;
- lpwds->cidSurfaceColor = surfaceCID;
- memcpy(&lpwds->bmiSurfaceFormat, lpImageFormat, sizeof(BMI)); /* Flawfinder: ignore */
- /* check to see if we have an attached surface */
- lpwds->dd.lpDDBackBuffer = NULL; /* just in case !! */
- if (nBackBuffers)
- {
- DDSCAPS ddscaps;
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- // Build flipping chain - set surfaces
- lpwds->dd.lpChain = new ENUMSURFACE[nBackBuffers+1];
- lpwds->dwFrontBuffer = 0;
- lpwds->dwNextBuffer = 1;
- lpwds->hOverlayIndexMutex = CreateMutex(NULL, FALSE, NULL);
- lpwds->hOverlayMutex = CreateMutex(NULL, FALSE, NULL);
- lpwds->dd.hAbort = CreateEvent(NULL, TRUE, FALSE, NULL);
- lpwds->dd.lpChain[0].lpSurface = lpwds->dd.lpDDSurface;
- lpwds->dd.lpDDSurface->GetAttachedSurface(&ddscaps, &lpwds->dd.lpDDBackBuffer);
- lpwds->dd.lpDDBackBuffer->Release();
- if (nBackBuffers > 1)
- {
- for (int i=1; i<nBackBuffers+1; i++)
- {
- lpwds->dd.lpChain[i-1].lpSurface->EnumAttachedSurfaces((void*)&lpwds->dd.lpChain[i].lpSurface, EnumSurfacesCallback);
- }
- }
- else
- {
- lpwds->dd.lpChain[1].lpSurface = lpwds->dd.lpDDBackBuffer;
- }
- // Build flipping chain - set hw mem locations
- for (int i=0; i<nBackBuffers+1; i++)
- {
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- lpwds->dd.lpChain[i].hEmpty = CreateEvent(NULL, TRUE, TRUE, NULL);
- lpwds->dd.lpChain[i].pHwMemBuffer = NULL;
- lpwds->dd.lpChain[i].dTimeAvailable = 0.0;
- }
- }
- lpwd->m_pSurfaceList->AddTail(lpwds);
- WinDraw2_OnPaletteChange(lpwd, lpwd->hWnd, WM_PALETTECHANGED);
- // Store the default cc values
- memset(&lpwds->dd.ddcc, 0, sizeof(lpwds->dd.ddcc));
- lpwds->dd.ddcc.dwSize = sizeof(lpwds->dd.ddcc);
- IDirectDrawColorControl *pcc = NULL;
- res = NOERROR;
- try
- {
- lpwds->dd.lpDDSurface->QueryInterface(IID_IDirectDrawColorControl, (void**)&pcc);
- if (pcc)
- {
- pcc->GetColorControls(&lpwds->dd.ddcc);
- pcc->Release();
- }
- }
- catch (...)
- {
- char szTmp[256]; /* Flawfinder: ignore */
- sprintf(szTmp, "WinDraw2_CreateDDSurface w %ld h %ld cid %ld bb %ld caps %lx", /* Flawfinder: ignore */
- ddsd.dwWidth, ddsd.dwHeight, surfaceCID, nBackBuffers, ddsd.ddsCaps.dwCaps);
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, szTmp);
- HX_RELEASE(pcc);
- memset(&lpwds->dd.ddcc, 0, sizeof(lpwds->dd.ddcc));
- }
- return res;
- }
- HRESULT WinDraw2_SetColorKey (LPWINDRAW lpwd, DWORD dwLowColor, DWORD dwHighColor)
- {
- HRESULT hr = E_FAIL;
- if (lpwd == NULL)
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- if (lpwd->fMode & WINDRAW_DIRECTDRAW)
- {
- DDCOLORKEY ddColorKey;
- /* convert color key values: */
- ddColorKey.dwColorSpaceLowValue = dwLowColor;
- ddColorKey.dwColorSpaceHighValue = dwHighColor;
- EnterCriticalSection(&lpwd->csPrimary);
- /* set color key: */
- if (lpwd->dd.lpDDSPrimary)
- {
- try
- {
- hr = lpwd->dd.lpDDSPrimary->SetColorKey(DDCKEY_DESTOVERLAY, &ddColorKey);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_SetColorKey");
- hr = HXR_FAIL;
- }
- }
- LeaveCriticalSection(&lpwd->csPrimary);
- }
- return hr;
- }
- HRESULT WinDraw2_SetOverlayPosition(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds, UINT32 x, UINT32 y)
- {
- HRESULT hr = E_FAIL;
- if (lpwd == NULL)
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- if (lpwds->fMode & WINDRAWSURFACE_OPENED && lpwds->fMode & WINDRAWSURFACE_OVERLAY)
- {
- try
- {
- hr = lpwds->dd.lpDDSurface->SetOverlayPosition(x,y);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDraw2_SetOverlayPosition");
- hr = HXR_FAIL;
- }
- }
- return hr;
- }
- HRESULT WinDraw2_UpdateOverlay(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds, RECT* pDestRect, RECT* pSrcRect, DWORD flags)
- {
- // {
- // char szBuff[256];
- // sprintf( szBuff,"UpdateOverlay src (%d, %d)-(%d, %d) dest(%d, %d)-(%d, %d) flags: %pn",
- // pSrcRect->left,
- // pSrcRect->top,
- // pSrcRect->right,
- // pSrcRect->bottom,
- // pDestRect->left,
- // pDestRect->top,
- // pDestRect->right,
- // pDestRect->bottom,
- // flags
- // );
- // _DumpString(szBuff);
- // }
- if ((lpwd == NULL) | (lpwds == NULL))
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- if (lpwds->fMode & WINDRAWSURFACE_OPENED && lpwds->fMode & WINDRAWSURFACE_OVERLAY)
- {
- EnterCriticalSection(&lpwd->csPrimary);
- HRESULT res;
- try
- {
- if (lpwds->dd.lpDDSurface)
- {
- res = lpwds->dd.lpDDSurface->UpdateOverlay(pSrcRect, lpwd->dd.lpDDSPrimary, pDestRect, flags, NULL);
- if (DDERR_SURFACELOST == res)
- {
- res = RestoreSurfaces(lpwd, lpwds);
- if (res == DD_OK)
- {
- lpwds->dd.lpDDSurface->UpdateOverlay(pSrcRect, lpwd->dd.lpDDSPrimary, pDestRect, flags, NULL);
- // Let caller know we lost our surfaces
- res = DDERR_SURFACELOST;
- }
- }
- }
- }
- catch(...)
- {
- char szTmp[256]; /* Flawfinder: ignore */
- sprintf(szTmp, "WinDraw2_UpdateOverlay srcRect %ld %ld %ld %ld dstRc %ld %ld %ld %ld", /* Flawfinder: ignore */
- pSrcRect->left, pSrcRect->top, pSrcRect->right, pSrcRect->bottom,
- pDestRect->left, pDestRect->top, pDestRect->right, pDestRect->bottom);
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, szTmp);
- res = HXR_FAIL;
- }
- LeaveCriticalSection(&lpwd->csPrimary);
- return res;
- }
- return E_FAIL;
- }
- HRESULT WinDraw2_GetOverlayPosition(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds, POINT* pLocation)
- {
- HRESULT hr = E_FAIL;
- if ((lpwd == NULL) | (lpwds == NULL))
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- if (lpwds->fMode & WINDRAWSURFACE_OPENED && lpwds->fMode & WINDRAWSURFACE_OVERLAY)
- {
- try
- {
- hr = lpwds->dd.lpDDSurface->GetOverlayPosition((LONG*) &pLocation->x, (LONG*) &pLocation->y);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDraw2_GetOverlayPosition");
- hr = HXR_FAIL;
- }
- }
- return hr;
- }
- BOOL WinDraw2_IsSurfaceVisible(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds)
- {
- if ((lpwd == NULL) | (lpwds == NULL))
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- if (lpwds->fMode & WINDRAWSURFACE_OPENED &&
- lpwds->fMode & WINDRAWSURFACE_OVERLAY &&
- lpwds->dd.lpDDSurface)
- {
- DDSCAPS ddcaps;
- memset(&ddcaps, 0, sizeof(DDSCAPS));
- try
- {
- lpwds->dd.lpDDSurface->GetCaps(&ddcaps);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDraw2_IsSurfaceVisible");
- return FALSE;
- }
- if (DDSCAPS_VISIBLE & ddcaps.dwCaps)
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL WinDraw2_IsDDAvailable(LPWINDRAW lpwd)
- {
- if (lpwd &&
- lpwd->fMode & WINDRAW_OPENED &&
- lpwd->fMode & WINDRAW_DIRECTDRAW &&
- lpwd->dd.lpDD2)
- {
- BOOL bRet = TRUE;
- #if DIRECTDRAW_VERSION > 0x0500
- IDirectDraw4 *pDD4 = NULL;
- lpwd->dd.lpDD2->QueryInterface(IID_IDirectDraw4, (void**)&pDD4);
- // First, check if another app has DD in exclusive mode
- if (pDD4)
- {
- try
- {
- HRESULT hr = pDD4->TestCooperativeLevel();
- bRet = !(hr == DDERR_EXCLUSIVEMODEALREADYSET);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_IsDDAvailable");
- bRet = TRUE;
- }
- pDD4->Release();
- }
- #endif //DIRECTDRAW_VERSION > 0x0500
- // Check if we have hardware assisted blitting
- if (bRet)
- {
- UINT32 ulCaps = 0,
- ulTemp;
- if (HXR_OK == Windraw_GetCaps(lpwd, &ulCaps, &ulTemp, &ulTemp))
- bRet = (ulCaps & HX_OVERLAY | ulCaps & HX_BLTFOURCC);
- }
- return bRet;
- }
- return FALSE;
- }
- /*
- * Creates a new GDI surface to be used for image data.
- * Use:
- * HRESULT WinDraw2_CreateGDISurface(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * LPBMI lpImageFormat, DWORD fSurfaceType, int nBackBuffers, DWORD dwCKey);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to initialize
- * lpImageFormat - pointer to BITMAPINFO structure describing image format
- * fSurfaceType - combination of desired properties for a surface
- * nBackBuffers - number of flippable backbuffers to allocate for this surface
- * dwCKey - a color key to use (if transparent surface)
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDraw2_CreateGDISurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- LPBMI lpImageFormat, DWORD fSurfaceType, int nBackBuffers, DWORD dwCKey)
- {
- int i;
- if (lpwd->fMode & WINDRAW_DIRECTDRAW)
- return E_INVALIDARG;
- /* check if surface of given color format can be created: */
- if (!IsGDI(lpwds->cidSurfaceColor))
- return E_FAIL;
- /* allocate GDI surfaces: */
- for (i=0; i<=(int)lpwds->dwBackBufferCount; i++)
- {
- LPGDISURFACE lpgdis;
- /* allocate a new surface: */
- if ((lpgdis = GDISurface_Alloc ((LPBITMAPINFO)lpImageFormat)) == NULL)
- goto release_buffers;
- /* store pointer to a new surface */
- lpwds->gdi.lpGDIBackBuffer [i] = lpgdis;
- }
- /* store surface parameters & exit: */
- lpwds->fMode |= WINDRAWSURFACE_OPENED;
- lpwds->gdi.lPitch = GetBitmapPitch ((LPBITMAPINFO)lpImageFormat);
- lpwd->m_pSurfaceList->AddTail(lpwds);
- WinDraw2_OnPaletteChange(lpwd, lpwd->hWnd, WM_PALETTECHANGED);
- return NOERROR;
- release_buffers:
- /* release GDI buffers: */
- for ( i--; i>=0; i--)
- {
- if (lpwds->gdi.lpGDIBackBuffer [i] != NULL)
- {
- GDISurface_Free(lpwds->gdi.lpGDIBackBuffer [i]);
- lpwds->gdi.lpGDIBackBuffer [i] = NULL;
- }
- }
- return E_FAIL;
- }
- /*
- * Creates a new surface to be used for image data.
- * Use:
- * HRESULT WinDraw2_CreateSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * LPBMI lpImageFormat, DWORD fSurfaceType, int nBackBuffers, DWORD dwCKey);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to initialize
- * lpImageFormat - pointer to BITMAPINFO structure describing image format
- * fSurfaceType - combination of desired properties for a surface
- * nBackBuffers - number of flippable backbuffers to allocate for this surface
- * dwCKey - a color key to use (if transparent surface)
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.