示例#1
0
static int AwayMsgPreShutdown(WPARAM wParam, LPARAM lParam)
{
	if (hWindowList)
		WindowList_BroadcastAsync(hWindowList,WM_CLOSE,0,0);
	if (hWindowList2)
		WindowList_BroadcastAsync(hWindowList2,WM_CLOSE,0,0);
	return 0;
}
示例#2
0
int StopAccounts(HYAMNPROTOPLUGIN Plugin)
{
	HACCOUNT Finder;

//1. wait to get write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write wait\n");
#endif
	SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write enter\n");
#endif
	for (Finder=Plugin->FirstAccount;Finder != NULL;Finder=Finder->Next)
	{
//2. set stop signal 
		StopSignalFcn(Finder);
		WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_STOPACCOUNT,(WPARAM)Finder,0);
		if (Plugin->Fcn->StopAccountFcnPtr != NULL)
			Plugin->Fcn->StopAccountFcnPtr(Finder);
	}

//leave write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write done\n");
#endif
	SWMRGDoneWriting(Plugin->AccountBrowserSO);

//Now, account is stopped. It can be removed from memory...
	return 1;
}
示例#3
0
void CMsgTree::Save()
{
	if (MsgTreePage.GetModified()) {
		MsgTreePage.PageToMemToDB();
		WindowList_BroadcastAsync(hMTWindowList, UM_MSGTREE_UPDATE, 0, 0);
	}
}
示例#4
0
void WINAPI SetStatusFcn(HACCOUNT Which, TCHAR *Value)
{
	if (Which != NULL) {
		mir_cslock lck(csAccountStatusCS);
		mir_tstrcpy(Which->Status, Value);
	}

	WindowList_BroadcastAsync(YAMNVar.MessageWnds, WM_YAMN_CHANGESTATUS, (WPARAM)Which, 0);
}
示例#5
0
static int ClcProtoAck(WPARAM, LPARAM lParam)
{
	ACKDATA *ack = (ACKDATA *) lParam;
	if (ack->type == ACKTYPE_STATUS) {
		WindowList_BroadcastAsync(hClcWindowList, INTM_INVALIDATE, 0, 0);
		if (ack->result == ACKRESULT_SUCCESS) {
			for (int i=0; i < cli.hClcProtoCount; i++) {
				if (!mir_strcmp(cli.clcProto[i].szProto, ack->szModule)) {
					cli.clcProto[i].dwStatus = (WORD) ack->lParam;
					break;
				}
			}
		}
	}
	return 0;
}
示例#6
0
void WINAPI SetStatusFcn(HACCOUNT Which,TCHAR *Value)
{
	if (Which==NULL)
		return;

#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"\tSetStatus:AccountStatusCS-cs wait\n");
#endif
	EnterCriticalSection(&AccountStatusCS);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"\tSetStatus:AccountStatusCS-cs enter\n");
#endif
	lstrcpy(Which->Status,Value);
	WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_CHANGESTATUS,(WPARAM)Which,0);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"\tSetStatus:AccountStatusCS-cs done\n");
