diff options
Diffstat (limited to 'fingerprint_mod/fingerprint.c')
-rw-r--r-- | fingerprint_mod/fingerprint.c | 1288 |
1 files changed, 1288 insertions, 0 deletions
diff --git a/fingerprint_mod/fingerprint.c b/fingerprint_mod/fingerprint.c new file mode 100644 index 0000000..400a37f --- /dev/null +++ b/fingerprint_mod/fingerprint.c @@ -0,0 +1,1288 @@ +//Start of header
+// Native include
+#include <windows.h>
+#include <stdio.h>
+
+//required Miranda SDK (files are in include subfolder)
+#include "newpluginapi.h"
+#include "m_system.h"
+#include "m_cluiframes.h"
+#include "m_database.h"
+
+#include "m_utils.h"
+
+//required updater header (not in Miranda SDK)
+#include "m_updater.h"
+
+//required iconlib header (not in Miranda SDK)
+#include "m_icolib.h"
+
+//resource definition header
+#include "resource.h"
+
+//Fingerprint services definition header
+#include "m_fingerprint.h"
+
+
+//Definition from other Miranda IM SDK
+#define MS_CLUI_LISTBEGINREBUILD "CLUI/ListBeginRebuild"
+#define ME_OPT_INITIALISE "Opt/Initialise"
+#define MS_UTILS_PATHTORELATIVE "Utils/PathToRelative"
+#define MS_PROTO_GETCONTACTBASEPROTO "Proto/GetContactBaseProto"
+#define MS_LANGPACK_TRANSLATESTRING "LangPack/TranslateString"
+#define Translate(s) ((char*)CallService(MS_LANGPACK_TRANSLATESTRING,0,(LPARAM)(s)))
+#define IsWinVerXPPlus() (LOBYTE(LOWORD(GetVersion()))>=5 && LOWORD(GetVersion())!=5)
+#define _CRT_SECURE_NO_DEPRECATE
+// End of SDK headers include
+
+#if defined(__GNUC__)
+#define _alloca alloca
+//#define FASTCALL
+#else
+#define FASTCALL __fastcall
+#endif
+
+
+#define mir_strncpy(a,b,c) { strncpy(a,b,c)[c-1] = 0; }
+
+#define LIB_NONE 0
+#define LIB_GET 1
+#define LIB_REG 2
+#define LIB_USE 3
+
+HANDLE hExtraImageListRebuild; // hook event handle for ME_CLIST_EXTRA_LIST_REBUILD
+HANDLE hExtraImageApply; // hook event handle for ME_CLIST_EXTRA_IMAGE_APPLY
+HANDLE hContactSettingChanged; // hook event handle for ME_DB_CONTACT_SETTINGCHANGED
+HANDLE hOptInitialise; // hook event handle for ME_OPT_INITIALISE
+HANDLE hIconsChanged; // hook event handle for ME_SKIN2_ICONSCHANGED
+HANDLE hModulesLoaded;
+HANDLE hPreShutdown; // hook event handle for ME_SYSTEM_PRESHUTDOWN
+HANDLE compClientServ=NULL;
+HANDLE getClientIcon=NULL;
+BYTE bColumn = 0;
+
+int OnIconsChanged(WPARAM wParam, LPARAM lParam);
+int OnExtraIconListRebuild(WPARAM wParam, LPARAM lParam);
+int OnExtraImageApply(WPARAM wParam, LPARAM lParam);
+int OnContactSettingChanged(WPARAM wParam, LPARAM lParam);
+int OnOptInitialise(WPARAM wParam, LPARAM lParam);
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam);
+int OnPreShutdown(WPARAM wParam, LPARAM lParam);
+int ServiceSameClients(WPARAM wParam, LPARAM lParam);
+int ServiceGetClientIcon(WPARAM wParam, LPARAM lParam);
+
+HICON FASTCALL CreateJoinedIcon(HICON hBottom, HICON hTop);
+HBITMAP FASTCALL CreateBitmap32(int cx, int cy);
+HBITMAP FASTCALL CreateBitmap32Point(int cx, int cy, void ** bits);
+BYTE FASTCALL GetIconIndexFromFI(short base, short overlay, short overlay2, short overlay3);
+void FASTCALL ClearFI();
+
+int FASTCALL ApplyFingerprintImage(HANDLE hContact,char *MirVer);
+HICON FASTCALL LoadIconFromExternalFile(char *filename,int nLibrary,char *IconName,int flag,char *Description,int internalidx, BOOL * NeedFree);
+BOOL FASTCALL WildCompare(char * name, char * mask);
+BOOL __inline WildCompareProc(char * name, char * mask);
+
+int FASTCALL DBGetStaticString(HANDLE hContact, const char* moduleName, const char* valueName, char* dest, int dest_len);
+
+typedef struct {
+ BYTE b;
+ BYTE g;
+ BYTE r;
+ BYTE a;
+} RGBA;
+
+typedef struct _knfpMask
+{
+ char *szIconName;
+ char *szMask;
+ char *szClientDescription;
+ char *szIconFileName;
+ int iIconIndex;
+ BYTE registeredIndex;
+ int SectionFlag;
+} KN_FP_MASK;
+
+typedef struct _foundInfo
+{
+ DWORD array;
+ BYTE registeredIndex;
+} FOUNDINFO;
+
+
+FOUNDINFO *fiList=NULL;
+int nFICount=0;
+
+//Including of fingerprint masks
+#include "fingerprints.h"
+//End of header
+
+HANDLE hHeap = NULL;
+
+BOOL SKIN2_RELEASEICON = FALSE;
+BOOL SKIN2_ADDICON = FALSE;
+char szPath[MAX_PATH],szMyPath[MAX_PATH];
+
+HINSTANCE g_hInst;
+PLUGINLINK *pluginLink;
+
+// PluginInfo & PluginInfoEx + UUID
+#include "version.h"
+
+#if defined(FULL) || defined(STANDARD) || defined(LITE)
+ #ifdef FULL
+ #define FP_MODULENAME "Fingerprint Mod (full)"
+ #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_FULL
+ #endif
+ #ifdef STANDARD
+ #define FP_MODULENAME "Fingerprint Mod (standard)"
+ #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_STANDARD
+ #endif
+ #ifdef LITE
+ #define FP_MODULENAME "Fingerprint Mod (lite)"
+ #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_LITE
+ #endif
+ #else
+ #define FP_MODULENAME "Fingerprint Mod (custom build)"
+ #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_CUSTOM
+#endif
+
+static PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ FP_MODULENAME,
+ __VERSION_DWORD,
+ "Fingerprint Mod (client version) icons module set extra icon of your buddies according to their client version",
+ "Artem Shpynov aka FYR, Bio, Faith Healer",
+ "faith@inbox.ru",
+ "© 2006-2007 Artem Shpynov aka FYR, Bio, Faith Healer",
+ "http://Faith.MirandaIM.Ru",
+ UNICODE_AWARE,
+ 0,
+ MIID_FINGERPRINT_MOD
+};
+
+static PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+ FP_MODULENAME,
+ __VERSION_DWORD,
+ "Fingerprint Mod (client version) icons module set extra icon of your buddies according to their client version",
+ "Artem Shpynov aka FYR, Bio, Faith Healer",
+ "faith@inbox.ru",
+ "© 2006-2007 Artem Shpynov aka FYR, Bio, Faith Healer",
+ "http://Faith.MirandaIM.Ru",
+ 0,
+ 0
+};
+
+__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{// Tell Miranda IM about plugin
+ return &pluginInfoEx;
+}
+
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{// Tell Miranda IM about plugin
+ return &pluginInfo;
+}
+
+static const MUUID interfaces[] = {MIID_FINGERPRINT,MIID_FINGERPRINT_MOD,MIID_FINGERPRINT_MOD_TYPE, MIID_LAST};
+__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+//End of PluginInfo & PluginInfoEx+ UUID block
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ g_hInst=hinstDLL;
+ return TRUE;
+}
+
+int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ pluginLink=link;
+ hModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,OnModulesLoaded);
+ hPreShutdown=HookEvent(ME_SYSTEM_PRESHUTDOWN,OnPreShutdown);
+ compClientServ=CreateServiceFunction(MS_FP_SAMECLIENTS,ServiceSameClients);
+ getClientIcon=CreateServiceFunction(MS_FP_GETCLIENTICON,ServiceGetClientIcon);
+ hHeap=HeapCreate(HEAP_NO_SERIALIZE,0,0);
+ return 0;
+}
+
+int __declspec(dllexport) Unload(void)
+{
+ HeapDestroy(hHeap);
+ ClearFI();
+ return 0;
+}
+
+void FASTCALL mir_strupr(char *string)
+{
+ char *cp;
+ for ( cp = string ; *cp ; ++cp )
+ if ( ('a' <= *cp) && (*cp <= 'z') )
+ *cp -= 'a' - 'A';
+}
+
+/*
+* FreeIcon
+* for mode > 0 it releases icon from iconlib
+* for mode < 0 it destroys icon
+*/
+void FASTCALL FreeIcon(HICON hIcon, int mode)
+{
+ if (!mode) return;
+ if (mode > 0 && SKIN2_RELEASEICON)
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, (WPARAM)0);
+ else
+ DestroyIcon(hIcon);
+}
+
+/*
+* Prepare
+* prepares upperstring masks and registers them in IcoLib
+*/
+void FASTCALL Prepare(KN_FP_MASK *mask)
+{
+ char *szNewMask;
+ if (!mask->szMask) return;
+ szNewMask = (char*)HeapAlloc(hHeap,HEAP_NO_SERIALIZE,strlen(mask->szMask)+1);
+ strcpy(szNewMask,mask->szMask);
+ mir_strupr(szNewMask);
+ mask->szMask = szNewMask;
+ if (SKIN2_ADDICON)
+ LoadIconFromExternalFile(mask->szIconFileName,LIB_REG,mask->szIconName,mask->SectionFlag,mask->szClientDescription,mask->iIconIndex,NULL);
+}
+
+/*
+* OnModulesLoaded
+* Hook necessary events here
+*/
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ KN_FP_MASK *mask;
+
+ bColumn = DBGetContactSettingByte(NULL,"Finger","ClientColumn",0);
+ if (!bColumn || bColumn > EXTRA_ICON_COUNT)
+ bColumn = EXTRA_ICON_CLIENT;
+
+#ifdef FULL
+// CallService("Update/RegisterFL", (WPARAM)2594, (LPARAM)&pluginInfo);
+#endif
+
+ //Hook necessary events
+ hIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, OnIconsChanged);
+// hOptInitialise = HookEvent(ME_OPT_INITIALISE, OnOptInitialise);
+ hExtraImageListRebuild = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD,OnExtraIconListRebuild);
+ hExtraImageApply = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, OnExtraImageApply);
+ hContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged);
+
+ SKIN2_ADDICON = ServiceExists(MS_SKIN2_ADDICON);
+ SKIN2_RELEASEICON = ServiceExists(MS_SKIN2_RELEASEICON);
+
+ GetModuleFileNameA(g_hInst, szMyPath, MAX_PATH);
+ CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)szMyPath, (LPARAM)szPath);
+
+ // prepare masks
+ for (i=0;i<DEFAULT_KN_FP_MASK_COUNT; i++)
+ {
+ mask = (KN_FP_MASK*)&def_kn_fp_mask[i];
+ if (mask) Prepare(mask);
+ }
+ for (i=0;i<DEFAULT_KN_FP_OVERLAYS_COUNT; i++)
+ {
+ mask = (KN_FP_MASK*)&def_kn_fp_overlays_mask[i];
+ if (mask) Prepare(mask);
+ }
+ for (i=0;i<DEFAULT_KN_FP_OVERLAYS2_COUNT; i++)
+ {
+ mask = (KN_FP_MASK*)&def_kn_fp_overlays2_mask[i];
+ if (mask) Prepare(mask);
+ }
+ for (i=0;i<DEFAULT_KN_FP_OVERLAYS3_COUNT; i++)
+ {
+ mask = (KN_FP_MASK*)&def_kn_fp_overlays3_mask[i];
+ if (mask) Prepare(mask);
+ }
+
+ // Updater support
+ if (ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update update = {0};
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfoEx.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(pluginInfoEx.version, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+
+#if defined(FULL) || defined(STANDARD) || defined(LITE)
+ #ifdef STANDARD
+ update.szBetaUpdateURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod.zip";
+ update.szBetaVersionURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_version.txt";
+ update.szBetaChangelogURL = "http://faith.mirandaim.ru/post/fingerprint_mod";
+ update.pbBetaVersionPrefix = (BYTE *)"Fingerprint Mod ";
+ #endif
+
+ #ifdef LITE
+ update.szBetaUpdateURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_lite.zip";
+ update.szBetaVersionURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_version.txt";
+ update.szBetaChangelogURL = "http://faith.mirandaim.ru/post/fingerprint_mod";
+ update.pbBetaVersionPrefix = (BYTE *)"Fingerprint Mod ";
+ #endif
+
+ #ifdef FULL
+ update.szUpdateURL = UPDATER_AUTOREGISTER;
+ update.szBetaUpdateURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_full.zip";
+ update.szBetaVersionURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_version.txt";
+ update.szBetaChangelogURL = "http://faith.mirandaim.ru/post/fingerprint_mod";
+ update.pbBetaVersionPrefix = (BYTE *)"Fingerprint Mod ";
+ #endif
+
+#else
+ update.szBetaUpdateURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_full.zip";
+ update.szBetaVersionURL = "http://faith.mirandaim.ru/archive/fingerprint_mod/fingerprint_mod_version.txt";
+ update.szBetaChangelogURL = "http://faith.mirandaim.ru/post/fingerprint_mod";
+ update.pbBetaVersionPrefix = (BYTE *)"Fingerprint Mod ";
+#endif
+
+
+ update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+ }
+
+ return 0;
+}
+
+/*
+* OnPreShutdown
+* Unhook events here (this is valid place to unhook all events to prevent crash on exiting)
+*/
+int OnPreShutdown(WPARAM wParam, LPARAM lParam)
+{
+ //Unhook events
+ UnhookEvent(hExtraImageListRebuild);
+ UnhookEvent(hExtraImageApply);
+ UnhookEvent(hContactSettingChanged);
+ UnhookEvent(hPreShutdown);
+ UnhookEvent(hModulesLoaded);
+ UnhookEvent(hIconsChanged);
+// UnhookEvent(hOptInitialise);
+ DestroyServiceFunction(compClientServ);
+ DestroyServiceFunction(getClientIcon);
+ return 0;
+}
+
+/* ApplyFingerprintImage
+* 1)Try to find appropriate mask
+* 2)Register icon in extraimage list if not yet registered (0xFF)
+* 3)Set ExtraImage for contact
+*/
+int FASTCALL ApplyFingerprintImage(HANDLE hContact,char *szMirVer)
+{
+ BYTE Index=0xFF;
+
+ if (szMirVer)
+ {
+ short i=0, j=-1, k=-1, l=-1;
+ char MirVer[256];
+
+ mir_strncpy(MirVer, szMirVer, sizeof(MirVer));
+ mir_strupr(MirVer);
+
+ while (i<DEFAULT_KN_FP_MASK_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_mask[i].szMask)) break;
+ i++;
+ }
+ if (i<DEFAULT_KN_FP_MASK_COUNT)
+ {
+ j=0;
+ while (j<DEFAULT_KN_FP_OVERLAYS_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_overlays_mask[j].szMask)) break;
+ j++;
+ }
+
+ k=0;
+ while (k<DEFAULT_KN_FP_OVERLAYS2_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_overlays2_mask[k].szMask)) break;
+ k++;
+ }
+
+ l=0;
+ while (l<DEFAULT_KN_FP_OVERLAYS3_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_overlays3_mask[l].szMask)) break;
+ l++;
+ }
+ }
+
+ i=(i<DEFAULT_KN_FP_MASK_COUNT)?i:-1;
+ j=(j<DEFAULT_KN_FP_OVERLAYS_COUNT)?j:-1;
+ k=(k<DEFAULT_KN_FP_OVERLAYS2_COUNT)?k:-1;
+ l=(l<DEFAULT_KN_FP_OVERLAYS3_COUNT)?l:-1;
+
+ Index=GetIconIndexFromFI(i, j, k, l);
+ }
+ if (hContact)
+ {
+ IconExtraColumn iec;
+ iec.cbSize=sizeof(IconExtraColumn);
+ iec.hImage=(HANDLE)(int)Index;
+ iec.ColumnType=bColumn;//EXTRA_ICON_CLIENT;
+ CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)hContact,(LPARAM)&iec);
+ }
+ return 0;
+}
+
+/*
+* OnExtraIconListRebuild
+* Set all registered indexes in array to 0xFF (unregistered icon)
+*/
+int OnExtraIconListRebuild(WPARAM wParam, LPARAM lParam)
+{
+ ClearFI();
+ return 0;
+}
+
+/*
+* OnIconsChanged
+*/
+int OnIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ ClearFI();
+ return 0;
+}
+
+/*
+int OnOptInitialise(WPARAM wParam, LPARAM lParam)
+{
+ return 0;
+}
+*/
+
+/*
+* OnExtraImageApply
+* Try to get MirVer value from db for contact and if success calls ApplyFingerprintImage
+*/
+int OnExtraImageApply(WPARAM wParam, LPARAM lParam)
+{
+ if (!wParam) return 0;
+
+ {
+ HANDLE hContact=(HANDLE)wParam;
+ char szProto[256], szVer[256];
+
+ if (!DBGetStaticString(hContact, "Protocol", "p", szProto, sizeof(szProto)) &&
+ !DBGetStaticString(hContact, szProto, "MirVer", szVer, sizeof(szVer)))
+ {
+ ApplyFingerprintImage(hContact,szVer);
+ }
+ else
+ ApplyFingerprintImage(hContact,NULL);
+ }
+ return 0;
+}
+
+/*
+* OnContactSettingChanged
+* if contact settings changed apply new image or remove it
+*/
+int OnContactSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ if ((HANDLE)wParam == NULL) return 0;
+
+ {
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
+ if (cws && cws->szSetting && !strcmp(cws->szSetting,"MirVer"))
+ {
+
+ if (cws->value.type==DBVT_ASCIIZ)
+ ApplyFingerprintImage((HANDLE)wParam,cws->value.pszVal);
+ else if (cws->value.type==DBVT_UTF8 || cws->value.type==DBVT_WCHAR)
+ ApplyFingerprintImage((HANDLE)wParam,cws->value.ptszVal);
+ else
+ ApplyFingerprintImage((HANDLE)wParam,NULL);
+ }
+ }
+ return 0;
+}
+
+/*
+* LoadIconFromExternalFile
+* If iconlib module presents register icon there
+* Regiister and return icon within iconlib
+* or from resourse
+*/
+// TO DO: Extracting icons from clienticons.dll or other external files require futher
+// destroying of icon... need to add field to list, modify it and remove icon on unload
+// Otherwise it will cause gdi resources leaking.
+// So nowtime it is commented out
+
+HICON FASTCALL LoadIconFromExternalFile(char *filename, int nLibrary, char *IconName, int flag, char *Description, int internalidx, int *NeedFree)
+{
+ HICON hIcon=NULL;
+
+ if (IconName==NULL) return NULL;
+
+ if (SKIN2_ADDICON && nLibrary)
+ {
+ if (nLibrary!=LIB_REG)
+ hIcon=((HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IconName));
+
+ if (hIcon==NULL && (nLibrary&LIB_REG) && IconName!=NULL)
+ {
+ SKINICONDESC sid={0};
+ char *SectName="";
+
+ switch (flag)
+ {
+ #if defined(ICQ) || defined(JABBER) || defined(MSN) || defined(AIM) || defined(YAHOO) || defined(IRC)
+ case 1: SectName="Fingerprint client icons/ MirandaIM clients"; break;
+ case 2: SectName="Fingerprint client icons/ Multi-protocol clients"; break;
+ #endif
+
+ #ifdef ICQ
+ #ifndef LITE
+ case 3: SectName="Fingerprint client icons/ICQ clients/Official clients"; break;
+ #else
+ case 3: SectName="Fingerprint client icons/ICQ clients"; break;
+ #endif
+ case 4: SectName="Fingerprint client icons/ICQ clients"; break;
+ #endif
+
+ #ifdef JABBER
+ case 5: SectName="Fingerprint client icons/Jabber clients"; break;
+ #endif
+
+ #ifdef MSN
+ case 6: SectName="Fingerprint client icons/MSN clients"; break;
+ #endif
+
+ #ifdef AIM
+ case 7: SectName="Fingerprint client icons/AIM clients"; break;
+ #endif
+
+ #ifdef YAHOO
+ case 8: SectName="Fingerprint client icons/Yahoo clients"; break;
+ #endif
+
+ #ifdef IRC
+ case 9: SectName="Fingerprint client icons/IRC clients"; break;
+ #endif
+
+ case 10: SectName="Fingerprint client icons/Jabber clients"; break;
+
+ #ifdef SKYPE
+ case 11: SectName="Fingerprint client icons/Skype clients"; break;
+ #endif
+
+ #ifdef GADU_GADU
+ case 12: SectName="Fingerprint client icons/Gadu-Gadu clients"; break;
+ #endif
+
+ #if defined(MIR_PACKS) && defined(MIR_PACKS_OVERLAYS)
+ case 13: SectName="Fingerprint client icons/ MirandaIM clients/packs overlays"; break;
+ #elif defined(MIR_PACKS) && defined(MIR_PACKS_FULL)
+ case 13: SectName="Fingerprint client icons/ MirandaIM clients/custom packs"; break;
+ #endif
+
+ #ifdef MAIL_RU
+ case 14: SectName="Fingerprint client icons/Mail.Ru clients"; break;
+ #endif
+
+
+ #ifndef LITE
+ case 15: SectName="Fingerprint client icons/ MirandaIM clients/overlays"; break;
+ #else
+ case 15: SectName="Fingerprint client icons/ MirandaIM overlays"; break;
+ #endif
+
+ #if defined(SUB_CLIENTS) || defined(OVERLAY_AS_DOT) || defined(LITE)
+ case 16: SectName="Fingerprint client icons/ MirandaIM clients/sub-clients overlays"; break;
+ #endif
+
+ case 17: SectName="Fingerprint client icons/[ other clients ]"; break;
+
+/* case 18: SectName="Fingerprint client icons/[ other clients ]/overlay icons"; break; */
+
+ case 18: SectName="Fingerprint client icons/[ overlay icons ]"; break;
+
+
+ default: SectName="Fingerprint client icons"; break;
+ }
+
+ sid.cbSize = sizeof(sid);
+ sid.pszSection = Translate(SectName);
+ sid.pszName=IconName;
+ sid.pszDescription=Description;
+ sid.pszDefaultFile=szPath;
+ sid.iDefaultIndex=-internalidx;
+ sid.cx=sid.cy=16;
+
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ if (nLibrary!=LIB_REG)
+ hIcon=((HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IconName));
+ }
+ }
+ if (NeedFree) *NeedFree= (hIcon && SKIN2_RELEASEICON);
+ if (!hIcon && nLibrary!=LIB_REG)
+ {
+ ExtractIconExA(szMyPath, -internalidx, NULL, &hIcon, 1);
+ if (hIcon && NeedFree) *NeedFree=-1;
+ }
+ return hIcon;
+}
+
+/*
+* WildCompare
+* Compare 'name' string with 'mask' strings.
+* Masks can contain '*' or '?' wild symbols
+* Asterics '*' symbol covers 'empty' symbol too e.g WildCompare("Tst","T*st*"), returns TRUE
+* In order to handle situation 'at least one any sybol' use "?*" combination:
+* e.g WildCompare("Tst","T?*st*"), returns FALSE, but both WildCompare("Test","T?*st*") and
+* WildCompare("Teeest","T?*st*") return TRUE.
+*
+* Function is case sensitive! so convert input or modify func to use _qtoupper()
+*
+* Mask can contain several submasks. In this case each submask (including first)
+* should start from '|' e.g: "|first*submask|second*mask".
+*
+* Dec 25, 2006 by FYR:
+* Added Exception to masks: the mask "|^mask3|mask2|mask1" means:
+* if NOT according to mask 3 AND (mask1 OR mask2)
+* EXCEPTION should be BEFORE main mask:
+* IF Exception match - the comparing stops as FALSE
+* IF Exception does not match - comparing continue
+* IF Mask match - comparing stops as TRUE
+* IF Mask does not not match comparing continue
+*/
+BOOL FASTCALL WildCompare(char * name, char * mask)
+{
+
+ if (*mask!='|') return WildCompareProc(name,mask);
+
+ {
+ int s=1,e=1;
+ static char temp[100]; //lets made temp static local var - should be faster than dynamic
+// char * temp = _alloca(strlen(mask));
+ int bExcept;
+
+ while (mask[e]!='\0')
+ {
+ s=e;
+ while(mask[e]!='\0' && mask[e]!='|') e++;
+
+ // exception mask
+ bExcept= (*(mask+s)=='^');
+ if (bExcept) s++;
+
+ memcpy(temp,mask+s,e-s);
+ temp[e-s]='\0';
+
+ if (WildCompareProc(name,temp))
+ return !bExcept;
+
+ if (mask[e]!='\0')
+ e++;
+ else
+ return FALSE;
+ }
+ return FALSE;
+ }
+}
+
+//#define _qtoupper(_c) (((_c)>='a' && (_c)<='z')?((_c)-'a'+'A'):(_c))
+//#define _qtoupper(_c) (((_c)>='a' && (_c)<='z')?((_c)&0x5F):(_c))
+
+BOOL __inline WildCompareProc(char * name, char * mask)
+{
+ char * last='\0';
+ for(;; mask++, name++)
+ {
+ if(*mask != '?' && *mask != *name) break;
+ if(*name == '\0') return ((BOOL)!*mask);
+ }
+ if(*mask != '*') return FALSE;
+ for(;; mask++, name++)
+ {
+ while(*mask == '*')
+ {
+ last = mask++;
+ if(*mask == '\0') return ((BOOL)!*mask); /* true */
+ }
+ if(*name == '\0') return ((BOOL)!*mask); /* *mask == EOS */
+ if(*mask != '?' && *mask != *name) name -= (size_t)(mask - last) - 1, mask = last;
+ }
+}
+
+/*
+* ServiceGetClientIcon
+* MS_FP_GETCLIENTICON service implementation.
+* wParam - char * MirVer value to get client for.
+* lParam - int noCopy - if wParam is equal to "1" will return icon handler without copiing icon.
+*/
+int ServiceGetClientIcon(WPARAM wParam, LPARAM lParam)
+{
+ char *szMirVer=(char*)wParam; // MirVer value to get client for.
+/*
+ static HICON hIcon=NULL; // returned HICON
+ if (hIcon) {
+ DestroyIcon(hIcon);
+ hIcon=NULL;
+ }
+*/
+ if (!szMirVer) return 0;
+
+ {
+ HICON hIcon=NULL; // returned HICON
+ int NoCopy=(int)lParam; // noCopy
+ HICON icMain=NULL;
+ HICON icOverlay=NULL;
+ HICON icOverlay2=NULL;
+ HICON icOverlay3=NULL;
+ BOOL needFreeBase=FALSE;
+ BOOL needFreeOverlay=FALSE;
+ BOOL needFreeOverlay2=FALSE;
+ BOOL needFreeOverlay3=FALSE;
+ short base=-1, overlay=-1, overlay2=-1, overlay3=-1;
+
+ BYTE Index=0xFF;
+ short i=0;
+ short j, k, l;
+ char MirVer[256];
+
+ mir_strncpy(MirVer, szMirVer, sizeof(MirVer));
+ mir_strupr(MirVer);
+
+ while (i<DEFAULT_KN_FP_MASK_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_mask[i].szMask)) break;
+ i++;
+ }
+ if (i<DEFAULT_KN_FP_MASK_COUNT)
+ {
+ j=0;
+ while (j<DEFAULT_KN_FP_OVERLAYS_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_overlays_mask[j].szMask)) break;
+ j++;
+ }
+
+ k=0;
+ while (k<DEFAULT_KN_FP_OVERLAYS2_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_overlays2_mask[k].szMask)) break;
+ k++;
+ }
+
+ l=0;
+ while (l<DEFAULT_KN_FP_OVERLAYS3_COUNT)
+ {
+ if(WildCompare(MirVer,def_kn_fp_overlays3_mask[l].szMask)) break;
+ l++;
+ }
+
+ base = (i<DEFAULT_KN_FP_MASK_COUNT)?i:-1;
+ overlay = (j<DEFAULT_KN_FP_OVERLAYS_COUNT)?j:-1;
+ overlay2 = (k<DEFAULT_KN_FP_OVERLAYS2_COUNT)?k:-1;
+ overlay3 = (l<DEFAULT_KN_FP_OVERLAYS3_COUNT)?l:-1;
+ }
+
+ if (base!=-1)
+ {
+ KN_FP_MASK * mainMask=&(def_kn_fp_mask[base]);
+ icMain=LoadIconFromExternalFile(mainMask->szIconFileName,LIB_USE,mainMask->szIconName,mainMask->SectionFlag,mainMask->szClientDescription,mainMask->iIconIndex,&needFreeBase);
+
+ if (icMain)
+ {
+ KN_FP_MASK * overlayMask=(overlay!=-1)?&(def_kn_fp_overlays_mask[overlay]):NULL;
+ KN_FP_MASK * overlay2Mask=(overlay2!=-1)?&(def_kn_fp_overlays2_mask[overlay2]):NULL;
+ KN_FP_MASK * overlay3Mask=(overlay3!=-1)?&(def_kn_fp_overlays3_mask[overlay3]):NULL;
+ icOverlay=(overlayMask==NULL)?NULL:LoadIconFromExternalFile(overlayMask->szIconFileName,LIB_USE,overlayMask->szIconName,overlayMask->SectionFlag,overlayMask->szClientDescription,overlayMask->iIconIndex,&needFreeOverlay);
+ icOverlay2=(overlay2Mask==NULL)?NULL:LoadIconFromExternalFile(overlay2Mask->szIconFileName,LIB_USE,overlay2Mask->szIconName,overlay2Mask->SectionFlag,overlay2Mask->szClientDescription,overlay2Mask->iIconIndex,&needFreeOverlay2);
+ icOverlay3=(overlay3Mask==NULL)?NULL:LoadIconFromExternalFile(overlay3Mask->szIconFileName,LIB_USE,overlay3Mask->szIconName,overlay3Mask->SectionFlag,overlay3Mask->szClientDescription,overlay3Mask->iIconIndex,&needFreeOverlay3);
+
+ hIcon=icMain;
+
+ if (overlayMask)
+ hIcon=CreateJoinedIcon(hIcon,icOverlay);
+
+ if (overlay2Mask)
+ {
+ HICON hTmp = hIcon;
+ hIcon=CreateJoinedIcon(hIcon,icOverlay2);
+ if (overlayMask && hTmp)
+ DestroyIcon(hTmp);
+ }
+
+ if (overlay3Mask)
+ {
+ HICON hTmp = hIcon;
+ hIcon=CreateJoinedIcon(hIcon,icOverlay3);
+ if (overlayMask && hTmp)
+ DestroyIcon(hTmp);
+ }
+
+ }
+ }
+
+
+ if (hIcon==icMain)
+ hIcon=CopyIcon(icMain);
+
+ FreeIcon(icMain,needFreeBase);
+ FreeIcon(icOverlay,needFreeOverlay);
+ FreeIcon(icOverlay2,needFreeOverlay2);
+ FreeIcon(icOverlay3,needFreeOverlay3);
+/*
+ if (hIcon && !NoCopy)
+ return (int)CopyIcon(hIcon);
+*/
+ return (int)hIcon;
+ }
+}
+
+/*
+ * ServiceSameClient
+ * MS_FP_SAMECLIENTS service implementation.
+ * wParam - char * first MirVer value
+ * lParam - char * second MirVer value
+ * return pointer to char string - client desription (do not destroy) if clients are same
+ */
+int ServiceSameClients(WPARAM wParam, LPARAM lParam)
+{
+ char * szMirVerFirst =(char*)wParam; // MirVer value to get client for.
+ char * szMirVerSecond =(char*)lParam; // MirVer value to get client for.
+ int firstIndex, secondIndex;
+ BOOL Result=FALSE;
+ firstIndex=secondIndex=0;
+ if (!szMirVerFirst || !szMirVerSecond) return (int)NULL; //one of its is not null
+ {
+ char MirVerFirst[256], MirVerSecond[256];
+ mir_strncpy(MirVerFirst, szMirVerFirst, sizeof(MirVerFirst));
+ mir_strncpy(MirVerSecond, szMirVerSecond, sizeof(MirVerSecond));
+ mir_strupr(MirVerFirst);
+ mir_strupr(MirVerSecond);
+
+ while (firstIndex<DEFAULT_KN_FP_MASK_COUNT)
+ {
+ if(WildCompare(MirVerFirst,def_kn_fp_mask[firstIndex].szMask)) break;
+ firstIndex++;
+ }
+ while (secondIndex<DEFAULT_KN_FP_MASK_COUNT)
+ {
+ if(WildCompare(MirVerSecond,def_kn_fp_mask[secondIndex].szMask)) break;
+ secondIndex++;
+ }
+ if (firstIndex==secondIndex && firstIndex<DEFAULT_KN_FP_MASK_COUNT)
+ return (int)def_kn_fp_mask[firstIndex].szClientDescription;
+ }
+ return (int)NULL;
+}
+
+/******************************************************************************
+ * Futher routines is for creating joined 'overlay' icons. *
+ ******************************************************************************/
+
+ /*
+ * CreateBitmap32 - Create DIB 32 bitmap with sizes cx*cy
+ */
+
+HBITMAP FASTCALL CreateBitmap32(int cx, int cy)
+{
+ return CreateBitmap32Point(cx,cy,NULL);
+}
+
+ /*
+ * CreateBitmap32 - Create DIB 32 bitmap with sizes cx*cy and put reference
+ * to new bitmap pixel image memory area to void ** bits
+ */
+HBITMAP FASTCALL CreateBitmap32Point(int cx, int cy, void ** bits)
+{
+ BITMAPINFO bmpi = {0};
+ VOID * ptPixels = NULL;
+ HBITMAP DirectBitmap;
+
+ if ( cx < 0 || cy < 0 ) return NULL;
+
+ bmpi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmpi.bmiHeader.biWidth=cx;
+ bmpi.bmiHeader.biHeight=cy;
+ bmpi.bmiHeader.biPlanes=1;
+// bmpi.bmiHeader.biCompression = BI_RGB;
+ bmpi.bmiHeader.biBitCount=32;
+
+ DirectBitmap = CreateDIBSection(NULL,
+ &bmpi,
+ DIB_RGB_COLORS,
+ &ptPixels,
+ NULL, 0);
+ GdiFlush();
+ if (ptPixels) memset(ptPixels,0,cx*cy*4);
+ if (bits!=NULL) *bits=ptPixels;
+
+ return DirectBitmap;
+}
+/*
+* checkHasAlfa - checks if image has at least one BYTE in alpha channel
+* that is not a 0. (is image real 32 bit or just 24 bit)
+*/
+BOOL FASTCALL checkHasAlfa(BYTE * from, int widthByte, int height)
+{
+ DWORD * pt=(DWORD*)from;
+ DWORD * lim = pt+widthByte*height;
+ while (pt < lim)
+ {
+ if (*pt&0xFF000000) return TRUE;
+ pt++;
+ }
+
+ return FALSE;
+}
+
+/*
+* checkHasMask - checks if mask image has at least one that is not a 0.
+* Not sure is it required or not
+*/
+BOOL FASTCALL checkHasMask(BYTE * from)
+{
+ int i;
+ for (i=0; i<16*16/8; i++)
+ {
+ if (from[i]!=0) return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+* GetMaskBit - return value of apropriate mask bit in line at x position
+*/
+BOOL __inline GetMaskBit(BYTE *line, int x)
+{
+ return ((*(line+(x>>3)))&(0x01<<(7-(x&0x07))))!=0;
+}
+
+
+/*
+* blend - alpha blend ARGB values of 2 pixels. X1 - underlaying,
+* X2 - overlaying points.
+*/
+DWORD FASTCALL blend(DWORD X1,DWORD X2)
+{
+ RGBA *q1 = (RGBA*)&X1;
+ RGBA *q2 = (RGBA*)&X2;
+ BYTE a_1=~q1->a;
+ BYTE a_2=~q2->a;
+ WORD am=q1->a*a_2;
+
+ WORD ar=q1->a+((a_1*q2->a)/255);
+ // if a2 more than 0 than result should be more
+ // or equal (if a1==0) to a2, else in combination
+ // with mask we can get here black points
+
+ ar=(q2->a > ar)?q2->a:ar;
+
+ if (ar==0) return 0;
+
+ {
+ WORD arm=ar*255;
+ WORD rr=((q1->r*am + q2->r*q2->a*255))/arm;
+ WORD gr=((q1->g*am + q2->g*q2->a*255))/arm;
+ WORD br=((q1->b*am + q2->b*q2->a*255))/arm;
+ return (ar<<24)|(rr<<16)|(gr<<8)|br;
+ }
+}
+/*
+* CreateJoinedIcon - creates new icon by drawing hTop over hBottom.
+*/
+HICON FASTCALL CreateJoinedIcon(HICON hBottom, HICON hTop)
+{
+ BOOL drawn = 0;
+ HDC tempDC, tempDC2, tempDC3;
+ HICON res=NULL;
+ HBITMAP oImage,nImage;
+ HBITMAP nMask, hbm, obmp, obmp2;
+ BITMAP bmp={0};
+ BYTE *ptPixels = NULL;
+ ICONINFO iNew={0};
+ BYTE p[32] = {0};
+
+ tempDC=CreateCompatibleDC(NULL);
+ nImage=CreateBitmap32Point(16,16,(void**)&ptPixels);
+ oImage=SelectObject(tempDC,nImage);
+
+// if (ptPixels) memset(ptPixels,0,16*16*4);
+
+ if (IsWinVerXPPlus())
+ {
+ ICONINFO iciBottom={0};
+ ICONINFO iciTop={0};
+
+ BITMAP bmp_top={0};
+ BITMAP bmp_top_mask={0};
+
+ BITMAP bmp_bottom={0};
+ BITMAP bmp_bottom_mask={0};
+
+ GetIconInfo(hBottom,&iciBottom);
+ GetObject(iciBottom.hbmColor,sizeof(BITMAP),&bmp_bottom);
+ GetObject(iciBottom.hbmMask,sizeof(BITMAP),&bmp_bottom_mask);
+
+ GetIconInfo(hTop,&iciTop);
+ GetObject(iciTop.hbmColor,sizeof(BITMAP),&bmp_top);
+ GetObject(iciTop.hbmMask,sizeof(BITMAP),&bmp_top_mask);
+
+ if (bmp_bottom.bmBitsPixel==32 &&bmp_top.bmBitsPixel==32)
+ {
+ BYTE * BottomBuffer, * TopBuffer, * BottomMaskBuffer, * TopMaskBuffer;
+ BYTE * bb, * tb, * bmb, * tmb;
+ BYTE * db=ptPixels;
+ int vstep_d=16*4;
+ int vstep_b=bmp_bottom.bmWidthBytes;
+ int vstep_t=bmp_top.bmWidthBytes;
+ int vstep_bm=bmp_bottom_mask.bmWidthBytes;
+ int vstep_tm=bmp_top_mask.bmWidthBytes;
+
+ if (bmp_bottom.bmBits)
+ bb=BottomBuffer=(BYTE*)bmp_bottom.bmBits;
+ else
+ {
+ BottomBuffer=(BYTE*)_alloca(bmp_bottom.bmHeight*bmp_bottom.bmWidthBytes);
+ GetBitmapBits(iciBottom.hbmColor,bmp_bottom.bmHeight*bmp_bottom.bmWidthBytes,BottomBuffer);
+ bb=BottomBuffer+vstep_b*(bmp_bottom.bmHeight-1);
+ vstep_b=-vstep_b;
+ }
+ if (bmp_top.bmBits)
+ tb=TopBuffer=(BYTE*)bmp_top.bmBits;
+ else
+ {
+ TopBuffer=(BYTE*)_alloca(bmp_top.bmHeight*bmp_top.bmWidthBytes);
+ GetBitmapBits(iciTop.hbmColor,bmp_top.bmHeight*bmp_top.bmWidthBytes,TopBuffer);
+ tb=TopBuffer+vstep_t*(bmp_top.bmHeight-1);
+ vstep_t=-vstep_t;
+ }
+ if (bmp_bottom_mask.bmBits)
+ bmb=BottomMaskBuffer=(BYTE*)bmp_bottom_mask.bmBits;
+ else
+ {
+ BottomMaskBuffer=(BYTE*)_alloca(bmp_bottom_mask.bmHeight*bmp_bottom_mask.bmWidthBytes);
+ GetBitmapBits(iciBottom.hbmMask,bmp_bottom_mask.bmHeight*bmp_bottom_mask.bmWidthBytes,BottomMaskBuffer);
+ bmb=BottomMaskBuffer+vstep_bm*(bmp_bottom_mask.bmHeight-1);
+ vstep_bm=-vstep_bm;
+ }
+ if (bmp_top_mask.bmBits)
+ tmb=TopMaskBuffer=(BYTE*)bmp_top_mask.bmBits;
+ else
+ {
+ TopMaskBuffer=(BYTE*)_alloca(bmp_top_mask.bmHeight*bmp_top_mask.bmWidthBytes);
+ GetBitmapBits(iciTop.hbmMask,bmp_top_mask.bmHeight*bmp_top_mask.bmWidthBytes,TopMaskBuffer);
+ tmb=TopMaskBuffer+vstep_tm*(bmp_top_mask.bmHeight-1);
+ vstep_tm=-vstep_tm;
+ }
+ {
+ int x; int y;
+ BOOL topHasAlpha = checkHasAlfa(TopBuffer,bmp_top.bmWidthBytes,bmp_top.bmHeight);
+ BOOL bottomHasAlpha = checkHasAlfa(BottomBuffer,bmp_bottom.bmWidthBytes,bmp_bottom.bmHeight);
+ BOOL topHasMask = !topHasAlpha && checkHasMask(TopMaskBuffer);
+ BOOL bottomHasMask = !bottomHasAlpha && checkHasMask(BottomMaskBuffer);
+
+ for (y=0; y<16; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ DWORD bottom_d=((DWORD*)bb)[x];
+ DWORD top_d=((DWORD*)tb)[x];
+
+ if (topHasMask)
+ {
+ if (GetMaskBit(tmb,x))
+ top_d&=0xFFFFFF;
+ else
+ top_d|=0xFF000000;
+ }
+
+ if (bottomHasMask)
+ {
+ if (GetMaskBit(bmb,x))
+ bottom_d&=0xFFFFFF;
+ else
+ bottom_d|=0xFF000000;
+ }
+
+ ((DWORD*)db)[x]=blend(bottom_d,top_d);
+ }
+ bb+=vstep_b;
+ tb+=vstep_t;
+ bmb+=vstep_bm;
+ tmb+=vstep_tm;
+ db+=vstep_d;
+ }
+ }
+
+ drawn = 1;
+ }
+
+ DeleteObject(iciBottom.hbmColor);
+ DeleteObject(iciTop.hbmColor);
+ DeleteObject(iciBottom.hbmMask);
+ DeleteObject(iciTop.hbmMask);
+ }
+
+ if (!drawn)
+ {
+ DrawIconEx(tempDC,0,0,hBottom,16,16,0,NULL,DI_NORMAL);
+ DrawIconEx(tempDC,0,0,hTop,16,16,0,NULL,DI_NORMAL);
+ }
+
+ nMask=CreateBitmap(16,16,1,1,(void*)&p);
+ tempDC2=CreateCompatibleDC(NULL);
+ tempDC3=CreateCompatibleDC(NULL);
+ hbm=CreateCompatibleBitmap(tempDC3,16,16);
+ obmp=SelectObject(tempDC2,nMask);
+ obmp2=SelectObject(tempDC3,hbm);
+ DrawIconEx(tempDC2,0,0,hBottom,16,16,0,NULL,DI_MASK);
+ DrawIconEx(tempDC3,0,0,hTop,16,16,0,NULL,DI_MASK);
+ BitBlt(tempDC2,0,0,16,16,tempDC3,0,0,SRCAND);
+
+ GdiFlush();
+
+ SelectObject(tempDC2,obmp);
+ DeleteDC(tempDC2);
+
+ SelectObject(tempDC3,obmp2);
+ DeleteDC(tempDC3);
+
+ SelectObject(tempDC,oImage);
+ DeleteDC(tempDC);
+
+ DeleteObject(hbm);
+
+ iNew.fIcon=TRUE;
+ iNew.hbmColor=nImage;
+ iNew.hbmMask=nMask;
+ res=CreateIconIndirect(&iNew);
+
+ DeleteObject(nImage);
+ DeleteObject(nMask);
+
+ return res;
+}
+
+BYTE FASTCALL GetIconIndexFromFI(short base, short overlay, short overlay2, short overlay3)
+{
+ int i;
+ DWORD val;
+ BYTE found=0xFF;
+ BOOL needFreeBase=FALSE, needFreeOverlay=FALSE, needFreeOverlay2=FALSE, needFreeOverlay3=FALSE;
+
+ if (base==-1 || nFICount == 0xFF) return found;
+
+ val = (base<<24)|((overlay&0xFF)<<16)|((overlay2&0xFF)<<8)|(overlay3&0xFF);
+
+ for (i=0; i<nFICount; i++)
+ if (fiList[i].array==val)
+ {
+ found=fiList[i].registeredIndex;
+ break;
+ }
+
+ if (found==0xff && i==nFICount) //not found - then add
+ {
+ KN_FP_MASK * mainMask=&(def_kn_fp_mask[base]);
+ HICON icMain=LoadIconFromExternalFile(mainMask->szIconFileName,LIB_USE,mainMask->szIconName,mainMask->SectionFlag,mainMask->szClientDescription,mainMask->iIconIndex,&needFreeBase);
+
+ fiList=realloc(fiList,sizeof(FOUNDINFO)*(nFICount+1));
+ fiList[nFICount].array=val;
+
+ if (icMain!=NULL)
+ {
+ KN_FP_MASK * overlayMask=(overlay!=-1)?&(def_kn_fp_overlays_mask[overlay]):NULL;
+ KN_FP_MASK * overlay2Mask=(overlay2!=-1)?&(def_kn_fp_overlays2_mask[overlay2]):NULL;
+ KN_FP_MASK * overlay3Mask=(overlay3!=-1)?&(def_kn_fp_overlays3_mask[overlay3]):NULL;
+ HICON icOverlay=(overlayMask==NULL)?NULL:LoadIconFromExternalFile(overlayMask->szIconFileName,LIB_USE,overlayMask->szIconName,overlayMask->SectionFlag,overlayMask->szClientDescription,overlayMask->iIconIndex,&needFreeOverlay);
+ HICON icOverlay2=(overlay2Mask==NULL)?NULL:LoadIconFromExternalFile(overlay2Mask->szIconFileName,LIB_USE,overlay2Mask->szIconName,overlay2Mask->SectionFlag,overlay2Mask->szClientDescription,overlay2Mask->iIconIndex,&needFreeOverlay2);
+ HICON icOverlay3=(overlay3Mask==NULL)?NULL:LoadIconFromExternalFile(overlay3Mask->szIconFileName,LIB_USE,overlay3Mask->szIconName,overlay3Mask->SectionFlag,overlay3Mask->szClientDescription,overlay3Mask->iIconIndex,&needFreeOverlay3);
+ HICON icRes=icMain;
+
+ if (overlayMask)
+ icRes = CreateJoinedIcon(icRes,icOverlay);
+
+ if (overlay2Mask)
+ {
+ HICON hTmp = icRes;
+ icRes=CreateJoinedIcon(icRes,icOverlay2);
+ if (overlayMask && hTmp)
+ DestroyIcon(hTmp);
+ }
+
+ if (overlay3Mask)
+ {
+ HICON hTmp = icRes;
+ icRes=CreateJoinedIcon(icRes,icOverlay3);
+ if (overlayMask && hTmp)
+ DestroyIcon(hTmp);
+ }
+
+ fiList[nFICount].registeredIndex=(icRes)?CallService(MS_CLIST_EXTRA_ADD_ICON,(WPARAM)icRes,0):0xFF;
+
+ found=fiList[nFICount].registeredIndex;
+
+ if (icRes && icRes!=icMain) DestroyIcon(icRes);
+ FreeIcon(icMain,needFreeBase);
+ FreeIcon(icOverlay,needFreeOverlay);
+ FreeIcon(icOverlay2,needFreeOverlay2);
+ FreeIcon(icOverlay3,needFreeOverlay3);
+
+ }
+ else
+ {
+ fiList[nFICount].registeredIndex=0xFF;
+ }
+ nFICount++;
+ }
+
+ return found;
+}
+
+
+void FASTCALL ClearFI()
+{
+ if (fiList!=NULL)
+ free(fiList);
+ fiList=NULL;
+ nFICount=0;
+ return;
+}
+
+
+// (c) by George Hazan
+int FASTCALL DBGetStaticString(HANDLE hContact, const char* moduleName, const char* valueName, char* dest, int dest_len)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING sVal;
+
+ dbv.pszVal = dest;
+ dbv.cchVal = dest_len;
+ dbv.type = DBVT_ASCIIZ;
+
+ sVal.pValue = &dbv;
+ sVal.szModule = moduleName;
+ sVal.szSetting = valueName;
+
+ if (CallService(MS_DB_CONTACT_GETSETTINGSTATIC, ( WPARAM )hContact, ( LPARAM )&sVal ) != 0)
+ return 1;
+
+ return (dbv.type != DBVT_ASCIIZ);
+}
|