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/user3... ============================================================================== --- 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/user3... ============================================================================== --- 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/user3... ============================================================================== --- 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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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;