From 2ab468f0ac05d1f257fbf8aa6add9512eabbcc20 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 13 Jul 2012 07:39:26 +0000 Subject: Clist_modern: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@939 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Clist_modern/src/modern_awaymsg.cpp | 232 ++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 plugins/Clist_modern/src/modern_awaymsg.cpp (limited to 'plugins/Clist_modern/src/modern_awaymsg.cpp') diff --git a/plugins/Clist_modern/src/modern_awaymsg.cpp b/plugins/Clist_modern/src/modern_awaymsg.cpp new file mode 100644 index 0000000000..342b3eefad --- /dev/null +++ b/plugins/Clist_modern/src/modern_awaymsg.cpp @@ -0,0 +1,232 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2008 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. + +*/ + +/* +* Author Artem Shpynov aka FYR +* Copyright 2000-2008 Artem Shpynov +*/ + +////////////////////////////////////////////////////////////////////////// +// Module to Request Away Messages + +#include "hdr/modern_commonheaders.h" +#include "hdr/modern_awaymsg.h" +#include "newpluginapi.h" +#include "hdr/modern_sync.h" + +#define AMASKPERIOD 3000 +#define amlock EnterCriticalSection(&amLockChain) +#define amunlock LeaveCriticalSection(&amLockChain) + +typedef struct _tag_amChainItem { + HANDLE hContact; + _tag_amChainItem *Next; +} AMCHAINITEM; + +static AMCHAINITEM * amFirstChainItem = NULL; +static AMCHAINITEM * amLastChainItem = NULL; +static CRITICAL_SECTION amLockChain; +static HANDLE hamProcessEvent = NULL; +static DWORD amRequestTick = 0; + + +static int amAddHandleToChain(HANDLE hContact); +static HANDLE amGetCurrentChain(); +static int amThreadProc(HWND hwnd); + +/* +* Add contact handle to requests queue +*/ +static int amAddHandleToChain(HANDLE hContact) +{ + AMCHAINITEM * workChain; + amlock; + { + //check that handle is present + AMCHAINITEM * wChain; + wChain = amFirstChainItem; + if (wChain) + do { + if (wChain->hContact == hContact) + { + amunlock; + return 0; + } + } while(wChain = (AMCHAINITEM *)wChain->Next); + } + if ( !amFirstChainItem) + { + amFirstChainItem = (AMCHAINITEM*)malloc(sizeof(AMCHAINITEM)); + workChain = amFirstChainItem; + } + else + { + amLastChainItem->Next = (AMCHAINITEM*)malloc(sizeof(AMCHAINITEM)); + workChain = (AMCHAINITEM *)amLastChainItem->Next; + } + amLastChainItem = workChain; + workChain->Next = NULL; + workChain->hContact = hContact; + amunlock; + SetEvent(hamProcessEvent); + return 1; +} + + +/* +* Gets handle from queue for request +*/ +static HANDLE amGetCurrentChain() +{ + AMCHAINITEM * workChain; + HANDLE res = NULL; + amlock; + if (amFirstChainItem) + { + res = amFirstChainItem->hContact; + workChain = amFirstChainItem->Next; + free(amFirstChainItem); + amFirstChainItem = (AMCHAINITEM *)workChain; + } + amunlock; + return res; +} + +/* +* Tread sub to ask protocol to retrieve away message +*/ +static int amThreadProc(HWND hwnd) +{ + DWORD time; + HANDLE hContact; + HANDLE ACK = 0; + displayNameCacheEntry dnce; + memset( &dnce, 0, sizeof(dnce)); + + while (!MirandaExiting()) + { + hContact = amGetCurrentChain(); + while (hContact) + { + time = GetTickCount(); + if ((time-amRequestTick) < AMASKPERIOD) + { + SleepEx(AMASKPERIOD-(time-amRequestTick)+10,TRUE); + if (MirandaExiting()) + { + g_dwAwayMsgThreadID = 0; + return 0; + } + } + CListSettings_FreeCacheItemData(&dnce); + dnce.hContact = (HANDLE)hContact; + Sync(CLUI_SyncGetPDNCE, (WPARAM) 0,(LPARAM)&dnce); + if (dnce.ApparentMode != ID_STATUS_OFFLINE) //don't ask if contact is always invisible (should be done with protocol) + ACK = (HANDLE)CallContactService(hContact,PSS_GETAWAYMSG,0,0); + if ( !ACK) + { + ACKDATA ack; + ack.hContact = hContact; + ack.type = ACKTYPE_AWAYMSG; + ack.result = ACKRESULT_FAILED; + if (dnce.m_cache_cszProto) + ack.szModule = dnce.m_cache_cszProto; + else + ack.szModule = NULL; + ClcDoProtoAck(hContact, &ack); + } + CListSettings_FreeCacheItemData(&dnce); + amRequestTick = time; + hContact = amGetCurrentChain(); + if (hContact) + { + DWORD i=0; + do + { + i++; + SleepEx(50,TRUE); + } while (i < AMASKPERIOD/50 && !MirandaExiting()); + } + else break; + if (MirandaExiting()) + { + g_dwAwayMsgThreadID = 0; + return 0; + } + } + WaitForSingleObjectEx(hamProcessEvent, INFINITE, TRUE); + ResetEvent(hamProcessEvent); + if (MirandaExiting()) + { + g_dwAwayMsgThreadID = 0; + return 0; + } + } + g_dwAwayMsgThreadID = 0; + return 1; +} + +BOOL amWakeThread() +{ + if (hamProcessEvent && g_dwAwayMsgThreadID) + { + SetEvent(hamProcessEvent); + + return TRUE; + } + + return FALSE; +} + +/* +* Sub to be called outside on status changing to retrieve away message +*/ +void amRequestAwayMsg(HANDLE hContact) +{ + char *szProto; + if ( !g_CluiData.bInternalAwayMsgDiscovery || !hContact) + return; + //Do not re-ask for chat rooms + szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (szProto == NULL || db_get_b(hContact, szProto, "ChatRoom", 0) != 0) + return; + amAddHandleToChain(hContact); +} + +void InitAwayMsgModule() +{ + InitializeCriticalSection(&amLockChain); + hamProcessEvent = CreateEvent(NULL,FALSE,FALSE,NULL); + g_dwAwayMsgThreadID = (DWORD)mir_forkthread((pThreadFunc)amThreadProc,0); +} + +void UninitAwayMsgModule() +{ + SetEvent(hamProcessEvent); + CloseHandle(hamProcessEvent); + amlock; + while (amGetCurrentChain()); + amunlock; + DeleteCriticalSection(&amLockChain); +} -- cgit v1.2.3