summaryrefslogtreecommitdiff
path: root/plugins/Modernb/modern_sync.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:10:43 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-05-18 22:10:43 +0000
commit725f68b6808a8a30778f58223fac75386f082785 (patch)
treeccba410760749d45139e5e78fd5e08f416ade1a0 /plugins/Modernb/modern_sync.cpp
parentf920ef497f3299ae24fe783ce03bdd93b419f764 (diff)
plugins folders renaming
git-svn-id: http://svn.miranda-ng.org/main/trunk@61 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Modernb/modern_sync.cpp')
-rw-r--r--plugins/Modernb/modern_sync.cpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/plugins/Modernb/modern_sync.cpp b/plugins/Modernb/modern_sync.cpp
new file mode 100644
index 0000000000..1941b376f2
--- /dev/null
+++ b/plugins/Modernb/modern_sync.cpp
@@ -0,0 +1,172 @@
+#include "hdr/modern_commonheaders.h"
+#include "hdr/modern_sync.h"
+
+typedef struct tagSYNCCALLITEM
+{
+ WPARAM wParam;
+ LPARAM lParam;
+ int nResult;
+ HANDLE hDoneEvent;
+ PSYNCCALLBACKPROC pfnProc;
+} SYNCCALLITEM;
+static void CALLBACK _SyncCallerUserAPCProc(ULONG_PTR dwParam)
+{
+ SYNCCALLITEM* item = (SYNCCALLITEM*) dwParam;
+ 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:
+ {
+ P0PARAMFUNC pfnProc=(P0PARAMFUNC)proc;
+ return pfnProc();
+ }
+ case 1:
+ {
+ P1PARAMFUNC pfnProc=(P1PARAMFUNC)proc;
+ return pfnProc((WPARAM)params[1]);
+ }
+ case 2:
+ {
+ P2PARAMFUNC pfnProc=(P2PARAMFUNC)proc;
+ return pfnProc((WPARAM)params[1],(LPARAM)params[2]);
+ }
+ case 3:
+ {
+ P3PARAMFUNC pfnProc=(P3PARAMFUNC)proc;
+ return pfnProc((WPARAM)params[1],(LPARAM)params[2], (LPARAM)params[3]);
+ }
+ case 4:
+ {
+ P4PARAMFUNC pfnProc=(P4PARAMFUNC)proc;
+ return pfnProc((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 (g_hMainThread==NULL || pfnProc==NULL)
+ return E_FAIL;
+
+ SYNCCALLITEM item={0};
+
+ if (GetCurrentThreadId()!=g_dwMainThreadID)
+ {
+ item.wParam = wParam;
+ item.lParam = lParam;
+ item.pfnProc = pfnProc;
+ item.hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ QueueUserAPC(_SyncCallerUserAPCProc, g_hMainThread, (ULONG_PTR) &item);
+ PostMessage(pcli->hwndContactList,WM_NULL,0,0); // let this get processed in its own time
+
+ 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 );
+}
+