//*************************************************************************************** // // Google Extension plugin for the Miranda IM's Jabber protocol // Copyright (c) 2011 bems@jabber.org, George Hazan (ghazan@jabber.ru) // // 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 "stdafx.h" #include "resources.h" #include "options.h" #define AVA_FILE_NAME_FORMAT _T("%s\\%s\\AvatarCache\\Jabber\\") _T(SHORT_PLUGIN_NAME) _T(".pseudoava.png") #define AVA_RES_TYPE _T("PNG") #define SRMM_MODULE_NAME "SRMM" #define SRMM_AVATAR_SETTING_NAME "Avatar" #define SET_AVATAR_INTERVAL 2000 LPTSTR CreateAvaFile(HANDLE *hFile) { TCHAR name[MAX_PATH + 2]; TCHAR path[MAX_PATH + 2]; TCHAR full[MAX_PATH + 2]; if (CallService(MS_DB_GETPROFILENAMET, (WPARAM)SIZEOF(name), (LPARAM)&name)) return NULL; for (int i = lstrlen(name); i >= 0; i--) if ('.' == name[i]) { name[i] = 0; break; } if (CallService(MS_DB_GETPROFILEPATHT, (WPARAM)SIZEOF(path), (LPARAM)&path)) return NULL; mir_sntprintf(full, SIZEOF(full), AVA_FILE_NAME_FORMAT, path, name); CreateDirectoryTreeT(full); HANDLE h = CreateFile(full, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (h == INVALID_HANDLE_VALUE) return NULL; if (hFile) *hFile = h; else CloseHandle(h); return mir_tstrdup(full); } BOOL SaveAvatar(HANDLE hFile) { HRSRC hres = FindResource(g_hInst, MAKEINTRESOURCE(IDI_PSEUDOAVA), AVA_RES_TYPE); if (!hres) return FALSE; HGLOBAL hglob = LoadResource(g_hInst, hres); if (!hglob) return FALSE; PVOID p = LockResource(hglob); if (!p) return FALSE; DWORD l = SizeofResource(g_hInst, hres); if (!l) return FALSE; DWORD written; if (!WriteFile(hFile, p, l, &written, NULL)) return FALSE; return written == l; } struct AVACHANGED { HANDLE hTimer; HANDLE hContact; }; VOID CALLBACK CallSetAvatar(PVOID lpParameter, BOOLEAN TimerOrWaitFired) { Thread_Push(0); __try { AVACHANGED *ach = (AVACHANGED*)lpParameter; __try { SetAvatar(ach->hContact); DeleteTimerQueueTimer(NULL, ach->hTimer, NULL); } __finally { free(ach); } } __finally { Thread_Pop(); } } int AvaChanged(WPARAM wParam, LPARAM lParam) { if (!lParam && db_get_b((HANDLE)wParam, SHORT_PLUGIN_NAME, PSEUDOCONTACT_FLAG, 0)) { BOOL enqueued = FALSE; AVACHANGED *ach = (AVACHANGED*)malloc(sizeof(AVACHANGED)); __try { ach->hContact = (HANDLE)wParam; enqueued = CreateTimerQueueTimer(&ach->hTimer, NULL, CallSetAvatar, ach, SET_AVATAR_INTERVAL, 0, WT_EXECUTEONLYONCE); } __finally { if (!enqueued) free(ach); } } return 0; } CRITICAL_SECTION g_csSetAvatar; HANDLE hAvaChanged = 0; BOOL initialized = FALSE; BOOL InitAvaUnit(BOOL init) { if (init) { hAvaChanged = HookEvent(ME_AV_AVATARCHANGED, AvaChanged); InitializeCriticalSection(&g_csSetAvatar); initialized = TRUE; return hAvaChanged != 0; } else { if (initialized) { initialized = FALSE; DeleteCriticalSection(&g_csSetAvatar); } if (hAvaChanged) { UnhookEvent(hAvaChanged); hAvaChanged = 0; } return TRUE; } } void SetAvatar(HANDLE hContact) { mir_cslock lck(g_csSetAvatar); avatarCacheEntry *ava = (avatarCacheEntry*)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)hContact, 0); if (ava && GetFileAttributes(&ava->szFilename[0]) != INVALID_FILE_ATTRIBUTES) return; HANDLE hFile; ptrT avaFile( CreateAvaFile(&hFile)); if (avaFile == NULL) return; BOOL saved = SaveAvatar(hFile); CloseHandle(hFile); hFile = 0; if (!saved) return; if (ava) CallService(MS_AV_SETAVATART, (WPARAM)hContact, (LPARAM)_T("")); CallService(MS_AV_SETAVATART, (WPARAM)hContact, (LPARAM)avaFile); db_set_ts(hContact, SRMM_MODULE_NAME, SRMM_AVATAR_SETTING_NAME, avaFile); }