aboutsummaryrefslogtreecommitdiff
path: root/Src/auth/Loginbox/imageCache.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/auth/Loginbox/imageCache.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/auth/Loginbox/imageCache.cpp')
-rw-r--r--Src/auth/Loginbox/imageCache.cpp357
1 files changed, 357 insertions, 0 deletions
diff --git a/Src/auth/Loginbox/imageCache.cpp b/Src/auth/Loginbox/imageCache.cpp
new file mode 100644
index 00000000..cef2c205
--- /dev/null
+++ b/Src/auth/Loginbox/imageCache.cpp
@@ -0,0 +1,357 @@
+#include "./imageCache.h"
+#include "./imageLoader.h"
+#include "./graphics.h"
+#include "./loginBox.h"
+
+#include <api/service/waservicefactory.h>
+#include "../../ombrowser/ifc_omutility.h"
+#include "../../ombrowser/ifc_omcachemanager.h"
+#include "../../ombrowser/ifc_omcachegroup.h"
+#include "../../ombrowser/ifc_omcacherecord.h"
+
+#include "../api.h"
+
+LoginImageCache::LoginImageCache(HWND hLoginbox)
+ : ref(1), hwnd(hLoginbox), group(NULL)
+{
+ InitializeCriticalSection(&lock);
+}
+
+LoginImageCache::~LoginImageCache()
+{
+ if (NULL != group)
+ {
+ group->Release();
+ }
+
+ DeleteCriticalSection(&lock);
+}
+
+HRESULT LoginImageCache::CreateInstance(HWND hLoginbox, LoginImageCache **instance)
+{
+ if (NULL == instance)
+ return E_POINTER;
+
+ *instance = NULL;
+ if (NULL == hLoginbox) return E_INVALIDARG;
+
+ *instance = new LoginImageCache(hLoginbox);
+ if (NULL == *instance) return E_OUTOFMEMORY;
+
+ return S_OK;
+}
+
+size_t LoginImageCache::AddRef()
+{
+ return InterlockedIncrement((LONG*)&ref);
+}
+
+size_t LoginImageCache::Release()
+{
+ if (0 == ref)
+ return ref;
+
+ LONG r = InterlockedDecrement((LONG*)&ref);
+ if (0 == r)
+ delete(this);
+
+ return r;
+}
+
+int LoginImageCache::QueryInterface(GUID interface_guid, void **object)
+{
+ if (NULL == object) return E_POINTER;
+
+ if (IsEqualIID(interface_guid, IFC_OmCacheCallback))
+ *object = static_cast<ifc_omcachecallback*>(this);
+ else
+ {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
+
+ if (NULL == *object)
+ return E_UNEXPECTED;
+
+ AddRef();
+ return S_OK;
+}
+
+void LoginImageCache::PathChanged(ifc_omcacherecord *record)
+{
+ HWND hLoginbox;
+
+ EnterCriticalSection(&lock);
+
+ hLoginbox = hwnd;
+
+ LeaveCriticalSection(&lock);
+
+ if (NULL != hLoginbox && FALSE != IsWindow(hLoginbox))
+ {
+ IMAGECACHERESULT result;
+ result.imageCache = this;
+ result.cacheRecord = record;
+ SendMessage(hLoginbox, NLBM_IMAGECACHED, 0, (LPARAM)&result);
+ }
+
+}
+
+void LoginImageCache::Finish()
+{
+ EnterCriticalSection(&lock);
+
+ ifc_omcachegroup *groupCopy = group;
+ if (NULL != groupCopy)
+ groupCopy->AddRef();
+
+ LeaveCriticalSection(&lock);
+
+ if (NULL != groupCopy)
+ {
+ groupCopy->Clear();
+
+ WCHAR szGroup[64] = {0};
+ if (SUCCEEDED(groupCopy->GetName(szGroup, ARRAYSIZE(szGroup))))
+ {
+ waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(IFC_OmUtility);
+ if (NULL != serviceFactory)
+ {
+ ifc_omutility *omUtility = (ifc_omutility*)serviceFactory->getInterface();
+ if (NULL != omUtility)
+ {
+ ifc_omcachemanager *cacheManager;
+ if (SUCCEEDED(omUtility->GetCacheManager(&cacheManager)))
+ {
+ cacheManager->Delete(szGroup);
+ cacheManager->Release();
+ }
+ omUtility->Release();
+ }
+ }
+ }
+
+ groupCopy->Release();
+ }
+}
+
+HRESULT LoginImageCache::InitGroup()
+{
+ HRESULT hr;
+ EnterCriticalSection(&lock);
+ if (NULL != group)
+ {
+ hr = S_FALSE;
+ }
+ else
+ {
+ hr = S_OK;
+ waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(IFC_OmUtility);
+ if (NULL != serviceFactory)
+ {
+ ifc_omutility *omUtility = (ifc_omutility*)serviceFactory->getInterface();
+ if (NULL != omUtility)
+ {
+ ifc_omcachemanager *cacheManager;
+ if (SUCCEEDED(omUtility->GetCacheManager(&cacheManager)))
+ {
+ if (FAILED(cacheManager->Find(L"loginBox", TRUE, &group, NULL)))
+ group = NULL;
+ cacheManager->Release();
+ }
+ omUtility->Release();
+ }
+ }
+
+ if (NULL == group)
+ hr = E_NOINTERFACE;
+ }
+
+ LeaveCriticalSection(&lock);
+ return hr;
+}
+
+HRESULT LoginImageCache::GetImageListIndex(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled)
+{
+ if (NULL == pszPath || L'\0' == *pszPath)
+ return E_INVALIDARG;
+
+ HRESULT hr;
+ WCHAR szBuffer[2048] = {0};
+
+ EnterCriticalSection(&lock);
+
+ BOOL fCreated = FALSE;
+
+ hr = InitGroup();
+ if (SUCCEEDED(hr))
+ {
+
+ ifc_omcacherecord *record;
+ hr = group->Find(pszPath, TRUE, &record, &fCreated);
+ if (S_OK != hr)
+ {
+ if (S_FALSE == hr)
+ hr = E_PENDING;
+ }
+ else
+ {
+ record->RegisterCallback(this);
+
+ hr = record->GetPath(szBuffer, ARRAYSIZE(szBuffer));
+ record->Release();
+ }
+ }
+
+ LeaveCriticalSection(&lock);
+
+ if (FAILED(hr))
+ return hr;
+
+ return GetImageListIndexLocal(szBuffer, himl, index, indexActive, indexDisabled);
+}
+
+HRESULT LoginImageCache::GetImageListIndexLocal(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled)
+{
+ if (NULL == himl || NULL == pszPath || L'\0' == *pszPath)
+ return E_INVALIDARG;
+
+ if (NULL == index && NULL == indexActive && NULL == indexDisabled)
+ return E_INVALIDARG;
+
+ INT destWidth, destHeight;
+ if (0 == ImageList_GetIconSize(himl, &destWidth, &destHeight))
+ return E_FAIL;
+
+ INT imageWidth, imageHeight;
+ HBITMAP hbmp = ImageLoader_LoadBitmap(NULL, pszPath, FALSE, &imageWidth, &imageHeight);
+ if (NULL == hbmp)
+ return E_FAIL;
+
+
+ HRESULT hr = S_OK;
+
+ RECT imageRect;
+ SetRect(&imageRect, 0, 0, imageWidth, imageHeight);
+
+ if (NULL != indexActive)
+ {
+ *indexActive = ImageList_Add(himl, hbmp, NULL);
+ if (((UINT)-1) == *indexActive) hr = E_FAIL;
+ }
+
+ if (NULL != index)
+ {
+ Image_AdjustSaturationAlpha(hbmp, &imageRect, -150, -100);
+
+ *index = ImageList_Add(himl, hbmp, NULL);
+ if (((UINT)-1) == *index) hr = E_FAIL;
+ }
+
+ if (NULL != indexDisabled)
+ {
+ Image_AdjustSaturationAlpha(hbmp, &imageRect, -600, -600);
+
+ *indexDisabled = ImageList_Add(himl, hbmp, NULL);
+ if (((UINT)-1) == *indexDisabled) hr = E_FAIL;
+ }
+
+ if (NULL != hbmp)
+ DeleteObject(hbmp);
+
+ return hr;
+
+}
+
+HBITMAP LoginImageCache::AdjustBitmapSize(HBITMAP hBitmap, INT forceWidth, INT forceHeight)
+{
+ BITMAP bm;
+ if (sizeof(BITMAP) != GetObject(hBitmap, sizeof(bm), &bm))
+ return NULL;
+ if (bm.bmHeight < 0) bm.bmHeight = -bm.bmHeight;
+
+ if (bm.bmWidth == forceWidth && bm.bmHeight == forceHeight)
+ return hBitmap;
+
+ HDC hdc, hdcSrc, hdcDst;
+ hdc = GetDCEx(NULL, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
+ if (NULL == hdc) return NULL;
+
+ hdcSrc = CreateCompatibleDC(hdc);
+ hdcDst = CreateCompatibleDC(hdc);
+
+ BITMAPINFOHEADER bhi;
+ ZeroMemory(&bhi, sizeof(bhi));
+ bhi.biSize = sizeof(bhi);
+ bhi.biCompression = BI_RGB;
+ bhi.biBitCount = 32;
+ bhi.biPlanes = 1;
+ bhi.biWidth = forceWidth;
+ bhi.biHeight = -forceHeight;
+
+ UINT *pixelData;
+ HBITMAP hbmpDst = CreateDIBSection(NULL, (LPBITMAPINFO)&bhi, DIB_RGB_COLORS, (void**)&pixelData, NULL, 0);
+ if (NULL != hbmpDst)
+ {
+ for (INT i = 0; i < forceWidth * forceHeight; i++)
+ pixelData[i] = 0x00FFFFFF;
+ }
+
+ ReleaseDC(NULL, hdc);
+
+ if (NULL != hdcSrc && NULL != hdcDst && NULL != hbmpDst)
+ {
+ HBITMAP hbmpSrcOrig = (HBITMAP)SelectObject(hdcSrc, hBitmap);
+ HBITMAP hbmpDstOrig = (HBITMAP)SelectObject(hdcDst, hbmpDst);
+
+ BOOL result;
+ if (bm.bmWidth <= forceWidth && bm.bmHeight <= forceHeight)
+ {
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+
+ result = GdiAlphaBlend(hdcDst, (forceWidth - bm.bmWidth)/2, (forceHeight - bm.bmHeight)/2,
+ bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, bf);
+ }
+ else
+ {
+ SetStretchBltMode(hdcDst, HALFTONE);
+ result = StretchBlt(hdcDst, 0, 0, forceWidth, forceHeight,
+ hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
+ }
+
+
+ if(FALSE != result)
+ {
+ hBitmap = hbmpDst;
+ hbmpDst = NULL;
+ }
+ else
+ hBitmap = NULL;
+
+ SelectObject(hdcSrc, hbmpSrcOrig);
+ SelectObject(hdcDst, hbmpDstOrig);
+ }
+ else
+ {
+ hBitmap = NULL;
+ }
+
+ if (NULL != hdcDst) DeleteDC(hdcDst);
+ if (NULL != hdcSrc) DeleteDC(hdcSrc);
+ if (NULL != hbmpDst) DeleteObject(hbmpDst);
+
+ return hBitmap;
+}
+
+#define CBCLASS LoginImageCache
+START_DISPATCH;
+CB(ADDREF, AddRef)
+CB(RELEASE, Release)
+CB(QUERYINTERFACE, QueryInterface)
+VCB(API_PATHCHANGED, PathChanged)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file