#endif
	LeaveCriticalSection(&AccountStatusCS);
}
示例#7
0
void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD)
{
	PYAMN_PROTOPLUGINQUEUE ActualPlugin;
	HACCOUNT ActualAccount;
	HANDLE ThreadRunningEV;
	DWORD Status, tid;

//	we use event to signal, that running thread has all needed stack parameters copied
	if (NULL==(ThreadRunningEV=CreateEvent(NULL, FALSE, FALSE, NULL)))
		return;
//	if we want to close miranda, we get event and do not run checking anymore
	if (WAIT_OBJECT_0==WaitForSingleObject(ExitEV, 0))
		return;
//	Get actual status of current user in Miranda
		Status=CallService(MS_CLIST_GETSTATUSMODE, 0, 0);

	EnterCriticalSection(&PluginRegCS);
	for (ActualPlugin=FirstProtoPlugin;ActualPlugin != NULL;ActualPlugin=ActualPlugin->Next)
	{
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile, "TimerProc:AccountBrowserSO-read wait\n");
#endif
		if (WAIT_OBJECT_0 != SWMRGWaitToRead(ActualPlugin->Plugin->AccountBrowserSO, 0))			//we want to access accounts immiadtelly
		{
#ifdef DEBUG_SYNCHRO
			DebugLog(SynchroFile, "TimerProc:AccountBrowserSO-read enter failed\n");
#endif
			LeaveCriticalSection(&PluginRegCS);
			return;
		}
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile, "TimerProc:AccountBrowserSO-read enter\n");
#endif
		for (ActualAccount=ActualPlugin->Plugin->FirstAccount;ActualAccount != NULL;ActualAccount=ActualAccount->Next)
		{
			if (ActualAccount->Plugin==NULL || ActualAccount->Plugin->Fcn==NULL)		//account not inited
				continue;
#ifdef DEBUG_SYNCHRO
			DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read wait\n");
#endif
			if (WAIT_OBJECT_0 != SWMRGWaitToRead(ActualAccount->AccountAccessSO, 0))
			{
#ifdef DEBUG_SYNCHRO
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read wait failed\n");
#endif
				continue;
			}
#ifdef DEBUG_SYNCHRO

			switch(Status)
			{
			case ID_STATUS_OFFLINE:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status offline\n");
				break;
			case ID_STATUS_ONLINE:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status online\n");
				break;
			case ID_STATUS_AWAY:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status away\n");
				break;
			case ID_STATUS_DND:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status dnd\n");
				break;
			case ID_STATUS_NA:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status na\n");
				break;
			case ID_STATUS_OCCUPIED:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status occupied\n");
				break;
			case ID_STATUS_FREECHAT:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status freechat\n");
				break;
			case ID_STATUS_INVISIBLE:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status invisible\n");
				break;
			case ID_STATUS_ONTHEPHONE:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status onthephone\n");
				break;
			case ID_STATUS_OUTTOLUNCH:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status outtolunch\n");
				break;
			default:
				DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read enter status unknown\n");
				break;
			}
#endif
			BOOL isAccountCounting = 0;
			if (
				(ActualAccount->Flags & YAMN_ACC_ENA) &&
				(((ActualAccount->StatusFlags & YAMN_ACC_ST0) && (Status<=ID_STATUS_OFFLINE)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST1) && (Status==ID_STATUS_ONLINE)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST2) && (Status==ID_STATUS_AWAY)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST3) && (Status==ID_STATUS_DND)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST4) && (Status==ID_STATUS_NA)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST5) && (Status==ID_STATUS_OCCUPIED)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST6) && (Status==ID_STATUS_FREECHAT)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST7) && (Status==ID_STATUS_INVISIBLE)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST8) && (Status==ID_STATUS_ONTHEPHONE)) ||
				((ActualAccount->StatusFlags & YAMN_ACC_ST9) && (Status==ID_STATUS_OUTTOLUNCH))))
			{

				if ((!ActualAccount->Interval && !ActualAccount->TimeLeft) || ActualAccount->Plugin->Fcn->TimeoutFcnPtr==NULL)
				{
					goto ChangeIsCountingStatusLabel;
				}
				if (ActualAccount->TimeLeft) {
					ActualAccount->TimeLeft--;
					isAccountCounting = TRUE;
				}
#ifdef DEBUG_SYNCHRO
					DebugLog(SynchroFile, "TimerProc:time left : %i\n", ActualAccount->TimeLeft);
#endif
				WindowList_BroadcastAsync(YAMNVar.MessageWnds, WM_YAMN_CHANGETIME, (WPARAM)ActualAccount, (LPARAM)ActualAccount->TimeLeft);
				if (!ActualAccount->TimeLeft)
				{
					struct CheckParam ParamToPlugin={YAMN_CHECKVERSION, ThreadRunningEV, ActualAccount, YAMN_NORMALCHECK, (void *)0, NULL};
					HANDLE NewThread;

					ActualAccount->TimeLeft=ActualAccount->Interval;
					if (NULL==(NewThread=CreateThread(NULL, 0, (YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->TimeoutFcnPtr, &ParamToPlugin, 0, &tid)))
					{
#ifdef DEBUG_SYNCHRO
						DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read done\n");
#endif
						ReadDoneFcn(ActualAccount->AccountAccessSO);
						continue;
					}
					else
					{
						WaitForSingleObject(ThreadRunningEV, INFINITE);
						CloseHandle(NewThread);
					}
				}

			}
ChangeIsCountingStatusLabel:
#ifdef DEBUG_SYNCHRO
			DebugLog(SynchroFile, "TimerProc:ActualAccountSO-read done\n");
#endif
			if (((ActualAccount->isCounting) != 0) != isAccountCounting) {
				ActualAccount->isCounting=isAccountCounting;
				WORD cStatus = db_get_w(ActualAccount->hContact, YAMN_DBMODULE, "Status", 0);
				switch (cStatus) {
					case ID_STATUS_ONLINE:
					case ID_STATUS_OFFLINE:
						db_set_w(ActualAccount->hContact, YAMN_DBMODULE, "Status", isAccountCounting?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
					default: break;
				}
			}
			ReadDoneFcn(ActualAccount->AccountAccessSO);
		}
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile, "TimerProc:AccountBrowserSO-read done\n");
#endif
		SWMRGDoneReading(ActualPlugin->Plugin->AccountBrowserSO);
	}
	LeaveCriticalSection(&PluginRegCS);
	CloseHandle(ThreadRunningEV);
	return;
}
示例#8
0
/*
int FindPluginAccount(WPARAM wParam,LPARAM lParam)
{
	HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
	HACCOUNT Finder=(HACCOUNT)lParam;

	if (Finder=NULL)	Finder=Plugin->FirstAccount;

//	for (;Finder != NULL && Finder->PluginID != Plugin->PluginInfo->PluginID;Finder=(HACCOUNT)Finder->Next);
	return (int)Finder;
}
*/
INT_PTR DeleteAccountSvc(WPARAM wParam,LPARAM lParam)
{
//Deleting account works on these steps:
//1. set signal that account should stop activity (set event)
//	setting this event we achieve, that any access to account is failed,
//	so threads do not start any work with accounts (better saying threads of plugins should not start)
//2. wait to get write access to chained list of accounts
//3. we can write to chained list, so we change chain not to show to actual account
//	now, any thread browsing list of accounts does not browse through actual account
//	actual account seems to be hidden (it exists, but it is not in accounts chained list (chained list=queue))
//Now, we should delete account from memory, BUT!!!
//	Any thread can still be waked up and start asking account synchronizing object
//	If account is deleted, asking about access to read account can throw memory exception (reading for
//	a synchronizing object from memory, that was deleted)
//So, we cannot now delete account. We have to wait until we are sure no thread will be using account anymore
//	(or to the end of Miranda, but problem is in allocated memory- it is allocated and Miranda is SMALLER, faster, easier, isn't it?)
//	This deleting is achieved in 2 ways:
//	We have event in UsingThreads synchronization objects. This event signals that no thread will use actual account
//	1. Any thread using account first increment UsingThread, so we know that account is used
//	2. If thread is about to close, it should decrement UsingThread
//	3. If thread creates another thread, that will use account, caller has to wait until the new thread does not
//		increment UsingThreads (imagine that caller ends before the new thread set it: if no other thread is using
//		account, account is automaticaly (decreasing UsingThreads) signaled as "not used" and we delete it. But then
//		new thread is going to read account...).
//4. wait until UsingThread Event is signaled
//5. delete account from memory

	HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
	HACCOUNT Which=(HACCOUNT)lParam;
	HACCOUNT Finder;
	DWORD tid;

//1. set stop signal 
	StopSignalFcn(Which);
	WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_STOPACCOUNT,(WPARAM)Which,0);
	if (Plugin->Fcn->StopAccountFcnPtr != NULL)
		Plugin->Fcn->StopAccountFcnPtr(Which);

