From 200aa11bbd25189047b388b88b3fc1f50b785d7c Mon Sep 17 00:00:00 2001 From: sje Date: Wed, 1 Nov 2006 14:37:48 +0000 Subject: git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@8 4f64403b-2f21-0410-a795-97e2b3489a10 --- metacontacts/meta_main.c | 261 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 metacontacts/meta_main.c (limited to 'metacontacts/meta_main.c') diff --git a/metacontacts/meta_main.c b/metacontacts/meta_main.c new file mode 100644 index 0000000..e66221f --- /dev/null +++ b/metacontacts/meta_main.c @@ -0,0 +1,261 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_main.c +* +* Functions used by Miranda to launch the plugin. +* Centralizes functions needed by Miranda to get +* information about the plugin and to initialize it +* and to dispose of it properly. +*/ + +/*! \mainpage MetaContacts plugin + * \image html ulp.gif + * \section desc Description + * This library is a plugin for Miranda IM.\n + * It allows the user to group several contacts from different + * protocols (such as AIM or ICQ) into one unique metacontact.\n + * + * \section principle How does it work ? + * Only one protocol will be used at a time (the default protocol).\n + * This protocol is referenced in the proper field of the MetaContact + * section in the Database. + * + * \subsection send Emission of messages + * The plugin will search through the Database to get the default protocol + * (i.e. the protocol used to communicate with),\n and then call the Send function + * provided by this protocol. + * + * \subsection recv Reception of messages + * When a contact is converted to a metacontact, or when it is added to an existing + * metacontact, it gets a pseudo protocol \n (named "MetaContacts") in the protocol chain.\n + * Usually, when a message is received, all the protocols in the chain get this message, + * the real protocol (for example ICQ) at the end.\n But here, the message will be intercepted + * by the MetaContact protocol, which will inhibit the further reception.\n The message will + * then be redirected to the MetaContact, that will display it normally. + * + * \subsection handling Handling MetaContacts + * There are four functionnality for handling MetaContacts : + * \li Convert a contact to a MetaContact. + * \li Add a contact to an existing MetaContact. + * \li Edit a MetaContact. + * \li Delete a MetaContact. + * + * They all are accessible via the context-menu displayed when a right click has occured, + * but not at the same time : The 2 first will appear when the menu concerns a simple contact.\n + * whereas the 2 last are only accessible from a MetaContact.\n + * Those functions are self-explanatory, and a MessageBox is shown before any modification, so, for + * further information, take a look at the Dialogs shown when they are called.\n + * + * \section cvats Caveats + * Several functionnalities have not yet been developped : + * \li Assigning contacts by Drag'n'Drop + * \li Updating dynamically the status of the MetaContact + * \li Merging history of all the contacts attached to MetaContact + * \li Handling Files and URLs as well as Messages + * \li and some other little functionnalities... + * + * Some of those functionnalities will not be developped due to the architecture + * of Miranda (the 2 first, for example) + * + * \section mail Contact + * For any comment, suggestion or question, send a mail to shaalj@free.fr.\n + * This code is provided as-is, and I cannot be held responsible for any harm + * done to your database by this plugin.\n + * Test it first on a fake database before using it normally. + */ + +#include "metacontacts.h" + +// Use VersionNo.h to set the version number, and ensure resource file is not open +#include "version.h" + +struct MM_INTERFACE memoryManagerInterface; + +BOOL os_unicode_enabled = FALSE; + +//! Information gathered by Miranda, displayed in the plugin pane of the Option Dialog +PLUGININFO pluginInfo={ + sizeof(PLUGININFO), + //META_PROTO, + __PLUGIN_NAME, // altered here and on file listing, so as not to match original + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESC, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + 0, + 0 +}; + +HINSTANCE hInstance; //!< Global reference to the application +PLUGINLINK *pluginLink; //!< Link between Miranda and this plugin + +HANDLE metaMainThread; //!< Duplicate of thread handle + +/** Called by Miranda to get the information associated to this plugin. +* It only returns the PLUGININFO structure, without any test on the version +* @param mirandaVersion The version of the application calling this function +*/ +__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +/** DLL entry point +* Required to store the instance handle +*/ +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInstance=hinstDLL; + DisableThreadLibraryCalls(hInstance); + return TRUE; +} + +/** Prepare the plugin to stop +* Called by Miranda when it will exit or when the plugin gets deselected +*/ +__declspec(dllexport)int Unload(void) +{ + // see also meta_services.c, Meta_PreShutdown + Meta_CloseHandles(); + //MessageBox(0, "Unload complete", "MC", MB_OK); + return 0; +} + +BOOL IsUnicodeOS() +{ + OSVERSIONINFOW os; + memset(&os, 0, sizeof(OSVERSIONINFOW)); + os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + return (GetVersionExW(&os) != 0); +} + +/** Initializes the services provided and the link to those needed +* Called when the plugin is loaded into Miranda +*/ +int __declspec(dllexport)Load(PLUGINLINK *link) +{ + PROTOCOLDESCRIPTOR pd; + DBVARIANT dbv; + + pluginLink=link; + DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &metaMainThread, THREAD_SET_CONTEXT, FALSE, 0 ); + + memoryManagerInterface.cbSize = sizeof(memoryManagerInterface); + CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&memoryManagerInterface); + + os_unicode_enabled = IsUnicodeOS(); + + if(ServiceExists(MS_DB_SETSETTINGRESIDENT)) { // 0.6+ + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/Status")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/IdleTS")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/ContactCountCheck")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/Handle")); + CallService(MS_DB_SETSETTINGRESIDENT, TRUE, (LPARAM)(META_PROTO "/WindowOpen")); + } + + //set all contacts to 'offline', and initialize subcontact counter for db consistency check + { + HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0); + char *proto; + while(hContact != NULL) { + //proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if(!DBGetContactSetting(hContact, "Protocol", "p", &dbv)) { + proto = dbv.pszVal; + if (proto && !lstrcmp( META_PROTO, proto)) { + DBWriteContactSettingWord(hContact, META_PROTO, "Status", ID_STATUS_OFFLINE); + DBWriteContactSettingDword(hContact, META_PROTO, "IdleTS", 0); + DBWriteContactSettingByte(hContact, META_PROTO, "ContactCountCheck", 0); + + // restore any saved defaults that might have remained if miranda was closed or crashed while a convo was happening + if(DBGetContactSettingDword(hContact, META_PROTO, "SavedDefault", (DWORD)-1) != (DWORD)-1) { + DBWriteContactSettingDword(hContact, META_PROTO, "Default", DBGetContactSettingDword(hContact, META_PROTO, "SavedDefault", 0)); + DBWriteContactSettingDword(hContact, META_PROTO, "SavedDefault", (DWORD)-1); + } + + } + DBFreeVariant(&dbv); + } + + hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); + } + } + + Meta_ReadOptions(&options); + + + // sets subcontact handles to metacontacts, and metacontact handles to subcontacts + // (since these handles are not necessarily the same from run to run of miranda) + + // also verifies that subcontacts: have metacontacts, and that contact numbers are reasonable, + // that metacontacts: have the correct number of subcontacts, and have reasonable defaults + if(Meta_SetHandles()) { + // error - db corruption + if(!DBGetContactSettingByte(0, META_PROTO, "DisabledMessageShown", 0)) { + MessageBox(0, Translate("Error - Database corruption.\nPlugin disabled."), Translate("MetaContacts"), MB_OK | MB_ICONERROR); + DBWriteContactSettingByte(0, META_PROTO, "DisabledMessageShown", 1); + } + //Meta_HideMetaContacts(TRUE); + return 1; + } + + DBDeleteContactSetting(0, META_PROTO, "DisabledMessageShown"); + + // add our modules to the KnownModules list + { + DBVARIANT dbv; + if (DBGetContactSetting(NULL, "KnownModules", META_PROTO, &dbv)) + DBWriteContactSettingString(NULL, "KnownModules", META_PROTO, META_PROTO); + DBFreeVariant(&dbv); + } + + ZeroMemory(&pd,sizeof(pd)); + pd.cbSize=sizeof(pd); + + pd.szName=META_FILTER; + pd.type=PROTOTYPE_FILTER; + CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); + + ZeroMemory(&pd,sizeof(pd)); + pd.cbSize=sizeof(pd); + + pd.szName=META_PROTO; + pd.type = PROTOTYPE_PROTOCOL; + CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); + + // further db setup done in modules loaded (nick [protocol string required] & clist display name) + + Meta_InitServices(); + + // moved to 'modules loaded' event handler (in meta_services.c) because we need to + // check protocol for jabber hack, and the proto modules must be loaded + //Meta_HideLinkedContactsAndSetHandles(); + + if(ServiceExists(MS_MSG_GETWINDOWAPI)) { + message_window_api_enabled = TRUE; + } + + // for clist_meta_mw - write hidden group name to DB + DBWriteContactSettingString(0, META_PROTO, "HiddenGroupName", META_HIDDEN_GROUP); + + return 0; +} -- cgit v1.2.3