[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 6 May 2012 08:17:48 +0000 (08:17 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 6 May 2012 08:17:48 +0000 (08:17 +0000)
- Create default hatch brush bitmaps on win32k init
- After creating a PDEV fill the fields in the ahsurf array that are not filled by the driver with these bitmaps
- don't create a new bitmap when a hatch brush is created, instead only store the style and use the related bitmap from the PDEV when realizing the brush.
- Fix the palette of DIB brushes, when realizing the brush
- Don't leak the bitmaps for DIB brushes in BRUSH_Cleanup

svn path=/trunk/; revision=56523

reactos/win32ss/gdi/eng/engbrush.c
reactos/win32ss/gdi/eng/pdevobj.c
reactos/win32ss/gdi/ntgdi/brush.c
reactos/win32ss/gdi/ntgdi/brush.h
reactos/win32ss/user/ntuser/main.c

index ea930c1..d709af6 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+static const ULONG gaulHatchBrushes[HS_DDI_MAX][8] =
+{
+    {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
+    {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL   */
+    {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL  */
+    {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL  */
+    {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS      */
+    {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E}  /* HS_DIAGCROSS  */
+};
+
+HSURF gahsurfHatch[HS_DDI_MAX];
+
 /** Internal functions ********************************************************/
 
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitBrushImpl(VOID)
+{
+    ULONG i;
+    SIZEL sizl = {8, 8};
+
+    /* Loop all hatch styles */
+    for (i = 0; i < HS_DDI_MAX; i++)
+    {
+        /* Create a default hatch bitmap */
+        gahsurfHatch[i] = (HSURF)EngCreateBitmap(sizl,
+                                                 0,
+                                                 BMF_1BPP,
+                                                 0,
+                                                 (PVOID)gaulHatchBrushes[i]);
+    }
+
+    return STATUS_SUCCESS;
+}
+
 VOID
 NTAPI
 EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
@@ -38,7 +72,8 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
 
     pebo->ppalSurf = pebo->psurfTrg->ppal;
     GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject);
-    //pebo->ppalDC = pdc->dclevel.ppal;
+    pebo->ppalDC = pdc->dclevel.ppal;
+    GDIOBJ_vReferenceObjectByPointer(&pebo->ppalDC->BaseObject);
 
     if (pbrush->flAttrs & BR_IS_NULL)
     {
@@ -111,7 +146,10 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
         pebo->BrushObject.pvRbrush = NULL;
     }
 
+    /* Dereference the palettes */
     PALETTE_ShareUnlockPalette(pebo->ppalSurf);
+    PALETTE_ShareUnlockPalette(pebo->ppalDC);
+    if (pebo->ppalDIB) PALETTE_ShareUnlockPalette(pebo->ppalDIB);
 }
 
 VOID
@@ -186,6 +224,41 @@ EngRealizeBrush(
     return TRUE;
 }
 
+static
+PPALETTE
+FixupDIBBrushPalette(
+    _In_ PPALETTE ppalDIB,
+    _In_ PPALETTE ppalDC)
+{
+    PPALETTE ppalNew;
+    ULONG i, iPalIndex, crColor;
+
+    /* Allocate a new palette */
+    ppalNew = PALETTE_AllocPalette(PAL_INDEXED,
+                                   ppalDIB->NumColors,
+                                   NULL,
+                                   0,
+                                   0,
+                                   0);
+
+    /* Loop all colors */
+    for (i = 0; i < ppalDIB->NumColors; i++)
+    {
+        /* Get the RGB color, which is the index into the DC palette */
+        iPalIndex = PALETTE_ulGetRGBColorFromIndex(ppalDIB, i);
+
+        /* Roll over when index is too big */
+        iPalIndex %= ppalDC->NumColors;
+
+        /* Set the indexed DC color as the new color */
+        crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, iPalIndex);
+        PALETTE_vSetRGBColorForIndex(ppalNew, i, crColor);
+    }
+
+    /* Return the new palette */
+    return ppalNew;
+}
+
 BOOL
 NTAPI
 EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
@@ -193,23 +266,40 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
     BOOL bResult;
     PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
     PSURFACE psurfPattern, psurfMask;
-    PPDEVOBJ ppdev = NULL;
+    PPDEVOBJ ppdev;
     EXLATEOBJ exlo;
     PPALETTE ppalPattern;
+    PBRUSH pbr = pebo->pbrush;
+    HBITMAP hbmPattern;
+    ULONG iHatch;
 
     /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
     ASSERT(pebo->psurfTrg);
 
     ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
+    if (!ppdev) ppdev = gppdevPrimary;
 
-    // FIXME: all SURFACEs need a PDEV
-    if (ppdev && bCallDriver)
+    if (bCallDriver)
         pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
 
     if (!pfnRealzizeBrush)
         pfnRealzizeBrush = EngRealizeBrush;
 
-    psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
+    /* Check if this is a hatch brush */
+    if (pbr->flAttrs & BR_IS_HATCH)
+    {
+        /* Get the hatch brush pattern from the PDEV */
+        hbmPattern = (HBITMAP)ppdev->ahsurf[pbr->ulStyle];
+        iHatch = pbr->ulStyle;
+    }
+    else
+    {
+        /* Use the brushes pattern */
+        hbmPattern = pbr->hbmPattern;
+        iHatch = -1;
+    }
+
+    psurfPattern = SURFACE_ShareLockSurface(hbmPattern);
     ASSERT(psurfPattern);
     ASSERT(psurfPattern->ppal);
 
@@ -217,11 +307,11 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
     psurfMask = NULL;
 
     /* DIB brushes with DIB_PAL_COLORS usage need a new palette */
-    if (pebo->pbrush->flAttrs & BR_IS_DIBPALCOLORS)
+    if (pbr->flAttrs & BR_IS_DIBPALCOLORS)
     {
         ASSERT(FALSE);
-        ppalPattern = 0; //CreateDIBPalette(psurfPattern->ppal, pebo->ppalDC);
-        // pebo->ppalDIB = ppalPattern;
+        ppalPattern = FixupDIBBrushPalette(psurfPattern->ppal, pebo->ppalDC);
+        pebo->ppalDIB = ppalPattern;
     }
     else
     {
@@ -243,7 +333,7 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
                                &psurfPattern->SurfObj,
                                psurfMask ? &psurfMask->SurfObj : NULL,
                                &exlo.xlo,
-                               -1); // FIXME: what about hatch brushes?
+                               iHatch);
 
     /* Cleanup the XLATEOBJ */
     EXLATEOBJ_vCleanup(&exlo);
index 5b3771f..d64edc2 100644 (file)
@@ -136,6 +136,7 @@ PDEVOBJ_bEnablePDEV(
     PWSTR pwszLogAddress)
 {
     PFN_DrvEnablePDEV pfnEnablePDEV;
+    ULONG i;
 
     DPRINT("PDEVOBJ_bEnablePDEV()\n");
 
@@ -165,6 +166,13 @@ PDEVOBJ_bEnablePDEV(
     /* Setup Palette */
     ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
 
+    /* Setup hatch brushes */
+    for (i = 0; i < HS_DDI_MAX; i++)
+    {
+        if (ppdev->ahsurf[i] == NULL)
+            ppdev->ahsurf[i] = gahsurfHatch[i];
+    }
+
     DPRINT("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
 
     return TRUE;
index ba76b3e..b3a969c 100644 (file)
@@ -25,16 +25,6 @@ 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   */
-    {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL  */
-    {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL  */
-    {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS      */
-    {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E}  /* HS_DIAGCROSS  */
-};
-
 BOOL
 FASTCALL
 IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
@@ -129,9 +119,8 @@ NTAPI
 BRUSH_Cleanup(PVOID ObjectBody)
 {
     PBRUSH pbrush = (PBRUSH)ObjectBody;
-    if (pbrush->flAttrs & (BR_IS_HATCH | BR_IS_BITMAP))
+    if (pbrush->hbmPattern)
     {
-        ASSERT(pbrush->hbmPattern);
         GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED);
         GreDeleteObject(pbrush->hbmPattern);
     }
@@ -273,34 +262,23 @@ IntGdiCreateHatchBrush(
 {
     HBRUSH hBrush;
     PBRUSH pbrush;
-    HBITMAP hPattern;
 
     if (Style < 0 || Style >= NB_HATCH_STYLES)
     {
         return 0;
     }
 
-    hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
-    if (hPattern == NULL)
-    {
-        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return NULL;
-    }
-
     pbrush = BRUSH_AllocBrushWithHandle();
     if (pbrush == NULL)
     {
-        GreDeleteObject(hPattern);
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
     }
     hBrush = pbrush->BaseObject.hHmgr;
 
     pbrush->flAttrs |= BR_IS_HATCH;
-    pbrush->hbmPattern = hPattern;
     pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
-
-    GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
+    pbrush->ulStyle = Style;
 
     GDIOBJ_vUnlockObject(&pbrush->BaseObject);
 
index cf88361..78d5a10 100644 (file)
@@ -96,8 +96,15 @@ typedef struct _EBRUSHOBJ
 INT FASTCALL BRUSH_GetObject (PBRUSH GdiObject, INT Count, LPLOGBRUSH Buffer);
 BOOL NTAPI BRUSH_Cleanup(PVOID ObjectBody);
 
+extern HSURF gahsurfHatch[HS_DDI_MAX];
+
 struct _DC;
 
+INIT_FUNCTION
+NTSTATUS
+NTAPI
+InitBrushImpl(VOID);
+
 VOID
 NTAPI
 EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);
index 8543fa4..8d7d7e1 100644 (file)
@@ -75,7 +75,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
                                            sizeof(PROCESSINFO),
                                            USERTAG_PROCESSINFO);
 
-        if (ppiCurrent == NULL) 
+        if (ppiCurrent == NULL)
         {
             ERR_CH(UserProcess, "Failed to allocate ppi for PID:%d\n", Process->UniqueProcessId);
             RETURN( STATUS_NO_MEMORY);
@@ -127,7 +127,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
         ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
         EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent);
         KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE);
-        
+
 
         /* map the gdi handle table to user land */
         Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
@@ -163,7 +163,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
         TRACE_CH(UserProcess, "Destroying ppi 0x%x\n", ppiCurrent);
         ppiCurrent->W32PF_flags |= W32PF_TERMINATED;
 
-        if (ppiScrnSaver == ppiCurrent) 
+        if (ppiScrnSaver == ppiCurrent)
             ppiScrnSaver = NULL;
 
         if (ppiCurrent->InputIdleEvent)
@@ -244,7 +244,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
     }
 
     RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));
-    
+
     PsSetThreadWin32Thread(Thread, ptiCurrent);
     pTeb->Win32ThreadInfo = ptiCurrent;
     ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
@@ -275,14 +275,14 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
     if (ptiCurrent->KeyboardLayout)
         UserReferenceObject(ptiCurrent->KeyboardLayout);
     ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
-    
+
     /* Initialize the CLIENTINFO */
     pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
     RtlZeroMemory(pci, sizeof(CLIENTINFO));
     pci->ppi = ptiCurrent->ppi;
     pci->fsHooks = ptiCurrent->fsHooks;
     pci->dwTIFlags = ptiCurrent->TIF_flags;
-    if (ptiCurrent->KeyboardLayout) 
+    if (ptiCurrent->KeyboardLayout)
         pci->hKL = ptiCurrent->KeyboardLayout->hkl;
 
     /* Assign a default window station and desktop to the process */
@@ -614,6 +614,7 @@ DriverEntry(
     CreateStockObjects();
     CreateSysColorObjects();
 
+    NT_ROF(InitBrushImpl());
     NT_ROF(InitPDEVImpl());
     NT_ROF(InitLDEVImpl());
     NT_ROF(InitDeviceImpl());