[ros-diffs] [jgardou] 47140: [WIN32K] - Set NULL owner to copied bitmap when creating indirect icons - Rewrite UserDrawIconEx, inspired from wine code - fix palette creation for 16 bits DIB - Always assign a palette to bitmap created with BITMAP_CopyBitmap and IntCreateCompatibeBitmap. [USER32] - Use DIB section when creating icons - Use something called "header" Now mode switching is almost glitchless.

jgardou at svn.reactos.org jgardou at svn.reactos.org
Sun May 9 13:35:36 CEST 2010


Author: jgardou
Date: Sun May  9 13:35:36 2010
New Revision: 47140

URL: http://svn.reactos.org/svn/reactos?rev=47140&view=rev
Log:
[WIN32K]
  - Set NULL owner to copied bitmap when creating indirect icons
  - Rewrite UserDrawIconEx, inspired from wine code
  - fix palette creation for 16 bits DIB
  - Always assign a palette to bitmap created with BITMAP_CopyBitmap and IntCreateCompatibeBitmap.
[USER32]
  - Use DIB section when creating icons
  - Use something called "header"
Now mode switching is almost glitchless.

Modified:
    branches/reactos-yarotows/dll/win32/user32/include/cursor.h
    branches/reactos-yarotows/dll/win32/user32/windows/bitmap.c
    branches/reactos-yarotows/dll/win32/user32/windows/icon.c
    branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c
    branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c
    branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c

Modified: branches/reactos-yarotows/dll/win32/user32/include/cursor.h
URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/dll/win32/user32/include/cursor.h?rev=47140&r1=47139&r2=47140&view=diff
==============================================================================
--- branches/reactos-yarotows/dll/win32/user32/include/cursor.h [iso-8859-1] (original)
+++ branches/reactos-yarotows/dll/win32/user32/include/cursor.h [iso-8859-1] Sun May  9 13:35:36 2010
@@ -1,2 +1,32 @@
 HCURSOR
-CursorIconToCursor(HICON hIcon, BOOL SemiTransparent);
+CursorIconToCursor(HICON hIcon,
+                   BOOL SemiTransparent);
+
+HICON CreateCursorIconFromData(PVOID ImageData,
+                               ICONIMAGE* IconImage,
+                               int cxDesired,
+                               int cyDesired,
+                               int xHotspot,
+                               int yHotspot,
+                               BOOL fIcon);
+
+/*
+ *  The following macro function accounts for the irregularities of
+ *   accessing cursor and icon resources in files and resource entries.
+ */
+typedef BOOL
+(*fnGetCIEntry)(LPVOID dir, int n, int *width, int *height, int *bits );
+
+int
+CURSORICON_FindBestCursor(LPVOID dir,
+                          fnGetCIEntry get_entry,
+                          int Width,
+                          int Height,
+                          int ColorBits);
+int
+CURSORICON_FindBestIcon(LPVOID dir,
+                        fnGetCIEntry get_entry,
+                        int Width,
+                        int Height,
+                        int ColorBits);
+

Modified: branches/reactos-yarotows/dll/win32/user32/windows/bitmap.c
URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/dll/win32/user32/windows/bitmap.c?rev=47140&r1=47139&r2=47140&view=diff
==============================================================================
--- branches/reactos-yarotows/dll/win32/user32/windows/bitmap.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/dll/win32/user32/windows/bitmap.c [iso-8859-1] Sun May  9 13:35:36 2010
@@ -56,11 +56,6 @@
 
 #include "poppack.h"
 
