-#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 STDCALL 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;
+
+ 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;
}
-/* 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; \
-} \
-BOOL STDCALL 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); \
- _SEH_TRY \
- { \
- ProbeForWrite(pt, \
- sizeof( type ), \
- 1); \
- *pt = Safept; \
- } \
- _SEH_HANDLE \
- { \
- Status = _SEH_GetExceptionCode(); \
- } \
- _SEH_END; \
- if(!NT_SUCCESS(Status)) \
- { \
- SetLastNtError(Status); \
- return FALSE; \
- } \
- return TRUE; \
+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;
}
-#define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
-INT STDCALL 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; \
+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;
+}
-static
VOID
-CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr)
+FASTCALL
+DCU_SetDcUndeletable(HDC hDC)
{
- XForm2MatrixS( &dc->Dc_Attr.mxWorldToDevice, &dc->w.xformWorld2Vport);
- XForm2MatrixS( &dc->Dc_Attr.mxDevicetoWorld, &dc->w.xformVport2World);
- XForm2MatrixS( &dc->Dc_Attr.mxWorldToPage, &dc->w.xformWorld2Wnd);
- MmCopyToCaller(Dc_Attr, &dc->Dc_Attr, sizeof(DC_ATTR));
+ 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
-DCU_SyncDcAttrtoUser(PDC dc)
+IntSetDefaultRegion(PDC pdc)
{
- PDC_ATTR Dc_Attr = dc->pDc_Attr;
-
- if (Dc_Attr == ((PDC_ATTR)&dc->Dc_Attr)) return TRUE; // No need to copy self.
-
- if (!Dc_Attr) return FALSE;
- else
- CopytoUserDcAttr( dc, Dc_Attr);
- return TRUE;
+ 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
-FASTCALL
-DCU_SynchDcAttrtoUser(HDC hDC)
+
+BOOL APIENTRY
+NtGdiCancelDC(HDC hDC)
{
- PDC pDC = DC_LockDc ( hDC );
- if (!pDC) return FALSE;
- BOOL Ret = DCU_SyncDcAttrtoUser(pDC);
- DC_UnlockDc( pDC );
- return Ret;
+ UNIMPLEMENTED;
+ return FALSE;
}
-DC_GET_VAL( INT, NtGdiGetMapMode, iMapMode )
-DC_GET_VAL( INT, NtGdiGetPolyFillMode, jFillMode )
-DC_GET_VAL( COLORREF, NtGdiGetBkColor, crBackgroundClr )
-DC_GET_VAL( INT, NtGdiGetBkMode, jBkMode )
-DC_GET_VAL( INT, NtGdiGetROP2, jROP2 )
-DC_GET_VAL( INT, NtGdiGetStretchBltMode, jStretchBltMode )
-DC_GET_VAL( UINT, NtGdiGetTextAlign, lTextAlign )
-DC_GET_VAL( COLORREF, NtGdiGetTextColor, crForegroundClr )
+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!
-DC_GET_VAL_EX( GetViewportExtEx, szlViewportExt.cx, szlViewportExt.cy, SIZE, cx, cy )
-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 )
-DC_GET_VAL_EX ( GetCurrentPositionEx, ptlCurrent.x, ptlCurrent.y, POINT, x, y )
+ /* "Undocumented Windows" info is slightly confusing.
+ */
-DC_SET_MODE( NtGdiSetBkMode, jBkMode, TRANSPARENT, OPAQUE )
-DC_SET_MODE( NtGdiSetPolyFillMode, jFillMode, ALTERNATE, WINDING )
-DC_SET_MODE( NtGdiSetROP2, jROP2, R2_BLACK, R2_WHITE )
-DC_SET_MODE( NtGdiSetStretchBltMode, jStretchBltMode, BLACKONWHITE, HALFTONE )
+ 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);
-COLORREF STDCALL
-NtGdiSetBkColor(HDC hDC, COLORREF color)
+ return wRet;
+}
+
+
+BOOL
+APIENTRY
+NtGdiGetDCDword(
+ HDC hDC,
+ UINT u,
+ DWORD *Result)
{
- 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;
- hBrush = Dc_Attr->hbrush;
- DC_UnlockDc(dc);
- NtGdiSelectObject(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;
}
+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;
+}