[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / brush.c
index 72b7fd3..f72d7d1 100644 (file)
@@ -35,180 +35,80 @@ static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
     {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E}  /* HS_DIAGCROSS  */
 };
 
-
-PVOID
+BOOL
 FASTCALL
-AllocateObjectAttr(VOID)
+IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
 {
-  PTHREADINFO pti;
-  PPROCESSINFO ppi;
-  PVOID pAttr;
-  PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
-  PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
-  int i;
-
-  pti = PsGetCurrentThreadWin32Thread();
-  if (pti->pgdiBrushAttr)
-  {
-     pAttr = pti->pgdiBrushAttr; // Get the free one.
-     pti->pgdiBrushAttr = NULL;
-     return pAttr;
-  }
-
-  ppi = PsGetCurrentProcessWin32Process();
-
-  if (!ppi->pBrushAttrList) // If set point is null, allocate new group.
-  {
-     pGdiObjAttrEntry = EngAllocUserMem(sizeof(GDI_OBJ_ATTR_ENTRY), 0);
-
-     if (!pGdiObjAttrEntry)
-     {
-        DPRINT1("Attr Failed User Allocation!\n");
-        return NULL;
-     }
-
-     DPRINT("AllocObjectAttr User 0x%x\n",pGdiObjAttrEntry);
+    // FIXME:
+    if (pbr->flAttrs & GDIBRUSH_IS_GLOBAL) return TRUE;
 
-     pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
-                                                  sizeof(GDI_OBJ_ATTR_FREELIST),
-                                                  GDITAG_BRUSH_FREELIST);
-     if ( !pGdiObjAttrFreeList )
-     {
-        EngFreeUserMem(pGdiObjAttrEntry);
-        return NULL;
-     }
-
-     RtlZeroMemory(pGdiObjAttrFreeList, sizeof(GDI_OBJ_ATTR_FREELIST));
-
-     DPRINT("AllocObjectAttr Ex 0x%x\n",pGdiObjAttrFreeList);
+    if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) || ulOwner == GDI_OBJ_HMGR_NONE)
+    {
+        // Deny user access to User Data.
+        GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
+        // FIXME: deallocate brush attr
+    }
 
-     InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
+    if (ulOwner == GDI_OBJ_HMGR_POWNED)
+    {
+        // Allow user access to User Data.
+        GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pbr->pBrushAttr);
+        // FIXME: allocate brush attr
+    }
 
-     pGdiObjAttrFreeList->nEntries = GDIOBJATTRFREE;
-     // Start at the bottom up and set end of free list point.
-     ppi->pBrushAttrList = &pGdiObjAttrEntry->Attr[GDIOBJATTRFREE-1];
-     // Build the free attr list.
-     for ( i = 0; i < GDIOBJATTRFREE; i++)
-     {
-         pGdiObjAttrFreeList->AttrList[i] = &pGdiObjAttrEntry->Attr[i];
-     }
-  }
+    GDIOBJ_vSetObjectOwner(&pbr->BaseObject, ulOwner);
 
-  pAttr = ppi->pBrushAttrList;
-  pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
+    return TRUE;
+}
 
-  // Free the list when it is full!
-  if ( pGdiObjAttrFreeList->nEntries-- == 1)
-  {  // No more free entries, so yank the list.
-     RemoveEntryList( &pGdiObjAttrFreeList->Entry );
+BOOL
+NTAPI
+BRUSH_bAllocBrushAttr(PBRUSH pbr)
+{
+    PPROCESSINFO ppi;
+    BRUSH_ATTR *pBrushAttr;
 
-     ExFreePoolWithTag( pGdiObjAttrFreeList, GDITAG_BRUSH_FREELIST );
+    ppi = PsGetCurrentProcessWin32Process();
+    ASSERT(ppi);
 
-     if ( IsListEmpty( &ppi->GDIBrushAttrFreeList ) )
-     {
-        ppi->pBrushAttrList = NULL;
-        return pAttr;
-     }
+    pBrushAttr = GdiPoolAllocate(ppi->pPoolDcAttr);
+    if (!pBrushAttr)
+    {
+        DPRINT1("Could not allocate brush attr\n");
+        return FALSE;
+    }
 
-     pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
-  }
+    /* Copy the content from the kernel mode dc attr */
+    pbr->pBrushAttr = pBrushAttr;
+    *pbr->pBrushAttr = pbr->BrushAttr;
 
-  ppi->pBrushAttrList = pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1];
+    /* Set the object attribute in the handle table */
+    GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pBrushAttr);
 
-  return pAttr;
+    DPRINT("BRUSH_bAllocBrushAttr: pbr=%p, pbr->pdcattr=%p\n", pbr, pbr->pBrushAttr);
+    return TRUE;
 }
 
