Alexandre Julliard : user32: Fix destruction of the active cursor.

Alexandre Julliard julliard at winehq.org
Wed Oct 13 11:43:09 CDT 2010


Module: wine
Branch: master
Commit: e8723a5dee0134f9a0470d3850eebbdf0bef9889
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e8723a5dee0134f9a0470d3850eebbdf0bef9889

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Oct 13 15:38:06 2010 +0200

user32: Fix destruction of the active cursor.

---

 dlls/user32/cursoricon.c       |   44 ++++++++++++++++++---------------------
 dlls/user32/tests/cursoricon.c |   10 ++++----
 2 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 9732db6..eeaae7a 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -387,22 +387,6 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
 }
 
 /**********************************************************************
- *              is_icon_shared
- */
-static BOOL is_icon_shared( HICON handle )
-{
-    struct cursoricon_object *info;
-    BOOL ret = FALSE;
-
-    if ((info = get_icon_ptr( handle )))
-    {
-        ret = info->rsrc != NULL;
-        release_icon_ptr( handle, info );
-    }
-    return ret;
-}
-
-/**********************************************************************
  *              get_icon_size
  */
 BOOL get_icon_size( HICON handle, SIZE *size )
@@ -1357,7 +1341,11 @@ HICON WINAPI CopyIcon( HICON hIcon )
     struct cursoricon_object *ptrOld, *ptrNew;
     HICON hNew;
 
-    if (!(ptrOld = get_icon_ptr( hIcon ))) return 0;
+    if (!(ptrOld = get_icon_ptr( hIcon )))
+    {
+        SetLastError( ERROR_INVALID_CURSOR_HANDLE );
+        return 0;
+    }
     if ((hNew = alloc_icon_handle(1)))
     {
         ptrNew = get_icon_ptr( hNew );
@@ -1381,10 +1369,19 @@ HICON WINAPI CopyIcon( HICON hIcon )
  */
 BOOL WINAPI DestroyIcon( HICON hIcon )
 {
+    BOOL ret = FALSE;
+    struct cursoricon_object *obj = get_icon_ptr( hIcon );
+
     TRACE_(icon)("%p\n", hIcon );
 
-    if (!is_icon_shared( hIcon )) free_icon_handle( hIcon );
-    return TRUE;
+    if (obj)
+    {
+        BOOL shared = (obj->rsrc != NULL);
+        release_icon_ptr( hIcon, obj );
+        ret = (GetCursor() != hIcon);
+        if (!shared) free_icon_handle( hIcon );
+    }
+    return ret;
 }
 
 
@@ -1393,11 +1390,6 @@ BOOL WINAPI DestroyIcon( HICON hIcon )
  */
 BOOL WINAPI DestroyCursor( HCURSOR hCursor )
 {
-    if (GetCursor() == hCursor)
-    {
-        WARN_(cursor)("Destroying active cursor!\n" );
-        return FALSE;
-    }
     return DestroyIcon( hCursor );
 }
 
@@ -1419,6 +1411,7 @@ BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
  */
 HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cursor to show */ )
 {
+    struct cursoricon_object *obj;
     HCURSOR hOldCursor;
     int show_count;
     BOOL ret;
@@ -1441,6 +1434,9 @@ HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cu
 
     /* Change the cursor shape only if it is visible */
     if (show_count >= 0 && hOldCursor != hCursor) USER_Driver->pSetCursor( hCursor );
+
+    if (!(obj = get_icon_ptr( hOldCursor ))) return 0;
+    release_icon_ptr( hOldCursor, obj );
     return hOldCursor;
 }
 
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 57419e5..8f7db52 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -82,7 +82,7 @@ static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARA
             SetLastError(0xdeadbeef);
             ret = DestroyCursor((HCURSOR) lParam);
             error = GetLastError();
-            todo_wine ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
+            ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
             ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD ||
                error == 0xdeadbeef,  /* vista */
                 "Last error: %u\n", error);
@@ -1769,8 +1769,8 @@ static void test_DestroyCursor(void)
 
     SetLastError(0xdeadbeef);
     ret = GetIconInfo( cursor, &new_info );
-    todo_wine ok( !ret || broken(ret), /* nt4 */ "GetIconInfo succeeded\n" );
-    todo_wine ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE ||
+    ok( !ret || broken(ret), /* nt4 */ "GetIconInfo succeeded\n" );
+    ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE ||
         broken(GetLastError() == 0xdeadbeef), /* win9x */
         "wrong error %u\n", GetLastError() );
 
@@ -1824,7 +1824,7 @@ static void test_DestroyCursor(void)
     if (new_cursor != cursor)  /* win9x */
         ok(cursor2 == new_cursor, "SetCursor returned %p/%p\n", cursor2, cursor);
     else
-        todo_wine ok(!cursor2, "SetCursor returned %p/%p\n", cursor2, cursor);
+        ok(!cursor2, "SetCursor returned %p/%p\n", cursor2, cursor);
     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
 
     cursor2 = GetCursor();
@@ -1835,7 +1835,7 @@ static void test_DestroyCursor(void)
     if (new_cursor != cursor)  /* win9x */
         ok( ret, "DestroyCursor succeeded\n" );
     else
-        todo_wine ok( !ret, "DestroyCursor succeeded\n" );
+        ok( !ret, "DestroyCursor succeeded\n" );
     error = GetLastError();
     ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE || GetLastError() == 0xdeadbeef,
         "wrong error %u\n", GetLastError() );




More information about the wine-cvs mailing list