Commit e8723a5d authored by Alexandre Julliard's avatar Alexandre Julliard

user32: Fix destruction of the active cursor.

parent 1aab7ea8
...@@ -387,22 +387,6 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width, ...@@ -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 * get_icon_size
*/ */
BOOL get_icon_size( HICON handle, SIZE *size ) BOOL get_icon_size( HICON handle, SIZE *size )
...@@ -1357,7 +1341,11 @@ HICON WINAPI CopyIcon( HICON hIcon ) ...@@ -1357,7 +1341,11 @@ HICON WINAPI CopyIcon( HICON hIcon )
struct cursoricon_object *ptrOld, *ptrNew; struct cursoricon_object *ptrOld, *ptrNew;
HICON hNew; 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))) if ((hNew = alloc_icon_handle(1)))
{ {
ptrNew = get_icon_ptr( hNew ); ptrNew = get_icon_ptr( hNew );
...@@ -1381,10 +1369,19 @@ HICON WINAPI CopyIcon( HICON hIcon ) ...@@ -1381,10 +1369,19 @@ HICON WINAPI CopyIcon( HICON hIcon )
*/ */
BOOL WINAPI DestroyIcon( HICON hIcon ) BOOL WINAPI DestroyIcon( HICON hIcon )
{ {
BOOL ret = FALSE;
struct cursoricon_object *obj = get_icon_ptr( hIcon );
TRACE_(icon)("%p\n", hIcon ); TRACE_(icon)("%p\n", hIcon );
if (!is_icon_shared( hIcon )) free_icon_handle( hIcon ); if (obj)
return TRUE; {
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 ) ...@@ -1393,11 +1390,6 @@ BOOL WINAPI DestroyIcon( HICON hIcon )
*/ */
BOOL WINAPI DestroyCursor( HCURSOR hCursor ) BOOL WINAPI DestroyCursor( HCURSOR hCursor )
{ {
if (GetCursor() == hCursor)
{
WARN_(cursor)("Destroying active cursor!\n" );
return FALSE;
}
return DestroyIcon( hCursor ); return DestroyIcon( hCursor );
} }
...@@ -1419,6 +1411,7 @@ BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon ) ...@@ -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 */ ) HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cursor to show */ )
{ {
struct cursoricon_object *obj;
HCURSOR hOldCursor; HCURSOR hOldCursor;
int show_count; int show_count;
BOOL ret; BOOL ret;
...@@ -1441,6 +1434,9 @@ HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cu ...@@ -1441,6 +1434,9 @@ HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cu
/* Change the cursor shape only if it is visible */ /* Change the cursor shape only if it is visible */
if (show_count >= 0 && hOldCursor != hCursor) USER_Driver->pSetCursor( hCursor ); 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; return hOldCursor;
} }
......
...@@ -82,7 +82,7 @@ static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARA ...@@ -82,7 +82,7 @@ static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARA
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DestroyCursor((HCURSOR) lParam); ret = DestroyCursor((HCURSOR) lParam);
error = GetLastError(); 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 || ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD ||
error == 0xdeadbeef, /* vista */ error == 0xdeadbeef, /* vista */
"Last error: %u\n", error); "Last error: %u\n", error);
...@@ -1769,8 +1769,8 @@ static void test_DestroyCursor(void) ...@@ -1769,8 +1769,8 @@ static void test_DestroyCursor(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = GetIconInfo( cursor, &new_info ); ret = GetIconInfo( cursor, &new_info );
todo_wine ok( !ret || broken(ret), /* nt4 */ "GetIconInfo succeeded\n" ); ok( !ret || broken(ret), /* nt4 */ "GetIconInfo succeeded\n" );
todo_wine ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE || ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE ||
broken(GetLastError() == 0xdeadbeef), /* win9x */ broken(GetLastError() == 0xdeadbeef), /* win9x */
"wrong error %u\n", GetLastError() ); "wrong error %u\n", GetLastError() );
...@@ -1824,7 +1824,7 @@ static void test_DestroyCursor(void) ...@@ -1824,7 +1824,7 @@ static void test_DestroyCursor(void)
if (new_cursor != cursor) /* win9x */ if (new_cursor != cursor) /* win9x */
ok(cursor2 == new_cursor, "SetCursor returned %p/%p\n", cursor2, cursor); ok(cursor2 == new_cursor, "SetCursor returned %p/%p\n", cursor2, cursor);
else 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() ); ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
cursor2 = GetCursor(); cursor2 = GetCursor();
...@@ -1835,7 +1835,7 @@ static void test_DestroyCursor(void) ...@@ -1835,7 +1835,7 @@ static void test_DestroyCursor(void)
if (new_cursor != cursor) /* win9x */ if (new_cursor != cursor) /* win9x */
ok( ret, "DestroyCursor succeeded\n" ); ok( ret, "DestroyCursor succeeded\n" );
else else
todo_wine ok( !ret, "DestroyCursor succeeded\n" ); ok( !ret, "DestroyCursor succeeded\n" );
error = GetLastError(); error = GetLastError();
ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE || GetLastError() == 0xdeadbeef, ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE || GetLastError() == 0xdeadbeef,
"wrong error %u\n", GetLastError() ); "wrong error %u\n", GetLastError() );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment