From 7df19254e64619d6b077a7c69b456a39d4a810cb Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 30 Jan 2015 23:30:48 +0000 Subject: - avatar support functions moved to the separate module; - added support for setting our own avatar git-svn-id: http://svn.miranda-ng.org/main/trunk@11963 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/WhatsApp_10.vcxproj | 1 + protocols/WhatsApp/WhatsApp_10.vcxproj.filters | 3 + protocols/WhatsApp/WhatsApp_12.vcxproj | 1 + protocols/WhatsApp/WhatsApp_12.vcxproj.filters | 3 + protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp | 12 +- protocols/WhatsApp/src/WhatsAPI++/WAConnection.h | 2 +- protocols/WhatsApp/src/avatars.cpp | 123 +++++++++++++++++++++ protocols/WhatsApp/src/common.h | 1 + protocols/WhatsApp/src/proto.cpp | 63 +---------- protocols/WhatsApp/src/proto.h | 2 + protocols/WhatsApp/src/version.h | 2 +- 11 files changed, 146 insertions(+), 67 deletions(-) create mode 100644 protocols/WhatsApp/src/avatars.cpp diff --git a/protocols/WhatsApp/WhatsApp_10.vcxproj b/protocols/WhatsApp/WhatsApp_10.vcxproj index 0d1f57f208..fcace9e0a4 100644 --- a/protocols/WhatsApp/WhatsApp_10.vcxproj +++ b/protocols/WhatsApp/WhatsApp_10.vcxproj @@ -172,6 +172,7 @@ + diff --git a/protocols/WhatsApp/WhatsApp_10.vcxproj.filters b/protocols/WhatsApp/WhatsApp_10.vcxproj.filters index 7ab73c9b4c..eb0a64d9d5 100644 --- a/protocols/WhatsApp/WhatsApp_10.vcxproj.filters +++ b/protocols/WhatsApp/WhatsApp_10.vcxproj.filters @@ -122,6 +122,9 @@ WhatsAPI++\Source Files + + Miranda Plugin\Source Files + diff --git a/protocols/WhatsApp/WhatsApp_12.vcxproj b/protocols/WhatsApp/WhatsApp_12.vcxproj index 5cb112c3a1..c38387e23a 100644 --- a/protocols/WhatsApp/WhatsApp_12.vcxproj +++ b/protocols/WhatsApp/WhatsApp_12.vcxproj @@ -174,6 +174,7 @@ + diff --git a/protocols/WhatsApp/WhatsApp_12.vcxproj.filters b/protocols/WhatsApp/WhatsApp_12.vcxproj.filters index 9dd21638c1..7511e22832 100644 --- a/protocols/WhatsApp/WhatsApp_12.vcxproj.filters +++ b/protocols/WhatsApp/WhatsApp_12.vcxproj.filters @@ -125,6 +125,9 @@ WhatsAPI++\Source Files + + Miranda Plugin\Source Files + diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp index 34b0f2a899..c08066426e 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp @@ -835,14 +835,18 @@ void WAConnection::sendQueryLastOnline(const std::string &jid) throw (WAExceptio << XATTR("id", id) << XATTR("type", "get") << XATTR("to", jid)); } -void WAConnection::sendSetPicture(const std::string &jid, std::vector* data) throw (WAException) +void WAConnection::sendSetPicture(const std::string &jid, std::vector* data, std::vector* preview) throw (WAException) { std::string id = this->makeId("set_photo_"); this->pending_server_requests[id] = new IqResultSetPhotoHandler(this, jid); - ProtocolTreeNode *listNode = new ProtocolTreeNode("picture", data, NULL) << XATTR("xmlns", "w:profile:picture"); - out.write(ProtocolTreeNode("iq", listNode) - << XATTR("id", id) << XATTR("type", "set") << XATTR("to", jid)); + std::vector* messageChildren = new std::vector(); + if (preview) + messageChildren->push_back(new ProtocolTreeNode("picture", preview, NULL) << XATTR("type", "preview")); + if (data) + messageChildren->push_back(new ProtocolTreeNode("picture", data, NULL) << XATTR("type", "image")); + out.write(ProtocolTreeNode("iq", NULL, messageChildren) + << XATTR("id", id) << XATTR("type", "set") << XATTR("to", jid) << XATTR("xmlns", "w:profile:picture")); } void WAConnection::sendStatusUpdate(std::string& status) throw (WAException) diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h index 6ed955caa7..6f4fb2b4f2 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h @@ -412,7 +412,7 @@ public: void sendSetNewSubject(const std::string& gjid, const std::string& subject) throw (WAException); void sendStatusUpdate(std::string& status) throw (WAException); void sendGetPicture(const std::string& jid, const std::string& type) throw (WAException); - void sendSetPicture(const std::string& jid, std::vector* data) throw (WAException); + void sendSetPicture(const std::string& jid, std::vector* data, std::vector* preview) throw (WAException); void sendNotificationReceived(const std::string& from, const std::string& id) throw(WAException); void sendDeleteAccount() throw(WAException); }; diff --git a/protocols/WhatsApp/src/avatars.cpp b/protocols/WhatsApp/src/avatars.cpp new file mode 100644 index 0000000000..8bdfe9212b --- /dev/null +++ b/protocols/WhatsApp/src/avatars.cpp @@ -0,0 +1,123 @@ +#include "common.h" + +INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) +{ + PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam; + + ptrA id(getStringA(AI->hContact, WHATSAPP_KEY_ID)); + if (id == NULL) + return GAIR_NOAVATAR; + + std::tstring tszFileName = GetAvatarFileName(AI->hContact); + _tcsncpy_s(AI->filename, tszFileName.c_str(), _TRUNCATE); + AI->format = PA_FORMAT_JPEG; + + ptrA szAvatarId(getStringA(AI->hContact, WHATSAPP_KEY_AVATAR_ID)); + if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0) + if (AI->hContact != NULL && m_pConnection != NULL) { + m_pConnection->sendGetPicture((const char*)id, "image"); + return GAIR_WAITFOR; + } + + debugLogA("No avatar"); + return GAIR_NOAVATAR; +} + +INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) +{ + switch (wParam) { + case AF_PROPORTION: + return PIP_SQUARE; + + case AF_FORMATSUPPORTED: // Jabber supports avatars of virtually all formats + return PA_FORMAT_JPEG; + + case AF_ENABLED: + return TRUE; + + case AF_MAXSIZE: + POINT *size = (POINT*)lParam; + if (size) + size->x = size->y = 640; + return 0; + } + return -1; +} + +std::tstring WhatsAppProto::GetAvatarFileName(MCONTACT hContact) +{ + std::tstring result = m_tszAvatarFolder + _T("\\"); + + std::string jid; + if (hContact != NULL) { + ptrA szId(getStringA(hContact, "ID")); + if (szId == NULL) + return _T(""); + + jid = szId; + } + else jid = m_szJid; + + return result + std::tstring(_A2T(jid.c_str())) + _T(".jpg"); +} + +INT_PTR WhatsAppProto::GetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + std::tstring tszOwnAvatar(m_tszAvatarFolder + _T("\\myavatar.jpg")); + _tcsncpy_s((TCHAR*)wParam, lParam, tszOwnAvatar.c_str(), _TRUNCATE); + return 0; +} + +static std::vector* sttFileToMem(const TCHAR *ptszFileName) +{ + HANDLE hFile = CreateFile(ptszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return NULL; + + DWORD upperSize, lowerSize = GetFileSize(hFile, &upperSize); + std::vector *result = new std::vector(lowerSize); + ReadFile(hFile, (void*)result->data(), lowerSize, &upperSize, NULL); + CloseHandle(hFile); + return result; +} + +INT_PTR WhatsAppProto::SetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + if (!isOnline()) + return 1; + + const TCHAR *ptszFileName = (const TCHAR*)lParam; + if (_taccess(ptszFileName, 4) != 0) + return errno; + + ResizeBitmap resize = { 0 }; + if ((resize.hBmp = (HBITMAP)CallService(MS_UTILS_LOADBITMAPT, 0, (LPARAM)ptszFileName)) == NULL) + return 2; + resize.size = sizeof(resize); + resize.fit = RESIZEBITMAP_KEEP_PROPORTIONS; + resize.max_height = resize.max_width = 96; + + HBITMAP hbmpPreview = (HBITMAP)CallService(MS_IMG_RESIZE, (LPARAM)&resize, 0); + if (hbmpPreview == NULL) + return 3; + + TCHAR tszTempFile[MAX_PATH], tszMyFile[MAX_PATH]; + mir_sntprintf(tszMyFile, SIZEOF(tszMyFile), _T("%s\\myavatar.jpg"), m_tszAvatarFolder.c_str()); + mir_sntprintf(tszTempFile, SIZEOF(tszTempFile), _T("%s\\myavatar.preview.jpg"), m_tszAvatarFolder.c_str()); + + IMGSRVC_INFO saveInfo = { sizeof(saveInfo), 0 }; + saveInfo.hbm = hbmpPreview; + saveInfo.tszName = tszTempFile; + saveInfo.dwMask = IMGI_HBITMAP; + saveInfo.fif = FIF_JPEG; + CallService(MS_IMG_SAVE, (WPARAM)&saveInfo, IMGL_TCHAR); + + if (hbmpPreview != resize.hBmp) + DeleteObject(hbmpPreview); + DeleteObject(resize.hBmp); + + CopyFile(ptszFileName, tszMyFile, FALSE); + + m_pConnection->sendSetPicture(m_szJid, sttFileToMem(ptszFileName), sttFileToMem(tszTempFile)); + return 0; +} diff --git a/protocols/WhatsApp/src/common.h b/protocols/WhatsApp/src/common.h index e6bff0462a..41a9dc1866 100644 --- a/protocols/WhatsApp/src/common.h +++ b/protocols/WhatsApp/src/common.h @@ -47,6 +47,7 @@ Copyright #include #include #include +#include #include #include #include diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index 0d7285bb60..42ec1990eb 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -23,6 +23,8 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : CreateProtoService(PS_GETAVATARINFOT, &WhatsAppProto::GetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, &WhatsAppProto::GetAvatarCaps); + CreateProtoService(PS_GETMYAVATART, &WhatsAppProto::GetMyAvatar); + CreateProtoService(PS_SETMYAVATART, &WhatsAppProto::SetMyAvatar); HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit); HookProtoEvent(ME_SYSTEM_MODULESLOADED, &WhatsAppProto::OnModulesLoaded); @@ -354,67 +356,6 @@ void WhatsAppProto::RequestFriendship(MCONTACT hContact) } } -INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) -{ - PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam; - - ptrA id(getStringA(AI->hContact, WHATSAPP_KEY_ID)); - if (id == NULL) - return GAIR_NOAVATAR; - - std::tstring tszFileName = GetAvatarFileName(AI->hContact); - _tcsncpy_s(AI->filename, tszFileName.c_str(), _TRUNCATE); - AI->format = PA_FORMAT_JPEG; - - ptrA szAvatarId(getStringA(AI->hContact, WHATSAPP_KEY_AVATAR_ID)); - if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0) - if (AI->hContact != NULL && m_pConnection != NULL) { - m_pConnection->sendGetPicture((const char*)id, "image"); - return GAIR_WAITFOR; - } - - debugLogA("No avatar"); - return GAIR_NOAVATAR; -} - -INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) { - case AF_PROPORTION: - return PIP_SQUARE; - - case AF_FORMATSUPPORTED: // Jabber supports avatars of virtually all formats - return PA_FORMAT_JPEG; - - case AF_ENABLED: - return TRUE; - - case AF_MAXSIZE: - POINT *size = (POINT*)lParam; - if (size) - size->x = size->y = 96; - return 0; - } - return -1; -} - -std::tstring WhatsAppProto::GetAvatarFileName(MCONTACT hContact) -{ - std::tstring result = m_tszAvatarFolder + _T("\\"); - - std::string jid; - if (hContact != NULL) { - ptrA szId(getStringA(hContact, "ID")); - if (szId == NULL) - return _T(""); - - jid = szId; - } - else jid = m_szJid; - - return result + std::tstring(_A2T(jid.c_str())) + _T(".jpg"); -} - LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index cff4d14f65..b0c5c8a6bf 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -151,6 +151,8 @@ private: INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM); INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM); + INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM); + INT_PTR __cdecl SetMyAvatar(WPARAM, LPARAM); ////////////////////////////////////////////////////////////////////////////////////// // Handles, Locks diff --git a/protocols/WhatsApp/src/version.h b/protocols/WhatsApp/src/version.h index f762aa15d7..5d83753125 100644 --- a/protocols/WhatsApp/src/version.h +++ b/protocols/WhatsApp/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 2 -#define __BUILD_NUM 5 +#define __BUILD_NUM 6 #include -- cgit v1.2.3