[GDI32]
[reactos.git] / reactos / dll / win32 / gdi32 / objects / region.c
index 5cc6382..b8d7077 100644 (file)
@@ -104,31 +104,20 @@ BOOL
 FASTCALL
 DeleteRegion( HRGN hRgn )
 {
-#if 0
   PRGN_ATTR Rgn_Attr;
 
   if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) &&
       ( Rgn_Attr != NULL ))
   {
-     PTEB pTeb = NtCurrentTeb();
-     if (pTeb->Win32ThreadInfo != NULL)
-     {
-        if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
-        {
-           PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
-                                                      pTeb->GdiTebBatch.Offset);
-           pgO->gbHdr.Cmd = GdiBCDelRgn;
-           pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
-           pgO->hgdiobj = (HGDIOBJ)hRgn;
-
-           pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
-           pTeb->GdiBatchCount++;
-           if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
-           return TRUE;
-        }
-     }
+      PGDIBSOBJECT pgO;
+      
+      pgO = GdiAllocBatchCommand(NULL, GdiBCDelRgn);
+      if (pgO)
+      {
+          pgO->hgdiobj = (HGDIOBJ)hRgn;
+          return TRUE;
+      }
   }
-#endif
   return NtGdiDeleteObjectApp((HGDIOBJ) hRgn);
 }
 
@@ -204,7 +193,6 @@ CombineRgn(HRGN  hDest,
            HRGN  hSrc2,
            INT  CombineMode)
 {
-#if 0
   PRGN_ATTR pRgn_Attr_Dest = NULL;
   PRGN_ATTR pRgn_Attr_Src1 = NULL;
   PRGN_ATTR pRgn_Attr_Src2 = NULL;
@@ -218,9 +206,8 @@ CombineRgn(HRGN  hDest,
        !pRgn_Attr_Dest ||
        !pRgn_Attr_Src1 ||
         pRgn_Attr_Src1->Flags > SIMPLEREGION )
-#endif
      return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
-#if 0
+
   /* Handle COPY and use only src1. */
   if ( CombineMode == RGN_COPY )
   {
@@ -274,19 +261,29 @@ CombineRgn(HRGN  hDest,
            DPRINT1("RGN_COPY was handled! CombineMode %d\n",CombineMode);
            return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
         }
+        /* Now handle DIFF. */
+        if ( pRgn_Attr_Src1->Flags == NULLREGION )
+        {
+           if (SetRectRgn( hDest, 0, 0, 0, 0))
+              return NULLREGION;
+           goto ERROR_Exit;
+        }
 
-        if ( pRgn_Attr_Src1->Flags != NULLREGION &&
-             pRgn_Attr_Src2->Flags != NULLREGION )
+        if ( pRgn_Attr_Src2->Flags != NULLREGION )
         {
            Complexity = ComplexityFromRects( &pRgn_Attr_Src1->Rect, &pRgn_Attr_Src2->Rect);
-           /* If same or overlapping and norm just go K. */
-           if (Complexity == SAME_RGN || Complexity == OVERLAPPING_RGN)
-              return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
+
+           if ( Complexity != DIFF_RGN )
+           {
+              if ( Complexity != INVERTED_RGN)
+                 /* If same or overlapping and norm just go K. */
+                 return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
+
+              if (SetRectRgn( hDest, 0, 0, 0, 0))
+                 return NULLREGION;
+              goto ERROR_Exit;
+           }
         }
-        /* Just NULL rgn. */
-        if (SetRectRgn( hDest, 0, 0, 0, 0))
-           return NULLREGION;
-        goto ERROR_Exit;
      }
      else /* Handle OR or XOR. */
      {
@@ -389,7 +386,6 @@ ERROR_Exit:
   /* Even on error the flag is set dirty and force server side to redraw. */
   pRgn_Attr_Dest->AttrFlags |= ATTR_RGN_DIRTY;
   return ERROR;
-#endif
 }
 
 /*
@@ -574,8 +570,110 @@ INT
 WINAPI
 ExtSelectClipRgn( IN HDC hdc, IN HRGN hrgn, IN INT iMode)
 {
-    /* FIXME some part need be done on user mode size */
-    return NtGdiExtSelectClipRgn(hdc,hrgn, iMode);
+  INT Ret;
+  HRGN NewRgn = NULL;
+
+#if 0
+// Handle something other than a normal dc object.
+  if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
+  {
+    if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
+      return MFDRV_ExtSelectClipRgn( hdc, );
+    else
+    {
+      PLDC pLDC = GdiGetLDC(hdc);
+      if ( pLDC )
+      {
+         if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExtSelectClipRgn( hdc, ))
+             return NtGdiExtSelectClipRgn(hdc, );
+      }
+      else
+        SetLastError(ERROR_INVALID_HANDLE);
+      return ERROR;
+    }
+  }
+#endif
+#if 0
+  if ( hrgn )
+  {
+     if ( GetLayout(hdc) & LAYOUT_RTL )
+     {
+        if ( MirrorRgnDC(hdc, hrgn, &NewRgn) )
+        {
+           if ( NewRgn ) hrgn = NewRgn;
+        }
+     }
+  }
+#endif
+  /* Batch handles RGN_COPY only! */
+  if (iMode == RGN_COPY)
+  {
+#if 0
+     PDC_ATTR pDc_Attr;
+     PRGN_ATTR pRgn_Attr = NULL;
+
+     /* hrgn can be NULL unless the RGN_COPY mode is specified. */
+     if (hrgn)
+        GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr);
+
+     if ( GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr) &&
+          pDc_Attr )
+     {
+        PGDI_TABLE_ENTRY pEntry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hdc);
+        PTEB pTeb = NtCurrentTeb();
+        
+        if ( pTeb->Win32ThreadInfo != NULL &&
+             pTeb->GdiTebBatch.HDC == hdc &&
+            !(pDc_Attr->ulDirty_ & DC_DIBSECTION) &&
+            !(pEntry->Flags & GDI_ENTRY_VALIDATE_VIS) )
+        {
+           if (!hrgn ||
+                (hrgn && pRgn_Attr && pRgn_Attr->Flags <= SIMPLEREGION) )
+           {
+              if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSEXTSELCLPRGN)) <= GDIBATCHBUFSIZE)
+              {
+                 PGDIBSEXTSELCLPRGN pgO = (PGDIBSEXTSELCLPRGN)(&pTeb->GdiTebBatch.Buffer[0] +
+                                                      pTeb->GdiTebBatch.Offset);
+                 pgO->gbHdr.Cmd = GdiBCExtSelClipRgn;
+                 pgO->gbHdr.Size = sizeof(GDIBSEXTSELCLPRGN);
+                 pgO->fnMode = iMode;
+
+                 if ( hrgn && pRgn_Attr )
+                 {
+                    Ret = pRgn_Attr->Flags;
+
+                    if ( pDc_Attr->VisRectRegion.Rect.left   >= pRgn_Attr->Rect.right  ||
+                         pDc_Attr->VisRectRegion.Rect.top    >= pRgn_Attr->Rect.bottom ||
+                         pDc_Attr->VisRectRegion.Rect.right  <= pRgn_Attr->Rect.left   ||
+                         pDc_Attr->VisRectRegion.Rect.bottom <= pRgn_Attr->Rect.top )
+                       Ret = NULLREGION;
+
+                    pgO->left   = pRgn_Attr->Rect.left;
+                    pgO->top    = pRgn_Attr->Rect.top;
+                    pgO->right  = pRgn_Attr->Rect.right;
+                    pgO->bottom = pRgn_Attr->Rect.bottom;
+                 }
+                 else
+                 {
+                    Ret = pDc_Attr->VisRectRegion.Flags;
+                    pgO->fnMode |= 0x80000000; // Set no hrgn mode.
+                 }
+                 pTeb->GdiTebBatch.Offset += sizeof(GDIBSEXTSELCLPRGN);
+                 pTeb->GdiBatchCount++;
+                 if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
+                 if ( NewRgn ) DeleteObject(NewRgn);
+                 return Ret;
+              }
+           }
+        }
+     }
+#endif
+  }
+  Ret = NtGdiExtSelectClipRgn(hdc, hrgn, iMode);
+
+  if ( NewRgn ) DeleteObject(NewRgn);
+
+  return Ret;
 }
 
 /*
@@ -634,13 +732,11 @@ WINAPI
 GetRgnBox(HRGN hrgn,
           LPRECT prcOut)
 {
-#if 0
   PRGN_ATTR Rgn_Attr;
 
   if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr))
-#endif
      return NtGdiGetRgnBox(hrgn, prcOut);
-#if 0
+
   if (Rgn_Attr->Flags == NULLREGION)
   {
      prcOut->left   = 0;
@@ -656,7 +752,6 @@ GetRgnBox(HRGN hrgn,
      RtlCopyMemory( prcOut, &Rgn_Attr->Rect, sizeof(RECT));
   }
   return Rgn_Attr->Flags;
-#endif
 }
 
 /*
@@ -747,14 +842,12 @@ OffsetRgn( HRGN hrgn,
           int nXOffset,
           int nYOffset)
 {
-#if 0
   PRGN_ATTR pRgn_Attr;
   int nLeftRect, nTopRect, nRightRect, nBottomRect;
 
   if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
-#endif
      return NtGdiOffsetRgn(hrgn,nXOffset,nYOffset);
-#if 0
+
   if ( pRgn_Attr->Flags == NULLREGION)
      return pRgn_Attr->Flags;
 
@@ -792,7 +885,6 @@ OffsetRgn( HRGN hrgn,
      }
   }
   return pRgn_Attr->Flags;
-#endif
 }
 
 /*
@@ -804,13 +896,11 @@ PtInRegion(IN HRGN hrgn,
            int x,
            int y)
 {
-#if 0
   PRGN_ATTR pRgn_Attr;
 
   if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
-#endif
      return NtGdiPtInRegion(hrgn,x,y);
-#if 0
+
   if ( pRgn_Attr->Flags == NULLREGION)
      return FALSE;
 
@@ -818,7 +908,6 @@ PtInRegion(IN HRGN hrgn,
      return NtGdiPtInRegion(hrgn,x,y);
 
   return INRECT( pRgn_Attr->Rect, x, y);
-#endif
 }
 
 /*
@@ -829,14 +918,12 @@ WINAPI
 RectInRegion(HRGN hrgn,
              LPCRECT prcl)
 {
-#if 0
   PRGN_ATTR pRgn_Attr;
   RECTL rc;
 
   if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr))
-#endif
      return NtGdiRectInRegion(hrgn, (LPRECT) prcl);
-#if 0
+
   if ( pRgn_Attr->Flags == NULLREGION)
      return FALSE;
 
@@ -870,7 +957,6 @@ RectInRegion(HRGN hrgn,
      return TRUE;
 
   return FALSE;
-#endif
 }
 
 /*
@@ -896,13 +982,11 @@ SetRectRgn(HRGN hrgn,
            int nRightRect,
            int nBottomRect)
 {
-#if 0
   PRGN_ATTR Rgn_Attr;
 
   if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr))
-#endif
      return NtGdiSetRectRgn(hrgn, nLeftRect, nTopRect, nRightRect, nBottomRect);
-#if 0
+
   if ((nLeftRect == nRightRect) || (nTopRect == nBottomRect))
   {
      Rgn_Attr->AttrFlags |= ATTR_RGN_DIRTY;
@@ -931,7 +1015,6 @@ SetRectRgn(HRGN hrgn,
   Rgn_Attr->AttrFlags |= ATTR_RGN_DIRTY ;
   Rgn_Attr->Flags = SIMPLEREGION;
   return TRUE;
-#endif
 }
 
 /*