summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-05-10 21:45:21 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-05-10 21:45:21 +0300
commitad9b7e867404e4c2d14153a2d5c63007338101e4 (patch)
tree2817d07cbabe4b13e6d41fe9fc540800cd7527d6 /src
parentd19032779296481ece089c77a2c180a4f383b788 (diff)
Windows-specific code moved from mir_app to mir_core
Diffstat (limited to 'src')
-rw-r--r--src/mir_app/src/CMPluginBase.cpp2
-rw-r--r--src/mir_app/src/ei_services.cpp2
-rw-r--r--src/mir_app/src/mir_app.def3
-rw-r--r--src/mir_app/src/mir_app64.def3
-rw-r--r--src/mir_app/src/miranda.cpp203
-rw-r--r--src/mir_app/src/miranda.h7
-rw-r--r--src/mir_app/src/newplugins.cpp8
-rw-r--r--src/mir_app/src/options.cpp2
-rw-r--r--src/mir_app/src/pluginopts.cpp2
-rw-r--r--src/mir_app/src/stdafx.h4
-rw-r--r--src/mir_core/src/Windows/miranda.cpp221
-rw-r--r--src/mir_core/src/mir_core.def10
-rw-r--r--src/mir_core/src/mir_core64.def10
-rw-r--r--src/mir_core/src/miranda.h9
-rw-r--r--src/mir_core/src/modules.cpp13
-rw-r--r--src/mir_core/src/stdafx.h4
16 files changed, 279 insertions, 224 deletions
diff --git a/src/mir_app/src/CMPluginBase.cpp b/src/mir_app/src/CMPluginBase.cpp
index 9ec679553d..d22d410f41 100644
--- a/src/mir_app/src/CMPluginBase.cpp
+++ b/src/mir_app/src/CMPluginBase.cpp
@@ -101,7 +101,7 @@ MIR_APP_DLL(CMPluginBase&) GetPluginByInstance(HINSTANCE hInst)
static void wipePluginData(CMPluginBase *pPlugin)
{
- if (g_bMirandaTerminated)
+ if (Miranda_IsTerminated())
return;
KillModuleMenus(pPlugin);
diff --git a/src/mir_app/src/ei_services.cpp b/src/mir_app/src/ei_services.cpp
index 56e3d22b15..fa6bbd21e1 100644
--- a/src/mir_app/src/ei_services.cpp
+++ b/src/mir_app/src/ei_services.cpp
@@ -179,7 +179,7 @@ static void ResetSlots(BaseExtraIcon *extra, ExtraIconGroup *group, int iOldSlot
for (auto &hContact : Contacts())
Clist_SetExtraIcon(hContact, i, INVALID_HANDLE_VALUE);
- if (!g_bMirandaTerminated) {
+ if (!Miranda_IsTerminated()) {
Clist_InitAutoRebuild(g_clistApi.hwndContactTree);
eiOptionsRefresh();
}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index a647bd99eb..9cec7e4a5c 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -269,8 +269,6 @@ Srmm_RedrawToolbarIcons @338
Srmm_GetNthButton @339
Srmm_GetButtonCount @340
Srmm_ClickToolbarIcon @341
-Miranda_WaitOnHandle @342
-Miranda_IsTerminated @343
Miranda_OkToExit @344
Miranda_GetVersion @345
Miranda_GetFileVersion @346
@@ -687,7 +685,6 @@ ImageList_AddSkinIcon @774
Clist_GetGroup @775
Clist_SetGroup @776
?ReportSelfAvatarChanged@PROTO_INTERFACE@@QAEXXZ @777 NONAME
-Miranda_GetIdle @778 NONAME
Ignore_Allow @779
Ignore_Ignore @780
Ignore_IsIgnored @781
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index d9a6785125..f168a206af 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -269,8 +269,6 @@ Srmm_RedrawToolbarIcons @338
Srmm_GetNthButton @339
Srmm_GetButtonCount @340
Srmm_ClickToolbarIcon @341
-Miranda_WaitOnHandle @342
-Miranda_IsTerminated @343
Miranda_OkToExit @344
Miranda_GetVersion @345
Miranda_GetFileVersion @346
@@ -687,7 +685,6 @@ ImageList_AddSkinIcon @774
Clist_GetGroup @775
Clist_SetGroup @776
?ReportSelfAvatarChanged@PROTO_INTERFACE@@QEAAXXZ @777 NONAME
-Miranda_GetIdle @778 NONAME
Ignore_Allow @779
Ignore_Ignore @780
Ignore_IsIgnored @781
diff --git a/src/mir_app/src/miranda.cpp b/src/mir_app/src/miranda.cpp
index ab95ae30a2..12c4d64c69 100644
--- a/src/mir_app/src/miranda.cpp
+++ b/src/mir_app/src/miranda.cpp
@@ -36,16 +36,9 @@ int LoadDefaultModules(void);
void UnloadNewPluginsModule(void);
void UnloadDefaultModules(void);
-typedef HRESULT(STDAPICALLTYPE* pfnBufferedPaintInit)(void);
-pfnBufferedPaintInit bufferedPaintInit;
-
-typedef HRESULT(STDAPICALLTYPE* pfnBufferedPaintUninit)(void);
-pfnBufferedPaintUninit bufferedPaintUninit;
-
HANDLE hOkToExitEvent, hModulesLoadedEvent;
-HANDLE hShutdownEvent, hPreShutdownEvent;
uint32_t hMainThreadId;
-bool g_bModulesLoadedFired = false, g_bMirandaTerminated = false;
+bool g_bModulesLoadedFired = false;
int g_iIconX, g_iIconY, g_iIconSX, g_iIconSY;
CMPlugin g_plugin;
@@ -69,57 +62,6 @@ CMPlugin::CMPlugin() :
{}
/////////////////////////////////////////////////////////////////////////////////////////
-
-struct MWaitableObject
-{
- MWaitableObject(MWaitableStub pFunc, HANDLE hEvent) :
- m_bOwnsEvent(false),
- m_hEvent(hEvent),
- m_pFunc(pFunc),
- m_pInfo(INVALID_HANDLE_VALUE)
- {
- if (hEvent == nullptr) {
- m_hEvent = CreateEvent(nullptr, TRUE, TRUE, nullptr);
- m_bOwnsEvent = true;
- }
- }
-
- MWaitableObject(MWaitableStubEx pFunc, void *pInfo) :
- m_bOwnsEvent(true),
- m_hEvent(CreateEvent(nullptr, TRUE, TRUE, nullptr)),
- m_pFuncEx(pFunc),
- m_pInfo(pInfo)
- {}
-
- ~MWaitableObject()
- {
- if (m_bOwnsEvent)
- ::CloseHandle(m_hEvent);
- }
-
- HANDLE m_hEvent;
- union {
- MWaitableStub m_pFunc;
- MWaitableStubEx m_pFuncEx;
- };
- void *m_pInfo;
-
- bool m_bOwnsEvent;
-};
-
-static OBJLIST<MWaitableObject> arWaitableObjects(1, HandleKeySortT);
-
-MIR_APP_DLL(void) Miranda_WaitOnHandle(MWaitableStub pFunc, HANDLE hEvent)
-{
- arWaitableObjects.insert(new MWaitableObject(pFunc, hEvent));
-}
-
-MIR_APP_DLL(void) Miranda_WaitOnHandleEx(MWaitableStubEx pFunc, void *pInfo)
-{
- arWaitableObjects.insert(new MWaitableObject(pFunc, pInfo));
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
// dll entry point
BOOL WINAPI DllMain(HINSTANCE hinstDLL, uint32_t dwReason, LPVOID)
@@ -143,42 +85,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, uint32_t dwReason, LPVOID)
/////////////////////////////////////////////////////////////////////////////////////////
-static void __cdecl compactHeapsThread(void*)
-{
- Thread_SetName("compactHeapsThread");
-
- while (!Miranda_IsTerminated()) {
- SleepEx((1000 * 60) * 5, TRUE); // every 5 minutes
-
- HANDLE hHeaps[256];
- uint32_t hc = GetProcessHeaps(255, (PHANDLE)&hHeaps);
- if (hc != 0 && hc < 256) {
- __try {
- for (uint32_t j = 0; j < hc; j++)
- HeapCompact(hHeaps[j], 0);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {}
- }
- }
-}
-
-static uint32_t dwEventTime = 0;
-void checkIdle(MSG * msg)
-{
- switch (msg->message) {
- case WM_MOUSEACTIVATE:
- case WM_MOUSEMOVE:
- case WM_CHAR:
- dwEventTime = GetTickCount();
- }
-}
-
-MIR_APP_DLL(uint32_t) Miranda_GetIdle()
-{
- return dwEventTime;
-}
-
static int SystemShutdownProc(WPARAM, LPARAM)
{
UnloadDefaultModules();
@@ -265,59 +171,23 @@ static MSystemWindow *g_pSystemWindow;
/////////////////////////////////////////////////////////////////////////////////////////
-static void crtErrorHandler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned, uintptr_t)
-{}
-
-static uint32_t myWait()
-{
- HANDLE *hWaitObjects = (HANDLE*)_alloca(arWaitableObjects.getCount() * sizeof(HANDLE));
- for (int i = 0; i < arWaitableObjects.getCount(); i++)
- hWaitObjects[i] = arWaitableObjects[i].m_hEvent;
-
- return MsgWaitForMultipleObjectsEx(arWaitableObjects.getCount(), hWaitObjects, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
-}
-
int WINAPI mir_main(LPTSTR cmdLine)
{
hMainThreadId = GetCurrentThreadId();
- _set_invalid_parameter_handler(&crtErrorHandler);
-#ifdef _DEBUG
- _CrtSetReportMode(_CRT_ASSERT, 0);
-#endif
-
CmdLine_Parse(cmdLine);
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C");
-#ifdef _DEBUG
- if (CmdLine_GetOption(L"memdebug"))
- _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
-#endif
-
- HMODULE hThemeAPI;
- if (IsWinVerVistaPlus()) {
- hThemeAPI = LoadLibrary(L"uxtheme.dll");
- if (hThemeAPI) {
- bufferedPaintInit = (pfnBufferedPaintInit)GetProcAddress(hThemeAPI, "BufferedPaintInit");
- bufferedPaintUninit = (pfnBufferedPaintUninit)GetProcAddress(hThemeAPI, "BufferedPaintUninit");
- }
- }
- else hThemeAPI = nullptr;
-
- if (bufferedPaintInit)
- bufferedPaintInit();
-
- OleInitialize(nullptr);
-
g_pSystemWindow = new MSystemWindow();
g_pSystemWindow->Create();
+ BeginMessageLoop();
+
int result = 0;
if (LoadDefaultModules()) {
- g_bMirandaTerminated = true;
- NotifyEventHooks(hPreShutdownEvent, 0, 0);
- NotifyEventHooks(hShutdownEvent, 0, 0);
+ Miranda_SetTerminated();
+
UnloadDefaultModules();
result = 1;
@@ -333,79 +203,22 @@ int WINAPI mir_main(LPTSTR cmdLine)
// ensure that the kernel hooks the SystemShutdownProc() after all plugins
HookEvent(ME_SYSTEM_SHUTDOWN, SystemShutdownProc);
- mir_forkthread(compactHeapsThread);
- dwEventTime = GetTickCount();
- uint32_t myPid = GetCurrentProcessId();
-
- bool messageloop = true;
- while (messageloop) {
- MSG msg;
- BOOL dying = FALSE;
- uint32_t rc = myWait();
- if (rc < WAIT_OBJECT_0 + arWaitableObjects.getCount()) {
- auto &pWait = arWaitableObjects[rc - WAIT_OBJECT_0];
- if (pWait.m_pInfo == INVALID_HANDLE_VALUE)
- (*pWait.m_pFunc)();
- else
- (*pWait.m_pFuncEx)(pWait.m_pInfo);
-
- if (pWait.m_bOwnsEvent)
- arWaitableObjects.remove(&pWait);
- }
-
- while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
- if (msg.message != WM_QUIT) {
- HWND h = GetForegroundWindow();
- DWORD pid = 0;
- checkIdle(&msg);
- if (h != nullptr && GetWindowThreadProcessId(h, &pid) && pid == myPid && GetClassLongPtr(h, GCW_ATOM) == 32770)
- if (h != nullptr && IsDialogMessage(h, &msg)) /* Wine fix. */
- continue;
-
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else if (!dying) {
- dying++;
- g_bMirandaTerminated = true;
- NotifyEventHooks(hPreShutdownEvent, 0, 0);
-
- // this spins and processes the msg loop, objects and APC.
- Thread_Wait();
- NotifyEventHooks(hShutdownEvent, 0, 0);
- // if the hooks generated any messages, it'll get processed before the second WM_QUIT
- PostQuitMessage(0);
- }
- else if (dying)
- messageloop = false;
- }
- }
+ EnterMessageLoop();
}
UnloadNewPluginsModule();
UnloadCoreModule();
- if (hThemeAPI)
- FreeLibrary(hThemeAPI);
-
UninitTray();
delete g_pSystemWindow;
- OleUninitialize();
-
- if (bufferedPaintUninit)
- bufferedPaintUninit();
+ LeaveMessageLoop();
return result;
}
/////////////////////////////////////////////////////////////////////////////////////////
-MIR_APP_DLL(bool) Miranda_IsTerminated()
-{
- return g_bMirandaTerminated;
-}
-
MIR_APP_DLL(bool) Miranda_OkToExit()
{
return NotifyEventHooks(hOkToExitEvent, 0, 0) == 0;
@@ -493,8 +306,6 @@ extern HANDLE hOptionsInitEvent;
int LoadSystemModule(void)
{
- hShutdownEvent = CreateHookableEvent(ME_SYSTEM_SHUTDOWN);
- hPreShutdownEvent = CreateHookableEvent(ME_SYSTEM_PRESHUTDOWN);
hModulesLoadedEvent = CreateHookableEvent(ME_SYSTEM_MODULESLOADED);
hOkToExitEvent = CreateHookableEvent(ME_SYSTEM_OKTOEXIT);
hOptionsInitEvent = CreateHookableEvent(ME_OPT_INITIALISE);
diff --git a/src/mir_app/src/miranda.h b/src/mir_app/src/miranda.h
index aadf1a35b6..c3f476c21a 100644
--- a/src/mir_app/src/miranda.h
+++ b/src/mir_app/src/miranda.h
@@ -41,12 +41,16 @@ void UnloadIdleModule(void);
/**** miranda.cpp **********************************************************************/
+EXTERN_C MIR_CORE_DLL(void) BeginMessageLoop(void);
+EXTERN_C MIR_CORE_DLL(void) EnterMessageLoop(void);
+EXTERN_C MIR_CORE_DLL(void) LeaveMessageLoop(void);
+
extern uint32_t hMainThreadId;
extern HANDLE hOkToExitEvent, hModulesLoadedEvent;
extern HANDLE hAccListChanged;
extern wchar_t mirandabootini[MAX_PATH];
extern struct pluginEntry *plugin_checker, *plugin_crshdmp, *plugin_service, *plugin_clist;
-extern bool g_bModulesLoadedFired, g_bMirandaTerminated;
+extern bool g_bModulesLoadedFired;
/**** newplugins.cpp *******************************************************************/
@@ -96,7 +100,6 @@ int ImageList_ReplaceIcon_IconLibLoaded(HIMAGELIST hIml, int nIndex, HICON hIcon
extern int hMainMenuObject, hContactMenuObject, hStatusMenuObject;
extern HANDLE hPreBuildMainMenuEvent, hPreBuildContactMenuEvent;
-extern HANDLE hShutdownEvent, hPreShutdownEvent;
extern HMENU hMainMenu, hStatusMenu;
extern OBJLIST<CListEvent> g_cliEvents;
diff --git a/src/mir_app/src/newplugins.cpp b/src/mir_app/src/newplugins.cpp
index 7e90950040..7ff6548751 100644
--- a/src/mir_app/src/newplugins.cpp
+++ b/src/mir_app/src/newplugins.cpp
@@ -199,7 +199,7 @@ LBL_Error:
CMPluginBase *ppb = pImpl->m_pPlugin;
if (g_bModulesLoadedFired) {
- if (CallPluginEventHook(ppb->getInst(), hModulesLoadedEvent, 0, 0) != 0)
+ if (CallPluginEventHook(ppb->getInst(), ME_SYSTEM_MODULESLOADED, 0, 0) != 0)
goto LBL_Error;
NotifyEventHooks(hevLoadModule, (WPARAM)ppb, (LPARAM)ppb->getInst());
@@ -328,14 +328,14 @@ bool Plugin_UnloadDyn(pluginEntry *p)
CMPluginBase *ppb = p->m_pPlugin;
if (ppb != nullptr) {
if (HINSTANCE hInst = ppb->getInst()) {
- if (CallPluginEventHook(hInst, hOkToExitEvent, 0, 0) != 0)
+ if (CallPluginEventHook(hInst, ME_SYSTEM_OKTOEXIT, 0, 0) != 0)
return false;
KillModuleAccounts(hInst);
KillModuleSubclassing(hInst);
- CallPluginEventHook(hInst, hPreShutdownEvent, 0, 0);
- CallPluginEventHook(hInst, hShutdownEvent, 0, 0);
+ CallPluginEventHook(hInst, ME_SYSTEM_PRESHUTDOWN, 0, 0);
+ CallPluginEventHook(hInst, ME_SYSTEM_SHUTDOWN, 0, 0);
KillModuleEventHooks(hInst);
KillModuleServices(hInst);
diff --git a/src/mir_app/src/options.cpp b/src/mir_app/src/options.cpp
index fb11b10f7e..022d7e339f 100644
--- a/src/mir_app/src/options.cpp
+++ b/src/mir_app/src/options.cpp
@@ -1264,7 +1264,7 @@ static INT_PTR OpenOptionsDialog(WPARAM, LPARAM)
static int OptDynamicLoadOptions(WPARAM, LPARAM hInstance)
{
OptionsPageList arPages(1);
- CallPluginEventHook((HINSTANCE)hInstance, hOptionsInitEvent, (WPARAM)&arPages, 0);
+ CallPluginEventHook((HINSTANCE)hInstance, ME_OPT_INITIALISE, (WPARAM)&arPages, 0);
return 0;
}
diff --git a/src/mir_app/src/pluginopts.cpp b/src/mir_app/src/pluginopts.cpp
index 9e604033aa..593d4978aa 100644
--- a/src/mir_app/src/pluginopts.cpp
+++ b/src/mir_app/src/pluginopts.cpp
@@ -218,7 +218,7 @@ static bool LoadPluginDynamically(PluginListItemData *dat)
goto LBL_Error;
CMPluginBase *ppb = pPlug->m_pPlugin;
- if (CallPluginEventHook(ppb->getInst(), hModulesLoadedEvent, 0, 0) != 0)
+ if (CallPluginEventHook(ppb->getInst(), ME_SYSTEM_MODULESLOADED, 0, 0) != 0)
goto LBL_Error;
// if dynamically loaded plugin contains protocols, initialize the corresponding accounts
diff --git a/src/mir_app/src/stdafx.h b/src/mir_app/src/stdafx.h
index e005d2a725..d6770083fa 100644
--- a/src/mir_app/src/stdafx.h
+++ b/src/mir_app/src/stdafx.h
@@ -43,10 +43,6 @@ typedef struct SslHandle *HSSL;
#include <process.h>
#endif
-#ifdef _DEBUG
-#include <crtdbg.h>
-#endif
-
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
diff --git a/src/mir_core/src/Windows/miranda.cpp b/src/mir_core/src/Windows/miranda.cpp
index d6c63c7ca1..aea24d96d8 100644
--- a/src/mir_core/src/Windows/miranda.cpp
+++ b/src/mir_core/src/Windows/miranda.cpp
@@ -43,8 +43,76 @@ HINSTANCE g_hInst = nullptr;
HCURSOR g_hCursorNS, g_hCursorWE;
HANDLE hThreadQueueEmpty;
+HANDLE hShutdownEvent, hPreShutdownEvent;
uint32_t mir_tls = 0;
+static bool g_bMirandaTerminated = false;
+
+MIR_CORE_DLL(bool) Miranda_IsTerminated()
+{
+ return g_bMirandaTerminated;
+}
+
+MIR_CORE_DLL(void) Miranda_SetTerminated(void)
+{
+ g_bMirandaTerminated = true;
+
+ NotifyEventHooks(hPreShutdownEvent, 0, 0);
+ NotifyEventHooks(hShutdownEvent, 0, 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+struct MWaitableObject
+{
+ MWaitableObject(MWaitableStub pFunc, HANDLE hEvent) :
+ m_bOwnsEvent(false),
+ m_hEvent(hEvent),
+ m_pFunc(pFunc),
+ m_pInfo(INVALID_HANDLE_VALUE)
+ {
+ if (hEvent == nullptr) {
+ m_hEvent = CreateEvent(nullptr, TRUE, TRUE, nullptr);
+ m_bOwnsEvent = true;
+ }
+ }
+
+ MWaitableObject(MWaitableStubEx pFunc, void *pInfo) :
+ m_bOwnsEvent(true),
+ m_hEvent(CreateEvent(nullptr, TRUE, TRUE, nullptr)),
+ m_pFuncEx(pFunc),
+ m_pInfo(pInfo)
+ {}
+
+ ~MWaitableObject()
+ {
+ if (m_bOwnsEvent)
+ ::CloseHandle(m_hEvent);
+ }
+
+ HANDLE m_hEvent;
+ union
+ {
+ MWaitableStub m_pFunc;
+ MWaitableStubEx m_pFuncEx;
+ };
+ void *m_pInfo;
+
+ bool m_bOwnsEvent;
+};
+
+static OBJLIST<MWaitableObject> arWaitableObjects(1, HandleKeySortT);
+
+MIR_CORE_DLL(void) Miranda_WaitOnHandle(MWaitableStub pFunc, HANDLE hEvent)
+{
+ arWaitableObjects.insert(new MWaitableObject(pFunc, hEvent));
+}
+
+MIR_CORE_DLL(void) Miranda_WaitOnHandleEx(MWaitableStubEx pFunc, void *pInfo)
+{
+ arWaitableObjects.insert(new MWaitableObject(pFunc, pInfo));
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
static INT_PTR RestartMiranda(WPARAM wParam, LPARAM lParam)
@@ -116,6 +184,9 @@ static void LoadCoreModule(void)
CreateServiceFunction(MS_SYSTEM_RESTART, RestartMiranda);
+ hShutdownEvent = CreateHookableEvent(ME_SYSTEM_SHUTDOWN);
+ hPreShutdownEvent = CreateHookableEvent(ME_SYSTEM_PRESHUTDOWN);
+
pfnRtlGenRandom = (PGENRANDOM)GetProcAddress(GetModuleHandleA("advapi32"), "SystemFunction036");
}
@@ -131,6 +202,156 @@ MIR_CORE_DLL(void) UnloadCoreModule(void)
}
/////////////////////////////////////////////////////////////////////////////////////////
+// Message loop
+
+static HMODULE hThemeAPI;
+
+typedef HRESULT(STDAPICALLTYPE *pfnBufferedPaintInit)(void);
+pfnBufferedPaintInit bufferedPaintInit;
+
+typedef HRESULT(STDAPICALLTYPE *pfnBufferedPaintUninit)(void);
+pfnBufferedPaintUninit bufferedPaintUninit;
+
+static void crtErrorHandler(const wchar_t *, const wchar_t *, const wchar_t *, unsigned, uintptr_t)
+{}
+
+static void __cdecl compactHeapsThread(void*)
+{
+ Thread_SetName("compactHeapsThread");
+
+ while (!Miranda_IsTerminated()) {
+ SleepEx((1000 * 60) * 5, TRUE); // every 5 minutes
+
+ HANDLE hHeaps[256];
+ uint32_t hc = GetProcessHeaps(255, (PHANDLE)&hHeaps);
+ if (hc != 0 && hc < 256) {
+ __try {
+ for (uint32_t j = 0; j < hc; j++)
+ HeapCompact(hHeaps[j], 0);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {}
+ }
+ }
+}
+
+MIR_CORE_DLL(void) BeginMessageLoop()
+{
+ _set_invalid_parameter_handler(&crtErrorHandler);
+
+ #ifdef _DEBUG
+ _CrtSetReportMode(_CRT_ASSERT, 0);
+ #endif
+
+ #ifdef _DEBUG
+ if (CmdLine_GetOption(L"memdebug"))
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+ #endif
+
+ hThemeAPI = LoadLibrary(L"uxtheme.dll");
+ if (hThemeAPI) {
+ bufferedPaintInit = (pfnBufferedPaintInit)GetProcAddress(hThemeAPI, "BufferedPaintInit");
+ bufferedPaintUninit = (pfnBufferedPaintUninit)GetProcAddress(hThemeAPI, "BufferedPaintUninit");
+ }
+
+ if (bufferedPaintInit)
+ bufferedPaintInit();
+
+ OleInitialize(nullptr);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static uint32_t dwEventTime = 0;
+
+void checkIdle(MSG *msg)
+{
+ switch (msg->message) {
+ case WM_MOUSEACTIVATE:
+ case WM_MOUSEMOVE:
+ case WM_CHAR:
+ dwEventTime = GetTickCount();
+ }
+}
+
+MIR_CORE_DLL(uint32_t) Miranda_GetIdle()
+{
+ return dwEventTime;
+}
+
+static uint32_t myWait()
+{
+ HANDLE *hWaitObjects = (HANDLE *)_alloca(arWaitableObjects.getCount() * sizeof(HANDLE));
+ for (int i = 0; i < arWaitableObjects.getCount(); i++)
+ hWaitObjects[i] = arWaitableObjects[i].m_hEvent;
+
+ return MsgWaitForMultipleObjectsEx(arWaitableObjects.getCount(), hWaitObjects, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
+}
+
+MIR_CORE_DLL(void) EnterMessageLoop()
+{
+ mir_forkthread(compactHeapsThread);
+ dwEventTime = GetTickCount();
+ uint32_t myPid = GetCurrentProcessId();
+
+ bool messageloop = true;
+ while (messageloop) {
+ MSG msg;
+ BOOL dying = FALSE;
+ uint32_t rc = myWait();
+ if (rc < WAIT_OBJECT_0 + arWaitableObjects.getCount()) {
+ auto &pWait = arWaitableObjects[rc - WAIT_OBJECT_0];
+ if (pWait.m_pInfo == INVALID_HANDLE_VALUE)
+ (*pWait.m_pFunc)();
+ else
+ (*pWait.m_pFuncEx)(pWait.m_pInfo);
+
+ if (pWait.m_bOwnsEvent)
+ arWaitableObjects.remove(&pWait);
+ }
+
+ while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
+ if (msg.message != WM_QUIT) {
+ HWND h = GetForegroundWindow();
+ DWORD pid = 0;
+ checkIdle(&msg);
+ if (h != nullptr && GetWindowThreadProcessId(h, &pid) && pid == myPid && GetClassLongPtr(h, GCW_ATOM) == 32770)
+ if (h != nullptr && IsDialogMessage(h, &msg)) /* Wine fix. */
+ continue;
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ else if (!dying) {
+ dying++;
+ g_bMirandaTerminated = true;
+ NotifyEventHooks(hPreShutdownEvent, 0, 0);
+
+ // this spins and processes the msg loop, objects and APC.
+ Thread_Wait();
+ NotifyEventHooks(hShutdownEvent, 0, 0);
+ // if the hooks generated any messages, it'll get processed before the second WM_QUIT
+ PostQuitMessage(0);
+ }
+ else if (dying)
+ messageloop = false;
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+MIR_CORE_DLL(void) LeaveMessageLoop()
+{
+ OleUninitialize();
+
+ if (bufferedPaintUninit) {
+ bufferedPaintUninit();
+ FreeLibrary(hThemeAPI);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
// entry point
BOOL WINAPI DllMain(HINSTANCE hinstDLL, uint32_t fdwReason, LPVOID)
diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def
index 965ef0703e..f2034f9ae2 100644
--- a/src/mir_core/src/mir_core.def
+++ b/src/mir_core/src/mir_core.def
@@ -2,8 +2,11 @@ LIBRARY mir_core.mir
EXPORTS
?g_pCurrDb@@3PAVMDatabaseCommon@@A @1 NONAME
-DeleteDirectoryTreeW @2
+BeginMessageLoop @2 NONAME
+EnterMessageLoop @3 NONAME
+LeaveMessageLoop @4 NONAME
CallFunctionAsync @5
+DeleteDirectoryTreeW @6
CallPluginEventHook @7
CallService @8
CallServiceSync @9
@@ -19,6 +22,7 @@ CreateServiceFunctionParam @18
DestroyHookableEvent @19
DestroyServiceFunction @20
GetExceptionFilter @21
+Miranda_GetIdle @22 NONAME
HookEvent @23
HookEventMessage @24
HookEventObj @25
@@ -1531,3 +1535,7 @@ db_copy_module @1736
?move@MFilePath@@QAE_NPB_W@Z @1755 NONAME
?search@MFilePath@@QAE?AVMFileIterator@1@XZ @1756 NONAME
??Eiterator@MFileIterator@MFilePath@@QAE?AV012@XZ @1757 NONAME
+Miranda_IsTerminated @1758 NONAME
+Miranda_SetTerminated @1759 NONAME
+Miranda_WaitOnHandle @1760 NONAME
+Miranda_WaitOnHandleEx @1761 NONAME
diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def
index 741a548e83..8834dde5db 100644
--- a/src/mir_core/src/mir_core64.def
+++ b/src/mir_core/src/mir_core64.def
@@ -2,8 +2,11 @@ LIBRARY mir_core.mir
EXPORTS
?g_pCurrDb@@3PEAVMDatabaseCommon@@EA @1 NONAME
-DeleteDirectoryTreeW @2
+BeginMessageLoop @2 NONAME
+EnterMessageLoop @3 NONAME
+LeaveMessageLoop @4 NONAME
CallFunctionAsync @5
+DeleteDirectoryTreeW @6
CallPluginEventHook @7
CallService @8
CallServiceSync @9
@@ -19,6 +22,7 @@ CreateServiceFunctionParam @18
DestroyHookableEvent @19
DestroyServiceFunction @20
GetExceptionFilter @21
+Miranda_GetIdle @22 NONAME
HookEvent @23
HookEventMessage @24
HookEventObj @25
@@ -1531,3 +1535,7 @@ db_copy_module @1736
?move@MFilePath@@QEAA_NPEB_W@Z @1755 NONAME
?search@MFilePath@@QEAA?AVMFileIterator@1@XZ @1756 NONAME
??Eiterator@MFileIterator@MFilePath@@QEAA?AV012@XZ @1757 NONAME
+Miranda_IsTerminated @1758 NONAME
+Miranda_SetTerminated @1759 NONAME
+Miranda_WaitOnHandle @1760 NONAME
+Miranda_WaitOnHandleEx @1761 NONAME
diff --git a/src/mir_core/src/miranda.h b/src/mir_core/src/miranda.h
index 147bc1998f..24a15d0af9 100644
--- a/src/mir_core/src/miranda.h
+++ b/src/mir_core/src/miranda.h
@@ -65,7 +65,7 @@ struct THookSubscriber
struct THook : public MZeroedObject
{
- char name[ MAXMODULELABELLENGTH ];
+ char name[MAXMODULELABELLENGTH];
int id;
int subscriberCount;
THookSubscriber* subscriber;
@@ -82,6 +82,13 @@ extern LIST<CMPluginBase> pluginListAddr;
char* LangPackTranslateString(const MUUID *pUuid, const char *szEnglish, const int W);
/////////////////////////////////////////////////////////////////////////////////////////
+// miranda.cpp
+
+EXTERN_C MIR_CORE_DLL(void) BeginMessageLoop(void);
+EXTERN_C MIR_CORE_DLL(void) EnterMessageLoop(void);
+EXTERN_C MIR_CORE_DLL(void) LeaveMessageLoop(void);
+
+/////////////////////////////////////////////////////////////////////////////////////////
// threads.cpp
extern uint32_t mir_tls;
diff --git a/src/mir_core/src/modules.cpp b/src/mir_core/src/modules.cpp
index 6e867aa95c..1636d7449e 100644
--- a/src/mir_core/src/modules.cpp
+++ b/src/mir_core/src/modules.cpp
@@ -63,15 +63,14 @@ struct TService
LIST<TService> services(100, NumericKeySortT);
-typedef struct
+struct TServiceToMainThreadItem
{
HANDLE hDoneEvent;
WPARAM wParam;
LPARAM lParam;
int result;
const char *name;
-}
-TServiceToMainThreadItem;
+};
// other static variables
static BOOL bServiceMode = FALSE;
@@ -154,9 +153,13 @@ MIR_CORE_DLL(int) SetHookDefaultForHookableEvent(HANDLE hEvent, MIRANDAHOOK pfnH
return 0;
}
-MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, HANDLE hEvent, WPARAM wParam, LPARAM lParam)
+MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, const char *pszEvent, WPARAM wParam, LPARAM lParam)
{
- THook *p = (THook*)hEvent;
+ int idx;
+ if ((idx = hooks.getIndex((THook *)pszEvent)) == -1)
+ return -1;
+
+ THook *p = hooks[idx];
if (p == nullptr || hInst == nullptr)
return -1;
diff --git a/src/mir_core/src/stdafx.h b/src/mir_core/src/stdafx.h
index f053907693..54ec535a4c 100644
--- a/src/mir_core/src/stdafx.h
+++ b/src/mir_core/src/stdafx.h
@@ -42,6 +42,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <process.h>
#include <io.h>
#include <direct.h>
+
+ #ifdef _DEBUG
+ #include <crtdbg.h>
+ #endif
#else
#include <Elementary.h>
#endif // _WINDOWS