Damjan Jovanovic : winemenubuilder: Defer best icon selection to when we generate the native icons.
Alexandre Julliard
julliard at winehq.org
Mon Aug 23 10:50:16 CDT 2010
Module: wine
Branch: master
Commit: d58f2680d1d0320b01cb88d736523cf521f6adc9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d58f2680d1d0320b01cb88d736523cf521f6adc9
Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date: Sun Aug 22 19:46:51 2010 +0200
winemenubuilder: Defer best icon selection to when we generate the native icons.
---
programs/winemenubuilder/winemenubuilder.c | 162 ++++++++++++++++------------
1 files changed, 91 insertions(+), 71 deletions(-)
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 445fe53..8941cbf 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -301,54 +301,108 @@ end:
return SUCCEEDED(hr);
}
-static IStream* module_icon_to_stream(GRPICONDIRENTRY *grpIconDirEntry, BITMAPINFO *pIcon)
+static IStream *add_module_icons_to_stream(HMODULE hModule, GRPICONDIR *grpIconDir)
{
- SIZE_T size;
- HGLOBAL hGlobal = NULL;
+ int i;
+ SIZE_T iconsSize = 0;
+ BYTE *icons = NULL;
+ ICONDIRENTRY *iconDirEntries = NULL;
IStream *stream = NULL;
- char *p;
- ICONDIR *pIconDir;
- ICONDIRENTRY *pIconDirEntry;
HRESULT hr = E_FAIL;
+ ULONG bytesWritten;
+ ICONDIR iconDir;
+ SIZE_T iconOffset;
+ int validEntries = 0;
+ LARGE_INTEGER zero;
- size = sizeof(ICONDIR) + sizeof(ICONDIRENTRY) + grpIconDirEntry->dwBytesInRes;
- hGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
- if (hGlobal == NULL)
+ for (i = 0; i < grpIconDir->idCount; i++)
+ iconsSize += grpIconDir->idEntries[i].dwBytesInRes;
+ icons = HeapAlloc(GetProcessHeap(), 0, iconsSize);
+ if (icons == NULL)
{
WINE_ERR("out of memory allocating icon\n");
goto end;
}
- p = GlobalLock(hGlobal);
- pIconDir = (ICONDIR*)p;
- pIconDir->idReserved = 0;
- pIconDir->idType = 1;
- pIconDir->idCount = 1;
- p += sizeof(ICONDIR);
- pIconDirEntry = (ICONDIRENTRY*)p;
- pIconDirEntry->bWidth = grpIconDirEntry->bWidth;
- pIconDirEntry->bHeight = grpIconDirEntry->bHeight;
- pIconDirEntry->bColorCount = grpIconDirEntry->bColorCount;
- pIconDirEntry->bReserved = grpIconDirEntry->bReserved;
- pIconDirEntry->wPlanes = grpIconDirEntry->wPlanes;
- pIconDirEntry->wBitCount = grpIconDirEntry->wBitCount;
- pIconDirEntry->dwBytesInRes = grpIconDirEntry->dwBytesInRes;
- pIconDirEntry->dwImageOffset = sizeof(ICONDIR) + sizeof(ICONDIRENTRY);
- p += sizeof(ICONDIRENTRY);
- memcpy(p, pIcon, grpIconDirEntry->dwBytesInRes);
- GlobalUnlock(hGlobal);
-
- hr = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);
+ iconDirEntries = HeapAlloc(GetProcessHeap(), 0, grpIconDir->idCount*sizeof(ICONDIRENTRY));
+ if (iconDirEntries == NULL)
+ {
+ WINE_ERR("out of memory allocating icon dir entries\n");
+ goto end;
+ }
+
+ hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
if (FAILED(hr))
{
- WINE_ERR("could not create stream on icon hglobal, error 0x%08X\n", hr);
+ WINE_ERR("error creating icon stream\n");
+ goto end;
+ }
+
+ iconOffset = 0;
+ for (i = 0; i < grpIconDir->idCount; i++)
+ {
+ HRSRC hResInfo;
+ LPCWSTR lpName = MAKEINTRESOURCEW(grpIconDir->idEntries[i].nID);
+ if ((hResInfo = FindResourceW(hModule, lpName, (LPCWSTR)RT_ICON)))
+ {
+ HGLOBAL hResData;
+ if ((hResData = LoadResource(hModule, hResInfo)))
+ {
+ BITMAPINFO *pIcon;
+ if ((pIcon = LockResource(hResData)))
+ {
+ iconDirEntries[validEntries].bWidth = grpIconDir->idEntries[i].bWidth;
+ iconDirEntries[validEntries].bHeight = grpIconDir->idEntries[i].bHeight;
+ iconDirEntries[validEntries].bColorCount = grpIconDir->idEntries[i].bColorCount;
+ iconDirEntries[validEntries].bReserved = grpIconDir->idEntries[i].bReserved;
+ iconDirEntries[validEntries].wPlanes = grpIconDir->idEntries[i].wPlanes;
+ iconDirEntries[validEntries].wBitCount = grpIconDir->idEntries[i].wBitCount;
+ iconDirEntries[validEntries].dwBytesInRes = grpIconDir->idEntries[i].dwBytesInRes;
+ iconDirEntries[validEntries].dwImageOffset = iconOffset;
+ validEntries++;
+ memcpy(&icons[iconOffset], pIcon, grpIconDir->idEntries[i].dwBytesInRes);
+ iconOffset += grpIconDir->idEntries[i].dwBytesInRes;
+ }
+ FreeResource(hResData);
+ }
+ }
+ }
+
+ if (validEntries == 0)
+ {
+ WINE_ERR("no valid icon entries\n");
goto end;
}
- hr = S_OK;
+
+ iconDir.idReserved = 0;
+ iconDir.idType = 1;
+ iconDir.idCount = validEntries;
+ hr = IStream_Write(stream, &iconDir, sizeof(iconDir), &bytesWritten);
+ if (FAILED(hr) || bytesWritten != sizeof(iconDir))
+ {
+ WINE_ERR("error 0x%08X writing icon stream\n", hr);
+ goto end;
+ }
+ for (i = 0; i < validEntries; i++)
+ iconDirEntries[i].dwImageOffset += sizeof(ICONDIR) + validEntries*sizeof(ICONDIRENTRY);
+ hr = IStream_Write(stream, iconDirEntries, validEntries*sizeof(ICONDIRENTRY), &bytesWritten);
+ if (FAILED(hr) || bytesWritten != validEntries*sizeof(ICONDIRENTRY))
+ {
+ WINE_ERR("error 0x%08X writing icon dir entries to stream\n", hr);
+ goto end;
+ }
+ hr = IStream_Write(stream, icons, iconOffset, &bytesWritten);
+ if (FAILED(hr) || bytesWritten != iconOffset)
+ {
+ WINE_ERR("error 0x%08X writing icon images to stream\n", hr);
+ goto end;
+ }
+ zero.QuadPart = 0;
+ hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
end:
- if (hGlobal && stream == NULL)
- GlobalFree(hGlobal);
+ HeapFree(GetProcessHeap(), 0, icons);
+ HeapFree(GetProcessHeap(), 0, iconDirEntries);
if (FAILED(hr) && stream != NULL)
{
IStream_Release(stream);
@@ -374,15 +428,9 @@ static HRESULT open_module_icon(LPCWSTR szFileName, int nIndex, IStream **ppStre
{
HMODULE hModule;
HRSRC hResInfo;
- LPCWSTR lpName = NULL;
HGLOBAL hResData;
GRPICONDIR *pIconDir;
- BITMAPINFO *pIcon;
ENUMRESSTRUCT sEnumRes;
- int nMax = 0;
- int nMaxBits = 0;
- GRPICONDIRENTRY iconDirEntry = {0};
- int i;
HRESULT hr = E_FAIL;
hModule = LoadLibraryExW(szFileName, 0, LOAD_LIBRARY_AS_DATAFILE);
@@ -418,20 +466,9 @@ static HRESULT open_module_icon(LPCWSTR szFileName, int nIndex, IStream **ppStre
{
if ((pIconDir = LockResource(hResData)))
{
- lpName = MAKEINTRESOURCEW(pIconDir->idEntries[0].nID); /* default to first entry */
- for (i = 0; i < pIconDir->idCount; i++)
- {
- if (pIconDir->idEntries[i].wBitCount >= nMaxBits)
- {
- if ((pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth) >= nMax)
- {
- lpName = MAKEINTRESOURCEW(pIconDir->idEntries[i].nID);
- nMax = pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth;
- nMaxBits = pIconDir->idEntries[i].wBitCount;
- iconDirEntry = pIconDir->idEntries[i];
- }
- }
- }
+ *ppStream = add_module_icons_to_stream(hModule, pIconDir);
+ if (*ppStream)
+ hr = S_OK;
}
FreeResource(hResData);
@@ -443,23 +480,6 @@ static HRESULT open_module_icon(LPCWSTR szFileName, int nIndex, IStream **ppStre
FreeLibrary(hModule);
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
-
- if ((hResInfo = FindResourceW(hModule, lpName, (LPCWSTR)RT_ICON)))
- {
- if ((hResData = LoadResource(hModule, hResInfo)))
- {
- if ((pIcon = LockResource(hResData)))
- {
- *ppStream = module_icon_to_stream(&iconDirEntry, pIcon);
- if (*ppStream)
- hr = S_OK;
- else
- hr = E_FAIL;
- }
-
- FreeResource(hResData);
- }
- }
FreeLibrary(hModule);
return hr;
More information about the wine-cvs
mailing list