reactos/subsystems/win32/win32k/objects/dcutil.c
Timo Kreuzer 160142322e [WIN32K]
Make the SURFACE structure a bit more like the half documented windows version.

svn path=/branches/reactos-yarotows/; revision=47603
2010-06-05 21:19:41 +00:00

467 lines
10 KiB
C

#include <win32k.h>
#define NDEBUG
#include <debug.h>
COLORREF FASTCALL
IntGdiSetBkColor(HDC hDC, COLORREF color)
{
COLORREF oldColor;
PDC dc;
PDC_ATTR pdcattr;
HBRUSH hBrush;
if (!(dc = DC_LockDc(hDC)))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
pdcattr = dc->pdcattr;
oldColor = pdcattr->crBackgroundClr;
pdcattr->crBackgroundClr = color;
pdcattr->ulBackgroundClr = (ULONG)color;
pdcattr->ulDirty_ &= ~(DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
hBrush = pdcattr->hbrush;
DC_UnlockDc(dc);
NtGdiSelectBrush(hDC, hBrush);
return oldColor;
}
INT FASTCALL
IntGdiSetBkMode(HDC hDC, INT Mode)
{
COLORREF oldMode;
PDC dc;
PDC_ATTR pdcattr;
if (!(dc = DC_LockDc(hDC)))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
pdcattr = dc->pdcattr;
oldMode = pdcattr->lBkMode;
pdcattr->jBkMode = Mode;
pdcattr->lBkMode = Mode;
DC_UnlockDc(dc);
return oldMode;
}
UINT
FASTCALL
IntGdiSetTextAlign(HDC hDC,
UINT Mode)
{
UINT prevAlign;
DC *dc;
PDC_ATTR pdcattr;
dc = DC_LockDc(hDC);
if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return GDI_ERROR;
}
pdcattr = dc->pdcattr;
prevAlign = pdcattr->lTextAlign;
pdcattr->lTextAlign = Mode;
DC_UnlockDc(dc);
return prevAlign;
}
COLORREF
FASTCALL
IntGdiSetTextColor(HDC hDC,
COLORREF color)
{
COLORREF crOldColor;
PDC pdc;
PDC_ATTR pdcattr;
pdc = DC_LockDc(hDC);
if (!pdc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
pdcattr = pdc->pdcattr;
// What about ulForegroundClr, like in gdi32?
crOldColor = pdcattr->crForegroundClr;
pdcattr->crForegroundClr = color;
DC_vUpdateTextBrush(pdc);
DC_UnlockDc(pdc);
return crOldColor;
}
VOID
FASTCALL
DCU_SetDcUndeletable(HDC hDC)
{
PDC dc = DC_LockDc(hDC);
if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return;
}
dc->fs |= DC_FLAG_PERMANENT;
DC_UnlockDc(dc);
return;
}
#if 0
BOOL FASTCALL
IntIsPrimarySurface(SURFOBJ *SurfObj)
{
if (PrimarySurface.pSurface == NULL)
{
return FALSE;
}
return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
}
#endif
BOOL
FASTCALL
IntSetDefaultRegion(PDC pdc)
{
PSURFACE pSurface;
PROSRGNDATA prgn;
RECTL rclWnd, rclClip;
IntGdiReleaseRaoRgn(pdc);
rclWnd.left = 0;
rclWnd.top = 0;
rclWnd.right = pdc->dclevel.sizl.cx;
rclWnd.bottom = pdc->dclevel.sizl.cy;
rclClip = rclWnd;
// EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
{
pSurface = pdc->dclevel.pSurface;
if (pSurface && pSurface->flags & PDEV_SURFACE)
{
rclClip.left += pdc->ppdev->ptlOrigion.x;
rclClip.top += pdc->ppdev->ptlOrigion.y;
rclClip.right += pdc->ppdev->ptlOrigion.x;
rclClip.bottom += pdc->ppdev->ptlOrigion.y;
}
}
// EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
prgn = pdc->prgnVis;
if (prgn && prgn != prgnDefault)
{
REGION_SetRectRgn( prgn,
rclClip.left,
rclClip.top,
rclClip.right ,
rclClip.bottom );
}
else
{
prgn = IntSysCreateRectpRgn( rclClip.left,
rclClip.top,
rclClip.right ,
rclClip.bottom );
pdc->prgnVis = prgn;
}
if (prgn)
{
pdc->ptlDCOrig.x = 0;
pdc->ptlDCOrig.y = 0;
pdc->erclWindow = rclWnd;
pdc->erclClip = rclClip;
/* Might be an InitDC or DCE....*/
pdc->ptlFillOrigin.x = pdc->dcattr.VisRectRegion.Rect.right;
pdc->ptlFillOrigin.y = pdc->dcattr.VisRectRegion.Rect.bottom;
return TRUE;
}
pdc->prgnVis = prgnDefault;
return FALSE;
}
BOOL APIENTRY
NtGdiCancelDC(HDC hDC)
{
UNIMPLEMENTED;
return FALSE;
}
WORD APIENTRY
IntGdiSetHookFlags(HDC hDC, WORD Flags)
{
WORD wRet;
DC *dc = DC_LockDc(hDC);
if (NULL == dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
wRet = dc->fs & DC_FLAG_DIRTY_RAO; // Fixme wrong flag!
/* "Undocumented Windows" info is slightly confusing.
*/
DPRINT("DC %p, Flags %04x\n", hDC, Flags);
if (Flags & DCHF_INVALIDATEVISRGN)
{
/* hVisRgn has to be updated */
dc->fs |= DC_FLAG_DIRTY_RAO;
}
else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
{
dc->fs &= ~DC_FLAG_DIRTY_RAO;
}
DC_UnlockDc(dc);
return wRet;
}
BOOL
APIENTRY
NtGdiGetDCDword(
HDC hDC,
UINT u,
DWORD *Result)
{
BOOL Ret = TRUE;
PDC pdc;
PDC_ATTR pdcattr;
DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
if (!Result)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdc = DC_LockDc(hDC);
if (!pdc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
pdcattr = pdc->pdcattr;
switch (u)
{
case GdiGetJournal:
break;
case GdiGetRelAbs:
SafeResult = pdcattr->lRelAbs;
break;
case GdiGetBreakExtra:
SafeResult = pdcattr->lBreakExtra;
break;
case GdiGerCharBreak:
SafeResult = pdcattr->cBreak;
break;
case GdiGetArcDirection:
if (pdcattr->dwLayout & LAYOUT_RTL)
SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
else
SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
break;
case GdiGetEMFRestorDc:
break;
case GdiGetFontLanguageInfo:
SafeResult = IntGetFontLanguageInfo(pdc);
break;
case GdiGetIsMemDc:
SafeResult = pdc->dctype;
break;
case GdiGetMapMode:
SafeResult = pdcattr->iMapMode;
break;
case GdiGetTextCharExtra:
SafeResult = pdcattr->lTextExtra;
break;
default:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (Ret)
{
_SEH2_TRY
{
ProbeForWrite(Result, sizeof(DWORD), 1);
*Result = SafeResult;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
Ret = FALSE;
}
}
DC_UnlockDc(pdc);
return Ret;
}
BOOL
APIENTRY
NtGdiGetAndSetDCDword(
HDC hDC,
UINT u,
DWORD dwIn,
DWORD *Result)
{
BOOL Ret = TRUE;
PDC pdc;
PDC_ATTR pdcattr;
DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
if (!Result)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdc = DC_LockDc(hDC);
if (!pdc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
pdcattr = pdc->pdcattr;
switch (u)
{
case GdiGetSetCopyCount:
SafeResult = pdc->ulCopyCount;
pdc->ulCopyCount = dwIn;
break;
case GdiGetSetTextAlign:
SafeResult = pdcattr->lTextAlign;
pdcattr->lTextAlign = dwIn;
// pdcattr->flTextAlign = dwIn; // Flags!
break;
case GdiGetSetRelAbs:
SafeResult = pdcattr->lRelAbs;
pdcattr->lRelAbs = dwIn;
break;
case GdiGetSetTextCharExtra:
SafeResult = pdcattr->lTextExtra;
pdcattr->lTextExtra = dwIn;
break;
case GdiGetSetSelectFont:
break;
case GdiGetSetMapperFlagsInternal:
if (dwIn & ~1)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
SafeResult = pdcattr->flFontMapper;
pdcattr->flFontMapper = dwIn;
break;
case GdiGetSetMapMode:
SafeResult = IntGdiSetMapMode(pdc, dwIn);
break;
case GdiGetSetArcDirection:
if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
{
SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
if (dwIn == AD_CLOCKWISE)
{
pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
break;
}
pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
}
else // Left to Right
{
SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
AD_COUNTERCLOCKWISE;
if (dwIn == AD_COUNTERCLOCKWISE)
{
pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
break;
}
pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
}
break;
default:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (Ret)
{
_SEH2_TRY
{
ProbeForWrite(Result, sizeof(DWORD), 1);
*Result = SafeResult;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
Ret = FALSE;
}
}
DC_UnlockDc(pdc);
return Ret;
}