-/* forward declarations... actually in user32\windows\icon.c but useful here */
-HICON CreateCursorIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot, BOOL fIcon);
-CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, int height, int colors);
-CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, int width, int height, int colors);
-
 /* FUNCTIONS *****************************************************************/
 
 /*
@@ -95,13 +90,6 @@
    return Handle;
 }
 
-
-/*
- *  The following macro functions account for the irregularities of
- *   accessing cursor and icon resources in files and resource entries.
- */
-typedef BOOL (*fnGetCIEntry)( LPVOID dir, int n,
-                              int *width, int *height, int *bits );
 
 /**********************************************************************
  *	    CURSORICON_FindBestCursor2
@@ -311,16 +299,6 @@
       return NULL;
    }
 
-   /* Get a handle to the screen dc, the icon we create is going to be
-    * compatable with this. */
-   hScreenDc = CreateDCW(NULL, NULL, NULL, NULL);
-   if (hScreenDc == NULL)
-   {
-      UnmapViewOfFile(IconDIR);
-      RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-      return NULL;
-   }
-
    if (fuLoad & LR_MONOCHROME)
    {
       ColorBits = 1;
@@ -334,14 +312,12 @@
    dirEntry = CURSORICON_FindBestCursorFile( IconDIR, width, height, ColorBits );
    if (!dirEntry)
    {
-      DeleteDC(hScreenDc);
       UnmapViewOfFile(IconDIR);
       return NULL;
    }
 
    if ( dirEntry->dwDIBOffset > filesize )
    {
-      DeleteDC(hScreenDc);
       UnmapViewOfFile(IconDIR);
       return NULL;
    }
@@ -355,7 +331,6 @@
    SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwDIBSize);
    if (SafeIconImage == NULL)
    {
-      DeleteDC(hScreenDc);
       UnmapViewOfFile(IconDIR);
       return NULL;
    }
@@ -384,9 +359,8 @@
    /* Make data point to the start of the XOR image data. */
    Data = (PBYTE)SafeIconImage + HeaderSize;
 
-   hIcon = CreateCursorIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2, Icon);
+   hIcon = CreateCursorIconFromData(Data, SafeIconImage, width, height, width/2, height/2, Icon);
    RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-   DeleteDC(hScreenDc);
 
    return hIcon;
 }

Modified: branches/reactos-yarotows/dll/win32/user32/windows/icon.c
URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/dll/win32/user32/windows/icon.c?rev=47140&r1=47139&r2=47140&view=diff
==============================================================================
--- branches/reactos-yarotows/dll/win32/user32/windows/icon.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/dll/win32/user32/windows/icon.c [iso-8859-1] Sun May  9 13:35:36 2010
@@ -36,11 +36,11 @@
 
 
 HICON
