diff options
author | Alexander Lantsev <aunsane@gmail.com> | 2015-04-14 20:32:40 +0000 |
---|---|---|
committer | Alexander Lantsev <aunsane@gmail.com> | 2015-04-14 20:32:40 +0000 |
commit | 4d0735ab834be6c541e7e577fbe76c888bf4d09f (patch) | |
tree | 8e290ade50e86e7b5f53a2b66bb0f1f2a2119982 /protocols/Tox/src | |
parent | 31ba819bd0994a0a48a174cba37b5985522ff3f8 (diff) |
Tox: second approach for audio support
git-svn-id: http://svn.miranda-ng.org/main/trunk@12827 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Tox/src')
-rw-r--r-- | protocols/Tox/src/common.h | 12 | ||||
-rw-r--r-- | protocols/Tox/src/main.cpp | 9 | ||||
-rw-r--r-- | protocols/Tox/src/resource.h | 4 | ||||
-rw-r--r-- | protocols/Tox/src/tox_accounts.cpp | 2 | ||||
-rw-r--r-- | protocols/Tox/src/tox_contacts.cpp | 30 | ||||
-rw-r--r-- | protocols/Tox/src/tox_events.cpp | 76 | ||||
-rw-r--r-- | protocols/Tox/src/tox_icons.cpp | 15 | ||||
-rw-r--r-- | protocols/Tox/src/tox_messages.cpp | 4 | ||||
-rw-r--r-- | protocols/Tox/src/tox_multimedia.cpp | 58 | ||||
-rw-r--r-- | protocols/Tox/src/tox_profile.cpp | 10 | ||||
-rw-r--r-- | protocols/Tox/src/tox_proto.cpp | 9 | ||||
-rw-r--r-- | protocols/Tox/src/tox_proto.h | 8 |
12 files changed, 181 insertions, 56 deletions
diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h index ba70f43c92..0c5fa59879 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -19,7 +19,6 @@ #include <m_database.h>
#include <m_langpack.h>
-#include <m_clist.h>
#include <m_options.h>
#include <m_netlib.h>
#include <m_popup.h>
@@ -32,6 +31,7 @@ #include <m_chat.h>
#include <m_genmenu.h>
#include <m_clc.h>
+#include <m_clist.h>
#include <m_clistint.h>
#include <m_gui.h>
@@ -57,7 +57,7 @@ struct CToxProto; extern HINSTANCE g_hInstance;
-#define MODULE "TOX"
+#define MODULE "Tox"
#define TOX_ERROR -1
@@ -81,7 +81,13 @@ extern HINSTANCE g_hInstance; #define TOX_SETTINGS_NODE_PKEY TOX_SETTINGS_NODE_PREFIX"%d_PubKey"
#define TOX_SETTINGS_NODE_COUNT TOX_SETTINGS_NODE_PREFIX"Count"
-#define TOX_DB_EVENT_TYPE_ACTION 10001
+enum TOX_DB_EVENT
+{
+ DB_EVENT_ACTION = 10001,
+ DB_EVENT_AUDIO_CALL = 20001
+};
+
+#define PSR_AUDIO "/RecvAudio"
#define TOX_MAX_AVATAR_SIZE 1024 * 1024
diff --git a/protocols/Tox/src/main.cpp b/protocols/Tox/src/main.cpp index b2af02340b..4d7cd0ab50 100644 --- a/protocols/Tox/src/main.cpp +++ b/protocols/Tox/src/main.cpp @@ -1,6 +1,7 @@ #include "common.h"
int hLangpack;
+CLIST_INTERFACE* pcli;
HINSTANCE g_hInstance;
HMODULE g_hToxLibrary = NULL;
@@ -31,7 +32,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) return &pluginInfo;
}
-extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST };
extern "C" int __declspec(dllexport) Load(void)
{
@@ -39,18 +40,16 @@ extern "C" int __declspec(dllexport) Load(void) if (g_hToxLibrary == NULL)
return 0;
+ mir_getCLI();
mir_getLP(&pluginInfo);
PROTOCOLDESCRIPTOR pd = { sizeof(pd) };
- pd.szName = MODULE;
+ pd.szName = "TOX";
pd.type = PROTOTYPE_PROTOCOL;
pd.fnInit = (pfnInitProto)CToxProto::InitAccount;
pd.fnUninit = (pfnUninitProto)CToxProto::UninitAccount;
CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd);
- CToxProto::InitIcons();
- CToxProto::InitMenus();
-
HookEvent(ME_SYSTEM_MODULESLOADED, &CToxProto::OnModulesLoaded);
return 0;
diff --git a/protocols/Tox/src/resource.h b/protocols/Tox/src/resource.h index 35c43d6488..8b06bab10e 100644 --- a/protocols/Tox/src/resource.h +++ b/protocols/Tox/src/resource.h @@ -11,6 +11,8 @@ #define IDD_OPTIONS_NODES 107
#define IDD_ADDNODE 108
#define IDD_NODE_EDITOR 109
+#define IDI_ICON1 109
+#define IDI_AUDIO_CALL 109
#define IDD_OPTIONS_AV 110
#define IDD_CHATROOM_INVITE 172
#define IDC_CCLIST 173
@@ -46,7 +48,7 @@ //
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 108
+#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1025
#define _APS_NEXT_SYMED_VALUE 101
diff --git a/protocols/Tox/src/tox_accounts.cpp b/protocols/Tox/src/tox_accounts.cpp index 21f884272c..5d1bf1886d 100644 --- a/protocols/Tox/src/tox_accounts.cpp +++ b/protocols/Tox/src/tox_accounts.cpp @@ -35,7 +35,7 @@ int CToxProto::OnAccountLoaded(WPARAM, LPARAM) HookProtoEvent(ME_USERINFO_INITIALISE, &CToxProto::OnUserInfoInit);
HookProtoEvent(ME_MSG_PRECREATEEVENT, &CToxProto::OnPreCreateMessage);
- //InitGroupChatModule
+ HookEvent(ME_DB_EVENT_ADDED, &CToxProto::OnDbEventAdded);
return 0;
}
diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index f5d72f8efc..3afc60f0bb 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -216,6 +216,36 @@ INT_PTR CToxProto::OnGrantAuth(WPARAM hContact, LPARAM) return 0;
}
+int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM)
+{
+ if (!IsOnline())
+ {
+ return -1;
+ }
+
+ if (!isChatRoom(hContact))
+ {
+ int32_t friendNumber = GetToxFriendNumber(hContact);
+ TOX_ERR_FRIEND_DELETE error;
+ if (!tox_friend_delete(tox, friendNumber, &error))
+ {
+ debugLogA(__FUNCTION__": failed to delete friend (%d)", error);
+ return error;
+ }
+ }
+ /*else
+ {
+ OnLeaveChatRoom(hContact, 0);
+ int groupNumber = 0; // ???
+ if (groupNumber == TOX_ERROR || tox_del_groupchat(tox, groupNumber) == TOX_ERROR)
+ {
+ return 1;
+ }
+ }*/
+
+ return 0;
+}
+
void CToxProto::OnFriendRequest(Tox*, const uint8_t *pubKey, const uint8_t *message, size_t length, void *arg)
{
CToxProto *proto = (CToxProto*)arg;
diff --git a/protocols/Tox/src/tox_events.cpp b/protocols/Tox/src/tox_events.cpp index 406999549a..255358d687 100644 --- a/protocols/Tox/src/tox_events.cpp +++ b/protocols/Tox/src/tox_events.cpp @@ -2,37 +2,69 @@ int CToxProto::OnModulesLoaded(WPARAM, LPARAM)
{
+ CToxProto::InitIcons();
+ CToxProto::InitMenus();
+ CToxProto::InitCustomDbEvents();
+
hProfileFolderPath = FoldersRegisterCustomPathT("Tox", Translate("Profiles folder"), MIRANDA_USERDATAT);
return 0;
}
-int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM)
+void CToxProto::InitCustomDbEvents()
{
- if (!IsOnline())
- {
- return -1;
- }
+ DBEVENTTYPEDESCR dbEventType = { sizeof(dbEventType) };
+ dbEventType.module = MODULE;
+ dbEventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
+
+ dbEventType.eventType = DB_EVENT_ACTION;
+ dbEventType.descr = Translate("Action");
+ CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType);
+
+ dbEventType.eventType = DB_EVENT_AUDIO_CALL;
+ dbEventType.descr = Translate("Audio call");
+ dbEventType.eventIcon = GetIconHandle("audio_call");
+ CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType);
+}
+
+int CToxProto::OnDbEventAdded(WPARAM hContact, LPARAM hEvent)
+{
+ DWORD dwSignature;
- if (!isChatRoom(hContact))
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.cbBlob = sizeof(DWORD);
+ dbei.pBlob = (PBYTE)&dwSignature;
+ db_event_get(hEvent, &dbei);
+ if (dbei.flags & (DBEF_SENT | DBEF_READ) || dbei.eventType <= DB_EVENT_ACTION || dwSignature == 0)
+ return 0;
+
+ DBEVENTTYPEDESCR *dbEventType = (DBEVENTTYPEDESCR*)CallService(MS_DB_EVENT_GETTYPE, (WPARAM)MODULE, dbei.eventType);
+ if (dbEventType == NULL)
+ return 0;
+
+ CLISTEVENT cle = { sizeof(cle) };
+ cle.flags |= CLEF_TCHAR;
+ cle.hContact = hContact;
+ cle.hDbEvent = hEvent;
+ cle.hIcon = Skin_GetIconByHandle(dbEventType->eventIcon);
+
+ TCHAR szTooltip[256];
+ mir_sntprintf(szTooltip, SIZEOF(szTooltip), _T("%s %s %s"), _A2T(dbEventType->descr), TranslateT("from"), pcli->pfnGetContactDisplayName(hContact, 0));
+ cle.ptszTooltip = szTooltip;
+
+ char szService[256];
+ switch (dbei.eventType)
{
- int32_t friendNumber = GetToxFriendNumber(hContact);
- TOX_ERR_FRIEND_DELETE error;
- if (!tox_friend_delete(tox, friendNumber, &error))
- {
- debugLogA(__FUNCTION__": failed to delete friend (%d)", error);
- return error;
- }
+ case DB_EVENT_AUDIO_CALL:
+ mir_snprintf(szService, SIZEOF(szService), "%s/AudioCall", GetContactProto(hContact));
+ break;
+
+ default: + return 0;
}
- /*else
- {
- OnLeaveChatRoom(hContact, 0);
- int groupNumber = 0; // ???
- if (groupNumber == TOX_ERROR || tox_del_groupchat(tox, groupNumber) == TOX_ERROR)
- {
- return 1;
- }
- }*/
+ cle.pszService = szService;
+
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle);
return 0;
}
\ No newline at end of file diff --git a/protocols/Tox/src/tox_icons.cpp b/protocols/Tox/src/tox_icons.cpp index 505dbec2e3..9a62c5069b 100644 --- a/protocols/Tox/src/tox_icons.cpp +++ b/protocols/Tox/src/tox_icons.cpp @@ -2,7 +2,8 @@ IconInfo CToxProto::Icons[] =
{
- { LPGENT("Protocol icon"), "main", IDI_TOX },
+ { LPGENT("Protocol icon"), "main", IDI_TOX },
+ { LPGENT("Audio call"), "audio_call", IDI_AUDIO_CALL },
};
void CToxProto::InitIcons()
@@ -27,18 +28,15 @@ void CToxProto::InitIcons() sid.ptszDescription = Icons[i].Description;
sid.iDefaultIndex = -Icons[i].IconId;
Icons[i].Handle = Skin_AddIcon(&sid);
- }
+ }
}
HANDLE CToxProto::GetIconHandle(const char *name)
{
for (size_t i = 0; i < SIZEOF(Icons); i++)
- {
if (mir_strcmpi(Icons[i].Name, name) == 0)
- {
return Icons[i].Handle;
- }
- }
+
return 0;
}
@@ -48,16 +46,13 @@ HANDLE CToxProto::GetSkinIconHandle(const char *name) mir_snprintf(iconName, SIZEOF(iconName), "%s_%s", MODULE, name);
HANDLE hIcon = Skin_GetIconHandle(iconName);
if (hIcon == NULL)
- {
hIcon = GetIconHandle(name);
- }
+
return hIcon;
}
void CToxProto::UninitIcons()
{
for (size_t i = 0; i < SIZEOF(Icons); i++)
- {
Skin_RemoveIcon(Icons[i].Name);
- }
}
\ No newline at end of file diff --git a/protocols/Tox/src/tox_messages.cpp b/protocols/Tox/src/tox_messages.cpp index 60de33d5d9..3a78ff5b76 100644 --- a/protocols/Tox/src/tox_messages.cpp +++ b/protocols/Tox/src/tox_messages.cpp @@ -27,7 +27,7 @@ void CToxProto::OnFriendMessage(Tox*, uint32_t friendNumber, TOX_MESSAGE_TYPE ty recv.timestamp = time(NULL);
recv.szMessage = rawMessage;
recv.lParam = type == TOX_MESSAGE_TYPE_NORMAL
- ? EVENTTYPE_MESSAGE : TOX_DB_EVENT_TYPE_ACTION;
+ ? EVENTTYPE_MESSAGE : DB_EVENT_ACTION;
ProtoChainRecvMsg(hContact, &recv);
@@ -117,7 +117,7 @@ int CToxProto::OnPreCreateMessage(WPARAM, LPARAM lParam) memcpy(action, &evt->dbei->pBlob[4], evt->dbei->cbBlob);
mir_free(evt->dbei->pBlob);
evt->dbei->pBlob = action;
- evt->dbei->eventType = TOX_DB_EVENT_TYPE_ACTION;
+ evt->dbei->eventType = DB_EVENT_ACTION;
return 0;
}
diff --git a/protocols/Tox/src/tox_multimedia.cpp b/protocols/Tox/src/tox_multimedia.cpp index 214f35f8d0..ba795bb0d7 100644 --- a/protocols/Tox/src/tox_multimedia.cpp +++ b/protocols/Tox/src/tox_multimedia.cpp @@ -1,6 +1,62 @@ #include "common.h"
-void CToxProto::OnAvInvite(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvInvite(void*, int32_t callId, void *arg)
+{
+ CToxProto *proto = (CToxProto*)arg;
+
+ int friendNumber = toxav_get_peer_id(proto->toxAv, callId, 0);
+ if (friendNumber == TOX_ERROR)
+ {
+ proto->debugLogA(__FUNCTION__": failed to get friend number");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ MCONTACT hContact = proto->GetContact(friendNumber);
+ if (hContact == NULL)
+ {
+ proto->debugLogA(__FUNCTION__": failed to get contact");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ ToxAvCSettings dest;
+ if (toxav_get_peer_csettings(proto->toxAv, callId, 0, &dest) != av_ErrorNone)
+ {
+ proto->debugLogA(__FUNCTION__": failed to get codec settings");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ if (dest.call_type != av_TypeAudio)
+ {
+ proto->debugLogA(__FUNCTION__": video call is unsupported");
+ toxav_reject(proto->toxAv, callId, Translate("Video call is unsupported"));
+ return;
+ }
+
+ PROTORECVEVENT recv = { 0 };
+ recv.timestamp = time(NULL);
+ recv.flags = PREF_UTF;
+ recv.szMessage = mir_utf8encodeT(TranslateT("Incoming call"));
+ ProtoChainRecv(hContact, PSR_AUDIO, hContact, (LPARAM)&recv);
+}
+
+INT_PTR CToxProto::OnRecvAudioCall(WPARAM hContact, LPARAM lParam)
+{
+ PROTORECVEVENT *pre = (PROTORECVEVENT*)lParam;
+
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.szModule = m_szModuleName;
+ dbei.timestamp = pre->timestamp;
+ dbei.flags = DBEF_UTF;
+ dbei.eventType = DB_EVENT_AUDIO_CALL;
+ dbei.cbBlob = (DWORD)mir_strlen(pre->szMessage) + 1;
+ dbei.pBlob = (PBYTE)pre->szMessage;
+
+ return (INT_PTR)db_event_add(hContact, &dbei);
+}
+
void CToxProto::OnAvRinging(void*, int32_t callId, void *arg) { }
void CToxProto::OnAvStart(void*, int32_t callId, void *arg) { }
void CToxProto::OnAvEnd(void*, int32_t callId, void *arg) { }
diff --git a/protocols/Tox/src/tox_profile.cpp b/protocols/Tox/src/tox_profile.cpp index 2affb68422..afbf5f577e 100644 --- a/protocols/Tox/src/tox_profile.cpp +++ b/protocols/Tox/src/tox_profile.cpp @@ -65,13 +65,16 @@ bool CToxProto::LoadToxProfile(Tox_Options *options) return false;
}
}
+ uint8_t *encryptedData = (uint8_t*)mir_calloc(size - TOX_PASS_ENCRYPTION_EXTRA_LENGTH);
TOX_ERR_DECRYPTION coreDecryptError;
- if (!tox_pass_decrypt(data, size, (uint8_t*)password, mir_strlen(password), data, &coreDecryptError))
+ if (!tox_pass_decrypt(data, size, (uint8_t*)password, mir_strlen(password), encryptedData, &coreDecryptError))
{
debugLogA(__FUNCTION__": failed to load tox profile (%d)", coreDecryptError);
mir_free(data);
return false;
}
+ mir_free(data);
+ data = encryptedData;
size -= TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
}
@@ -94,10 +97,11 @@ void CToxProto::SaveToxProfile() uint8_t *data = (uint8_t*)mir_calloc(size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH);
tox_get_savedata(tox, data);
- if (password && strlen(password))
+ size_t passwordLen = mir_strlen(password);
+ if (password && passwordLen)
{
TOX_ERR_ENCRYPTION coreEncryptError;
- if (!tox_pass_encrypt(data, size, (uint8_t*)password, strlen(password), data, &coreEncryptError))
+ if (!tox_pass_encrypt(data, size, (uint8_t*)password, passwordLen, data, &coreEncryptError))
{
debugLogA(__FUNCTION__": failed to encrypt tox profile");
mir_free(data);
diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index 03a1b1ad3a..55285f9b31 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -12,13 +12,8 @@ CToxProto::CToxProto(const char* protoName, const TCHAR* userName) : SetAllContactsStatus(ID_STATUS_OFFLINE);
- // custom event
- DBEVENTTYPEDESCR dbEventType = { sizeof(dbEventType) };
- dbEventType.module = m_szModuleName;
- dbEventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
- dbEventType.eventType = TOX_DB_EVENT_TYPE_ACTION;
- dbEventType.descr = Translate("Action");
- CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType);
+ // services
+ CreateProtoService(PSR_AUDIO, &CToxProto::OnRecvAudioCall);
// avatars
CreateProtoService(PS_GETAVATARCAPS, &CToxProto::GetAvatarCaps);
diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index 07d229c4d2..8d75753713 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -61,6 +61,8 @@ public: static void UninitMenus();
// events
+ static void InitCustomDbEvents();
+
static int OnModulesLoaded(WPARAM, LPARAM);
private:
@@ -135,7 +137,7 @@ private: int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam);
// events
- int __cdecl OnContactDeleted(MCONTACT, LPARAM);
+ static int __cdecl OnDbEventAdded(WPARAM hContact, LPARAM hEvent);
// userinfo
static INT_PTR CALLBACK UserInfoProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -160,6 +162,8 @@ private: INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM lParam);
INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM);
+ int __cdecl OnContactDeleted(MCONTACT, LPARAM);
+
static void OnFriendRequest(Tox *tox, const uint8_t *pubKey, const uint8_t *message, size_t length, void *arg);
static void OnFriendNameChange(Tox *tox, uint32_t friendNumber, const uint8_t *name, size_t length, void *arg);
static void OnStatusMessageChanged(Tox *tox, uint32_t friendNumber, const uint8_t *message, size_t length, void *arg);
@@ -250,6 +254,8 @@ private: static void OnAvRequestTimeout(void*, int32_t callId, void *arg);
static void OnAvPeerTimeout(void*, int32_t callId, void *arg);
+ INT_PTR __cdecl OnRecvAudioCall(WPARAM wParam, LPARAM lParam);
+
// utils
TOX_USER_STATUS MirandaToToxStatus(int status);
int ToxToMirandaStatus(TOX_USER_STATUS userstatus);
|