[ros-diffs] [jgardou] 48034: [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

jgardou at svn.reactos.org jgardou at svn.reactos.org
Wed Jul 14 09:54:44 UTC 2010


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.pspec?rev=48034&r1=48033&r2=48034&view=diff
==============================================================================
--- 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/cursoricon.c?rev=48034&r1=48033&r2=48034&view=diff
==============================================================================
--- 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/ntuser/cursoricon.c?rev=48034&r1=48033&r2=48034&view=diff
==============================================================================
--- 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/ntuser/simplecall.c?rev=48034&r1=48033&r2=48034&view=diff
==============================================================================
--- 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:




More information about the Ros-diffs mailing list