From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- fingerprint_mod/fingerprint.c | 1288 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1288 insertions(+) create mode 100644 fingerprint_mod/fingerprint.c (limited to 'fingerprint_mod/fingerprint.c') 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 +#include + +//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;iszSetting && !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 (iszIconFileName,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>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; iszIconFileName,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); +} -- cgit v1.2.3