From 4d0735ab834be6c541e7e577fbe76c888bf4d09f Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Tue, 14 Apr 2015 20:32:40 +0000 Subject: Tox: second approach for audio support git-svn-id: http://svn.miranda-ng.org/main/trunk@12827 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/Tox_12.vcxproj | 1 + protocols/Tox/Tox_12.vcxproj.filters | 3 ++ protocols/Tox/res/resource.rc | 29 +++++--------- protocols/Tox/src/common.h | 12 ++++-- protocols/Tox/src/main.cpp | 9 ++--- protocols/Tox/src/resource.h | 4 +- protocols/Tox/src/tox_accounts.cpp | 2 +- protocols/Tox/src/tox_contacts.cpp | 30 ++++++++++++++ protocols/Tox/src/tox_events.cpp | 76 +++++++++++++++++++++++++----------- protocols/Tox/src/tox_icons.cpp | 15 +++---- protocols/Tox/src/tox_messages.cpp | 4 +- protocols/Tox/src/tox_multimedia.cpp | 58 ++++++++++++++++++++++++++- protocols/Tox/src/tox_profile.cpp | 10 +++-- protocols/Tox/src/tox_proto.cpp | 9 +---- protocols/Tox/src/tox_proto.h | 8 +++- 15 files changed, 195 insertions(+), 75 deletions(-) (limited to 'protocols') diff --git a/protocols/Tox/Tox_12.vcxproj b/protocols/Tox/Tox_12.vcxproj index ccca25ba81..fdc7534fea 100644 --- a/protocols/Tox/Tox_12.vcxproj +++ b/protocols/Tox/Tox_12.vcxproj @@ -255,6 +255,7 @@ copy docs\tox.ini "$(SolutionDir)$(Configuration)64\Plugins" /y + diff --git a/protocols/Tox/Tox_12.vcxproj.filters b/protocols/Tox/Tox_12.vcxproj.filters index 8eb7c5ef2e..88c4bd4376 100644 --- a/protocols/Tox/Tox_12.vcxproj.filters +++ b/protocols/Tox/Tox_12.vcxproj.filters @@ -168,5 +168,8 @@ Resource Files\Icons + + Resource Files\Icons + \ No newline at end of file diff --git a/protocols/Tox/res/resource.rc b/protocols/Tox/res/resource.rc index 93c44fb49d..13cd90fe18 100644 --- a/protocols/Tox/res/resource.rc +++ b/protocols/Tox/res/resource.rc @@ -12,25 +12,6 @@ ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// Neutral (Default) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD) -LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT -#pragma code_page(1251) - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_TOX ICON "icons\\tox.ico" -#endif // Neutral (Default) resources -///////////////////////////////////////////////////////////////////////////// - - ///////////////////////////////////////////////////////////////////////////// // Russian (Russia) resources @@ -74,6 +55,16 @@ END LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL #pragma code_page(1252) +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_TOX ICON "icons\\tox.ico" +IDI_AUDIO_CALL ICON "icons\\audio_call.ico" + ///////////////////////////////////////////////////////////////////////////// // // Dialog 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 #include -#include #include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include #include @@ -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); -- cgit v1.2.3