From 9814933f4bc5a7a4320819de54e313d8fc0ceffe Mon Sep 17 00:00:00 2001 From: sje Date: Wed, 3 Oct 2007 05:26:48 +0000 Subject: initial revision of new metacontacts git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@338 4f64403b-2f21-0410-a795-97e2b3489a10 --- meta2/api.cpp | 317 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 meta2/api.cpp (limited to 'meta2/api.cpp') diff --git a/meta2/api.cpp b/meta2/api.cpp new file mode 100644 index 0000000..03e3c71 --- /dev/null +++ b/meta2/api.cpp @@ -0,0 +1,317 @@ +#include "common.h" +#include "api.h" +#include "proto.h" +#include "core_functions.h" + +HANDLE hEventDefaultChanged = 0, hEventForceSend = 0, hEventUnforceSend = 0, hSubcontactsChanged = 0; + +void FireSubcontactsChanged(HANDLE hMeta) { + NotifyEventHooks(hSubcontactsChanged, (WPARAM)hMeta, 0); +} + +//get the handle for a contact's parent metacontact +//wParam=(HANDLE)hSubContact +//lParam=0 +//returns a handle to the parent metacontact, or null if this contact is not a subcontact +int MetaAPI_GetMeta(WPARAM wParam, LPARAM lParam) { + return (int)(HANDLE)DBGetContactSettingDword((HANDLE)wParam, MODULE, "Handle", 0); +} + +//gets the handle for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the default contact, or null on failure +int MetaAPI_GetDefault(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + if(metaMap.exists(hMeta) == false || metaMap[hMeta].size() == 0) return 0; + + int def = DBGetContactSettingByte(hMeta, MODULE, "Default", -1); + if(def < 0 || def >= metaMap[hMeta].size()) return 0; + + return (int)metaMap[hMeta][def].handle(); +} + +//gets the contact number for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns an int contact number, or -1 on failure +int MetaAPI_GetDefaultNum(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + if(metaMap.exists(hMeta) == false || metaMap[hMeta].size() == 0) return -1; + + int def = DBGetContactSettingByte(hMeta, MODULE, "Default", -1); + if(def < 0 || def >= metaMap[hMeta].size()) return -1; + return def; +} + +//gets the handle for the 'most online' contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the 'most online' contact +int MetaAPI_GetMostOnline(WPARAM wParam, LPARAM lParam) { + return (int)Meta_GetMostOnline((HANDLE)wParam); +} + +//gets the number of subcontacts for a metacontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns an int representing the number of subcontacts for the given metacontact, or -1 on failure +int MetaAPI_GetNumContacts(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + if(metaMap.exists(hMeta)) return metaMap[hMeta].size(); + return -1; +} + +//gets the handle of a subcontact, using the subcontact's number +//wParam=(HANDLE)hMetaContact +//lParam=(int)contact number +//returns a handle to the specified subcontact +int MetaAPI_GetContact(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + if(metaMap.exists(hMeta) && lParam >= 0 && metaMap[hMeta].size() > lParam) return (int)metaMap[hMeta][lParam].handle(); + return 0; +} + +//sets the default contact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(int)contact number +//returns 0 on success +int MetaAPI_SetDefaultContactNum(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + DWORD num_contacts = metaMap.exists(hMeta) ? metaMap[hMeta].size() : -1; + if(num_contacts < 0) + return 1; + if((DWORD)lParam >= num_contacts || (DWORD)lParam < 0) + return 1; + if(DBWriteContactSettingByte((HANDLE)wParam, MODULE, "Default", (DWORD)lParam)) + return 1; + + NotifyEventHooks(hEventDefaultChanged, wParam, (LPARAM)metaMap[hMeta][(int)lParam].handle()); + return 0; +} + +//sets the default contact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success +int MetaAPI_SetDefaultContact(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam, hSub = (HANDLE)lParam; + HANDLE hMetaFromSub = (HANDLE)DBGetContactSettingDword(hSub, MODULE, "Handle", 0); + if(hMetaFromSub != hMeta || metaMap.exists(hMeta) == false) + return 1; + + int contact_num = metaMap[hMeta].index_of(hSub); + if(contact_num == -1) return 1; + + if(DBWriteContactSettingByte(hMeta, MODULE, "Default", contact_num)) + return 1; + + NotifyEventHooks(hEventDefaultChanged, wParam, lParam); + return 0; +} + +//temporarily forces the metacontact to send using a specific subcontact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(int)contact number +//returns 0 on success +int MetaAPI_ForceSendContactNum(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + int contact_num = (int)lParam; + if(!hMeta || metaMap.exists(hMeta) == false || contact_num < 0 || contact_num >= metaMap[hMeta].size() || DBGetContactSettingByte(hMeta, MODULE, "ForceDefault", 0)) + return 1; + + HANDLE hSub = metaMap[hMeta][contact_num].handle(); + HANDLE hMetaFromSub = (HANDLE)DBGetContactSettingDword(hSub, MODULE, "Handle", 0); + if(hMetaFromSub != hMeta) + return 1; + + DBWriteContactSettingDword(hMeta, MODULE, "ForceSend", (DWORD)hSub); + + NotifyEventHooks(hEventForceSend, wParam, (LPARAM)hSub); + return 0; +} + +//temporarily forces the metacontact to send using a specific subcontact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success (will fail if 'force default' is in effect) +int MetaAPI_ForceSendContact(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam, hSub = (HANDLE)lParam; + HANDLE hMetaFromSub = (HANDLE)DBGetContactSettingDword(hSub, MODULE, "Handle", 0); + if(!hSub || !hMeta || hMetaFromSub != hMeta || !metaMap.exists(hMeta) || metaMap[hMeta].index_of(hSub) == -1 || DBGetContactSettingByte(hMeta, MODULE, "ForceDefault", 0)) + return 1; + + DBWriteContactSettingDword(hMeta, MODULE, "ForceSend", (DWORD)hSub); + + NotifyEventHooks(hEventForceSend, wParam, lParam); + return 0; +} + +//'unforces' the metacontact to send using a specific subcontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 0 on success (will fail if 'force default' is in effect) +int MetaAPI_UnforceSendContact(WPARAM wParam, LPARAM lParam) { + if(DBGetContactSettingByte((HANDLE)wParam, MODULE, "ForceDefault", 0) == 0) + return 1; + + DBWriteContactSettingDword((HANDLE)wParam, MODULE, "ForceSend", 0); + + NotifyEventHooks(hEventUnforceSend, wParam, lParam); + return 0; +} + + +//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact +// overrides 'force send' above, and will even force use of offline contacts +// will send ME_MC_FORCESEND event +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 1(true) or 0(false) representing new state of 'force default' +int MetaAPI_ForceDefault(WPARAM wParam, LPARAM lParam) { + int old_state = DBGetContactSettingByte((HANDLE)wParam, MODULE, "ForceDefault", 0); + DBWriteContactSettingByte((HANDLE)wParam, MODULE, "ForceDefault", old_state ? 0 : 1); + return old_state ? 0 : 1; +} + +// method to get state of 'force' for a metacontact +// wParam=(HANDLE)hMetaContact +// lParam= (int)&contact_number or NULL +// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to, +// or if none is in force, the value (DWORD)-1 will be copied +// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above) +int MetaAPI_GetForceState(WPARAM wParam, LPARAM lParam) { + HANDLE hMeta = (HANDLE)wParam; + HANDLE hContact; + + if(!hMeta || !metaMap.exists(hMeta)) return 0; + + if(DBGetContactSettingByte(hMeta, MODULE, "ForceDefault", 0)) { + if(lParam) *(DWORD *)lParam = DBGetContactSettingByte((HANDLE)wParam, MODULE, "Default", -1); + return 1; + } + + hContact = (HANDLE)DBGetContactSettingDword(hMeta, MODULE, "ForceSend", 0); + + if(!hContact) { + if(lParam) *(DWORD *)lParam = -1; + } else { + if(lParam) *(DWORD *)lParam = (DWORD)metaMap[hMeta].index_of(hContact); + } + + return 0; +} + +// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :) +// wParam=lParam=0 +int MetaAPI_GetProtoName(WPARAM wParam, LPARAM lParam) { + return (int)MODULE; +} + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=0 +// convert a given contact into a metacontact +int MetaAPI_ConvertToMeta(WPARAM wParam, LPARAM lParam) { + return (int)Meta_Convert((HANDLE)wParam); +} + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=(HANDLE)hMeta +// add an existing contact to a metacontact +int MetaAPI_AddToMeta(WPARAM wParam, LPARAM lParam) { + Meta_Assign((HANDLE)wParam, (HANDLE)lParam); + return 0; +} + +// added 0.9.5.0 (22/3/05) +// wParam=0 +// lParam=(HANDLE)hContact +// remove a contact from a metacontact +int MetaAPI_RemoveFromMeta(WPARAM wParam, LPARAM lParam) { + Meta_Remove((HANDLE)lParam); + return 0; +} + +// added 0.9.13.2 (6/10/05) +// wParam=(BOOL)disable +// lParam=0 +// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting +// should be called once in your 'onmodulesloaded' event handler +bool meta_group_hack_disabled = false; +int MetaAPI_DisableHiddenGroup(WPARAM wParam, LPARAM lParam) { + meta_group_hack_disabled = (BOOL)wParam; + return 0; +} + +int ModulesLoadedAPI(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0); + char *proto; + HANDLE hMeta; + while(hContact != NULL) { + DWORD id = DBGetContactSettingDword(hContact, MODULE, "ParentMetaID", (DWORD)-1); + if(id != (DWORD)-1) { + hMeta = GetMetaHandle(id); + if(hMeta) { + if(id >= next_meta_id) next_meta_id = id + 1; + metaMap[hMeta].add(hContact); + DBWriteContactSettingDword(hContact, MODULE, "Handle", (DWORD)hMeta); + DBWriteContactSettingByte(hContact, MODULE, "IsSubcontact", 1); + } else + DBDeleteContactSetting(hContact, MODULE, "ParentMetaID"); + } else if(IsMetacontact(hContact)) { + meta_count++; + DBWriteContactSettingWord(hContact, MODULE, "Status", ID_STATUS_OFFLINE); + } + + hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); + } + + return 0; +} + +#define NUM_API_SERVICES 17 +HANDLE hServicesAPI[NUM_API_SERVICES] = {0}; +HANDLE hEventModulesLoadedAPI = 0; +void InitAPI() { + int i = 0; + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETMETACONTACT, MetaAPI_GetMeta); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETDEFAULTCONTACT, MetaAPI_GetDefault); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETDEFAULTCONTACTNUM, MetaAPI_GetDefaultNum); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETMOSTONLINECONTACT, MetaAPI_GetMostOnline); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETNUMCONTACTS, MetaAPI_GetNumContacts); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETSUBCONTACT, MetaAPI_GetContact); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_SETDEFAULTCONTACTNUM, MetaAPI_SetDefaultContactNum); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_SETDEFAULTCONTACT, MetaAPI_SetDefaultContact); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_FORCESENDCONTACTNUM, MetaAPI_ForceSendContactNum); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_FORCESENDCONTACT, MetaAPI_ForceSendContact); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_UNFORCESENDCONTACT, MetaAPI_UnforceSendContact); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETPROTOCOLNAME, MetaAPI_GetProtoName); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_GETFORCESTATE, MetaAPI_GetForceState); + + hServicesAPI[i++] = CreateServiceFunction(MS_MC_CONVERTTOMETA, MetaAPI_ConvertToMeta); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_ADDTOMETA, MetaAPI_AddToMeta); + hServicesAPI[i++] = CreateServiceFunction(MS_MC_REMOVEFROMMETA, MetaAPI_RemoveFromMeta); + + hServicesAPI[i++] = CreateServiceFunction(MS_MC_DISABLEHIDDENGROUP, MetaAPI_DisableHiddenGroup); + + hEventDefaultChanged = CreateHookableEvent(ME_MC_DEFAULTTCHANGED); + hEventForceSend = CreateHookableEvent(ME_MC_FORCESEND); + hEventUnforceSend = CreateHookableEvent(ME_MC_UNFORCESEND); + hSubcontactsChanged = CreateHookableEvent(ME_MC_SUBCONTACTSCHANGED); + + //hEventModulesLoadedAPI = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoadedAPI); + ModulesLoadedAPI(0, 0); +} + +void DeinitAPI() { + if(hEventModulesLoadedAPI) UnhookEvent(hEventModulesLoadedAPI); + DestroyHookableEvent(hSubcontactsChanged); + DestroyHookableEvent(hEventUnforceSend); + DestroyHookableEvent(hEventForceSend); + DestroyHookableEvent(hEventDefaultChanged); + + for(int i = 0; i < NUM_API_SERVICES; i++) + DestroyServiceFunction(hServicesAPI[i]); +} \ No newline at end of file -- cgit v1.2.3