-CreateCursorIconFromData(HDC hDC, PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot, BOOL fIcon)
-{
-   BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
-   BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
+CreateCursorIconFromData(PVOID ImageData, ICONIMAGE* IconImage, int cxDesired, int cyDesired, int xHotspot, int yHotspot, BOOL fIcon)
+{
    ICONINFO IconInfo;
+   PVOID pBits ;
+   HICON res;
 
    IconInfo.fIcon = fIcon;
    IconInfo.xHotspot = xHotspot;
@@ -50,16 +50,40 @@
    {
        IconInfo.hbmColor = (HBITMAP)0;
        IconImage->icHeader.biHeight *= 2;
-       IconInfo.hbmMask = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
-                                  ImageData, (BITMAPINFO*)IconImage,
-                                  DIB_RGB_COLORS);
+       IconInfo.hbmMask = CreateDIBSection(0,
+                                           (BITMAPINFO*)IconImage,
+                                           DIB_RGB_COLORS,
+                                           &pBits,
+                                           NULL,
+                                           0);
+       if(!pBits)
+       {
+           ERR("Could not create a DIB section\n");
+           return NULL;
+       }
+       CopyMemory(pBits,
+                  ImageData,
+                  (((IconImage->icHeader.biWidth + 31) & ~31 ) >> 3) * IconImage->icHeader.biHeight) ;
    }
    else
    {
+       BYTE BitmapInfoBuffer[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
+       BITMAPINFO *bwBIH = (BITMAPINFO *)BitmapInfoBuffer;
        /* Create the XOR bitmap */
-       IconInfo.hbmColor = CreateDIBitmap(hDC, &IconImage->icHeader, CBM_INIT,
-                                          ImageData, (BITMAPINFO*)IconImage,
-                                          DIB_RGB_COLORS);
+       IconInfo.hbmColor = CreateDIBSection(0,
+                                            (BITMAPINFO*)IconImage,
+                                            DIB_RGB_COLORS,
+                                            &pBits,
+                                            NULL,
+                                            0);
+       if(!pBits)
+       {
+           ERR("Could not create a DIB section\n");
+           return NULL;
+       }
+       CopyMemory(pBits,
+                  ImageData,
+                  (((IconImage->icHeader.biWidth * IconImage->icHeader.biBitCount+ 31) & ~31 ) >> 3) * IconImage->icHeader.biHeight) ;
 
        /* Make ImageData point to the start of the AND image data. */
        ImageData = ((PBYTE)ImageData) + (((IconImage->icHeader.biWidth *
@@ -89,17 +113,30 @@
        bwBIH->bmiColors[1].rgbRed = 0xff;
        bwBIH->bmiColors[1].rgbReserved = 0;
 
-       /* Create the AND bitmap. */
-       IconInfo.hbmMask = CreateDIBitmap(hDC, &bwBIH->bmiHeader, 0,
-                                         ImageData, bwBIH, DIB_RGB_COLORS);
-
-       SetDIBits(hDC, IconInfo.hbmMask, 0, IconImage->icHeader.biHeight,
-                 ImageData, bwBIH, DIB_RGB_COLORS);
+       IconInfo.hbmMask = CreateDIBSection(0,
+                                           bwBIH,
+                                           DIB_RGB_COLORS,
+                                           &pBits,
+                                           NULL,
+                                           0);
+       if(!pBits)
+       {
+           ERR("Could not create a DIB section\n");
+           DeleteObject(IconInfo.hbmColor);
+           return NULL;
+       }
+       CopyMemory(pBits,
+                  ImageData,
+                  (((IconImage->icHeader.biWidth + 31) & ~31 ) >> 3) * IconImage->icHeader.biHeight) ;
    }
 
-
    /* Create the icon based on everything we have so far */
-   return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
+   /* Use indirect creation, as DIBSection can't be shared between processes */
+   res = NtUserCreateCursorIconHandle(&IconInfo, TRUE);
+   DeleteObject(IconInfo.hbmMask);
+   if(IconInfo.hbmColor) DeleteObject(IconInfo.hbmColor);
+
+   return res;
 }
 
 /*
@@ -203,7 +240,6 @@
   ULONG HeaderSize;
   ULONG ColourCount;
   PVOID Data;
-  HDC hScreenDc;
   WORD wXHotspot;
   WORD wYHotspot;
 
@@ -259,17 +295,8 @@
   /* make data point to the start of the XOR image data */
   Data = (PBYTE)SafeIconImage + HeaderSize;
 
-  /* get a handle to the screen dc, the icon we create is going to be compatable with this */
-  hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
-  if (hScreenDc == NULL)
-    {
+  hIcon = CreateCursorIconFromData(Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot, fIcon);
       RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-      return(NULL);
-    }
-
-  hIcon = CreateCursorIconFromData(hScreenDc, Data, SafeIconImage, cxDesired, cyDesired, wXHotspot, wYHotspot, fIcon);
-  RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
-  DeleteDC(hScreenDc);
 
   return hIcon;
 }
@@ -427,19 +454,12 @@
 
 
 
-/*
- *  The following macro function accounts for the irregularities of
- *   accessing cursor and icon resources in files and resource entries.
- */
-typedef BOOL
-(*fnGetCIEntry)(LPVOID dir, int n, int *width, int *height, int *bits );
-
 /**********************************************************************
  *	    CURSORICON_FindBestIcon
  *
  * Find the icon closest to the requested size and number of colors.
  */
-static int
+int
 CURSORICON_FindBestIcon(LPVOID dir,
                         fnGetCIEntry get_entry,
                         int Width,
@@ -495,7 +515,7 @@
  * FIXME: parameter 'color' ignored and entries with more than 1 bpp
  *        ignored too
  */
-static int
+int
 CURSORICON_FindBestCursor(LPVOID dir,
                           fnGetCIEntry get_entry,
                           int Width,

Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c
URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c?rev=47140&r1=47139&r2=47140&view=diff
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Sun May  9 13:35:36 2010
@@ -110,7 +110,7 @@
     HCURSOR hOldCursor = (HCURSOR)0;
     HDC hdcScreen;
     BOOL bResult;
-	
+
 	CurInfo = IntGetSysCursorInfo();
 
     OldCursor = CurInfo->CurrentCursorObject;
@@ -522,26 +522,34 @@
             {
                 // FIXME: WTF?
                 CurIcon->IconInfo.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
-                CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
+                GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
+                if(CurIcon->IconInfo.hbmColor)
+                {
+                    CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
+                    GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
+                }
             }
-            if (CurIcon->IconInfo.hbmColor &&
-                    (psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor)))
+            else
             {
-                CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-                CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-                SURFACE_UnlockSurface(psurfBmp);
-                GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
-            }
-            if (CurIcon->IconInfo.hbmMask &&
-                    (psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmMask)))
-            {
-                if (CurIcon->IconInfo.hbmColor == NULL)
+                if (CurIcon->IconInfo.hbmColor &&
+                        (psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor)))
                 {
                     CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-                    CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy >> 1;
+                    CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+                    SURFACE_UnlockSurface(psurfBmp);
+                    GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
                 }
-                SURFACE_UnlockSurface(psurfBmp);
-                GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
+                if (CurIcon->IconInfo.hbmMask &&
+                        (psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmMask)))
+                {
+                    if(!CurIcon->IconInfo.hbmColor)
+                    {
+                        CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+                        CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy*2;
+                    }
+                    SURFACE_UnlockSurface(psurfBmp);
+                    GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
+                }
             }
 
             /* Calculate icon hotspot */
@@ -789,8 +797,8 @@
 
     DesktopWindow = UserGetDesktopWindow();
 
-    if (prcl != NULL && 
-       (prcl->right > prcl->left) && 
+    if (prcl != NULL &&
+       (prcl->right > prcl->left) &&
        (prcl->bottom > prcl->top) &&
         DesktopWindow != NULL)
     {
@@ -1268,6 +1276,7 @@
     return FALSE;
 }
 
+/* Mostly inspired from wine code */
 BOOL
 UserDrawIconEx(
     HDC hDc,
@@ -1282,18 +1291,15 @@
 {
     BOOL Ret = FALSE;
     HBITMAP hbmMask, hbmColor;
-    BITMAP bmpMask, bmpColor;
+    BITMAP bmpColor, bm;
     BOOL DoFlickerFree;
     SIZE IconSize;
-
-    HDC hdcOff;
+    INT iOldBkColor = 0, iOldTxtColor = 0;
+
+    HDC hMemDC, hOffDC = NULL;
     HGDIOBJ hOldOffBrush = 0;
     HGDIOBJ hOldOffBmp = 0;
-    HBITMAP hbmOff = 0;
-    HDC hdcMask = 0;
-    HGDIOBJ hOldMask = NULL;
-    HDC hdcImage = 0;
-    HGDIOBJ hOldImage = NULL;
+    HBITMAP hTmpBmp = 0, hOffBmp = 0;
     BOOL bAlpha = FALSE;
 
     hbmMask = pIcon->IconInfo.hbmMask;
@@ -1302,13 +1308,19 @@
     if (istepIfAniCur)
         DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
 
-    if (!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bmpMask))
+    if (!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bm))
     {
         return FALSE;
     }
 
     if (hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), (PVOID)&bmpColor))
     {
+        return FALSE;
+    }
+
+    if(!(hMemDC = NtGdiCreateCompatibleDC(hDc)))
+    {
+        DPRINT1("NtGdiCreateCompatibleDC failed!\n");
         return FALSE;
     }
 
