Alexandre Julliard : user32: Reimplement loading of 16-bit cursors and icons using 16-bit resource functions .
Alexandre Julliard
julliard at winehq.org
Tue Dec 22 09:58:56 CST 2009
Module: wine
Branch: master
Commit: d5b270eaddc9d3de249e410b98ce6fe5d177ccc4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d5b270eaddc9d3de249e410b98ce6fe5d177ccc4
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Dec 21 17:38:44 2009 +0100
user32: Reimplement loading of 16-bit cursors and icons using 16-bit resource functions.
---
dlls/user32/user16.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 129 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/user16.c b/dlls/user32/user16.c
index b338720..0957ba2 100644
--- a/dlls/user32/user16.c
+++ b/dlls/user32/user16.c
@@ -33,6 +33,7 @@
#include "user_private.h"
#include "win.h"
#include "controls.h"
+#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(user);
@@ -248,6 +249,62 @@ static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
/**********************************************************************
+ * Management of the 16-bit cursor/icon cache
+ */
+
+struct cache_entry
+{
+ struct list entry;
+ HINSTANCE16 inst;
+ HRSRC16 rsrc;
+ HRSRC16 group;
+ HICON16 icon;
+ INT count;
+};
+
+static struct list icon_cache = LIST_INIT( icon_cache );
+
+static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
+{
+ struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
+
+ if (!cache) return;
+ cache->inst = inst;
+ cache->rsrc = rsrc;
+ cache->group = group;
+ cache->icon = icon;
+ cache->count = 1;
+ list_add_tail( &icon_cache, &cache->entry );
+}
+
+static HICON16 find_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc )
+{
+ struct cache_entry *cache;
+
+ LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
+ {
+ if (cache->inst != inst || cache->rsrc != rsrc) continue;
+ cache->count++;
+ return cache->icon;
+ }
+ return 0;
+}
+
+static int release_shared_icon( HICON16 icon )
+{
+ struct cache_entry *cache;
+
+ LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
+ {
+ if (cache->icon != icon) continue;
+ if (!cache->count) return 0;
+ return --cache->count;
+ }
+ return -1;
+}
+
+
+/**********************************************************************
* InitApp (USER.5)
*/
INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
@@ -755,7 +812,7 @@ BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
*/
HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
{
- return HCURSOR_16(LoadCursorA(HINSTANCE_32(hInstance), name));
+ return LoadImage16( hInstance, name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
}
@@ -764,7 +821,7 @@ HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
*/
HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
{
- return HICON_16(LoadIconA(HINSTANCE_32(hInstance), name));
+ return LoadImage16( hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
}
/**********************************************************************
@@ -1685,11 +1742,67 @@ DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
* LoadImage (USER.389)
*
*/
-HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type,
- INT16 desiredx, INT16 desiredy, UINT16 loadflags)
+HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 cx, INT16 cy, UINT16 flags)
{
- return HANDLE_16(LoadImageA(HINSTANCE_32(hinst), name, type, desiredx,
- desiredy, loadflags));
+ if (!hinst || (flags & LR_LOADFROMFILE))
+ return HICON_16( LoadImageA( 0, name, type, cx, cy, flags ));
+
+ hinst = GetExePtr( hinst );
+
+ if (flags & LR_DEFAULTSIZE)
+ {
+ if (type == IMAGE_ICON)
+ {
+ if (!cx) cx = GetSystemMetrics(SM_CXICON);
+ if (!cy) cy = GetSystemMetrics(SM_CYICON);
+ }
+ else if (type == IMAGE_CURSOR)
+ {
+ if (!cx) cx = GetSystemMetrics(SM_CXCURSOR);
+ if (!cy) cy = GetSystemMetrics(SM_CYCURSOR);
+ }
+ }
+
+ switch (type)
+ {
+ case IMAGE_BITMAP:
+ return HBITMAP_16( LoadImageA( HINSTANCE_32(hinst), name, type, cx, cy, flags ));
+
+ case IMAGE_ICON:
+ case IMAGE_CURSOR:
+ {
+ HANDLE16 handle;
+ HICON16 hIcon = 0;
+ HRSRC16 hRsrc, hGroupRsrc;
+ BYTE *dir, *bits;
+ INT id = 0;
+
+ if (!(hRsrc = FindResource16( hinst, name,
+ (LPCSTR)(type == IMAGE_ICON ? RT_GROUP_ICON : RT_GROUP_CURSOR ))))
+ return 0;
+ hGroupRsrc = hRsrc;
+
+ if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
+ if ((dir = LockResource16( handle ))) id = LookupIconIdFromDirectory( dir, type == IMAGE_ICON );
+ FreeResource16( handle );
+ if (!id) return 0;
+
+ if (!(hRsrc = FindResource16( hinst, MAKEINTRESOURCEA(id),
+ (LPCSTR)(type == IMAGE_ICON ? RT_ICON : RT_CURSOR) ))) return 0;
+
+ if ((flags & LR_SHARED) && (hIcon = find_shared_icon( hinst, hRsrc ) ) != 0) return hIcon;
+
+ if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
+ bits = LockResource16( handle );
+ hIcon = CreateIconFromResourceEx16( bits, 0, type == IMAGE_ICON, 0x00030000, cx, cy, flags );
+ FreeResource16( handle );
+
+ if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
+ return hIcon;
+ }
+ default:
+ return 0;
+ }
}
/******************************************************************************
@@ -2199,7 +2312,15 @@ HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
*/
BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
{
- return DestroyIcon32(hIcon, 0);
+ int count;
+
+ TRACE("%04x\n", hIcon );
+
+ count = release_shared_icon( hIcon );
+ if (count != -1) return !count;
+ /* assume non-shared */
+ GlobalFree16( hIcon );
+ return TRUE;
}
/***********************************************************************
@@ -2207,7 +2328,7 @@ BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
*/
BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
{
- return DestroyIcon32(hCursor, 0);
+ return DestroyIcon16( hCursor );
}
More information about the wine-cvs
mailing list