Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

645 lines
15 KiB

#include "stdafx.h"
#include "imgutil.h"
#include "ddraw.h"
#include "cddsurf.h"
// Get rid of "synonyms" warning
#pragma warning(disable : 4097)
// Get rid of "unused formal parameters warning"
#pragma warning(disable : 4100)
#undef DEFINE_GUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,
0x20,0xAF,0x0B,0xE5,0x60 );
DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,
0x20,0xAF,0x0B,0xE5,0x60 );
const RGBQUAD g_rgbBgColor = { 0xFF, 0xFF, 0xFF, 0 };
const RGBQUAD g_rgbFgColor = { 0x00, 0x00, 0x00, 0 };
const PALETTEENTRY g_peVga[16] =
{
{ 0x00, 0x00, 0x00, 0x00 }, // Black
{ 0x80, 0x00, 0x00, 0x00 }, // Dark red
{ 0x00, 0x80, 0x00, 0x00 }, // Dark green
{ 0x80, 0x80, 0x00, 0x00 }, // Dark yellow
{ 0x00, 0x00, 0x80, 0x00 }, // Dark blue
{ 0x80, 0x00, 0x80, 0x00 }, // Dark purple
{ 0x00, 0x80, 0x80, 0x00 }, // Dark aqua
{ 0xC0, 0xC0, 0xC0, 0x00 }, // Light grey
{ 0x80, 0x80, 0x80, 0x00 }, // Dark grey
{ 0xFF, 0x00, 0x00, 0x00 }, // Light red
{ 0x00, 0xFF, 0x00, 0x00 }, // Light green
{ 0xFF, 0xFF, 0x00, 0x00 }, // Light yellow
{ 0x00, 0x00, 0xFF, 0x00 }, // Light blue
{ 0xFF, 0x00, 0xFF, 0x00 }, // Light purple
{ 0x00, 0xFF, 0xFF, 0x00 }, // Light aqua
{ 0xFF, 0xFF, 0xFF, 0x00 } // White
};
#define Verify(x) (x)
LONG g_lSecondaryObjCount = 0;
#define DecrementSecondaryObjectCount( idCaller ) DecrementSecondaryObjectCount_Actual()
inline void
DecrementSecondaryObjectCount_Actual()
{
InterlockedDecrement(&g_lSecondaryObjCount);
}
#define IncrementSecondaryObjectCount( idCaller ) IncrementSecondaryObjectCount_Actual()
inline void
IncrementSecondaryObjectCount_Actual()
{
Verify(InterlockedIncrement(&g_lSecondaryObjCount) > 0);
}
CBaseFT::CBaseFT(CRITICAL_SECTION * pcs)
{
_ulRefs = 1;
_ulAllRefs = 1;
_pcs = pcs;
IncrementSecondaryObjectCount(10);
}
CBaseFT::~CBaseFT()
{
DecrementSecondaryObjectCount(10);
}
void CBaseFT::Passivate()
{
}
ULONG CBaseFT::Release()
{
ULONG ulRefs = (ULONG)InterlockedDecrement((LONG *)&_ulRefs);
if (ulRefs == 0)
{
Passivate();
SubRelease();
}
return(ulRefs);
}
ULONG CBaseFT::SubRelease()
{
ULONG ulRefs = (ULONG)InterlockedDecrement((LONG *)&_ulAllRefs);
if (ulRefs == 0)
{
delete this;
}
return(ulRefs);
}
void CopyColorsFromPaletteEntries(RGBQUAD *prgb, const PALETTEENTRY *ppe,
UINT uCount)
{
while (uCount--)
{
prgb->rgbRed = ppe->peRed;
prgb->rgbGreen = ppe->peGreen;
prgb->rgbBlue = ppe->peBlue;
prgb->rgbReserved = 0;
prgb++;
ppe++;
}
}
void CopyPaletteEntriesFromColors(PALETTEENTRY *ppe, const RGBQUAD *prgb,
UINT uCount)
{
while (uCount--)
{
ppe->peRed = prgb->rgbRed;
ppe->peGreen = prgb->rgbGreen;
ppe->peBlue = prgb->rgbBlue;
ppe->peFlags = 0;
prgb++;
ppe++;
}
}
#define MASK565_0 0x0000F800
#define MASK565_1 0x000007E0
#define MASK565_2 0x0000001F
HBITMAP ImgCreateDib(LONG xWid, LONG yHei, BOOL fPal, int cBitsPerPix,
int cEnt, PALETTEENTRY * ppe, BYTE ** ppbBits, int * pcbRow)
{
struct {
BITMAPINFOHEADER bmih;
union {
RGBQUAD argb[256];
WORD aw[256];
DWORD adw[3];
} u;
} bmi;
int i;
if (cBitsPerPix != 8)
fPal = FALSE;
bmi.bmih.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmih.biWidth = xWid;
bmi.bmih.biHeight = yHei;
bmi.bmih.biPlanes = 1;
bmi.bmih.biBitCount = (WORD)((cBitsPerPix == 15) ? 16 : cBitsPerPix);
bmi.bmih.biCompression = (cBitsPerPix == 16) ? BI_BITFIELDS : BI_RGB;
bmi.bmih.biSizeImage = 0;
bmi.bmih.biXPelsPerMeter = 0;
bmi.bmih.biYPelsPerMeter = 0;
bmi.bmih.biClrUsed = 0;
bmi.bmih.biClrImportant = 0;
if (cBitsPerPix == 1)
{
bmi.bmih.biClrUsed = 2;
if (cEnt > 2)
cEnt = 2;
if (cEnt > 0)
{
bmi.bmih.biClrImportant = cEnt;
CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt);
}
else
{
bmi.u.argb[0] = g_rgbBgColor;
bmi.u.argb[1] = g_rgbFgColor;
}
}
else if (cBitsPerPix == 4)
{
bmi.bmih.biClrUsed = 16;
if (cEnt > 16)
cEnt = 16;
if (cEnt > 0)
{
bmi.bmih.biClrImportant = cEnt;
CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt);
}
else
{
bmi.bmih.biClrImportant = 16;
CopyColorsFromPaletteEntries(bmi.u.argb, g_peVga, 16);
}
}
else if (cBitsPerPix == 8)
{
if (fPal)
{
bmi.bmih.biClrUsed = 256;
for (i = 0; i < 256; ++i)
bmi.u.aw[i] = (WORD)i;
}
else
{
if (cEnt > 0 && cEnt < 256)
{
bmi.bmih.biClrUsed = cEnt;
bmi.bmih.biClrImportant = cEnt;
}
else
bmi.bmih.biClrUsed = 256;
if (cEnt && ppe)
{
CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt);
}
}
}
else if (cBitsPerPix == 16)
{
bmi.u.adw[0] = MASK565_0;
bmi.u.adw[1] = MASK565_1;
bmi.u.adw[2] = MASK565_2;
}
return ImgCreateDibFromInfo((BITMAPINFO *)&bmi, fPal ? DIB_PAL_COLORS : DIB_RGB_COLORS, ppbBits, pcbRow);
}
HBITMAP ImgCreateDibFromInfo(BITMAPINFO * pbmi, UINT wUsage, BYTE ** ppbBits, int * pcbRow)
{
HDC hdcMem = NULL;
HBITMAP hbm = NULL;
BYTE * pbBits;
int cbRow;
LONG xWid, yHei;
int cBitsPerPix;
xWid = pbmi->bmiHeader.biWidth;
yHei = pbmi->bmiHeader.biHeight;
cBitsPerPix = pbmi->bmiHeader.biBitCount;
cbRow = ((xWid * cBitsPerPix + 31) & ~31) / 8;
if (pcbRow)
{
*pcbRow = cbRow;
}
hdcMem = CreateCompatibleDC(NULL);
if (hdcMem == NULL)
goto Cleanup;
hbm = CreateDIBSection(hdcMem, pbmi, wUsage, (void **)&pbBits, NULL, 0);
if (hbm && ppbBits)
{
*ppbBits = pbBits;
}
Cleanup:
if (hdcMem)
DeleteDC(hdcMem);
return(hbm);
}
CDDrawWrapper::CDDrawWrapper(HBITMAP hbmDib)
{
m_hbmDib = hbmDib;
GetObject(hbmDib, sizeof(DIBSECTION), &m_dsSurface);
m_lPitch = ((m_dsSurface.dsBmih.biWidth * m_dsSurface.dsBmih.biBitCount + 31) & ~31) / 8;
if (m_dsSurface.dsBmih.biHeight > 0)
{
m_pbBits = (BYTE *)m_dsSurface.dsBm.bmBits + (m_dsSurface.dsBm.bmHeight - 1) * m_lPitch;
m_lPitch = -m_lPitch;
}
else
{
m_pbBits = (BYTE *)m_dsSurface.dsBm.bmBits;
}
// left, top already 0
m_rcSurface.right = m_dsSurface.dsBm.bmWidth;
m_rcSurface.bottom = m_dsSurface.dsBm.bmHeight;
// initialize transparent index to -1
m_ddColorKey.dwColorSpaceLowValue = m_ddColorKey.dwColorSpaceHighValue = (DWORD)-1;
}
CDDrawWrapper::~CDDrawWrapper()
{
}
STDMETHODIMP
CDDrawWrapper::QueryInterface(REFIID riid, void ** ppv)
{
if (riid == IID_IDirectDrawSurface)
*ppv = (IUnknown *)(IDirectDrawSurface *)this;
else if (riid == IID_IDirectDrawPalette)
*ppv = (IUnknown *)(IDirectDrawPalette *)this;
else if (riid == IID_IUnknown)
*ppv = (IUnknown *)(IDirectDrawSurface *)this;
else
*ppv = NULL;
if (*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return(S_OK);
}
else
{
return(E_NOINTERFACE);
}
}
STDMETHODIMP_(ULONG)
CDDrawWrapper::AddRef()
{
return(super::AddRef());
}
STDMETHODIMP_(ULONG)
CDDrawWrapper::Release()
{
return(super::Release());
}
STDMETHODIMP CDDrawWrapper::GetColorKey(DWORD dw, LPDDCOLORKEY lpKey)
{
if (dw != DDCKEY_SRCBLT)
return E_INVALIDARG;
if (lpKey == NULL)
return E_POINTER;
memcpy(lpKey, &m_ddColorKey, sizeof(DDCOLORKEY));
return S_OK;
}
STDMETHODIMP CDDrawWrapper::GetPalette(LPDIRECTDRAWPALETTE FAR* ppPal)
{
if (ppPal == NULL)
return E_POINTER;
// Return interface to set color table if DIB section has one
if (m_dsSurface.dsBmih.biBitCount <= 8)
{
*ppPal = (LPDIRECTDRAWPALETTE)this;
((LPUNKNOWN)*ppPal)->AddRef();
return S_OK;
}
else
{
*ppPal = NULL;
return E_NOINTERFACE;
}
}
STDMETHODIMP CDDrawWrapper::SetColorKey(DWORD dwFlags, LPDDCOLORKEY pDDColorKey)
{
if (dwFlags != DDCKEY_SRCBLT)
return E_INVALIDARG;
if (pDDColorKey == NULL)
return E_POINTER;
memcpy(&m_ddColorKey, pDDColorKey, sizeof(DDCOLORKEY));
return S_OK;
}
STDMETHODIMP CDDrawWrapper::SetEntries(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries)
{
RGBQUAD argb[256];
DWORD nColors = (DWORD)(1 << m_dsSurface.dsBmih.biBitCount);
UINT nColorsSet;
HDC hdc;
HBITMAP hbm;
if (dwFlags)
return E_INVALIDARG;
if (dwStart >= nColors || dwStart + dwCount > nColors)
return E_INVALIDARG;
if (pEntries == NULL)
return E_POINTER;
CopyColorsFromPaletteEntries(argb, pEntries, dwCount);
hdc = CreateCompatibleDC(NULL);
if (hdc)
{
hbm = (HBITMAP)SelectObject(hdc, m_hbmDib);
nColorsSet = SetDIBColorTable(hdc, (UINT)dwStart, (UINT)dwCount, argb);
SelectObject(hdc, hbm);
DeleteDC(hdc);
}
else
nColorsSet = 0;
return nColorsSet ? S_OK : E_FAIL;
}
STDMETHODIMP CDDrawWrapper::GetEntries(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries)
{
RGBQUAD argb[256];
DWORD nColors = (DWORD)(1 << m_dsSurface.dsBmih.biBitCount);
UINT nColorsGet;
HDC hdc;
HBITMAP hbm;
if (dwFlags)
return E_INVALIDARG;
if (dwStart >= nColors || dwStart + dwCount > nColors)
return E_INVALIDARG;
if (pEntries == NULL)
return E_POINTER;
hdc = CreateCompatibleDC(NULL);
if (hdc)
{
hbm = (HBITMAP)SelectObject(hdc, m_hbmDib);
nColorsGet = GetDIBColorTable(hdc, (UINT)dwStart, (UINT)dwCount, argb);
SelectObject(hdc, hbm);
DeleteDC(hdc);
}
else
return E_FAIL;
if (nColorsGet)
CopyPaletteEntriesFromColors(pEntries, argb, dwCount);
return nColorsGet ? S_OK : E_FAIL;
}
STDMETHODIMP CDDrawWrapper::Lock(LPRECT pRect, LPDDSURFACEDESC pSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
RECT rcClip;
if (pRect == NULL || pSurfaceDesc == NULL)
return E_POINTER;
if (pSurfaceDesc->dwSize != sizeof(DDSURFACEDESC))
return E_INVALIDARG;
if (hEvent)
return E_INVALIDARG;
IntersectRect(&rcClip, pRect, &m_rcSurface);
if (!EqualRect(&rcClip, pRect))
return E_INVALIDARG;
pSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
pSurfaceDesc->dwWidth = m_dsSurface.dsBm.bmWidth;
pSurfaceDesc->dwHeight = m_dsSurface.dsBm.bmHeight;
pSurfaceDesc->lPitch = m_lPitch;
pSurfaceDesc->lpSurface = (LPVOID)(m_pbBits
+ pRect->top * m_lPitch
+ ((pRect->left * m_dsSurface.dsBmih.biBitCount) / 8));
return S_OK;
}
STDMETHODIMP CDDrawWrapper::Unlock(LPVOID pBits)
{
return S_OK;
}
// The remainder of these methods are not needed by the plugin filters
STDMETHODIMP CDDrawWrapper::AddAttachedSurface(LPDIRECTDRAWSURFACE lpdds)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::AddOverlayDirtyRect(LPRECT lprc)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::Blt(LPRECT lprcDest, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dw, LPDDBLTFX lpfx)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::BltBatch(LPDDBLTBATCH lpBlt, DWORD dwCount, DWORD dwFlags)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dwTrans)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpdds)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::EnumAttachedSurfaces(LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::EnumOverlayZOrders(DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::Flip(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetAttachedSurface(LPDDSCAPS lpCaps, LPDIRECTDRAWSURFACE FAR * lpdds)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetBltStatus(DWORD dw)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetCaps(LPDDSCAPS lpCaps)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetClipper(LPDIRECTDRAWCLIPPER FAR* lpClipper)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetDC(HDC FAR * lphdc)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetFlipStatus(DWORD dw)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetOverlayPosition(LPLONG lpl1, LPLONG lpl2)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetPixelFormat(LPDDPIXELFORMAT pPixelFormat)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetSurfaceDesc(LPDDSURFACEDESC pSurfaceDesc)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::Initialize(LPDIRECTDRAW pDD, LPDDSURFACEDESC pSurfaceDesc)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::IsLost()
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::ReleaseDC(HDC hdc)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::Restore()
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::SetClipper(LPDIRECTDRAWCLIPPER pClipper)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::SetOverlayPosition(LONG x, LONG y)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::SetPalette(LPDIRECTDRAWPALETTE pDDPal)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::UpdateOverlay(LPRECT prc, LPDIRECTDRAWSURFACE pdds, LPRECT prc2, DWORD dw, LPDDOVERLAYFX pfx)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::UpdateOverlayDisplay(DWORD dw)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::UpdateOverlayZOrder(DWORD dw, LPDIRECTDRAWSURFACE pdds)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::GetCaps(LPDWORD lpdw)
{
return E_NOTIMPL;
}
STDMETHODIMP CDDrawWrapper::Initialize(LPDIRECTDRAW lpdd, DWORD dwCount, LPPALETTEENTRY pEntries)
{
return E_NOTIMPL;
}