@@ -1317,15 +1329,22 @@
         IconSize.cx = bmpColor.bmWidth;
         IconSize.cy = bmpColor.bmHeight;
     }
-    else
-    {
-        IconSize.cx = bmpMask.bmWidth;
-        IconSize.cy = bmpMask.bmHeight / 2;
-    }
+    else /* take it from mask */
+    {
+        IconSize.cx = bm.bmWidth;
+        IconSize.cy = bm.bmHeight/2;
+    }
+
+    if (!diFlags)
+        diFlags = DI_NORMAL;
 
     /* NtGdiCreateCompatibleBitmap will create a monochrome bitmap
        when cxWidth or cyHeight is 0 */
-    if ((bmpColor.bmBitsPixel == 32) && (cxWidth != 0) && (cyHeight != 0))
+    if (hbmColor
+            && (bmpColor.bmBitsPixel == 32)
+            && (cxWidth != 0)
+            && (cyHeight != 0)
+            && (diFlags & DI_IMAGE))
     {
         SURFACE *psurfOff = NULL;
         PFN_DIB_GetPixel fnSource_GetPixel = NULL;
@@ -1333,7 +1352,7 @@
 
         /* In order to correctly display 32 bit icons Windows first scans the image,
            because information about transparency is not stored in any image's headers */
-        psurfOff = SURFACE_LockSurface(hbmColor ? hbmColor : hbmMask);
+        psurfOff = SURFACE_LockSurface(hbmColor);
         if (psurfOff)
         {
             fnSource_GetPixel = DibFunctionsForBitmapFormat[psurfOff->SurfObj.iBitmapFormat].DIB_GetPixel;
@@ -1355,9 +1374,6 @@
         }
     }
 
