diff options
author | George Hazan <ghazan@miranda.im> | 2023-01-28 19:58:25 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2023-01-28 19:58:25 +0300 |
commit | 3e00af6e0b04bca9e5398f250c7dd4280da608cc (patch) | |
tree | c435ee6859581a5226a9af4bcc989cf07196d115 /src | |
parent | 11fbe8d4d458c856dcbf7e6d18561b467ef368d3 (diff) |
IRC: fix for event broadcasting
Diffstat (limited to 'src')
-rw-r--r-- | src/core/stdmsg/src/msgdialog.cpp | 1 | ||||
-rw-r--r-- | src/mir_app/src/chat_manager.cpp | 21 | ||||
-rw-r--r-- | src/mir_app/src/chat_svc.cpp | 228 | ||||
-rw-r--r-- | src/mir_app/src/mir_app.def | 1 | ||||
-rw-r--r-- | src/mir_app/src/mir_app64.def | 1 |
5 files changed, 113 insertions, 139 deletions
diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index 359b308022..67401eea28 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -267,7 +267,6 @@ void CMsgDialog::OnActivate() StopFlash();
if (isChat()) {
- g_chatApi.SetActiveSession(m_si);
UpdateStatusBar();
if (db_get_w(m_hContact, m_si->pszModule, "ApparentMode", 0) != 0)
diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index 608e1bedac..014c092322 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -56,25 +56,6 @@ static int compareModules(const MODULEINFO *p1, const MODULEINFO *p2) static LIST<MODULEINFO> g_arModules(5, compareModules);
/////////////////////////////////////////////////////////////////////////////////////////
-
-static void SetActiveSession(SESSION_INFO *si)
-{
- if (si) {
- replaceStrW(g_chatApi.szActiveWndID, si->ptszID);
- replaceStr(g_chatApi.szActiveWndModule, si->pszModule);
- }
-}
-
-static SESSION_INFO* GetActiveSession(void)
-{
- SESSION_INFO *si = Chat_Find(g_chatApi.szActiveWndID, g_chatApi.szActiveWndModule);
- if (si)
- return si;
-
- return g_arSessions[0];
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
// Log manager functions
// Necessary to keep track of events in a window log
@@ -893,8 +874,6 @@ static void CreateNick(const SESSION_INFO *, const LOGINFO *lin, CMStringW &wszN static void ResetApi()
{
- g_chatApi.SetActiveSession = ::SetActiveSession;
- g_chatApi.GetActiveSession = ::GetActiveSession;
g_chatApi.SM_CreateSession = ::SM_CreateSession;
g_chatApi.SM_GetStatusIcon = ::SM_GetStatusIcon;
g_chatApi.SM_GetCount = ::SM_GetCount;
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index d4462ec3d2..7dd1c64498 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -268,6 +268,7 @@ MIR_APP_DLL(SESSION_INFO*) Chat_NewSession( struct ChatConrolParam
{
+ const char *pszModule;
SESSION_INFO *si;
int command;
};
@@ -283,25 +284,17 @@ static void SetInitDone(SESSION_INFO *si) p->iIconIndex = si->iStatusCount - p->iIconIndex - 1;
}
-static INT_PTR __stdcall stubRoomControl(void *param)
+static int RoomControlHandler(int iCommand, SESSION_INFO *si)
{
- ChatConrolParam *p = (ChatConrolParam*)param;
-
- mir_cslock lck(csChat);
- SESSION_INFO *si = g_arSessions.find(p->si);
- if (si == nullptr)
- return GC_EVENT_ERROR;
-
- switch (p->command) {
+ switch (iCommand) {
case WINDOW_HIDDEN:
SetInitDone(si);
- g_chatApi.SetActiveSession(si);
break;
case WINDOW_VISIBLE:
case SESSION_INITDONE:
SetInitDone(si);
- if (p->command != SESSION_INITDONE || !Chat::bPopupOnJoin)
+ if (iCommand != SESSION_INITDONE || !Chat::bPopupOnJoin)
g_chatApi.ShowRoom(si);
break;
@@ -335,9 +328,41 @@ static INT_PTR __stdcall stubRoomControl(void *param) return 0;
}
+static INT_PTR __stdcall stubRoomControl(void *param)
+{
+ ChatConrolParam *p = (ChatConrolParam*)param;
+
+ mir_cslock lck(csChat);
+ if (p->si) {
+ SESSION_INFO *si = g_arSessions.find(p->si);
+ if (si == nullptr)
+ return GC_EVENT_ERROR;
+
+ return RoomControlHandler(p->command, si);
+ }
+
+ for (auto &si : g_arSessions)
+ if (si->bInitDone && !mir_strcmpi(si->pszModule, p->pszModule))
+ RoomControlHandler(p->command, si);
+
+ return 0;
+}
+
+MIR_APP_DLL(int) Chat_Control(const char *pszModule, int iCommand)
+{
+ if (!pszModule)
+ return GC_EVENT_ERROR;
+
+ ChatConrolParam param = { pszModule, 0, iCommand };
+ return CallFunctionSync(stubRoomControl, ¶m);
+}
+
MIR_APP_DLL(int) Chat_Control(SESSION_INFO *si, int iCommand)
{
- ChatConrolParam param = { si, iCommand };
+ if (!si)
+ return GC_EVENT_ERROR;
+
+ ChatConrolParam param = { 0, si, iCommand };
return CallFunctionSync(stubRoomControl, ¶m);
}
@@ -404,64 +429,22 @@ static void AddUser(GCEVENT *gce) g_chatApi.OnNewUser(si, ui);
}
-static BOOL AddEventToAllMatchingUID(GCEVENT *gce)
-{
- int bManyFix = 0;
-
- for (auto &si : g_arSessions) {
- if (!si->bInitDone || mir_strcmpi(si->pszModule, gce->si->pszModule))
- continue;
-
- if (!g_chatApi.UM_FindUser(si, gce->pszUID.w))
- continue;
-
- if (g_chatApi.OnEventBroadcast)
- g_chatApi.OnEventBroadcast(si, gce);
-
- if (si->pDlg && si->bInitDone) {
- if (SM_AddEvent(si, gce, FALSE))
- si->pDlg->AddLog();
- else
- RedrawLog2(si);
- }
-
- if (!(gce->dwFlags & GCEF_NOTNOTIFY))
- g_chatApi.DoSoundsFlashPopupTrayStuff(si, gce, FALSE, bManyFix);
-
- bManyFix++;
- if ((gce->dwFlags & GCEF_ADDTOLOG) && g_Settings->bLoggingEnabled)
- LogToFile(si, gce);
- }
-
- return 0;
-}
-
-static INT_PTR CALLBACK sttEventStub(void *_param)
+static BOOL HandleChatEvent(GCEVENT &gce, int bManyFix)
{
- ptrW wszId, wszUid, wszNick, wszText, wszStatus, wszUserInfo;
-
- GCEVENT gce = *(GCEVENT*)_param;
- if (gce.dwFlags & GCEF_UTF8) {
- gce.pszUID.w = (wszUid = mir_utf8decodeW(gce.pszUID.a));
- gce.pszNick.w = (wszNick = mir_utf8decodeW(gce.pszNick.a));
- gce.pszText.w = (wszText = mir_utf8decodeW(gce.pszText.a));
- gce.pszStatus.w = (wszStatus = mir_utf8decodeW(gce.pszStatus.a));
- gce.pszUserInfo.w = (wszUserInfo = mir_utf8decodeW(gce.pszUserInfo.a));
- gce.dwFlags &= ~GCEF_UTF8;
- }
-
- if (NotifyEventHooks(hHookEvent, 0, LPARAM(&gce)))
- return 1;
+ // no channel - nothing to do
+ SESSION_INFO *si = gce.si;
+ if (si == nullptr)
+ return GC_EVENT_ERROR;
bool bIsHighlighted = false, bRemoveFlag = false;
// Do different things according to type of event
switch (gce.iType) {
case GC_EVENT_SETCONTACTSTATUS:
- return SM_SetContactStatus(gce.si, gce.pszUID.w, (uint16_t)gce.dwItemData);
+ return SM_SetContactStatus(si, gce.pszUID.w, (uint16_t)gce.dwItemData);
case GC_EVENT_TOPIC:
- if (SESSION_INFO *si = gce.si) {
+ {
wchar_t *pwszNew = RemoveFormatting(gce.pszText.w);
if (!mir_wstrcmp(si->ptszTopic, pwszNew)) // nothing changed? exiting
return 0;
@@ -485,24 +468,24 @@ static INT_PTR CALLBACK sttEventStub(void *_param) break;
case GC_EVENT_ADDSTATUS:
- SM_GiveStatus(gce.si, gce.pszUID.w, gce.pszStatus.w);
+ SM_GiveStatus(si, gce.pszUID.w, gce.pszStatus.w);
bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce);
break;
case GC_EVENT_REMOVESTATUS:
- SM_TakeStatus(gce.si, gce.pszUID.w, gce.pszStatus.w);
+ SM_TakeStatus(si, gce.pszUID.w, gce.pszStatus.w);
bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce);
break;
case GC_EVENT_MESSAGE:
case GC_EVENT_ACTION:
- if (!gce.bIsMe && gce.si && gce.pszText.w) {
- bIsHighlighted = g_chatApi.IsHighlighted(gce.si, &gce);
+ if (!gce.bIsMe && si && gce.pszText.w) {
+ bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
}
break;
case GC_EVENT_NICK:
- SM_ChangeNick(gce.si, &gce);
+ SM_ChangeNick(si, &gce);
bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce);
break;
@@ -522,65 +505,79 @@ static INT_PTR CALLBACK sttEventStub(void *_param) break;
}
- // Decide which window (log) should have the event
- SESSION_INFO *si = nullptr;
- if (gce.si) {
- si = gce.si;
- }
- else if (gce.iType == GC_EVENT_NOTICE || gce.iType == GC_EVENT_INFORMATION) {
- si = g_chatApi.GetActiveSession();
- if (!si)
- return 0;
- }
- else {
- // Send the event to all windows with a user pszUID. Used for broadcasting QUIT etc
- AddEventToAllMatchingUID(&gce);
- if (!bRemoveFlag)
- return 0;
- }
-
// add to log
- if (si) {
- if (gce.dwFlags & GCEF_SILENT)
- return 0;
-
- // fix for IRC's old style mode notifications. Should not affect any other protocol
- if ((gce.iType == GC_EVENT_ADDSTATUS || gce.iType == GC_EVENT_REMOVESTATUS) && !(gce.dwFlags & GCEF_ADDTOLOG))
- return 0;
-
- if (gce.iType == GC_EVENT_JOIN && gce.time == 0)
- return 0;
+ if (gce.dwFlags & GCEF_SILENT)
+ return 0;
- if (si && (si->bInitDone || gce.iType == GC_EVENT_TOPIC || (gce.iType == GC_EVENT_JOIN && gce.bIsMe))) {
- if (gce.pszNick.w == nullptr && gce.pszUID.w != nullptr) {
- USERINFO *ui = g_chatApi.UM_FindUser(si, gce.pszUID.w);
- if (ui != nullptr)
- gce.pszNick.w = ui->pszNick;
- }
+ // fix for IRC's old style mode notifications. Should not affect any other protocol
+ if ((gce.iType == GC_EVENT_ADDSTATUS || gce.iType == GC_EVENT_REMOVESTATUS) && !(gce.dwFlags & GCEF_ADDTOLOG))
+ return 0;
- int isOk = SM_AddEvent(si, &gce, bIsHighlighted);
- if (si->pDlg) {
- if (isOk)
- si->pDlg->AddLog();
- else
- RedrawLog2(si);
- }
+ if (gce.iType == GC_EVENT_JOIN && gce.time == 0)
+ return 0;
- if (!(gce.dwFlags & GCEF_NOTNOTIFY))
- g_chatApi.DoSoundsFlashPopupTrayStuff(si, &gce, bIsHighlighted, 0);
+ if (si && (si->bInitDone || gce.iType == GC_EVENT_TOPIC || (gce.iType == GC_EVENT_JOIN && gce.bIsMe))) {
+ if (gce.pszNick.w == nullptr && gce.pszUID.w != nullptr) {
+ USERINFO *ui = g_chatApi.UM_FindUser(si, gce.pszUID.w);
+ if (ui != nullptr)
+ gce.pszNick.w = ui->pszNick;
+ }
- if ((gce.dwFlags & GCEF_ADDTOLOG) && g_Settings->bLoggingEnabled)
- LogToFile(si, &gce);
+ int isOk = SM_AddEvent(si, &gce, bIsHighlighted);
+ if (si->pDlg) {
+ if (isOk)
+ si->pDlg->AddLog();
+ else
+ RedrawLog2(si);
}
- if (!bRemoveFlag)
- return 0;
+ if (!(gce.dwFlags & GCEF_NOTNOTIFY))
+ g_chatApi.DoSoundsFlashPopupTrayStuff(si, &gce, bIsHighlighted, bManyFix);
+
+ if ((gce.dwFlags & GCEF_ADDTOLOG) && g_Settings->bLoggingEnabled)
+ LogToFile(si, &gce);
}
if (bRemoveFlag)
- return SM_RemoveUser(gce.si, gce.pszUID.w) == 0;
+ return SM_RemoveUser(si, gce.pszUID.w) == 0;
- return GC_EVENT_ERROR;
+ return 0;
+}
+
+static INT_PTR CALLBACK sttEventStub(void *_param)
+{
+ ptrW wszId, wszUid, wszNick, wszText, wszStatus, wszUserInfo;
+
+ GCEVENT gce = *(GCEVENT*)_param;
+ if (gce.dwFlags & GCEF_UTF8) {
+ gce.pszUID.w = (wszUid = mir_utf8decodeW(gce.pszUID.a));
+ gce.pszNick.w = (wszNick = mir_utf8decodeW(gce.pszNick.a));
+ gce.pszText.w = (wszText = mir_utf8decodeW(gce.pszText.a));
+ gce.pszStatus.w = (wszStatus = mir_utf8decodeW(gce.pszStatus.a));
+ gce.pszUserInfo.w = (wszUserInfo = mir_utf8decodeW(gce.pszUserInfo.a));
+ gce.dwFlags &= ~GCEF_UTF8;
+ }
+
+ if (NotifyEventHooks(hHookEvent, 0, LPARAM(&gce)))
+ return 1;
+
+ if (gce.dwFlags & GCEF_BROADCAST) {
+ gce.dwFlags &= ~GCEF_BROADCAST;
+
+ const char *pszModule = gce.pszModule;
+ int bManyFix = 0;
+
+ for (auto &si : g_arSessions) {
+ if (!si->bInitDone || mir_strcmpi(si->pszModule, pszModule))
+ continue;
+
+ gce.si = si;
+ HandleChatEvent(gce, bManyFix++);
+ }
+ return 0;
+ }
+
+ return HandleChatEvent(gce, 0);
}
MIR_APP_DLL(int) Chat_Event(GCEVENT *gce)
@@ -951,9 +948,6 @@ void UnloadChatModule(void) if (!bInited)
return;
- mir_free(g_chatApi.szActiveWndID);
- mir_free(g_chatApi.szActiveWndModule);
-
FreeMsgLogBitmaps();
OptionsUnInit();
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index bae7600aec..8150a19b26 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -816,3 +816,4 @@ Srmm_CreateHotkey @886 NONAME ?Chat_SetUserInfo@@YGHPAUSESSION_INFO@@PAX@Z @931 NONAME
?Chat_Terminate@@YGHPAUSESSION_INFO@@_N@Z @932 NONAME
?Chat_Terminate@@YGHPBD_N@Z @933 NONAME
+?Chat_Control@@YGHPBDH@Z @934 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 20cdf0907d..520d097e19 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -816,3 +816,4 @@ Srmm_CreateHotkey @886 NONAME ?Chat_SetUserInfo@@YAHPEAUSESSION_INFO@@PEAX@Z @931 NONAME
?Chat_Terminate@@YAHPEAUSESSION_INFO@@_N@Z @932 NONAME
?Chat_Terminate@@YAHPEBD_N@Z @933 NONAME
+?Chat_Control@@YAHPEBDH@Z @934 NONAME
|