-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-/*
- * DC device-independent Get/SetXXX functions
- * (RJJ) swiped from WINE
- */
-
-#define DC_GET_VAL( func_type, func_name, dc_field ) \
-func_type APIENTRY func_name( HDC hdc ) \
-{ \
- func_type ft; \
- PDC dc = DC_LockDc( hdc ); \
- PDC_ATTR Dc_Attr; \
- if (!dc) \
- { \
- SetLastWin32Error(ERROR_INVALID_HANDLE); \
- return 0; \
- } \
- Dc_Attr = dc->pDc_Attr; \
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
- ft = Dc_Attr->dc_field; \
- DC_UnlockDc(dc); \
- return ft; \
-}
+COLORREF FASTCALL
+IntGdiSetBkColor(HDC hDC, COLORREF color)
+{
+ COLORREF oldColor;
+ PDC dc;
+ PDC_ATTR pdcattr;
+ HBRUSH hBrush;
-/* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
- * important that the function has the right signature, for the implementation
- * we can do whatever we want.
- */
-#define DC_GET_VAL_EX( FuncName, ret_x, ret_y, type, ax, ay ) \
-VOID FASTCALL Int##FuncName ( PDC dc, LP##type pt) \
-{ \
- PDC_ATTR Dc_Attr; \
- ASSERT(dc); \
- ASSERT(pt); \
- Dc_Attr = dc->pDc_Attr; \
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
- pt->ax = Dc_Attr->ret_x; \
- pt->ay = Dc_Attr->ret_y; \
+ 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;
}
-#if 0
-BOOL APIENTRY NtGdi##FuncName ( HDC hdc, LP##type pt ) \
-{ \
- NTSTATUS Status = STATUS_SUCCESS; \
- type Safept; \
- PDC dc; \
- if(!pt) \
- { \
- SetLastWin32Error(ERROR_INVALID_PARAMETER); \
- return FALSE; \
- } \
- if(!(dc = DC_LockDc(hdc))) \
- { \
- SetLastWin32Error(ERROR_INVALID_HANDLE); \
- return FALSE; \
- } \
- Int##FuncName( dc, &Safept); \
- DC_UnlockDc(dc); \
- _SEH2_TRY \
- { \
- ProbeForWrite(pt, \
- sizeof( type ), \
- 1); \
- *pt = Safept; \
- } \
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
- { \
- Status = _SEH2_GetExceptionCode(); \
- } \
- _SEH2_END; \
- if(!NT_SUCCESS(Status)) \
- { \
- SetLastNtError(Status); \
- return FALSE; \
- } \
- return TRUE; \
-}
-#endif
+INT FASTCALL
+IntGdiSetBkMode(HDC hDC, INT Mode)
+{
+ COLORREF oldMode;
+ PDC dc;
+ PDC_ATTR pdcattr;
-#define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
-INT APIENTRY func_name( HDC hdc, INT mode ) \
-{ \
- INT prevMode; \
- PDC dc; \
- PDC_ATTR Dc_Attr; \
- if ((mode < min_val) || (mode > max_val)) \
- { \
- SetLastWin32Error(ERROR_INVALID_PARAMETER); \
- return 0; \
- } \
- dc = DC_LockDc ( hdc ); \
- if ( !dc ) \
- { \
- SetLastWin32Error(ERROR_INVALID_HANDLE); \
- return 0; \
- } \
- Dc_Attr = dc->pDc_Attr; \
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
- prevMode = Dc_Attr->dc_field; \
- Dc_Attr->dc_field = mode; \
- DC_UnlockDc ( dc ); \
- return prevMode; \
+ 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
-VOID
-CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr)
+UINT
+FASTCALL
+IntGdiSetTextAlign(HDC hDC,
+ UINT Mode)
{
- NTSTATUS Status = STATUS_SUCCESS;
- dc->Dc_Attr.mxWorldToDevice = dc->DcLevel.mxWorldToDevice;
- dc->Dc_Attr.mxDeviceToWorld = dc->DcLevel.mxDeviceToWorld;
- dc->Dc_Attr.mxWorldToPage = dc->DcLevel.mxWorldToPage;
-
- _SEH2_TRY
- {
- ProbeForWrite( Dc_Attr,
- sizeof(DC_ATTR),
- 1);
- RtlCopyMemory( Dc_Attr,
- &dc->Dc_Attr,
- sizeof(DC_ATTR));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
+ 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;
-BOOL
+ 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_SyncDcAttrtoUser(PDC dc)
+DCU_SetDcUndeletable(HDC hDC)
{
- PDC_ATTR Dc_Attr = dc->pDc_Attr;
+ PDC dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return;
+ }
- if (Dc_Attr == ((PDC_ATTR)&dc->Dc_Attr)) return TRUE; // No need to copy self.
+ dc->fs |= DC_FLAG_PERMANENT;
+ DC_UnlockDc(dc);
+ return;
+}
- if (!Dc_Attr) return FALSE;
- else
- CopytoUserDcAttr( dc, Dc_Attr);
- return TRUE;
+#if 0
+BOOL FASTCALL
+IntIsPrimarySurface(SURFOBJ *SurfObj)
+{
+ if (PrimarySurface.pSurface == NULL)
+ {
+ return FALSE;
+ }
+ return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
}
+#endif
BOOL
FASTCALL
-DCU_SynchDcAttrtoUser(HDC hDC)
+IntSetDefaultRegion(PDC pdc)
{
- BOOL Ret;
- PDC pDC = DC_LockDc ( hDC );
- if (!pDC) return FALSE;
- Ret = DCU_SyncDcAttrtoUser(pDC);
- DC_UnlockDc( pDC );
- return Ret;
-}
+ PSURFACE pSurface;
+ PROSRGNDATA prgn;
+ RECTL rclWnd, rclClip;
+ IntGdiReleaseRaoRgn(pdc);
-DC_GET_VAL( INT, IntGdiGetMapMode, iMapMode )
-DC_GET_VAL( INT, IntGdiGetPolyFillMode, jFillMode )
-DC_GET_VAL( COLORREF, IntGdiGetBkColor, crBackgroundClr )
-DC_GET_VAL( INT, IntGdiGetBkMode, jBkMode )
-DC_GET_VAL( INT, IntGdiGetROP2, jROP2 )
-DC_GET_VAL( INT, IntGdiGetStretchBltMode, jStretchBltMode )
-DC_GET_VAL( UINT, IntGdiGetTextAlign, lTextAlign )
-DC_GET_VAL( COLORREF, IntGdiGetTextColor, crForegroundClr )
+ rclWnd.left = 0;
+ rclWnd.top = 0;
+ rclWnd.right = pdc->dclevel.sizl.cx;
+ rclWnd.bottom = pdc->dclevel.sizl.cy;
+ rclClip = rclWnd;
-DC_GET_VAL_EX( GetViewportOrgEx, ptlViewportOrg.x, ptlViewportOrg.y, POINT, x, y )
-DC_GET_VAL_EX( GetWindowExtEx, szlWindowExt.cx, szlWindowExt.cy, SIZE, cx, cy )
-DC_GET_VAL_EX( GetWindowOrgEx, ptlWindowOrg.x, ptlWindowOrg.y, POINT, x, y )
+// 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);
-DC_SET_MODE( IntGdiSetPolyFillMode, jFillMode, ALTERNATE, WINDING )
-DC_SET_MODE( IntGdiSetROP2, jROP2, R2_BLACK, R2_WHITE )
-DC_SET_MODE( IntGdiSetStretchBltMode, jStretchBltMode, BLACKONWHITE, HALFTONE )
+ 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;
+ }
-COLORREF FASTCALL
-IntGdiSetBkColor(HDC hDC, COLORREF color)
-{
- COLORREF oldColor;
- PDC dc;
- PDC_ATTR Dc_Attr;
- HBRUSH hBrush;
-
- if (!(dc = DC_LockDc(hDC)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return CLR_INVALID;
- }
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- oldColor = Dc_Attr->crBackgroundClr;
- Dc_Attr->crBackgroundClr = color;
- Dc_Attr->ulBackgroundClr = (ULONG)color;
- Dc_Attr->ulDirty_ &= ~(DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
- hBrush = Dc_Attr->hbrush;
- DC_UnlockDc(dc);
- NtGdiSelectBrush(hDC, hBrush);
- return oldColor;
+ pdc->prgnVis = prgnDefault;
+ return FALSE;
}
-INT FASTCALL
-IntGdiSetBkMode(HDC hDC, INT Mode)
+
+BOOL APIENTRY
+NtGdiCancelDC(HDC hDC)
{
- COLORREF oldMode;
- PDC dc;
- PDC_ATTR Dc_Attr;
-
- if (!(dc = DC_LockDc(hDC)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return CLR_INVALID;
- }
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- oldMode = Dc_Attr->lBkMode;
- Dc_Attr->jBkMode = Mode;
- Dc_Attr->lBkMode = Mode;
- DC_UnlockDc(dc);
- return oldMode;
+ UNIMPLEMENTED;
+ return FALSE;
}
-UINT
-FASTCALL
-IntGdiSetTextAlign(HDC hDC,
- UINT Mode)
+
+WORD APIENTRY
+IntGdiSetHookFlags(HDC hDC, WORD Flags)
{
- UINT prevAlign;
- DC *dc;
- PDC_ATTR Dc_Attr;
+ WORD wRet;
+ DC *dc = DC_LockDc(hDC);
- dc = DC_LockDc(hDC);
- if (!dc)
+ if (NULL == dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return GDI_ERROR;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
}
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- prevAlign = Dc_Attr->lTextAlign;
- Dc_Attr->lTextAlign = Mode;
- DC_UnlockDc( dc );
- return prevAlign;
+
+ 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;
}
-COLORREF
-FASTCALL
-IntGdiSetTextColor(HDC hDC,
- COLORREF color)
+
+BOOL
+APIENTRY
+NtGdiGetDCDword(
+ HDC hDC,
+ UINT u,
+ DWORD *Result)
{
- COLORREF oldColor;
- PDC dc = DC_LockDc(hDC);
- PDC_ATTR Dc_Attr;
- HBRUSH hBrush;
-
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return CLR_INVALID;
- }
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- oldColor = Dc_Attr->crForegroundClr;
- Dc_Attr->crForegroundClr = color;
- hBrush = Dc_Attr->hbrush;
- Dc_Attr->ulDirty_ &= ~(DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
- DC_UnlockDc( dc );
- NtGdiSelectBrush(hDC, hBrush);
- return oldColor;
+ 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;
}
-VOID
-FASTCALL
-DCU_SetDcUndeletable(HDC hDC)
+BOOL
+APIENTRY
+NtGdiGetAndSetDCDword(
+ HDC hDC,
+ UINT u,
+ DWORD dwIn,
+ DWORD *Result)
{
- PDC dc = DC_LockDc(hDC);
- if (!dc)
+ 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)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return;
+ _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->DC_Flags |= DC_FLAG_PERMANENT;
- DC_UnlockDc( dc );
- return;
+ DC_UnlockDc(pdc);
+ return Ret;
}