[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / brush.c
index 07cb63e..f72d7d1 100644 (file)
@@ -1,17 +1,31 @@
-/* 
+/*
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS win32 subsystem
  * PURPOSE:           Functions for brushes
  * FILE:              subsystem/win32/win32k/objects/brush.c
- * PROGRAMER:         
+ * PROGRAMER:
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
-static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
+#define GDIOBJATTRFREE 170
+
+typedef struct _GDI_OBJ_ATTR_FREELIST
+{
+  LIST_ENTRY Entry;
+  DWORD nEntries;
+  PVOID AttrList[GDIOBJATTRFREE];
+} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST;
+
+typedef struct _GDI_OBJ_ATTR_ENTRY
+{
+  RGN_ATTR Attr[GDIOBJATTRFREE];
+} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
+
+static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
 {
     {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
     {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL   */
@@ -21,6 +35,82 @@ static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
     {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E}  /* HS_DIAGCROSS  */
 };
 
+BOOL
+FASTCALL
+IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
+{
+    // FIXME:
+    if (pbr->flAttrs & GDIBRUSH_IS_GLOBAL) return TRUE;
+
+    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
+    }
+
+    if (ulOwner == GDI_OBJ_HMGR_POWNED)
+    {
+        // Allow user access to User Data.
+        GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pbr->pBrushAttr);
+        // FIXME: allocate brush attr
+    }
+
+    GDIOBJ_vSetObjectOwner(&pbr->BaseObject, ulOwner);
+
+    return TRUE;
+}
+
+BOOL
+NTAPI
+BRUSH_bAllocBrushAttr(PBRUSH pbr)
+{
+    PPROCESSINFO ppi;
+    BRUSH_ATTR *pBrushAttr;
+
+    ppi = PsGetCurrentProcessWin32Process();
+    ASSERT(ppi);
+
+    pBrushAttr = GdiPoolAllocate(ppi->pPoolDcAttr);
+    if (!pBrushAttr)
+    {
+        DPRINT1("Could not allocate brush attr\n");
+        return FALSE;
+    }
+
+    /* Copy the content from the kernel mode dc attr */
+    pbr->pBrushAttr = pBrushAttr;
+    *pbr->pBrushAttr = pbr->BrushAttr;
+
+    /* Set the object attribute in the handle table */
+    GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pBrushAttr);
+
+    DPRINT("BRUSH_bAllocBrushAttr: pbr=%p, pbr->pdcattr=%p\n", pbr, pbr->pBrushAttr);
+    return TRUE;
+}
+
+
+VOID
+NTAPI
+BRUSH_vFreeBrushAttr(PBRUSH pbr)
+{
+#if 0
+    PPROCESSINFO ppi;
+
+    if (pbrush->pBrushAttr == &pbrush->BrushAttr) return;
+
+    /* Reset the object attribute in the handle table */
+    GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
+
+    /* 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
 INTERNAL_CALL
 BRUSH_Cleanup(PVOID ObjectBody)
@@ -29,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)
     {
@@ -102,129 +198,6 @@ BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer)
     return sizeof(LOGBRUSH);
 }
 
-/**
- * @name CalculateColorTableSize
- *
- * Internal routine to calculate the number of color table entries.
- *
- * @param BitmapInfoHeader
- *        Input bitmap information header, can be any version of
- *        BITMAPINFOHEADER or BITMAPCOREHEADER.
- *
- * @param ColorSpec
- *        Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
- *        or DIB_RGB_COLORS). On successful return this value is normalized
- *        according to the bitmap info.
- *
- * @param ColorTableSize
- *        On successful return this variable is filled with number of
- *        entries in color table for the image with specified parameters.
- *
- * @return
- *    TRUE if the input values together form a valid image, FALSE otherwise.
- */
-BOOL
-APIENTRY
-CalculateColorTableSize(
-    CONST BITMAPINFOHEADER *BitmapInfoHeader,
-    UINT *ColorSpec,
-    UINT *ColorTableSize)
-{
-    WORD BitCount;
-    DWORD ClrUsed;
-    DWORD Compression;
-
-    /*
-     * At first get some basic parameters from the passed BitmapInfoHeader
-     * structure. It can have one of the following formats:
-     * - BITMAPCOREHEADER (the oldest one with totally different layout
-     *                     from the others)
-     * - BITMAPINFOHEADER (the standard and most common header)
-     * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
-     * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
-     */
-    if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
-    {
-        BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;
-        ClrUsed = 0;
-        Compression = BI_RGB;
-    }
-    else
-    {
-        BitCount = BitmapInfoHeader->biBitCount;
-        ClrUsed = BitmapInfoHeader->biClrUsed;
-        Compression = BitmapInfoHeader->biCompression;
-    }
-
-    switch (Compression)
-    {
-        case BI_BITFIELDS:
-            if (*ColorSpec == DIB_PAL_COLORS)
-                *ColorSpec = DIB_RGB_COLORS;
-
-            if (BitCount != 16 && BitCount != 32)
-                return FALSE;
-
-            /* For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
-             * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
-             * For BITMAPINFOHEADER the color masks are stored in the palette. */
-            if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))
-                *ColorTableSize = 0;
-            else
-                *ColorTableSize = 3;
-
-            return TRUE;
-
-        case BI_RGB:
-            switch (BitCount)
-            {
-                case 1:
-                    *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;
-                    return TRUE;
-
-                case 4:
-                    *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
-                    return TRUE;
-
-                case 8:
-                    *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
-                    return TRUE;
-
-                default:
-                    if (*ColorSpec == DIB_PAL_COLORS)
-                        *ColorSpec = DIB_RGB_COLORS;
-                    if (BitCount != 16 && BitCount != 24 && BitCount != 32)
-                        return FALSE;
-                    *ColorTableSize = ClrUsed;
-                    return TRUE;
-            }
-
-        case BI_RLE4:
-            if (BitCount == 4)
-            {
-                *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
-                return TRUE;
-            }
-            return FALSE;
-
-        case BI_RLE8:
-            if (BitCount == 8)
-            {
-                *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
-                return TRUE;
-            }
-            return FALSE;
-
-        case BI_JPEG:
-        case BI_PNG:
-            *ColorTableSize = ClrUsed;
-            return TRUE;
-
-        default:
-            return FALSE;
-    }
-}
-
 HBRUSH
 APIENTRY
 IntGdiCreateDIBBrush(
@@ -237,52 +210,33 @@ IntGdiCreateDIBBrush(
     PBRUSH pbrush;
     HBITMAP hPattern;
     ULONG_PTR DataPtr;
-    UINT PaletteEntryCount;
-    PSURFACE psurfPattern;
-    INT PaletteType;
+    PVOID pvDIBits;
 
     if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
     {
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
-        return NULL;
-    }
-
-    if (!CalculateColorTableSize(&BitmapInfo->bmiHeader,
-                                 &ColorSpec,
-                                 &PaletteEntryCount))
-    {
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
         return NULL;
     }
 
-    // FIXME: What about BI_BITFIELDS
-    DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize;
-    if (ColorSpec == DIB_RGB_COLORS)
-        DataPtr += PaletteEntryCount * sizeof(RGBQUAD);
-    else
-        DataPtr += PaletteEntryCount * sizeof(USHORT);
+    DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
 
-    hPattern = IntGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth,
-                                  BitmapInfo->bmiHeader.biHeight,
-                                  BitmapInfo->bmiHeader.biPlanes,
-                                  BitmapInfo->bmiHeader.biBitCount,
-                                  (PVOID)DataPtr);
+    hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0);
     if (hPattern == NULL)
     {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
-
-    psurfPattern = SURFACE_LockSurface(hPattern);
-    ASSERT(psurfPattern != NULL);
-    psurfPattern->hDIBPalette = BuildDIBPalette(BitmapInfo, &PaletteType);
-    SURFACE_UnlockSurface(psurfPattern);
+       RtlCopyMemory(pvDIBits,
+                         (PVOID)DataPtr,
+                                 DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth,
+                                       BitmapInfo->bmiHeader.biHeight,
+                                       BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes));
 
     pbrush = BRUSH_AllocBrushWithHandle();
     if (pbrush == NULL)
     {
         GreDeleteObject(hPattern);
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
     hBrush = pbrush->BaseObject.hHmgr;
@@ -291,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;
 }
