static void ReloadMyAvatar(LPVOID lpParam) { char *szProto = (char *)lpParam; mir_sleep(500); for (int i = 0; !g_shutDown && i < g_MyAvatars.getCount(); i++) { char *myAvatarProto = g_MyAvatars[i].szProtoname; if (szProto[0] == 0) { // Notify to all possibles if (mir_strcmp(myAvatarProto, szProto)) { if (!ProtoServiceExists(myAvatarProto, PS_SETMYAVATAR)) continue; if (!Proto_IsAvatarsEnabled(myAvatarProto)) continue; } } else if (mir_strcmp(myAvatarProto, szProto)) continue; if (g_MyAvatars[i].hbmPic) DeleteObject(g_MyAvatars[i].hbmPic); if (CreateAvatarInCache(INVALID_CONTACT_ID, &g_MyAvatars[i], myAvatarProto) != -1) NotifyEventHooks(hMyAvatarChanged, (WPARAM)myAvatarProto, (LPARAM)&g_MyAvatars[i]); else NotifyEventHooks(hMyAvatarChanged, (WPARAM)myAvatarProto, 0); } free(lpParam); }
static int InternalRemoveMyAvatar(char *protocol) { SetIgnoreNotify(protocol, TRUE); // Remove avatar int ret = 0; if (protocol != NULL) { if ( ProtoServiceExists(protocol, PS_SETMYAVATAR)) ret = SaveAvatar(protocol, NULL); else ret = -3; if (ret == 0) { // Has global avatar? DBVARIANT dbv = {0}; if ( !db_get_ts(NULL, AVS_MODULE, "GlobalUserAvatarFile", &dbv)) { db_free(&dbv); db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); DeleteGlobalUserAvatar(); } } } else { PROTOACCOUNT **accs; int i,count; ProtoEnumAccounts( &count, &accs ); for (i = 0; i < count; i++) { if ( !ProtoServiceExists( accs[i]->szModuleName, PS_SETMYAVATAR)) continue; if (!Proto_IsAvatarsEnabled( accs[i]->szModuleName )) continue; // Found a protocol int retTmp = SaveAvatar( accs[i]->szModuleName, NULL); if (retTmp != 0) ret = retTmp; } DeleteGlobalUserAvatar(); if (ret) db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); else db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 0); } SetIgnoreNotify(protocol, FALSE); ReportMyAvatarChanged(WPARAM((protocol == NULL ) ? "" : protocol), 0); return ret; }
INT_PTR avSetMyAvatar(char* protocol, TCHAR* tszPath) { TCHAR FileName[MAX_PATH]; TCHAR *szFinalName = NULL; BOOL allAcceptXML; BOOL allAcceptSWF; // Protocol allow seting of avatar? if (protocol != NULL && !CanSetMyAvatar((WPARAM)protocol, 0)) return -1; if (tszPath == NULL && hwndSetMyAvatar != 0) { SetForegroundWindow(hwndSetMyAvatar); SetFocus(hwndSetMyAvatar); ShowWindow(hwndSetMyAvatar, SW_SHOW); return -2; } SetMyAvatarHookData data = { 0 }; // Check for XML and SWF if (protocol == NULL) { allAcceptXML = TRUE; allAcceptSWF = TRUE; int count; PROTOACCOUNT **accs; ProtoEnumAccounts(&count, &accs); for (int i = 0; i < count; i++) { if (!ProtoServiceExists(accs[i]->szModuleName, PS_SETMYAVATAR)) continue; if (!Proto_IsAvatarsEnabled(accs[i]->szModuleName)) continue; allAcceptXML = allAcceptXML && Proto_IsAvatarFormatSupported(accs[i]->szModuleName, PA_FORMAT_XML); allAcceptSWF = allAcceptSWF && Proto_IsAvatarFormatSupported(accs[i]->szModuleName, PA_FORMAT_SWF); } data.square = db_get_b(0, AVS_MODULE, "SetAllwaysMakeSquare", 0); } else { allAcceptXML = Proto_IsAvatarFormatSupported(protocol, PA_FORMAT_XML); allAcceptSWF = Proto_IsAvatarFormatSupported(protocol, PA_FORMAT_SWF); data.protocol = protocol; data.square = (Proto_AvatarImageProportion(protocol) & PIP_SQUARE) || db_get_b(0, AVS_MODULE, "SetAllwaysMakeSquare", 0); } if (tszPath == NULL) { data.protocol = protocol; CMString filter; FilterGetStrings(filter, allAcceptXML, allAcceptSWF); TCHAR inipath[1024]; FoldersGetCustomPathT(hMyAvatarsFolder, inipath, SIZEOF(inipath), _T(".")); OPENFILENAME ofn = { 0 }; ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = FileName; ofn.lpstrFilter = filter; ofn.nMaxFile = MAX_PATH; ofn.nMaxFileTitle = MAX_PATH; ofn.Flags = OFN_FILEMUSTEXIST | OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLESIZING | OFN_ENABLEHOOK; ofn.lpstrInitialDir = inipath; ofn.lpTemplateName = MAKEINTRESOURCE(IDD_SET_OWN_SUBCLASS); ofn.lpfnHook = SetMyAvatarHookProc; ofn.lCustData = (LPARAM)&data; *FileName = '\0'; ofn.lpstrDefExt = _T(""); ofn.hInstance = g_hInst; TCHAR title[256]; if (protocol == NULL) mir_sntprintf(title, SIZEOF(title), TranslateT("Set My Avatar")); else { TCHAR* prototmp = mir_a2t(protocol); mir_sntprintf(title, SIZEOF(title), TranslateT("Set My Avatar for %s"), prototmp); mir_free(prototmp); } ofn.lpstrTitle = title; if (!GetOpenFileName(&ofn)) return 1; szFinalName = FileName; } else szFinalName = (TCHAR*)tszPath; // filename is now set, check it and perform all needed action if (szFinalName[0] == '\0') return InternalRemoveMyAvatar(protocol); return InternalSetMyAvatar(protocol, szFinalName, data, allAcceptXML, allAcceptSWF); }
static int InternalSetMyAvatar(char *protocol, TCHAR *szFinalName, SetMyAvatarHookData &data, BOOL allAcceptXML, BOOL allAcceptSWF) { int format = ProtoGetAvatarFormat(szFinalName); if (format == PA_FORMAT_UNKNOWN || _taccess(szFinalName, 4) == -1) return -3; // file exists... HBITMAP hBmp = NULL; if (format == PA_FORMAT_SWF) { if (!allAcceptSWF) return -4; } else if (format == PA_FORMAT_XML) { if (!allAcceptXML) return -4; } else { // Try to open if is not a flash or XML hBmp = (HBITMAP)CallService(MS_IMG_LOAD, (WPARAM)szFinalName, IMGL_TCHAR); if (hBmp == NULL) return -4; } SetIgnoreNotify(protocol, TRUE); int ret = 0; if (protocol != NULL) { ret = SetProtoMyAvatar(protocol, hBmp, szFinalName, format, data.square, data.grow); if (ret == 0) { DeleteGlobalUserAvatar(); db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); } } else { int count; PROTOACCOUNT **accs; ProtoEnumAccounts(&count, &accs); for (int i = 0; i < count; i++) { if (!ProtoServiceExists(accs[i]->szModuleName, PS_SETMYAVATAR)) continue; if (!Proto_IsAvatarsEnabled(accs[i]->szModuleName)) continue; int retTmp = SetProtoMyAvatar(accs[i]->szModuleName, hBmp, szFinalName, format, data.square, data.grow); if (retTmp != 0) ret = retTmp; } DeleteGlobalUserAvatar(); if (ret) db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); else { // Copy avatar file to store as global one TCHAR globalFile[1024]; BOOL saved = TRUE; if (FoldersGetCustomPathT(hGlobalAvatarFolder, globalFile, SIZEOF(globalFile), _T(""))) { mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s%s"), g_szDataPath, _T("GlobalAvatar")); CreateDirectory(globalFile, NULL); } TCHAR *ext = _tcsrchr(szFinalName, _T('.')); // Can't be NULL here if (format == PA_FORMAT_XML || format == PA_FORMAT_SWF) { mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s\\my_global_avatar%s"), globalFile, ext); CopyFile(szFinalName, globalFile, FALSE); } else { // Resize (to avoid too big avatars) ResizeBitmap rb = { 0 }; rb.size = sizeof(ResizeBitmap); rb.hBmp = hBmp; rb.max_height = 300; rb.max_width = 300; rb.fit = (data.grow ? 0 : RESIZEBITMAP_FLAG_DONT_GROW) | (data.square ? RESIZEBITMAP_MAKE_SQUARE : RESIZEBITMAP_KEEP_PROPORTIONS); HBITMAP hBmpTmp = (HBITMAP)CallService(MS_IMG_RESIZE, WPARAM(&rb), 0); // Check if need to resize if (hBmpTmp == hBmp || hBmpTmp == NULL) { // Use original image mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s\\my_global_avatar%s"), globalFile, ext); CopyFile(szFinalName, globalFile, FALSE); } else { // Save as PNG mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s\\my_global_avatar.png"), globalFile); if (BmpFilterSaveBitmap(hBmpTmp, globalFile, 0)) saved = FALSE; DeleteObject(hBmpTmp); } } if (saved) { TCHAR relFile[1024]; if (PathToRelativeT(globalFile, relFile, g_szDataPath)) db_set_ts(NULL, AVS_MODULE, "GlobalUserAvatarFile", relFile); else db_set_ts(NULL, AVS_MODULE, "GlobalUserAvatarFile", globalFile); db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 0); } else db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); } } DeleteObject(hBmp); SetIgnoreNotify(protocol, FALSE); ReportMyAvatarChanged(WPARAM((protocol == NULL) ? "" : protocol), 0); return ret; }