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_sync.cpp | 147 +++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 plugins/Clist_modern/src/modern_sync.cpp (limited to 'plugins/Clist_modern/src/modern_sync.cpp') diff --git a/plugins/Clist_modern/src/modern_sync.cpp b/plugins/Clist_modern/src/modern_sync.cpp new file mode 100644 index 0000000000..df3572766e --- /dev/null +++ b/plugins/Clist_modern/src/modern_sync.cpp @@ -0,0 +1,147 @@ +#include "hdr/modern_commonheaders.h" +#include "hdr/modern_sync.h" + +struct SYNCCALLITEM +{ + WPARAM wParam; + LPARAM lParam; + int nResult; + HANDLE hDoneEvent; + PSYNCCALLBACKPROC pfnProc; +}; + +static void CALLBACK _SyncCallerUserAPCProc(void* param) +{ + SYNCCALLITEM* item = (SYNCCALLITEM*)param; + item->nResult = item->pfnProc(item->wParam, item->lParam); + SetEvent(item->hDoneEvent); +} + +static INT_PTR SyncCaller(WPARAM proc, LPARAM lParam) +{ + typedef int (*P0PARAMFUNC)(); + typedef int (*P1PARAMFUNC)(WPARAM); + typedef int (*P2PARAMFUNC)(WPARAM, LPARAM); + typedef int (*P3PARAMFUNC)(WPARAM, LPARAM, LPARAM); + typedef int (*P4PARAMFUNC)(WPARAM, LPARAM, LPARAM, LPARAM); + + LPARAM * params = (LPARAM *)lParam; + int count = params[0]; + switch (count) { + case 0: + return ((P0PARAMFUNC)proc)(); + + case 1: + return ((P1PARAMFUNC)proc)((WPARAM)params[1]); + + case 2: + return ((P2PARAMFUNC)proc)((WPARAM)params[1],(LPARAM)params[2]); + + case 3: + return ((P3PARAMFUNC)proc)((WPARAM)params[1],(LPARAM)params[2], (LPARAM)params[3]); + + case 4: + return ((P4PARAMFUNC)proc)((WPARAM)params[1],(LPARAM)params[2], (LPARAM)params[3], (LPARAM)params[4]); + } + return 0; +} + +int SyncCall(void * vproc, int count, ... ) +{ + LPARAM params[5]; + va_list va; + int i; + params[0] = (LPARAM)count; + va_start(va, count); + for (i=0; i < count && i < SIZEOF(params)-1; i++) + params[i+1] = va_arg(va,LPARAM); + + va_end(va); + return SyncCallProxy(SyncCaller, (WPARAM)vproc, (LPARAM) params); +} + +int SyncCallProxy(PSYNCCALLBACKPROC pfnProc, WPARAM wParam, LPARAM lParam, CRITICAL_SECTION * cs /*= NULL */) +{ + SYNCCALLITEM item = {0}; + + int nReturn = 0; + + if ( cs != NULL ) { + if ( !fnTryEnterCriticalSection ) { // for poor OSes like Win98 + EnterCriticalSection( cs ); + int result = pfnProc( wParam, lParam ); + LeaveCriticalSection( cs ); + return result; + } + + if ( fnTryEnterCriticalSection( cs )) { //simple call (Fastest) + int result = pfnProc(wParam,lParam); + LeaveCriticalSection( cs ); + return result; + } + else { //Window SendMessage Call(Middle) + if ( SyncCallWinProcProxy( pfnProc, wParam, lParam, nReturn ) == S_OK) + return nReturn; + } + } + if ( SyncCallAPCProxy( pfnProc, wParam, lParam, nReturn ) == S_OK) + return nReturn; + + return NULL; +} + +HRESULT SyncCallWinProcProxy( PSYNCCALLBACKPROC pfnProc, WPARAM wParam, LPARAM lParam, int& nReturn ) +{ + nReturn = 0; + if (pcli->hwndContactList == NULL ) + return E_FAIL; + + SYNCCALLITEM item = {0}; + item.wParam = wParam; + item.lParam = lParam; + item.pfnProc = pfnProc; + nReturn = SendMessage(pcli->hwndContactList, UM_SYNCCALL, (WPARAM)&item,0); + return S_OK; +} + +HRESULT SyncCallAPCProxy( PSYNCCALLBACKPROC pfnProc, WPARAM wParam, LPARAM lParam, int& hReturn ) +{ + hReturn = 0; + + if (pfnProc == NULL) + return E_FAIL; + + if (GetCurrentThreadId() != g_dwMainThreadID) { + SYNCCALLITEM item = {0}; + item.wParam = wParam; + item.lParam = lParam; + item.pfnProc = pfnProc; + item.hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + CallFunctionAsync(_SyncCallerUserAPCProc, &item); + + WaitForSingleObject(item.hDoneEvent, INFINITE); + CloseHandle(item.hDoneEvent); + + hReturn = item.nResult; + + return S_OK; + } + /* else */ + + hReturn = pfnProc(wParam, lParam); + return S_OK; +} + +LRESULT SyncOnWndProcCall( WPARAM wParam ) +{ + SYNCCALLITEM *psci = (SYNCCALLITEM *)wParam; + if (psci) + return psci->pfnProc( psci->wParam, psci->lParam ); + return 0; +} + +int DoCall( PSYNCCALLBACKPROC pfnProc, WPARAM wParam, LPARAM lParam ) +{ + return SyncCallProxy( pfnProc, 0, lParam ); +} -- cgit v1.2.3