aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/PaletteManager.cpp
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/PaletteManager.cpp
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/Winamp/PaletteManager.cpp')
-rw-r--r--Src/Winamp/PaletteManager.cpp458
1 files changed, 458 insertions, 0 deletions
diff --git a/Src/Winamp/PaletteManager.cpp b/Src/Winamp/PaletteManager.cpp
new file mode 100644
index 00000000..451c14c0
--- /dev/null
+++ b/Src/Winamp/PaletteManager.cpp
@@ -0,0 +1,458 @@
+#include "api.h"
+#include "PaletteManager.h"
+#include <api/skin/skinparse.h>
+
+#define COLOR_WHITE (0xffffff)
+#define COLOR_BLACK (0x000000)
+#define COLOR_ERROR (0xff00ff)
+
+
+static ARGB32 parseColor(const wchar_t *color, int *error)
+{
+ if (color == NULL || *color == '\0') { if (error) *error = 1; return COLOR_ERROR; }
+ if (!WCSICMP(color, L"white")) return COLOR_WHITE;
+ if (!WCSICMP(color, L"black")) return COLOR_BLACK;
+ if (wcschr(color, ','))
+ {
+ int r = 0, g = 0, b = 0;
+ if (swscanf(color, L"%d,%d,%d", &r, &g, &b) != 3) return COLOR_ERROR;
+ return RGB(r, g, b); // our colors are reversed internally
+ }
+ if (*color == '#')
+ {
+ int r = 0, g = 0, b = 0;
+ if (swscanf(color, L"#%02x%02x%02x", &r, &g, &b) != 3) return COLOR_ERROR;
+ return RGB(r, g, b);
+ }
+ if (error) *error = 1;
+ return COLOR_ERROR;
+}
+#pragma warning(push)
+#pragma warning(disable : 4355)
+PaletteManager::PaletteManager() : paletteGC(this)
+{
+ skinpart_iterator = 1;
+ genericcounter = 0;
+ WASABI_API_SYSCB->syscb_registerCallback(&paletteGC);
+ WASABI_API_SVC->service_register(&gammaFilterFactory);
+}
+#pragma warning(pop)
+
+PaletteManager::~PaletteManager()
+{
+ WASABI_API_SVC->service_deregister(&gammaFilterFactory);
+ WASABI_API_SYSCB->syscb_deregisterCallback(&paletteGC);
+}
+
+void PaletteManager::StartTransaction()
+{
+ skinColorList.setAutoSort(FALSE);
+ skinAliasList.setAutoSort(FALSE);
+ skinCursorList.setAutoSort(FALSE);
+ skinBitmapList.setAutoSort(FALSE);
+}
+
+void PaletteManager::EndTransaction()
+{
+ skinAliasList.sort();
+ skinColorList.sort();
+ skinCursorList.sort();
+ skinBitmapList.sort();
+}
+
+const int *PaletteManager::getSkinPartIteratorPtr()
+{
+ return &skinpart_iterator;
+}
+
+int PaletteManager::newSkinPart()
+{
+ return ++skinpart_iterator;
+}
+
+int PaletteManager::getSkinPartIterator()
+{
+ return skinpart_iterator;
+}
+
+void PaletteManager::AddAlias(const wchar_t *id, const wchar_t *target)
+{
+ // TODO: benski, in transaction, set some transaction_iterator = skinpart_iterator?
+ skinAliasList.addItem(new SkinElementAlias(id, target, skinpart_iterator, genericcounter++));
+}
+
+void PaletteManager::Reset()
+{
+ skinAliasList.deleteAll();
+ skinColorList.deleteAll();
+ skinCursorList.deleteAll();
+ skinBitmapList.deleteAll();
+ skinAliasList.setAutoSort(FALSE);
+ skinColorList.setAutoSort(FALSE);
+ skinCursorList.setAutoSort(FALSE);
+ skinBitmapList.setAutoSort(FALSE);
+}
+
+const wchar_t *PaletteManager::getElementAlias(const wchar_t *alias)
+{
+ if (alias == NULL) return NULL;
+ int pos;
+ SkinElementAlias *sea = skinAliasList.findLastItem(alias, &pos);
+ if (sea == NULL) return NULL;
+ return skinAliasList.enumItem(pos)->getTargetId();
+}
+
+void PaletteManager::UnloadElements(int skinpart)
+{
+ for (int i = 0;i < skinAliasList.getNumItems();i++)
+ {
+ if (skinAliasList.enumItem(i)->getSkinPartId() == skinpart)
+ {
+ delete skinAliasList.enumItem(i);
+ skinAliasList.removeByPos(i);
+ i--;
+ }
+ }
+ for (int i = 0;i < skinColorList.getNumItems();i++)
+ {
+ if (skinColorList.enumItem(i)->getSkinPartId() == skinpart)
+ {
+ delete skinColorList.enumItem(i);
+ skinColorList.removeByPos(i);
+ i--;
+ }
+ }
+ for (int i = 0;i < skinCursorList.getNumItems();i++)
+ {
+ if (skinCursorList.enumItem(i)->getScriptId() == skinpart)
+ {
+ delete skinCursorList.enumItem(i);
+ skinCursorList.removeByPos(i);
+ i--;
+ }
+ }
+ for (int i = 0;i < skinBitmapList.getNumItems();i++)
+ {
+ if (skinBitmapList.enumItem(i)->getSkinPartId() == skinpart)
+ {
+ delete skinBitmapList.enumItem(i);
+ skinBitmapList.removeByPos(i);
+ i--;
+ }
+ }
+
+}
+
+SkinItem *PaletteManager::getAliasAncestor(SkinItem *item)
+{
+ SkinElementAlias *elem = static_cast<SkinElementAlias *>(item);
+ int pos = skinAliasList.searchItem(elem);
+ if (pos <= 0) return NULL;
+ const wchar_t *it = elem->getAliasName();
+ pos--;
+ SkinElementAlias *aelem = skinAliasList.enumItem(pos);
+ if (aelem == NULL) return NULL;
+ const wchar_t *ait = aelem->getAliasName();
+ if (!WCSICMP(it, ait)) return aelem;
+ return NULL;
+}
+
+void PaletteManager::AddColor(const wchar_t *id, ARGB32 value, const wchar_t *colorgroup, const wchar_t *path, ifc_xmlreaderparams *params)
+{
+ skinColorList.addItem(new SkinColorElement(id, value, skinpart_iterator, genericcounter++, colorgroup, path, params));
+}
+
+int PaletteManager::getNumColorElements()
+{
+ return skinColorList.getNumItems();
+}
+
+const wchar_t *PaletteManager::enumColorElement(int n)
+{
+ return skinColorList.enumItem(n)->getId();
+}
+
+ARGB32 *PaletteManager::getColorElementRef(const wchar_t *type, const wchar_t **grp)
+{
+ const wchar_t *alias = getElementAlias(type);
+ if (alias != NULL)
+ type = alias;
+
+ if (grp != NULL) *grp = NULL;
+ SkinColorElement *sce = skinColorList.findLastItem(type);
+ if (sce == NULL) return NULL;
+ if (grp != NULL) *grp = sce->getColorGroup();
+ return (unsigned long *)(sce->getColorRef());
+}
+
+SkinItem *PaletteManager::getColorAncestor(SkinItem *item)
+{
+ SkinColorElement *elem = static_cast<SkinColorElement *>(item);
+ int pos = skinColorList.searchItem(elem);
+ if (pos <= 0) return NULL;
+ const wchar_t *it = elem->getId();
+ pos--;
+ SkinColorElement *aelem = skinColorList.enumItem(pos);
+ if (aelem == NULL) return NULL;
+ const wchar_t *ait = aelem->getId();
+ if (!WCSICMP(it, ait)) return aelem;
+ return NULL;
+}
+
+ARGB32 PaletteManager::getColorElement(const wchar_t *type, const wchar_t **grp)
+{
+ const wchar_t *alias = getElementAlias(type);
+ if (alias != NULL)
+ type = alias;
+ ARGB32 *v = getColorElementRef(type, grp);
+ if (!v)
+ {
+ int err = 0;
+ ARGB32 r = parseColor(type, &err);
+ if (!err) return r;
+ }
+ return v ? *v : RGB(255, 0, 255);
+}
+
+void PaletteManager::AddCursor(const wchar_t *id, const wchar_t *bitmapid, int x, int y, const wchar_t *path, ifc_xmlreaderparams *params)
+{
+ skinCursorList.addItem(new SkinCursorElement(id, bitmapid, x, y, skinpart_iterator, genericcounter++, path, params));
+}
+
+OSCURSOR PaletteManager::getCursor(const wchar_t *id)
+{
+ int pos = getCursorElement(id);
+ if (pos >= 0)
+ {
+ SkinCursorElement *sce = enumCursorElement(pos);
+ return sce->getCursor();
+ }
+ return INVALIDOSCURSORHANDLE;
+}
+
+int PaletteManager::getCursorElement(const wchar_t *id)
+{
+ const wchar_t *alias = getElementAlias(id);
+ if (alias != NULL)
+ id = alias;
+
+ int pos;
+ SkinCursorElement *sce = skinCursorList.findLastItem(id, &pos);
+ if (sce == NULL) return 0;
+ return pos;
+}
+
+SkinCursorElement *PaletteManager::enumCursorElement(int n)
+{
+ return skinCursorList.enumItem(n);
+}
+
+int PaletteManager::getNumSkinCursorElements()
+{
+ return skinCursorList.getNumItems();
+}
+
+SkinItem *PaletteManager::getCursorAncestor(SkinItem *item)
+{
+ SkinCursorElement *elem = static_cast<SkinCursorElement *>(item);
+ int pos = skinCursorList.searchItem(elem);
+ if (pos <= 0) return NULL;
+ const wchar_t *it = elem->getId();
+ pos--;
+ SkinCursorElement *aelem = skinCursorList.enumItem(pos);
+ if (aelem == NULL) return NULL;
+ const wchar_t *ait = aelem->getId();
+ if (!WCSICMP(it, ait)) return aelem;
+ return NULL;
+}
+
+const wchar_t *PaletteManager::getSkinCursorBitmapId(const wchar_t *cursor)
+{
+ int pos = getCursorElement(cursor);
+ if (pos < 0) return NULL;
+ SkinCursorElement *sce = enumCursorElement(pos);
+ return sce->getBitmapId();
+}
+
+void PaletteManager::AddBitmap(const wchar_t *id, const wchar_t *filename, const wchar_t *path, int x, int y, int w, int h, ifc_xmlreaderparams *params, const wchar_t *colorgroup)
+{
+ skinBitmapList.addItem(new SkinBitmapElement(id, filename, path, x, y, w, h, params, skinpart_iterator, genericcounter++, colorgroup));
+}
+
+
+int PaletteManager::getBitmapElement(const wchar_t *type)
+{
+ if (type == NULL)
+ return -1;
+ const wchar_t *alias = getElementAlias(type);
+ if (alias != NULL)
+ {
+ int pos;
+ SkinBitmapElement *sbe = skinBitmapList.findLastItem(alias, &pos);
+ if (sbe == NULL) return -1;
+ return pos;
+ }
+ else
+ {
+ int pos;
+ SkinBitmapElement *sbe = skinBitmapList.findLastItem(type, &pos);
+ if (sbe == NULL) return -1;
+ return pos;
+ }
+}
+
+RegionServer *PaletteManager::requestSkinRegion(const wchar_t *id)
+{
+ int n = getBitmapElement(id);
+ if (n == -1) return NULL;
+
+ SkinBitmapElement *el = skinBitmapList.enumItem(n);
+ // if (el->region != NULL) el->region->getRegion()->debug();
+ return el->getRegionServer();
+}
+
+void PaletteManager::cacheSkinRegion(const wchar_t *id, api_region *r)
+{
+ int n = getBitmapElement(id);
+ if (n == -1) return ;
+ SkinBitmapElement *el = skinBitmapList.enumItem(n);
+ ASSERT(el != NULL);
+ if (el->getRegionServer() != NULL)
+ {
+ DebugString("Trying to cache a region but cache is already set!\n");
+ return ;
+ }
+ el->setRegionServer(new ElementRegionServer(r));
+ //el->region->getRegion()->debug();
+}
+
+SkinItem *PaletteManager::getBitmapAncestor(SkinItem *item)
+{
+ SkinBitmapElement *elem = static_cast<SkinBitmapElement *>(item);
+ int pos = skinBitmapList.searchItem(elem);
+ if (pos <= 0) return NULL;
+ const wchar_t *it = elem->getId();
+ pos--;
+ SkinBitmapElement *aelem = skinBitmapList.enumItem(pos);
+ if (aelem == NULL) return NULL;
+ const wchar_t *ait = aelem->getId();
+ if (!WCSICMP(it, ait)) return aelem;
+ return NULL;
+}
+
+SkinBitmapElement *PaletteManager::enumBitmapElement(int n)
+{
+ return skinBitmapList.enumItem(n);
+}
+
+int PaletteManager::getNumBitmapElement()
+{
+ return skinBitmapList.getNumItems();
+}
+
+const wchar_t *PaletteManager::getSkinBitmapFilename(const wchar_t *id, int *x, int *y, int *w, int *h, const wchar_t **root_path, ifc_xmlreaderparams **params)
+{
+ int i = getBitmapElement(id); // can return skinBitmapList.getNumItems(), check for that.
+ if (i < 0) return id;
+
+ SkinBitmapElement *sbe = skinBitmapList.enumItem(i);
+
+ if (i < skinBitmapList.getNumItems() && !WCSICMP(id, sbe->getId()))
+ {
+ if (x) *x = sbe->getX();
+ if (y) *y = sbe->getY();
+ if (w) *w = sbe->getW();
+ if (h) *h = sbe->getH();
+ if (params) *params = sbe->getParams();
+ if (root_path) *root_path = sbe->getXmlRootPath();
+ return sbe->getFilename();
+ }
+ return id; //FUCKO: const
+}
+
+
+
+
+
+const wchar_t *PaletteManager::getGammaGroupFromId(const wchar_t *id)
+{
+ int i = getBitmapElement(id);
+ if (i < 0)
+ return NULL;
+ return skinBitmapList[i]->getParams()->getItemValue(L"gammagroup");
+}
+
+int PaletteManager::getLayerFromId(const wchar_t *id)
+{
+ int i = getBitmapElement(id);
+ if (i < 0) return 0;
+ const wchar_t *a = skinBitmapList[i]->getParams()->getItemValue(L"layer");
+ if (a == NULL) return 0;
+ return WTOI(a);
+}
+
+void PaletteManager::onGarbageCollect()
+{
+ for (int i = 0;i < regsrvGC.getNumItems();i++)
+ {
+ ElementRegionServer *srv = regsrvGC.enumItem(i);
+ if (srv->getNumRefs() == 0)
+ {
+ delete srv;
+ regsrvGC.removeByPos(i);
+ i--;
+ }
+ }
+}
+
+void PaletteManager::garbageCollectRegionServer(ElementRegionServer *rs)
+{
+ if (rs->getNumRefs() == 0)
+ {
+ delete rs;
+ return ;
+ }
+ regsrvGC.addItem(rs);
+}
+
+
+int PaletteGC::gccb_onGarbageCollect()
+{
+ parent->onGarbageCollect();
+ return 1;
+}
+
+#define CBCLASS PaletteManager
+START_DISPATCH;
+VCB(API_PALETTE_STARTTRANSACTION, StartTransaction)
+VCB(API_PALETTE_ENDTRANSACTION, EndTransaction)
+VCB(API_PALETTE_RESET, Reset)
+CB(API_PALETTE_GETSKINPARTITERATORPTR,getSkinPartIteratorPtr)
+CB(API_PALETTE_NEWSKINPART,newSkinPart)
+CB(API_PALETTE_GETSKINPARTITERATOR,getSkinPartIterator)
+VCB(API_PALETTE_UNLOADELEMENTS,UnloadElements)
+VCB(API_PALETTE_ADDALIAS,AddAlias)
+CB(API_PALETTE_GETELEMENTALIAS,getElementAlias)
+CB(API_PALETTE_GETALIASANCESTOR,getAliasAncestor)
+VCB(API_PALETTE_ADDCOLOR,AddColor)
+CB(API_PALETTE_GETNUMCOLORELEMENTS,getNumColorElements)
+CB(API_PALETTE_ENUMCOLORELEMENT,enumColorElement)
+CB(API_PALETTE_GETCOLORELEMENTREF,getColorElementRef)
+CB(API_PALETTE_GETCOLORANCESTOR,getColorAncestor)
+CB(API_PALETTE_GETCOLORELEMENT,getColorElement)
+VCB(API_PALETTE_ADDCURSOR,AddCursor)
+CB(API_PALETTE_GETCURSORELEMENT,getCursorElement)
+CB(API_PALETTE_GETCURSOR,getCursor)
+CB(API_PALETTE_GETCURSORANCESTOR,getCursorAncestor)
+CB(API_PALETTE_GETSKINCURSORBITMAPID,getSkinCursorBitmapId)
+VCB(API_PALETTE_ADDBITMAP,AddBitmap)
+CB(API_PALETTE_GETBITMAPELEMENT,getBitmapElement)
+CB(API_PALETTE_GETBITMAPANCESTOR,getBitmapAncestor)
+CB(API_PALETTE_GETNUMBITMAPELEMENT,getNumBitmapElement)
+CB(API_PALETTE_GETSKINBITMAPFILENAME,getSkinBitmapFilename)
+CB(API_PALETTE_GETGAMMAGROUPFROMID,getGammaGroupFromId)
+CB(API_PALETTE_GETLAYERFROMID,getLayerFromId)
+CB(API_PALETTE_REQUESTSKINREGION,requestSkinRegion)
+VCB(API_PALETTE_CACHESKINREGION,cacheSkinRegion)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file