-VOID
-FASTCALL
-FreeObjectAttr(PVOID pAttr)
-{
-  PTHREADINFO pti;
-  PPROCESSINFO ppi;
-  PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
-
-  pti = PsGetCurrentThreadWin32Thread();
-
-  if (!pti) return;
-
-  if (!pti->pgdiBrushAttr)
-  {  // If it is null, just cache it for the next time.
-     pti->pgdiBrushAttr = pAttr;
-     return;
-  }
-
-  ppi = PsGetCurrentProcessWin32Process();
-
-  pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
-
-  // We add to the list of free entries, so this will grows!
-  if ( IsListEmpty(&ppi->GDIBrushAttrFreeList) ||
-       pGdiObjAttrFreeList->nEntries == GDIOBJATTRFREE )
-  {
-     pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
-                                                  sizeof(GDI_OBJ_ATTR_FREELIST),
-                                                  GDITAG_BRUSH_FREELIST);
-     if ( !pGdiObjAttrFreeList )
-     {
-        return;
-     }
-     InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
-     pGdiObjAttrFreeList->nEntries = 0;
-  }
-  // Up count, save the entry and set end of free list point.
-  ++pGdiObjAttrFreeList->nEntries; // Top Down...
-  pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1] = pAttr;
-  ppi->pBrushAttrList = pAttr;
-
-  return;
-}
 
-BOOL
-FASTCALL
-IntGdiSetBrushOwner(PBRUSH pbr, DWORD OwnerMask)
+VOID
+NTAPI
+BRUSH_vFreeBrushAttr(PBRUSH pbr)
 {
-  HBRUSH hBR;
-  PEPROCESS Owner = NULL;
-  PGDI_TABLE_ENTRY pEntry = NULL;
-
-  if (!pbr) return FALSE;
-
-  hBR = pbr->BaseObject.hHmgr;
-
-  if (!hBR || (GDI_HANDLE_GET_TYPE(hBR) != GDI_OBJECT_TYPE_BRUSH))
-     return FALSE;
-  else
-  {
-     INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hBR);
-     pEntry = &GdiHandleTable->Entries[Index];
-  }
-
-  if (pbr->flAttrs & GDIBRUSH_IS_GLOBAL)
-  {
-     GDIOBJ_ShareUnlockObjByPtr((POBJ)pbr);
-     return TRUE;
-  }
-
-  if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
-  {
-     // Set this Brush to inaccessible mode and to an Owner of NONE.
-//     if (OwnerMask == GDI_OBJ_HMGR_NONE) Owner = OwnerMask;
-
-     if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, Owner))
-        return FALSE;
+#if 0
+    PPROCESSINFO ppi;
 
-     // Deny user access to User Data.
-     pEntry->UserData = NULL; // This hBR is inaccessible!
-  }
+    if (pbrush->pBrushAttr == &pbrush->BrushAttr) return;
 
-  if (OwnerMask == GDI_OBJ_HMGR_POWNED)
-  {
-     if (!GDIOBJ_SetOwnership((HGDIOBJ) hBR, PsGetCurrentProcess() ))
-        return FALSE;
+    /* Reset the object attribute in the handle table */
+    GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
 
-     // Allow user access to User Data.
-     pEntry->UserData = pbr->pBrushAttr;
-  }
-  return TRUE;
+    /* Free memory from the process gdi pool */
+    ppi = PsGetCurrentProcessWin32Process();
+    ASSERT(ppi);
+    GdiPoolFree(ppi->pPoolBrushAttr, pbr->pBrushAttr);
+#endif
+    /* Reset to kmode brush attribute */
+    pbr->pBrushAttr = &pbr->BrushAttr;
 }
 
 BOOL
@@ -219,10 +119,16 @@ BRUSH_Cleanup(PVOID ObjectBody)
     if (pbrush->flAttrs & (GDIBRUSH_IS_HATCH | GDIBRUSH_IS_BITMAP))
     {
         ASSERT(pbrush->hbmPattern);
-        GDIOBJ_SetOwnership(pbrush->hbmPattern, PsGetCurrentProcess());
+        GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED);
         GreDeleteObject(pbrush->hbmPattern);
     }
 
+    /* Check if there is a usermode attribute */
+    if (pbrush->pBrushAttr != &pbrush->BrushAttr)
+    {
+        BRUSH_vFreeBrushAttr(pbrush);
+    }
+
     /* Free the kmode styles array of EXTPENS */
     if (pbrush->pStyle)
     {
@@ -339,9 +245,9 @@ IntGdiCreateDIBBrush(
     pbrush->hbmPattern = hPattern;
     /* FIXME: Fill in the rest of fields!!! */
 
-    GDIOBJ_SetOwnership(hPattern, NULL);
+    GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
 
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -381,9 +287,9 @@ IntGdiCreateHatchBrush(
     pbrush->hbmPattern = hPattern;
     pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
 
-    GDIOBJ_SetOwnership(hPattern, NULL);
+    GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
 
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -417,9 +323,9 @@ IntGdiCreatePatternBrush(
     pbrush->hbmPattern = hPattern;
     /* FIXME: Fill in the rest of fields!!! */
 
-    GDIOBJ_SetOwnership(hPattern, NULL);
+    GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
 
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -445,7 +351,7 @@ IntGdiCreateSolidBrush(
     pbrush->BrushAttr.lbColor = Color & 0x00FFFFFF;
     /* FIXME: Fill in the rest of fields!!! */
 
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -466,7 +372,7 @@ IntGdiCreateNullBrush(VOID)
     hBrush = pbrush->BaseObject.hHmgr;
 
     pbrush->flAttrs |= GDIBRUSH_IS_NULL;
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -477,12 +383,12 @@ IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color)
 {
     PBRUSH pbrush;
 
-    pbrush = BRUSH_LockBrush(hBrush);
+    pbrush = BRUSH_ShareLockBrush(hBrush);
     if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
     {
         pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
     }
-    BRUSH_UnlockBrush(pbrush);
+    BRUSH_ShareUnlockBrush(pbrush);
 }