/* * Contactlist management functions */ #include "skype.h" #include "skypeapi.h" #include "debug.h" #include "pthread.h" #include "gchat.h" #include "voiceservice.h" #pragma warning (push) #pragma warning (disable: 4100) // unreferenced formal parameter #include #pragma warning (pop) #pragma warning (disable: 4706) // assignment within conditional expression // Imported Globals extern HINSTANCE hInst; extern BOOL bSkypeOut, bIsImoproxy; extern char protocol, g_szProtoName[]; // Handles static HANDLE hMenuCallItem, hMenuCallHangup, hMenuSkypeOutCallItem, hMenuHoldCallItem, hMenuFileTransferItem, hMenuChatInitItem; // Check if alpha blending icons are supported // Seems to be not neccessary /* BOOL SupportAlphaIcons(void) { HANDLE hMod; DLLVERSIONINFO tDVI={0}; BOOL retval=FALSE; FARPROC pDllGetVersion; if (!(hMod=LoadLibrary("comctl32.dll"))) return FALSE; if (pDllGetVersion=GetProcAddress(hMod, "DllGetVersion")) { tDVI.cbSize=sizeof(tDVI); if (!pDllGetVersion ((DLLVERSIONINFO *)&tDVI)) { if (GetDeviceCaps(GetDC(NULL), BITSPIXEL)*GetDeviceCaps(GetDC(NULL), PLANES)>=32 && tDVI.dwMajorVersion>=6) retval=TRUE; } } FreeLibrary(hMod); return retval; } */ CLISTMENUITEM CallItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); mi.pszContactOwner=SKYPE_PROTONAME; mi.ptszName=LPGENT("Call (Skype)"); mi.pszService=SKYPE_CALL; return mi; } CLISTMENUITEM SkypeOutCallItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_HIDDEN|CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALLSKYPEOUT)); mi.ptszName=LPGENT("Call using SkypeOut"); mi.pszService=SKYPEOUT_CALL; return mi; } CLISTMENUITEM HupItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); mi.pszContactOwner=SKYPE_PROTONAME; mi.ptszName=LPGENT("Hang up call (Skype)"); mi.pszService=SKYPE_CALLHANGUP; return mi; } CLISTMENUITEM SkypeOutHupItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); mi.ptszName=LPGENT("Hang up SkypeOut call"); mi.pszService=SKYPEOUT_CALL; return mi; } CLISTMENUITEM HoldCallItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HOLD)); mi.ptszName=LPGENT("Hold call"); mi.pszService=SKYPE_HOLDCALL; return mi; } CLISTMENUITEM ResumeCallItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_RESUME)); mi.ptszName=LPGENT("Resume call"); mi.pszService=SKYPE_HOLDCALL; return mi; } CLISTMENUITEM FileTransferItem(void) { CLISTMENUITEM mi={0}; // Stolen from file.c of Miranda core mi.cbSize=sizeof(mi); mi.position=-2000020000; mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; mi.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE); mi.ptszName=LPGENT("&File"); mi.pszContactOwner=SKYPE_PROTONAME; mi.pszService=SKYPE_SENDFILE; return mi; } CLISTMENUITEM ChatInitItem(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000020000; mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; mi.hIcon=LoadIcon( hInst, MAKEINTRESOURCE( IDI_INVITE )); mi.ptszName=LPGENT("&Open group chat"); mi.pszContactOwner=SKYPE_PROTONAME; mi.pszService=SKYPE_CHATNEW; return mi; } HANDLE add_contextmenu(MCONTACT hContact) { CLISTMENUITEM mi; UNREFERENCED_PARAMETER(hContact); if (!HasVoiceService()) { mi=CallItem(); hMenuCallItem=Menu_AddContactMenuItem(&mi); mi=HupItem(); hMenuCallHangup=Menu_AddContactMenuItem(&mi); } mi=SkypeOutCallItem(); hMenuSkypeOutCallItem=Menu_AddContactMenuItem(&mi); if (!HasVoiceService()) { mi=HoldCallItem(); hMenuHoldCallItem=Menu_AddContactMenuItem(&mi); } // We cannot use flag PF1_FILESEND for sending files, as Skype opens its own // sendfile-Dialog. mi=FileTransferItem(); hMenuFileTransferItem=Menu_AddContactMenuItem(&mi); mi=ChatInitItem(); hMenuChatInitItem=Menu_AddContactMenuItem(&mi); ZeroMemory(&mi,sizeof(mi)); mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)); mi.pszContactOwner=SKYPE_PROTONAME; mi.ptszName=LPGENT("Import Skype history"); mi.pszService=SKYPE_IMPORTHISTORY; return Menu_AddContactMenuItem(&mi); } HANDLE add_mainmenu(void) { CLISTMENUITEM mi={0}; mi.cbSize=sizeof(mi); mi.position=-2000005000; mi.flags=CMIF_TCHAR; mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ADD)); mi.pszContactOwner=SKYPE_PROTONAME; mi.ptszName=LPGENT("Add Skype contact"); mi.pszService=SKYPE_ADDUSER; return Menu_AddMainMenuItem(&mi); } int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { DBVARIANT dbv; CLISTMENUITEM mi; char *szProto; BOOL callAvailable = FALSE; BOOL hangupAvailable = FALSE; UNREFERENCED_PARAMETER(lParam); if (!(szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0))) return 0; if (!HasVoiceService()) { // Clear hold-Item in case it exists mi=HoldCallItem(); mi.flags|=CMIM_ALL; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); } if (!strcmp(szProto, SKYPE_PROTONAME)) { if (!HasVoiceService()) { if (!db_get((MCONTACT)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { if (db_get_b((MCONTACT)wParam, SKYPE_PROTONAME, "OnHold", 0)) mi=ResumeCallItem(); else mi=HoldCallItem(); mi.flags=CMIM_ALL; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); callAvailable = FALSE; hangupAvailable = TRUE; db_free(&dbv); } else { callAvailable = TRUE; hangupAvailable = FALSE; } if (db_get_b((MCONTACT)wParam, SKYPE_PROTONAME, "ChatRoom", 0)!=0) { callAvailable = FALSE; hangupAvailable = FALSE; } mi = CallItem(); mi.flags |= CMIM_ALL | (!callAvailable?CMIF_HIDDEN:0); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallItem,(LPARAM)&mi); mi = HupItem(); mi.flags |= CMIM_ALL | (!hangupAvailable?CMIF_HIDDEN:0); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallHangup,(LPARAM)&mi); } // Clear SkypeOut menu in case it exists mi=SkypeOutCallItem(); mi.flags|=CMIM_ALL; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); // File sending and groupchat-creation works starting with protocol version 5 if (protocol>=5) { mi=FileTransferItem(); if (db_get_b((MCONTACT)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) mi.flags ^= CMIF_HIDDEN; mi.flags |= CMIM_FLAGS; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuFileTransferItem,(LPARAM)&mi); } if (protocol>=5 || bIsImoproxy) { mi=ChatInitItem(); if (db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0) && db_get_b((MCONTACT)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) mi.flags ^= CMIF_HIDDEN; mi.flags |= CMIM_FLAGS; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuChatInitItem,(LPARAM)&mi); } } else if (bSkypeOut) { if (!db_get((MCONTACT)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { mi=SkypeOutHupItem(); db_free(&dbv); } else { mi=SkypeOutCallItem(); if(!db_get((MCONTACT)wParam,"UserInfo","MyPhone0",&dbv)) { db_free(&dbv); mi.flags=0; } } mi.flags|=CMIM_ALL; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); } return 0; } /* int ClistDblClick(WPARAM wParam, LPARAM lParam) { char *szProto; szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, wParam, 0 ); if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_w((HANDLE)wParam, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)==ID_STATUS_ONTHEPHONE) { SkypeCall(wParam, 0); } return 0; } */ MCONTACT find_contact(char *name) { int tCompareResult; DBVARIANT dbv; // already on list? for (MCONTACT hContact = db_find_first(); hContact != NULL; hContact=db_find_next(hContact)) { char *szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, hContact, 0 ); if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) { if (db_get_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; tCompareResult = strcmp(dbv.pszVal, name); db_free(&dbv); if (tCompareResult) continue; return hContact; // already there, return handle } } return NULL; } MCONTACT find_contactT(TCHAR *name) { int tCompareResult; DBVARIANT dbv; // already on list? for (MCONTACT hContact=db_find_first(); hContact != NULL; hContact=db_find_next(hContact)) { char *szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, hContact, 0 ); if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) { if (db_get_ts(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; tCompareResult = _tcscmp(dbv.ptszVal, name); db_free(&dbv); if (tCompareResult) continue; return hContact; // already there, return handle } } return NULL; } MCONTACT add_contact(char *name, DWORD flags) { MCONTACT hContact; // already on list? if (hContact=find_contact(name)) { if (!(flags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 1)) { db_unset( hContact, "CList", "NotOnList" ); db_unset( hContact, "CList", "Hidden" ); } LOG(("add_contact: Found %s", name)); return hContact; // already there, return handle } // no, so add LOG(("add_contact: Adding %s", name)); hContact=(MCONTACT)CallServiceSync(MS_DB_CONTACT_ADD, 0, 0); if (hContact) { if (CallServiceSync(MS_PROTO_ADDTOCONTACT, hContact,(LPARAM)SKYPE_PROTONAME)!=0) { LOG(("add_contact: Ouch! MS_PROTO_ADDTOCONTACT failed for some reason")); CallServiceSync(MS_DB_CONTACT_DELETE, hContact, 0); return NULL; } if (name[0]) db_set_s(hContact, SKYPE_PROTONAME, SKYPE_NAME, name); if (flags & PALF_TEMPORARY ) { db_set_b(hContact, "CList", "NotOnList", 1); db_set_b(hContact, "CList", "Hidden", 1); } if (name[0]) { SkypeSend("GET USER %s DISPLAYNAME", name); } else {LOG(("add_contact: Info: The contact added has no name."));} } else {LOG(("add_contact: Ouch! MS_DB_CONTACT_ADD failed for some reason"));} LOG(("add_contact succeeded")); return hContact; } void logoff_contacts(BOOL bCleanup) { MCONTACT hContact; char *szProto; DBVARIANT dbv={0}; LOG(("logoff_contacts: Logging off contacts.")); for (hContact=db_find_first();hContact != NULL;hContact=db_find_next(hContact)) { szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, hContact, 0 ); if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME)) { if (db_get_w(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) db_set_w(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE); db_unset(hContact, SKYPE_PROTONAME, "CallId"); if (db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==1) { if (db_get_ts(hContact, SKYPE_PROTONAME, "ChatRoomID", &dbv)) continue; RemChat (dbv.ptszVal); db_free(&dbv); } if (db_get_s(hContact, SKYPE_PROTONAME, "Typing_Stream", &dbv) == 0) { if (bCleanup) SkypeSend ("ALTER APPLICATION libpurple_typing DISCONNECT %s", dbv.pszVal); db_free(&dbv); db_unset(hContact, SKYPE_PROTONAME, "Typing_Stream"); } } } if (bCleanup && (protocol>=5 || bIsImoproxy)) SkypeSend ("DELETE APPLICATION libpurple_typing"); }