1
0

PaletteManager.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. #include "api.h"
  2. #include "PaletteManager.h"
  3. #include <api/skin/skinparse.h>
  4. #define COLOR_WHITE (0xffffff)
  5. #define COLOR_BLACK (0x000000)
  6. #define COLOR_ERROR (0xff00ff)
  7. static ARGB32 parseColor(const wchar_t *color, int *error)
  8. {
  9. if (color == NULL || *color == '\0') { if (error) *error = 1; return COLOR_ERROR; }
  10. if (!WCSICMP(color, L"white")) return COLOR_WHITE;
  11. if (!WCSICMP(color, L"black")) return COLOR_BLACK;
  12. if (wcschr(color, ','))
  13. {
  14. int r = 0, g = 0, b = 0;
  15. if (swscanf(color, L"%d,%d,%d", &r, &g, &b) != 3) return COLOR_ERROR;
  16. return RGB(r, g, b); // our colors are reversed internally
  17. }
  18. if (*color == '#')
  19. {
  20. int r = 0, g = 0, b = 0;
  21. if (swscanf(color, L"#%02x%02x%02x", &r, &g, &b) != 3) return COLOR_ERROR;
  22. return RGB(r, g, b);
  23. }
  24. if (error) *error = 1;
  25. return COLOR_ERROR;
  26. }
  27. #pragma warning(push)
  28. #pragma warning(disable : 4355)
  29. PaletteManager::PaletteManager() : paletteGC(this)
  30. {
  31. skinpart_iterator = 1;
  32. genericcounter = 0;
  33. WASABI_API_SYSCB->syscb_registerCallback(&paletteGC);
  34. WASABI_API_SVC->service_register(&gammaFilterFactory);
  35. }
  36. #pragma warning(pop)
  37. PaletteManager::~PaletteManager()
  38. {
  39. WASABI_API_SVC->service_deregister(&gammaFilterFactory);
  40. WASABI_API_SYSCB->syscb_deregisterCallback(&paletteGC);
  41. }
  42. void PaletteManager::StartTransaction()
  43. {
  44. skinColorList.setAutoSort(FALSE);
  45. skinAliasList.setAutoSort(FALSE);
  46. skinCursorList.setAutoSort(FALSE);
  47. skinBitmapList.setAutoSort(FALSE);
  48. }
  49. void PaletteManager::EndTransaction()
  50. {
  51. skinAliasList.sort();
  52. skinColorList.sort();
  53. skinCursorList.sort();
  54. skinBitmapList.sort();
  55. }
  56. const int *PaletteManager::getSkinPartIteratorPtr()
  57. {
  58. return &skinpart_iterator;
  59. }
  60. int PaletteManager::newSkinPart()
  61. {
  62. return ++skinpart_iterator;
  63. }
  64. int PaletteManager::getSkinPartIterator()
  65. {
  66. return skinpart_iterator;
  67. }
  68. void PaletteManager::AddAlias(const wchar_t *id, const wchar_t *target)
  69. {
  70. // TODO: benski, in transaction, set some transaction_iterator = skinpart_iterator?
  71. skinAliasList.addItem(new SkinElementAlias(id, target, skinpart_iterator, genericcounter++));
  72. }
  73. void PaletteManager::Reset()
  74. {
  75. skinAliasList.deleteAll();
  76. skinColorList.deleteAll();
  77. skinCursorList.deleteAll();
  78. skinBitmapList.deleteAll();
  79. skinAliasList.setAutoSort(FALSE);
  80. skinColorList.setAutoSort(FALSE);
  81. skinCursorList.setAutoSort(FALSE);
  82. skinBitmapList.setAutoSort(FALSE);
  83. }
  84. const wchar_t *PaletteManager::getElementAlias(const wchar_t *alias)
  85. {
  86. if (alias == NULL) return NULL;
  87. int pos;
  88. SkinElementAlias *sea = skinAliasList.findLastItem(alias, &pos);
  89. if (sea == NULL) return NULL;
  90. return skinAliasList.enumItem(pos)->getTargetId();
  91. }
  92. void PaletteManager::UnloadElements(int skinpart)
  93. {
  94. for (int i = 0;i < skinAliasList.getNumItems();i++)
  95. {
  96. if (skinAliasList.enumItem(i)->getSkinPartId() == skinpart)
  97. {
  98. delete skinAliasList.enumItem(i);
  99. skinAliasList.removeByPos(i);
  100. i--;
  101. }
  102. }
  103. for (int i = 0;i < skinColorList.getNumItems();i++)
  104. {
  105. if (skinColorList.enumItem(i)->getSkinPartId() == skinpart)
  106. {
  107. delete skinColorList.enumItem(i);
  108. skinColorList.removeByPos(i);
  109. i--;
  110. }
  111. }
  112. for (int i = 0;i < skinCursorList.getNumItems();i++)
  113. {
  114. if (skinCursorList.enumItem(i)->getScriptId() == skinpart)
  115. {
  116. delete skinCursorList.enumItem(i);
  117. skinCursorList.removeByPos(i);
  118. i--;
  119. }
  120. }
  121. for (int i = 0;i < skinBitmapList.getNumItems();i++)
  122. {
  123. if (skinBitmapList.enumItem(i)->getSkinPartId() == skinpart)
  124. {
  125. delete skinBitmapList.enumItem(i);
  126. skinBitmapList.removeByPos(i);
  127. i--;
  128. }
  129. }
  130. }
  131. SkinItem *PaletteManager::getAliasAncestor(SkinItem *item)
  132. {
  133. SkinElementAlias *elem = static_cast<SkinElementAlias *>(item);
  134. int pos = skinAliasList.searchItem(elem);
  135. if (pos <= 0) return NULL;
  136. const wchar_t *it = elem->getAliasName();
  137. pos--;
  138. SkinElementAlias *aelem = skinAliasList.enumItem(pos);
  139. if (aelem == NULL) return NULL;
  140. const wchar_t *ait = aelem->getAliasName();
  141. if (!WCSICMP(it, ait)) return aelem;
  142. return NULL;
  143. }
  144. void PaletteManager::AddColor(const wchar_t *id, ARGB32 value, const wchar_t *colorgroup, const wchar_t *path, ifc_xmlreaderparams *params)
  145. {
  146. skinColorList.addItem(new SkinColorElement(id, value, skinpart_iterator, genericcounter++, colorgroup, path, params));
  147. }
  148. int PaletteManager::getNumColorElements()
  149. {
  150. return skinColorList.getNumItems();
  151. }
  152. const wchar_t *PaletteManager::enumColorElement(int n)
  153. {
  154. return skinColorList.enumItem(n)->getId();
  155. }
  156. ARGB32 *PaletteManager::getColorElementRef(const wchar_t *type, const wchar_t **grp)
  157. {
  158. const wchar_t *alias = getElementAlias(type);
  159. if (alias != NULL)
  160. type = alias;
  161. if (grp != NULL) *grp = NULL;
  162. SkinColorElement *sce = skinColorList.findLastItem(type);
  163. if (sce == NULL) return NULL;
  164. if (grp != NULL) *grp = sce->getColorGroup();
  165. return (unsigned long *)(sce->getColorRef());
  166. }
  167. SkinItem *PaletteManager::getColorAncestor(SkinItem *item)
  168. {
  169. SkinColorElement *elem = static_cast<SkinColorElement *>(item);
  170. int pos = skinColorList.searchItem(elem);
  171. if (pos <= 0) return NULL;
  172. const wchar_t *it = elem->getId();
  173. pos--;
  174. SkinColorElement *aelem = skinColorList.enumItem(pos);
  175. if (aelem == NULL) return NULL;
  176. const wchar_t *ait = aelem->getId();
  177. if (!WCSICMP(it, ait)) return aelem;
  178. return NULL;
  179. }
  180. ARGB32 PaletteManager::getColorElement(const wchar_t *type, const wchar_t **grp)
  181. {
  182. const wchar_t *alias = getElementAlias(type);
  183. if (alias != NULL)
  184. type = alias;
  185. ARGB32 *v = getColorElementRef(type, grp);
  186. if (!v)
  187. {
  188. int err = 0;
  189. ARGB32 r = parseColor(type, &err);
  190. if (!err) return r;
  191. }
  192. return v ? *v : RGB(255, 0, 255);
  193. }
  194. void PaletteManager::AddCursor(const wchar_t *id, const wchar_t *bitmapid, int x, int y, const wchar_t *path, ifc_xmlreaderparams *params)
  195. {
  196. skinCursorList.addItem(new SkinCursorElement(id, bitmapid, x, y, skinpart_iterator, genericcounter++, path, params));
  197. }
  198. OSCURSOR PaletteManager::getCursor(const wchar_t *id)
  199. {
  200. int pos = getCursorElement(id);
  201. if (pos >= 0)
  202. {
  203. SkinCursorElement *sce = enumCursorElement(pos);
  204. return sce->getCursor();
  205. }
  206. return INVALIDOSCURSORHANDLE;
  207. }
  208. int PaletteManager::getCursorElement(const wchar_t *id)
  209. {
  210. const wchar_t *alias = getElementAlias(id);
  211. if (alias != NULL)
  212. id = alias;
  213. int pos;
  214. SkinCursorElement *sce = skinCursorList.findLastItem(id, &pos);
  215. if (sce == NULL) return 0;
  216. return pos;
  217. }
  218. SkinCursorElement *PaletteManager::enumCursorElement(int n)
  219. {
  220. return skinCursorList.enumItem(n);
  221. }
  222. int PaletteManager::getNumSkinCursorElements()
  223. {
  224. return skinCursorList.getNumItems();
  225. }
  226. SkinItem *PaletteManager::getCursorAncestor(SkinItem *item)
  227. {
  228. SkinCursorElement *elem = static_cast<SkinCursorElement *>(item);
  229. int pos = skinCursorList.searchItem(elem);
  230. if (pos <= 0) return NULL;
  231. const wchar_t *it = elem->getId();
  232. pos--;
  233. SkinCursorElement *aelem = skinCursorList.enumItem(pos);
  234. if (aelem == NULL) return NULL;
  235. const wchar_t *ait = aelem->getId();
  236. if (!WCSICMP(it, ait)) return aelem;
  237. return NULL;
  238. }
  239. const wchar_t *PaletteManager::getSkinCursorBitmapId(const wchar_t *cursor)
  240. {
  241. int pos = getCursorElement(cursor);
  242. if (pos < 0) return NULL;
  243. SkinCursorElement *sce = enumCursorElement(pos);
  244. return sce->getBitmapId();
  245. }
  246. 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)
  247. {
  248. skinBitmapList.addItem(new SkinBitmapElement(id, filename, path, x, y, w, h, params, skinpart_iterator, genericcounter++, colorgroup));
  249. }
  250. int PaletteManager::getBitmapElement(const wchar_t *type)
  251. {
  252. if (type == NULL)
  253. return -1;
  254. const wchar_t *alias = getElementAlias(type);
  255. if (alias != NULL)
  256. {
  257. int pos;
  258. SkinBitmapElement *sbe = skinBitmapList.findLastItem(alias, &pos);
  259. if (sbe == NULL) return -1;
  260. return pos;
  261. }
  262. else
  263. {
  264. int pos;
  265. SkinBitmapElement *sbe = skinBitmapList.findLastItem(type, &pos);
  266. if (sbe == NULL) return -1;
  267. return pos;
  268. }
  269. }
  270. RegionServer *PaletteManager::requestSkinRegion(const wchar_t *id)
  271. {
  272. int n = getBitmapElement(id);
  273. if (n == -1) return NULL;
  274. SkinBitmapElement *el = skinBitmapList.enumItem(n);
  275. // if (el->region != NULL) el->region->getRegion()->debug();
  276. return el->getRegionServer();
  277. }
  278. void PaletteManager::cacheSkinRegion(const wchar_t *id, api_region *r)
  279. {
  280. int n = getBitmapElement(id);
  281. if (n == -1) return ;
  282. SkinBitmapElement *el = skinBitmapList.enumItem(n);
  283. ASSERT(el != NULL);
  284. if (el->getRegionServer() != NULL)
  285. {
  286. DebugString("Trying to cache a region but cache is already set!\n");
  287. return ;
  288. }
  289. el->setRegionServer(new ElementRegionServer(r));
  290. //el->region->getRegion()->debug();
  291. }
  292. SkinItem *PaletteManager::getBitmapAncestor(SkinItem *item)
  293. {
  294. SkinBitmapElement *elem = static_cast<SkinBitmapElement *>(item);
  295. int pos = skinBitmapList.searchItem(elem);
  296. if (pos <= 0) return NULL;
  297. const wchar_t *it = elem->getId();
  298. pos--;
  299. SkinBitmapElement *aelem = skinBitmapList.enumItem(pos);
  300. if (aelem == NULL) return NULL;
  301. const wchar_t *ait = aelem->getId();
  302. if (!WCSICMP(it, ait)) return aelem;
  303. return NULL;
  304. }
  305. SkinBitmapElement *PaletteManager::enumBitmapElement(int n)
  306. {
  307. return skinBitmapList.enumItem(n);
  308. }
  309. int PaletteManager::getNumBitmapElement()
  310. {
  311. return skinBitmapList.getNumItems();
  312. }
  313. 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)
  314. {
  315. int i = getBitmapElement(id); // can return skinBitmapList.getNumItems(), check for that.
  316. if (i < 0) return id;
  317. SkinBitmapElement *sbe = skinBitmapList.enumItem(i);
  318. if (i < skinBitmapList.getNumItems() && !WCSICMP(id, sbe->getId()))
  319. {
  320. if (x) *x = sbe->getX();
  321. if (y) *y = sbe->getY();
  322. if (w) *w = sbe->getW();
  323. if (h) *h = sbe->getH();
  324. if (params) *params = sbe->getParams();
  325. if (root_path) *root_path = sbe->getXmlRootPath();
  326. return sbe->getFilename();
  327. }
  328. return id; //FUCKO: const
  329. }
  330. const wchar_t *PaletteManager::getGammaGroupFromId(const wchar_t *id)
  331. {
  332. int i = getBitmapElement(id);
  333. if (i < 0)
  334. return NULL;
  335. return skinBitmapList[i]->getParams()->getItemValue(L"gammagroup");
  336. }
  337. int PaletteManager::getLayerFromId(const wchar_t *id)
  338. {
  339. int i = getBitmapElement(id);
  340. if (i < 0) return 0;
  341. const wchar_t *a = skinBitmapList[i]->getParams()->getItemValue(L"layer");
  342. if (a == NULL) return 0;
  343. return WTOI(a);
  344. }
  345. void PaletteManager::onGarbageCollect()
  346. {
  347. for (int i = 0;i < regsrvGC.getNumItems();i++)
  348. {
  349. ElementRegionServer *srv = regsrvGC.enumItem(i);
  350. if (srv->getNumRefs() == 0)
  351. {
  352. delete srv;
  353. regsrvGC.removeByPos(i);
  354. i--;
  355. }
  356. }
  357. }
  358. void PaletteManager::garbageCollectRegionServer(ElementRegionServer *rs)
  359. {
  360. if (rs->getNumRefs() == 0)
  361. {
  362. delete rs;
  363. return ;
  364. }
  365. regsrvGC.addItem(rs);
  366. }
  367. int PaletteGC::gccb_onGarbageCollect()
  368. {
  369. parent->onGarbageCollect();
  370. return 1;
  371. }
  372. #define CBCLASS PaletteManager
  373. START_DISPATCH;
  374. VCB(API_PALETTE_STARTTRANSACTION, StartTransaction)
  375. VCB(API_PALETTE_ENDTRANSACTION, EndTransaction)
  376. VCB(API_PALETTE_RESET, Reset)
  377. CB(API_PALETTE_GETSKINPARTITERATORPTR,getSkinPartIteratorPtr)
  378. CB(API_PALETTE_NEWSKINPART,newSkinPart)
  379. CB(API_PALETTE_GETSKINPARTITERATOR,getSkinPartIterator)
  380. VCB(API_PALETTE_UNLOADELEMENTS,UnloadElements)
  381. VCB(API_PALETTE_ADDALIAS,AddAlias)
  382. CB(API_PALETTE_GETELEMENTALIAS,getElementAlias)
  383. CB(API_PALETTE_GETALIASANCESTOR,getAliasAncestor)
  384. VCB(API_PALETTE_ADDCOLOR,AddColor)
  385. CB(API_PALETTE_GETNUMCOLORELEMENTS,getNumColorElements)
  386. CB(API_PALETTE_ENUMCOLORELEMENT,enumColorElement)
  387. CB(API_PALETTE_GETCOLORELEMENTREF,getColorElementRef)
  388. CB(API_PALETTE_GETCOLORANCESTOR,getColorAncestor)
  389. CB(API_PALETTE_GETCOLORELEMENT,getColorElement)
  390. VCB(API_PALETTE_ADDCURSOR,AddCursor)
  391. CB(API_PALETTE_GETCURSORELEMENT,getCursorElement)
  392. CB(API_PALETTE_GETCURSOR,getCursor)
  393. CB(API_PALETTE_GETCURSORANCESTOR,getCursorAncestor)
  394. CB(API_PALETTE_GETSKINCURSORBITMAPID,getSkinCursorBitmapId)
  395. VCB(API_PALETTE_ADDBITMAP,AddBitmap)
  396. CB(API_PALETTE_GETBITMAPELEMENT,getBitmapElement)
  397. CB(API_PALETTE_GETBITMAPANCESTOR,getBitmapAncestor)
  398. CB(API_PALETTE_GETNUMBITMAPELEMENT,getNumBitmapElement)
  399. CB(API_PALETTE_GETSKINBITMAPFILENAME,getSkinBitmapFilename)
  400. CB(API_PALETTE_GETGAMMAGROUPFROMID,getGammaGroupFromId)
  401. CB(API_PALETTE_GETLAYERFROMID,getLayerFromId)
  402. CB(API_PALETTE_REQUESTSKINREGION,requestSkinRegion)
  403. VCB(API_PALETTE_CACHESKINREGION,cacheSkinRegion)
  404. END_DISPATCH;
  405. #undef CBCLASS