pidgin/pidgin

f9ea6d5e8992
Use PurpleCredentialManager instead of the old keyring api.

Testing Done:
Connected with bonjour (no password), irc (optional password, non set), and xmpp (password required, not saved, entered manually, not saved) and verified that all of them connected properly.

Reviewed at https://reviews.imfreedom.org/r/289/
/*
* purple
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "internal.h"
#include "purpleprivate.h"
#include "conversations.h"
static GList *conversations = NULL;
static GList *ims = NULL;
static GList *chats = NULL;
static PurpleConversationUiOps *default_ops = NULL;
/*
* A hash table used for efficient lookups of conversations by name.
* struct _purple_hconv => PurpleConversation*
*/
static GHashTable *conversation_cache = NULL;
struct _purple_hconv {
gboolean im;
char *name;
PurpleAccount *account;
};
static guint
_purple_conversations_hconv_hash(struct _purple_hconv *hc)
{
return g_str_hash(hc->name) ^ hc->im ^ g_direct_hash(hc->account);
}
static guint
_purple_conversations_hconv_equal(struct _purple_hconv *hc1, struct _purple_hconv *hc2)
{
return (hc1->im == hc2->im &&
hc1->account == hc2->account &&
g_str_equal(hc1->name, hc2->name));
}
static void
_purple_conversations_hconv_free_key(struct _purple_hconv *hc)
{
g_free(hc->name);
g_free(hc);
}
void
purple_conversations_add(PurpleConversation *conv)
{
PurpleAccount *account;
struct _purple_hconv *hc;
g_return_if_fail(conv != NULL);
if (g_list_find(conversations, conv) != NULL)
return;
conversations = g_list_prepend(conversations, conv);
if (PURPLE_IS_IM_CONVERSATION(conv))
ims = g_list_prepend(ims, conv);
else
chats = g_list_prepend(chats, conv);
account = purple_conversation_get_account(conv);
hc = g_new(struct _purple_hconv, 1);
hc->name = g_strdup(purple_normalize(account,
purple_conversation_get_name(conv)));
hc->account = account;
hc->im = PURPLE_IS_IM_CONVERSATION(conv);
g_hash_table_insert(conversation_cache, hc, conv);
}
void
purple_conversations_remove(PurpleConversation *conv)
{
PurpleAccount *account;
struct _purple_hconv hc;
g_return_if_fail(conv != NULL);
conversations = g_list_remove(conversations, conv);
if (PURPLE_IS_IM_CONVERSATION(conv))
ims = g_list_remove(ims, conv);
else
chats = g_list_remove(chats, conv);
account = purple_conversation_get_account(conv);
hc.name = (gchar *)purple_normalize(account,
purple_conversation_get_name(conv));
hc.account = account;
hc.im = PURPLE_IS_IM_CONVERSATION(conv);
g_hash_table_remove(conversation_cache, &hc);
}
void
_purple_conversations_update_cache(PurpleConversation *conv, const char *name,
PurpleAccount *account)
{
PurpleAccount *old_account;
struct _purple_hconv *hc;
g_return_if_fail(conv != NULL);
g_return_if_fail(account != NULL || name != NULL);
old_account = purple_conversation_get_account(conv);
hc = g_new(struct _purple_hconv, 1);
hc->im = PURPLE_IS_IM_CONVERSATION(conv);
hc->account = old_account;
hc->name = (gchar *)purple_normalize(old_account,
purple_conversation_get_name(conv));
g_hash_table_remove(conversation_cache, hc);
if (account)
hc->account = account;
if (name)
hc->name = g_strdup(purple_normalize(hc->account, name));
g_hash_table_insert(conversation_cache, hc, conv);
}
GList *
purple_conversations_get_all(void)
{
return conversations;
}
GList *
purple_conversations_get_ims(void)
{
return ims;
}
GList *
purple_conversations_get_chats(void)
{
return chats;
}
PurpleConversation *
purple_conversations_find_with_account(const char *name,
PurpleAccount *account)
{
PurpleConversation *c = NULL;
struct _purple_hconv hc;
g_return_val_if_fail(name != NULL, NULL);
hc.name = (gchar *)purple_normalize(account, name);
hc.account = account;
hc.im = TRUE;
c = g_hash_table_lookup(conversation_cache, &hc);
if (!c) {
hc.im = FALSE;
c = g_hash_table_lookup(conversation_cache, &hc);
}
return c;
}
PurpleIMConversation *
purple_conversations_find_im_with_account(const char *name,
PurpleAccount *account)
{
PurpleIMConversation *im = NULL;
struct _purple_hconv hc;
g_return_val_if_fail(name != NULL, NULL);
hc.name = (gchar *)purple_normalize(account, name);
hc.account = account;
hc.im = TRUE;
im = g_hash_table_lookup(conversation_cache, &hc);
return im;
}
PurpleChatConversation *
purple_conversations_find_chat_with_account(const char *name,
PurpleAccount *account)
{
PurpleChatConversation *c = NULL;
struct _purple_hconv hc;
g_return_val_if_fail(name != NULL, NULL);
hc.name = (gchar *)purple_normalize(account, name);
hc.account = account;
hc.im = FALSE;
c = g_hash_table_lookup(conversation_cache, &hc);
return c;
}
PurpleChatConversation *
purple_conversations_find_chat(const PurpleConnection *gc, int id)
{
GList *l;
PurpleChatConversation *chat;
for (l = purple_conversations_get_chats(); l != NULL; l = l->next) {
chat = (PurpleChatConversation *)l->data;
if (purple_chat_conversation_get_id(chat) == id &&
purple_conversation_get_connection(PURPLE_CONVERSATION(chat)) == gc)
return chat;
}
return NULL;
}
void
purple_conversations_set_ui_ops(PurpleConversationUiOps *ops)
{
default_ops = ops;
}
PurpleConversationUiOps *
purple_conversations_get_ui_ops(void)
{
return default_ops;
}
void *
purple_conversations_get_handle(void)
{
static int handle;
return &handle;
}
void
purple_conversations_init(void)
{
void *handle = purple_conversations_get_handle();
conversation_cache = g_hash_table_new_full((GHashFunc)_purple_conversations_hconv_hash,
(GEqualFunc)_purple_conversations_hconv_equal,
(GDestroyNotify)_purple_conversations_hconv_free_key, NULL);
/**********************************************************************
* Register preferences
**********************************************************************/
/* Conversations */
purple_prefs_add_none("/purple/conversations");
/* Conversations -> Chat */
purple_prefs_add_none("/purple/conversations/chat");
purple_prefs_add_bool("/purple/conversations/chat/show_nick_change", TRUE);
/* Conversations -> IM */
purple_prefs_add_none("/purple/conversations/im");
purple_prefs_add_bool("/purple/conversations/im/send_typing", TRUE);
/**********************************************************************
* Register signals
**********************************************************************/
purple_signal_register(handle, "writing-im-msg",
purple_marshal_BOOLEAN__POINTER_POINTER, G_TYPE_BOOLEAN, 2,
PURPLE_TYPE_IM_CONVERSATION, PURPLE_TYPE_MESSAGE);
purple_signal_register(handle, "wrote-im-msg",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_IM_CONVERSATION, PURPLE_TYPE_MESSAGE);
purple_signal_register(handle, "sent-attention",
purple_marshal_VOID__POINTER_POINTER_POINTER_UINT,
G_TYPE_NONE, 4, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
purple_signal_register(handle, "got-attention",
purple_marshal_VOID__POINTER_POINTER_POINTER_UINT,
G_TYPE_NONE, 4, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
purple_signal_register(handle, "sending-im-msg",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE,
2, PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_MESSAGE);
purple_signal_register(handle, "sent-im-msg",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE,
2, PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_MESSAGE);
purple_signal_register(handle, "receiving-im-msg",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT,
G_TYPE_POINTER, /* pointer to a string */
G_TYPE_POINTER, /* pointer to a string */
PURPLE_TYPE_IM_CONVERSATION,
G_TYPE_POINTER); /* pointer to a string */
purple_signal_register(handle, "received-im-msg",
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
G_TYPE_STRING, PURPLE_TYPE_IM_CONVERSATION, G_TYPE_UINT);
purple_signal_register(handle, "blocked-im-msg",
purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT,
G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT);
purple_signal_register(handle, "writing-chat-msg",
purple_marshal_BOOLEAN__POINTER_POINTER, G_TYPE_BOOLEAN, 2,
PURPLE_TYPE_IM_CONVERSATION, PURPLE_TYPE_MESSAGE);
purple_signal_register(handle, "wrote-chat-msg",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_IM_CONVERSATION, PURPLE_TYPE_MESSAGE);
purple_signal_register(handle, "sending-chat-msg",
purple_marshal_VOID__POINTER_POINTER_UINT, G_TYPE_NONE,
3, PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_MESSAGE, G_TYPE_UINT);
purple_signal_register(handle, "sent-chat-msg",
purple_marshal_VOID__POINTER_POINTER_UINT, G_TYPE_NONE,
3, PURPLE_TYPE_ACCOUNT, PURPLE_TYPE_MESSAGE, G_TYPE_UINT);
purple_signal_register(handle, "receiving-chat-msg",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
G_TYPE_BOOLEAN, 5, PURPLE_TYPE_ACCOUNT,
G_TYPE_POINTER, /* pointer to a string */
G_TYPE_POINTER, /* pointer to a string */
PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_POINTER); /* pointer to an unsigned int */
purple_signal_register(handle, "received-chat-msg",
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT,
G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
G_TYPE_STRING, PURPLE_TYPE_CHAT_CONVERSATION, G_TYPE_UINT);
purple_signal_register(handle, "conversation-created",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_CONVERSATION);
purple_signal_register(handle, "conversation-updated",
purple_marshal_VOID__POINTER_UINT, G_TYPE_NONE, 2,
PURPLE_TYPE_CONVERSATION, G_TYPE_UINT);
purple_signal_register(handle, "deleting-conversation",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_CONVERSATION);
purple_signal_register(handle, "buddy-typing",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
purple_signal_register(handle, "buddy-typed",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
purple_signal_register(handle, "buddy-typing-stopped",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_ACCOUNT, G_TYPE_STRING);
purple_signal_register(handle, "chat-user-joining",
purple_marshal_BOOLEAN__POINTER_POINTER_UINT,
G_TYPE_BOOLEAN, 3, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING, G_TYPE_UINT);
purple_signal_register(handle, "chat-user-joined",
purple_marshal_VOID__POINTER_POINTER_UINT_UINT,
G_TYPE_NONE, 4, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
purple_signal_register(handle, "chat-user-flags",
purple_marshal_VOID__POINTER_UINT_UINT, G_TYPE_NONE, 3,
PURPLE_TYPE_CHAT_USER, G_TYPE_UINT, G_TYPE_UINT);
purple_signal_register(handle, "chat-user-leaving",
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
G_TYPE_BOOLEAN, 3, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING, G_TYPE_STRING);
purple_signal_register(handle, "chat-user-left",
purple_marshal_VOID__POINTER_POINTER_POINTER,
G_TYPE_NONE, 3, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING, G_TYPE_STRING);
purple_signal_register(handle, "chat-inviting-user",
purple_marshal_VOID__POINTER_POINTER_POINTER,
G_TYPE_NONE, 3, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING,
G_TYPE_POINTER); /* pointer to a string */
purple_signal_register(handle, "chat-invited-user",
purple_marshal_VOID__POINTER_POINTER_POINTER,
G_TYPE_NONE, 3, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING, G_TYPE_STRING);
purple_signal_register(handle, "chat-invited",
purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER,
G_TYPE_INT, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
purple_signal_register(handle, "chat-invite-blocked",
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER,
G_TYPE_NONE, 5, PURPLE_TYPE_ACCOUNT, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER); /* (GHashTable *) */
purple_signal_register(handle, "chat-joined",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_CHAT_CONVERSATION);
purple_signal_register(handle, "chat-join-failed",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_CONNECTION, G_TYPE_POINTER);
purple_signal_register(handle, "chat-left",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_CHAT_CONVERSATION);
purple_signal_register(handle, "chat-topic-changed",
purple_marshal_VOID__POINTER_POINTER_POINTER,
G_TYPE_NONE, 3, PURPLE_TYPE_CHAT_CONVERSATION,
G_TYPE_STRING, G_TYPE_STRING);
purple_signal_register(handle, "cleared-message-history",
purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
PURPLE_TYPE_CONVERSATION);
purple_signal_register(handle, "conversation-extended-menu",
purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
PURPLE_TYPE_CONVERSATION,
G_TYPE_POINTER); /* (GList **) */
}
void
purple_conversations_uninit(void)
{
while (conversations)
g_object_unref(G_OBJECT(conversations->data));
g_hash_table_destroy(conversation_cache);
purple_signals_unregister_by_instance(purple_conversations_get_handle());
}