# HG changeset patch # User Mark Doliner # Date 1094789376 0 # Node ID 9baedaca25c7f13f2dd5adab5483615b7f6b2a5d # Parent c892b6dbc341d83477e239b2fa383da3a5a36307 [gaim-migrate @ 10923] This is a patch from Dave West. He says it makes people show up as online/offline for him. It crashes for me. I've changed some things from his patch, so I'm gonna commit it and let people work from there. I feel it's a step in the right direction. committer: Tailor Script diff -r c892b6dbc341 -r 9baedaca25c7 src/gtkblist.c --- a/src/gtkblist.c Fri Sep 10 02:51:22 2004 +0000 +++ b/src/gtkblist.c Fri Sep 10 04:09:36 2004 +0000 @@ -3476,13 +3476,13 @@ /* XXX: why do we assume we have a buddy here? */ if (!gtknode) { #if 0 - gaim_debug(GAIM_DEBUG_ERROR, "gtkblist", "buddy %s has no ui_data\n", ((GaimBuddy *)node)->name); + gaim_debug_error("gtkblist", "buddy %s has no ui_data\n", ((GaimBuddy *)node)->name); #endif return FALSE; } if (!gtkblist) { - gaim_debug(GAIM_DEBUG_ERROR, "gtkblist", "get_iter_from_node was called, but we don't seem to have a blist\n"); + gaim_debug_error("gtkblist", "get_iter_from_node was called, but we don't seem to have a blist\n"); return FALSE; } @@ -3766,10 +3766,11 @@ contact = (GaimContact*)node; buddy = gaim_contact_get_priority_buddy(contact); - if(buddy && (buddy->present != GAIM_BUDDY_OFFLINE || - (gaim_account_is_connected(buddy->account) && - gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || - gaim_blist_node_get_bool(node, "show_offline"))) { + if (buddy && (gaim_presence_is_online(buddy->presence) || + (gaim_account_is_connected(buddy->account) && + gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || + gaim_blist_node_get_bool(node, "show_offline"))) + { GtkTreeIter iter; if(!insert_node(list, node, &iter)) @@ -3819,14 +3820,15 @@ /* First things first, update the contact */ gaim_gtk_blist_update_contact(list, node->parent); - if(gtkparentnode->contact_expanded && - (buddy->present != GAIM_BUDDY_OFFLINE || + if (gtkparentnode->contact_expanded && + (gaim_presence_is_online(buddy->presence) || (gaim_account_is_connected(buddy->account) && - gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || - gaim_blist_node_get_bool(node->parent, "show_offline"))) { + gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || + gaim_blist_node_get_bool(node->parent, "show_offline"))) + { GtkTreeIter iter; - if(!insert_node(list, node, &iter)) + if (!insert_node(list, node, &iter)) return; buddy_node(buddy, &iter, node); @@ -4556,7 +4558,7 @@ } else { /* we're logging in or something... do nothing */ /* or should I make the blist? */ - gaim_debug(GAIM_DEBUG_WARNING, "blist", + gaim_debug_warning("gtkblist", "docklet_toggle called with gaim_connections_get_all() " "but no blist!\n"); } @@ -4599,6 +4601,19 @@ } } +void gaim_gtk_blist_status_changed(GaimBuddy *buddy, GaimStatus *status) +{ + g_return_if_fail(buddy != NULL); + + /* + * What do we do with status here? + * g_return_if_fail(status != NULL); + */ + + gaim_debug_info("gtkblist", "Updating buddy list\n"); + gaim_gtk_blist_update(gaim_get_blist(), (GaimBlistNode*)buddy); +} + static GaimBlistUiOps blist_ui_ops = { gaim_gtk_blist_new_list, @@ -4610,7 +4625,8 @@ gaim_gtk_blist_set_visible, gaim_gtk_blist_request_add_buddy, gaim_gtk_blist_request_add_chat, - gaim_gtk_blist_request_add_group + gaim_gtk_blist_request_add_group, + gaim_gtk_blist_status_changed }; diff -r c892b6dbc341 -r 9baedaca25c7 src/prpl.c --- a/src/prpl.c Fri Sep 10 02:51:22 2004 +0000 +++ b/src/prpl.c Fri Sep 10 04:09:36 2004 +0000 @@ -256,12 +256,7 @@ presence = gaim_buddy_get_presence(buddy); - /* - * TODO: Set a presence's sign-on time. We don't support this yet. - */ - gaim_debug_warning("prpl", - "Attempting to set a user's sign-on time, but we " - "don't support this yet! FIX IT!\n"); + gaim_presence_set_login_time(presence, login_time); } void @@ -339,6 +334,36 @@ prpl_info->set_status(account, status); } +GList * +gaim_prpl_get_statuses(GaimAccount *account, GaimPresence *presence) +{ + GaimPlugin *prpl; + GaimPluginProtocolInfo *prpl_info; + GList *statuses = NULL; + GList *l; + GaimStatus *status; + + g_return_val_if_fail(account != NULL, NULL); + g_return_val_if_fail(presence != NULL, NULL); + + prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); + + if (prpl == NULL) + return NULL; + + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); + if (prpl_info == NULL || prpl_info->status_types == NULL) + return NULL; + + for (l = prpl_info->status_types(account); l != NULL; l = l->next) + { + status = gaim_status_new((GaimStatusType *)l->data, presence); + statuses = g_list_append(statuses, status); + } + + return statuses; +} + /************************************************************************** * Protocol Plugin Subsystem API diff -r c892b6dbc341 -r 9baedaca25c7 src/prpl.h --- a/src/prpl.h Fri Sep 10 02:51:22 2004 +0000 +++ b/src/prpl.h Fri Sep 10 04:09:36 2004 +0000 @@ -409,6 +409,16 @@ */ void gaim_prpl_set_account_status(GaimAccount *account, GaimStatus *status); +/** + * Retrieves the list of stock status types from a prpl. + * + * @param account The account the user is on. + * @param presence The presence for which we're going to get statuses + * + * @return List of statuses + */ +GList *gaim_prpl_get_statuses(GaimAccount *account, GaimPresence *presence); + /*@}*/ /**************************************************************************/ diff -r c892b6dbc341 -r 9baedaca25c7 src/status.c --- a/src/status.c Fri Sep 10 02:51:22 2004 +0000 +++ b/src/status.c Fri Sep 10 04:09:36 2004 +0000 @@ -67,6 +67,7 @@ gboolean idle; time_t idle_time; + time_t login_time; unsigned int warning_level; @@ -117,6 +118,7 @@ { GaimAccount *account; char *name; + guint id; } GaimStatusBuddyKey; @@ -216,6 +218,7 @@ g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); g_return_val_if_fail(id != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail(attr_id != NULL, NULL); g_return_val_if_fail(attr_name != NULL, NULL); g_return_val_if_fail(attr_value != NULL, NULL); @@ -567,6 +570,8 @@ { GaimPresenceContext context = gaim_presence_get_context(presence); + gaim_debug_info("notify_status_update", "Context is %d\n", context); + if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) { GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); @@ -613,11 +618,11 @@ status_type = gaim_status_get_type(status); - if (!active && gaim_status_type_is_independent(status_type)) + if (!active && !gaim_status_type_is_independent(status_type)) { gaim_debug(GAIM_DEBUG_ERROR, "status", - "Cannot deactivate an exclusive status (%s).\n", - gaim_status_type_get_id(status_type)); + "Cannot deactivate an exclusive status (%s).\n", + gaim_status_type_get_id(status_type)); return; } @@ -628,14 +633,12 @@ { const GList *l; - for (l = gaim_presence_get_statuses(presence); - l != NULL; - l = l->next) + for (l = gaim_presence_get_statuses(presence); l != NULL; l = l->next) { GaimStatus *temp_status = (GaimStatus *)l->data; GaimStatusType *temp_type; - if (temp_status == status) + if (!gaim_status_compare(temp_status, status)) continue; temp_type = gaim_status_get_type(temp_status); @@ -912,12 +915,11 @@ gaim_presence_new_for_account(GaimAccount *account) { GaimPresence *presence; - g_return_val_if_fail(account != NULL, NULL); presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); - presence->u.account = account; + presence->statuses = gaim_prpl_get_statuses(account, presence); return presence; } @@ -930,8 +932,8 @@ g_return_val_if_fail(conv != NULL, NULL); presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); - presence->u.chat.conv = conv; + /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ return presence; } @@ -941,19 +943,31 @@ { GaimPresence *presence; GaimStatusBuddyKey *key; + GaimAccount *account; + gchar *hash_seed; g_return_val_if_fail(buddy != NULL, NULL); + account = buddy->account; + hash_seed = g_strdup_printf("%s:%s:%s", buddy->name, account->username, + account->protocol_id); + key = g_new0(GaimStatusBuddyKey, 1); key->account = buddy->account; key->name = g_strdup(buddy->name); + key->id = g_str_hash(hash_seed); - if ((presence = g_hash_table_lookup(buddy_presences, key)) == NULL) + g_free(hash_seed); + hash_seed = NULL; + + presence = g_hash_table_lookup(buddy_presences, key); + if (presence == NULL) { presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); presence->u.buddy.name = g_strdup(buddy->name); presence->u.buddy.account = buddy->account; + presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); g_hash_table_insert(buddy_presences, key, presence); } @@ -997,6 +1011,9 @@ g_free(presence->u.chat.user); } + if (buddy_presences != NULL) + g_hash_table_destroy(buddy_presences); + if (presence->statuses != NULL) g_list_free(presence->statuses); @@ -1174,6 +1191,17 @@ } void +gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) +{ + g_return_if_fail(presence != NULL); + + if (presence->login_time == login_time) + return; + + presence->login_time = login_time; +} + +void gaim_presence_set_warning_level(GaimPresence *presence, unsigned int level) { g_return_if_fail(presence != NULL); @@ -1267,12 +1295,29 @@ gaim_presence_get_status(const GaimPresence *presence, const char *status_id) { GaimStatus *status; + const GList *l = NULL; g_return_val_if_fail(presence != NULL, NULL); g_return_val_if_fail(status_id != NULL, NULL); - status = (GaimStatus *)g_hash_table_lookup(presence->status_table, - status_id); + /* What's the purpose of this hash table? */ + status = (GaimStatus *)g_hash_table_lookup(presence->status_table, + status_id); + + if (status == NULL) { + for (l = gaim_presence_get_statuses(presence); + l != NULL && status == NULL; l = l->next) + { + GaimStatus *temp_status = l->data; + + if (!strcmp(status_id, gaim_status_get_id(temp_status))) + status = temp_status; + } + + if (status != NULL) + g_hash_table_insert(presence->status_table, + g_strdup(gaim_status_get_id(status)), status); + } return status; } @@ -1446,6 +1491,24 @@ primitive_scores[index] = GPOINTER_TO_INT(value); } +guint +gaim_buddy_presences_hash(gconstpointer key) +{ + return ((GaimStatusBuddyKey *)key)->id; +} + +gboolean +gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) +{ + GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; + GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; + + if (key_a->id == key_b->id) + return TRUE; + else + return FALSE; +} + void gaim_statuses_init(void) { @@ -1483,6 +1546,10 @@ gaim_prefs_connect_callback("/core/status/scores/idle", score_pref_changed_cb, GINT_TO_POINTER(SCORE_IDLE)); + + /* XXX - I don't think this is destroyed correctly. --Mark */ + buddy_presences = g_hash_table_new(gaim_buddy_presences_hash, + gaim_buddy_presences_equal); } void diff -r c892b6dbc341 -r 9baedaca25c7 src/status.h --- a/src/status.h Fri Sep 10 02:51:22 2004 +0000 +++ b/src/status.h Fri Sep 10 04:09:36 2004 +0000 @@ -654,6 +654,14 @@ time_t idle_time); /** + * Sets the login time on a presence. + * + * @param presence The presence. + * @param level The login time. + */ +void gaim_presence_set_login_time(GaimPresence *presence, time_t login_time); + +/** * Sets the warning level on a presence. * * @param presence The presence.