-    if (!diFlags)
-        diFlags = DI_NORMAL;
-
     if (!cxWidth)
         cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
                    UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
@@ -1369,203 +1385,173 @@
     DoFlickerFree = (hbrFlickerFreeDraw &&
                      (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));
 
-    if (DoFlickerFree || bAlpha)
-    {
-        RECTL r;
-        BITMAP bm;
-        SURFACE *psurfOff = NULL;
-
-        r.right = cxWidth;
-        r.bottom = cyHeight;
-
-        hdcOff = NtGdiCreateCompatibleDC(hDc);
-        if (!hdcOff)
-        {
-            DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
-            return FALSE;
-        }
-
-        hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
-        if (!hbmOff)
-        {
-            DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
-            goto cleanup;
-        }
-
-        /* make sure we have a 32 bit offscreen bitmap
-          otherwise we can't do alpha blending */
-        psurfOff = SURFACE_LockSurface(hbmOff);
-        if (psurfOff == NULL)
-        {
-            DPRINT1("BITMAPOBJ_LockBitmap() failed!\n");
-            goto cleanup;
-        }
-        BITMAP_GetObject(psurfOff, sizeof(BITMAP), (PVOID)&bm);
-
-        if (bm.bmBitsPixel != 32)
-            bAlpha = FALSE;
-
-        SURFACE_UnlockSurface(psurfOff);
-
-        hOldOffBmp = NtGdiSelectBitmap(hdcOff, hbmOff);
-        if (!hOldOffBmp)
-        {
-            DPRINT1("NtGdiSelectBitmap() failed!\n");
-            goto cleanup;
-        }
-
-        if (DoFlickerFree)
-        {
-            hOldOffBrush = NtGdiSelectBrush(hdcOff, hbrFlickerFreeDraw);
-            if (!hOldOffBrush)
+    if (DoFlickerFree)
+    {
+        hOffDC = NtGdiCreateCompatibleDC(hDc);
+        if(!hOffDC)
+        {
+            DPRINT1("NtGdiCreateCompatibleBitmap failed!\n");
+            Ret = FALSE;
+            goto Cleanup ;
+        }
+        hOffBmp = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
+        if(!hOffBmp)
+        {
+            DPRINT1("NtGdiCreateCompatibleBitmap failed!\n");
+            goto Cleanup ;
+        }
+        hOldOffBmp = NtGdiSelectBitmap(hOffDC, hOffBmp);
+        hOldOffBrush = NtGdiSelectBrush(hOffDC, hbrFlickerFreeDraw);
+        NtGdiPatBlt(hOffDC, 0, 0, cxWidth, cyHeight, PATCOPY);
+        NtGdiSelectBrush(hOffDC, hOldOffBrush);
+    }
+    else
+    {
+        /* Set Background/foreground colors */
+        iOldTxtColor = IntGdiSetTextColor(hDc, 0); //black
+        iOldBkColor = IntGdiSetBkColor(hDc, 0x00FFFFFF); //white
+    }
+
+
+    if (hbmMask && (diFlags & DI_MASK) && !bAlpha)
+    {
+        hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
+        NtGdiStretchBlt(hOffDC ? hOffDC : hDc,
+                        hOffDC ? 0 : xLeft,
+                        hOffDC ? 0 : yTop,
+                        cxWidth,
+                        cyHeight,
+                        hMemDC,
+                        0,
+                        0,
+                        IconSize.cx,
+                        IconSize.cy,
+                        SRCAND,
+                        0);
+        NtGdiSelectBitmap(hMemDC, hTmpBmp);
+    }
+
+    if(diFlags & DI_IMAGE)
+    {
+        if (bAlpha)
+        {
+            BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
+            DWORD Pixel;
+            BYTE Red, Green, Blue, Alpha;
+            DWORD Count = 0;
+            INT i, j;
+            PSURFACE psurf;
+            PBYTE pBits ;
+            HBITMAP hMemBmp = NULL;
+
+            pBits = ExAllocatePoolWithTag(PagedPool,
+                                          bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
+                                          TAG_BITMAP);
+            if (pBits == NULL)
             {
-                DPRINT1("NtGdiSelectBrush() failed!\n");
-                goto cleanup;
+                Ret = FALSE;
+                goto CleanupAlpha;
             }
 
-            NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
-        }
+            hMemBmp = BITMAP_CopyBitmap(hbmColor);
+            if(!hMemBmp)
+            {
+                DPRINT1("BITMAP_CopyBitmap failed!");
+                goto CleanupAlpha;
+            }
+
+            psurf = SURFACE_LockSurface(hMemBmp);
+            if(!psurf)
+            {
+                DPRINT1("SURFACE_LockSurface failed!\n");
+                goto CleanupAlpha;
+            }
+            /* get color bits */
+            IntGetBitmapBits(psurf,
+                             bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
+                             pBits);
+
+            /* premultiply with the alpha channel value */
+            for (i = 0; i < cyHeight; i++)
+            {
+                for (j = 0; j < cxWidth; j++)
+                {
+                    Pixel = *(DWORD *)(pBits + Count);
+
+                    Alpha = ((BYTE)(Pixel >> 24) & 0xff);
+
+                    Red   = (((BYTE)(Pixel >>  0)) * Alpha) / 0xff;
+                    Green = (((BYTE)(Pixel >>  8)) * Alpha) / 0xff;
+                    Blue  = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
+
+                    *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
+
+                    Count += sizeof(DWORD);
+                }
+            }
+
+            /* set mem bits */
+            IntSetBitmapBits(psurf,
+                             bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
+                             pBits);
+            SURFACE_UnlockSurface(psurf);
+
+            hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
+
+            NtGdiAlphaBlend(hOffDC ? hOffDC : hDc,
+                            hOffDC ? 0 : xLeft,
+                            hOffDC ? 0 : yTop,
+                            cxWidth,
+                            cyHeight,
+                            hMemDC,
+                            0,
+                            0,
+                            IconSize.cx,
+                            IconSize.cy,
+                            pixelblend,
+                            NULL);
+            NtGdiSelectBitmap(hMemDC, hTmpBmp);
+        CleanupAlpha:
+            if(pBits) ExFreePoolWithTag(pBits, TAG_BITMAP);
+            if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
+        }
+        else if (hbmColor)
+        {
+            DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
+            hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmColor);
+            NtGdiStretchBlt(hOffDC ? hOffDC : hDc,
+                            hOffDC ? 0 : xLeft,
+                            hOffDC ? 0 : yTop,
+                            cxWidth,
+                            cyHeight,
+                            hMemDC,
+                            0,
+                            0,
+                            IconSize.cx,
+                            IconSize.cy,
+                            rop,
+                            0);
+            NtGdiSelectBitmap(hMemDC, hTmpBmp);
+        }
+    }
+
+    if(hOffDC)
+    {
+        NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hOffDC, 0, 0, SRCCOPY, 0, 0);
     }
     else
