[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / region.c
index 9a26749..99698c0 100644 (file)
@@ -2032,9 +2032,19 @@ REGION_AllocRgnWithHandle(INT nReg)
     HRGN hReg;
     PROSRGNDATA pReg;
 
-    pReg = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
-    if(!pReg)
+    pReg = (PROSRGNDATA)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE,
+                                              sizeof(REGION),
+                                              BASEFLAG_LOOKASIDE);
+    if (!pReg)
     {
+        DPRINT1("Could not allocate a palette.\n");
+        return NULL;
+    }
+
+    if (!GDIOBJ_hInsertObject(&pReg->BaseObject, GDI_OBJ_HMGR_POWNED))
+    {
+        DPRINT1("Could not insert palette into handle table.\n");
+        GDIOBJ_vFreeObject(&pReg->BaseObject);
         return NULL;
     }
 
@@ -2051,8 +2061,8 @@ REGION_AllocRgnWithHandle(INT nReg)
         pReg->Buffer = ExAllocatePoolWithTag(PagedPool, nReg * sizeof(RECT), TAG_REGION);
         if (!pReg->Buffer)
         {
-            RGNOBJAPI_Unlock(pReg);
-            GDIOBJ_FreeObjByHandle(hReg, GDI_OBJECT_TYPE_REGION);
+            DPRINT1("Could not allocate region buffer\n");
+            GDIOBJ_vDeleteObject(&pReg->BaseObject);
             return NULL;
         }
     }
@@ -2061,10 +2071,36 @@ REGION_AllocRgnWithHandle(INT nReg)
     pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
     pReg->rdh.nCount = nReg;
     pReg->rdh.nRgnSize = nReg * sizeof(RECT);
+    pReg->prgnattr = &pReg->rgnattr;
 
     return pReg;
 }
 
+BOOL
+NTAPI
+REGION_bAllocRgnAttr(PREGION prgn)
+{
+    PPROCESSINFO ppi;
+    PRGN_ATTR prgnattr;
+
+    ppi = PsGetCurrentProcessWin32Process();
+    ASSERT(ppi);
+
+    prgnattr = GdiPoolAllocate(ppi->pPoolRgnAttr);
+    if (!prgnattr)
+    {
+        DPRINT1("Could not allocate RGN attr\n");
+        return FALSE;
+    }
+
+    /* Set the object attribute in the handle table */
+    prgn->prgnattr = prgnattr;
+    GDIOBJ_vSetObjectAttr(&prgn->BaseObject, prgnattr);
+
+    return TRUE;
+}
+
+
 //
 // Allocate User Space Region Handle.
 //
@@ -2072,34 +2108,31 @@ PROSRGNDATA
 FASTCALL
 REGION_AllocUserRgnWithHandle(INT nRgn)
 {
-    PROSRGNDATA pRgn;
-    PGDI_TABLE_ENTRY Entry;
+    PREGION prgn;
+
+    prgn = REGION_AllocRgnWithHandle(nRgn);
+    if (!prgn)
+    {
+        return NULL;
+    }
 
-    pRgn = REGION_AllocRgnWithHandle(nRgn);
-    if (pRgn)
+    if (!REGION_bAllocRgnAttr(prgn))
     {
-       Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, pRgn->BaseObject.hHmgr);
-       Entry->UserData = AllocateObjectAttr();
-       RtlZeroMemory(Entry->UserData, sizeof(RGN_ATTR));
+        ASSERT(FALSE);
     }
-    return pRgn;
+
+    return prgn;
 }
 
