summaryrefslogtreecommitdiff
path: root/plugins/VoiceService/src/VoiceCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/VoiceService/src/VoiceCall.cpp')
-rw-r--r--plugins/VoiceService/src/VoiceCall.cpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/plugins/VoiceService/src/VoiceCall.cpp b/plugins/VoiceService/src/VoiceCall.cpp
new file mode 100644
index 0000000000..fbfd0760a1
--- /dev/null
+++ b/plugins/VoiceService/src/VoiceCall.cpp
@@ -0,0 +1,257 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "stdafx.h"
+
+static wchar_t *popupTitles[] = {
+ LPGENW("Voice call started"),
+ LPGENW("Voice call ringing"),
+ LPGENW("Voice call"),
+ LPGENW("Voice call on hold"),
+ LPGENW("Voice call ended"),
+ LPGENW("Voice call busy"),
+};
+
+static wchar_t *stateTexts[] = {
+ LPGENW("Call from %s has started"),
+ LPGENW("Call from %s is ringing"),
+ LPGENW("Calling %s"),
+ LPGENW("Call from %s is on hold"),
+ LPGENW("Call from %s has ended"),
+ LPGENW("%s is busy"),
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// VoiceCall class members
+
+VoiceCall::VoiceCall(VoiceProvider *module, const char *id)
+ : module(module), id(mir_strdup(id))
+{
+ hContact = NULL;
+ name[0] = 0;
+ number[0] = 0;
+ displayName[0] = 0;
+ state = -1;
+ end_time = 0;
+ clistBlinking = false;
+ incoming = false;
+ secure = false;
+ hwnd = NULL;
+ CreateDisplayName();
+}
+
+VoiceCall::~VoiceCall()
+{
+ RemoveNotifications();
+ mir_free(id);
+ id = NULL;
+}
+
+void VoiceCall::AppendCallerID(MCONTACT aHContact, const wchar_t *aName, const wchar_t *aNumber)
+{
+ bool changed = false;
+
+ if (aHContact != NULL) {
+ hContact = aHContact;
+ changed = true;
+ }
+
+ if (!IsEmptyW(aName)) {
+ lstrcpyn(name, aName, _countof(name));
+ changed = true;
+ }
+
+ if (!IsEmptyW(aNumber)) {
+ lstrcpyn(number, aNumber, _countof(number));
+ changed = true;
+ }
+
+ if (changed)
+ CreateDisplayName();
+}
+
+void VoiceCall::CreateDisplayName()
+{
+ wchar_t *contact = NULL;
+ if (hContact != NULL)
+ contact = Clist_GetContactDisplayName(hContact, 0);
+
+ wchar_t *nameTmp = NULL;
+ if (lstrcmp(name, number) != 0)
+ nameTmp = name;
+
+ if (contact != NULL) {
+ if (!IsEmptyW(number))
+ mir_snwprintf(displayName, _countof(displayName), _T("%s <%s>"), contact, number);
+ else
+ lstrcpyn(displayName, contact, _countof(displayName));
+ }
+ else if (!IsEmptyW(nameTmp) && !IsEmptyW(number)) {
+ mir_snwprintf(displayName, _countof(displayName), _T("%s <%s>"), name, number);
+ }
+ else if (!IsEmptyW(nameTmp)) {
+ lstrcpyn(displayName, name, _countof(displayName));
+ }
+ else if (!IsEmptyW(number)) {
+ lstrcpyn(displayName, number, _countof(displayName));
+ }
+ else {
+ lstrcpyn(displayName, TranslateT("Unknown number"), _countof(displayName));
+ }
+}
+
+void VoiceCall::RemoveNotifications()
+{
+ if (hwnd != NULL) {
+ DestroyWindow(hwnd);
+ hwnd = NULL;
+ }
+
+ if (clistBlinking) {
+ g_clistApi.pfnRemoveEvent(hContact, (LPARAM)this);
+ clistBlinking = false;
+ }
+}
+
+void VoiceCall::SetState(int aState)
+{
+ if (state == aState)
+ return;
+
+ if (aState == VOICE_STATE_RINGING)
+ incoming = true;
+ else if (aState == VOICE_STATE_CALLING)
+ incoming = false;
+
+ RemoveNotifications();
+
+ state = aState;
+
+ if (IsFinished()) {
+ if (end_time == 0)
+ end_time = GetTickCount();
+
+ // Remove id because providers can re-use them
+ mir_free(id);
+ id = NULL;
+ }
+
+ Notify();
+}
+
+void VoiceCall::Notify(bool popup, bool sound, bool clist)
+{
+ if (popup) {
+ wchar_t text[512];
+ mir_snwprintf(text, _countof(text), TranslateW(stateTexts[state]), displayName);
+
+ ShowPopup(NULL, TranslateW(popupTitles[state]), text);
+ }
+
+ if (sound)
+ Skin_PlaySound(g_sounds[state].szName);
+
+ if (clist && state == VOICE_STATE_RINGING) {
+ CLISTEVENT ce = {};
+ ce.hContact = hContact;
+ ce.hIcon = g_plugin.getIcon(IDI_RINGING);
+ ce.hDbEvent = 1001;
+ ce.pszService = MS_VOICESERVICE_CLIST_DBLCLK;
+ ce.lParam = (LPARAM)this;
+ g_clistApi.pfnAddEvent(&ce);
+
+ IcoLib_ReleaseIcon(ce.hIcon);
+
+ clistBlinking = true;
+ }
+
+ if (hwnd_frame != NULL)
+ PostMessage(hwnd_frame, WMU_REFRESH, 0, 0);
+}
+
+bool VoiceCall::IsFinished()
+{
+ return IsFinalState(state);
+}
+
+bool VoiceCall::CanDrop()
+{
+ return !IsFinished();
+}
+
+void VoiceCall::Drop()
+{
+ if (!CanDrop())
+ return;
+
+ RemoveNotifications();
+
+ CallProtoService(module->name, PS_VOICE_DROPCALL, (WPARAM)id, 0);
+}
+
+bool VoiceCall::CanAnswer()
+{
+ return state == -1 || state == VOICE_STATE_RINGING || state == VOICE_STATE_ON_HOLD;
+}
+
+void VoiceCall::Answer()
+{
+ if (!CanAnswer())
+ return;
+
+ RemoveNotifications();
+
+ CallProtoService(module->name, PS_VOICE_ANSWERCALL, (WPARAM)id, 0);
+}
+
+bool VoiceCall::CanHold()
+{
+ return module->CanHold() && (state == -1 || state == VOICE_STATE_TALKING);
+}
+
+void VoiceCall::Hold()
+{
+ if (!CanHold())
+ return;
+
+ RemoveNotifications();
+
+ CallProtoService(module->name, PS_VOICE_HOLDCALL, (WPARAM)id, 0);
+}
+
+bool VoiceCall::CanSendDTMF()
+{
+ return module->CanSendDTMF() && state == VOICE_STATE_TALKING;
+}
+
+void VoiceCall::SendDTMF(wchar_t c)
+{
+ if (!CanSendDTMF())
+ return;
+
+ CallProtoService(module->name, PS_VOICE_SEND_DTMF, (WPARAM)id, (LPARAM)c);
+}
+
+void VoiceCall::SetNewCallHWND(HWND _h)
+{
+ if (_h != NULL)
+ RemoveNotifications();
+
+ hwnd = _h;
+}