Protocol::Protocol(const char *aName, const TCHAR *descr) { mir_strncpy(name, aName, _countof(name)); mir_tstrncpy(description, descr, _countof(description)); data_changed = true; // Load services int caps = CallProtoService(name, PS_GETCAPS, PFLAGNUM_1, 0); if (caps & PF1_IM) valid = true; else return; can_have_listening_to = (ProtoServiceExists(name, PS_SET_LISTENINGTO) != 0); PF3 = CallProtoService(name, PS_GETCAPS, (WPARAM)PFLAGNUM_3, 0); caps = CallProtoService(name, PS_GETCAPS, PFLAGNUM_4, 0); can_have_avatar = (caps & PF4_AVATARS) != 0; can_set_nick = ProtoServiceExists(name, PS_SETMYNICKNAME) != FALSE; // Initial value GetStatus(); GetStatusMsg(); GetNick(); GetAvatar(); }
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 Proto_GetDelayAfterFail(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_DELAYAFTERFAIL, 0); return 0; }
void SetStatus(WORD code, StatusItem* item, char *szAccName) { if (code == IDCLOSE) return; PROTOACCOUNT* pdescr = Proto_GetAccount(szAccName); if (pdescr == nullptr) return; if (!ProtoServiceExists(szAccName, PS_SETCUSTOMSTATUSEX)) return; int statusToSet; CUSTOM_STATUS ics = { sizeof(CUSTOM_STATUS) }; ics.flags = CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE | CSSF_UNICODE; if (code == IDC_CANCEL) { statusToSet = 0; ics.ptszName = L""; ics.ptszMessage = L""; } else if (code == IDOK && item != nullptr) { statusToSet = item->m_iIcon + 1; ics.ptszName = variables_parsedup(item->m_tszTitle, nullptr, NULL); ics.ptszMessage = variables_parsedup(item->m_tszMessage, nullptr, NULL); } else return; ics.status = &statusToSet; CallProtoService(szAccName, PS_SETCUSTOMSTATUSEX, 0, (LPARAM)&ics); }
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); }
BOOL Proto_NeedDelaysForAvatars(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_DONTNEEDDELAYS, 0) <= 0; return TRUE; }
BOOL Proto_IsFetchingWhenProtoNotVisibleAllowed(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_FETCHIFPROTONOTVISIBLE, 0); return FALSE; }
int Proto_GetAvatarMaxFileSize(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_MAXFILESIZE, 0); return 0; }
void AddEventThread(void *arg) { HANDLE hContact = (HANDLE)arg; TCHAR stzTitle[MAX_TITLE_LEN], stzText[MAX_TEXT_LEN]; char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); if (szProto == NULL) return; if (ProtoServiceExists(szProto, JS_PARSE_XMPP_URI)) { GetJabberAdvStatusText(hContact, szProto, "mood", "title", stzTitle, SIZEOF(stzTitle)); if (stzTitle[0]) { GetJabberAdvStatusText(hContact, szProto, "mood", "text", stzText, SIZEOF(stzText)); LogXstatusChange(hContact, szProto, TYPE_JABBER_MOOD, stzTitle, stzText); } GetJabberAdvStatusText(hContact, szProto, "activity", "title", stzTitle, SIZEOF(stzTitle)); if (stzTitle[0]) { GetJabberAdvStatusText(hContact, szProto, "activity", "text", stzText, SIZEOF(stzText)); LogXstatusChange(hContact, szProto, TYPE_JABBER_ACTIVITY, stzTitle, stzText); } } else { GetIcqXStatus(hContact, szProto, "XStatusName", stzTitle, SIZEOF(stzTitle)); if (stzTitle[0]) { GetIcqXStatus(hContact, szProto, "XStatusMsg", stzText, SIZEOF(stzText)); LogXstatusChange(hContact, szProto, TYPE_ICQ_XSTATUS, stzTitle, stzText); } } }
int Proto_AvatarImageProportion(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_PROPORTION, 0); return 0; }
BOOL Proto_IsAvatarsEnabled(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_ENABLED, 0); return TRUE; }
static void sttPreviewSkin(MODERNOPTOBJECT *obj, TCHAR *fn, LPDRAWITEMSTRUCT lps) { if (!fn) return; if (ProtoServiceExists(obj->lpzThemeModuleName, TS_SKIN_PREVIEW)) { CallProtoService(obj->lpzThemeModuleName, TS_SKIN_PREVIEW, (WPARAM)lps, (LPARAM)fn); return; } HBITMAP hbmPreview = Bitmap_Load(CMString(fn) + _T(".png")); if (!hbmPreview) return; BITMAP bmp; GetObject(hbmPreview, sizeof(bmp), &bmp); SIZE szDst = { abs(bmp.bmWidth), abs(bmp.bmHeight) }; if ((szDst.cx > lps->rcItem.right - lps->rcItem.left) || (szDst.cy > lps->rcItem.bottom - lps->rcItem.top)) { float q = min( float(lps->rcItem.right - lps->rcItem.left) / szDst.cx, float(lps->rcItem.bottom - lps->rcItem.top) / szDst.cy); szDst.cx *= q; szDst.cy *= q; } POINT ptDst = { (lps->rcItem.left + lps->rcItem.right - szDst.cx) / 2, (lps->rcItem.top + lps->rcItem.bottom - szDst.cy) / 2 }; HDC hdc = CreateCompatibleDC(lps->hDC); SelectObject(hdc, hbmPreview); SetStretchBltMode(hdc, HALFTONE); StretchBlt(lps->hDC, ptDst.x, ptDst.y, szDst.cx, szDst.cy, hdc, 0, 0, abs(bmp.bmWidth), abs(bmp.bmHeight), SRCCOPY); DeleteDC(hdc); DeleteObject(hbmPreview); }
BOOL Proto_IsFetchingWhenContactOfflineAllowed(const char *proto) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_FETCHIFCONTACTOFFLINE, 0); return FALSE; }
static int OnCreateMenuItems(WPARAM, LPARAM) { for (auto &pa : Accounts()) if (ProtoServiceExists(pa->szModuleName, PS_SETCUSTOMSTATUSEX)) addProtoStatusMenuItem(pa->szModuleName); return 0; }
static INT_PTR CanSetMyAvatar(WPARAM wParam, LPARAM) { char *protocol = (char *)wParam; if (protocol == NULL || fei == NULL) return 0; return ProtoServiceExists(protocol, PS_SETMYAVATAR); }
TCHAR *Hlp_GetProtocolName(const char *proto) { char protoname[256]; if ((!ProtoServiceExists(proto, PS_GETNAME)) || (CallProtoService(proto, PS_GETNAME, (WPARAM)sizeof(protoname), (LPARAM)protoname))) return NULL; return mir_a2t(protoname); }
int Protocol::GetNickMaxLength() { if (!ProtoServiceExists(name, PS_GETMYNICKNAMEMAXLENGTH)) return MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE; int ret = CallProtoService(name, PS_GETMYNICKNAMEMAXLENGTH, 0, 0); if (ret <= 0) ret = MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE; return ret; }
BOOL Proto_IsAvatarFormatSupported(const char *proto, int format) { if (ProtoServiceExists(proto, PS_GETAVATARCAPS)) return CallProtoService(proto, PS_GETAVATARCAPS, AF_FORMATSUPPORTED, format); if (format >= PA_FORMAT_SWF) return FALSE; return TRUE; }
void HideNudgeButton(MCONTACT hContact) { char *szProto = GetContactProto(hContact); if (!ProtoServiceExists(szProto, PS_SEND_NUDGE)) { BBButton bbd = { sizeof(bbd) }; bbd.bbbFlags = BBSF_HIDDEN | BBSF_DISABLED; bbd.pszModuleName = "Nudge"; bbd.dwButtonID = 6000; CallService(MS_BB_SETBUTTONSTATE, hContact, (LPARAM)&bbd); } }
static INT_PTR VoiceRegister(WPARAM wParam, LPARAM lParam) { VOICE_MODULE *in = (VOICE_MODULE *) wParam; if (in == NULL || in->cbSize < sizeof(VOICE_MODULE) || in->name == NULL || in->description == NULL) return -1; if (FindModule(in->name) != NULL) return -2; if (!ProtoServiceExists(in->name, PS_VOICE_CALL) || !ProtoServiceExists(in->name, PS_VOICE_ANSWERCALL) || !ProtoServiceExists(in->name, PS_VOICE_DROPCALL)) return -3; modules.insert(new VoiceProvider(in->name, in->description, in->flags, in->icon)); if (hwnd_frame != NULL) PostMessage(hwnd_frame, WMU_REFRESH, 0, 0); return 0; }
void Protocol::GetStatusMsg(int aStatus, TCHAR *msg, size_t msg_size) { if (!CanGetStatusMsg()) lcopystr(msg, _T(""), msg_size); else if (aStatus == status && ProtoServiceExists(name, PS_GETMYAWAYMSG)) { ptrT tmp((TCHAR *)CallProtoService(name, PS_GETMYAWAYMSG, 0, SGMA_TCHAR)); lcopystr(msg, tmp == NULL ? _T("") : tmp, msg_size); } else if (ServiceExists(MS_AWAYMSG_GETSTATUSMSGT)) { ptrT tmp((TCHAR *)CallService(MS_AWAYMSG_GETSTATUSMSGT, (WPARAM)aStatus, (LPARAM)name)); lcopystr(msg, tmp == NULL ? _T("") : tmp, msg_size); } }
//This function gets HWND of the window, the number, and the message. void StartSmsSend(HWND hWndDlg,SIZE_T dwModuleIndex,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPWSTR lpwszMessage,SIZE_T dwMessageSize) { if (ssSMSSettings.ppaSMSAccounts && dwModuleIndex!=-1 && dwModuleIndex<ssSMSSettings.dwSMSAccountsCount) { LPSTR lpszMessageUTF; LPWSTR lpwszMessageXMLEncoded; SIZE_T dwMessageUTFBuffSize,dwMessageXMLEncodedSize,dwBuffSize; DBEVENTINFO *pdbei; dwMessageXMLEncodedSize=((dwMessageSize+MAX_PATH)*sizeof(WCHAR)*6); lpwszMessageXMLEncoded=(LPWSTR)MEMALLOC(dwMessageXMLEncodedSize); if (lpwszMessageXMLEncoded) { EncodeXML(lpwszMessage,dwMessageSize,lpwszMessageXMLEncoded,(dwMessageXMLEncodedSize/sizeof(WCHAR)),&dwMessageXMLEncodedSize); dwMessageUTFBuffSize=(dwMessageXMLEncodedSize+MAX_PATH); lpszMessageUTF=(LPSTR)MEMALLOC(dwMessageUTFBuffSize); if (lpszMessageUTF) { dwBuffSize=(dwPhoneSize+MAX_PATH+WideCharToMultiByte(CP_UTF8,0,lpwszMessage,dwMessageSize,lpszMessageUTF,dwMessageUTFBuffSize,NULL,NULL)); pdbei=(DBEVENTINFO*)MEMALLOC((sizeof(DBEVENTINFO)+dwBuffSize)); if (pdbei) { char szPhone[MAX_PHONE_LEN]; LPSTR lpszBuff=(LPSTR)(pdbei+1); HANDLE hProcess; WideCharToMultiByte(CP_UTF8,0,lpwszPhone,dwPhoneSize,szPhone,MAX_PHONE_LEN,NULL,NULL); dwPhoneSize=CopyNumberA(szPhone,szPhone,dwPhoneSize); pdbei->timestamp=time(NULL); pdbei->flags=(DBEF_SENT|DBEF_UTF); pdbei->eventType=ICQEVENTTYPE_SMS; pdbei->cbBlob=(mir_snprintf(lpszBuff,dwBuffSize,"SMS To: +%s\r\n%s",szPhone,lpszMessageUTF)+4); pdbei->pBlob=(PBYTE)lpszBuff; SendSMSWindowDbeiSet(hWndDlg,pdbei); char *szProto = ssSMSSettings.ppaSMSAccounts[dwModuleIndex]->szModuleName; if ( ProtoServiceExists(szProto, MS_ICQ_SENDSMS)) { WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpszMessageUTF,dwMessageUTFBuffSize,NULL,NULL); hProcess = (HANDLE)ProtoCallService(szProto, MS_ICQ_SENDSMS, (WPARAM)szPhone,(LPARAM)lpszMessageUTF); SendSMSWindowHProcessSet(hWndDlg,hProcess); } else MEMFREE(pdbei); } MEMFREE(lpszMessageUTF); } MEMFREE(lpwszMessageXMLEncoded); } } }
bool VoiceProvider::CanCall(const TCHAR *number) { if (number == NULL || number[0] == 0) return false; if ((flags & VOICE_CAPS_CALL_STRING) == 0) return false; if (ProtoServiceExists(name, PS_VOICE_CALL_STRING_VALID)) return CallProtoService(name, PS_VOICE_CALL_STRING_VALID, (WPARAM) number, 0) != FALSE; if (is_protocol) { return CallProtoService(name, PS_GETSTATUS, 0, 0) > ID_STATUS_OFFLINE; } return true; }
int Protocol::GetStatus() { INT_PTR iStatus = CallProtoService(name, PS_GETSTATUS, 0, 0); if (iStatus == CALLSERVICE_NOTFOUND) return status = ID_STATUS_OFFLINE; if (iStatus != status) data_changed = true; status = (int)iStatus; // check if protocol supports custom status CUSTOM_STATUS css = { sizeof(css) }; TCHAR tszXStatusName[256], tszXStatusMessage[1024]; if (ProtoServiceExists(name, PS_GETCUSTOMSTATUSEX)) { // check if custom status is set css.flags = CSSF_TCHAR | CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE | CSSF_DEFAULT_NAME; css.status = &custom_status; css.ptszName = tszXStatusName; css.ptszMessage = tszXStatusMessage; if (CallProtoService(name, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&css) != 0) tszXStatusMessage[0] = tszXStatusName[0] = 0, custom_status = 0; } else custom_status = 0; // if protocol supports custom status, but it is not set (custom_status will be -1), show normal status if (custom_status < 0) custom_status = 0; if (custom_status == 0) { TCHAR *tmp = pcli->pfnGetStatusModeDescription(status, 0); lcopystr(status_name, tmp, _countof(status_name)); } else { TCHAR *p = (tszXStatusName[0] != 0) ? TranslateTS(tszXStatusName) : TranslateT("<no status name>"); if (tszXStatusMessage[0]) mir_sntprintf(status_name, _T("%s: %s"), p, tszXStatusMessage); else lcopystr(status_name, p, _countof(status_name)); } return status; }
/** Call when we want to send a user is typing message * * @param wParam HANDLE to the contact that we are typing to * @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF */ static INT_PTR Meta_UserIsTyping(WPARAM hMeta, LPARAM lParam) { DBCachedContact *cc = CheckMeta(hMeta); if (cc == NULL) return 0; // forward to sending protocol, if supported MCONTACT hMostOnline = Meta_GetMostOnline(cc); Meta_CopyContactNick(cc, hMostOnline); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (proto) if (ProtoServiceExists(proto, PSS_USERISTYPING)) ProtoCallService(proto, PSS_USERISTYPING, hMostOnline, lParam); return 0; }
VoiceProvider::VoiceProvider(const char *name, const TCHAR *description, int flags, const char *icon) { strncpy(this->name, name, MAX_REGS(this->name)); this->name[MAX_REGS(this->name)-1] = 0; lstrcpyn(this->description, description, MAX_REGS(this->description)); if (icon == NULL) this->icon[0] = 0; else lstrcpynA(this->icon, icon, MAX_REGS(this->icon)); this->flags = flags; is_protocol = IsProtocol(name); canHold = (ProtoServiceExists(name, PS_VOICE_HOLDCALL) != 0); char str[MAXMODULELABELLENGTH]; mir_snprintf(str, MAX_REGS(str), "%s%s", name, PE_VOICE_CALL_STATE); state_hook = HookEvent(str, VoiceState); }
void updateXstatusProto(PROTOCOL_INFO *protoInfo) { if (!ProtoServiceExists(protoInfo->szProto, PS_GETCUSTOMSTATUSEX)) return; // Retrieve xstatus.count CUSTOM_STATUS xstatus = { sizeof(xstatus) }; xstatus.flags = CSSF_STATUSES_COUNT; xstatus.wParam = &(protoInfo->xstatus.count); CallProtoService(protoInfo->szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); (protoInfo->xstatus.count)++; // Don't forget about xstatus=0 (None) // Alloc and initiailize xstatus.enabled array protoInfo->xstatus.enabled = (BOOL *)malloc(protoInfo->xstatus.count * sizeof(BOOL)); if (!protoInfo->xstatus.enabled) protoInfo->xstatus.count = 0; else for (unsigned i=0; i < protoInfo->xstatus.count; i++) protoInfo->xstatus.enabled[i] = FALSE; }
static void AddAccount(PROTOACCOUNT *acc) { if (!IsAccountEnabled(acc)) return; if (IsEmptyA(acc->szModuleName)) return; if (!ProtoServiceExists(acc->szModuleName, PS_VOICE_CAPS)) return; int flags = CallProtoService(acc->szModuleName, PS_VOICE_CAPS, 0, 0); if ((flags & VOICE_CAPS_VOICE) == 0) return; VOICE_MODULE vm = {0}; vm.cbSize = sizeof(vm); vm.name = acc->szModuleName; vm.description = acc->tszAccountName; vm.flags = flags; VoiceRegister((WPARAM) &vm, 0); }
void ModulesLoadedServices() { // Now initialize things for(unsigned int i = 0; i < protos.count; i++) { if (!(CallProtoService(protos.info[i].name, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) continue; if (ProtoServiceExists(protos.info[i].name, PS_GETMYAWAYMSG)) continue; protos.info[i].flags = CallProtoService(protos.info[i].name, PS_GETCAPS, PFLAGNUM_3, 0); if (protos.info[i].flags == 0) continue; // Is a valid proto protos.info[i].initialized = TRUE; protos.info[i].handleGetAwayMsg = (HANDLE) CreateProtoServiceFunction(protos.info[i].name, PS_GETMYAWAYMSG, getAwayFuncs[i]); } }
INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA*)lParam; // This is a simple contact // (this should normally not happen, since linked contacts do not appear on the list.) DBCachedContact *cc = CheckMeta(ccs->hContact); if (cc == NULL || cc->nDefault == -1) return 0; MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (!proto) return 0; PROTO_AVATAR_INFORMATIONT AI; AI.cbSize = sizeof(AI); AI.hContact = ccs->hContact; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if (CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(ccs->hContact, "ContactPhoto", "File", AI.filename); hMostOnline = Meta_GetMostOnline(cc); Meta_CopyContactNick(cc, hMostOnline); if (!hMostOnline) return 0; ccs->hContact = hMostOnline; if (!ProtoServiceExists(proto, PSS_GETINFO)) return 0; // fail return CallContactService(ccs->hContact, PSS_GETINFO, ccs->wParam, ccs->lParam); }