/* Scriver Copyright (c) 2000-09 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdafx.h" static MessageSendQueueItem *global_sendQueue = nullptr; static mir_cs queueMutex; wchar_t* GetSendBufferMsg(MessageSendQueueItem *item) { return mir_utf8decodeW(item->sendBuffer); } MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender) { MessageSendQueueItem *item = (MessageSendQueueItem*)mir_calloc(sizeof(MessageSendQueueItem)); mir_cslock lck(queueMutex); item->hwndSender = hwndSender; item->next = global_sendQueue; if (global_sendQueue != nullptr) global_sendQueue->prev = item; global_sendQueue = item; return item; } MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, MCONTACT hContact) { mir_cslock lck(queueMutex); for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) if (item->hwndSender == hwndSender && item->hContact == hContact && item->hwndErrorDlg == nullptr) return item; return nullptr; } MessageSendQueueItem* FindSendQueueItem(MCONTACT hContact, HANDLE hSendId) { mir_cslock lock(queueMutex); for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) if (item->hContact == hContact && item->hSendId == hSendId) return item; return nullptr; } BOOL RemoveSendQueueItem(MessageSendQueueItem* item) { HWND hwndSender = item->hwndSender; mir_cslock lock(queueMutex); if (item->prev != nullptr) item->prev->next = item->next; else global_sendQueue = item->next; if (item->next != nullptr) item->next->prev = item->prev; mir_free(item->sendBuffer); mir_free(item->proto); mir_free(item); for (item = global_sendQueue; item != nullptr; item = item->next) if (item->hwndSender == hwndSender) return FALSE; return TRUE; } void ReportSendQueueTimeouts(HWND hwndSender) { MessageSendQueueItem *item, *item2; int timeout = db_get_dw(0, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT); mir_cslock lock(queueMutex); for (item = global_sendQueue; item != nullptr; item = item2) { item2 = item->next; if (item->timeout < timeout) { item->timeout += 1000; if (item->timeout >= timeout) { if (item->hwndSender == hwndSender && item->hwndErrorDlg == nullptr) { if (hwndSender != nullptr) { ErrorWindowData *ewd = (ErrorWindowData *)mir_alloc(sizeof(ErrorWindowData)); ewd->szName = mir_wstrdup(pcli->pfnGetContactDisplayName(item->hContact, 0)); ewd->szDescription = mir_wstrdup(TranslateT("The message send timed out.")); ewd->szText = GetSendBufferMsg(item); ewd->hwndParent = hwndSender; ewd->queueItem = item; PostMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)ewd); } else { /* TODO: Handle errors outside messaging window in a better way */ RemoveSendQueueItem(item); } } } } } } void ReleaseSendQueueItems(HWND hwndSender) { mir_cslock lock(queueMutex); for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) { if (item->hwndSender == hwndSender) { item->hwndSender = nullptr; if (item->hwndErrorDlg != nullptr) DestroyWindow(item->hwndErrorDlg); item->hwndErrorDlg = nullptr; } } } int ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact) { int count = 0; mir_cslock lock(queueMutex); for (MessageSendQueueItem *item = global_sendQueue; item != nullptr; item = item->next) { if (item->hContact == hContact && item->hwndSender == nullptr) { item->hwndSender = hwndSender; item->timeout = 0; count++; } } return count; } void RemoveAllSendQueueItems() { MessageSendQueueItem *item, *item2; mir_cslock lock(queueMutex); for (item = global_sendQueue; item != nullptr; item = item2) { item2 = item->next; RemoveSendQueueItem(item); } } void SendSendQueueItem(MessageSendQueueItem* item) { mir_cslockfull lock(queueMutex); item->timeout = 0; if (item->prev != nullptr) { item->prev->next = item->next; if (item->next != nullptr) item->next->prev = item->prev; item->next = global_sendQueue; item->prev = nullptr; if (global_sendQueue != nullptr) global_sendQueue->prev = item; global_sendQueue = item; } lock.unlock(); item->hSendId = (HANDLE)ProtoChainSend(item->hContact, PSS_MESSAGE, item->flags, (LPARAM)item->sendBuffer); }