-PROSRGNDATA
-FASTCALL
-RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
+VOID
+NTAPI
+REGION_vSyncRegion(PREGION pRgn)
 {
-  PGDI_TABLE_ENTRY Entry;
-  PRGN_ATTR pRgn_Attr;
-  BOOL Hit = FALSE;
-  PROSRGNDATA pRgn = NULL;
-
-  pRgn = REGION_LockRgn(hRgn);
+  PRGN_ATTR pRgn_Attr = NULL;
 
-  if (pRgn && GDIOBJ_OwnedByCurrentProcess(hRgn))
+  if (pRgn && pRgn->prgnattr != &pRgn->rgnattr)
   {
-     Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, hRgn);
-     pRgn_Attr = Entry->UserData;
+     pRgn_Attr = GDIOBJ_pvGetObjectAttr(&pRgn->BaseObject);
 
      if ( pRgn_Attr )
      {
@@ -2126,30 +2159,29 @@ RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
                  pRgn_Attr->AttrFlags &= ~ATTR_RGN_DIRTY;
               }
            }
-           else
-           { // This object is cached an waiting for it's resurrection by the users.
-              Hit = TRUE;
-           }
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
         }
         _SEH2_END;
-
-        if (Hit)
-        {
-           REGION_UnlockRgn(pRgn);
-           return NULL;
-        }
-        if (ppRgn_Attr)
-           *ppRgn_Attr = pRgn_Attr;
-     }
-     else
-     {
-        if (ppRgn_Attr)
-           *ppRgn_Attr = NULL;
      }
   }
+
+}
+
+PROSRGNDATA
+FASTCALL
+RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
+{
+  PROSRGNDATA pRgn = NULL;
+
+  pRgn = REGION_LockRgn(hRgn);
+
+  REGION_vSyncRegion(pRgn);
+
+  if (ppRgn_Attr)
+     *ppRgn_Attr = pRgn->prgnattr;
+
   return pRgn;
 }
 
@@ -2157,13 +2189,11 @@ VOID
 FASTCALL
 RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
 {
-  PGDI_TABLE_ENTRY Entry;
   PRGN_ATTR pRgn_Attr;
 
-  if (pRgn && GDIOBJ_OwnedByCurrentProcess(pRgn->BaseObject.hHmgr))
+  if (pRgn && GreGetObjectOwner(pRgn->BaseObject.hHmgr) == GDI_OBJ_HMGR_POWNED)
   {
-     Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, pRgn->BaseObject.hHmgr);
-     pRgn_Attr = Entry->UserData;
+     pRgn_Attr = GDIOBJ_pvGetObjectAttr(&pRgn->BaseObject);
 
      if ( pRgn_Attr )
      {
@@ -2199,42 +2229,69 @@ PROSRGNDATA
 FASTCALL
 IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
 {
-  PROSRGNDATA pRgn;
+    PREGION prgn;
 
-  pRgn = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
-  if (!pRgn)
-  {
-     return NULL;
-  }
-  pRgn->Buffer = &pRgn->rdh.rcBound;
-  REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
-  REGION_UnlockRgn(pRgn);
-  return pRgn;
+    /* Allocate a region, witout a handle */
+    prgn = (PREGION)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE, sizeof(REGION), 0);
+    if (!prgn)
+    {
+        return NULL;
+    }
+
+    /* Initialize it */
+    prgn->Buffer = &prgn->rdh.rcBound;
+    prgn->prgnattr = &prgn->rgnattr;
+    REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
+
+    return prgn;
 }
 
 HRGN
 FASTCALL
 IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
 {
-  PROSRGNDATA pRgn = IntSysCreateRectpRgn(LeftRect,TopRect,RightRect,BottomRect);
-  return (pRgn ? pRgn->BaseObject.hHmgr : NULL);
+    PREGION prgn;
+    HRGN hrgn;
+
+    /* Allocate a region, witout a handle */
+    prgn = (PREGION)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION, sizeof(REGION));
+    if (!prgn)
+    {
+        return NULL;
+    }
+
+    /* Initialize it */
+    prgn->Buffer = &prgn->rdh.rcBound;
+    REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
+    hrgn = prgn->BaseObject.hHmgr;
+    prgn->prgnattr = &prgn->rgnattr;
+
+    REGION_UnlockRgn(prgn);
+
+    return hrgn;
 }
 
 BOOL INTERNAL_CALL
 REGION_Cleanup(PVOID ObjectBody)
 {
     PROSRGNDATA pRgn = (PROSRGNDATA)ObjectBody;
+    PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+    ASSERT(ppi);
+
+    ASSERT(pRgn->prgnattr);
+    if (pRgn->prgnattr != &pRgn->rgnattr)
+        GdiPoolFree(ppi->pPoolRgnAttr, pRgn->prgnattr);
+
     if (pRgn->Buffer && pRgn->Buffer != &pRgn->rdh.rcBound)
         ExFreePoolWithTag(pRgn->Buffer, TAG_REGION);
     return TRUE;
 }
 