//2. wait to get write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write wait\n");
#endif
	SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write enter\n");
#endif

//3. remove from queue (chained list)
	if (Plugin->FirstAccount==NULL)
	{
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write done\n");
#endif
		SWMRGDoneWriting(Plugin->AccountBrowserSO);
		return 0;
	}
	if (Plugin->FirstAccount==Which)
	{
		Finder=Plugin->FirstAccount->Next;
		Plugin->FirstAccount=Finder;
	}
	else
	{
		for (Finder=Plugin->FirstAccount;Which != Finder->Next;Finder=Finder->Next);
		Finder->Next=Finder->Next->Next;
	}
//leave write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write done\n");
#endif
	SWMRGDoneWriting(Plugin->AccountBrowserSO);

//4. wait while event "UsingThread" is not signaled
//	And what to do, if this event will be signaled in 1 hour? (Although it's paranoia, because we have sent "delete signal", so
//	other threads do not start any new work with actual account) We will wait in blocked state?
//	No, of course not. We will create new thread, that will wait and additionally remove our thread in background.
//5. So, the last point (deleting from memory) is performed in new DeleteAccountInBackground thread

	if ((Plugin->Fcn != NULL) && (Plugin->Fcn->WriteAccountsFcnPtr != NULL))
			Plugin->Fcn->WriteAccountsFcnPtr();
	CloseHandle(CreateThread(NULL,0,DeleteAccountInBackground,(LPVOID)Which,0,&tid));

