-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-static
-VOID
-CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr, FLONG Dirty)
+COLORREF FASTCALL
+IntGdiSetBkColor(HDC hDC, COLORREF color)
{
- Dc_Attr->hpen = dc->Dc_Attr.hpen;
- Dc_Attr->hbrush = dc->Dc_Attr.hbrush;
- Dc_Attr->hColorSpace = dc->Dc_Attr.hColorSpace;
- Dc_Attr->hlfntNew = dc->Dc_Attr.hlfntNew;
-
- Dc_Attr->jROP2 = dc->Dc_Attr.jROP2;
- Dc_Attr->jFillMode = dc->Dc_Attr.jFillMode;
- Dc_Attr->jStretchBltMode = dc->Dc_Attr.jStretchBltMode;
- Dc_Attr->lRelAbs = dc->Dc_Attr.lRelAbs;
- Dc_Attr->jBkMode = dc->Dc_Attr.jBkMode;
-
- Dc_Attr->crBackgroundClr = dc->Dc_Attr.crBackgroundClr;
- Dc_Attr->ulBackgroundClr = dc->Dc_Attr.ulBackgroundClr;
- Dc_Attr->crForegroundClr = dc->Dc_Attr.crForegroundClr;
- Dc_Attr->ulForegroundClr = dc->Dc_Attr.ulForegroundClr;
-
- Dc_Attr->ulBrushClr = dc->Dc_Attr.ulBrushClr;
- Dc_Attr->crBrushClr = dc->Dc_Attr.crBrushClr;
-
- Dc_Attr->ulPenClr = dc->Dc_Attr.ulPenClr;
- Dc_Attr->crPenClr = dc->Dc_Attr.crPenClr;
-
- Dc_Attr->ptlBrushOrigin = dc->Dc_Attr.ptlBrushOrigin;
-
- Dc_Attr->lTextAlign = dc->Dc_Attr.lTextAlign;
- Dc_Attr->lTextExtra = dc->Dc_Attr.lTextExtra;
- Dc_Attr->cBreak = dc->Dc_Attr.cBreak;
- Dc_Attr->lBreakExtra = dc->Dc_Attr.lBreakExtra;
- Dc_Attr->iMapMode = dc->Dc_Attr.iMapMode;
- Dc_Attr->iGraphicsMode = dc->Dc_Attr.iGraphicsMode;
-
- Dc_Attr->ptlCurrent = dc->Dc_Attr.ptlCurrent;
- Dc_Attr->ptlWindowOrg = dc->Dc_Attr.ptlWindowOrg;
- Dc_Attr->szlWindowExt = dc->Dc_Attr.szlWindowExt;
- Dc_Attr->ptlViewportOrg = dc->Dc_Attr.ptlViewportOrg;
- Dc_Attr->szlViewportExt = dc->Dc_Attr.szlViewportExt;
-
- Dc_Attr->ulDirty_ = dc->Dc_Attr.ulDirty_; //Copy flags! We may have set them.
-
- XForm2MatrixS( &Dc_Attr->mxWorldToDevice, &dc->w.xformWorld2Vport);
- XForm2MatrixS( &Dc_Attr->mxDevicetoWorld, &dc->w.xformVport2World);
- XForm2MatrixS( &Dc_Attr->mxWorldToPage, &dc->w.xformWorld2Wnd);
+ 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;
}
-static
-VOID
-CopyFromUserDcAttr(PDC dc, PDC_ATTR Dc_Attr, FLONG Dirty)
+INT FASTCALL
+IntGdiSetBkMode(HDC hDC, INT Mode)
{
- if ( (Dirty & DIRTY_FILL) || (Dc_Attr->ulDirty_ & DIRTY_FILL))
- {
- dc->Dc_Attr.ulBrushClr = Dc_Attr->ulBrushClr;
- dc->Dc_Attr.crBrushClr = Dc_Attr->crBrushClr;
- Dc_Attr->ulDirty_ &= ~DIRTY_FILL;
- }
- if ( Dirty & DIRTY_LINE || (Dc_Attr->ulDirty_ & DIRTY_LINE))
- {
- dc->Dc_Attr.crBackgroundClr = Dc_Attr->crBackgroundClr;
- dc->Dc_Attr.ulBackgroundClr = Dc_Attr->ulBackgroundClr;
- dc->Dc_Attr.ulPenClr = Dc_Attr->ulPenClr;
- dc->Dc_Attr.crPenClr = Dc_Attr->crPenClr;
- Dc_Attr->ulDirty_ &= ~DIRTY_LINE;
- }
- if ( Dirty & DIRTY_TEXT || (Dc_Attr->ulDirty_ & DIRTY_TEXT))
- {
- dc->Dc_Attr.crForegroundClr = Dc_Attr->crForegroundClr;
- dc->Dc_Attr.ulForegroundClr = Dc_Attr->ulForegroundClr;
- Dc_Attr->ulDirty_ &= ~DIRTY_TEXT;
- }
-
- if ( Dirty & (DC_MODE_DIRTY|DC_FONTTEXT_DIRTY) ||
- (Dc_Attr->ulDirty_ & (DC_MODE_DIRTY|DC_FONTTEXT_DIRTY)))
- {
- dc->Dc_Attr.jROP2 = Dc_Attr->jROP2;
- dc->Dc_Attr.iGraphicsMode = Dc_Attr->iGraphicsMode;
- dc->Dc_Attr.lFillMode = Dc_Attr->lFillMode;
- dc->Dc_Attr.flFontMapper = Dc_Attr->flFontMapper;
- dc->Dc_Attr.lBreakExtra = Dc_Attr->lBreakExtra;
- dc->Dc_Attr.cBreak = Dc_Attr->cBreak;
- }
+ 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;
}
-static
-BOOL
-ReadWriteVMDcAttr(PDC dc, FLONG Dirty, BOOL Write)
+UINT
+FASTCALL
+IntGdiSetTextAlign(HDC hDC,
+ UINT Mode)
{
- BOOL Ret = FALSE;
- KeEnterCriticalRegion();
+ UINT prevAlign;
+ DC *dc;
+ PDC_ATTR pdcattr;
+
+ dc = DC_LockDc(hDC);
+ if (!dc)
{
- INT Index = GDI_HANDLE_GET_INDEX(dc->hHmgr);
- PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
- HANDLE ProcessId = (HANDLE)(((ULONG_PTR)(Entry->ProcessId)) & ~1);
- DC_ATTR lDc_AttrData;
-
- if(Entry->UserData)
- {
- NTSTATUS Status = ZwReadVirtualMemory ( ProcessId,
- &(Entry->UserData),
- &lDc_AttrData,
- sizeof(DC_ATTR),
- NULL );
- if (Write)
- {
- if (NT_SUCCESS(Status)) CopytoUserDcAttr(dc, &lDc_AttrData, Dirty);
- Ret = TRUE;
- }
- else
- {
- if (NT_SUCCESS(Status)) CopyFromUserDcAttr(dc, &lDc_AttrData, Dirty);
- Ret = TRUE;
- }
- if (Write)
- Status = ZwWriteVirtualMemory ( ProcessId,
- &(Entry->UserData),
- &lDc_AttrData,
- sizeof(DC_ATTR),
- NULL );
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- Ret = FALSE;
- }
- }
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return GDI_ERROR;
}
- KeLeaveCriticalRegion();
- return Ret;
+ pdcattr = dc->pdcattr;
+ prevAlign = pdcattr->lTextAlign;
+ pdcattr->lTextAlign = Mode;
+ DC_UnlockDc(dc);
+ return prevAlign;
}
-
-BOOL
+COLORREF
FASTCALL
-DCU_UpdateUserXForms(PDC pDC, ULONG uMask)
+IntGdiSetTextColor(HDC hDC,
+ COLORREF color)
{
- PDC_ATTR DC_Attr = pDC->pDc_Attr;
-
- if (!uMask) return FALSE;
+ COLORREF crOldColor;
+ PDC pdc;
+ PDC_ATTR pdcattr;
- if (!DC_Attr) return FALSE;
- else
- {
- NTSTATUS Status = STATUS_SUCCESS;
- KeEnterCriticalRegion();
- _SEH_TRY
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
{
- ProbeForWrite(DC_Attr,
- sizeof(DC_ATTR),
- 1);
- if (uMask & WORLD_XFORM_CHANGED)
- XForm2MatrixS( &DC_Attr->mxWorldToDevice, &pDC->w.xformWorld2Vport);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return CLR_INVALID;
+ }
+ pdcattr = pdc->pdcattr;
- if (uMask & DEVICE_TO_WORLD_INVALID)
- XForm2MatrixS( &DC_Attr->mxDevicetoWorld, &pDC->w.xformVport2World);
+ // What about ulForegroundClr, like in gdi32?
+ crOldColor = pdcattr->crForegroundClr;
+ pdcattr->crForegroundClr = color;
+ DC_vUpdateTextBrush(pdc);
- if (uMask & WORLD_TO_PAGE_IDENTITY)
- XForm2MatrixS( &DC_Attr->mxWorldToPage, &pDC->w.xformWorld2Wnd);
- }
- _SEH_HANDLE
+ DC_UnlockDc(pdc);
+
+ return crOldColor;
+}
+
+VOID
+FASTCALL
+DCU_SetDcUndeletable(HDC hDC)
+{
+ PDC dc = DC_LockDc(hDC);
+ if (!dc)
{
- Status = _SEH_GetExceptionCode();
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return;
}
- _SEH_END;
- KeLeaveCriticalRegion();
- if(!NT_SUCCESS(Status))
+
+ dc->fs |= DC_FLAG_PERMANENT;
+ DC_UnlockDc(dc);
+ return;
+}
+
+#if 0
+BOOL FASTCALL
+IntIsPrimarySurface(SURFOBJ *SurfObj)
+{
+ if (PrimarySurface.pSurface == NULL)
{
- SetLastNtError(Status);
- return FALSE;
+ return FALSE;
}
- }
- return TRUE;
+ return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
}
+#endif
BOOL
FASTCALL
-DCU_SyncDcAttrtoUser(PDC dc, FLONG Dirty)
+IntSetDefaultRegion(PDC pdc)
{
- BOOL TryHarder = FALSE;
- PDC_ATTR Dc_Attr = dc->pDc_Attr;
- if (!Dirty) return FALSE;
- if (!Dc_Attr) return FALSE;
- else
- {
- NTSTATUS Status = STATUS_SUCCESS;
- KeEnterCriticalRegion();
- _SEH_TRY
+ 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
{
- ProbeForWrite(Dc_Attr,
- sizeof(DC_ATTR),
- 1);
- CopytoUserDcAttr( dc, Dc_Attr, Dirty);
+ prgn = IntSysCreateRectpRgn( rclClip.left,
+ rclClip.top,
+ rclClip.right ,
+ rclClip.bottom );
+ pdc->prgnVis = prgn;
}
- _SEH_HANDLE
+
+ if (prgn)
{
- Status = _SEH_GetExceptionCode();
+ 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;
}
- _SEH_END;
- KeLeaveCriticalRegion();
- if(!NT_SUCCESS(Status)) TryHarder = TRUE;
- if (TryHarder) return ReadWriteVMDcAttr( dc, Dirty, TRUE);
- }
- return TRUE;
+
+ pdc->prgnVis = prgnDefault;
+ return FALSE;
}
-BOOL
-FASTCALL
-DCU_SynchDcAttrtoUser(HDC hDC, FLONG Dirty)
+
+BOOL APIENTRY
+NtGdiCancelDC(HDC hDC)
{
- PDC pDC = DC_LockDc ( hDC );
- if (!pDC) return FALSE;
- BOOL Ret = DCU_SyncDcAttrtoUser(pDC, Dirty);
- DC_UnlockDc( pDC );
- return Ret;
+ 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
-FASTCALL
-DCU_SyncDcAttrtoW32k(PDC dc, FLONG Dirty)
+APIENTRY
+NtGdiGetDCDword(
+ HDC hDC,
+ UINT u,
+ DWORD *Result)
{
- BOOL TryHarder = FALSE;
- PDC_ATTR Dc_Attr = dc->pDc_Attr;
- if (!Dirty) return FALSE;
- if (!Dc_Attr) return FALSE;
- else
- {
+ BOOL Ret = TRUE;
+ PDC pdc;
+ PDC_ATTR pdcattr;
+
+ DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
- KeEnterCriticalRegion();
- _SEH_TRY
+
+ if (!Result)
{
- ProbeForRead(Dc_Attr,
- sizeof(DC_ATTR),
- 1);
- CopyFromUserDcAttr( dc, Dc_Attr, Dirty);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- _SEH_HANDLE
+
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
{
- Status = _SEH_GetExceptionCode();
+ 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;
+ }
}
- _SEH_END;
- KeLeaveCriticalRegion();
- if(!NT_SUCCESS(Status)) TryHarder = TRUE;
- if (TryHarder) return ReadWriteVMDcAttr( dc, Dirty, FALSE);
- }
- return TRUE;
+
+ DC_UnlockDc(pdc);
+ return Ret;
}
BOOL
-FASTCALL
-DCU_SynchDcAttrtoW32k(HDC hDC, FLONG Dirty)
+APIENTRY
+NtGdiGetAndSetDCDword(
+ HDC hDC,
+ UINT u,
+ DWORD dwIn,
+ DWORD *Result)
{
- PDC pDC = DC_LockDc ( hDC );
- if (!pDC) return FALSE;
- BOOL Ret = DCU_SyncDcAttrtoW32k(pDC, Dirty);
- DC_UnlockDc( pDC );
- return Ret;
-}
+ 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;
+}