Alexandre Julliard : user32: Store icon objects directly in the cache instead of using a separate structure .
Alexandre Julliard
julliard at winehq.org
Mon Oct 11 13:15:13 CDT 2010
Module: wine
Branch: master
Commit: 76e7fcc9d8bfae05fac2119eb653ee85c1fd24ce
URL: http://source.winehq.org/git/wine.git/?a=commit;h=76e7fcc9d8bfae05fac2119eb653ee85c1fd24ce
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Oct 11 14:55:46 2010 +0200
user32: Store icon objects directly in the cache instead of using a separate structure.
---
dlls/user32/cursoricon.c | 149 +++++++++++++---------------------------------
1 files changed, 42 insertions(+), 107 deletions(-)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 1af3aa4..d2219d2 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -25,6 +25,7 @@
#include "config.h"
#include "wine/port.h"
+#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
@@ -37,6 +38,7 @@
#include "wine/exception.h"
#include "wine/server.h"
#include "controls.h"
+#include "win.h"
#include "user_private.h"
#include "wine/list.h"
#include "wine/unicode.h"
@@ -75,31 +77,8 @@ static HDC screen_dc;
static const WCHAR DISPLAYW[] = {'D','I','S','P','L','A','Y',0};
-
-/**********************************************************************
- * ICONCACHE for cursors/icons loaded with LR_SHARED.
- */
-typedef struct tagICONCACHE
-{
- struct list entry;
- HMODULE hModule;
- HRSRC hRsrc;
- HRSRC hGroupRsrc;
- HICON hIcon;
-} ICONCACHE;
-
static struct list icon_cache = LIST_INIT( icon_cache );
-static CRITICAL_SECTION IconCrst;
-static CRITICAL_SECTION_DEBUG critsect_debug =
-{
- 0, 0, &IconCrst,
- { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
- 0, 0, { (DWORD_PTR)(__FILE__ ": IconCrst") }
-};
-static CRITICAL_SECTION IconCrst = { &critsect_debug, -1, 0, 0, 0, 0 };
-
-
/**********************************************************************
* User objects management
*/
@@ -114,9 +93,11 @@ struct cursoricon_frame
struct cursoricon_object
{
struct user_object obj; /* object header */
+ struct list entry; /* entry in shared icons list */
ULONG_PTR param; /* opaque param used by 16-bit code */
HMODULE module; /* module for icons loaded from resources */
LPWSTR resname; /* resource name for icons loaded from resources */
+ HRSRC rsrc; /* resource for shared icons */
BOOL is_icon; /* whether icon or cursor */
UINT width;
UINT height;
@@ -162,6 +143,8 @@ static BOOL free_icon_handle( HICON handle )
ULONG_PTR param = obj->param;
UINT i;
+ assert( !obj->rsrc ); /* shared icons can't be freed */
+
for (i=0; i<obj->num_frames; i++)
{
if (obj->frames[i].alpha) DeleteObject( obj->frames[i].alpha );
@@ -401,77 +384,19 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
}
/**********************************************************************
- * CURSORICON_FindSharedIcon
- */
-static HICON CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc )
-{
- HICON hIcon = 0;
- ICONCACHE *ptr;
-
- EnterCriticalSection( &IconCrst );
-
- LIST_FOR_EACH_ENTRY( ptr, &icon_cache, ICONCACHE, entry )
- if ( ptr->hModule == hModule && ptr->hRsrc == hRsrc )
- {
- hIcon = ptr->hIcon;
- break;
- }
-
- LeaveCriticalSection( &IconCrst );
-
- return hIcon;
-}
-
-/*************************************************************************
- * CURSORICON_FindCache
- *
- * Given a handle, find the corresponding cache element
- *
- * PARAMS
- * Handle [I] handle to an Image
- *
- * RETURNS
- * Success: The cache entry
- * Failure: NULL
- *
+ * is_icon_shared
*/
-static ICONCACHE* CURSORICON_FindCache(HICON hIcon)
+static BOOL is_icon_shared( HICON handle )
{
- ICONCACHE *ptr;
- ICONCACHE *pRet=NULL;
-
- EnterCriticalSection( &IconCrst );
+ struct cursoricon_object *info;
+ BOOL ret = FALSE;
- LIST_FOR_EACH_ENTRY( ptr, &icon_cache, ICONCACHE, entry )
+ if ((info = get_icon_ptr( handle )))
{
- if ( hIcon == ptr->hIcon )
- {
- pRet = ptr;
- break;
- }
+ ret = info->rsrc != NULL;
+ release_icon_ptr( handle, info );
}
-
- LeaveCriticalSection( &IconCrst );
-
- return pRet;
-}
-
-/**********************************************************************
- * CURSORICON_AddSharedIcon
- */
-static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HRSRC hGroupRsrc, HICON hIcon )
-{
- ICONCACHE *ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(ICONCACHE) );
- if ( !ptr ) return;
-
- ptr->hModule = hModule;
- ptr->hRsrc = hRsrc;
- ptr->hIcon = hIcon;
- ptr->hGroupRsrc = hGroupRsrc;
-
- EnterCriticalSection( &IconCrst );
- list_add_head( &icon_cache, &ptr->entry );
- LeaveCriticalSection( &IconCrst );
+ return ret;
}
/**********************************************************************
@@ -849,7 +774,7 @@ done:
return ret;
}
-static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi, HMODULE module, LPCWSTR resname,
+static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi, HMODULE module, LPCWSTR resname, HRSRC rsrc,
POINT hotspot, BOOL bIcon, INT width, INT height, UINT cFlag )
{
HICON hObj;
@@ -908,6 +833,11 @@ static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi, HMODULE module, LPCW
}
else info->resname = MAKEINTRESOURCEW( LOWORD(resname) );
+ if (module && (cFlag & LR_SHARED))
+ {
+ info->rsrc = rsrc;
+ list_add_head( &icon_cache, &info->entry );
+ }
release_icon_ptr( hObj, info );
USER_Driver->pCreateCursorIcon( hObj );
}
@@ -1180,7 +1110,7 @@ HICON WINAPI CreateIconFromResourceEx( LPBYTE bits, UINT cbSize,
bmi = (BITMAPINFO *)(pt + 2);
}
- return CURSORICON_CreateIconFromBMI( bmi, NULL, NULL, hotspot, bIcon, width, height, cFlag );
+ return CURSORICON_CreateIconFromBMI( bmi, NULL, NULL, NULL, hotspot, bIcon, width, height, cFlag );
}
@@ -1242,7 +1172,7 @@ static HICON CURSORICON_LoadFromFile( LPCWSTR filename,
hotspot.x = entry->xHotspot;
hotspot.y = entry->yHotspot;
- hIcon = CURSORICON_CreateIconFromBMI( (BITMAPINFO *)&bits[entry->dwDIBOffset], NULL, NULL,
+ hIcon = CURSORICON_CreateIconFromBMI( (BITMAPINFO *)&bits[entry->dwDIBOffset], NULL, NULL, NULL,
hotspot, !fCursor, width, height, loadflags );
end:
TRACE("loaded %s -> %p\n", debugstr_w( filename ), hIcon );
@@ -1261,7 +1191,7 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
{
HANDLE handle = 0;
HICON hIcon = 0;
- HRSRC hRsrc, hGroupRsrc;
+ HRSRC hRsrc;
CURSORICONDIR *dir;
CURSORICONDIRENTRY *dirEntry;
LPBYTE bits;
@@ -1285,7 +1215,6 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
if (!(hRsrc = FindResourceW( hInstance, name,
(LPWSTR)(fCursor ? RT_GROUP_CURSOR : RT_GROUP_ICON) )))
return 0;
- hGroupRsrc = hRsrc;
/* Find the best entry in the directory */
@@ -1306,9 +1235,21 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
(LPWSTR)(fCursor ? RT_CURSOR : RT_ICON) ))) return 0;
/* If shared icon, check whether it was already loaded */
- if ( (loadflags & LR_SHARED)
- && (hIcon = CURSORICON_FindSharedIcon( hInstance, hRsrc ) ) != 0 )
- return hIcon;
+ if (loadflags & LR_SHARED)
+ {
+ struct cursoricon_object *ptr;
+
+ USER_Lock();
+ LIST_FOR_EACH_ENTRY( ptr, &icon_cache, struct cursoricon_object, entry )
+ {
+ if (ptr->module != hInstance) continue;
+ if (ptr->rsrc != hRsrc) continue;
+ hIcon = ptr->obj.handle;
+ break;
+ }
+ USER_Unlock();
+ if (hIcon) return hIcon;
+ }
if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
bits = LockResource( handle );
@@ -1325,15 +1266,9 @@ static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
hotspot.y = pt[1];
bits += 2 * sizeof(SHORT);
}
- hIcon = CURSORICON_CreateIconFromBMI( (BITMAPINFO *)bits, hInstance, name, hotspot,
- !fCursor, width, height, loadflags );
+ hIcon = CURSORICON_CreateIconFromBMI( (BITMAPINFO *)bits, hInstance, name, hRsrc,
+ hotspot, !fCursor, width, height, loadflags );
FreeResource( handle );
-
- /* If shared icon, add to icon cache */
-
- if ( hIcon && (loadflags & LR_SHARED) )
- CURSORICON_AddSharedIcon( hInstance, hRsrc, hGroupRsrc, hIcon );
-
return hIcon;
}
@@ -1447,7 +1382,7 @@ BOOL WINAPI DestroyIcon( HICON hIcon )
{
TRACE_(icon)("%p\n", hIcon );
- if (!CURSORICON_FindCache( hIcon )) free_icon_handle( hIcon );
+ if (!is_icon_shared( hIcon )) free_icon_handle( hIcon );
return TRUE;
}
@@ -2591,7 +2526,7 @@ HANDLE WINAPI CopyImage( HANDLE hnd, UINT type, INT desiredx,
if (!(icon = get_icon_ptr( hnd ))) return 0;
- if (icon->module && (flags & LR_COPYFROMRESOURCE))
+ if (icon->rsrc && (flags & LR_COPYFROMRESOURCE))
res = CURSORICON_Load( icon->module, icon->resname, desiredx, desiredy, depth,
type == IMAGE_CURSOR, flags );
else
More information about the wine-cvs
mailing list