-// use REGION_FreeRgnByHandle(hRgn); for systems regions.
 VOID FASTCALL
 REGION_Delete(PROSRGNDATA pRgn)
 {
   if ( pRgn == prgnDefault) return;
-  REGION_FreeRgn(pRgn);
+  GDIOBJ_vDeleteObject(&pRgn->BaseObject);
 }
 
 VOID FASTCALL
@@ -2298,28 +2355,27 @@ BOOL
 FASTCALL
 IntGdiSetRegionOwner(HRGN hRgn, DWORD OwnerMask)
 {
-  INT Index;
-  PGDI_TABLE_ENTRY Entry;
-/*
-  System Regions:
-     These regions do not use attribute sections and when allocated, use gdiobj
-     level functions.
- */
-  // FIXME! HAX!!! Remove this once we get everything right!
-  Index = GDI_HANDLE_GET_INDEX(hRgn);
-  Entry = &GdiHandleTable->Entries[Index];
-  if (Entry->UserData) FreeObjectAttr(Entry->UserData);
-  Entry->UserData = NULL;
-  //
-  if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
-  {
-     return GDIOBJ_SetOwnership(hRgn, NULL);
-  }
-  if (OwnerMask == GDI_OBJ_HMGR_POWNED)
-  {
-     return GDIOBJ_SetOwnership((HGDIOBJ) hRgn, PsGetCurrentProcess() );
-  }
-  return FALSE;
+    PREGION prgn;
+    PRGN_ATTR prgnattr;
+    PPROCESSINFO ppi;
+
+    prgn = REGION_LockRgn(hRgn);
+    if (!prgn)
+    {
+        return FALSE;
+    }
+
+    prgnattr = GDIOBJ_pvGetObjectAttr(&prgn->BaseObject);
+    if (prgnattr)
+    {
+        GDIOBJ_vSetObjectAttr(&prgn->BaseObject, NULL);
+        prgn->prgnattr = NULL;
+        ppi = PsGetCurrentProcessWin32Process();
+        GdiPoolFree(ppi->pPoolRgnAttr, prgnattr);
+    }
+    RGNOBJAPI_Unlock(prgn);
+
+     return GreSetObjectOwner(hRgn, OwnerMask);
 }
 
 INT
@@ -2366,6 +2422,7 @@ IntGdiCombineRgn(PROSRGNDATA destRgn,
            {
               DPRINT1("IntGdiCombineRgn requires hSrc2 != NULL for combine mode %d!\n", CombineMode);
               EngSetLastError(ERROR_INVALID_HANDLE);
+              ASSERT(FALSE);
            }
         }
      }