@@ -313,10 +267,10 @@ IntGdiCreateHatchBrush(
         return 0;
     }
 
-    hPattern = IntGdiCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
+    hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
     if (hPattern == NULL)
     {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
 
@@ -324,7 +278,7 @@ IntGdiCreateHatchBrush(
     if (pbrush == NULL)
     {
         GreDeleteObject(hPattern);
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
     hBrush = pbrush->BaseObject.hHmgr;
@@ -333,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;
 }
@@ -352,7 +306,7 @@ IntGdiCreatePatternBrush(
     hPattern = BITMAP_CopyBitmap(hBitmap);
     if (hPattern == NULL)
     {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
 
@@ -360,7 +314,7 @@ IntGdiCreatePatternBrush(
     if (pbrush == NULL)
     {
         GreDeleteObject(hPattern);
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
     hBrush = pbrush->BaseObject.hHmgr;
@@ -369,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;
 }
@@ -387,17 +341,17 @@ IntGdiCreateSolidBrush(
     pbrush = BRUSH_AllocBrushWithHandle();
     if (pbrush == NULL)
     {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
     hBrush = pbrush->BaseObject.hHmgr;
 
     pbrush->flAttrs |= GDIBRUSH_IS_SOLID;
 
-    pbrush->BrushAttr.lbColor = Color;
+    pbrush->BrushAttr.lbColor = Color & 0x00FFFFFF;
     /* FIXME: Fill in the rest of fields!!! */
 
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -412,13 +366,13 @@ IntGdiCreateNullBrush(VOID)
     pbrush = BRUSH_AllocBrushWithHandle();
     if (pbrush == NULL)
     {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
     hBrush = pbrush->BaseObject.hHmgr;
 
     pbrush->flAttrs |= GDIBRUSH_IS_NULL;
-    BRUSH_UnlockBrush(pbrush);
+    GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
     return hBrush;
 }
@@ -429,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);
 }
 
 
@@ -457,7 +411,7 @@ NtGdiCreateDIBBrush(
     SafeBitmapInfoAndData = EngAllocMem(FL_ZERO_MEMORY, BitmapInfoSize, TAG_DIB);
     if (SafeBitmapInfoAndData == NULL)
     {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
 
@@ -535,7 +489,7 @@ NtGdiSetBrushOrg(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point)
     dc = DC_LockDc(hDC);
     if (dc == NULL)
     {
-        SetLastWin32Error(ERROR_INVALID_HANDLE);
+        EngSetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
     pdcattr = dc->pdcattr;
@@ -567,6 +521,7 @@ NtGdiSetBrushOrg(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point)
 
     pdcattr->ptlBrushOrigin.x = XOrg;
     pdcattr->ptlBrushOrigin.y = YOrg;
+    IntptlBrushOrigin(dc, XOrg, YOrg );
     DC_UnlockDc(dc);
 
     return TRUE;