-        hdcOff = hDc;
-
-    if (diFlags & DI_IMAGE)
-    {
-        hdcImage = NtGdiCreateCompatibleDC(hDc);
-        if (!hdcImage)
-        {
-            DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
-            goto cleanup;
-        }
-        hOldImage = NtGdiSelectBitmap(hdcImage, (hbmColor ? hbmColor : hbmMask));
-        if (!hOldImage)
-        {
-            DPRINT("NtGdiSelectBitmap() failed!\n");
-            goto cleanup;
-        }
-    }
-
-    /* If DI_IMAGE flag is specified and hbmMask exists, then always use mask for drawing */
-    if (diFlags & DI_MASK || (diFlags & DI_IMAGE && hbmMask))
-    {
-        hdcMask = NtGdiCreateCompatibleDC(hDc);
-        if (!hdcMask)
-        {
-            DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
-            goto cleanup;
-        }
-
-        hOldMask = NtGdiSelectBitmap(hdcMask, hbmMask);
-        if (!hOldMask)
-        {
-            DPRINT("NtGdiSelectBitmap() failed!\n");
-            goto cleanup;
-        }
-    }
-
-    if (hdcMask || hdcImage)
-    {
-        GreStretchBltMask(hdcOff,
-                          (DoFlickerFree || bAlpha) ? 0 : xLeft,
-                          (DoFlickerFree || bAlpha) ? 0 : yTop,
-                          cxWidth,
-                          cyHeight,
-                          hdcImage ? hdcImage : hdcMask,
-                          0,
-                          0,
-                          IconSize.cx,
-                          IconSize.cy,
-                          SRCCOPY,
-                          0,
-                          hdcMask,
-                          0,
-                          hdcImage ? 0 : IconSize.cy);
-    }
-
-    if (hOldMask) NtGdiSelectBitmap(hdcMask, hOldMask);
-    if (hOldImage) NtGdiSelectBitmap(hdcImage, hOldImage);
-    if (hdcImage) NtGdiDeleteObjectApp(hdcImage);
-    if (hdcMask) NtGdiDeleteObjectApp(hdcMask);
-
-    if (bAlpha)
-    {
-        BITMAP bm;
-        SURFACE *psurfOff = NULL;
-        PBYTE pBits = NULL;
-        BLENDFUNCTION BlendFunc;
-        DWORD Pixel;
-        BYTE Red, Green, Blue, Alpha;
-        DWORD Count = 0;
-        INT i, j;
-
-        psurfOff = SURFACE_LockSurface(hbmOff);
-        if (psurfOff == NULL)
-        {
-            DPRINT1("BITMAPOBJ_LockBitmap() failed!\n");
-            goto cleanup;
-        }
-        BITMAP_GetObject(psurfOff, sizeof(BITMAP), (PVOID)&bm);
-
-        pBits = ExAllocatePoolWithTag(PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP);
-        if (pBits == NULL)
-        {
-            DPRINT1("ExAllocatePoolWithTag() failed!\n");
-            SURFACE_UnlockSurface(psurfOff);
-            goto cleanup;
-        }
-
-        /* get icon bits */
-        IntGetBitmapBits(psurfOff, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
-
-        /* premultiply with the alpha channel value */
-        for (i = 0; i < cyHeight; i++)
-        {
-            for (j = 0; j < cxWidth; j++)
-            {
-                Pixel = *(DWORD *)(pBits + Count);
-
-                Alpha = ((BYTE)(Pixel >> 24) & 0xff);
-
-                Red   = (((BYTE)(Pixel >>  0)) * Alpha) / 0xff;
-                Green = (((BYTE)(Pixel >>  8)) * Alpha) / 0xff;
-                Blue  = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
-
-                *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
-
-                Count += sizeof(DWORD);
-            }
-        }
-
-        /* set icon bits */
-        IntSetBitmapBits(psurfOff, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
-        ExFreePoolWithTag(pBits, TAG_BITMAP);
-
-        SURFACE_UnlockSurface(psurfOff);
-
-        BlendFunc.BlendOp = AC_SRC_OVER;
-        BlendFunc.BlendFlags = 0;
-        BlendFunc.SourceConstantAlpha = 255;
-        BlendFunc.AlphaFormat = AC_SRC_ALPHA;
-
-        NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight,
-                        hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0);
-    }
-    else if (DoFlickerFree)
-    {
-        NtGdiBitBlt(hDc, xLeft, yTop, cxWidth,
-                    cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
-    }
-
-    Ret = TRUE;
-
-cleanup:
-    if (DoFlickerFree || bAlpha)
-    {
-        if (hOldOffBmp) NtGdiSelectBitmap(hdcOff, hOldOffBmp);
-        if (hOldOffBrush) NtGdiSelectBrush(hdcOff, hOldOffBrush);
-        if (hbmOff) GreDeleteObject(hbmOff);
-        if (hdcOff) NtGdiDeleteObjectApp(hdcOff);
-    }
+    {
+        IntGdiSetBkColor(hDc, iOldBkColor);
+        IntGdiSetTextColor(hDc, iOldTxtColor);
+    }
+
+    Ret = TRUE ;
+
+Cleanup:
+    NtGdiDeleteObjectApp(hMemDC);
+    if(hOldOffBmp) NtGdiSelectBitmap(hOffDC, hOldOffBmp);
+    if(hOffDC) NtGdiDeleteObjectApp(hOffDC);
+    if(hOffBmp) NtGdiDeleteObjectApp(hOffBmp);
 
     return Ret;
 }

Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c
URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c?rev=47140&r1=47139&r2=47140&view=diff
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] Sun May  9 13:35:36 2010
@@ -151,15 +151,9 @@
                                      NULL);
             /* Set palette */
             psurf = SURFACE_LockSurface(Bmp);