@@ -2447,7 +2504,7 @@ IntGdiPaintRgn(
     if (!REGION_LPTODP(dc, tmpVisRgn, hRgn) ||
          NtGdiOffsetRgn(tmpVisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
     {
-        REGION_FreeRgnByHandle(tmpVisRgn);
+        GreDeleteObject(tmpVisRgn);
         return FALSE;
     }
 
@@ -2456,7 +2513,7 @@ IntGdiPaintRgn(
     visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL);
     if (visrgn == NULL)
     {
-        REGION_FreeRgnByHandle(tmpVisRgn);
+        GreDeleteObject(tmpVisRgn);
         return FALSE;
     }
 
@@ -2477,7 +2534,7 @@ IntGdiPaintRgn(
                        0xFFFF);//FIXME:don't know what to put here
 
     RGNOBJAPI_Unlock(visrgn);
-    REGION_FreeRgnByHandle(tmpVisRgn);
+    GreDeleteObject(tmpVisRgn);
 
     // Fill the region
     return bRet;
@@ -3271,46 +3328,55 @@ IntRectInRegion(
 //
 INT
 APIENTRY
-NtGdiCombineRgn(HRGN  hDest,
-                HRGN  hSrc1,
-                HRGN  hSrc2,
-                INT  CombineMode)
+NtGdiCombineRgn(
+    IN HRGN hrgnDst,
+    IN HRGN hrgnSrc1,
+    IN HRGN hrgnSrc2,
+    IN INT iMode)
 {
-  INT result = ERROR;
-  PROSRGNDATA destRgn, src1Rgn, src2Rgn = NULL;
-
-  if ( CombineMode > RGN_COPY && CombineMode < RGN_AND)
-  {
-     EngSetLastError(ERROR_INVALID_PARAMETER);
-     return ERROR;
-  }
+    HRGN ahrgn[3];
+    PREGION aprgn[3];
+    INT iResult;
 
-  destRgn = RGNOBJAPI_Lock(hDest, NULL);
-  if (!destRgn)
-  {
-     EngSetLastError(ERROR_INVALID_HANDLE);
-     return ERROR;
-  }
+    if (iMode < RGN_AND || iMode > RGN_COPY)
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return ERROR;
+    }
 
-  src1Rgn = RGNOBJAPI_Lock(hSrc1, NULL);
-  if (!src1Rgn)
-  {
-     RGNOBJAPI_Unlock(destRgn);
-     EngSetLastError(ERROR_INVALID_HANDLE);
-     return ERROR;
-  }
+    if (!hrgnDst || !hrgnSrc1 || (iMode != RGN_COPY && !hrgnSrc2))
+    {
+        DPRINT1("NtGdiCombineRgn: %p, %p, %p, %d\n",
+                hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return ERROR;
+    }
 
-  if (hSrc2)
-     src2Rgn = RGNOBJAPI_Lock(hSrc2, NULL);
+    /* Lock all regions */
+    ahrgn[0] = hrgnDst;
+    ahrgn[1] = hrgnSrc1;
+    ahrgn[2] = iMode != RGN_COPY ? hrgnSrc2 : NULL;
+    if (!GDIOBJ_bLockMultipleObjects(3, ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
+    {
+        DPRINT1("NtGdiCombineRgn: %p, %p, %p, %d\n",
+                hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return ERROR;
+    }
 
-  result = IntGdiCombineRgn( destRgn, src1Rgn, src2Rgn, CombineMode);
+    /* HACK: Sync usermode attributes */
+    REGION_vSyncRegion(aprgn[0]);
+    REGION_vSyncRegion(aprgn[1]);
+    if (aprgn[2]) REGION_vSyncRegion(aprgn[2]);
 
-  if (src2Rgn)
-     RGNOBJAPI_Unlock(src2Rgn);
-  RGNOBJAPI_Unlock(src1Rgn);
-  RGNOBJAPI_Unlock(destRgn);
+    /* Call the internal function */
+    iResult = IntGdiCombineRgn(aprgn[0], aprgn[1], aprgn[2], iMode);
 
-  return result;
+    /* Cleanup and return */
+    REGION_UnlockRgn(aprgn[0]);
+    REGION_UnlockRgn(aprgn[1]);
+    if (aprgn[2]) REGION_UnlockRgn(aprgn[2]);
+    return iResult;
 }
 
 HRGN
@@ -3678,13 +3744,13 @@ NtGdiFrameRgn(
     }
     if (!REGION_CreateFrameRgn(FrameRgn, hRgn, Width, Height))
     {
-        REGION_FreeRgnByHandle(FrameRgn);
+        GreDeleteObject(FrameRgn);
         return FALSE;
     }
 
     Ret = NtGdiFillRgn(hDC, FrameRgn, hBrush);
 
-    REGION_FreeRgnByHandle(FrameRgn);
+    GreDeleteObject(FrameRgn);
     return Ret;
 }