[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / subsystems / win32 / win32k / objects / dcutil.c
index a45f2ab..0471c7d 100644 (file)
 
-#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;
+}