-            if(!psurf)
-            {
-                DPRINT1("Could not lock surface?\n");
-            }
-            else
-            {
-                psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
-                SURFACE_UnlockSurface(psurf);
-            }
+            ASSERT(psurf);
+            psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
+            SURFACE_UnlockSurface(psurf);
         }
         else
         {
@@ -190,6 +184,15 @@
                                              dibs.dsBm.bmPlanes,
                                              dibs.dsBm.bmBitsPixel,
                                              NULL);
+                    /* Assign palette */
+                    if(Bmp && psurf->ppal)
+                    {
+                        PSURFACE psurfBmp = SURFACE_LockSurface(Bmp);
+                        ASSERT(psurfBmp);
+                        psurfBmp->ppal = psurf->ppal;
+                        GDIOBJ_IncrementShareCount((POBJ)psurf->ppal);
+                        SURFACE_UnlockSurface(psurfBmp);
+                    }
                 }
                 else
                 {
@@ -890,6 +893,14 @@
             IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
             ExFreePoolWithTag(buf,TAG_BITMAP);
             resBitmap->flFlags = Bitmap->flFlags;
+            /* Copy palette */
+            if(Bitmap->hDIBPalette)
+                resBitmap->ppal = PALETTE_ShareLockPalette(Bitmap->hDIBPalette);
+            else if (Bitmap->ppal)
+            {
+                resBitmap->ppal = Bitmap->ppal ;
+                GDIOBJ_IncrementShareCount(&Bitmap->ppal->BaseObject);
+            }
             GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
         }
         else

Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c?rev=47140&r1=47139&r2=47140&view=diff
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Sun May  9 13:35:36 2010
@@ -1473,17 +1473,22 @@
         switch (bi->biBitCount)
         {
             case 15:
+                dsBitfields[0] = 0x7c00;
+                dsBitfields[1] = 0x03e0;
+                dsBitfields[2] = 0x001f;
+                break;
+
             case 16:
-                dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB       : 0x7c00;
-                dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x03e0;
-                dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x001f;
+                dsBitfields[0] = 0xF800;
+                dsBitfields[1] = 0x07e0;
+                dsBitfields[2] = 0x001f;
                 break;
 
             case 24:
             case 32:
-                dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB       : 0xff0000;
-                dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x00ff00;
-                dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x0000ff;
+                dsBitfields[0] = 0xff0000;
+                dsBitfields[1] = 0x00ff00;
+                dsBitfields[2] = 0x0000ff;
                 break;
         }
     }
@@ -1741,13 +1746,20 @@
         GreenMask = ((ULONG *)bmi->bmiColors)[1];
         BlueMask = ((ULONG *)bmi->bmiColors)[2];
     }
-    else if (bits < 24)
+    else if (bits == 15)
     {
         *paletteType = PAL_BITFIELDS;
         RedMask = 0x7c00;
         GreenMask = 0x03e0;
         BlueMask = 0x001f;
     }
+    else if (bits == 16)
+    {
+        *paletteType = PAL_BITFIELDS;
+        RedMask = 0xF800;
+        GreenMask = 0x07e0;
+        BlueMask = 0x001f;
+    }
     else
     {
         *paletteType = PAL_BGR;




More information about the Ros-diffs mailing list