Author: jgardou
Date: Wed Jul 14 09:54:44 2010
New Revision: 48034
URL:
http://svn.reactos.org/svn/reactos?rev=48034&view=rev
Log:
[USER32]
- There is no exported "CopyCursor", it's a macro.
- There is no "NtUserCreateCursorIconHandle" function in win32k. Use correct
functions to create a cursorIcon handle.
- Bring in WINE's CreateIconIndirect
[WIN32K]
- Dereference CursorIcon Object in NtUserCallOneParam
- Shared Icons need their bitmaps to be unowned
Modified:
trunk/reactos/dll/win32/user32/user32.pspec
trunk/reactos/dll/win32/user32/windows/cursoricon.c
trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
Modified: trunk/reactos/dll/win32/user32/user32.pspec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/user32.ps…
==============================================================================
--- trunk/reactos/dll/win32/user32/user32.pspec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/user32.pspec [iso-8859-1] Wed Jul 14 09:54:44 2010
@@ -759,7 +759,6 @@
; @ stdcall CharNextExW(long wstr long)
; @ stdcall CharPrevExW(long wstr wstr long)
; @ stub ClientThreadConnect
-@ stdcall CopyCursor(long) ; In msdn it is written, that function is available, but in
win 2k3 r2 it is absent
; @ stub EnumDisplayDeviceModesA ;(str long ptr long)
; @ stub EnumDisplayDeviceModesW ;(wstr long ptr long)
; @ stdcall GetMenuIndex(ptr ptr)
Modified: trunk/reactos/dll/win32/user32/windows/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/c…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/cursoricon.c [iso-8859-1] Wed Jul 14 09:54:44
2010
@@ -66,6 +66,25 @@
0, 0, { (DWORD_PTR)(__FILE__ ": IconCrst") }
};
static CRITICAL_SECTION IconCrst = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+/***********************************************************************
+ * CreateCursorIconHandle
+ *
+ * Creates a handle with everything in there
+ */
+static
+HICON
+CreateCursorIconHandle( PICONINFO IconInfo )
+{
+ HICON hIcon = (HICON)NtUserCallOneParam(0, //FIXME ?
+ ONEPARAM_ROUTINE_CREATECURICONHANDLE);
+ if(!hIcon)
+ return NULL;
+
+ NtUserSetCursorContents(hIcon, IconInfo);
+ return hIcon;
+}
+
/***********************************************************************
@@ -563,7 +582,7 @@
IconInfo.hbmColor = color;
IconInfo.hbmMask = mask;
- return NtUserCreateCursorIconHandle(&IconInfo, FALSE);
+ return CreateCursorIconHandle(&IconInfo);
}
@@ -1386,55 +1405,120 @@
return NtUserGetIconInfo(hIcon, iconinfo, 0, 0, 0, 0);
}
+/* copy an icon bitmap, even when it can't be selected into a DC */
+/* helper for CreateIconIndirect */
+static void stretch_blt_icon( HDC hdc_dst, int dst_x, int dst_y, int dst_width, int
dst_height,
+ HBITMAP src, int width, int height )
+{
+ HDC hdc = CreateCompatibleDC( 0 );
+
+ if (!SelectObject( hdc, src )) /* do it the hard way */
+ {
+ BITMAPINFO *info;
+ void *bits;
+
+ if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO,
bmiColors[256] )))) return;
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info->bmiHeader.biWidth = width;
+ info->bmiHeader.biHeight = height;
+ info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
+ info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biSizeImage = height * get_dib_width_bytes( width,
info->bmiHeader.biBitCount );
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+ bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
+ if (bits && GetDIBits( hdc, src, 0, height, bits, info, DIB_RGB_COLORS
))
+ StretchDIBits( hdc_dst, dst_x, dst_y, dst_width, dst_height,
+ 0, 0, width, height, bits, info, DIB_RGB_COLORS, SRCCOPY );
+
+ HeapFree( GetProcessHeap(), 0, bits );
+ HeapFree( GetProcessHeap(), 0, info );
+ }
+ else StretchBlt( hdc_dst, dst_x, dst_y, dst_width, dst_height, hdc, 0, 0, width,
height, SRCCOPY );
+
+ DeleteDC( hdc );
+}
+
/**********************************************************************
* CreateIconIndirect (USER32.@)
*/
HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
{
- BITMAP ColorBitmap;
- BITMAP MaskBitmap;
- ICONINFO safeIconInfo;
-
- if(!iconinfo)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return (HICON)0;
- }
-
- safeIconInfo = *iconinfo;
-
- if(!GetObjectW(safeIconInfo.hbmMask, sizeof(BITMAP), &MaskBitmap))
- {
- return (HICON)0;
- }
-
- /* Try to get color bitmap */
- if (GetObjectW(safeIconInfo.hbmColor, sizeof(BITMAP), &ColorBitmap))
- {
- /* Compare size of color and mask bitmap*/
- if (ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
- ColorBitmap.bmHeight != MaskBitmap.bmHeight)
- {
- ERR("Color and mask size are different!");
- SetLastError(ERROR_INVALID_PARAMETER);
- return (HICON)0;
- }
- /* Test if they are inverted */
- if(ColorBitmap.bmBitsPixel == 1)
- {
- if(MaskBitmap.bmBitsPixel != 1)
- {
- safeIconInfo.hbmMask = iconinfo->hbmColor;
- safeIconInfo.hbmColor = iconinfo->hbmMask;
- }
- else
- {
- /* Wine tests say so */
- safeIconInfo.hbmColor = NULL;
- }
- }
- }
- return (HICON)NtUserCreateCursorIconHandle(&safeIconInfo, TRUE);
+ BITMAP bmpXor, bmpAnd;
+ HBITMAP color = 0, mask;
+ int width, height;
+ HDC hdc;
+ ICONINFO iinfo;
+
+ TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
+ iconinfo->hbmColor, iconinfo->hbmMask,
+ iconinfo->xHotspot, iconinfo->yHotspot, iconinfo->fIcon);
+
+ if (!iconinfo->hbmMask) return 0;
+
+ GetObjectW( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd );
+ TRACE("mask: width %d, height %d, width bytes %d, planes %u, bpp %u\n",
+ bmpAnd.bmWidth, bmpAnd.bmHeight, bmpAnd.bmWidthBytes,
+ bmpAnd.bmPlanes, bmpAnd.bmBitsPixel);
+
+ if (iconinfo->hbmColor)
+ {
+ GetObjectW( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor );
+ TRACE("color: width %d, height %d, width bytes %d, planes %u, bpp
%u\n",
+ bmpXor.bmWidth, bmpXor.bmHeight, bmpXor.bmWidthBytes,
+ bmpXor.bmPlanes, bmpXor.bmBitsPixel);
+
+ width = bmpXor.bmWidth;
+ height = bmpXor.bmHeight;
+ if (bmpXor.bmPlanes * bmpXor.bmBitsPixel != 1)
+ {
+ color = CreateCompatibleBitmap( screen_dc, width, height );
+ mask = CreateBitmap( width, height, 1, 1, NULL );
+ }
+ else mask = CreateBitmap( width, height * 2, 1, 1, NULL );
+ }
+ else
+ {
+ width = bmpAnd.bmWidth;
+ height = bmpAnd.bmHeight;
+ mask = CreateBitmap( width, height, 1, 1, NULL );
+ }
+
+ hdc = CreateCompatibleDC( 0 );
+ SelectObject( hdc, mask );
+ stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmMask, bmpAnd.bmWidth,
bmpAnd.bmHeight );
+
+ if (color)
+ {
+ SelectObject( hdc, color );
+ stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height
);
+ }
+ else if (iconinfo->hbmColor)
+ {
+ stretch_blt_icon( hdc, 0, height, width, height, iconinfo->hbmColor, width,
height );
+ }
+ else height /= 2;
+
+ DeleteDC( hdc );
+
+ iinfo.hbmColor = color ;
+ iinfo.hbmMask = mask ;
+ iinfo.fIcon = iconinfo->fIcon;
+ if (iinfo.fIcon)
+ {
+ iinfo.xHotspot = width / 2;
+ iinfo.yHotspot = height / 2;
+ }
+ else
+ {
+ iinfo.xHotspot = iconinfo->xHotspot;
+ iinfo.yHotspot = iconinfo->yHotspot;
+ }
+
+ return CreateCursorIconHandle(&iinfo);
}
/******************************************************************************
@@ -2047,23 +2131,6 @@
return res;
}
-#undef CopyCursor
-/*
- * @implemented
- */
-HCURSOR
-WINAPI
-CopyCursor(HCURSOR pcur)
-{
- ICONINFO IconInfo;
-
- if(GetIconInfo((HANDLE)pcur, &IconInfo))
- {
- return (HCURSOR)NtUserCreateCursorIconHandle(&IconInfo, FALSE);
- }
- return (HCURSOR)0;
-}
-
/* INTERNAL ******************************************************************/
/* This callback routine is called directly after switching to gui mode */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Wed Jul 14
09:54:44 2010
@@ -1030,11 +1030,13 @@
}
/* Delete old bitmaps */
- if (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor)
+ if ((CurIcon->IconInfo.hbmColor)
+ && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
{
GreDeleteObject(CurIcon->IconInfo.hbmColor);
}
- if (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
+ if ((CurIcon->IconInfo.hbmMask)
+ && (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask))
{
GreDeleteObject(CurIcon->IconInfo.hbmMask);
}
@@ -1226,6 +1228,15 @@
}
done:
+ if(Ret)
+ {
+ /* This icon is shared now */
+ GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
+ if(CurIcon->IconInfo.hbmColor)
+ {
+ GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
+ }
+ }
UserDereferenceObject(CurIcon);
RETURN(Ret);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Wed Jul 14
09:54:44 2010
@@ -195,6 +195,7 @@
case ONEPARAM_ROUTINE_CREATECURICONHANDLE:
{
PCURICON_OBJECT CurIcon;
+ DWORD_PTR Result ;
if (!(CurIcon = IntCreateCurIconHandle()))
{
@@ -202,7 +203,9 @@
RETURN(0);
}
- RETURN((DWORD_PTR)CurIcon->Self);
+ Result = (DWORD_PTR)CurIcon->Self;
+ UserDereferenceObject(CurIcon);
+ RETURN(Result);
}
case ONEPARAM_ROUTINE_GETCURSORPOSITION: