diff options
Diffstat (limited to 'plugins/VoiceService/src/VoiceCall.cpp')
-rw-r--r-- | plugins/VoiceService/src/VoiceCall.cpp | 257 |
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; +} |