//Now, plugin can consider account as deleted, but plugin really can achieve deleting this account from memory when using
//event UsingThreads.
	return 1;
}
示例#9
0
int PreShutdownHistoryModule(WPARAM, LPARAM)
{
	if (hWindowList)
		WindowList_BroadcastAsync(hWindowList,WM_DESTROY,0,0);
	return 0;
}
示例#10
0
static int OnIconLibIconChanged(WPARAM, LPARAM)
{
	WindowList_BroadcastAsync(hButtonWindowList, MBM_REFRESHICOLIBICON, 0, 0);
	return 0;
}
示例#11
0
static int ClcIconsChanged(WPARAM, LPARAM)
{
	WindowList_BroadcastAsync(hClcWindowList, INTM_INVALIDATE, 0, 0);
	return 0;
}
示例#12
0
static int ClcContactIconChanged(WPARAM wParam, LPARAM lParam)
{
	WindowList_BroadcastAsync(hClcWindowList, INTM_ICONCHANGED, wParam, lParam);
	return 0;
}
示例#13
0
static int ClcContactDeleted(WPARAM wParam, LPARAM lParam)
{
	WindowList_BroadcastAsync(hClcWindowList, INTM_CONTACTDELETED, wParam, lParam);
	return 0;
}
示例#14
0
int Buttons_OnSkinModeSettingsChanged(WPARAM, LPARAM)
{
	WindowList_BroadcastAsync(hButtonWindowList, MBM_UPDATETRANSPARENTFLAG, 0, 2);
	return 0;
}
示例#15
0
文件: mim.cpp 项目: 0xmono/miranda-ng
void CMimAPI::BroadcastMessageAsync(UINT msg, WPARAM wParam, LPARAM lParam)
{
	WindowList_BroadcastAsync(m_hMessageWindowList, msg, wParam, lParam);
}
示例#16
0
int PreshutdownSendRecv(WPARAM wParam, LPARAM lParam)
{
	WindowList_BroadcastAsync(g_dat->hMessageWindowList, WM_CLOSE, 0, 0);
	return 0;
}
示例#17
0
static int AwayMsgPreShutdown(WPARAM, LPARAM)
{
	if (hWindowList) WindowList_BroadcastAsync(hWindowList,WM_CLOSE,0,0);
	return 0;
}