diff options
author | George Hazan <george.hazan@gmail.com> | 2015-06-13 16:55:17 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2015-06-13 16:55:17 +0000 |
commit | cbe3cb21f5bca61a03bbd4ae811ee906e09b3f4f (patch) | |
tree | 4854fb66f4d59940efa3c1590237915851074dbf /src/modules/metacontacts/meta_services.cpp | |
parent | 351bcbec48ed77af5f8efcc4d5198707922c5d86 (diff) |
- miranda32.exe now does nothing bug extends PATH to %miranda_root%\libs and loads mir_app.dll;
- everything that was in miranda32.exe (including resources) moved to mir_app.dll;
- exports from mir_app.dll now available for using directly, without perversions;
- src/stdplug.h deleted;
git-svn-id: http://svn.miranda-ng.org/main/trunk@14143 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/modules/metacontacts/meta_services.cpp')
-rw-r--r-- | src/modules/metacontacts/meta_services.cpp | 912 |
1 files changed, 0 insertions, 912 deletions
diff --git a/src/modules/metacontacts/meta_services.cpp b/src/modules/metacontacts/meta_services.cpp deleted file mode 100644 index 72f60c5f71..0000000000 --- a/src/modules/metacontacts/meta_services.cpp +++ /dev/null @@ -1,912 +0,0 @@ -/*
-former MetaContacts Plugin for Miranda IM.
-
-Copyright © 2014 Miranda NG Team
-Copyright © 2004-07 Scott Ellis
-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.
-*/
-
-#include "..\..\core\commonheaders.h"
-
-#include <m_nudge.h>
-
-#include "metacontacts.h"
-
-extern "C" MIR_CORE_DLL(void) db_mc_notifyDefChange(WPARAM wParam, LPARAM lParam);
-
-char *pendingACK = 0; // Name of the protocol in which an ACK is about to come.
-
-int previousMode, // Previous status of the MetaContacts Protocol
-mcStatus; // Current status of the MetaContacts Protocol
-
-HANDLE
-hSubcontactsChanged, // HANDLE to the 'contacts changed' event
-hEventNudge;
-
-UINT_PTR setStatusTimerId = 0;
-BOOL firstSetOnline = TRUE; // see Meta_SetStatus function
-
-OBJLIST<MetaSrmmData> arMetaWindows(1, NumericKeySortT);
-
-/** Get the capabilities of the "MetaContacts" protocol.
-*
-* @param wParam : equals to one of the following values :\n
-<tt> PFLAGNUM_1 | PFLAGNUM_2 | PFLAGNUM_3 | PFLAGNUM_4 | PFLAG_UNIQUEIDTEXT | PFLAG_MAXLENOFMESSAGE | PFLAG_UNIQUEIDSETTING </tt>.
-* @param lParam : Allways set to 0.
-*
-* @return Depending on the \c WPARAM.
-*/
-INT_PTR Meta_GetCaps(WPARAM wParam, LPARAM lParam)
-{
- switch (wParam) {
- case PFLAGNUM_1:
- return PF1_IM | PF1_CHAT | PF1_FILESEND | PF1_MODEMSGRECV | PF1_NUMERICUSERID;
-
- case PFLAGNUM_2:
- return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
-
- case PFLAGNUM_3:
- return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
-
- case PFLAGNUM_4:
- return PF4_SUPPORTTYPING | PF4_AVATARS;
-
- case PFLAGNUM_5:
- return PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE;
-
- case PFLAG_MAXLENOFMESSAGE:
- return 2000;
- }
- return 0;
-}
-
-/** Copy the name of the protocole into lParam
-* @param wParam : max size of the name
-* @param lParam : reference to a char *, which will hold the name
-*/
-
-INT_PTR Meta_GetName(WPARAM wParam, LPARAM lParam)
-{
- char *name = (char *)Translate(META_PROTO);
- size_t size = min(mir_strlen(name), wParam - 1); // copy only the first size bytes.
- if (strncpy((char *)lParam, name, size) == NULL)
- return 1;
- ((char *)lParam)[size] = '\0';
- return 0;
-}
-
-/** Loads the icon corresponding to the status
-* Called by the CList when the status changes.
-* @param wParam : one of the following values : \n
-<tt>PLI_PROTOCOL | PLI_ONLINE | PLI_OFFLINE</tt>
-* @return an \c HICON in which the icon has been loaded.
-*/
-
-INT_PTR Meta_LoadIcon(WPARAM wParam, LPARAM lParam)
-{
- UINT id;
- switch (wParam & 0xFFFF) {
- case PLI_PROTOCOL:
- id = IDI_MCMENU;
- break;
- case PLI_ONLINE:
- id = IDI_MCMENU;
- break;
- case PLI_OFFLINE:
- id = IDI_MCMENU;
- break;
- default:
- return 0;
- }
-
- return (INT_PTR)LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON,
- GetSystemMetrics(wParam & PLIF_SMALL ? SM_CXSMICON : SM_CXICON),
- GetSystemMetrics(wParam & PLIF_SMALL ? SM_CYSMICON : SM_CYICON), 0);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static void Meta_SetSrmmSub(MCONTACT hMeta, MCONTACT hSub)
-{
- MetaSrmmData tmp = { hMeta };
- if (MetaSrmmData *p = arMetaWindows.find(&tmp))
- p->m_hSub = hSub;
-}
-
-static INT_PTR MetaFilter_RecvMessage(WPARAM wParam, LPARAM lParam)
-{
- CCSDATA *ccs = (CCSDATA*)lParam;
- DBCachedContact *cc = currDb->m_cache->GetCachedContact(ccs->hContact);
- if (cc && cc->IsSub())
- Meta_SetSrmmSub(cc->parentID, cc->contactID);
-
- CallService(MS_PROTO_CHAINRECV, wParam, lParam);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CALLBACK SetStatusThread(HWND hWnd, UINT msg, UINT_PTR id, DWORD dw)
-{
- previousMode = mcStatus;
-
- mcStatus = ID_STATUS_ONLINE;
- ProtoBroadcastAck(META_PROTO, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus);
-
- KillTimer(0, setStatusTimerId);
-}
-
-/** Changes the status and notifies everybody
-* @param wParam : The new mode
-* @param lParam : Allways set to 0.
-*/
-
-INT_PTR Meta_SetStatus(WPARAM wParam, LPARAM lParam)
-{
- // firstSetOnline starts out true - used to delay metacontact's 'onlineness' to prevent double status notifications on startup
- if (mcStatus == ID_STATUS_OFFLINE && firstSetOnline) {
- // causes crash on exit if miranda is closed in under options.set_status_from_offline milliseconds!
- setStatusTimerId = SetTimer(0, 0, options.set_status_from_offline_delay, SetStatusThread);
- firstSetOnline = FALSE;
- }
- else {
- previousMode = mcStatus;
- mcStatus = (int)wParam;
- ProtoBroadcastAck(META_PROTO, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus);
- }
- return 0;
-}
-
-/** Returns the current status
-*/
-INT_PTR Meta_GetStatus(WPARAM wParam, LPARAM lParam)
-{
- return mcStatus;
-}
-
-//////////////////////////////////////////////////////////
-/// Copied from MSN plugin - sent acks need to be from different thread :(
-//////////////////////////////////////////////////////////
-
-struct TFakeAckParams
-{
- HANDLE hEvent;
- MCONTACT hContact;
- LONG id;
- char msg[512];
-};
-
-static void __cdecl sttFakeAckFail(void *param)
-{
- TFakeAckParams *tParam = (TFakeAckParams*)param;
- WaitForSingleObject(tParam->hEvent, INFINITE);
-
- Sleep(100);
- ProtoBroadcastAck(META_PROTO, tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)tParam->id, (WPARAM)tParam->msg);
-
- CloseHandle(tParam->hEvent);
- mir_free(tParam);
-}
-
-INT_PTR Meta_SendNudge(WPARAM wParam, LPARAM lParam)
-{
- DBCachedContact *cc = CheckMeta(wParam);
- if (cc == NULL)
- return 1;
-
- MCONTACT hSubContact = Meta_GetMostOnline(cc);
- return CallProtoService(GetContactProto(hSubContact), PS_SEND_NUDGE, hSubContact, lParam);
-}
-
-/** Send a message to the protocol specific network.
-*
-* Call the function specific to the protocol that belongs
-* to the contact chosen to send the message.
-*
-* @param wParam : index of the protocol in the protocol chain.
-* @param lParam : CCSDATA structure holding all the information abour rhe message.
-*
-* @return 0 on success, 1 otherwise.
-*/
-
-INT_PTR Meta_SendMessage(WPARAM wParam, LPARAM lParam)
-{
- CCSDATA *ccs = (CCSDATA*)lParam;
-
- DBCachedContact *cc = CheckMeta(ccs->hContact);
- if (cc == NULL || cc->nDefault == -1) {
- // This is a simple contact, let through the stack of protocols
- // (this should normally not happen, since linked contacts do not appear on the list.)
- return CallService(MS_PROTO_CHAINSEND, wParam, lParam);
- }
-
- MCONTACT hMostOnline = db_mc_getSrmmSub(cc->contactID);
- if (!hMostOnline) {
- // send failure to notify user of reason
- HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
- TFakeAckParams *tfap = (TFakeAckParams *)mir_alloc(sizeof(TFakeAckParams));
- tfap->hContact = ccs->hContact;
- tfap->hEvent = hEvent;
- tfap->id = 10;
- strncpy(tfap->msg, Translate("No online contacts found."), SIZEOF(tfap->msg) - 1);
-
- CloseHandle(mir_forkthread(sttFakeAckFail, (void*)tfap));
- SetEvent(hEvent);
- return 10;
- }
-
- Meta_CopyContactNick(cc, hMostOnline);
-
- ccs->hContact = hMostOnline;
- char *proto = GetContactProto(hMostOnline);
- Meta_SetNick(proto); // (no matter what was there before)
-
- return CallContactService(ccs->hContact, PSS_MESSAGE, ccs->wParam, ccs->lParam);
-}
-
-/** Called when an ACK is received.
-*
-* Retransmit the ACK sent by a simple contact so that it
-* looks like it was the MetaContact that sends the ACK.
-*
-* @param wParam : Allways set to 0.
-* @param lParam : Reference to a ACKDATA that contains information about the ACK.
-* @returns 0 on success, 1 otherwise.
-*/
-
-int Meta_HandleACK(WPARAM, LPARAM lParam)
-{
- ACKDATA *ack = (ACKDATA*)lParam;
- if (ack == NULL)
- return 0;
- DBCachedContact *cc = CheckMeta(ack->hContact);
- if (cc == NULL)
- return 0;
-
- if (!mir_strcmp(ack->szModule, META_PROTO))
- return 0; // don't rebroadcast our own acks
-
- // if it's for something we don't support, ignore
- if (ack->type != ACKTYPE_MESSAGE && ack->type != ACKTYPE_CHAT && ack->type != ACKTYPE_FILE && ack->type != ACKTYPE_AWAYMSG && ack->type != ACKTYPE_AVATAR && ack->type != ACKTYPE_GETINFO)
- return 0;
-
- // change the hContact in the avatar info struct, if it's the avatar we're using - else drop it
- if (ack->type == ACKTYPE_AVATAR) {
- if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED || ack->result == ACKRESULT_STATUS) {
- DBVARIANT dbv;
-
- // change avatar if the most online supporting avatars changes, or if we don't have one
- MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
- if (ack->hContact == 0 || ack->hContact != hMostOnline)
- return 0;
-
- if (!db_get(ack->hContact, "ContactPhoto", "File", &dbv)) {
- db_set_ts(cc->contactID, "ContactPhoto", "File", dbv.ptszVal);
- db_free(&dbv);
- }
-
- if (ack->hProcess) {
- PROTO_AVATAR_INFORMATION ai;
- memcpy(&ai, (PROTO_AVATAR_INFORMATION*)ack->hProcess, sizeof(ai));
- if (ai.hContact)
- ai.hContact = cc->contactID;
-
- return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, (HANDLE)&ai, ack->lParam);
- }
-
- return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, 0, ack->lParam);
- }
- }
-
- return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, ack->hProcess, ack->lParam);
-}
-
-/** Call whenever a contact changes one of its settings (for example, the status)
-**
-* @param wParam HANDLE to the contact that has change of its setting.
-* @param lParam Reference to a structure that contains the setting that has changed (not used)
-*/
-
-int Meta_SettingChanged(WPARAM hContact, LPARAM lParam)
-{
- DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam;
- char buffer[512];
-
- // the only global options we're interested in
- if (hContact == 0)
- return 0;
-
- DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact);
- if (cc == NULL || !cc->IsSub())
- return 0;
-
- DBCachedContact *ccMeta = currDb->m_cache->GetCachedContact(cc->parentID);
- if (ccMeta == NULL || !ccMeta->IsMeta())
- return 0;
-
- // This contact is attached to a MetaContact.
- int contact_number = Meta_GetContactNumber(ccMeta, hContact);
- if (contact_number == -1)
- return 0; // exit - db corruption
-
- if (!mir_strcmp(dcws->szSetting, "IP")) {
- if (dcws->value.type == DBVT_DWORD)
- db_set_dw(ccMeta->contactID, META_PROTO, "IP", dcws->value.dVal);
- else
- db_unset(ccMeta->contactID, META_PROTO, "IP");
- }
- else if (!mir_strcmp(dcws->szSetting, "RealIP")) {
- if (dcws->value.type == DBVT_DWORD)
- db_set_dw(ccMeta->contactID, META_PROTO, "RealIP", dcws->value.dVal);
- else
- db_unset(ccMeta->contactID, META_PROTO, "RealIP");
- }
- else if (!mir_strcmp(dcws->szSetting, "ListeningTo")) {
- switch (dcws->value.type) {
- case DBVT_ASCIIZ:
- db_set_s(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal);
- break;
- case DBVT_UTF8:
- db_set_utf(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal);
- break;
- case DBVT_WCHAR:
- db_set_ws(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal);
- break;
- case DBVT_DELETED:
- db_unset(ccMeta->contactID, META_PROTO, "ListeningTo");
- break;
- }
- }
- else if (!mir_strcmp(dcws->szSetting, "Nick") && dcws->value.type != DBVT_DELETED) {
- // subcontact nick has changed - update metacontact
- mir_snprintf(buffer, "Nick%d", contact_number);
- db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value);
-
- ptrT tszMyhandle(db_get_tsa(hContact, "CList", "MyHandle"));
- if (tszMyhandle == NULL) {
- mir_snprintf(buffer, "CListName%d", contact_number);
- db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value);
- }
-
- // copy nick to metacontact, if it's the most online
- MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta);
- Meta_CopyContactNick(ccMeta, hMostOnline);
- }
- else if (!mir_strcmp(dcws->szSetting, "IdleTS")) {
- if (dcws->value.type == DBVT_DWORD)
- db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", dcws->value.dVal);
- else if (dcws->value.type == DBVT_DELETED)
- db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", 0);
- }
- else if (!mir_strcmp(dcws->szSetting, "LogonTS")) {
- if (dcws->value.type == DBVT_DWORD)
- db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", dcws->value.dVal);
- else if (dcws->value.type == DBVT_DELETED)
- db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", 0);
- }
- else if (!mir_strcmp(dcws->szModule, "CList") && !mir_strcmp(dcws->szSetting, "MyHandle")) {
- if (dcws->value.type == DBVT_DELETED) {
- char *proto = GetContactProto(hContact);
- mir_snprintf(buffer, "CListName%d", contact_number);
-
- DBVARIANT dbv;
- if (proto && !db_get_ts(hContact, proto, "Nick", &dbv)) {
- db_set_ts(ccMeta->contactID, META_PROTO, buffer, dbv.ptszVal);
- db_free(&dbv);
- }
- else db_unset(ccMeta->contactID, META_PROTO, buffer);
- }
- else {
- // subcontact clist displayname has changed - update metacontact
- mir_snprintf(buffer, "CListName%d", contact_number);
- db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value);
- }
-
- // copy nick to metacontact, if it's the most online
- Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta));
- }
- // subcontact changing status
- else if (!mir_strcmp(dcws->szSetting, "Status") && dcws->value.type != DBVT_DELETED) {
- // update subcontact status setting
- mir_snprintf(buffer, "Status%d", contact_number);
- db_set_w(ccMeta->contactID, META_PROTO, buffer, dcws->value.wVal);
-
- mir_snprintf(buffer, "StatusString%d", contact_number);
- db_set_ts(ccMeta->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0));
-
- // set status to that of most online contact
- MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta);
- if (hMostOnline != db_mc_getDefault(ccMeta->contactID))
- db_mc_notifyDefChange(ccMeta->contactID, hMostOnline);
-
- Meta_CopyContactNick(ccMeta, hMostOnline);
- Meta_FixStatus(ccMeta);
-
- // most online contact with avatar support might have changed - update avatar
- hMostOnline = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS);
- if (hMostOnline) {
- PROTO_AVATAR_INFORMATION ai = { 0 };
- ai.hContact = ccMeta->contactID;
- ai.format = PA_FORMAT_UNKNOWN;
- _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE);
- if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS)
- db_set_ts(ccMeta->contactID, "ContactPhoto", "File", ai.filename);
- }
- }
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Contact's deletion hook
-
-int Meta_ContactDeleted(WPARAM hContact, LPARAM lParam)
-{
- DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact);
- if (cc == NULL)
- return 0;
-
- // is a subcontact - update meta contact
- if (cc->IsSub()) {
- DBCachedContact *ccMeta = CheckMeta(cc->parentID);
- if (ccMeta) {
- Meta_RemoveContactNumber(ccMeta, Meta_GetContactNumber(ccMeta, hContact), true);
- NotifyEventHooks(hSubcontactsChanged, ccMeta->contactID, 0);
-
- // no more subs? remove the meta itself
- if (ccMeta->nSubs == 0)
- CallService(MS_DB_CONTACT_DELETE, ccMeta->contactID, 0);
- }
- return 0;
- }
-
- // not a subcontact - is it a metacontact?
- if (!cc->IsMeta())
- return 0;
-
- if (cc->nSubs > 0)
- NotifyEventHooks(hSubcontactsChanged, hContact, 0);
-
- // remove & restore all subcontacts
- for (int i = 0; i < cc->nSubs; i++) {
- currDb->MetaDetouchSub(cc, i);
-
- // stop ignoring, if we were
- if (options.bSuppressStatus)
- CallService(MS_IGNORE_UNIGNORE, cc->pSubs[i], IGNOREEVENT_USERONLINE);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Call when we want to send a user is typing message
-//
-// @param wParam HANDLE to the contact that we are typing to
-// @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF
-
-static INT_PTR Meta_UserIsTyping(WPARAM hMeta, LPARAM lParam)
-{
- DBCachedContact *cc = CheckMeta(hMeta);
- if (cc == NULL)
- return 0;
-
- // forward to sending protocol, if supported
- MCONTACT hMostOnline = Meta_GetMostOnline(cc);
- Meta_CopyContactNick(cc, hMostOnline);
- if (!hMostOnline)
- return 0;
-
- char *proto = GetContactProto(hMostOnline);
- if (proto)
- if (ProtoServiceExists(proto, PSS_USERISTYPING))
- CallProtoService(proto, PSS_USERISTYPING, hMostOnline, lParam);
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Called when user info is about to be shown
-//
-// Returns 1 to stop event processing and opens page for metacontact default
-// contact (returning 1 to stop it doesn't work!)
-
-static int Meta_UserInfo(WPARAM wParam, LPARAM hMeta)
-{
- DBCachedContact *cc = CheckMeta(hMeta);
- if (cc == NULL || cc->nDefault == -1)
- return 0;
-
- CallService(MS_USERINFO_SHOWDIALOG, Meta_GetContactHandle(cc, cc->nDefault), 0);
- return 1;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// record window open/close status for subs & metas
-
-static int Meta_MessageWindowEvent(WPARAM wParam, LPARAM lParam)
-{
- MessageWindowEventData *mwed = (MessageWindowEventData*)lParam;
- if (mwed->uType == MSG_WINDOW_EVT_OPEN) {
- DBCachedContact *cc = currDb->m_cache->GetCachedContact(mwed->hContact);
- if (cc != NULL) {
- Meta_UpdateSrmmIcon(cc, db_get_w(cc->contactID, META_PROTO, "Status", ID_STATUS_OFFLINE));
- if (cc->IsMeta()) {
- MetaSrmmData *p = new MetaSrmmData;
- p->m_hMeta = cc->contactID;
- p->m_hSub = db_mc_getMostOnline(cc->contactID);
- p->m_hWnd = mwed->hwndWindow;
- arMetaWindows.insert(p);
-
- if (p->m_hSub != db_mc_getDefault(cc->contactID))
- db_mc_setDefault(cc->contactID, p->m_hSub, false);
- }
- }
- }
- else if (mwed->uType == MSG_WINDOW_EVT_CLOSING) {
- for (int i = 0; i < arMetaWindows.getCount(); i++)
- if (arMetaWindows[i].m_hWnd == mwed->hwndWindow)
- arMetaWindows.remove(i);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// returns manually chosen sub in the meta window
-
-static INT_PTR Meta_SrmmCurrentSub(WPARAM hMeta, LPARAM lParam)
-{
- MetaSrmmData tmp = { hMeta };
- if (MetaSrmmData *p = arMetaWindows.find(&tmp))
- return p->m_hSub;
-
- return db_mc_getMostOnline(hMeta);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// we assume that it could be called only for the metacontacts
-
-static int Meta_SrmmIconClicked(WPARAM hMeta, LPARAM lParam)
-{
- StatusIconClickData *sicd = (StatusIconClickData*)lParam;
- if (mir_strcmp(sicd->szModule, META_PROTO))
- return 0;
-
- DBCachedContact *cc = CheckMeta(hMeta);
- if (cc == NULL)
- return 0;
-
- HMENU hMenu = CreatePopupMenu();
- int iDefault = Meta_GetContactNumber(cc, db_mc_getSrmmSub(cc->contactID));
-
- MENUITEMINFO mii = { sizeof(mii) };
- mii.fMask = MIIM_ID | MIIM_STATE | MIIM_STRING;
- for (int i = 0; i < cc->nSubs; i++) {
- char *szProto = GetContactProto(cc->pSubs[i]);
- if (szProto == NULL) continue;
-
- PROTOACCOUNT *pa = ProtoGetAccount(szProto);
- if (pa == NULL)
- continue;
-
- CMString tszNick;
- if (options.menu_contact_label == DNT_DID)
- tszNick = cli.pfnGetContactDisplayName(cc->pSubs[i], 0);
- else
- Meta_GetSubNick(hMeta, i, tszNick);
- tszNick.AppendFormat(_T(" [%s]"), pa->tszAccountName);
-
- mii.wID = i + 1;
- mii.fState = (i == iDefault) ? MFS_CHECKED : MFS_ENABLED;
- mii.dwTypeData = tszNick.GetBuffer();
- mii.cch = tszNick.GetLength();
- InsertMenuItem(hMenu, i, TRUE, &mii);
- }
-
- UINT res = TrackPopupMenu(hMenu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_BOTTOMALIGN | TPM_LEFTALIGN, sicd->clickLocation.x, sicd->clickLocation.y, 0, cli.hwndContactTree, NULL);
- if (res > 0) {
- MCONTACT hChosen = Meta_GetContactHandle(cc, res - 1);
-
- MetaSrmmData tmp = { cc->contactID };
- if (MetaSrmmData *p = arMetaWindows.find(&tmp))
- p->m_hSub = hChosen;
-
- db_mc_setDefault(cc->contactID, hChosen, true);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Called when all the plugin are loaded into Miranda.
-//
-// Initializes the 4 menus present in the context-menu
-
-int Meta_ModulesLoaded(WPARAM wParam, LPARAM lParam)
-{
- HookEvent(ME_CLIST_PREBUILDCONTACTMENU, Meta_ModifyMenu);
-
- // hook srmm window close/open events
- HookEvent(ME_MSG_WINDOWEVENT, Meta_MessageWindowEvent);
- HookEvent(ME_MSG_ICONPRESSED, Meta_SrmmIconClicked);
-
- // create menu items
- InitMenus();
-
- // create srmm icon
- StatusIconData sid = { sizeof(sid) };
- sid.szModule = META_PROTO;
- sid.flags = MBF_TCHAR;
- sid.tszTooltip = LPGENT("Select metacontact");
- sid.hIcon = LoadSkinnedProtoIcon(META_PROTO, ID_STATUS_ONLINE);
- Srmm_AddIcon(&sid);
- return 0;
-}
-
-static VOID CALLBACK sttMenuThread(PVOID param)
-{
- HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)param, 0);
-
- TPMPARAMS tpmp = { 0 };
- tpmp.cbSize = sizeof(tpmp);
- BOOL menuRet = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, menuMousePoint.x, menuMousePoint.y, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), &tpmp);
-
- CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuRet), MPCF_CONTACTMENU), (LPARAM)param);
-
- DestroyMenu(hMenu);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR Meta_ContactMenuFunc(WPARAM hMeta, LPARAM lParam)
-{
- DBCachedContact *cc = CheckMeta(hMeta);
- if (cc == NULL)
- return 0;
-
- MCONTACT hContact = Meta_GetContactHandle(cc, (int)lParam);
-
- if (options.menu_function == FT_MSG) {
- // open message window if protocol supports message sending or chat, else simulate double click
- char *proto = GetContactProto(hContact);
- if (proto) {
- INT_PTR caps = CallProtoService(proto, PS_GETCAPS, PFLAGNUM_1, 0);
- if ((caps & PF1_IMSEND) || (caps & PF1_CHAT)) {
- // set default contact for sending/status and open message window
- Meta_SetSrmmSub(hMeta, hContact);
- db_mc_setDefaultNum(hMeta, lParam, false);
- CallService(MS_MSG_SENDMESSAGET, hMeta, 0);
- }
- else // protocol does not support messaging - simulate double click
- CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0);
- }
- else // protocol does not support messaging - simulate double click
- CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0);
- }
- else if (options.menu_function == FT_MENU) // show contact's context menu
- CallFunctionAsync(sttMenuThread, (void*)hContact);
- else if (options.menu_function == FT_INFO) // show user info for subcontact
- CallService(MS_USERINFO_SHOWDIALOG, hContact, 0);
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// file transfer support - mostly not required, since subcontacts do the receiving
-
-INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam)
-{
- CCSDATA *ccs = (CCSDATA*)lParam;
- DBCachedContact *cc = CheckMeta(ccs->hContact);
- if (cc == NULL || cc->nDefault == -1)
- return 0;
-
- MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_FILESEND);
- if (!hMostOnline)
- return 0;
-
- char *proto = GetContactProto(hMostOnline);
- if (proto)
- return CallContactService(hMostOnline, PSS_FILE, ccs->wParam, ccs->lParam);
-
- return 0; // fail
-}
-
-INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam)
-{
- CCSDATA *ccs = (CCSDATA*)lParam;
- DBCachedContact *cc = CheckMeta(ccs->hContact);
- if (cc == NULL || cc->nDefault == -1)
- return 0;
-
- MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_MODEMSGRECV);
- if (!hMostOnline)
- return 0;
-
- char *proto = GetContactProto(hMostOnline);
- if (!proto)
- return 0;
-
- ccs->hContact = hMostOnline;
- return CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam);
-}
-
-INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam)
-{
- PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
- DBCachedContact *cc = CheckMeta(pai->hContact);
- if (cc == NULL)
- return GAIR_NOAVATAR;
-
- if (cc->nDefault == -1)
- return 0;
-
- MCONTACT hSub = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
- if (!hSub)
- return GAIR_NOAVATAR;
-
- char *proto = GetContactProto(hSub);
- if (!proto)
- return GAIR_NOAVATAR;
-
- pai->hContact = hSub;
- INT_PTR result = CallProtoService(proto, PS_GETAVATARINFO, wParam, lParam);
- pai->hContact = cc->contactID;
- if (result != CALLSERVICE_NOTFOUND)
- return result;
-
- return GAIR_NOAVATAR; // fail
-}
-
-INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam)
-{
- CCSDATA *ccs = (CCSDATA*)lParam;
-
- // This is a simple contact
- // (this should normally not happen, since linked contacts do not appear on the list.)
- DBCachedContact *cc = CheckMeta(ccs->hContact);
- if (cc == NULL || cc->nDefault == -1)
- return 0;
-
- MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS);
- if (!hMostOnline)
- return 0;
-
- char *proto = GetContactProto(hMostOnline);
- if (!proto)
- return 0;
-
- PROTO_AVATAR_INFORMATION ai;
- ai.hContact = ccs->hContact;
- ai.format = PA_FORMAT_UNKNOWN;
- _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE);
- if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS)
- db_set_ts(ccs->hContact, "ContactPhoto", "File", ai.filename);
-
- hMostOnline = Meta_GetMostOnline(cc);
- Meta_CopyContactNick(cc, hMostOnline);
-
- if (!hMostOnline)
- return 0;
-
- ccs->hContact = hMostOnline;
- if (!ProtoServiceExists(proto, PSS_GETINFO))
- return 0; // fail
-
- return CallContactService(ccs->hContact, PSS_GETINFO, ccs->wParam, ccs->lParam);
-}
-
-int Meta_CallMostOnline(WPARAM hContact, LPARAM lParam)
-{
- DBCachedContact *cc = CheckMeta(hContact);
- if (cc == NULL)
- return 0;
-
- Meta_CopyContactNick(cc, db_mc_getSrmmSub(cc->contactID));
- Meta_FixStatus(cc);
- return 0;
-}
-
-int Meta_PreShutdown(WPARAM wParam, LPARAM lParam)
-{
- Meta_SetStatus(ID_STATUS_OFFLINE, 0);
- Meta_SuppressStatus(FALSE);
- if (setStatusTimerId)
- KillTimer(0, setStatusTimerId);
- return 0;
-}
-
-INT_PTR MenuFunc(WPARAM wParam, LPARAM lParam, LPARAM param)
-{
- return Meta_ContactMenuFunc(wParam, param);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Initializes all services provided by the plugin
-//
-// Creates every function and hooks the event desired.
-
-void Meta_InitServices()
-{
- previousMode = mcStatus = ID_STATUS_OFFLINE;
-
- CreateServiceFunction("MetaContacts/Convert", Meta_Convert);
- CreateServiceFunction("MetaContacts/AddTo", Meta_AddTo);
- CreateServiceFunction("MetaContacts/Edit", Meta_Edit);
- CreateServiceFunction("MetaContacts/Delete", Meta_Delete);
- CreateServiceFunction("MetaContacts/Default", Meta_Default);
-
- // hidden contact menu items...ho hum
- for (int i = 0; i < MAX_CONTACTS; i++) {
- char szServiceName[100];
- mir_snprintf(szServiceName, SIZEOF(szServiceName), "MetaContacts/MenuFunc%d", i);
- CreateServiceFunctionParam(szServiceName, MenuFunc, i);
- }
-
- CreateProtoServiceFunction(META_PROTO, PS_GETCAPS, Meta_GetCaps);
- CreateProtoServiceFunction(META_PROTO, PS_GETNAME, Meta_GetName);
- CreateProtoServiceFunction(META_PROTO, PS_LOADICON, Meta_LoadIcon);
-
- CreateProtoServiceFunction(META_PROTO, PS_SETSTATUS, Meta_SetStatus);
-
- CreateProtoServiceFunction(META_PROTO, PS_GETSTATUS, Meta_GetStatus);
- CreateProtoServiceFunction(META_PROTO, PSS_MESSAGE, Meta_SendMessage);
-
- CreateProtoServiceFunction(META_PROTO, PSS_USERISTYPING, Meta_UserIsTyping);
-
- // file recv is done by subcontacts
- CreateProtoServiceFunction(META_PROTO, PSS_FILE, Meta_FileSend);
- CreateProtoServiceFunction(META_PROTO, PSS_GETAWAYMSG, Meta_GetAwayMsg);
- CreateProtoServiceFunction(META_PROTO, PS_GETAVATARINFO, Meta_GetAvatarInfo);
- CreateProtoServiceFunction(META_PROTO, PSS_GETINFO, Meta_GetInfo);
-
- // receive filter
- CreateProtoServiceFunction(META_FILTER, PSR_MESSAGE, MetaFilter_RecvMessage);
-
- // API services and events
- CreateApiServices();
-
- CreateServiceFunction("MetaContacts/OnOff", Meta_OnOff);
- CreateServiceFunction(MS_MC_GETSRMMSUB, Meta_SrmmCurrentSub);
-
- CreateProtoServiceFunction(META_PROTO, PS_SEND_NUDGE, Meta_SendNudge);
-
- // create our hookable events
- hSubcontactsChanged = CreateHookableEvent(ME_MC_SUBCONTACTSCHANGED);
-
- // hook other module events we need
- HookEvent(ME_PROTO_ACK, Meta_HandleACK);
- HookEvent(ME_DB_CONTACT_DELETED, Meta_ContactDeleted);
- HookEvent(ME_DB_CONTACT_SETTINGCHANGED, Meta_SettingChanged);
- HookEvent(ME_OPT_INITIALISE, Meta_OptInit);
- HookEvent(ME_SYSTEM_MODULESLOADED, Meta_ModulesLoaded);
- HookEvent(ME_SYSTEM_PRESHUTDOWN, Meta_PreShutdown);
-
- // hook our own events, used to call Meta_GetMostOnline which sets nick for metacontact
- HookEvent(ME_MC_DEFAULTTCHANGED, Meta_CallMostOnline);
-
- // redirect nudge events
- hEventNudge = CreateHookableEvent(META_PROTO "/Nudge");
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Destroy created events
-
-void Meta_CloseHandles()
-{
- DestroyHookableEvent(hSubcontactsChanged);
- DestroyHookableEvent(hEventNudge);
-}
|