Handle non-source ROPs and pattern ROPs

svn path=/trunk/; revision=6402
This commit is contained in:
Gé van Geldorp 2003-10-22 17:44:01 +00:00
parent 4909784b30
commit 7cb9ea96db

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: bitmaps.c,v 1.40 2003/10/04 21:09:29 gvg Exp $ */ /* $Id: bitmaps.c,v 1.41 2003/10/22 17:44:01 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <stdlib.h> #include <stdlib.h>
@ -47,38 +47,53 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
INT YSrc, INT YSrc,
DWORD ROP) DWORD ROP)
{ {
GDIMULTILOCK Lock[2] = {{hDCDest, 0, GDI_OBJECT_TYPE_DC}, {hDCSrc, 0, GDI_OBJECT_TYPE_DC}};
PDC DCDest = NULL; PDC DCDest = NULL;
PDC DCSrc = NULL; PDC DCSrc = NULL;
PSURFOBJ SurfDest, SurfSrc; PSURFOBJ SurfDest, SurfSrc;
PSURFGDI SurfGDIDest, SurfGDISrc; PSURFGDI SurfGDIDest, SurfGDISrc;
RECTL DestRect; RECTL DestRect;
POINTL SourcePoint; POINTL SourcePoint;
//PBITMAPOBJ DestBitmapObj;
//PBITMAPOBJ SrcBitmapObj;
BOOL Status; BOOL Status;
PPALGDI PalDestGDI, PalSourceGDI; PPALGDI PalDestGDI, PalSourceGDI;
PXLATEOBJ XlateObj = NULL; PXLATEOBJ XlateObj = NULL;
HPALETTE SourcePalette, DestPalette; HPALETTE SourcePalette, DestPalette;
ULONG SourceMode, DestMode; ULONG SourceMode, DestMode;
PBRUSHOBJ BrushObj;
BOOL UsesSource = ((ROP & 0xCC0000) >> 2) != (ROP & 0x330000);
BOOL UsesPattern = ((ROP & 0xF00000) >> 4) != (ROP & 0x0F0000);
if ( !GDIOBJ_LockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0])) ) DCDest = DC_LockDc(hDCDest);
if (NULL == DCDest)
{ {
DPRINT1("GDIOBJ_LockMultipleObj() failed\n" ); DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return STATUS_INVALID_PARAMETER; SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
} }
DCDest = Lock[0].pObj; if (UsesSource)
DCSrc = Lock[1].pObj; {
DCSrc = DC_LockDc(hDCSrc);
if ( !DCDest || !DCSrc ) if (NULL == DCSrc)
return STATUS_INVALID_PARAMETER; {
DC_UnlockDc(hDCDest);
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
}
else
{
DCSrc = NULL;
}
/* Offset the destination and source by the origin of their DCs. */ /* Offset the destination and source by the origin of their DCs. */
XDest += DCDest->w.DCOrgX; XDest += DCDest->w.DCOrgX;
YDest += DCDest->w.DCOrgY; YDest += DCDest->w.DCOrgY;
if (UsesSource)
{
XSrc += DCSrc->w.DCOrgX; XSrc += DCSrc->w.DCOrgX;
YSrc += DCSrc->w.DCOrgY; YSrc += DCSrc->w.DCOrgY;
}
DestRect.left = XDest; DestRect.left = XDest;
DestRect.top = YDest; DestRect.top = YDest;
@ -88,12 +103,33 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
SourcePoint.x = XSrc; SourcePoint.x = XSrc;
SourcePoint.y = YSrc; SourcePoint.y = YSrc;
// Determine surfaces to be used in the bitblt /* Determine surfaces to be used in the bitblt */
SurfDest = (PSURFOBJ)AccessUserObject((ULONG)DCDest->Surface); SurfDest = (PSURFOBJ)AccessUserObject((ULONG)DCDest->Surface);
SurfSrc = (PSURFOBJ)AccessUserObject((ULONG)DCSrc->Surface);
SurfGDIDest = (PSURFGDI)AccessInternalObjectFromUserObject(SurfDest); SurfGDIDest = (PSURFGDI)AccessInternalObjectFromUserObject(SurfDest);
if (UsesSource)
{
SurfSrc = (PSURFOBJ)AccessUserObject((ULONG)DCSrc->Surface);
SurfGDISrc = (PSURFGDI)AccessInternalObjectFromUserObject(SurfSrc); SurfGDISrc = (PSURFGDI)AccessInternalObjectFromUserObject(SurfSrc);
}
else
{
SurfSrc = NULL;
SurfGDISrc = NULL;
}
if (UsesPattern)
{
BrushObj = BRUSHOBJ_LockBrush(DCDest->w.hBrush);
if (NULL == BrushObj)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
}
else
{
BrushObj = NULL;
}
if (DCDest->w.hPalette != 0) if (DCDest->w.hPalette != 0)
{ {
@ -104,7 +140,7 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
DestPalette = NtGdiGetStockObject(DEFAULT_PALETTE); DestPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
} }
if(DCSrc->w.hPalette != 0) if (UsesSource && DCSrc->w.hPalette != 0)
{ {
SourcePalette = DCSrc->w.hPalette; SourcePalette = DCSrc->w.hPalette;
} }
@ -116,7 +152,11 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
PalSourceGDI = PALETTE_LockPalette(SourcePalette); PalSourceGDI = PALETTE_LockPalette(SourcePalette);
if (NULL == PalSourceGDI) if (NULL == PalSourceGDI)
{ {
GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock) / sizeof(Lock[0])); if (UsesSource)
{
DC_UnlockDc(hDCSrc);
}
DC_UnlockDc(hDCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -132,7 +172,11 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
PalDestGDI = PALETTE_LockPalette(DestPalette); PalDestGDI = PALETTE_LockPalette(DestPalette);
if (NULL == PalDestGDI) if (NULL == PalDestGDI)
{ {
GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock) / sizeof(Lock[0])); if (UsesSource)
{
DC_UnlockDc(hDCSrc);
}
DC_UnlockDc(hDCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -143,17 +187,29 @@ BOOL STDCALL NtGdiBitBlt(HDC hDCDest,
XlateObj = (PXLATEOBJ)IntEngCreateXlate(DestMode, SourceMode, DestPalette, SourcePalette); XlateObj = (PXLATEOBJ)IntEngCreateXlate(DestMode, SourceMode, DestPalette, SourcePalette);
if (NULL == XlateObj) if (NULL == XlateObj)
{ {
GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock) / sizeof(Lock[0])); if (UsesSource)
{
DC_UnlockDc(hDCSrc);
}
DC_UnlockDc(hDCDest);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return FALSE; return FALSE;
} }
/* Perform the bitblt operation */ /* Perform the bitblt operation */
Status = IntEngBitBlt(SurfDest, SurfSrc, NULL, DCDest->CombinedClip, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, ROP); Status = IntEngBitBlt(SurfDest, SurfSrc, NULL, DCDest->CombinedClip, XlateObj,
&DestRect, &SourcePoint, NULL, BrushObj, NULL, ROP);
EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj);
if (UsesPattern)
GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock) / sizeof(Lock[0])); {
BRUSHOBJ_UnlockBrush(DCDest->w.hBrush);
}
if (UsesSource)
{
DC_UnlockDc(hDCSrc);
}
DC_UnlockDc(hDCDest);
return Status; return Status;
} }