summaryrefslogtreecommitdiff
path: root/protocols/Tlen
diff options
context:
space:
mode:
authorRozhuk Ivan <rozhuk.im@gmail.com>2014-11-27 18:39:28 +0000
committerRozhuk Ivan <rozhuk.im@gmail.com>2014-11-27 18:39:28 +0000
commitfe7d09b9df2514c587376b924379ae1ccb1ff7a6 (patch)
treee1a934ec4642cf496c7d3489717bab878e467e5f /protocols/Tlen
parent6646a524809f33c1167128e85ef44b4990182894 (diff)
Tlen: code cleanup
git-svn-id: http://svn.miranda-ng.org/main/trunk@11119 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Tlen')
-rw-r--r--protocols/Tlen/src/tlen_avatar.cpp881
-rw-r--r--protocols/Tlen/src/tlen_opt.cpp1343
-rw-r--r--protocols/Tlen/src/tlen_xml.cpp1141
3 files changed, 1691 insertions, 1674 deletions
diff --git a/protocols/Tlen/src/tlen_avatar.cpp b/protocols/Tlen/src/tlen_avatar.cpp
index e6b1673ce0..6d468591bf 100644
--- a/protocols/Tlen/src/tlen_avatar.cpp
+++ b/protocols/Tlen/src/tlen_avatar.cpp
@@ -1,440 +1,441 @@
-/*
-
-Tlen Protocol Plugin for Miranda NG
-Copyright (C) 2004-2007 Piotr Piastucki
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-
-#include "tlen.h"
-#include "tlen_list.h"
-#include "tlen_avatar.h"
-#include <stdio.h>
-#include <io.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-/* TlenGetAvatarFileName() - gets a file name for the avatar image */
-
-void TlenGetAvatarFileName(TlenProtocol *proto, TLEN_LIST_ITEM *item, TCHAR* ptszDest, int cbLen)
-{
-
- int tPathLen = mir_sntprintf(ptszDest, cbLen, TEXT("%s\\%S"), VARST( TEXT("%miranda_avatarcache%")), proto->m_szModuleName);
- if (_taccess(ptszDest, 0)) {
- int ret = CreateDirectoryTreeT(ptszDest);
- if (ret == 0)
- proto->debugLog(_T("getAvatarFilename(): Created new directory for avatar cache: %s."), ptszDest);
- else {
- proto->debugLog(_T("getAvatarFilename(): Can not create directory for avatar cache: %s. errno=%d: %s"), ptszDest, errno, strerror(errno));
- TCHAR buffer[512];
- mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot create avatars cache directory. ERROR: %d: %s\n%s"), errno, _tcserror(errno), ptszDest);
- PUShowMessageT(buffer, SM_WARNING);
- }
- }
-
- int format = PA_FORMAT_PNG;
-
- ptszDest[ tPathLen++ ] = '\\';
- if (item != NULL)
- format = item->avatarFormat;
- else if (proto->threadData != NULL)
- format = proto->threadData->avatarFormat;
- else
- format = db_get_dw(NULL, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN);
-
- const TCHAR *tszFileType = ProtoGetAvatarExtension(format);
- if ( item != NULL )
- mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S%s"), ptrA( TlenSha1(item->jid)), tszFileType);
- else
- mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S_avatar%s"), proto->m_szModuleName, tszFileType);
-}
-
-static void RemoveAvatar(TlenProtocol *proto, MCONTACT hContact) {
- TCHAR tFileName[ MAX_PATH ];
- if (hContact == NULL) {
- proto->threadData->avatarHash[0] = '\0';
- }
- TlenGetAvatarFileName( proto, NULL, tFileName, sizeof tFileName );
- DeleteFile(tFileName);
- db_unset(hContact, "ContactPhoto", "File");
- db_unset(hContact, proto->m_szModuleName, "AvatarHash");
- db_unset(hContact, proto->m_szModuleName, "AvatarFormat");
- ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0);
-}
-
-static void SetAvatar(TlenProtocol *proto, MCONTACT hContact, TLEN_LIST_ITEM *item, char *data, int len, DWORD format) {
- TCHAR filename[MAX_PATH];
- char md5[33];
- mir_md5_state_t ctx;
- DWORD digest[4];
-
- if (format == PA_FORMAT_UNKNOWN && len > 4)
- format = ProtoGetBufferFormat(data);
-
- mir_md5_init( &ctx );
- mir_md5_append( &ctx, ( BYTE* )data, len);
- mir_md5_finish( &ctx, ( BYTE* )digest );
-
- sprintf( md5, "%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3])); //!!!!!!!!!!!!!!
- if (item != NULL) {
- char *hash = item->avatarHash;
- item->avatarFormat = format;
- item->avatarHash = mir_strdup(md5);
- mir_free(hash);
- } else {
- proto->threadData->avatarFormat = format;
- strcpy(proto->threadData->avatarHash, md5);
- }
- TlenGetAvatarFileName(proto, item, filename, sizeof filename );
- DeleteFile(filename);
- FILE *out = _tfopen(filename, TEXT("wb") );
- if (out != NULL) {
- fwrite(data, len, 1, out);
- fclose(out);
- db_set_ts(hContact, "ContactPhoto", "File", filename );
- db_set_s(hContact, proto->m_szModuleName, "AvatarHash", md5);
- db_set_dw(hContact, proto->m_szModuleName, "AvatarFormat", format);
- } else {
- TCHAR buffer[128];
- mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot save new avatar file \"%s\" Error:\n\t%s (Error: %d)"), filename, _tcserror(errno), errno);
- PUShowMessageT(buffer, SM_WARNING);
- proto->debugLog(buffer);
- return;
- }
- ProtoBroadcastAck( proto->m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL , 0);
-}
-
-int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, TLEN_LIST_ITEM *item) {
- XmlNode *aNode;
- char *oldHash = NULL;
- char *md5 = NULL, *type = NULL;
- MCONTACT hContact;
- hContact = NULL;
- if (item != NULL) {
- if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return 0;
- }
- if (item == NULL) {
- oldHash = proto->threadData->avatarHash;
- } else {
- oldHash = item->avatarHash;
- }
- if (avatarNode != NULL) {
- aNode = TlenXmlGetChild(avatarNode, "a");
- if (aNode != NULL) {
- type = TlenXmlGetAttrValue(aNode, "type");
- md5 = TlenXmlGetAttrValue(aNode, "md5");
- }
- }
- if (md5 != NULL) {
- /* check contact's avatar hash - md5 */
- if (oldHash == NULL || strcmp(oldHash, md5)) {
- if (item != NULL) {
- item->newAvatarDownloading = TRUE;
- }
- TlenGetAvatar(proto, hContact);
- return 1;
- }
- } else {
- /* remove avatar */
- if (oldHash != NULL) {
- if (item != NULL) {
- item->avatarHash = NULL;
- mir_free(oldHash);
- item->newAvatarDownloading = FALSE;
- }
- RemoveAvatar(proto, hContact);
- return 1;
- }
- }
- return 0;
-}
-
-void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, TLEN_LIST_ITEM *item) {
- MCONTACT hContact;
- if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return;
- TlenProcessAvatarNode(proto, TlenXmlGetChild(node, "avatar"), item);
-}
-
-
-static char *replaceTokens(const char *base, const char *uri, const char *login, const char* token, int type, int access) {
- char *result;
- int i, l, size;
- l = (int)strlen(uri);
- size = (int)strlen(base);
- for (i = 0; i < l; ) {
- if (!strncmp(uri + i, "^login^", 7)) {
- size += (int)strlen(login);
- i += 7;
- } else if (!strncmp(uri + i, "^type^", 6)) {
- size++;
- i += 6;
- } else if (!strncmp(uri + i, "^token^", 7)) {
- size += (int)strlen(token);
- i += 7;
- } else if (!strncmp(uri + i, "^access^", 8)) {
- size++;
- i += 8;
- } else {
- size++;
- i++;
- }
- }
- result = (char *)mir_alloc(size +1);
- strcpy(result, base);
- size = (int)strlen(base);
- for (i = 0; i < l; ) {
- if (!strncmp(uri + i, "^login^", 7)) {
- strcpy(result + size, login);
- size += (int)strlen(login);
- i += 7;
- } else if (!strncmp(uri + i, "^type^", 6)) {
- result[size++] = '0' + type;
- i += 6;
- } else if (!strncmp(uri + i, "^token^", 7)) {
- strcpy(result + size, token);
- size += (int)strlen(token);
- i += 7;
- } else if (!strncmp(uri + i, "^access^", 8)) {
- result[size++] = '0' + access;
- i += 8;
- } else {
- result[size++] = uri[i++];
- }
- }
- result[size] = '\0';
- return result;
-}
-
-
-static int getAvatarMutex = 0;
-
-typedef struct {
- TlenProtocol *proto;
- MCONTACT hContact;
-} TLENGETAVATARTHREADDATA;
-
-static void TlenGetAvatarThread(void *ptr) {
-
- TLEN_LIST_ITEM *item = NULL;
- NETLIBHTTPREQUEST req;
- NETLIBHTTPREQUEST *resp;
- TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)ptr;
- MCONTACT hContact = data->hContact;
- char *request;
- char *login = NULL;
- if (hContact != NULL) {
- char *jid = TlenJIDFromHContact(data->proto, hContact);
- login = TlenNickFromJID(jid);
- item = TlenListGetItemPtr(data->proto, LIST_ROSTER, jid);
- mir_free(jid);
- } else {
- login = mir_strdup(data->proto->threadData->username);
- }
- if ((data->proto->threadData != NULL && hContact == NULL) || item != NULL) {
- DWORD format = PA_FORMAT_UNKNOWN;
- if (item != NULL) {
- item->newAvatarDownloading = TRUE;
- }
- request = replaceTokens(data->proto->threadData->tlenConfig.mailBase, data->proto->threadData->tlenConfig.avatarGet, login, data->proto->threadData->avatarToken, 0, 0);
- ZeroMemory(&req, sizeof(req));
- req.cbSize = sizeof(req);
- req.requestType = data->proto->threadData->tlenConfig.avatarGetMthd;
- req.flags = 0;
- req.headersCount = 0;
- req.headers = NULL;
- req.dataLength = 0;
- req.szUrl = request;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)&req);
- if (item != NULL) {
- item->newAvatarDownloading = FALSE;
- }
- if (resp != NULL) {
- if (resp->resultCode/100 == 2) {
- if (resp->dataLength > 0) {
- int i;
- for (i=0; i<resp->headersCount; i++ ) {
- if (!strcmpi(resp->headers[i].szName, "Content-Type")) {
- if (!strcmpi(resp->headers[i].szValue, "image/png"))
- format = PA_FORMAT_PNG;
- else if (!strcmpi(resp->headers[i].szValue, "image/x-png"))
- format = PA_FORMAT_PNG;
- else if (!strcmpi(resp->headers[i].szValue, "image/jpeg"))
- format = PA_FORMAT_JPEG;
- else if (!strcmpi(resp->headers[i].szValue, "image/jpg"))
- format = PA_FORMAT_JPEG;
- else if (!strcmpi(resp->headers[i].szValue, "image/gif"))
- format = PA_FORMAT_GIF;
- else if (!strcmpi(resp->headers[i].szValue, "image/bmp"))
- format = PA_FORMAT_BMP;
-
- break;
- }
- }
- SetAvatar(data->proto, hContact, item, resp->pData, resp->dataLength, format);
- } else {
- RemoveAvatar(data->proto, hContact);
- }
- }
- CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
- }
- mir_free(request);
- mir_free(login);
- }
- if (hContact == NULL) {
- getAvatarMutex = 0;
- }
- mir_free(data);
-}
-
-void TlenGetAvatar(TlenProtocol *proto, MCONTACT hContact) {
- if (hContact == NULL) {
- if (getAvatarMutex != 0) {
- return;
- }
- getAvatarMutex = 1;
- }
- {
- TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)mir_alloc(sizeof(TLENGETAVATARTHREADDATA));
- data->proto = proto;
- data->hContact = hContact;
- forkthread(TlenGetAvatarThread, 0, data);
- }
-}
-
-typedef struct {
- TlenProtocol *proto;
- NETLIBHTTPREQUEST *req;
-} TLENREMOVEAVATARTHREADDATA;
-
-static void TlenRemoveAvatarRequestThread(void *ptr) {
- NETLIBHTTPREQUEST *resp;
- TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA*)ptr;
- NETLIBHTTPREQUEST *req = (NETLIBHTTPREQUEST *)data->req;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req);
- mir_free(req->szUrl);
- mir_free(req->headers);
- mir_free(req->pData);
- mir_free(req);
- if (resp != NULL) {
- CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
- RemoveAvatar(data->proto, NULL);
- }
- mir_free(data);
-
-}
-
-typedef struct {
- TlenProtocol *proto;
- NETLIBHTTPREQUEST *req;
- char *data;
- int length;
-} TLENUPLOADAVATARTHREADDATA;
-
-boolean checkUploadAvatarResponse(TlenProtocol *proto, NETLIBHTTPREQUEST *resp){
- if (resp == NULL){
- proto->debugLogA("Error while setting avatar on Tlen account (no response)");
- PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (no response)"), SM_WARNING);
- return false;
- }
- if (resp->resultCode != 200 || !resp->dataLength || !resp->pData) {
- proto->debugLogA("Error while setting avatar on Tlen account (invalid response) resultCode=%d, dataLength=%d", resp->resultCode, resp->dataLength);
- PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (invalid response)"), SM_WARNING);
- return false;
- }
- if (strncmp(resp->pData, "<ok", 3)){
- proto->debugLogA("Error while setting avatar on Tlen account: %s", resp->pData);
- PUShowMessageT(TranslateT("Error while setting avatar on Tlen account"), SM_WARNING);
- return false;
- }
- return true;
-}
-
-static void TlenUploadAvatarRequestThread(void *ptr) {
- NETLIBHTTPREQUEST *resp;
- TLENUPLOADAVATARTHREADDATA * data = (TLENUPLOADAVATARTHREADDATA *) ptr;
- NETLIBHTTPREQUEST *req = data->req;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req);
- if (checkUploadAvatarResponse(data->proto, resp)) {
- CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
- SetAvatar(data->proto, NULL, NULL, data->data, data->length, PA_FORMAT_PNG);
- }
- mir_free(req->szUrl);
- mir_free(req->headers);
- mir_free(req->pData);
- mir_free(req);
- mir_free(data->data);
- mir_free(data);
-}
-
-void TlenRemoveAvatar(TlenProtocol *proto) {
- NETLIBHTTPREQUEST *req;
- char *request;
- if (proto->threadData != NULL) {
- TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA *)mir_alloc(sizeof(TLENREMOVEAVATARTHREADDATA));
- req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST));
- data->proto =proto;
- data->req = req;
- request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarRemove, "", proto->threadData->avatarToken, 0, 0);
- ZeroMemory(req, sizeof(NETLIBHTTPREQUEST));
- req->cbSize = sizeof(NETLIBHTTPREQUEST);
- req->requestType = proto->threadData->tlenConfig.avatarGetMthd;
- req->szUrl = request;
- forkthread(TlenRemoveAvatarRequestThread, 0, data);
- }
-}
-
-
-void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access) {
- NETLIBHTTPREQUEST *req;
- NETLIBHTTPHEADER *headers;
- TLENUPLOADAVATARTHREADDATA *threadData;
- char *request;
- unsigned char *buffer;
- if (proto->threadData != NULL && dataLen > 0 && data != NULL) {
- char *mpartHead = "--AaB03x\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"plik.png\"\r\nContent-Type: image/png\r\n\r\n";
- char *mpartTail = "\r\n--AaB03x--\r\n";
- int size, sizeHead = (int)strlen(mpartHead), sizeTail = (int)strlen(mpartTail);
- request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarUpload, "", proto->threadData->avatarToken, 0, access);
- threadData = (TLENUPLOADAVATARTHREADDATA *)mir_alloc(sizeof(TLENUPLOADAVATARTHREADDATA));
- threadData->proto = proto;
- req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST));
- headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER));
- ZeroMemory(req, sizeof(NETLIBHTTPREQUEST));
- req->cbSize = sizeof(NETLIBHTTPREQUEST);
- req->requestType = proto->threadData->tlenConfig.avatarUploadMthd;
- req->szUrl = request;
- req->flags = 0;
- headers[0].szName = "Content-Type";
- headers[0].szValue = "multipart/form-data; boundary=AaB03x";
- req->headersCount = 1;
- req->headers = headers;
- size = dataLen + sizeHead + sizeTail;
- buffer = (unsigned char *)mir_alloc(size);
- memcpy(buffer, mpartHead, sizeHead);
- memcpy(buffer + sizeHead, data, dataLen);
- memcpy(buffer + sizeHead + dataLen, mpartTail, sizeTail);
- req->dataLength = size;
- req->pData = (char*)buffer;
- threadData->req = req;
- threadData->data = (char *) mir_alloc(dataLen);
- memcpy(threadData->data, data, dataLen);
- threadData->length = dataLen;
- forkthread(TlenUploadAvatarRequestThread, 0, threadData);
- }
-}
-
+/*
+
+Tlen Protocol Plugin for Miranda NG
+Copyright (C) 2004-2007 Piotr Piastucki
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+
+#include "tlen.h"
+#include "tlen_list.h"
+#include "tlen_avatar.h"
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* TlenGetAvatarFileName() - gets a file name for the avatar image */
+
+void TlenGetAvatarFileName(TlenProtocol *proto, TLEN_LIST_ITEM *item, TCHAR* ptszDest, int cbLen)
+{
+
+ int tPathLen = mir_sntprintf(ptszDest, cbLen, TEXT("%s\\%S"), VARST( TEXT("%miranda_avatarcache%")), proto->m_szModuleName);
+ if (_taccess(ptszDest, 0)) {
+ int ret = CreateDirectoryTreeT(ptszDest);
+ if (ret == 0)
+ proto->debugLog(_T("getAvatarFilename(): Created new directory for avatar cache: %s."), ptszDest);
+ else {
+ proto->debugLog(_T("getAvatarFilename(): Can not create directory for avatar cache: %s. errno=%d: %s"), ptszDest, errno, strerror(errno));
+ TCHAR buffer[512];
+ mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot create avatars cache directory. ERROR: %d: %s\n%s"), errno, _tcserror(errno), ptszDest);
+ PUShowMessageT(buffer, SM_WARNING);
+ }
+ }
+
+ int format = PA_FORMAT_PNG;
+
+ ptszDest[ tPathLen++ ] = '\\';
+ if (item != NULL)
+ format = item->avatarFormat;
+ else if (proto->threadData != NULL)
+ format = proto->threadData->avatarFormat;
+ else
+ format = db_get_dw(NULL, proto->m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN);
+
+ const TCHAR *tszFileType = ProtoGetAvatarExtension(format);
+ if ( item != NULL )
+ mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S%s"), ptrA( TlenSha1(item->jid)), tszFileType);
+ else
+ mir_sntprintf(ptszDest + tPathLen, MAX_PATH - tPathLen, TEXT("%S_avatar%s"), proto->m_szModuleName, tszFileType);
+}
+
+static void RemoveAvatar(TlenProtocol *proto, MCONTACT hContact) {
+ TCHAR tFileName[ MAX_PATH ];
+ if (hContact == NULL) {
+ proto->threadData->avatarHash[0] = '\0';
+ }
+ TlenGetAvatarFileName( proto, NULL, tFileName, sizeof tFileName );
+ DeleteFile(tFileName);
+ db_unset(hContact, "ContactPhoto", "File");
+ db_unset(hContact, proto->m_szModuleName, "AvatarHash");
+ db_unset(hContact, proto->m_szModuleName, "AvatarFormat");
+ ProtoBroadcastAck(proto->m_szModuleName, NULL, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0);
+}
+
+static void SetAvatar(TlenProtocol *proto, MCONTACT hContact, TLEN_LIST_ITEM *item, char *data, int len, DWORD format) {
+ TCHAR filename[MAX_PATH];
+ char md5[33];
+ mir_md5_state_t ctx;
+ DWORD digest[4];
+
+ if (format == PA_FORMAT_UNKNOWN && len > 4)
+ format = ProtoGetBufferFormat(data);
+
+ mir_md5_init( &ctx );
+ mir_md5_append( &ctx, ( BYTE* )data, len);
+ mir_md5_finish( &ctx, ( BYTE* )digest );
+
+ sprintf( md5, "%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3])); //!!!!!!!!!!!!!!
+ if (item != NULL) {
+ char *hash = item->avatarHash;
+ item->avatarFormat = format;
+ item->avatarHash = mir_strdup(md5);
+ mir_free(hash);
+ } else {
+ proto->threadData->avatarFormat = format;
+ strcpy(proto->threadData->avatarHash, md5);
+ }
+ TlenGetAvatarFileName(proto, item, filename, sizeof filename );
+ DeleteFile(filename);
+ FILE *out = _tfopen(filename, TEXT("wb") );
+ if (out != NULL) {
+ fwrite(data, len, 1, out);
+ fclose(out);
+ db_set_ts(hContact, "ContactPhoto", "File", filename );
+ db_set_s(hContact, proto->m_szModuleName, "AvatarHash", md5);
+ db_set_dw(hContact, proto->m_szModuleName, "AvatarFormat", format);
+ } else {
+ TCHAR buffer[128];
+ mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Cannot save new avatar file \"%s\" Error:\n\t%s (Error: %d)"), filename, _tcserror(errno), errno);
+ PUShowMessageT(buffer, SM_WARNING);
+ proto->debugLog(buffer);
+ return;
+ }
+ ProtoBroadcastAck( proto->m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL , 0);
+}
+
+int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, TLEN_LIST_ITEM *item) {
+ XmlNode *aNode;
+ char *oldHash = NULL;
+ char *md5 = NULL, *type = NULL;
+ MCONTACT hContact;
+ hContact = NULL;
+ if (item != NULL) {
+ if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return 0;
+ }
+ if (item == NULL) {
+ oldHash = proto->threadData->avatarHash;
+ } else {
+ oldHash = item->avatarHash;
+ }
+ if (avatarNode != NULL) {
+ aNode = TlenXmlGetChild(avatarNode, "a");
+ if (aNode != NULL) {
+ type = TlenXmlGetAttrValue(aNode, "type");
+ md5 = TlenXmlGetAttrValue(aNode, "md5");
+ }
+ }
+ if (md5 != NULL) {
+ /* check contact's avatar hash - md5 */
+ if (oldHash == NULL || strcmp(oldHash, md5)) {
+ if (item != NULL) {
+ item->newAvatarDownloading = TRUE;
+ }
+ TlenGetAvatar(proto, hContact);
+ return 1;
+ }
+ } else {
+ /* remove avatar */
+ if (oldHash != NULL) {
+ if (item != NULL) {
+ item->avatarHash = NULL;
+ mir_free(oldHash);
+ item->newAvatarDownloading = FALSE;
+ }
+ RemoveAvatar(proto, hContact);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, TLEN_LIST_ITEM *item) {
+ MCONTACT hContact;
+ if ((hContact=TlenHContactFromJID(proto, item->jid)) == NULL) return;
+ TlenProcessAvatarNode(proto, TlenXmlGetChild(node, "avatar"), item);
+}
+
+
+static char *replaceTokens(const char *base, const char *uri, const char *login, const char* token, int type, int access) {
+ char *result;
+ int i, l, size;
+ l = (int)strlen(uri);
+ size = (int)strlen(base);
+ for (i = 0; i < l; ) {
+ if (!strncmp(uri + i, "^login^", 7)) {
+ size += (int)strlen(login);
+ i += 7;
+ } else if (!strncmp(uri + i, "^type^", 6)) {
+ size++;
+ i += 6;
+ } else if (!strncmp(uri + i, "^token^", 7)) {
+ size += (int)strlen(token);
+ i += 7;
+ } else if (!strncmp(uri + i, "^access^", 8)) {
+ size++;
+ i += 8;
+ } else {
+ size++;
+ i++;
+ }
+ }
+ result = (char *)mir_alloc(size +1);
+ strcpy(result, base);
+ size = (int)strlen(base);
+ for (i = 0; i < l; ) {
+ if (!strncmp(uri + i, "^login^", 7)) {
+ strcpy(result + size, login);
+ size += (int)strlen(login);
+ i += 7;
+ } else if (!strncmp(uri + i, "^type^", 6)) {
+ result[size++] = '0' + type;
+ i += 6;
+ } else if (!strncmp(uri + i, "^token^", 7)) {
+ strcpy(result + size, token);
+ size += (int)strlen(token);
+ i += 7;
+ } else if (!strncmp(uri + i, "^access^", 8)) {
+ result[size++] = '0' + access;
+ i += 8;
+ } else {
+ result[size++] = uri[i++];
+ }
+ }
+ result[size] = '\0';
+ return result;
+}
+
+
+static int getAvatarMutex = 0;
+
+typedef struct {
+ TlenProtocol *proto;
+ MCONTACT hContact;
+} TLENGETAVATARTHREADDATA;
+
+static void TlenGetAvatarThread(void *ptr) {
+
+ TLEN_LIST_ITEM *item = NULL;
+ NETLIBHTTPREQUEST req;
+ NETLIBHTTPREQUEST *resp;
+ TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)ptr;
+ MCONTACT hContact = data->hContact;
+ char *request;
+ char *login = NULL;
+ if (hContact != NULL) {
+ char *jid = TlenJIDFromHContact(data->proto, hContact);
+ login = TlenNickFromJID(jid);
+ item = TlenListGetItemPtr(data->proto, LIST_ROSTER, jid);
+ mir_free(jid);
+ } else {
+ if (data->proto->threadData != NULL)
+ login = mir_strdup(data->proto->threadData->username);
+ }
+ if ((data->proto->threadData != NULL && hContact == NULL) || item != NULL) {
+ DWORD format = PA_FORMAT_UNKNOWN;
+ if (item != NULL) {
+ item->newAvatarDownloading = TRUE;
+ }
+ request = replaceTokens(data->proto->threadData->tlenConfig.mailBase, data->proto->threadData->tlenConfig.avatarGet, login, data->proto->threadData->avatarToken, 0, 0);
+ ZeroMemory(&req, sizeof(req));
+ req.cbSize = sizeof(req);
+ req.requestType = data->proto->threadData->tlenConfig.avatarGetMthd;
+ req.flags = 0;
+ req.headersCount = 0;
+ req.headers = NULL;
+ req.dataLength = 0;
+ req.szUrl = request;
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)&req);
+ if (item != NULL) {
+ item->newAvatarDownloading = FALSE;
+ }
+ if (resp != NULL) {
+ if (resp->resultCode/100 == 2) {
+ if (resp->dataLength > 0) {
+ int i;
+ for (i=0; i<resp->headersCount; i++ ) {
+ if (!strcmpi(resp->headers[i].szName, "Content-Type")) {
+ if (!strcmpi(resp->headers[i].szValue, "image/png"))
+ format = PA_FORMAT_PNG;
+ else if (!strcmpi(resp->headers[i].szValue, "image/x-png"))
+ format = PA_FORMAT_PNG;
+ else if (!strcmpi(resp->headers[i].szValue, "image/jpeg"))
+ format = PA_FORMAT_JPEG;
+ else if (!strcmpi(resp->headers[i].szValue, "image/jpg"))
+ format = PA_FORMAT_JPEG;
+ else if (!strcmpi(resp->headers[i].szValue, "image/gif"))
+ format = PA_FORMAT_GIF;
+ else if (!strcmpi(resp->headers[i].szValue, "image/bmp"))
+ format = PA_FORMAT_BMP;
+
+ break;
+ }
+ }
+ SetAvatar(data->proto, hContact, item, resp->pData, resp->dataLength, format);
+ } else {
+ RemoveAvatar(data->proto, hContact);
+ }
+ }
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
+ }
+ mir_free(request);
+ mir_free(login);
+ }
+ if (hContact == NULL) {
+ getAvatarMutex = 0;
+ }
+ mir_free(data);
+}
+
+void TlenGetAvatar(TlenProtocol *proto, MCONTACT hContact) {
+ if (hContact == NULL) {
+ if (getAvatarMutex != 0) {
+ return;
+ }
+ getAvatarMutex = 1;
+ }
+ {
+ TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)mir_alloc(sizeof(TLENGETAVATARTHREADDATA));
+ data->proto = proto;
+ data->hContact = hContact;
+ forkthread(TlenGetAvatarThread, 0, data);
+ }
+}
+
+typedef struct {
+ TlenProtocol *proto;
+ NETLIBHTTPREQUEST *req;
+} TLENREMOVEAVATARTHREADDATA;
+
+static void TlenRemoveAvatarRequestThread(void *ptr) {
+ NETLIBHTTPREQUEST *resp;
+ TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA*)ptr;
+ NETLIBHTTPREQUEST *req = (NETLIBHTTPREQUEST *)data->req;
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req);
+ mir_free(req->szUrl);
+ mir_free(req->headers);
+ mir_free(req->pData);
+ mir_free(req);
+ if (resp != NULL) {
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
+ RemoveAvatar(data->proto, NULL);
+ }
+ mir_free(data);
+
+}
+
+typedef struct {
+ TlenProtocol *proto;
+ NETLIBHTTPREQUEST *req;
+ char *data;
+ int length;
+} TLENUPLOADAVATARTHREADDATA;
+
+boolean checkUploadAvatarResponse(TlenProtocol *proto, NETLIBHTTPREQUEST *resp){
+ if (resp == NULL){
+ proto->debugLogA("Error while setting avatar on Tlen account (no response)");
+ PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (no response)"), SM_WARNING);
+ return false;
+ }
+ if (resp->resultCode != 200 || !resp->dataLength || !resp->pData) {
+ proto->debugLogA("Error while setting avatar on Tlen account (invalid response) resultCode=%d, dataLength=%d", resp->resultCode, resp->dataLength);
+ PUShowMessageT(TranslateT("Error while setting avatar on Tlen account (invalid response)"), SM_WARNING);
+ return false;
+ }
+ if (strncmp(resp->pData, "<ok", 3)){
+ proto->debugLogA("Error while setting avatar on Tlen account: %s", resp->pData);
+ PUShowMessageT(TranslateT("Error while setting avatar on Tlen account"), SM_WARNING);
+ return false;
+ }
+ return true;
+}
+
+static void TlenUploadAvatarRequestThread(void *ptr) {
+ NETLIBHTTPREQUEST *resp;
+ TLENUPLOADAVATARTHREADDATA * data = (TLENUPLOADAVATARTHREADDATA *) ptr;
+ NETLIBHTTPREQUEST *req = data->req;
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->m_hNetlibUser, (LPARAM)req);
+ if (checkUploadAvatarResponse(data->proto, resp)) {
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
+ SetAvatar(data->proto, NULL, NULL, data->data, data->length, PA_FORMAT_PNG);
+ }
+ mir_free(req->szUrl);
+ mir_free(req->headers);
+ mir_free(req->pData);
+ mir_free(req);
+ mir_free(data->data);
+ mir_free(data);
+}
+
+void TlenRemoveAvatar(TlenProtocol *proto) {
+ NETLIBHTTPREQUEST *req;
+ char *request;
+ if (proto->threadData != NULL) {
+ TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA *)mir_alloc(sizeof(TLENREMOVEAVATARTHREADDATA));
+ req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST));
+ data->proto =proto;
+ data->req = req;
+ request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarRemove, "", proto->threadData->avatarToken, 0, 0);
+ ZeroMemory(req, sizeof(NETLIBHTTPREQUEST));
+ req->cbSize = sizeof(NETLIBHTTPREQUEST);
+ req->requestType = proto->threadData->tlenConfig.avatarGetMthd;
+ req->szUrl = request;
+ forkthread(TlenRemoveAvatarRequestThread, 0, data);
+ }
+}
+
+
+void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access) {
+ NETLIBHTTPREQUEST *req;
+ NETLIBHTTPHEADER *headers;
+ TLENUPLOADAVATARTHREADDATA *threadData;
+ char *request;
+ unsigned char *buffer;
+ if (proto->threadData != NULL && dataLen > 0 && data != NULL) {
+ char *mpartHead = "--AaB03x\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"plik.png\"\r\nContent-Type: image/png\r\n\r\n";
+ char *mpartTail = "\r\n--AaB03x--\r\n";
+ int size, sizeHead = (int)strlen(mpartHead), sizeTail = (int)strlen(mpartTail);
+ request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarUpload, "", proto->threadData->avatarToken, 0, access);
+ threadData = (TLENUPLOADAVATARTHREADDATA *)mir_alloc(sizeof(TLENUPLOADAVATARTHREADDATA));
+ threadData->proto = proto;
+ req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST));
+ headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER));
+ ZeroMemory(req, sizeof(NETLIBHTTPREQUEST));
+ req->cbSize = sizeof(NETLIBHTTPREQUEST);
+ req->requestType = proto->threadData->tlenConfig.avatarUploadMthd;
+ req->szUrl = request;
+ req->flags = 0;
+ headers[0].szName = "Content-Type";
+ headers[0].szValue = "multipart/form-data; boundary=AaB03x";
+ req->headersCount = 1;
+ req->headers = headers;
+ size = dataLen + sizeHead + sizeTail;
+ buffer = (unsigned char *)mir_alloc(size);
+ memcpy(buffer, mpartHead, sizeHead);
+ memcpy(buffer + sizeHead, data, dataLen);
+ memcpy(buffer + sizeHead + dataLen, mpartTail, sizeTail);
+ req->dataLength = size;
+ req->pData = (char*)buffer;
+ threadData->req = req;
+ threadData->data = (char *) mir_alloc(dataLen);
+ memcpy(threadData->data, data, dataLen);
+ threadData->length = dataLen;
+ forkthread(TlenUploadAvatarRequestThread, 0, threadData);
+ }
+}
+
diff --git a/protocols/Tlen/src/tlen_opt.cpp b/protocols/Tlen/src/tlen_opt.cpp
index 5e6d26ebd3..110124bced 100644
--- a/protocols/Tlen/src/tlen_opt.cpp
+++ b/protocols/Tlen/src/tlen_opt.cpp
@@ -1,665 +1,678 @@
-/*
-
-Jabber Protocol Plugin for Miranda IM
-Tlen Protocol Plugin for Miranda NG
-Copyright (C) 2002-2004 Santithorn Bunchua
-Copyright (C) 2004-2007 Piotr Piastucki
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-#include "tlen.h"
-#include "tlen_list.h"
-#include "tlen_voice.h"
-#include <commctrl.h>
-#include "resource.h"
-
-static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-
-typedef struct TabDefStruct {
- DLGPROC dlgProc;
- DWORD dlgId;
- TCHAR *tabName;
-} TabDef;
-
-static TabDef tabPages[] = {
- {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, LPGENT("General")},
- {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, LPGENT("Voice Chats")},
- {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, LPGENT("Advanced")},
- {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, LPGENT("Notifications")}
- };
-
-void TlenLoadOptions(TlenProtocol *proto)
-{
- proto->tlenOptions.savePassword = db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE);
- proto->tlenOptions.useEncryption = db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE);
- proto->tlenOptions.reconnect = db_get_b(NULL, proto->m_szModuleName, "Reconnect", TRUE);
- proto->tlenOptions.alertPolicy = db_get_w(NULL, proto->m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR);
- proto->tlenOptions.rosterSync = db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE);
- proto->tlenOptions.offlineAsInvisible = db_get_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", FALSE);
- proto->tlenOptions.leaveOfflineMessage = db_get_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", TRUE);
- proto->tlenOptions.offlineMessageOption = db_get_w(NULL, proto->m_szModuleName, "OfflineMessageOption", 0);
- proto->tlenOptions.ignoreAdvertisements = db_get_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", TRUE);
- proto->tlenOptions.groupChatPolicy = db_get_w(NULL, proto->m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK);
- proto->tlenOptions.voiceChatPolicy = db_get_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK);
- proto->tlenOptions.imagePolicy = db_get_w(NULL, proto->m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR);
- proto->tlenOptions.enableAvatars = db_get_b(NULL, proto->m_szModuleName, "EnableAvatars", TRUE);
- proto->tlenOptions.enableVersion = db_get_b(NULL, proto->m_szModuleName, "EnableVersion", TRUE);
- proto->tlenOptions.useNudge = db_get_b(NULL, proto->m_szModuleName, "UseNudge", FALSE);
- proto->tlenOptions.logAlerts = db_get_b(NULL, proto->m_szModuleName, "LogAlerts", TRUE);
- proto->tlenOptions.sendKeepAlive = db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE);
- proto->tlenOptions.useNewP2P = TRUE;
-}
-
-static int changed = 0;
-
-static void ApplyChanges(TlenProtocol *proto, int i) {
- changed &= ~i;
- if (changed == 0) {
- TlenLoadOptions(proto);
- }
-}
-
-static void MarkChanges(int i, HWND hWnd) {
- SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
- changed |= i;
-}
-
-
-int TlenProtocol::OptionsInit(WPARAM wParam, LPARAM)
-{
- OPTIONSDIALOGPAGE odp = { sizeof(odp) };
- odp.hInstance = hInst;
- odp.ptszGroup = LPGENT("Network");
- odp.ptszTitle = m_tszUserName;
- odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
- odp.dwInitParam = (LPARAM)this;
- for (int i = 0; i < SIZEOF(tabPages); i++) {
- odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId);
- odp.pfnDlgProc = tabPages[i].dlgProc;
- odp.ptszTab = tabPages[i].tabName;
- Options_AddPage(wParam, &odp);
- }
- return 0;
-}
-
-static LRESULT CALLBACK TlenValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_CHAR:
- if (strchr("\"&'/:<>@", wParam&0xff) != NULL)
- return 0;
- break;
- }
- return mir_callNextSubclass(hwndEdit, TlenValidateUsernameWndProc, msg, wParam, lParam);
-}
-
-INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- char text[256];
-
- TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- switch (msg) {
- case WM_INITDIALOG:
- {
- DBVARIANT dbv;
- proto = (TlenProtocol *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
- TranslateDialogDefault(hwndDlg);
- if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal);
- db_free(&dbv);
- }
- if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) {
- SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal);
- db_free(&dbv);
- }
- CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE));
-
- mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc);
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_EDIT_USERNAME:
- case IDC_EDIT_PASSWORD:
- if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE)
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- case IDC_SAVEPASSWORD:
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- case IDC_REGISTERACCOUNT:
- CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER);
- break;
- }
- break;
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- BOOL reconnectRequired = FALSE;
- DBVARIANT dbv;
-
- GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text));
- if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal))
- reconnectRequired = TRUE;
- if (dbv.pszVal != NULL) db_free(&dbv);
- db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text));
-
- if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) {
- GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text));
- if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal))
- reconnectRequired = TRUE;
- if (dbv.pszVal != NULL) db_free(&dbv);
- db_set_s(NULL, proto->m_szModuleName, "Password", text);
- }
- else
- db_unset(NULL, proto->m_szModuleName, "Password");
-
- db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD));
- if (reconnectRequired && proto->isConnected)
- MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND);
- TlenLoadOptions(proto);
- return TRUE;
- }
- }
- break;
- }
- return FALSE;
-}
-
-static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- char text[256];
-
- TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- switch (msg) {
- case WM_INITDIALOG:
- {
- DBVARIANT dbv;
- proto = (TlenProtocol *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
- TranslateDialogDefault(hwndDlg);
- if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal);
- db_free(&dbv);
- }
- if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) {
- SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal);
- db_free(&dbv);
- }
- CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE));
-
- CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect);
- CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync);
- CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible);
- CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage);
- CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements);
- CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars);
- CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion);
- CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge);
- CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts);
-
- SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts"));
- SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts"));
- SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts"));
- SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0);
-
- SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me"));
- SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts"));
- SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations"));
- SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts"));
- SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation"));
- SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0);
-
- SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images"));
- SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts"));
- SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images"));
- SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0);
-
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("<Last message>"));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_ONLINE, 0));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_AWAY, 0));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_NA, 0));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_DND, 0));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_FREECHAT, 0));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_INVISIBLE, 0));
- SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0);
-
- mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc);
- return TRUE;
- }
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_EDIT_USERNAME:
- case IDC_EDIT_PASSWORD:
- if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE)
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- // Fall through
- case IDC_SAVEPASSWORD:
- case IDC_RECONNECT:
- case IDC_ROSTER_SYNC:
- case IDC_IGNORE_ADVERTISEMENTS:
- case IDC_SHOW_OFFLINE:
- case IDC_OFFLINE_MESSAGE:
- MarkChanges(1, hwndDlg);
- break;
- case IDC_LOG_ALERTS:
- CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED);
- MarkChanges(1, hwndDlg);
- break;
- case IDC_NUDGE_SUPPORT:
- CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED);
- MarkChanges(1, hwndDlg);
- break;
- case IDC_REGISTERACCOUNT:
- CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER);
- break;
- case IDC_OFFLINE_MESSAGE_OPTION:
- case IDC_ALERT_POLICY:
- case IDC_MUC_POLICY:
- if (HIWORD(wParam) == CBN_SELCHANGE)
- MarkChanges(1, hwndDlg);
- break;
- default:
- MarkChanges(1, hwndDlg);
- break;
- }
- break;
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- BOOL reconnectRequired = FALSE;
- DBVARIANT dbv;
-
- GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text));
- if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal))
- reconnectRequired = TRUE;
- if (dbv.pszVal != NULL) db_free(&dbv);
- db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text));
-
- if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) {
- GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text));
- if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal))
- reconnectRequired = TRUE;
- if (dbv.pszVal != NULL) db_free(&dbv);
- db_set_s(NULL, proto->m_szModuleName, "Password", text);
- }
- else
- db_unset(NULL, proto->m_szModuleName, "Password");
-
- db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD));
- db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT));
- db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC));
- db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE));
- db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS));
- db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE));
- db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0));
- db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0));
- db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0));
- db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0));
- db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS));
- db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO));
- db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT));
- db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS));
- if (reconnectRequired && proto->isConnected)
- MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND);
- ApplyChanges(proto, 1);
- return TRUE;
- }
- }
- break;
- }
- return FALSE;
-}
-
-static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- switch (msg) {
- case WM_INITDIALOG:
- {
- TranslateDialogDefault(hwndDlg);
- proto = (TlenProtocol *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
- SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me"));
- SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts"));
- SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations"));
- SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts"));
- SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation"));
- SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0);
- TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN));
- TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT));
- return TRUE;
- }
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_VOICE_POLICY:
- case IDC_VOICE_DEVICE_IN:
- case IDC_VOICE_DEVICE_OUT:
- if (HIWORD(wParam) == CBN_SELCHANGE)
- MarkChanges(2, hwndDlg);
- break;
- }
- break;
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- db_set_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0));
- db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0));
- db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0));
- ApplyChanges(proto, 2);
- return TRUE;
- }
- }
- break;
- }
-
- return FALSE;
-}
-
-static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- char text[256];
- BOOL bChecked;
- TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- {
- DBVARIANT dbv;
- proto = (TlenProtocol *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
- TranslateDialogDefault(hwndDlg);
- if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal);
- db_free(&dbv);
- }
- else SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl"));
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE);
- EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE);
-
- if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal);
- db_free(&dbv);
- }
- else SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl"));
-
- SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE);
-
- CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE));
-
- CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE));
-
- CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE));
- // File transfer options
- bChecked = FALSE;
- if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) {
- bChecked = TRUE;
- CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE);
- }
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked);
- if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE)
- CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE);
- else
- bChecked = FALSE;
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked);
-
- SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding"));
- SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS4"));
- SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS5"));
- SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0);
- if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal);
- db_free(&dbv);
- }
- SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE);
- if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal);
- db_free(&dbv);
- }
- if (!db_get_s(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) {
- SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal);
- db_free(&dbv);
- }
- return TRUE;
- }
- case WM_COMMAND:
- {
- switch (LOWORD(wParam)) {
- case IDC_FILE_PROXY_TYPE:
- if (HIWORD(wParam) == CBN_SELCHANGE)
- MarkChanges(4, hwndDlg);
- break;
- case IDC_EDIT_LOGIN_SERVER:
- case IDC_HOST:
- case IDC_HOSTPORT:
- case IDC_FILE_PROXY_HOST:
- case IDC_FILE_PROXY_PORT:
- case IDC_FILE_PROXY_USER:
- case IDC_FILE_PROXY_PASSWORD:
- if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE)
- MarkChanges(4, hwndDlg);
- break;
- case IDC_FILE_USE_PROXY:
- bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked);
- case IDC_FILE_PROXY_USE_AUTH:
- bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked);
- EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked);
- MarkChanges(4, hwndDlg);
- break;
- case IDC_KEEPALIVE:
- case IDC_VISIBILITY_SUPPORT:
- case IDC_USE_SSL:
- MarkChanges(4, hwndDlg);
- break;
- }
- }
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- WORD port;
- BOOL useEncryption;
- BOOL reconnectRequired = FALSE;
- DBVARIANT dbv;
- GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text));
- if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal))
- reconnectRequired = TRUE;
- if (dbv.pszVal != NULL) db_free(&dbv);
- db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text));
-
- GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text));
- if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal))
- reconnectRequired = TRUE;
- if (dbv.pszVal != NULL) db_free(&dbv);
- db_set_s(NULL, proto->m_szModuleName, "ManualHost", text);
-
- port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE);
- if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port)
- reconnectRequired = TRUE;
- db_set_w(NULL, proto->m_szModuleName, "ManualPort", port);
-
- proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE);
- db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive);
-
- useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL);
- if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption)
- reconnectRequired = TRUE;
- db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption);
-
- db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT));
-
- // File transfer options
- db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY));
- db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0));
-
- GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text));
- db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text);
-
- db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE));
- db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH));
-
- GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text));
- db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text);
-
- GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text));
- db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text);
-
- if (reconnectRequired && proto->isConnected)
- MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND);
- ApplyChanges(proto, 4);
- return TRUE;
- }
- break;
- }
-
- return FALSE;
-}
-
-#define POPUP_DEFAULT_COLORBKG 0xDCBDA5
-#define POPUP_DEFAULT_COLORTXT 0x000000
-
-static void MailPopupPreview(DWORD colorBack, DWORD colorText, TCHAR *title, TCHAR *emailInfo, int delay)
-{
- POPUPDATAT ppd = { 0 };
- HICON hIcon = GetIcolibIcon(IDI_MAIL);
- ppd.lchIcon = CopyIcon(hIcon);
- ReleaseIcolibIcon(hIcon);
- _tcscpy(ppd.lptzContactName, title);
- _tcscpy(ppd.lptzText, emailInfo);
- ppd.colorBack = colorBack;
- ppd.colorText = colorText;
- ppd.iSeconds = delay;
- if ( ServiceExists(MS_POPUP_ADDPOPUPT))
- PUAddPopupT(&ppd);
-}
-
-static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- switch (msg) {
- case WM_INITDIALOG:
- {
- BYTE delayMode;
- proto = (TlenProtocol *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
- TranslateDialogDefault(hwndDlg);
- CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE));
- SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG));
- SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT));
- SetDlgItemInt(hwndDlg, IDC_DELAY, db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4), FALSE);
- delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0);
- if (delayMode == 1) {
- CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE);
- } else if (delayMode == 2) {
- CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE);
- } else {
- CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE);
- }
- return TRUE;
- }
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_COLORTXT:
- case IDC_COLORBKG:
- case IDC_ENABLEPOPUP:
- case IDC_DELAY:
- case IDC_DELAY_POPUP:
- case IDC_DELAY_CUSTOM:
- case IDC_DELAY_PERMANENT:
- MarkChanges(8, hwndDlg);
- break;
- case IDC_PREVIEW:
- {
- int delay;
- TCHAR title[256];
- if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) {
- delay=0;
- } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) {
- delay=-1;
- } else {
- delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE);
- }
- mir_sntprintf(title, SIZEOF(title), TranslateT("%S mail"), proto->m_szModuleName);
- MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0),
- (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0),
- title,
- _T("From: test@test.test\nSubject: test"),
- delay);
- }
-
- }
- break;
-
-
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- BYTE delayMode;
- db_set_b(NULL, proto->m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP));
- db_set_dw(NULL, proto->m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0));
- db_set_dw(NULL, proto->m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0));
- db_set_dw(NULL, proto->m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE));
- delayMode=0;
- if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) {
- delayMode=1;
- } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) {
- delayMode=2;
-
- }
- db_set_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", delayMode);
- ApplyChanges(proto, 8);
- return TRUE;
- }
- }
- break;
-
- }
- return FALSE;
-}
-
+/*
+
+Jabber Protocol Plugin for Miranda IM
+Tlen Protocol Plugin for Miranda NG
+Copyright (C) 2002-2004 Santithorn Bunchua
+Copyright (C) 2004-2007 Piotr Piastucki
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "tlen.h"
+#include "tlen_list.h"
+#include "tlen_voice.h"
+#include <commctrl.h>
+#include "resource.h"
+
+static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+typedef struct TabDefStruct {
+ DLGPROC dlgProc;
+ DWORD dlgId;
+ TCHAR *tabName;
+} TabDef;
+
+static TabDef tabPages[] = {
+ {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, LPGENT("General")},
+ {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, LPGENT("Voice Chats")},
+ {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, LPGENT("Advanced")},
+ {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, LPGENT("Notifications")}
+ };
+
+void TlenLoadOptions(TlenProtocol *proto)
+{
+ proto->tlenOptions.savePassword = db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE);
+ proto->tlenOptions.useEncryption = db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE);
+ proto->tlenOptions.reconnect = db_get_b(NULL, proto->m_szModuleName, "Reconnect", TRUE);
+ proto->tlenOptions.alertPolicy = db_get_w(NULL, proto->m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR);
+ proto->tlenOptions.rosterSync = db_get_b(NULL, proto->m_szModuleName, "RosterSync", FALSE);
+ proto->tlenOptions.offlineAsInvisible = db_get_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", FALSE);
+ proto->tlenOptions.leaveOfflineMessage = db_get_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", TRUE);
+ proto->tlenOptions.offlineMessageOption = db_get_w(NULL, proto->m_szModuleName, "OfflineMessageOption", 0);
+ proto->tlenOptions.ignoreAdvertisements = db_get_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", TRUE);
+ proto->tlenOptions.groupChatPolicy = db_get_w(NULL, proto->m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK);
+ proto->tlenOptions.voiceChatPolicy = db_get_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK);
+ proto->tlenOptions.imagePolicy = db_get_w(NULL, proto->m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR);
+ proto->tlenOptions.enableAvatars = db_get_b(NULL, proto->m_szModuleName, "EnableAvatars", TRUE);
+ proto->tlenOptions.enableVersion = db_get_b(NULL, proto->m_szModuleName, "EnableVersion", TRUE);
+ proto->tlenOptions.useNudge = db_get_b(NULL, proto->m_szModuleName, "UseNudge", FALSE);
+ proto->tlenOptions.logAlerts = db_get_b(NULL, proto->m_szModuleName, "LogAlerts", TRUE);
+ proto->tlenOptions.sendKeepAlive = db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE);
+ proto->tlenOptions.useNewP2P = TRUE;
+}
+
+static int changed = 0;
+
+static void ApplyChanges(TlenProtocol *proto, int i) {
+ changed &= ~i;
+ if (changed == 0) {
+ TlenLoadOptions(proto);
+ }
+}
+
+static void MarkChanges(int i, HWND hWnd) {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ changed |= i;
+}
+
+
+int TlenProtocol::OptionsInit(WPARAM wParam, LPARAM)
+{
+ OPTIONSDIALOGPAGE odp = { sizeof(odp) };
+ odp.hInstance = hInst;
+ odp.ptszGroup = LPGENT("Network");
+ odp.ptszTitle = m_tszUserName;
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
+ odp.dwInitParam = (LPARAM)this;
+ for (int i = 0; i < SIZEOF(tabPages); i++) {
+ odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId);
+ odp.pfnDlgProc = tabPages[i].dlgProc;
+ odp.ptszTab = tabPages[i].tabName;
+ Options_AddPage(wParam, &odp);
+ }
+ return 0;
+}
+
+static LRESULT CALLBACK TlenValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_CHAR:
+ if (strchr("\"&'/:<>@", wParam&0xff) != NULL)
+ return 0;
+ break;
+ }
+ return mir_callNextSubclass(hwndEdit, TlenValidateUsernameWndProc, msg, wParam, lParam);
+}
+
+INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ char text[256];
+
+ TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ proto = (TlenProtocol *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
+ TranslateDialogDefault(hwndDlg);
+ if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal);
+ db_free(&dbv);
+ }
+ if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal);
+ db_free(&dbv);
+ }
+ CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE));
+
+ mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_EDIT_USERNAME:
+ case IDC_EDIT_PASSWORD:
+ if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_SAVEPASSWORD:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_REGISTERACCOUNT:
+ CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ BOOL reconnectRequired = FALSE;
+ DBVARIANT dbv;
+
+ GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text));
+ dbv.pszVal = NULL;
+ if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || lstrcmpA(text, dbv.pszVal))
+ reconnectRequired = TRUE;
+ if (dbv.pszVal != NULL)
+ db_free(&dbv);
+ db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text));
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) {
+ GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text));
+ dbv.pszVal = NULL;
+ if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || lstrcmpA(text, dbv.pszVal))
+ reconnectRequired = TRUE;
+ if (dbv.pszVal != NULL)
+ db_free(&dbv);
+ db_set_s(NULL, proto->m_szModuleName, "Password", text);
+ }
+ else
+ db_unset(NULL, proto->m_szModuleName, "Password");
+
+ db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD));
+ if (reconnectRequired && proto->isConnected)
+ MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND);
+ TlenLoadOptions(proto);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ char text[256];
+
+ TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ proto = (TlenProtocol *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
+ TranslateDialogDefault(hwndDlg);
+ if (!db_get_ts(NULL, proto->m_szModuleName, "LoginName", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal);
+ db_free(&dbv);
+ }
+ if (!db_get(NULL, proto->m_szModuleName, "Password", &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal);
+ db_free(&dbv);
+ }
+ CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, db_get_b(NULL, proto->m_szModuleName, "SavePassword", TRUE));
+
+ CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect);
+ CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync);
+ CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible);
+ CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage);
+ CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements);
+ CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars);
+ CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion);
+ CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge);
+ CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts);
+
+ SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts"));
+ SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts"));
+ SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts"));
+ SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me"));
+ SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts"));
+ SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations"));
+ SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts"));
+ SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation"));
+ SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images"));
+ SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts"));
+ SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images"));
+ SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("<Last message>"));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_ONLINE, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_AWAY, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_NA, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_DND, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_FREECHAT, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(ID_STATUS_INVISIBLE, 0));
+ SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0);
+
+ mir_subclassWindow(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), TlenValidateUsernameWndProc);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_EDIT_USERNAME:
+ case IDC_EDIT_PASSWORD:
+ if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ // Fall through
+ case IDC_SAVEPASSWORD:
+ case IDC_RECONNECT:
+ case IDC_ROSTER_SYNC:
+ case IDC_IGNORE_ADVERTISEMENTS:
+ case IDC_SHOW_OFFLINE:
+ case IDC_OFFLINE_MESSAGE:
+ MarkChanges(1, hwndDlg);
+ break;
+ case IDC_LOG_ALERTS:
+ CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED);
+ MarkChanges(1, hwndDlg);
+ break;
+ case IDC_NUDGE_SUPPORT:
+ CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED);
+ MarkChanges(1, hwndDlg);
+ break;
+ case IDC_REGISTERACCOUNT:
+ CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER);
+ break;
+ case IDC_OFFLINE_MESSAGE_OPTION:
+ case IDC_ALERT_POLICY:
+ case IDC_MUC_POLICY:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ MarkChanges(1, hwndDlg);
+ break;
+ default:
+ MarkChanges(1, hwndDlg);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ BOOL reconnectRequired = FALSE;
+ DBVARIANT dbv;
+
+ GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text));
+ dbv.pszVal = NULL;
+ if (db_get(NULL, proto->m_szModuleName, "LoginName", &dbv) || lstrcmpA(text, dbv.pszVal))
+ reconnectRequired = TRUE;
+ if (dbv.pszVal != NULL)
+ db_free(&dbv);
+ db_set_s(NULL, proto->m_szModuleName, "LoginName", strlwr(text));
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) {
+ GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text));
+ dbv.pszVal = NULL;
+ if (db_get(NULL, proto->m_szModuleName, "Password", &dbv) || lstrcmpA(text, dbv.pszVal))
+ reconnectRequired = TRUE;
+ if (dbv.pszVal != NULL)
+ db_free(&dbv);
+ db_set_s(NULL, proto->m_szModuleName, "Password", text);
+ }
+ else
+ db_unset(NULL, proto->m_szModuleName, "Password");
+
+ db_set_b(NULL, proto->m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD));
+ db_set_b(NULL, proto->m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT));
+ db_set_b(NULL, proto->m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC));
+ db_set_b(NULL, proto->m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE));
+ db_set_b(NULL, proto->m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS));
+ db_set_b(NULL, proto->m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE));
+ db_set_w(NULL, proto->m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, proto->m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, proto->m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, proto->m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0));
+ db_set_b(NULL, proto->m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS));
+ db_set_b(NULL, proto->m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO));
+ db_set_b(NULL, proto->m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT));
+ db_set_b(NULL, proto->m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS));
+ if (reconnectRequired && proto->isConnected)
+ MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND);
+ ApplyChanges(proto, 1);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ proto = (TlenProtocol *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
+ SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me"));
+ SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts"));
+ SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations"));
+ SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts"));
+ SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation"));
+ SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0);
+ TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN));
+ TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_VOICE_POLICY:
+ case IDC_VOICE_DEVICE_IN:
+ case IDC_VOICE_DEVICE_OUT:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ MarkChanges(2, hwndDlg);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ db_set_w(NULL, proto->m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, proto->m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0));
+ ApplyChanges(proto, 2);
+ return TRUE;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ char text[256];
+ BOOL bChecked;
+ TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ proto = (TlenProtocol *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
+ TranslateDialogDefault(hwndDlg);
+ if (!db_get_ts(NULL, proto->m_szModuleName, "LoginServer", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal);
+ db_free(&dbv);
+ }
+ else SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl"));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE);
+
+ if (!db_get_ts(NULL, proto->m_szModuleName, "ManualHost", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal);
+ db_free(&dbv);
+ }
+ else SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl"));
+
+ SetDlgItemInt(hwndDlg, IDC_HOSTPORT, db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE);
+
+ CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, proto->m_szModuleName, "KeepAlive", TRUE));
+
+ CheckDlgButton(hwndDlg, IDC_USE_SSL, db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE));
+
+ CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, db_get_b(NULL, proto->m_szModuleName, "VisibilitySupport", FALSE));
+ // File transfer options
+ bChecked = FALSE;
+ if (db_get_b(NULL, proto->m_szModuleName, "UseFileProxy", FALSE) == TRUE) {
+ bChecked = TRUE;
+ CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE);
+ }
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked);
+ if (db_get_b(NULL, proto->m_szModuleName, "FileProxyAuth", FALSE) == TRUE)
+ CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE);
+ else
+ bChecked = FALSE;
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked);
+
+ SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding"));
+ SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS4"));
+ SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("SOCKS5"));
+ SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, db_get_w(NULL, proto->m_szModuleName, "FileProxyType", 0), 0);
+ if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyHost", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal);
+ db_free(&dbv);
+ }
+ SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, db_get_w(NULL, proto->m_szModuleName, "FileProxyPort", 0), FALSE);
+ if (!db_get_ts(NULL, proto->m_szModuleName, "FileProxyUsername", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal);
+ db_free(&dbv);
+ }
+ if (!db_get_s(NULL, proto->m_szModuleName, "FileProxyPassword", &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal);
+ db_free(&dbv);
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_FILE_PROXY_TYPE:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_EDIT_LOGIN_SERVER:
+ case IDC_HOST:
+ case IDC_HOSTPORT:
+ case IDC_FILE_PROXY_HOST:
+ case IDC_FILE_PROXY_PORT:
+ case IDC_FILE_PROXY_USER:
+ case IDC_FILE_PROXY_PASSWORD:
+ if ((HWND)lParam == GetFocus() && HIWORD(wParam) == EN_CHANGE)
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_FILE_USE_PROXY:
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked);
+ case IDC_FILE_PROXY_USE_AUTH:
+ bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked);
+ MarkChanges(4, hwndDlg);
+ break;
+ case IDC_KEEPALIVE:
+ case IDC_VISIBILITY_SUPPORT:
+ case IDC_USE_SSL:
+ MarkChanges(4, hwndDlg);
+ break;
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ WORD port;
+ BOOL useEncryption;
+ BOOL reconnectRequired = FALSE;
+ DBVARIANT dbv;
+
+ GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text));
+ dbv.pszVal = NULL;
+ if (db_get(NULL, proto->m_szModuleName, "LoginServer", &dbv) || lstrcmpA(text, dbv.pszVal))
+ reconnectRequired = TRUE;
+ if (dbv.pszVal != NULL)
+ db_free(&dbv);
+ db_set_s(NULL, proto->m_szModuleName, "LoginServer", strlwr(text));
+
+ GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text));
+ dbv.pszVal = NULL;
+ if (db_get(NULL, proto->m_szModuleName, "ManualHost", &dbv) || lstrcmpA(text, dbv.pszVal))
+ reconnectRequired = TRUE;
+ if (dbv.pszVal != NULL)
+ db_free(&dbv);
+ db_set_s(NULL, proto->m_szModuleName, "ManualHost", text);
+
+ port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE);
+ if (db_get_w(NULL, proto->m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port)
+ reconnectRequired = TRUE;
+ db_set_w(NULL, proto->m_szModuleName, "ManualPort", port);
+
+ proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE);
+ db_set_b(NULL, proto->m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive);
+
+ useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL);
+ if (db_get_b(NULL, proto->m_szModuleName, "UseEncryption", TRUE) != useEncryption)
+ reconnectRequired = TRUE;
+ db_set_b(NULL, proto->m_szModuleName, "UseEncryption", (BYTE) useEncryption);
+
+ db_set_b(NULL, proto->m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT));
+
+ // File transfer options
+ db_set_b(NULL, proto->m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY));
+ db_set_w(NULL, proto->m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0));
+
+ GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text));
+ db_set_s(NULL, proto->m_szModuleName, "FileProxyHost", text);
+
+ db_set_w(NULL, proto->m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE));
+ db_set_b(NULL, proto->m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH));
+
+ GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text));
+ db_set_s(NULL, proto->m_szModuleName, "FileProxyUsername", text);
+
+ GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text));
+ db_set_s(NULL, proto->m_szModuleName, "FileProxyPassword", text);
+
+ if (reconnectRequired && proto->isConnected)
+ MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND);
+ ApplyChanges(proto, 4);
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+#define POPUP_DEFAULT_COLORBKG 0xDCBDA5
+#define POPUP_DEFAULT_COLORTXT 0x000000
+
+static void MailPopupPreview(DWORD colorBack, DWORD colorText, TCHAR *title, TCHAR *emailInfo, int delay)
+{
+ POPUPDATAT ppd = { 0 };
+ HICON hIcon = GetIcolibIcon(IDI_MAIL);
+ ppd.lchIcon = CopyIcon(hIcon);
+ ReleaseIcolibIcon(hIcon);
+ _tcscpy(ppd.lptzContactName, title);
+ _tcscpy(ppd.lptzText, emailInfo);
+ ppd.colorBack = colorBack;
+ ppd.colorText = colorText;
+ ppd.iSeconds = delay;
+ if ( ServiceExists(MS_POPUP_ADDPOPUPT))
+ PUAddPopupT(&ppd);
+}
+
+static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ BYTE delayMode;
+ proto = (TlenProtocol *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto);
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, db_get_b(NULL, proto->m_szModuleName, "MailPopupEnabled", TRUE));
+ SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG));
+ SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, db_get_dw(NULL, proto->m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT));
+ SetDlgItemInt(hwndDlg, IDC_DELAY, db_get_dw(NULL, proto->m_szModuleName, "MailPopupDelay", 4), FALSE);
+ delayMode = db_get_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", 0);
+ if (delayMode == 1) {
+ CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE);
+ } else if (delayMode == 2) {
+ CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE);
+ } else {
+ CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE);
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_COLORTXT:
+ case IDC_COLORBKG:
+ case IDC_ENABLEPOPUP:
+ case IDC_DELAY:
+ case IDC_DELAY_POPUP:
+ case IDC_DELAY_CUSTOM:
+ case IDC_DELAY_PERMANENT:
+ MarkChanges(8, hwndDlg);
+ break;
+ case IDC_PREVIEW:
+ {
+ int delay;
+ TCHAR title[256];
+ if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) {
+ delay=0;
+ } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) {
+ delay=-1;
+ } else {
+ delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE);
+ }
+ mir_sntprintf(title, SIZEOF(title), TranslateT("%S mail"), proto->m_szModuleName);
+ MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0),
+ (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0),
+ title,
+ _T("From: test@test.test\nSubject: test"),
+ delay);
+ }
+
+ }
+ break;
+
+
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ BYTE delayMode;
+ db_set_b(NULL, proto->m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP));
+ db_set_dw(NULL, proto->m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0));
+ db_set_dw(NULL, proto->m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0));
+ db_set_dw(NULL, proto->m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE));
+ delayMode=0;
+ if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) {
+ delayMode=1;
+ } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) {
+ delayMode=2;
+
+ }
+ db_set_b(NULL, proto->m_szModuleName, "MailPopupDelayMode", delayMode);
+ ApplyChanges(proto, 8);
+ return TRUE;
+ }
+ }
+ break;
+
+ }
+ return FALSE;
+}
+
diff --git a/protocols/Tlen/src/tlen_xml.cpp b/protocols/Tlen/src/tlen_xml.cpp
index a3e2d892e8..87fdd52211 100644
--- a/protocols/Tlen/src/tlen_xml.cpp
+++ b/protocols/Tlen/src/tlen_xml.cpp
@@ -1,569 +1,572 @@
-/*
-
-Jabber Protocol Plugin for Miranda IM
-Tlen Protocol Plugin for Miranda NG
-Copyright (C) 2002-2004 Santithorn Bunchua
-Copyright (C) 2004-2007 Piotr Piastucki
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-#include "tlen.h"
-#include <ctype.h>
-
-static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr);
-static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child);
-
-void TlenXmlInitState(XmlState *xmlState)
-{
- if (xmlState == NULL) return;
- xmlState->root.name = NULL;
- xmlState->root.depth = 0;
- xmlState->root.numAttr = 0;
- xmlState->root.maxNumAttr = 0;
- xmlState->root.attr = NULL;
- xmlState->root.numChild = 0;
- xmlState->root.maxNumChild = 0;
- xmlState->root.child = NULL;
- xmlState->root.text = NULL;
- xmlState->root.state = NODE_OPEN;
- xmlState->callback1_open = NULL;
- xmlState->callback1_close = NULL;
- xmlState->callback2_open = NULL;
- xmlState->callback2_close = NULL;
- xmlState->userdata1_open = NULL;
- xmlState->userdata1_close = NULL;
- xmlState->userdata2_open = NULL;
- xmlState->userdata2_close = NULL;
-}
-
-void TlenXmlDestroyState(XmlState *xmlState)
-{
- int i;
- XmlNode *node;
-
- if (xmlState == NULL) return;
- // Note: cannot use TlenXmlFreeNode() to free xmlState->root
- // because it will do mir_free(xmlState->root) which is not freeable.
- node = &(xmlState->root);
- // Free all children first
- for (i=0; i<node->numChild; i++)
- TlenXmlFreeNode(node->child[i]);
- if (node->child) mir_free(node->child);
- // Free all attributes
- for (i=0; i<node->numAttr; i++) {
- if (node->attr[i]->name) mir_free(node->attr[i]->name);
- if (node->attr[i]->value) mir_free(node->attr[i]->value);
- mir_free(node->attr[i]);
- }
- if (node->attr) mir_free(node->attr);
- // Free string field
- if (node->text) mir_free(node->text);
- if (node->name) mir_free(node->name);
-}
-
-BOOL TlenXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata)
-{
- if (depth == 1 && type == ELEM_OPEN) {
- xmlState->callback1_open = callback;
- xmlState->userdata1_open = userdata;
- }
- else if (depth == 1 && type == ELEM_CLOSE) {
- xmlState->callback1_close = callback;
- xmlState->userdata1_close = userdata;
- }
- else if (depth == 2 && type == ELEM_OPEN) {
- xmlState->callback2_open = callback;
- xmlState->userdata2_open = userdata;
- }
- else if (depth == 2 && type == ELEM_CLOSE) {
- xmlState->callback2_close = callback;
- xmlState->userdata2_close = userdata;
- }
- else
- return FALSE;
-
- return TRUE;
-}
-
-#define TAG_MAX_LEN 50
-#define ATTR_MAX_LEN 1024
-int TlenXmlParse(XmlState *xmlState, char *buffer, int datalen)
-{
- char *p, *q, *r, *eob;
- char *str;
- int num;
- char tag[TAG_MAX_LEN];
- char attr[ATTR_MAX_LEN];
- XmlElemType elemType = ELEM_OPEN;
-
- eob = buffer + datalen;
- num = 0;
- // Skip leading whitespaces
- for (p=buffer; p<eob && isspace(*p); p++,num++);
- while (num < datalen) {
- if (*p == '<') { // found starting bracket
- for (q=p+1; q<eob && *q != '>'; q++);
- if (q < eob) { // found closing bracket
- for (r=p+1; *r != '>' && *r != ' ' && *r != '\t'; r++);
- if (r-(p+1) > TAG_MAX_LEN) {
-// TlenLog("TAG_MAX_LEN too small, ignore current tag");
- }
- else {
- if (*(p+1) == '/') { // closing tag
- strncpy(tag, p+2, r-(p+2));
- tag[r-(p+2)] = '\0';
- elemType = ELEM_CLOSE;
- }
- else {
- if (*(r-1) == '/') { // single open/close tag
- strncpy(tag, p+1, r-(p+1)-1);
- tag[r-(p+1)-1] = '\0';
- elemType = ELEM_OPENCLOSE;
- }
- else {
- strncpy(tag, p+1, r-(p+1));
- tag[r-(p+1)] = '\0';
- elemType = ELEM_OPEN;
- }
- }
- for (;r<q && (*r == ' ' || *r == '\t'); r++);
- if (q-r > ATTR_MAX_LEN) {
-// TlenLog("ATTR_MAX_LEN too small, ignore current tag");
- }
- else {
- strncpy(attr, r, q-r);
- if ((q-r)>0 && attr[q-r-1] == '/') {
- attr[q-r-1] = '\0';
- elemType = ELEM_OPENCLOSE;
- }
- else
- attr[q-r] = '\0';
- TlenXmlProcessElem(xmlState, elemType, tag, attr);
- }
- }
- num += (q-p+1);
- p = q + 1;
- if (elemType == ELEM_CLOSE || elemType == ELEM_OPENCLOSE) {
- // Skip whitespaces after end tags
- for (; p<eob && isspace(*p); p++,num++);
- }
- }
- else
- break;
- }
- else { // found inner text
- for (q=p+1; q<eob && *q != '<'; q++);
- if (q < eob) { // found starting bracket of the next element
- str = (char *) mir_alloc(q-p+1);
- strncpy(str, p, q-p);
- str[q-p] = '\0';
- TlenXmlProcessElem(xmlState, ELEM_TEXT, str, NULL);
- mir_free(str);
- num += (q-p);
- p = q;
- }
- else
- break;
- }
- }
-
- return num;
-}
-
-static void TlenXmlParseAttr(XmlNode *node, char *text)
-{
- char *kstart, *vstart;
- int klen, vlen;
- char *p;
- XmlAttr *a;
-
- if (node == NULL || text == NULL || strlen(text) <= 0)
- return;
-
- for (p=text;;) {
-
- // Skip leading whitespaces
- for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++);
- if (*p == '\0')
- break;
-
- // Fetch key
- kstart = p;
- for (;*p != '\0' && *p != '=' && *p != ' ' && *p != '\t'; p++);
- klen = p-kstart;
-
- if (node->numAttr >= node->maxNumAttr) {
- node->maxNumAttr = node->numAttr + 20;
- node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *));
- }
- a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr));
- node->numAttr++;
-
- // Skip possible whitespaces between key and '='
- for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++);
-
- if (*p == '\0') {
- a->name = (char *) mir_alloc(klen+1);
- strncpy(a->name, kstart, klen);
- a->name[klen] = '\0';
- a->value = mir_strdup("");
- break;
- }
-
- if (*p != '=') {
- a->name = (char *) mir_alloc(klen+1);
- strncpy(a->name, kstart, klen);
- a->name[klen] = '\0';
- a->value = mir_strdup("");
- continue;
- }
-
- // Found '='
- p++;
-
- // Skip possible whitespaces between '=' and value
- for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++);
-
- if (*p == '\0') {
- a->name = (char *) mir_alloc(klen+1);
- strncpy(a->name, kstart, klen);
- a->name[klen] = '\0';
- a->value = mir_strdup("");
- break;
- }
-
- // Fetch value
- if (*p == '\'' || *p == '"') {
- p++;
- vstart = p;
- for (;*p != '\0' && *p != *(vstart-1); p++);
- vlen = p-vstart;
- if (*p != '\0') p++;
- }
- else {
- vstart = p;
- for (;*p != '\0' && *p != ' ' && *p != '\t'; p++);
- vlen = p-vstart;
- }
-
- a->name = (char *) mir_alloc(klen+1);
- strncpy(a->name, kstart, klen);
- a->name[klen] = '\0';
- a->value = (char *) mir_alloc(vlen+1);
- strncpy(a->value, vstart, vlen);
- a->value[vlen] = '\0';
- }
-}
-
-static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr)
-{
- XmlNode *node, *parentNode, *n;
- //BOOL activateCallback = FALSE;
- char *text, *attr;
-
- if (elemText == NULL) return FALSE;
-
- if (elemType == ELEM_OPEN && !strcmp(elemText, "?xml")) {
-// TlenLog("XML: skip <?xml> tag");
- return TRUE;
- }
-
- // Find active node
- node = &(xmlState->root);
- parentNode = NULL;
- while (node->numChild>0 && node->child[node->numChild-1]->state == NODE_OPEN) {
- parentNode = node;
- node = node->child[node->numChild-1];
- }
-
- if (node->state != NODE_OPEN) return FALSE;
-
- text = mir_strdup(elemText);
-
- if (elemAttr)
- attr = mir_strdup(elemAttr);
- else
- attr = NULL;
-
- switch (elemType) {
- case ELEM_OPEN:
- if (node->numChild >= node->maxNumChild) {
- node->maxNumChild = node->numChild + 20;
- node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *));
- }
- n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode));
- node->numChild++;
- n->name = text;
- n->depth = node->depth + 1;
- n->state = NODE_OPEN;
- n->numChild = n->maxNumChild = 0;
- n->child = NULL;
- n->numAttr = n->maxNumAttr = 0;
- n->attr = NULL;
- TlenXmlParseAttr(n, attr);
- n->text = NULL;
- if (n->depth == 1 && xmlState->callback1_open != NULL)
- (*(xmlState->callback1_open))(n, xmlState->userdata1_open);
- if (n->depth == 2 && xmlState->callback2_open != NULL)
- (*xmlState->callback2_open)(n, xmlState->userdata2_open);
- break;
- case ELEM_OPENCLOSE:
- if (node->numChild >= node->maxNumChild) {
- node->maxNumChild = node->numChild + 20;
- node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *));
- }
- n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode));
- node->numChild++;
- n->name = text;
- n->depth = node->depth + 1;
- n->state = NODE_CLOSE;
- n->numChild = n->maxNumAttr = 0;
- n->child = NULL;
- n->numAttr = n->maxNumAttr = 0;
- n->attr = NULL;
- TlenXmlParseAttr(n, attr);
- n->text = NULL;
- if (n->depth == 1 && xmlState->callback1_close != NULL) {
- (*(xmlState->callback1_close))(n, xmlState->userdata1_close);
- TlenXmlRemoveChild(node, n);
- }
- if (n->depth == 2 && xmlState->callback2_close != NULL) {
- (*xmlState->callback2_close)(n, xmlState->userdata2_close);
- TlenXmlRemoveChild(node, n);
- }
- break;
- case ELEM_CLOSE:
- if (node->name != NULL && !strcmp(node->name, text)) {
- node->state = NODE_CLOSE;
- int nodeDepth = node->depth;
- if (nodeDepth == 1 && xmlState->callback1_close != NULL) {
- (*(xmlState->callback1_close))(node, xmlState->userdata1_close);
- TlenXmlRemoveChild(parentNode, node);
- }
- if (nodeDepth == 2 && xmlState->callback2_close != NULL) {
- (*xmlState->callback2_close)(node, xmlState->userdata2_close);
- TlenXmlRemoveChild(parentNode, node);
- }
- mir_free(text);
- }
- else {
-// TlenLog("XML: Closing </%s> without opening tag", text);
- mir_free(text);
- if (attr) mir_free(attr);
- return FALSE;
- }
- break;
- case ELEM_TEXT:
- node->text = text;
- break;
- default:
- mir_free(text);
- if (attr) mir_free(attr);
- return FALSE;
- }
-
- if (attr) mir_free(attr);
-
- return TRUE;
-}
-
-char *TlenXmlGetAttrValue(XmlNode *node, char *key)
-{
- int i;
-
- if (node == NULL || node->numAttr <= 0 || key == NULL || strlen(key) <= 0)
- return NULL;
- for (i=0; i<node->numAttr; i++) {
- if (node->attr[i]->name && !strcmp(key, node->attr[i]->name))
- return node->attr[i]->value;
- }
- return NULL;
-}
-
-XmlNode *TlenXmlGetChild(XmlNode *node, char *tag)
-{
- return TlenXmlGetNthChild(node, tag, 1);
-}
-
-XmlNode *TlenXmlGetNthChild(XmlNode *node, char *tag, int nth)
-{
- int i, num;
-
- if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || nth < 1)
- return NULL;
- num = 1;
- for (i=0; i<node->numChild; i++) {
- if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) {
- if (num == nth) {
- return node->child[i];
- }
- num++;
- }
- }
- return NULL;
-}
-
-XmlNode *TlenXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue)
-{
- int i;
- char *str;
-
- if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || attrKey == NULL || strlen(attrKey) <= 0 || attrValue == NULL || strlen(attrValue) <= 0)
- return NULL;
- for (i=0; i<node->numChild; i++) {
- if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) {
- if ((str=TlenXmlGetAttrValue(node->child[i], attrKey)) != NULL)
- if (!strcmp(str, attrValue))
- return node->child[i];
- }
- }
- return NULL;
-}
-
-static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child)
-{
- int i;
-
- if (node == NULL || child == NULL || node->numChild <= 0) return;
- for (i=0; i<node->numChild; i++) {
- if (node->child[i] == child)
- break;
- }
- if (i < node->numChild) {
- for (++i; i<node->numChild; i++)
- node->child[i-1] = node->child[i];
- node->numChild--;
- TlenXmlFreeNode(child);
- }
-}
-
-void TlenXmlFreeNode(XmlNode *node)
-{
- int i;
-
- if (node == NULL) return;
- // Free all children first
- for (i=0; i<node->numChild; i++)
- TlenXmlFreeNode(node->child[i]);
- if (node->child) mir_free(node->child);
- // Free all attributes
- for (i=0; i<node->numAttr; i++) {
- if (node->attr[i]->name) mir_free(node->attr[i]->name);
- if (node->attr[i]->value) mir_free(node->attr[i]->value);
- mir_free(node->attr[i]);
- }
- if (node->attr) mir_free(node->attr);
- // Free string field
- if (node->text) mir_free(node->text);
- if (node->name) mir_free(node->name);
- // Free the node itself
- mir_free(node);
-}
-
-XmlNode *TlenXmlCopyNode(XmlNode *node)
-{
- XmlNode *n;
- int i;
-
- if (node == NULL) return NULL;
- n = (XmlNode *) mir_alloc(sizeof(XmlNode));
- // Copy attributes
- if (node->numAttr > 0) {
- n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *));
- for (i=0; i<node->numAttr; i++) {
- n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr));
- if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name);
- else n->attr[i]->name = NULL;
- if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value);
- else n->attr[i]->value = NULL;
- }
- }
- else
- n->attr = NULL;
- // Recursively copy children
- if (node->numChild > 0) {
- n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *));
- for (i=0; i<node->numChild; i++)
- n->child[i] = TlenXmlCopyNode(node->child[i]);
- }
- else
- n->child = NULL;
- // Copy other fields
- n->numAttr = node->numAttr;
- n->maxNumAttr = node->numAttr;
- n->numChild = node->numChild;
- n->maxNumChild = node->numChild;
- n->depth = node->depth;
- n->state = node->state;
- n->name = (node->name)?mir_strdup(node->name):NULL;
- n->text = (node->text)?mir_strdup(node->text):NULL;
-
- return n;
-}
-
-XmlNode *TlenXmlCreateNode(char *name)
-{
- XmlNode *n;
-
- if (name == NULL)
- return NULL;
-
- n = (XmlNode *) mir_alloc(sizeof(XmlNode));
- memset(n, 0, sizeof(XmlNode));
- n->name = mir_strdup(name);
- return n;
-}
-
-void TlenXmlAddAttr(XmlNode *n, char *name, char *value)
-{
- int i;
-
- if (n == NULL || name == NULL || value == NULL)
- return;
-
- i = n->numAttr;
- (n->numAttr)++;
- n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr);
- n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr));
- n->attr[i]->name = mir_strdup(name);
- n->attr[i]->value = mir_strdup(value);
-}
-
-XmlNode *TlenXmlAddChild(XmlNode *n, char *name)
-{
- int i;
-
- if (n == NULL || name == NULL)
- return NULL;
-
- i = n->numChild;
- n->numChild++;
- n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild);
- n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode));
- memset(n->child[i], 0, sizeof(XmlNode));
- n->child[i]->name = mir_strdup(name);
- return n->child[i];
-}
-
-void TlenXmlAddText(XmlNode *n, char *text)
-{
- if (n != NULL && text != NULL) {
- if (n->text) mir_free(n->text);
- n->text = mir_strdup(text);
- }
-}
-
+/*
+
+Jabber Protocol Plugin for Miranda IM
+Tlen Protocol Plugin for Miranda NG
+Copyright (C) 2002-2004 Santithorn Bunchua
+Copyright (C) 2004-2007 Piotr Piastucki
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "tlen.h"
+#include <ctype.h>
+
+static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr);
+static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child);
+
+void TlenXmlInitState(XmlState *xmlState)
+{
+ if (xmlState == NULL) return;
+ xmlState->root.name = NULL;
+ xmlState->root.depth = 0;
+ xmlState->root.numAttr = 0;
+ xmlState->root.maxNumAttr = 0;
+ xmlState->root.attr = NULL;
+ xmlState->root.numChild = 0;
+ xmlState->root.maxNumChild = 0;
+ xmlState->root.child = NULL;
+ xmlState->root.text = NULL;
+ xmlState->root.state = NODE_OPEN;
+ xmlState->callback1_open = NULL;
+ xmlState->callback1_close = NULL;
+ xmlState->callback2_open = NULL;
+ xmlState->callback2_close = NULL;
+ xmlState->userdata1_open = NULL;
+ xmlState->userdata1_close = NULL;
+ xmlState->userdata2_open = NULL;
+ xmlState->userdata2_close = NULL;
+}
+
+void TlenXmlDestroyState(XmlState *xmlState)
+{
+ int i;
+ XmlNode *node;
+
+ if (xmlState == NULL)
+ return;
+ // Note: cannot use TlenXmlFreeNode() to free xmlState->root
+ // because it will do mir_free(xmlState->root) which is not freeable.
+ node = &(xmlState->root);
+ // Free all children first
+ for (i=0; i<node->numChild; i++)
+ TlenXmlFreeNode(node->child[i]);
+ mir_free(node->child);
+ // Free all attributes
+ for (i=0; i<node->numAttr; i++) {
+ mir_free(node->attr[i]->name);
+ mir_free(node->attr[i]->value);
+ mir_free(node->attr[i]);
+ }
+ mir_free(node->attr);
+ // Free string field
+ mir_free(node->text);
+ mir_free(node->name);
+ /* mir_free(xmlState) - no need, work with static. */
+}
+
+BOOL TlenXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(XmlNode*, void*), void *userdata)
+{
+ if (depth == 1 && type == ELEM_OPEN) {
+ xmlState->callback1_open = callback;
+ xmlState->userdata1_open = userdata;
+ }
+ else if (depth == 1 && type == ELEM_CLOSE) {
+ xmlState->callback1_close = callback;
+ xmlState->userdata1_close = userdata;
+ }
+ else if (depth == 2 && type == ELEM_OPEN) {
+ xmlState->callback2_open = callback;
+ xmlState->userdata2_open = userdata;
+ }
+ else if (depth == 2 && type == ELEM_CLOSE) {
+ xmlState->callback2_close = callback;
+ xmlState->userdata2_close = userdata;
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+#define TAG_MAX_LEN 50
+#define ATTR_MAX_LEN 1024
+int TlenXmlParse(XmlState *xmlState, char *buffer, int datalen)
+{
+ char *p, *q, *r, *eob;
+ char *str;
+ int num;
+ char tag[TAG_MAX_LEN];
+ char attr[ATTR_MAX_LEN];
+ XmlElemType elemType = ELEM_OPEN;
+
+ eob = buffer + datalen;
+ num = 0;
+ // Skip leading whitespaces
+ for (p=buffer; p<eob && isspace(*p); p++,num++);
+ while (num < datalen) {
+ if (*p == '<') { // found starting bracket
+ for (q=p+1; q<eob && *q != '>'; q++);
+ if (q < eob) { // found closing bracket
+ for (r=p+1; *r != '>' && *r != ' ' && *r != '\t'; r++);
+ if (r-(p+1) > TAG_MAX_LEN) {
+// TlenLog("TAG_MAX_LEN too small, ignore current tag");
+ }
+ else {
+ if (*(p+1) == '/') { // closing tag
+ strncpy(tag, p+2, r-(p+2));
+ tag[r-(p+2)] = '\0';
+ elemType = ELEM_CLOSE;
+ }
+ else {
+ if (*(r-1) == '/') { // single open/close tag
+ strncpy(tag, p+1, r-(p+1)-1);
+ tag[r-(p+1)-1] = '\0';
+ elemType = ELEM_OPENCLOSE;
+ }
+ else {
+ strncpy(tag, p+1, r-(p+1));
+ tag[r-(p+1)] = '\0';
+ elemType = ELEM_OPEN;
+ }
+ }
+ for (;r<q && (*r == ' ' || *r == '\t'); r++);
+ if (q-r > ATTR_MAX_LEN) {
+// TlenLog("ATTR_MAX_LEN too small, ignore current tag");
+ }
+ else {
+ strncpy(attr, r, q-r);
+ if ((q-r)>0 && attr[q-r-1] == '/') {
+ attr[q-r-1] = '\0';
+ elemType = ELEM_OPENCLOSE;
+ }
+ else
+ attr[q-r] = '\0';
+ TlenXmlProcessElem(xmlState, elemType, tag, attr);
+ }
+ }
+ num += (q-p+1);
+ p = q + 1;
+ if (elemType == ELEM_CLOSE || elemType == ELEM_OPENCLOSE) {
+ // Skip whitespaces after end tags
+ for (; p<eob && isspace(*p); p++,num++);
+ }
+ }
+ else
+ break;
+ }
+ else { // found inner text
+ for (q=p+1; q<eob && *q != '<'; q++);
+ if (q < eob) { // found starting bracket of the next element
+ str = (char *) mir_alloc(q-p+1);
+ strncpy(str, p, q-p);
+ str[q-p] = '\0';
+ TlenXmlProcessElem(xmlState, ELEM_TEXT, str, NULL);
+ mir_free(str);
+ num += (q-p);
+ p = q;
+ }
+ else
+ break;
+ }
+ }
+
+ return num;
+}
+
+static void TlenXmlParseAttr(XmlNode *node, char *text)
+{
+ char *kstart, *vstart;
+ int klen, vlen;
+ char *p;
+ XmlAttr *a;
+
+ if (node == NULL || text == NULL || strlen(text) <= 0)
+ return;
+
+ for (p=text;;) {
+
+ // Skip leading whitespaces
+ for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++);
+ if (*p == '\0')
+ break;
+
+ // Fetch key
+ kstart = p;
+ for (;*p != '\0' && *p != '=' && *p != ' ' && *p != '\t'; p++);
+ klen = p-kstart;
+
+ if (node->numAttr >= node->maxNumAttr) {
+ node->maxNumAttr = node->numAttr + 20;
+ node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *));
+ }
+ a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr));
+ node->numAttr++;
+
+ // Skip possible whitespaces between key and '='
+ for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++);
+
+ if (*p == '\0') {
+ a->name = (char *) mir_alloc(klen+1);
+ strncpy(a->name, kstart, klen);
+ a->name[klen] = '\0';
+ a->value = mir_strdup("");
+ break;
+ }
+
+ if (*p != '=') {
+ a->name = (char *) mir_alloc(klen+1);
+ strncpy(a->name, kstart, klen);
+ a->name[klen] = '\0';
+ a->value = mir_strdup("");
+ continue;
+ }
+
+ // Found '='
+ p++;
+
+ // Skip possible whitespaces between '=' and value
+ for (;*p != '\0' && (*p == ' ' || *p == '\t'); p++);
+
+ if (*p == '\0') {
+ a->name = (char *) mir_alloc(klen+1);
+ strncpy(a->name, kstart, klen);
+ a->name[klen] = '\0';
+ a->value = mir_strdup("");
+ break;
+ }
+
+ // Fetch value
+ if (*p == '\'' || *p == '"') {
+ p++;
+ vstart = p;
+ for (;*p != '\0' && *p != *(vstart-1); p++);
+ vlen = p-vstart;
+ if (*p != '\0') p++;
+ }
+ else {
+ vstart = p;
+ for (;*p != '\0' && *p != ' ' && *p != '\t'; p++);
+ vlen = p-vstart;
+ }
+
+ a->name = (char *) mir_alloc(klen+1);
+ strncpy(a->name, kstart, klen);
+ a->name[klen] = '\0';
+ a->value = (char *) mir_alloc(vlen+1);
+ strncpy(a->value, vstart, vlen);
+ a->value[vlen] = '\0';
+ }
+}
+
+static BOOL TlenXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr)
+{
+ XmlNode *node, *parentNode, *n;
+ //BOOL activateCallback = FALSE;
+ char *text, *attr;
+
+ if (elemText == NULL) return FALSE;
+
+ if (elemType == ELEM_OPEN && !strcmp(elemText, "?xml")) {
+// TlenLog("XML: skip <?xml> tag");
+ return TRUE;
+ }
+
+ // Find active node
+ node = &(xmlState->root);
+ parentNode = NULL;
+ while (node->numChild>0 && node->child[node->numChild-1]->state == NODE_OPEN) {
+ parentNode = node;
+ node = node->child[node->numChild-1];
+ }
+
+ if (node->state != NODE_OPEN) return FALSE;
+
+ text = mir_strdup(elemText);
+
+ if (elemAttr)
+ attr = mir_strdup(elemAttr);
+ else
+ attr = NULL;
+
+ switch (elemType) {
+ case ELEM_OPEN:
+ if (node->numChild >= node->maxNumChild) {
+ node->maxNumChild = node->numChild + 20;
+ node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *));
+ }
+ n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode));
+ node->numChild++;
+ n->name = text;
+ n->depth = node->depth + 1;
+ n->state = NODE_OPEN;
+ n->numChild = n->maxNumChild = 0;
+ n->child = NULL;
+ n->numAttr = n->maxNumAttr = 0;
+ n->attr = NULL;
+ TlenXmlParseAttr(n, attr);
+ n->text = NULL;
+ if (n->depth == 1 && xmlState->callback1_open != NULL)
+ (*(xmlState->callback1_open))(n, xmlState->userdata1_open);
+ if (n->depth == 2 && xmlState->callback2_open != NULL)
+ (*xmlState->callback2_open)(n, xmlState->userdata2_open);
+ break;
+ case ELEM_OPENCLOSE:
+ if (node->numChild >= node->maxNumChild) {
+ node->maxNumChild = node->numChild + 20;
+ node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *));
+ }
+ n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode));
+ node->numChild++;
+ n->name = text;
+ n->depth = node->depth + 1;
+ n->state = NODE_CLOSE;
+ n->numChild = n->maxNumAttr = 0;
+ n->child = NULL;
+ n->numAttr = n->maxNumAttr = 0;
+ n->attr = NULL;
+ TlenXmlParseAttr(n, attr);
+ n->text = NULL;
+ if (n->depth == 1 && xmlState->callback1_close != NULL) {
+ (*(xmlState->callback1_close))(n, xmlState->userdata1_close);
+ TlenXmlRemoveChild(node, n);
+ }
+ if (n->depth == 2 && xmlState->callback2_close != NULL) {
+ (*xmlState->callback2_close)(n, xmlState->userdata2_close);
+ TlenXmlRemoveChild(node, n);
+ }
+ break;
+ case ELEM_CLOSE:
+ if (node->name != NULL && !strcmp(node->name, text)) {
+ node->state = NODE_CLOSE;
+ int nodeDepth = node->depth;
+ if (nodeDepth == 1 && xmlState->callback1_close != NULL) {
+ (*(xmlState->callback1_close))(node, xmlState->userdata1_close);
+ TlenXmlRemoveChild(parentNode, node);
+ }
+ if (nodeDepth == 2 && xmlState->callback2_close != NULL) {
+ (*xmlState->callback2_close)(node, xmlState->userdata2_close);
+ TlenXmlRemoveChild(parentNode, node);
+ }
+ mir_free(text);
+ }
+ else {
+// TlenLog("XML: Closing </%s> without opening tag", text);
+ mir_free(text);
+ if (attr) mir_free(attr);
+ return FALSE;
+ }
+ break;
+ case ELEM_TEXT:
+ node->text = text;
+ break;
+ default:
+ mir_free(text);
+ if (attr) mir_free(attr);
+ return FALSE;
+ }
+
+ if (attr) mir_free(attr);
+
+ return TRUE;
+}
+
+char *TlenXmlGetAttrValue(XmlNode *node, char *key)
+{
+ int i;
+
+ if (node == NULL || node->numAttr <= 0 || key == NULL || strlen(key) <= 0)
+ return NULL;
+ for (i=0; i<node->numAttr; i++) {
+ if (node->attr[i]->name && !strcmp(key, node->attr[i]->name))
+ return node->attr[i]->value;
+ }
+ return NULL;
+}
+
+XmlNode *TlenXmlGetChild(XmlNode *node, char *tag)
+{
+ return TlenXmlGetNthChild(node, tag, 1);
+}
+
+XmlNode *TlenXmlGetNthChild(XmlNode *node, char *tag, int nth)
+{
+ int i, num;
+
+ if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || nth < 1)
+ return NULL;
+ num = 1;
+ for (i=0; i<node->numChild; i++) {
+ if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) {
+ if (num == nth) {
+ return node->child[i];
+ }
+ num++;
+ }
+ }
+ return NULL;
+}
+
+XmlNode *TlenXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue)
+{
+ int i;
+ char *str;
+
+ if (node == NULL || node->numChild <= 0 || tag == NULL || strlen(tag) <= 0 || attrKey == NULL || strlen(attrKey) <= 0 || attrValue == NULL || strlen(attrValue) <= 0)
+ return NULL;
+ for (i=0; i<node->numChild; i++) {
+ if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) {
+ if ((str=TlenXmlGetAttrValue(node->child[i], attrKey)) != NULL)
+ if (!strcmp(str, attrValue))
+ return node->child[i];
+ }
+ }
+ return NULL;
+}
+
+static void TlenXmlRemoveChild(XmlNode *node, XmlNode *child)
+{
+ int i;
+
+ if (node == NULL || child == NULL || node->numChild <= 0) return;
+ for (i=0; i<node->numChild; i++) {
+ if (node->child[i] == child)
+ break;
+ }
+ if (i < node->numChild) {
+ for (++i; i<node->numChild; i++)
+ node->child[i-1] = node->child[i];
+ node->numChild--;
+ TlenXmlFreeNode(child);
+ }
+}
+
+void TlenXmlFreeNode(XmlNode *node)
+{
+ int i;
+
+ if (node == NULL)
+ return;
+ // Free all children first
+ for (i=0; i<node->numChild; i++)
+ TlenXmlFreeNode(node->child[i]);
+ mir_free(node->child);
+ // Free all attributes
+ for (i=0; i<node->numAttr; i++) {
+ mir_free(node->attr[i]->name);
+ mir_free(node->attr[i]->value);
+ mir_free(node->attr[i]);
+ }
+ mir_free(node->attr);
+ // Free string field
+ mir_free(node->text);
+ mir_free(node->name);
+ // Free the node itself
+ mir_free(node);
+}
+
+XmlNode *TlenXmlCopyNode(XmlNode *node)
+{
+ XmlNode *n;
+ int i;
+
+ if (node == NULL) return NULL;
+ n = (XmlNode *) mir_alloc(sizeof(XmlNode));
+ // Copy attributes
+ if (node->numAttr > 0) {
+ n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *));
+ for (i=0; i<node->numAttr; i++) {
+ n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr));
+ if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name);
+ else n->attr[i]->name = NULL;
+ if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value);
+ else n->attr[i]->value = NULL;
+ }
+ }
+ else
+ n->attr = NULL;
+ // Recursively copy children
+ if (node->numChild > 0) {
+ n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *));
+ for (i=0; i<node->numChild; i++)
+ n->child[i] = TlenXmlCopyNode(node->child[i]);
+ }
+ else
+ n->child = NULL;
+ // Copy other fields
+ n->numAttr = node->numAttr;
+ n->maxNumAttr = node->numAttr;
+ n->numChild = node->numChild;
+ n->maxNumChild = node->numChild;
+ n->depth = node->depth;
+ n->state = node->state;
+ n->name = (node->name)?mir_strdup(node->name):NULL;
+ n->text = (node->text)?mir_strdup(node->text):NULL;
+
+ return n;
+}
+
+XmlNode *TlenXmlCreateNode(char *name)
+{
+ XmlNode *n;
+
+ if (name == NULL)
+ return NULL;
+
+ n = (XmlNode *) mir_alloc(sizeof(XmlNode));
+ memset(n, 0, sizeof(XmlNode));
+ n->name = mir_strdup(name);
+ return n;
+}
+
+void TlenXmlAddAttr(XmlNode *n, char *name, char *value)
+{
+ int i;
+
+ if (n == NULL || name == NULL || value == NULL)
+ return;
+
+ i = n->numAttr;
+ (n->numAttr)++;
+ n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr);
+ n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr));
+ n->attr[i]->name = mir_strdup(name);
+ n->attr[i]->value = mir_strdup(value);
+}
+
+XmlNode *TlenXmlAddChild(XmlNode *n, char *name)
+{
+ int i;
+
+ if (n == NULL || name == NULL)
+ return NULL;
+
+ i = n->numChild;
+ n->numChild++;
+ n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild);
+ n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode));
+ memset(n->child[i], 0, sizeof(XmlNode));
+ n->child[i]->name = mir_strdup(name);
+ return n->child[i];
+}
+
+void TlenXmlAddText(XmlNode *n, char *text)
+{
+ if (n != NULL && text != NULL) {
+ if (n->text) mir_free(n->text);
+ n->text = mir_strdup(text);
+ }
+}
+