summaryrefslogtreecommitdiff
path: root/plugins/Clist_modern/src/modern_sync.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-13 07:39:26 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-13 07:39:26 +0000
commit2ab468f0ac05d1f257fbf8aa6add9512eabbcc20 (patch)
tree7eb6482089b07994ae77d264e120f3e7772c2fd6 /plugins/Clist_modern/src/modern_sync.cpp
parentccb4003b6178f4c195350ae29896fdd442412af4 (diff)
Clist_modern: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@939 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Clist_modern/src/modern_sync.cpp')
-rw-r--r--plugins/Clist_modern/src/modern_sync.cpp147
1 files changed, 147 insertions, 0 deletions
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 );
+}