# HG changeset patch # User Mark Doliner # Date 1233138217 0 # Node ID 8c8948b9f6025e09839a38e4b48a120c7f479228 # Parent 9bff90dfb2e5ee76a4df1aa2531fd8d2f1188602# Parent 29f953732186db6b506b88315fa6a624e844c0b0 propagate from branch 'im.pidgin.pidgin' (head 8ae2fca06a3be4b99cc677c8f880d9521a35ec8b) to branch 'im.pidgin.pidgin.next.minor' (head 3725318168b46a11998066b36f9311e26d51885b) diff -r 29f953732186 -r 8c8948b9f602 .mtn-ignore --- a/.mtn-ignore Wed Jan 28 04:27:01 2009 +0000 +++ b/.mtn-ignore Wed Jan 28 10:23:37 2009 +0000 @@ -10,6 +10,7 @@ .*\.def$ .*\.dll$ .*\.exe$ +.*\.loT$ intltool-.* Doxyfile(\.mingw)?$ aclocal.m4 diff -r 29f953732186 -r 8c8948b9f602 .todo --- a/.todo Wed Jan 28 04:27:01 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ - - - Gaim TODO List - - - - diff -r 29f953732186 -r 8c8948b9f602 COPYRIGHT --- a/COPYRIGHT Wed Jan 28 04:27:01 2009 +0000 +++ b/COPYRIGHT Wed Jan 28 10:23:37 2009 +0000 @@ -85,6 +85,7 @@ Lorenzo Colitti Collabora Ltd. Jeff Connelly +Chris Connett Nathan Conrad Felipe Contreras Alex Converse diff -r 29f953732186 -r 8c8948b9f602 ChangeLog --- a/ChangeLog Wed Jan 28 04:27:01 2009 +0000 +++ b/ChangeLog Wed Jan 28 10:23:37 2009 +0000 @@ -1,5 +1,20 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.6.0 (??/??/????): + General: + * Theme support in libpurple thanks to Justin Rodriguez's summer of code + project. With some minor additions and clean ups from Paul Aurich. + + Pidgin: + * Added -f command line option to tell Pidgin to ignore NetworkManager + and assume it has a valid network connection. + * Allow plugins to specify custom link types to the GtkIMHtml widget. + * The status message input box at the bottom of the buddy list expands + correctly when starting a new line of text. + * Pressing the Enter key in the message entry box of the New Status + dialog and various other dialogs now causes the cursor to move to + the next line. + version 2.5.5 (??/??/????): libpurple: * Fix transfer of buddy icons, custom smileys and files from the @@ -609,13 +624,13 @@ version 2.2.0 (09/13/2007): http://developer.pidgin.im/query?status=closed&milestone=2.2.0 - Libpurple: + libpurple: * New protocol plugin: MySpaceIM (Jeff Connelly, Google Summer of Code) * XMPP enhancements. See - http://www.adiumx.com/blog/2007/07/soc-xmpp-update.php (Andreas + http://www.adiumx.com/blog/2007/07/soc-xmpp-update.php (Andreas Monitzer, Google Summer of Code for Adium) - * Certificate management. Libpurple will validate certificates on + * Certificate management. libpurple will validate certificates on SSL-encrypted protocols (William Ehlhardt, Google Summer of Code) * Some adjustments were made to fix sending messages when using the MSN HTTP method. (Laszlo Pandy) diff -r 29f953732186 -r 8c8948b9f602 ChangeLog.API --- a/ChangeLog.API Wed Jan 28 04:27:01 2009 +0000 +++ b/ChangeLog.API Wed Jan 28 10:23:37 2009 +0000 @@ -1,5 +1,73 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.6.0 (??/??/????): + libpurple: + Added: + * PURPLE_BLIST_NODE + * PURPLE_GROUP + * PURPLE_CONTACT + * PURPLE_BUDDY + * PURPLE_CHAT + * purple_buddy_get_protocol_data + * purple_buddy_set_protocol_data + * purple_buddy_get_local_buddy_alias + * purple_blist_get_buddies + * purple_blist_get_ui_data + * purple_blist_set_ui_data + * purple_blist_node_get_ui_data + * purple_blist_node_set_ui_data + * purple_connection_get_protocol_data + * purple_connection_set_protocol_data + * purple_global_proxy_set_info + * purple_log_get_activity_score + * purple_network_force_online + * purple_request_field_get_group + * purple_request_field_get_ui_data + * purple_request_field_set_ui_data + * purple_strequal + * xmlnode_from_file + + Deprecated: + * purple_buddy_get_local_alias + * purple_notify_user_info_remove_entry + * purple_status_type_set_primary_attr + * purple_status_type_add_attr + * purple_status_type_add_attrs + * purple_status_type_add_attrs_vargs + * purple_status_type_get_primary_attr + * purple_status_set_attr_boolean + * purple_status_set_attr_int + * purple_status_set_attr_string + * purple_presence_add_status + * purple_presence_add_list + + pidgin: + Added: + * gtk_imhtml_class_register_protocol + * gtk_imhtml_link_get_url, gtk_imhtml_link_get_text_tag, + gtk_imhtml_link_activate functions to process GtkIMHtmlLink + objects from GtkIMHtml protocol callbacks. + * gtk_imhtml_set_return_inserts_newline + * pidgin_blist_set_theme + * pidgin_blist_get_theme + * pidgin_sound_is_customized + * pidgin_utils_init, pidgin_utils_uninit + + perl: + Changed: + * Made a bunch of functions act more perl-like. Call the new() + functions as Class->new(...) instead of Class::new(...): + * Purple::Request::Fields::new + * Purple::Request::Field::new + * Purple::Request::Field::account_new + * Purple::Request::Field::bool_new + * Purple::Request::Field::choice_new + * Purple::Request::Field::int_new + * Purple::Request::Field::label_new + * Purple::Request::Field::list_new + * Purple::Request::Field::string_new + * Purple::Request::Field::group_new + version 2.5.5 (??/??/2009): libpurple: Changed: diff -r 29f953732186 -r 8c8948b9f602 Makefile.am --- a/Makefile.am Wed Jan 28 04:27:01 2009 +0000 +++ b/Makefile.am Wed Jan 28 10:23:37 2009 +0000 @@ -10,6 +10,7 @@ README.mingw \ config.h.mingw \ doxy2devhelp.xsl \ + fix-casts.sh \ gaim.pc.in \ gaim-uninstalled.pc.in \ intltool-extract.in \ diff -r 29f953732186 -r 8c8948b9f602 Makefile.mingw --- a/Makefile.mingw Wed Jan 28 04:27:01 2009 +0000 +++ b/Makefile.mingw Wed Jan 28 10:23:37 2009 +0000 @@ -2,7 +2,7 @@ # # Author: hermanator12002@yahoo.com # Date 9/11/02 -# Description: Top Makefile for win32 (mingw) port of Pidgin and LibPurple +# Description: Top Makefile for win32 (mingw) port of Pidgin and libpurple # PIDGIN_TREE_TOP := . diff -r 29f953732186 -r 8c8948b9f602 configure.ac --- a/configure.ac Wed Jan 28 04:27:01 2009 +0000 +++ b/configure.ac Wed Jan 28 10:23:37 2009 +0000 @@ -1103,6 +1103,7 @@ msnp9) dynamic_msn=yes ;; myspace) dynamic_myspace=yes ;; novell) dynamic_novell=yes ;; + null) dynamic_null=yes ;; oscar) dynamic_oscar=yes ;; aim) dynamic_oscar=yes ;; icq) dynamic_oscar=yes ;; @@ -1117,21 +1118,6 @@ *) echo "Invalid dynamic protocol $i!!" ; exit ;; esac done -AM_CONDITIONAL(DYNAMIC_BONJOUR, test "x$dynamic_bonjour" = "xyes" -a [ "x$avahiincludes" = "xyes" -a "x$avahilibs " = "xyes" ] ) -AM_CONDITIONAL(DYNAMIC_GG, test "x$dynamic_gg" = "xyes") -AM_CONDITIONAL(DYNAMIC_IRC, test "x$dynamic_irc" = "xyes") -AM_CONDITIONAL(DYNAMIC_JABBER, test "x$dynamic_jabber" = "xyes") -AM_CONDITIONAL(DYNAMIC_MSN, test "x$dynamic_msn" = "xyes") -AM_CONDITIONAL(DYNAMIC_MYSPACE, test "x$dynamic_myspace" = "xyes") -AM_CONDITIONAL(DYNAMIC_NOVELL, test "x$dynamic_novell" = "xyes") -AM_CONDITIONAL(DYNAMIC_OSCAR, test "x$dynamic_oscar" = "xyes") -AM_CONDITIONAL(DYNAMIC_QQ, test "x$dynamic_qq" = "xyes") -AM_CONDITIONAL(DYNAMIC_SAMETIME, test "x$dynamic_sametime" = "xyes" -a "x$have_meanwhile" = "xyes") -AM_CONDITIONAL(DYNAMIC_SILC, test "x$dynamic_silc" = "xyes" -a "x$have_silc" = "xyes") -AM_CONDITIONAL(DYNAMIC_SIMPLE, test "x$dynamic_simple" = "xyes") -AM_CONDITIONAL(DYNAMIC_TOC, test "x$dynamic_toc" = "xyes") -AM_CONDITIONAL(DYNAMIC_YAHOO, test "x$dynamic_yahoo" = "xyes") -AM_CONDITIONAL(DYNAMIC_ZEPHYR, test "x$dynamic_zephyr" = "xyes") AC_ARG_ENABLE(plugins, [AC_HELP_STRING([--disable-plugins], [compile without plugin support])], , enable_plugins=yes) AC_ARG_WITH(krb4, [AC_HELP_STRING([--with-krb4=PREFIX], [compile Zephyr plugin with Kerberos 4 support])], kerberos="$withval", kerberos="no") diff -r 29f953732186 -r 8c8948b9f602 doc/TCL-HOWTO.dox --- a/doc/TCL-HOWTO.dox Wed Jan 28 04:27:01 2009 +0000 +++ b/doc/TCL-HOWTO.dox Wed Jan 28 10:23:37 2009 +0000 @@ -332,7 +332,7 @@ callbacks will live in the namespace @c event underneath that namespace. To briefly illustrate, the signal @c receiving-im-msg is provided with three arguments; the account on which the IM was -received, the screen name of the user sending the IM, and the text of +received, the name of the buddy sending the IM, and the text of the IM. These arguments live in the variables @c event::account, @c event::sender, and @c event::buffer, respectively. Therefore a callback which notifies the user of an incoming IM containing the word 'shizzle' diff -r 29f953732186 -r 8c8948b9f602 doc/notify-signals.dox --- a/doc/notify-signals.dox Wed Jan 28 04:27:01 2009 +0000 +++ b/doc/notify-signals.dox Wed Jan 28 10:23:37 2009 +0000 @@ -18,7 +18,7 @@ @note If adding a PurpleNotifyUserInfoEntry, be sure not to free it -- PurpleNotifyUserInfo assumes responsibility for its objects. @param account The account on which the info was obtained. - @param who The screen name of the user whose info is to be displayed. + @param who The name of the buddy whose info is to be displayed. @param user_info The information to be displayed, as PurpleNotifyUserInfoEntry objects @endsignaldef diff -r 29f953732186 -r 8c8948b9f602 doc/pidgin.1.in --- a/doc/pidgin.1.in Wed Jan 28 04:27:01 2009 +0000 +++ b/doc/pidgin.1.in Wed Jan 28 10:23:37 2009 +0000 @@ -128,11 +128,11 @@ .TP .B Alias Create an alias for this buddy. This will show an editable text field where -the buddy's screen name was displayed. In this field one can give this +the buddy's name was displayed. In this field one can give this buddy an alternate, more friendly name to appear on the buddy list and in conversations. -For example, if a buddy's name screen name was jsmith1281xx and his real +For example, if a buddy's name was jsmith1281xx and his real name was 'John Q. Smith,' one could create an alias as to identify the buddy by his common name. .LP @@ -150,7 +150,7 @@ Clicking \fIDelete\fR will delete the currently selected account. Clicking \fIAdd\fR or \fIModify\fR will invoke a \fBModify Account\fR window. Here, the user can add or alter account information. When creating -a new account, the user will submit a screen name and password. The user will +a new account, the user will submit a username and password. The user will also choose the protocol for the account. If \fIRemember Password\fR is chosen, the password will be saved in @@ -545,7 +545,7 @@ .br \fI~/.purple/status.xml\fR: stores the user's away messages. .br - \fI~/.purple/logs/PROTOCOL/ACCOUNT/SCREENNAME/DATE.{html,txt}\fR: conversation logs. + \fI~/.purple/logs/PROTOCOL/ACCOUNT/BUDDYNAME/DATE.{html,txt}\fR: conversation logs. .SH DIRECTORIES \fI@prefix@/lib/pidgin/\fR: Pidgin's plugins directory. diff -r 29f953732186 -r 8c8948b9f602 finch/gntaccount.c --- a/finch/gntaccount.c Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/gntaccount.c Wed Jan 28 10:23:37 2009 +0000 @@ -65,7 +65,7 @@ GntWidget *window; GntWidget *protocol; - GntWidget *screenname; + GntWidget *username; GntWidget *password; GntWidget *alias; @@ -118,8 +118,8 @@ plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); prplinfo = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); - /* Screenname && user-splits */ - value = gnt_entry_get_text(GNT_ENTRY(dialog->screenname)); + /* Username && user-splits */ + value = gnt_entry_get_text(GNT_ENTRY(dialog->username)); if (value == NULL || *value == '\0') { @@ -326,7 +326,7 @@ } if (username != NULL) - gnt_entry_set_text(GNT_ENTRY(dialog->screenname), username); + gnt_entry_set_text(GNT_ENTRY(dialog->username), username); g_free(username); } @@ -546,7 +546,7 @@ gnt_box_set_pad(GNT_BOX(hbox), 0); gnt_box_add_widget(GNT_BOX(window), hbox); - dialog->screenname = entry = gnt_entry_new(NULL); + dialog->username = entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Username:"))); gnt_box_add_widget(GNT_BOX(hbox), entry); diff -r 29f953732186 -r 8c8948b9f602 finch/gntblist.c --- a/finch/gntblist.c Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/gntblist.c Wed Jan 28 10:23:37 2009 +0000 @@ -357,7 +357,7 @@ int color = 0; if (PURPLE_BLIST_NODE_IS_CONTACT(node)) - node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); + node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) return 0; @@ -388,7 +388,7 @@ if (fnode && fnode->signed_timer) flag |= GNT_TEXT_FLAG_BLINK; else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { - node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact *)node); + node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); fnode = FINCH_GET_DATA(node); if (fnode && fnode->signed_timer) flag |= GNT_TEXT_FLAG_BLINK; @@ -886,7 +886,7 @@ const char *name = NULL; if (PURPLE_BLIST_NODE_IS_CONTACT(node)) - node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); /* XXX: this can return NULL?! */ + node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); /* XXX: this can return NULL?! */ if (node == NULL) return NULL; @@ -1027,7 +1027,7 @@ return; if (PURPLE_BLIST_NODE_IS_CONTACT(node)) - node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); + node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { @@ -1438,16 +1438,16 @@ if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { PurpleBuddy *b = (PurpleBuddy*) node; type = PURPLE_LOG_IM; - name = g_strdup(b->name); - account = b->account; + name = g_strdup(purple_buddy_get_name(b)); + account = purple_buddy_get_account(b); } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat *c = (PurpleChat*) node; PurplePluginProtocolInfo *prpl_info = NULL; type = PURPLE_LOG_CHAT; - account = c->account; + account = purple_chat_get_account(c); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); if (prpl_info && prpl_info->get_chat_name) { - name = prpl_info->get_chat_name(c->components); + name = prpl_info->get_chat_name(purple_chat_get_components(c)); } } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { finch_log_show_contact((PurpleContact *)node); @@ -1571,8 +1571,8 @@ ggblist->tagged = g_list_prepend(ggblist->tagged, node); } if (PURPLE_BLIST_NODE_IS_CONTACT(node)) - node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); - if (PURPLE_BLIST_NODE_IS_BUDDY(node)) + update_buddy_display(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)), ggblist); + else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) update_buddy_display((PurpleBuddy*)node, ggblist); else update_node_display(node, ggblist); @@ -1612,7 +1612,7 @@ purple_blist_add_group((PurpleGroup*)node, (PurpleBlistNode*)tg); } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { update_buddy_display(purple_contact_get_priority_buddy((PurpleContact*)node), ggblist); - if ((PurpleBlistNode*)tg == target) { + if (PURPLE_BLIST_NODE(tg) == target) { /* The target is a group, just add the contact to the group. */ purple_blist_add_contact((PurpleContact*)node, tg, NULL); } else if (tc) { @@ -1624,7 +1624,7 @@ } } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { update_buddy_display((PurpleBuddy*)node, ggblist); - if ((PurpleBlistNode*)tg == target) { + if (PURPLE_BLIST_NODE(tg) == target) { /* The target is a group. Add this buddy in a new contact under this group. */ purple_blist_add_buddy((PurpleBuddy*)node, NULL, tg, NULL); } else if (PURPLE_BLIST_NODE_IS_CONTACT(target)) { @@ -1639,7 +1639,7 @@ } } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { update_node_display(node, ggblist); - if ((PurpleBlistNode*)tg == target) + if (PURPLE_BLIST_NODE(tg) == target) purple_blist_add_chat((PurpleChat*)node, tg, NULL); else purple_blist_add_chat((PurpleChat*)node, NULL, target); @@ -1685,7 +1685,7 @@ create_group_menu(GNT_MENU(context), NULL); title = g_strdup(_("Buddy List")); } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { - ggblist->cnode = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); + ggblist->cnode = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); create_buddy_menu(GNT_MENU(context), (PurpleBuddy*)ggblist->cnode); title = g_strdup(purple_contact_get_alias((PurpleContact*)node)); } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { @@ -2415,8 +2415,8 @@ switch (purple_blist_node_get_type(n1)) { case PURPLE_BLIST_CONTACT_NODE: - n1 = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)n1); - n2 = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)n2); + n1 = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(n1))); + n2 = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(n2))); /* now compare the presence of the priority buddies */ case PURPLE_BLIST_BUDDY_NODE: ret = purple_presence_compare(purple_buddy_get_presence((PurpleBuddy*)n1), diff -r 29f953732186 -r 8c8948b9f602 finch/gntconv.c --- a/finch/gntconv.c Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/gntconv.c Wed Jan 28 10:23:37 2009 +0000 @@ -496,8 +496,9 @@ buddies = purple_find_buddies(account, name); for (cur = buddies; cur != NULL; cur = cur->next) { PurpleBlistNode *node = cur->data; - if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) { - finch_log_show_contact((PurpleContact *)node->parent); + if ((node != NULL) && + (purple_blist_node_get_sibling_prev(node) || purple_blist_node_get_sibling_next(node))) { + finch_log_show_contact((PurpleContact *)purple_blist_node_get_parent(node)); g_slist_free(buddies); return; } @@ -529,7 +530,7 @@ gnt_menuitem_set_submenu(item, GNT_MENU(sub)); for (; buds; buds = g_slist_delete_link(buds, buds)) { - PurpleBlistNode *node = (PurpleBlistNode *)purple_buddy_get_contact((PurpleBuddy *)buds->data); + PurpleBlistNode *node = PURPLE_BLIST_NODE(purple_buddy_get_contact(PURPLE_BUDDY(buds->data))); for (node = purple_blist_node_get_first_child(node); node != NULL; node = purple_blist_node_get_sibling_next(node)) { PurpleBuddy *buddy = (PurpleBuddy *)node; diff -r 29f953732186 -r 8c8948b9f602 finch/gntlog.c --- a/finch/gntlog.c Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/gntlog.c Wed Jan 28 10:23:37 2009 +0000 @@ -49,7 +49,7 @@ struct log_viewer_hash_t { PurpleLogType type; - char *screenname; + char *username; PurpleAccount *account; PurpleContact *contact; }; @@ -62,7 +62,7 @@ return g_direct_hash(viewer->contact); if (viewer->account) { - return g_str_hash(viewer->screenname) + + return g_str_hash(viewer->username) + g_str_hash(purple_account_get_username(viewer->account)); } @@ -88,10 +88,10 @@ return FALSE; } - if (a->screenname && b->screenname) { - normal = g_strdup(purple_normalize(a->account, a->screenname)); + if (a->username && b->username) { + normal = g_strdup(purple_normalize(a->account, a->username)); ret = (a->account == b->account) && - !strcmp(normal, purple_normalize(b->account, b->screenname)); + !strcmp(normal, purple_normalize(b->account, b->username)); g_free(normal); } else { ret = (a == b); @@ -155,7 +155,7 @@ lv = g_hash_table_lookup(log_viewers, ht); g_hash_table_remove(log_viewers, ht); - g_free(ht->screenname); + g_free(ht->username); g_free(ht); } else syslog_viewer = NULL; @@ -284,7 +284,7 @@ if (!purple_prefs_get_bool("/purple/logging/log_chats")) log_preferences = _("Chats will only be logged if the \"Log all chats\" preference is enabled."); } - g_free(ht->screenname); + g_free(ht->username); g_free(ht); } @@ -365,31 +365,31 @@ *list = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, set->name, set->account), *list); } -void finch_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account) +void finch_log_show(PurpleLogType type, const char *username, PurpleAccount *account) { struct log_viewer_hash_t *ht; FinchLogViewer *lv = NULL; - const char *name = screenname; + const char *name = username; char *title; GList *logs = NULL; int size = 0; if (type != PURPLE_LOG_IM) { g_return_if_fail(account != NULL); - g_return_if_fail(screenname != NULL); + g_return_if_fail(username != NULL); } ht = g_new0(struct log_viewer_hash_t, 1); ht->type = type; - ht->screenname = g_strdup(screenname); + ht->username = g_strdup(username); ht->account = account; if (log_viewers == NULL) { log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal); } else if ((lv = g_hash_table_lookup(log_viewers, ht))) { gnt_window_present(lv->window); - g_free(ht->screenname); + g_free(ht->username); g_free(ht); return; } @@ -397,7 +397,7 @@ if (type == PURPLE_LOG_CHAT) { PurpleChat *chat; - chat = purple_blist_find_chat(account, screenname); + chat = purple_blist_find_chat(account, username); if (chat != NULL) name = purple_chat_get_name(chat); @@ -405,8 +405,8 @@ } else { PurpleBuddy *buddy; - if (screenname) { - buddy = purple_find_buddy(account, screenname); + if (username) { + buddy = purple_find_buddy(account, username); if (buddy != NULL) name = purple_buddy_get_contact_alias(buddy); title = g_strdup_printf(_("Conversations with %s"), name); @@ -415,9 +415,9 @@ } } - if (screenname) { - logs = purple_log_get_logs(type, screenname, account); - size = purple_log_get_total_size(type, screenname, account); + if (username) { + logs = purple_log_get_logs(type, username, account); + size = purple_log_get_total_size(type, username, account); } else { /* This will happen only for IMs */ GHashTable *table = purple_log_get_log_sets(); @@ -458,12 +458,16 @@ for (child = purple_blist_node_get_first_child((PurpleBlistNode*)contact); child; child = purple_blist_node_get_sibling_next(child)) { + const char *name; + PurpleAccount *account; if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) continue; - logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, ((PurpleBuddy *)child)->name, - ((PurpleBuddy *)child)->account), logs); - total_log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy *)child)->name, ((PurpleBuddy *)child)->account); + name = purple_buddy_get_name((PurpleBuddy *)child); + account = purple_buddy_get_account((PurpleBuddy *)child); + logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, name, + account), logs); + total_log_size += purple_log_get_total_size(PURPLE_LOG_IM, name, account); } logs = g_list_sort(logs, purple_log_compare); diff -r 29f953732186 -r 8c8948b9f602 finch/gntlog.h --- a/finch/gntlog.h Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/gntlog.h Wed Jan 28 10:23:37 2009 +0000 @@ -50,7 +50,7 @@ -void finch_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account); +void finch_log_show(PurpleLogType type, const char *username, PurpleAccount *account); void finch_log_show_contact(PurpleContact *contact); void finch_syslog_show(void); diff -r 29f953732186 -r 8c8948b9f602 finch/gntrequest.c --- a/finch/gntrequest.c Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/gntrequest.c Wed Jan 28 10:23:37 2009 +0000 @@ -39,6 +39,12 @@ #include "debug.h" #include "util.h" +/* XXX: Until gobjectification ... */ +#undef FINCH_GET_DATA +#undef FINCH_SET_DATA +#define FINCH_GET_DATA(obj) purple_request_field_get_ui_data(obj) +#define FINCH_SET_DATA(obj, data) purple_request_field_set_ui_data(obj, data) + typedef struct { void *user_data; @@ -393,11 +399,11 @@ } static void -update_selected_account(GntEntry *screenname, const char *start, const char *end, +update_selected_account(GntEntry *username, const char *start, const char *end, GntComboBox *accountlist) { GList *accounts = gnt_tree_get_rows(GNT_TREE(accountlist->dropdown)); - const char *name = gnt_entry_get_text(screenname); + const char *name = gnt_entry_get_text(username); while (accounts) { if (purple_find_buddy(accounts->data, name)) { gnt_combo_box_set_selected(accountlist, accounts->data); @@ -419,7 +425,7 @@ } static GntWidget* -create_string_field(PurpleRequestField *field, GntWidget **screenname) +create_string_field(PurpleRequestField *field, GntWidget **username) { const char *hint = purple_request_field_get_type_hint(field); GntWidget *entry = gnt_entry_new( @@ -435,8 +441,8 @@ gnt_entry_add_suggest(GNT_ENTRY(entry), purple_buddy_get_name((PurpleBuddy*)node)); } gnt_entry_set_always_suggest(GNT_ENTRY(entry), TRUE); - if (screenname) - *screenname = entry; + if (username) + *username = entry; } else if (hint && !strcmp(hint, "group")) { PurpleBlistNode *node; for (node = purple_blist_get_root(); node; @@ -569,7 +575,7 @@ { GntWidget *window, *box; GList *grlist; - GntWidget *screenname = NULL, *accountlist = NULL; + GntWidget *username = NULL, *accountlist = NULL; window = setup_request_window(title, primary, secondary, PURPLE_REQUEST_FIELDS); @@ -617,7 +623,7 @@ } else if (type == PURPLE_REQUEST_FIELD_STRING) { - FINCH_SET_DATA(field, create_string_field(field, &screenname)); + FINCH_SET_DATA(field, create_string_field(field, &username)); } else if (type == PURPLE_REQUEST_FIELD_INTEGER) { @@ -633,7 +639,8 @@ } else if (type == PURPLE_REQUEST_FIELD_ACCOUNT) { - accountlist = FINCH_SET_DATA(field, create_account_field(field)); + accountlist = create_account_field(field); + FINCH_SET_DATA(field, accountlist); } else { @@ -655,8 +662,8 @@ setup_default_callback(window, cancel_cb, userdata); gnt_widget_show(window); - if (screenname && accountlist) { - g_signal_connect(screenname, "completion", G_CALLBACK(update_selected_account), accountlist); + if (username && accountlist) { + g_signal_connect(username, "completion", G_CALLBACK(update_selected_account), accountlist); } g_object_set_data(G_OBJECT(window), "fields", allfields); diff -r 29f953732186 -r 8c8948b9f602 finch/plugins/grouping.c --- a/finch/plugins/grouping.c Wed Jan 28 04:27:01 2009 +0000 +++ b/finch/plugins/grouping.c Wed Jan 28 10:23:37 2009 +0000 @@ -87,7 +87,7 @@ switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_CONTACT_NODE: - node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); + node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); ret = PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node) ? &online : &offline; break; case PURPLE_BLIST_BUDDY_NODE: diff -r 29f953732186 -r 8c8948b9f602 fix-casts.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fix-casts.sh Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,18 @@ +#!/bin/sh + +if [ $# -eq 0 ]; then + echo "Usage: `basename "$0"` PurpleFoo..." + echo + echo "This script searches the *current working directory* and replaces casts" + echo "with GObject-style type checking and casting macros." + echo 'For example, "(PurpleBuddy *)b" becomes "PURPLE_BUDDY(b)".' + exit 0 +fi + +for struct in $* ; do + cast=`echo $struct | sed "s|[A-Z]|_\0|g" | tr "a-z" "A-Z" | sed "s|^_||"` + for file in `grep -rl "([[:space:]]*$struct[[:space:]]*\*[[:space:]]*)" . --include=*.c --exclude=purple-client-bindings.c` ; do + sed -i "s|([[:space:]]*$struct[[:space:]]*\*[[:space:]]*)[[:space:]]*(|$cast(|g" $file + sed -i "s|([[:space:]]*$struct[[:space:]]*\*[[:space:]]*)[[:space:]]*\([^(][^,);]*\)|$cast(\1)|g" $file + done +done diff -r 29f953732186 -r 8c8948b9f602 libpurple/Makefile.am --- a/libpurple/Makefile.am Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/Makefile.am Wed Jan 28 10:23:37 2009 +0000 @@ -75,7 +75,12 @@ stringref.c \ stun.c \ sound.c \ + sound-theme.c \ + sound-theme-loader.c \ sslconn.c \ + theme.c \ + theme-loader.c \ + theme-manager.c \ upnp.c \ util.c \ value.c \ @@ -128,7 +133,12 @@ stringref.h \ stun.h \ sound.h \ + sound-theme.h \ + sound-theme-loader.h \ sslconn.h \ + theme.h \ + theme-loader.h \ + theme-manager.h \ upnp.h \ util.h \ value.h \ diff -r 29f953732186 -r 8c8948b9f602 libpurple/Makefile.mingw --- a/libpurple/Makefile.mingw Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/Makefile.mingw Wed Jan 28 10:23:37 2009 +0000 @@ -1,7 +1,7 @@ # # Makefile.mingw # -# Description: Makefile for win32 (mingw) version of LibPurple +# Description: Makefile for win32 (mingw) version of libpurple # PIDGIN_TREE_TOP := .. @@ -67,10 +67,15 @@ signals.c \ smiley.c \ sound.c \ + sound-theme.c \ + sound-theme-loader.c \ sslconn.c \ status.c \ stringref.c \ stun.c \ + theme.c \ + theme-loader.c \ + theme-manager.c \ upnp.c \ util.c \ value.c \ diff -r 29f953732186 -r 8c8948b9f602 libpurple/account.c --- a/libpurple/account.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/account.c Wed Jan 28 10:23:37 2009 +0000 @@ -178,9 +178,7 @@ { const char *string_value = purple_value_get_string(attr_value); const char *default_string_value = purple_value_get_string(default_value); - if (((string_value == NULL) && (default_string_value == NULL)) || - ((string_value != NULL) && (default_string_value != NULL) && - !strcmp(string_value, default_string_value))) + if (purple_strequal(string_value, default_string_value)) return NULL; value = g_strdup(purple_value_get_string(attr_value)); } @@ -511,11 +509,11 @@ /* Ignore this setting */ continue; - if (!strcmp(str_type, "string")) + if (purple_strequal(str_type, "string")) type = PURPLE_PREF_STRING; - else if (!strcmp(str_type, "int")) + else if (purple_strequal(str_type, "int")) type = PURPLE_PREF_INT; - else if (!strcmp(str_type, "bool")) + else if (purple_strequal(str_type, "bool")) type = PURPLE_PREF_BOOLEAN; else /* Ignore this setting */ @@ -660,17 +658,17 @@ child = xmlnode_get_child(node, "type"); if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL)) { - if (!strcmp(data, "global")) + if (purple_strequal(data, "global")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_GLOBAL); - else if (!strcmp(data, "none")) + else if (purple_strequal(data, "none")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE); - else if (!strcmp(data, "http")) + else if (purple_strequal(data, "http")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_HTTP); - else if (!strcmp(data, "socks4")) + else if (purple_strequal(data, "socks4")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4); - else if (!strcmp(data, "socks5")) + else if (purple_strequal(data, "socks5")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5); - else if (!strcmp(data, "envvar")) + else if (purple_strequal(data, "envvar")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR); else { @@ -2027,7 +2025,7 @@ { PurpleStatusType *status_type = (PurpleStatusType *)l->data; - if (!strcmp(purple_status_type_get_id(status_type), id)) + if (purple_strequal(purple_status_type_get_id(status_type), id)) return status_type; } @@ -2238,9 +2236,9 @@ PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; - + if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2255,20 +2253,20 @@ PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; - + if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - + if (prpl_info) { GList *cur, *groups = NULL; /* Make a list of what group each buddy is in */ for (cur = buddies; cur != NULL; cur = cur->next) { - PurpleBlistNode *node = cur->data; - groups = g_list_append(groups, node->parent->parent); + PurpleBuddy *buddy = cur->data; + groups = g_list_append(groups, purple_buddy_get_group(buddy)); } if (prpl_info->add_buddies != NULL) @@ -2294,13 +2292,13 @@ PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; - + if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - + if (prpl_info && prpl_info->remove_buddy) prpl_info->remove_buddy(gc, buddy, group); } @@ -2311,13 +2309,13 @@ PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; - + if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - + if (prpl_info) { if (prpl_info->remove_buddies) prpl_info->remove_buddies(gc, buddies, groups); @@ -2339,9 +2337,9 @@ PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; - + if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2357,11 +2355,11 @@ PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; - + purple_account_set_password(account, new_pw); - + if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2375,15 +2373,15 @@ PurpleConnection *gc; PurplePluginProtocolInfo *prpl_info = NULL; PurplePlugin *prpl = NULL; - + g_return_val_if_fail(account, FALSE); g_return_val_if_fail(buddy, FALSE); gc = purple_account_get_connection(account); if (gc == NULL) return FALSE; - - prpl = purple_connection_get_prpl(gc); + + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2518,23 +2516,26 @@ purple_accounts_remove(account); /* Remove this account's buddies */ - for (gnode = purple_blist_get_root(); gnode != NULL; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); + gnode != NULL; + gnode = purple_blist_node_get_sibling_next(gnode)) + { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - cnode = gnode->child; + cnode = purple_blist_node_get_first_child(gnode); while (cnode) { - PurpleBlistNode *cnode_next = cnode->next; + PurpleBlistNode *cnode_next = purple_blist_node_get_sibling_next(cnode); if(PURPLE_BLIST_NODE_IS_CONTACT(cnode)) { - bnode = cnode->child; + bnode = purple_blist_node_get_first_child(cnode); while (bnode) { - PurpleBlistNode *bnode_next = bnode->next; + PurpleBlistNode *bnode_next = purple_blist_node_get_sibling_next(bnode); if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) { PurpleBuddy *b = (PurpleBuddy *)bnode; - if (b->account == account) + if (purple_buddy_get_account(b) == account) purple_blist_remove_buddy(b); } bnode = bnode_next; @@ -2542,7 +2543,7 @@ } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) { PurpleChat *c = (PurpleChat *)cnode; - if (c->account == account) + if (purple_chat_get_account(c) == account) purple_blist_remove_chat(c); } cnode = cnode_next; @@ -2633,11 +2634,11 @@ for (l = purple_accounts_get_all(); l != NULL; l = l->next) { account = (PurpleAccount *)l->data; - if (protocol_id && strcmp(account->protocol_id, protocol_id)) + if (protocol_id && !purple_strequal(account->protocol_id, protocol_id)) continue; who = g_strdup(purple_normalize(account, name)); - if (!strcmp(purple_normalize(account, purple_account_get_username(account)), who)) { + if (purple_strequal(purple_normalize(account, purple_account_get_username(account)), who)) { g_free(who); return account; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/account.h --- a/libpurple/account.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/account.h Wed Jan 28 10:23:37 2009 +0000 @@ -253,7 +253,7 @@ * Notifies the user that a remote user has wants to add the local user * to his or her buddy list and requires authorization to do so. * - * This will present a dialog informing the user of this and ask if the + * This will present a dialog informing the user of this and ask if the * user authorizes or denies the remote user from adding him. * * @param account The account that was added diff -r 29f953732186 -r 8c8948b9f602 libpurple/blist.c --- a/libpurple/blist.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/blist.c Wed Jan 28 10:23:37 2009 +0000 @@ -82,7 +82,7 @@ static guint _purple_blist_hbuddy_equal(struct _purple_hbuddy *hb1, struct _purple_hbuddy *hb2) { - return ((!strcmp(hb1->name, hb2->name)) && hb1->account == hb2->account && hb1->group == hb2->group); + return (purple_strequal(hb1->name, hb2->name) && hb1->account == hb2->account && hb1->group == hb2->group); } static void _purple_blist_hbuddy_free_key(struct _purple_hbuddy *hb) @@ -382,11 +382,11 @@ if (!value) return; - if (!type || !strcmp(type, "string")) + if (!type || purple_strequal(type, "string")) purple_blist_node_set_string(node, name, value); - else if (!strcmp(type, "bool")) + else if (purple_strequal(type, "bool")) purple_blist_node_set_bool(node, name, atoi(value)); - else if (!strcmp(type, "int")) + else if (purple_strequal(type, "int")) purple_blist_node_set_int(node, name, atoi(value)); g_free(value); @@ -453,9 +453,9 @@ for (x = cnode->child; x; x = x->next) { if (x->type != XMLNODE_TYPE_TAG) continue; - if (!strcmp(x->name, "buddy")) + if (purple_strequal(x->name, "buddy")) parse_buddy(group, contact, x); - else if (!strcmp(x->name, "setting")) + else if (purple_strequal(x->name, "setting")) parse_setting((PurpleBlistNode*)contact, x); } @@ -528,12 +528,12 @@ for (cnode = groupnode->child; cnode; cnode = cnode->next) { if (cnode->type != XMLNODE_TYPE_TAG) continue; - if (!strcmp(cnode->name, "setting")) + if (purple_strequal(cnode->name, "setting")) parse_setting((PurpleBlistNode*)group, cnode); - else if (!strcmp(cnode->name, "contact") || - !strcmp(cnode->name, "person")) + else if (purple_strequal(cnode->name, "contact") || + purple_strequal(cnode->name, "person")) parse_contact(group, cnode); - else if (!strcmp(cnode->name, "chat")) + else if (purple_strequal(cnode->name, "chat")) parse_chat(group, cnode); } } @@ -590,11 +590,11 @@ if (x->type != XMLNODE_TYPE_TAG) continue; - if (!strcmp(x->name, "permit")) { + if (purple_strequal(x->name, "permit")) { name = xmlnode_get_data(x); purple_privacy_permit_add(account, name, TRUE); g_free(name); - } else if (!strcmp(x->name, "block")) { + } else if (purple_strequal(x->name, "block")) { name = xmlnode_get_data(x); purple_privacy_deny_add(account, name, TRUE); g_free(name); @@ -699,6 +699,24 @@ return purplebuddylist ? purplebuddylist->root : NULL; } +GHashTable * +purple_blist_get_buddies() +{ + return purplebuddylist ? purplebuddylist->buddies : NULL; +} + +void * +purple_blist_get_ui_data() +{ + return purplebuddylist->ui_data; +} + +void +purple_blist_set_ui_data(void *ui_data) +{ + purplebuddylist->ui_data = ui_data; +} + void purple_blist_show() { PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); @@ -774,12 +792,28 @@ return node? node->prev : NULL; } +void * +purple_blist_node_get_ui_data(const PurpleBlistNode *node) +{ + g_return_val_if_fail(node, NULL); + + return node->ui_data; +} + +void +purple_blist_node_set_ui_data(PurpleBlistNode *node, void *ui_data) { + g_return_if_fail(node); + + node->ui_data = ui_data; +} + void purple_blist_update_buddy_status(PurpleBuddy *buddy, PurpleStatus *old_status) { PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); PurplePresence *presence; PurpleStatus *status; + PurpleBlistNode *cnode; g_return_if_fail(buddy != NULL); @@ -794,16 +828,18 @@ purple_signal_emit(purple_blist_get_handle(), "buddy-signed-on", buddy); - ((PurpleContact*)((PurpleBlistNode*)buddy)->parent)->online++; - if (((PurpleContact*)((PurpleBlistNode*)buddy)->parent)->online == 1) - ((PurpleGroup *)((PurpleBlistNode *)buddy)->parent->parent)->online++; + cnode = buddy->node.parent; + if (++(PURPLE_CONTACT(cnode)->online) == 1) + PURPLE_GROUP(cnode->parent)->online++; } else if (!purple_status_is_online(status) && purple_status_is_online(old_status)) { + purple_blist_node_set_int(&buddy->node, "last_seen", time(NULL)); purple_signal_emit(purple_blist_get_handle(), "buddy-signed-off", buddy); - ((PurpleContact*)((PurpleBlistNode*)buddy)->parent)->online--; - if (((PurpleContact*)((PurpleBlistNode*)buddy)->parent)->online == 0) - ((PurpleGroup *)((PurpleBlistNode *)buddy)->parent->parent)->online--; + + cnode = buddy->node.parent; + if (--(PURPLE_CONTACT(cnode)->online) == 0) + PURPLE_GROUP(cnode->parent)->online--; } else { purple_signal_emit(purple_blist_get_handle(), "buddy-status-changed", buddy, old_status, @@ -1025,7 +1061,7 @@ g_return_if_fail(source != NULL); g_return_if_fail(new_name != NULL); - if (*new_name == '\0' || !strcmp(new_name, source->name)) + if (*new_name == '\0' || purple_strequal(new_name, source->name)) return; dest = purple_find_group(new_name); @@ -1092,7 +1128,7 @@ /* Notify all PRPLs */ /* TODO: Is this condition needed? Seems like it would always be TRUE */ - if(old_name && source && strcmp(source->name, old_name)) { + if(old_name && purple_strequal(source->name, old_name)) { for (accts = purple_group_get_accounts(source); accts; accts = g_slist_remove(accts, accts->data)) { PurpleAccount *account = accts->data; PurpleConnection *gc = NULL; @@ -1101,7 +1137,7 @@ GList *l = NULL, *buddies = NULL; gc = purple_account_get_connection(account); - + if(gc) prpl = purple_connection_get_prpl(gc); @@ -1166,17 +1202,17 @@ return chat; } -PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *screenname, const char *alias) +PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias) { PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); PurpleBuddy *buddy; g_return_val_if_fail(account != NULL, FALSE); - g_return_val_if_fail(screenname != NULL, FALSE); + g_return_val_if_fail(name != NULL, FALSE); buddy = g_new0(PurpleBuddy, 1); buddy->account = account; - buddy->name = g_strdup(screenname); + buddy->name = g_strdup(name); buddy->alias = g_strdup(alias); buddy->presence = purple_presence_new_for_buddy(buddy); ((PurpleBlistNode *)buddy)->type = PURPLE_BLIST_BUDDY_NODE; @@ -1232,6 +1268,23 @@ return buddy->icon; } +gpointer +purple_buddy_get_protocol_data(const PurpleBuddy *buddy) +{ + g_return_val_if_fail(buddy != NULL, NULL); + + return buddy->proto_data; +} + +void +purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data) +{ + g_return_if_fail(buddy != NULL); + + buddy->proto_data = data; +} + + void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node) { PurpleBlistNode *cnode = (PurpleBlistNode*)chat; @@ -1339,7 +1392,7 @@ g = (PurpleGroup*)node->parent->parent; } else if (contact) { c = contact; - g = (PurpleGroup *)((PurpleBlistNode *)c)->parent; + g = PURPLE_GROUP(PURPLE_BLIST_NODE(c)->parent); } else { g = group; if (g == NULL) @@ -1421,16 +1474,14 @@ } if (PURPLE_BUDDY_IS_ONLINE(buddy)) { - ((PurpleContact*)bnode->parent)->online++; - if (((PurpleContact*)bnode->parent)->online == 1) - ((PurpleGroup*)bnode->parent->parent)->online++; + if (++(PURPLE_CONTACT(bnode->parent)->online) == 1) + PURPLE_GROUP(bnode->parent->parent)->online++; } if (purple_account_is_connected(buddy->account)) { - ((PurpleContact*)bnode->parent)->currentsize++; - if (((PurpleContact*)bnode->parent)->currentsize == 1) - ((PurpleGroup*)bnode->parent->parent)->currentsize++; + if (++(PURPLE_CONTACT(bnode->parent)->currentsize) == 1) + PURPLE_GROUP(bnode->parent->parent)->currentsize++; } - ((PurpleContact*)bnode->parent)->totalsize++; + PURPLE_CONTACT(bnode->parent)->totalsize++; hb = g_new(struct _purple_hbuddy, 1); hb->name = g_strdup(purple_normalize(buddy->account, buddy->name)); @@ -1546,7 +1597,7 @@ g_return_if_fail(contact != NULL); g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT((PurpleBlistNode*)contact)); - if ((PurpleBlistNode*)contact == node) + if (PURPLE_BLIST_NODE(contact) == node) return; if (node && (PURPLE_BLIST_NODE_IS_CONTACT(node) || @@ -2056,6 +2107,12 @@ return buddy->name; } +const char *purple_buddy_get_local_buddy_alias(PurpleBuddy *buddy) +{ + g_return_val_if_fail(buddy, NULL); + return buddy->alias; +} + const char *purple_buddy_get_server_alias(PurpleBuddy *buddy) { g_return_val_if_fail(buddy != NULL, NULL); @@ -2300,7 +2357,7 @@ { g_return_val_if_fail(buddy != NULL, NULL); - return (PurpleContact*)((PurpleBlistNode*)buddy)->parent; + return PURPLE_CONTACT(PURPLE_BLIST_NODE(buddy)->parent); } PurplePresence *purple_buddy_get_presence(const PurpleBuddy *buddy) diff -r 29f953732186 -r 8c8948b9f602 libpurple/blist.h --- a/libpurple/blist.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/blist.h Wed Jan 28 10:23:37 2009 +0000 @@ -75,12 +75,37 @@ } PurpleBlistNodeFlags; +/** + * @since 2.6.0 + */ +#define PURPLE_BLIST_NODE(obj) ((PurpleBlistNode *)(obj)) + #define PURPLE_BLIST_NODE_HAS_FLAG(b, f) (purple_blist_node_get_flags((PurpleBlistNode*)(b)) & (f)) #define PURPLE_BLIST_NODE_SHOULD_SAVE(b) (! PURPLE_BLIST_NODE_HAS_FLAG(b, PURPLE_BLIST_NODE_FLAG_NO_SAVE)) #define PURPLE_BLIST_NODE_NAME(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_CHAT_NODE ? purple_chat_get_name((PurpleChat*)n) : \ purple_blist_node_get_type(n) == PURPLE_BLIST_BUDDY_NODE ? purple_buddy_get_name((PurpleBuddy*)n) : NULL) +/** + * @since 2.6.0 + */ +#define PURPLE_GROUP(obj) ((PurpleGroup *)(obj)) + +/** + * @since 2.6.0 + */ +#define PURPLE_CONTACT(obj) ((PurpleContact *)(obj)) + +/** + * @since 2.6.0 + */ +#define PURPLE_BUDDY(obj) ((PurpleBuddy *)(obj)) + +/** + * @since 2.6.0 + */ +#define PURPLE_CHAT(obj) ((PurpleChat *)(obj)) + #include "account.h" #include "buddyicon.h" #include "status.h" @@ -111,7 +136,7 @@ */ struct _PurpleBuddy { PurpleBlistNode node; /**< The node that this buddy inherits from */ - char *name; /**< The screenname of the buddy. */ + char *name; /**< The name of the buddy. */ char *alias; /**< The user-set alias of the buddy */ char *server_alias; /**< The server-specified alias of the buddy. (i.e. MSN "Friendly Names") */ void *proto_data; /**< This allows the prpl to associate whatever data it wants with a buddy */ @@ -156,9 +181,6 @@ PurpleAccount *account; /**< The account this chat is attached to */ }; -#endif /* PURPLE_HIDE_STRUCTS && PURPLE_BLIST_STRUCTS */ - - /** * The Buddy List */ @@ -168,6 +190,8 @@ void *ui_data; /**< UI-specific data. */ }; +#endif /* PURPLE_HIDE_STRUCTS && PURPLE_BLIST_STRUCTS */ + /** * Buddy list UI operations. * @@ -236,6 +260,33 @@ PurpleBlistNode *purple_blist_get_root(void); /** + * Returns the hash table of every buddy in the list. + * + * @return The hash table of every buddy in the list. + * + * @since 2.6.0 + */ +GHashTable *purple_blist_get_buddies(void); + +/** + * Returns the UI data for the list. + * + * @return The UI data for the list. + * + * @since 2.6.0 + */ +void *purple_blist_get_ui_data(void); + +/** + * Sets the UI data for the list. + * + * @param ui_data The UI data for the list. + * + * @since 2.6.0 + */ +void purple_blist_set_ui_data(void *ui_data); + +/** * Returns the next node of a given node. This function is to be used to iterate * over the tree returned by purple_get_blist. * @@ -302,6 +353,25 @@ PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node); /** + * Returns the UI data of a given node. + * + * @param node The node. + * @return The UI data. + * @since 2.6.0 + */ +void *purple_blist_node_get_ui_data(const PurpleBlistNode *node); + +/** + * Sets the UI data of a given node. + * + * @param node The node. + * @param ui_data The UI data. + * + * @since 2.6.0 + */ +void purple_blist_node_set_ui_data(PurpleBlistNode *node, void *ui_data); + +/** * Shows the buddy list, creating a new one if necessary. */ void purple_blist_show(void); @@ -331,6 +401,7 @@ * Updates a node's custom icon. * * @param node The PurpleBlistNode whose custom icon has changed. + * * @since 2.5.0 */ void purple_blist_update_node_icon(PurpleBlistNode *node); @@ -423,11 +494,11 @@ * Creates a new buddy * * @param account The account this buddy will get added to - * @param screenname The screenname of the new buddy + * @param name The name of the new buddy * @param alias The alias of the new buddy (or NULL if unaliased) * @return A newly allocated buddy */ -PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *screenname, const char *alias); +PurpleBuddy *purple_buddy_new(PurpleAccount *account, const char *name, const char *alias); /** * Sets a buddy's icon. @@ -470,6 +541,32 @@ PurpleBuddyIcon *purple_buddy_get_icon(const PurpleBuddy *buddy); /** + * Returns a buddy's protocol-specific data. + * + * This should only be called from the associated prpl. + * + * @param buddy The buddy. + * @return The protocol data. + * + * @see purple_buddy_set_protocol_data() + * @since 2.6.0 + */ +gpointer purple_buddy_get_protocol_data(const PurpleBuddy *buddy); + +/** + * Sets a buddy's protocol-specific data. + * + * This should only be called from the associated prpl. + * + * @param buddy The buddy. + * @param data The data. + * + * @see purple_buddy_get_protocol_data() + * @since 2.6.0 + */ +void purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data); + +/** * Returns a buddy's contact. * * @param buddy The buddy. @@ -659,15 +756,18 @@ */ const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_BLIST_C_) /** * Returns the correct alias for this user, ignoring server aliases. Used * when a user-recognizable name is required. In order: buddy's alias; buddy's * contact alias; buddy's user name. - * + * * @param buddy The buddy whose alias will be returned. * @return The appropriate name or alias. + * @deprecated Try purple_buddy_get_alias(), if server aliases are okay. */ const char *purple_buddy_get_local_alias(PurpleBuddy *buddy); +#endif /** * Returns the correct name to display for a buddy. In order of precedence: @@ -680,6 +780,16 @@ const char *purple_buddy_get_alias(PurpleBuddy *buddy); /** + * Returns the local alias for the buddy, or @c NULL if none exists. + * + * @param buddy The buddy + * @return The local alias for the buddy + * + * @since 2.6.0 + */ +const char *purple_buddy_get_local_buddy_alias(PurpleBuddy *buddy); + +/** * Returns the correct name to display for a blist chat. * * @param chat The chat whose name will be returned. @@ -688,19 +798,19 @@ const char *purple_chat_get_name(PurpleChat *chat); /** - * Finds the buddy struct given a screenname and an account + * Finds the buddy struct given a name and an account * * @param account The account this buddy belongs to - * @param name The buddy's screenname + * @param name The buddy's name * @return The buddy or NULL if the buddy does not exist */ PurpleBuddy *purple_find_buddy(PurpleAccount *account, const char *name); /** - * Finds the buddy struct given a screenname, an account, and a group + * Finds the buddy struct given a name, an account, and a group * * @param account The account this buddy belongs to - * @param name The buddy's screenname + * @param name The buddy's name * @param group The group to look in * @return The buddy or NULL if the buddy does not exist in the group */ @@ -708,10 +818,10 @@ PurpleGroup *group); /** - * Finds all PurpleBuddy structs given a screenname and an account + * Finds all PurpleBuddy structs given a name and an account * * @param account The account this buddy belongs to - * @param name The buddy's screenname (or NULL to return all buddies in the account) + * @param name The buddy's name (or NULL to return all buddies in the account) * * @return A GSList of buddies (which must be freed), or NULL if the buddy doesn't exist */ @@ -751,6 +861,7 @@ * @param chat The chat. * * @return The account the chat belongs to. + * * @since 2.4.0 */ PurpleAccount *purple_chat_get_account(PurpleChat *chat); @@ -761,6 +872,7 @@ * @param chat The chat. * * @constreturn The hashtable. + * * @since 2.4.0 */ GHashTable *purple_chat_get_components(PurpleChat *chat); @@ -979,6 +1091,7 @@ * @param node The node. * * @return The type of the node. + * * @since 2.1.0 */ PurpleBlistNodeType purple_blist_node_get_type(PurpleBlistNode *node); diff -r 29f953732186 -r 8c8948b9f602 libpurple/buddyicon.c --- a/libpurple/buddyicon.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/buddyicon.c Wed Jan 28 10:23:37 2009 +0000 @@ -153,7 +153,7 @@ { const char *dirname; char *path; - + g_return_if_fail(img != NULL); if (!purple_buddy_icons_is_caching()) @@ -175,7 +175,7 @@ } purple_util_write_data_to_file_absolute(path, purple_imgstore_get_data(img), - purple_imgstore_get_size(img)); + purple_imgstore_get_size(img)); g_free(path); } @@ -453,7 +453,7 @@ if (conv != NULL) purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set); - + /* icon's refcount was incremented above */ if (icon) purple_buddy_icon_unref(icon); } @@ -757,7 +757,7 @@ g_hash_table_insert(pointer_icon_cache, account, img); else g_hash_table_remove(pointer_icon_cache, account); - + if (purple_account_is_connected(account)) { PurpleConnection *gc; @@ -889,7 +889,9 @@ if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBlistNode *child; - for (child = node->child ; child ; child = child->next) + for (child = purple_blist_node_get_first_child(node); + child; + child = purple_blist_node_get_sibling_next(child)) { PurpleBuddy *buddy; PurpleConversation *conv; @@ -986,7 +988,7 @@ { purple_blist_node_remove_setting(node, setting_name); - if (!strcmp(setting_name, "buddy_icon")) + if (purple_strequal(setting_name, "buddy_icon")) { purple_blist_node_remove_setting(node, "avatar_hash"); purple_blist_node_remove_setting(node, "icon_checksum"); @@ -1083,7 +1085,7 @@ g_free(new_filename); - if (!strcmp(setting_name, "buddy_icon")) + if (purple_strequal(setting_name, "buddy_icon")) { const char *hash; @@ -1098,7 +1100,7 @@ PurpleAccount *account = purple_buddy_get_account((PurpleBuddy *)node); const char *prpl_id = purple_account_get_protocol_id(account); - if (!strcmp(prpl_id, "prpl-yahoo")) + if (purple_strequal(prpl_id, "prpl-yahoo")) { int checksum = purple_blist_node_get_int(node, "icon_checksum"); if (checksum != 0) diff -r 29f953732186 -r 8c8948b9f602 libpurple/certificate.c --- a/libpurple/certificate.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/certificate.c Wed Jan 28 10:23:37 2009 +0000 @@ -51,7 +51,7 @@ { PurpleCertificateVerificationRequest *vrq; PurpleCertificateScheme *scheme; - + g_return_if_fail(subject_name != NULL); /* If you don't have a cert to check, why are you requesting that it be verified? */ @@ -97,10 +97,10 @@ "Failed to verify certificate for %s\n", vrq->subject_name); } - - - - + + + + /* Pass the results on to the request's callback */ (vrq->cb)(st, vrq->cb_data); @@ -154,7 +154,7 @@ purple_certificate_destroy (PurpleCertificate *crt) { PurpleCertificateScheme *scheme; - + if (NULL == crt) return; scheme = crt->scheme; @@ -206,7 +206,7 @@ "Checking signature chain for uid=%s\n", uid); g_free(uid); - + /* If this is a single-certificate chain, say that it is valid */ if (chain->next == NULL) { purple_debug_info("certificate", @@ -218,9 +218,9 @@ crt = (PurpleCertificate *)(chain->data); /* And start with the second certificate in the chain */ for ( cur = chain->next; cur; cur = cur->next ) { - + issuer = (PurpleCertificate *)(cur->data); - + /* Check the signature for this link */ if (! purple_certificate_signed_by(crt, issuer) ) { uid = purple_certificate_get_unique_id(issuer); @@ -228,7 +228,7 @@ "...Bad or missing signature by %s\nChain is INVALID\n", uid); g_free(uid); - + return FALSE; } @@ -237,7 +237,7 @@ "...Good signature by %s\n", uid); g_free(uid); - + /* The issuer is now the next crt whose signature is to be checked */ crt = issuer; @@ -283,7 +283,7 @@ g_return_val_if_fail(crt->scheme, NULL); scheme = crt->scheme; - + g_return_val_if_fail(scheme->get_fingerprint_sha1, NULL); fpr = (scheme->get_fingerprint_sha1)(crt); @@ -354,7 +354,7 @@ g_return_val_if_fail(crt, FALSE); scheme = crt->scheme; - + g_return_val_if_fail(scheme, FALSE); /* If both provided references are NULL, what are you doing calling @@ -371,7 +371,7 @@ { gchar *path; gchar *esc_scheme_name, *esc_name, *esc_id; - + g_return_val_if_fail(pool, NULL); g_return_val_if_fail(pool->scheme_name, NULL); g_return_val_if_fail(pool->name, NULL); @@ -380,7 +380,7 @@ esc_scheme_name = pool ? g_strdup(purple_escape_filename(pool->scheme_name)) : NULL; esc_name = pool ? g_strdup(purple_escape_filename(pool->name)) : NULL; esc_id = id ? g_strdup(purple_escape_filename(id)) : NULL; - + path = g_build_filename(purple_user_dir(), "certificates", /* TODO: constantize this? */ esc_scheme_name, @@ -404,7 +404,7 @@ if (purple_certificate_find_scheme(pool->scheme_name) == NULL) { return FALSE; } - + return TRUE; } @@ -441,7 +441,7 @@ purple_certificate_pool_store(PurpleCertificatePool *pool, const gchar *id, PurpleCertificate *crt) { gboolean ret = FALSE; - + g_return_val_if_fail(pool, FALSE); g_return_val_if_fail(id, FALSE); g_return_val_if_fail(pool->put_cert, FALSE); @@ -461,13 +461,13 @@ } return ret; -} +} gboolean purple_certificate_pool_delete(PurpleCertificatePool *pool, const gchar *id) { gboolean ret = FALSE; - + g_return_val_if_fail(pool, FALSE); g_return_val_if_fail(id, FALSE); g_return_val_if_fail(pool->delete_cert, FALSE); @@ -496,7 +496,7 @@ purple_certificate_pool_destroy_idlist(GList *idlist) { GList *l; - + /* Iterate through and free them strings */ for ( l = idlist; l; l = l->next ) { g_free(l->data); @@ -520,7 +520,7 @@ vrq->subject_name, id); /* Signal what happened back to the caller */ - if (1 == id) { + if (1 == id) { /* Accepted! */ purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_VALID); @@ -557,11 +557,11 @@ } else { cn_match = _("(DOES NOT MATCH)"); } - + /* Make messages */ primary = g_strdup_printf(_("%s has presented the following certificate for just-this-once use:"), vrq->subject_name); secondary = g_strdup_printf(_("Common name: %s %s\nFingerprint (SHA1): %s"), cn, cn_match, sha_asc); - + /* Make a semi-pretty display */ purple_request_accept_cancel( vrq->cb_data, /* TODO: Find what the handle ought to be */ @@ -575,7 +575,7 @@ vrq, x509_singleuse_verify_cb, x509_singleuse_verify_cb ); - + /* Cleanup */ g_free(primary); g_free(secondary); @@ -644,13 +644,13 @@ /* lazy_init calls this function, so calling lazy_init here is a Bad Thing */ - + g_return_val_if_fail(crt, FALSE); g_return_val_if_fail(crt->scheme, FALSE); /* Make sure that this is some kind of X.509 certificate */ /* TODO: Perhaps just check crt->scheme->name instead? */ g_return_val_if_fail(crt->scheme == purple_certificate_find_scheme(x509_ca.scheme_name), FALSE); - + el = g_new0(x509_ca_element, 1); el->dn = purple_certificate_get_unique_id(crt); el->crt = purple_certificate_copy(crt); @@ -675,7 +675,7 @@ const gchar *entry; GPatternSpec *pempat; GList *iter = NULL; - + if (x509_ca_initialized) return TRUE; /* Check that X.509 is registered */ @@ -791,7 +791,7 @@ for (cur = lst; cur; cur = cur->next) { x509_ca_element *el = cur->data; - if (el->dn && !strcmp(dn, el->dn)) { + if (purple_strequal(dn, el->dn)) { return el; } } @@ -832,7 +832,7 @@ } else { crt = NULL; } - + return crt; } @@ -840,7 +840,7 @@ x509_ca_put_cert(const gchar *id, PurpleCertificate *crt) { gboolean ret = FALSE; - + g_return_val_if_fail(x509_ca_lazy_init(), FALSE); /* TODO: This is a quick way of doing this. At some point the change @@ -854,7 +854,7 @@ x509_ca_delete_cert(const gchar *id) { x509_ca_element *el; - + g_return_val_if_fail(x509_ca_lazy_init(), FALSE); g_return_val_if_fail(id, FALSE); @@ -870,7 +870,7 @@ /* Unlink it from the memory cache and destroy it */ x509_ca_certs = g_list_remove(x509_ca_certs, el); x509_ca_element_free(el); - + return TRUE; } @@ -878,7 +878,7 @@ x509_ca_get_idlist(void) { GList *l, *idlist; - + g_return_val_if_fail(x509_ca_lazy_init(), NULL); idlist = NULL; @@ -886,7 +886,7 @@ x509_ca_element *el = l->data; idlist = g_list_prepend(idlist, g_strdup(el->dn)); } - + return idlist; } @@ -921,7 +921,7 @@ { gchar *poolpath; int ret; - + /* Set up key cache here if it isn't already done */ poolpath = purple_certificate_pool_mkpath(&x509_tls_peers, NULL); ret = purple_build_dir(poolpath, 0700); /* Make it this user only */ @@ -937,13 +937,13 @@ { gchar *keypath; gboolean ret = FALSE; - + g_return_val_if_fail(id, FALSE); keypath = purple_certificate_pool_mkpath(&x509_tls_peers, id); ret = g_file_test(keypath, G_FILE_TEST_IS_REGULAR); - + g_free(keypath); return ret; } @@ -954,14 +954,14 @@ PurpleCertificateScheme *x509; PurpleCertificate *crt; gchar *keypath; - + g_return_val_if_fail(id, NULL); /* Is it in the pool? */ if ( !x509_tls_peers_cert_in_pool(id) ) { return NULL; } - + /* Look up the X.509 scheme */ x509 = purple_certificate_find_scheme("x509"); g_return_val_if_fail(x509, NULL); @@ -990,7 +990,7 @@ /* Work out the filename and export */ keypath = purple_certificate_pool_mkpath(&x509_tls_peers, id); ret = purple_certificate_export(keypath, crt); - + g_free(keypath); return ret; } @@ -1012,7 +1012,7 @@ } /* OK, so work out the keypath and delete the thing */ - keypath = purple_certificate_pool_mkpath(&x509_tls_peers, id); + keypath = purple_certificate_pool_mkpath(&x509_tls_peers, id); if ( unlink(keypath) != 0 ) { purple_debug_error("certificate/tls_peers", "Unlink of %s failed!\n", @@ -1047,7 +1047,7 @@ while ( (entry = g_dir_read_name(dir)) != NULL ) { /* Unescape the filename */ const char *unescaped = purple_unescape_filename(entry); - + /* Copy the entry name into our list (GLib owns the original string) */ idlist = g_list_prepend(idlist, g_strdup(unescaped)); @@ -1055,7 +1055,7 @@ /* Release the directory */ g_dir_close(dir); - + return idlist; } @@ -1143,7 +1143,7 @@ g_return_if_fail(c); g_return_if_fail(c->vrq); - + vrq = c->vrq; x509_tls_cached_ua_ctx_free(c); @@ -1155,7 +1155,7 @@ purple_debug_info("certificate/x509/tls_cached", "User ACCEPTED cert\nCaching first in chain for future use as %s...\n", cache_id); - + purple_certificate_pool_store(tls_peers, cache_id, vrq->cert_chain->data); @@ -1195,7 +1195,7 @@ /* Make messages */ primary = g_strdup_printf(_("Accept certificate for %s?"), vrq->subject_name); - + /* Make a semi-pretty display */ purple_request_action( vrq->cb_data, /* TODO: Find what the handle ought to be */ @@ -1211,7 +1211,7 @@ _("Accept"), x509_tls_cached_user_auth_accept_cb, _("Reject"), x509_tls_cached_user_auth_reject_cb, _("_View Certificate..."), x509_tls_cached_show_cert); - + /* Cleanup */ g_free(primary); } @@ -1225,7 +1225,7 @@ "Certificate for %s does not match cached. " "Auto-rejecting!\n", vrq->subject_name); - + purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_INVALID); return; } @@ -1245,7 +1245,7 @@ /* The peer's certificate should be the first in the list */ PurpleCertificate *peer_crt = (PurpleCertificate *) vrq->cert_chain->data; - + PurpleCertificate *cached_crt; GByteArray *peer_fpr, *cached_fpr; @@ -1278,7 +1278,7 @@ /* vrq now becomes the problem of the user */ x509_tls_cached_unknown_peer(vrq); } - + purple_certificate_destroy(cached_crt); g_byte_array_free(peer_fpr, TRUE); g_byte_array_free(cached_fpr, TRUE); @@ -1305,7 +1305,7 @@ "not self-signed" */ if ( purple_certificate_signed_by(peer_crt, peer_crt) ) { gchar *msg; - + purple_debug_info("certificate/x509/tls_cached", "Certificate for %s is self-signed.\n", vrq->subject_name); @@ -1316,13 +1316,13 @@ "is self-signed. It cannot be " "automatically checked."), vrq->subject_name); - + x509_tls_cached_user_auth(vrq,msg); g_free(msg); return; } /* if (self signed) */ - + /* Next, check that the certificate chain is valid */ if ( ! purple_certificate_check_signature_chain(chain) ) { /* TODO: Tell the user where the chain broke? */ @@ -1390,7 +1390,7 @@ } g_free(ca_id); - + /* Check the signature */ if ( !purple_certificate_signed_by(end_crt, ca_crt) ) { /* TODO: If signed_by ever returns a reason, maybe mention @@ -1406,7 +1406,7 @@ "Authority from which it claims to " "have a signature."), vrq->subject_name); - + purple_notify_error(NULL, /* TODO: Probably wrong */ _("SSL Certificate Error"), _("Invalid certificate authority" @@ -1425,7 +1425,7 @@ vrq->subject_name) ) { gchar *sn = purple_certificate_get_subject_name(peer_crt); gchar *msg; - + purple_debug_info("certificate/x509/tls_cached", "Name mismatch: Certificate given for %s " "has a name of %s\n", @@ -1441,7 +1441,7 @@ "connecting to the service you " "believe you are."), vrq->subject_name, sn); - + x509_tls_cached_user_auth(vrq,msg); g_free(sn); @@ -1465,7 +1465,7 @@ "Unable to locate tls_peers certificate " "cache.\n"); } - + /* Whew! Done! */ purple_certificate_verify_complete(vrq, PURPLE_CERTIFICATE_VALID); } @@ -1481,7 +1481,7 @@ purple_debug_info("certificate/x509/tls_cached", "Starting verify for %s\n", vrq->subject_name); - + tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name,tls_peers_name); if (!tls_peers) { @@ -1494,7 +1494,7 @@ x509_tls_cached_unknown_peer(vrq); return; } - + /* Check if the peer has a certificate cached already */ purple_debug_info("certificate/x509/tls_cached", "Checking for cached cert...\n"); @@ -1583,7 +1583,7 @@ name); /* TODO: Signalling and such? */ - + return NULL; } @@ -1611,7 +1611,7 @@ purple_debug_info("certificate", "CertificateScheme %s registered\n", scheme->name); - + return TRUE; } @@ -1664,7 +1664,7 @@ scheme_name, ver_name); /* TODO: Signalling and such? */ - + return NULL; } @@ -1742,7 +1742,7 @@ scheme_name, pool_name); /* TODO: Signalling and such? */ - + return NULL; } @@ -1830,11 +1830,11 @@ } cert_pools = g_list_remove(cert_pools, pool); - + /* TODO: Signalling? */ purple_signal_unregister(pool, "certificate-stored"); purple_signal_unregister(pool, "certificate-deleted"); - + purple_debug_info("certificate", "CertificatePool %s unregistered\n", pool->name); diff -r 29f953732186 -r 8c8948b9f602 libpurple/certificate.h --- a/libpurple/certificate.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/certificate.h Wed Jan 28 10:23:37 2009 +0000 @@ -60,7 +60,7 @@ typedef void (*PurpleCertificateVerifiedCallback) (PurpleCertificateVerificationStatus st, gpointer userdata); - + /** A certificate instance * * An opaque data structure representing a single certificate under some @@ -96,7 +96,7 @@ /** Internal pool data */ gpointer data; - + /** * Set up the Pool's internal state * @@ -249,7 +249,7 @@ /** Retrieve the certificate activation/expiration times */ gboolean (* get_times)(PurpleCertificate *crt, time_t *activation, time_t *expiration); - + void (*_purple_reserved1)(void); void (*_purple_reserved2)(void); void (*_purple_reserved3)(void); @@ -276,7 +276,7 @@ /** Name of the Verifier - case insensitive */ gchar *name; - + /** * Start the verification process * @@ -326,14 +326,14 @@ * For X.509 certificates, this is the Common Name */ gchar *subject_name; - + /** List of certificates in the chain to be verified (such as that returned by purple_ssl_get_peer_certificates ) * * This is most relevant for X.509 certificates used in SSL sessions. * The list order should be: certificate, issuer, issuer's issuer, etc. */ GList *cert_chain; - + /** Internal data used by the Verifier code */ gpointer data; @@ -437,7 +437,7 @@ * * @return TRUE if 'crt' has a valid signature made by 'issuer', * otherwise FALSE - * @todo Find a way to give the reason (bad signature, not the issuer, etc.) + * @todo Find a way to give the reason (bad signature, not the issuer, etc.) */ gboolean purple_certificate_signed_by(PurpleCertificate *crt, PurpleCertificate *issuer); @@ -523,7 +523,7 @@ /** * Check the subject name against that on the certificate * @param crt Certificate instance - * @param name Name to check. + * @param name Name to check. * @return TRUE if it is a match, else FALSE */ gboolean diff -r 29f953732186 -r 8c8948b9f602 libpurple/cipher.c --- a/libpurple/cipher.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/cipher.c Wed Jan 28 10:23:37 2009 +0000 @@ -512,7 +512,7 @@ } static void -md4_append(PurpleCipherContext *context, const guchar *data, size_t len) +md4_append(PurpleCipherContext *context, const guchar *data, size_t len) { struct MD4_Context *mctx = purple_cipher_context_get_data(context); const guint32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); @@ -551,7 +551,7 @@ char *p = (char *)mctx->block + offset; int padding = 56 - (offset + 1); - + if(in_len<16) return FALSE; if(out_len) *out_len = 16; *p++ = 0x80; @@ -659,7 +659,7 @@ hctx = purple_cipher_context_get_data(context); - if (!strcmp(name, "hash")) { + if (purple_strequal(name, "hash")) { g_free(hctx->name); if (hctx->hash) purple_cipher_context_destroy(hctx->hash); @@ -676,7 +676,7 @@ hctx = purple_cipher_context_get_data(context); - if (!strcmp(name, "hash")) { + if (purple_strequal(name, "hash")) { return hctx->name; } @@ -684,7 +684,7 @@ } static void -hmac_append(PurpleCipherContext *context, const guchar *data, size_t len) +hmac_append(PurpleCipherContext *context, const guchar *data, size_t len) { struct HMAC_Context *hctx = purple_cipher_context_get_data(context); @@ -778,7 +778,7 @@ hmac_set_key_with_len(context, key, strlen((char *)key)); } -static size_t +static size_t hmac_get_block_size(PurpleCipherContext *context) { struct HMAC_Context *hctx = purple_cipher_context_get_data(context); @@ -1022,11 +1022,11 @@ * 16 encryption rounds. * To calculate subkeys for decryption the caller * have to reorder the generated subkeys. - * + * * rawkey: 8 Bytes of key data * subkey: Array of at least 32 guint32s. Will be filled * with calculated subkeys. - * + * **/ static void des_key_schedule (const guint8 * rawkey, guint32 * subkey) @@ -1186,7 +1186,7 @@ buf, output+offset, 0); - } + } return 0; } @@ -1216,7 +1216,7 @@ buf, output+offset, 1); - } + } return 0; } @@ -1692,11 +1692,11 @@ ctx = purple_cipher_context_get_data(context); - if(!strcmp(name, "sizeHi")) { + if(purple_strequal(name, "sizeHi")) { ctx->sizeHi = GPOINTER_TO_INT(value); - } else if(!strcmp(name, "sizeLo")) { + } else if(purple_strequal(name, "sizeLo")) { ctx->sizeLo = GPOINTER_TO_INT(value); - } else if(!strcmp(name, "lenW")) { + } else if(purple_strequal(name, "lenW")) { ctx->lenW = GPOINTER_TO_INT(value); } } @@ -1707,11 +1707,11 @@ ctx = purple_cipher_context_get_data(context); - if(!strcmp(name, "sizeHi")) { + if(purple_strequal(name, "sizeHi")) { return GINT_TO_POINTER(ctx->sizeHi); - } else if(!strcmp(name, "sizeLo")) { + } else if(purple_strequal(name, "sizeLo")) { return GINT_TO_POINTER(ctx->sizeLo); - } else if(!strcmp(name, "lenW")) { + } else if(purple_strequal(name, "lenW")) { return GINT_TO_POINTER(ctx->lenW); } @@ -1942,12 +1942,12 @@ ctx = purple_cipher_context_get_data(context); - if(!strcmp(name, "key_len")) { + if(purple_strequal(name, "key_len")) { ctx->key_len = GPOINTER_TO_INT(value); } } -static size_t +static size_t rc4_get_key_size (PurpleCipherContext *context) { struct RC4Context *ctx; @@ -1967,7 +1967,7 @@ ctx = purple_cipher_context_get_data(context); - if(!strcmp(name, "key_len")) { + if(purple_strequal(name, "key_len")) { return GINT_TO_POINTER(ctx->key_len); } diff -r 29f953732186 -r 8c8948b9f602 libpurple/cipher.h --- a/libpurple/cipher.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/cipher.h Wed Jan 28 10:23:37 2009 +0000 @@ -422,7 +422,7 @@ size_t purple_cipher_context_get_block_size(PurpleCipherContext *context); /** - * Sets the key with a given length on a context + * Sets the key with a given length on a context * * @param context The context whose key to set * @param key The key diff -r 29f953732186 -r 8c8948b9f602 libpurple/circbuffer.c --- a/libpurple/circbuffer.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/circbuffer.c Wed Jan 28 10:23:37 2009 +0000 @@ -44,7 +44,7 @@ static void grow_circ_buffer(PurpleCircBuffer *buf, gsize len) { int in_offset = 0, out_offset = 0; int start_buflen; - + g_return_if_fail(buf != NULL); start_buflen = buf->buflen; @@ -94,7 +94,7 @@ int len_stored; g_return_if_fail(buf != NULL); - + /* Grow the buffer, if necessary */ if ((buf->buflen - buf->bufused) < len) grow_circ_buffer(buf, len); diff -r 29f953732186 -r 8c8948b9f602 libpurple/cmds.c --- a/libpurple/cmds.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/cmds.c Wed Jan 28 10:23:37 2009 +0000 @@ -236,7 +236,7 @@ for (l = cmds; l; l = l->next) { c = l->data; - if (strcmp(c->cmd, cmd) != 0) + if (!purple_strequal(c->cmd, cmd)) continue; found = TRUE; @@ -250,8 +250,8 @@ right_type = TRUE; - if ((c->flags & PURPLE_CMD_FLAG_PRPL_ONLY) && c->prpl_id && - (strcmp(c->prpl_id, prpl_id) != 0)) + if ((c->flags & PURPLE_CMD_FLAG_PRPL_ONLY) && + !purple_strequal(c->prpl_id, prpl_id)) continue; right_prpl = TRUE; @@ -320,8 +320,8 @@ if (!(c->flags & PURPLE_CMD_FLAG_CHAT)) continue; - if (conv && (c->flags & PURPLE_CMD_FLAG_PRPL_ONLY) && c->prpl_id && - (strcmp(c->prpl_id, purple_account_get_protocol_id(purple_conversation_get_account(conv))) != 0)) + if (conv && (c->flags & PURPLE_CMD_FLAG_PRPL_ONLY) && + !purple_strequal(c->prpl_id, purple_account_get_protocol_id(purple_conversation_get_account(conv)))) continue; ret = g_list_append(ret, c->cmd); @@ -342,7 +342,7 @@ for (l = cmds; l; l = l->next) { c = l->data; - if (cmd && (strcmp(cmd, c->cmd) != 0)) + if (cmd && !purple_strequal(cmd, c->cmd)) continue; if (conv && (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)) @@ -352,8 +352,8 @@ if (!(c->flags & PURPLE_CMD_FLAG_CHAT)) continue; - if (conv && (c->flags & PURPLE_CMD_FLAG_PRPL_ONLY) && c->prpl_id && - (strcmp(c->prpl_id, purple_account_get_protocol_id(purple_conversation_get_account(conv))) != 0)) + if (conv && (c->flags & PURPLE_CMD_FLAG_PRPL_ONLY) && + !purple_strequal(c->prpl_id, purple_account_get_protocol_id(purple_conversation_get_account(conv)))) continue; ret = g_list_append(ret, c->help); diff -r 29f953732186 -r 8c8948b9f602 libpurple/connection.c --- a/libpurple/connection.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/connection.c Wed Jan 28 10:23:37 2009 +0000 @@ -191,16 +191,16 @@ PurpleConnection *gc; PurplePlugin *prpl; PurplePluginProtocolInfo *prpl_info; - + g_return_if_fail(account != NULL); - + prpl = purple_find_prpl(purple_account_get_protocol_id(account)); - + if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); else { gchar *message; - + message = g_strdup_printf(_("Missing protocol plugin for %s"), purple_account_get_username(account)); purple_notify_error(NULL, _("Unregistration Error"), message, NULL); @@ -212,7 +212,7 @@ prpl_info->unregister_user(account, cb, user_data); return; } - + if (((password == NULL) || (*password == '\0')) && !(prpl_info->options & OPT_PROTO_NO_PASSWORD) && !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL)) @@ -221,10 +221,10 @@ "a password.\n", purple_account_get_username(account)); return; } - + gc = g_new0(PurpleConnection, 1); PURPLE_DBUS_REGISTER_POINTER(gc, PurpleConnection); - + gc->prpl = prpl; if ((password != NULL) && (*password != '\0')) gc->password = g_strdup(password); @@ -232,11 +232,11 @@ purple_connection_set_state(gc, PURPLE_CONNECTING); connections = g_list_append(connections, gc); purple_account_set_connection(account, gc); - + purple_signal_emit(purple_connections_get_handle(), "signing-on", gc); - + purple_debug_info("connection", "Unregistering. gc = %p\n", gc); - + prpl_info->unregister_user(account, cb, user_data); } @@ -285,7 +285,7 @@ buddies = purple_find_buddies(account, NULL); while (buddies != NULL) { PurpleBuddy *buddy = buddies->data; - buddy->proto_data = NULL; + purple_buddy_set_protocol_data(buddy, NULL); buddies = g_slist_delete_link(buddies, buddies); } @@ -427,6 +427,13 @@ gc->display_name = g_strdup(name); } +void +purple_connection_set_protocol_data(PurpleConnection *connection, void *proto_data) { + g_return_if_fail(connection != NULL); + + connection->proto_data = proto_data; +} + PurpleConnectionState purple_connection_get_state(const PurpleConnection *gc) { @@ -467,6 +474,13 @@ return gc->display_name; } +void * +purple_connection_get_protocol_data(const PurpleConnection *connection) { + g_return_val_if_fail(connection != NULL, NULL); + + return connection->proto_data; +} + void purple_connection_update_progress(PurpleConnection *gc, const char *text, size_t step, size_t count) diff -r 29f953732186 -r 8c8948b9f602 libpurple/connection.h --- a/libpurple/connection.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/connection.h Wed Jan 28 10:23:37 2009 +0000 @@ -42,7 +42,7 @@ PURPLE_CONNECTION_FORMATTING_WBFO = 0x0008, /**< The text buffer must be formatted as a whole */ PURPLE_CONNECTION_NO_NEWLINES = 0x0010, /**< No new lines are allowed in outgoing messages */ PURPLE_CONNECTION_NO_FONTSIZE = 0x0020, /**< Connection does not send/receive font sizes */ - PURPLE_CONNECTION_NO_URLDESC = 0x0040, /**< Connection does not support descriptions with links */ + PURPLE_CONNECTION_NO_URLDESC = 0x0040, /**< Connection does not support descriptions with links */ PURPLE_CONNECTION_NO_IMAGES = 0x0080, /**< Connection does not support sending of images */ PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY = 0x0100 /**< Connection supports sending and receiving custom smileys */ @@ -56,7 +56,9 @@ } PurpleConnectionState; -/** Possible errors that can cause a connection to be closed. +/** + * Possible errors that can cause a connection to be closed. + * * @since 2.3.0 */ typedef enum @@ -92,7 +94,7 @@ PURPLE_CONNECTION_ERROR_NAME_IN_USE = 6, /** The username/server/other preference for the account isn't valid. - * For instance, on IRC the screen name cannot contain white space. + * For instance, on IRC the username cannot contain white space. * This reason should not be used for incorrect passwords etc: use * #PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED for that. * @@ -148,71 +150,84 @@ #include "status.h" #include "sslconn.h" -/** Connection UI operations. Used to notify the user of changes to - * connections, such as being disconnected, and to respond to the - * underlying network connection appearing and disappearing. UIs should - * call #purple_connections_set_ui_ops() with an instance of this struct. +/** + * Connection UI operations. Used to notify the user of changes to + * connections, such as being disconnected, and to respond to the + * underlying network connection appearing and disappearing. UIs should + * call #purple_connections_set_ui_ops() with an instance of this struct. * - * @see @ref ui-ops + * @see @ref ui-ops */ typedef struct { - /** When an account is connecting, this operation is called to notify - * the UI of what is happening, as well as which @a step out of @a - * step_count has been reached (which might be displayed as a progress - * bar). - * @see #purple_connection_update_progress + /** + * When an account is connecting, this operation is called to notify + * the UI of what is happening, as well as which @a step out of @a + * step_count has been reached (which might be displayed as a progress + * bar). + * @see #purple_connection_update_progress */ void (*connect_progress)(PurpleConnection *gc, const char *text, size_t step, size_t step_count); - /** Called when a connection is established (just before the - * @ref signed-on signal). + /** + * Called when a connection is established (just before the + * @ref signed-on signal). */ void (*connected)(PurpleConnection *gc); - /** Called when a connection is ended (between the @ref signing-off - * and @ref signed-off signals). + + /** + * Called when a connection is ended (between the @ref signing-off + * and @ref signed-off signals). */ void (*disconnected)(PurpleConnection *gc); - /** Used to display connection-specific notices. (Pidgin's Gtk user - * interface implements this as a no-op; #purple_connection_notice(), - * which uses this operation, is not used by any of the protocols - * shipped with libpurple.) + /** + * Used to display connection-specific notices. (Pidgin's Gtk user + * interface implements this as a no-op; #purple_connection_notice(), + * which uses this operation, is not used by any of the protocols + * shipped with libpurple.) */ void (*notice)(PurpleConnection *gc, const char *text); - /** Called when an error causes a connection to be disconnected. - * Called before #disconnected. - * @param text a localized error message. - * @see #purple_connection_error - * @deprecated in favour of - * #PurpleConnectionUiOps.report_disconnect_reason. + /** + * Called when an error causes a connection to be disconnected. + * Called before #disconnected. + * @param text a localized error message. + * @see #purple_connection_error + * @deprecated in favour of + * #PurpleConnectionUiOps.report_disconnect_reason. */ void (*report_disconnect)(PurpleConnection *gc, const char *text); - /** Called when libpurple discovers that the computer's network - * connection is active. On Linux, this uses Network Manager if - * available; on Windows, it uses Win32's network change notification - * infrastructure. + /** + * Called when libpurple discovers that the computer's network + * connection is active. On Linux, this uses Network Manager if + * available; on Windows, it uses Win32's network change notification + * infrastructure. */ void (*network_connected)(void); - /** Called when libpurple discovers that the computer's network - * connection has gone away. + + /** + * Called when libpurple discovers that the computer's network + * connection has gone away. */ void (*network_disconnected)(void); - /** Called when an error causes a connection to be disconnected. + /** + * Called when an error causes a connection to be disconnected. * Called before #disconnected. This op is intended to replace * #report_disconnect. If both are implemented, this will be called * first; however, there's no real reason to implement both. + * * @param reason why the connection ended, if known, or * #PURPLE_CONNECTION_ERROR_OTHER_ERROR, if not. * @param text a localized message describing the disconnection * in more detail to the user. * @see #purple_connection_error_reason + * * @since 2.3.0 */ void (*report_disconnect_reason)(PurpleConnection *gc, @@ -354,6 +369,16 @@ void purple_connection_set_display_name(PurpleConnection *gc, const char *name); /** + * Sets the protocol data for a connection. + * + * @param connection The PurpleConnection. + * @param proto_data The protocol data to set for the connection. + * + * @since 2.6.0 + */ +void purple_connection_set_protocol_data(PurpleConnection *connection, void *proto_data); + +/** * Returns the connection state. * * @param gc The connection. @@ -385,6 +410,7 @@ * @param gc The connection. * * @return The protocol plugin. + * * @since 2.4.0 */ PurplePlugin * purple_connection_get_prpl(const PurpleConnection *gc); @@ -408,6 +434,17 @@ const char *purple_connection_get_display_name(const PurpleConnection *gc); /** + * Gets the protocol data from a connection. + * + * @param connection The PurpleConnection. + * + * @return The protocol data for the connection. + * + * @since 2.6.0 + */ +void *purple_connection_get_protocol_data(const PurpleConnection *connection); + +/** * Updates the connection progress. * * @param gc The connection. @@ -450,6 +487,7 @@ * @param gc the connection which is closing. * @param reason why the connection is closing. * @param description a non-@c NULL localized description of the error. + * * @since 2.3.0 */ void @@ -461,6 +499,7 @@ * Closes a connection due to an SSL error; this is basically a shortcut to * turning the #PurpleSslErrorType into a #PurpleConnectionError and a * human-readable string and then calling purple_connection_error_reason(). + * * @since 2.3.0 */ void @@ -484,6 +523,7 @@ * * @return @c TRUE if the account should not be automatically reconnected, and * @c FALSE otherwise. + * * @since 2.3.0 */ gboolean diff -r 29f953732186 -r 8c8948b9f602 libpurple/conversation.c --- a/libpurple/conversation.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/conversation.c Wed Jan 28 10:23:37 2009 +0000 @@ -665,7 +665,7 @@ text = purple_buddy_get_contact_alias(b); } else if(purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { if(account && ((chat = purple_blist_find_chat(account, name)) != NULL)) - text = chat->alias; + text = purple_chat_get_name(chat); } @@ -912,7 +912,7 @@ if (purple_account_get_alias(account) != NULL) alias = account->alias; - else if (b != NULL && strcmp(b->name, purple_buddy_get_contact_alias(b))) + else if (b != NULL && !purple_strequal(purple_buddy_get_name(b), purple_buddy_get_contact_alias(b))) alias = purple_buddy_get_contact_alias(b); else if (purple_connection_get_display_name(gc) != NULL) alias = purple_connection_get_display_name(gc); @@ -1480,7 +1480,7 @@ str = g_strdup(purple_normalize(account, who)); - if (!strcmp(str, purple_normalize(account, chat->nick))) { + if (purple_strequal(str, purple_normalize(account, chat->nick))) { flags |= PURPLE_MESSAGE_SEND; } else { flags |= PURPLE_MESSAGE_RECV; @@ -1601,7 +1601,7 @@ const char *extra_msg = (extra_msgs ? extra_msgs->data : NULL); if(!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { - if (!strcmp(chat->nick, purple_normalize(conv->account, user))) { + if (purple_strequal(chat->nick, purple_normalize(conv->account, user))) { const char *alias2 = purple_account_get_alias(conv->account); if (alias2 != NULL) alias = alias2; @@ -1692,7 +1692,7 @@ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); g_return_if_fail(prpl_info != NULL); - if (!strcmp(chat->nick, purple_normalize(conv->account, old_user))) { + if (purple_strequal(chat->nick, purple_normalize(conv->account, old_user))) { const char *alias; /* Note this for later. */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/conversation.h --- a/libpurple/conversation.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/conversation.h Wed Jan 28 10:23:37 2009 +0000 @@ -1350,7 +1350,7 @@ * Retrieves the extended menu items for the conversation. * * @param conv The conversation. - * + * * @return A list of PurpleMenuAction items, harvested by the * chat-extended-menu signal. The list and the menuaction * items should be freed by the caller. diff -r 29f953732186 -r 8c8948b9f602 libpurple/core.c --- a/libpurple/core.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/core.c Wed Jan 28 10:23:37 2009 +0000 @@ -46,9 +46,11 @@ #include "signals.h" #include "smiley.h" #include "sound.h" +#include "sound-theme-loader.h" #include "sslconn.h" #include "status.h" #include "stun.h" +#include "theme-manager.h" #include "util.h" #ifdef HAVE_DBUS @@ -143,6 +145,8 @@ purple_plugins_probe(G_MODULE_SUFFIX); + purple_theme_manager_init(); + /* The buddy icon code uses the imgstore, so init it early. */ purple_imgstore_init(); @@ -171,7 +175,7 @@ purple_xfers_init(); purple_idle_init(); purple_smileys_init(); - + purple_theme_manager_init(); /* * Call this early on to try to auto-detect our IP address and * hopefully save some time later. @@ -181,6 +185,9 @@ if (ops != NULL && ops->ui_init != NULL) ops->ui_init(); + /* The UI may have registered some theme types, so refresh them */ + purple_theme_manager_refresh(); + return TRUE; } @@ -233,6 +240,7 @@ purple_savedstatuses_uninit(); purple_status_uninit(); purple_sound_uninit(); + purple_theme_manager_uninit(); purple_xfers_uninit(); purple_proxy_uninit(); purple_dnsquery_uninit(); @@ -350,15 +358,7 @@ const char *user_dir = purple_user_dir(); char *dbus_owner_user_dir = purple_dbus_owner_user_dir(); - if (NULL == user_dir && NULL != dbus_owner_user_dir) - is_single_instance = TRUE; - else if (NULL != user_dir && NULL == dbus_owner_user_dir) - is_single_instance = TRUE; - else if (NULL == user_dir && NULL == dbus_owner_user_dir) - is_single_instance = FALSE; - else - is_single_instance = strcmp(dbus_owner_user_dir, user_dir); - + is_single_instance = !purple_strequal(dbus_owner_user_dir, user_dir); g_free(dbus_owner_user_dir); } } @@ -489,7 +489,7 @@ if (g_file_test(name, G_FILE_TEST_IS_SYMLINK)) { /* We're only going to duplicate a logs symlink. */ - if (!strcmp(entry, "logs")) + if (purple_strequal(entry, "logs")) { char *link; #if GLIB_CHECK_VERSION(2,4,0) @@ -532,7 +532,8 @@ logs_dir = g_build_filename(user_dir, "logs", NULL); - if (!strcmp(link, "../.purple/logs") || !strcmp(link, logs_dir)) + if (purple_strequal(link, "../.purple/logs") || + purple_strequal(link, logs_dir)) { /* If the symlink points to the new directory, we're * likely just trying again after a failed migration, @@ -577,7 +578,7 @@ /* Deal with directories... */ if (g_file_test(name, G_FILE_TEST_IS_DIR)) { - if (!strcmp(entry, "icons")) + if (purple_strequal(entry, "icons")) { /* This is a special case for the Album plugin, which * stores data in the icons folder. We're not copying @@ -646,7 +647,7 @@ g_dir_close(icons_dir); } - else if (!strcmp(entry, "plugins")) + else if (purple_strequal(entry, "plugins")) { /* Do nothing, because we broke plugin compatibility. * This means that the plugins directory gets left behind. */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/core.h --- a/libpurple/core.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/core.h Wed Jan 28 10:23:37 2009 +0000 @@ -90,17 +90,17 @@ /** *

- * Calls purple_core_quit(). This can be used as the function - * passed to purple_timeout_add() when you want to shutdown Purple - * in a specified amount of time. When shutting down Purple + * Calls purple_core_quit(). This can be used as the function + * passed to purple_timeout_add() when you want to shutdown Purple + * in a specified amount of time. When shutting down Purple * from a plugin, you must use this instead of purple_core_quit(); - * for an immediate exit, use a timeout value of 0: + * for an immediate exit, use a timeout value of 0: *

* * purple_timeout_add(0, purple_core_quitcb, NULL); * *

- * This is ensures that code from your plugin is not being + * This is ensures that code from your plugin is not being * executed when purple_core_quit() is called. If the plugin * called purple_core_quit() directly, you would get a core dump * after purple_core_quit() executes and control returns to your diff -r 29f953732186 -r 8c8948b9f602 libpurple/dbus-bindings.h --- a/libpurple/dbus-bindings.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/dbus-bindings.h Wed Jan 28 10:23:37 2009 +0000 @@ -84,7 +84,7 @@ int first_arg_type, va_list var_args); -dbus_int32_t* purple_dbusify_GList(GList *list, gboolean free_memory, +dbus_int32_t* purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len); dbus_int32_t* purple_dbusify_GSList(GSList *list, gboolean free_memory, dbus_int32_t *len); diff -r 29f953732186 -r 8c8948b9f602 libpurple/dbus-server.h --- a/libpurple/dbus-server.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/dbus-server.h Wed Jan 28 10:23:37 2009 +0000 @@ -173,7 +173,7 @@ /** * Determines whether this instance owns the DBus service name - * + * * @since 2.1.0 */ gboolean purple_dbus_is_owner(void); diff -r 29f953732186 -r 8c8948b9f602 libpurple/desktopitem.c --- a/libpurple/desktopitem.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/desktopitem.c Wed Jan 28 10:23:37 2009 +0000 @@ -41,12 +41,12 @@ * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * The Gnome Library 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 * Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, @@ -67,7 +67,7 @@ GList *languages; PurpleDesktopItemType type; - + /* `modified' means that the ditem has been * modified since the last save. */ gboolean modified; @@ -108,30 +108,30 @@ switch (type [0]) { case 'A': - if (!strcmp (type, "Application")) + if (purple_strequal (type, "Application")) return PURPLE_DESKTOP_ITEM_TYPE_APPLICATION; break; case 'L': - if (!strcmp (type, "Link")) + if (purple_strequal (type, "Link")) return PURPLE_DESKTOP_ITEM_TYPE_LINK; break; case 'F': - if (!strcmp (type, "FSDevice")) + if (purple_strequal (type, "FSDevice")) return PURPLE_DESKTOP_ITEM_TYPE_FSDEVICE; break; case 'M': - if (!strcmp (type, "MimeType")) + if (purple_strequal (type, "MimeType")) return PURPLE_DESKTOP_ITEM_TYPE_MIME_TYPE; break; case 'D': - if (!strcmp (type, "Directory")) + if (purple_strequal (type, "Directory")) return PURPLE_DESKTOP_ITEM_TYPE_DIRECTORY; break; case 'S': - if (!strcmp (type, "Service")) + if (purple_strequal (type, "Service")) return PURPLE_DESKTOP_ITEM_TYPE_SERVICE; - else if (!strcmp (type, "ServiceType")) + else if (purple_strequal (type, "ServiceType")) return PURPLE_DESKTOP_ITEM_TYPE_SERVICE_TYPE; break; default: @@ -149,12 +149,12 @@ if (section == NULL) return NULL; - if (strcmp (section, "Desktop Entry") == 0) + if (purple_strequal (section, "Desktop Entry")) return NULL; for (li = item->sections; li != NULL; li = li->next) { sec = li->data; - if (strcmp (sec->name, section) == 0) + if (purple_strequal (sec->name, section)) return sec; } @@ -235,7 +235,7 @@ item->keys = g_list_append (item->keys, g_strdup (key)); - g_hash_table_replace (item->main_hash, + g_hash_table_replace (item->main_hash, g_strdup (key), g_strdup (value)); } else { @@ -264,7 +264,7 @@ set (item, attr, value); - if (strcmp (attr, PURPLE_DESKTOP_ITEM_TYPE) == 0) + if (purple_strequal (attr, PURPLE_DESKTOP_ITEM_TYPE)) item->type = type_from_string (value); } @@ -280,7 +280,7 @@ retval->main_hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_free); - + /* These are guaranteed to be set */ _purple_desktop_item_set_string (retval, PURPLE_DESKTOP_ITEM_NAME, @@ -354,16 +354,16 @@ p++; if (*p == ' ') p++; - if (strcmp (p, "UTF-8") == 0) { + if (purple_strequal (p, "UTF-8")) { return ENCODING_UTF8; - } else if (strcmp (p, "Legacy-Mixed") == 0) { + } else if (purple_strequal (p, "Legacy-Mixed")) { return ENCODING_LEGACY_MIXED; } else { /* According to the spec we're not supposed * to read a file like this */ return ENCODING_UNKNOWN; } - } else if (strcmp ("[KDE Desktop Entry]", buf) == 0) { + } else if (purple_strequal ("[KDE Desktop Entry]", buf)) { old_kde = TRUE; /* don't break yet, we still want to support * Encoding even here */ @@ -557,7 +557,7 @@ char *utf8_string; if (char_encoding == NULL) return NULL; - if (strcmp (char_encoding, "ASCII") == 0) { + if (purple_strequal (char_encoding, "ASCII")) { return decode_string_and_dup (value); } utf8_string = g_convert (value, -1, "UTF-8", char_encoding, @@ -673,7 +673,7 @@ char *val; /* we always store everything in UTF-8 */ if (cur_section == NULL && - strcmp (key, PURPLE_DESKTOP_ITEM_ENCODING) == 0) { + purple_strequal (key, PURPLE_DESKTOP_ITEM_ENCODING)) { k = g_strdup (key); val = g_strdup ("UTF-8"); } else { @@ -690,14 +690,14 @@ g_free (locale); return; } - + g_strchomp (val); /* For old KDE entries, we can also split by a comma * on sort order, so convert to semicolons */ if (old_kde && cur_section == NULL && - strcmp (key, PURPLE_DESKTOP_ITEM_SORT_ORDER) == 0 && + purple_strequal (key, PURPLE_DESKTOP_ITEM_SORT_ORDER) && strchr (val, ';') == NULL) { int i; for (i = 0; val[i] != '\0'; i++) { @@ -720,7 +720,7 @@ /* Take care of the language part */ if (locale != NULL && - strcmp (locale, "C") == 0) { + purple_strequal (locale, "C")) { char *p; /* Whack C locale */ p = strchr (k, '['); @@ -791,11 +791,10 @@ PURPLE_DESKTOP_ITEM_TYPE); if (type == NULL && uri != NULL) { char *base = g_path_get_basename (uri); - if (base != NULL && - strcmp (base, ".directory") == 0) { + if (purple_strequal(base, ".directory")) { /* This gotta be a directory */ g_hash_table_replace (item->main_hash, - g_strdup (PURPLE_DESKTOP_ITEM_TYPE), + g_strdup (PURPLE_DESKTOP_ITEM_TYPE), g_strdup ("Directory")); item->keys = g_list_prepend (item->keys, g_strdup (PURPLE_DESKTOP_ITEM_TYPE)); @@ -813,7 +812,7 @@ lookup_locale (const PurpleDesktopItem *item, const char *key, const char *locale) { if (locale == NULL || - strcmp (locale, "C") == 0) { + purple_strequal (locale, "C")) { return lookup (item, key); } else { const char *ret; @@ -857,7 +856,7 @@ type = lookup (item, PURPLE_DESKTOP_ITEM_TYPE); /* understand old gnome style url exec thingies */ - if (type != NULL && strcmp (type, "URL") == 0) { + if (purple_strequal(type, "URL")) { const char *exec = lookup (item, PURPLE_DESKTOP_ITEM_EXEC); set (item, PURPLE_DESKTOP_ITEM_TYPE, "Link"); if (exec != NULL) { @@ -877,7 +876,7 @@ if (name == NULL) name = g_strdup (_("No name")); g_hash_table_replace (item->main_hash, - g_strdup (PURPLE_DESKTOP_ITEM_NAME), + g_strdup (PURPLE_DESKTOP_ITEM_NAME), name); item->keys = g_list_prepend (item->keys, g_strdup (PURPLE_DESKTOP_ITEM_NAME)); @@ -885,7 +884,7 @@ if (lookup (item, PURPLE_DESKTOP_ITEM_ENCODING) == NULL) { /* We store everything in UTF-8 so write that down */ g_hash_table_replace (item->main_hash, - g_strdup (PURPLE_DESKTOP_ITEM_ENCODING), + g_strdup (PURPLE_DESKTOP_ITEM_ENCODING), g_strdup ("UTF-8")); item->keys = g_list_prepend (item->keys, g_strdup (PURPLE_DESKTOP_ITEM_ENCODING)); @@ -893,7 +892,7 @@ if (lookup (item, PURPLE_DESKTOP_ITEM_VERSION) == NULL) { /* this is the version that we follow, so write it down */ g_hash_table_replace (item->main_hash, - g_strdup (PURPLE_DESKTOP_ITEM_VERSION), + g_strdup (PURPLE_DESKTOP_ITEM_VERSION), g_strdup ("1.0")); item->keys = g_list_prepend (item->keys, g_strdup (PURPLE_DESKTOP_ITEM_VERSION)); @@ -954,7 +953,7 @@ while ((c = getc (df)) != EOF) { if (c == '\r') /* Ignore Carriage Return */ continue; - + switch (state) { case OnSecHeader: @@ -968,13 +967,11 @@ cur_section->keys = g_list_reverse (cur_section->keys); } - if (strcmp (CharBuffer, - "KDE Desktop Entry") == 0) { + if (purple_strequal (CharBuffer, "KDE Desktop Entry")) { /* Main section */ cur_section = NULL; old_kde = TRUE; - } else if (strcmp (CharBuffer, - "Desktop Entry") == 0) { + } else if (purple_strequal(CharBuffer, "Desktop Entry")) { /* Main section */ cur_section = NULL; } else { @@ -1025,16 +1022,16 @@ /* On first pass, don't allow dangling keys */ if (state == FirstBrace) break; - + if ((c == ' ' && state != KeyDefOnKey) || c == '\t') break; - + if (c == '\n' || PURPLE_DESKTOP_ITEM_OVERFLOW) { /* Abort Definition */ next = CharBuffer; state = KeyDef; break; } - + if (c == '=' || PURPLE_DESKTOP_ITEM_OVERFLOW){ *next = '\0'; @@ -1067,7 +1064,7 @@ break; } /* switch */ - + } /* while ((c = getc_unlocked (f)) != EOF) */ if (c == EOF && state == KeyValue) { *next = '\0'; @@ -1158,7 +1155,7 @@ printf ("Can't open %s: %s", filename, g_strerror(errno)); return NULL; } - + retval = ditem_load(dfile, FALSE, filename); return retval; @@ -1203,7 +1200,7 @@ /* Languages */ retval->languages = g_list_copy (item->languages); for (li = retval->languages; li != NULL; li = li->next) - li->data = g_strdup (li->data); + li->data = g_strdup (li->data); /* Keys */ retval->keys = g_list_copy (item->keys); diff -r 29f953732186 -r 8c8948b9f602 libpurple/desktopitem.h --- a/libpurple/desktopitem.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/desktopitem.h Wed Jan 28 10:23:37 2009 +0000 @@ -41,12 +41,12 @@ * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * The Gnome Library 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 * Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, @@ -155,7 +155,7 @@ * * @param item The item to be copied * - * @return The new copy + * @return The new copy */ PurpleDesktopItem *purple_desktop_item_copy (const PurpleDesktopItem *item); diff -r 29f953732186 -r 8c8948b9f602 libpurple/eventloop.h --- a/libpurple/eventloop.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/eventloop.h Wed Jan 28 10:23:37 2009 +0000 @@ -119,8 +119,8 @@ * @see purple_input_remove */ gboolean (*input_remove)(guint handle); - - + + /** * If implemented, should get the current error status for an input. * @@ -161,7 +161,7 @@ /*@{*/ /** * Creates a callback timer. - * + * * The timer will repeat until the function returns @c FALSE. The * first call will be at the end of the first interval. * @@ -185,12 +185,12 @@ * * This function allows UIs to group timers for better power efficiency. For * this reason, @a interval may be rounded by up to a second. - * + * * @param interval The time between calls of the function, in * seconds. * @param function The function to call. * @param data data to pass to @a function. - * @return A handle to the timer which can be passed to + * @return A handle to the timer which can be passed to * purple_timeout_remove() to remove the timer. * * @since 2.1.0 diff -r 29f953732186 -r 8c8948b9f602 libpurple/idle.c --- a/libpurple/idle.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/idle.c Wed Jan 28 10:23:37 2009 +0000 @@ -126,14 +126,14 @@ idle_reporting = purple_prefs_get_string("/purple/away/idle_reporting"); auto_away = purple_prefs_get_bool("/purple/away/away_when_idle"); - if (!strcmp(idle_reporting, "system") && + if (purple_strequal(idle_reporting, "system") && (idle_ui_ops != NULL) && (idle_ui_ops->get_time_idle != NULL)) { /* Use system idle time (mouse or keyboard movement, etc.) */ time_idle = idle_ui_ops->get_time_idle(); idle_recheck_interval = 1; } - else if (!strcmp(idle_reporting, "purple")) + else if (purple_strequal(idle_reporting, "purple")) { /* Use 'Purple idle' */ time_idle = time(NULL) - last_active_time; @@ -214,7 +214,7 @@ /* - * Check idle and set the timer to fire at the next idle-worth event + * Check idle and set the timer to fire at the next idle-worth event */ static gboolean check_idleness_timer(void) diff -r 29f953732186 -r 8c8948b9f602 libpurple/internal.h --- a/libpurple/internal.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/internal.h Wed Jan 28 10:23:37 2009 +0000 @@ -102,7 +102,7 @@ #include #ifdef PURPLE_PLUGINS -# ifdef HAVE_DLFCN_H +# ifdef HAVE_DLFCN_H # include # endif #endif diff -r 29f953732186 -r 8c8948b9f602 libpurple/log.c --- a/libpurple/log.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/log.c Wed Jan 28 10:23:37 2009 +0000 @@ -34,6 +34,7 @@ #include "util.h" #include "stringref.h" #include "imgstore.h" +#include "time.h" static GSList *loggers = NULL; @@ -46,6 +47,7 @@ PurpleAccount *account; }; static GHashTable *logsize_users = NULL; +static GHashTable *logsize_users_decayed = NULL; static void log_get_log_sets_common(GHashTable *sets); @@ -161,14 +163,27 @@ lu->account = log->account; if(g_hash_table_lookup_extended(logsize_users, lu, NULL, &ptrsize)) { + char *tmp = lu->name; + total = GPOINTER_TO_INT(ptrsize); total += written; g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(total)); + + /* The hash table takes ownership of lu, so create a new one + * for the logsize_users_decayed check below. */ + lu = g_new(struct _purple_logsize_user, 1); + lu->name = g_strdup(tmp); + lu->account = log->account; + } + + if(g_hash_table_lookup_extended(logsize_users_decayed, lu, NULL, &ptrsize)) { + total = GPOINTER_TO_INT(ptrsize); + total += written; + g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(total)); } else { g_free(lu->name); g_free(lu); } - } char *purple_log_read(PurpleLog *log, PurpleLogReadFlags *flags) @@ -200,7 +215,7 @@ static guint _purple_logsize_user_equal(struct _purple_logsize_user *lu1, struct _purple_logsize_user *lu2) { - return (lu1->account == lu2->account && (!strcmp(lu1->name, lu2->name))); + return (lu1->account == lu2->account && purple_strequal(lu1->name, lu2->name)); } static void _purple_logsize_user_free_key(struct _purple_logsize_user *lu) @@ -250,6 +265,49 @@ return size; } +gint purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account) +{ + gpointer ptrscore; + int score; + GSList *n; + struct _purple_logsize_user *lu; + time_t now; + time(&now); + + lu = g_new(struct _purple_logsize_user, 1); + lu->name = g_strdup(purple_normalize(account, name)); + lu->account = account; + + if(g_hash_table_lookup_extended(logsize_users_decayed, lu, NULL, &ptrscore)) { + score = GPOINTER_TO_INT(ptrscore); + g_free(lu->name); + g_free(lu); + } else { + double score_double = 0.0; + for (n = loggers; n; n = n->next) { + PurpleLogLogger *logger = n->data; + + if(logger->list) { + GList *logs = (logger->list)(type, name, account); + + while (logs) { + PurpleLog *log = (PurpleLog*)(logs->data); + /* Activity score counts bytes in the log, exponentially + decayed with a half-life of 14 days. */ + score_double += purple_log_get_size(log) * + pow(0.5, difftime(now, log->time)/1209600.0); + purple_log_free(log); + logs = g_list_delete_link(logs, logs); + } + } + } + + score = (gint)score_double; + g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(score)); + } + return score; +} + gboolean purple_log_is_deletable(PurpleLog *log) { g_return_val_if_fail(log != NULL, FALSE); @@ -324,7 +382,7 @@ GSList *l = loggers; while (l) { logger = l->data; - if (!strcmp(logger->id, value)) { + if (purple_strequal(logger->id, value)) { purple_log_logger_set(logger); return; } @@ -406,7 +464,7 @@ if (g_slist_find(loggers, logger)) return; loggers = g_slist_append(loggers, logger); - if (strcmp(purple_prefs_get_string("/purple/logging/format"), logger->id) == 0) { + if (purple_strequal(purple_prefs_get_string("/purple/logging/format"), logger->id)) { purple_prefs_trigger_callback("/purple/logging/format"); } } @@ -588,11 +646,11 @@ void *handle = purple_log_get_handle(); purple_prefs_add_none("/purple/logging"); - purple_prefs_add_bool("/purple/logging/log_ims", FALSE); - purple_prefs_add_bool("/purple/logging/log_chats", FALSE); + purple_prefs_add_bool("/purple/logging/log_ims", TRUE); + purple_prefs_add_bool("/purple/logging/log_chats", TRUE); purple_prefs_add_bool("/purple/logging/log_system", FALSE); - purple_prefs_add_string("/purple/logging/format", "txt"); + purple_prefs_add_string("/purple/logging/format", "html"); html_logger = purple_log_logger_new("html", _("HTML"), 11, NULL, @@ -661,6 +719,9 @@ logsize_users = g_hash_table_new_full((GHashFunc)_purple_logsize_user_hash, (GEqualFunc)_purple_logsize_user_equal, (GDestroyNotify)_purple_logsize_user_free_key, NULL); + logsize_users_decayed = g_hash_table_new_full((GHashFunc)_purple_logsize_user_hash, + (GEqualFunc)_purple_logsize_user_equal, + (GDestroyNotify)_purple_logsize_user_free_key, NULL); } void @@ -679,6 +740,9 @@ purple_log_logger_remove(old_logger); purple_log_logger_free(old_logger); old_logger = NULL; + + g_hash_table_destroy(logsize_users); + g_hash_table_destroy(logsize_users_decayed); } /**************************************************************************** @@ -1019,7 +1083,7 @@ continue; prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - if (!strcmp(protocol_unescaped, prpl_info->list_icon((PurpleAccount *)account_iter->data, NULL))) + if (purple_strequal(protocol_unescaped, prpl_info->list_icon((PurpleAccount *)account_iter->data, NULL))) accounts = g_list_prepend(accounts, account_iter->data); } g_free(protocol_unescaped); @@ -1039,7 +1103,7 @@ /* Find the account for username in the list of accounts for protocol. */ username_unescaped = purple_unescape_filename(username); for (account_iter = g_list_first(accounts) ; account_iter != NULL ; account_iter = account_iter->next) { - if (!strcmp(((PurpleAccount *)account_iter->data)->username, username_unescaped)) { + if (purple_strequal(((PurpleAccount *)account_iter->data)->username, username_unescaped)) { account = account_iter->data; break; } @@ -1068,14 +1132,14 @@ /* Chat for .chat or .system at the end of the name to determine the type. */ if (len >= 7) { gchar *tmp = &name[len - 7]; - if (!strcmp(tmp, ".system")) { + if (purple_strequal(tmp, ".system")) { set->type = PURPLE_LOG_SYSTEM; *tmp = '\0'; } } if (len > 5) { gchar *tmp = &name[len - 5]; - if (!strcmp(tmp, ".chat")) { + if (purple_strequal(tmp, ".chat")) { set->type = PURPLE_LOG_CHAT; *tmp = '\0'; } @@ -1773,29 +1837,29 @@ sscanf(convostart, "%*s %s %d %d:%d:%d %d", month, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year); /* Ugly hack, in case current locale is not English */ - if (strcmp(month, "Jan") == 0) { + if (purple_strequal(month, "Jan")) { tm.tm_mon= 0; - } else if (strcmp(month, "Feb") == 0) { + } else if (purple_strequal(month, "Feb")) { tm.tm_mon = 1; - } else if (strcmp(month, "Mar") == 0) { + } else if (purple_strequal(month, "Mar")) { tm.tm_mon = 2; - } else if (strcmp(month, "Apr") == 0) { + } else if (purple_strequal(month, "Apr")) { tm.tm_mon = 3; - } else if (strcmp(month, "May") == 0) { + } else if (purple_strequal(month, "May")) { tm.tm_mon = 4; - } else if (strcmp(month, "Jun") == 0) { + } else if (purple_strequal(month, "Jun")) { tm.tm_mon = 5; - } else if (strcmp(month, "Jul") == 0) { + } else if (purple_strequal(month, "Jul")) { tm.tm_mon = 6; - } else if (strcmp(month, "Aug") == 0) { + } else if (purple_strequal(month, "Aug")) { tm.tm_mon = 7; - } else if (strcmp(month, "Sep") == 0) { + } else if (purple_strequal(month, "Sep")) { tm.tm_mon = 8; - } else if (strcmp(month, "Oct") == 0) { + } else if (purple_strequal(month, "Oct")) { tm.tm_mon = 9; - } else if (strcmp(month, "Nov") == 0) { + } else if (purple_strequal(month, "Nov")) { tm.tm_mon = 10; - } else if (strcmp(month, "Dec") == 0) { + } else if (purple_strequal(month, "Dec")) { tm.tm_mon = 11; } tm.tm_year -= 1900; @@ -1930,7 +1994,7 @@ /* Make sure we're dealing with a log file. */ ext = &name[len - 4]; - if (strcmp(ext, ".log")) { + if (!purple_strequal(ext, ".log")) { g_free(name); continue; } @@ -1943,7 +2007,7 @@ set->type = PURPLE_LOG_IM; if (len > 9) { char *tmp = &name[len - 9]; - if (!strcmp(tmp, ".chat")) { + if (purple_strequal(tmp, ".chat")) { set->type = PURPLE_LOG_CHAT; *tmp = '\0'; } @@ -1952,22 +2016,28 @@ set->name = set->normalized_name = name; /* Search the buddy list to find the account and to determine if this is a buddy. */ - for (gnode = purple_get_blist()->root; !found && gnode != NULL; gnode = gnode->next) + for (gnode = purple_blist_get_root(); + !found && gnode != NULL; + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; !found && cnode != NULL; cnode = cnode->next) + for (cnode = purple_blist_node_get_first_child(gnode); + !found && cnode != NULL; + cnode = purple_blist_node_get_sibling_next(cnode)) { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; !found && bnode != NULL; bnode = bnode->next) + for (bnode = purple_blist_node_get_first_child(cnode); + !found && bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *buddy = (PurpleBuddy *)bnode; - if (!strcmp(buddy->name, name)) { - set->account = buddy->account; + if (purple_strequal(purple_buddy_get_name(buddy), name)) { + set->account = purple_buddy_get_account(buddy); set->buddy = TRUE; found = TRUE; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/log.h --- a/libpurple/log.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/log.h Wed Jan 28 10:23:37 2009 +0000 @@ -194,7 +194,7 @@ * Creates a new log * * @param type The type of log this is. - * @param name The name of this conversation (screenname, chat name, + * @param name The name of this conversation (buddy name, chat name, * etc.) * @param account The account the conversation is occurring on * @param conv The conversation being logged @@ -294,6 +294,19 @@ int purple_log_get_total_size(PurpleLogType type, const char *name, PurpleAccount *account); /** + * Returns the activity score of a log, based on total size in bytes, + * which is then decayed based on age + * + * @param type The type of the log + * @param name The name of the log + * @param account The account + * @return The activity score + * + * @since 2.6.0 + */ +int purple_log_get_activity_score(PurpleLogType type, const char *name, PurpleAccount *account); + +/** * Tests whether a log is deletable * * A return value of @c FALSE indicates that purple_log_delete() will fail on this diff -r 29f953732186 -r 8c8948b9f602 libpurple/nat-pmp.c --- a/libpurple/nat-pmp.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/nat-pmp.c Wed Jan 28 10:23:37 2009 +0000 @@ -126,7 +126,7 @@ for (i = 0; i < RTAX_MAX; i++) { - if (bitmask & (1 << i)) + if (bitmask & (1 << i)) { addrs[i] = sa; #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN @@ -139,7 +139,7 @@ sa = (struct sockaddr*)(sizeof(struct sockaddr_in6) + (char *)sa); #endif #endif - } + } else { addrs[i] = NULL; @@ -192,7 +192,7 @@ mib[5] = 0; /* Determine the buffer side needed to get the full routing table */ - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { purple_debug_warning("nat-pmp", "sysctl: net.route.0.0.dump estimate\n"); return NULL; @@ -205,7 +205,7 @@ } /* Read the routing table into buf */ - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { purple_debug_warning("nat-pmp", "sysctl: net.route.0.0.dump\n"); return NULL; @@ -213,12 +213,12 @@ lim = buf + needed; - for (next = buf; next < lim; next += rtm->rtm_msglen) + for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; sa = (struct sockaddr *)(rtm + 1); - - if (sa->sa_family == AF_INET) + + if (sa->sa_family == AF_INET) { sin = (struct sockaddr_in*) sa; @@ -240,7 +240,7 @@ memcpy(&mask, rti_info[RTAX_NETMASK], sizeof(mask)); if (rtm->rtm_addrs & RTA_GATEWAY && - is_default_route(&addr, &mask)) + is_default_route(&addr, &mask)) { if (rti_info[RTAX_GATEWAY]) { struct sockaddr_in *rti_sin = (struct sockaddr_in *)rti_info[RTAX_GATEWAY]; @@ -263,7 +263,7 @@ } /*! - * purple_pmp_get_public_ip() will return the publicly facing IP address of the + * purple_pmp_get_public_ip() will return the publicly facing IP address of the * default NAT gateway. The function will return NULL if: * - The gateway doesn't support NAT-PMP * - The gateway errors in some other spectacular fashion @@ -278,10 +278,10 @@ PurplePmpIpRequest req; PurplePmpIpResponse resp; int sendfd; - + if (pmp_info.status == PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER) return NULL; - + if ((pmp_info.status == PURPLE_PMP_STATUS_DISCOVERED) && (pmp_info.publicip != NULL)) { #ifdef PMP_DEBUG @@ -318,7 +318,7 @@ /* The NAT-PMP spec says we should attempt to contact the gateway 9 times, doubling the time we wait each time. * Even starting with a timeout of 0.1 seconds, that means that we have a total waiting of 204.6 seconds. * With the recommended timeout of 0.25 seconds, we're talking 511.5 seconds (8.5 minutes). - * + * * This seems really silly... if this were nonblocking, a couple retries might be in order, but it's not at present. */ #ifdef PMP_DEBUG @@ -327,7 +327,7 @@ #endif /* TODO: Non-blocking! */ - + if (sendto(sendfd, &req, sizeof(req), 0, (struct sockaddr *)(gateway), sizeof(struct sockaddr)) < 0) { purple_debug_info("nat-pmp", "There was an error sending the NAT-PMP public IP request! (%s)\n", g_strerror(errno)); @@ -370,7 +370,7 @@ if (!publicsockaddr) { g_free(gateway); - + pmp_info.status = PURPLE_PMP_STATUS_UNABLE_TO_DISCOVER; return NULL; } @@ -437,7 +437,7 @@ /* The NAT-PMP spec says we should attempt to contact the gateway 9 times, doubling the time we wait each time. * Even starting with a timeout of 0.1 seconds, that means that we have a total waiting of 204.6 seconds. * With the recommended timeout of 0.25 seconds, we're talking 511.5 seconds (8.5 minutes). - * + * * This seems really silly... if this were nonblocking, a couple retries might be in order, but it's not at present. * XXX Make this nonblocking. * XXX This code looks like the pmp_get_public_ip() code. Can it be consolidated? diff -r 29f953732186 -r 8c8948b9f602 libpurple/network.c --- a/libpurple/network.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/network.c Wed Jan 28 10:23:37 2009 +0000 @@ -92,6 +92,10 @@ static NMState nm_get_network_state(void); #endif +#if defined(HAVE_NETWORKMANAGER) || defined(_WIN32) +static gboolean force_online; +#endif + const unsigned char * purple_network_ip_atoi(const char *ip) { @@ -648,6 +652,9 @@ purple_network_is_available(void) { #ifdef HAVE_NETWORKMANAGER + if (force_online) + return TRUE; + if (!have_nm_state) { have_nm_state = TRUE; @@ -662,12 +669,20 @@ return FALSE; #elif defined _WIN32 - return (current_network_count > 0); + return (current_network_count > 0 || force_online); #else return TRUE; #endif } +void +purple_network_force_online() +{ +#if defined(HAVE_NETWORKMANAGER) || defined(_WIN32) + force_online = TRUE; +#endif +} + #ifdef HAVE_NETWORKMANAGER static void nm_update_state(NMState state) diff -r 29f953732186 -r 8c8948b9f602 libpurple/network.h --- a/libpurple/network.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/network.h Wed Jan 28 10:23:37 2009 +0000 @@ -208,6 +208,17 @@ gboolean purple_network_is_available(void); /** + * Makes purple_network_is_available() always return @c TRUE. + * + * This is what backs the --force-online command line argument in Pidgin, + * for example. This is useful for offline testing, especially when + * combined with nullprpl. + * + * @since 2.6.0 + */ +void purple_network_force_online(void); + +/** * Get the handle for the network system * * @return the handle to the network system diff -r 29f953732186 -r 8c8948b9f602 libpurple/notify.c --- a/libpurple/notify.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/notify.c Wed Jan 28 10:23:37 2009 +0000 @@ -444,7 +444,7 @@ purple_notify_user_info_entry_new(const char *label, const char *value) { PurpleNotifyUserInfoEntry *user_info_entry; - + user_info_entry = g_new0(PurpleNotifyUserInfoEntry, 1); PURPLE_DBUS_REGISTER_POINTER(user_info_entry, PurpleNotifyUserInfoEntry); user_info_entry->label = g_strdup(label); @@ -458,7 +458,7 @@ purple_notify_user_info_entry_destroy(PurpleNotifyUserInfoEntry *user_info_entry) { g_return_if_fail(user_info_entry != NULL); - + g_free(user_info_entry->label); g_free(user_info_entry->value); PURPLE_DBUS_UNREGISTER_POINTER(user_info_entry); @@ -469,11 +469,11 @@ purple_notify_user_info_new() { PurpleNotifyUserInfo *user_info; - + user_info = g_new0(PurpleNotifyUserInfo, 1); PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo); user_info->user_info_entries = NULL; - + return user_info; } @@ -484,10 +484,10 @@ for (l = user_info->user_info_entries; l != NULL; l = l->next) { PurpleNotifyUserInfoEntry *user_info_entry = l->data; - + purple_notify_user_info_entry_destroy(user_info_entry); } - + g_list_free(user_info->user_info_entries); PURPLE_DBUS_UNREGISTER_POINTER(user_info); g_free(user_info); @@ -506,7 +506,7 @@ { GList *l; GString *text; - + text = g_string_new(""); for (l = user_info->user_info_entries; l != NULL; l = l->next) { @@ -532,7 +532,7 @@ if ((user_info_entry->type != PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK) && (l->next && ((((PurpleNotifyUserInfoEntry *)(l->next->data))->type != PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK)))) g_string_append(text, newline); - + /* Add an extra newline after a section header */ if (user_info_entry->type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER) g_string_append(text, newline); @@ -563,7 +563,7 @@ purple_notify_user_info_entry_get_value(PurpleNotifyUserInfoEntry *user_info_entry) { g_return_val_if_fail(user_info_entry != NULL, NULL); - + return user_info_entry->value; } @@ -596,7 +596,7 @@ purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value) { PurpleNotifyUserInfoEntry *entry; - + entry = purple_notify_user_info_entry_new(label, value); user_info->user_info_entries = g_list_append(user_info->user_info_entries, entry); } @@ -623,7 +623,7 @@ purple_notify_user_info_add_section_header(PurpleNotifyUserInfo *user_info, const char *label) { PurpleNotifyUserInfoEntry *entry; - + entry = purple_notify_user_info_entry_new(label, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER; @@ -634,10 +634,10 @@ purple_notify_user_info_prepend_section_header(PurpleNotifyUserInfo *user_info, const char *label) { PurpleNotifyUserInfoEntry *entry; - + entry = purple_notify_user_info_entry_new(label, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER; - + user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry); } @@ -645,7 +645,7 @@ purple_notify_user_info_add_section_break(PurpleNotifyUserInfo *user_info) { PurpleNotifyUserInfoEntry *entry; - + entry = purple_notify_user_info_entry_new(NULL, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK; @@ -656,10 +656,10 @@ purple_notify_user_info_prepend_section_break(PurpleNotifyUserInfo *user_info) { PurpleNotifyUserInfoEntry *entry; - + entry = purple_notify_user_info_entry_new(NULL, NULL); entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK; - + user_info->user_info_entries = g_list_prepend(user_info->user_info_entries, entry); } diff -r 29f953732186 -r 8c8948b9f602 libpurple/notify.h --- a/libpurple/notify.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/notify.h Wed Jan 28 10:23:37 2009 +0000 @@ -291,6 +291,7 @@ */ void purple_notify_searchresults_row_add(PurpleNotifySearchResults *results, GList *row); + #if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) /** * Returns a number of the rows in the search results object. @@ -558,14 +559,21 @@ */ void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_NOTIFY_C_) /** * Remove a PurpleNotifyUserInfoEntry from a PurpleNotifyUserInfo object * without freeing the entry. * * @param user_info The PurpleNotifyUserInfo * @param user_info_entry The PurpleNotifyUserInfoEntry + * + * @deprecated Nothing is using this function and it should be removed + * in 3.0.0. Or, if we decide we want to keep it in 3.0.0 + * then we should make purple_notify_user_info_entry_destroy + * public so that entries can be free'd after they're removed. */ void purple_notify_user_info_remove_entry(PurpleNotifyUserInfo *user_info, PurpleNotifyUserInfoEntry *user_info_entry); +#endif /** * Create a new PurpleNotifyUserInfoEntry diff -r 29f953732186 -r 8c8948b9f602 libpurple/ntlm.h --- a/libpurple/ntlm.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/ntlm.h Wed Jan 28 10:23:37 2009 +0000 @@ -46,7 +46,7 @@ * * @param type2 String containing the base64 encoded type2 message * @param flags If not @c NULL, this will store the flags for the message - * + * * @return The nonce for use in message type3. This is a statically * allocated 8 byte binary string. */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugin.c --- a/libpurple/plugin.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugin.c Wed Jan 28 10:23:37 2009 +0000 @@ -218,7 +218,7 @@ g_free(basename); if (plugin != NULL) { - if (!strcmp(filename, plugin->path)) + if (purple_strequal(filename, plugin->path)) return plugin; else if (!purple_plugin_is_unloadable(plugin)) { @@ -357,7 +357,7 @@ return NULL; } else if (plugin->info->ui_requirement && - strcmp(plugin->info->ui_requirement, purple_core_get_ui())) + !purple_strequal(plugin->info->ui_requirement, purple_core_get_ui())) { plugin->error = g_strdup_printf(_("You are using %s, but this plugin requires %s."), purple_core_get_ui(), plugin->info->ui_requirement); @@ -1538,7 +1538,7 @@ for (l = plugins; l != NULL; l = l->next) { plugin = l->data; - if (!strcmp(plugin->info->name, name)) + if (purple_strequal(plugin->info->name, name)) return plugin; } @@ -1554,7 +1554,7 @@ for (l = plugins; l != NULL; l = l->next) { plugin = l->data; - if (plugin->path != NULL && !strcmp(plugin->path, filename)) + if (purple_strequal(plugin->path, filename)) return plugin; } @@ -1577,7 +1577,7 @@ if (plugin->path != NULL) { tmp = purple_plugin_get_basename(plugin->path); - if (!strcmp(tmp, basename)) + if (purple_strequal(tmp, basename)) { g_free(tmp); return plugin; @@ -1603,7 +1603,7 @@ { plugin = l->data; - if (plugin->info->id != NULL && !strcmp(plugin->info->id, id)) + if (purple_strequal(plugin->info->id, id)) return plugin; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugin.h --- a/libpurple/plugin.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugin.h Wed Jan 28 10:23:37 2009 +0000 @@ -183,7 +183,7 @@ /** NULL for plugin actions menu, set to the PurpleConnection for account actions menu */ gpointer context; - + gpointer user_data; }; @@ -358,7 +358,7 @@ * Returns a plugin's name. * * @param plugin The plugin. - * + * * @return THe name of the plugin, or @c NULL. */ const gchar *purple_plugin_get_name(const PurplePlugin *plugin); diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugins/Makefile.mingw --- a/libpurple/plugins/Makefile.mingw Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugins/Makefile.mingw Wed Jan 28 10:23:37 2009 +0000 @@ -1,7 +1,7 @@ # # Makefile.mingw # -# Description: Makefile for win32 (mingw) version of LibPurple Plugins +# Description: Makefile for win32 (mingw) version of libpurple Plugins # PIDGIN_TREE_TOP := ../.. diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugins/autoaccept.c --- a/libpurple/plugins/autoaccept.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugins/autoaccept.c Wed Jan 28 10:23:37 2009 +0000 @@ -95,7 +95,7 @@ char *dirname; account = xfer->account; - node = (PurpleBlistNode *)purple_find_buddy(account, xfer->who); + node = PURPLE_BLIST_NODE(purple_find_buddy(account, xfer->who)); if (!node) { diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugins/perl/common/BuddyList.xs --- a/libpurple/plugins/perl/common/BuddyList.xs Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugins/perl/common/BuddyList.xs Wed Jan 28 10:23:37 2009 +0000 @@ -363,9 +363,9 @@ PROTOTYPES: ENABLE Purple::BuddyList::Buddy -purple_buddy_new(account, screenname, alias) +purple_buddy_new(account, name, alias) Purple::Account account - const char *screenname + const char *name const char *alias const char * diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugins/perl/common/Request.xs --- a/libpurple/plugins/perl/common/Request.xs Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugins/perl/common/Request.xs Wed Jan 28 10:23:37 2009 +0000 @@ -211,10 +211,11 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_account_new(id, text, account = NULL) +purple_request_field_account_new(class, id, text, account = NULL) const char *id const char *text Purple::Account account + C_ARGS: id, text, account Purple::Account purple_request_field_account_get_default_value(field) @@ -255,10 +256,11 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_bool_new(id, text, default_value = TRUE) +purple_request_field_bool_new(class, id, text, default_value = TRUE) const char *id const char *text gboolean default_value + C_ARGS: id, text, default_value gboolean purple_request_field_bool_get_default_value(field) @@ -282,10 +284,11 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_choice_new(id, text, default_value = 0) +purple_request_field_choice_new(class, id, text, default_value = 0) const char *id const char *text int default_value + C_ARGS: id, text, default_value void purple_request_field_choice_add(field, label) @@ -324,10 +327,11 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_int_new(id, text, default_value = 0) +purple_request_field_int_new(clas, id, text, default_value = 0) const char *id const char *text int default_value + C_ARGS: id, text, default_value int purple_request_field_int_get_default_value(field) @@ -355,17 +359,19 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_label_new(id, text) +purple_request_field_label_new(class, id, text) const char *id const char *text + C_ARGS: id, text MODULE = Purple::Request PACKAGE = Purple::Request::Field PREFIX = purple_request_field_ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_list_new(id, text) +purple_request_field_list_new(class, id, text) const char *id const char *text + C_ARGS: id, text void purple_request_field_list_add(field, item, data) @@ -425,10 +431,11 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_new(id, text, type) +purple_request_field_new(class, id, text, type) const char *id const char *text Purple::RequestFieldType type + C_ARGS: id, text, type void purple_request_field_set_label(field, label) @@ -454,11 +461,12 @@ PROTOTYPES: ENABLE Purple::Request::Field -purple_request_field_string_new(id, text, default_value, multiline) +purple_request_field_string_new(class, id, text, default_value, multiline) const char *id const char *text const char *default_value gboolean multiline + C_ARGS: id, text, default_value, multiline const char * purple_request_field_string_get_default_value(field) @@ -527,8 +535,9 @@ Purple::Request::Field::Group group Purple::Request::Field::Group -purple_request_field_group_new(title) +purple_request_field_group_new(class, title) const char *title + C_ARGS: title MODULE = Purple::Request PACKAGE = Purple::Request::Field PREFIX = purple_request_field_ PROTOTYPES: ENABLE @@ -561,7 +570,8 @@ PROTOTYPES: ENABLE Purple::Request::Fields -purple_request_fields_new() +purple_request_fields_new(class) + C_ARGS: /* void */ void purple_request_fields_add_group(fields, group) diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugins/statenotify.c --- a/libpurple/plugins/statenotify.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugins/statenotify.c Wed Jan 28 10:23:37 2009 +0000 @@ -33,7 +33,7 @@ g_return_if_fail(conv->type == PURPLE_CONV_TYPE_IM); /* Prevent duplicate notifications for buddies in multiple groups */ - if (buddy != purple_find_buddy(buddy->account, buddy->name)) + if (buddy != purple_find_buddy(account, buddy_name)) return; who = purple_buddy_get_alias(buddy); diff -r 29f953732186 -r 8c8948b9f602 libpurple/plugins/tcl/tcl_cmds.c --- a/libpurple/plugins/tcl/tcl_cmds.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/plugins/tcl/tcl_cmds.c Wed Jan 28 10:23:37 2009 +0000 @@ -401,9 +401,9 @@ return NULL; if (!strcmp(type, "buddy")) { - node = (PurpleBlistNode *)purple_find_buddy(account, name); + node = PURPLE_BLIST_NODE(purple_find_buddy(account, name)); } else if (!strcmp(type, "group")) { - node = (PurpleBlistNode *)purple_blist_find_chat(account, name); + node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, name)); } return node; diff -r 29f953732186 -r 8c8948b9f602 libpurple/pounce.c --- a/libpurple/pounce.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/pounce.c Wed Jan 28 10:23:37 2009 +0000 @@ -326,7 +326,7 @@ data->buffer = NULL; } - if (!strcmp(element_name, "pounce")) { + if (purple_strequal(element_name, "pounce")) { const char *ui = g_hash_table_lookup(atts, "ui"); if (ui == NULL) { @@ -338,7 +338,7 @@ data->events = 0; } - else if (!strcmp(element_name, "account")) { + else if (purple_strequal(element_name, "account")) { const char *protocol_id = g_hash_table_lookup(atts, "protocol"); if (protocol_id == NULL) { @@ -348,7 +348,7 @@ else data->protocol_id = g_strdup(protocol_id); } - else if (!strcmp(element_name, "option")) { + else if (purple_strequal(element_name, "option")) { const char *type = g_hash_table_lookup(atts, "type"); if (type == NULL) { @@ -358,7 +358,7 @@ else data->option_type = g_strdup(type); } - else if (!strcmp(element_name, "event")) { + else if (purple_strequal(element_name, "event")) { const char *type = g_hash_table_lookup(atts, "type"); if (type == NULL) { @@ -368,7 +368,7 @@ else data->event_type = g_strdup(type); } - else if (!strcmp(element_name, "action")) { + else if (purple_strequal(element_name, "action")) { const char *type = g_hash_table_lookup(atts, "type"); if (type == NULL) { @@ -378,7 +378,7 @@ else data->action_name = g_strdup(type); } - else if (!strcmp(element_name, "param")) { + else if (purple_strequal(element_name, "param")) { const char *param_name = g_hash_table_lookup(atts, "name"); if (param_name == NULL) { @@ -404,7 +404,7 @@ data->buffer = NULL; } - if (!strcmp(element_name, "account")) { + if (purple_strequal(element_name, "account")) { char *tmp; g_free(data->account_name); data->account_name = g_strdup(buffer); @@ -412,43 +412,43 @@ data->protocol_id = g_strdup(_purple_oscar_convert(buffer, tmp)); g_free(tmp); } - else if (!strcmp(element_name, "pouncee")) { + else if (purple_strequal(element_name, "pouncee")) { g_free(data->pouncee); data->pouncee = g_strdup(buffer); } - else if (!strcmp(element_name, "option")) { - if (!strcmp(data->option_type, "on-away")) + else if (purple_strequal(element_name, "option")) { + if (purple_strequal(data->option_type, "on-away")) data->options |= PURPLE_POUNCE_OPTION_AWAY; g_free(data->option_type); data->option_type = NULL; } - else if (!strcmp(element_name, "event")) { - if (!strcmp(data->event_type, "sign-on")) + else if (purple_strequal(element_name, "event")) { + if (purple_strequal(data->event_type, "sign-on")) data->events |= PURPLE_POUNCE_SIGNON; - else if (!strcmp(data->event_type, "sign-off")) + else if (purple_strequal(data->event_type, "sign-off")) data->events |= PURPLE_POUNCE_SIGNOFF; - else if (!strcmp(data->event_type, "away")) + else if (purple_strequal(data->event_type, "away")) data->events |= PURPLE_POUNCE_AWAY; - else if (!strcmp(data->event_type, "return-from-away")) + else if (purple_strequal(data->event_type, "return-from-away")) data->events |= PURPLE_POUNCE_AWAY_RETURN; - else if (!strcmp(data->event_type, "idle")) + else if (purple_strequal(data->event_type, "idle")) data->events |= PURPLE_POUNCE_IDLE; - else if (!strcmp(data->event_type, "return-from-idle")) + else if (purple_strequal(data->event_type, "return-from-idle")) data->events |= PURPLE_POUNCE_IDLE_RETURN; - else if (!strcmp(data->event_type, "start-typing")) + else if (purple_strequal(data->event_type, "start-typing")) data->events |= PURPLE_POUNCE_TYPING; - else if (!strcmp(data->event_type, "typed")) + else if (purple_strequal(data->event_type, "typed")) data->events |= PURPLE_POUNCE_TYPED; - else if (!strcmp(data->event_type, "stop-typing")) + else if (purple_strequal(data->event_type, "stop-typing")) data->events |= PURPLE_POUNCE_TYPING_STOPPED; - else if (!strcmp(data->event_type, "message-received")) + else if (purple_strequal(data->event_type, "message-received")) data->events |= PURPLE_POUNCE_MESSAGE_RECEIVED; g_free(data->event_type); data->event_type = NULL; } - else if (!strcmp(element_name, "action")) { + else if (purple_strequal(element_name, "action")) { if (data->pounce != NULL) { purple_pounce_action_register(data->pounce, data->action_name); purple_pounce_action_set_enabled(data->pounce, data->action_name, TRUE); @@ -457,7 +457,7 @@ g_free(data->action_name); data->action_name = NULL; } - else if (!strcmp(element_name, "param")) { + else if (purple_strequal(element_name, "param")) { if (data->pounce != NULL) { purple_pounce_action_set_attribute(data->pounce, data->action_name, data->param_name, buffer); @@ -466,7 +466,7 @@ g_free(data->param_name); data->param_name = NULL; } - else if (!strcmp(element_name, "events")) { + else if (purple_strequal(element_name, "events")) { PurpleAccount *account; account = purple_accounts_find(data->account_name, data->protocol_id); @@ -499,11 +499,11 @@ g_free(data->pouncee); data->pouncee = NULL; } - else if (!strcmp(element_name, "save")) { + else if (purple_strequal(element_name, "save")) { if (data->pounce != NULL) purple_pounce_set_save(data->pounce, TRUE); } - else if (!strcmp(element_name, "pounce")) { + else if (purple_strequal(element_name, "pounce")) { data->pounce = NULL; data->events = 0; data->options = 0; @@ -1023,7 +1023,7 @@ for (iter = pounces; iter; iter = iter->next) { PurplePounce *pounce = iter->data; - if (pounce->ui_type && strcmp(pounce->ui_type, ui) == 0) + if (purple_strequal(pounce->ui_type, ui)) list = g_list_prepend(list, pounce); } list = g_list_reverse(list); @@ -1042,35 +1042,39 @@ static void buddy_state_cb(PurpleBuddy *buddy, PurplePounceEvent event) { - purple_pounce_execute(buddy->account, buddy->name, event); + PurpleAccount *account = purple_buddy_get_account(buddy); + const gchar *name = purple_buddy_get_name(buddy); + + purple_pounce_execute(account, name, event); } static void buddy_status_changed_cb(PurpleBuddy *buddy, PurpleStatus *old_status, PurpleStatus *status) { + PurpleAccount *account = purple_buddy_get_account(buddy); + const gchar *name = purple_buddy_get_name(buddy); gboolean old_available, available; available = purple_status_is_available(status); old_available = purple_status_is_available(old_status); if (available && !old_available) - purple_pounce_execute(buddy->account, buddy->name, - PURPLE_POUNCE_AWAY_RETURN); + purple_pounce_execute(account, name, PURPLE_POUNCE_AWAY_RETURN); else if (!available && old_available) - purple_pounce_execute(buddy->account, buddy->name, - PURPLE_POUNCE_AWAY); + purple_pounce_execute(account, name, PURPLE_POUNCE_AWAY); } static void buddy_idle_changed_cb(PurpleBuddy *buddy, gboolean old_idle, gboolean idle) { + PurpleAccount *account = purple_buddy_get_account(buddy); + const gchar *name = purple_buddy_get_name(buddy); + if (idle && !old_idle) - purple_pounce_execute(buddy->account, buddy->name, - PURPLE_POUNCE_IDLE); + purple_pounce_execute(account, name, PURPLE_POUNCE_IDLE); else if (!idle && old_idle) - purple_pounce_execute(buddy->account, buddy->name, - PURPLE_POUNCE_IDLE_RETURN); + purple_pounce_execute(account, name, PURPLE_POUNCE_IDLE_RETURN); } static void diff -r 29f953732186 -r 8c8948b9f602 libpurple/prefs.c --- a/libpurple/prefs.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/prefs.c Wed Jan 28 10:23:37 2009 +0000 @@ -250,33 +250,34 @@ GString *pref_name_full; GList *tmp; - if(strcmp(element_name, "pref") && strcmp(element_name, "item")) + if(!purple_strequal(element_name, "pref") && + !purple_strequal(element_name, "item")) return; for(i = 0; attribute_names[i]; i++) { - if(!strcmp(attribute_names[i], "name")) { + if(purple_strequal(attribute_names[i], "name")) { pref_name = attribute_values[i]; - } else if(!strcmp(attribute_names[i], "type")) { - if(!strcmp(attribute_values[i], "bool")) + } else if(purple_strequal(attribute_names[i], "type")) { + if(purple_strequal(attribute_values[i], "bool")) pref_type = PURPLE_PREF_BOOLEAN; - else if(!strcmp(attribute_values[i], "int")) + else if(purple_strequal(attribute_values[i], "int")) pref_type = PURPLE_PREF_INT; - else if(!strcmp(attribute_values[i], "string")) + else if(purple_strequal(attribute_values[i], "string")) pref_type = PURPLE_PREF_STRING; - else if(!strcmp(attribute_values[i], "stringlist")) + else if(purple_strequal(attribute_values[i], "stringlist")) pref_type = PURPLE_PREF_STRING_LIST; - else if(!strcmp(attribute_values[i], "path")) + else if(purple_strequal(attribute_values[i], "path")) pref_type = PURPLE_PREF_PATH; - else if(!strcmp(attribute_values[i], "pathlist")) + else if(purple_strequal(attribute_values[i], "pathlist")) pref_type = PURPLE_PREF_PATH_LIST; else return; - } else if(!strcmp(attribute_names[i], "value")) { + } else if(purple_strequal(attribute_names[i], "value")) { pref_value = attribute_values[i]; } } - if(!strcmp(element_name, "item")) { + if(purple_strequal(element_name, "item")) { struct purple_pref *pref; pref_name_full = g_string_new(""); @@ -301,7 +302,7 @@ } else { char *decoded; - if(!pref_name || !strcmp(pref_name, "/")) + if(!pref_name || purple_strequal(pref_name, "/")) return; pref_name_full = g_string_new(pref_name); @@ -352,7 +353,7 @@ const gchar *element_name, gpointer user_data, GError **error) { - if(prefs_stack && !strcmp(element_name, "pref")) { + if(prefs_stack && purple_strequal(element_name, "pref")) { g_free(prefs_stack->data); prefs_stack = g_list_delete_link(prefs_stack, prefs_stack); } @@ -521,7 +522,7 @@ char *parent_name = get_path_dirname(name); struct purple_pref *ret = &prefs; - if(strcmp(parent_name, "/")) { + if(!purple_strequal(parent_name, "/")) { ret = find_pref(parent_name); } @@ -571,7 +572,7 @@ my_name = get_path_basename(name); for(sibling = parent->first_child; sibling; sibling = sibling->sibling) { - if(!strcmp(sibling->name, my_name)) { + if(purple_strequal(sibling->name, my_name)) { g_free(my_name); return NULL; } @@ -849,10 +850,7 @@ return; } - if((value && !pref->value.string) || - (!value && pref->value.string) || - (value && pref->value.string && - strcmp(pref->value.string, value))) { + if (!purple_strequal(pref->value.string, value)) { g_free(pref->value.string); pref->value.string = g_strdup(value); do_callbacks(name, pref); @@ -909,10 +907,7 @@ return; } - if((value && !pref->value.string) || - (!value && pref->value.string) || - (value && pref->value.string && - strcmp(pref->value.string, value))) { + if (!purple_strequal(pref->value.string, value)) { g_free(pref->value.string); pref->value.string = g_strdup(value); do_callbacks(name, pref); @@ -1106,7 +1101,7 @@ next = child->sibling; for(newchild = newpref->first_child; newchild != NULL; newchild = newchild->sibling) { - if(!strcmp(child->name, newchild->name)) + if(purple_strequal(child->name, newchild->name)) { purple_prefs_rename_node(child, newchild); break; diff -r 29f953732186 -r 8c8948b9f602 libpurple/prefs.h --- a/libpurple/prefs.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/prefs.h Wed Jan 28 10:23:37 2009 +0000 @@ -67,8 +67,8 @@ #endif /**************************************************************************/ -/** @name Prefs API - Preferences are named according to a directory-like structure. +/** @name Prefs API + Preferences are named according to a directory-like structure. Example: "/plugins/core/potato/is_from_idaho" (probably a boolean) */ /**************************************************************************/ /*@{*/ diff -r 29f953732186 -r 8c8948b9f602 libpurple/privacy.c --- a/libpurple/privacy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/privacy.c Wed Jan 28 10:23:37 2009 +0000 @@ -224,8 +224,10 @@ while (list != NULL) { PurpleBuddy *buddy = list->data; - if (!g_slist_find_custom(account->permit, buddy->name, (GCompareFunc)g_utf8_collate)) - purple_privacy_permit_add(account, buddy->name, local); + const gchar *name = purple_buddy_get_name(buddy); + + if (!g_slist_find_custom(account->permit, name, (GCompareFunc)g_utf8_collate)) + purple_privacy_permit_add(account, name, local); list = g_slist_delete_link(list, list); } } @@ -259,7 +261,7 @@ for (list = account->permit; list != NULL;) { char *person = list->data; list = list->next; - if (strcmp(norm, person) != 0) + if (!purple_strequal(norm, person)) purple_privacy_permit_remove(account, person, local); } } @@ -303,7 +305,7 @@ for (list = account->deny; list != NULL; ) { char *person = list->data; list = list->next; - if (strcmp(norm, person) != 0) + if (!purple_strequal(norm, person)) purple_privacy_deny_remove(account, person, local); } } diff -r 29f953732186 -r 8c8948b9f602 libpurple/privacy.h --- a/libpurple/privacy.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/privacy.h Wed Jan 28 10:23:37 2009 +0000 @@ -125,7 +125,7 @@ * changed to PURPLE_PRIVACY_ALLOW_USERS, all the * buddies are added to the allow-list, and the * user is also added to the allow-list. - * + * * @param account The account. * @param who The name of the user. * @param local Whether the change is local-only. diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/Makefile.mingw --- a/libpurple/protocols/Makefile.mingw Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/Makefile.mingw Wed Jan 28 10:23:37 2009 +0000 @@ -2,7 +2,7 @@ # # Author: hermanator12002@yahoo.com # Date 9/11/02 -# Description: Protocols Makefile for win32 (mingw) port of LibPurple +# Description: Protocols Makefile for win32 (mingw) port of libpurple # PIDGIN_TREE_TOP := ../.. diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/bonjour/bonjour.c --- a/libpurple/protocols/bonjour/bonjour.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Wed Jan 28 10:23:37 2009 +0000 @@ -261,9 +261,10 @@ static void bonjour_remove_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group) { - if (buddy->proto_data) { - bonjour_buddy_delete(buddy->proto_data); - buddy->proto_data = NULL; + BonjourBuddy *bb = purple_buddy_get_protocol_data(buddy); + if (bb) { + bonjour_buddy_delete(bb); + purple_buddy_set_protocol_data(buddy, NULL); } } @@ -303,7 +304,7 @@ PurpleBuddy *buddy = purple_find_buddy(connection->account, who); BonjourBuddy *bb; - if (buddy == NULL || buddy->proto_data == NULL) + if (buddy == NULL || (bb = purple_buddy_get_protocol_data(buddy)) == NULL) { /* * This buddy is not in our buddy list, and therefore does not really @@ -312,7 +313,6 @@ return; } - bb = buddy->proto_data; bonjour_jabber_close_conversation(bb->conversation); bb->conversation = NULL; } @@ -351,7 +351,7 @@ { PurplePresence *presence; PurpleStatus *status; - BonjourBuddy *bb = buddy->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(buddy); const char *status_description; const char *message; @@ -417,8 +417,7 @@ { PurpleBuddy *buddy = purple_find_buddy(connection->account, who); - return (buddy != NULL && buddy->proto_data != NULL); - + return (buddy != NULL && purple_buddy_get_protocol_data(buddy) != NULL); } static gboolean diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/bonjour/bonjour_ft.c --- a/libpurple/protocols/bonjour/bonjour_ft.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/bonjour/bonjour_ft.c Wed Jan 28 10:23:37 2009 +0000 @@ -386,10 +386,9 @@ buddy = purple_find_buddy(xfer->account, xfer->who); /* this buddy is offline. */ - if (buddy == NULL || buddy->proto_data == NULL) + if (buddy == NULL || (bb = purple_buddy_get_protocol_data(buddy)) == NULL) return; - bb = (BonjourBuddy *)buddy->proto_data; /* Assume it is the first IP. We could do something like keep track of which one is in use or something. */ if (bb->ips) xf->buddy_ip = g_strdup(bb->ips->data); @@ -410,6 +409,7 @@ const char *type, *id; BonjourData *bd; PurpleXfer *xfer; + const gchar *name = NULL; g_return_if_fail(pc != NULL); g_return_if_fail(packet != NULL); @@ -421,6 +421,8 @@ purple_debug_info("bonjour", "xep-si-parse.\n"); + name = purple_buddy_get_name(pb); + type = xmlnode_get_attrib(packet, "type"); id = xmlnode_get_attrib(packet, "id"); if(type) { @@ -448,31 +450,34 @@ /* TODO: Make sure that it is advertising a bytestreams transfer */ - bonjour_xfer_receive(pc, id, sid, pb->name, filesize, filename, XEP_BYTESTREAMS); + bonjour_xfer_receive(pc, id, sid, name, filesize, filename, XEP_BYTESTREAMS); parsed_receive = TRUE; } if (!parsed_receive) { + BonjourData *bd = purple_connection_get_protocol_data(pc); + purple_debug_info("bonjour", "rejecting unrecognized si SET offer.\n"); - xep_ft_si_reject((BonjourData *)pc->proto_data, id, pb->name, "403", "cancel"); + xep_ft_si_reject(bd, id, name, "403", "cancel"); /*TODO: Send Cancel (501) */ } } else if(!strcmp(type, "result")) { purple_debug_info("bonjour", "si offer Message type - RESULT.\n"); - xfer = bonjour_si_xfer_find(bd, id, pb->name); + xfer = bonjour_si_xfer_find(bd, id, name); if(xfer == NULL) { + BonjourData *bd = purple_connection_get_protocol_data(pc); purple_debug_info("bonjour", "xfer find fail.\n"); - xep_ft_si_reject((BonjourData *)pc->proto_data, id, pb->name, "403", "cancel"); + xep_ft_si_reject(bd, id, name, "403", "cancel"); } else bonjour_bytestreams_init(xfer); } else if(!strcmp(type, "error")) { purple_debug_info("bonjour", "si offer Message type - ERROR.\n"); - xfer = bonjour_si_xfer_find(bd, id, pb->name); + xfer = bonjour_si_xfer_find(bd, id, name); if(xfer == NULL) purple_debug_info("bonjour", "xfer find fail.\n"); @@ -501,7 +506,7 @@ purple_debug_info("bonjour", "xep-bytestreams-parse.\n"); type = xmlnode_get_attrib(packet, "type"); - from = pb->name; + from = purple_buddy_get_name(pb); query = xmlnode_get_child(packet,"query"); if(type) { if(!strcmp(type, "set")) { @@ -841,8 +846,10 @@ static void bonjour_bytestreams_connect(PurpleXfer *xfer, PurpleBuddy *pb) { + PurpleAccount *account = NULL; XepXfer *xf; char dstaddr[41]; + const gchar *name = NULL; unsigned char hashval[20]; char *p; int i; @@ -856,7 +863,10 @@ if(!xf) return; - p = g_strdup_printf("%s%s%s", xf->sid, pb->name, purple_account_get_username(pb->account)); + name = purple_buddy_get_name(pb); + account = purple_buddy_get_account(pb); + + p = g_strdup_printf("%s%s%s", xf->sid, name, purple_account_get_username(account)); purple_cipher_digest_region("sha1", (guchar *)p, strlen(p), sizeof(hashval), hashval, NULL); g_free(p); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/bonjour/buddy.c --- a/libpurple/protocols/bonjour/buddy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/bonjour/buddy.c Wed Jan 28 10:23:37 2009 +0000 @@ -157,8 +157,8 @@ purple_blist_add_buddy(buddy, NULL, group, NULL); } - buddy->proto_data = bonjour_buddy; name = purple_buddy_get_name(buddy); + purple_buddy_set_protocol_data(buddy, bonjour_buddy); /* Create the alias for the buddy using the first and the last name */ if (bonjour_buddy->nick && *bonjour_buddy->nick) @@ -210,8 +210,8 @@ if (PURPLE_BLIST_NODE_SHOULD_SAVE(pb)) { purple_prpl_got_user_status(purple_buddy_get_account(pb), purple_buddy_get_name(pb), "offline", NULL); - bonjour_buddy_delete(pb->proto_data); - pb->proto_data = NULL; + bonjour_buddy_delete(purple_buddy_get_protocol_data(pb)); + purple_buddy_set_protocol_data(pb, NULL); } else { purple_account_remove_buddy(purple_buddy_get_account(pb), pb, NULL); purple_blist_remove_buddy(pb); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/bonjour/jabber.c --- a/libpurple/protocols/bonjour/jabber.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Wed Jan 28 10:23:37 2009 +0000 @@ -240,17 +240,21 @@ _match_buddies_by_address(gpointer key, gpointer value, gpointer data) { PurpleBuddy *pb = value; + PurpleAccount *account = NULL; + BonjourBuddy *bb = NULL; struct _match_buddies_by_address_t *mbba = data; + account = purple_buddy_get_account(pb); + bb = purple_buddy_get_protocol_data(pb); + /* * If the current PurpleBuddy's data is not null and the PurpleBuddy's account * is the same as the account requesting the check then continue to determine * whether one of the buddies IPs matches the target IP. */ - if (mbba->jdata->account == pb->account && pb->proto_data != NULL) + if (mbba->jdata->account == account && bb != NULL) { const char *ip; - BonjourBuddy *bb = pb->proto_data; GSList *tmp = bb->ips; while(tmp) { @@ -268,7 +272,7 @@ _send_data_write_cb(gpointer data, gint source, PurpleInputCondition cond) { PurpleBuddy *pb = data; - BonjourBuddy *bb = pb->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(pb); BonjourJabberConversation *bconv = bb->conversation; int ret, writelen; @@ -285,13 +289,16 @@ if (ret < 0 && errno == EAGAIN) return; else if (ret <= 0) { - PurpleConversation *conv; + PurpleConversation *conv = NULL; + PurpleAccount *account = NULL; const char *error = g_strerror(errno); purple_debug_error("bonjour", "Error sending message to buddy %s error: %s\n", purple_buddy_get_name(pb), error ? error : "(null)"); - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, pb->account); + account = purple_buddy_get_account(pb); + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account); if (conv != NULL) purple_conversation_write(conv, NULL, _("Unable to send message."), @@ -310,7 +317,7 @@ { gint ret; int len = strlen(message); - BonjourBuddy *bb = pb->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(pb); BonjourJabberConversation *bconv = bb->conversation; /* If we're not ready to actually send, append it to the buffer */ @@ -329,12 +336,15 @@ ret = 0; else if (ret <= 0) { PurpleConversation *conv; + PurpleAccount *account; const char *error = g_strerror(errno); purple_debug_error("bonjour", "Error sending message to buddy %s error: %s\n", purple_buddy_get_name(pb), error ? error : "(null)"); - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, pb->account); + account = purple_buddy_get_account(pb); + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account); if (conv != NULL) purple_conversation_write(conv, NULL, _("Unable to send message."), @@ -373,11 +383,12 @@ /* Inform the user that the conversation has been closed */ BonjourBuddy *bb = NULL; + const gchar *name = bconv->pb ? purple_buddy_get_name(bconv->pb) : "(unknown)"; - purple_debug_info("bonjour", "Recieved conversation close notification from %s.\n", bconv->pb ? bconv->pb->name : "(unknown)"); + purple_debug_info("bonjour", "Recieved conversation close notification from %s.\n", name); if(bconv->pb != NULL) - bb = bconv->pb->proto_data; + bb = purple_buddy_get_protocol_data(bconv->pb); #if 0 if(bconv->pb != NULL) { PurpleConversation *conv; @@ -411,9 +422,11 @@ purple_debug_warning("bonjour", "receive error: %s\n", err ? err : "(null)"); bonjour_jabber_close_conversation(bconv); - if (bconv->pb != NULL && bconv->pb->proto_data != NULL) { - BonjourBuddy *bb = bconv->pb->proto_data; - bb->conversation = NULL; + if (bconv->pb != NULL) { + BonjourBuddy *bb = purple_buddy_get_protocol_data(bconv->pb); + + if(bb != NULL) + bb->conversation = NULL; } /* I guess we really don't need to notify the user. @@ -421,7 +434,8 @@ } return; } else if (len == 0) { /* The other end has closed the socket */ - purple_debug_warning("bonjour", "Connection closed (without stream end) by %s.\n", (bconv->pb && bconv->pb->name) ? bconv->pb->name : "(unknown)"); + const gchar *name = purple_buddy_get_name(bconv->pb); + purple_debug_warning("bonjour", "Connection closed (without stream end) by %s.\n", (name) ? name : "(unknown)"); bonjour_jabber_stream_ended(bconv); return; } else { @@ -465,7 +479,7 @@ BonjourBuddy *bb = NULL; if(bconv->pb) { - bb = bconv->pb->proto_data; + bb = purple_buddy_get_protocol_data(bconv->pb); bname = purple_buddy_get_name(bconv->pb); } @@ -644,7 +658,7 @@ mbba = g_new0(struct _match_buddies_by_address_t, 1); mbba->address = address_text; mbba->jdata = jdata; - g_hash_table_foreach(purple_get_blist()->buddies, _match_buddies_by_address, mbba); + g_hash_table_foreach(purple_blist_get_buddies(), _match_buddies_by_address, mbba); if (mbba->matched_buddies == NULL) { purple_debug_info("bonjour", "We don't like invisible buddies, this is not a superheros comic\n"); @@ -743,17 +757,20 @@ _connected_to_buddy(gpointer data, gint source, const gchar *error) { PurpleBuddy *pb = data; - BonjourBuddy *bb = pb->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(pb); bb->conversation->connect_data = NULL; if (source < 0) { - PurpleConversation *conv; + PurpleConversation *conv = NULL; + PurpleAccount *account = NULL; purple_debug_error("bonjour", "Error connecting to buddy %s at %s:%d error: %s\n", purple_buddy_get_name(pb), bb->conversation->ip, bb->port_p2pj, error ? error : "(null)"); - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, pb->account); + account = purple_buddy_get_account(pb); + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account); if (conv != NULL) purple_conversation_write(conv, NULL, _("Unable to send the message, the conversation couldn't be started."), @@ -766,12 +783,15 @@ if (!bonjour_jabber_send_stream_init(bb->conversation, source)) { const char *err = g_strerror(errno); - PurpleConversation *conv; + PurpleConversation *conv = NULL; + PurpleAccount *account = NULL; purple_debug_error("bonjour", "Error starting stream with buddy %s at %s:%d error: %s\n", purple_buddy_get_name(pb), bb->conversation->ip, bb->port_p2pj, err ? err : "(null)"); - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, pb->account); + account = purple_buddy_get_account(pb); + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, account); if (conv != NULL) purple_conversation_write(conv, NULL, _("Unable to send the message, the conversation couldn't be started."), @@ -791,14 +811,14 @@ void bonjour_jabber_conv_match_by_name(BonjourJabberConversation *bconv) { - PurpleBuddy *pb; + PurpleBuddy *pb = NULL; + BonjourBuddy *bb = NULL; g_return_if_fail(bconv->ip != NULL); g_return_if_fail(bconv->pb == NULL); pb = purple_find_buddy(bconv->account, bconv->buddy_name); - if (pb && pb->proto_data) { - BonjourBuddy *bb = pb->proto_data; + if (pb && (bb = purple_buddy_get_protocol_data(pb))) { const char *ip; GSList *tmp = bb->ips; @@ -848,7 +868,7 @@ mbba = g_new0(struct _match_buddies_by_address_t, 1); mbba->address = bconv->ip; mbba->jdata = jdata; - g_hash_table_foreach(purple_get_blist()->buddies, _match_buddies_by_address, mbba); + g_hash_table_foreach(purple_blist_get_buddies(), _match_buddies_by_address, mbba); /* If there is exactly one match, use it */ if(mbba->matched_buddies != NULL) { @@ -856,7 +876,7 @@ purple_debug_error("bonjour", "More than one buddy matched for ip %s.\n", bconv->ip); else { PurpleBuddy *pb = mbba->matched_buddies->data; - BonjourBuddy *bb = pb->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(pb); purple_debug_info("bonjour", "Matched buddy %s to incoming conversation using IP (%s)\n", purple_buddy_get_name(pb), bconv->ip); @@ -896,12 +916,10 @@ g_return_val_if_fail(to != NULL, NULL); pb = purple_find_buddy(jdata->account, to); - if (pb == NULL || pb->proto_data == NULL) + if (pb == NULL || (bb = purple_buddy_get_protocol_data(pb)) == NULL) /* You can not send a message to an offline buddy */ return NULL; - bb = (BonjourBuddy *) pb->proto_data; - /* Check if there is a previously open conversation */ if (bb->conversation == NULL) { @@ -948,7 +966,7 @@ int ret; pb = _find_or_start_conversation(jdata, to); - if (pb == NULL || pb->proto_data == NULL) { + if (pb == NULL || (bb = purple_buddy_get_protocol_data(pb)) == NULL) { purple_debug_info("bonjour", "Can't send a message to an offline buddy (%s).\n", to); /* You can not send a message to an offline buddy */ return -10000; @@ -956,8 +974,6 @@ purple_markup_html_to_xhtml(body, &xhtml, &message); - bb = pb->proto_data; - message_node = xmlnode_new("message"); xmlnode_set_attrib(message_node, "to", bb->name); xmlnode_set_attrib(message_node, "from", purple_account_get_username(jdata->account)); @@ -1007,7 +1023,7 @@ /* Disconnect this conv. from the buddy here so it can't be disposed of twice.*/ if(bconv->pb != NULL) { - BonjourBuddy *bb = bconv->pb->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(bconv->pb); if (bb->conversation == bconv) bb->conversation = NULL; } @@ -1036,7 +1052,7 @@ tmp_next = xfers->next; /* We only need to cancel this if it hasn't actually started transferring. */ /* This will change if we ever support IBB transfers. */ - if (strcmp(xfer->who, bconv->pb->name) == 0 + if (strcmp(xfer->who, purple_buddy_get_name(bconv->pb)) == 0 && (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_NOT_STARTED || purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_UNKNOWN)) { purple_xfer_cancel_remote(xfer); @@ -1095,7 +1111,7 @@ buddies = purple_find_buddies(jdata->account, NULL); for (l = buddies; l; l = l->next) { - BonjourBuddy *bb = ((PurpleBuddy*) l->data)->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data((PurpleBuddy*) l->data); if (bb != NULL) { bonjour_jabber_close_conversation(bb->conversation); bb->conversation = NULL; @@ -1158,15 +1174,20 @@ check_if_blocked(PurpleBuddy *pb) { gboolean blocked = FALSE; - GSList *l; + GSList *l = NULL; PurpleAccount *acc = purple_buddy_get_account(pb); if(acc == NULL) return FALSE; + acc = purple_buddy_get_account(pb); + for(l = acc->deny; l != NULL; l = l->next) { - if(!purple_utf8_strcasecmp(pb->name, (char *)l->data)) { - purple_debug_info("bonjour", "%s has been blocked by %s.\n", pb->name, acc->username); + const gchar *name = purple_buddy_get_name(pb); + const gchar *username = purple_account_get_username(acc); + + if(!purple_utf8_strcasecmp(name, (char *)l->data)) { + purple_debug_info("bonjour", "%s has been blocked by %s.\n", name, username); blocked = TRUE; break; } @@ -1178,16 +1199,19 @@ xep_iq_parse(xmlnode *packet, PurpleBuddy *pb) { xmlnode *child; + PurpleAccount *account; + PurpleConnection *gc; if(check_if_blocked(pb)) return; + account = purple_buddy_get_account(pb); + gc = purple_account_get_connection(account); + if ((child = xmlnode_get_child(packet, "si")) || (child = xmlnode_get_child(packet, "error"))) - xep_si_parse(purple_account_get_connection(pb->account), - packet, pb); + xep_si_parse(gc, packet, pb); else - xep_bytestreams_parse(purple_account_get_connection(pb->account), - packet, pb); + xep_bytestreams_parse(gc, packet, pb); } int diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/bonjour/mdns_avahi.c --- a/libpurple/protocols/bonjour/mdns_avahi.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/bonjour/mdns_avahi.c Wed Jan 28 10:23:37 2009 +0000 @@ -124,7 +124,7 @@ g_return_if_fail(r != NULL); pb = purple_find_buddy(account, name); - bb = (pb != NULL) ? pb->proto_data : NULL; + bb = (pb != NULL) ? purple_buddy_get_protocol_data(pb) : NULL; switch (event) { case AVAHI_RESOLVER_FAILURE: @@ -252,7 +252,7 @@ purple_debug_info("bonjour", "_browser_callback - Remove service\n"); pb = purple_find_buddy(account, name); if (pb != NULL) { - BonjourBuddy *bb = pb->proto_data; + BonjourBuddy *bb = purple_buddy_get_protocol_data(pb); AvahiBuddyImplData *b_impl; GSList *l; AvahiSvcResolverData *rd_search; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/gg/buddylist.c --- a/libpurple/protocols/gg/buddylist.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/gg/buddylist.c Wed Jan 28 10:23:37 2009 +0000 @@ -41,37 +41,46 @@ GGPInfo *info = gc->proto_data; PurpleAccount *account = purple_connection_get_account(gc); - PurpleBuddyList *blist; PurpleBlistNode *gnode, *cnode, *bnode; PurpleBuddy *buddy; uin_t *userlist = NULL; gchar *types = NULL; int size = 0, ret = 0; - if ((blist = purple_get_blist()) == NULL) - return; - - for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); + gnode != NULL; + gnode = purple_blist_node_get_sibling_next(gnode)) + { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode != NULL; + cnode = purple_blist_node_get_sibling_next(cnode)) + { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) + { + const gchar *name = NULL; + if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; buddy = (PurpleBuddy *)bnode; - if (buddy->account != account) + if (purple_buddy_get_account(buddy) != account) continue; + name = purple_buddy_get_name(buddy); + size++; userlist = (uin_t *) g_renew(uin_t, userlist, size); types = (gchar *) g_renew(gchar, types, size); - userlist[size - 1] = ggp_str_to_uin(buddy->name); + userlist[size - 1] = ggp_str_to_uin(name); types[size - 1] = GG_USER_NORMAL; purple_debug_info("gg", "ggp_buddylist_send: adding %d\n", userlist[size - 1]); @@ -173,36 +182,45 @@ void ggp_buddylist_offline(PurpleConnection *gc) { PurpleAccount *account = purple_connection_get_account(gc); - PurpleBuddyList *blist; PurpleBlistNode *gnode, *cnode, *bnode; PurpleBuddy *buddy; - if ((blist = purple_get_blist()) == NULL) - return; - - for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); + gnode != NULL; + gnode = purple_blist_node_get_sibling_next(gnode)) + { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode != NULL; + cnode = purple_blist_node_get_sibling_next(cnode)) + { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) + { + const gchar *name = NULL; + if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; buddy = (PurpleBuddy *)bnode; + + name = purple_buddy_get_name(buddy); - if (buddy->account != account) + if (purple_buddy_get_account(buddy) != account) continue; purple_prpl_got_user_status( - account, buddy->name, "offline", NULL); + account, name, "offline", NULL); purple_debug_info("gg", "ggp_buddylist_offline: gone: %s\n", - buddy->name); + name); } } } @@ -212,41 +230,46 @@ /* char *ggp_buddylist_dump(PurpleAccount *account) {{{ */ char *ggp_buddylist_dump(PurpleAccount *account) { - PurpleBuddyList *blist; PurpleBlistNode *gnode, *cnode, *bnode; PurpleGroup *group; PurpleBuddy *buddy; - GString *buddylist; + GString *buddylist = g_string_sized_new(1024); char *ptr; - if ((blist = purple_get_blist()) == NULL) - return NULL; - - buddylist = g_string_sized_new(1024); - - for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); + gnode != NULL; + gnode = purple_blist_node_get_sibling_next(gnode)) + { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; group = (PurpleGroup *)gnode; - for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode != NULL; + cnode = purple_blist_node_get_sibling_next(cnode)) + { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) { - gchar *name, *alias, *gname; + for (bnode = purple_blist_node_get_first_child(cnode); + bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) + { + const gchar *name, *alias, *gname; if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; buddy = (PurpleBuddy *)bnode; - if (buddy->account != account) + if (purple_buddy_get_account(buddy) != account) continue; - name = buddy->name; - alias = buddy->alias ? buddy->alias : buddy->name; - gname = group->name; + name = purple_buddy_get_name(buddy); + alias = purple_buddy_get_alias(buddy); + if(alias == NULL) + alias = name; + gname = purple_group_get_name(group); g_string_append_printf(buddylist, "%s;%s;%s;%s;%s;%s;%s;%s%s\r\n", diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/gg/gg.c --- a/libpurple/protocols/gg/gg.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/gg/gg.c Wed Jan 28 10:23:37 2009 +0000 @@ -2052,11 +2052,12 @@ { PurpleAccount *account; GGPInfo *info = gc->proto_data; + const gchar *name = purple_buddy_get_name(buddy); - gg_add_notify(info->session, ggp_str_to_uin(buddy->name)); + gg_add_notify(info->session, ggp_str_to_uin(name)); account = purple_connection_get_account(gc); - if (strcmp(purple_account_get_username(account), buddy->name) == 0) { + if (strcmp(purple_account_get_username(account), name) == 0) { ggp_status_fake_to_self(account); } } @@ -2066,7 +2067,7 @@ { GGPInfo *info = gc->proto_data; - gg_remove_notify(info->session, ggp_str_to_uin(buddy->name)); + gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy))); } static void ggp_join_chat(PurpleConnection *gc, GHashTable *data) diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/irc/irc.c --- a/libpurple/protocols/irc/irc.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/irc/irc.c Wed Jan 28 10:23:37 2009 +0000 @@ -564,7 +564,7 @@ { struct irc_conn *irc = (struct irc_conn *)gc->proto_data; struct irc_buddy *ib = g_new0(struct irc_buddy, 1); - ib->name = g_strdup(buddy->name); + ib->name = g_strdup(purple_buddy_get_name(buddy)); g_hash_table_insert(irc->buddies, ib->name, ib); /* if the timer isn't set, this is during signon, so we don't want to flood @@ -577,7 +577,7 @@ static void irc_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { struct irc_conn *irc = (struct irc_conn *)gc->proto_data; - g_hash_table_remove(irc->buddies, buddy->name); + g_hash_table_remove(irc->buddies, purple_buddy_get_name(buddy)); } static void read_input(struct irc_conn *irc, int len) diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/irc/msgs.c --- a/libpurple/protocols/irc/msgs.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/irc/msgs.c Wed Jan 28 10:23:37 2009 +0000 @@ -79,6 +79,7 @@ PurpleConnection *gc; PurpleStatus *status; PurpleBlistNode *gnode, *cnode, *bnode; + PurpleAccount *account; if ((gc = purple_account_get_connection(irc->account)) == NULL || PURPLE_CONNECTION_IS_CONNECTED(gc)) @@ -86,6 +87,7 @@ purple_connection_set_display_name(gc, nick); purple_connection_set_state(gc, PURPLE_CONNECTED); + account = purple_connection_get_account(gc); /* If we're away then set our away message */ status = purple_account_get_active_status(irc->account); @@ -95,20 +97,29 @@ } /* this used to be in the core, but it's not now */ - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); + gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) + { if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) + { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for(bnode = cnode->child; bnode; bnode = bnode->next) { + for(bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) + { PurpleBuddy *b; if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *)bnode; - if(b->account == gc->account) { + if(purple_buddy_get_account(b) == account) { struct irc_buddy *ib = g_new0(struct irc_buddy, 1); - ib->name = g_strdup(b->name); + ib->name = g_strdup(purple_buddy_get_name(b)); g_hash_table_insert(irc->buddies, ib->name, ib); } } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/jabber/adhoccommands.c --- a/libpurple/protocols/jabber/adhoccommands.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/jabber/adhoccommands.c Wed Jan 28 10:23:37 2009 +0000 @@ -211,8 +211,9 @@ if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { JabberAdHocCommands *cmd = data; PurpleBuddy *buddy = (PurpleBuddy *) node; - JabberStream *js = purple_account_get_connection(buddy->account)->proto_data; - + PurpleAccount *account = purple_buddy_get_account(buddy); + JabberStream *js = purple_account_get_connection(account)->proto_data; + jabber_adhoc_execute(js, cmd); } } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/jabber/buddy.c Wed Jan 28 10:23:37 2009 +0000 @@ -422,7 +422,7 @@ { PurpleStoredImage *img; JabberIq *iq; - JabberStream *js = gc->proto_data; + JabberStream *js = purple_connection_get_protocol_data(gc); xmlnode *vc_node; const struct tag_attr *tag_attr; @@ -496,7 +496,7 @@ PurplePresence *gpresence; PurpleStatus *status; - if(((JabberStream*)gc->proto_data)->pep) { + if(((JabberStream*)purple_connection_get_protocol_data(gc))->pep) { /* XEP-0084: User Avatars */ if(img) { /* @@ -558,7 +558,7 @@ g_free(base64avatar); /* publish the avatar itself */ - jabber_pep_publish((JabberStream*)gc->proto_data, publish); + jabber_pep_publish((JabberStream*)purple_connection_get_protocol_data(gc), publish); /* next step: publish the metadata */ publish = xmlnode_new("publish"); @@ -584,7 +584,7 @@ g_free(heightstring); /* publish the metadata */ - jabber_pep_publish((JabberStream*)gc->proto_data, publish); + jabber_pep_publish((JabberStream*)purple_connection_get_protocol_data(gc), publish); g_free(hash); } else { @@ -1780,7 +1780,7 @@ void jabber_buddy_get_info(PurpleConnection *gc, const char *who) { - JabberStream *js = gc->proto_data; + JabberStream *js = purple_connection_get_protocol_data(gc); JabberID *jid = jabber_id_new(who); if (!jid) @@ -1840,10 +1840,10 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - js = gc->proto_data; + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + js = purple_connection_get_protocol_data(gc); - jabber_buddy_set_invisibility(js, buddy->name, TRUE); + jabber_buddy_set_invisibility(js, purple_buddy_get_name(buddy), TRUE); } static void jabber_buddy_make_visible(PurpleBlistNode *node, gpointer data) @@ -1855,10 +1855,10 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - js = gc->proto_data; + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + js = purple_connection_get_protocol_data(gc); - jabber_buddy_set_invisibility(js, buddy->name, FALSE); + jabber_buddy_set_invisibility(js, purple_buddy_get_name(buddy), FALSE); } static void jabber_buddy_cancel_presence_notification(PurpleBlistNode *node, @@ -1871,11 +1871,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - js = gc->proto_data; + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + js = purple_connection_get_protocol_data(gc); /* I wonder if we should prompt the user before doing this */ - jabber_presence_subscription_set(js, buddy->name, "unsubscribed"); + jabber_presence_subscription_set(js, purple_buddy_get_name(buddy), "unsubscribed"); } static void jabber_buddy_rerequest_auth(PurpleBlistNode *node, gpointer data) @@ -1887,10 +1887,10 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - js = gc->proto_data; + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + js = purple_connection_get_protocol_data(gc); - jabber_presence_subscription_set(js, buddy->name, "subscribe"); + jabber_presence_subscription_set(js, purple_buddy_get_name(buddy), "subscribe"); } @@ -1903,18 +1903,18 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - js = gc->proto_data; + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + js = purple_connection_get_protocol_data(gc); - jabber_presence_subscription_set(js, buddy->name, "unsubscribe"); + jabber_presence_subscription_set(js, purple_buddy_get_name(buddy), "unsubscribe"); } static void jabber_buddy_login(PurpleBlistNode *node, gpointer data) { if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { /* simply create a directed presence of the current status */ PurpleBuddy *buddy = (PurpleBuddy *) node; - PurpleConnection *gc = purple_account_get_connection(buddy->account); - JabberStream *js = gc->proto_data; + PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + JabberStream *js = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); PurplePresence *gpresence = purple_account_get_presence(account); PurpleStatus *status = purple_presence_get_active_status(gpresence); @@ -1928,7 +1928,7 @@ g_free(msg); - xmlnode_set_attrib(presence, "to", buddy->name); + xmlnode_set_attrib(presence, "to", purple_buddy_get_name(buddy)); jabber_send(js, presence); xmlnode_free(presence); @@ -1939,12 +1939,13 @@ if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { /* simply create a directed unavailable presence */ PurpleBuddy *buddy = (PurpleBuddy *) node; - JabberStream *js = purple_account_get_connection(buddy->account)->proto_data; + PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + JabberStream *js = purple_connection_get_protocol_data(gc); xmlnode *presence; presence = jabber_presence_create_js(js, JABBER_BUDDY_STATE_UNAVAILABLE, NULL, 0); - xmlnode_set_attrib(presence, "to", buddy->name); + xmlnode_set_attrib(presence, "to", purple_buddy_get_name(buddy)); jabber_send(js, presence); xmlnode_free(presence); @@ -1953,9 +1954,10 @@ static GList *jabber_buddy_menu(PurpleBuddy *buddy) { - PurpleConnection *gc = purple_account_get_connection(buddy->account); - JabberStream *js = gc->proto_data; - JabberBuddy *jb = jabber_buddy_find(js, buddy->name, TRUE); + PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + JabberStream *js = purple_connection_get_protocol_data(gc); + const char *name = purple_buddy_get_name(buddy); + JabberBuddy *jb = jabber_buddy_find(js, name, TRUE); GList *jbrs; GList *m = NULL; @@ -2010,7 +2012,7 @@ * that gateways on the roster can be identified by having no '@' in their jid. This is a faily safe assumption, since * people don't tend to have a server or other service there. */ - if (g_utf8_strchr(buddy->name, -1, '@') == NULL) { + if (g_utf8_strchr(name, -1, '@') == NULL) { act = purple_menu_action_new(_("Log In"), PURPLE_CALLBACK(jabber_buddy_login), NULL, NULL); @@ -2478,7 +2480,7 @@ void jabber_user_search_begin(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; - JabberStream *js = gc->proto_data; + JabberStream *js = purple_connection_get_protocol_data(gc); purple_request_input(gc, _("Enter a User Directory"), _("Enter a User Directory"), _("Select a user directory to search"), diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/jabber/google.c --- a/libpurple/protocols/jabber/google.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/jabber/google.c Wed Jan 28 10:23:37 2009 +0000 @@ -283,6 +283,7 @@ xmlnode *group; PurpleBuddy *b; JabberBuddy *jb; + const char *balias; js = (JabberStream*)(gc->proto_data); @@ -309,13 +310,14 @@ g = purple_buddy_get_group(b); group = xmlnode_new_child(item, "group"); - xmlnode_insert_data(group, g->name, -1); + xmlnode_insert_data(group, purple_group_get_name(g), -1); buddies = buddies->next; } + balias = purple_buddy_get_local_buddy_alias(b); xmlnode_set_attrib(item, "jid", who); - xmlnode_set_attrib(item, "name", b->alias ? b->alias : ""); + xmlnode_set_attrib(item, "name", balias ? balias : ""); xmlnode_set_attrib(item, "gr:t", "B"); xmlnode_set_attrib(query, "xmlns:gr", "google:roster"); xmlnode_set_attrib(query, "gr:ext", "2"); @@ -348,6 +350,7 @@ xmlnode *item; xmlnode *group; PurpleBuddy *b; + const char *balias; g_return_if_fail(gc != NULL); g_return_if_fail(who != NULL); @@ -357,7 +360,7 @@ if (!js || !js->server_caps & JABBER_CAP_GOOGLE_ROSTER) return; - buddies = purple_find_buddies(js->gc->account, who); + buddies = purple_find_buddies(purple_connection_get_account(js->gc), who); if(!buddies) return; @@ -375,13 +378,14 @@ g = purple_buddy_get_group(b); group = xmlnode_new_child(item, "group"); - xmlnode_insert_data(group, g->name, -1); + xmlnode_insert_data(group, purple_group_get_name(g), -1); buddies = buddies->next; } + balias = purple_buddy_get_local_buddy_alias(b); xmlnode_set_attrib(item, "jid", who); - xmlnode_set_attrib(item, "name", b->alias ? b->alias : ""); + xmlnode_set_attrib(item, "name", balias ? balias : ""); xmlnode_set_attrib(query, "xmlns:gr", "google:roster"); xmlnode_set_attrib(query, "gr:ext", "2"); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Jan 28 10:23:37 2009 +0000 @@ -1620,13 +1620,14 @@ { JabberStream *js; JabberBuddy *jb = NULL; - - if(!b->account->gc) + PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(b)); + + if(!gc) return NULL; - js = b->account->gc->proto_data; + js = gc->proto_data; if(js) - jb = jabber_buddy_find(js, b->name, FALSE); + jb = jabber_buddy_find(js, purple_buddy_get_name(b), FALSE); if(!PURPLE_BUDDY_IS_ONLINE(b)) { if(jb && (jb->subscription & JABBER_SUB_PENDING || @@ -1640,9 +1641,11 @@ { char *ret = NULL; JabberBuddy *jb = NULL; - - if (b->account->gc && b->account->gc->proto_data) - jb = jabber_buddy_find(b->account->gc->proto_data, b->name, FALSE); + PurpleAccount *account = purple_buddy_get_account(b); + PurpleConnection *gc = purple_account_get_connection(account); + + if (gc && gc->proto_data) + jb = jabber_buddy_find(gc->proto_data, purple_buddy_get_name(b), FALSE); if(jb && !PURPLE_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) { ret = g_strdup(_("Not Authorized")); @@ -1671,14 +1674,19 @@ void jabber_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { JabberBuddy *jb; + PurpleAccount *account; + PurpleConnection *gc; g_return_if_fail(b != NULL); - g_return_if_fail(b->account != NULL); - g_return_if_fail(b->account->gc != NULL); - g_return_if_fail(b->account->gc->proto_data != NULL); - - jb = jabber_buddy_find(b->account->gc->proto_data, b->name, - FALSE); + + account = purple_buddy_get_account(b); + g_return_if_fail(account != NULL); + + gc = purple_account_get_connection(account); + g_return_if_fail(gc != NULL); + g_return_if_fail(gc->proto_data != NULL); + + jb = jabber_buddy_find(gc->proto_data, purple_buddy_get_name(b), FALSE); if(jb) { JabberBuddyResource *jbr = NULL; @@ -2014,19 +2022,24 @@ if(!(jid = jabber_id_new(name))) return NULL; - for(gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { - for(cnode = gnode->child; cnode; cnode = cnode->next) { + for(gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { PurpleChat *chat = (PurpleChat*)cnode; const char *room, *server; + GHashTable *components; if(!PURPLE_BLIST_NODE_IS_CHAT(cnode)) continue; - if(chat->account != account) + if (purple_chat_get_account(chat) != account) continue; - if(!(room = g_hash_table_lookup(chat->components, "room"))) + components = purple_chat_get_components(chat); + if(!(room = g_hash_table_lookup(components, "room"))) continue; - if(!(server = g_hash_table_lookup(chat->components, "server"))) + if(!(server = g_hash_table_lookup(components, "server"))) continue; if(jid->node && jid->domain && diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/jabber/roster.c --- a/libpurple/protocols/jabber/roster.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/jabber/roster.c Wed Jan 28 10:23:37 2009 +0000 @@ -80,15 +80,16 @@ buddies = g_slist_remove(buddies, b); - if((l = g_slist_find_custom(g2, g->name, (GCompareFunc)strcmp))) { - const char *servernick; + if((l = g_slist_find_custom(g2, purple_group_get_name(g), (GCompareFunc)strcmp))) { + const char *servernick, *balias; /* Previously stored serverside / buddy-supplied alias */ if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"))) serv_got_alias(js->gc, jid, servernick); /* Alias from our roster retrieval */ - if(alias && (!b->alias || strcmp(b->alias, alias))) + balias = purple_buddy_get_local_buddy_alias(b); + if(alias && (!balias || strcmp(balias, alias))) purple_serv_got_private_alias(js->gc, jid, alias); g_free(l->data); g2 = g_slist_delete_link(g2, l); @@ -119,11 +120,13 @@ /* If we just learned about ourself, then fake our status, * because we won't be receiving a normal presence message * about ourself. */ - if(!strcmp(b->name, my_bare_jid)) { + if(!strcmp(purple_buddy_get_name(b), my_bare_jid)) { PurplePresence *gpresence; PurpleStatus *status; + PurpleAccount *account; - gpresence = purple_account_get_presence(js->gc->account); + account = purple_connection_get_account(js->gc); + gpresence = purple_account_get_presence(account); status = purple_presence_get_active_status(gpresence); jabber_presence_fake_to_self(js, status); } @@ -273,6 +276,7 @@ GSList *groups = NULL, *l; JabberIq *iq; xmlnode *query, *item, *group; + const char *balias; if (js->currently_parsing_roster_push) return; @@ -289,7 +293,7 @@ while(buddies) { b = buddies->data; g = purple_buddy_get_group(b); - groups = g_slist_append(groups, g->name); + groups = g_slist_append(groups, (char *)purple_group_get_name(g)); buddies = g_slist_remove(buddies, b); } } @@ -301,7 +305,8 @@ xmlnode_set_attrib(item, "jid", name); - xmlnode_set_attrib(item, "name", b->alias ? b->alias : ""); + balias = purple_buddy_get_local_buddy_alias(b); + xmlnode_set_attrib(item, "name", balias ? balias : ""); for(l = groups; l; l = l->next) { group = xmlnode_new_child(item, "group"); @@ -327,14 +332,16 @@ JabberBuddy *jb; JabberBuddyResource *jbr; char *my_bare_jid; + const char *name; if(!js->roster_parsed) return; - if(!(who = jabber_get_bare_jid(buddy->name))) + name = purple_buddy_get_name(buddy); + if(!(who = jabber_get_bare_jid(name))) return; - jb = jabber_buddy_find(js, buddy->name, FALSE); + jb = jabber_buddy_find(js, name, FALSE); jabber_roster_update(js, who, NULL); @@ -375,6 +382,7 @@ GSList *buddies, *groups = NULL; PurpleBuddy *b; PurpleGroup *g; + const char *gname; if(!old_group || !new_group || !strcmp(old_group, new_group)) return; @@ -383,10 +391,11 @@ while(buddies) { b = buddies->data; g = purple_buddy_get_group(b); - if(!strcmp(g->name, old_group)) + gname = purple_group_get_name(g); + if(!strcmp(gname, old_group)) groups = g_slist_append(groups, (char*)new_group); /* ick */ else - groups = g_slist_append(groups, g->name); + groups = g_slist_append(groups, (char*)gname); buddies = g_slist_remove(buddies, b); } jabber_roster_update(gc->proto_data, name, groups); @@ -397,15 +406,17 @@ PurpleGroup *group, GList *moved_buddies) { GList *l; + const char *gname = purple_group_get_name(group); for(l = moved_buddies; l; l = l->next) { PurpleBuddy *buddy = l->data; - jabber_roster_group_change(gc, buddy->name, old_name, group->name); + jabber_roster_group_change(gc, purple_buddy_get_name(buddy), old_name, gname); } } void jabber_roster_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { - GSList *buddies = purple_find_buddies(gc->account, buddy->name); + const char *name = purple_buddy_get_name(buddy); + GSList *buddies = purple_find_buddies(purple_connection_get_account(gc), name); buddies = g_slist_remove(buddies, buddy); if(buddies != NULL) { @@ -416,11 +427,11 @@ while(buddies) { tmpbuddy = buddies->data; tmpgroup = purple_buddy_get_group(tmpbuddy); - groups = g_slist_append(groups, tmpgroup->name); + groups = g_slist_append(groups, (char *)purple_group_get_name(tmpgroup)); buddies = g_slist_remove(buddies, tmpbuddy); } - jabber_roster_update(gc->proto_data, buddy->name, groups); + jabber_roster_update(gc->proto_data, name, groups); g_slist_free(groups); } else { JabberIq *iq = jabber_iq_new_query(gc->proto_data, JABBER_IQ_SET, @@ -428,7 +439,7 @@ xmlnode *query = xmlnode_get_child(iq->node, "query"); xmlnode *item = xmlnode_new_child(query, "item"); - xmlnode_set_attrib(item, "jid", buddy->name); + xmlnode_set_attrib(item, "jid", name); xmlnode_set_attrib(item, "subscription", "remove"); jabber_iq_send(iq); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/msn/directconn.c --- a/libpurple/protocols/msn/directconn.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/msn/directconn.c Wed Jan 28 10:23:37 2009 +0000 @@ -201,24 +201,6 @@ g_free(buffer); -#if 0 - /* Let's write the length of the data. */ - ret = write(directconn->fd, &len, sizeof(len)); - - /* Let's write the data. */ - ret = write(directconn->fd, data, len); - - char *str; - str = g_strdup_printf("/home/revo/msntest/w%.4d.bin", directconn->c); - - FILE *tf = g_fopen(str, "w"); - fwrite(&len, 1, sizeof(len), tf); - fwrite(data, 1, len, tf); - fclose(tf); - - g_free(str); -#endif - directconn->c++; return ret; @@ -341,7 +323,7 @@ MsnMessage *msg; #ifdef DEBUG_DC - str = g_strdup_printf("/home/revo/msntest/r%.4d.bin", directconn->c); + str = g_strdup_printf("%s/msntest/r%.4d.bin", g_get_home_dir(), directconn->c); FILE *tf = g_fopen(str, "w"); fwrite(body, 1, len, tf); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/msn/msn.c Wed Jan 28 10:23:37 2009 +0000 @@ -457,23 +457,27 @@ PurpleConnection *gc; MsnSession *session; MsnMobileData *data; + PurpleAccount *account; + const char *name; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + account = purple_buddy_get_account(buddy); + gc = purple_account_get_connection(account); + name = purple_buddy_get_name(buddy); session = gc->proto_data; data = g_new0(MsnMobileData, 1); data->gc = gc; - data->passport = buddy->name; + data->passport = name; purple_request_input(gc, NULL, _("Send a mobile message."), NULL, NULL, TRUE, FALSE, NULL, _("Page"), G_CALLBACK(send_to_mobile_cb), _("Close"), G_CALLBACK(close_mobile_page_cb), - purple_connection_get_account(gc), purple_buddy_get_name(buddy), NULL, + account, name, NULL, data); } @@ -505,6 +509,7 @@ { PurpleBuddy *buddy; PurpleConnection *gc; + PurpleAccount *account; MsnSession *session; MsnSwitchBoard *swboard; @@ -514,13 +519,14 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + account = purple_buddy_get_account(buddy); + gc = purple_account_get_connection(account); session = gc->proto_data; swboard = msn_switchboard_new(session); msn_switchboard_request(swboard); - msn_switchboard_request_add_user(swboard, buddy->name); + msn_switchboard_request_add_user(swboard, purple_buddy_get_name(buddy)); /* TODO: This might move somewhere else, after USR might be */ swboard->chat_id = msn_switchboard_get_chat_id(); @@ -528,9 +534,9 @@ swboard->flag = MSN_SB_FLAG_IM; /* Local alias > Display name > Username */ - if ((alias = purple_account_get_alias(buddy->account)) == NULL) + if ((alias = purple_account_get_alias(account)) == NULL) if ((alias = purple_connection_get_display_name(gc)) == NULL) - alias = purple_account_get_username(buddy->account); + alias = purple_account_get_username(account); purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), alias, NULL, PURPLE_CBFLAGS_NONE, TRUE); @@ -613,7 +619,7 @@ static const char * msn_list_emblems(PurpleBuddy *b) { - MsnUser *user = b->proto_data; + MsnUser *user = purple_buddy_get_protocol_data(b); if (user != NULL) { if (user->clientid & MSN_CLIENT_CAP_BOT) @@ -694,7 +700,7 @@ PurplePresence *presence = purple_buddy_get_presence(buddy); PurpleStatus *status = purple_presence_get_active_status(presence); - user = buddy->proto_data; + user = purple_buddy_get_protocol_data(buddy); if (purple_presence_is_online(presence)) { @@ -937,7 +943,7 @@ g_return_val_if_fail(buddy != NULL, NULL); - user = buddy->proto_data; + user = purple_buddy_get_protocol_data(buddy); if (user != NULL) { @@ -950,8 +956,8 @@ } } - if (g_ascii_strcasecmp(buddy->name, - purple_account_get_username(buddy->account))) + if (g_ascii_strcasecmp(purple_buddy_get_name(buddy), + purple_account_get_username(purple_buddy_get_account(buddy)))) { act = purple_menu_action_new(_("Initiate _Chat"), PURPLE_CALLBACK(initiate_chat_cb), @@ -1419,14 +1425,15 @@ { MsnSession *session; MsnUserList *userlist; - const char *who; + const char *who, *gname; MsnUser *user; session = gc->proto_data; userlist = session->userlist; - who = msn_normalize(gc->account, buddy->name); - - purple_debug_info("msn", "Add user:%s to group:%s\n", who, (group && group->name) ? group->name : "(null)"); + who = msn_normalize(purple_connection_get_account(gc), purple_buddy_get_name(buddy)); + + gname = group ? purple_group_get_name(group) : NULL; + purple_debug_info("msn", "Add user:%s to group:%s\n", who, gname ? gname : "(null)"); if (!session->logged_in) { #if 0 @@ -1453,10 +1460,10 @@ if ((user != NULL) && (user->networkid != MSN_NETWORK_UNKNOWN)) { /* We already know this buddy and their network. This function knows what to do with users already in the list and stuff... */ - msn_userlist_add_buddy(userlist, who, group ? group->name : NULL); + msn_userlist_add_buddy(userlist, who, gname); } else { /* We need to check the network for this buddy first */ - msn_userlist_save_pending_buddy(userlist, who, group ? group->name : NULL); + msn_userlist_save_pending_buddy(userlist, who, gname); msn_notification_send_fqy(session, who); } } @@ -1474,7 +1481,7 @@ return; /* XXX - Does buddy->name need to be msn_normalize'd here? --KingAnt */ - msn_userlist_rem_buddy(userlist, buddy->name); + msn_userlist_rem_buddy(userlist, purple_buddy_get_name(buddy)); } static void @@ -1727,20 +1734,22 @@ PurpleGroup *group, GList *moved_buddies) { MsnSession *session; + const char *gname; session = gc->proto_data; g_return_if_fail(session != NULL); g_return_if_fail(session->userlist != NULL); + gname = purple_group_get_name(group); if (msn_userlist_find_group_with_name(session->userlist, old_name) != NULL) { - msn_contact_rename_group(session, old_name, group->name); + msn_contact_rename_group(session, old_name, gname); } else { /* not found */ - msn_add_group(session, NULL, group->name); + msn_add_group(session, NULL, gname); } } @@ -1800,20 +1809,22 @@ { MsnSession *session; MsnCmdProc *cmdproc; + const char *gname; session = gc->proto_data; cmdproc = session->notification->cmdproc; - - purple_debug_info("msn", "Remove group %s\n", group->name); + gname = purple_group_get_name(group); + + purple_debug_info("msn", "Remove group %s\n", gname); /*we can't delete the default group*/ - if(!strcmp(group->name, MSN_INDIVIDUALS_GROUP_NAME)|| - !strcmp(group->name, MSN_NON_IM_GROUP_NAME)) + if(!strcmp(gname, MSN_INDIVIDUALS_GROUP_NAME)|| + !strcmp(gname, MSN_NON_IM_GROUP_NAME)) { purple_debug_info("msn", "This group can't be removed, returning.\n"); return ; } - msn_del_group(session, group->name); + msn_del_group(session, gname); } /** @@ -1830,17 +1841,19 @@ if (b) { char *tmp; - - if (b->alias && b->alias[0]) + const char *alias; + + alias = purple_buddy_get_local_buddy_alias(b); + if (alias && alias[0]) { - char *aliastext = g_markup_escape_text(b->alias, -1); + char *aliastext = g_markup_escape_text(alias, -1); purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext); g_free(aliastext); } - if (b->server_alias) + if ((alias = purple_buddy_get_server_alias(b)) != NULL) { - char *nicktext = g_markup_escape_text(b->server_alias, -1); + char *nicktext = g_markup_escape_text(alias, -1); tmp = g_strdup_printf("%s", nicktext); purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp); g_free(tmp); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/msn/session.c --- a/libpurple/protocols/msn/session.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/msn/session.c Wed Jan 28 10:23:37 2009 +0000 @@ -269,16 +269,21 @@ * being logged in. This no longer happens, so we manually iterate * over the whole buddy list to identify sync issues. */ - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { PurpleGroup *group = (PurpleGroup *)gnode; const char *group_name; if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - group_name = group->name; - for(cnode = gnode->child; cnode; cnode = cnode->next) { + group_name = purple_group_get_name(group); + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for(bnode = cnode->child; bnode; bnode = bnode->next) { + for(bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *b; if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/msn/user.c --- a/libpurple/protocols/msn/user.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/msn/user.c Wed Jan 28 10:23:37 2009 +0000 @@ -289,9 +289,8 @@ b = purple_buddy_new(account, passport, NULL); purple_blist_add_buddy(b, NULL, g, NULL); } - b->proto_data = user; + purple_buddy_set_protocol_data(b, user); /*Update the blist Node info*/ -// purple_blist_node_set_string(&(b->node), "", ""); } /*check if the msn user is online*/ diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/msn/userlist.c --- a/libpurple/protocols/msn/userlist.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/msn/userlist.c Wed Jan 28 10:23:37 2009 +0000 @@ -930,31 +930,37 @@ msn_userlist_load(MsnSession *session) { PurpleBlistNode *gnode, *cnode, *bnode; - PurpleConnection *gc = purple_account_get_connection(session->account); + PurpleAccount *account = session->account; + PurpleConnection *gc = purple_account_get_connection(account); GSList *l; MsnUser * user; g_return_if_fail(gc != NULL); - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *b; if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *)bnode; - if (b->account == gc->account) + if (purple_buddy_get_account(b) == account) { user = msn_userlist_find_add_user(session->userlist, - b->name,NULL); - b->proto_data = user; + purple_buddy_get_name(b), NULL); + purple_buddy_set_protocol_data(b, user); msn_user_set_op(user, MSN_LIST_FL_OP); } } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/myspace/README --- a/libpurple/protocols/myspace/README Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/myspace/README Wed Jan 28 10:23:37 2009 +0000 @@ -1,9 +1,8 @@ -MySpaceIM Protocol Plugin for Libpurple by Jeff Connelly 20070807 - +MySpaceIM Protocol Plugin for libpurple by Jeff Connelly 2007-08-07 Greetings. This package contains a plugin for libpurple (as used in -Pidgin, formerly Gaim) to connect to the new MySpaceIM instant messaging -network and send/receive messages. Functionality is only basic as of yet, +Pidgin, formerly Gaim) to connect to the new MySpaceIM instant messaging +network and send/receive messages. Functionality is only basic as of yet, and this code should be considered alpha quality. This code was initially developed under Google Summer of Code 2007. @@ -15,10 +14,10 @@ Login using your _email address_ you use to login to myspace.com. You can't login using your numeric ID or alias. -To test it out, send a message to yourself (by your username or numeric -uid (email not yet supported)) or tom (6221). In either case you should -get a reply. You should also be able to talk to other MySpaceIM users if -you desire. Replies will always be shown as coming from a user's username, +To test it out, send a message to yourself (by your username or numeric +uid (email not yet supported)) or tom (6221). In either case you should +get a reply. You should also be able to talk to other MySpaceIM users if +you desire. Replies will always be shown as coming from a user's username, even if you IM by email or userid. Feedback welcome. You can IM my test account at "msimprpl" if you feel like it. @@ -26,4 +25,3 @@ Enjoy, -Jeff Connelly msimprpl@xyzzy.cjb.net - diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/myspace/myspace.c Wed Jan 28 10:23:37 2009 +0000 @@ -202,7 +202,7 @@ /* Next, see if on buddy list and know uid. */ buddy = purple_find_buddy(session->account, username); if (buddy) { - uid = purple_blist_node_get_int(&buddy->node, "UserID"); + uid = purple_blist_node_get_int(PURPLE_BLIST_NODE(buddy), "UserID"); } else { uid = 0; } @@ -311,7 +311,7 @@ /* See finch/gnthistory.c */ buddy = cur->data; - uid = purple_blist_node_get_int(&buddy->node, "UserID"); + uid = purple_blist_node_get_int(PURPLE_BLIST_NODE(buddy), "UserID"); name = purple_buddy_get_name(buddy); if (uid == wanted_uid) @@ -383,12 +383,17 @@ MsimSession *session; MsimUser *user; const gchar *display_name, *headline; + PurpleAccount *account; + PurpleConnection *gc; g_return_val_if_fail(buddy != NULL, NULL); user = msim_get_user_from_buddy(buddy); - session = (MsimSession *)buddy->account->gc->proto_data; + account = purple_buddy_get_account(buddy); + gc = purple_account_get_connection(account); + session = (MsimSession *)gc->proto_data; + g_return_val_if_fail(MSIM_SESSION_VALID(session), NULL); display_name = headline = NULL; @@ -435,8 +440,10 @@ if (PURPLE_BUDDY_IS_ONLINE(buddy)) { MsimSession *session; - - session = (MsimSession *)buddy->account->gc->proto_data; + PurpleAccount *account = purple_buddy_get_account(buddy); + PurpleConnection *gc = purple_account_get_connection(account); + + session = (MsimSession *)gc->proto_data; g_return_if_fail(MSIM_SESSION_VALID(session)); @@ -1036,11 +1043,11 @@ * of numbers in the buddy list. */ if (display_name != NULL) { - purple_blist_node_set_string(&buddy->node, "DisplayName", display_name); + purple_blist_node_set_string(PURPLE_BLIST_NODE(buddy), "DisplayName", display_name); serv_got_alias(session->gc, username, display_name); } else { serv_got_alias(session->gc, username, - purple_blist_node_get_string(&buddy->node, "DisplayName")); + purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "DisplayName")); } } g_free(display_name); @@ -1050,7 +1057,7 @@ user->id = uid; /* Keep track of the user ID across sessions */ - purple_blist_node_set_int(&buddy->node, "UserID", uid); + purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy), "UserID", uid); /* Stores a few fields in the MsimUser, relevant to the buddy itself. * AvatarURL, Headline, ContactID. */ @@ -1376,7 +1383,7 @@ user->id = msim_msg_get_integer(msg, "f"); /* Keep track of the user ID across sessions */ - purple_blist_node_set_int(&buddy->node, "UserID", user->id); + purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy), "UserID", user->id); msim_store_user_info(session, msg, NULL); } else { @@ -2630,10 +2637,14 @@ MsimMessage *msg; MsimMessage *msg_persist; MsimMessage *body; + const char *name, *gname; session = (MsimSession *)gc->proto_data; + name = purple_buddy_get_name(buddy); + gname = group ? purple_group_get_name(group) : NULL; + purple_debug_info("msim", "msim_add_buddy: want to add %s to %s\n", - buddy->name, (group && group->name) ? group->name : "(no group)"); + name, gname ? gname : "(no group)"); msg = msim_msg_new( "addbuddy", MSIM_TYPE_BOOLEAN, TRUE, @@ -2642,7 +2653,7 @@ "reason", MSIM_TYPE_STRING, g_strdup(""), NULL); - if (!msim_postprocess_outgoing(session, msg, buddy->name, "newprofileid", "reason")) { + if (!msim_postprocess_outgoing(session, msg, name, "newprofileid", "reason")) { purple_notify_error(NULL, NULL, _("Failed to add buddy"), _("'addbuddy' command failed.")); msim_msg_free(msg); return; @@ -2654,7 +2665,7 @@ body = msim_msg_new( "ContactID", MSIM_TYPE_STRING, g_strdup(""), - "GroupName", MSIM_TYPE_STRING, g_strdup(group->name), + "GroupName", MSIM_TYPE_STRING, g_strdup(gname), "Position", MSIM_TYPE_INTEGER, 1000, "Visibility", MSIM_TYPE_INTEGER, 1, "NickName", MSIM_TYPE_STRING, g_strdup(""), @@ -2675,7 +2686,7 @@ "body", MSIM_TYPE_DICTIONARY, body, NULL); - if (!msim_postprocess_outgoing(session, msg_persist, buddy->name, "body", NULL)) + if (!msim_postprocess_outgoing(session, msg_persist, name, "body", NULL)) { purple_notify_error(NULL, NULL, _("Failed to add buddy"), _("persist command failed")); msim_msg_free(msg_persist); @@ -2684,7 +2695,14 @@ msim_msg_free(msg_persist); /* Add to allow list, remove from block list */ - msim_update_blocklist_for_buddy(session, buddy->name, TRUE, FALSE); + msim_update_blocklist_for_buddy(session, name, TRUE, FALSE); +} + +static void +msim_buddy_free(PurpleBuddy *buddy) +{ + msim_user_free(purple_buddy_get_protocol_data(buddy)); + purple_buddy_set_protocol_data(buddy, NULL); } /** @@ -2696,8 +2714,10 @@ MsimSession *session; MsimMessage *delbuddy_msg; MsimMessage *persist_msg; + const char *name; session = (MsimSession *)gc->proto_data; + name = purple_buddy_get_name(buddy); delbuddy_msg = msim_msg_new( "delbuddy", MSIM_TYPE_BOOLEAN, TRUE, @@ -2705,7 +2725,7 @@ /* 'delprofileid' with uid will be inserted here. */ NULL); - if (!msim_postprocess_outgoing(session, delbuddy_msg, buddy->name, "delprofileid", NULL)) { + if (!msim_postprocess_outgoing(session, delbuddy_msg, name, "delprofileid", NULL)) { purple_notify_error(NULL, NULL, _("Failed to remove buddy"), _("'delbuddy' command failed")); msim_msg_free(delbuddy_msg); return; @@ -2724,7 +2744,7 @@ "body", MSIM_TYPE_STRING, g_strdup("ContactID="), NULL); - if (!msim_postprocess_outgoing(session, persist_msg, buddy->name, "body", NULL)) { + if (!msim_postprocess_outgoing(session, persist_msg, name, "body", NULL)) { purple_notify_error(NULL, NULL, _("Failed to remove buddy"), _("persist command failed")); msim_msg_free(persist_msg); return; @@ -2736,15 +2756,12 @@ * doesn't seem like it would be necessary, but the official client * does it) */ - if (!msim_update_blocklist_for_buddy(session, buddy->name, FALSE, FALSE)) { + if (!msim_update_blocklist_for_buddy(session, name, FALSE, FALSE)) { purple_notify_error(NULL, NULL, _("Failed to remove buddy"), _("blocklist command failed")); return; } - if (buddy->proto_data) { - msim_user_free(buddy->proto_data); - buddy->proto_data = NULL; - } + msim_buddy_free(buddy); } /** @@ -2834,13 +2851,6 @@ msim_update_blocklist_for_buddy(session, name, FALSE, FALSE); } -static void -msim_buddy_free(PurpleBuddy *buddy) -{ - msim_user_free(buddy->proto_data); - buddy->proto_data = NULL; -} - /** * Returns a string of a username in canonical form. Basically removes all the * spaces, lowercases the string, and looks up user IDs to usernames. diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/myspace/user.c --- a/libpurple/protocols/myspace/user.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/myspace/user.c Wed Jan 28 10:23:37 2009 +0000 @@ -52,17 +52,14 @@ return NULL; } - if (!buddy->proto_data) { + if (!(user = purple_buddy_get_protocol_data(buddy))) { /* No MsimUser for this buddy; make one. */ user = g_new0(MsimUser, 1); user->buddy = buddy; - user->id = purple_blist_node_get_int((PurpleBlistNode*)buddy, "UserID"); - buddy->proto_data = (gpointer)user; + purple_buddy_set_protocol_data(buddy, user); } - user = (MsimUser *)(buddy->proto_data); - return user; } @@ -111,6 +108,7 @@ { PurplePresence *presence; gchar *str; + guint uid; guint cv; /* Useful to identify the account the tooltip refers to. @@ -119,6 +117,8 @@ purple_notify_user_info_add_pair(user_info, _("User"), user->username); } + uid = purple_blist_node_get_int((PurpleBlistNode *)user->buddy, "UserID"); + /* a/s/l...the vitals */ if (user->age) { char age[16]; @@ -209,9 +209,9 @@ gsize len, const gchar *error_message) { - MsimUser *user; - - user = (MsimUser *)user_data; + MsimUser *user = (MsimUser *)user_data; + const char *name = purple_buddy_get_name(user->buddy); + PurpleAccount *account; purple_debug_info("msim_downloaded_buddy_icon", "Downloaded %" G_GSIZE_FORMAT " bytes\n", len); @@ -219,12 +219,12 @@ if (!url_text) { purple_debug_info("msim_downloaded_buddy_icon", "failed to download icon for %s", - user->buddy->name); + name); return; } - purple_buddy_icons_set_for_user(user->buddy->account, - user->buddy->name, + account = purple_buddy_get_account(user->buddy); + purple_buddy_icons_set_for_user(account, name, g_memdup((gchar *)url_text, len), len, /* Use URL itself as buddy icon "checksum" (TODO: ETag) */ user->image_url); /* checksum */ @@ -247,7 +247,9 @@ static void msim_set_artist_or_title(MsimUser *user, const char *new_artist, const char *new_title) { PurplePresence *presence; + PurpleAccount *account; const char *prev_artist, *prev_title; + const char *name; if (user->buddy == NULL) /* User not on buddy list so nothing to do */ @@ -261,8 +263,11 @@ if (new_title && !*new_title) new_title = NULL; + account = purple_buddy_get_account(user->buddy); + name = purple_buddy_get_name(user->buddy); + if (!new_artist && !new_title) { - purple_prpl_got_user_status_deactive(user->buddy->account, user->buddy->name, "tune"); + purple_prpl_got_user_status_deactive(account, name, "tune"); return; } @@ -282,7 +287,7 @@ if (!new_title) new_title = prev_title; - purple_prpl_got_user_status(user->buddy->account, user->buddy->name, "tune", + purple_prpl_got_user_status(account, name, "tune", PURPLE_TUNE_TITLE, new_title, PURPLE_TUNE_ARTIST, new_artist, NULL); @@ -299,14 +304,16 @@ static void msim_store_user_info_each(const gchar *key_str, gchar *value_str, MsimUser *user) { + const char *name = user->buddy ? purple_buddy_get_name(user->buddy) : NULL; + if (g_str_equal(key_str, "UserID") || g_str_equal(key_str, "ContactID")) { /* Save to buddy list, if it exists, for quick cached uid lookup with msim_uid2username_from_blist(). */ user->id = atol(value_str); g_free(value_str); if (user->buddy) { - purple_debug_info("msim", "associating uid %s with username %s\n", key_str, user->buddy->name); - purple_blist_node_set_int(&user->buddy->node, "UserID", user->id); + purple_debug_info("msim", "associating uid %s with username %s\n", key_str, name); + purple_blist_node_set_int(PURPLE_BLIST_NODE(user->buddy), "UserID", user->id); } /* Need to store in MsimUser, too? What if not on blist? */ } else if (g_str_equal(key_str, "Age")) { @@ -359,9 +366,8 @@ /* Instead of showing 'no photo' picture, show nothing. */ if (g_str_equal(user->image_url, "http://x.myspace.com/images/no_pic.gif")) { - purple_buddy_icons_set_for_user(user->buddy->account, - user->buddy->name, - NULL, 0, NULL); + purple_buddy_icons_set_for_user(purple_buddy_get_account(user->buddy), + name, NULL, 0, NULL); return; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/myspace/zap.c --- a/libpurple/protocols/myspace/zap.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/myspace/zap.c Wed Jan 28 10:23:37 2009 +0000 @@ -173,13 +173,13 @@ buddy = (PurpleBuddy *)node; /* Find the session */ - account = buddy->account; + account = purple_buddy_get_account(buddy); gc = purple_account_get_connection(account); session = (MsimSession *)gc->proto_data; zap = GPOINTER_TO_INT(zap_num_ptr); - purple_prpl_send_attention(session->gc, buddy->name, zap); + purple_prpl_send_attention(session->gc, purple_buddy_get_name(buddy), zap); } /** Return menu, if any, for a buddy list node. */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/novell/novell.c --- a/libpurple/protocols/novell/novell.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/novell/novell.c Wed Jan 28 10:23:37 2009 +0000 @@ -293,7 +293,7 @@ nm_user_record_get_display_id(user_record)); alias = purple_buddy_get_alias(buddy); - if (alias == NULL || *alias == '\0' || (strcmp(alias, buddy->name) == 0)) { + if (alias == NULL || *alias == '\0' || (strcmp(alias, purple_buddy_get_name(buddy)) == 0)) { purple_blist_alias_buddy(buddy, nm_user_record_get_full_name(user_record)); @@ -1175,10 +1175,12 @@ const char *status_id; const char *text = NULL; const char *dn; + const char *name; int idle = 0; gboolean loggedin = TRUE; - account = buddy->account; + account = purple_buddy_get_account(buddy); + name = purple_buddy_get_name(buddy); switch (novellstatus) { case NM_STATUS_AVAILABLE: @@ -1205,7 +1207,7 @@ } /* Get status text for the user */ - dn = nm_lookup_dn(user, buddy->name); + dn = nm_lookup_dn(user, name); if (dn) { NMUserRecord *user_record = nm_find_user_record(user, dn); if (user_record) { @@ -1213,9 +1215,9 @@ } } - purple_prpl_got_user_status(account, buddy->name, status_id, + purple_prpl_got_user_status(account, name, status_id, "message", text, NULL); - purple_prpl_got_user_idle(account, buddy->name, + purple_prpl_got_user_idle(account, name, (novellstatus == NM_STATUS_AWAY_IDLE), idle); } @@ -1230,44 +1232,46 @@ PurpleBlistNode *bnode; PurpleGroup *group; PurpleBuddy *buddy; - PurpleBuddyList *blist; GSList *rem_list = NULL; GSList *l; NMFolder *folder = NULL; const char *gname = NULL; - if ((blist = purple_get_blist())) { - for (gnode = blist->root; gnode; gnode = gnode->next) { - if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { + if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) + continue; + group = (PurpleGroup *) gnode; + gname = purple_group_get_name(group); + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { + if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - group = (PurpleGroup *) gnode; - for (cnode = gnode->child; cnode; cnode = cnode->next) { - if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { + if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) { - if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - buddy = (PurpleBuddy *) bnode; - if (buddy->account == user->client_data) { - gname = group->name; - if (strcmp(group->name, NM_ROOT_FOLDER_NAME) == 0) - gname = ""; - folder = nm_find_folder(user, gname); - if (folder == NULL || - !nm_folder_find_contact_by_display_id(folder, buddy->name)) { - rem_list = g_slist_append(rem_list, buddy); - } + buddy = (PurpleBuddy *) bnode; + if (purple_buddy_get_account(buddy) == user->client_data) { + if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) + gname = ""; + folder = nm_find_folder(user, gname); + if (folder == NULL || + !nm_folder_find_contact_by_display_id(folder, purple_buddy_get_name(buddy))) { + rem_list = g_slist_append(rem_list, buddy); } } } } - - if (rem_list) { - for (l = rem_list; l; l = l->next) { - purple_blist_remove_buddy(l->data); - } - g_slist_free(rem_list); + } + + if (rem_list) { + for (l = rem_list; l; l = l->next) { + purple_blist_remove_buddy(l->data); } + g_slist_free(rem_list); } } @@ -1613,14 +1617,14 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); user = gc->proto_data; if (user == NULL) return; /* We should already have a userrecord for the buddy */ - user_record = nm_find_user_record(user, buddy->name); + user_record = nm_find_user_record(user, purple_buddy_get_name(buddy)); if (user_record == NULL) return; @@ -2538,7 +2542,7 @@ NMContact *contact; NMUser *user; NMERR_T rc = NM_OK; - const char *alias, *gname; + const char *alias, *gname, *bname; if (gc == NULL || buddy == NULL || group == NULL) return; @@ -2554,22 +2558,22 @@ return; contact = nm_create_contact(); - nm_contact_set_dn(contact, buddy->name); + nm_contact_set_dn(contact, purple_buddy_get_name(buddy)); /* Remove the PurpleBuddy (we will add it back after adding it * to the server side list). Save the alias if there is one. */ alias = purple_buddy_get_alias(buddy); - if (alias && strcmp(alias, buddy->name)) + bname = purple_buddy_get_name(buddy); + if (alias && strcmp(alias, bname)) nm_contact_set_display_name(contact, alias); purple_blist_remove_buddy(buddy); buddy = NULL; - if (strcmp(group->name, NM_ROOT_FOLDER_NAME) == 0) { + gname = purple_group_get_name(group); + if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) { gname = ""; - } else { - gname = group->name; } folder = nm_find_folder(user, gname); @@ -2603,11 +2607,10 @@ return; user = (NMUser *) gc->proto_data; - if (user && (dn = nm_lookup_dn(user, buddy->name))) { - if (strcmp(group->name, NM_ROOT_FOLDER_NAME) == 0) { + if (user && (dn = nm_lookup_dn(user, purple_buddy_get_name(buddy)))) { + gname = purple_group_get_name(group); + if (strcmp(gname, NM_ROOT_FOLDER_NAME) == 0) { gname = ""; - } else { - gname = group->name; } folder = nm_find_folder(user, gname); if (folder) { @@ -2637,7 +2640,7 @@ user = (NMUser *) gc->proto_data; if (user) { - NMFolder *folder = nm_find_folder(user, group->name); + NMFolder *folder = nm_find_folder(user, purple_group_get_name(group)); if (folder) { rc = nm_send_remove_folder(user, folder, @@ -2684,9 +2687,11 @@ } if (group) { + const char *balias; buddy = purple_find_buddy_in_group(user->client_data, name, group); - if (buddy && strcmp(buddy->alias, alias)) + balias = buddy ? purple_buddy_get_local_buddy_alias(buddy) : NULL; + if (balias && strcmp(balias, alias)) purple_blist_alias_buddy(buddy, alias); } @@ -2777,8 +2782,9 @@ user = gc->proto_data; if (user) { + const char *gname = purple_group_get_name(group); /* Does new folder exist already? */ - if (nm_find_folder(user, group->name)) { + if (nm_find_folder(user, gname)) { /* purple_blist_rename_group() adds the buddies * to the new group and removes the old group... * so there is nothing more to do here. @@ -2793,7 +2799,7 @@ folder = nm_find_folder(user, old_name); if (folder) { - rc = nm_send_rename_folder(user, folder, group->name, + rc = nm_send_rename_folder(user, folder, gname, _rename_folder_resp_cb, NULL); _check_for_disconnect(user, rc); } @@ -2819,12 +2825,12 @@ if (buddy == NULL) return; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); if (gc == NULL || (user = gc->proto_data) == NULL) return; if (PURPLE_BUDDY_IS_ONLINE(buddy)) { - user_record = nm_find_user_record(user, buddy->name); + user_record = nm_find_user_record(user, purple_buddy_get_name(buddy)); if (user_record) { status = nm_user_record_get_status(user_record); text = nm_user_record_get_status_text(user_record); @@ -2923,14 +2929,16 @@ { const char *text = NULL; const char *dn = NULL; - - if (buddy && buddy->account) { - PurpleConnection *gc = purple_account_get_connection(buddy->account); + PurpleAccount *account; + + account = buddy ? purple_buddy_get_account(buddy) : NULL; + if (buddy && account) { + PurpleConnection *gc = purple_account_get_connection(account); if (gc && gc->proto_data) { NMUser *user = gc->proto_data; - dn = nm_lookup_dn(user, buddy->name); + dn = nm_lookup_dn(user, purple_buddy_get_name(buddy)); if (dn) { NMUserRecord *user_record = nm_find_user_record(user, dn); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/null/README --- a/libpurple/protocols/null/README Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/null/README Wed Jan 28 10:23:37 2009 +0000 @@ -28,11 +28,10 @@ ----------------------- To build, just run ./configure as usual in the root directory of the pidgin -source distribution. Then cd libpurple/protocols/null and type make. To -install, copy libnull.la and .libs/libnull.so into your ~/.purple/plugins -directory. Then run Pidgin. +source distribution. Then cd libpurple/protocols/null and then make. To +install, run make install. Then run Pidgin. -To build nullprpl on Windows (with Cygwin/MinGW), use Makefile.mingw. +To build nullprpl on Windows (with Cygwin/MinGW), use: make -f Makefile.mingw ----- USAGE diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/null/nullprpl.c --- a/libpurple/protocols/null/nullprpl.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/null/nullprpl.c Wed Jan 28 10:23:37 2009 +0000 @@ -220,25 +220,7 @@ */ static const char *nullprpl_list_icon(PurpleAccount *acct, PurpleBuddy *buddy) { - /* shamelessly steal (er, borrow) the meanwhile protocol icon. it's cute! */ - return "meanwhile"; -} - -static const char *nullprpl_list_emblem(PurpleBuddy *buddy) -{ - const char* emblem; - - if (get_nullprpl_gc(buddy->name)) { - PurplePresence *presence = purple_buddy_get_presence(buddy); - PurpleStatus *status = purple_presence_get_active_status(presence); - emblem = purple_status_get_name(status); - } else { - emblem = "offline"; - } - - purple_debug_info("nullprpl", "using emblem %s for %s's buddy %s\n", - emblem, buddy->account->username, buddy->name); - return emblem; + return "null"; } static char *nullprpl_status_text(PurpleBuddy *buddy) { @@ -304,22 +286,22 @@ acct->username, NULL_STATUS_ONLINE, NULL_STATUS_AWAY, NULL_STATUS_OFFLINE); - type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, NULL_STATUS_ONLINE, - NULL_STATUS_ONLINE, TRUE); - purple_status_type_add_attr(type, "message", _("Online"), - purple_value_new(PURPLE_TYPE_STRING)); + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + NULL_STATUS_ONLINE, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), + NULL); types = g_list_prepend(types, type); - type = purple_status_type_new(PURPLE_STATUS_AWAY, NULL_STATUS_AWAY, - NULL_STATUS_AWAY, TRUE); - purple_status_type_add_attr(type, "message", _("Away"), - purple_value_new(PURPLE_TYPE_STRING)); + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, + NULL_STATUS_AWAY, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), + NULL); types = g_list_prepend(types, type); - - type = purple_status_type_new(PURPLE_STATUS_OFFLINE, NULL_STATUS_OFFLINE, - NULL_STATUS_OFFLINE, TRUE); - purple_status_type_add_attr(type, "message", _("Offline"), - purple_value_new(PURPLE_TYPE_STRING)); + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE, + NULL_STATUS_OFFLINE, NULL, TRUE, TRUE, FALSE, + "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), + NULL); types = g_list_prepend(types, type); return g_list_reverse(types); @@ -1073,7 +1055,7 @@ PURPLE_ICON_SCALE_DISPLAY, /* scale_rules */ }, nullprpl_list_icon, /* list_icon */ - nullprpl_list_emblem, /* list_emblem */ + NULL, /* list_emblem */ nullprpl_status_text, /* status_text */ nullprpl_tooltip_text, /* tooltip_text */ nullprpl_status_types, /* status_types */ @@ -1130,24 +1112,24 @@ NULL, /* whiteboard_prpl_ops */ NULL, /* send_raw */ NULL, /* roomlist_room_serialize */ - NULL, /* padding... */ - NULL, - NULL, - sizeof(PurplePluginProtocolInfo), /* struct_size */ - NULL + NULL, /* unregister_user */ + NULL, /* send_attention */ + NULL, /* attention_types */ + sizeof(PurplePluginProtocolInfo), /* struct_size */ + NULL, /* get_account_text_table */ }; static void nullprpl_init(PurplePlugin *plugin) { /* see accountopt.h for information about user splits and protocol options */ PurpleAccountUserSplit *split = purple_account_user_split_new( - _("Example user split (unused)"), /* text shown to user */ - "default", /* default value */ - '@'); /* field separator */ + _("Example user split"), /* text shown to user */ + "default", /* default value */ + '@'); /* field separator */ PurpleAccountOption *option = purple_account_option_string_new( - _("Example option (unused)"), /* text shown to user */ - "example", /* pref name */ - "default"); /* default value */ + _("Example option"), /* text shown to user */ + "example", /* pref name */ + "default"); /* default value */ purple_debug_info("nullprpl", "starting up\n"); @@ -1156,13 +1138,13 @@ /* register whisper chat command, /msg */ purple_cmd_register("msg", - "ws", /* args: recipient and message */ + "ws", /* args: recipient and message */ PURPLE_CMD_P_DEFAULT, /* priority */ PURPLE_CMD_FLAG_CHAT, "prpl-null", send_whisper, "msg <username> <message>: send a private message, aka a whisper", - NULL); /* userdata */ + NULL); /* userdata */ /* get ready to store offline messages */ goffline_messages = g_hash_table_new_full(g_str_hash, /* hash fn */ @@ -1189,12 +1171,12 @@ NULL, /* dependencies */ PURPLE_PRIORITY_DEFAULT, /* priority */ NULLPRPL_ID, /* id */ - "Nullprpl", /* name */ - "0.3", /* version */ - "Null Protocol Plugin", /* summary */ - "Null Protocol Plugin", /* description */ - "Ryan Barrett ", /* author */ - "http://snarfed.org/space/pidgin+null+protocol+plugin", /* homepage */ + "Null - Testing Plugin", /* name */ + DISPLAY_VERSION, /* version */ + N_("Null Protocol Plugin"), /* summary */ + N_("Null Protocol Plugin"), /* description */ + NULL, /* author */ + PURPLE_WEBSITE, /* homepage */ NULL, /* load */ NULL, /* unload */ nullprpl_destroy, /* destroy */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_admin.c --- a/libpurple/protocols/oscar/family_admin.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_admin.c Wed Jan 28 10:23:37 2009 +0000 @@ -21,9 +21,8 @@ /* * Family 0x0007 - Account Administration. * - * Used for stuff like changing the formating of your screen name, changing your + * Used for stuff like changing the formating of your username, changing your * email address, requesting an account confirmation email, getting account info, - * */ #include "oscar.h" @@ -32,7 +31,7 @@ * Subtype 0x0002 - Request a bit of account info. * * Info should be one of the following: - * 0x0001 - Screen name formatting + * 0x0001 - Username formatting * 0x0011 - Email address * 0x0013 - Unknown */ @@ -111,7 +110,7 @@ } /** - * Subtype 0x0004 - Set screenname formatting. + * Subtype 0x0004 - Set the formatting of username (change spaces and capitalization). */ void aim_admin_setnick(OscarData *od, FlapConnection *conn, const char *newnick) diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_alert.c --- a/libpurple/protocols/oscar/family_alert.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_alert.c Wed Jan 28 10:23:37 2009 +0000 @@ -22,10 +22,10 @@ * Family 0x0018 - Email notification * * Used for being alerted when the email address(es) associated with - * your screen name get new electronic-m. For normal AIM accounts, you - * get the email address screenname@netscape.net. AOL accounts have - * screenname@aol.com, and can also activate a netscape.net account. - * + * your username get new electronic-m. For normal AIM accounts, you + * get the email address username@netscape.net. AOL accounts have + * username@aol.com, and can also activate a netscape.net account. + * Note: This information might be out of date. */ #include "oscar.h" @@ -88,7 +88,7 @@ * but this is coded so it will handle that, and handle it well. * This tells you if you have unread mail or not, the URL you * should use to access that mail, and the domain name for the - * email account (screenname@domainname.com). If this is the + * email account (username@domainname.com). If this is the * first 0x0007 SNAC you've received since you signed on, or if * this is just a periodic status update, this will also contain * the number of unread emails that you have. diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_auth.c --- a/libpurple/protocols/oscar/family_auth.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_auth.c Wed Jan 28 10:23:37 2009 +0000 @@ -229,7 +229,7 @@ /* Truncate ICQ and AOL passwords, if necessary */ password_len = strlen(password); - if (aim_snvalid_icq(sn) && (password_len > MAXICQPASSLEN)) + if (oscar_util_valid_name_icq(sn) && (password_len > MAXICQPASSLEN)) password_len = MAXICQPASSLEN; else if (truncate_pass && password_len > 8) password_len = 8; @@ -293,11 +293,11 @@ tlvlist = aim_tlvlist_read(bs); /* - * No matter what, we should have a screen name. + * No matter what, we should have a username. */ if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) { - info->sn = aim_tlv_getstr(tlvlist, 0x0001, 1); - purple_connection_set_display_name(od->gc, info->sn); + info->bn = aim_tlv_getstr(tlvlist, 0x0001, 1); + purple_connection_set_display_name(od->gc, info->bn); } /* @@ -394,7 +394,7 @@ #if 0 /* - * Unknown. Seen on an @mac.com screen name with value of 0x003f + * Unknown. Seen on an @mac.com username with value of 0x003f */ if (aim_tlv_gettlv(tlvlist, 0x0055, 1)) { /* Unhandled */ @@ -421,7 +421,7 @@ * - connect * - server sends flap version * - client sends flap version - * - client sends screen name (17/6) + * - client sends username (17/6) * - server sends hash key (17/7) * - client sends auth request (17/2 -- aim_send_login) * - server yells @@ -460,7 +460,7 @@ * Subtype 0x0006 * * In AIM 3.5 protocol, the first stage of login is to request login from the - * Authorizer, passing it the screen name for verification. If the name is + * Authorizer, passing it the username for verification. If the name is * invalid, a 0017/0003 is spit back, with the standard error contents. If * valid, a 0017/0007 comes back, which is the signal to send it the main * login command (0017/0002). @@ -527,7 +527,7 @@ /* * If the truncate_pass TLV exists then we should truncate the * user's password to 8 characters. This flag is sent to us - * when logging in with an AOL user's screen name. + * when logging in with an AOL user's username. */ truncate_pass = aim_tlv_gettlv(tlvlist, 0x0026, 1) != NULL; @@ -597,7 +597,7 @@ { if (od->authinfo != NULL) { - g_free(od->authinfo->sn); + g_free(od->authinfo->bn); g_free(od->authinfo->bosip); g_free(od->authinfo->errorurl); g_free(od->authinfo->email); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_bart.c --- a/libpurple/protocols/oscar/family_bart.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_bart.c Wed Jan 28 10:23:37 2009 +0000 @@ -90,26 +90,26 @@ * Subtype 0x0004 - Request someone's icon. * * @param od The oscar session. - * @param sn The screen name of the person who's icon you are requesting. + * @param bn The name of the buddy whose icon you are requesting. * @param iconcsum The MD5 checksum of the icon you are requesting. * @param iconcsumlen Length of the MD5 checksum given above. Should be 10 bytes. * @return Return 0 if no errors, otherwise return the error number. */ int -aim_bart_request(OscarData *od, const char *sn, guint8 iconcsumtype, const guint8 *iconcsum, guint16 iconcsumlen) +aim_bart_request(OscarData *od, const char *bn, guint8 iconcsumtype, const guint8 *iconcsum, guint16 iconcsumlen) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_BART)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_BART)) || !bn || !strlen(bn) || !iconcsum || !iconcsumlen) return -EINVAL; - byte_stream_new(&bs, 1+strlen(sn) + 4 + 1+iconcsumlen); + byte_stream_new(&bs, 1+strlen(bn) + 4 + 1+iconcsumlen); - /* Screen name */ - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + /* Buddy name */ + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); /* Some numbers. You like numbers, right? */ byte_stream_put8(&bs, 0x01); @@ -138,11 +138,11 @@ { int ret = 0; aim_rxcallback_t userfunc; - char *sn; + char *bn; guint16 flags, iconlen; guint8 iconcsumtype, iconcsumlen, *iconcsum, *icon; - sn = byte_stream_getstr(bs, byte_stream_get8(bs)); + bn = byte_stream_getstr(bs, byte_stream_get8(bs)); flags = byte_stream_get16(bs); iconcsumtype = byte_stream_get8(bs); iconcsumlen = byte_stream_get8(bs); @@ -151,9 +151,9 @@ icon = byte_stream_getraw(bs, iconlen); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, sn, iconcsumtype, iconcsum, iconcsumlen, icon, iconlen); + ret = userfunc(od, conn, frame, bn, iconcsumtype, iconcsum, iconcsumlen, icon, iconlen); - g_free(sn); + g_free(bn); g_free(iconcsum); g_free(icon); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_bos.c --- a/libpurple/protocols/oscar/family_bos.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_bos.c Wed Jan 28 10:23:37 2009 +0000 @@ -94,8 +94,7 @@ * AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names * AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again * - * list should be a list of - * screen names in the form "Screen Name One&ScreenNameTwo&" etc. + * list should be a list of "Buddy Name One&BuddyNameTwo&" etc. * * Equivelents to options in WinAIM: * - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_buddy.c --- a/libpurple/protocols/oscar/family_buddy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Wed Jan 28 10:23:37 2009 +0000 @@ -121,7 +121,7 @@ * * This just builds the "set buddy list" command then queues it. * - * buddy_list = "Screen Name One&ScreenNameTwo&"; + * buddy_list = "Buddy Name One&BuddyNameTwo&"; * * XXX Clean this up. * @@ -222,7 +222,7 @@ ret = userfunc(od, conn, frame, &userinfo); if (snac->subtype == SNAC_SUBTYPE_BUDDY_ONCOMING && userinfo.flags & AIM_FLAG_AWAY) - aim_locate_autofetch_away_message(od, userinfo.sn); + aim_locate_autofetch_away_message(od, userinfo.bn); aim_info_free(&userinfo); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_feedbag.c --- a/libpurple/protocols/oscar/family_feedbag.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Wed Jan 28 10:23:37 2009 +0000 @@ -243,7 +243,7 @@ if (!cur1->name && cur2->name) return 6; - if (cur1->name && cur2->name && aim_sncmp(cur1->name, cur2->name)) + if (cur1->name && cur2->name && oscar_util_name_compare(cur1->name, cur2->name)) return 7; if (cur1->gid != cur2->gid) @@ -285,8 +285,8 @@ } /** - * Locally find an item given a group name, screen name, and type. If group name - * and screen name are null, then just return the first item of the given type. + * Locally find an item given a group name, buddy name, and type. If group name + * and buddy name are null, then just return the first item of the given type. * * @param list A pointer to the current list of items. * @param gn The group name of the desired item. @@ -294,31 +294,31 @@ * @param type The type of the desired item. * @return Return a pointer to the item if found, else return NULL. */ -struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *sn, guint16 type) +struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type) { struct aim_ssi_item *cur; if (!list) return NULL; - if (gn && sn) { /* For finding buddies in groups */ + if (gn && bn) { /* For finding buddies in groups */ for (cur=list; cur; cur=cur->next) - if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) { + if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) { struct aim_ssi_item *curg; for (curg=list; curg; curg=curg->next) - if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(aim_sncmp(curg->name, gn))) + if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(oscar_util_name_compare(curg->name, gn))) return cur; } } else if (gn) { /* For finding groups */ for (cur=list; cur; cur=cur->next) { - if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(aim_sncmp(cur->name, gn))) { + if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(oscar_util_name_compare(cur->name, gn))) { return cur; } } - } else if (sn) { /* For finding permits, denies, and ignores */ + } else if (bn) { /* For finding permits, denies, and ignores */ for (cur=list; cur; cur=cur->next) { - if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) { + if ((cur->type == type) && (cur->name) && !(oscar_util_name_compare(cur->name, bn))) { return cur; } } @@ -336,14 +336,14 @@ * Check if the given buddy exists in any group in the buddy list. * * @param list A pointer to the current list of items. - * @param sn The group name of the desired item. + * @param bn The group name of the desired item. * @return Return a pointer to the name of the item if found, else return NULL; */ -struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *sn) +struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn) { - if (!sn) + if (!bn) return NULL; - return aim_ssi_itemlist_finditem(list, NULL, sn, AIM_SSI_TYPE_BUDDY); + return aim_ssi_itemlist_finditem(list, NULL, bn, AIM_SSI_TYPE_BUDDY); } /** @@ -353,12 +353,12 @@ * @param bn The buddy name of the desired item. * @return Return a pointer to the name of the item if found, else return NULL; */ -char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *sn) +char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn) { struct aim_ssi_item *cur, *curg; - if (!list || !sn) + if (!list || !bn) return NULL; - if (!(cur = aim_ssi_itemlist_exists(list, sn))) + if (!(cur = aim_ssi_itemlist_exists(list, bn))) return NULL; if (!(curg = aim_ssi_itemlist_find(list, cur->gid, 0x0000))) return NULL; @@ -406,14 +406,14 @@ * * @param list A pointer to the current list of items. * @param gn The group of the buddy. - * @param sn The name of the buddy. + * @param bn The name of the buddy. * @return A pointer to a NULL terminated string that is the buddy's * alias, or NULL if the buddy has no alias. You should free * this returned value! */ -char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn) +char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn) { - struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); + struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); if (cur) { aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x0131, 1); if (tlv && tlv->length) @@ -427,14 +427,14 @@ * * @param list A pointer to the current list of items. * @param gn The group of the buddy. - * @param sn The name of the buddy. + * @param bn The name of the buddy. * @return A pointer to a NULL terminated string that is the buddy's * comment, or NULL if the buddy has no comment. You should free * this returned value! */ -char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *sn) +char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn) { - struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); + struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); if (cur) { aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x013c, 1); if (tlv && tlv->length) { @@ -449,12 +449,12 @@ * * @param list A pointer to the current list of items. * @param gn The group of the buddy. - * @param sn The name of the buddy. + * @param bn The name of the buddy. * @return 1 if you are waiting for authorization; 0 if you are not */ -gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn) +gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn) { - struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); + struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, bn, AIM_SSI_TYPE_BUDDY); if (cur) { if (aim_tlv_gettlv(cur->data, 0x0066, 1)) return TRUE; @@ -678,7 +678,7 @@ cur2 = cur->next; while (cur2) { next2 = cur2->next; - if ((cur->type == cur2->type) && (cur->gid == cur2->gid) && (cur->name != NULL) && (cur2->name != NULL) && (!aim_sncmp(cur->name, cur2->name))) { + if ((cur->type == cur2->type) && (cur->gid == cur2->gid) && (cur->name != NULL) && (cur2->name != NULL) && (!oscar_util_name_compare(cur->name, cur2->name))) { aim_ssi_itemlist_del(&od->ssi.local, cur2); } cur2 = next2; @@ -916,16 +916,16 @@ * @param od The oscar odion. * @param oldgn The group that the buddy is currently in. * @param newgn The group that the buddy should be moved in to. - * @param sn The name of the buddy to be moved. + * @param bn The name of the buddy to be moved. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn) +int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *bn) { struct aim_ssi_item *buddy; GSList *data; /* Find the buddy */ - buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, sn, AIM_SSI_TYPE_BUDDY); + buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, bn, AIM_SSI_TYPE_BUDDY); if (buddy == NULL) return -EINVAL; @@ -933,10 +933,10 @@ data = aim_tlvlist_copy(buddy->data); /* Delete the old item */ - aim_ssi_delbuddy(od, sn, oldgn); + aim_ssi_delbuddy(od, bn, oldgn); /* Add the new item using the EXACT SAME TLV list */ - aim_ssi_addbuddy(od, sn, newgn, data, NULL, NULL, NULL, FALSE); + aim_ssi_addbuddy(od, bn, newgn, data, NULL, NULL, NULL, FALSE); return 0; } @@ -946,19 +946,19 @@ * * @param od The oscar odion. * @param gn The group that the buddy is currently in. - * @param sn The screen name of the buddy. + * @param bn The name of the buddy. * @param alias The new alias for the buddy, or NULL if you want to remove * a buddy's comment. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *sn, const char *alias) +int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *bn, const char *alias) { struct aim_ssi_item *tmp; - if (!od || !gn || !sn) + if (!od || !gn || !bn) return -EINVAL; - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY))) + if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY))) return -EINVAL; /* Either add or remove the 0x0131 TLV from the TLV chain */ @@ -976,19 +976,19 @@ * * @param od The oscar odion. * @param gn The group that the buddy is currently in. - * @param sn The screen name of the buddy. + * @param bn The name of the buddy. * @param alias The new comment for the buddy, or NULL if you want to remove * a buddy's comment. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_editcomment(OscarData *od, const char *gn, const char *sn, const char *comment) +int aim_ssi_editcomment(OscarData *od, const char *gn, const char *bn, const char *comment) { struct aim_ssi_item *tmp; - if (!od || !gn || !sn) + if (!od || !gn || !bn) return -EINVAL; - if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY))) + if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, gn, bn, AIM_SSI_TYPE_BUDDY))) return -EINVAL; /* Either add or remove the 0x0131 TLV from the TLV chain */ @@ -1681,20 +1681,20 @@ * Authorizes a contact so they can add you to their contact list. * */ -int aim_ssi_sendauth(OscarData *od, char *sn, char *msg) +int aim_ssi_sendauth(OscarData *od, char *bn, char *msg) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !bn) return -EINVAL; - byte_stream_new(&bs, 1+strlen(sn) + 2+(msg ? strlen(msg)+1 : 0) + 2); + byte_stream_new(&bs, 1+strlen(bn) + 2+(msg ? strlen(msg)+1 : 0) + 2); - /* Screen name */ - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + /* Username */ + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); /* Message (null terminated) */ byte_stream_put16(&bs, msg ? strlen(msg) : 0); @@ -1722,13 +1722,13 @@ int ret = 0; aim_rxcallback_t userfunc; guint16 tmp; - char *sn, *msg; + char *bn, *msg; - /* Read screen name */ + /* Read buddy name */ if ((tmp = byte_stream_get8(bs))) - sn = byte_stream_getstr(bs, tmp); + bn = byte_stream_getstr(bs, tmp); else - sn = NULL; + bn = NULL; /* Read message (null terminated) */ if ((tmp = byte_stream_get16(bs))) @@ -1740,9 +1740,9 @@ tmp = byte_stream_get16(bs); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, sn, msg); + ret = userfunc(od, conn, frame, bn, msg); - g_free(sn); + g_free(bn); g_free(msg); return ret; @@ -1755,20 +1755,20 @@ * granted, denied, or dropped. * */ -int aim_ssi_sendauthrequest(OscarData *od, char *sn, const char *msg) +int aim_ssi_sendauthrequest(OscarData *od, char *bn, const char *msg) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !bn) return -EINVAL; - byte_stream_new(&bs, 1+strlen(sn) + 2+(msg ? strlen(msg)+1 : 0) + 2); + byte_stream_new(&bs, 1+strlen(bn) + 2+(msg ? strlen(msg)+1 : 0) + 2); - /* Screen name */ - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + /* Username */ + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); /* Message (null terminated) */ byte_stream_put16(&bs, msg ? strlen(msg) : 0); @@ -1796,13 +1796,13 @@ int ret = 0; aim_rxcallback_t userfunc; guint16 tmp; - char *sn, *msg; + char *bn, *msg; - /* Read screen name */ + /* Read buddy name */ if ((tmp = byte_stream_get8(bs))) - sn = byte_stream_getstr(bs, tmp); + bn = byte_stream_getstr(bs, tmp); else - sn = NULL; + bn = NULL; /* Read message (null terminated) */ if ((tmp = byte_stream_get16(bs))) @@ -1814,9 +1814,9 @@ tmp = byte_stream_get16(bs); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, sn, msg); + ret = userfunc(od, conn, frame, bn, msg); - g_free(sn); + g_free(bn); g_free(msg); return ret; @@ -1832,20 +1832,20 @@ * if reply=0x01 then grant * */ -int aim_ssi_sendauthreply(OscarData *od, char *sn, guint8 reply, const char *msg) +int aim_ssi_sendauthreply(OscarData *od, char *bn, guint8 reply, const char *msg) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_FEEDBAG)) || !bn) return -EINVAL; - byte_stream_new(&bs, 1+strlen(sn) + 1 + 2+(msg ? (strlen(msg)+1) : 0) + 2); + byte_stream_new(&bs, 1+strlen(bn) + 1 + 2+(msg ? (strlen(msg)+1) : 0) + 2); - /* Screen name */ - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + /* Username */ + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); /* Grant or deny */ byte_stream_put8(&bs, reply); @@ -1880,13 +1880,13 @@ aim_rxcallback_t userfunc; guint16 tmp; guint8 reply; - char *sn, *msg; + char *bn, *msg; - /* Read screen name */ + /* Read buddy name */ if ((tmp = byte_stream_get8(bs))) - sn = byte_stream_getstr(bs, tmp); + bn = byte_stream_getstr(bs, tmp); else - sn = NULL; + bn = NULL; /* Read reply */ reply = byte_stream_get8(bs); @@ -1901,9 +1901,9 @@ tmp = byte_stream_get16(bs); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, sn, reply, msg); + ret = userfunc(od, conn, frame, bn, reply, msg); - g_free(sn); + g_free(bn); g_free(msg); return ret; @@ -1917,18 +1917,18 @@ int ret = 0; aim_rxcallback_t userfunc; guint16 tmp; - char *sn; + char *bn; - /* Read screen name */ + /* Read buddy name */ if ((tmp = byte_stream_get8(bs))) - sn = byte_stream_getstr(bs, tmp); + bn = byte_stream_getstr(bs, tmp); else - sn = NULL; + bn = NULL; if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, sn); + ret = userfunc(od, conn, frame, bn); - g_free(sn); + g_free(bn); return ret; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_icbm.c --- a/libpurple/protocols/oscar/family_icbm.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Wed Jan 28 10:23:37 2009 +0000 @@ -61,16 +61,16 @@ * @param bs The bstream to write the ICBM header to. * @param c c is for cookie, and cookie is for me. * @param channel The ICBM channel (1 through 4). - * @param sn Null-terminated scrizeen nizame. + * @param bn Null-terminated scrizeen nizame. * @return The number of bytes written. It's really not useful. */ -static int aim_im_puticbm(ByteStream *bs, const guchar *c, guint16 channel, const char *sn) +static int aim_im_puticbm(ByteStream *bs, const guchar *c, guint16 channel, const char *bn) { byte_stream_putraw(bs, c, 8); byte_stream_put16(bs, channel); - byte_stream_put8(bs, strlen(sn)); - byte_stream_putstr(bs, sn); - return 8+2+1+strlen(sn); + byte_stream_put8(bs, strlen(bn)); + byte_stream_putstr(bs, bn); + return 8+2+1+strlen(bn); } /** @@ -324,7 +324,7 @@ aim_icbm_makecookie(cookie); /* ICBM header */ - aim_im_puticbm(&data, cookie, 0x0001, args->destsn); + aim_im_puticbm(&data, cookie, 0x0001, args->destbn); /* Message TLV (type 0x0002) */ byte_stream_put16(&data, 0x0002); @@ -410,7 +410,7 @@ } /* XXX - should be optional */ - snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1); + snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, args->destbn, strlen(args->destbn)+1); flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0006, 0x0000, snacid, &data); byte_stream_destroy(&data); @@ -431,11 +431,11 @@ * that requires an explicit message length. Use aim_im_sendch1_ext(). * */ -int aim_im_sendch1(OscarData *od, const char *sn, guint16 flags, const char *msg) +int aim_im_sendch1(OscarData *od, const char *bn, guint16 flags, const char *msg) { struct aim_sendimext_args args; - args.destsn = sn; + args.destbn = bn; args.flags = flags; args.msg = msg; args.msglen = strlen(msg); @@ -451,7 +451,7 @@ /* * Subtype 0x0006 - Send a chat invitation. */ -int aim_im_sendch2_chatinvite(OscarData *od, const char *sn, const char *msg, guint16 exchange, const char *roomname, guint16 instance) +int aim_im_sendch2_chatinvite(OscarData *od, const char *bn, const char *msg, guint16 exchange, const char *roomname, guint16 instance) { FlapConnection *conn; ByteStream bs; @@ -465,18 +465,18 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM))) return -EINVAL; - if (!sn || !msg || !roomname) + if (!bn || !msg || !roomname) return -EINVAL; aim_icbm_makecookie(cookie); - byte_stream_new(&bs, 1142+strlen(sn)+strlen(roomname)+strlen(msg)); - - snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, sn, strlen(sn)+1); + byte_stream_new(&bs, 1142+strlen(bn)+strlen(roomname)+strlen(msg)); + + snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, bn, strlen(bn)+1); /* XXX should be uncached by an unwritten 'invite accept' handler */ priv = g_malloc(sizeof(struct aim_invite_priv)); - priv->sn = g_strdup(sn); + priv->bn = g_strdup(bn); priv->roomname = g_strdup(roomname); priv->exchange = exchange; priv->instance = instance; @@ -487,7 +487,7 @@ g_free(priv); /* ICBM Header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); /* * TLV t(0005) @@ -532,7 +532,7 @@ * This is also performance sensitive. (If you can believe it...) * */ -int aim_im_sendch2_icon(OscarData *od, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum) +int aim_im_sendch2_icon(OscarData *od, const char *bn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum) { FlapConnection *conn; ByteStream bs; @@ -542,17 +542,17 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM))) return -EINVAL; - if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN)) + if (!bn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN)) return -EINVAL; aim_icbm_makecookie(cookie); - byte_stream_new(&bs, 8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2); + byte_stream_new(&bs, 8+2+1+strlen(bn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); /* * TLV t(0005) @@ -623,7 +623,7 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM))) return -EINVAL; - if (!args || !args->destsn || !args->rtfmsg) + if (!args || !args->destbn || !args->rtfmsg) return -EINVAL; servdatalen = 2+2+16+2+4+1+2 + 2+2+4+4+4 + 2+4+2+strlen(args->rtfmsg)+1 + 4+4+4+strlen(rtfcap)+1; @@ -635,7 +635,7 @@ snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, args->destsn); + aim_im_puticbm(&bs, cookie, 0x0002, args->destbn); /* TLV t(0005) - Encompasses everything below. */ byte_stream_put16(&bs, 0x0005); @@ -708,12 +708,12 @@ if (conn == NULL) return; - byte_stream_new(&bs, 118+strlen(peer_conn->sn)); + byte_stream_new(&bs, 118+strlen(peer_conn->bn)); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn); + aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->bn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -757,12 +757,12 @@ if (conn == NULL) return; - byte_stream_new(&bs, 11+strlen(peer_conn->sn) + 4+2+8+16); + byte_stream_new(&bs, 11+strlen(peer_conn->bn) + 4+2+8+16); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->sn); + aim_im_puticbm(&bs, peer_conn->cookie, 0x0002, peer_conn->bn); byte_stream_put16(&bs, 0x0005); byte_stream_put16(&bs, 0x001a); @@ -783,7 +783,7 @@ * "I want to connect through a proxy server" */ void -aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber) +aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 port, guint16 requestnumber) { FlapConnection *conn; ByteStream bs; @@ -795,12 +795,12 @@ if (conn == NULL) return; - byte_stream_new(&bs, 246+strlen(sn)); + byte_stream_new(&bs, 246+strlen(bn)); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -835,7 +835,7 @@ * remote user to connect to us via a proxy server. */ void -aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber) +aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 pin, guint16 requestnumber) { FlapConnection *conn; ByteStream bs; @@ -848,12 +848,12 @@ if (conn == NULL) return; - byte_stream_new(&bs, 246+strlen(sn)); + byte_stream_new(&bs, 246+strlen(bn)); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -898,7 +898,7 @@ * */ void -aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles) +aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles) { FlapConnection *conn; ByteStream bs; @@ -915,7 +915,7 @@ snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -981,7 +981,7 @@ * remote user to connect to us via a proxy server. */ void -aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles) +aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles) { FlapConnection *conn; ByteStream bs; @@ -999,7 +999,7 @@ snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); @@ -1073,29 +1073,29 @@ * Subtype 0x0006 - Request the status message of the given ICQ user. * * @param od The oscar session. - * @param sn The UIN of the user of whom you wish to request info. + * @param bn The UIN of the user of whom you wish to request info. * @param type The type of info you wish to request. This should be the current * state of the user, as one of the AIM_ICQ_STATE_* defines. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_im_sendch2_geticqaway(OscarData *od, const char *sn, int type) +int aim_im_sendch2_geticqaway(OscarData *od, const char *bn, int type) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; guchar cookie[8]; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM)) || !bn) return -EINVAL; aim_icbm_makecookie(cookie); - byte_stream_new(&bs, 8+2+1+strlen(sn) + 4+0x5e + 4); + byte_stream_new(&bs, 8+2+1+strlen(bn) + 4+0x5e + 4); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0002, sn); + aim_im_puticbm(&bs, cookie, 0x0002, bn); /* TLV t(0005) - Encompasses almost everything below. */ byte_stream_put16(&bs, 0x0005); /* T */ @@ -1176,12 +1176,12 @@ * but thats ok, because it gives me time to try to figure out what kind of drugs the AOL people * were taking when they merged the two protocols. * - * @param sn The destination screen name. + * @param bn The destination buddy name. * @param type The type of message. 0x0007 for authorization denied. 0x0008 for authorization granted. * @param message The message you want to send, it should be null terminated. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_im_sendch4(OscarData *od, const char *sn, guint16 type, const char *message) +int aim_im_sendch4(OscarData *od, const char *bn, guint16 type, const char *message) { FlapConnection *conn; ByteStream bs; @@ -1191,17 +1191,17 @@ if (!od || !(conn = flap_connection_findbygroup(od, 0x0002))) return -EINVAL; - if (!sn || !type || !message) + if (!bn || !type || !message) return -EINVAL; - byte_stream_new(&bs, 8+3+strlen(sn)+12+strlen(message)+1+4); + byte_stream_new(&bs, 8+3+strlen(bn)+12+strlen(message)+1+4); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0006, 0x0000, NULL, 0); aim_icbm_makecookie(cookie); /* ICBM header */ - aim_im_puticbm(&bs, cookie, 0x0004, sn); + aim_im_puticbm(&bs, cookie, 0x0004, bn); /* * TLV t(0005) @@ -1246,8 +1246,8 @@ guchar cookie[8]; guint16 channel; GSList *tlvlist; - char *sn; - int snlen; + char *bn; + int bnlen; guint16 icbmflags = 0; guint8 flag1 = 0, flag2 = 0; gchar *msg = NULL; @@ -1264,8 +1264,8 @@ return 0; } - snlen = byte_stream_get8(bs); - sn = byte_stream_getstr(bs, snlen); + bnlen = byte_stream_get8(bs); + bn = byte_stream_getstr(bs, bnlen); tlvlist = aim_tlvlist_read(bs); @@ -1296,9 +1296,9 @@ } if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, channel, sn, msg, icbmflags, flag1, flag2); - - g_free(sn); + ret = userfunc(od, conn, frame, channel, bn, msg, icbmflags, flag1, flag2); + + g_free(bn); g_free(msg); aim_tlvlist_free(tlvlist); @@ -1480,7 +1480,7 @@ msglen = byte_stream_get16(&mbs); if (msglen > byte_stream_empty(&mbs)) { - purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); + purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn); break; } @@ -1588,7 +1588,7 @@ if (length > byte_stream_empty(bs)) { - purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); + purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn); break; } @@ -1611,7 +1611,7 @@ args.featureslen = byte_stream_get16(bs); if (args.featureslen > byte_stream_empty(bs)) { - purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); + purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn); break; } if (args.featureslen == 0) @@ -1686,7 +1686,7 @@ if (length > byte_stream_empty(bs)) { - purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->sn); + purple_debug_misc("oscar", "Received an IM containing an invalid message part from %s. They are probably trying to do something malicious.\n", userinfo->bn); break; } g_free(args.extdata); @@ -1761,7 +1761,7 @@ bnlen = byte_stream_get16(servdata); bn = byte_stream_getstr(servdata, bnlen); - purple_debug_misc("oscar", "got a buddy list from %s: group %s, buddy %s\n", userinfo->sn, gn, bn); + purple_debug_misc("oscar", "got a buddy list from %s: group %s, buddy %s\n", userinfo->bn, gn, bn); g_free(bn); } @@ -2250,7 +2250,7 @@ } /* - * Subtype 0x0008 - Send a warning to sn. + * Subtype 0x0008 - Send a warning to bn. * * Flags: * AIM_WARN_ANON Send as an anonymous (doesn't count as much) @@ -2258,21 +2258,21 @@ * returns -1 on error (couldn't alloc packet), 0 on success. * */ -int aim_im_warn(OscarData *od, FlapConnection *conn, const char *sn, guint32 flags) +int aim_im_warn(OscarData *od, FlapConnection *conn, const char *bn, guint32 flags) { ByteStream bs; aim_snacid_t snacid; - if (!od || !conn || !sn) + if (!od || !conn || !bn) return -EINVAL; - byte_stream_new(&bs, strlen(sn)+3); - - snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0008, 0x0000, sn, strlen(sn)+1); + byte_stream_new(&bs, strlen(bn)+3); + + snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0008, 0x0000, bn, strlen(bn)+1); byte_stream_put16(&bs, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000); - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); flap_connection_send_snac(od, conn, SNAC_FAMILY_ICBM, 0x0008, 0x0000, snacid, &bs); @@ -2314,7 +2314,7 @@ * AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers" * */ -int aim_im_denytransfer(OscarData *od, const char *sn, const guchar *cookie, guint16 code) +int aim_im_denytransfer(OscarData *od, const char *bn, const guchar *cookie, guint16 code) { FlapConnection *conn; ByteStream bs; @@ -2324,15 +2324,15 @@ if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM))) return -EINVAL; - byte_stream_new(&bs, 8+2+1+strlen(sn)+6); + byte_stream_new(&bs, 8+2+1+strlen(bn)+6); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x000b, 0x0000, NULL, 0); byte_stream_putraw(&bs, cookie, 8); byte_stream_put16(&bs, 0x0002); /* channel */ - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); aim_tlvlist_add_16(&tlvlist, 0x0003, code); aim_tlvlist_write(&bs, &tlvlist); @@ -2345,7 +2345,7 @@ return 0; } -static void parse_status_note_text(OscarData *od, guchar *cookie, char *sn, ByteStream *bs) +static void parse_status_note_text(OscarData *od, guchar *cookie, char *bn, ByteStream *bs) { struct aim_icq_info *info; struct aim_icq_info *prev_info; @@ -2499,10 +2499,10 @@ g_free(status_note_text); g_free(stripped_status_note_text); - buddy = purple_find_buddy(account, sn); + buddy = purple_find_buddy(account, bn); if (buddy == NULL) { - purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", sn); + purple_debug_misc("oscar", "clientautoresp: buddy %s was not found.\n", bn); g_free(status_note); return; } @@ -2513,7 +2513,7 @@ presence = purple_buddy_get_presence(buddy); status = purple_presence_get_active_status(presence); - purple_prpl_got_user_status(account, sn, + purple_prpl_got_user_status(account, bn, purple_status_get_id(status), "message", status_note, NULL); @@ -2530,26 +2530,26 @@ int ret = 0; aim_rxcallback_t userfunc; guint16 channel, reason; - char *sn; + char *bn; guchar *cookie; - guint8 snlen; + guint8 bnlen; cookie = byte_stream_getraw(bs, 8); channel = byte_stream_get16(bs); - snlen = byte_stream_get8(bs); - sn = byte_stream_getstr(bs, snlen); + bnlen = byte_stream_get8(bs); + bn = byte_stream_getstr(bs, bnlen); reason = byte_stream_get16(bs); if (channel == 0x0002) { if (reason == 0x0003) /* channel-specific */ /* parse status note text */ - parse_status_note_text(od, cookie, sn, bs); + parse_status_note_text(od, cookie, bn, bs); byte_stream_get16(bs); /* Unknown */ byte_stream_get16(bs); /* Unknown */ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, channel, sn, reason, cookie); + ret = userfunc(od, conn, frame, channel, bn, reason, cookie); } else if (channel == 0x0004) { /* ICQ message */ switch (reason) { @@ -2594,20 +2594,20 @@ msg = byte_stream_getraw(bs, len); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, channel, sn, reason, state, msg); + ret = userfunc(od, conn, frame, channel, bn, reason, state, msg); g_free(msg); } break; default: { if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, channel, sn, reason); + ret = userfunc(od, conn, frame, channel, bn, reason); } break; } /* end switch */ } g_free(cookie); - g_free(sn); + g_free(bn); return ret; } @@ -2625,17 +2625,17 @@ aim_rxcallback_t userfunc; guint16 ch; guchar *cookie; - char *sn; + char *bn; int ret = 0; cookie = byte_stream_getraw(bs, 8); ch = byte_stream_get16(bs); - sn = byte_stream_getstr(bs, byte_stream_get8(bs)); + bn = byte_stream_getstr(bs, byte_stream_get8(bs)); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, ch, sn); - - g_free(sn); + ret = userfunc(od, conn, frame, ch, bn); + + g_free(bn); g_free(cookie); return ret; @@ -2672,7 +2672,7 @@ * and Purple 0.60 and newer. * */ -int aim_im_sendmtn(OscarData *od, guint16 type1, const char *sn, guint16 type2) +int aim_im_sendmtn(OscarData *od, guint16 type1, const char *bn, guint16 type2) { FlapConnection *conn; ByteStream bs; @@ -2681,10 +2681,10 @@ if (!od || !(conn = flap_connection_findbygroup(od, 0x0002))) return -EINVAL; - if (!sn) + if (!bn) return -EINVAL; - byte_stream_new(&bs, 11+strlen(sn)+2); + byte_stream_new(&bs, 11+strlen(bn)+2); snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x0014, 0x0000, NULL, 0); @@ -2703,10 +2703,10 @@ byte_stream_put16(&bs, type1); /* - * Dest sn + * Dest buddy name */ - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); /* * Type 2 (should be 0x0000, 0x0001, or 0x0002 for mtn) @@ -2731,20 +2731,20 @@ { int ret = 0; aim_rxcallback_t userfunc; - char *sn; - guint8 snlen; + char *bn; + guint8 bnlen; guint16 type1, type2; byte_stream_advance(bs, 8); /* Unknown - All 0's */ type1 = byte_stream_get16(bs); - snlen = byte_stream_get8(bs); - sn = byte_stream_getstr(bs, snlen); + bnlen = byte_stream_get8(bs); + bn = byte_stream_getstr(bs, bnlen); type2 = byte_stream_get16(bs); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, type1, sn, type2); - - g_free(sn); + ret = userfunc(od, conn, frame, type1, bn, type2); + + g_free(bn); return ret; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_locate.c --- a/libpurple/protocols/oscar/family_locate.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Wed Jan 28 10:23:37 2009 +0000 @@ -100,7 +100,7 @@ 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}, /* Supports "new status message features" (Who advertises this one?) */ - /* OSCAR_CAPABILITY_HOST_STATUS_TEXT_AWARE */ + /* OSCAR_CAPABILITY_HOST_STATUS_TEXT_AWARE */ {OSCAR_CAPABILITY_GENERICUNKNOWN, {0x09, 0x46, 0x01, 0x0a, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, @@ -112,7 +112,7 @@ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, /* Client only asserts caps for services in which it is participating */ - /* OSCAR_CAPABILITY_SMARTCAPS */ + /* OSCAR_CAPABILITY_SMARTCAPS */ {OSCAR_CAPABILITY_GENERICUNKNOWN, {0x09, 0x46, 0x01, 0xff, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, @@ -253,11 +253,11 @@ FlapConnection *conn; aim_rxcallback_t userfunc; - cur = aim_locate_finduserinfo(od, userinfo->sn); + cur = aim_locate_finduserinfo(od, userinfo->bn); if (cur == NULL) { cur = (aim_userinfo_t *)g_new0(aim_userinfo_t, 1); - cur->sn = g_strdup(userinfo->sn); + cur->bn = g_strdup(userinfo->bn); cur->next = od->locate.userinfo; od->locate.userinfo = cur; } @@ -366,35 +366,35 @@ } /** - * Remove this screen name from our queue. If this info was requested + * Remove this buddy name from our queue. If this info was requested * by our info request queue, then pop the next element off of the queue. * * @param od The aim session. - * @param sn Screen name of the info we just received. + * @param bn Buddy name of the info we just received. * @return True if the request was explicit (client requested the info), * false if the request was implicit (libfaim request the info). */ static int -aim_locate_gotuserinfo(OscarData *od, FlapConnection *conn, const char *sn) +aim_locate_gotuserinfo(OscarData *od, FlapConnection *conn, const char *bn) { struct userinfo_node *cur, *del; int was_explicit = TRUE; - while ((od->locate.requested != NULL) && (aim_sncmp(sn, od->locate.requested->sn) == 0)) { + while ((od->locate.requested != NULL) && (oscar_util_name_compare(bn, od->locate.requested->bn) == 0)) { del = od->locate.requested; od->locate.requested = del->next; was_explicit = FALSE; - g_free(del->sn); + g_free(del->bn); g_free(del); } cur = od->locate.requested; while ((cur != NULL) && (cur->next != NULL)) { - if (aim_sncmp(sn, cur->next->sn) == 0) { + if (oscar_util_name_compare(bn, cur->next->bn) == 0) { del = cur->next; cur->next = del->next; was_explicit = FALSE; - g_free(del->sn); + g_free(del->bn); g_free(del); } else cur = cur->next; @@ -404,34 +404,34 @@ } void -aim_locate_autofetch_away_message(OscarData *od, const char *sn) +aim_locate_autofetch_away_message(OscarData *od, const char *bn) { struct userinfo_node *cur; /* Make sure we haven't already made an info request for this buddy */ for (cur = od->locate.requested; cur != NULL; cur = cur->next) - if (aim_sncmp(sn, cur->sn) == 0) + if (oscar_util_name_compare(bn, cur->bn) == 0) return; /* Add a new node to our request queue */ cur = (struct userinfo_node *)g_malloc(sizeof(struct userinfo_node)); - cur->sn = g_strdup(sn); + cur->bn = g_strdup(bn); cur->next = od->locate.requested; od->locate.requested = cur; - aim_locate_getinfoshort(od, cur->sn, 0x00000002); + aim_locate_getinfoshort(od, cur->bn, 0x00000002); } -aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *sn) { +aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *bn) { aim_userinfo_t *cur = NULL; - if (sn == NULL) + if (bn == NULL) return NULL; cur = od->locate.userinfo; while (cur != NULL) { - if (aim_sncmp(cur->sn, sn) == 0) + if (oscar_util_name_compare(cur->bn, bn) == 0) return cur; cur = cur->next; } @@ -552,7 +552,7 @@ void aim_info_free(aim_userinfo_t *info) { - g_free(info->sn); + g_free(info->bn); g_free(info->iconcsum); g_free(info->info); g_free(info->info_encoding); @@ -572,7 +572,7 @@ aim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *outinfo) { int curtlv, tlvcnt; - guint8 snlen; + guint8 bnlen; if (!bs || !outinfo) return -EINVAL; @@ -581,11 +581,11 @@ memset(outinfo, 0x00, sizeof(aim_userinfo_t)); /* - * Screen name. Stored as an unterminated string prepended with a + * Username. Stored as an unterminated string prepended with a * byte containing its length. */ - snlen = byte_stream_get8(bs); - outinfo->sn = byte_stream_getstr(bs, snlen); + bnlen = byte_stream_get8(bs); + outinfo->bn = byte_stream_getstr(bs, bnlen); /* * Warning Level. Stored as an unsigned short. @@ -881,7 +881,7 @@ */ #ifdef LOG_UNKNOWN_TLV purple_debug_misc("oscar", "userinfo: **warning: unexpected TLV:\n"); - purple_debug_misc("oscar", "userinfo: sn =%s\n", outinfo->sn); + purple_debug_misc("oscar", "userinfo: bn =%s\n", outinfo->bn); dumptlv(od, type, bs, length); #endif } @@ -906,8 +906,8 @@ if (!bs || !info) return -EINVAL; - byte_stream_put8(bs, strlen(info->sn)); - byte_stream_putstr(bs, info->sn); + byte_stream_put8(bs, strlen(info->bn)); + byte_stream_putstr(bs, info->bn); byte_stream_put16(bs, info->warnlevel); @@ -922,7 +922,7 @@ /* XXX - So, ICQ_OSCAR_SUPPORT is never defined anywhere... */ #ifdef ICQ_OSCAR_SUPPORT - if (atoi(info->sn) != 0) { + if (atoi(info->bn) != 0) { if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS) aim_tlvlist_add_16(&tlvlist, 0x0006, info->icqinfo.status); if (info->present & AIM_USERINFO_PRESENT_ICQIPADDR) @@ -953,35 +953,35 @@ aim_rxcallback_t userfunc; aim_snac_t *snac2; guint16 reason; - char *sn; + char *bn; int was_explicit; if (!(snac2 = aim_remsnac(od, snac->id))) { - purple_debug_misc("oscar", "faim: locate.c, error(): received response from unknown request!\n"); + purple_debug_misc("oscar", "locate error: received response from unknown request!\n"); return 0; } if ((snac2->family != SNAC_FAMILY_LOCATE) && (snac2->type != 0x0015)) { - purple_debug_misc("oscar", "faim: locate.c, error(): received response from invalid request! %d\n", snac2->family); + purple_debug_misc("oscar", "locate error: received response from invalid request! %d\n", snac2->family); return 0; } - if (!(sn = snac2->data)) { - purple_debug_misc("oscar", "faim: locate.c, error(): received response from request without a screen name!\n"); + if (!(bn = snac2->data)) { + purple_debug_misc("oscar", "locate error: received response from request without a buddy name!\n"); return 0; } reason = byte_stream_get16(bs); /* - * Remove this screen name from our queue. If the client requested + * Remove this buddy name from our queue. If the client requested * this buddy's info explicitly, then notify them that we do not have * info for this buddy. */ - was_explicit = aim_locate_gotuserinfo(od, conn, sn); + was_explicit = aim_locate_gotuserinfo(od, conn, bn); if (was_explicit == TRUE) if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - ret = userfunc(od, conn, frame, reason, sn); + ret = userfunc(od, conn, frame, reason, bn); if (snac2) g_free(snac2->data); @@ -1157,29 +1157,29 @@ /* * Subtype 0x0005 - Request info of another AIM user. * - * @param sn The screenname whose info you wish to request. + * @param bn The buddy name whose info you wish to request. * @param infotype The type of info you wish to request. * 0x0001 - Info/profile * 0x0003 - Away message * 0x0004 - Capabilities */ int -aim_locate_getinfo(OscarData *od, const char *sn, guint16 infotype) +aim_locate_getinfo(OscarData *od, const char *bn, guint16 infotype) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !bn) return -EINVAL; - byte_stream_new(&bs, 2+1+strlen(sn)); + byte_stream_new(&bs, 2+1+strlen(bn)); snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0005, 0x0000, NULL, 0); byte_stream_put16(&bs, infotype); - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x0005, 0x0000, snacid, &bs); @@ -1229,18 +1229,18 @@ aim_tlvlist_free(tlvlist); aim_locate_adduserinfo(od, userinfo); - userinfo2 = aim_locate_finduserinfo(od, userinfo->sn); + userinfo2 = aim_locate_finduserinfo(od, userinfo->bn); aim_info_free(userinfo); g_free(userinfo); /* - * Remove this screen name from our queue. If the client requested + * Remove this buddy name from our queue. If the client requested * this buddy's info explicitly, then notify them that we have info * for this buddy. */ if (userinfo2 != NULL) { - was_explicit = aim_locate_gotuserinfo(od, conn, userinfo2->sn); + was_explicit = aim_locate_gotuserinfo(od, conn, userinfo2->bn); if (was_explicit == TRUE) if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, userinfo2); @@ -1307,7 +1307,7 @@ /* * Subtype 0x000b - Huh? What is this? */ -int aim_locate_000b(OscarData *od, const char *sn) +int aim_locate_000b(OscarData *od, const char *bn) { FlapConnection *conn; ByteStream bs; @@ -1315,15 +1315,15 @@ return -EINVAL; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !bn) return -EINVAL; - byte_stream_new(&bs, 1+strlen(sn)); + byte_stream_new(&bs, 1+strlen(bn)); snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x000b, 0x0000, NULL, 0); - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); flap_connection_send_snac(od, conn, SNAC_FAMILY_LOCATE, 0x000b, 0x0000, snacid, &bs); @@ -1380,7 +1380,7 @@ * Subtype 0x0015 - Request the info of a user using the short method. This is * what iChat uses. It normally is VERY leniently rate limited. * - * @param sn The screen name whose info you wish to request. + * @param bn The buddy name whose info you wish to request. * @param flags The bitmask which specifies the type of info you wish to request. * 0x00000001 - Info/profile. * 0x00000002 - Away message. @@ -1389,21 +1389,21 @@ * @return Return 0 if no errors, otherwise return the error number. */ int -aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags) +aim_locate_getinfoshort(OscarData *od, const char *bn, guint32 flags) { FlapConnection *conn; ByteStream bs; aim_snacid_t snacid; - if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn) + if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !bn) return -EINVAL; - byte_stream_new(&bs, 4 + 1 + strlen(sn)); + byte_stream_new(&bs, 4 + 1 + strlen(bn)); byte_stream_put32(&bs, flags); - byte_stream_put8(&bs, strlen(sn)); - byte_stream_putstr(&bs, sn); + byte_stream_put8(&bs, strlen(bn)); + byte_stream_putstr(&bs, bn); - snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, sn, strlen(sn)+1); + snacid = aim_cachesnac(od, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, bn, strlen(bn)+1); flap_connection_send_snac_with_priority(od, conn, SNAC_FAMILY_LOCATE, 0x0015, 0x0000, snacid, &bs, FALSE); byte_stream_destroy(&bs); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/family_odir.c --- a/libpurple/protocols/oscar/family_odir.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/family_odir.c Wed Jan 28 10:23:37 2009 +0000 @@ -31,7 +31,7 @@ /** * Subtype 0x0002 - Submit a User Search Request * - * Search for an AIM screen name based on their email address. + * Search for an AIM buddy based on their email address. * * @param od The oscar session. * @param region Should be "us-ascii" unless you know what you're doing. @@ -70,7 +70,7 @@ /** * Subtype 0x0002 - Submit a User Search Request * - * Search for an AIM screen name based on various info + * Search for an AIM buddy based on various info * about the person. * * @param od The oscar session. @@ -202,7 +202,7 @@ new->country = aim_tlv_getstr(tlvlist, 0x0006, 1); new->state = aim_tlv_getstr(tlvlist, 0x0007, 1); new->city = aim_tlv_getstr(tlvlist, 0x0008, 1); - new->sn = aim_tlv_getstr(tlvlist, 0x0009, 1); + new->bn = aim_tlv_getstr(tlvlist, 0x0009, 1); new->interest = aim_tlv_getstr(tlvlist, 0x000b, 1); new->nick = aim_tlv_getstr(tlvlist, 0x000c, 1); new->zip = aim_tlv_getstr(tlvlist, 0x000d, 1); @@ -228,7 +228,7 @@ g_free(del->country); g_free(del->state); g_free(del->city); - g_free(del->sn); + g_free(del->bn); g_free(del->interest); g_free(del->nick); g_free(del->zip); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/odc.c --- a/libpurple/protocols/oscar/odc.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/odc.c Wed Jan 28 10:23:37 2009 +0000 @@ -62,7 +62,7 @@ PurpleConversation *conv; account = purple_connection_get_account(conn->od->gc); - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn); purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(tmp); } @@ -90,11 +90,11 @@ purple_debug_info("oscar", "Outgoing ODC frame to %s with " "type=0x%04x, flags=0x%04x, payload length=%u\n", - conn->sn, frame->type, frame->flags, frame->payload.len); + conn->bn, frame->type, frame->flags, frame->payload.len); account = purple_connection_get_account(conn->od->gc); username = purple_account_get_username(account); - memcpy(frame->sn, username, strlen(username)); + memcpy(frame->bn, username, strlen(username)); memcpy(frame->cookie, conn->cookie, 8); length = 76; @@ -116,7 +116,7 @@ byte_stream_put16(&bs, frame->flags); byte_stream_put16(&bs, 0x0000); byte_stream_put16(&bs, 0x0000); - byte_stream_putraw(&bs, frame->sn, 32); + byte_stream_putraw(&bs, frame->bn, 32); byte_stream_putraw(&bs, frame->payload.data, frame->payload.len); peer_connection_send(conn, &bs); @@ -366,7 +366,7 @@ g_datalist_clear(&attributes); /* Append the message up to the tag */ - utf8 = purple_plugin_oscar_decode_im_part(account, conn->sn, + utf8 = purple_plugin_oscar_decode_im_part(account, conn->bn, encoding, 0x0000, tmp, start - tmp); if (utf8 != NULL) { g_string_append(newmsg, utf8); @@ -386,7 +386,7 @@ /* Append any remaining message data */ if (tmp <= msgend) { - utf8 = purple_plugin_oscar_decode_im_part(account, conn->sn, + utf8 = purple_plugin_oscar_decode_im_part(account, conn->bn, encoding, 0x0000, tmp, msgend - tmp); if (utf8 != NULL) { g_string_append(newmsg, utf8); @@ -400,7 +400,7 @@ imflags |= PURPLE_MESSAGE_IMAGES; if (autoreply) imflags |= PURPLE_MESSAGE_AUTO_RESP; - serv_got_im(gc, conn->sn, newmsg->str, imflags, time(NULL)); + serv_got_im(gc, conn->bn, newmsg->str, imflags, time(NULL)); g_string_free(newmsg, TRUE); /* unref any images we allocated */ @@ -503,11 +503,11 @@ byte_stream_advance(bs, 4); frame->flags = byte_stream_get16(bs); byte_stream_advance(bs, 4); - byte_stream_getrawbuf(bs, frame->sn, 32); + byte_stream_getrawbuf(bs, frame->bn, 32); purple_debug_info("oscar", "Incoming ODC frame from %s with " "type=0x%04x, flags=0x%04x, payload length=%u\n", - frame->sn, frame->type, frame->flags, frame->payload.len); + frame->bn, frame->type, frame->flags, frame->payload.len); if (!conn->ready) { @@ -558,7 +558,7 @@ /* Tell the local user that we are connected */ account = purple_connection_get_account(gc); - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn); purple_conversation_write(conv, NULL, _("Direct IM established"), PURPLE_MESSAGE_SYSTEM, time(NULL)); } @@ -576,16 +576,16 @@ /* I had to leave this. It's just too funny. It reminds me of my sister. */ purple_debug_info("oscar", "ohmigod! %s has started typing " "(DirectIM). He's going to send you a message! " - "*squeal*\n", conn->sn); - serv_got_typing(gc, conn->sn, 0, PURPLE_TYPING); + "*squeal*\n", conn->bn); + serv_got_typing(gc, conn->bn, 0, PURPLE_TYPING); } else if (frame->flags & 0x0004) { - serv_got_typing(gc, conn->sn, 0, PURPLE_TYPED); + serv_got_typing(gc, conn->bn, 0, PURPLE_TYPED); } else { - serv_got_typing_stopped(gc, conn->sn); + serv_got_typing_stopped(gc, conn->bn); } if (frame->payload.len > 0) @@ -598,12 +598,12 @@ size1 = purple_str_size_to_units(frame->payload.len); size2 = purple_str_size_to_units(DIRECTIM_MAX_FILESIZE); - tmp = g_strdup_printf(_("%s tried to send you a %s file, but we only allow files up to %s over Direct IM. Try using file transfer instead.\n"), conn->sn, size1, size2); + tmp = g_strdup_printf(_("%s tried to send you a %s file, but we only allow files up to %s over Direct IM. Try using file transfer instead.\n"), conn->bn, size1, size2); g_free(size1); g_free(size2); account = purple_connection_get_account(conn->od->gc); - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn); purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(tmp); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/oft.c --- a/libpurple/protocols/oscar/oft.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/oft.c Wed Jan 28 10:23:37 2009 +0000 @@ -544,7 +544,7 @@ frame.name = byte_stream_getraw(bs, frame.name_length); purple_debug_info("oscar", "Incoming OFT frame from %s with " - "type=0x%04x\n", conn->sn, frame.type); + "type=0x%04x\n", conn->bn, frame.type); /* TODOFT: peer_oft_dirconvert_fromstupid(frame->name); */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/oscar.c Wed Jan 28 10:23:37 2009 +0000 @@ -204,7 +204,7 @@ void oscar_set_info(PurpleConnection *gc, const char *info); static void oscar_set_info_and_status(PurpleAccount *account, gboolean setinfo, const char *rawinfo, gboolean setstatus, PurpleStatus *status); static void oscar_set_extendedstatus(PurpleConnection *gc); -static void oscar_format_screenname(PurpleConnection *gc, const char *nick); +static void oscar_format_username(PurpleConnection *gc, const char *nick); static gboolean purple_ssi_rerequestdata(gpointer data); static void oscar_free_name_data(struct name_data *data) { @@ -362,7 +362,7 @@ const char *charset = NULL; char *ret = NULL; - if(aim_snvalid_icq(purple_account_get_username(account))) + if(oscar_util_valid_name_icq(purple_account_get_username(account))) charset = purple_account_get_string(account, "encoding", NULL); if(charset && *charset) @@ -414,7 +414,7 @@ * charsetstr1 is always set to what the correct encoding should be. */ gchar * -purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcesn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen) +purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcebn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen) { gchar *ret = NULL; const gchar *charsetstr1, *charsetstr2; @@ -428,7 +428,7 @@ charsetstr1 = "UTF-16BE"; charsetstr2 = "UTF-8"; } else if (charset == AIM_CHARSET_CUSTOM) { - if ((sourcesn != NULL) && aim_snvalid_icq(sourcesn)) + if ((sourcebn != NULL) && oscar_util_valid_name_icq(sourcebn)) charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); else charsetstr1 = "ISO-8859-1"; @@ -458,7 +458,7 @@ str[datalen] = '\0'; salvage = purple_utf8_salvage(str); tmp = g_strdup_printf(_("(There was an error receiving this message. Either you and %s have different encodings selected, or %s has a buggy client.)"), - sourcesn, sourcesn); + sourcebn, sourcebn); ret = g_strdup_printf("%s %s", salvage, tmp); g_free(tmp); g_free(str); @@ -473,11 +473,11 @@ */ static void purple_plugin_oscar_convert_to_best_encoding(PurpleConnection *gc, - const char *destsn, const gchar *from, + const char *destbn, const gchar *from, gchar **msg, int *msglen_int, guint16 *charset, guint16 *charsubset) { - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); GError *err = NULL; aim_userinfo_t *userinfo = NULL; @@ -499,13 +499,13 @@ * capability, and they are online, then attempt to send * as UTF-16BE. */ - if ((destsn != NULL) && aim_snvalid_icq(destsn)) - userinfo = aim_locate_finduserinfo(od, destsn); + if ((destbn != NULL) && oscar_util_valid_name_icq(destbn)) + userinfo = aim_locate_finduserinfo(od, destbn); if ((userinfo != NULL) && (userinfo->capabilities & OSCAR_CAPABILITY_UNICODE)) { PurpleBuddy *b; - b = purple_find_buddy(account, destsn); + b = purple_find_buddy(account, destbn); if ((b != NULL) && (PURPLE_BUDDY_IS_ONLINE(b))) { *msg = g_convert(from, -1, "UTF-16BE", "UTF-8", NULL, &msglen, &err); @@ -529,7 +529,7 @@ * ICQ then attempt to send as the user specified character encoding. */ charsetstr = "ISO-8859-1"; - if ((destsn != NULL) && aim_snvalid_icq(destsn)) + if ((destbn != NULL) && oscar_util_valid_name_icq(destbn)) charsetstr = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); /* @@ -808,16 +808,16 @@ gchar *message = NULL, *itmsurl = NULL, *tmp; gboolean is_away; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); if (userinfo == NULL) - userinfo = aim_locate_finduserinfo(od, b->name); + userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b)); if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL))) return; if (b == NULL) - b = purple_find_buddy(purple_connection_get_account(gc), userinfo->sn); + b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn); if (b) { presence = purple_buddy_get_presence(b); @@ -884,7 +884,7 @@ if (b) { if (purple_presence_is_online(presence)) { - if (aim_snvalid_icq(b->name) || is_away || !message || !(*message)) { + if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) { /* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message. * If the status name and the message are the same, only show one. */ const char *status_name = purple_status_get_name(status); @@ -899,21 +899,20 @@ message = tmp; } + } else if (aim_ssi_waitingforauth(od->ssi.local, + aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)), + purple_buddy_get_name(b))) + { + /* Note if an offline buddy is not authorized */ + tmp = g_strdup_printf("%s%s%s", + _("Not Authorized"), + (message && *message) ? ": " : "", + (message && *message) ? message : ""); + g_free(message); + message = tmp; } else { - if (aim_ssi_waitingforauth(od->ssi.local, - aim_ssi_itemlist_findparentname(od->ssi.local, b->name), - b->name)) { - /* Note if an offline buddy is not authorized */ - tmp = g_strdup_printf("%s%s%s", - _("Not Authorized"), - (message && *message) ? ": " : "", - (message && *message) ? message : ""); - g_free(message); - message = tmp; - } else { - g_free(message); - message = g_strdup(_("Offline")); - } + g_free(message); + message = g_strdup(_("Offline")); } } @@ -931,27 +930,30 @@ PurpleGroup *g = NULL; struct buddyinfo *bi = NULL; char *tmp; - - od = gc->proto_data; + const char *bname, *gname = NULL; + + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL))) return; + bname = purple_buddy_get_name(b); if (userinfo == NULL) - userinfo = aim_locate_finduserinfo(od, b->name); + userinfo = aim_locate_finduserinfo(od, bname); if (b == NULL) - b = purple_find_buddy(account, userinfo->sn); + b = purple_find_buddy(account, userinfo->bn); if (b != NULL) { g = purple_buddy_get_group(b); + gname = purple_group_get_name(g); presence = purple_buddy_get_presence(b); status = purple_presence_get_active_status(presence); } if (userinfo != NULL) - bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->sn)); + bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn)); if ((bi != NULL) && (bi->ipaddr != 0)) { tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", @@ -969,8 +971,8 @@ g_free(tmp); } - if ((b != NULL) && (b->name != NULL) && (g != NULL) && (g->name != NULL)) { - tmp = aim_ssi_getcomment(od->ssi.local, g->name, b->name); + if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) { + tmp = aim_ssi_getcomment(od->ssi.local, gname, bname); if (tmp != NULL) { char *tmp2 = g_markup_escape_text(tmp, strlen(tmp)); g_free(tmp); @@ -1017,7 +1019,7 @@ static struct chat_connection * find_oscar_chat(PurpleConnection *gc, int id) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); GSList *cur; struct chat_connection *cc; @@ -1034,7 +1036,7 @@ static struct chat_connection * find_oscar_chat_by_conn(PurpleConnection *gc, FlapConnection *conn) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); GSList *cur; struct chat_connection *cc; @@ -1051,7 +1053,7 @@ static struct chat_connection * find_oscar_chat_by_conv(PurpleConnection *gc, PurpleConversation *conv) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); GSList *cur; struct chat_connection *cc; @@ -1076,7 +1078,7 @@ static void oscar_chat_kill(PurpleConnection *gc, struct chat_connection *cc) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); /* Notify the conversation window that we've left the chat */ serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(cc->conv))); @@ -1292,10 +1294,10 @@ od->chpass = FALSE; } if (od->setnick) { - purple_debug_info("oscar", "formatting screen name\n"); - aim_admin_setnick(od, conn, od->newsn); - g_free(od->newsn); - od->newsn = NULL; + purple_debug_info("oscar", "formatting username\n"); + aim_admin_setnick(od, conn, od->newformatting); + g_free(od->newformatting); + od->newformatting = NULL; od->setnick = FALSE; } if (od->conf) { @@ -1391,7 +1393,7 @@ guint32 presence; gc = data; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); report_idle = strcmp((const char *)value, "none") != 0; presence = aim_ssi_getpresence(od->ssi.local); @@ -1414,7 +1416,7 @@ guint32 presence; gc = data; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); presence = aim_ssi_getpresence(od->ssi.local); if (value) @@ -1431,8 +1433,9 @@ FlapConnection *newconn; gc = purple_account_get_connection(account); - od = gc->proto_data = oscar_data_new(); + od = oscar_data_new(); od->gc = gc; + purple_connection_set_protocol_data(gc, od); oscar_data_addhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, purple_connerr, 0); oscar_data_addhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, flap_connection_established, 0); @@ -1499,7 +1502,7 @@ purple_debug_misc("oscar", "oscar_login: gc = %p\n", gc); - if (!aim_snvalid(purple_account_get_username(account))) { + if (!oscar_util_valid_name(purple_account_get_username(account))) { gchar *buf; buf = g_strdup_printf(_("Unable to login: Could not sign on as %s because the username is invalid. Usernames must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), purple_account_get_username(account)); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, buf); @@ -1507,7 +1510,7 @@ return; } - if (aim_snvalid_icq((purple_account_get_username(account)))) { + if (oscar_util_valid_name_icq((purple_account_get_username(account)))) { od->icq = TRUE; } else { gc->flags |= PURPLE_CONNECTION_HTML; @@ -1578,7 +1581,7 @@ { OscarData *od; - od = (OscarData *)gc->proto_data; + od = purple_connection_get_protocol_data(gc); while (od->oscar_chats) { @@ -1594,7 +1597,7 @@ g_free(cr); } oscar_data_destroy(od); - gc->proto_data = NULL; + purple_connection_set_protocol_data(gc, NULL); purple_prefs_disconnect_by_handle(gc); @@ -1605,7 +1608,7 @@ purple_parse_auth_resp(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; - PurpleAccount *account = gc->account; + PurpleAccount *account = purple_connection_get_account(gc); char *host; int port; int i; FlapConnection *newconn; @@ -1619,13 +1622,13 @@ va_end(ap); purple_debug_info("oscar", - "inside auth_resp (Username: %s)\n", info->sn); + "inside auth_resp (Username: %s)\n", info->bn); if (info->errorcode || !info->bosip || !info->cookielen || !info->cookie) { char buf[256]; switch (info->errorcode) { case 0x01: - /* Unregistered screen name */ + /* Unregistered username */ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_USERNAME, _("Invalid username.")); break; case 0x05: @@ -1644,7 +1647,7 @@ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("The AOL Instant Messenger service is temporarily unavailable.")); break; case 0x18: - /* screen name connecting too frequently */ + /* username connecting too frequently */ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); break; case 0x1c: @@ -1722,7 +1725,7 @@ purple_parse_auth_securid_request_yes_cb(gpointer user_data, const char *msg) { PurpleConnection *gc = user_data; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_auth_securid_send(od, msg); } @@ -1774,7 +1777,7 @@ static void damn_you(gpointer data, gint source, PurpleInputCondition c) { struct pieceofcrap *pos = data; - OscarData *od = pos->gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(pos->gc); char in = '\0'; int x = 0; unsigned char m[17]; @@ -1840,7 +1843,7 @@ pos->fd = source; if (source < 0) { - GHashTable *ui_info = purple_core_get_ui_info(); + GHashTable *ui_info = purple_core_get_ui_info(); buf = g_strdup_printf(_("You may be disconnected shortly. " "Check %s for updates."), ((ui_info && g_hash_table_lookup(ui_info, "website")) ? (char *)g_hash_table_lookup(ui_info, "website") : PURPLE_WEBSITE)); @@ -2077,28 +2080,28 @@ static gboolean purple_requesticqstatusnote(gpointer data) { PurpleConnection *gc = data; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); while (od->statusnotes_queue != NULL) { - char *sn; + char *bn; struct aim_ssi_item *ssi_item; aim_tlv_t *note_hash; - sn = od->statusnotes_queue->data; + bn = od->statusnotes_queue->data; ssi_item = aim_ssi_itemlist_finditem(od->ssi.local, - NULL, sn, AIM_SSI_TYPE_BUDDY); + NULL, bn, AIM_SSI_TYPE_BUDDY); if (ssi_item != NULL) { note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1); if (note_hash != NULL) { - aim_icq_getstatusnote(od, sn, note_hash->value, note_hash->length); + aim_icq_getstatusnote(od, bn, note_hash->value, note_hash->length); } } - od->statusnotes_queue = g_slist_remove(od->statusnotes_queue, sn); - g_free(sn); + od->statusnotes_queue = g_slist_remove(od->statusnotes_queue, bn); + g_free(bn); } od->statusnotes_queue_timer = 0; @@ -2126,7 +2129,7 @@ va_end(ap); g_return_val_if_fail(info != NULL, 1); - g_return_val_if_fail(info->sn != NULL, 1); + g_return_val_if_fail(info->bn != NULL, 1); if (info->present & AIM_USERINFO_PRESENT_FLAGS) { if (info->flags & AIM_FLAG_AWAY) @@ -2140,7 +2143,7 @@ } } - if (aim_snvalid_icq(info->sn)) { + if (oscar_util_valid_name_icq(info->bn)) { if (type & AIM_ICQ_STATE_CHAT) status_id = OSCAR_STATUS_ID_FREE4CHAT; else if (type & AIM_ICQ_STATE_DND) @@ -2166,9 +2169,9 @@ if (info->flags & AIM_FLAG_WIRELESS) { - purple_prpl_got_user_status(account, info->sn, OSCAR_STATUS_ID_MOBILE, NULL); + purple_prpl_got_user_status(account, info->bn, OSCAR_STATUS_ID_MOBILE, NULL); } else { - purple_prpl_got_user_status_deactive(account, info->sn, OSCAR_STATUS_ID_MOBILE); + purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE); } if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) @@ -2193,7 +2196,7 @@ if (tmp2 == NULL && itmsurl != NULL) tmp2 = ""; - purple_prpl_got_user_status(account, info->sn, status_id, + purple_prpl_got_user_status(account, info->bn, status_id, "message", tmp2, "itmsurl", itmsurl, NULL); g_free(tmp); @@ -2202,17 +2205,17 @@ } else { - PurpleBuddy *b = purple_find_buddy(account, info->sn); + PurpleBuddy *b = purple_find_buddy(account, info->bn); PurplePresence *presence = purple_buddy_get_presence(b); PurpleStatus *old_status = purple_presence_get_active_status(presence); PurpleStatus *new_status = purple_presence_get_status(presence, status_id); - + /* If our status_id would change with this update, pass it to the core. * However, if our status_id would not change, do nothing, as we would clear out any existing * attributes on the status prematurely. purple_got_infoblock() will update the message as needed. */ if (old_status != new_status) - purple_prpl_got_user_status(account, info->sn, status_id, NULL); + purple_prpl_got_user_status(account, info->bn, status_id, NULL); } /* Login time stuff */ @@ -2220,7 +2223,7 @@ signon = info->onlinesince; else if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN) signon = time(NULL) - info->sessionlen; - purple_prpl_got_user_login_time(account, info->sn, signon); + purple_prpl_got_user_login_time(account, info->bn, signon); /* Idle time stuff */ /* info->idletime is the number of minutes that this user has been idle */ @@ -2228,15 +2231,15 @@ time_idle = time(NULL) - info->idletime * 60; if (time_idle > 0) - purple_prpl_got_user_idle(account, info->sn, TRUE, time_idle); + purple_prpl_got_user_idle(account, info->bn, TRUE, time_idle); else - purple_prpl_got_user_idle(account, info->sn, FALSE, 0); + purple_prpl_got_user_idle(account, info->bn, FALSE, 0); /* Server stored icon stuff */ - bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, info->sn)); + bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, info->bn)); if (!bi) { bi = g_new0(struct buddyinfo, 1); - g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, info->sn)), bi); + g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, info->bn)), bi); } bi->typingnot = FALSE; bi->ico_informed = FALSE; @@ -2248,20 +2251,20 @@ PurpleBuddy *b = NULL; b16 = purple_base16_encode(info->iconcsum, info->iconcsumlen); - b = purple_find_buddy(account, info->sn); + b = purple_find_buddy(account, info->bn); if (b != NULL) saved_b16 = purple_buddy_icons_get_checksum_for_user(b); if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) { /* Invalidate the old icon for this user */ - purple_buddy_icons_set_for_user(account, info->sn, NULL, 0, NULL); + purple_buddy_icons_set_for_user(account, info->bn, NULL, 0, NULL); /* Fetch the new icon (if we're not already doing so) */ - if (g_slist_find_custom(od->requesticon, info->sn, - (GCompareFunc)aim_sncmp) == NULL) + if (g_slist_find_custom(od->requesticon, info->bn, + (GCompareFunc)oscar_util_name_compare) == NULL) { od->requesticon = g_slist_prepend(od->requesticon, - g_strdup(purple_normalize(account, info->sn))); + g_strdup(purple_normalize(account, info->bn))); purple_icons_fetch(gc); } } @@ -2284,7 +2287,7 @@ aim_tlv_t *note_hash; ssi_item = aim_ssi_itemlist_finditem(od->ssi.local, - NULL, info->sn, AIM_SSI_TYPE_BUDDY); + NULL, info->bn, AIM_SSI_TYPE_BUDDY); if (ssi_item != NULL) { note_hash = aim_tlv_gettlv(ssi_item->data, 0x015c, 1); @@ -2299,10 +2302,10 @@ * buddy. */ if (od->statusnotes_queue == NULL || - g_slist_find_custom(od->statusnotes_queue, info->sn, (GCompareFunc)strcmp) == NULL) + g_slist_find_custom(od->statusnotes_queue, info->bn, (GCompareFunc)strcmp) == NULL) { od->statusnotes_queue = g_slist_prepend(od->statusnotes_queue, - g_strdup(info->sn)); + g_strdup(info->bn)); if (od->statusnotes_queue_timer > 0) purple_timeout_remove(od->statusnotes_queue_timer); @@ -2333,9 +2336,9 @@ info = va_arg(ap, aim_userinfo_t *); va_end(ap); - purple_prpl_got_user_status(account, info->sn, OSCAR_STATUS_ID_OFFLINE, NULL); - purple_prpl_got_user_status_deactive(account, info->sn, OSCAR_STATUS_ID_MOBILE); - g_hash_table_remove(od->buddyinfo, purple_normalize(gc->account, info->sn)); + purple_prpl_got_user_status(account, info->bn, OSCAR_STATUS_ID_OFFLINE, NULL); + purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE); + g_hash_table_remove(od->buddyinfo, purple_normalize(gc->account, info->bn)); return 1; } @@ -2353,15 +2356,15 @@ GData *attribs; purple_debug_misc("oscar", "Received IM from %s with %d parts\n", - userinfo->sn, args->mpmsg.numparts); + userinfo->bn, args->mpmsg.numparts); if (args->mpmsg.numparts == 0) return 1; - bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->sn)); + bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn)); if (!bi) { bi = g_new0(struct buddyinfo, 1); - g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, userinfo->sn)), bi); + g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, userinfo->bn)), bi); } if (args->icbmflags & AIM_IMFLAGS_AWAY) @@ -2373,7 +2376,7 @@ bi->typingnot = FALSE; if ((args->icbmflags & AIM_IMFLAGS_HASICON) && (args->iconlen) && (args->iconsum) && (args->iconstamp)) { - purple_debug_misc("oscar", "%s has an icon\n", userinfo->sn); + purple_debug_misc("oscar", "%s has an icon\n", userinfo->bn); if ((args->iconlen != bi->ico_len) || (args->iconsum != bi->ico_csum) || (args->iconstamp != bi->ico_time)) { bi->ico_need = TRUE; bi->ico_len = args->iconlen; @@ -2389,8 +2392,8 @@ size_t len = purple_imgstore_get_size(img); purple_debug_info("oscar", "Sending buddy icon to %s (%" G_GSIZE_FORMAT " bytes)\n", - userinfo->sn, len); - aim_im_sendch2_icon(od, userinfo->sn, data, len, + userinfo->bn, len); + aim_im_sendch2_icon(od, userinfo->bn, data, len, purple_buddy_icons_get_account_icon_timestamp(account), aimutil_iconsum(data, len)); } @@ -2399,7 +2402,7 @@ message = g_string_new(""); curpart = args->mpmsg.parts; while (curpart != NULL) { - tmp = purple_plugin_oscar_decode_im_part(account, userinfo->sn, curpart->charset, + tmp = purple_plugin_oscar_decode_im_part(account, userinfo->bn, curpart->charset, curpart->charsubset, curpart->data, curpart->datalen); if (tmp != NULL) { g_string_append(message, tmp); @@ -2419,7 +2422,7 @@ * Note: There *may* be some clients which send messages as HTML formatted - * they need to be special-cased somehow. */ - if (aim_snvalid_icq(purple_account_get_username(account)) && aim_snvalid_icq(userinfo->sn)) { + if (oscar_util_valid_name_icq(purple_account_get_username(account)) && oscar_util_valid_name_icq(userinfo->bn)) { /* being recevied by ICQ from ICQ - escape HTML so it is displayed as sent */ gchar *tmp2 = g_markup_escape_text(tmp, -1); g_free(tmp); @@ -2457,7 +2460,7 @@ g_datalist_clear(&attribs); } - serv_got_im(gc, userinfo->sn, tmp, flags, + serv_got_im(gc, userinfo->bn, tmp, flags, (args->icbmflags & AIM_IMFLAGS_OFFLINE) ? args->timestamp : time(NULL)); g_free(tmp); @@ -2476,13 +2479,13 @@ gc = od->gc; account = purple_connection_get_account(gc); - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); if (args == NULL) return 0; purple_debug_misc("oscar", "Incoming rendezvous message of type %u, " - "user %s, status %hu\n", args->type, userinfo->sn, args->status); + "user %s, status %hu\n", args->type, userinfo->bn, args->status); if (args->msg != NULL) { @@ -2528,7 +2531,7 @@ g_strdup_printf("%d", args->info.chat.roominfo.exchange)); serv_got_chat_invite(gc, utf8name, - userinfo->sn, + userinfo->bn, message, components); } @@ -2538,14 +2541,14 @@ { if (args->status == AIM_RENDEZVOUS_PROPOSE) { - peer_connection_got_proposition(od, userinfo->sn, message, args); + peer_connection_got_proposition(od, userinfo->bn, message, args); } else if (args->status == AIM_RENDEZVOUS_CANCEL) { /* The other user canceled a peer request */ PeerConnection *conn; - conn = peer_connection_find_by_cookie(od, userinfo->sn, args->cookie); + conn = peer_connection_find_by_cookie(od, userinfo->bn, args->cookie); /* * If conn is NULL it means we haven't tried to create * a connection with that user. They may be trying to @@ -2576,7 +2579,7 @@ else if (args->type & OSCAR_CAPABILITY_BUDDYICON) { - purple_buddy_icons_set_for_user(account, userinfo->sn, + purple_buddy_icons_set_for_user(account, userinfo->bn, g_memdup(args->info.icon.icon, args->info.icon.length), args->info.icon.length, NULL); @@ -2613,9 +2616,10 @@ PurpleAccount *account; PurpleBuddy *buddy; PurpleGroup *group; + const char *bname, *gname; gc = data->gc; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); buddy = purple_find_buddy(account, data->name); if (buddy != NULL) @@ -2625,15 +2629,17 @@ if (group != NULL) { + bname = purple_buddy_get_name(buddy); + gname = purple_group_get_name(group); purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n", - buddy->name, group->name); + bname, gname); aim_ssi_sendauthrequest(od, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list.")); - if (!aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY)) + if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY)) { - aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE); + aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE); /* Mobile users should always be online */ - if (buddy->name[0] == '+') { + if (bname[0] == '+') { purple_prpl_got_user_status(account, purple_buddy_get_name(buddy), OSCAR_STATUS_ID_AVAILABLE, NULL); @@ -2673,8 +2679,8 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - purple_auth_sendrequest(gc, buddy->name); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + purple_auth_sendrequest(gc, purple_buddy_get_name(buddy)); } /* When other people ask you for authorization */ @@ -2683,7 +2689,7 @@ { struct name_data *data = cbdata; PurpleConnection *gc = data->gc; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_ssi_sendauthreply(od, data->name, 0x01, NULL); @@ -2695,7 +2701,7 @@ purple_auth_dontgrant(struct name_data *data, char *msg) { PurpleConnection *gc = data->gc; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_ssi_sendauthreply(od, data->name, 0x00, msg ? msg : _("No reason given.")); } @@ -2809,21 +2815,21 @@ case 0x06: { /* Someone requested authorization */ if (i >= 6) { struct name_data *data = g_new(struct name_data, 1); - gchar *sn = g_strdup_printf("%u", args->uin); + gchar *bn = g_strdup_printf("%u", args->uin); gchar *reason = NULL; if (msg2[5] != NULL) - reason = purple_plugin_oscar_decode_im_part(account, sn, AIM_CHARSET_CUSTOM, 0x0000, msg2[5], strlen(msg2[5])); + reason = purple_plugin_oscar_decode_im_part(account, bn, AIM_CHARSET_CUSTOM, 0x0000, msg2[5], strlen(msg2[5])); purple_debug_info("oscar", "Received an authorization request from UIN %u\n", args->uin); data->gc = gc; - data->name = sn; + data->name = bn; data->nick = NULL; - purple_account_request_authorization(account, sn, NULL, NULL, - reason, purple_find_buddy(account, sn) != NULL, + purple_account_request_authorization(account, bn, NULL, NULL, + reason, purple_find_buddy(account, bn) != NULL, purple_auth_grant, purple_auth_dontgrant_msgprompt, data); g_free(reason); @@ -3025,7 +3031,7 @@ "You missed %hu messages from %s because they were invalid.", nummissed), nummissed, - userinfo->sn); + userinfo->bn); break; case 1: /* Message too large */ buf = g_strdup_printf( @@ -3034,7 +3040,7 @@ "You missed %hu messages from %s because they were too large.", nummissed), nummissed, - userinfo->sn); + userinfo->bn); break; case 2: /* Rate exceeded */ buf = g_strdup_printf( @@ -3043,7 +3049,7 @@ "You missed %hu messages from %s because the rate limit has been exceeded.", nummissed), nummissed, - userinfo->sn); + userinfo->bn); break; case 3: /* Evil Sender */ buf = g_strdup_printf( @@ -3052,7 +3058,7 @@ "You missed %hu messages from %s because his/her warning level is too high.", nummissed), nummissed, - userinfo->sn); + userinfo->bn); break; case 4: /* Evil Receiver */ buf = g_strdup_printf( @@ -3061,7 +3067,7 @@ "You missed %hu messages from %s because your warning level is too high.", nummissed), nummissed, - userinfo->sn); + userinfo->bn); break; default: buf = g_strdup_printf( @@ -3070,11 +3076,11 @@ "You missed %hu messages from %s for an unknown reason.", nummissed), nummissed, - userinfo->sn); + userinfo->bn); break; } - if (!purple_conv_present_error(userinfo->sn, account, buf)) + if (!purple_conv_present_error(userinfo->bn, account, buf)) purple_notify_error(od->gc, NULL, buf, NULL); g_free(buf); @@ -3192,7 +3198,7 @@ static int purple_parse_msgerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; #ifdef TODOFT - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); PurpleXfer *xfer; #endif va_list ap; @@ -3220,7 +3226,7 @@ } #endif - /* Data is assumed to be the destination sn */ + /* Data is assumed to be the destination bn */ buf = g_strdup_printf(_("Unable to send message: %s"), (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("Unknown reason.")); if (!purple_conv_present_error(data, purple_connection_get_account(gc), buf)) { g_free(buf); @@ -3237,25 +3243,25 @@ PurpleConnection *gc = od->gc; va_list ap; guint16 type1, type2; - char *sn; + char *bn; va_start(ap, fr); type1 = (guint16) va_arg(ap, unsigned int); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); type2 = (guint16) va_arg(ap, unsigned int); va_end(ap); switch (type2) { case 0x0000: { /* Text has been cleared */ - serv_got_typing_stopped(gc, sn); + serv_got_typing_stopped(gc, bn); } break; case 0x0001: { /* Paused typing */ - serv_got_typing(gc, sn, 0, PURPLE_TYPED); + serv_got_typing(gc, bn, 0, PURPLE_TYPED); } break; case 0x0002: { /* Typing */ - serv_got_typing(gc, sn, 0, PURPLE_TYPING); + serv_got_typing(gc, bn, 0, PURPLE_TYPING); } break; default: { @@ -3263,7 +3269,7 @@ * It looks like iChat sometimes sends typing notification * with type1=0x0001 and type2=0x000f. Not sure why. */ - purple_debug_info("oscar", "Received unknown typing notification message from %s. Type1 is 0x%04x and type2 is 0x%04hx.\n", sn, type1, type2); + purple_debug_info("oscar", "Received unknown typing notification message from %s. Type1 is 0x%04x and type2 is 0x%04hx.\n", bn, type1, type2); } break; } @@ -3324,7 +3330,7 @@ oscar_user_info_append_extra_info(gc, user_info, NULL, userinfo); - if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !aim_snvalid_sms(userinfo->sn)) { + if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) { /* An SMS contact is always online; its Online Since valid is not useful */ time_t t = userinfo->onlinesince; oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t))); @@ -3358,11 +3364,11 @@ purple_notify_user_info_add_section_break(user_info); tmp = g_strdup_printf("%s", - purple_normalize(account, userinfo->sn), _("View web profile")); + purple_normalize(account, userinfo->bn), _("View web profile")); purple_notify_user_info_add_pair(user_info, NULL, tmp); g_free(tmp); - purple_notify_userinfo(gc, userinfo->sn, user_info, NULL, NULL); + purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); return 1; @@ -3384,14 +3390,14 @@ userinfo = va_arg(ap, aim_userinfo_t *); va_end(ap); - b = purple_find_buddy(account, userinfo->sn); + b = purple_find_buddy(account, userinfo->bn); if (b == NULL) return 1; - if (!aim_snvalid_icq(userinfo->sn)) + if (!oscar_util_valid_name_icq(userinfo->bn)) { - if (strcmp(purple_buddy_get_name(b), userinfo->sn) != 0) - serv_got_alias(gc, purple_buddy_get_name(b), userinfo->sn); + if (strcmp(purple_buddy_get_name(b), userinfo->bn) != 0) + serv_got_alias(gc, purple_buddy_get_name(b), userinfo->bn); else serv_got_alias(gc, purple_buddy_get_name(b), NULL); } @@ -3408,7 +3414,7 @@ userinfo->away, userinfo->away_len); g_free(charset); - purple_prpl_got_user_status(account, userinfo->sn, + purple_prpl_got_user_status(account, userinfo->bn, purple_status_get_id(status), "message", message, NULL); g_free(message); @@ -3529,7 +3535,7 @@ return 1; for (i = 0; i < count; i++) - purple_conv_chat_add_user(PURPLE_CONV_CHAT(c->conv), info[i].sn, NULL, PURPLE_CBFLAGS_NONE, TRUE); + purple_conv_chat_add_user(PURPLE_CONV_CHAT(c->conv), info[i].bn, NULL, PURPLE_CBFLAGS_NONE, TRUE); return 1; } @@ -3552,7 +3558,7 @@ return 1; for (i = 0; i < count; i++) - purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c->conv), info[i].sn, NULL); + purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c->conv), info[i].bn, NULL); return 1; } @@ -3621,7 +3627,7 @@ if (utf8 == NULL) /* The conversion failed! */ utf8 = g_strdup(_("[Unable to display a message from this user because it contained invalid characters.]")); - serv_got_chat_in(gc, ccon->id, info->sn, 0, utf8, time((time_t)NULL)); + serv_got_chat_in(gc, ccon->id, info->bn, 0, utf8, time((time_t)NULL)); g_free(utf8); return 1; @@ -3629,11 +3635,15 @@ static int purple_email_parseupdate(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { va_list ap; - PurpleConnection *gc = od->gc; + PurpleConnection *gc; + PurpleAccount *account; struct aim_emailinfo *emailinfo; int havenewmail; char *alertitle, *alerturl; + gc = od->gc; + account = purple_connection_get_account(gc); + va_start(ap, fr); emailinfo = va_arg(ap, struct aim_emailinfo *); havenewmail = va_arg(ap, int); @@ -3641,12 +3651,13 @@ alerturl = va_arg(ap, char *); va_end(ap); - if ((emailinfo != NULL) && purple_account_get_check_mail(gc->account)) { - gchar *to = g_strdup_printf("%s%s%s", purple_account_get_username(purple_connection_get_account(gc)), - emailinfo->domain ? "@" : "", - emailinfo->domain ? emailinfo->domain : ""); - if (emailinfo->unread && havenewmail) - purple_notify_emails(gc, emailinfo->nummsgs, FALSE, NULL, NULL, (const char **)&to, (const char **)&emailinfo->url, NULL, NULL); + if (account != NULL && emailinfo != NULL && emailinfo->unread && havenewmail) { + gchar *to = g_strdup_printf("%s%s%s", + purple_account_get_username(account), + emailinfo->domain ? "@" : "", + emailinfo->domain ? emailinfo->domain : ""); + purple_notify_emails(gc, emailinfo->nummsgs, FALSE, NULL, NULL, + (const char **)&to, (const char **)&emailinfo->url, NULL, NULL); g_free(to); } @@ -3659,12 +3670,12 @@ static int purple_icon_parseicon(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; va_list ap; - char *sn; + char *bn; guint8 iconcsumtype, *iconcsum, *icon; guint16 iconcsumlen, iconlen; va_start(ap, fr); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); iconcsumtype = va_arg(ap, int); iconcsum = va_arg(ap, guint8 *); iconcsumlen = va_arg(ap, int); @@ -3679,7 +3690,7 @@ if ((iconlen > 0) && (iconlen != 90)) { char *b16 = purple_base16_encode(iconcsum, iconcsumlen); purple_buddy_icons_set_for_user(purple_connection_get_account(gc), - sn, g_memdup(icon, iconlen), iconlen, b16); + bn, g_memdup(icon, iconlen), iconlen, b16); g_free(b16); } @@ -3689,7 +3700,7 @@ static void purple_icons_fetch(PurpleConnection *gc) { - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_userinfo_t *userinfo; FlapConnection *conn; @@ -3736,14 +3747,14 @@ static int purple_parse_msgack(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { va_list ap; guint16 type; - char *sn; + char *bn; va_start(ap, fr); type = (guint16) va_arg(ap, unsigned int); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); va_end(ap); - purple_debug_info("oscar", "Sent message to %s.\n", sn); + purple_debug_info("oscar", "Sent message to %s.\n", bn); return 1; } @@ -3803,7 +3814,7 @@ userinfo = va_arg(ap, aim_userinfo_t *); va_end(ap); - purple_prpl_got_account_warning_level(account, (userinfo && userinfo->sn) ? userinfo->sn : NULL, (newevil/10.0) + 0.5); + purple_prpl_got_account_warning_level(account, (userinfo && userinfo->bn) ? userinfo->bn : NULL, (newevil/10.0) + 0.5); #endif return 1; @@ -3818,7 +3829,7 @@ info = va_arg(ap, aim_userinfo_t *); va_end(ap); - purple_connection_set_display_name(od->gc, info->sn); + purple_connection_set_display_name(od->gc, info->bn); /* * What's with the + 0.5? @@ -3927,13 +3938,13 @@ PurpleAccount *account; PurpleStatus *status; PurplePresence *presence; - const char *message, *itmsurl; + const char *username, *message, *itmsurl; char *tmp; va_list ap; guint16 maxpermits, maxdenies; gc = od->gc; - od = (OscarData *)gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); va_start(ap, fr); @@ -3956,12 +3967,13 @@ if (purple_account_get_user_info(account) != NULL) serv_set_info(gc, purple_account_get_user_info(account)); - if (!od->icq && strcmp(purple_account_get_username(account), purple_connection_get_display_name(gc)) != 0) + username = purple_account_get_username(account); + if (!od->icq && strcmp(username, purple_connection_get_display_name(gc)) != 0) /* - * Format the screen name for AIM accounts if it's different + * Format the username for AIM accounts if it's different * than what's currently set. */ - oscar_format_screenname(gc, account->username); + oscar_format_username(gc, username); /* Set our available message based on the current status */ status = purple_account_get_active_status(account); @@ -3995,13 +4007,13 @@ /* * The "if" statement here is a pathetic attempt to not attempt to * connect to the alerts servce (aka email notification) if this - * screen name does not support it. I think mail notification + * username does not support it. I think mail notification * works for @mac.com accounts but does not work for the newer * @anythingelse.com accounts. If that's true then this change * breaks mail notification for @mac.com accounts, but it gets rid * of an annoying error at signon for @anythingelse.com accounts. */ - if ((od->authinfo->email != NULL) && ((strchr(gc->account->username, '@') == NULL))) + if (od->authinfo->email != NULL && strchr(username, '@') == NULL) aim_srv_requestnew(od, SNAC_FAMILY_ALERT); return 1; @@ -4065,9 +4077,9 @@ user_info = purple_notify_user_info_new(); g_snprintf(who, sizeof(who), "%u", info->uin); - buddy = purple_find_buddy(purple_connection_get_account(gc), who); + buddy = purple_find_buddy(account, who); if (buddy != NULL) - bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(buddy->account, buddy->name)); + bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, purple_buddy_get_name(buddy))); else bi = NULL; @@ -4084,7 +4096,7 @@ } oscar_user_info_convert_and_add(account, user_info, _("First Name"), info->first); oscar_user_info_convert_and_add(account, user_info, _("Last Name"), info->last); - if (info->email && info->email[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->email))) { + if (info->email && info->email[0] && (utf8 = oscar_utf8_try_convert(account, info->email))) { buf = g_strdup_printf("%s", utf8, utf8); purple_notify_user_info_add_pair(user_info, _("Email Address"), buf); g_free(buf); @@ -4093,7 +4105,7 @@ if (info->numaddresses && info->email2) { int i; for (i = 0; i < info->numaddresses; i++) { - if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_utf8_try_convert(gc->account, info->email2[i]))) { + if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_utf8_try_convert(account, info->email2[i]))) { buf = g_strdup_printf("%s", utf8, utf8); purple_notify_user_info_add_pair(user_info, _("Email Address"), buf); g_free(buf); @@ -4128,7 +4140,7 @@ snprintf(age, sizeof(age), "%hhd", info->age); purple_notify_user_info_add_pair(user_info, _("Age"), age); } - if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->personalwebpage))) { + if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_utf8_try_convert(account, info->personalwebpage))) { buf = g_strdup_printf("%s", utf8, utf8); purple_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf); g_free(buf); @@ -4164,7 +4176,7 @@ oscar_user_info_convert_and_add(account, user_info, _("Division"), info->workdivision); oscar_user_info_convert_and_add(account, user_info, _("Position"), info->workposition); - if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_utf8_try_convert(gc->account, info->workwebpage))) { + if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_utf8_try_convert(account, info->workwebpage))) { char *webpage = g_strdup_printf("%s", utf8, utf8); purple_notify_user_info_add_pair(user_info, _("Web Page"), webpage); g_free(webpage); @@ -4198,7 +4210,7 @@ if (info->uin && info->nick && info->nick[0] && (utf8 = oscar_utf8_try_convert(account, info->nick))) { g_snprintf(who, sizeof(who), "%u", info->uin); serv_got_alias(gc, who, utf8); - if ((b = purple_find_buddy(gc->account, who))) { + if ((b = purple_find_buddy(account, who))) { purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", utf8); } g_free(utf8); @@ -4328,7 +4340,7 @@ PurpleConnection *gc = od->gc; va_list ap; guint16 perms, err; - char *url, *sn, *email; + char *url, *bn, *email; int change; va_start(ap, fr); @@ -4336,15 +4348,15 @@ perms = (guint16) va_arg(ap, unsigned int); err = (guint16) va_arg(ap, unsigned int); url = va_arg(ap, char *); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); email = va_arg(ap, char *); va_end(ap); purple_debug_misc("oscar", - "account info: because of %s, perms=0x%04x, err=0x%04x, url=%s, sn=%s, email=%s\n", + "account info: because of %s, perms=0x%04x, err=0x%04x, url=%s, bn=%s, email=%s\n", change ? "change" : "request", perms, err, (url != NULL) ? url : "(null)", - (sn != NULL) ? sn : "(null)", + (bn != NULL) ? bn : "(null)", (email != NULL) ? email : "(null)"); if ((err > 0) && (url != NULL)) { @@ -4386,7 +4398,7 @@ OscarData *od; FlapConnection *conn; - od = (OscarData *)gc->proto_data; + od = purple_connection_get_protocol_data(gc); conn = flap_connection_getbytype(od, SNAC_FAMILY_LOCATE); if (conn != NULL) flap_connection_send_keepalive(od, conn); @@ -4398,7 +4410,7 @@ OscarData *od; PeerConnection *conn; - od = (OscarData *)gc->proto_data; + od = purple_connection_get_protocol_data(gc); conn = peer_connection_find_by_type(od, name, OSCAR_CAPABILITY_DIRECTIM); if ((conn != NULL) && (conn->ready)) @@ -4408,7 +4420,7 @@ else { /* Don't send if this turkey is in our deny list */ GSList *list; - for (list=gc->account->deny; (list && aim_sncmp(name, list->data)); list=list->next); + for (list=gc->account->deny; (list && oscar_util_name_compare(name, list->data)); list=list->next); if (!list) { struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(gc->account, name)); if (bi && bi->typingnot) { @@ -4494,7 +4506,7 @@ /* Convert the message to a good encoding */ purple_plugin_oscar_convert_to_best_encoding(conn->od->gc, - conn->sn, msg->str, &tmp, &tmplen, &charset, &charsubset); + conn->bn, msg->str, &tmp, &tmplen, &charset, &charsubset); g_string_free(msg, TRUE); msg = g_string_new_len(tmp, tmplen); g_free(tmp); @@ -4520,11 +4532,11 @@ char *tmp1, *tmp2; gboolean is_sms, is_html; - od = (OscarData *)gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); ret = 0; - is_sms = aim_snvalid_sms(name); + is_sms = oscar_util_valid_name_sms(name); if (od->icq && is_sms) { /* @@ -4562,7 +4574,7 @@ "You must be Direct Connected to send IM Images."), PURPLE_MESSAGE_ERROR, time(NULL)); - buddy = purple_find_buddy(gc->account, name); + buddy = purple_find_buddy(account, name); bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, name)); if (!bi) { @@ -4637,17 +4649,17 @@ purple_imgstore_unref(img); } - args.destsn = name; + args.destbn = name; /* * If we're IMing an SMS user or an ICQ user from an ICQ account, then strip HTML. */ - if (aim_snvalid_sms(name)) { + if (oscar_util_valid_name_sms(name)) { /* Messaging an SMS (mobile) user */ tmp2 = purple_markup_strip_html(tmp1); is_html = FALSE; - } else if (aim_snvalid_icq(purple_account_get_username(account))) { - if (aim_snvalid_icq(name)) { + } else if (oscar_util_valid_name_icq(purple_account_get_username(account))) { + if (oscar_util_valid_name_icq(name)) { /* From ICQ to ICQ */ tmp2 = purple_markup_strip_html(tmp1); is_html = FALSE; @@ -4707,9 +4719,9 @@ * AIM users can only request AIM info. */ void oscar_get_info(PurpleConnection *gc, const char *name) { - OscarData *od = (OscarData *)gc->proto_data; - - if (od->icq && aim_snvalid_icq(name)) + OscarData *od = purple_connection_get_protocol_data(gc); + + if (od->icq && oscar_util_valid_name_icq(name)) aim_icq_getallinfo(od, name); else aim_locate_getinfoshort(od, name, 0x00000003); @@ -4719,14 +4731,14 @@ static void oscar_set_dir(PurpleConnection *gc, const char *first, const char *middle, const char *last, const char *maiden, const char *city, const char *state, const char *country, int web) { /* XXX - some of these things are wrong, but i'm lazy */ - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_locate_setdirinfo(od, first, middle, last, maiden, NULL, NULL, city, state, NULL, 0, web); } #endif void oscar_set_idle(PurpleConnection *gc, int time) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_srv_setidle(od, time); } @@ -4772,7 +4784,7 @@ const gchar *status_id; guint32 data = 0x00000000; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); status = purple_account_get_active_status(account); status_id = purple_status_get_id(status); @@ -4806,7 +4818,7 @@ gboolean setstatus, PurpleStatus *status) { PurpleConnection *gc = purple_account_get_connection(account); - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); PurpleStatusType *status_type; PurpleStatusPrimitive primitive; @@ -4919,7 +4931,7 @@ OscarData *od = NULL; if (gc) - od = (OscarData *)gc->proto_data; + od = purple_connection_get_protocol_data(gc); if (!od) return; @@ -4949,14 +4961,14 @@ oscar_set_info_and_status(account, FALSE, NULL, TRUE, status); /* Set the ICQ status for ICQ accounts only */ - if (aim_snvalid_icq(purple_account_get_username(account))) + if (oscar_util_valid_name_icq(purple_account_get_username(account))) oscar_set_status_icq(account, status); } #ifdef CRAZY_WARN void oscar_warn(PurpleConnection *gc, const char *name, gboolean anonymous) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_im_warn(od, od->conn, name, anonymous ? AIM_WARN_ANON : 0); } #endif @@ -4965,14 +4977,17 @@ oscar_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { OscarData *od; PurpleAccount *account; - - od = (OscarData *)gc->proto_data; + const char *bname, *gname; + + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); - - if (!aim_snvalid(buddy->name)) { + bname = purple_buddy_get_name(buddy); + gname = purple_group_get_name(group); + + if (!oscar_util_valid_name(bname)) { gchar *buf; - buf = g_strdup_printf(_("Could not add the buddy %s because the username is invalid. Usernames must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), buddy->name); - if (!purple_conv_present_error(buddy->name, account, buf)) + buf = g_strdup_printf(_("Could not add the buddy %s because the username is invalid. Usernames must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), bname); + if (!purple_conv_present_error(bname, account, buf)) purple_notify_error(gc, NULL, _("Unable to Add"), buf); g_free(buf); @@ -4982,39 +4997,40 @@ return; } - if ((od->ssi.received_data) && !(aim_ssi_itemlist_finditem(od->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY))) { + if ((od->ssi.received_data) && !(aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))) { purple_debug_info("oscar", - "ssi: adding buddy %s to group %s\n", buddy->name, group->name); - aim_ssi_addbuddy(od, buddy->name, group->name, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); + "ssi: adding buddy %s to group %s\n", bname, gname); + aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, 0); /* Mobile users should always be online */ - if (buddy->name[0] == '+') { + if (bname[0] == '+') { purple_prpl_got_user_status(account, - purple_buddy_get_name(buddy), - OSCAR_STATUS_ID_AVAILABLE, NULL); + bname, OSCAR_STATUS_ID_AVAILABLE, NULL); purple_prpl_got_user_status(account, - purple_buddy_get_name(buddy), - OSCAR_STATUS_ID_MOBILE, NULL); + bname, OSCAR_STATUS_ID_MOBILE, NULL); } } /* XXX - Should this be done from AIM accounts, as well? */ if (od->icq) - aim_icq_getalias(od, buddy->name); + aim_icq_getalias(od, bname); } void oscar_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); if (od->ssi.received_data) { + const char *gname = purple_group_get_name(group); + const char *bname = purple_buddy_get_name(buddy); purple_debug_info("oscar", - "ssi: deleting buddy %s from group %s\n", buddy->name, group->name); - aim_ssi_delbuddy(od, buddy->name, group->name); + "ssi: deleting buddy %s from group %s\n", bname, gname); + aim_ssi_delbuddy(od, bname, gname); } } void oscar_move_buddy(PurpleConnection *gc, const char *name, const char *old_group, const char *new_group) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); + if (od->ssi.received_data && strcmp(old_group, new_group)) { purple_debug_info("oscar", "ssi: moving buddy %s from group %s to group %s\n", name, old_group, new_group); @@ -5023,7 +5039,8 @@ } void oscar_alias_buddy(PurpleConnection *gc, const char *name, const char *alias) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); + if (od->ssi.received_data) { char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name); if (gname) { @@ -5038,10 +5055,11 @@ * FYI, the OSCAR SSI code removes empty groups automatically. */ void oscar_rename_group(PurpleConnection *gc, const char *old_name, PurpleGroup *group, GList *moved_buddies) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); if (od->ssi.received_data) { - if (aim_ssi_itemlist_finditem(od->ssi.local, group->name, NULL, AIM_SSI_TYPE_GROUP)) { + const char *gname = purple_group_get_name(group); + if (aim_ssi_itemlist_finditem(od->ssi.local, gname, NULL, AIM_SSI_TYPE_GROUP)) { GList *cur, *groups = NULL; PurpleAccount *account = purple_connection_get_account(gc); @@ -5051,25 +5069,25 @@ /* node is PurpleBuddy, parent is a PurpleContact. * We must go two levels up to get the Group */ groups = g_list_append(groups, - node->parent->parent); + purple_buddy_get_group((PurpleBuddy*)node)); } purple_account_remove_buddies(account, moved_buddies, groups); purple_account_add_buddies(account, moved_buddies); g_list_free(groups); purple_debug_info("oscar", - "ssi: moved all buddies from group %s to %s\n", old_name, group->name); + "ssi: moved all buddies from group %s to %s\n", old_name, gname); } else { - aim_ssi_rename_group(od, old_name, group->name); + aim_ssi_rename_group(od, old_name, gname); purple_debug_info("oscar", - "ssi: renamed group %s to %s\n", old_name, group->name); + "ssi: renamed group %s to %s\n", old_name, gname); } } } void oscar_remove_group(PurpleConnection *gc, PurpleGroup *group) { - aim_ssi_delgroup(gc->proto_data, group->name); + aim_ssi_delgroup(purple_connection_get_protocol_data(gc), purple_group_get_name(group)); } static gboolean purple_ssi_rerequestdata(gpointer data) { @@ -5150,7 +5168,7 @@ guint32 timestamp; gc = od->gc; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); va_start(ap, fr); @@ -5178,33 +5196,44 @@ /* Buddies */ cur = NULL; if ((blist = purple_get_blist()) != NULL) { - for (gnode = blist->root; gnode; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { + const char *gname; if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; g = (PurpleGroup *)gnode; - for (cnode = gnode->child; cnode; cnode = cnode->next) { + gname = purple_group_get_name(g); + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { + const char *bname; if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *)bnode; - if (b->account == gc->account) { - if (aim_ssi_itemlist_exists(od->ssi.local, b->name)) { + bname = purple_buddy_get_name(b); + if (purple_buddy_get_account(b) == account) { + if (aim_ssi_itemlist_exists(od->ssi.local, bname)) { /* If the buddy is an ICQ user then load his nickname */ const char *servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"); char *alias; + const char *balias; if (servernick) - serv_got_alias(gc, b->name, servernick); + serv_got_alias(gc, bname, servernick); /* Store local alias on server */ - alias = aim_ssi_getalias(od->ssi.local, g->name, b->name); - if (!alias && b->alias && strlen(b->alias)) - aim_ssi_aliasbuddy(od, g->name, b->name, b->alias); + alias = aim_ssi_getalias(od->ssi.local, gname, bname); + balias = purple_buddy_get_local_buddy_alias(b); + if (!alias && balias && *balias) + aim_ssi_aliasbuddy(od, gname, bname, balias); g_free(alias); } else { purple_debug_info("oscar", - "ssi: removing buddy %s from local list\n", b->name); + "ssi: removing buddy %s from local list\n", bname); /* We can't actually remove now because it will screw up our looping */ cur = g_slist_prepend(cur, b); } @@ -5221,8 +5250,8 @@ } /* Permit list */ - if (gc->account->permit) { - next = gc->account->permit; + if (account->permit) { + next = account->permit; while (next != NULL) { cur = next; next = next->next; @@ -5235,8 +5264,8 @@ } /* Deny list */ - if (gc->account->deny) { - next = gc->account->deny; + if (account->deny) { + next = account->deny; while (next != NULL) { cur = next; next = next->next; @@ -5280,7 +5309,7 @@ if (g_utf8_validate(gname, -1, NULL)) gname_utf8 = g_strdup(gname); else - gname_utf8 = oscar_utf8_try_convert(gc->account, gname); + gname_utf8 = oscar_utf8_try_convert(account, gname); } else gname_utf8 = NULL; @@ -5300,18 +5329,18 @@ } else alias_utf8 = NULL; - b = purple_find_buddy_in_group(gc->account, curitem->name, g); + b = purple_find_buddy_in_group(account, curitem->name, g); if (b) { /* Get server stored alias */ purple_blist_alias_buddy(b, alias_utf8); } else { - b = purple_buddy_new(gc->account, curitem->name, alias_utf8); + b = purple_buddy_new(account, curitem->name, alias_utf8); purple_debug_info("oscar", - "ssi: adding buddy %s to group %s to local list\n", curitem->name, g->name); + "ssi: adding buddy %s to group %s to local list\n", curitem->name, gname); purple_blist_add_buddy(b, NULL, g, NULL); } - if (!aim_sncmp(curitem->name, account->username)) { + if (!oscar_util_name_compare(curitem->name, purple_account_get_username(account))) { char *comment = aim_ssi_getcomment(od->ssi.local, gname, curitem->name); if (comment != NULL) { @@ -5321,7 +5350,7 @@ } /* Mobile users should always be online */ - if (b->name[0] == '+') { + if (curitem->name[0] == '+') { purple_prpl_got_user_status(account, purple_buddy_get_name(b), OSCAR_STATUS_ID_AVAILABLE, NULL); @@ -5344,7 +5373,7 @@ if (g_utf8_validate(gname, -1, NULL)) gname_utf8 = g_strdup(gname); else - gname_utf8 = oscar_utf8_try_convert(gc->account, gname); + gname_utf8 = oscar_utf8_try_convert(account, gname); } else gname_utf8 = NULL; @@ -5359,7 +5388,7 @@ if (curitem->name) { /* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */ GSList *list; - for (list=account->permit; (list && aim_sncmp(curitem->name, list->data)); list=list->next); + for (list=account->permit; (list && oscar_util_name_compare(curitem->name, list->data)); list=list->next); if (!list) { purple_debug_info("oscar", "ssi: adding permit buddy %s to local list\n", curitem->name); @@ -5371,7 +5400,7 @@ case 0x0003: { /* Deny buddy */ if (curitem->name) { GSList *list; - for (list=account->deny; (list && aim_sncmp(curitem->name, list->data)); list=list->next); + for (list=account->deny; (list && oscar_util_name_compare(curitem->name, list->data)); list=list->next); if (!list) { purple_debug_info("oscar", "ssi: adding deny buddy %s to local list\n", curitem->name); @@ -5388,7 +5417,7 @@ "ssi: changing permdeny from %d to %hhu\n", account->perm_deny, permdeny); account->perm_deny = permdeny; if (od->icq && account->perm_deny == PURPLE_PRIVACY_ALLOW_USERS) { - purple_presence_set_status_active(account->presence, OSCAR_STATUS_ID_INVISIBLE, TRUE); + purple_presence_set_status_active(purple_account_get_presence(account), OSCAR_STATUS_ID_INVISIBLE, TRUE); } } } @@ -5535,13 +5564,11 @@ purple_blist_add_buddy(b, NULL, g, NULL); /* Mobile users should always be online */ - if (b->name[0] == '+') { + if (name[0] == '+') { purple_prpl_got_user_status(account, - purple_buddy_get_name(b), - OSCAR_STATUS_ID_AVAILABLE, NULL); + name, OSCAR_STATUS_ID_AVAILABLE, NULL); purple_prpl_got_user_status(account, - purple_buddy_get_name(b), - OSCAR_STATUS_ID_MOBILE, NULL); + name, OSCAR_STATUS_ID_MOBILE, NULL); } } @@ -5570,36 +5597,36 @@ static int purple_ssi_authgiven(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; va_list ap; - char *sn, *msg; + char *bn, *msg; gchar *dialog_msg, *nombre; struct name_data *data; PurpleBuddy *buddy; va_start(ap, fr); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); msg = va_arg(ap, char *); va_end(ap); purple_debug_info("oscar", - "ssi: %s has given you permission to add him to your buddy list\n", sn); - - buddy = purple_find_buddy(gc->account, sn); + "ssi: %s has given you permission to add him to your buddy list\n", bn); + + buddy = purple_find_buddy(purple_connection_get_account(gc), bn); if (buddy && (purple_buddy_get_alias_only(buddy))) - nombre = g_strdup_printf("%s (%s)", sn, purple_buddy_get_alias_only(buddy)); + nombre = g_strdup_printf("%s (%s)", bn, purple_buddy_get_alias_only(buddy)); else - nombre = g_strdup(sn); + nombre = g_strdup(bn); dialog_msg = g_strdup_printf(_("The user %s has given you permission to add him or her to your buddy list. Do you want to add this user?"), nombre); g_free(nombre); data = g_new(struct name_data, 1); data->gc = gc; - data->name = g_strdup(sn); + data->name = g_strdup(bn); data->nick = (buddy ? g_strdup(purple_buddy_get_alias_only(buddy)) : NULL); purple_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg, PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), sn, NULL, + purple_connection_get_account(gc), bn, NULL, data, G_CALLBACK(purple_icq_buddyadd), G_CALLBACK(oscar_free_name_data)); @@ -5611,7 +5638,7 @@ static int purple_ssi_authrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; va_list ap; - char *sn; + char *bn; char *msg; PurpleAccount *account = purple_connection_get_account(gc); gchar *reason = NULL; @@ -5619,24 +5646,24 @@ PurpleBuddy *buddy; va_start(ap, fr); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); msg = va_arg(ap, char *); va_end(ap); purple_debug_info("oscar", - "ssi: received authorization request from %s\n", sn); - - buddy = purple_find_buddy(account, sn); + "ssi: received authorization request from %s\n", bn); + + buddy = purple_find_buddy(account, bn); if (msg != NULL) - reason = purple_plugin_oscar_decode_im_part(account, sn, AIM_CHARSET_CUSTOM, 0x0000, msg, strlen(msg)); + reason = purple_plugin_oscar_decode_im_part(account, bn, AIM_CHARSET_CUSTOM, 0x0000, msg, strlen(msg)); data = g_new(struct name_data, 1); data->gc = gc; - data->name = g_strdup(sn); + data->name = g_strdup(bn); data->nick = (buddy ? g_strdup(purple_buddy_get_alias_only(buddy)) : NULL); - purple_account_request_authorization(account, sn, NULL, + purple_account_request_authorization(account, bn, NULL, (buddy ? purple_buddy_get_alias_only(buddy) : NULL), reason, buddy != NULL, purple_auth_grant, purple_auth_dontgrant_msgprompt, data); @@ -5648,25 +5675,25 @@ static int purple_ssi_authreply(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; va_list ap; - char *sn, *msg; + char *bn, *msg; gchar *dialog_msg, *nombre; guint8 reply; PurpleBuddy *buddy; va_start(ap, fr); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); reply = (guint8)va_arg(ap, int); msg = va_arg(ap, char *); va_end(ap); purple_debug_info("oscar", - "ssi: received authorization reply from %s. Reply is 0x%04hhx\n", sn, reply); - - buddy = purple_find_buddy(gc->account, sn); + "ssi: received authorization reply from %s. Reply is 0x%04hhx\n", bn, reply); + + buddy = purple_find_buddy(purple_connection_get_account(gc), bn); if (buddy && (purple_buddy_get_alias_only(buddy))) - nombre = g_strdup_printf("%s (%s)", sn, purple_buddy_get_alias_only(buddy)); + nombre = g_strdup_printf("%s (%s)", bn, purple_buddy_get_alias_only(buddy)); else - nombre = g_strdup(sn); + nombre = g_strdup(bn); if (reply) { /* Granted */ @@ -5685,17 +5712,19 @@ static int purple_ssi_gotadded(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; + PurpleAccount *account = purple_connection_get_account(gc); va_list ap; - char *sn; + char *bn; PurpleBuddy *buddy; va_start(ap, fr); - sn = va_arg(ap, char *); + bn = va_arg(ap, char *); va_end(ap); - buddy = purple_find_buddy(gc->account, sn); - purple_debug_info("oscar", "ssi: %s added you to their buddy list\n", sn); - purple_account_notify_added(gc->account, sn, NULL, (buddy ? purple_buddy_get_alias_only(buddy) : NULL), NULL); + buddy = purple_find_buddy(account, bn); + purple_debug_info("oscar", "ssi: %s added you to their buddy list\n", bn); + purple_account_notify_added(account, bn, NULL, + (buddy ? purple_buddy_get_alias_only(buddy) : NULL), NULL); return 1; } @@ -5744,7 +5773,7 @@ void oscar_join_chat(PurpleConnection *gc, GHashTable *data) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); FlapConnection *conn; char *name, *exchange; int exchange_int; @@ -5779,7 +5808,7 @@ void oscar_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); struct chat_connection *ccon = find_oscar_chat(gc, id); if (ccon == NULL) @@ -5799,14 +5828,16 @@ g_return_if_fail(conv != NULL); - purple_debug_info("oscar", "Leaving chat room %s\n", conv->name); + purple_debug_info("oscar", "Leaving chat room %s\n", + purple_conversation_get_name(conv)); cc = find_oscar_chat(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv))); oscar_chat_kill(gc, cc); } -int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags) { - OscarData *od = (OscarData *)gc->proto_data; +int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags) +{ + OscarData *od = purple_connection_get_protocol_data(gc); PurpleConversation *conv = NULL; struct chat_connection *c = NULL; char *buf, *buf2, *buf3; @@ -5873,30 +5904,32 @@ const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b) { - if ((b == NULL) || (b->name == NULL) || aim_snvalid_sms(b->name)) + const char *name = b ? purple_buddy_get_name(b) : NULL; + if ((b == NULL) || (name == NULL) || oscar_util_valid_name_sms(name)) { - if (a == NULL || aim_snvalid_icq(purple_account_get_username(a))) + if (a == NULL || oscar_util_valid_name_icq(purple_account_get_username(a))) return "icq"; else return "aim"; } - if (aim_snvalid_icq(b->name)) + if (oscar_util_valid_name_icq(name)) return "icq"; return "aim"; } const char *oscar_list_icon_aim(PurpleAccount *a, PurpleBuddy *b) { - if ((b == NULL) || (b->name == NULL) || aim_snvalid_sms(b->name)) + const char *name = b ? purple_buddy_get_name(b) : NULL; + if ((b == NULL) || (name == NULL) || oscar_util_valid_name_sms(name)) { - if (a != NULL && aim_snvalid_icq(purple_account_get_username(a))) + if (a != NULL && oscar_util_valid_name_icq(purple_account_get_username(a))) return "icq"; else return "aim"; } - if (aim_snvalid_icq(b->name)) + if (oscar_util_valid_name_icq(name)) return "icq"; return "aim"; } @@ -5910,14 +5943,16 @@ PurpleStatus *status; const char *status_id; aim_userinfo_t *userinfo = NULL; - - account = b->account; + const char *name; + + account = purple_buddy_get_account(b); + name = purple_buddy_get_name(b); if (account != NULL) - gc = account->gc; + gc = purple_account_get_connection(account); if (gc != NULL) - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); if (od != NULL) - userinfo = aim_locate_finduserinfo(od, b->name); + userinfo = aim_locate_finduserinfo(od, name); presence = purple_buddy_get_presence(b); status = purple_presence_get_active_status(presence); @@ -5925,9 +5960,9 @@ if (purple_presence_is_online(presence) == FALSE) { char *gname; - if ((b->name) && (od) && (od->ssi.received_data) && - (gname = aim_ssi_itemlist_findparentname(od->ssi.local, b->name)) && - (aim_ssi_waitingforauth(od->ssi.local, gname, b->name))) { + if ((name) && (od) && (od->ssi.received_data) && + (gname = aim_ssi_itemlist_findparentname(od->ssi.local, name)) && + (aim_ssi_waitingforauth(od->ssi.local, gname, name))) { return "not-authorized"; } } @@ -5950,15 +5985,17 @@ void oscar_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { PurpleConnection *gc; + PurpleAccount *account; OscarData *od; aim_userinfo_t *userinfo; if (!PURPLE_BUDDY_IS_ONLINE(b)) return; - gc = b->account->gc; - od = gc->proto_data; - userinfo = aim_locate_finduserinfo(od, b->name); + account = purple_buddy_get_account(b); + gc = purple_account_get_connection(account); + od = purple_connection_get_protocol_data(gc); + userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b)); oscar_user_info_append_status(gc, user_info, b, userinfo, /* strip_html_tags */ TRUE); @@ -5979,15 +6016,16 @@ gc = purple_account_get_connection(purple_buddy_get_account(b)); account = purple_connection_get_account(gc); - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); presence = purple_buddy_get_presence(b); status = purple_presence_get_active_status(presence); id = purple_status_get_id(status); if ((od != NULL) && !purple_presence_is_online(presence)) { - char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, b->name); - if (aim_ssi_waitingforauth(od->ssi.local, gname, b->name)) + const char *name = purple_buddy_get_name(b); + char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, name); + if (aim_ssi_waitingforauth(od->ssi.local, gname, name)) ret = g_strdup(_("Not Authorized")); else ret = g_strdup(_("Offline")); @@ -6087,7 +6125,7 @@ void oscar_set_permit_deny(PurpleConnection *gc) { PurpleAccount *account = purple_connection_get_account(gc); - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); if (od->ssi.received_data) { switch (account->perm_deny) { @@ -6114,28 +6152,28 @@ } void oscar_add_permit(PurpleConnection *gc, const char *who) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); purple_debug_info("oscar", "ssi: About to add a permit\n"); if (od->ssi.received_data) aim_ssi_addpermit(od, who); } void oscar_add_deny(PurpleConnection *gc, const char *who) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); purple_debug_info("oscar", "ssi: About to add a deny\n"); if (od->ssi.received_data) aim_ssi_adddeny(od, who); } void oscar_rem_permit(PurpleConnection *gc, const char *who) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); purple_debug_info("oscar", "ssi: About to delete a permit\n"); if (od->ssi.received_data) aim_ssi_delpermit(od, who); } void oscar_rem_deny(PurpleConnection *gc, const char *who) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); purple_debug_info("oscar", "ssi: About to delete a deny\n"); if (od->ssi.received_data) aim_ssi_deldeny(od, who); @@ -6151,7 +6189,7 @@ g_return_val_if_fail(account != NULL, NULL); /* Used to flag some statuses as "user settable" or not */ - is_icq = aim_snvalid_icq(purple_account_get_username(account)); + is_icq = oscar_util_valid_name_icq(purple_account_get_username(account)); /* Common status types */ /* Really the available message should only be settable for AIM accounts */ @@ -6217,24 +6255,33 @@ } static void oscar_ssi_editcomment(struct name_data *data, const char *text) { - PurpleConnection *gc = data->gc; - OscarData *od = gc->proto_data; + PurpleConnection *gc; + PurpleAccount *account; + OscarData *od; PurpleBuddy *b; PurpleGroup *g; - - if (!(b = purple_find_buddy(purple_connection_get_account(data->gc), data->name))) { + const char *username; + + gc = data->gc; + od = purple_connection_get_protocol_data(gc); + account = purple_connection_get_account(gc); + + b = purple_find_buddy(account, data->name); + if (b == NULL) { oscar_free_name_data(data); return; } - if (!(g = purple_buddy_get_group(b))) { + g = purple_buddy_get_group(b); + if (g == NULL) { oscar_free_name_data(data); return; } - aim_ssi_editcomment(od, g->name, data->name, text); - - if (!aim_sncmp(data->name, gc->account->username)) + aim_ssi_editcomment(od, purple_group_get_name(g), data->name, text); + + username = purple_account_get_username(account); + if (!oscar_util_name_compare(data->name, username)) purple_check_comment(od, text); oscar_free_name_data(data); @@ -6250,23 +6297,27 @@ char *comment; gchar *comment_utf8; gchar *title; + PurpleAccount *account; + const char *name; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - od = gc->proto_data; + name = purple_buddy_get_name(buddy); + account = purple_buddy_get_account(buddy); + gc = purple_account_get_connection(account); + od = purple_connection_get_protocol_data(gc); if (!(g = purple_buddy_get_group(buddy))) return; data = g_new(struct name_data, 1); - comment = aim_ssi_getcomment(od->ssi.local, g->name, buddy->name); - comment_utf8 = comment ? oscar_utf8_try_convert(gc->account, comment) : NULL; + comment = aim_ssi_getcomment(od->ssi.local, purple_group_get_name(g), name); + comment_utf8 = comment ? oscar_utf8_try_convert(account, comment) : NULL; data->gc = gc; - data->name = g_strdup(purple_buddy_get_name(buddy)); + data->name = g_strdup(name); data->nick = g_strdup(purple_buddy_get_alias_only(buddy)); title = g_strdup_printf(_("Buddy Comment for %s"), data->name); @@ -6274,7 +6325,7 @@ comment_utf8, TRUE, FALSE, NULL, _("_OK"), G_CALLBACK(oscar_ssi_editcomment), _("_Cancel"), G_CALLBACK(oscar_free_name_data), - purple_connection_get_account(gc), data->name, NULL, + account, data->name, NULL, data); g_free(title); @@ -6306,26 +6357,28 @@ PurpleConnection *gc; gchar *buf; struct oscar_ask_directim_data *data; + PurpleAccount *account; node = object; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *)node; - gc = purple_account_get_connection(buddy->account); + account = purple_buddy_get_account(buddy); + gc = purple_account_get_connection(account); data = g_new0(struct oscar_ask_directim_data, 1); - data->who = g_strdup(buddy->name); - data->od = gc->proto_data; + data->who = g_strdup(purple_buddy_get_name(buddy)); + data->od = purple_connection_get_protocol_data(gc); buf = g_strdup_printf(_("You have selected to open a Direct IM connection with %s."), - buddy->name); + data->who); purple_request_action(gc, NULL, buf, _("Because this reveals your IP address, it " "may be considered a security risk. Do you " "wish to continue?"), 0, /* Default action is "connect" */ - purple_connection_get_account(gc), data->who, NULL, + account, data->who, NULL, data, 2, _("C_onnect"), G_CALLBACK(oscar_ask_directim_yes_cb), _("_Cancel"), G_CALLBACK(oscar_ask_directim_no_cb)); @@ -6341,9 +6394,10 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *)node; - gc = purple_account_get_connection(buddy->account); - - aim_locate_getinfoshort(gc->proto_data, purple_buddy_get_name(buddy), 0x00000003); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + + aim_locate_getinfoshort(purple_connection_get_protocol_data(gc), + purple_buddy_get_name(buddy), 0x00000003); } static GList * @@ -6354,13 +6408,16 @@ GList *menu; PurpleMenuAction *act; aim_userinfo_t *userinfo; - - gc = purple_account_get_connection(buddy->account); - od = gc->proto_data; - userinfo = aim_locate_finduserinfo(od, buddy->name); + PurpleAccount *account; + const char *bname = purple_buddy_get_name(buddy); + + account = purple_buddy_get_account(buddy); + gc = purple_account_get_connection(account); + od = purple_connection_get_protocol_data(gc); + userinfo = aim_locate_finduserinfo(od, bname); menu = NULL; - if (od->icq && aim_snvalid_icq(purple_buddy_get_name(buddy))) + if (od->icq && oscar_util_valid_name_icq(bname)) { act = purple_menu_action_new(_("Get AIM Info"), PURPLE_CALLBACK(oscar_get_aim_info_cb), @@ -6388,7 +6445,7 @@ #endif if (userinfo && - aim_sncmp(purple_account_get_username(buddy->account), buddy->name) && + oscar_util_name_compare(purple_account_get_username(account), bname) && PURPLE_BUDDY_IS_ONLINE(buddy)) { if (userinfo->capabilities & OSCAR_CAPABILITY_DIRECTIM) @@ -6412,8 +6469,8 @@ if (od->ssi.received_data && purple_buddy_get_group(buddy) != NULL) { char *gname; - gname = aim_ssi_itemlist_findparentname(od->ssi.local, buddy->name); - if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, buddy->name)) + gname = aim_ssi_itemlist_findparentname(od->ssi.local, bname); + if (gname && aim_ssi_waitingforauth(od->ssi.local, gname, bname)) { act = purple_menu_action_new(_("Re-request Authorization"), PURPLE_CALLBACK(purple_auth_sendrequest_menu), @@ -6439,7 +6496,7 @@ static void oscar_icq_privacy_opts(PurpleConnection *gc, PurpleRequestFields *fields) { - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); PurpleRequestField *f; gboolean auth, web_aware; @@ -6490,13 +6547,13 @@ gc); } -static void oscar_format_screenname(PurpleConnection *gc, const char *nick) { - OscarData *od = gc->proto_data; - if (!aim_sncmp(purple_account_get_username(purple_connection_get_account(gc)), nick)) { +static void oscar_format_username(PurpleConnection *gc, const char *nick) { + OscarData *od = purple_connection_get_protocol_data(gc); + if (!oscar_util_name_compare(purple_account_get_username(purple_connection_get_account(gc)), nick)) { if (!flap_connection_getbytype(od, SNAC_FAMILY_ADMIN)) { od->setnick = TRUE; - g_free(od->newsn); - od->newsn = g_strdup(nick); + g_free(od->newformatting); + od->newformatting = g_strdup(nick); aim_srv_requestnew(od, SNAC_FAMILY_ADMIN); } else { aim_admin_setnick(od, flap_connection_getbytype(od, SNAC_FAMILY_ADMIN), nick); @@ -6514,7 +6571,7 @@ FlapConnection *conn; gc = (PurpleConnection *)action->context; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); conn = flap_connection_getbytype(od, SNAC_FAMILY_ADMIN); if (conn != NULL) { @@ -6528,7 +6585,7 @@ static void oscar_show_email(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); FlapConnection *conn = flap_connection_getbytype(od, SNAC_FAMILY_ADMIN); if (conn) { @@ -6541,7 +6598,7 @@ static void oscar_change_email(PurpleConnection *gc, const char *email) { - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); FlapConnection *conn = flap_connection_getbytype(od, SNAC_FAMILY_ADMIN); if (conn) { @@ -6567,29 +6624,40 @@ static void oscar_show_awaitingauth(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); gchar *nombre, *text, *tmp; PurpleBlistNode *gnode, *cnode, *bnode; + PurpleAccount *account; int num=0; text = g_strdup(""); - - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + account = purple_connection_get_account(gc); + + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { PurpleGroup *group = (PurpleGroup *)gnode; + const char *gname; if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) { + gname = purple_group_get_name(group); + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *buddy = (PurpleBuddy *)bnode; + const char *bname; if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - if (buddy->account == gc->account && aim_ssi_waitingforauth(od->ssi.local, group->name, buddy->name)) { + bname = purple_buddy_get_name(buddy); + if (purple_buddy_get_account(buddy) == account && aim_ssi_waitingforauth(od->ssi.local, gname, bname)) { if (purple_buddy_get_alias_only(buddy)) - nombre = g_strdup_printf(" %s (%s)", buddy->name, purple_buddy_get_alias_only(buddy)); + nombre = g_strdup_printf(" %s (%s)", bname, purple_buddy_get_alias_only(buddy)); else - nombre = g_strdup_printf(" %s", buddy->name); + nombre = g_strdup_printf(" %s", bname); tmp = g_strdup_printf("%s%s
", text, nombre); g_free(text); text = tmp; @@ -6615,7 +6683,7 @@ static void search_by_email_cb(PurpleConnection *gc, const char *email) { - OscarData *od = (OscarData *)gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); aim_search_address(od, email); } @@ -6655,7 +6723,7 @@ static void oscar_show_chpassurl(PurplePluginAction *action) { PurpleConnection *gc = (PurpleConnection *) action->context; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); gchar *substituted = purple_strreplace(od->authinfo->chpassurl, "%s", purple_account_get_username(purple_connection_get_account(gc))); purple_notify_uri(gc, substituted); g_free(substituted); @@ -6669,7 +6737,7 @@ void oscar_set_icon(PurpleConnection *gc, PurpleStoredImage *img) { - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); if (img == NULL) { aim_ssi_delicon(od); @@ -6698,7 +6766,7 @@ OscarData *od; PurpleAccount *account; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); if (od != NULL) @@ -6712,7 +6780,7 @@ */ if (((userinfo == NULL) || (userinfo->capabilities & OSCAR_CAPABILITY_SENDFILE)) && - aim_sncmp(who, purple_account_get_username(account))) + oscar_util_name_compare(who, purple_account_get_username(account))) { return TRUE; } @@ -6729,7 +6797,7 @@ PurpleAccount *account; PeerConnection *conn; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); account = purple_connection_get_account(gc); xfer = purple_xfer_new(account, PURPLE_XFER_SEND, who); @@ -6773,7 +6841,7 @@ oscar_actions(PurplePlugin *plugin, gpointer context) { PurpleConnection *gc = (PurpleConnection *) context; - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); GList *menu = NULL; PurplePluginAction *act; @@ -6853,7 +6921,7 @@ void oscar_change_passwd(PurpleConnection *gc, const char *old, const char *new) { - OscarData *od = gc->proto_data; + OscarData *od = purple_connection_get_protocol_data(gc); if (od->icq) { aim_icq_changepasswd(od, new); @@ -6877,7 +6945,7 @@ OscarData *od; PeerConnection *conn; - od = gc->proto_data; + od = purple_connection_get_protocol_data(gc); conn = peer_connection_find_by_type(od, who, OSCAR_CAPABILITY_DIRECTIM); if (conn != NULL) @@ -6968,14 +7036,14 @@ /* aim:GoIM?screenname=SCREENNAME&message=MESSAGE */ if (!g_ascii_strcasecmp(cmd, "GoIM")) { - char *sname = g_hash_table_lookup(params, "screenname"); - if (sname) { + char *bname = g_hash_table_lookup(params, "screenname"); + if (bname) { char *message = g_hash_table_lookup(params, "message"); PurpleConversation *conv = purple_find_conversation_with_account( - PURPLE_CONV_TYPE_IM, sname, acct); + PURPLE_CONV_TYPE_IM, bname, acct); if (conv == NULL) - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, sname); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, bname); purple_conversation_present(conv); if (message) { @@ -7008,9 +7076,9 @@ } /* aim:AddBuddy?screenname=SCREENNAME&groupname=GROUPNAME*/ else if (!g_ascii_strcasecmp(cmd, "AddBuddy")) { - char *sname = g_hash_table_lookup(params, "screenname"); + char *bname = g_hash_table_lookup(params, "screenname"); char *gname = g_hash_table_lookup(params, "groupname"); - purple_blist_request_add_buddy(acct, sname, gname, NULL); + purple_blist_request_add_buddy(acct, bname, gname, NULL); return TRUE; } @@ -7040,7 +7108,7 @@ option = purple_account_option_bool_new(_("Allow multiple simultaneous logins"), "allow_multiple_logins", OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS); prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option); - + if (init) return; init = TRUE; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/oscar.h Wed Jan 28 10:23:37 2009 +0000 @@ -75,7 +75,7 @@ #define FAIM_SNAC_HASH_SIZE 16 /* - * Current Maximum Length for Screen Names (not including NULL) + * Current Maximum Length for usernames (not including NULL) * * Currently only names up to 16 characters can be registered * however it is apparently legal for them to be larger. @@ -470,7 +470,7 @@ gboolean setemail; char *email; gboolean setnick; - char *newsn; + char *newformatting; gboolean chpass; char *oldp; char *newp; @@ -577,7 +577,7 @@ struct aim_authresp_info { - char *sn; + char *bn; guint16 errorcode; char *errorurl; guint16 regstatus; @@ -606,8 +606,8 @@ } chat; }; -int aim_request_login(OscarData *od, FlapConnection *conn, const char *sn); -int aim_send_login(OscarData *od, FlapConnection *conn, const char *sn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key, gboolean allow_multiple_logins); +int aim_request_login(OscarData *od, FlapConnection *conn, const char *bn); +int aim_send_login(OscarData *od, FlapConnection *conn, const char *bn, const char *password, gboolean truncate_pass, ClientInfo *ci, const char *key, gboolean allow_multiple_logins); /* 0x000b */ int aim_auth_securid_send(OscarData *od, const char *securid); void oscar_data_addhandler(OscarData *od, guint16 family, guint16 subtype, aim_rxcallback_t newhandler, guint16 flags); @@ -806,7 +806,7 @@ { /* These are _required_ */ - const char *destsn; + const char *destbn; guint32 flags; /* often 0 */ /* Only required if not using multipart messages */ @@ -835,7 +835,7 @@ */ struct aim_sendrtfmsg_args { - const char *destsn; + const char *destbn; guint32 fgcolor; guint32 bgcolor; const char *rtfmsg; /* must be in RTF */ @@ -949,28 +949,28 @@ /* 0x0002 */ int aim_im_setparams(OscarData *od, struct aim_icbmparameters *params); /* 0x0004 */ int aim_im_reqparams(OscarData *od); /* 0x0006 */ int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args); -/* 0x0006 */ int aim_im_sendch1(OscarData *, const char *destsn, guint16 flags, const char *msg); -/* 0x0006 */ int aim_im_sendch2_chatinvite(OscarData *od, const char *sn, const char *msg, guint16 exchange, const char *roomname, guint16 instance); -/* 0x0006 */ int aim_im_sendch2_icon(OscarData *od, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum); +/* 0x0006 */ int aim_im_sendch1(OscarData *, const char *destbn, guint16 flags, const char *msg); +/* 0x0006 */ int aim_im_sendch2_chatinvite(OscarData *od, const char *bn, const char *msg, guint16 exchange, const char *roomname, guint16 instance); +/* 0x0006 */ int aim_im_sendch2_icon(OscarData *od, const char *bn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum); /* 0x0006 */ int aim_im_sendch2_rtfmsg(OscarData *od, struct aim_sendrtfmsg_args *args); /* 0x0006 */ void aim_im_sendch2_cancel(PeerConnection *peer_conn); /* 0x0006 */ void aim_im_sendch2_connected(PeerConnection *peer_conn); -/* 0x0006 */ void aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber); -/* 0x0006 */ void aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber); -/* 0x0006 */ void aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles); -/* 0x0006 */ void aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles); +/* 0x0006 */ void aim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 port, guint16 requestnumber); +/* 0x0006 */ void aim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 pin, guint16 requestnumber); +/* 0x0006 */ void aim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles); +/* 0x0006 */ void aim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *bn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles); -/* 0x0006 */ int aim_im_sendch2_geticqaway(OscarData *od, const char *sn, int type); -/* 0x0006 */ int aim_im_sendch4(OscarData *od, const char *sn, guint16 type, const char *message); -/* 0x0008 */ int aim_im_warn(OscarData *od, FlapConnection *conn, const char *destsn, guint32 flags); -/* 0x000b */ int aim_im_denytransfer(OscarData *od, const char *sn, const guchar *cookie, guint16 code); +/* 0x0006 */ int aim_im_sendch2_geticqaway(OscarData *od, const char *bn, int type); +/* 0x0006 */ int aim_im_sendch4(OscarData *od, const char *bn, guint16 type, const char *message); +/* 0x0008 */ int aim_im_warn(OscarData *od, FlapConnection *conn, const char *destbn, guint32 flags); +/* 0x000b */ int aim_im_denytransfer(OscarData *od, const char *bn, const guchar *cookie, guint16 code); /* 0x0010 */ int aim_im_reqofflinemsgs(OscarData *od); -/* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *sn, guint16 type2); +/* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *bn, guint16 type2); void aim_icbm_makecookie(guchar* cookie); gchar *oscar_encoding_extract(const char *encoding); gchar *oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen); -gchar *purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcesn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen); +gchar *purple_plugin_oscar_decode_im_part(PurpleAccount *account, const char *sourcebn, guint16 charset, guint16 charsubset, const gchar *data, gsize datalen); /* 0x0002 - family_locate.c */ @@ -1005,13 +1005,13 @@ struct userinfo_node { - char *sn; + char *bn; struct userinfo_node *next; }; typedef struct aim_userinfo_s { - char *sn; + char *bn; guint16 warnlevel; /* evil percent * 10 (999 = 99.9%) */ guint16 idletime; /* in seconds */ guint16 flags; @@ -1057,7 +1057,7 @@ struct aim_invite_priv { - char *sn; + char *bn; char *roomname; guint16 exchange; guint16 instance; @@ -1080,7 +1080,7 @@ #define AIM_COOKIETYPE_OFTIMAGE 0x14 #define AIM_COOKIETYPE_OFTICON 0x15 -aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *sn); +aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *bn); void aim_locate_dorequest(OscarData *od); /* 0x0002 */ int aim_locate_reqrights(OscarData *od); @@ -1088,11 +1088,11 @@ /* 0x0004 */ int aim_locate_setprofile(OscarData *od, const char *profile_encoding, const gchar *profile, const int profile_len, const char *awaymsg_encoding, const gchar *awaymsg, const int awaymsg_len); /* 0x0005 */ int aim_locate_getinfo(OscarData *od, const char *, guint16); /* 0x0009 */ int aim_locate_setdirinfo(OscarData *od, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy); -/* 0x000b */ int aim_locate_000b(OscarData *od, const char *sn); +/* 0x000b */ int aim_locate_000b(OscarData *od, const char *bn); /* 0x000f */ int aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy); -/* 0x0015 */ int aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags); +/* 0x0015 */ int aim_locate_getinfoshort(OscarData *od, const char *bn, guint32 flags); -void aim_locate_autofetch_away_message(OscarData *od, const char *sn); +void aim_locate_autofetch_away_message(OscarData *od, const char *bn); guint32 aim_locate_getcaps(OscarData *od, ByteStream *bs, int len); guint32 aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len); void aim_info_free(aim_userinfo_t *); @@ -1159,7 +1159,7 @@ char *country; char *state; char *city; - char *sn; + char *bn; char *interest; char *nick; char *zip; @@ -1176,7 +1176,7 @@ /* 0x0010 - family_bart.c */ int aim_bart_upload(OscarData *od, const guint8 *icon, guint16 iconlen); -int aim_bart_request(OscarData *od, const char *sn, guint8 iconcsumtype, const guint8 *iconstr, guint16 iconstrlen); +int aim_bart_request(OscarData *od, const char *bn, guint8 iconcsumtype, const guint8 *iconstr, guint16 iconstrlen); @@ -1226,20 +1226,20 @@ /* 0x0007 */ int aim_ssi_enable(OscarData *od); /* 0x0011 */ int aim_ssi_modbegin(OscarData *od); /* 0x0012 */ int aim_ssi_modend(OscarData *od); -/* 0x0014 */ int aim_ssi_sendauth(OscarData *od, char *sn, char *msg); -/* 0x0018 */ int aim_ssi_sendauthrequest(OscarData *od, char *sn, const char *msg); -/* 0x001a */ int aim_ssi_sendauthreply(OscarData *od, char *sn, guint8 reply, const char *msg); +/* 0x0014 */ int aim_ssi_sendauth(OscarData *od, char *bn, char *msg); +/* 0x0018 */ int aim_ssi_sendauthrequest(OscarData *od, char *bn, const char *msg); +/* 0x001a */ int aim_ssi_sendauthreply(OscarData *od, char *bn, guint8 reply, const char *msg); /* Client functions for retrieving SSI data */ struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, guint16 gid, guint16 bid); -struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *sn, guint16 type); -struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *sn); -char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *sn); +struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *bn, guint16 type); +struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *bn); +char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *bn); int aim_ssi_getpermdeny(struct aim_ssi_item *list); guint32 aim_ssi_getpresence(struct aim_ssi_item *list); -char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn); -char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *sn); -gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn); +char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *bn); +char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *bn); +gboolean aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *bn); /* Client functions for changing SSI data */ int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, GSList *tlvlist, const char *alias, const char *comment, const char *smsnum, gboolean needauth); @@ -1249,9 +1249,9 @@ int aim_ssi_delgroup(OscarData *od, const char *group); int aim_ssi_delpermit(OscarData *od, const char *name); int aim_ssi_deldeny(OscarData *od, const char *name); -int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn); -int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *sn, const char *alias); -int aim_ssi_editcomment(OscarData *od, const char *gn, const char *sn, const char *alias); +int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *bn); +int aim_ssi_aliasbuddy(OscarData *od, const char *gn, const char *bn, const char *alias); +int aim_ssi_editcomment(OscarData *od, const char *gn, const char *bn, const char *alias); int aim_ssi_rename_group(OscarData *od, const char *oldgn, const char *newgn); int aim_ssi_cleanlist(OscarData *od); int aim_ssi_deletelist(OscarData *od); @@ -1497,11 +1497,10 @@ int aimutil_itemcnt(char *toSearch, char dl); char *aimutil_itemindex(char *toSearch, int theindex, char dl); -gboolean aim_snvalid(const char *sn); -gboolean aim_snvalid_icq(const char *sn); -gboolean aim_snvalid_sms(const char *sn); -int aim_snlen(const char *sn); -int aim_sncmp(const char *sn1, const char *sn2); +gboolean oscar_util_valid_name(const char *bn); +gboolean oscar_util_valid_name_icq(const char *bn); +gboolean oscar_util_valid_name_sms(const char *bn); +int oscar_util_name_compare(const char *bn1, const char *bn2); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/peer.c --- a/libpurple/protocols/oscar/peer.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/peer.c Wed Jan 28 10:23:37 2009 +0000 @@ -69,7 +69,7 @@ #endif PeerConnection * -peer_connection_find_by_type(OscarData *od, const char *sn, OscarCapability type) +peer_connection_find_by_type(OscarData *od, const char *bn, OscarCapability type) { GSList *cur; PeerConnection *conn; @@ -77,7 +77,7 @@ for (cur = od->peer_connections; cur != NULL; cur = cur->next) { conn = cur->data; - if ((conn->type == type) && !aim_sncmp(conn->sn, sn)) + if ((conn->type == type) && !oscar_util_name_compare(conn->bn, bn)) return conn; } @@ -88,7 +88,7 @@ * @param cookie This must be exactly 8 characters. */ PeerConnection * -peer_connection_find_by_cookie(OscarData *od, const char *sn, const guchar *cookie) +peer_connection_find_by_cookie(OscarData *od, const char *bn, const guchar *cookie) { GSList *cur; PeerConnection *conn; @@ -96,7 +96,7 @@ for (cur = od->peer_connections; cur != NULL; cur = cur->next) { conn = cur->data; - if (!memcmp(conn->cookie, cookie, 8) && !aim_sncmp(conn->sn, sn)) + if (!memcmp(conn->cookie, cookie, 8) && !oscar_util_name_compare(conn->bn, bn)) return conn; } @@ -104,7 +104,7 @@ } PeerConnection * -peer_connection_new(OscarData *od, OscarCapability type, const char *sn) +peer_connection_new(OscarData *od, OscarCapability type, const char *bn) { PeerConnection *conn; PurpleAccount *account; @@ -114,7 +114,7 @@ conn = g_new0(PeerConnection, 1); conn->od = od; conn->type = type; - conn->sn = g_strdup(sn); + conn->bn = g_strdup(bn); conn->buffer_outgoing = purple_circ_buffer_new(0); conn->listenerfd = -1; conn->fd = -1; @@ -228,7 +228,7 @@ conn->xfer = NULL; } - g_free(conn->sn); + g_free(conn->bn); g_free(conn->error_message); g_free(conn->proxyip); g_free(conn->clientip); @@ -698,20 +698,20 @@ if (conn->type == OSCAR_CAPABILITY_DIRECTIM) { aim_im_sendch2_odc_requestdirect(od, - conn->cookie, conn->sn, purple_network_ip_atoi(listener_ip), + conn->cookie, conn->bn, purple_network_ip_atoi(listener_ip), listener_port, ++conn->lastrequestnumber); /* Print a message to a local conversation window */ - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn); tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for " - "Direct IM."), conn->sn, listener_ip, listener_port); + "Direct IM."), conn->bn, listener_ip, listener_port); purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(tmp); } else if (conn->type == OSCAR_CAPABILITY_SENDFILE) { aim_im_sendch2_sendfile_requestdirect(od, - conn->cookie, conn->sn, + conn->cookie, conn->bn, purple_network_ip_atoi(listener_ip), listener_port, ++conn->lastrequestnumber, (const gchar *)conn->xferdata.name, @@ -790,7 +790,7 @@ PurpleConversation *conv; tmp = g_strdup_printf(_("Attempting to connect to %s:%hu."), conn->verifiedip, conn->port); - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn); purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(tmp); @@ -863,7 +863,7 @@ gchar *tmp; PurpleConversation *conv; tmp = g_strdup(_("Attempting to connect via proxy server.")); - conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->sn); + conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, conn->bn); purple_conversation_write(conv, NULL, tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(tmp); @@ -888,13 +888,13 @@ * Initiate a peer connection with someone. */ void -peer_connection_propose(OscarData *od, OscarCapability type, const char *sn) +peer_connection_propose(OscarData *od, OscarCapability type, const char *bn) { PeerConnection *conn; if (type == OSCAR_CAPABILITY_DIRECTIM) { - conn = peer_connection_find_by_type(od, sn, type); + conn = peer_connection_find_by_type(od, bn, type); if (conn != NULL) { if (conn->ready) @@ -903,10 +903,10 @@ PurpleConversation *conv; purple_debug_info("oscar", "Already have a direct IM " - "session with %s.\n", sn); + "session with %s.\n", bn); account = purple_connection_get_account(od->gc); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, - sn, account); + bn, account); if (conv != NULL) purple_conversation_present(conv); return; @@ -917,7 +917,7 @@ } } - conn = peer_connection_new(od, type, sn); + conn = peer_connection_new(od, type, bn); conn->flags |= PEER_CONNECTION_FLAG_INITIATED_BY_ME; conn->flags |= PEER_CONNECTION_FLAG_APPROVED; aim_icbm_makecookie(conn->cookie); @@ -954,7 +954,7 @@ conn = data; - aim_im_denytransfer(conn->od, conn->sn, conn->cookie, + aim_im_denytransfer(conn->od, conn->bn, conn->cookie, AIM_TRANSFER_DENY_DECLINE); peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL); } @@ -963,7 +963,7 @@ * Someone else wants to establish a peer connection with us. */ void -peer_connection_got_proposition(OscarData *od, const gchar *sn, const gchar *message, IcbmArgsCh2 *args) +peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *message, IcbmArgsCh2 *args) { PurpleConnection *gc; PurpleAccount *account; @@ -979,7 +979,7 @@ * and we should try connecting to them, instead. Or they want * to go through a proxy. */ - conn = peer_connection_find_by_cookie(od, sn, args->cookie); + conn = peer_connection_find_by_cookie(od, bn, args->cookie); if ((conn != NULL) && (conn->type == args->type)) { purple_debug_info("oscar", "Remote user wants to try a " @@ -1003,12 +1003,12 @@ /* If this is a direct IM, then close any existing session */ if (args->type == OSCAR_CAPABILITY_DIRECTIM) { - conn = peer_connection_find_by_type(od, sn, args->type); + conn = peer_connection_find_by_type(od, bn, args->type); if (conn != NULL) { /* Close the old direct IM and start a new one */ purple_debug_info("oscar", "Received new direct IM request " - "from %s. Destroying old connection.\n", sn); + "from %s. Destroying old connection.\n", bn); peer_connection_destroy(conn, OSCAR_DISCONNECT_REMOTE_CLOSED, NULL); } } @@ -1022,12 +1022,12 @@ { purple_debug_warning("oscar", "%s tried to send you a file with incomplete " - "information.\n", sn); + "information.\n", bn); return; } } - conn = peer_connection_new(od, args->type, sn); + conn = peer_connection_new(od, args->type, bn); memcpy(conn->cookie, args->cookie, 8); if (args->use_proxy) conn->proxyip = g_strdup(args->proxyip); @@ -1040,7 +1040,7 @@ if (args->type == OSCAR_CAPABILITY_DIRECTIM) { buf = g_strdup_printf(_("%s has just asked to directly connect to %s"), - sn, purple_account_get_username(account)); + bn, purple_account_get_username(account)); purple_request_action(conn, NULL, buf, _("This requires a direct connection between " @@ -1049,7 +1049,7 @@ "revealed, this may be considered a privacy " "risk."), PURPLE_DEFAULT_ACTION_NONE, - account, sn, NULL, + account, bn, NULL, conn, 2, _("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb), _("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb)); @@ -1058,7 +1058,7 @@ { gchar *filename; - conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, sn); + conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, bn); if (conn->xfer) { conn->xfer->data = conn; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/peer.h --- a/libpurple/protocols/oscar/peer.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/peer.h Wed Jan 28 10:23:37 2009 +0000 @@ -83,7 +83,7 @@ /* Unknown */ guint16 flags; /* 38 */ /* Unknown */ - guchar sn[32]; /* 44 */ + guchar bn[32]; /* 44 */ /* Unknown */ ByteStream payload; /* 76 */ }; @@ -137,7 +137,7 @@ { OscarData *od; OscarCapability type; - char *sn; + char *bn; guchar magic[4]; guchar cookie[8]; guint16 lastrequestnumber; @@ -228,12 +228,12 @@ * @param type The type of the peer connection. One of * OSCAR_CAPABILITY_DIRECTIM or OSCAR_CAPABILITY_SENDFILE. */ -PeerConnection *peer_connection_new(OscarData *od, OscarCapability type, const char *sn); +PeerConnection *peer_connection_new(OscarData *od, OscarCapability type, const char *bn); void peer_connection_destroy(PeerConnection *conn, OscarDisconnectReason reason, const gchar *error_message); void peer_connection_schedule_destroy(PeerConnection *conn, OscarDisconnectReason reason, const gchar *error_message); -PeerConnection *peer_connection_find_by_type(OscarData *od, const char *sn, OscarCapability type); -PeerConnection *peer_connection_find_by_cookie(OscarData *od, const char *sn, const guchar *cookie); +PeerConnection *peer_connection_find_by_type(OscarData *od, const char *bn, OscarCapability type); +PeerConnection *peer_connection_find_by_cookie(OscarData *od, const char *bn, const guchar *cookie); void peer_connection_listen_cb(gpointer data, gint source, PurpleInputCondition cond); void peer_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond); @@ -241,8 +241,8 @@ void peer_connection_trynext(PeerConnection *conn); void peer_connection_finalize_connection(PeerConnection *conn); -void peer_connection_propose(OscarData *od, OscarCapability type, const char *sn); -void peer_connection_got_proposition(OscarData *od, const gchar *sn, const gchar *message, IcbmArgsCh2 *args); +void peer_connection_propose(OscarData *od, OscarCapability type, const char *bn); +void peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *message, IcbmArgsCh2 *args); /* * For ODC diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/peer_proxy.c --- a/libpurple/protocols/oscar/peer_proxy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/peer_proxy.c Wed Jan 28 10:23:37 2009 +0000 @@ -63,19 +63,19 @@ { ProxyFrame frame; PurpleAccount *account; - const gchar *sn; - guint8 sn_length; + const gchar *bn; + guint8 bn_length; memset(&frame, 0, sizeof(ProxyFrame)); frame.type = PEER_PROXY_TYPE_CREATE; frame.flags = 0x0000; account = purple_connection_get_account(conn->od->gc); - sn = purple_account_get_username(account); - sn_length = strlen(sn); - byte_stream_new(&frame.payload, 1 + sn_length + 8 + 20); - byte_stream_put8(&frame.payload, sn_length); - byte_stream_putraw(&frame.payload, (const guint8 *)sn, sn_length); + bn = purple_account_get_username(account); + bn_length = strlen(bn); + byte_stream_new(&frame.payload, 1 + bn_length + 8 + 20); + byte_stream_put8(&frame.payload, bn_length); + byte_stream_putraw(&frame.payload, (const guint8 *)bn, bn_length); byte_stream_putraw(&frame.payload, conn->cookie, 8); byte_stream_put16(&frame.payload, 0x0001); /* Type */ @@ -99,19 +99,19 @@ { ProxyFrame frame; PurpleAccount *account; - const gchar *sn; - guint8 sn_length; + const gchar *bn; + guint8 bn_length; memset(&frame, 0, sizeof(ProxyFrame)); frame.type = PEER_PROXY_TYPE_JOIN; frame.flags = 0x0000; account = purple_connection_get_account(conn->od->gc); - sn = purple_account_get_username(account); - sn_length = strlen(sn); - byte_stream_new(&frame.payload, 1 + sn_length + 2 + 8 + 20); - byte_stream_put8(&frame.payload, sn_length); - byte_stream_putraw(&frame.payload, (const guint8 *)sn, sn_length); + bn = purple_account_get_username(account); + bn_length = strlen(bn); + byte_stream_new(&frame.payload, 1 + bn_length + 2 + 8 + 20); + byte_stream_put8(&frame.payload, bn_length); + byte_stream_putraw(&frame.payload, (const guint8 *)bn, bn_length); byte_stream_put16(&frame.payload, pin); byte_stream_putraw(&frame.payload, conn->cookie, 8); @@ -149,11 +149,11 @@ if (conn->type == OSCAR_CAPABILITY_DIRECTIM) aim_im_sendch2_odc_requestproxy(conn->od, conn->cookie, - conn->sn, ip, pin, ++conn->lastrequestnumber); + conn->bn, ip, pin, ++conn->lastrequestnumber); else if (conn->type == OSCAR_CAPABILITY_SENDFILE) { aim_im_sendch2_sendfile_requestproxy(conn->od, - conn->cookie, conn->sn, + conn->cookie, conn->bn, ip, pin, ++conn->lastrequestnumber, (const gchar *)conn->xferdata.name, conn->xferdata.size, conn->xferdata.totfiles); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/snactypes.h --- a/libpurple/protocols/oscar/snactypes.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/snactypes.h Wed Jan 28 10:23:37 2009 +0000 @@ -252,7 +252,6 @@ * SNAC Family: Authorizer * * Used only in protocol versions three and above. - * */ #define SNAC_SUBTYPE_AUTH_ERROR 0x0001 #define SNAC_SUBTYPE_AUTH_LOGINREQEST 0x0002 @@ -266,8 +265,7 @@ * SNAC Family: Email * * Used for getting information on the email address - * associated with your screen name. - * + * associated with your username. */ #define SNAC_SUBTYPE_ALERT_ERROR 0x0001 #define SNAC_SUBTYPE_ALERT_SENDCOOKIES 0x0006 @@ -280,7 +278,6 @@ * This isn't truly a SNAC family either, but using * these, we can integrated non-SNAC services into * the SNAC-centered libfaim callback structure. - * */ #define AIM_CB_SPECIAL_CONNERR 0x0003 #define AIM_CB_SPECIAL_CONNINITDONE 0x0006 diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/oscar/util.c --- a/libpurple/protocols/oscar/util.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/oscar/util.c Wed Jan 28 10:23:37 2009 +0000 @@ -136,27 +136,27 @@ } /** - * Check if the given screen name is a valid AIM screen name. + * Check if the given name is a valid AIM username. * Example: BobDole * Example: Henry_Ford@mac.com * Example: 1KrazyKat@example.com * - * @return TRUE if the screen name is valid, FALSE if not. + * @return TRUE if the name is valid, FALSE if not. */ static gboolean -aim_snvalid_aim(const char *sn) +oscar_util_valid_name_aim(const char *name) { int i; - if (purple_email_is_valid(sn)) + if (purple_email_is_valid(name)) return TRUE; - /* Normal AIM screen names can't start with a number */ - if (isdigit(sn[0])) + /* Normal AIM usernames can't start with a number */ + if (isdigit(name[0])) return FALSE; - for (i = 0; sn[i] != '\0'; i++) { - if (!isalnum(sn[i]) && (sn[i] != ' ')) + for (i = 0; name[i] != '\0'; i++) { + if (!isalnum(name[i]) && (name[i] != ' ')) return FALSE; } @@ -164,18 +164,18 @@ } /** - * Check if the given screen name is a valid ICQ screen name. + * Check if the given name is a valid ICQ username. * Example: 1234567 * - * @return TRUE if the screen name is valid, FALSE if not. + * @return TRUE if the name is valid, FALSE if not. */ gboolean -aim_snvalid_icq(const char *sn) +oscar_util_valid_name_icq(const char *name) { int i; - for (i = 0; sn[i] != '\0'; i++) { - if (!isdigit(sn[i])) + for (i = 0; name[i] != '\0'; i++) { + if (!isdigit(name[i])) return FALSE; } @@ -183,21 +183,21 @@ } /** - * Check if the given screen name is a valid SMS screen name. + * Check if the given name is a valid SMS username. * Example: +19195551234 * - * @return TRUE if the screen name is valid, FALSE if not. + * @return TRUE if the name is valid, FALSE if not. */ gboolean -aim_snvalid_sms(const char *sn) +oscar_util_valid_name_sms(const char *name) { int i; - if (sn[0] != '+') + if (name[0] != '+') return FALSE; - for (i = 1; sn[i] != '\0'; i++) { - if (!isdigit(sn[i])) + for (i = 1; name[i] != '\0'; i++) { + if (!isdigit(name[i])) return FALSE; } @@ -205,44 +205,46 @@ } /** - * Check if the given screen name is a valid oscar screen name. + * Check if the given name is a valid oscar username. * - * @return TRUE if the screen name is valid, FALSE if not. + * @return TRUE if the name is valid, FALSE if not. */ gboolean -aim_snvalid(const char *sn) +oscar_util_valid_name(const char *name) { - if ((sn == NULL) || (*sn == '\0')) + if ((name == NULL) || (*name == '\0')) return FALSE; - return aim_snvalid_icq(sn) || aim_snvalid_sms(sn) || aim_snvalid_aim(sn); + return oscar_util_valid_name_icq(name) + || oscar_util_valid_name_sms(name) + || oscar_util_valid_name_aim(name); } /** - * This takes two screen names and compares them using the rules - * on screen names for AIM/AOL. Mainly, this means case and space + * This takes two names and compares them using the rules + * on usernames for AIM/AOL. Mainly, this means case and space * insensitivity (all case differences and spacing differences are - * ignored, with the exception that screen names can not start with + * ignored, with the exception that usernames can not start with * a space). * * @return 0 if equal, non-0 if different */ /* TODO: Do something different for email addresses. */ int -aim_sncmp(const char *sn1, const char *sn2) +oscar_util_name_compare(const char *name1, const char *name2) { - if ((sn1 == NULL) || (sn2 == NULL)) + if ((name1 == NULL) || (name2 == NULL)) return -1; do { - while (*sn2 == ' ') - sn2++; - while (*sn1 == ' ') - sn1++; - if (toupper(*sn1) != toupper(*sn2)) + while (*name2 == ' ') + name2++; + while (*name1 == ' ') + name1++; + if (toupper(*name1) != toupper(*name2)) return 1; - } while ((*sn1 != '\0') && sn1++ && sn2++); + } while ((*name1 != '\0') && name1++ && name2++); return 0; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/buddy_info.c --- a/libpurple/protocols/qq/buddy_info.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/buddy_info.c Wed Jan 28 10:23:37 2009 +0000 @@ -612,7 +612,7 @@ gchar *alias_utf8; PurpleAccount *account = purple_connection_get_account(gc); - qd = (qq_data *) gc->proto_data; + qd = (qq_data *)purple_connection_get_protocol_data(gc); uid = strtoul(segments[QQ_INFO_UID], NULL, 10); who = uid_to_purple_name(uid); @@ -631,15 +631,16 @@ buddy = purple_find_buddy(gc->account, who); } - if (buddy == NULL || buddy->proto_data == NULL) { + /* if the buddy is null, the api will catch it and return null here */ + bd = purple_buddy_get_protocol_data(buddy); + + if (buddy == NULL || bd) { g_free(who); g_free(alias_utf8); return; } /* update buddy list (including myself, if myself is the buddy) */ - bd = (qq_buddy_data *)buddy->proto_data; - bd->age = strtol(segments[QQ_INFO_AGE], NULL, 10); bd->gender = strtol(segments[QQ_INFO_GENDER], NULL, 10); bd->face = strtol(segments[QQ_INFO_FACE], NULL, 10); @@ -768,8 +769,7 @@ for (it = buddies; it; it = it->next) { buddy = it->data; if (buddy == NULL) continue; - if (buddy->proto_data == NULL) continue; - bd = (qq_buddy_data *)buddy->proto_data; + if ((bd = purple_buddy_get_protocol_data(buddy)) == NULL) continue; if (bd->uid == 0) continue; /* keep me as end of packet*/ if (bd->uid == qd->uid) continue; bytes += qq_put32(buf + bytes, bd->uid); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/buddy_list.c --- a/libpurple/protocols/qq/buddy_list.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/buddy_list.c Wed Jan 28 10:23:37 2009 +0000 @@ -232,7 +232,7 @@ /* create no-auth buddy */ buddy = qq_buddy_new(gc, bs.uid); } - bd = (buddy == NULL) ? NULL : (qq_buddy_data *)buddy->proto_data; + bd = (buddy == NULL) ? NULL : (qq_buddy_data *)purple_buddy_get_protocol_data(buddy); if (bd == NULL) { purple_debug_error("QQ", "Got an online buddy %u, but not in my buddy list\n", bs.uid); @@ -334,7 +334,7 @@ #endif buddy = qq_buddy_find_or_new(gc, bd.uid); - if (buddy == NULL || buddy->proto_data == NULL) { + if (buddy == NULL || purple_buddy_get_protocol_data(buddy) == NULL) { g_free(bd.nickname); continue; } @@ -342,7 +342,7 @@ bd.last_update = time(NULL); qq_update_buddy_status(gc, bd.uid, bd.status, bd.comm_flag); - g_memmove(buddy->proto_data, &bd, sizeof(qq_buddy_data)); + g_memmove(purple_buddy_get_protocol_data(buddy), &bd, sizeof(qq_buddy_data)); /* nickname has been copy to buddy_data do not free g_free(bd.nickname); */ @@ -567,7 +567,7 @@ /* create no-auth buddy */ buddy = qq_buddy_new(gc, bs.uid); } - bd = (buddy == NULL) ? NULL : (qq_buddy_data *) buddy->proto_data; + bd = (buddy == NULL) ? NULL : (qq_buddy_data *)purple_buddy_get_protocol_data(buddy); if (bd == NULL) { purple_debug_warning("QQ", "Got status of no-auth buddy %u\n", bs.uid); return; @@ -659,9 +659,10 @@ for (it = buddies; it; it = it->next) { buddy = it->data; if (buddy == NULL) continue; - if (buddy->proto_data == NULL) continue; - bd = (qq_buddy_data *)buddy->proto_data; + bd = purple_buddy_get_protocol_data(buddy); + if (bd == NULL) continue; + if (bd->uid == 0) continue; if (bd->uid == qd->uid) continue; /* my status is always online in my buddy list */ if (tm_limit < bd->last_update) continue; @@ -681,16 +682,20 @@ GSList *buddies, *it; gint count = 0; - qd = (qq_data *) (gc->proto_data); + qd = (qq_data *)purple_connection_get_protocol_data(gc); buddies = purple_find_buddies(purple_connection_get_account(gc), NULL); for (it = buddies; it; it = it->next) { + qq_buddy_data *qbd = NULL; + buddy = it->data; if (buddy == NULL) continue; - if (buddy->proto_data == NULL) continue; - qq_buddy_data_free(buddy->proto_data); - buddy->proto_data = NULL; + qbd = purple_buddy_get_protocol_data(buddy); + if (qbd == NULL) continue; + + qq_buddy_data_free(qbd); + purple_buddy_set_protocol_data(buddy, NULL); count++; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/buddy_opt.c --- a/libpurple/protocols/qq/buddy_opt.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/buddy_opt.c Wed Jan 28 10:23:37 2009 +0000 @@ -101,6 +101,7 @@ { gchar *who; PurpleBuddy *buddy; + qq_buddy_data *bd; g_return_val_if_fail(gc != NULL, NULL); @@ -113,11 +114,12 @@ purple_debug_error("QQ", "Can not find purple buddy of %u\n", uid); return NULL; } - if (buddy->proto_data == NULL) { + + if ((bd = purple_buddy_get_protocol_data(buddy)) == NULL) { purple_debug_error("QQ", "Can not find buddy data of %u\n", uid); return NULL; } - return (qq_buddy_data *)buddy->proto_data; + return bd; } void qq_buddy_data_free(qq_buddy_data *bd) @@ -149,7 +151,7 @@ purple_debug_info("QQ", "Add new purple buddy: [%u]\n", uid); who = uid_to_purple_name(uid); buddy = purple_buddy_new(gc->account, who, NULL); /* alias is NULL */ - buddy->proto_data = NULL; + purple_buddy_set_protocol_data(buddy, NULL); g_free(who); @@ -162,11 +164,14 @@ static void qq_buddy_free(PurpleBuddy *buddy) { + qq_buddy_data *bd; + g_return_if_fail(buddy); - if (buddy->proto_data) { - qq_buddy_data_free(buddy->proto_data); + + if ((bd = purple_buddy_get_protocol_data(buddy)) != NULL) { + qq_buddy_data_free(bd); } - buddy->proto_data = NULL; + purple_buddy_set_protocol_data(buddy, NULL); purple_blist_remove_buddy(buddy); } @@ -186,6 +191,7 @@ PurpleBuddy *qq_buddy_find_or_new(PurpleConnection *gc, guint32 uid) { PurpleBuddy *buddy; + qq_buddy_data *bd; g_return_val_if_fail(gc->account != NULL && uid != 0, NULL); @@ -197,11 +203,12 @@ } } - if (buddy->proto_data != NULL) { + if (purple_buddy_get_protocol_data(buddy) != NULL) { return buddy; } - buddy->proto_data = qq_buddy_data_new(uid); + bd = qq_buddy_data_new(uid); + purple_buddy_set_protocol_data(buddy, bd); return buddy; } @@ -691,7 +698,7 @@ if (!qd->is_login) return; /* IMPORTANT ! */ - uid = purple_name_to_uid(buddy->name); + uid = purple_name_to_uid(purple_buddy_get_name(buddy)); if (uid > 0) { if (qd->client_version > 2005) { request_add_buddy_no_auth_ex(gc, uid); @@ -782,6 +789,7 @@ gchar **segments; gchar *dest_uid, *reply; PurpleBuddy *buddy; + qq_buddy_data *bd; g_return_if_fail(data != NULL && data_len != 0); g_return_if_fail(uid != 0); @@ -826,10 +834,10 @@ if (buddy == NULL) { buddy = qq_buddy_new(gc, uid); } - if (buddy != NULL && buddy->proto_data != NULL) { + if (buddy != NULL && (bd = purple_buddy_get_protocol_data(buddy)) != NULL) { /* Not authorized now, free buddy data */ - qq_buddy_data_free(buddy->proto_data); - buddy->proto_data = NULL; + qq_buddy_data_free(bd); + purple_buddy_set_protocol_data(buddy, NULL); } add_buddy_authorize_input(gc, uid, NULL, 0); @@ -905,6 +913,7 @@ void qq_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { qq_data *qd; + qq_buddy_data *bd; guint32 uid; g_return_if_fail(gc != NULL && gc->proto_data != NULL); @@ -914,7 +923,7 @@ if (!qd->is_login) return; - uid = purple_name_to_uid(buddy->name); + uid = purple_name_to_uid(purple_buddy_get_name(buddy)); if (uid > 0 && uid != qd->uid) { if (qd->client_version > 2005) { qq_request_auth_code(gc, QQ_AUTH_INFO_BUDDY, QQ_AUTH_INFO_REMOVE_BUDDY, uid); @@ -924,11 +933,11 @@ } } - if (buddy->proto_data) { - qq_buddy_data_free(buddy->proto_data); - buddy->proto_data = NULL; + if ((bd = purple_buddy_get_protocol_data(buddy)) != NULL) { + qq_buddy_data_free(bd); + purple_buddy_set_protocol_data(buddy, NULL); } else { - purple_debug_warning("QQ", "Empty buddy data of %s\n", buddy->name); + purple_debug_warning("QQ", "Empty buddy data of %s\n", purple_buddy_get_name(buddy)); } /* Do not call purple_blist_remove_buddy, @@ -1216,6 +1225,7 @@ gint bytes; gchar **segments; gchar *primary, *secondary; + qq_buddy_data *bd; g_return_if_fail(from != NULL && to != NULL); @@ -1255,10 +1265,10 @@ g_return_if_fail(uid != 0); buddy = qq_buddy_find(gc, uid); - if (buddy != NULL && buddy->proto_data != NULL) { + if (buddy != NULL && (bd = purple_buddy_get_protocol_data(buddy)) != NULL) { /* Not authorized now, free buddy data */ - qq_buddy_data_free(buddy->proto_data); - buddy->proto_data = NULL; + qq_buddy_data_free(bd); + purple_buddy_set_protocol_data(buddy, NULL); } } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/group_internal.c --- a/libpurple/protocols/qq/group_internal.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/group_internal.c Wed Jan 28 10:23:37 2009 +0000 @@ -103,16 +103,21 @@ void qq_room_update_chat_info(PurpleChat *chat, qq_room_data *rmd) { + GHashTable *components; + if (rmd->title_utf8 != NULL && strlen(rmd->title_utf8) > 0) { purple_blist_alias_chat(chat, rmd->title_utf8); } - g_hash_table_replace(chat->components, + + components = purple_chat_get_components(chat); + + g_hash_table_replace(components, g_strdup(QQ_ROOM_KEY_INTERNAL_ID), g_strdup_printf("%u", rmd->id)); - g_hash_table_replace(chat->components, + g_hash_table_replace(components, g_strdup(QQ_ROOM_KEY_EXTERNAL_ID), g_strdup_printf("%u", rmd->ext_id)); - g_hash_table_replace(chat->components, + g_hash_table_replace(components, g_strdup(QQ_ROOM_KEY_TITLE_UTF8), g_strdup(rmd->title_utf8)); } @@ -251,11 +256,13 @@ member->uid = member_uid; buddy = purple_find_buddy(purple_connection_get_account(gc), uid_to_purple_name(member_uid)); if (buddy != NULL) { - bd = (qq_buddy_data *) buddy->proto_data; + const gchar *alias = NULL; + + bd = purple_buddy_get_protocol_data(buddy); if (bd != NULL && bd->nickname != NULL) member->nickname = g_strdup(bd->nickname); - else if (buddy->alias != NULL) - member->nickname = g_strdup(buddy->alias); + else if ((alias = purple_buddy_get_alias(buddy)) != NULL) + member->nickname = g_strdup(alias); } rmd->members = g_list_append(rmd->members, member); } @@ -384,16 +391,19 @@ } count = 0; - for (node = ((PurpleBlistNode *) purple_group)->child; node != NULL; node = node->next) { + for (node = purple_blist_node_get_first_child((PurpleBlistNode *)purple_group); + node != NULL; + node = purple_blist_node_get_sibling_next(node)) + { if ( !PURPLE_BLIST_NODE_IS_CHAT(node)) { continue; } /* got one */ chat = (PurpleChat *) node; - if (account != chat->account) /* not qq account*/ + if (account != purple_chat_get_account(chat)) /* not qq account*/ continue; - rmd = room_data_new_by_hashtable(gc, chat->components); + rmd = room_data_new_by_hashtable(gc, purple_chat_get_components(chat)); qd->groups = g_list_append(qd->groups, rmd); count++; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/im.c --- a/libpurple/protocols/qq/im.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/im.c Wed Jan 28 10:23:37 2009 +0000 @@ -788,7 +788,7 @@ /* create no-auth buddy */ buddy = qq_buddy_new(gc, im_header->uid_from); } - bd = (buddy == NULL) ? NULL : (qq_buddy_data *) buddy->proto_data; + bd = (buddy == NULL) ? NULL : purple_buddy_get_protocol_data(buddy); if (bd != NULL) { bd->client_tag = im_header->version_from; bd->face = im_text.sender_icon; @@ -889,7 +889,7 @@ /* create no-auth buddy */ buddy = qq_buddy_new(gc, im_header->uid_from); } - bd = (buddy == NULL) ? NULL : (qq_buddy_data *) buddy->proto_data; + bd = (buddy == NULL) ? NULL : purple_buddy_get_protocol_data(buddy); if (bd != NULL) { bd->client_tag = im_header->version_from; bd->face = im_text.sender_icon; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/qq.c --- a/libpurple/protocols/qq/qq.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/qq.c Wed Jan 28 10:23:37 2009 +0000 @@ -246,7 +246,7 @@ qq_buddy_data *bd; GString *status; - bd = (qq_buddy_data *) b->proto_data; + bd = purple_buddy_get_protocol_data(b); if (bd == NULL) return NULL; @@ -289,7 +289,7 @@ g_return_if_fail(b != NULL); - bd = (qq_buddy_data *) b->proto_data; + bd = purple_buddy_get_protocol_data(b); if (bd == NULL) return; @@ -380,11 +380,12 @@ qq_data *qd; qq_buddy_data *buddy; - if (!b || !(account = b->account) || - !(gc = purple_account_get_connection(account)) || !(qd = gc->proto_data)) + if (!b || !(account = purple_buddy_get_account(b)) || + !(gc = purple_account_get_connection(account)) || + !(qd = purple_connection_get_protocol_data(gc))) return NULL; - buddy = (qq_buddy_data *)b->proto_data; + buddy = purple_buddy_get_protocol_data(b); if (!buddy) { return "not-authorized"; } @@ -693,8 +694,9 @@ static void action_chat_quit(PurpleBlistNode * node) { PurpleChat *chat = (PurpleChat *)node; - PurpleConnection *gc = purple_account_get_connection(chat->account); - GHashTable *components = chat -> components; + PurpleAccount *account = purple_chat_get_account(chat); + PurpleConnection *gc = purple_account_get_connection(account); + GHashTable *components = purple_chat_get_components(chat); gchar *num_str; guint32 room_id; @@ -712,8 +714,9 @@ static void action_chat_get_info(PurpleBlistNode * node) { PurpleChat *chat = (PurpleChat *)node; - PurpleConnection *gc = purple_account_get_connection(chat->account); - GHashTable *components = chat -> components; + PurpleAccount *account = purple_chat_get_account(chat); + PurpleConnection *gc = purple_account_get_connection(account); + GHashTable *components = purple_chat_get_components(chat); gchar *num_str; guint32 room_id; @@ -800,7 +803,7 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); qq_add_buddy(gc, buddy, NULL); } @@ -813,7 +816,7 @@ PurpleConnection *gc = purple_account_get_connection(buddy->account); qq_data *qd = gc->proto_data; */ - qq_buddy_data *bd = (qq_buddy_data *)buddy->proto_data; + qq_buddy_data *bd = purple_buddy_get_protocol_data(buddy); if (bd == NULL) { act = purple_menu_action_new(_("Add Buddy"), diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/qq/send_file.c --- a/libpurple/protocols/qq/send_file.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/qq/send_file.c Wed Jan 28 10:23:37 2009 +0000 @@ -808,7 +808,7 @@ "Received a FACE ip detect from %d, so he/she must be online :)\n", sender_uid); b = purple_find_buddy(gc->account, sender_name); - bd = (b == NULL) ? NULL : (qq_buddy_data *) b->proto_data; + bd = (b == NULL) ? NULL : purple_buddy_get_protocol_data(b); if (bd) { if(0 != info->remote_real_ip) { g_memmove(&(bd->ip), &info->remote_real_ip, sizeof(bd->ip)); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/sametime/sametime.c --- a/libpurple/protocols/sametime/sametime.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/sametime/sametime.c Wed Jan 28 10:23:37 2009 +0000 @@ -663,7 +663,6 @@ */ PurpleAccount *acct; - PurpleBuddyList *blist; PurpleBlistNode *gn, *cn, *bn; PurpleGroup *grp; PurpleBuddy *bdy; @@ -674,10 +673,8 @@ acct = purple_connection_get_account(gc); g_return_if_fail(acct != NULL); - blist = purple_get_blist(); - g_return_if_fail(blist != NULL); - - for(gn = blist->root; gn; gn = gn->next) { + for(gn = purple_blist_get_root(); gn; + gn = purple_blist_node_get_sibling_next(gn)) { const char *owner; const char *gname; enum mwSametimeGroupType gtype; @@ -702,13 +699,13 @@ /* the group's actual name may be different from the purple group's name. Find whichever is there */ gname = purple_blist_node_get_string(gn, GROUP_KEY_NAME); - if(! gname) gname = grp->name; + if(! gname) gname = purple_group_get_name(grp); /* we save this, but never actually honor it */ gopen = ! purple_blist_node_get_bool(gn, GROUP_KEY_COLLAPSED); stg = mwSametimeGroup_new(stlist, gtype, gname); - mwSametimeGroup_setAlias(stg, grp->name); + mwSametimeGroup_setAlias(stg, purple_group_get_name(grp)); mwSametimeGroup_setOpen(stg, gopen); /* don't attempt to put buddies in a dynamic group, it breaks @@ -716,27 +713,31 @@ if(gtype == mwSametimeGroup_DYNAMIC) continue; - for(cn = gn->child; cn; cn = cn->next) { + for(cn = purple_blist_node_get_first_child(gn); + cn; + cn = purple_blist_node_get_sibling_next(cn)) { if(! PURPLE_BLIST_NODE_IS_CONTACT(cn)) continue; - for(bn = cn->child; bn; bn = bn->next) { + for(bn = purple_blist_node_get_first_child(cn); + bn; + bn = purple_blist_node_get_sibling_next(bn)) { if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue; if(! PURPLE_BLIST_NODE_SHOULD_SAVE(bn)) continue; bdy = (PurpleBuddy *) bn; - if(bdy->account == acct) { + if(purple_buddy_get_account(bdy) == acct) { struct mwSametimeUser *stu; enum mwSametimeUserType utype; - idb.user = bdy->name; + idb.user = (char *)purple_buddy_get_name(bdy); utype = purple_blist_node_get_int(bn, BUDDY_KEY_TYPE); if(! utype) utype = mwSametimeUser_NORMAL; stu = mwSametimeUser_new(stg, utype, &idb); - mwSametimeUser_setShortName(stu, bdy->server_alias); - mwSametimeUser_setAlias(stu, bdy->alias); + mwSametimeUser_setShortName(stu, purple_buddy_get_server_alias(bdy)); + mwSametimeUser_setAlias(stu, purple_buddy_get_local_buddy_alias(bdy)); } } } @@ -816,7 +817,7 @@ static gboolean buddy_is_external(PurpleBuddy *b) { g_return_val_if_fail(b != NULL, FALSE); - return purple_str_has_prefix(b->name, "@E "); + return purple_str_has_prefix(purple_buddy_get_name(b), "@E "); } @@ -825,7 +826,7 @@ static void buddy_add(struct mwPurplePluginData *pd, PurpleBuddy *buddy) { - struct mwAwareIdBlock idb = { mwAware_USER, (char *) buddy->name, NULL }; + struct mwAwareIdBlock idb = { mwAware_USER, (char *) purple_buddy_get_name(buddy), NULL }; struct mwAwareList *list; PurpleGroup *group; @@ -890,7 +891,7 @@ GList *add; n = purple_blist_node_get_string((PurpleBlistNode *) group, GROUP_KEY_NAME); - if(! n) n = group->name; + if(! n) n = purple_group_get_name(group); idb.user = (char *) n; add = g_list_prepend(NULL, &idb); @@ -926,7 +927,8 @@ NSTR(name), NSTR(alias)); /* first attempt at finding the group, by the name key */ - for(gn = blist->root; gn; gn = gn->next) { + for(gn = purple_blist_get_root(); gn; + gn = purple_blist_node_get_sibling_next(gn)) { const char *n, *o; if(! PURPLE_BLIST_NODE_IS_GROUP(gn)) continue; n = purple_blist_node_get_string(gn, GROUP_KEY_NAME); @@ -1006,23 +1008,27 @@ g_return_if_fail(group != NULL); - DEBUG_INFO("clearing members from pruned group %s\n", NSTR(group->name)); + DEBUG_INFO("clearing members from pruned group %s\n", NSTR(purple_group_get_name(group))); gc = purple_account_get_connection(acct); g_return_if_fail(gc != NULL); gn = (PurpleBlistNode *) group; - for(cn = gn->child; cn; cn = cn->next) { + for(cn = purple_blist_node_get_first_child(gn); + cn; + cn = purple_blist_node_get_sibling_next(cn)) { if(! PURPLE_BLIST_NODE_IS_CONTACT(cn)) continue; - for(bn = cn->child; bn; bn = bn->next) { + for(bn = purple_blist_node_get_first_child(cn); + bn; + bn = purple_blist_node_get_sibling_next(bn)) { PurpleBuddy *gb = (PurpleBuddy *) bn; if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue; - if(gb->account == acct) { - DEBUG_INFO("clearing %s from group\n", NSTR(gb->name)); + if(purple_buddy_get_account(gb) == acct) { + DEBUG_INFO("clearing %s from group\n", NSTR(purple_buddy_get_name(gb))); prune = g_list_prepend(prune, gb); } } @@ -1059,7 +1065,7 @@ g_return_if_fail(group != NULL); - DEBUG_INFO("pruning membership of group %s\n", NSTR(group->name)); + DEBUG_INFO("pruning membership of group %s\n", NSTR(purple_group_get_name(group))); acct = purple_connection_get_account(gc); g_return_if_fail(acct != NULL); @@ -1078,18 +1084,22 @@ gn = (PurpleBlistNode *) group; - for(cn = gn->child; cn; cn = cn->next) { + for(cn = purple_blist_node_get_first_child(gn); + cn; + cn = purple_blist_node_get_sibling_next(cn)) { if(! PURPLE_BLIST_NODE_IS_CONTACT(cn)) continue; - for(bn = cn->child; bn; bn = bn->next) { + for(bn = purple_blist_node_get_first_child(cn); + bn; + bn = purple_blist_node_get_sibling_next(bn)) { PurpleBuddy *gb = (PurpleBuddy *) bn; if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue; /* if the account is correct and they're not in our table, mark them for pruning */ - if(gb->account == acct && !g_hash_table_lookup(stusers, gb->name)) { - DEBUG_INFO("marking %s for pruning\n", NSTR(gb->name)); + if(purple_buddy_get_account(gb) == acct && !g_hash_table_lookup(stusers, purple_buddy_get_name(gb))) { + DEBUG_INFO("marking %s for pruning\n", NSTR(purple_buddy_get_name(gb))); prune = g_list_prepend(prune, gb); } } @@ -1145,7 +1155,8 @@ g_list_free(gtl); /* find all groups which should be pruned from the local list */ - for(gn = blist->root; gn; gn = gn->next) { + for(gn = purple_blist_get_root(); gn; + gn = purple_blist_node_get_sibling_next(gn)) { PurpleGroup *grp = (PurpleGroup *) gn; const char *gname, *owner; struct mwSametimeGroup *stgrp; @@ -1164,12 +1175,12 @@ /* we actually are synching by this key as opposed to the group title, which can be different things in the st list */ gname = purple_blist_node_get_string(gn, GROUP_KEY_NAME); - if(! gname) gname = grp->name; + if(! gname) gname = purple_group_get_name(grp); stgrp = g_hash_table_lookup(stgroups, gname); if(! stgrp) { /* remove the whole group */ - DEBUG_INFO("marking group %s for pruning\n", grp->name); + DEBUG_INFO("marking group %s for pruning\n", purple_group_get_name(grp)); g_prune = g_list_prepend(g_prune, grp); } else { @@ -1284,6 +1295,7 @@ GString *str; char *tmp; + const char *gname; g_return_if_fail(pd != NULL); @@ -1295,11 +1307,12 @@ str = g_string_new(NULL); tmp = (char *) purple_blist_node_get_string(node, GROUP_KEY_NAME); - - g_string_append_printf(str, _("Group Title: %s
"), group->name); + gname = purple_group_get_name(group); + + g_string_append_printf(str, _("Group Title: %s
"), gname); g_string_append_printf(str, _("Notes Group ID: %s
"), tmp); - tmp = g_strdup_printf(_("Info for Group %s"), group->name); + tmp = g_strdup_printf(_("Info for Group %s"), gname); purple_notify_formatted(gc, tmp, _("Notes Address Book Information"), NULL, str->str, NULL, NULL); @@ -1356,19 +1369,24 @@ PurpleBlistNode *gnode, *cnode, *bnode; GList *add_buds = NULL; - for(gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + for(gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if(! PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if(! PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for(bnode = cnode->child; bnode; bnode = bnode->next) { + for(bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *b; if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - + b = (PurpleBuddy *)bnode; - if(b->account == acct) { + if(purple_buddy_get_account(b) == acct) { add_buds = g_list_append(add_buds, b); } } @@ -1388,7 +1406,6 @@ PurpleConnection *gc; PurpleAccount *acct; struct mwStorageUnit *unit; - PurpleBuddyList *blist; PurpleBlistNode *l; gc = pd->gc; @@ -1399,8 +1416,8 @@ mwServiceStorage_load(pd->srvc_store, unit, fetch_blist_cb, pd, NULL); /* find all the NAB groups and subscribe to them */ - blist = purple_get_blist(); - for(l = blist->root; l; l = l->next) { + for(l = purple_blist_get_root(); l; + l = purple_blist_node_get_sibling_next(l)) { PurpleGroup *group = (PurpleGroup *) l; enum mwSametimeGroupType gt; const char *owner; @@ -3239,10 +3256,10 @@ static char *mw_prpl_status_text(PurpleBuddy *b) { PurpleConnection *gc; struct mwPurplePluginData *pd; - struct mwAwareIdBlock t = { mwAware_USER, b->name, NULL }; + struct mwAwareIdBlock t = { mwAware_USER, (char *)purple_buddy_get_name(b), NULL }; const char *ret = NULL; - if ((gc = purple_account_get_connection(b->account)) + if ((gc = purple_account_get_connection(purple_buddy_get_account(b))) && (pd = gc->proto_data)) ret = mwServiceAware_getText(pd->srvc_aware, &t); @@ -3299,13 +3316,13 @@ static void mw_prpl_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { PurpleConnection *gc; struct mwPurplePluginData *pd = NULL; - struct mwAwareIdBlock idb = { mwAware_USER, b->name, NULL }; + struct mwAwareIdBlock idb = { mwAware_USER, (char *)purple_buddy_get_name(b), NULL }; const char *message = NULL; const char *status; char *tmp; - if ((gc = purple_account_get_connection(b->account)) + if ((gc = purple_account_get_connection(purple_buddy_get_account(b))) && (pd = gc->proto_data)) message = mwServiceAware_getText(pd->srvc_aware, &idb); @@ -3321,7 +3338,7 @@ } if(full && pd != NULL) { - tmp = user_supports_text(pd->srvc_aware, b->name); + tmp = user_supports_text(pd->srvc_aware, purple_buddy_get_name(b)); if(tmp) { purple_notify_user_info_add_pair(user_info, _("Supports"), tmp); g_free(tmp); @@ -3333,34 +3350,34 @@ } } - -static GList *mw_prpl_status_types(PurpleAccount *acct) { - GList *types = NULL; - PurpleStatusType *type; - - type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, MW_STATE_ACTIVE, - NULL, TRUE); - purple_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), - purple_value_new(PURPLE_TYPE_STRING)); - types = g_list_append(types, type); - - type = purple_status_type_new(PURPLE_STATUS_AWAY, MW_STATE_AWAY, - NULL, TRUE); - purple_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), - purple_value_new(PURPLE_TYPE_STRING)); - types = g_list_append(types, type); - - type = purple_status_type_new(PURPLE_STATUS_UNAVAILABLE, MW_STATE_BUSY, - _("Do Not Disturb"), TRUE); - purple_status_type_add_attr(type, MW_STATE_MESSAGE, _("Message"), - purple_value_new(PURPLE_TYPE_STRING)); - types = g_list_append(types, type); - - type = purple_status_type_new(PURPLE_STATUS_OFFLINE, MW_STATE_OFFLINE, - NULL, TRUE); - types = g_list_append(types, type); - - return types; +static GList *mw_prpl_status_types(PurpleAccount *acct) +{ + GList *types = NULL; + PurpleStatusType *type; + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + MW_STATE_ACTIVE, NULL, TRUE, TRUE, FALSE, + MW_STATE_MESSAGE, _("Message"), purple_value_new(PURPLE_TYPE_STRING), + NULL); + types = g_list_append(types, type); + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, + MW_STATE_AWAY, NULL, TRUE, TRUE, FALSE, + MW_STATE_MESSAGE, _("Message"), purple_value_new(PURPLE_TYPE_STRING), + NULL); + types = g_list_append(types, type); + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, + MW_STATE_BUSY, _("Do Not Disturb"), TRUE, TRUE, FALSE, + MW_STATE_MESSAGE, _("Message"), purple_value_new(PURPLE_TYPE_STRING), + NULL); + types = g_list_append(types, type); + + type = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, + MW_STATE_OFFLINE, NULL, TRUE, TRUE, FALSE); + types = g_list_append(types, type); + + return types; } @@ -3383,7 +3400,7 @@ struct mwConference *conf; struct mwIdBlock idb = { NULL, NULL }; - acct = buddy->account; + acct = purple_buddy_get_account(buddy); gc = purple_account_get_connection(acct); pd = gc->proto_data; srvc = pd->srvc_conf; @@ -3397,7 +3414,7 @@ conf = mwConference_new(srvc, topic); mwConference_open(conf); - idb.user = buddy->name; + idb.user = (char *)purple_buddy_get_name(buddy); mwConference_invite(conf, &idb, invite); } @@ -3417,7 +3434,7 @@ g_return_if_fail(buddy != NULL); - acct = buddy->account; + acct = purple_buddy_get_account(buddy); g_return_if_fail(acct != NULL); gc = purple_account_get_connection(acct); @@ -3437,7 +3454,7 @@ msgA = _("Create conference with user"); msgB = _("Please enter a topic for the new conference, and an invitation" " message to be sent to %s"); - msg1 = g_strdup_printf(msgB, buddy->name); + msg1 = g_strdup_printf(msgB, purple_buddy_get_name(buddy)); purple_request_fields(gc, _("New Conference"), msgA, msg1, fields, @@ -3474,7 +3491,7 @@ blist_menu_conf_create(buddy, msg); } else { - struct mwIdBlock idb = { buddy->name, NULL }; + struct mwIdBlock idb = { (char *)purple_buddy_get_name(buddy), NULL }; mwConference_invite(d, &idb, msg); } } @@ -3495,7 +3512,7 @@ const char *msgB; char *msg; - acct = buddy->account; + acct = purple_buddy_get_account(buddy); g_return_if_fail(acct != NULL); gc = purple_account_get_connection(acct); @@ -3523,7 +3540,7 @@ msgB = _("Select a conference from the list below to send an invite to" " user %s. Select \"Create New Conference\" if you'd like to" " create a new conference to invite this user to."); - msg = g_strdup_printf(msgB, buddy->name); + msg = g_strdup_printf(msgB, purple_buddy_get_name(buddy)); purple_request_fields(gc, _("Invite to Conference"), msgA, msg, fields, @@ -3545,7 +3562,7 @@ g_return_if_fail(node != NULL); g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); - acct = buddy->account; + acct = purple_buddy_get_account(buddy); g_return_if_fail(acct != NULL); gc = purple_account_get_connection(acct); @@ -4186,8 +4203,8 @@ if(b) { guint32 type; - if(b->server_alias) { - purple_notify_user_info_add_pair(user_info, _("Full Name"), b->server_alias); + if(purple_buddy_get_server_alias(b)) { + purple_notify_user_info_add_pair(user_info, _("Full Name"), purple_buddy_get_server_alias(b)); } type = purple_blist_node_get_int((PurpleBlistNode *) b, BUDDY_KEY_CLIENT); @@ -4329,10 +4346,10 @@ static void notify_add(PurpleConnection *gc, GList *row, void *user_data) { BuddyAddData *data = user_data; - char *group_name = NULL; + const char *group_name = NULL; if (data && data->group) { - group_name = data->group->name; + group_name = purple_group_get_name(data->group); } purple_blist_request_add_buddy(purple_connection_get_account(gc), @@ -4414,7 +4431,7 @@ buddy = data->buddy; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); pd = gc->proto_data; if(results) @@ -4515,7 +4532,7 @@ srvc = pd->srvc_resolve; - query = g_list_prepend(NULL, buddy->name); + query = g_list_prepend(NULL, (char *)purple_buddy_get_name(buddy)); flags = mwResolveFlag_FIRST | mwResolveFlag_USERS; req = mwServiceResolve_resolve(srvc, query, flags, add_buddy_resolved, @@ -4568,7 +4585,7 @@ /* convert PurpleBuddy into a mwAwareIdBlock */ idb->type = mwAware_USER; - idb->user = (char *) b->name; + idb->user = (char *) purple_buddy_get_name(b); idb->community = NULL; /* put idb into the list associated with the buddy's group */ @@ -4593,7 +4610,7 @@ PurpleBuddy *buddy, PurpleGroup *group) { struct mwPurplePluginData *pd; - struct mwAwareIdBlock idb = { mwAware_USER, buddy->name, NULL }; + struct mwAwareIdBlock idb = { mwAware_USER, (char *)purple_buddy_get_name(buddy), NULL }; struct mwAwareList *list; GList *rem = g_list_prepend(NULL, &idb); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/silc/buddy.c --- a/libpurple/protocols/silc/buddy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/silc/buddy.c Wed Jan 28 10:23:37 2009 +0000 @@ -322,9 +322,12 @@ silcpurple_buddy_keyagr(PurpleBlistNode *node, gpointer data) { PurpleBuddy *buddy; + PurpleAccount *account; buddy = (PurpleBuddy *)node; - silcpurple_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE); + account = purple_buddy_get_account(buddy); + silcpurple_buddy_keyagr_do(purple_account_get_connection(account), + purple_buddy_get_name(buddy), FALSE); } @@ -341,12 +344,12 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); b = (PurpleBuddy *) node; - gc = purple_account_get_connection(b->account); + gc = purple_account_get_connection(purple_buddy_get_account(b)); sg = gc->proto_data; /* Find client entry */ clients = silc_client_get_clients_local(sg->client, sg->conn, - b->name, FALSE); + purple_buddy_get_name(b), FALSE); if (!clients) return; @@ -467,9 +470,9 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); - silcpurple_buddy_privkey(gc, buddy->name); + silcpurple_buddy_privkey(gc, purple_buddy_get_name(buddy)); } @@ -596,9 +599,9 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); - silcpurple_buddy_getkey(gc, buddy->name); + silcpurple_buddy_getkey(gc, purple_buddy_get_name(buddy)); } static void @@ -613,7 +616,7 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); b = (PurpleBuddy *) node; - gc = purple_account_get_connection(b->account); + gc = purple_account_get_connection(purple_buddy_get_account(b)); sg = gc->proto_data; pkfile = purple_blist_node_get_string(node, "public-key"); @@ -624,7 +627,7 @@ return; } - silcpurple_show_public_key(sg, b->name, public_key, NULL, NULL); + silcpurple_show_public_key(sg, purple_buddy_get_name(b), public_key, NULL, NULL); silc_pkcs_public_key_free(public_key); } @@ -686,6 +689,7 @@ if (b) { /* See if we have this buddy's public key. If we do use that to search the details. */ + gpointer proto_data; filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); if (filename) { /* Call WHOIS. The user info is displayed in the WHOIS @@ -695,15 +699,15 @@ return; } - if (!b->proto_data) { + if (!(proto_data = purple_buddy_get_protocol_data(b))) { g_snprintf(tmp, sizeof(tmp), - _("User %s is not present in the network"), b->name); + _("User %s is not present in the network"), purple_buddy_get_name(b)); purple_notify_error(gc, _("User Information"), _("Cannot get user information"), tmp); return; } - client_entry = silc_client_get_client_by_id(client, conn, b->proto_data); + client_entry = silc_client_get_client_by_id(client, conn, proto_data); if (client_entry) { /* Call WHOIS. The user info is displayed in the WHOIS command reply. */ @@ -721,7 +725,7 @@ { char tmp[512]; g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"), - r->b->name); + purple_buddy_get_name(r->b)); purple_notify_error(r->client->application, _("Add Buddy"), tmp, _("You cannot receive buddy notifications until you " "import his/her public key. You can use the Get Public Key " @@ -1033,7 +1037,7 @@ /* Now verify the public key */ r->offline_pk = silc_pkcs_public_key_encode(r->public_key, &r->offline_pk_len); - silcpurple_verify_public_key(r->client, r->conn, r->b->name, + silcpurple_verify_public_key(r->client, r->conn, purple_buddy_get_name(r->b), SILC_CONN_CLIENT, r->public_key, silcpurple_add_buddy_save, r); } @@ -1071,7 +1075,7 @@ { char tmp[512]; g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"), - r->b->name); + purple_buddy_get_name(r->b)); purple_request_action(r->client->application, _("Add Buddy"), tmp, _("To add the buddy you must import his/her public key. " "Press Import to import a public key."), 0, @@ -1209,6 +1213,7 @@ const char *filename; SilcClientEntry client_entry = NULL; SilcUInt16 cmd_ident; + const char *name; filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); @@ -1246,17 +1251,19 @@ silc_dlist_start(clients); client_entry = silc_dlist_get(clients); + name = purple_buddy_get_name(b); + /* If we searched using public keys and more than one entry was found the same person is logged on multiple times. */ - if (silc_dlist_count(clients) > 1 && r->pubkey_search && b->name) { + if (silc_dlist_count(clients) > 1 && r->pubkey_search && name) { if (r->init) { /* Find the entry that closest matches to the buddy nickname. */ SilcClientEntry entry; silc_dlist_start(clients); while ((entry = silc_dlist_get(clients))) { - if (!g_ascii_strncasecmp(b->name, entry->nickname, - strlen(b->name))) { + if (!g_ascii_strncasecmp(name, entry->nickname, + strlen(name))) { client_entry = entry; break; } @@ -1271,7 +1278,7 @@ /* The client was found. Now get its public key and verify that before adding the buddy. */ memset(&userpk, 0, sizeof(userpk)); - b->proto_data = silc_memdup(&client_entry->id, sizeof(client_entry->id)); + purple_buddy_set_protocol_data(b, silc_memdup(&client_entry->id, sizeof(client_entry->id))); r->client_id = client_entry->id; /* Get the public key from attributes, if not present then @@ -1335,7 +1342,7 @@ SilcClientConnection conn = sg->conn; SilcPurpleBuddyRes r; SilcBuffer attrs; - const char *filename, *name = b->name; + const char *filename, *name = purple_buddy_get_name(b); r = silc_calloc(1, sizeof(*r)); if (!r) @@ -1395,31 +1402,33 @@ void silcpurple_send_buddylist(PurpleConnection *gc) { - PurpleBuddyList *blist; PurpleBlistNode *gnode, *cnode, *bnode; PurpleBuddy *buddy; PurpleAccount *account; account = purple_connection_get_account(gc); - if ((blist = purple_get_blist()) != NULL) + for (gnode = purple_blist_get_root(); + gnode != NULL; + gnode = purple_blist_node_get_sibling_next(gnode)) { - for (gnode = blist->root; gnode != NULL; gnode = gnode->next) + if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) + continue; + for (cnode = purple_blist_node_get_first_child(gnode); + cnode != NULL; + cnode = purple_blist_node_get_sibling_next(cnode)) { - if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) + if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) + for (bnode = purple_blist_node_get_first_child(cnode); + bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) { - if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) + if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) - { - if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) - continue; - buddy = (PurpleBuddy *)bnode; - if (purple_buddy_get_account(buddy) == account) - silcpurple_add_buddy_i(gc, buddy, TRUE); - } + buddy = (PurpleBuddy *)bnode; + if (purple_buddy_get_account(buddy) == account) + silcpurple_add_buddy_i(gc, buddy, TRUE); } } } @@ -1428,7 +1437,7 @@ void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { - silc_free(buddy->proto_data); + silc_free(purple_buddy_get_protocol_data(buddy)); } void silcpurple_idle_set(PurpleConnection *gc, int idle) @@ -1469,10 +1478,12 @@ char *silcpurple_status_text(PurpleBuddy *b) { - SilcPurple sg = b->account->gc->proto_data; + PurpleAccount *account = purple_buddy_get_account(b); + PurpleConnection *gc = purple_account_get_connection(account); + SilcPurple sg = gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; - SilcClientID *client_id = b->proto_data; + SilcClientID *client_id = purple_buddy_get_protocol_data(b); SilcClientEntry client_entry; SilcAttributePayload attr; SilcAttributeMood mood = 0; @@ -1533,10 +1544,12 @@ void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) { - SilcPurple sg = b->account->gc->proto_data; + PurpleAccount *account = purple_buddy_get_account(b); + PurpleConnection *gc = purple_account_get_connection(account); + SilcPurple sg = gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; - SilcClientID *client_id = b->proto_data; + SilcClientID *client_id = purple_buddy_get_protocol_data(b); SilcClientEntry client_entry; char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; char tmp[256]; @@ -1610,12 +1623,12 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); b = (PurpleBuddy *) node; - gc = purple_account_get_connection(b->account); + gc = purple_account_get_connection(purple_buddy_get_account(b)); sg = gc->proto_data; /* Call KILL */ silc_client_command_call(sg->client, sg->conn, NULL, "KILL", - b->name, "Killed by operator", NULL); + purple_buddy_get_name(b), "Killed by operator", NULL); } typedef struct { @@ -1633,7 +1646,8 @@ GList *silcpurple_buddy_menu(PurpleBuddy *buddy) { - PurpleConnection *gc = purple_account_get_connection(buddy->account); + PurpleAccount *account = purple_buddy_get_account(buddy); + PurpleConnection *gc = purple_account_get_connection(account); SilcPurple sg = gc->proto_data; SilcClientConnection conn = sg->conn; const char *pkfile = NULL; @@ -1645,7 +1659,7 @@ pkfile = purple_blist_node_get_string((PurpleBlistNode *) buddy, "public-key"); client_entry = silc_client_get_client_by_id(sg->client, sg->conn, - buddy->proto_data); + purple_buddy_get_protocol_data(buddy)); if (client_entry && silc_client_private_message_key_is_set(sg->client, diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/silc/chat.c --- a/libpurple/protocols/silc/chat.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/silc/chat.c Wed Jan 28 10:23:37 2009 +0000 @@ -182,7 +182,9 @@ silcpurple_chat_getinfo_menu(PurpleBlistNode *node, gpointer data) { PurpleChat *chat = (PurpleChat *)node; - silcpurple_chat_getinfo(chat->account->gc, chat->components); + PurpleAccount *account = purple_chat_get_account(chat); + silcpurple_chat_getinfo(purple_account_get_connection(account), + purple_chat_get_components(chat)); } @@ -496,11 +498,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "+C", NULL); } @@ -549,7 +551,7 @@ g_hash_table_replace(comp, "passphrase", g_strdup(passphrase)); cn = purple_chat_new(sg->account, alias, comp); - g = (PurpleGroup *)p->c->node.parent; + g = purple_chat_get_group(p->c); purple_blist_add_chat(cn, g, (PurpleBlistNode *)p->c); /* Associate to a real channel */ @@ -583,7 +585,7 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; p = silc_calloc(1, sizeof(*p)); @@ -591,7 +593,7 @@ return; p->sg = sg; - p->channel = g_hash_table_lookup(chat->components, "channel"); + p->channel = g_hash_table_lookup(purple_chat_get_components(chat), "channel"); p->c = purple_blist_find_chat(sg->account, p->channel); fields = purple_request_fields_new(); @@ -633,11 +635,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "-f", NULL); } @@ -652,7 +654,7 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; if (!sg->conn) @@ -663,7 +665,7 @@ (default key). */ /* Call CMODE */ - channel = g_hash_table_lookup(chat->components, "channel"); + channel = g_hash_table_lookup(purple_chat_get_components(chat), "channel"); silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", channel, "+f", NULL); } @@ -729,13 +731,13 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; if (!sg->conn) return; - ch = g_strdup(g_hash_table_lookup(chat->components, "channel")); + ch = g_strdup(g_hash_table_lookup(purple_chat_get_components(chat), "channel")); channel = silc_client_get_channel(sg->client, sg->conn, (char *)ch); if (!channel) return; @@ -764,11 +766,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "-t", NULL); } @@ -782,11 +784,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "+t", NULL); } @@ -800,11 +802,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "-p", NULL); } @@ -818,11 +820,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "+p", NULL); } @@ -836,11 +838,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "-s", NULL); } @@ -854,11 +856,11 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_CHAT(node)); chat = (PurpleChat *) node; - gc = purple_account_get_connection(chat->account); + gc = purple_account_get_connection(purple_chat_get_account(chat)); sg = gc->proto_data; silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(chat->components, "channel"), + g_hash_table_lookup(purple_chat_get_components(chat), "channel"), "+s", NULL); } @@ -877,8 +879,8 @@ GList *silcpurple_chat_menu(PurpleChat *chat) { - GHashTable *components = chat->components; - PurpleConnection *gc = purple_account_get_connection(chat->account); + GHashTable *components = purple_chat_get_components(chat); + PurpleConnection *gc = purple_account_get_connection(purple_chat_get_account(chat)); SilcPurple sg = gc->proto_data; SilcClientConnection conn = sg->conn; const char *chname = NULL; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/silc/ops.c --- a/libpurple/protocols/silc/ops.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/silc/ops.c Wed Jan 28 10:23:37 2009 +0000 @@ -431,6 +431,7 @@ va_list va; PurpleConnection *gc = client->application; SilcPurple sg = gc->proto_data; + PurpleAccount *account = purple_connection_get_account(gc); PurpleConversation *convo; SilcClientEntry client_entry, client_entry2; SilcChannelEntry channel; @@ -856,19 +857,22 @@ silc_free(pk); /* Find buddy by associated public key */ - for (gnode = purple_get_blist()->root; gnode; - gnode = gnode->next) { + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if( !PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; - bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *)bnode; - if (b->account != gc->account) + if (purple_buddy_get_account(b) != account) continue; f = purple_blist_node_get_string(bnode, "public-key"); if (f && !strcmp(f, buf)) @@ -889,9 +893,9 @@ } } - silc_free(b->proto_data); - b->proto_data = silc_memdup(&client_entry->id, - sizeof(client_entry->id)); + silc_free(purple_buddy_get_protocol_data(b)); + purple_buddy_set_protocol_data(b, silc_memdup(&client_entry->id, + sizeof(client_entry->id))); if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) { break; } else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) { diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/simple/simple.c --- a/libpurple/protocols/simple/simple.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/simple/simple.c Wed Jan 28 10:23:37 2009 +0000 @@ -196,33 +196,41 @@ { struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; struct simple_buddy *b; - if(strcmp("sip:", buddy->name)) { - gchar *buf = g_strdup_printf("sip:%s", buddy->name); + const char *name = purple_buddy_get_name(buddy); + if(strcmp("sip:", name)) { + gchar *buf = g_strdup_printf("sip:%s", name); purple_blist_rename_buddy(buddy, buf); g_free(buf); } - if(!g_hash_table_lookup(sip->buddies, buddy->name)) { + if(!g_hash_table_lookup(sip->buddies, name)) { b = g_new0(struct simple_buddy, 1); - purple_debug_info("simple", "simple_add_buddy %s\n", buddy->name); - b->name = g_strdup(buddy->name); + purple_debug_info("simple", "simple_add_buddy %s\n", name); + b->name = g_strdup(name); g_hash_table_insert(sip->buddies, b->name, b); } else { - purple_debug_info("simple", "buddy %s already in internal list\n", buddy->name); + purple_debug_info("simple", "buddy %s already in internal list\n", name); } } static void simple_get_buddies(PurpleConnection *gc) { PurpleBlistNode *gnode, *cnode, *bnode; + PurpleAccount *account; purple_debug_info("simple", "simple_get_buddies\n"); - for(gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + account = purple_connection_get_account(gc); + for(gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for(bnode = cnode->child; bnode; bnode = bnode->next) { + for(bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - if(((PurpleBuddy*)bnode)->account == gc->account) + if(purple_buddy_get_account((PurpleBuddy*)bnode) == account) simple_add_buddy(gc, (PurpleBuddy*)bnode, (PurpleGroup *)gnode); } } @@ -231,9 +239,10 @@ static void simple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { + const char *name = purple_buddy_get_name(buddy); struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; - struct simple_buddy *b = g_hash_table_lookup(sip->buddies, buddy->name); - g_hash_table_remove(sip->buddies, buddy->name); + struct simple_buddy *b = g_hash_table_lookup(sip->buddies, name); + g_hash_table_remove(sip->buddies, name); g_free(b->name); g_free(b); } @@ -922,7 +931,7 @@ purple_blist_add_buddy(b, NULL, g, NULL); purple_blist_alias_buddy(b, uri); bs = g_new0(struct simple_buddy, 1); - bs->name = g_strdup(b->name); + bs->name = g_strdup(purple_buddy_get_name(b)); g_hash_table_insert(sip->buddies, bs->name, bs); } xmlnode_free(isc); diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Wed Jan 28 10:23:37 2009 +0000 @@ -385,7 +385,7 @@ for (i = list; i; i = i->next) { b = i->data; g = purple_buddy_get_group(b); - if (!purple_utf8_strcasecmp(group, g->name)) { + if (!purple_utf8_strcasecmp(group, purple_group_get_name(g))) { purple_debug(PURPLE_DEBUG_MISC, "yahoo", "Oh good, %s is in the right group (%s).\n", name, group); list = g_slist_delete_link(list, i); @@ -423,7 +423,8 @@ for (i = list; i; i = i->next) { b = i->data; g = purple_buddy_get_group(b); - purple_debug(PURPLE_DEBUG_MISC, "yahoo", "Deleting Buddy %s from group %s.\n", name, g->name); + purple_debug(PURPLE_DEBUG_MISC, "yahoo", "Deleting Buddy %s from group %s.\n", name, + purple_group_get_name(g)); purple_blist_remove_buddy(b); } } @@ -2027,21 +2028,23 @@ return; group = purple_buddy_get_group(buddy); - name = g_strdup(buddy->name); - account = buddy->account; + name = g_strdup(purple_buddy_get_name(buddy)); + account = purple_buddy_get_account(buddy); purple_debug(PURPLE_DEBUG_INFO, "blist", - "Removing '%s' from buddy list.\n", buddy->name); + "Removing '%s' from buddy list.\n", name); purple_account_remove_buddy(account, buddy, group); purple_blist_remove_buddy(buddy); - serv_add_deny(account->gc, name); + serv_add_deny(purple_account_get_connection(account), name); g_free(name); } -static void keep_buddy(PurpleBuddy *b) { - purple_privacy_deny_remove(b->account, b->name, 1); +static void keep_buddy(PurpleBuddy *b) +{ + purple_privacy_deny_remove(purple_buddy_get_account(b), + purple_buddy_get_name(b), 1); } static void yahoo_process_ignore(PurpleConnection *gc, struct yahoo_packet *pkt) { @@ -3128,11 +3131,12 @@ YahooFriend *f; PurplePresence *presence; - if (!b || !(account = b->account) || !(gc = purple_account_get_connection(account)) || - !(yd = gc->proto_data)) + if (!b || !(account = purple_buddy_get_account(b)) || + !(gc = purple_account_get_connection(account)) || + !(yd = gc->proto_data)) return NULL; - f = yahoo_friend_find(gc, b->name); + f = yahoo_friend_find(gc, purple_buddy_get_name(b)); if (!f) { return "not-authorized"; } @@ -3192,7 +3196,7 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); yd = gc->proto_data; id = yd->conf_id; @@ -3204,7 +3208,7 @@ yahoo_c_join(gc, components); g_hash_table_destroy(components); - yahoo_c_invite(gc, id, "Join my conference...", buddy->name); + yahoo_c_invite(gc, id, "Join my conference...", purple_buddy_get_name(buddy)); } static void yahoo_presence_settings(PurpleBlistNode *node, gpointer data) { @@ -3213,9 +3217,9 @@ int presence_val = GPOINTER_TO_INT(data); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - - yahoo_friend_update_presence(gc, buddy->name, presence_val); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + + yahoo_friend_update_presence(gc, purple_buddy_get_name(buddy), presence_val); } static void yahoo_game(PurpleBlistNode *node, gpointer data) { @@ -3233,10 +3237,10 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); yd = (struct yahoo_data *) gc->proto_data; - f = yahoo_friend_find(gc, buddy->name); + f = yahoo_friend_find(gc, purple_buddy_get_name(buddy)); if (!f) return; @@ -3258,8 +3262,10 @@ YahooFriend *f = NULL; const char *msg; char *msg2; - - f = yahoo_friend_find(b->account->gc, b->name); + PurpleAccount *account; + + account = purple_buddy_get_account(b); + f = yahoo_friend_find(purple_account_get_connection(account), purple_buddy_get_name(b)); if (!f) return g_strdup(_("Not on server list")); @@ -3288,8 +3294,10 @@ char *escaped; char *status = NULL; const char *presence = NULL; - - f = yahoo_friend_find(b->account->gc, b->name); + PurpleAccount *account; + + account = purple_buddy_get_account(b); + f = yahoo_friend_find(purple_account_get_connection(account), purple_buddy_get_name(b)); if (!f) status = g_strdup_printf("\n%s", _("Not on server list")); else { @@ -3340,7 +3348,7 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); yahoo_add_buddy(gc, buddy, NULL); } @@ -3354,9 +3362,9 @@ g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; - gc = purple_account_get_connection(buddy->account); - - yahoo_chat_goto(gc, buddy->name); + gc = purple_account_get_connection(purple_buddy_get_account(buddy)); + + yahoo_chat_goto(gc, purple_buddy_get_name(buddy)); } static GList *build_presence_submenu(YahooFriend *f, PurpleConnection *gc) { @@ -3400,9 +3408,10 @@ static void yahoo_doodle_blist_node(PurpleBlistNode *node, gpointer data) { PurpleBuddy *b = (PurpleBuddy *)node; - PurpleConnection *gc = b->account->gc; - - yahoo_doodle_initiate(gc, b->name); + PurpleAccount *account = purple_buddy_get_account(b); + PurpleConnection *gc = purple_account_get_connection(account); + + yahoo_doodle_initiate(gc, purple_buddy_get_name(b)); } static GList *yahoo_buddy_menu(PurpleBuddy *buddy) @@ -3410,12 +3419,12 @@ GList *m = NULL; PurpleMenuAction *act; - PurpleConnection *gc = purple_account_get_connection(buddy->account); + PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy)); struct yahoo_data *yd = gc->proto_data; static char buf2[1024]; YahooFriend *f; - f = yahoo_friend_find(gc, buddy->name); + f = yahoo_friend_find(gc, purple_buddy_get_name(buddy)); if (!f && !yd->wm) { act = purple_menu_action_new(_("Add Buddy"), @@ -3942,19 +3951,20 @@ const char *group = NULL; char *group2; YahooFriend *f; + const char *bname; if (!yd->logged_in) return; - if (!purple_privacy_check(purple_connection_get_account(gc), - purple_buddy_get_name(buddy))) + bname = purple_buddy_get_name(buddy); + if (!purple_privacy_check(purple_connection_get_account(gc), bname)) return; - f = yahoo_friend_find(gc, purple_buddy_get_name(buddy)); + f = yahoo_friend_find(gc, bname); g = purple_buddy_get_group(buddy); if (g) - group = g->name; + group = purple_group_get_name(g); else group = "Buddies"; @@ -3967,7 +3977,7 @@ 1, purple_connection_get_display_name(gc), 302, "319", 300, "319", - 7, buddy->name, + 7, bname, 334, "0", 301, "319", 303, "319" @@ -3981,19 +3991,22 @@ static void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; - struct yahoo_packet *pkt; + struct yahoo_packet *pkt; GSList *buddies, *l; PurpleGroup *g; gboolean remove = TRUE; char *cg; - - if (!(yahoo_friend_find(gc, buddy->name))) + const char *bname, *gname; + + bname = purple_buddy_get_name(buddy); + if (!(yahoo_friend_find(gc, bname))) return; - buddies = purple_find_buddies(purple_connection_get_account(gc), buddy->name); + gname = purple_group_get_name(group); + buddies = purple_find_buddies(purple_connection_get_account(gc), bname); for (l = buddies; l; l = l->next) { g = purple_buddy_get_group(l->data); - if (purple_utf8_strcasecmp(group->name, g->name)) { + if (purple_utf8_strcasecmp(gname, purple_group_get_name(g))) { remove = FALSE; break; } @@ -4002,12 +4015,12 @@ g_slist_free(buddies); if (remove) - g_hash_table_remove(yd->friends, buddy->name); - - cg = yahoo_string_encode(gc, group->name, NULL); + g_hash_table_remove(yd->friends, bname); + + cg = yahoo_string_encode(gc, gname, NULL); pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), - 7, buddy->name, 65, cg); + 7, bname, 65, cg); yahoo_packet_send_and_free(pkt, yd); g_free(cg); } @@ -4116,7 +4129,7 @@ struct yahoo_packet *pkt; char *gpn, *gpo; - gpn = yahoo_string_encode(gc, group->name, NULL); + gpn = yahoo_string_encode(gc, purple_group_get_name(group), NULL); gpo = yahoo_string_encode(gc, old_name, NULL); if (!strcmp(gpn, gpo)) { g_free(gpn); @@ -4271,7 +4284,7 @@ } /* This may not be the best way to do this, but we find the first key w/o a value - * and assume it is the screenname */ + * and assume it is the buddy name */ static void yahoo_find_uri_novalue_param(gpointer key, gpointer value, gpointer user_data) { char **retval = user_data; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/yahoo/yahoo_picture.c --- a/libpurple/protocols/yahoo/yahoo_picture.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo_picture.c Wed Jan 28 10:23:37 2009 +0000 @@ -569,7 +569,7 @@ checksum &= ~g; } - purple_debug_misc("yahoo", "Calculated buddy icon checksum: %d", checksum); + purple_debug_misc("yahoo", "Calculated buddy icon checksum: %d\n", checksum); return checksum; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/yahoo/yahoo_profile.c --- a/libpurple/protocols/yahoo/yahoo_profile.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo_profile.c Wed Jan 28 10:23:37 2009 +0000 @@ -699,8 +699,9 @@ info_data->name); if (b) { - if(b->alias && b->alias[0]) { - char *aliastext = g_markup_escape_text(b->alias, -1); + const char *balias = purple_buddy_get_local_buddy_alias(b); + if(balias && balias[0]) { + char *aliastext = g_markup_escape_text(balias, -1); purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext); g_free(aliastext); } @@ -715,7 +716,7 @@ /* Add the normal tooltip pairs */ yahoo_tooltip_text(b, user_info, TRUE); - if ((f = yahoo_friend_find(info_data->gc, b->name))) { + if ((f = yahoo_friend_find(info_data->gc, purple_buddy_get_name(b)))) { const char *ip; if ((ip = yahoo_friend_get_ip(f))) purple_notify_user_info_add_pair(user_info, _("IP Address"), ip); @@ -1213,7 +1214,9 @@ * in which case the user may or may not actually exist. * Hence this extra step. */ - f = yahoo_friend_find(b->account->gc, b->name); + PurpleAccount *account = purple_buddy_get_account(b); + f = yahoo_friend_find(purple_account_get_connection(account), + purple_buddy_get_name(b)); } str = f ? _("Could not retrieve the user's profile. " "This most likely is a temporary server-side problem. " diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/yahoo/yahoochat.c --- a/libpurple/protocols/yahoo/yahoochat.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoochat.c Wed Jan 28 10:23:37 2009 +0000 @@ -519,7 +519,7 @@ GList *l; GList *flags = NULL; for (l = members; l; l = l->next) - flags = g_list_append(flags, GINT_TO_POINTER(PURPLE_CBFLAGS_NONE)); + flags = g_list_prepend(flags, GINT_TO_POINTER(PURPLE_CBFLAGS_NONE)); if (c && purple_conv_chat_has_left(PURPLE_CONV_CHAT(c))) { /* this might be a hack, but oh well, it should nicely */ char *tmpmsg; diff -r 29f953732186 -r 8c8948b9f602 libpurple/protocols/zephyr/zephyr.c --- a/libpurple/protocols/zephyr/zephyr.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/protocols/zephyr/zephyr.c Wed Jan 28 10:23:37 2009 +0000 @@ -732,7 +732,7 @@ return ret; } -static gboolean pending_zloc(zephyr_account *zephyr,char *who) +static gboolean pending_zloc(zephyr_account *zephyr, const char *who) { GList *curr; @@ -771,6 +771,8 @@ int nlocs; char *user; PurpleBuddy *b; + const char *bname; + /* XXX add real error reporting */ if (ZParseLocations(¬ice, NULL, &nlocs, &user) != ZERR_NONE) return; @@ -780,15 +782,19 @@ b = purple_find_buddy(gc->account,stripped_user); g_free(stripped_user); } - if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user)) { + + bname = b ? purple_buddy_get_name(b) : NULL; + if ((b && pending_zloc(zephyr,bname)) || pending_zloc(zephyr,user)) { ZLocations_t locs; int one = 1; PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); char *tmp; + const char *balias; - purple_notify_user_info_add_pair(user_info, _("User"), (b ? b->name : user)); - if (b && b->alias) - purple_notify_user_info_add_pair(user_info, _("Alias"), b->alias); + purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user)); + balias = purple_buddy_get_local_buddy_alias(b); + if (b && balias) + purple_notify_user_info_add_pair(user_info, _("Alias"), balias); if (!nlocs) { purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); @@ -801,14 +807,14 @@ purple_notify_user_info_add_pair(user_info, _("Location"), tmp); g_free(tmp); } - purple_notify_userinfo(gc, (b ? b->name : user), + purple_notify_userinfo(gc, (b ? bname : user), user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); } else { if (nlocs>0) - purple_prpl_got_user_status(gc->account, b ? b->name : user, "available", NULL); + purple_prpl_got_user_status(gc->account, b ? bname : user, "available", NULL); else - purple_prpl_got_user_status(gc->account, b ? b->name : user, "offline", NULL); + purple_prpl_got_user_status(gc->account, b ? bname : user, "offline", NULL); } g_free(user); @@ -1141,6 +1147,7 @@ /* XXX fix */ char *user; PurpleBuddy *b; + const char *bname; int nlocs = 0; parse_tree *locations; gchar *locval; @@ -1160,15 +1167,18 @@ nlocs = 1; } - if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user) || pending_zloc(zephyr,local_zephyr_normalize(zephyr,user))){ + bname = b ? purple_buddy_get_name(b) : NULL; + if ((b && pending_zloc(zephyr,bname)) || pending_zloc(zephyr,user) || pending_zloc(zephyr,local_zephyr_normalize(zephyr,user))){ PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); char *tmp; + const char *balias; - purple_notify_user_info_add_pair(user_info, _("User"), (b ? b->name : user)); + purple_notify_user_info_add_pair(user_info, _("User"), (b ? bname : user)); - if (b && b->alias) - purple_notify_user_info_add_pair(user_info, _("Alias"), b->alias); - + balias = b ? purple_buddy_get_local_buddy_alias(b) : NULL; + if (balias) + purple_notify_user_info_add_pair(user_info, _("Alias"), balias); + if (!nlocs) { purple_notify_user_info_add_pair(user_info, NULL, _("Hidden or not logged-in")); } else { @@ -1179,14 +1189,14 @@ g_free(tmp); } - purple_notify_userinfo(gc, b ? b->name : user, + purple_notify_userinfo(gc, b ? bname : user, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); } else { if (nlocs>0) - purple_prpl_got_user_status(gc->account, b ? b->name : user, "available", NULL); + purple_prpl_got_user_status(gc->account, b ? bname : user, "available", NULL); else - purple_prpl_got_user_status(gc->account, b ? b->name : user, "offline", NULL); + purple_prpl_got_user_status(gc->account, b ? bname : user, "offline", NULL); } } else if (!g_ascii_strncasecmp(spewtype,"subscribed",10)) { @@ -1246,38 +1256,44 @@ static gint check_loc(gpointer_data) { - PurpleBlistNode *gnode, *cnode, *bnode; - ZLocations_t locations; - int numlocs; - int one = 1; + PurpleBlistNode *gnode, *cnode, *bnode; + ZLocations_t locations; + int numlocs; + int one = 1; - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *b = (PurpleBuddy *) bnode; if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - if (b->account->gc == zgc) { + if (purple_buddy_get_account(b)->gc == zgc) { char *chk; - chk = local_zephyr_normalize(b->name); - ZLocateUser(chk,&numlocs, ZAUTH); - if (numlocs) { - int i; - for(i=0;iname,1,0,0,0,0); - } - } - } - } - } - } - return TRUE; + const char *bname = purple_buddy_get_name(b); + chk = local_zephyr_normalize(bname); + ZLocateUser(chk,&numlocs, ZAUTH); + if (numlocs) { + int i; + for(i=0;iproto_data; + PurpleAccount *account = purple_connection_get_account(gc); if (use_zeph02(zephyr)) { ald.user = NULL; @@ -1295,22 +1312,28 @@ ald.version = NULL; } - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + for (gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { PurpleBuddy *b = (PurpleBuddy *) bnode; if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; - if (b->account->gc == gc) { + if (purple_buddy_get_account(b) == account) { const char *chk; + const char *name = purple_buddy_get_name(b); - chk = local_zephyr_normalize(zephyr,b->name); - purple_debug_info("zephyr","chk: %s b->name %s\n",chk,b->name); + chk = local_zephyr_normalize(zephyr,name); + purple_debug_info("zephyr","chk: %s b->name %s\n",chk,name); /* XXX add real error reporting */ /* doesn't matter if this fails or not; we'll just move on to the next one */ if (use_zeph02(zephyr)) { @@ -1323,9 +1346,9 @@ for(i=0;i0) - purple_prpl_got_user_status(gc->account,b->name,"available",NULL); + purple_prpl_got_user_status(account,name,"available",NULL); else - purple_prpl_got_user_status(gc->account,b->name,"offline",NULL); + purple_prpl_got_user_status(account,name,"offline",NULL); } } #else @@ -1936,6 +1959,7 @@ PurpleBuddy *b; char *fname; FILE *fd; + PurpleAccount *account; zephyr_account* zephyr = gc->proto_data; fname = g_strdup_printf("%s/.anyone", purple_home_dir()); fd = g_fopen(fname, "w"); @@ -1944,18 +1968,25 @@ return; } - for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { + account = purple_connection_get_account(gc); + for (gnode = purple_blist_get_root(); + gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for (cnode = gnode->child; cnode; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for (bnode = cnode->child; bnode; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) { if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *) bnode; - if (b->account == gc->account) { - gchar *stripped_user = zephyr_strip_local_realm(zephyr,b->name); + if (purple_buddy_get_account(b) == account) { + gchar *stripped_user = zephyr_strip_local_realm(zephyr, purple_buddy_get_name(b)); fprintf(fd, "%s\n", stripped_user); g_free(stripped_user); } @@ -2498,26 +2529,31 @@ PurpleBlistNode *gnode, *cnode; /* XXX needs to be %host%,%canon%, and %me% clean */ - for(gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { - for(cnode = gnode->child; cnode; cnode = cnode->next) { + for(gnode = purple_blist_get_root(); gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) { + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) { PurpleChat *chat = (PurpleChat*)cnode; char *zclass, *inst, *recip; char** triple; + GHashTable *components; if(!PURPLE_BLIST_NODE_IS_CHAT(cnode)) continue; - if(chat->account !=account) - continue; - if(!(zclass = g_hash_table_lookup(chat->components, "class"))) + if(purple_chat_get_account(chat) != account) continue; - if(!(inst = g_hash_table_lookup(chat->components, "instance"))) + components = purple_chat_get_components(chat); + if(!(zclass = g_hash_table_lookup(components, "class"))) + continue; + if(!(inst = g_hash_table_lookup(components, "instance"))) inst = g_strdup(""); - if(!(recip = g_hash_table_lookup(chat->components, "recipient"))) + if(!(recip = g_hash_table_lookup(components, "recipient"))) recip = g_strdup(""); /* purple_debug_info("zephyr","in zephyr_find_blist_chat name: %s\n",name?name:""); */ triple = g_strsplit(name,",",3); if (!g_ascii_strcasecmp(triple[0],zclass) && !g_ascii_strcasecmp(triple[1],inst) && !g_ascii_strcasecmp(triple[2],recip)) return chat; - + } } return NULL; diff -r 29f953732186 -r 8c8948b9f602 libpurple/proxy.c --- a/libpurple/proxy.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/proxy.c Wed Jan 28 10:23:37 2009 +0000 @@ -207,6 +207,16 @@ return global_proxy_info; } +void +purple_global_proxy_set_info(PurpleProxyInfo *info) +{ + g_return_if_fail(info != NULL); + + purple_proxy_info_destroy(global_proxy_info); + + global_proxy_info = info; +} + static PurpleProxyInfo * purple_gnome_proxy_get_info(void) { @@ -228,13 +238,13 @@ g_free(err); err = NULL; - if (!strcmp(tmp, "none\n")) { + if (purple_strequal(tmp, "none\n")) { info.type = PURPLE_PROXY_NONE; g_free(tmp); return &info; } - if (strcmp(tmp, "manual\n")) { + if (purple_strequal(tmp, "manual\n")) { /* Unknown setting. Fallback to using our global proxy settings. */ g_free(tmp); return purple_global_proxy_get_info(); @@ -263,7 +273,7 @@ g_free(err); err = NULL; - if (!strcmp(tmp, "true\n")) + if (purple_strequal(tmp, "true\n")) use_same_proxy = TRUE; g_free(tmp); tmp = NULL; @@ -1697,7 +1707,7 @@ return; msg_ret = s5_parse_chap_msg(connect_data); - + if (msg_ret < 0) return; @@ -2242,31 +2252,31 @@ { PurpleProxyInfo *info = purple_global_proxy_get_info(); - if (!strcmp(name, "/purple/proxy/type")) { + if (purple_strequal(name, "/purple/proxy/type")) { int proxytype; const char *type = value; - if (!strcmp(type, "none")) + if (purple_strequal(type, "none")) proxytype = PURPLE_PROXY_NONE; - else if (!strcmp(type, "http")) + else if (purple_strequal(type, "http")) proxytype = PURPLE_PROXY_HTTP; - else if (!strcmp(type, "socks4")) + else if (purple_strequal(type, "socks4")) proxytype = PURPLE_PROXY_SOCKS4; - else if (!strcmp(type, "socks5")) + else if (purple_strequal(type, "socks5")) proxytype = PURPLE_PROXY_SOCKS5; - else if (!strcmp(type, "envvar")) + else if (purple_strequal(type, "envvar")) proxytype = PURPLE_PROXY_USE_ENVVAR; else proxytype = -1; purple_proxy_info_set_type(info, proxytype); - } else if (!strcmp(name, "/purple/proxy/host")) + } else if (purple_strequal(name, "/purple/proxy/host")) purple_proxy_info_set_host(info, value); - else if (!strcmp(name, "/purple/proxy/port")) + else if (purple_strequal(name, "/purple/proxy/port")) purple_proxy_info_set_port(info, GPOINTER_TO_INT(value)); - else if (!strcmp(name, "/purple/proxy/username")) + else if (purple_strequal(name, "/purple/proxy/username")) purple_proxy_info_set_username(info, value); - else if (!strcmp(name, "/purple/proxy/password")) + else if (purple_strequal(name, "/purple/proxy/password")) purple_proxy_info_set_password(info, value); } diff -r 29f953732186 -r 8c8948b9f602 libpurple/proxy.h --- a/libpurple/proxy.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/proxy.h Wed Jan 28 10:23:37 2009 +0000 @@ -186,6 +186,14 @@ */ PurpleProxyInfo *purple_global_proxy_get_info(void); +/** + * Set purple's global proxy information. + * + * @param info The proxy information. + * @since 2.6.0 + */ +void purple_global_proxy_set_info(PurpleProxyInfo *info); + /*@}*/ /**************************************************************************/ diff -r 29f953732186 -r 8c8948b9f602 libpurple/prpl.c --- a/libpurple/prpl.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/prpl.c Wed Jan 28 10:23:37 2009 +0000 @@ -75,7 +75,7 @@ purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name) { g_return_if_fail(type != NULL); - + type->icon_name = name; } @@ -400,7 +400,7 @@ PurpleConversation *conv; gboolean (*send_attention)(PurpleConnection *, const char *, guint); PurpleBuddy *buddy; - const char *alias; + const char *alias; gchar *description; time_t mtime; @@ -425,7 +425,7 @@ } else { description = g_strdup_printf(_("Requesting %s's attention..."), alias); } - + flags = PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_NOTIFY | PURPLE_MESSAGE_SYSTEM; purple_debug_info("server", "serv_send_attention: sending '%s' to %s\n", @@ -511,7 +511,7 @@ for (l = purple_plugins_get_protocols(); l != NULL; l = l->next) { plugin = (PurplePlugin *)l->data; - if (!strcmp(plugin->info->id, id)) + if (purple_strequal(plugin->info->id, id)) return plugin; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/prpl.h --- a/libpurple/prpl.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/prpl.h Wed Jan 28 10:23:37 2009 +0000 @@ -178,9 +178,11 @@ OPT_PROTO_USE_POINTSIZE = 0x00000100, /** - * Set the Register button active when screenname is not given. + * Set the Register button active even when the username has not + * been specified. * - * Gadu-Gadu doesn't need a screenname to register new account. + * Gadu-Gadu doesn't need a username to register new account (because + * usernames are assigned by the server). */ OPT_PROTO_REGISTER_NOSCREENNAME = 0x00000200, @@ -211,7 +213,7 @@ /** * Returns the base icon name for the given buddy and account. - * If buddy is NULL and the account is non-NULL, it will return the + * If buddy is NULL and the account is non-NULL, it will return the * name to use for the account's icon. If both are NULL, it will * return the name to use for the protocol's icon. * @@ -413,7 +415,7 @@ * reasons. */ void (*unregister_user)(PurpleAccount *, PurpleAccountUnregistrationCb cb, void *user_data); - + /* Attention API for sending & receiving zaps/nudges/buzzes etc. */ gboolean (*send_attention)(PurpleConnection *gc, const char *username, guint type); GList *(*get_attention_types)(PurpleAccount *acct); @@ -594,7 +596,7 @@ /*@{*/ /** - * Notifies Purple that an account's idle state and time have changed. + * Notifies Purple that our account's idle state and time have changed. * * This is meant to be called from protocol plugins. * @@ -606,7 +608,7 @@ time_t idle_time); /** - * Notifies Purple of an account's log-in time. + * Notifies Purple of our account's log-in time. * * This is meant to be called from protocol plugins. * @@ -616,7 +618,7 @@ void purple_prpl_got_account_login_time(PurpleAccount *account, time_t login_time); /** - * Notifies Purple that an account's status has changed. + * Notifies Purple that our account's status has changed. * * This is meant to be called from protocol plugins. * @@ -627,13 +629,14 @@ */ void purple_prpl_got_account_status(PurpleAccount *account, const char *status_id, ...) G_GNUC_NULL_TERMINATED; + /** - * Notifies Purple that a user's idle state and time have changed. + * Notifies Purple that a buddy's idle state and time have changed. * * This is meant to be called from protocol plugins. * * @param account The account the user is on. - * @param name The screen name of the user. + * @param name The name of the buddy. * @param idle The user's idle state. * @param idle_time The user's idle time. This is the time at * which the user became idle, in seconds since @@ -644,24 +647,24 @@ gboolean idle, time_t idle_time); /** - * Notifies Purple of a user's log-in time. + * Notifies Purple of a buddy's log-in time. * * This is meant to be called from protocol plugins. * * @param account The account the user is on. - * @param name The screen name of the user. + * @param name The name of the buddy. * @param login_time The user's log-in time. */ void purple_prpl_got_user_login_time(PurpleAccount *account, const char *name, time_t login_time); /** - * Notifies Purple that a user's status has been activated. + * Notifies Purple that a buddy's status has been activated. * * This is meant to be called from protocol plugins. * * @param account The account the user is on. - * @param name The screen name of the user. + * @param name The name of the buddy. * @param status_id The status ID. * @param ... A NULL-terminated list of attribute IDs and values, * beginning with the value for @a attr_id. @@ -670,19 +673,19 @@ const char *status_id, ...) G_GNUC_NULL_TERMINATED; /** - * Notifies libpurple that a user's status has been deactivated + * Notifies libpurple that a buddy's status has been deactivated * * This is meant to be called from protocol plugins. * * @param account The account the user is on. - * @param name The screen name of the user. + * @param name The name of the buddy. * @param status_id The status ID. */ void purple_prpl_got_user_status_deactive(PurpleAccount *account, const char *name, const char *status_id); - + /** - * Informs the server that an account's status changed. + * Informs the server that our account's status changed. * * @param account The account the user is on. * @param old_status The previous status. @@ -703,37 +706,43 @@ */ GList *purple_prpl_get_statuses(PurpleAccount *account, PurplePresence *presence); -/** Send an attention request message. +/** + * Send an attention request message. * * @param gc The connection to send the message on. * @param who Whose attention to request. * @param type_code An index into the prpl's attention_types list determining the type - * of the attention request command to send. 0 if prpl only defines one - * (for example, Yahoo and MSN), but some protocols define more (MySpaceIM). + * of the attention request command to send. 0 if prpl only defines one + * (for example, Yahoo and MSN), but some protocols define more (MySpaceIM). * * Note that you can't send arbitrary PurpleAttentionType's, because there is * only a fixed set of attention commands. + * * @since 2.5.0 */ void purple_prpl_send_attention(PurpleConnection *gc, const char *who, guint type_code); -/** Process an incoming attention message. +/** + * Process an incoming attention message. * * @param gc The connection that received the attention message. * @param who Who requested your attention. * @param type_code An index into the prpl's attention_types list determining the type - * of the attention request command to send. + * of the attention request command to send. + * * @since 2.5.0 */ void purple_prpl_got_attention(PurpleConnection *gc, const char *who, guint type_code); -/** Process an incoming attention message in a chat. +/** + * Process an incoming attention message in a chat. * * @param gc The connection that received the attention message. * @param id The chat id. * @param who Who requested your attention. * @param type_code An index into the prpl's attention_types list determining the type - * of the attention request command to send. + * of the attention request command to send. + * * @since 2.5.0 */ void purple_prpl_got_attention_in_chat(PurpleConnection *gc, int id, const char *who, guint type_code); diff -r 29f953732186 -r 8c8948b9f602 libpurple/purple-send-async --- a/libpurple/purple-send-async Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/purple-send-async Wed Jan 28 10:23:37 2009 +0000 @@ -2,18 +2,18 @@ METHOD_NAME=$1 -if test -z "$METHOD_NAME" +if test -z "$METHOD_NAME" then - cat <ui_data; +} + +void +purple_request_field_set_ui_data(PurpleRequestField *field, + gpointer ui_data) +{ + g_return_if_fail(field != NULL); + + field->ui_data = ui_data; +} + gboolean purple_request_fields_all_required_filled(const PurpleRequestFields *fields) { @@ -443,6 +462,14 @@ return field->type; } +PurpleRequestFieldGroup * +purple_request_field_get_group(const PurpleRequestField *field) +{ + g_return_val_if_fail(field != NULL, NULL); + + return field->group; +} + const char * purple_request_field_get_id(const PurpleRequestField *field) { diff -r 29f953732186 -r 8c8948b9f602 libpurple/request.h --- a/libpurple/request.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/request.h Wed Jan 28 10:23:37 2009 +0000 @@ -30,6 +30,9 @@ #include #include +/** @copydoc _PurpleRequestField */ +typedef struct _PurpleRequestField PurpleRequestField; + #include "account.h" #define PURPLE_DEFAULT_ACTION_NONE -1 @@ -93,10 +96,11 @@ } PurpleRequestFieldGroup; +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_REQUEST_C_) /** * A request field. */ -typedef struct +struct _PurpleRequestField { PurpleRequestFieldType type; PurpleRequestFieldGroup *group; @@ -176,7 +180,8 @@ void *ui_data; -} PurpleRequestField; +}; +#endif /** * Request UI operations. @@ -521,6 +526,17 @@ PurpleRequestFieldType purple_request_field_get_type(const PurpleRequestField *field); /** + * Returns the group for the field. + * + * @param field The field. + * + * @return The UI data. + * + * @since 2.6.0 + */ +PurpleRequestFieldGroup *purple_request_field_get_group(const PurpleRequestField *field); + +/** * Returns the ID of a field. * * @param field The field. @@ -565,6 +581,30 @@ */ gboolean purple_request_field_is_required(const PurpleRequestField *field); +/** + * Returns the ui_data for a field. + * + * @param field The field. + * + * @return The UI data. + * + * @since 2.6.0 + */ +gpointer purple_request_field_get_ui_data(const PurpleRequestField *field); + +/** + * Sets the ui_data for a field. + * + * @param field The field. + * @param ui_data The UI data. + * + * @return The UI data. + * + * @since 2.6.0 + */ +void purple_request_field_set_ui_data(PurpleRequestField *field, + gpointer ui_data); + /*@}*/ /**************************************************************************/ diff -r 29f953732186 -r 8c8948b9f602 libpurple/savedstatuses.c --- a/libpurple/savedstatuses.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/savedstatuses.c Wed Jan 28 10:23:37 2009 +0000 @@ -461,7 +461,7 @@ ret = g_new0(PurpleSavedStatus, 1); attrib = xmlnode_get_attrib(status, "transient"); - if ((attrib == NULL) || (strcmp(attrib, "true"))) + if (!purple_strequal(attrib, "true")) { /* Read the title */ attrib = xmlnode_get_attrib(status, "name"); @@ -940,7 +940,7 @@ for (iter = saved_statuses; iter != NULL; iter = iter->next) { status = (PurpleSavedStatus *)iter->data; - if ((status->title != NULL) && !strcmp(status->title, title)) + if (purple_strequal(status->title, title)) return status; } @@ -975,8 +975,7 @@ status = (PurpleSavedStatus *)iter->data; if ((status->type == type) && purple_savedstatus_is_transient(status) && !purple_savedstatus_has_substatuses(status) && - (((status->message == NULL) && (message == NULL)) || - ((status->message != NULL) && (message != NULL) && !strcmp(status->message, message)))) + purple_strequal(status->message, message)) { return status; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/server.c --- a/libpurple/server.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/server.c Wed Jan 28 10:23:37 2009 +0000 @@ -152,7 +152,7 @@ auto_reply_pref = purple_prefs_get_string("/purple/away/auto_reply"); if((gc->flags & PURPLE_CONNECTION_AUTO_RESP) && !purple_presence_is_available(presence) && - strcmp(auto_reply_pref, "never")) { + !purple_strequal(auto_reply_pref, "never")) { struct last_auto_response *lar; lar = get_last_auto_response(gc, name); @@ -172,7 +172,7 @@ if(gc) prpl = purple_connection_get_prpl(gc); - + if(prpl) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -188,7 +188,7 @@ if(gc) prpl = purple_connection_get_prpl(gc); - + if(prpl) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -230,7 +230,7 @@ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); if(b && prpl_info && prpl_info->alias_buddy) { - prpl_info->alias_buddy(gc, b->name, b->alias); + prpl_info->alias_buddy(gc, purple_buddy_get_name(b), purple_buddy_get_local_buddy_alias(b)); } } @@ -247,20 +247,20 @@ while (buddies != NULL) { + const char *server_alias; + b = buddies->data; buddies = g_slist_delete_link(buddies, buddies); - if((b->server_alias == NULL && alias == NULL) || - (b->server_alias && alias && !strcmp(b->server_alias, alias))) - { + server_alias = purple_buddy_get_server_alias(b); + + if (purple_strequal(server_alias, alias)) continue; - } purple_blist_server_alias_buddy(b, alias); - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, account); - if(conv != NULL && alias != NULL && - who != NULL && strcmp(alias, who)) + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(b), account); + if (conv != NULL && alias != NULL && purple_strequal(alias, who)) { char *escaped = g_markup_escape_text(who, -1); char *escaped2 = g_markup_escape_text(alias, -1); @@ -289,11 +289,13 @@ buddies = purple_find_buddies(account, who); while(buddies != NULL) { + const char *balias; b = buddies->data; buddies = g_slist_delete_link(buddies, buddies); - if((!b->alias && !alias) || (b->alias && alias && !strcmp(b->alias, alias))) + balias = purple_buddy_get_local_buddy_alias(b); + if (purple_strequal(balias, alias)) continue; purple_blist_alias_buddy(b, alias); @@ -367,7 +369,9 @@ if(gc && og && ng) { if (prpl_info && prpl_info->group_buddy) { - prpl_info->group_buddy(gc, b->name, og->name, ng->name); + prpl_info->group_buddy(gc, purple_buddy_get_name(b), + purple_group_get_name(og), + purple_group_get_name(ng)); } } } @@ -666,8 +670,8 @@ if ((primitive == PURPLE_STATUS_AVAILABLE) || (primitive == PURPLE_STATUS_INVISIBLE) || mobile || - !strcmp(auto_reply_pref, "never") || - (!purple_presence_is_idle(presence) && !strcmp(auto_reply_pref, "awayidle"))) + purple_strequal(auto_reply_pref, "never") || + (!purple_presence_is_idle(presence) && purple_strequal(auto_reply_pref, "awayidle"))) { g_free(name); return; diff -r 29f953732186 -r 8c8948b9f602 libpurple/server.h --- a/libpurple/server.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/server.h Wed Jan 28 10:23:37 2009 +0000 @@ -55,8 +55,8 @@ void serv_move_buddy(PurpleBuddy *, PurpleGroup *, PurpleGroup *); int serv_send_im(PurpleConnection *, const char *, const char *, PurpleMessageFlags flags); -/** Get information about an account's attention commands, from the prpl. - * +/** Get information about an account's attention commands, from the prpl. + * * @return The attention command numbered 'code' from the prpl's attention_types, or NULL. */ PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account, guint type_code); @@ -76,14 +76,14 @@ */ void serv_send_attention(PurpleConnection *gc, const char *who, guint type_code); -/** Process an incoming attention message. +/** Process an incoming attention message. * * @deprecated Use purple_prpl_got_attention() instead. * * @param gc The connection that received the attention message. * @param who Who requested your attention. * @param type_code An index into the prpl's attention_types list determining the type - * of the attention request command to send. + * of the attention request command to send. */ void serv_got_attention(PurpleConnection *gc, const char *who, guint type_code); @@ -108,7 +108,7 @@ * aliases are the aliases or display names that buddies set for themselves. * * @param gc The connection on which the alias was received. - * @param who The screen name of the buddy whose alias was received. + * @param who The name of the buddy whose alias was received. * @param alias The alias that was received. */ void purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const char *alias); @@ -180,7 +180,7 @@ * function should be g_str_equal(). */ void purple_serv_got_join_chat_failed(PurpleConnection *gc, GHashTable *data); - + void serv_got_chat_left(PurpleConnection *g, int id); void serv_got_chat_in(PurpleConnection *g, int id, const char *who, PurpleMessageFlags flags, const char *message, time_t mtime); diff -r 29f953732186 -r 8c8948b9f602 libpurple/signals.c --- a/libpurple/signals.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/signals.c Wed Jan 28 10:23:37 2009 +0000 @@ -487,7 +487,7 @@ } #ifdef HAVE_DBUS - purple_dbus_signal_emit_purple(signal, signal_data->num_values, + purple_dbus_signal_emit_purple(signal, signal_data->num_values, signal_data->values, args); #endif /* HAVE_DBUS */ @@ -539,7 +539,7 @@ #ifdef HAVE_DBUS G_VA_COPY(tmp, args); - purple_dbus_signal_emit_purple(signal, signal_data->num_values, + purple_dbus_signal_emit_purple(signal, signal_data->num_values, signal_data->values, tmp); va_end(tmp); #endif /* HAVE_DBUS */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/signals.h --- a/libpurple/signals.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/signals.h Wed Jan 28 10:23:37 2009 +0000 @@ -137,7 +137,7 @@ /** * Connects a signal handler to a signal for a particular object. * (Its priority defaults to 0, aka #PURPLE_SIGNAL_PRIORITY_DEFAULT.) - * + * * Take care not to register a handler function twice. Purple will * not correct any mistakes for you in this area. * diff -r 29f953732186 -r 8c8948b9f602 libpurple/smiley.c --- a/libpurple/smiley.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/smiley.c Wed Jan 28 10:23:37 2009 +0000 @@ -722,7 +722,7 @@ smiley = purple_smiley_new_from_stream(shortcut, smiley_data, smiley_data_len); } - + return smiley; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/sound-theme-loader.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/sound-theme-loader.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,111 @@ +/* + * SoundThemeLoader for libpurple + * + * Pidgin 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 "sound-theme-loader.h" +#include "sound-theme.h" +#include "util.h" +#include "xmlnode.h" + +/***************************************************************************** + * Sound Theme Builder + *****************************************************************************/ + +static PurpleTheme * +purple_sound_loader_build(const gchar *dir) +{ + xmlnode *root_node = NULL, *sub_node; + gchar *filename_full, *data; + PurpleSoundTheme *theme = NULL; + + /* Find the theme file */ + g_return_val_if_fail(dir != NULL, NULL); + filename_full = g_build_filename(dir, "theme.xml", NULL); + + if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR)) + root_node = xmlnode_from_file(dir, "theme.xml", "sound themes", "sound-theme-loader"); + + g_free(filename_full); + g_return_val_if_fail(root_node != NULL, NULL); + + /* Parse the tree */ + sub_node = xmlnode_get_child(root_node, "description"); + data = xmlnode_get_data(sub_node); + + if (xmlnode_get_attrib(root_node, "name") != NULL) { + theme = g_object_new(PURPLE_TYPE_SOUND_THEME, + "type", "sound", + "name", xmlnode_get_attrib(root_node, "name"), + "author", xmlnode_get_attrib(root_node, "author"), + "image", xmlnode_get_attrib(root_node, "image"), + "directory", dir, + "description", data, NULL); + + sub_node = xmlnode_get_child(root_node, "event"); + + while (sub_node) { + purple_sound_theme_set_file(theme, + xmlnode_get_attrib(sub_node, "name"), + xmlnode_get_attrib(sub_node, "file")); + sub_node = xmlnode_get_next_twin(sub_node); + } + } + + xmlnode_free(root_node); + g_free(data); + return PURPLE_THEME(theme); +} + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +purple_sound_theme_loader_class_init(PurpleSoundThemeLoaderClass *klass) +{ + PurpleThemeLoaderClass *loader_klass = PURPLE_THEME_LOADER_CLASS(klass); + + loader_klass->purple_theme_loader_build = purple_sound_loader_build; +} + +GType +purple_sound_theme_loader_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PurpleSoundThemeLoaderClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)purple_sound_theme_loader_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PurpleSoundThemeLoader), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static(PURPLE_TYPE_THEME_LOADER, + "PurpleSoundThemeLoader", &info, 0); + } + return type; +} diff -r 29f953732186 -r 8c8948b9f602 libpurple/sound-theme-loader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/sound-theme-loader.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,71 @@ +/** + * @file sound-theme-loader.h Purple Sound Theme Loader Class API + */ + +/* 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 + */ + +#ifndef PURPLE_SOUND_THEME_LOADER_H +#define PURPLE_SOUND_THEME_LOADER_H + +#include +#include +#include "theme-loader.h" + +/** + * A purple sound theme loader. extends PurpleThemeLoader (theme-loader.h) + * This is a class designed to build sound themes + * + * PurpleSoundThemeLoader is a GObject. + */ +typedef struct _PurpleSoundThemeLoader PurpleSoundThemeLoader; +typedef struct _PurpleSoundThemeLoaderClass PurpleSoundThemeLoaderClass; + +#define PURPLE_TYPE_SOUND_THEME_LOADER (purple_sound_theme_loader_get_type()) +#define PURPLE_SOUND_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_SOUND_THEME_LOADER, PurpleSoundThemeLoader)) +#define PURPLE_SOUND_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_SOUND_THEME_LOADER, PurpleSoundThemeLoaderClass)) +#define PURPLE_IS_SOUND_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_SOUND_THEME_LOADER)) +#define PURPLE_IS_SOUND_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_SOUND_THEME_LOADER)) +#define PURPLE_SOUND_THEME_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_SOUND_THEME_LOADER, PurpleSoundThemeLoaderClass)) + +struct _PurpleSoundThemeLoader +{ + PurpleThemeLoader parent; +}; + +struct _PurpleSoundThemeLoaderClass +{ + PurpleThemeLoaderClass parent_class; +}; + +/**************************************************************************/ +/** @name Purple Theme-Loader API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType purple_sound_theme_loader_get_type(void); + +G_END_DECLS +#endif /* PURPLE_SOUND_THEME_LOADER_H */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/sound-theme.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/sound-theme.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,158 @@ +/* + * Sound Themes for libpurple + * + * Pidgin 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 "sound-theme.h" + +#define PURPLE_SOUND_THEME_GET_PRIVATE(Gobject) \ + ((PurpleSoundThemePrivate *) ((PURPLE_SOUND_THEME(Gobject))->priv)) + +/****************************************************************************** + * Structs + *****************************************************************************/ + +typedef struct { + /* used to store filenames of diffrent sounds */ + GHashTable *sound_files; +} PurpleSoundThemePrivate; + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GObjectClass *parent_class = NULL; + +/****************************************************************************** + * Enums + *****************************************************************************/ + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +purple_sound_theme_init(GTypeInstance *instance, + gpointer klass) +{ + PurpleSoundThemePrivate *priv; + + (PURPLE_SOUND_THEME(instance))->priv = g_new0(PurpleSoundThemePrivate, 1); + + priv = PURPLE_SOUND_THEME_GET_PRIVATE(instance); + + priv->sound_files = g_hash_table_new_full(g_str_hash, + g_str_equal, g_free, g_free); +} + +static void +purple_sound_theme_finalize(GObject *obj) +{ + PurpleSoundThemePrivate *priv; + + priv = PURPLE_SOUND_THEME_GET_PRIVATE(obj); + + g_hash_table_destroy(priv->sound_files); + + parent_class->finalize(obj); +} + +static void +purple_sound_theme_class_init(PurpleSoundThemeClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = g_type_class_peek_parent(klass); + + obj_class->finalize = purple_sound_theme_finalize; +} + +GType +purple_sound_theme_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PurpleSoundThemeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)purple_sound_theme_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PurpleSoundTheme), + 0, /* n_preallocs */ + purple_sound_theme_init, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static(PURPLE_TYPE_THEME, + "PurpleSoundTheme", &info, 0); + } + return type; +} + +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +const gchar * +purple_sound_theme_get_file(PurpleSoundTheme *theme, + const gchar *event) +{ + PurpleSoundThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_SOUND_THEME(theme), NULL); + + priv = PURPLE_SOUND_THEME_GET_PRIVATE(theme); + + return g_hash_table_lookup(priv->sound_files, event); +} + +gchar * +purple_sound_theme_get_file_full(PurpleSoundTheme *theme, + const gchar *event) +{ + const gchar *filename; + + g_return_val_if_fail(PURPLE_IS_SOUND_THEME(theme), NULL); + + filename = purple_sound_theme_get_file(theme, event); + + g_return_val_if_fail(filename, NULL); + + return g_build_filename(purple_theme_get_dir(PURPLE_THEME(theme)), filename, NULL); +} + +void +purple_sound_theme_set_file(PurpleSoundTheme *theme, + const gchar *event, + const gchar *filename) +{ + PurpleSoundThemePrivate *priv; + g_return_if_fail(PURPLE_IS_SOUND_THEME(theme)); + + priv = PURPLE_SOUND_THEME_GET_PRIVATE(theme); + + if (filename != NULL) + g_hash_table_replace(priv->sound_files, + g_strdup(event), g_strdup(filename)); + else + g_hash_table_remove(priv->sound_files, event); +} diff -r 29f953732186 -r 8c8948b9f602 libpurple/sound-theme.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/sound-theme.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,105 @@ +/** + * @file sound-theme.h Purple Sound Theme Abstact Class API + */ + +/* 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 + */ + +#ifndef PURPLE_SOUND_THEME_H +#define PURPLE_SOUND_THEME_H + +#include +#include +#include "theme.h" +#include "sound.h" + +/** + * extends PurpleTheme (theme.h) + * A purple sound theme. + * This is an object for Purple to represent a sound theme. + * + * PurpleSoundTheme is a PurpleTheme Object. + */ +typedef struct _PurpleSoundTheme PurpleSoundTheme; +typedef struct _PurpleSoundThemeClass PurpleSoundThemeClass; + +#define PURPLE_TYPE_SOUND_THEME (purple_sound_theme_get_type()) +#define PURPLE_SOUND_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_SOUND_THEME, PurpleSoundTheme)) +#define PURPLE_SOUND_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_SOUND_THEME, PurpleSoundThemeClass)) +#define PURPLE_IS_SOUND_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_SOUND_THEME)) +#define PURPLE_IS_SOUND_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_SOUND_THEME)) +#define PURPLE_SOUND_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_SOUND_THEME, PurpleSoundThemeClass)) + +struct _PurpleSoundTheme +{ + PurpleTheme parent; + gpointer priv; +}; + +struct _PurpleSoundThemeClass +{ + PurpleThemeClass parent_class; +}; + +/**************************************************************************/ +/** @name Purple Sound Theme API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType purple_sound_theme_get_type(void); + +/** + * Returns a copy of the filename for the sound event. + * + * @param event The purple sound event to look up. + * + * @returns The filename of the sound event. + */ +const gchar *purple_sound_theme_get_file(PurpleSoundTheme *theme, + const gchar *event); + +/** + * Returns a copy of the directory and filename for the sound event + * + * @param event The purple sound event to look up + * + * @returns The directory + '/' + filename of the sound event. This is + * a newly allocated string that should be freed with g_free. + */ +gchar *purple_sound_theme_get_file_full(PurpleSoundTheme *theme, + const gchar *event); + +/** + * Sets the filename for a given sound event + * + * @param event the purple sound event to look up + * @param filename the name of the file to be used for the event + */ +void purple_sound_theme_set_file(PurpleSoundTheme *theme, + const gchar *event, + const gchar *filename); + +G_END_DECLS +#endif /* PURPLE_SOUND_THEME_H */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/sound.c --- a/libpurple/sound.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/sound.c Wed Jan 28 10:23:37 2009 +0000 @@ -25,6 +25,8 @@ #include "blist.h" #include "prefs.h" #include "sound.h" +#include "sound-theme-loader.h" +#include "theme-manager.h" static PurpleSoundUiOps *sound_ui_ops = NULL; @@ -134,6 +136,8 @@ purple_prefs_add_none("/purple/sound"); purple_prefs_add_int("/purple/sound/while_status", STATUS_AVAILABLE); memset(last_played, 0, sizeof(last_played)); + + purple_theme_manager_register_type(g_object_new(PURPLE_TYPE_SOUND_THEME_LOADER, "type", "sound", NULL)); } void diff -r 29f953732186 -r 8c8948b9f602 libpurple/sslconn.c --- a/libpurple/sslconn.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/sslconn.c Wed Jan 28 10:23:37 2009 +0000 @@ -216,7 +216,7 @@ /* TODO: Move this elsewhere */ gsc->verifier = purple_certificate_find_verifier("x509","tls_cached"); - + ops = purple_ssl_get_ops(); ops->connectfunc(gsc); diff -r 29f953732186 -r 8c8948b9f602 libpurple/sslconn.h --- a/libpurple/sslconn.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/sslconn.h Wed Jan 28 10:23:37 2009 +0000 @@ -65,7 +65,7 @@ /** File descriptor used to refer to the socket */ int fd; - /** Glib event source ID; used to refer to the received data callback + /** Glib event source ID; used to refer to the received data callback * in the glib eventloop */ guint inpa; /** Data related to the underlying TCP connection */ @@ -133,7 +133,7 @@ * list can be guaranteed. */ GList * (* get_peer_certificates)(PurpleSslConnection * gsc); - + void (*_purple_reserved2)(void); void (*_purple_reserved3)(void); void (*_purple_reserved4)(void); diff -r 29f953732186 -r 8c8948b9f602 libpurple/status.c --- a/libpurple/status.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/status.c Wed Jan 28 10:23:37 2009 +0000 @@ -23,6 +23,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#define _PURPLE_STATUS_C_ + #include "internal.h" #include "blist.h" @@ -203,7 +205,7 @@ for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) { - if (!strcmp(id, status_primitive_map[i].id)) + if (purple_strequal(id, status_primitive_map[i].id)) return status_primitive_map[i].type; } @@ -451,7 +453,7 @@ { PurpleStatusAttr *attr = (PurpleStatusAttr *)l->data; - if (!strcmp(purple_status_attr_get_id(attr), id)) + if (purple_strequal(purple_status_attr_get_id(attr), id)) return attr; } @@ -477,7 +479,7 @@ { status_type = status_types->data; - if (!strcmp(id, status_type->id)) + if (purple_strequal(id, status_type->id)) return status_type; status_types = status_types->next; @@ -612,7 +614,8 @@ if (old_status != NULL) { - tmp = g_strdup_printf(_("%s (%s) changed status from %s to %s"), buddy_alias, buddy->name, + tmp = g_strdup_printf(_("%s (%s) changed status from %s to %s"), buddy_alias, + purple_buddy_get_name(buddy), purple_status_get_name(old_status), purple_status_get_name(new_status)); logtmp = g_markup_escape_text(tmp, -1); @@ -623,19 +626,21 @@ if (purple_status_is_active(new_status)) { - tmp = g_strdup_printf(_("%s (%s) is now %s"), buddy_alias, buddy->name, + tmp = g_strdup_printf(_("%s (%s) is now %s"), buddy_alias, + purple_buddy_get_name(buddy), purple_status_get_name(new_status)); logtmp = g_markup_escape_text(tmp, -1); } else { - tmp = g_strdup_printf(_("%s (%s) is no longer %s"), buddy_alias, buddy->name, + tmp = g_strdup_printf(_("%s (%s) is no longer %s"), buddy_alias, + purple_buddy_get_name(buddy), purple_status_get_name(new_status)); logtmp = g_markup_escape_text(tmp, -1); } } - log = purple_account_get_log(buddy->account, FALSE); + log = purple_account_get_log(purple_buddy_get_account(buddy), FALSE); if (log != NULL) { purple_log_write(log, PURPLE_MESSAGE_SYSTEM, buddy_alias, @@ -779,12 +784,8 @@ { const gchar *string_data = l->data; l = l->next; - if (((string_data == NULL) && (value->data.string_data == NULL)) || - ((string_data != NULL) && (value->data.string_data != NULL) && - !strcmp(string_data, value->data.string_data))) - { + if (purple_strequal(string_data, value->data.string_data)) continue; - } purple_status_set_attr_string(status, id, string_data); changed = TRUE; } @@ -1146,13 +1147,13 @@ PurpleAccount *account; g_return_val_if_fail(buddy != NULL, NULL); - account = buddy->account; + account = purple_buddy_get_account(buddy); presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_BUDDY); - presence->u.buddy.name = g_strdup(buddy->name); - presence->u.buddy.account = buddy->account; - presence->statuses = purple_prpl_get_statuses(buddy->account, presence); + presence->u.buddy.name = g_strdup(purple_buddy_get_name(buddy)); + presence->u.buddy.account = account; + presence->statuses = purple_prpl_get_statuses(account, presence); presence->u.buddy.buddy = buddy; @@ -1248,12 +1249,13 @@ time_t current_time, gboolean old_idle, gboolean idle) { PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); + PurpleAccount *account = purple_buddy_get_account(buddy); if (!old_idle && idle) { if (purple_prefs_get_bool("/purple/logging/log_system")) { - PurpleLog *log = purple_account_get_log(buddy->account, FALSE); + PurpleLog *log = purple_account_get_log(account, FALSE); if (log != NULL) { @@ -1273,7 +1275,7 @@ { if (purple_prefs_get_bool("/purple/logging/log_system")) { - PurpleLog *log = purple_account_get_log(buddy->account, FALSE); + PurpleLog *log = purple_account_get_log(account, FALSE); if (log != NULL) { @@ -1461,7 +1463,7 @@ { PurpleStatus *temp_status = l->data; - if (!strcmp(status_id, purple_status_get_id(temp_status))) + if (purple_strequal(status_id, purple_status_get_id(temp_status))) status = temp_status; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/status.h --- a/libpurple/status.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/status.h Wed Jan 28 10:23:37 2009 +0000 @@ -252,6 +252,7 @@ */ void purple_status_type_destroy(PurpleStatusType *status_type); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Sets a status type's primary attribute. * @@ -261,10 +262,14 @@ * * @param status_type The status type. * @param attr_id The ID of the primary attribute. + * + * @deprecated This function isn't used and should be removed in 3.0.0. */ void purple_status_type_set_primary_attr(PurpleStatusType *status_type, const char *attr_id); +#endif +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Adds an attribute to a status type. * @@ -272,10 +277,16 @@ * @param id The ID of the attribute. * @param name The name presented to the user. * @param value The value type of this attribute. + * + * @deprecated This function isn't needed and should be removed in 3.0.0. + * Status type attributes should be set when the status type + * is created, in the call to purple_status_type_new_with_attrs. */ void purple_status_type_add_attr(PurpleStatusType *status_type, const char *id, const char *name, PurpleValue *value); +#endif +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Adds multiple attributes to a status type. * @@ -284,18 +295,29 @@ * @param name The description of the first attribute. * @param value The value type of the first attribute attribute. * @param ... Additional attribute information. + * + * @deprecated This function isn't needed and should be removed in 3.0.0. + * Status type attributes should be set when the status type + * is created, in the call to purple_status_type_new_with_attrs. */ void purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id, const char *name, PurpleValue *value, ...) G_GNUC_NULL_TERMINATED; +#endif +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Adds multiple attributes to a status type using a va_list. * * @param status_type The status type to add the attribute to. * @param args The va_list of attributes. + * + * @deprecated This function isn't needed and should be removed in 3.0.0. + * Status type attributes should be set when the status type + * is created, in the call to purple_status_type_new_with_attrs. */ void purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args); +#endif /** * Returns the primitive type of a status type. @@ -378,14 +400,18 @@ */ gboolean purple_status_type_is_available(const PurpleStatusType *status_type); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Returns a status type's primary attribute ID. * * @param type The status type. * * @return The primary attribute's ID. + * + * @deprecated This function isn't used and should be removed in 3.0.0. */ const char *purple_status_type_get_primary_attr(const PurpleStatusType *type); +#endif /** * Returns the attribute with the specified ID. @@ -537,35 +563,50 @@ void purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active, GList *attrs); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Sets the boolean value of an attribute in a status with the specified ID. * * @param status The status. * @param id The attribute ID. * @param value The boolean value. + * + * @deprecated This function is only used by status.c and should be made + * static in 3.0.0. */ void purple_status_set_attr_boolean(PurpleStatus *status, const char *id, gboolean value); +#endif +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Sets the integer value of an attribute in a status with the specified ID. * * @param status The status. * @param id The attribute ID. * @param value The integer value. + * + * @deprecated This function is only used by status.c and should be made + * static in 3.0.0. */ void purple_status_set_attr_int(PurpleStatus *status, const char *id, int value); +#endif +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Sets the string value of an attribute in a status with the specified ID. * * @param status The status. * @param id The attribute ID. * @param value The string value. + * + * @deprecated This function is only used by status.c and should be made + * static in 3.0.0. */ void purple_status_set_attr_string(PurpleStatus *status, const char *id, const char *value); +#endif /** * Returns the status's type. @@ -773,22 +814,31 @@ */ void purple_presence_destroy(PurplePresence *presence); +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Adds a status to a presence. * * @param presence The presence. * @param status The status to add. + * + * @deprecated This function is only used by purple_presence_add_list, + * and both should be removed in 3.0.0. */ void purple_presence_add_status(PurplePresence *presence, PurpleStatus *status); +#endif +#if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_STATUS_C_) /** * Adds a list of statuses to the presence. * * @param presence The presence. * @param source_list The source list of statuses to add, which is not * modified or freed by this function. + * + * @deprecated This function isn't used and should be removed in 3.0.0. */ void purple_presence_add_list(PurplePresence *presence, GList *source_list); +#endif /** * Sets the active state of a status in a presence. diff -r 29f953732186 -r 8c8948b9f602 libpurple/stun.c --- a/libpurple/stun.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/stun.c Wed Jan 28 10:23:37 2009 +0000 @@ -388,9 +388,7 @@ /** Deal with the server name having changed since we did the lookup */ if (servername && strlen(servername) > 1 - && ((nattype.servername - && strcmp(servername, nattype.servername)) - || !nattype.servername)) { + && !purple_strequal(servername, nattype.servername)) { use_cached_result = FALSE; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/theme-loader.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/theme-loader.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,183 @@ +/* + * ThemeLoaders for libpurple + * + * Pidgin 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 "theme-loader.h" + +#define PURPLE_THEME_LOADER_GET_PRIVATE(PurpleThemeLoader) \ + ((PurpleThemeLoaderPrivate *) ((PurpleThemeLoader)->priv)) + +void purple_theme_loader_set_type_string(PurpleThemeLoader *loader, const gchar *type); + +/****************************************************************************** + * Structs + *****************************************************************************/ +typedef struct { + gchar *type; +} PurpleThemeLoaderPrivate; + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GObjectClass *parent_class = NULL; + +/****************************************************************************** + * Enums + *****************************************************************************/ + +enum { + PROP_ZERO = 0, + PROP_TYPE, +}; + +/****************************************************************************** + * GObject Stuff * + *****************************************************************************/ + +static void +purple_theme_loader_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *psec) +{ + PurpleThemeLoader *theme_loader = PURPLE_THEME_LOADER(obj); + + switch (param_id) { + case PROP_TYPE: + g_value_set_string(value, purple_theme_loader_get_type_string(theme_loader)); + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec); + break; + } +} + +static void +purple_theme_loader_set_property(GObject *obj, guint param_id, const GValue *value, + GParamSpec *psec) +{ + PurpleThemeLoader *loader = PURPLE_THEME_LOADER(obj); + + switch (param_id) { + case PROP_TYPE: + purple_theme_loader_set_type_string(loader, g_value_get_string(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec); + break; + } +} + +static void +purple_theme_loader_init(GTypeInstance *instance, + gpointer klass) +{ + PurpleThemeLoader *loader = PURPLE_THEME_LOADER(instance); + loader->priv = g_new0(PurpleThemeLoaderPrivate, 1); +} + +static void +purple_theme_loader_finalize(GObject *obj) +{ + PurpleThemeLoader *loader = PURPLE_THEME_LOADER(obj); + PurpleThemeLoaderPrivate *priv = PURPLE_THEME_LOADER_GET_PRIVATE(loader); + + g_free(priv->type); + + parent_class->finalize(obj); +} + +static void +purple_theme_loader_class_init(PurpleThemeLoaderClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + parent_class = g_type_class_peek_parent(klass); + + obj_class->get_property = purple_theme_loader_get_property; + obj_class->set_property = purple_theme_loader_set_property; + obj_class->finalize = purple_theme_loader_finalize; + + /* TYPE STRING (read only) */ + pspec = g_param_spec_string("type", "Type", + "The string represtenting the type of the theme", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(obj_class, PROP_TYPE, pspec); +} + +GType +purple_theme_loader_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PurpleThemeLoaderClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)purple_theme_loader_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PurpleThemeLoader), + 0, /* n_preallocs */ + purple_theme_loader_init, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static(G_TYPE_OBJECT, + "PurpleThemeLoader", &info, G_TYPE_FLAG_ABSTRACT); + } + return type; +} + +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +const gchar * +purple_theme_loader_get_type_string(PurpleThemeLoader *theme_loader) +{ + PurpleThemeLoaderPrivate *priv = NULL; + + g_return_val_if_fail(PURPLE_IS_THEME_LOADER(theme_loader), NULL); + + priv = PURPLE_THEME_LOADER_GET_PRIVATE(theme_loader); + return priv->type; +} + +/* < private > */ +void +purple_theme_loader_set_type_string(PurpleThemeLoader *loader, const gchar *type) +{ + PurpleThemeLoaderPrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME_LOADER(loader)); + + priv = PURPLE_THEME_LOADER_GET_PRIVATE(loader); + + g_free(priv->type); + priv->type = g_strdup(type); +} + +PurpleTheme * +purple_theme_loader_build(PurpleThemeLoader *loader, const gchar *dir) +{ + return PURPLE_THEME_LOADER_GET_CLASS(loader)->purple_theme_loader_build(dir); +} diff -r 29f953732186 -r 8c8948b9f602 libpurple/theme-loader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/theme-loader.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,92 @@ +/** + * @file theme-loader.h Purple Theme Loader Abstact Class API + */ + +/* 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 + */ + +#ifndef PURPLE_THEME_LOADER_H +#define PURPLE_THEME_LOADER_H + +#include +#include +#include "theme.h" + +/** + * A purple theme loader. + * This is an abstract class for Purple to use with the Purple theme manager. + * The loader is responsible for building each type of theme + * + * PurpleThemeLoader is a GObject. + */ +typedef struct _PurpleThemeLoader PurpleThemeLoader; +typedef struct _PurpleThemeLoaderClass PurpleThemeLoaderClass; + +#define PURPLE_TYPE_THEME_LOADER (purple_theme_loader_get_type()) +#define PURPLE_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_THEME_LOADER, PurpleThemeLoader)) +#define PURPLE_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_THEME_LOADER, PurpleThemeLoaderClass)) +#define PURPLE_IS_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_THEME_LOADER)) +#define PURPLE_IS_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_THEME_LOADER)) +#define PURPLE_THEME_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_THEME_LOADER, PurpleThemeLoaderClass)) + +struct _PurpleThemeLoader +{ + GObject parent; + gpointer priv; +}; + +struct _PurpleThemeLoaderClass +{ + GObjectClass parent_class; + PurpleTheme *((*purple_theme_loader_build)(const gchar*)); +}; + +/**************************************************************************/ +/** @name Purple Theme-Loader API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType purple_theme_loader_get_type(void); + +/** + * Returns the string represtenting the type of the theme loader + * + * @param self The theme loader + * + * @returns The string represting this type + */ +const gchar *purple_theme_loader_get_type_string(PurpleThemeLoader *self); + +/** + * Creates a new PurpleTheme + * + * @param dir The directory containing the theme + * + * @returns A PurpleTheme containing the information from the directory + */ +PurpleTheme *purple_theme_loader_build(PurpleThemeLoader *loader, const gchar *dir); + +G_END_DECLS +#endif /* PURPLE_THEME_LOADER_H */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/theme-manager.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/theme-manager.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,295 @@ +/* + * Themes for libpurple + * + * Pidgin 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 +#include + +#include "internal.h" +#include "theme-manager.h" +#include "util.h" + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GHashTable *theme_table = NULL; + +/***************************************************************************** + * GObject Stuff + ****************************************************************************/ + +GType +purple_theme_manager_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PurpleThemeManagerClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PurpleThemeManager), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* Value Table */ + }; + type = g_type_register_static(G_TYPE_OBJECT, + "PurpleThemeManager", &info, 0); + } + return type; +} + +/****************************************************************************** + * Helpers + *****************************************************************************/ + +/* makes a key of + '/' + */ +static gchar * +purple_theme_manager_make_key(const gchar *name, const gchar *type) +{ + g_return_val_if_fail(name && *name, NULL); + g_return_val_if_fail(type && *type, NULL); + return g_strconcat(type, "/", name, NULL); +} + +/* returns TRUE if theme is of type "user_data" */ +static gboolean +purple_theme_manager_is_theme_type(gchar *key, + gpointer value, + gchar *user_data) +{ + return g_str_has_prefix(key, g_strconcat(user_data, "/", NULL)); +} + +static gboolean +purple_theme_manager_is_theme(gchar *key, + gpointer value, + gchar *user_data) +{ + return PURPLE_IS_THEME(value); +} + +static void +purple_theme_manager_function_wrapper(gchar *key, + gpointer value, + PTFunc user_data) +{ + if (PURPLE_IS_THEME(value)) + (* user_data)(value); +} + +static void +purple_theme_manager_build_dir(const gchar *root) +{ + gchar *purple_dir, *theme_dir; + const gchar *name = NULL, *type = NULL; + GDir *rdir, *tdir; + PurpleThemeLoader *loader; + + rdir = g_dir_open(root, 0, NULL); + + if (!rdir) + return; + + /* Parses directory by root/name/purple/type */ + while ((name = g_dir_read_name(rdir))) { + purple_dir = g_build_filename(root, name, "purple", NULL); + tdir = g_dir_open(purple_dir, 0, NULL); + + if (!tdir) { + g_free(purple_dir); + + continue; + } + + while ((type = g_dir_read_name(tdir))) { + if ((loader = g_hash_table_lookup(theme_table, type))) { + PurpleTheme *theme = NULL; + + theme_dir = g_build_filename(purple_dir, type, NULL); + + theme = purple_theme_loader_build(loader, theme_dir); + + if (PURPLE_IS_THEME(theme)) + purple_theme_manager_add_theme(theme); + } + } + + g_dir_close(tdir); + g_free(purple_dir); + } + + g_dir_close(rdir); +} + +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +void +purple_theme_manager_init(void) +{ + theme_table = g_hash_table_new_full(g_str_hash, + g_str_equal, g_free, g_object_unref); +} + +void +purple_theme_manager_refresh(void) +{ + gchar *path = NULL; + const gchar *xdg = NULL; + gint i = 0; + + g_hash_table_foreach_remove(theme_table, + (GHRFunc) purple_theme_manager_is_theme, NULL); + + /* Add themes from ~/.purple */ + path = g_build_filename(purple_user_dir(), "themes", NULL); + purple_theme_manager_build_dir(path); + g_free(path); + + /* look for XDG_DATA_HOME. If we don't have it use ~/.local, and add it */ + if ((xdg = g_getenv("XDG_DATA_HOME")) != NULL) + path = g_build_filename(xdg, "themes", NULL); + else + path = g_build_filename(purple_home_dir(), ".local", "themes", NULL); + + purple_theme_manager_build_dir(path); + g_free(path); + + /* now dig through XDG_DATA_DIRS and add those too */ + xdg = g_getenv("XDG_DATA_DIRS"); + if (xdg) { + gchar **xdg_dirs = g_strsplit(xdg, G_SEARCHPATH_SEPARATOR_S, 0); + + for (i = 0; xdg_dirs[i]; i++) { + path = g_build_filename(xdg_dirs[i], "themes", NULL); + purple_theme_manager_build_dir(path); + g_free(path); + } + + g_strfreev(xdg_dirs); + } +} + +void +purple_theme_manager_uninit(void) +{ + g_hash_table_destroy(theme_table); +} + +void +purple_theme_manager_register_type(PurpleThemeLoader *loader) +{ + gchar *type; + + g_return_if_fail(PURPLE_IS_THEME_LOADER(loader)); + + type = g_strdup(purple_theme_loader_get_type_string(loader)); + g_return_if_fail(type); + + /* if something is already there do nothing */ + if (!g_hash_table_lookup(theme_table, type)) + g_hash_table_insert(theme_table, type, loader); +} + +void +purple_theme_manager_unregister_type(PurpleThemeLoader *loader) +{ + const gchar *type; + + g_return_if_fail(PURPLE_IS_THEME_LOADER(loader)); + + type = purple_theme_loader_get_type_string(loader); + g_return_if_fail(type); + + if (g_hash_table_lookup(theme_table, type) == loader) + { + g_hash_table_remove(theme_table, type); + + g_hash_table_foreach_remove(theme_table, + (GHRFunc)purple_theme_manager_is_theme_type, (gpointer)type); + } /* only free if given registered loader */ +} + +PurpleTheme * +purple_theme_manager_find_theme(const gchar *name, + const gchar *type) +{ + gchar *key; + PurpleTheme *theme; + + key = purple_theme_manager_make_key(name, type); + + g_return_val_if_fail(key, NULL); + + theme = g_hash_table_lookup(theme_table, key); + + g_free(key); + + return theme; +} + +void +purple_theme_manager_add_theme(PurpleTheme *theme) +{ + gchar *key; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + key = purple_theme_manager_make_key(purple_theme_get_name(theme), + purple_theme_get_type_string(theme)); + + g_return_if_fail(key); + + /* if something is already there do nothing */ + if (g_hash_table_lookup(theme_table, key) == NULL) + g_hash_table_insert(theme_table, key, theme); +} + +void +purple_theme_manager_remove_theme(PurpleTheme *theme) +{ + gchar *key; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + key = purple_theme_manager_make_key(purple_theme_get_name(theme), + purple_theme_get_type_string(theme)); + + g_return_if_fail(key); + + g_hash_table_remove(theme_table, key); + + g_free(key); +} + +void +purple_theme_manager_for_each_theme(PTFunc func) +{ + g_return_if_fail(func); + + g_hash_table_foreach(theme_table, + (GHFunc) purple_theme_manager_function_wrapper, func); +} diff -r 29f953732186 -r 8c8948b9f602 libpurple/theme-manager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/theme-manager.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,131 @@ +/** + * @file thememanager.h Theme Manager API + */ + +/* + * 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 + */ + +#ifndef PURPLE_THEME_MANAGER_H +#define PURPLE_THEME_MANAGER_H + +#include +#include +#include "theme.h" +#include "theme-loader.h" + +typedef void (*PTFunc) (PurpleTheme *); + +typedef struct _PurpleThemeManager PurpleThemeManager; +typedef struct _PurpleThemeManagerClass PurpleThemeManagerClass; + +#define PURPLE_TYPE_THEME_MANAGER (purple_theme_manager_get_type()) +#define PURPLE_THEME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManager)) +#define PURPLE_THEME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManagerClass)) +#define PURPLE_IS_THEME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_THEME_MANAGER)) +#define PURPLE_IS_THEME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_THEME_MANAGER)) +#define PURPLE_GET_THEME_MANAGER_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManagerClass)) + +struct _PurpleThemeManager { + GObject parent; +}; + +struct _PurpleThemeManagerClass { + GObjectClass parent_class; +}; + +/**************************************************************************/ +/** @name Purple Theme Manager API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * + * @internal. + */ +GType purple_theme_manager_get_type(void); + +/** + * Initalizes the theme manager. + */ +void purple_theme_manager_init(void); + +/** + * Uninitalizes the manager then frees all the themes and loaders it is + * responsible for. + */ +void purple_theme_manager_uninit(void); + +/** + * Rebuilds all the themes in the theme manager. + * (Removes all current themes but keeps the added loaders.) + */ +void purple_theme_manager_refresh(void); + +/** + * Finds the PurpleTheme object stored by the theme manager. + * + * @param name The name of the PurpleTheme. + * @param type The type of the PurpleTheme. + * + * @returns The PurpleTheme, or NULL if it wasn't found. + */ +PurpleTheme *purple_theme_manager_find_theme(const gchar *name, const gchar *type); + +/** + * Adds a PurpleTheme to the theme manager. If the theme already exists + * then this function does nothing. + * + * @param theme The PurpleTheme to add to the manager. + */ +void purple_theme_manager_add_theme(PurpleTheme *theme); + +/** + * Removes a PurpleTheme from the theme manager and frees the theme. + * + * @param theme The PurpleTheme to remove from the manager. + */ +void purple_theme_manager_remove_theme(PurpleTheme *theme); + +/** + * Adds a loader to the theme manager so it knows how to build themes. + * + * @param loader The PurpleThemeLoader to add. + */ +void purple_theme_manager_register_type(PurpleThemeLoader *loader); + +/** + * Removes the loader and all themes of the same type from the loader. + * + * @param loader The PurpleThemeLoader to be removed. + */ +void purple_theme_manager_unregister_type(PurpleThemeLoader *loader); + +/** + * Calls the given function on each purple theme. + * + * @param func The PTFunc to be applied to each theme. + */ +void purple_theme_manager_for_each_theme(PTFunc func); + +G_END_DECLS +#endif /* PURPLE_THEME_MANAGER_H */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/theme.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/theme.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,408 @@ +/* + * Themes for libpurple + * + * Pidgin 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 +#include + +#include "internal.h" +#include "theme.h" +#include "util.h" + +#define PURPLE_THEME_GET_PRIVATE(PurpleTheme) \ + ((PurpleThemePrivate *) ((PurpleTheme)->priv)) + +void purple_theme_set_type_string(PurpleTheme *theme, const gchar *type); + +/****************************************************************************** + * Structs + *****************************************************************************/ + +typedef struct { + gchar *name; + gchar *description; + gchar *author; + gchar *type; + gchar *dir; + gchar *img; +} PurpleThemePrivate; + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GObjectClass *parent_class = NULL; + +/****************************************************************************** + * Enums + *****************************************************************************/ + +enum { + PROP_ZERO = 0, + PROP_NAME, + PROP_DESCRIPTION, + PROP_AUTHOR, + PROP_TYPE, + PROP_DIR, + PROP_IMAGE +}; + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +purple_theme_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *psec) +{ + PurpleTheme *theme = PURPLE_THEME(obj); + + switch (param_id) { + case PROP_NAME: + g_value_set_string(value, purple_theme_get_name(theme)); + break; + case PROP_DESCRIPTION: + g_value_set_string(value, purple_theme_get_description(theme)); + break; + case PROP_AUTHOR: + g_value_set_string(value, purple_theme_get_author(theme)); + break; + case PROP_TYPE: + g_value_set_string(value, purple_theme_get_type_string(theme)); + break; + case PROP_DIR: + g_value_set_string(value, purple_theme_get_dir(theme)); + break; + case PROP_IMAGE: + g_value_set_string(value, purple_theme_get_image(theme)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec); + break; + } +} + +static void +purple_theme_set_property(GObject *obj, guint param_id, const GValue *value, + GParamSpec *psec) +{ + PurpleTheme *theme = PURPLE_THEME(obj); + + switch (param_id) { + case PROP_NAME: + purple_theme_set_name(theme, g_value_get_string(value)); + break; + case PROP_DESCRIPTION: + purple_theme_set_description(theme, g_value_get_string(value)); + break; + case PROP_AUTHOR: + purple_theme_set_author(theme, g_value_get_string(value)); + break; + case PROP_TYPE: + purple_theme_set_type_string(theme, g_value_get_string(value)); + break; + case PROP_DIR: + purple_theme_set_dir(theme, g_value_get_string(value)); + break; + case PROP_IMAGE: + purple_theme_set_image(theme, g_value_get_string(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec); + break; + } +} + +static void +purple_theme_init(GTypeInstance *instance, + gpointer klass) +{ + PurpleTheme *theme = PURPLE_THEME(instance); + theme->priv = g_new0(PurpleThemePrivate, 1); +} + +static void +purple_theme_finalize(GObject *obj) +{ + PurpleTheme *theme = PURPLE_THEME(obj); + PurpleThemePrivate *priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->name); + g_free(priv->description); + g_free(priv->author); + g_free(priv->type); + g_free(priv->dir); + g_free(priv->img); + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +static void +purple_theme_class_init(PurpleThemeClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + parent_class = g_type_class_peek_parent(klass); + + obj_class->get_property = purple_theme_get_property; + obj_class->set_property = purple_theme_set_property; + obj_class->finalize = purple_theme_finalize; + + /* NAME */ + pspec = g_param_spec_string("name", "Name", + "The name of the theme", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_class_install_property(obj_class, PROP_NAME, pspec); + + /* DESCRIPTION */ + pspec = g_param_spec_string("description", "Description", + "The description of the theme", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_class_install_property(obj_class, PROP_DESCRIPTION, pspec); + + /* AUTHOR */ + pspec = g_param_spec_string("author", "Author", + "The author of the theme", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_class_install_property(obj_class, PROP_AUTHOR, pspec); + + /* TYPE STRING (read only) */ + pspec = g_param_spec_string("type", "Type", + "The string represtenting the type of the theme", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property(obj_class, PROP_TYPE, pspec); + + /* DIRECTORY */ + pspec = g_param_spec_string("directory", "Directory", + "The directory that contains the theme and all its files", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + g_object_class_install_property(obj_class, PROP_DIR, pspec); + + /* PREVIEW IMAGE */ + pspec = g_param_spec_string("image", "Image", + "A preview image of the theme", + NULL, + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_IMAGE, pspec); +} + + +GType +purple_theme_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PurpleThemeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)purple_theme_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PurpleTheme), + 0, /* n_preallocs */ + purple_theme_init, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static (G_TYPE_OBJECT, + "PurpleTheme", &info, G_TYPE_FLAG_ABSTRACT); + } + return type; +} + +/****************************************************************************** + * Helper Functions + *****************************************************************************/ + +static gchar * +theme_clean_text(const gchar *text) +{ + gchar *clean_text = g_markup_escape_text(text, -1); + g_strdelimit(clean_text, "\n", ' '); + purple_str_strip_char(clean_text, '\r'); + return clean_text; +} + +/***************************************************************************** + * Public API function + *****************************************************************************/ + +const gchar * +purple_theme_get_name(PurpleTheme *theme) +{ + PurpleThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_THEME(theme), NULL); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + return priv->name; +} + +void +purple_theme_set_name(PurpleTheme *theme, const gchar *name) +{ + PurpleThemePrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->name); + priv->name = theme_clean_text(name); +} + +const gchar * +purple_theme_get_description(PurpleTheme *theme) +{ + PurpleThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_THEME(theme), NULL); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + return priv->description; +} + +void +purple_theme_set_description(PurpleTheme *theme, const gchar *description) +{ + PurpleThemePrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->description); + priv->description = theme_clean_text(description); +} + +const gchar * +purple_theme_get_author(PurpleTheme *theme) +{ + PurpleThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_THEME(theme), NULL); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + return priv->author; +} + +void +purple_theme_set_author(PurpleTheme *theme, const gchar *author) +{ + PurpleThemePrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->author); + priv->author = theme_clean_text(author); +} + +const gchar * +purple_theme_get_type_string(PurpleTheme *theme) +{ + PurpleThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_THEME(theme), NULL); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + return priv->type; +} + +/* < private > */ +void +purple_theme_set_type_string(PurpleTheme *theme, const gchar *type) +{ + PurpleThemePrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->type); + priv->type = g_strdup(type); +} + +const gchar * +purple_theme_get_dir(PurpleTheme *theme) +{ + PurpleThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_THEME(theme), NULL); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + return priv->dir; +} + +void +purple_theme_set_dir(PurpleTheme *theme, const gchar *dir) +{ + PurpleThemePrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->dir); + priv->dir = g_strdup(dir); +} + +const gchar * +purple_theme_get_image(PurpleTheme *theme) +{ + PurpleThemePrivate *priv; + + g_return_val_if_fail(PURPLE_IS_THEME(theme), NULL); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + return priv->img; +} + +gchar * +purple_theme_get_image_full(PurpleTheme *theme) +{ + const gchar *filename = purple_theme_get_image(theme); + + g_return_val_if_fail(filename, NULL); + + return g_build_filename(purple_theme_get_dir(PURPLE_THEME(theme)), filename, NULL); +} + +void +purple_theme_set_image(PurpleTheme *theme, const gchar *img) +{ + PurpleThemePrivate *priv; + + g_return_if_fail(PURPLE_IS_THEME(theme)); + + priv = PURPLE_THEME_GET_PRIVATE(theme); + + g_free(priv->img); + priv->img = g_strdup(img); +} diff -r 29f953732186 -r 8c8948b9f602 libpurple/theme.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/theme.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,175 @@ +/** + * @file theme.h Purple Theme Abstact Class API + */ + +/* 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 + */ + +#ifndef PURPLE_THEME_H +#define PURPLE_THEME_H + +#include +#include +#include "imgstore.h" + +/** + * A purple theme. + * This is an abstract class for Purple to use with the Purple theme manager. + * + * PurpleTheme is a GObject. + */ +typedef struct _PurpleTheme PurpleTheme; +typedef struct _PurpleThemeClass PurpleThemeClass; + +#define PURPLE_TYPE_THEME (purple_theme_get_type ()) +#define PURPLE_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PURPLE_TYPE_THEME, PurpleTheme)) +#define PURPLE_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PURPLE_TYPE_THEME, PurpleThemeClass)) +#define PURPLE_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PURPLE_TYPE_THEME)) +#define PURPLE_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PURPLE_TYPE_THEME)) +#define PURPLE_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PURPLE_TYPE_THEME, PurpleThemeClass)) + +struct _PurpleTheme +{ + GObject parent; + gpointer priv; +}; + +struct _PurpleThemeClass +{ + GObjectClass parent_class; +}; + +/**************************************************************************/ +/** @name Purple Theme API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType purple_theme_get_type(void); + +/** + * Returns the name of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return The string representating the name of the theme. + */ +const gchar *purple_theme_get_name(PurpleTheme *theme); + +/** + * Sets the name of the PurpleTheme object. + * + * @param theme The purple theme. + * @param name The name of the PurpleTheme object. + */ +void purple_theme_set_name(PurpleTheme *theme, const gchar *name); + +/** + * Returns the description of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return A short description of the theme. + */ +const gchar *purple_theme_get_description(PurpleTheme *theme); + +/** + * Sets the description of the PurpleTheme object. + * + * @param theme The purple theme. + * @param description The description of the PurpleTheme object. + */ +void purple_theme_set_description(PurpleTheme *theme, const gchar *description); + +/** + * Returns the author of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return The author of the theme. + */ +const gchar *purple_theme_get_author(PurpleTheme *theme); + +/** + * Sets the author of the PurpleTheme object. + * + * @param theme The purple theme. + * @param author The author of the PurpleTheme object. + */ +void purple_theme_set_author(PurpleTheme *theme, const gchar *author); + +/** + * Returns the type (string) of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return The string represtenting the type. + */ +const gchar *purple_theme_get_type_string(PurpleTheme *theme); + +/** + * Returns the directory of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return The string represtenting the theme directory. + */ +const gchar *purple_theme_get_dir(PurpleTheme *theme); + +/** + * Sets the directory of the PurpleTheme object. + * + * @param theme The purple theme. + * @param dir The directory of the PurpleTheme object. + */ +void purple_theme_set_dir(PurpleTheme *theme, const gchar *dir); + +/** + * Returns the image preview of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return The image preview of the PurpleTheme object. + */ +const gchar *purple_theme_get_image(PurpleTheme *theme); + +/** + * Returns the image preview and directory of the PurpleTheme object. + * + * @param theme The purple theme. + * + * @return The image preview of the PurpleTheme object. + */ +gchar *purple_theme_get_image_full(PurpleTheme *theme); + +/** + * Sets the directory of the PurpleTheme object. + * + * @param theme The purple theme. + * @param img The image preview of the PurpleTheme object. + */ +void purple_theme_set_image(PurpleTheme *theme, const gchar *img); + +G_END_DECLS +#endif /* PURPLE_THEME_H */ diff -r 29f953732186 -r 8c8948b9f602 libpurple/upnp.c --- a/libpurple/upnp.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/upnp.c Wed Jan 28 10:23:37 2009 +0000 @@ -715,7 +715,7 @@ g_free(totalSendMessage); g_free(addressOfControl); - + return gfud; } @@ -1048,7 +1048,7 @@ purple_upnp_get_handle(void) { static int handle; - + return &handle; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/util.c --- a/libpurple/util.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/util.c Wed Jan 28 10:23:37 2009 +0000 @@ -98,7 +98,7 @@ void purple_util_init(void) { - /* This does nothing right now. It exists for symmetry with + /* This does nothing right now. It exists for symmetry with * purple_util_uninit() and forwards compatibility. */ } @@ -1409,7 +1409,7 @@ struct purple_parse_tag *pt = tags->data; if(xhtml) g_string_append_printf(xhtml, "", pt->dest_tag); - if(plain && !strcmp(pt->src_tag, "a")) { + if(plain && purple_strequal(pt->src_tag, "a")) { /* if this is a link, we have to add the url to the plaintext, too */ if (cdata && url && (!g_string_equal(cdata, url) && (g_ascii_strncasecmp(url->str, "mailto:", 7) != 0 || @@ -2693,7 +2693,7 @@ return FALSE; } #endif - + /* Close file */ if (fclose(file) != 0) { @@ -2774,70 +2774,7 @@ xmlnode * purple_util_read_xml_from_file(const char *filename, const char *description) { - const char *user_dir = purple_user_dir(); - gchar *filename_full; - GError *error = NULL; - gchar *contents = NULL; - gsize length; - xmlnode *node = NULL; - - g_return_val_if_fail(user_dir != NULL, NULL); - - purple_debug_info("util", "Reading file %s from directory %s\n", - filename, user_dir); - - filename_full = g_build_filename(user_dir, filename, NULL); - - if (!g_file_test(filename_full, G_FILE_TEST_EXISTS)) - { - purple_debug_info("util", "File %s does not exist (this is not " - "necessarily an error)\n", filename_full); - g_free(filename_full); - return NULL; - } - - if (!g_file_get_contents(filename_full, &contents, &length, &error)) - { - purple_debug_error("util", "Error reading file %s: %s\n", - filename_full, error->message); - g_error_free(error); - } - - if ((contents != NULL) && (length > 0)) - { - node = xmlnode_from_str(contents, length); - - /* If we were unable to parse the file then save its contents to a backup file */ - if (node == NULL) - { - gchar *filename_temp; - - filename_temp = g_strdup_printf("%s~", filename); - purple_debug_error("util", "Error parsing file %s. Renaming old " - "file to %s\n", filename_full, filename_temp); - purple_util_write_data_to_file(filename_temp, contents, length); - g_free(filename_temp); - } - - g_free(contents); - } - - /* If we could not parse the file then show the user an error message */ - if (node == NULL) - { - gchar *title, *msg; - title = g_strdup_printf(_("Error Reading %s"), filename); - msg = g_strdup_printf(_("An error was encountered reading your " - "%s. They have not been loaded, and the old file " - "has been renamed to %s~."), description, filename_full); - purple_notify_error(NULL, NULL, title, msg); - g_free(title); - g_free(msg); - } - - g_free(filename_full); - - return node; + return xmlnode_from_file(purple_user_dir(), filename, description, "util"); } /* @@ -3012,7 +2949,7 @@ g_free(tmp); session = g_getenv("KDE_FULL_SESSION"); - if (session != NULL && !strcmp(session, "true")) + if (purple_strequal(session, "true")) return TRUE; /* If you run Purple from Konsole under !KDE, this will provide a @@ -3053,6 +2990,17 @@ /************************************************************************** * String Functions **************************************************************************/ +gboolean +purple_strequal(const gchar *left, const gchar *right) +{ +#if GLIB_CHECK_VERSION(2,16,0) + return (g_strcmp0(left, right) == 0); +#else + return ((left == NULL && right == NULL) || + (left != NULL && right != NULL && strcmp(left, right) == 0)); +#endif +} + const char * purple_normalize(const PurpleAccount *account, const char *str) { @@ -3167,7 +3115,7 @@ g_return_val_if_fail(x != NULL, FALSE); off = strlen(s) - strlen(x); - return (off >= 0 && !strcmp(s + off, x)); + return (off >= 0 && purple_strequal(s + off, x)); #endif } @@ -4764,7 +4712,7 @@ const char *_purple_oscar_convert(const char *act, const char *protocol) { - if (protocol && act && strcmp(protocol, "prpl-oscar") == 0) { + if (act && purple_strequal(protocol, "prpl-oscar")) { int i; for (i = 0; act[i] != '\0'; i++) if (!isdigit(act[i])) diff -r 29f953732186 -r 8c8948b9f602 libpurple/util.h --- a/libpurple/util.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/util.h Wed Jan 28 10:23:37 2009 +0000 @@ -775,6 +775,21 @@ /*@{*/ /** + * Tests two strings for equality. + * + * Unlike strcmp(), this function will not crash if one or both of the + * strings are @c NULL. + * + * @param left A string + * @param right A string to compare with left + * + * @return @c TRUE if the strings are the same, else @c FALSE. + * + * @since 2.6.0 + */ +gboolean purple_strequal(const gchar *left, const gchar *right); + +/** * Normalizes a string, so that it is suitable for comparison. * * The returned string will point to a static buffer, so if the diff -r 29f953732186 -r 8c8948b9f602 libpurple/whiteboard.c --- a/libpurple/whiteboard.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/whiteboard.c Wed Jan 28 10:23:37 2009 +0000 @@ -115,7 +115,7 @@ { wb = l->data; - if(wb->account == account && !strcmp(wb->who, who)) + if(wb->account == account && purple_strequal(wb->who, who)) return wb; l = l->next; diff -r 29f953732186 -r 8c8948b9f602 libpurple/xmlnode.c --- a/libpurple/xmlnode.c Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/xmlnode.c Wed Jan 28 10:23:37 2009 +0000 @@ -129,7 +129,7 @@ for(attr_node = node->child; attr_node; attr_node = attr_node->next) { if(attr_node->type == XMLNODE_TYPE_ATTRIB && - !strcmp(attr_node->name, attr)) + purple_strequal(attr_node->name, attr)) { if(sibling == NULL) { node->child = attr_node->next; @@ -146,20 +146,6 @@ } } -/* Compare two nullable xmlns strings. - * They are considered equal if they're both NULL or the strings are equal - */ -static gboolean _xmlnode_compare_xmlns(const char *xmlns1, const char *xmlns2) { - gboolean equal = FALSE; - - if (xmlns1 == NULL && xmlns2 == NULL) - equal = TRUE; - else if (xmlns1 != NULL && xmlns2 != NULL && !strcmp(xmlns1, xmlns2)) - equal = TRUE; - - return equal; -} - void xmlnode_remove_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns) { @@ -171,8 +157,8 @@ for(attr_node = node->child; attr_node; attr_node = attr_node->next) { if(attr_node->type == XMLNODE_TYPE_ATTRIB && - !strcmp(attr_node->name, attr) && - _xmlnode_compare_xmlns(xmlns, attr_node->xmlns)) + purple_strequal(attr, attr_node->name) && + purple_strequal(xmlns, attr_node->xmlns)) { if(sibling == NULL) { node->child = attr_node->next; @@ -252,7 +238,7 @@ g_return_val_if_fail(attr != NULL, NULL); for(x = node->child; x; x = x->next) { - if(x->type == XMLNODE_TYPE_ATTRIB && !strcmp(attr, x->name)) { + if(x->type == XMLNODE_TYPE_ATTRIB && purple_strequal(attr, x->name)) { return x->data; } } @@ -270,8 +256,8 @@ for(x = node->child; x; x = x->next) { if(x->type == XMLNODE_TYPE_ATTRIB && - !strcmp(attr, x->name) && - _xmlnode_compare_xmlns(xmlns, x->xmlns)) { + purple_strequal(attr, x->name) && + purple_strequal(xmlns, x->xmlns)) { return x->data; } } @@ -382,8 +368,8 @@ if(ns) xmlns = xmlnode_get_namespace(x); - if(x->type == XMLNODE_TYPE_TAG && name && !strcmp(parent_name, x->name) - && (!ns || (xmlns && !strcmp(ns, xmlns)))) { + if(x->type == XMLNODE_TYPE_TAG && purple_strequal(parent_name, x->name) + && purple_strequal(ns, xmlns)) { ret = x; break; } @@ -471,7 +457,7 @@ g_hash_table_foreach(node->namespace_map, (GHFunc)xmlnode_to_str_foreach_append_ns, text); } else if (node->xmlns) { - if(!node->parent || !node->parent->xmlns || strcmp(node->xmlns, node->parent->xmlns)) + if(!node->parent || !purple_strequal(node->xmlns, node->parent->xmlns)) { char *xmlns = g_markup_escape_text(node->xmlns, -1); g_string_append_printf(text, " xmlns='%s'", xmlns); @@ -642,7 +628,7 @@ if(!xpd->current || xpd->error) return; - + if(!text || !text_len) return; @@ -730,6 +716,78 @@ return ret; } +xmlnode * +xmlnode_from_file(const char *dir,const char *filename, const char *description, const char *process) +{ + gchar *filename_full; + GError *error = NULL; + gchar *contents = NULL; + gsize length; + xmlnode *node = NULL; + + g_return_val_if_fail(dir != NULL, NULL); + + purple_debug_info(process, "Reading file %s from directory %s\n", + filename, dir); + + filename_full = g_build_filename(dir, filename, NULL); + + if (!g_file_test(filename_full, G_FILE_TEST_EXISTS)) + { + purple_debug_info(process, "File %s does not exist (this is not " + "necessarily an error)\n", filename_full); + g_free(filename_full); + return NULL; + } + + if (!g_file_get_contents(filename_full, &contents, &length, &error)) + { + purple_debug_error(process, "Error reading file %s: %s\n", + filename_full, error->message); + g_error_free(error); + } + + if ((contents != NULL) && (length > 0)) + { + node = xmlnode_from_str(contents, length); + + /* If we were unable to parse the file then save its contents to a backup file */ + if (node == NULL) + { + gchar *filename_temp, *filename_temp_full; + + filename_temp = g_strdup_printf("%s~", filename); + filename_temp_full = g_build_filename(dir, filename_temp, NULL); + + purple_debug_error("util", "Error parsing file %s. Renaming old " + "file to %s\n", filename_full, filename_temp); + purple_util_write_data_to_file_absolute(filename_temp_full, contents, length); + + g_free(filename_temp_full); + g_free(filename_temp); + } + + g_free(contents); + } + + /* If we could not parse the file then show the user an error message */ + if (node == NULL) + { + gchar *title, *msg; + title = g_strdup_printf(_("Error Reading %s"), filename); + msg = g_strdup_printf(_("An error was encountered reading your " + "%s. The file has not been loaded, and the old file " + "has been renamed to %s~."), description, filename_full); + purple_notify_error(NULL, NULL, title, msg); + g_free(title); + g_free(msg); + } + + g_free(filename_full); + + return node; +} + static void xmlnode_copy_foreach_ns(gpointer key, gpointer value, gpointer user_data) { @@ -794,8 +852,8 @@ if(ns) xmlns = xmlnode_get_namespace(sibling); - if(sibling->type == XMLNODE_TYPE_TAG && !strcmp(node->name, sibling->name) && - (!ns || (xmlns && !strcmp(ns, xmlns)))) + if(sibling->type == XMLNODE_TYPE_TAG && purple_strequal(node->name, sibling->name) && + purple_strequal(ns, xmlns)) return sibling; } diff -r 29f953732186 -r 8c8948b9f602 libpurple/xmlnode.h --- a/libpurple/xmlnode.h Wed Jan 28 04:27:01 2009 +0000 +++ b/libpurple/xmlnode.h Wed Jan 28 10:23:37 2009 +0000 @@ -26,6 +26,8 @@ #ifndef _PURPLE_XMLNODE_H_ #define _PURPLE_XMLNODE_H_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -297,6 +299,22 @@ */ void xmlnode_free(xmlnode *node); +/** + * Creates a node from a XML File. Calling this on the + * root node of an XML document will parse the entire document + * into a tree of nodes, and return the xmlnode of the root. + * + * @param str The string of xml. + * @param description The description of the file being parsed + * @process The utility that is calling xmlnode_from_file + * + * @return The new node. + * + * @since 2.6.0 + */ +xmlnode *xmlnode_from_file(const char *dir, const char *filename, + const char *description, const char *process); + #ifdef __cplusplus } #endif diff -r 29f953732186 -r 8c8948b9f602 pidgin/Makefile.am --- a/pidgin/Makefile.am Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/Makefile.am Wed Jan 28 10:23:37 2009 +0000 @@ -78,6 +78,8 @@ pidginstock.c \ gtkaccount.c \ gtkblist.c \ + gtkblist-theme.c \ + gtkblist-theme-loader.c \ gtkcelllayout.c \ gtkcellrendererexpander.c \ gtkcellrendererprogress.c \ @@ -94,6 +96,8 @@ gtkeventloop.c \ gtkexpander.c \ gtkft.c \ + gtkicon-theme.c \ + gtkicon-theme-loader.c \ gtkidle.c \ gtkimhtml.c \ gtkimhtmltoolbar.c \ @@ -116,6 +120,7 @@ gtksourceiter.c \ gtksourceundomanager.c \ gtksourceview-marshal.c \ + gtkstatus-icon-theme.c \ gtkstatusbox.c \ gtkthemes.c \ gtkutils.c \ @@ -127,6 +132,8 @@ eggtrayicon.h \ gtkaccount.h \ gtkblist.h \ + gtkblist-theme.h \ + gtkblist-theme-loader.h \ gtkcelllayout.h \ gtkcellrendererexpander.h \ gtkcellrendererprogress.h \ @@ -146,6 +153,8 @@ gtkeventloop.h \ gtkexpander.h \ gtkft.h \ + gtkicon-theme.h \ + gtkicon-theme-loader.h \ gtkidle.h \ gtkgaim-compat.h \ gtkimhtml.h \ @@ -169,6 +178,7 @@ gtksourceiter.h \ gtksourceundomanager.h \ gtksourceview-marshal.h \ + gtkstatus-icon-theme.h \ gtkstatusbox.h \ pidginstock.h \ gtkthemes.h \ diff -r 29f953732186 -r 8c8948b9f602 pidgin/Makefile.mingw --- a/pidgin/Makefile.mingw Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/Makefile.mingw Wed Jan 28 10:23:37 2009 +0000 @@ -56,6 +56,8 @@ PIDGIN_C_SRC = \ gtkaccount.c \ gtkblist.c \ + gtkblist-theme.c \ + gtkblist-theme-loader.c \ gtkcertmgr.c \ gtkcellrendererexpander.c \ gtkcellrendererprogress.c \ @@ -68,6 +70,8 @@ gtkeventloop.c \ gtkexpander.c \ gtkft.c \ + gtkicon-theme.c \ + gtkicon-theme-loader.c \ gtkidle.c \ gtkimhtml.c \ gtkimhtmltoolbar.c \ @@ -88,6 +92,7 @@ gtksound.c \ gtksourceiter.c \ gtksourceundomanager.c \ + gtkstatus-icon-theme.c \ gtkstatusbox.c \ gtkthemes.c \ gtkutils.c \ diff -r 29f953732186 -r 8c8948b9f602 pidgin/eggtrayicon.c --- a/pidgin/eggtrayicon.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/eggtrayicon.c Wed Jan 28 10:23:37 2009 +0000 @@ -39,7 +39,7 @@ PROP_0, PROP_ORIENTATION }; - + static GtkPlugClass *parent_class = NULL; static void egg_tray_icon_init (EggTrayIcon *icon); @@ -102,7 +102,7 @@ { icon->stamp = 1; icon->orientation = GTK_ORIENTATION_HORIZONTAL; - + gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); } @@ -250,7 +250,7 @@ egg_tray_icon_manager_window_destroyed (icon); } } - + return GDK_FILTER_CONTINUE; } @@ -296,7 +296,7 @@ { XClientMessageEvent ev; Display *display; - + ev.type = ClientMessage; ev.window = window; ev.message_type = icon->system_tray_opcode_atom; @@ -335,7 +335,7 @@ gboolean dock_if_realized) { Display *xdisplay; - + if (icon->manager_window != None) return; @@ -345,7 +345,7 @@ return; XGrabServer (xdisplay); - + icon->manager_window = XGetSelectionOwner (xdisplay, icon->selection_atom); @@ -355,7 +355,7 @@ XUngrabServer (xdisplay); XFlush (xdisplay); - + if (icon->manager_window != None) { GdkWindow *gdkwin; @@ -380,7 +380,7 @@ egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon) { GdkWindow *gdkwin; - + g_return_if_fail (icon->manager_window != None); #if GTK_CHECK_VERSION(2,1,0) @@ -458,9 +458,9 @@ screen); icon->selection_atom = XInternAtom (xdisplay, buffer, False); - + icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); - + icon->system_tray_opcode_atom = XInternAtom (xdisplay, "_NET_SYSTEM_TRAY_OPCODE", False); @@ -514,11 +514,11 @@ gint len) { guint stamp; - + g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); g_return_val_if_fail (timeout >= 0, 0); g_return_val_if_fail (message != NULL, 0); - + if (icon->manager_window == None) return 0; @@ -526,7 +526,7 @@ len = strlen (message); stamp = icon->stamp++; - + /* Get ready to send the message */ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, (Window)gtk_plug_get_id (GTK_PLUG (icon)), @@ -576,7 +576,7 @@ { g_return_if_fail (EGG_IS_TRAY_ICON (icon)); g_return_if_fail (id > 0); - + egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, (Window)gtk_plug_get_id (GTK_PLUG (icon)), id, 0, 0); diff -r 29f953732186 -r 8c8948b9f602 pidgin/eggtrayicon.h --- a/pidgin/eggtrayicon.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/eggtrayicon.h Wed Jan 28 10:23:37 2009 +0000 @@ -33,7 +33,7 @@ #define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON)) #define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON)) #define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass)) - + typedef struct _EggTrayIcon EggTrayIcon; typedef struct _EggTrayIconClass EggTrayIconClass; @@ -42,7 +42,7 @@ GtkPlug parent_instance; guint stamp; - + Atom selection_atom; Atom manager_atom; Atom system_tray_opcode_atom; @@ -74,7 +74,7 @@ guint id); GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon *icon); - + G_END_DECLS #endif /* __EGG_TRAY_ICON_H__ */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/getopt.c --- a/pidgin/getopt.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/getopt.c Wed Jan 28 10:23:37 2009 +0000 @@ -178,7 +178,7 @@ { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; - + #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. @@ -219,7 +219,7 @@ to[i] = from[i]; } #endif /* GNU C library. */ - + /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have @@ -259,7 +259,7 @@ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } - + /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. @@ -663,7 +663,7 @@ } #endif /* _LIBC or not __GNU_LIBRARY__. */ - + #ifdef TEST /* Compile with -DTEST to make an executable for use in testing diff -r 29f953732186 -r 8c8948b9f602 pidgin/getopt1.c --- a/pidgin/getopt1.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/getopt1.c Wed Jan 28 10:23:37 2009 +0000 @@ -81,7 +81,7 @@ #endif /* _LIBC or not __GNU_LIBRARY__. */ - + #ifdef TEST #include diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkaccount.c Wed Jan 28 10:23:37 2009 +0000 @@ -51,7 +51,7 @@ { COLUMN_ICON, COLUMN_BUDDYICON, - COLUMN_SCREENNAME, + COLUMN_USERNAME, COLUMN_ENABLED, COLUMN_PROTOCOL, COLUMN_DATA, @@ -78,7 +78,7 @@ GtkListStore *model; GtkTreeIter drag_iter; - GtkTreeViewColumn *screenname_col; + GtkTreeViewColumn *username_col; } AccountsWindow; @@ -115,7 +115,7 @@ GtkWidget *login_frame; GtkWidget *protocol_menu; GtkWidget *password_box; - GtkWidget *screenname_entry; + GtkWidget *username_entry; GtkWidget *password_entry; GtkWidget *alias_entry; GtkWidget *remember_pass_check; @@ -256,7 +256,7 @@ } static gboolean -screenname_focus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) +username_focus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) { GHashTable *table; const char *label; @@ -275,7 +275,7 @@ } static void -screenname_changed_cb(GtkEntry *entry, AccountPrefsDialog *dialog) +username_changed_cb(GtkEntry *entry, AccountPrefsDialog *dialog) { if (dialog->ok_button) gtk_widget_set_sensitive(dialog->ok_button, @@ -290,7 +290,7 @@ } static gboolean -screenname_nofocus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) +username_nofocus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) { GdkColor color = {0, 34952, 35466, 34181}; GHashTable *table = NULL; @@ -301,13 +301,13 @@ label = g_hash_table_lookup(table, "login_label"); if (*gtk_entry_get_text(GTK_ENTRY(widget)) == '\0') { - /* We have to avoid hitting the screenname_changed_cb function + /* We have to avoid hitting the username_changed_cb function * because it enables buttons we don't want enabled yet ;) */ - g_signal_handlers_block_by_func(widget, G_CALLBACK(screenname_changed_cb), dialog); + g_signal_handlers_block_by_func(widget, G_CALLBACK(username_changed_cb), dialog); gtk_entry_set_text(GTK_ENTRY(widget), label); /* Make sure we can hit it again */ - g_signal_handlers_unblock_by_func(widget, G_CALLBACK(screenname_changed_cb), dialog); + g_signal_handlers_unblock_by_func(widget, G_CALLBACK(username_changed_cb), dialog); gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &color); } @@ -393,7 +393,7 @@ set = !(purple_account_is_connected(dialog->account) || purple_account_is_connecting(dialog->account)); gtk_widget_set_sensitive(dialog->protocol_menu, set); - gtk_widget_set_sensitive(dialog->screenname_entry, set); + gtk_widget_set_sensitive(dialog->username_entry, set); for (l = dialog->user_split_entries ; l != NULL ; l = l->next) gtk_widget_set_sensitive((GtkWidget *)l->data, set); @@ -449,13 +449,13 @@ gtk_widget_unref(dialog->protocol_menu); - /* Screen name */ - dialog->screenname_entry = gtk_entry_new(); + /* Username */ + dialog->username_entry = gtk_entry_new(); #if GTK_CHECK_VERSION(2,10,0) - g_object_set(G_OBJECT(dialog->screenname_entry), "truncate-multiline", TRUE, NULL); + g_object_set(G_OBJECT(dialog->username_entry), "truncate-multiline", TRUE, NULL); #endif - add_pref_box(dialog, vbox, _("_Username:"), dialog->screenname_entry); + add_pref_box(dialog, vbox, _("_Username:"), dialog->username_entry); if (dialog->account != NULL) username = g_strdup(purple_account_get_username(dialog->account)); @@ -468,17 +468,17 @@ table = dialog->prpl_info->get_account_text_table(NULL); label = g_hash_table_lookup(table, "login_label"); - gtk_entry_set_text(GTK_ENTRY(dialog->screenname_entry), label); - g_signal_connect(G_OBJECT(dialog->screenname_entry), "focus-in-event", - G_CALLBACK(screenname_focus_cb), dialog); - g_signal_connect(G_OBJECT(dialog->screenname_entry), "focus-out-event", - G_CALLBACK(screenname_nofocus_cb), dialog); - gtk_widget_modify_text(dialog->screenname_entry, GTK_STATE_NORMAL, &color); + gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), label); + g_signal_connect(G_OBJECT(dialog->username_entry), "focus-in-event", + G_CALLBACK(username_focus_cb), dialog); + g_signal_connect(G_OBJECT(dialog->username_entry), "focus-out-event", + G_CALLBACK(username_nofocus_cb), dialog); + gtk_widget_modify_text(dialog->username_entry, GTK_STATE_NORMAL, &color); g_hash_table_destroy(table); } - g_signal_connect(G_OBJECT(dialog->screenname_entry), "changed", - G_CALLBACK(screenname_changed_cb), dialog); + g_signal_connect(G_OBJECT(dialog->username_entry), "changed", + G_CALLBACK(username_changed_cb), dialog); /* Do the user split thang */ if (dialog->prpl_info == NULL) @@ -547,7 +547,7 @@ } if (username != NULL) - gtk_entry_set_text(GTK_ENTRY(dialog->screenname_entry), username); + gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), username); g_free(username); @@ -590,7 +590,7 @@ gtk_widget_hide(dialog->remember_pass_check); } - /* Do not let the user change the protocol/screenname while connected. */ + /* Do not let the user change the protocol/username while connected. */ update_editable(NULL, dialog); purple_signal_connect(purple_connections_get_handle(), "signing-on", dialog, G_CALLBACK(update_editable), dialog); @@ -1193,7 +1193,7 @@ PurpleAccount *account; /* Build the username string. */ - username = g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->screenname_entry))); + username = g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->username_entry))); if (dialog->prpl_info != NULL) { @@ -1933,7 +1933,7 @@ gtk_tree_view_column_set_resizable(column, FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); - /* Screen Name column */ + /* Username column */ column = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(column, _("Username")); gtk_tree_view_column_set_resizable(column, TRUE); @@ -1945,12 +1945,12 @@ gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", COLUMN_BUDDYICON); - /* Screen Name */ + /* Username */ renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, - "text", COLUMN_SCREENNAME); - dialog->screenname_col = column; + "text", COLUMN_USERNAME); + dialog->username_col = column; /* Protocol name */ @@ -2012,7 +2012,7 @@ gtk_list_store_set(store, iter, COLUMN_ICON, pixbuf, COLUMN_BUDDYICON, buddyicon, - COLUMN_SCREENNAME, purple_account_get_username(account), + COLUMN_USERNAME, purple_account_get_username(account), COLUMN_ENABLED, purple_account_get_enabled(account, PIDGIN_UI), COLUMN_PROTOCOL, purple_account_get_protocol_name(account), COLUMN_DATA, account, @@ -2186,7 +2186,7 @@ dialog->model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, /* COLUMN_ICON */ GDK_TYPE_PIXBUF, /* COLUMN_BUDDYICON */ - G_TYPE_STRING, /* COLUMN_SCREENNAME */ + G_TYPE_STRING, /* COLUMN_USERNAME */ G_TYPE_BOOLEAN, /* COLUMN_ENABLED */ G_TYPE_STRING, /* COLUMN_PROTOCOL */ G_TYPE_POINTER /* COLUMN_DATA */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkblist-theme-loader.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkblist-theme-loader.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,279 @@ +/* + * GTKBlistThemeLoader for Pidgin + * + * Pidgin 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 + +#include "xmlnode.h" + +#include "gtkblist-theme-loader.h" +#include "gtkblist-theme.h" + +/****************************************************************************** + * Globals + *****************************************************************************/ + +#define DEFAULT_TEXT_COLOR "black" + +/***************************************************************************** + * Buddy List Theme Builder + *****************************************************************************/ + +static PurpleTheme * +pidgin_blist_loader_build(const gchar *dir) +{ + xmlnode *root_node = NULL, *sub_node, *sub_sub_node; + gchar *filename_full, *data; + const gchar *temp; + gboolean success = TRUE; + GdkColor *bgcolor, *expanded_bgcolor, *collapsed_bgcolor, *contact_color; + GdkColor color; + FontColorPair *expanded, *collapsed, *contact, *online, *away, *offline, *idle, *message, *message_nick_said, *status; + PidginBlistLayout *layout; + PidginBlistTheme *theme; + + /* Find the theme file */ + g_return_val_if_fail(dir != NULL, NULL); + filename_full = g_build_filename(dir, "theme.xml", NULL); + + if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR)) + root_node = xmlnode_from_file(dir, "theme.xml", "buddy list themes", "blist-loader"); + + g_free(filename_full); + g_return_val_if_fail(root_node != NULL, NULL); + + sub_node = xmlnode_get_child(root_node, "description"); + data = xmlnode_get_data(sub_node); + + /* init all structs and colors */ + bgcolor = g_new0(GdkColor, 1); + expanded_bgcolor = g_new0(GdkColor, 1); + collapsed_bgcolor = g_new0(GdkColor, 1); + + layout = g_new0(PidginBlistLayout, 1); + + contact_color = g_new0(GdkColor, 1); + + expanded = g_new0(FontColorPair, 1); + collapsed = g_new0(FontColorPair, 1); + contact = g_new0(FontColorPair, 1); + online = g_new0(FontColorPair, 1); + away = g_new0(FontColorPair, 1); + offline = g_new0(FontColorPair, 1); + idle = g_new0(FontColorPair, 1); + message = g_new0(FontColorPair, 1); + message_nick_said = g_new0(FontColorPair, 1); + status = g_new0(FontColorPair, 1); + + /* */ + if ((success = (sub_node = xmlnode_get_child(root_node, "blist")) != NULL)) { + if ((temp = xmlnode_get_attrib(sub_node, "color")) != NULL && gdk_color_parse(temp, bgcolor)) + gdk_colormap_alloc_color(gdk_colormap_get_system(), bgcolor, FALSE, TRUE); + else { + g_free(bgcolor); + bgcolor = NULL; + } + } + + /* */ + if ((success = (success && (sub_node = xmlnode_get_child(root_node, "groups")) != NULL + && (sub_sub_node = xmlnode_get_child(sub_node, "expanded")) != NULL))) + { + expanded->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + + if ((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color)) + expanded->color = g_strdup(temp); + else expanded->color = g_strdup(DEFAULT_TEXT_COLOR); + + if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, expanded_bgcolor)) + gdk_colormap_alloc_color(gdk_colormap_get_system(), expanded_bgcolor, FALSE, TRUE); + else { + g_free(expanded_bgcolor); + expanded_bgcolor = NULL; + } + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "collapsed")) != NULL))) + { + collapsed->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + + if((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color)) + collapsed->color = g_strdup(temp); + else collapsed->color = g_strdup(DEFAULT_TEXT_COLOR); + + if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, collapsed_bgcolor)) + gdk_colormap_alloc_color(gdk_colormap_get_system(), collapsed_bgcolor, FALSE, TRUE); + else { + g_free(collapsed_bgcolor); + collapsed_bgcolor = NULL; + } + } + + /* */ + if ((success = (success && (sub_node = xmlnode_get_child(root_node, "buddys")) != NULL && + (sub_sub_node = xmlnode_get_child(sub_node, "placement")) != NULL))) + { + layout->status_icon = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) : 0; + layout->text = (temp = xmlnode_get_attrib(sub_sub_node, "name")) != NULL ? atoi(temp) : 1; + layout->emblem = (temp = xmlnode_get_attrib(sub_sub_node, "emblem")) != NULL ? atoi(temp) : 2; + layout->protocol_icon = (temp = xmlnode_get_attrib(sub_sub_node, "protocol_icon")) != NULL ? atoi(temp) : 3; + layout->buddy_icon = (temp = xmlnode_get_attrib(sub_sub_node, "buddy_icon")) != NULL ? atoi(temp) : 4; + layout->show_status = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) != 0 : 1; + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "background")) != NULL))) { + if(gdk_color_parse(xmlnode_get_attrib(sub_sub_node, "color"), contact_color)) + gdk_colormap_alloc_color(gdk_colormap_get_system(), contact_color, FALSE, TRUE); + else { + g_free(contact_color); + contact_color = NULL; + } + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "contact_text")) != NULL))) { + contact->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + contact->color = g_strdup(temp); + else contact->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "online_text")) != NULL))) { + online->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + online->color = g_strdup(temp); + else online->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "away_text")) != NULL))) { + away->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + away->color = g_strdup(temp); + else away->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "offline_text")) != NULL))) { + offline->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + online->color = g_strdup(temp); + else online->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "idle_text")) != NULL))) { + idle->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + idle->color = g_strdup(temp); + else online->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_text")) != NULL))) { + message->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + message->color = g_strdup(temp); + else message->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_nick_said_text")) != NULL))) { + message_nick_said->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + message_nick_said->color = g_strdup(temp); + else message_nick_said->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "status_text")) != NULL))) { + status->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font")); + if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) + status->color = g_strdup(temp); + else status->color = g_strdup(DEFAULT_TEXT_COLOR); + } + + /* name is required for theme manager */ + success = (success && xmlnode_get_attrib(root_node, "name") != NULL); + + /* the new theme */ + theme = g_object_new(PIDGIN_TYPE_BLIST_THEME, + "type", "blist", + "name", xmlnode_get_attrib(root_node, "name"), + "author", xmlnode_get_attrib(root_node, "author"), + "image", xmlnode_get_attrib(root_node, "image"), + "directory", dir, + "description", data, + "background-color", bgcolor, + "layout", layout, + "expanded-color", expanded_bgcolor, + "expanded-text", expanded, + "collapsed-color", collapsed_bgcolor, + "collapsed-text", collapsed, + "contact-color", contact_color, + "contact", contact, + "online", online, + "away", away, + "offline", offline, + "idle", idle, + "message", message, + "message_nick_said", message_nick_said, + "status", status, NULL); + + xmlnode_free(root_node); + g_free(data); + + /* malformed xml file - also frees all partial data*/ + if (!success) { + g_object_unref(theme); + theme = NULL; + } + + return PURPLE_THEME(theme); +} + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +pidgin_blist_theme_loader_class_init(PidginBlistThemeLoaderClass *klass) +{ + PurpleThemeLoaderClass *loader_klass = PURPLE_THEME_LOADER_CLASS(klass); + + loader_klass->purple_theme_loader_build = pidgin_blist_loader_build; +} + +GType +pidgin_blist_theme_loader_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PidginBlistThemeLoaderClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)pidgin_blist_theme_loader_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PidginBlistThemeLoader), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static(PURPLE_TYPE_THEME_LOADER, + "PidginBlistThemeLoader", &info, 0); + } + return type; +} diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkblist-theme-loader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkblist-theme-loader.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,71 @@ +/** + * @file gtkblist-loader.h Pidgin Buddy List Theme Loader Class API + */ + +/* pidgin + * + * Pidgin 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 + */ + +#ifndef PIDGIN_BLIST_THEME_LOADER_H +#define PIDGIN_BLIST_THEME_LOADER_H + +#include +#include +#include "theme-loader.h" + +/** + * A pidgin buddy list theme loader. extends PurpleThemeLoader (theme-loader.h) + * This is a class designed to build sound themes + * + * PidginBlistThemeLoader is a GObject. + */ +typedef struct _PidginBlistThemeLoader PidginBlistThemeLoader; +typedef struct _PidginBlistThemeLoaderClass PidginBlistThemeLoaderClass; + +#define PIDGIN_TYPE_BLIST_THEME_LOADER (pidgin_blist_theme_loader_get_type ()) +#define PIDGIN_BLIST_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_BLIST_THEME_LOADER, PidginBlistThemeLoader)) +#define PIDGIN_BLIST_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_BLIST_THEME_LOADER, PidginBlistThemeLoaderClass)) +#define PIDGIN_IS_BLIST_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_BLIST_THEME_LOADER)) +#define PIDGIN_IS_BLIST_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_BLIST_THEME_LOADER)) +#define PIDGIN_BLIST_THEME_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_BLIST_THEME_LOADER, PidginBlistThemeLoaderClass)) + +struct _PidginBlistThemeLoader +{ + PurpleThemeLoader parent; +}; + +struct _PidginBlistThemeLoaderClass +{ + PurpleThemeLoaderClass parent_class; +}; + +/**************************************************************************/ +/** @name Buddy List Theme-Loader API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType pidgin_blist_theme_loader_get_type(void); + +G_END_DECLS +#endif /* PIDGIN_BLIST_THEME_LOADER_H */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkblist-theme.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkblist-theme.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,784 @@ +/* + * Buddy List Themes for Pidgin + * + * Pidgin 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 "gtkblist-theme.h" + +#define PIDGIN_BLIST_THEME_GET_PRIVATE(Gobject) \ + ((PidginBlistThemePrivate *) ((PIDGIN_BLIST_THEME(Gobject))->priv)) + +/****************************************************************************** + * Structs + *****************************************************************************/ + +typedef struct { + /* Buddy list */ + gdouble opacity; + GdkColor *bgcolor; + PidginBlistLayout *layout; + + /* groups */ + GdkColor *expanded_color; + FontColorPair *expanded; + + GdkColor *collapsed_color; + FontColorPair *collapsed; + + /* buddy */ + GdkColor *contact_color; + + FontColorPair *contact; + + FontColorPair *online; + FontColorPair *away; + FontColorPair *offline; + FontColorPair *idle; + FontColorPair *message; + FontColorPair *message_nick_said; + + FontColorPair *status; + +} PidginBlistThemePrivate; + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GObjectClass *parent_class = NULL; + +/****************************************************************************** + * Enums + *****************************************************************************/ + +enum { + PROP_ZERO = 0, + PROP_BACKGROUND_COLOR, + PROP_OPACITY, + PROP_LAYOUT, + PROP_EXPANDED_COLOR, + PROP_EXPANDED_TEXT, + PROP_COLLAPSED_COLOR, + PROP_COLLAPSED_TEXT, + PROP_CONTACT_COLOR, + PROP_CONTACT, + PROP_ONLINE, + PROP_AWAY, + PROP_OFFLINE, + PROP_IDLE, + PROP_MESSAGE, + PROP_MESSAGE_NICK_SAID, + PROP_STATUS, +}; + +/****************************************************************************** + * Helpers + *****************************************************************************/ + +void +free_font_and_color(FontColorPair *pair) +{ + if (pair != NULL) { + if (pair->font) + g_free(pair->font); + if (pair->color) + g_free(pair->color); + g_free(pair); + } +} + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +pidgin_blist_theme_init(GTypeInstance *instance, + gpointer klass) +{ + (PIDGIN_BLIST_THEME(instance))->priv = g_new0(PidginBlistThemePrivate, 1); +} + +static void +pidgin_blist_theme_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *psec) +{ + PidginBlistTheme *theme = PIDGIN_BLIST_THEME(obj); + + switch (param_id) { + case PROP_BACKGROUND_COLOR: + g_value_set_pointer(value, pidgin_blist_theme_get_background_color(theme)); + break; + case PROP_OPACITY: + g_value_set_double(value, pidgin_blist_theme_get_opacity(theme)); + break; + case PROP_LAYOUT: + g_value_set_pointer(value, pidgin_blist_theme_get_layout(theme)); + break; + case PROP_EXPANDED_COLOR: + g_value_set_pointer(value, pidgin_blist_theme_get_expanded_background_color(theme)); + break; + case PROP_EXPANDED_TEXT: + g_value_set_pointer(value, pidgin_blist_theme_get_expanded_text_info(theme)); + break; + case PROP_COLLAPSED_COLOR: + g_value_set_pointer(value, pidgin_blist_theme_get_collapsed_background_color(theme)); + break; + case PROP_COLLAPSED_TEXT: + g_value_set_pointer(value, pidgin_blist_theme_get_collapsed_text_info(theme)); + break; + case PROP_CONTACT_COLOR: + g_value_set_pointer(value, pidgin_blist_theme_get_contact_color(theme)); + break; + case PROP_CONTACT: + g_value_set_pointer(value, pidgin_blist_theme_get_contact_text_info(theme)); + break; + case PROP_ONLINE: + g_value_set_pointer(value, pidgin_blist_theme_get_online_text_info(theme)); + break; + case PROP_AWAY: + g_value_set_pointer(value, pidgin_blist_theme_get_away_text_info(theme)); + break; + case PROP_OFFLINE: + g_value_set_pointer(value, pidgin_blist_theme_get_offline_text_info(theme)); + break; + case PROP_IDLE: + g_value_set_pointer(value, pidgin_blist_theme_get_idle_text_info(theme)); + break; + case PROP_MESSAGE: + g_value_set_pointer(value, pidgin_blist_theme_get_unread_message_text_info(theme)); + break; + case PROP_MESSAGE_NICK_SAID: + g_value_set_pointer(value, pidgin_blist_theme_get_unread_message_nick_said_text_info(theme)); + break; + case PROP_STATUS: + g_value_set_pointer(value, pidgin_blist_theme_get_status_text_info(theme)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec); + break; + } +} + +static void +pidgin_blist_theme_set_property(GObject *obj, guint param_id, const GValue *value, + GParamSpec *psec) +{ + PidginBlistTheme *theme = PIDGIN_BLIST_THEME(obj); + + switch (param_id) { + case PROP_BACKGROUND_COLOR: + pidgin_blist_theme_set_background_color(theme, g_value_get_pointer(value)); + break; + case PROP_OPACITY: + pidgin_blist_theme_set_opacity(theme, g_value_get_double(value)); + break; + case PROP_LAYOUT: + pidgin_blist_theme_set_layout(theme, g_value_get_pointer(value)); + break; + case PROP_EXPANDED_COLOR: + pidgin_blist_theme_set_expanded_background_color(theme, g_value_get_pointer(value)); + break; + case PROP_EXPANDED_TEXT: + pidgin_blist_theme_set_expanded_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_COLLAPSED_COLOR: + pidgin_blist_theme_set_collapsed_background_color(theme, g_value_get_pointer(value)); + break; + case PROP_COLLAPSED_TEXT: + pidgin_blist_theme_set_collapsed_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_CONTACT_COLOR: + pidgin_blist_theme_set_contact_color(theme, g_value_get_pointer(value)); + break; + case PROP_CONTACT: + pidgin_blist_theme_set_contact_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_ONLINE: + pidgin_blist_theme_set_online_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_AWAY: + pidgin_blist_theme_set_away_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_OFFLINE: + pidgin_blist_theme_set_offline_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_IDLE: + pidgin_blist_theme_set_idle_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_MESSAGE: + pidgin_blist_theme_set_unread_message_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_MESSAGE_NICK_SAID: + pidgin_blist_theme_set_unread_message_nick_said_text_info(theme, g_value_get_pointer(value)); + break; + case PROP_STATUS: + pidgin_blist_theme_set_status_text_info(theme, g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec); + break; + } +} + +static void +pidgin_blist_theme_finalize(GObject *obj) +{ + PidginBlistThemePrivate *priv; + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(obj); + + /* Buddy List */ + g_free(priv->layout); + + /* Group */ + free_font_and_color(priv->expanded); + free_font_and_color(priv->collapsed); + + /* Buddy */ + free_font_and_color(priv->contact); + free_font_and_color(priv->online); + free_font_and_color(priv->away); + free_font_and_color(priv->offline); + free_font_and_color(priv->message); + free_font_and_color(priv->message_nick_said); + free_font_and_color(priv->status); + + g_free(priv); + + parent_class->finalize (obj); +} + +static void +pidgin_blist_theme_class_init(PidginBlistThemeClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + parent_class = g_type_class_peek_parent (klass); + + obj_class->get_property = pidgin_blist_theme_get_property; + obj_class->set_property = pidgin_blist_theme_set_property; + obj_class->finalize = pidgin_blist_theme_finalize; + + /* Buddy List */ + pspec = g_param_spec_pointer("background-color", "Background Color", + "The background color for the buddy list", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_BACKGROUND_COLOR, pspec); + + pspec = g_param_spec_pointer("layout", "Layout", + "The layout of icons, name, and status of the blist", + G_PARAM_READWRITE); + + g_object_class_install_property(obj_class, PROP_LAYOUT, pspec); + + /* Group */ + pspec = g_param_spec_pointer("expanded-color", "Expanded Background Color", + "The background color of an expanded group", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_EXPANDED_COLOR, pspec); + + pspec = g_param_spec_pointer("expanded-text", "Expanded Text", + "The text information for when a group is expanded", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_EXPANDED_TEXT, pspec); + + pspec = g_param_spec_pointer("collapsed-color", "Collapsed Background Color", + "The background color of a collapsed group", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_COLLAPSED_COLOR, pspec); + + pspec = g_param_spec_pointer("collapsed-text", "Collapsed Text", + "The text information for when a group is collapsed", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_COLLAPSED_TEXT, pspec); + + /* Buddy */ + pspec = g_param_spec_pointer("contact-color", "Contact/Chat Background Color", + "The background color of a contact or chat", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_CONTACT_COLOR, pspec); + + pspec = g_param_spec_pointer("contact", "Contact Text", + "The text information for when a contact is expanded", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_CONTACT, pspec); + + pspec = g_param_spec_pointer("online", "On-line Text", + "The text information for when a buddy is online", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_ONLINE, pspec); + + pspec = g_param_spec_pointer("away", "Away Text", + "The text information for when a buddy is away", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_AWAY, pspec); + + pspec = g_param_spec_pointer("offline", "Off-line Text", + "The text information for when a buddy is off-line", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_OFFLINE, pspec); + + pspec = g_param_spec_pointer("idle", "Idle Text", + "The text information for when a buddy is idle", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_IDLE, pspec); + + pspec = g_param_spec_pointer("message", "Message Text", + "The text information for when a buddy has an unread message", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_MESSAGE, pspec); + + pspec = g_param_spec_pointer("message_nick_said", "Message (Nick Said) Text", + "The text information for when a chat has an unread message that mentions your nick", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_MESSAGE_NICK_SAID, pspec); + + pspec = g_param_spec_pointer("status", "Status Text", + "The text information for a buddy's status", + G_PARAM_READWRITE); + g_object_class_install_property(obj_class, PROP_STATUS, pspec); +} + +GType +pidgin_blist_theme_get_type (void) +{ + static GType type = 0; + if (type == 0) { + static GTypeInfo info = { + sizeof(PidginBlistThemeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)pidgin_blist_theme_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PidginBlistTheme), + 0, /* n_preallocs */ + pidgin_blist_theme_init, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static (PURPLE_TYPE_THEME, + "PidginBlistTheme", &info, 0); + } + return type; +} + + +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +/* get methods */ + +GdkColor * +pidgin_blist_theme_get_background_color(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->bgcolor; +} + +gdouble +pidgin_blist_theme_get_opacity(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), 1.0); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->opacity; +} + +PidginBlistLayout * +pidgin_blist_theme_get_layout(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->layout; +} + +GdkColor * +pidgin_blist_theme_get_expanded_background_color(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->expanded_color; +} + +FontColorPair * +pidgin_blist_theme_get_expanded_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->expanded; +} + +GdkColor * +pidgin_blist_theme_get_collapsed_background_color(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->collapsed_color; +} + +FontColorPair * +pidgin_blist_theme_get_collapsed_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->collapsed; +} + +GdkColor * +pidgin_blist_theme_get_contact_color(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->contact_color; +} + +FontColorPair * +pidgin_blist_theme_get_contact_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->contact; +} + +FontColorPair * +pidgin_blist_theme_get_online_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->online; +} + +FontColorPair * +pidgin_blist_theme_get_away_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->away; +} + +FontColorPair * +pidgin_blist_theme_get_offline_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->offline; +} + +FontColorPair * +pidgin_blist_theme_get_idle_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->idle; +} + +FontColorPair * +pidgin_blist_theme_get_unread_message_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->message; +} + +FontColorPair * +pidgin_blist_theme_get_unread_message_nick_said_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->message_nick_said; +} + +FontColorPair * +pidgin_blist_theme_get_status_text_info(PidginBlistTheme *theme) +{ + PidginBlistThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_BLIST_THEME(theme), NULL); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + return priv->status; +} + +/* Set Methods */ +void +pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, GdkColor *color) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + priv->bgcolor = color; +} + +void +pidgin_blist_theme_set_opacity(PidginBlistTheme *theme, gdouble opacity) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme) || opacity < 0.0 || opacity > 1.0); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + priv->opacity = opacity; +} + +void +pidgin_blist_theme_set_layout(PidginBlistTheme *theme, PidginBlistLayout *layout) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + g_free(priv->layout); + priv->layout = layout; +} + +void +pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, GdkColor *color) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + priv->expanded_color = color; +} + +void +pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->expanded); + priv->expanded = pair; +} + +void +pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, GdkColor *color) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + priv->collapsed_color = color; +} + +void +pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->collapsed); + priv->collapsed = pair; +} + +void +pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, GdkColor *color) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + priv->contact_color = color; +} + +void +pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->contact); + priv->contact = pair; +} + +void +pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->online); + priv->online = pair; +} + +void +pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->away); + priv->away = pair; +} + +void +pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->offline); + priv->offline = pair; +} + +void +pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->idle); + priv->idle = pair; +} + +void +pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->message); + priv->message = pair; +} + +void +pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->message_nick_said); + priv->message_nick_said = pair; +} + +void +pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, FontColorPair *pair) +{ + PidginBlistThemePrivate *priv; + + g_return_if_fail(PIDGIN_IS_BLIST_THEME(theme)); + + priv = PIDGIN_BLIST_THEME_GET_PRIVATE(G_OBJECT(theme)); + + free_font_and_color(priv->status); + priv->status = pair; +} diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkblist-theme.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkblist-theme.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,332 @@ +/** + * @file gtkblist-theme.h GTK+ Buddy List Theme API + */ + +/* pidgin + * + * Pidgin 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 + */ + +#ifndef PIDGIN_BLIST_THEME_H +#define PIDGIN_BLIST_THEME_H + +#include +#include +#include + +#include "theme.h" + +/** + * A pidgin buddy list theme. + * This is an object for Purple to represent a buddy list theme. + * + * PidginBlistTheme is a PurpleTheme Object. + */ +typedef struct _PidginBlistTheme PidginBlistTheme; +typedef struct _PidginBlistThemeClass PidginBlistThemeClass; + +#define PIDGIN_TYPE_BLIST_THEME (pidgin_blist_theme_get_type ()) +#define PIDGIN_BLIST_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_BLIST_THEME, PidginBlistTheme)) +#define PIDGIN_BLIST_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_BLIST_THEME, PidginBlistThemeClass)) +#define PIDGIN_IS_BLIST_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_BLIST_THEME)) +#define PIDGIN_IS_BLIST_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_BLIST_THEME)) +#define PIDGIN_BLIST_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_BLIST_THEME, PidginBlistThemeClass)) + +struct _PidginBlistTheme +{ + PurpleTheme parent; + gpointer priv; +}; + +struct _PidginBlistThemeClass +{ + PurpleThemeClass parent_class; +}; + +typedef struct +{ + gchar *font; + gchar *color; + +} FontColorPair; + +typedef struct +{ + gint status_icon; + gint text; + gint emblem; + gint protocol_icon; + gint buddy_icon; + gboolean show_status; + +} PidginBlistLayout; + +/**************************************************************************/ +/** @name FontColorPair API */ +/**************************************************************************/ + +/** + * Frees a font and color pair + */ +void free_font_and_color(FontColorPair *pair); + +/**************************************************************************/ +/** @name Purple Buddy List Theme API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType pidgin_blist_theme_get_type(void); + +/* get methods */ + +/** + * Returns the background color of the buddy list. + * + * @returns A gdk color. + */ + GdkColor *pidgin_blist_theme_get_background_color(PidginBlistTheme *theme); + +/** + * Returns the opacity of the buddy list window + * (0.0 or clear to 1.0 fully opaque). + * + * @returns The opacity + */ +gdouble pidgin_blist_theme_get_opacity(PidginBlistTheme *theme); + +/** + * Returns the layout to be used with the buddy list. + * + * @returns The buddy list layout. + */ + PidginBlistLayout *pidgin_blist_theme_get_layout(PidginBlistTheme *theme); + +/** + * Returns the background color to be used with expanded groups. + * + * @returns A gdk color. + */ + GdkColor *pidgin_blist_theme_get_expanded_background_color(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used with expanded groups. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_expanded_text_info(PidginBlistTheme *theme); + +/** + * Returns the background color to be used with collapsed groups. + * + * @returns A gdk color. + */ + GdkColor *pidgin_blist_theme_get_collapsed_background_color(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used with collapsed groups. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_collapsed_text_info(PidginBlistTheme *theme); + +/** + * Returns the colors to be used for contacts and chats. + * + * @returns A gdkcolor for contacts and chats. + */ + GdkColor *pidgin_blist_theme_get_contact_color(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for expanded contacts. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_contact_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for online buddies. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_online_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for away and idle buddies. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_away_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for offline buddies. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_offline_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for idle buddies. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_idle_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for buddies with unread messages. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_unread_message_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for chats with unread messages + * that mention your nick. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_unread_message_nick_said_text_info(PidginBlistTheme *theme); + +/** + * Returns the text font and color to be used for a buddy's status message. + * + * @returns A font and color pair. + */ + FontColorPair *pidgin_blist_theme_get_status_text_info(PidginBlistTheme *theme); + +/* Set Methods */ + +/** + * Sets the background color to be used for this buddy list theme. + * + * @param color The new background color. + */ +void pidgin_blist_theme_set_background_color(PidginBlistTheme *theme, GdkColor *color); + +/** + * Sets the opacity to be used for this buddy list theme. + * + * @param opacity The new opacity setting. + */ +void pidgin_blist_theme_set_opacity(PidginBlistTheme *theme, gdouble opacity); + +/** + * Sets the buddy list layout to be used for this buddy list theme. + * + * @param layout The new layout. + */ +void pidgin_blist_theme_set_layout(PidginBlistTheme *theme, PidginBlistLayout *layout); + +/** + * Sets the background color to be used for expanded groups. + * + * @param color The new background color. + */ +void pidgin_blist_theme_set_expanded_background_color(PidginBlistTheme *theme, GdkColor *color); + +/** + * Sets the text color and font to be used for expanded groups. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_expanded_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the background color to be used for collapsed groups. + * + * @param color The new background color. + */ +void pidgin_blist_theme_set_collapsed_background_color(PidginBlistTheme *theme, GdkColor *color); + +/** + * Sets the text color and font to be used for expanded groups. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_collapsed_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the background color to be used for contacts and chats. + * + * @param color The color to use for contacts and chats. + */ +void pidgin_blist_theme_set_contact_color(PidginBlistTheme *theme, GdkColor *color); + +/** + * Sets the text color and font to be used for expanded contacts. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_contact_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for online buddies. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_online_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for away and idle buddies. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_away_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for offline buddies. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_offline_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for idle buddies. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_idle_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for buddies with unread messages. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_unread_message_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for a chat with unread messages + * that mention your nick. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_unread_message_nick_said_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +/** + * Sets the text color and font to be used for buddy status messages. + * + * @param pair The new text font at color pair. + */ +void pidgin_blist_theme_set_status_text_info(PidginBlistTheme *theme, FontColorPair *pair); + +G_END_DECLS +#endif /* PIDGIN_BLIST_THEME_H */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkblist.c Wed Jan 28 10:23:37 2009 +0000 @@ -38,6 +38,8 @@ #include "request.h" #include "signals.h" #include "pidginstock.h" +#include "theme-loader.h" +#include "theme-manager.h" #include "util.h" #include "gtkaccount.h" @@ -58,6 +60,8 @@ #include "gtkstatusbox.h" #include "gtkscrollbook.h" #include "gtksmiley.h" +#include "gtkblist-theme.h" +#include "gtkblist-theme-loader.h" #include "gtkutils.h" #include "pidgin/minidialog.h" #include "pidgin/pidgintooltip.h" @@ -121,6 +125,9 @@ * is showing; @c NULL otherwise. */ PidginMiniDialog *signed_on_elsewhere; + + PidginBlistTheme *current_theme; + } PidginBuddyListPrivate; #define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \ @@ -142,7 +149,7 @@ #if GTK_CHECK_VERSION(2,2,1) static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); -static void sort_method_log(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); +static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); #endif static PidginBuddyList *gtkblist = NULL; @@ -164,7 +171,8 @@ static void set_urgent(void); typedef enum { - PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE = 1 << 0, /* Whether there's pending message in a conversation */ + PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE = 1 << 0, /* Whether there's pending message in a conversation */ + PIDGIN_BLIST_CHAT_HAS_PENDING_MESSAGE_WITH_NICK = 1 << 1, /* Whether there's a pending message in a chat that mentions our nick */ } PidginBlistNodeFlags; typedef struct _pidgin_blist_node { @@ -179,17 +187,6 @@ } conv; } PidginBlistNode; -static char dim_grey_string[8] = ""; -static char *dim_grey(void) -{ - if (!gtkblist) - return "dim grey"; - if (!dim_grey_string[0]) { - snprintf(dim_grey_string, sizeof(dim_grey_string), "%s", pidgin_get_dim_grey_string(gtkblist->treeview)); - } - return dim_grey_string; -} - /*************************************************** * Callbacks * ***************************************************/ @@ -329,17 +326,24 @@ static void gtk_blist_menu_info_cb(GtkWidget *w, PurpleBuddy *b) { - pidgin_retrieve_user_info(b->account->gc, purple_buddy_get_name(b)); + PurpleAccount *account = purple_buddy_get_account(b); + + pidgin_retrieve_user_info(purple_account_get_connection(account), + purple_buddy_get_name(b)); } static void gtk_blist_menu_im_cb(GtkWidget *w, PurpleBuddy *b) { - pidgin_dialogs_im_with_user(b->account, b->name); + pidgin_dialogs_im_with_user(purple_buddy_get_account(b), + purple_buddy_get_name(b)); } static void gtk_blist_menu_send_file_cb(GtkWidget *w, PurpleBuddy *b) { - serv_send_file(b->account->gc, b->name, NULL); + PurpleAccount *account = purple_buddy_get_account(b); + + serv_send_file(purple_account_get_connection(account), + purple_buddy_get_name(b), NULL); } static void gtk_blist_menu_move_to_cb(GtkWidget *w, PurpleBlistNode *node) @@ -364,7 +368,7 @@ static PurpleConversation * find_conversation_with_buddy(PurpleBuddy *buddy) { - PidginBlistNode *ui = buddy->node.ui_data; + PidginBlistNode *ui = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); if (ui) return ui->conv.conv; return purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, @@ -374,15 +378,20 @@ static void gtk_blist_join_chat(PurpleChat *chat) { + PurpleAccount *account; PurpleConversation *conv; PurplePluginProtocolInfo *prpl_info; + GHashTable *components; const char *name; char *chat_name; - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(chat->account))); + account = purple_chat_get_account(chat); + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); + + components = purple_chat_get_components(chat); if (prpl_info && prpl_info->get_chat_name) - chat_name = prpl_info->get_chat_name(chat->components); + chat_name = prpl_info->get_chat_name(components); else chat_name = NULL; @@ -392,14 +401,14 @@ name = purple_chat_get_name(chat); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name, - chat->account); + account); if (conv != NULL) { pidgin_conv_attach_to_conversation(conv); purple_conversation_present(conv); } - serv_join_chat(chat->account->gc, chat->components); + serv_join_chat(purple_account_get_connection(account), components); g_free(chat_name); } @@ -434,15 +443,15 @@ gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); node = g_value_get_pointer(&val); - switch (node->type) { + switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_CONTACT_NODE: - text = purple_contact_get_alias((PurpleContact *)node); + text = purple_contact_get_alias(PURPLE_CONTACT(node)); break; case PURPLE_BLIST_BUDDY_NODE: - text = purple_buddy_get_alias((PurpleBuddy *)node); + text = purple_buddy_get_alias(PURPLE_BUDDY(node)); break; case PURPLE_BLIST_GROUP_NODE: - text = ((PurpleGroup *)node)->name; + text = purple_group_get_name(PURPLE_GROUP(node)); break; default: g_return_if_reached(); @@ -470,17 +479,24 @@ for (tmp = merges; tmp; tmp = tmp->next) { PurpleBlistNode *node = tmp->data; PurpleBlistNode *b; + PurpleBlistNodeType type; int i = 0; - if (node->type == PURPLE_BLIST_BUDDY_NODE) - node = node->parent; - - if (node->type != PURPLE_BLIST_CONTACT_NODE) + type = purple_blist_node_get_type(node); + + if(type == PURPLE_BLIST_BUDDY_NODE) + node = purple_blist_node_get_parent(node); + + if(type == PURPLE_BLIST_CONTACT_NODE) continue; - - - for (b = node->child; b; b = b->next) + + for (b = purple_blist_node_get_first_child(node); + b; + b = purple_blist_node_get_sibling_next(b)) + { i++; + } + if (i > max) { contact = node; max = i; @@ -493,8 +509,8 @@ /* Merge all those buddies into this contact */ for (tmp = merges; tmp; tmp = tmp->next) { PurpleBlistNode *node = tmp->data; - if (node->type == PURPLE_BLIST_BUDDY_NODE) - node = node->parent; + if (purple_blist_node_get_type(node) == PURPLE_BLIST_BUDDY_NODE) + node = purple_blist_node_get_parent(node); if (node == contact) continue; @@ -516,9 +532,11 @@ int i = 0; char *a = g_utf8_casefold(alias, -1); - for (contact = group->child; contact; contact = contact->next) { + for (contact = purple_blist_node_get_first_child(group); + contact != NULL; + contact = purple_blist_node_get_sibling_next(contact)) { char *node_alias; - if (contact->type != PURPLE_BLIST_CONTACT_NODE) + if (purple_blist_node_get_type(contact) != PURPLE_BLIST_CONTACT_NODE) continue; node_alias = g_utf8_casefold(purple_contact_get_alias((PurpleContact *)contact), -1); @@ -530,11 +548,14 @@ } g_free(node_alias); - for (buddy = contact->child; buddy; buddy = buddy->next) { - if (buddy->type != PURPLE_BLIST_BUDDY_NODE) + for (buddy = purple_blist_node_get_first_child(contact); + buddy; + buddy = purple_blist_node_get_sibling_next(buddy)) + { + if (purple_blist_node_get_type(buddy) != PURPLE_BLIST_BUDDY_NODE) continue; - node_alias = g_utf8_casefold(purple_buddy_get_alias((PurpleBuddy *)buddy), -1); + node_alias = g_utf8_casefold(purple_buddy_get_alias(PURPLE_BUDDY(buddy)), -1); if (node_alias && !g_utf8_collate(node_alias, a)) { merges = g_list_append(merges, buddy); i++; @@ -576,39 +597,45 @@ gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), TRUE); g_object_set(G_OBJECT(gtkblist->text_rend), "editable", FALSE, NULL); - switch (node->type) + switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_CONTACT_NODE: { - PurpleContact *contact = (PurpleContact *)node; - struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data; - - if (contact->alias || gtknode->contact_expanded) { + PurpleContact *contact = PURPLE_CONTACT(node); + struct _pidgin_blist_node *gtknode = + (struct _pidgin_blist_node *)purple_blist_node_get_ui_data(node); + + if (purple_contact_get_alias(contact) || gtknode->contact_expanded) { purple_blist_alias_contact(contact, arg2); - gtk_blist_auto_personize(node->parent, arg2); + gtk_blist_auto_personize(purple_blist_node_get_parent(node), arg2); } else { PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact); purple_blist_alias_buddy(buddy, arg2); serv_alias_buddy(buddy); - gtk_blist_auto_personize(node->parent, arg2); + gtk_blist_auto_personize(purple_blist_node_get_parent(node), arg2); } } break; case PURPLE_BLIST_BUDDY_NODE: - purple_blist_alias_buddy((PurpleBuddy*)node, arg2); - serv_alias_buddy((PurpleBuddy *)node); - gtk_blist_auto_personize(node->parent->parent, arg2); + { + PurpleGroup *group = purple_buddy_get_group(PURPLE_BUDDY(node)); + + purple_blist_alias_buddy(PURPLE_BUDDY(node), arg2); + serv_alias_buddy(PURPLE_BUDDY(node)); + gtk_blist_auto_personize(PURPLE_BLIST_NODE(group), arg2); + } break; case PURPLE_BLIST_GROUP_NODE: dest = purple_find_group(arg2); - if (dest != NULL && purple_utf8_strcasecmp(arg2, ((PurpleGroup*) node)->name)) { - pidgin_dialogs_merge_groups((PurpleGroup*) node, arg2); - } else - purple_blist_rename_group((PurpleGroup*)node, arg2); + if (dest != NULL && purple_utf8_strcasecmp(arg2, purple_group_get_name(PURPLE_GROUP(node)))) { + pidgin_dialogs_merge_groups(PURPLE_GROUP(node), arg2); + } else { + purple_blist_rename_group(PURPLE_GROUP(node), arg2); + } break; case PURPLE_BLIST_CHAT_NODE: - purple_blist_alias_chat((PurpleChat*)node, arg2); + purple_blist_alias_chat(PURPLE_CHAT(node), arg2); break; default: break; @@ -695,7 +722,7 @@ if (!(get_iter_from_node(node, &iter))) { /* This is either a bug, or the buddy is in a collapsed contact */ - node = node->parent; + node = purple_blist_node_get_parent(node); if (!get_iter_from_node(node, &iter)) /* Now it's definitely a bug */ return; @@ -718,7 +745,8 @@ static void gtk_blist_menu_bp_cb(GtkWidget *w, PurpleBuddy *b) { - pidgin_pounce_editor_show(b->account, b->name, NULL); + pidgin_pounce_editor_show(purple_buddy_get_account(b), + purple_buddy_get_name(b), NULL); } static void gtk_blist_menu_showlog_cb(GtkWidget *w, PurpleBlistNode *node) @@ -732,19 +760,19 @@ if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { PurpleBuddy *b = (PurpleBuddy*) node; type = PURPLE_LOG_IM; - name = g_strdup(b->name); - account = b->account; + name = g_strdup(purple_buddy_get_name(b)); + account = purple_buddy_get_account(b); } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { - PurpleChat *c = (PurpleChat*) node; + PurpleChat *c = PURPLE_CHAT(node); PurplePluginProtocolInfo *prpl_info = NULL; type = PURPLE_LOG_CHAT; - account = c->account; + account = purple_chat_get_account(c); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); if (prpl_info && prpl_info->get_chat_name) { - name = prpl_info->get_chat_name(c->components); + name = prpl_info->get_chat_name(purple_chat_get_components(c)); } } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { - pidgin_log_show_contact((PurpleContact *)node); + pidgin_log_show_contact(PURPLE_CONTACT(node)); pidgin_clear_cursor(gtkblist->window); return; } else { @@ -757,10 +785,10 @@ if (name && account) { pidgin_log_show(type, name, account); - g_free(name); - pidgin_clear_cursor(gtkblist->window); } + + g_free(name); } static void gtk_blist_menu_showoffline_cb(GtkWidget *w, PurpleBlistNode *node) @@ -777,7 +805,10 @@ gboolean setting = !purple_blist_node_get_bool(node, "show_offline"); purple_blist_node_set_bool(node, "show_offline", setting); - for (bnode = node->child; bnode != NULL; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(node); + bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) + { purple_blist_node_set_bool(bnode, "show_offline", setting); pidgin_blist_update(purple_get_blist(), bnode); } @@ -786,9 +817,15 @@ gboolean setting = !purple_blist_node_get_bool(node, "show_offline"); purple_blist_node_set_bool(node, "show_offline", setting); - for (cnode = node->child; cnode != NULL; cnode = cnode->next) { + for (cnode = purple_blist_node_get_first_child(node); + cnode != NULL; + cnode = purple_blist_node_get_sibling_next(cnode)) + { purple_blist_node_set_bool(cnode, "show_offline", setting); - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) { + for (bnode = purple_blist_node_get_first_child(cnode); + bnode != NULL; + bnode = purple_blist_node_get_sibling_next(bnode)) + { purple_blist_node_set_bool(bnode, "show_offline", setting); pidgin_blist_update(purple_get_blist(), bnode); } @@ -900,9 +937,10 @@ static void pidgin_blist_update_privacy_cb(PurpleBuddy *buddy) { - if (buddy->node.ui_data == NULL || ((struct _pidgin_blist_node*)buddy->node.ui_data)->row == NULL) + struct _pidgin_blist_node *ui_data = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)); + if (ui_data == NULL || ui_data->row == NULL) return; - pidgin_blist_update_buddy(purple_get_blist(), (PurpleBlistNode*)(buddy), TRUE); + pidgin_blist_update_buddy(purple_get_blist(), PURPLE_BLIST_NODE(buddy), TRUE); } static void @@ -1032,7 +1070,7 @@ GtkWidget *img = NULL; PidginJoinChatData *data = NULL; - gtkblist = PIDGIN_BLIST(purple_get_blist()); + gtkblist = purple_blist_get_ui_data(); img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE)); data = g_new0(PidginJoinChatData, 1); @@ -1452,7 +1490,7 @@ pidgin_new_item_from_stock(menu, _("Add Buddy _Pounce..."), NULL, G_CALLBACK(gtk_blist_menu_bp_cb), buddy, 0, 0, NULL); - if (node->parent && node->parent->child->next && + if (node->parent && node->parent->child->next && !sub && !contact_expanded) { pidgin_new_item_from_stock(menu, _("View _Log"), NULL, G_CALLBACK(gtk_blist_menu_showlog_cb), @@ -1474,7 +1512,7 @@ if (!contact_expanded && contact != NULL) pidgin_append_blist_node_move_to_menu(menu, (PurpleBlistNode *)contact); - if (node->parent && node->parent->child->next && + if (node->parent && node->parent->child->next && !sub && !contact_expanded) { pidgin_separator(menu); pidgin_append_blist_node_privacy_menu(menu, node); @@ -1792,7 +1830,8 @@ return handled; } -static gboolean gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_data) +static gboolean +gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_data) { GtkTreePath *path; PurpleBlistNode *node; @@ -2496,7 +2535,7 @@ node = g_value_get_pointer(&val); if (PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) { - PurpleBuddy *b = PURPLE_BLIST_NODE_IS_BUDDY(node) ? (PurpleBuddy*)node : purple_contact_get_priority_buddy((PurpleContact*)node); + PurpleBuddy *b = PURPLE_BLIST_NODE_IS_BUDDY(node) ? PURPLE_BUDDY(node) : purple_contact_get_priority_buddy(PURPLE_CONTACT(node)); pidgin_dnd_file_manage(sd, b->account, b->name); gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); } else { @@ -2720,7 +2759,7 @@ * * */ -#define STATUS_SIZE 16 +#define STATUS_SIZE 16 #define TOOLTIP_BORDER 12 #define SMALL_SPACE 6 #define LARGE_SPACE 12 @@ -2982,18 +3021,18 @@ } static void -pidgin_blist_align_tooltip(struct tooltip_data *td, GtkWidget *widget) -{ - GtkTextDirection dir = gtk_widget_get_direction(widget); - - if (dir == GTK_TEXT_DIR_RTL) +pidgin_blist_align_tooltip(struct tooltip_data *td, GtkWidget *widget) +{ + GtkTextDirection dir = gtk_widget_get_direction(widget); + + if (dir == GTK_TEXT_DIR_RTL) { char* layout_name = purple_markup_strip_html(pango_layout_get_text(td->name_layout)); PangoDirection dir = pango_find_base_dir(layout_name, -1); if (dir == PANGO_DIRECTION_RTL || dir == PANGO_DIRECTION_NEUTRAL) - pango_layout_set_alignment(td->name_layout, PANGO_ALIGN_RIGHT); + pango_layout_set_alignment(td->name_layout, PANGO_ALIGN_RIGHT); g_free(layout_name); - pango_layout_set_alignment(td->layout, PANGO_ALIGN_RIGHT); + pango_layout_set_alignment(td->layout, PANGO_ALIGN_RIGHT); } } @@ -3082,7 +3121,7 @@ GValue val; struct _pidgin_blist_node *gtknode; - if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y + (gtkblist->tip_rect.height/2), + if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y + (gtkblist->tip_rect.height/2), &path, NULL, NULL, NULL)) return FALSE; gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); @@ -3168,7 +3207,7 @@ if (y < rect.y + (rect.height / 3) || y > rect.y + (2 * (rect.height /3))) return FALSE; - + rect.height = rect.height / 3; rect.y += rect.height; @@ -3287,10 +3326,10 @@ { N_("/_Tools"), NULL, NULL, 0, "", NULL }, { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 1, "", NULL }, { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "", NULL }, + { N_("/Tools/Custom Smile_ys"), "Y", pidgin_smiley_manager_show, 0, "", PIDGIN_STOCK_TOOLBAR_SMILEY }, { N_("/Tools/Plu_gins"), "U", pidgin_plugin_dialog_show, 2, "", PIDGIN_STOCK_TOOLBAR_PLUGINS }, { N_("/Tools/Pr_eferences"), "P", pidgin_prefs_show, 0, "", GTK_STOCK_PREFERENCES }, { N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "", NULL }, - { N_("/Tools/Smile_y"), "Y", pidgin_smiley_manager_show, 0, "", PIDGIN_STOCK_TOOLBAR_SMILEY }, { "/Tools/sep2", NULL, NULL, 0, "", NULL }, { N_("/Tools/_File Transfers"), "T", pidgin_xfer_dialog_show, 0, "", PIDGIN_STOCK_TOOLBAR_TRANSFER }, { N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "", NULL }, @@ -3815,19 +3854,22 @@ return ret; } -gchar *pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased) -{ - const char *name; - char *esc, *text = NULL; +gchar * +pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased) +{ + const char *name, *name_color, *name_font, *status_color, *status_font; + char *text = NULL; PurplePlugin *prpl; PurplePluginProtocolInfo *prpl_info = NULL; PurpleContact *contact; PurplePresence *presence; struct _pidgin_blist_node *gtkcontactnode = NULL; - char *idletime = NULL, *statustext = NULL; - time_t t; + char *idletime = NULL, *statustext = NULL, *nametext = NULL; PurpleConversation *conv = find_conversation_with_buddy(b); gboolean hidden_conv = FALSE; + gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); + FontColorPair *pair = NULL; + PidginBlistTheme *theme; if (conv != NULL) { PidginBlistNode *ui = b->node.ui_data; @@ -3841,178 +3883,171 @@ } /* XXX Good luck cleaning up this crap */ - contact = (PurpleContact*)((PurpleBlistNode*)b)->parent; + contact = PURPLE_CONTACT(PURPLE_BLIST_NODE(b)->parent); if(contact) - gtkcontactnode = ((PurpleBlistNode*)contact)->ui_data; - - if(gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias) + gtkcontactnode = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(contact)); + + /* Name */ + if (gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias) name = contact->alias; else name = purple_buddy_get_alias(b); - - esc = g_markup_escape_text(name, strlen(name)); + + nametext = g_markup_escape_text(name, strlen(name)); presence = purple_buddy_get_presence(b); - if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons") && aliased) - { - if (!selected && purple_presence_is_idle(presence)) - { - text = g_strdup_printf("%s", - dim_grey(), esc); - g_free(esc); - if (hidden_conv) { - char *tmp = text; - text = g_strdup_printf("%s", text); + /* Name is all that is needed */ + if (aliased && biglist) { + + /* Status Info */ + prpl = purple_find_prpl(purple_account_get_protocol_id(b->account)); + + if (prpl != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + + if (prpl_info && prpl_info->status_text && b->account->gc) { + char *tmp = prpl_info->status_text(b); + const char *end; + + if(tmp && !g_utf8_validate(tmp, -1, &end)) { + char *new = g_strndup(tmp, + g_utf8_pointer_to_offset(tmp, end)); + g_free(tmp); + tmp = new; + } + /* add ... to messages that are too long, GTK 2.6+ does it automatically */ +#if !GTK_CHECK_VERSION(2,6,0) + if(tmp) { + char buf[32]; + char *c = tmp; + int length = 0, vis=0; + gboolean inside = FALSE; + g_strdelimit(tmp, "\n", ' '); + purple_str_strip_char(tmp, '\r'); + + while(*c && vis < 20) { + if(*c == '&') + inside = TRUE; + else if(*c == ';') + inside = FALSE; + if(!inside) + vis++; + c = g_utf8_next_char(c); /* this is fun */ + } + + length = c - tmp; + + if(vis == 20) + g_snprintf(buf, sizeof(buf), "%%.%ds...", length); + else + g_snprintf(buf, sizeof(buf), "%%s "); + + statustext = g_strdup_printf(buf, tmp);purple_presence_is_idle(presence) + g_free(tmp); } - return text; - } - else if (hidden_conv) - { - char *tmp = esc; - esc = g_strdup_printf("%s", esc); - g_free(tmp); - } - return esc; - } - - prpl = purple_find_prpl(purple_account_get_protocol_id(b->account)); - - if (prpl != NULL) - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - - if (prpl_info && prpl_info->status_text && b->account->gc) { - char *tmp = prpl_info->status_text(b); - const char *end; - - if(tmp && !g_utf8_validate(tmp, -1, &end)) { - char *new = g_strndup(tmp, - g_utf8_pointer_to_offset(tmp, end)); - g_free(tmp); - tmp = new; +#else + if(tmp) { + g_strdelimit(tmp, "\n", ' '); + purple_str_strip_char(tmp, '\r'); + } + statustext = tmp; +#endif } -#if !GTK_CHECK_VERSION(2,6,0) - if(tmp) { - char buf[32]; - char *c = tmp; - int length = 0, vis=0; - gboolean inside = FALSE; - g_strdelimit(tmp, "\n", ' '); - purple_str_strip_char(tmp, '\r'); - - while(*c && vis < 20) { - if(*c == '&') - inside = TRUE; - else if(*c == ';') - inside = FALSE; - if(!inside) - vis++; - c = g_utf8_next_char(c); /* this is fun */ - } - - length = c - tmp; - - if(vis == 20) - g_snprintf(buf, sizeof(buf), "%%.%ds...", length); - else - g_snprintf(buf, sizeof(buf), "%%s "); - - statustext = g_strdup_printf(buf, tmp); - - g_free(tmp); - } -#else - if(tmp) { - g_strdelimit(tmp, "\n", ' '); - purple_str_strip_char(tmp, '\r'); - } - statustext = tmp; -#endif - } - - if(!purple_presence_is_online(presence) && !statustext) - statustext = g_strdup(_("Offline")); - else if (!statustext) - text = g_strdup(esc); - - if (purple_presence_is_idle(presence)) { - if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time")) { + if(!purple_presence_is_online(presence) && !statustext) + statustext = g_strdup(_("Offline")); + + /* Idle Text */ + if (purple_presence_is_idle(presence) && purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time")) { time_t idle_secs = purple_presence_get_idle_time(presence); if (idle_secs > 0) { int iday, ihrs, imin; + time_t t; time(&t); iday = (t - idle_secs) / (24 * 60 * 60); ihrs = ((t - idle_secs) / 60 / 60) % 24; imin = ((t - idle_secs) / 60) % 60; - if (iday) + if (iday) idletime = g_strdup_printf(_("Idle %dd %dh %02dm"), iday, ihrs, imin); else if (ihrs) idletime = g_strdup_printf(_("Idle %dh %02dm"), ihrs, imin); else idletime = g_strdup_printf(_("Idle %dm"), imin); - } - else + + } else idletime = g_strdup(_("Idle")); - - if (!selected) { - g_free(text); - text = g_strdup_printf("%s\n" - "%s%s%s", - dim_grey(), esc, dim_grey(), - idletime != NULL ? idletime : "", - (idletime != NULL && statustext != NULL) ? " - " : "", - statustext != NULL ? statustext : ""); - } - } - else if (!selected && !statustext) {/* We handle selected text later */ - g_free(text); - text = g_strdup_printf("%s", dim_grey(), esc); - } else if (!selected && !text) { - g_free(text); - text = g_strdup_printf("%s\n" - "%s", - dim_grey(), esc, dim_grey(), - statustext != NULL ? statustext : ""); } - } else if (!PURPLE_BUDDY_IS_ONLINE(b)) { - if (!selected && !statustext) {/* We handle selected text later */ - g_free(text); - text = g_strdup_printf("%s", dim_grey(), esc); - } else if (!selected && !text) - text = g_strdup_printf("%s\n" - "%s", - dim_grey(), esc, dim_grey(), - statustext != NULL ? statustext : ""); - - } - /* Not idle and not selected */ - else if (!selected && !text) - { - text = g_strdup_printf("%s\n" - "%s", - esc, dim_grey(), - statustext != NULL ? statustext : ""); - } - - /* It is selected. */ - if ((selected && !text) || (selected && idletime)) { - g_free(text); - text = g_strdup_printf("%s\n" - "%s%s%s", - esc, - idletime != NULL ? idletime : "", - (idletime != NULL && statustext != NULL) ? " - " : "", - statustext != NULL ? statustext : ""); - } - + } + + /* choose the colors of the text */ + theme = pidgin_blist_get_theme(); + + if (purple_presence_is_idle(presence)) { + if (theme) + pair = pidgin_blist_theme_get_idle_text_info(theme); + status_color = name_color = (pair != NULL && pair->color != NULL) ? pair->color : "dim grey"; + status_font = name_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + + } else if (!purple_presence_is_online(presence)) { + if (theme) + pair = pidgin_blist_theme_get_offline_text_info(theme); + name_color = (pair != NULL && pair->color != NULL) ? pair->color : "black"; + name_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + + if (theme) + pair = pidgin_blist_theme_get_status_text_info(theme); + status_color = (pair != NULL && pair->color != NULL) ? pair->color : "dim grey"; + status_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + + } else if (purple_presence_is_available(presence)) { + if (theme) + pair = pidgin_blist_theme_get_online_text_info(theme); + name_color = (pair != NULL && pair->color != NULL) ? pair->color : "black"; + name_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + + if (theme) + pair = pidgin_blist_theme_get_status_text_info(theme); + status_color = (pair != NULL && pair->color != NULL) ? pair->color : "dim grey"; + status_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + + } else { + if (theme) + pair = pidgin_blist_theme_get_away_text_info(theme); + name_color = (pair != NULL && pair->color != NULL) ? pair->color : "black"; + name_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + + if (theme) + pair = pidgin_blist_theme_get_status_text_info(theme); + status_color = (pair != NULL && pair->color != NULL) ? pair->color : "dim grey"; + status_font = (pair != NULL && pair->font != NULL) ? pair->font : ""; + } + + if (aliased && selected) { + name_color = "black"; + status_color = "black"; + } + + /* Put it all together */ + if (aliased && biglist && (statustext || idletime)) { + /* using breaks the status, so it must be seperated into */ + text = g_strdup_printf("%s\n" + "%s%s%s", + name_font, name_color, nametext, status_font, status_color, + idletime != NULL ? idletime : "", + (idletime != NULL && statustext != NULL) ? " - " : "", + statustext != NULL ? statustext : ""); + + } else + text = g_strdup_printf("%s", name_font, name_color, nametext); + + g_free(nametext); + g_free(statustext); g_free(idletime); - g_free(statustext); - g_free(esc); if (hidden_conv) { char *tmp = text; @@ -4062,7 +4097,7 @@ PurpleBlistNode *gnode, *cnode; if (gtk_blist_visibility == GDK_VISIBILITY_FULLY_OBSCURED - || !GTK_WIDGET_VISIBLE(gtkblist->window)) + || !GTK_WIDGET_VISIBLE(gtkblist->window)) return TRUE; for(gnode = list->root; gnode; gnode = gnode->next) { @@ -4331,6 +4366,10 @@ !(flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV))) return; ui->conv.flags |= PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE; + if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT + && (flag & PURPLE_MESSAGE_NICK)) + ui->conv.flags |= PIDGIN_BLIST_CHAT_HAS_PENDING_MESSAGE_WITH_NICK; + ui->conv.last_message = time(NULL); /* XXX: for lack of better data */ pidgin_blist_update(purple_get_blist(), node); } @@ -4341,7 +4380,8 @@ PidginBlistNode *ui = node->ui_data; if (ui->conv.conv != gtkconv->active_conv) return; - ui->conv.flags &= ~PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE; + ui->conv.flags &= ~(PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE | + PIDGIN_BLIST_CHAT_HAS_PENDING_MESSAGE_WITH_NICK); pidgin_blist_update(purple_get_blist(), node); } @@ -4450,7 +4490,7 @@ #if GTK_CHECK_VERSION(2,2,1) pidgin_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical); pidgin_blist_sort_method_reg("status", _("By status"), sort_method_status); - pidgin_blist_sort_method_reg("log_size", _("By log size"), sort_method_log); + pidgin_blist_sort_method_reg("log_size", _("By recent log activity"), sort_method_log_activity); #endif pidgin_blist_sort_method_set(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type")); } @@ -5258,11 +5298,144 @@ } #endif +/* builds the blist layout according to to the current theme */ +static void +pidgin_blist_build_layout(PurpleBuddyList *list) +{ + GtkTreeViewColumn *column; + PidginBlistLayout *layout; + PidginBlistTheme *theme; + GtkCellRenderer *rend; + gint i, status_icon = 0, text = 1, emblem = 2, protocol_icon = 3, buddy_icon = 4; + + + column = gtkblist->text_column; + + if ((theme = pidgin_blist_get_theme()) != NULL && (layout = pidgin_blist_theme_get_layout(theme)) != NULL) { + status_icon = layout->status_icon ; + text = layout->text; + emblem = layout->emblem; + protocol_icon = layout->protocol_icon; + buddy_icon = layout->buddy_icon; + } + + gtk_tree_view_column_clear(column); + + /* group */ + rend = pidgin_cell_renderer_expander_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, + "visible", GROUP_EXPANDER_VISIBLE_COLUMN, + "expander-visible", GROUP_EXPANDER_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "sensitive", GROUP_EXPANDER_COLUMN, + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + NULL); + + /* contact */ + rend = pidgin_cell_renderer_expander_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, + "visible", CONTACT_EXPANDER_VISIBLE_COLUMN, + "expander-visible", CONTACT_EXPANDER_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "sensitive", CONTACT_EXPANDER_COLUMN, + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + NULL); + + for (i = 0; i < 5; i++) { + + if (status_icon == i) { + /* status icons */ + rend = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, + "pixbuf", STATUS_ICON_COLUMN, + "visible", STATUS_ICON_VISIBLE_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + NULL); + g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); + + } else if (text == i) { + /* name */ + gtkblist->text_rend = rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, TRUE); + gtk_tree_view_column_set_attributes(column, rend, +#if GTK_CHECK_VERSION(2,6,0) + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + "markup", NAME_COLUMN, + NULL); +#if GTK_CHECK_VERSION(2,6,0) + g_signal_connect(G_OBJECT(rend), "editing-started", G_CALLBACK(gtk_blist_renderer_editing_started_cb), NULL); + g_signal_connect(G_OBJECT(rend), "editing-canceled", G_CALLBACK(gtk_blist_renderer_editing_cancelled_cb), list); +#endif + g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), list); + g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); +#if GTK_CHECK_VERSION(2,6,0) + g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); +#endif + + /* idle */ + rend = gtk_cell_renderer_text_new(); + g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, + "markup", IDLE_COLUMN, + "visible", IDLE_VISIBLE_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + NULL); + } else if (emblem == i) { + /* emblem */ + rend = gtk_cell_renderer_pixbuf_new(); + g_object_set(rend, "xalign", 1.0, "yalign", 0.5, "ypad", 0, "xpad", 3, NULL); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, "pixbuf", EMBLEM_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + "visible", EMBLEM_VISIBLE_COLUMN, NULL); + + } else if (protocol_icon == i) { + /* protocol icon */ + rend = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, + "pixbuf", PROTOCOL_ICON_COLUMN, + "visible", PROTOCOL_ICON_VISIBLE_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + NULL); + g_object_set(rend, "xalign", 0.0, "xpad", 3, "ypad", 0, NULL); + + } else if (buddy_icon == i) { + /* buddy icon */ + rend = gtk_cell_renderer_pixbuf_new(); + g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, "pixbuf", BUDDY_ICON_COLUMN, +#if GTK_CHECK_VERSION(2,6,0) + "cell-background-gdk", BGCOLOR_COLUMN, +#endif + "visible", BUDDY_ICON_VISIBLE_COLUMN, + NULL); + } + + }/* end for loop */ + +} + static void pidgin_blist_show(PurpleBuddyList *list) { PidginBuddyListPrivate *priv; void *handle; - GtkCellRenderer *rend; GtkTreeViewColumn *column; GtkWidget *menu; GtkWidget *ebox; @@ -5288,6 +5461,8 @@ gtkblist = PIDGIN_BLIST(list); priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); + priv->current_theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"), "blist")); + gtkblist->empty_avatar = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 32, 32); gdk_pixbuf_fill(gtkblist->empty_avatar, 0x00000000); @@ -5320,8 +5495,8 @@ gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu), blist_menu, NULL); pidgin_load_accels(); - g_signal_connect(G_OBJECT(accel_group), "accel-changed", - G_CALLBACK(pidgin_save_accels_cb), NULL); + g_signal_connect(G_OBJECT(accel_group), "accel-changed", G_CALLBACK(pidgin_save_accels_cb), NULL); + menu = gtk_item_factory_get_widget(gtkblist->ift, ""); gtkblist->menutray = pidgin_menu_tray_new(); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtkblist->menutray); @@ -5464,105 +5639,16 @@ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); + /* expander columns */ column = gtk_tree_view_column_new(); gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); gtk_tree_view_column_set_visible(column, FALSE); gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gtkblist->treeview), column); - gtkblist->text_column = column = gtk_tree_view_column_new (); - rend = pidgin_cell_renderer_expander_new(); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, - "visible", GROUP_EXPANDER_VISIBLE_COLUMN, - "expander-visible", GROUP_EXPANDER_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "sensitive", GROUP_EXPANDER_COLUMN, - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - NULL); - - rend = pidgin_cell_renderer_expander_new(); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, - "expander-visible", CONTACT_EXPANDER_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "sensitive", CONTACT_EXPANDER_COLUMN, - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - "visible", CONTACT_EXPANDER_VISIBLE_COLUMN, - NULL); - - rend = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, - "pixbuf", STATUS_ICON_COLUMN, - "visible", STATUS_ICON_VISIBLE_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - NULL); - g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); - - gtkblist->text_rend = rend = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start (column, rend, TRUE); - gtk_tree_view_column_set_attributes(column, rend, -#if GTK_CHECK_VERSION(2,6,0) - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - "markup", NAME_COLUMN, - NULL); -#if GTK_CHECK_VERSION(2,6,0) - g_signal_connect(G_OBJECT(rend), "editing-started", G_CALLBACK(gtk_blist_renderer_editing_started_cb), NULL); - g_signal_connect(G_OBJECT(rend), "editing-canceled", G_CALLBACK(gtk_blist_renderer_editing_cancelled_cb), list); -#endif - g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), list); - g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); -#if GTK_CHECK_VERSION(2,6,0) - g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); -#endif - gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); - - rend = gtk_cell_renderer_text_new(); - g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, - "markup", IDLE_COLUMN, - "visible", IDLE_VISIBLE_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - NULL); - - rend = gtk_cell_renderer_pixbuf_new(); - g_object_set(rend, "xalign", 1.0, "yalign", 0.5, "ypad", 0, "xpad", 3, NULL); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, "pixbuf", EMBLEM_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - "visible", EMBLEM_VISIBLE_COLUMN, NULL); - - rend = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, - "pixbuf", PROTOCOL_ICON_COLUMN, - "visible", PROTOCOL_ICON_VISIBLE_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - NULL); - g_object_set(rend, "xalign", 0.0, "xpad", 3, "ypad", 0, NULL); - - rend = gtk_cell_renderer_pixbuf_new(); - g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); - gtk_tree_view_column_pack_start(column, rend, FALSE); - gtk_tree_view_column_set_attributes(column, rend, "pixbuf", BUDDY_ICON_COLUMN, -#if GTK_CHECK_VERSION(2,6,0) - "cell-background-gdk", BGCOLOR_COLUMN, -#endif - "visible", BUDDY_ICON_VISIBLE_COLUMN, - NULL); - + /* everything else column */ + gtkblist->text_column = gtk_tree_view_column_new (); + gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->text_column); + pidgin_blist_build_layout(list); g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL); @@ -5955,7 +6041,7 @@ if (editing_blist) return; - + if (PURPLE_BLIST_NODE_IS_GROUP(node)) gnode = node; else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) @@ -5989,13 +6075,19 @@ GtkTreeIter iter; GtkTreePath *path; gboolean expanded; - GdkColor bgcolor; + GdkColor *bgcolor = NULL; GdkPixbuf *avatar = NULL; + PidginBlistTheme *theme = NULL; if(!insert_node(list, gnode, &iter)) return; - bgcolor = gtkblist->treeview->style->bg[GTK_STATE_ACTIVE]; + if ((theme = pidgin_blist_get_theme()) == NULL) + bgcolor = NULL; + else if (purple_blist_node_get_bool(gnode, "collapsed") || count <= 0) + bgcolor = pidgin_blist_theme_get_collapsed_background_color(theme); + else + bgcolor = pidgin_blist_theme_get_expanded_background_color(theme); path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(gtkblist->treeview), path); @@ -6013,7 +6105,7 @@ STATUS_ICON_COLUMN, NULL, NAME_COLUMN, title, NODE_COLUMN, gnode, - /* BGCOLOR_COLUMN, &bgcolor, */ + BGCOLOR_COLUMN, bgcolor, GROUP_EXPANDER_COLUMN, TRUE, GROUP_EXPANDER_VISIBLE_COLUMN, TRUE, CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE, @@ -6036,6 +6128,9 @@ char *mark, *esc; PurpleBlistNode *selected_node = NULL; GtkTreeIter iter; + FontColorPair *pair; + gchar *text_color, *text_font; + PidginBlistTheme *theme; group = (PurpleGroup*)gnode; @@ -6051,8 +6146,21 @@ purple_blist_get_group_size(group, FALSE)); } + theme = pidgin_blist_get_theme(); + if (theme == NULL) + pair = NULL; + else if (expanded) + pair = pidgin_blist_theme_get_expanded_text_info(theme); + else + pair = pidgin_blist_theme_get_collapsed_text_info(theme); + + + text_color = (selected || pair == NULL || pair->color == NULL) ? "black" : pair->color; + text_font = (pair == NULL || pair->font == NULL) ? "" : pair->font; + esc = g_markup_escape_text(group->name, -1); - mark = g_strdup_printf("%s%s", esc ? esc : "", group_count); + mark = g_strdup_printf("%s%s", + text_color, text_font, esc ? esc : "", group_count); g_free(esc); return mark; @@ -6060,14 +6168,15 @@ static void buddy_node(PurpleBuddy *buddy, GtkTreeIter *iter, PurpleBlistNode *node) { - PurplePresence *presence; + PurplePresence *presence = purple_buddy_get_presence(buddy); GdkPixbuf *status, *avatar, *emblem, *prpl_icon; + GdkColor *color = NULL; char *mark; char *idle = NULL; gboolean expanded = ((struct _pidgin_blist_node *)(node->parent->ui_data))->contact_expanded; gboolean selected = (gtkblist->selected_node == node); gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); - presence = purple_buddy_get_presence(buddy); + PidginBlistTheme *theme; if (editing_blist) return; @@ -6091,35 +6200,39 @@ emblem = pidgin_blist_get_emblem((PurpleBlistNode*) buddy); mark = pidgin_blist_get_name_markup(buddy, selected, TRUE); + theme = pidgin_blist_get_theme(); + if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_idle_time") && - purple_presence_is_idle(presence) && - !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons")) + purple_presence_is_idle(presence) && !biglist) { time_t idle_secs = purple_presence_get_idle_time(presence); if (idle_secs > 0) { + FontColorPair *pair = NULL; + const gchar *textcolor; time_t t; int ihrs, imin; time(&t); + ihrs = (t - idle_secs) / 3600; imin = ((t - idle_secs) / 60) % 60; - idle = g_strdup_printf("%d:%02d", ihrs, imin); - } - } - - if (purple_presence_is_idle(presence)) - { - if (idle && !selected) { - char *i2 = g_strdup_printf("%s", - dim_grey(), idle); - g_free(idle); - idle = i2; + + if (!selected && theme != NULL && (pair = pidgin_blist_theme_get_idle_text_info(theme)) != NULL && pair->color != NULL) + textcolor = pair->color; + else + textcolor = "black"; + + idle = g_strdup_printf("%d:%02d", textcolor, + (pair == NULL || pair->font == NULL) ? "" : pair->font, ihrs, imin); } } prpl_icon = pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_SMALL); + if (theme != NULL) + color = pidgin_blist_theme_get_contact_color(theme); + gtk_tree_store_set(gtkblist->treemodel, iter, STATUS_ICON_COLUMN, status, STATUS_ICON_VISIBLE_COLUMN, TRUE, @@ -6132,7 +6245,7 @@ EMBLEM_VISIBLE_COLUMN, (emblem != NULL), PROTOCOL_ICON_COLUMN, prpl_icon, PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"), - BGCOLOR_COLUMN, NULL, + BGCOLOR_COLUMN, color, CONTACT_EXPANDER_COLUMN, NULL, CONTACT_EXPANDER_VISIBLE_COLUMN, expanded, GROUP_EXPANDER_VISIBLE_COLUMN, FALSE, @@ -6190,19 +6303,41 @@ if(gtknode->contact_expanded) { GdkPixbuf *status; - char *mark; + gchar *mark, *tmp; + const gchar *fg_color, *font; + GdkColor *color = NULL; + PidginBlistTheme *theme = pidgin_blist_get_theme(); + FontColorPair *pair; + gboolean selected = (gtkblist->selected_node == cnode); + + mark = g_markup_escape_text(purple_contact_get_alias(contact), -1); + + theme = pidgin_blist_get_theme(); + if (theme == NULL) + pair = NULL; + else { + pair = pidgin_blist_theme_get_contact_text_info(theme); + color = pidgin_blist_theme_get_contact_color(theme); + } + + font = (pair == NULL || pair->font == NULL) ? "" : pair->font; + fg_color = (selected || pair == NULL || pair->color == NULL) ? "black" : pair->color; + + tmp = g_strdup_printf("%s", + font, fg_color, mark); + g_free(mark); + mark = tmp; status = pidgin_blist_get_status_icon(cnode, biglist? PIDGIN_STATUS_ICON_LARGE : PIDGIN_STATUS_ICON_SMALL); - mark = g_markup_escape_text(purple_contact_get_alias(contact), -1); gtk_tree_store_set(gtkblist->treemodel, &iter, STATUS_ICON_COLUMN, status, STATUS_ICON_VISIBLE_COLUMN, TRUE, NAME_COLUMN, mark, IDLE_COLUMN, NULL, IDLE_VISIBLE_COLUMN, FALSE, - BGCOLOR_COLUMN, NULL, + BGCOLOR_COLUMN, color, BUDDY_ICON_COLUMN, NULL, CONTACT_EXPANDER_COLUMN, TRUE, CONTACT_EXPANDER_VISIBLE_COLUMN, TRUE, @@ -6270,20 +6405,28 @@ if(purple_account_is_connected(chat->account)) { GtkTreeIter iter; GdkPixbuf *status, *avatar, *emblem, *prpl_icon; - char *mark; + const gchar *color, *font; + gchar *mark, *tmp; gboolean showicons = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); gboolean biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); PidginBlistNode *ui; PurpleConversation *conv; gboolean hidden; + GdkColor *bgcolor = NULL; + FontColorPair *pair; + PidginBlistTheme *theme; + gboolean selected = (gtkblist->selected_node == node); + gboolean nick_said = FALSE; if (!insert_node(list, node, &iter)) return; ui = node->ui_data; conv = ui->conv.conv; - hidden = (conv && (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE) && - pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv))); + if (conv && pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv))) { + hidden = (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE); + nick_said = (ui->conv.flags & PIDGIN_BLIST_CHAT_HAS_PENDING_MESSAGE_WITH_NICK); + } status = pidgin_blist_get_status_icon(node, biglist ? PIDGIN_STATUS_ICON_LARGE : PIDGIN_STATUS_ICON_SMALL); @@ -6296,14 +6439,36 @@ avatar = NULL; mark = g_markup_escape_text(purple_chat_get_name(chat), -1); - if (hidden) { - char *bold = g_strdup_printf("%s", mark); - g_free(mark); - mark = bold; - } + + theme = pidgin_blist_get_theme(); + + if (theme == NULL) + pair = NULL; + else if (nick_said) + pair = pidgin_blist_theme_get_unread_message_nick_said_text_info(theme); + else if (hidden) + pair = pidgin_blist_theme_get_unread_message_text_info(theme); + else pair = pidgin_blist_theme_get_online_text_info(theme); + + + font = (pair == NULL || pair->font == NULL) ? "" : pair->font; + if (selected || pair == NULL || pair->color == NULL) + /* nick_said color is the same as gtkconv:tab-label-attention */ + color = (nick_said ? "#006aff" : "black"); + else + color = pair->color; + + tmp = g_strdup_printf("%s", + font, color, hidden ? "bold" : "normal", mark); + + g_free(mark); + mark = tmp; prpl_icon = pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL); + if (theme != NULL) + bgcolor = pidgin_blist_theme_get_contact_color(theme); + gtk_tree_store_set(gtkblist->treemodel, &iter, STATUS_ICON_COLUMN, status, STATUS_ICON_VISIBLE_COLUMN, TRUE, @@ -6314,6 +6479,7 @@ PROTOCOL_ICON_COLUMN, prpl_icon, PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"), NAME_COLUMN, mark, + BGCOLOR_COLUMN, bgcolor, GROUP_EXPANDER_VISIBLE_COLUMN, FALSE, -1); @@ -6326,6 +6492,7 @@ g_object_unref(avatar); if(prpl_icon) g_object_unref(prpl_icon); + } else { pidgin_blist_hide_node(list, node, TRUE); } @@ -6983,7 +7150,7 @@ data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree()); pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Group:"), data->sg, data->group_combo, TRUE, NULL); - + data->autojoin = gtk_check_button_new_with_mnemonic(_("Auto_join when account becomes online.")); data->persistent = gtk_check_button_new_with_mnemonic(_("_Remain in chat after window is closed.")); gtk_box_pack_start(GTK_BOX(vbox), data->autojoin, FALSE, FALSE, 0); @@ -7187,6 +7354,34 @@ (GSourceFunc)buddy_signonoff_timeout_cb, buddy); } +void +pidgin_blist_set_theme(PidginBlistTheme *theme) +{ + PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); + PurpleBuddyList *list = purple_get_blist(); + + if (theme != NULL) + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/blist/theme", + purple_theme_get_name(PURPLE_THEME(theme))); + else + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/blist/theme", ""); + + priv->current_theme = theme; + + pidgin_blist_build_layout(list); + + pidgin_blist_refresh(list); +} + + +PidginBlistTheme * +pidgin_blist_get_theme() +{ + PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); + + return priv->current_theme; +} + void pidgin_blist_init(void) { void *gtk_blist_handle = pidgin_blist_get_handle(); @@ -7215,6 +7410,9 @@ /* This pref is used in pidgintooltip.c. */ purple_prefs_add_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay", 500); #endif + purple_prefs_add_string(PIDGIN_PREFS_ROOT "/blist/theme", ""); + + purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_BLIST_THEME_LOADER, "type", "blist", NULL)); /* Register our signals */ purple_signal_register(gtk_blist_handle, "gtkblist-hiding", @@ -7489,11 +7687,11 @@ } } -static void sort_method_log(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter) +static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter) { GtkTreeIter more_z; - int log_size = 0, this_log_size = 0; + int activity_score = 0, this_log_activity_score = 0; const char *buddy_name, *this_buddy_name; if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) { @@ -7503,8 +7701,11 @@ if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBlistNode *n; - for (n = node->child; n; n = n->next) - log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy*)(n))->name, ((PurpleBuddy*)(n))->account); + PurpleBuddy *buddy; + for (n = node->child; n; n = n->next) { + buddy = (PurpleBuddy*)n; + activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account); + } buddy_name = purple_contact_get_alias((PurpleContact*)node); } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) { /* we don't have a reliable way of getting the log filename @@ -7531,16 +7732,19 @@ GValue val; PurpleBlistNode *n; PurpleBlistNode *n2; + PurpleBuddy *buddy; int cmp; val.g_type = 0; gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); n = g_value_get_pointer(&val); - this_log_size = 0; + this_log_activity_score = 0; if(PURPLE_BLIST_NODE_IS_CONTACT(n)) { - for (n2 = n->child; n2; n2 = n2->next) - this_log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy*)(n2))->name, ((PurpleBuddy*)(n2))->account); + for (n2 = n->child; n2; n2 = n2->next) { + buddy = (PurpleBuddy*)n2; + this_log_activity_score += purple_log_get_activity_score(PURPLE_LOG_IM, buddy->name, buddy->account); + } this_buddy_name = purple_contact_get_alias((PurpleContact*)n); } else { this_buddy_name = NULL; @@ -7548,8 +7752,8 @@ cmp = purple_utf8_strcasecmp(buddy_name, this_buddy_name); - if (!PURPLE_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size || - ((log_size == this_log_size) && + if (!PURPLE_BLIST_NODE_IS_CONTACT(n) || activity_score > this_log_activity_score || + ((activity_score == this_log_activity_score) && (cmp < 0 || (cmp == 0 && node < n)))) { if (cur != NULL) { gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkblist.h --- a/pidgin/gtkblist.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkblist.h Wed Jan 28 10:23:37 2009 +0000 @@ -59,6 +59,7 @@ #include "pidgin.h" #include "blist.h" +#include "gtkblist-theme.h" /************************************************************************** * @name Structures @@ -250,6 +251,23 @@ */ void pidgin_blist_add_alert(GtkWidget *widget); +/** + * Sets the current theme for Pidgin to use + * + * @param theme the new theme to use + * + * @since 2.6.0 + */ +void pidgin_blist_set_theme(PidginBlistTheme *theme); + +/** + * Gets Pidgin's current buddy list theme + * + * @returns the current theme + * + * @since 2.6.0 + */ +PidginBlistTheme *pidgin_blist_get_theme(void); /************************************************************************** * @name GTK+ Buddy List sorting functions @@ -381,7 +399,7 @@ * * @param buddy The buddy to return markup from * @param selected Whether this buddy is selected. If TRUE, the markup will not change the color. - * @param aliased TRUE to return the appropriate alias of this buddy, FALSE to return its screenname and status information + * @param aliased TRUE to return the appropriate alias of this buddy, FALSE to return its username and status information * @return The markup for this buddy * * @since 2.1.0 diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkcellrendererexpander.c --- a/pidgin/gtkcellrendererexpander.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkcellrendererexpander.c Wed Jan 28 10:23:37 2009 +0000 @@ -18,14 +18,14 @@ * 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 * */ -/* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by +/* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by * Jonathon Blandford for RedHat, Inc. */ @@ -74,14 +74,14 @@ PROP_0, PROP_IS_EXPANDER }; - + static gpointer parent_class; /* static guint expander_cell_renderer_signals [LAST_SIGNAL]; */ GType pidgin_cell_renderer_expander_get_type (void) { static GType cell_expander_type = 0; - + if (!cell_expander_type) { static const GTypeInfo cell_expander_info = @@ -97,13 +97,13 @@ (GInstanceInitFunc) pidgin_cell_renderer_expander_init, NULL /* value_table */ }; - + cell_expander_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "PidginCellRendererExpander", &cell_expander_info, 0); } - + return cell_expander_type; } @@ -118,17 +118,17 @@ { GObjectClass *object_class = G_OBJECT_CLASS(class); GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class); - + parent_class = g_type_class_peek_parent (class); object_class->finalize = pidgin_cell_renderer_expander_finalize; object_class->get_property = pidgin_cell_renderer_expander_get_property; object_class->set_property = pidgin_cell_renderer_expander_set_property; - + cell_class->get_size = pidgin_cell_renderer_expander_get_size; cell_class->render = pidgin_cell_renderer_expander_render; cell_class->activate = pidgin_cell_renderer_expander_activate; - + g_object_class_install_property (object_class, PROP_IS_EXPANDER, g_param_spec_boolean ("expander-visible", @@ -162,7 +162,7 @@ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, psec); break; - + } } @@ -199,19 +199,19 @@ { gint calc_width; gint calc_height; - gint expander_size; - + gint expander_size; + gtk_widget_style_get(widget, "expander-size", &expander_size, NULL); - + calc_width = (gint) cell->xpad * 2 + expander_size; calc_height = (gint) cell->ypad * 2 + expander_size; - + if (width) *width = calc_width; - + if (height) *height = calc_height; - + if (cell_area) { if (x_offset) @@ -228,7 +228,7 @@ } -static void pidgin_cell_renderer_expander_render (GtkCellRenderer *cell, +static void pidgin_cell_renderer_expander_render(GtkCellRenderer *cell, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, @@ -237,7 +237,7 @@ guint flags) { PidginCellRendererExpander *cellexpander = (PidginCellRendererExpander *) cell; - + gboolean set; gint width, height; GtkStateType state; @@ -246,7 +246,7 @@ width = cell_area->width; height = cell_area->height; - + #if GTK_CHECK_VERSION(2,6,0) if (!cell->sensitive) state = GTK_STATE_INSENSITIVE; @@ -270,8 +270,11 @@ cell_area->x + cell->xpad + (width / 2), cell_area->y + cell->ypad + (height / 2), cell->is_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED); - if (cell->is_expanded) - gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0, + + /* only draw the line if the color isn't set - this prevents a bug where the hline appears only under the expander */ + g_object_get(cellexpander, "cell-background-set", &set, NULL); + if (cell->is_expanded && !set) + gtk_paint_hline (widget->style, window, state, NULL, widget, NULL, 0, widget->allocation.width, cell_area->y + cell_area->height); } diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkcellrendererexpander.h --- a/pidgin/gtkcellrendererexpander.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkcellrendererexpander.h Wed Jan 28 10:23:37 2009 +0000 @@ -12,7 +12,7 @@ * 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 diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkcellrendererprogress.c --- a/pidgin/gtkcellrendererprogress.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkcellrendererprogress.c Wed Jan 28 10:23:37 2009 +0000 @@ -18,14 +18,14 @@ * 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 * */ -/* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by +/* This is taken largely from GtkCellRenderer[Text|Pixbuf|Toggle] by * Jonathon Blandford for RedHat, Inc. */ @@ -76,14 +76,14 @@ PROP_TEXT, PROP_SHOW_TEXT }; - + static gpointer parent_class; /* static guint progress_cell_renderer_signals [LAST_SIGNAL]; */ GType pidgin_cell_renderer_progress_get_type (void) { static GType cell_progress_type = 0; - + if (!cell_progress_type) { static const GTypeInfo cell_progress_info = @@ -99,13 +99,13 @@ (GInstanceInitFunc) pidgin_cell_renderer_progress_init, NULL /* value_table */ }; - + cell_progress_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "PidginCellRendererProgress", &cell_progress_info, 0); } - + return cell_progress_type; } @@ -120,16 +120,16 @@ { GObjectClass *object_class = G_OBJECT_CLASS(class); GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class); - + parent_class = g_type_class_peek_parent (class); object_class->finalize = pidgin_cell_renderer_progress_finalize; object_class->get_property = pidgin_cell_renderer_progress_get_property; object_class->set_property = pidgin_cell_renderer_progress_set_property; - + cell_class->get_size = pidgin_cell_renderer_progress_get_size; cell_class->render = pidgin_cell_renderer_progress_render; - + g_object_class_install_property (object_class, PROP_PERCENTAGE, g_param_spec_double ("percentage", @@ -228,16 +228,16 @@ { gint calc_width; gint calc_height; - + calc_width = (gint) cell->xpad * 2 + 50; calc_height = (gint) cell->ypad * 2 + 12; - + if (width) *width = calc_width; - + if (height) *height = calc_height; - + if (cell_area) { if (x_offset) @@ -263,13 +263,13 @@ guint flags) { PidginCellRendererProgress *cellprogress = (PidginCellRendererProgress *) cell; - + gint width, height; GtkStateType state; width = cell_area->width; height = cell_area->height; - + if (GTK_WIDGET_HAS_FOCUS (widget)) state = GTK_STATE_ACTIVE; else @@ -280,7 +280,7 @@ gtk_paint_box (widget->style, window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, + GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, "trough", cell_area->x + cell->xpad, cell_area->y + cell->ypad, diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkcellrendererprogress.h --- a/pidgin/gtkcellrendererprogress.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkcellrendererprogress.h Wed Jan 28 10:23:37 2009 +0000 @@ -12,7 +12,7 @@ * 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 diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkcellview.c --- a/pidgin/gtkcellview.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkcellview.c Wed Jan 28 10:23:37 2009 +0000 @@ -463,14 +463,14 @@ area = widget->allocation; /* we draw on our very own window, initialize x and y to zero */ - area.x = widget->allocation.x + (rtl ? widget->allocation.width : 0); + area.x = widget->allocation.x + (rtl ? widget->allocation.width : 0); area.y = widget->allocation.y; if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) state = GTK_CELL_RENDERER_PRELIT; else state = 0; - + /* PACK_START */ for (i = cellview->priv->cell_list; i; i = i->next) { @@ -483,7 +483,7 @@ continue; area.width = info->real_width; - if (rtl) + if (rtl) area.x -= area.width; gtk_cell_renderer_render (info->cell, @@ -492,11 +492,11 @@ /* FIXME! */ &area, &area, &event->area, state); - if (!rtl) + if (!rtl) area.x += info->real_width; } - area.x = rtl ? widget->allocation.x : (widget->allocation.x + widget->allocation.width); + area.x = rtl ? widget->allocation.x : (widget->allocation.x + widget->allocation.width); /* PACK_END */ for (i = cellview->priv->cell_list; i; i = i->next) @@ -511,7 +511,7 @@ area.width = info->real_width; if (!rtl) - area.x -= area.width; + area.x -= area.width; gtk_cell_renderer_render (info->cell, widget->window, @@ -550,7 +550,7 @@ GtkTreePath *path; g_return_if_fail (cellview->priv->displayed_row != NULL); - + path = gtk_tree_row_reference_get_path (cellview->priv->displayed_row); gtk_tree_model_get_iter (cellview->priv->model, &iter, path); gtk_tree_path_free (path); @@ -666,7 +666,7 @@ gtk_cell_view_cell_layout_clear_attributes (layout, info->cell); g_object_unref (G_OBJECT (info->cell)); g_free (info); - cellview->priv->cell_list = g_list_delete_link (cellview->priv->cell_list, + cellview->priv->cell_list = g_list_delete_link (cellview->priv->cell_list, cellview->priv->cell_list); } } @@ -719,7 +719,7 @@ g_free (list->data); list = list->next->next; } - + g_slist_free (info->attributes); info->attributes = NULL; } @@ -905,7 +905,7 @@ * gtk_cell_view_set_displayed_row: * @cell_view: a #GtkCellView * @path: a #GtkTreePath or %NULL to unset. - * + * * Sets the row of the model that is currently displayed * by the #GtkCellView. If the path is unset, then the * contents of the cellview "stick" at their last value; diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkconv.c Wed Jan 28 10:23:37 2009 +0000 @@ -201,11 +201,11 @@ switch (purple_conversation_get_type(conv)) { case PURPLE_CONV_TYPE_IM: - node = (PurpleBlistNode*)purple_find_buddy(conv->account, conv->name); + node = PURPLE_BLIST_NODE(purple_find_buddy(conv->account, conv->name)); node = node ? node->parent : NULL; break; case PURPLE_CONV_TYPE_CHAT: - node = (PurpleBlistNode*)purple_blist_find_chat(conv->account, conv->name); + node = PURPLE_BLIST_NODE(purple_blist_find_chat(conv->account, conv->name)); break; default: break; @@ -1395,7 +1395,7 @@ if (logging == purple_conversation_is_logging(conv)) return; - + node = get_conversation_blist_node(conv); if (logging) @@ -1835,7 +1835,7 @@ gtk_tree_selection_select_path(GTK_TREE_SELECTION( gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list))), path); gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkchat->list), - path, NULL, FALSE); + path, NULL, FALSE); gtk_widget_grab_focus(GTK_WIDGET(gtkchat->list)); gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); @@ -1867,7 +1867,7 @@ GtkTreeIter iter; GtkTreeModel *model; gchar *who; - + model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); @@ -2058,7 +2058,7 @@ gtkconv = (PidginConversation *)data; conv = gtkconv->active_conv; win = gtkconv->win; - + if (conv_keypress_common(gtkconv, event)) return TRUE; @@ -2516,7 +2516,7 @@ if (ops && ops->update) ops->update(NULL, (PurpleBlistNode*)b); - /* XXX Seanegan: We really need a util function to return a pixbuf for a Presence to avoid all this switching */ + /* XXX Seanegan: We really need a util function to return a pixbuf for a Presence to avoid all this switching */ if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) status = pidgin_create_status_icon(PURPLE_STATUS_AWAY, parent, icon_size); else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) @@ -2542,7 +2542,7 @@ status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_CHAT, size, "GtkWidget"); } - } + } return status; } @@ -2585,11 +2585,11 @@ gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status); gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status); - gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), + gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), &(gtkconv->infopane_iter), CONV_ICON_COLUMN, infopane_status, -1); - gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), + gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), &(gtkconv->infopane_iter), CONV_EMBLEM_COLUMN, emblem, -1); if (emblem) @@ -3850,7 +3850,7 @@ { PurpleBlistNode *node; - node = (PurpleBlistNode *) purple_buddy_get_contact((PurpleBuddy *)l->data); + node = PURPLE_BLIST_NODE(purple_buddy_get_contact(PURPLE_BUDDY(l->data))); for (node = node->child; node != NULL; node = node->next) { @@ -4799,7 +4799,7 @@ gtkconv->infopane = gtk_cell_view_new(); gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); - gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), + gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), GTK_TREE_MODEL(gtkconv->infopane_model)); g_object_unref(gtkconv->infopane_model); gtk_list_store_append(gtkconv->infopane_model, &(gtkconv->infopane_iter)); @@ -5033,9 +5033,9 @@ static PidginConversation * pidgin_conv_find_gtkconv(PurpleConversation * conv) { - PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name), *b; + PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name); PurpleContact *c; - PurpleBlistNode *cn; + PurpleBlistNode *cn, *bn; if (!bud) return NULL; @@ -5043,8 +5043,9 @@ if (!(c = purple_buddy_get_contact(bud))) return NULL; - cn = (PurpleBlistNode *)c; - for (b = (PurpleBuddy *)cn->child; b; b = (PurpleBuddy *) ((PurpleBlistNode *)b)->next) { + cn = PURPLE_BLIST_NODE(c); + for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) { + PurpleBuddy *b = PURPLE_BUDDY(bn); PurpleConversation *conv; if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) { if (conv->ui_data) @@ -5494,7 +5495,7 @@ gtkconv->newday = mktime(tm); } -/* Detect string direction and encapsulate the string in RLE/LRE/PDF unicode characters +/* Detect string direction and encapsulate the string in RLE/LRE/PDF unicode characters str - pointer to string (string is re-allocated and the pointer updated) */ static void str_embed_direction_chars(char **str) @@ -5531,14 +5532,14 @@ } /* Returns true if the given HTML contains RTL text */ -static gboolean +static gboolean html_is_rtl(const char *html) { GData *attributes; const gchar *start, *end; gboolean res = FALSE; - if (purple_markup_find_tag("span", html, &start, &end, &attributes)) + if (purple_markup_find_tag("span", html, &start, &end, &attributes)) { /* tmp is a member of attributes and is free with g_datalist_clear call */ const char *tmp = g_datalist_get_data(&attributes, "dir"); @@ -6462,10 +6463,10 @@ PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name); window_icon = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); - + if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) gdk_pixbuf_saturate_and_pixelate(window_icon, window_icon, 0.0, FALSE); - + g_object_ref(window_icon); l = g_list_append(l, window_icon); } else { @@ -6658,7 +6659,7 @@ pango_attr_list_unref(list); } else gtk_label_set_attributes(GTK_LABEL(gtkconv->tab_label), NULL); - + if (pidgin_conv_window_is_active_conversation(conv)) update_typing_icon(gtkconv); @@ -7230,7 +7231,7 @@ PurpleConversation *conv = l->data; if (!PIDGIN_CONVERSATION(conv)) continue; - if (GPOINTER_TO_INT(value)) + if (GPOINTER_TO_INT(value)) gtk_widget_show(PIDGIN_CONVERSATION(conv)->infopane_hbox); else gtk_widget_hide(PIDGIN_CONVERSATION(conv)->infopane_hbox); @@ -7640,7 +7641,7 @@ list = purple_conversation_get_message_history(conv); if (list) { switch (purple_conversation_get_type(conv)) { - case PURPLE_CONV_TYPE_IM: + case PURPLE_CONV_TYPE_IM: { GList *convs; list = g_list_copy(list); @@ -8406,7 +8407,7 @@ G_CALLBACK(notebook_leave_cb), gtkconv->win); return FALSE; } - + if (e->button == 3) { /* Right click was pressed. Popup the context menu. */ GtkWidget *menu = gtk_menu_new(), *sub; @@ -8432,7 +8433,7 @@ } return FALSE; } - + static gboolean notebook_press_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win) { @@ -9012,7 +9013,7 @@ static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) { int x, y; - + if (GTK_WIDGET_VISIBLE(w)) gtk_window_get_position(GTK_WINDOW(w), &x, &y); else @@ -9022,7 +9023,7 @@ * when the window is being maximized */ if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) return FALSE; - + /* don't save off-screen positioning */ if (x + event->width < 0 || y + event->height < 0 || @@ -9038,7 +9039,7 @@ /* continue to handle event normally */ return FALSE; - + } static void @@ -9119,7 +9120,7 @@ /* Intercept keystrokes from the menu items */ g_signal_connect(G_OBJECT(win->window), "key_press_event", G_CALLBACK(window_keypress_cb), win); - + /* Create the notebook. */ win->notebook = gtk_notebook_new(); @@ -9281,7 +9282,7 @@ win->gtkconvs = g_list_append(win->gtkconvs, gtkconv); gtkconv->win = win; - if (win->gtkconvs && win->gtkconvs->next && win->gtkconvs->next->next == NULL) + if (win->gtkconvs && win->gtkconvs->next && win->gtkconvs->next->next == NULL) pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data)); @@ -9440,11 +9441,11 @@ gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); } - gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, - !tabs_side && !angle, + gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, + !tabs_side && !angle, TRUE, GTK_PACK_START); - if (pidgin_conv_window_get_gtkconv_count(win) == 1) + if (pidgin_conv_window_get_gtkconv_count(win) == 1) gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") && (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") || @@ -9655,7 +9656,7 @@ if (win == NULL) { win = pidgin_conv_window_new(); - g_signal_connect(G_OBJECT(win->window), "configure_event", + g_signal_connect(G_OBJECT(win->window), "configure_event", G_CALLBACK(gtk_conv_configure_cb), NULL); pidgin_conv_window_add_gtkconv(win, conv); @@ -9670,7 +9671,7 @@ conv_placement_last_created_win_type_configured_cb(GtkWidget *w, GdkEventConfigure *event, PidginConversation *conv) { - int x, y; + int x, y; PurpleConversationType type = purple_conversation_get_type(conv->active_conv); GList *all; @@ -9683,7 +9684,7 @@ * when the window is being maximized */ if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) return FALSE; - + /* don't save off-screen positioning */ if (x + event->width < 0 || y + event->height < 0 || @@ -9737,11 +9738,11 @@ purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/width"), purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/height")); } - + pidgin_conv_window_add_gtkconv(win, conv); pidgin_conv_window_show(win); - g_signal_connect(G_OBJECT(win->window), "configure_event", + g_signal_connect(G_OBJECT(win->window), "configure_event", G_CALLBACK(conv_placement_last_created_win_type_configured_cb), conv); } else pidgin_conv_window_add_gtkconv(win, conv); @@ -9755,7 +9756,7 @@ win = pidgin_conv_window_new(); - g_signal_connect(G_OBJECT(win->window), "configure_event", + g_signal_connect(G_OBJECT(win->window), "configure_event", G_CALLBACK(gtk_conv_configure_cb), NULL); pidgin_conv_window_add_gtkconv(win, conv); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkdebug.c --- a/pidgin/gtkdebug.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkdebug.c Wed Jan 28 10:23:37 2009 +0000 @@ -769,7 +769,7 @@ win->filter = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, - NULL, _("Filter"), _("Filter"), + NULL, _("Filter"), _("Filter"), NULL, NULL, G_CALLBACK(regex_filter_toggled_cb), win); @@ -821,7 +821,7 @@ GTK_TOOLBAR_CHILD_WIDGET, gtk_label_new(_("Level ")), NULL, _("Select the debug filter level."), NULL, NULL, NULL, NULL); - + win->filterlevel = gtk_combo_box_new_text(); gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_CHILD_WIDGET, win->filterlevel, diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkdialogs.c Wed Jan 28 10:23:37 2009 +0000 @@ -349,7 +349,7 @@ } #if 0 -/* This function puts the version number onto the pixmap we use in the 'about' +/* This function puts the version number onto the pixmap we use in the 'about' * screen in Pidgin. */ static void pidgin_logo_versionize(GdkPixbuf **original, GtkWidget *widget) { @@ -487,7 +487,7 @@ _("Retired Crazy Patch Writers")); add_developers(str, retired_patch_writers); g_string_append(str, "
"); - + /* Current Translators */ g_string_append_printf(str, "%s:
", _("Current Translators")); @@ -1061,8 +1061,8 @@ g_return_if_fail(contact != NULL); g_return_if_fail(buddy != NULL); - if (((PurpleBlistNode*)contact)->child == (PurpleBlistNode*)buddy && - !((PurpleBlistNode*)buddy)->next) { + if (PURPLE_BLIST_NODE(contact)->child == PURPLE_BLIST_NODE(buddy) && + PURPLE_BLIST_NODE(buddy)->next == NULL) { pidgin_dialogs_remove_buddy(buddy); } else { gchar *text; @@ -1116,7 +1116,7 @@ ggp = g_new(struct _PidginGroupMergeObject, 1); ggp->parent = source; ggp->new_name = g_strdup(new_name); - + purple_request_action(source, NULL, _("Merge Groups"), text, 0, NULL, NULL, NULL, ggp, 2, diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkdnd-hints.c --- a/pidgin/gtkdnd-hints.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkdnd-hints.c Wed Jan 28 10:23:37 2009 +0000 @@ -46,7 +46,7 @@ /** * Info about each hint widget. See DndHintWindowId enum. */ -static HintWindowInfo hint_windows[] = { +static HintWindowInfo hint_windows[] = { { NULL, "arrow-up.xpm", -13/2, 0 }, { NULL, "arrow-down.xpm", -13/2, -16 }, { NULL, "arrow-left.xpm", 0, -13/2 }, @@ -139,7 +139,7 @@ dnd_hints_hide(i); } -void +void dnd_hints_hide(DndHintWindowId i) { GtkWidget *w = hint_windows[i].widget; @@ -148,7 +148,7 @@ gtk_widget_hide(w); } -void +void dnd_hints_show(DndHintWindowId id, gint x, gint y) { GtkWidget *w; @@ -165,7 +165,7 @@ } } -void +void dnd_hints_show_relative(DndHintWindowId id, GtkWidget *widget, DndHintPosition horiz, DndHintPosition vert) { diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkdocklet-x11.c --- a/pidgin/gtkdocklet-x11.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkdocklet-x11.c Wed Jan 28 10:23:37 2009 +0000 @@ -5,7 +5,7 @@ * Copyright (C) 2003 Herman Bloggs * Inspired by a similar plugin by: * John (J5) Palmieri - * + * * 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 @@ -15,7 +15,7 @@ * 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 @@ -59,7 +59,7 @@ docklet_x11_embedded_cb(GtkWidget *widget, void *data) { purple_debug(PURPLE_DEBUG_INFO, "docklet", "embedded\n"); - + g_source_remove(embed_timeout); embed_timeout = 0; pidgin_docklet_embedded(); @@ -211,9 +211,9 @@ if (embed_timeout) g_source_remove(embed_timeout); - + pidgin_docklet_remove(); - + g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_x11_destroyed_cb), NULL); gtk_widget_destroy(GTK_WIDGET(docklet)); @@ -239,7 +239,7 @@ */ purple_debug_info("docklet", "failed to embed within timeout\n"); pidgin_docklet_remove(); - + return FALSE; } diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkdocklet.h --- a/pidgin/gtkdocklet.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkdocklet.h Wed Jan 28 10:23:37 2009 +0000 @@ -1,11 +1,11 @@ -/* +/* * System tray icon (aka docklet) plugin for Purple - * + * * Copyright (C) 2002-3 Robert McQueen * Copyright (C) 2003 Herman Bloggs * Inspired by a similar plugin by: * John (J5) Palmieri - * + * * 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 @@ -15,7 +15,7 @@ * 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 diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkexpander.c --- a/pidgin/gtkexpander.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkexpander.c Wed Jan 28 10:23:37 2009 +0000 @@ -63,7 +63,7 @@ guint expanded : 1; guint use_underline : 1; - guint use_markup : 1; + guint use_markup : 1; guint button_down : 1; guint prelight : 1; }; @@ -129,7 +129,7 @@ gtk_expander_get_type (void) { static GType expander_type = 0; - + if (!expander_type) { static const GTypeInfo expander_info = @@ -144,12 +144,12 @@ 0, /* n_preallocs */ (GInstanceInitFunc) gtk_expander_init, }; - + expander_type = g_type_register_static (GTK_TYPE_BIN, "GtkExpander", &expander_info, 0); } - + return expander_type; } @@ -314,7 +314,7 @@ GParamSpec *pspec) { GtkExpander *expander = GTK_EXPANDER (object); - + switch (prop_id) { case PROP_EXPANDED: @@ -382,7 +382,7 @@ gtk_expander_destroy (GtkObject *object) { GtkExpanderPrivate *priv = GTK_EXPANDER (object)->priv; - + if (priv->animation_timeout) { g_source_remove (priv->animation_timeout); @@ -407,7 +407,7 @@ border_width = GTK_CONTAINER (widget)->border_width; get_expander_bounds (GTK_EXPANDER (widget), &expander_rect); - + attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x + border_width; attributes.y = expander_rect.y; @@ -831,7 +831,7 @@ NULL); ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; - + x = widget->allocation.x + border_width; y = widget->allocation.y + border_width; @@ -853,7 +853,7 @@ width += expander_size + 2 * expander_spacing; height = MAX (height, expander_size + 2 * expander_spacing); } - + width += 2 * focus_pad + 2 * focus_width; height += 2 * focus_pad + 2 * focus_width; @@ -1115,16 +1115,16 @@ GtkDirectionType direction) { GtkExpander *expander = GTK_EXPANDER (widget); - + if (!focus_current_site (expander, direction)) { GtkWidget *old_focus_child; gboolean widget_is_focus; FocusSite site = FOCUS_NONE; - + widget_is_focus = gtk_widget_is_focus (widget); old_focus_child = GTK_CONTAINER (widget)->focus_child; - + if (old_focus_child && old_focus_child == expander->priv->label_widget) site = FOCUS_LABEL; else if (old_focus_child) @@ -1192,9 +1192,9 @@ /** * gtk_expander_new: * @label: the text of the label - * + * * Creates a new expander using @label as the text of the label. - * + * * Return value: a new #GtkExpander widget. * * Since: 2.4 @@ -1209,14 +1209,14 @@ * gtk_expander_new_with_mnemonic: * @label: the text of the label with an underscore in front of the * mnemonic character - * + * * Creates a new expander using @label as the text of the label. * If characters in @label are preceded by an underscore, they are underlined. - * If you need a literal underscore character in a label, use '__' (two - * underscores). The first underlined character represents a keyboard + * If you need a literal underscore character in a label, use '__' (two + * underscores). The first underlined character represents a keyboard * accelerator called a mnemonic. * Pressing Alt and that key activates the button. - * + * * Return value: a new #GtkExpander widget. * * Since: 2.4 @@ -1328,7 +1328,7 @@ { gtk_expander_start_animation (expander); } - else + else { priv->expander_style = expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED; @@ -1643,7 +1643,7 @@ * gtk_expander_set_label_widget(). * * Return value: the label widget, or %NULL if there is none. - * + * * Since: 2.4 **/ GtkWidget * diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkicon-theme-loader.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkicon-theme-loader.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,111 @@ +/* + * PidginIconThemeLoader for Pidgin + * + * Pidgin 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 "gtkicon-theme-loader.h" +#include "gtkstatus-icon-theme.h" + +#include "xmlnode.h" + +/***************************************************************************** + * Icon Theme Builder + *****************************************************************************/ + +static PurpleTheme * +pidgin_icon_loader_build(const gchar *dir) +{ + xmlnode *root_node = NULL, *sub_node; + gchar *filename_full, *data; + PidginIconTheme *theme = NULL; + + /* Find the theme file */ + g_return_val_if_fail(dir != NULL, NULL); + filename_full = g_build_filename(dir, "theme.xml", NULL); + + if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR)) + root_node = xmlnode_from_file(dir, "theme.xml", "sound themes", "sound-theme-loader"); + + g_free(filename_full); + g_return_val_if_fail(root_node != NULL, NULL); + + /* Parse the tree */ + sub_node = xmlnode_get_child(root_node, "description"); + data = xmlnode_get_data(sub_node); + + if (xmlnode_get_attrib(root_node, "name") != NULL) { + theme = g_object_new(PIDGIN_TYPE_STATUS_ICON_THEME, + "type", "status-icon", + "name", xmlnode_get_attrib(root_node, "name"), + "author", xmlnode_get_attrib(root_node, "author"), + "image", xmlnode_get_attrib(root_node, "image"), + "directory", dir, + "description", data, NULL); + + sub_node = xmlnode_get_child(root_node, "icon"); + + while (sub_node) { + pidgin_icon_theme_set_icon(theme, + xmlnode_get_attrib(sub_node, "id"), + xmlnode_get_attrib(sub_node, "file")); + sub_node = xmlnode_get_next_twin(sub_node); + } + } + + xmlnode_free(root_node); + g_free(data); + return PURPLE_THEME(theme); +} + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +pidgin_icon_theme_loader_class_init (PidginIconThemeLoaderClass *klass) +{ + PurpleThemeLoaderClass *loader_klass = PURPLE_THEME_LOADER_CLASS(klass); + + loader_klass->purple_theme_loader_build = pidgin_icon_loader_build; +} + + +GType +pidgin_icon_theme_loader_get_type (void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PidginIconThemeLoaderClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)pidgin_icon_theme_loader_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PidginIconThemeLoader), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static (PURPLE_TYPE_THEME_LOADER, + "PidginIconThemeLoader", &info, 0); + } + return type; +} diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkicon-theme-loader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkicon-theme-loader.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,71 @@ +/** + * @file gtkicon-loader.h Pidgin Icon Theme Loader Class API + */ + +/* 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 + */ + +#ifndef PIDGIN_ICON_THEME_LOADER_H +#define PIDGIN_ICON_THEME_LOADER_H + +#include +#include +#include "theme-loader.h" + +/** + * A pidgin icon theme loader. Extends PurpleThemeLoader (theme-loader.h) + * This is a class designed to build icon themes + * + * PidginIconThemeLoader is a GObject. + */ +typedef struct _PidginIconThemeLoader PidginIconThemeLoader; +typedef struct _PidginIconThemeLoaderClass PidginIconThemeLoaderClass; + +#define PIDGIN_TYPE_ICON_THEME_LOADER (pidgin_icon_theme_loader_get_type ()) +#define PIDGIN_ICON_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_ICON_THEME_LOADER, PidginIconThemeLoader)) +#define PIDGIN_ICON_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_ICON_THEME_LOADER, PidginIconThemeLoaderClass)) +#define PIDGIN_IS_ICON_THEME_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_ICON_THEME_LOADER)) +#define PIDGIN_IS_ICON_THEME_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_ICON_THEME_LOADER)) +#define PIDGIN_ICON_THEME_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_ICON_THEME_LOADER, PidginIconThemeLoaderClass)) + +struct _PidginIconThemeLoader +{ + PurpleThemeLoader parent; +}; + +struct _PidginIconThemeLoaderClass +{ + PurpleThemeLoaderClass parent_class; +}; + +/**************************************************************************/ +/** @name Pidgin Icon Theme-Loader API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType pidgin_icon_theme_loader_get_type(void); + +G_END_DECLS +#endif /* PIDGIN_ICON_THEME_LOADER_H */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkicon-theme.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkicon-theme.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,142 @@ +/* + * Icon Themes for Pidgin + * + * Pidgin 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 "gtkicon-theme.h" +#include "pidginstock.h" + +#include + +#define PIDGIN_ICON_THEME_GET_PRIVATE(Gobject) \ + ((PidginIconThemePrivate *) ((PIDGIN_ICON_THEME(Gobject))->priv)) + +/****************************************************************************** + * Structs + *****************************************************************************/ + +typedef struct { + /* used to store filenames of diffrent icons */ + GHashTable *icon_files; +} PidginIconThemePrivate; + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GObjectClass *parent_class = NULL; + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +pidgin_icon_theme_init(GTypeInstance *instance, + gpointer klass) +{ + PidginIconThemePrivate *priv; + + (PIDGIN_ICON_THEME(instance))->priv = g_new0(PidginIconThemePrivate, 1); + + priv = PIDGIN_ICON_THEME_GET_PRIVATE(instance); + + priv->icon_files = g_hash_table_new_full(g_str_hash, + g_str_equal, g_free, g_free); +} + +static void +pidgin_icon_theme_finalize(GObject *obj) +{ + PidginIconThemePrivate *priv; + + priv = PIDGIN_ICON_THEME_GET_PRIVATE(obj); + + g_hash_table_destroy(priv->icon_files); + g_free(priv); + + parent_class->finalize(obj); +} + +static void +pidgin_icon_theme_class_init(PidginIconThemeClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = g_type_class_peek_parent(klass); + + obj_class->finalize = pidgin_icon_theme_finalize; +} + +GType +pidgin_icon_theme_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof(PidginIconThemeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)pidgin_icon_theme_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(PidginIconTheme), + 0, /* n_preallocs */ + pidgin_icon_theme_init, /* instance_init */ + NULL, /* value table */ + }; + type = g_type_register_static(PURPLE_TYPE_THEME, + "PidginIconTheme", &info, G_TYPE_FLAG_ABSTRACT); + } + return type; +} + +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +const gchar * +pidgin_icon_theme_get_icon(PidginIconTheme *theme, + const gchar *id) +{ + PidginIconThemePrivate *priv; + + g_return_val_if_fail(PIDGIN_IS_ICON_THEME(theme), NULL); + + priv = PIDGIN_ICON_THEME_GET_PRIVATE(theme); + + return g_hash_table_lookup(priv->icon_files, id); +} + +void +pidgin_icon_theme_set_icon(PidginIconTheme *theme, + const gchar *id, + const gchar *filename) +{ + PidginIconThemePrivate *priv; + g_return_if_fail(PIDGIN_IS_ICON_THEME(theme)); + + priv = PIDGIN_ICON_THEME_GET_PRIVATE(theme); + + if (filename != NULL) + g_hash_table_replace(priv->icon_files, + g_strdup(id), g_strdup(filename)); + else + g_hash_table_remove(priv->icon_files, id); +} diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkicon-theme.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkicon-theme.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,93 @@ +/** + * @file icon-theme.h Pidgin Icon Theme Class API + */ + +/* pidgin + * + * Pidgin 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 + */ + +#ifndef PIDGIN_ICON_THEME_H +#define PIDGIN_ICON_THEME_H + +#include +#include +#include "theme.h" + +/** + * extends PurpleTheme (theme.h) + * A pidgin icon theme. + * This object represents a Pidgin icon theme. + * + * PidginIconTheme is a PurpleTheme Object. + */ +typedef struct _PidginIconTheme PidginIconTheme; +typedef struct _PidginIconThemeClass PidginIconThemeClass; + +#define PIDGIN_TYPE_ICON_THEME (pidgin_icon_theme_get_type ()) +#define PIDGIN_ICON_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_ICON_THEME, PidginIconTheme)) +#define PIDGIN_ICON_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_ICON_THEME, PidginIconThemeClass)) +#define PIDGIN_IS_ICON_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_ICON_THEME)) +#define PIDGIN_IS_ICON_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_ICON_THEME)) +#define PIDGIN_ICON_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_ICON_THEME, PidginIconThemeClass)) + +struct _PidginIconTheme +{ + PurpleTheme parent; + gpointer priv; +}; + +struct _PidginIconThemeClass +{ + PurpleThemeClass parent_class; +}; + +/**************************************************************************/ +/** @name Pidgin Icon Theme API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType pidgin_icon_theme_get_type(void); + +/** + * Returns a copy of the filename for the icon event or NULL if it is not set + * + * @param event the pidgin icon event to look up + * + * @returns the filename of the icon event + */ +const gchar *pidgin_icon_theme_get_icon(PidginIconTheme *theme, + const gchar *event); + +/** + * Sets the filename for a given icon id, setting the icon to NULL will remove the icon from the theme + * + * @param icon_id a string representing what the icon is to be used for + * @param filename the name of the file to be used for the given id + */ +void pidgin_icon_theme_set_icon(PidginIconTheme *theme, + const gchar *icon_id, + const gchar *filename); + +G_END_DECLS +#endif /* PIDGIN_ICON_THEME_H */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkimhtml.c Wed Jan 28 10:23:37 2009 +0000 @@ -88,6 +88,22 @@ GtkTextMark *mark; }; +struct _GtkIMHtmlLink +{ + GtkIMHtml *imhtml; + gchar *url; + GtkTextTag *tag; +}; + +typedef struct _GtkIMHtmlProtocol +{ + char *name; + int length; + + gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link); + gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu); +} GtkIMHtmlProtocol; + static gboolean gtk_text_view_drag_motion (GtkWidget *widget, GdkDragContext *context, @@ -115,6 +131,9 @@ static void imhtml_font_grow(GtkIMHtml *imhtml); static void imhtml_font_shrink(GtkIMHtml *imhtml); static void imhtml_clear_formatting(GtkIMHtml *imhtml); +static int gtk_imhtml_is_protocol(const char *text); +static void gtk_imhtml_activate_tag(GtkIMHtml *imhtml, GtkTextTag *tag); +static void gtk_imhtml_link_destroy(GtkIMHtmlLink *link); /* POINT_SIZE converts from AIM font sizes to a point size scale factor. */ #define MAX_FONT_SIZE 7 @@ -349,7 +368,7 @@ g_string_free (t->values, TRUE); g_free (t->children); } - + g_free (t); } } @@ -819,7 +838,7 @@ &tag_area.x, &tag_area.y); - + rect.height = tag_area.y + tag_area.height - rect.y + gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(widget)) + gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)); @@ -1106,8 +1125,8 @@ GtkTextIter iter; GtkIMHtmlOptions flags = plaintext ? GTK_IMHTML_NO_SMILEY : (GTK_IMHTML_NO_NEWLINE | GTK_IMHTML_NO_COMMENTS); - if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) - gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); + /* Delete any currently selected text */ + gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, gtk_text_buffer_get_insert(imhtml->text_buffer)); if (!imhtml->wbfo && !plaintext) @@ -1391,6 +1410,38 @@ } +static GtkIMHtmlProtocol * +imhtml_find_protocol(const char *url, gboolean reverse) +{ + GtkIMHtmlClass *klass; + GList *iter; + GtkIMHtmlProtocol *proto = NULL; + int length = reverse ? strlen(url) : -1; + + klass = g_type_class_ref(GTK_TYPE_IMHTML); + for (iter = klass->protocols; iter; iter = iter->next) { + proto = iter->data; + if (g_ascii_strncasecmp(url, proto->name, reverse ? MIN(length, proto->length) : proto->length) == 0) { + return proto; + } + } + return NULL; +} + +static void +imhtml_url_clicked(GtkIMHtml *imhtml, const char *url) +{ + GtkIMHtmlProtocol *proto = imhtml_find_protocol(url, FALSE); + GtkIMHtmlLink *link; + if (!proto) + return; + link = g_new0(GtkIMHtmlLink, 1); + link->imhtml = g_object_ref(imhtml); + link->url = g_strdup(url); + proto->activate(imhtml, link); /* XXX: Do something with the return value? */ + gtk_imhtml_link_destroy(link); +} + /* Boring GTK+ stuff */ static void gtk_imhtml_class_init (GtkIMHtmlClass *klass) { @@ -1475,6 +1526,7 @@ klass->toggle_format = imhtml_toggle_format; klass->message_send = imhtml_message_send; klass->clear_format = imhtml_clear_formatting; + klass->url_clicked = imhtml_url_clicked; klass->undo = gtk_imhtml_undo; klass->redo = gtk_imhtml_redo; @@ -1688,37 +1740,14 @@ return imhtml_type; } -struct url_data { - GObject *object; - gchar *url; - GtkTextTag *tag; -}; - -static void url_data_destroy(gpointer mydata) -{ - struct url_data *data = mydata; - g_object_unref(data->object); - g_object_unref(data->tag); - g_free(data->url); - g_free(data); -} - -static void url_open(GtkWidget *w, struct url_data *data) -{ - if(!data) return; - g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); - g_object_set_data(G_OBJECT(data->tag), "visited", GINT_TO_POINTER(TRUE)); - gtk_imhtml_set_link_color(GTK_IMHTML(data->object), data->tag); -} - -static void url_copy(GtkWidget *w, gchar *url) { - GtkClipboard *clipboard; - - clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text(clipboard, url, -1); - - clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text(clipboard, url, -1); +static void gtk_imhtml_link_destroy(GtkIMHtmlLink *link) +{ + if (link->imhtml) + g_object_unref(link->imhtml); + if (link->tag) + g_object_unref(link->tag); + g_free(link->url); + g_free(link); } /* The callback for an event on a link tag. */ @@ -1734,21 +1763,16 @@ if (gtk_text_buffer_get_selection_bounds( gtk_text_iter_get_buffer(arg2), &start, &end)) return FALSE; - - /* A link was clicked--we emit the "url_clicked" signal - * with the URL as the argument */ - g_object_ref(G_OBJECT(tag)); - g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url")); - g_object_unref(G_OBJECT(tag)); - g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE)); - gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag); + gtk_imhtml_activate_tag(GTK_IMHTML(imhtml), tag); return FALSE; } else if(event_button->button == 3) { - GtkWidget *img, *item, *menu; - struct url_data *tempdata = g_new(struct url_data, 1); - tempdata->object = g_object_ref(imhtml); - tempdata->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url")); - tempdata->tag = g_object_ref(tag); + GList *children; + GtkWidget *menu; + GtkIMHtmlProtocol *proto; + GtkIMHtmlLink *link = g_new(GtkIMHtmlLink, 1); + link->imhtml = g_object_ref(imhtml); + link->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url")); + link->tag = g_object_ref(tag); /* Don't want the tooltip around if user right-clicked on link */ if (GTK_IMHTML(imhtml)->tip_window) { @@ -1764,43 +1788,23 @@ else gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->arrow_cursor); menu = gtk_menu_new(); - g_object_set_data_full(G_OBJECT(menu), "x-imhtml-url-data", tempdata, url_data_destroy); - - /* buttons and such */ - - if (!strncmp(tempdata->url, "mailto:", 7)) - { - /* Copy Email Address */ - img = gtk_image_new_from_stock(GTK_STOCK_COPY, - GTK_ICON_SIZE_MENU); - item = gtk_image_menu_item_new_with_mnemonic( - _("_Copy Email Address")); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(url_copy), tempdata->url + 7); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + g_object_set_data_full(G_OBJECT(menu), "x-imhtml-url-data", link, + (GDestroyNotify)gtk_imhtml_link_destroy); + + proto = imhtml_find_protocol(link->url, FALSE); + + if (proto && proto->context_menu) { + proto->context_menu(GTK_IMHTML(link->imhtml), link, menu); } - else - { - /* Open Link in Browser */ - img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, - GTK_ICON_SIZE_MENU); - item = gtk_image_menu_item_new_with_mnemonic( - _("_Open Link in Browser")); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(url_open), tempdata); + + children = gtk_container_get_children(GTK_CONTAINER(menu)); + if (!children) { + GtkWidget *item = gtk_menu_item_new_with_label(_("No actions available")); + gtk_widget_show(item); + gtk_widget_set_sensitive(item, FALSE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - - /* Copy Link Location */ - img = gtk_image_new_from_stock(GTK_STOCK_COPY, - GTK_ICON_SIZE_MENU); - item = gtk_image_menu_item_new_with_mnemonic( - _("_Copy Link Location")); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(url_copy), tempdata->url); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } else { + g_list_free(children); } @@ -1884,10 +1888,7 @@ links = g_strsplit((char *)sd->data, "\n", 0); while((link = links[i]) != NULL){ - if(purple_str_has_prefix(link, "http://") || - purple_str_has_prefix(link, "https://") || - purple_str_has_prefix(link, "ftp://")) - { + if (gtk_imhtml_is_protocol(link)) { gchar *label; if(links[i + 1]) @@ -1896,7 +1897,7 @@ label = links[i]; gtk_imhtml_insert_link(imhtml, mark, link, label); - } else if (link=='\0') { + } else if (*link == '\0') { /* Ignore blank lines */ } else { /* Special reasons, aka images being put in via other tag, etc. */ @@ -2067,7 +2068,7 @@ { if (smiley->imhtml) { gtk_smiley_tree_remove(smiley->imhtml->default_smilies, smiley); - g_hash_table_foreach(smiley->imhtml->smiley_data, + g_hash_table_foreach(smiley->imhtml->smiley_data, gtk_imhtml_disassociate_smiley_foreach, smiley); g_signal_handlers_disconnect_matched(smiley->imhtml, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, smiley); @@ -2096,13 +2097,13 @@ g_signal_handlers_disconnect_matched(smiley->imhtml, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, smiley); } - + smiley->imhtml = imhtml; gtk_smiley_tree_insert (tree, smiley); - + /* connect destroy signal for the imhtml */ - g_signal_connect(imhtml, "destroy", G_CALLBACK(gtk_imhtml_disconnect_smiley), + g_signal_connect(imhtml, "destroy", G_CALLBACK(gtk_imhtml_disconnect_smiley), smiley); } @@ -2198,14 +2199,17 @@ return gtk_smiley_get_image(smiley); } -#define VALID_TAG(x) if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ - *tag = g_strndup (string, strlen (x)); \ - *len = strlen (x) + 1; \ +#define VALID_TAG(x) do { \ + if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ + if (tag) *tag = g_strndup (string, strlen (x)); \ + if (len) *len = strlen (x) + 1; \ return TRUE; \ } \ - (*type)++ - -#define VALID_OPT_TAG(x) if (!g_ascii_strncasecmp (string, x " ", strlen (x " "))) { \ + if (type) (*type)++; \ + } while (0) + +#define VALID_OPT_TAG(x) do { \ + if (!g_ascii_strncasecmp (string, x " ", strlen (x " "))) { \ const gchar *c = string + strlen (x " "); \ gchar e = '"'; \ gboolean quote = FALSE; \ @@ -2222,12 +2226,13 @@ c++; \ } \ if (*c) { \ - *tag = g_strndup (string, c - string); \ - *len = c - string + 1; \ + if (tag) *tag = g_strndup (string, c - string); \ + if (len) *len = c - string + 1; \ return TRUE; \ } \ } \ - (*type)++ + if (type) (*type)++; \ + } while (0) static gboolean @@ -2237,8 +2242,8 @@ gint *type) { char *close; - *type = 1; - + if (type) + *type = 1; if (!(close = strchr (string, '>'))) return FALSE; @@ -2311,15 +2316,20 @@ if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) { gchar *e = strstr (string + strlen("!--"), "-->"); if (e) { - *len = e - string + strlen ("-->"); - *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); + if (len) + *len = e - string + strlen ("-->"); + if (tag) + *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); return TRUE; } } - *type = -1; - *len = close - string + 1; - *tag = g_strndup(string, *len - 1); + if (type) + *type = -1; + if (len) + *len = close - string + 1; + if (tag) + *tag = g_strndup(string, *len - 1); return TRUE; } @@ -2382,26 +2392,12 @@ return g_string_free(ret, FALSE); } -static const char *accepted_protocols[] = { - "http://", - "https://", - "ftp://" -}; - -static const int accepted_protocols_size = 3; - /* returns if the beginning of the text is a protocol. If it is the protocol, returns the length so the caller knows how long the protocol string is. */ static int gtk_imhtml_is_protocol(const char *text) { - gint i; - - for(i=0; ilength : 0; } /* @@ -2606,7 +2602,7 @@ count++; } - + g_free(in_color); return g_strdup_printf("#%02X%02X%02X", rgbval[0], rgbval[1], rgbval[2]); } @@ -2655,7 +2651,7 @@ c = text; len = strlen(text); ws = g_malloc(len + 1); - ws[0] = 0; + ws[0] = '\0'; gtk_text_buffer_begin_user_action(imhtml->text_buffer); while (pos < len) { @@ -3307,8 +3303,7 @@ ws[wpos] = '\n'; wpos++; gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); - ws[0] = '\0'; - wpos = 0; + ws[0] = '\0'; wpos = 0; /* NEW_BIT (NEW_TEXT_BIT); */ } else if (!br) { /* Don't insert a space immediately after an HTML break */ /* A newline is defined by HTML as whitespace, which means we have to replace it with a word boundary. @@ -3319,19 +3314,42 @@ ws[wpos] = ' '; wpos++; gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); - ws[0] = '\0'; - wpos = 0; + ws[0] = '\0'; wpos = 0; } c++; pos++; - } else if ((len_protocol = gtk_imhtml_is_protocol(c)) > 0){ + } else if ((pos == 0 || wpos == 0 || isspace(*(c - 1))) && + (len_protocol = gtk_imhtml_is_protocol(c)) > 0) { br = FALSE; - while(len_protocol--){ - /* Skip the next len_protocol characters, but make sure they're - copied into the ws array. - */ - ws [wpos++] = *c++; - pos++; + if (wpos > 0) { + gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); + ws[0] = '\0'; wpos = 0; + } + while (len_protocol--) { + /* Skip the next len_protocol characters, but + * make sure they're copied into the ws array. + */ + ws [wpos++] = *c++; + pos++; + } + if (!imhtml->edit.link && (imhtml->format_functions & GTK_IMHTML_LINK)) { + while (*c && !isspace((int)*c) && + (*c != '<' || !gtk_imhtml_is_tag(c + 1, NULL, NULL, NULL))) { + if (*c == '&' && (amp = purple_markup_unescape_entity(c, &tlen))) { + while (*amp) + ws[wpos++] = *amp++; + c += tlen; + pos += tlen; + } else { + ws [wpos++] = *c++; + pos++; + } + } + ws[wpos] = '\0'; + gtk_imhtml_toggle_link(imhtml, ws); + gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, wpos); + ws[0] = '\0'; wpos = 0; + gtk_imhtml_toggle_link(imhtml, NULL); } } else if (*c) { br = FALSE; @@ -3355,7 +3373,7 @@ ws[wpos++] = 0xE2; ws[wpos++] = 0x80; ws[wpos++] = 0x8F; - + if (!rtl_direction) { /* insert LRM character to set direction */ @@ -3368,8 +3386,7 @@ ws[wpos] = '\0'; gtk_text_buffer_insert(imhtml->text_buffer, &line_iter, ws, wpos); gtk_text_buffer_get_end_iter(gtk_text_iter_get_buffer(&line_iter), iter); - ws[0] = '\0'; - wpos = 0; + ws[0] = '\0'; wpos = 0; } while (fonts) { @@ -4885,8 +4902,8 @@ { GtkTextIter iter; - if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) - gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); + /* Delete any currently selected text */ + gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); gtk_imhtml_toggle_link(imhtml, url); gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); @@ -4899,8 +4916,8 @@ GtkTextMark *mark; GtkTextIter iter; - if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) - gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); + /* Delete any currently selected text */ + gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); mark = gtk_text_buffer_get_insert(imhtml->text_buffer); @@ -5753,3 +5770,104 @@ g_free(smiley); } +gboolean gtk_imhtml_class_register_protocol(const char *name, + gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link), + gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu)) +{ + GtkIMHtmlClass *klass; + GtkIMHtmlProtocol *proto; + + g_return_val_if_fail(name, FALSE); + + klass = g_type_class_ref(GTK_TYPE_IMHTML); + g_return_val_if_fail(klass, FALSE); + + if ((proto = imhtml_find_protocol(name, TRUE))) { + if (activate) { + return FALSE; + } + g_free(proto->name); + g_free(proto); + klass->protocols = g_list_remove(klass->protocols, proto); + return TRUE; + } else if (!activate) { + return FALSE; + } + + proto = g_new0(GtkIMHtmlProtocol, 1); + proto->name = g_strdup(name); + proto->length = strlen(name); + proto->activate = activate; + proto->context_menu = context_menu; + klass->protocols = g_list_prepend(klass->protocols, proto); + + return TRUE; +} + +static void +gtk_imhtml_activate_tag(GtkIMHtml *imhtml, GtkTextTag *tag) +{ + /* A link was clicked--we emit the "url_clicked" signal + * with the URL as the argument */ + g_object_ref(G_OBJECT(tag)); + g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url")); + g_object_unref(G_OBJECT(tag)); + g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE)); + gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag); +} + +gboolean gtk_imhtml_link_activate(GtkIMHtmlLink *link) +{ + g_return_val_if_fail(link, FALSE); + + if (link->tag) { + gtk_imhtml_activate_tag(link->imhtml, link->tag); + } else if (link->url) { + g_signal_emit(link->imhtml, signals[URL_CLICKED], 0, link->url); + } else + return FALSE; + return TRUE; +} + +const char *gtk_imhtml_link_get_url(GtkIMHtmlLink *link) +{ + return link->url; +} + +const GtkTextTag * gtk_imhtml_link_get_text_tag(GtkIMHtmlLink *link) +{ + return link->tag; +} + +static gboolean return_add_newline_cb(GtkWidget *widget, gpointer data) +{ + GtkTextBuffer *buffer; + GtkTextMark *mark; + GtkTextIter iter; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); + + /* Delete any currently selected text */ + gtk_text_buffer_delete_selection(buffer, TRUE, TRUE); + + /* Insert a newline at the current cursor position */ + mark = gtk_text_buffer_get_insert(buffer); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); + gtk_imhtml_insert_html_at_iter(GTK_IMHTML(widget), "\n", 0, &iter); + + /* + * If we just newlined ourselves past the end of the visible area + * then scroll down so the cursor is in view. + */ + gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(widget), + gtk_text_buffer_get_insert(buffer), + 0, FALSE, 0.0, 0.0); + + return TRUE; +} + +void gtk_imhtml_set_return_inserts_newline(GtkIMHtml *imhtml) +{ + g_signal_connect(G_OBJECT(imhtml), "message_send", + G_CALLBACK(return_add_newline_cb), NULL); +} diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkimhtml.h --- a/pidgin/gtkimhtml.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkimhtml.h Wed Jan 28 10:23:37 2009 +0000 @@ -61,6 +61,11 @@ typedef struct _GtkIMHtmlHr GtkIMHtmlHr; typedef struct _GtkIMHtmlFuncs GtkIMHtmlFuncs; +/** + * @since 2.6.0 + */ +typedef struct _GtkIMHtmlLink GtkIMHtmlLink; + typedef enum { GTK_IMHTML_BOLD = 1 << 0, GTK_IMHTML_ITALIC = 1 << 1, @@ -156,6 +161,7 @@ gboolean (*message_send)(GtkIMHtml *); void (*undo)(GtkIMHtml *); void (*redo)(GtkIMHtml *); + GList *protocols; /* List of GtkIMHtmlProtocol's */ }; struct _GtkIMHtmlFontDetail { @@ -885,6 +891,74 @@ * @since 2.5.0 */ void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley); + +/** + * Register a protocol with the GtkIMHtml widget. Registering a protocol would + * allow certain text to be clickable. + * + * @param name The name of the protocol (e.g. http://) + * @param activate The callback to trigger when the protocol text is clicked. + * Removes any current protocol definition if @c NULL. The + * callback should return @c TRUE if the link was activated + * properly, @c FALSE otherwise. + * @param context_menu The callback to trigger when the context menu is popped + * up on the protocol text. The callback should return + * @c TRUE if the request for context menu was processed + * successfully, @c FALSE otherwise. + * + * @return @c TRUE if the protocol was successfully registered (or unregistered, when #activate is @c NULL) + * + * @since 2.6.0 + */ +gboolean gtk_imhtml_class_register_protocol(const char *name, + gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link), + gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu)); + +/** + * Get the URL associated with a link. This should be used by the IMHtml protocol-callbacks. + * + * @param link The GtkIMHtmlLink object sent to the callback functions + * + * @return The URL + * + * @since 2.6.0 + */ +const char *gtk_imhtml_link_get_url(GtkIMHtmlLink *link); + +/** + * Get the GtkTextTag object (if any) associated with a particular link. + * + * @param link The GtkIMHtmlLink object sent to the callback functions + * + * @return The GtkTextTag object, or @c NULL + * + * @since 2.6.0 + */ +const GtkTextTag *gtk_imhtml_link_get_text_tag(GtkIMHtmlLink *link); + +/** + * Activates a GtkIMHtmlLink object. This triggers the 'url-clicked' signal, marks the + * link as visited (when possible). + * + * @param link The GtkIMHtmlLink object sent to the callback functions + * + * @return @c TRUE if 'url-clicked' signal was emitted, @c FALSE otherwise. + * + * @since 2.6.0 + */ +gboolean gtk_imhtml_link_activate(GtkIMHtmlLink *link); + +/** + * By default this widget intercepts presses of the "return" key and + * emits the "message_send" signal instead. If you don't want this + * behavior, and you want the standard GtkTextView behavior of + * inserting a newline into the buffer, then call this function. + * + * @param imhtml The GtkIMHtml where you want the "return" key to add + * newline and not emit the "message_send" signal. + */ +void gtk_imhtml_set_return_inserts_newline(GtkIMHtml *imhtml); + /*@}*/ #ifdef __cplusplus diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkimhtmltoolbar.c --- a/pidgin/gtkimhtmltoolbar.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Wed Jan 28 10:23:37 2009 +0000 @@ -680,7 +680,7 @@ is custom smiley-enabled */ if (supports_custom && psmiley && !(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) { gchar tip[128]; - g_snprintf(tip, sizeof(tip), + g_snprintf(tip, sizeof(tip), _("This smiley is disabled because a custom smiley exists for this shortcut:\n %s"), face); gtk_tooltips_set_tip(toolbar->tooltips, button, tip, NULL); @@ -808,7 +808,7 @@ unique_smileys = g_slist_prepend(unique_smileys, smiley); } } - + /* we need to reverse the list to get the smileys in the correct order */ unique_smileys = g_slist_reverse(unique_smileys); @@ -1413,13 +1413,13 @@ menuitem = gtk_menu_item_new_with_mnemonic(_("_Horizontal rule")); g_signal_connect(G_OBJECT(menuitem), "activate" , G_CALLBACK(insert_hr_cb), toolbar); gtk_menu_shell_append(GTK_MENU_SHELL(insert_menu), menuitem); - toolbar->insert_hr = menuitem; + toolbar->insert_hr = menuitem; g_signal_connect_swapped(G_OBJECT(insert_button), "button-press-event", G_CALLBACK(gtk_widget_activate), insert_button); g_signal_connect(G_OBJECT(insert_button), "activate", G_CALLBACK(pidgin_menu_clicked), insert_menu); g_signal_connect(G_OBJECT(insert_menu), "deactivate", G_CALLBACK(pidgin_menu_deactivate), insert_button); toolbar->sml = NULL; - + /* Sep */ sep = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 0); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtklog.c --- a/pidgin/gtklog.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtklog.c Wed Jan 28 10:23:37 2009 +0000 @@ -45,7 +45,7 @@ struct log_viewer_hash_t { PurpleLogType type; - char *screenname; + char *buddyname; PurpleAccount *account; PurpleContact *contact; }; @@ -57,7 +57,7 @@ if (viewer->contact != NULL) return g_direct_hash(viewer->contact); - return g_str_hash(viewer->screenname) + + return g_str_hash(viewer->buddyname) + g_str_hash(purple_account_get_username(viewer->account)); } @@ -80,9 +80,9 @@ return FALSE; } - normal = g_strdup(purple_normalize(a->account, a->screenname)); + normal = g_strdup(purple_normalize(a->account, a->buddyname)); ret = (a->account == b->account) && - !strcmp(normal, purple_normalize(b->account, b->screenname)); + !strcmp(normal, purple_normalize(b->account, b->buddyname)); g_free(normal); return ret; @@ -209,7 +209,7 @@ lv = g_hash_table_lookup(log_viewers, ht); g_hash_table_remove(log_viewers, ht); - g_free(ht->screenname); + g_free(ht->buddyname); g_free(ht); } else syslog_viewer = NULL; @@ -556,7 +556,7 @@ if (!purple_prefs_get_bool("/purple/logging/log_chats")) log_preferences = _("Chats will only be logged if the \"Log all chats\" preference is enabled."); } - g_free(ht->screenname); + g_free(ht->buddyname); g_free(ht); } @@ -681,27 +681,27 @@ return lv; } -void pidgin_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account) { +void pidgin_log_show(PurpleLogType type, const char *buddyname, PurpleAccount *account) { struct log_viewer_hash_t *ht; PidginLogViewer *lv = NULL; - const char *name = screenname; + const char *name = buddyname; char *title; GdkPixbuf *prpl_icon; g_return_if_fail(account != NULL); - g_return_if_fail(screenname != NULL); + g_return_if_fail(buddyname != NULL); ht = g_new0(struct log_viewer_hash_t, 1); ht->type = type; - ht->screenname = g_strdup(screenname); + ht->buddyname = g_strdup(buddyname); ht->account = account; if (log_viewers == NULL) { log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal); } else if ((lv = g_hash_table_lookup(log_viewers, ht))) { gtk_window_present(GTK_WINDOW(lv->window)); - g_free(ht->screenname); + g_free(ht->buddyname); g_free(ht); return; } @@ -709,7 +709,7 @@ if (type == PURPLE_LOG_CHAT) { PurpleChat *chat; - chat = purple_blist_find_chat(account, screenname); + chat = purple_blist_find_chat(account, buddyname); if (chat != NULL) name = purple_chat_get_name(chat); @@ -717,7 +717,7 @@ } else { PurpleBuddy *buddy; - buddy = purple_find_buddy(account, screenname); + buddy = purple_find_buddy(account, buddyname); if (buddy != NULL) name = purple_buddy_get_contact_alias(buddy); @@ -726,9 +726,9 @@ prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM); - display_log_viewer(ht, purple_log_get_logs(type, screenname, account), + display_log_viewer(ht, purple_log_get_logs(type, buddyname, account), title, gtk_image_new_from_pixbuf(prpl_icon), - purple_log_get_total_size(type, screenname, account)); + purple_log_get_total_size(type, buddyname, account)); if (prpl_icon) g_object_unref(prpl_icon); @@ -760,13 +760,19 @@ return; } - for (child = contact->node.child ; child ; child = child->next) { + for (child = purple_blist_node_get_first_child((PurpleBlistNode*)contact) ; + child != NULL ; + child = purple_blist_node_get_sibling_next(child)) { + const char *buddy_name; + PurpleAccount *account; + if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) continue; - logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, ((PurpleBuddy *)child)->name, - ((PurpleBuddy *)child)->account), logs); - total_log_size += purple_log_get_total_size(PURPLE_LOG_IM, ((PurpleBuddy *)child)->name, ((PurpleBuddy *)child)->account); + buddy_name = purple_buddy_get_name((PurpleBuddy *)child); + account = purple_buddy_get_account((PurpleBuddy *)child); + logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, buddy_name, account), logs); + total_log_size += purple_log_get_total_size(PURPLE_LOG_IM, buddy_name, account); } logs = g_list_sort(logs, purple_log_compare); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtklog.h --- a/pidgin/gtklog.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtklog.h Wed Jan 28 10:23:37 2009 +0000 @@ -9,7 +9,7 @@ * Pidgin 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 @@ -53,7 +53,7 @@ -void pidgin_log_show(PurpleLogType type, const char *screenname, PurpleAccount *account); +void pidgin_log_show(PurpleLogType type, const char *buddyname, PurpleAccount *account); void pidgin_log_show_contact(PurpleContact *contact); void pidgin_syslog_show(void); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkmain.c --- a/pidgin/gtkmain.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkmain.c Wed Jan 28 10:23:37 2009 +0000 @@ -310,6 +310,7 @@ pidgin_log_init(); pidgin_docklet_init(); pidgin_smileys_init(); + pidgin_utils_init(); } static GHashTable *ui_info = NULL; @@ -323,6 +324,7 @@ #endif /* Uninit */ + pidgin_utils_uninit(); pidgin_smileys_uninit(); pidgin_conversations_uninit(); pidgin_status_uninit(); @@ -385,6 +387,7 @@ "Usage: %s [OPTION]...\n\n" " -c, --config=DIR use DIR for config files\n" " -d, --debug print debugging messages to stdout\n" + " -f, --force-online force online, regardless of network status\n" " -h, --help display this help and exit\n" " -m, --multiple do not ensure single instance\n" " -n, --nologin don't automatically login\n" @@ -398,6 +401,7 @@ "Usage: %s [OPTION]...\n\n" " -c, --config=DIR use DIR for config files\n" " -d, --debug print debugging messages to stdout\n" + " -f, --force-online force online, regardless of network status\n" " -h, --help display this help and exit\n" " -m, --multiple do not ensure single instance\n" " -n, --nologin don't automatically login\n" @@ -457,10 +461,10 @@ int main(int argc, char *argv[]) #endif { + gboolean opt_force_online = FALSE; gboolean opt_help = FALSE; gboolean opt_login = FALSE; gboolean opt_nologin = FALSE; - gboolean opt_nocrash = FALSE; gboolean opt_version = FALSE; gboolean opt_si = TRUE; /* Check for single instance? */ char *opt_config_dir_arg = NULL; @@ -485,17 +489,17 @@ GList *active_accounts; struct option long_options[] = { - {"config", required_argument, NULL, 'c'}, - {"debug", no_argument, NULL, 'd'}, - {"help", no_argument, NULL, 'h'}, - {"login", optional_argument, NULL, 'l'}, - {"multiple", no_argument, NULL, 'm'}, - {"nologin", no_argument, NULL, 'n'}, - {"nocrash", no_argument, NULL, 'x'}, - {"session", required_argument, NULL, 's'}, - {"version", no_argument, NULL, 'v'}, - {"display", required_argument, NULL, 'D'}, - {"sync", no_argument, NULL, 'S'}, + {"config", required_argument, NULL, 'c'}, + {"debug", no_argument, NULL, 'd'}, + {"force-online", no_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {"login", optional_argument, NULL, 'l'}, + {"multiple", no_argument, NULL, 'm'}, + {"nologin", no_argument, NULL, 'n'}, + {"session", required_argument, NULL, 's'}, + {"version", no_argument, NULL, 'v'}, + {"display", required_argument, NULL, 'D'}, + {"sync", no_argument, NULL, 'S'}, {0, 0, 0, 0} }; @@ -602,9 +606,9 @@ opterr = 1; while ((opt = getopt_long(argc, argv, #ifndef _WIN32 - "c:dhmnl::s:v", + "c:dfhmnl::s:v", #else - "c:dhmnl::v", + "c:dfhmnl::v", #endif long_options, NULL)) != -1) { switch (opt) { @@ -615,6 +619,9 @@ case 'd': /* debug */ debug_enabled = TRUE; break; + case 'f': /* force-online */ + opt_force_online = TRUE; + break; case 'h': /* help */ opt_help = TRUE; break; @@ -637,9 +644,6 @@ case 'm': /* do not ensure single instance. */ opt_si = FALSE; break; - case 'x': /* --nocrash */ - opt_nocrash = TRUE; - break; case 'D': /* --display */ case 'S': /* --sync */ /* handled by gtk_init_check below */ @@ -816,6 +820,11 @@ opt_config_dir_arg = NULL; } + /* This needs to be before purple_blist_show() so the + * statusbox gets the forced online status. */ + if (opt_force_online) + purple_network_force_online(); + /* * We want to show the blist early in the init process so the * user feels warm and fuzzy (not cold and prickley). diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkpluginpref.c --- a/pidgin/gtkpluginpref.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkpluginpref.c Wed Jan 28 10:23:37 2009 +0000 @@ -93,7 +93,7 @@ case PURPLE_PLUGIN_PREF_NONE: default: if (format == PURPLE_STRING_FORMAT_TYPE_NONE) - { + { entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), purple_prefs_get_string(pref_name)); gtk_entry_set_max_length(GTK_ENTRY(entry), diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkpounce.c --- a/pidgin/gtkpounce.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkpounce.c Wed Jan 28 10:23:37 2009 +0000 @@ -535,7 +535,7 @@ /* Create the window. */ dialog->window = window = gtk_dialog_new(); - gtk_window_set_title(GTK_WINDOW(window), (cur_pounce == NULL ? _("New Buddy Pounce") : _("Edit Buddy Pounce"))); + gtk_window_set_title(GTK_WINDOW(window), (cur_pounce == NULL ? _("Add Buddy Pounce") : _("Modify Buddy Pounce"))); gtk_window_set_role(GTK_WINDOW(window), "buddy_pounce"); gtk_container_set_border_width(GTK_CONTAINER(dialog->window), PIDGIN_HIG_BORDER); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkpounce.h --- a/pidgin/gtkpounce.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkpounce.h Wed Jan 28 10:23:37 2009 +0000 @@ -8,7 +8,7 @@ * Pidgin 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 diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkprefs.c Wed Jan 28 10:23:37 2009 +0000 @@ -35,6 +35,8 @@ #include "request.h" #include "savedstatuses.h" #include "sound.h" +#include "sound-theme.h" +#include "theme-manager.h" #include "util.h" #include "network.h" @@ -47,6 +49,7 @@ #include "gtkprefs.h" #include "gtksavedstatuses.h" #include "gtksound.h" +#include "gtkstatus-icon-theme.h" #include "gtkthemes.h" #include "gtkutils.h" #include "pidginstock.h" @@ -56,6 +59,8 @@ #define PROXYUSER 2 #define PROXYPASS 3 +#define PREFS_OPTIMAL_ICON_SIZE 32 + static int sound_row_sel = 0; static GtkWidget *prefsnotebook; @@ -69,6 +74,12 @@ static int notebook_page = 0; static GtkTreeRowReference *previous_smiley_row = NULL; +static gboolean prefs_themes_unsorted = TRUE; +static GtkListStore *prefs_sound_themes; +static GtkListStore *prefs_blist_themes; +static GtkListStore *prefs_status_icon_themes; + + /* * PROTOTYPES */ @@ -546,6 +557,212 @@ gtk_drag_finish(dc, FALSE, FALSE, t); } +/* Rebuild the markup for the sound theme selection for "(Custom)" themes */ +static void +pref_sound_generate_markup() +{ + gboolean print_custom, customized; + const gchar *name, *author, *description, *current_theme; + gchar *markup; + PurpleSoundTheme *theme; + GtkTreeIter iter; + + customized = pidgin_sound_is_customized(); + current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"); + + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_sound_themes), &iter)) { + do { + gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1); + + print_custom = customized && g_str_equal(current_theme, name); + + if (g_str_equal(name, "")) + markup = g_strdup_printf("(Default)%s%s - None\nThe default Pidgin sound theme", + print_custom ? " " : "", print_custom ? "(Custom)" : ""); + else { + theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound")); + author = purple_theme_get_author(PURPLE_THEME(theme)); + description = purple_theme_get_description(PURPLE_THEME(theme)); + + markup = g_strdup_printf("%s%s%s%s%s\n%s", + name, print_custom ? " " : "", print_custom ? "(Custom)" : "", + author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : ""); + } + + gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1); + + g_free(markup); + + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter)); + } +} + +/* adds the themes to the theme list from the manager so they can be sisplayed in prefs */ +static void +prefs_themes_sort(PurpleTheme *theme) +{ + GdkPixbuf *pixbuf = NULL; + GtkTreeIter iter; + gchar *image_full = NULL, *markup; + const gchar *name, *author, *description; + + if (PURPLE_IS_SOUND_THEME(theme)){ + + image_full = purple_theme_get_image_full(theme); + if (image_full != NULL){ + pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); + g_free(image_full); + } else pixbuf = NULL; + + gtk_list_store_append(prefs_sound_themes, &iter); + gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1); + + if (pixbuf != NULL) + gdk_pixbuf_unref(pixbuf); + + } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_STATUS_ICON_THEME(theme)){ + GtkListStore *store; + + if (PIDGIN_IS_BLIST_THEME(theme)) + store = prefs_blist_themes; + else store = prefs_status_icon_themes; + + image_full = purple_theme_get_image_full(theme); + if (image_full != NULL){ + pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); + g_free(image_full); + } else pixbuf = NULL; + + name = purple_theme_get_name(theme); + author = purple_theme_get_author(theme); + description = purple_theme_get_description(theme); + + markup = g_strdup_printf("%s%s%s\n%s", name, author != NULL ? " - " : "", + author != NULL ? author : "", description != NULL ? description : ""); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1); + + g_free(markup); + if (pixbuf != NULL) + gdk_pixbuf_unref(pixbuf); + } + +} + +/* init all the theme variables so that the themes can be sorted later and used by pref pages */ +static void +prefs_themes_init() +{ + GdkPixbuf *pixbuf = NULL; + gchar *filename; + GtkTreeIter iter; + + filename = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL); + pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); + g_free(filename); + + /* sound themes */ + prefs_sound_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + gtk_list_store_append(prefs_sound_themes, &iter); + gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, "", -1); + + /* blist themes */ + prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + gtk_list_store_append(prefs_blist_themes, &iter); + gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, "(Default) - None\n" + "The default Pidgin buddy list theme", 2, "", -1); + + /* status icon themes */ + prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + gtk_list_store_append(prefs_status_icon_themes, &iter); + gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, "(Default) - None\n" + "The default Pidgin status icon theme", 2, "", -1); + + gdk_pixbuf_unref(pixbuf); +} + +/* builds a theme combo box from a list store with colums: icon preview, markup, theme name */ +static GtkWidget * +prefs_build_theme_combo_box(GtkListStore *store, const gchar *current_theme) +{ + GtkWidget *combo_box; + GtkCellRenderer *cell_rend; + GtkTreeIter iter; + gchar *theme = NULL; + gboolean unset = TRUE; + + g_return_val_if_fail(store != NULL && current_theme != NULL, NULL); + + combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); + + cell_rend = gtk_cell_renderer_pixbuf_new(); + gtk_cell_renderer_set_fixed_size(cell_rend, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "pixbuf", 0, NULL); + + cell_rend = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL); +/*#if GTK_CHECK_VERSION(2,6,0) + g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); +#endif*/ + + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { + do { + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1); + + if (g_str_equal(current_theme, theme)) { + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter); + unset = FALSE; + } + + g_free(theme); + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); + } + + if (unset) + gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0); + + return combo_box; +} + +/* sets the current sound theme */ +static void +prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + gint i; + gchar *pref; + gchar *new_theme; + gboolean success; + GtkTreeIter new_iter; + + success = gtk_combo_box_get_active_iter(combo_box, &new_iter); + g_return_if_fail(success); + + gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &new_iter, 2, &new_theme, -1); + + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme); + + /* New theme removes all customization */ + for(i=0; i < PURPLE_NUM_SOUNDS; i++){ + pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", + pidgin_sound_get_event_option(i)); + purple_prefs_set_path(pref, ""); + g_free(pref); + } + + /* gets rid of the "(Custom)" from the last selection */ + pref_sound_generate_markup(); + + gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); + + g_free(new_theme); +} + /* Does same as normal sort, except "none" is sorted first */ static gint pidgin_sort_smileys (GtkTreeModel *model, GtkTreeIter *a, @@ -922,6 +1139,40 @@ gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0); } +/* sets the current buddy list theme */ +static void +prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + PidginBlistTheme *theme; + GtkTreeIter iter; + gchar *name = NULL; + + g_return_if_fail(gtk_combo_box_get_active_iter(combo_box, &iter)); + gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1); + + theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist")); + g_free(name); + + pidgin_blist_set_theme(theme); +} + +/* sets the current icon theme */ +static void +prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + PidginStatusIconTheme *theme; + GtkTreeIter iter; + gchar *name = NULL; + + g_return_if_fail(gtk_combo_box_get_active_iter(combo_box, &iter)); + gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1); + + theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon")); + g_free(name); + + pidgin_stock_load_status_icon_theme(theme); +} + static GtkWidget * interface_page(void) { @@ -929,6 +1180,7 @@ GtkWidget *vbox; GtkWidget *vbox2; GtkWidget *label; + GtkWidget *combo_box; GtkSizeGroup *sg; GList *names = NULL; @@ -937,6 +1189,19 @@ sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + /* Buddy List Themes */ + vbox = pidgin_make_frame(ret, _("Buddy List Theme")); + + combo_box = prefs_build_theme_combo_box(prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme")); + gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_blist_theme_cb, NULL); + + /* Status Icon Themes */ + combo_box = prefs_build_theme_combo_box(prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme")); + gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_status_icon_theme_cb, NULL); + + /* System Tray */ vbox = pidgin_make_frame(ret, _("System Tray Icon")); label = pidgin_prefs_dropdown(vbox, _("_Show system tray icon:"), PURPLE_PREF_STRING, PIDGIN_PREFS_ROOT "/docklet/show", @@ -1738,6 +2003,8 @@ g_free(pref); gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); + + pref_sound_generate_markup(); } static void @@ -1760,6 +2027,8 @@ */ if (sound == sound_row_sel) gtk_entry_set_text(GTK_ENTRY(sound_entry), filename); + + pref_sound_generate_markup(); } static void select_sound(GtkWidget *button, gpointer being_NULL_is_fun) @@ -1828,6 +2097,8 @@ if (sound_entry) gtk_entry_set_text(GTK_ENTRY(sound_entry), (file && *file != '\0') ? file : _("(default)")); g_value_unset (&val); + + pref_sound_generate_markup(); } @@ -1853,7 +2124,7 @@ sound_page(void) { GtkWidget *ret; - GtkWidget *vbox, *sw, *button; + GtkWidget *vbox, *sw, *button, *combo_box; GtkSizeGroup *sg; GtkTreeIter iter; GtkWidget *event_view; @@ -1947,7 +2218,6 @@ purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method", sound_changed2_cb, vbox); #endif - vbox = pidgin_make_frame(ret, _("Sound Events")); /* The following is an ugly hack to make the frame expand so the @@ -1959,6 +2229,14 @@ gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent), vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START); + /* SOUND THEMES */ + combo_box = prefs_build_theme_combo_box(prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme")); + pref_sound_generate_markup(); + gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_sound_theme_cb, NULL); + + /* SOUND SELECTION */ sw = gtk_scrolled_window_new(NULL,NULL); gtk_widget_set_size_request(sw, -1, 100); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); @@ -2192,6 +2470,14 @@ return; } + /* Refresh the list of themes before showing the preferences window */ + purple_theme_manager_refresh(); + + /* add everything in the theme manager before the window is loaded */ + if (prefs_themes_unsorted) { + purple_theme_manager_for_each_theme(prefs_themes_sort); + prefs_themes_unsorted = FALSE; + } /* copy the preferences to tmp values... * I liked "take affect immediately" Oh well :-( */ /* (that should have been "effect," right?) */ @@ -2286,6 +2572,9 @@ purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", ""); purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder", ""); + /* Themes */ + prefs_themes_init(); + /* Smiley Themes */ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/smileys"); purple_prefs_add_string(PIDGIN_PREFS_ROOT "/smileys/theme", "Default"); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkprefs.h --- a/pidgin/gtkprefs.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkprefs.h Wed Jan 28 10:23:37 2009 +0000 @@ -59,7 +59,7 @@ * @param max The maximum value of the spin button * @param sg If not NULL, the size group to which the spin button will be added * @return An hbox containing both the label and the spinner. Can be - * used to set the widgets to sensitive or insensitive based on the + * used to set the widgets to sensitive or insensitive based on the * value of a checkbox. */ GtkWidget *pidgin_prefs_labeled_spin_button(GtkWidget *page, diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkrequest.c Wed Jan 28 10:23:37 2009 +0000 @@ -384,6 +384,8 @@ gtk_imhtml_append_text(GTK_IMHTML(entry), default_value, GTK_IMHTML_NO_SCROLL); gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); + + gtk_imhtml_set_return_inserts_newline(GTK_IMHTML(entry)); } else { if (multiline) { @@ -682,15 +684,17 @@ static void req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field) { + PurpleRequestFieldGroup *group; PidginRequestData *req_data; const char *text = gtk_entry_get_text(GTK_ENTRY(entry)); purple_request_field_string_set_value(field, (*text == '\0' ? NULL : text)); - req_data = (PidginRequestData *)field->group->fields_list->ui_data; + group = purple_request_field_get_group(field); + req_data = (PidginRequestData *)group->fields_list->ui_data; gtk_widget_set_sensitive(req_data->ok_button, - purple_request_fields_all_required_filled(field->group->fields_list)); + purple_request_fields_all_required_filled(group->fields_list)); } static void @@ -711,7 +715,8 @@ if (purple_str_has_prefix(type_hint, "screenname")) { GtkWidget *optmenu = NULL; - GList *fields = field->group->fields; + PurpleRequestFieldGroup *group = purple_request_field_get_group(field); + GList *fields = group->fields; while (fields) { PurpleRequestField *fld = fields->data; @@ -722,9 +727,11 @@ const char *type_hint = purple_request_field_get_type_hint(fld); if (type_hint != NULL && strcmp(type_hint, "account") == 0) { - if (fld->ui_data == NULL) - fld->ui_data = create_account_field(fld); - optmenu = GTK_WIDGET(fld->ui_data); + optmenu = GTK_WIDGET(purple_request_field_get_ui_data(fld)); + if (optmenu == NULL) { + optmenu = GTK_WIDGET(create_account_field(fld)); + purple_request_field_set_ui_data(field, optmenu); + } break; } } @@ -1338,24 +1345,26 @@ gtk_widget_show(label); } - if (field->ui_data != NULL) - widget = GTK_WIDGET(field->ui_data); - else if (type == PURPLE_REQUEST_FIELD_STRING) - widget = create_string_field(field); - else if (type == PURPLE_REQUEST_FIELD_INTEGER) - widget = create_int_field(field); - else if (type == PURPLE_REQUEST_FIELD_BOOLEAN) - widget = create_bool_field(field); - else if (type == PURPLE_REQUEST_FIELD_CHOICE) - widget = create_choice_field(field); - else if (type == PURPLE_REQUEST_FIELD_LIST) - widget = create_list_field(field); - else if (type == PURPLE_REQUEST_FIELD_IMAGE) - widget = create_image_field(field); - else if (type == PURPLE_REQUEST_FIELD_ACCOUNT) - widget = create_account_field(field); - else - continue; + widget = GTK_WIDGET(purple_request_field_get_ui_data(field)); + if (widget == NULL) + { + if (type == PURPLE_REQUEST_FIELD_STRING) + widget = create_string_field(field); + else if (type == PURPLE_REQUEST_FIELD_INTEGER) + widget = create_int_field(field); + else if (type == PURPLE_REQUEST_FIELD_BOOLEAN) + widget = create_bool_field(field); + else if (type == PURPLE_REQUEST_FIELD_CHOICE) + widget = create_choice_field(field); + else if (type == PURPLE_REQUEST_FIELD_LIST) + widget = create_list_field(field); + else if (type == PURPLE_REQUEST_FIELD_IMAGE) + widget = create_image_field(field); + else if (type == PURPLE_REQUEST_FIELD_ACCOUNT) + widget = create_account_field(field); + else + continue; + } if (label) gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget); @@ -1400,7 +1409,7 @@ gtk_widget_show(widget); - field->ui_data = widget; + purple_request_field_set_ui_data(field, widget); } } } diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksavedstatuses.c --- a/pidgin/gtksavedstatuses.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksavedstatuses.c Wed Jan 28 10:23:37 2009 +0000 @@ -76,7 +76,7 @@ STATUS_EDITOR_COLUMN_WINDOW, STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, STATUS_EDITOR_COLUMN_ICON, - STATUS_EDITOR_COLUMN_SCREENNAME, + STATUS_EDITOR_COLUMN_USERNAME, /** A hidden column containing the ID of this PurpleStatusType. */ STATUS_EDITOR_COLUMN_STATUS_ID, STATUS_EDITOR_COLUMN_STATUS_NAME, @@ -1007,7 +1007,7 @@ g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(status_editor_substatus_cb), dialog); - /* Screen Name column */ + /* Username column */ column = gtk_tree_view_column_new(); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_column_set_title(column, _("Username")); @@ -1020,11 +1020,11 @@ gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", STATUS_EDITOR_COLUMN_ICON); - /* Screen Name */ + /* Username */ renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, "text", - STATUS_EDITOR_COLUMN_SCREENNAME); + STATUS_EDITOR_COLUMN_USERNAME); /* Status column */ column = gtk_tree_view_column_new(); @@ -1086,7 +1086,7 @@ STATUS_EDITOR_COLUMN_ACCOUNT, account, STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, (substatus != NULL), STATUS_EDITOR_COLUMN_ICON, pixbuf, - STATUS_EDITOR_COLUMN_SCREENNAME, purple_account_get_username(account), + STATUS_EDITOR_COLUMN_USERNAME, purple_account_get_username(account), STATUS_EDITOR_COLUMN_STATUS_ID, id, STATUS_EDITOR_COLUMN_STATUS_NAME, name, STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message, @@ -1218,6 +1218,8 @@ gtk_container_set_focus_chain(GTK_CONTAINER(hbox), focus_chain); g_list_free(focus_chain); + gtk_imhtml_set_return_inserts_newline(dialog->message); + if ((saved_status != NULL) && (purple_savedstatus_get_message(saved_status) != NULL)) gtk_imhtml_append_text(GTK_IMHTML(text), purple_savedstatus_get_message(saved_status), 0); @@ -1547,7 +1549,7 @@ /* Seed the input widgets with the current values */ /* Only look at the saved status if we can't find it in the parent status dialog's substatuses model */ - gtk_tree_model_get(GTK_TREE_MODEL(status_editor->model), &iter, + gtk_tree_model_get(GTK_TREE_MODEL(status_editor->model), &iter, STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &parent_dialog_has_substatus, -1); if (parent_dialog_has_substatus) { gtk_tree_model_get(GTK_TREE_MODEL(status_editor->model), &iter, @@ -1656,7 +1658,7 @@ * And whether or not that emblem is visible */ SS_MENU_EMBLEM_VISIBLE_COLUMN, - + SS_MENU_NUM_COLUMNS }; diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkscrollbook.h --- a/pidgin/gtkscrollbook.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkscrollbook.h Wed Jan 28 10:23:37 2009 +0000 @@ -51,7 +51,7 @@ GtkWidget *left_arrow; GtkWidget *right_arrow; GList *children; - + /* Padding for future expansion */ void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksession.c --- a/pidgin/gtksession.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksession.c Wed Jan 28 10:23:37 2009 +0000 @@ -108,7 +108,7 @@ purple_debug(PURPLE_DEBUG_INFO, NULL, "done.\n"); } -/* We call any handler installed before (or after) ice_init but +/* We call any handler installed before (or after) ice_init but * avoid calling the default libICE handler which does an exit(). * * This means we do nothing by default, which is probably correct, diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksmiley.c --- a/pidgin/gtksmiley.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksmiley.c Wed Jan 28 10:23:37 2009 +0000 @@ -225,6 +225,12 @@ entry = gtk_entry_get_text(GTK_ENTRY(s->smile)); if (!entry || !*entry) { + /* + * TODO: We should enable/disable the add button based on + * whether the user has entered all required data. That + * would eliminate the need for this check and provide a + * better user experience. + */ purple_notify_error(s->parent, _("Custom Smiley"), _("More Data needed"), _("Please provide a shortcut to associate with the smiley.")); @@ -233,9 +239,12 @@ emoticon = purple_smileys_find_by_shortcut(entry); if (emoticon && emoticon != s->smiley) { + gchar *msg; + msg = g_strdup_printf(_("A custom smiley for '%s' already exists. " + "Please use a different shortcut."), entry); purple_notify_error(s->parent, _("Custom Smiley"), - _("Duplicate Shortcut"), - _("A custom smiley for the selected shortcut already exists. Please specify a different shortcut.")); + _("Duplicate Shortcut"), msg); + g_free(msg); return; } @@ -273,7 +282,7 @@ gsize size = 0; gchar *filename; const gchar *dirname = purple_smileys_get_storing_dir(); - + /* since this may be called before purple_smiley_new_* has ever been called, we create the storing dir, if it doesn't exist yet, to be able to save the pixbuf before adding the smiley */ @@ -286,7 +295,7 @@ dirname, g_strerror(errno)); } } - + gdk_pixbuf_save_to_buffer(s->custom_pixbuf, &buffer, &size, "png", NULL, "compression", "9", NULL, NULL); filename = purple_util_get_image_filename(buffer, size); @@ -385,7 +394,7 @@ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)), hbox); - label = gtk_label_new_with_mnemonic(_("Smiley _Image")); + label = gtk_label_new_with_mnemonic(_("_Image:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); @@ -415,8 +424,8 @@ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)),hbox); - /* Smiley shortcut */ - label = gtk_label_new_with_mnemonic(_("Smiley S_hortcut")); + /* Shortcut text */ + label = gtk_label_new_with_mnemonic(_("S_hortcut text:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); @@ -520,9 +529,9 @@ gtk_tree_view_column_pack_start(column, rend, FALSE); gtk_tree_view_column_add_attribute(column, rend, "pixbuf", ICON); - /* Shortcut */ + /* Shortcut Text */ column = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title(column, _("Shortcut")); + gtk_tree_view_column_set_title(column, _("Shortcut Text")); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); @@ -712,7 +721,7 @@ _("Custom Smiley Manager"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_ADD, GTK_RESPONSE_YES, + PIDGIN_STOCK_ADD, GTK_RESPONSE_YES, PIDGIN_STOCK_MODIFY, PIDGIN_RESPONSE_MODIFY, GTK_STOCK_DELETE, GTK_RESPONSE_NO, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, @@ -740,4 +749,3 @@ gtk_widget_show(win); } - diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksmiley.h --- a/pidgin/gtksmiley.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksmiley.h Wed Jan 28 10:23:37 2009 +0000 @@ -25,8 +25,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#ifndef _PIDGIN_GTKSMILEY_H_ -#define _PIDGIN_GTKSMILEY_H_ +#ifndef PIDGIN_GTKSMILEY_H +#define PIDGIN_GTKSMILEY_H #include "smiley.h" @@ -62,7 +62,7 @@ * * @constreturn A GtkIMHmlSmiley list */ -GSList* pidgin_smileys_get_all(void); +GSList *pidgin_smileys_get_all(void); /****************************************************************************** * Smiley Manager @@ -100,4 +100,4 @@ */ void pidgin_smiley_editor_set_image(PidginSmiley *editor, GdkPixbuf *image); -#endif /* _PIDGIN_GTKSMILEY_H_*/ +#endif /* PIDGIN_GTKSMILEY_H */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksound.c --- a/pidgin/gtksound.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksound.c Wed Jan 28 10:23:37 2009 +0000 @@ -40,6 +40,8 @@ #include "notify.h" #include "prefs.h" #include "sound.h" +#include "sound-theme.h" +#include "theme-manager.h" #include "util.h" #include "gtkconv.h" @@ -294,6 +296,7 @@ purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/file/nick_said", ""); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/enabled/pounce_default", TRUE); purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/file/pounce_default", ""); + purple_prefs_add_string(PIDGIN_PREFS_ROOT "/sound/theme", ""); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/conv_focus", TRUE); purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/sound/mute", FALSE); purple_prefs_add_path(PIDGIN_PREFS_ROOT "/sound/command", ""); @@ -557,6 +560,8 @@ { char *enable_pref; char *file_pref; + const char *theme_name; + PurpleSoundTheme *theme; if ((event == PURPLE_SOUND_BUDDY_ARRIVE) && mute_login_sounds) return; @@ -573,13 +578,31 @@ /* check NULL for sounds that don't have an option, ie buddy pounce */ if (purple_prefs_get_bool(enable_pref)) { char *filename = g_strdup(purple_prefs_get_path(file_pref)); - if(!filename || !strlen(filename)) { + theme_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"); + + if (theme_name && *theme_name && (!filename || !*filename)) { + /* Use theme */ g_free(filename); + + theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(theme_name, "sound")); + filename = purple_sound_theme_get_file_full(theme, sounds[event].pref); + + if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR)){ /* Use Default sound in this case */ + purple_debug_error("sound", "The file: (%s) %s\n from theme: %s, was not found or wasn't readable\n", + sounds[event].pref, filename, theme_name); + g_free(filename); + } + } + + if (!filename || !strlen(filename)) { /* Use Default sounds */ + g_free(filename); + /* XXX Consider creating a constant for "sounds/purple" to be shared with Finch */ filename = g_build_filename(DATADIR, "sounds", "purple", sounds[event].def, NULL); } purple_sound_play_file(filename, NULL); + g_free(filename); } @@ -587,6 +610,29 @@ g_free(file_pref); } +gboolean +pidgin_sound_is_customized(void) +{ + gint i; + gchar *path, *file; + + for (i = 0; i < PURPLE_NUM_SOUNDS; i++) { + path = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", sounds[i].pref); + file = g_strdup(purple_prefs_get_path(path)); + g_free(path); + + if (file && file[0] != '\0'){ + g_free(file); + return TRUE; + } + + g_free(file); + } + + return FALSE; + +} + static PurpleSoundUiOps sound_ui_ops = { pidgin_sound_init, diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksound.h --- a/pidgin/gtksound.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksound.h Wed Jan 28 10:23:37 2009 +0000 @@ -63,6 +63,15 @@ */ void *pidgin_sound_get_handle(void); +/** + * Returns true Pidgin is using customized sounds + * + * @return TRUE if non default sounds are used. + * + * @since 2.6.0 + */ +gboolean pidgin_sound_is_customized(void); + /*@}*/ #endif /* _PIDGINSOUND_H_ */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksourceiter.c --- a/pidgin/gtksourceiter.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksourceiter.c Wed Jan 28 10:23:37 2009 +0000 @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * gtksourceiter.c * * Pidgin is the legal property of its developers, whose names are too numerous @@ -7,7 +7,7 @@ * * The following copyright notice applies to this file: * - * Copyright (C) 2000 - 2005 Paolo Maggi + * Copyright (C) 2000 - 2005 Paolo Maggi * Copyright (C) 2002, 2003 Jeroen Zwartepoorte * * This program is free software; you can redistribute it and/or modify @@ -206,7 +206,7 @@ finally_2: g_free (normalized_s1); - g_free (normalized_s2); + g_free (normalized_s2); return ret; } @@ -247,7 +247,7 @@ { /* being UTF8 correct sucks; this accounts for extra offsets coming from canonical decompositions of - UTF8 characters (e.g. accented characters) which + UTF8 characters (e.g. accented characters) which g_utf8_normalize() performs */ gchar *normal; gchar buffer[6]; @@ -530,14 +530,14 @@ * @match_start: return location for start of match, or %%NULL. * @match_end: return location for end of match, or %%NULL. * @limit: bound for the search, or %%NULL for the end of the buffer. - * - * Searches forward for @str. Any match is returned by setting - * @match_start to the first character of the match and @match_end to the + * + * Searches forward for @str. Any match is returned by setting + * @match_start to the first character of the match and @match_end to the * first character after the match. The search will not continue past * @limit. Note that a search is a linear or O(n) operation, so you * may wish to use @limit to avoid locking up your UI on large * buffers. - * + * * If the #GTK_SOURCE_SEARCH_VISIBLE_ONLY flag is present, the match may * have invisible text interspersed in @str. i.e. @str will be a * possibly-noncontiguous subsequence of the matched range. similarly, @@ -550,7 +550,7 @@ * * Same as gtk_text_iter_forward_search(), but supports case insensitive * searching. - * + * * Return value: whether a match was found. **/ gboolean @@ -574,7 +574,7 @@ if ((flags & GTK_SOURCE_SEARCH_CASE_INSENSITIVE) == 0) return gtk_text_iter_forward_search (iter, str, flags, match_start, match_end, - limit); + limit); if (limit && gtk_text_iter_compare (iter, limit) >= 0) return FALSE; @@ -650,10 +650,10 @@ * @match_start: return location for start of match, or %%NULL. * @match_end: return location for end of match, or %%NULL. * @limit: location of last possible @match_start, or %%NULL for start of buffer. - * + * * Same as gtk_text_iter_backward_search(), but supports case insensitive * searching. - * + * * Return value: whether a match was found. **/ gboolean @@ -677,7 +677,7 @@ if ((flags & GTK_SOURCE_SEARCH_CASE_INSENSITIVE) == 0) return gtk_text_iter_backward_search (iter, str, flags, match_start, match_end, - limit); + limit); if (limit && gtk_text_iter_compare (iter, limit) <= 0) return FALSE; diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksourceiter.h --- a/pidgin/gtksourceiter.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksourceiter.h Wed Jan 28 10:23:37 2009 +0000 @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * gtksourceiter.h * * Pidgin is the legal property of its developers, whose names are too numerous @@ -7,7 +7,7 @@ * * The following copyright notice applies to this file: * - * Copyright (C) 2000 - 2005 Paolo Maggi + * Copyright (C) 2000 - 2005 Paolo Maggi * Copyright (C) 2002, 2003 Jeroen Zwartepoorte * * This program is free software; you can redistribute it and/or modify diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksourceundomanager.c --- a/pidgin/gtksourceundomanager.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksourceundomanager.c Wed Jan 28 10:23:37 2009 +0000 @@ -4,8 +4,8 @@ * This file is part of GtkSourceView * * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence - * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi - * Copyright (C) 2002-2005 Paolo Maggi + * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi + * Copyright (C) 2002-2005 Paolo Maggi * * 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 @@ -19,7 +19,7 @@ * * 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, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1301, USA. */ @@ -49,14 +49,14 @@ GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR, } GtkSourceUndoActionType; -/* +/* * We use offsets instead of GtkTextIters because the last ones * require to much memory in this context without giving us any advantage. - */ + */ struct _GtkSourceUndoInsertAction { - gint pos; + gint pos; gchar *text; gint length; gint chars; @@ -79,7 +79,7 @@ struct _GtkSourceUndoAction { GtkSourceUndoActionType action_type; - + union { GtkSourceUndoInsertAction insert; GtkSourceUndoDeleteAction delete; @@ -92,7 +92,7 @@ guint mergeable : 1; /* It is TRUE whether the action is marked as "modified". - * An action is marked as "modified" if it changed the + * An action is marked as "modified" if it changed the * state of the buffer from "not modified" to "modified". Only the first * action of a group can be marked as modified. * There can be a single action marked as "modified" in the actions list. @@ -106,29 +106,29 @@ struct _GtkSourceUndoManagerPrivate { GtkTextBuffer *document; - + GList* actions; - gint next_redo; + gint next_redo; gint actions_in_current_group; - + gint running_not_undoable_actions; gint num_of_groups; gint max_undo_levels; - + guint can_undo : 1; guint can_redo : 1; - + /* It is TRUE whether, while undoing an action of the current group (with order_in_group > 1), * the state of the buffer changed from "not modified" to "modified". */ - guint modified_undoing_group : 1; + guint modified_undoing_group : 1; /* Pointer to the action (in the action list) marked as "modified". - * It is NULL when no action is marked as "modified". - * It is INVALID when the action marked as "modified" has been removed + * It is NULL when no action is marked as "modified". + * It is INVALID when the action marked as "modified" has been removed * from the action list (freeing the list or resizing it) */ GtkSourceUndoAction *modified_action; }; @@ -143,33 +143,33 @@ static void gtk_source_undo_manager_init (GtkSourceUndoManager *um); static void gtk_source_undo_manager_finalize (GObject *object); -static void gtk_source_undo_manager_insert_text_handler (GtkTextBuffer *buffer, +static void gtk_source_undo_manager_insert_text_handler (GtkTextBuffer *buffer, GtkTextIter *pos, - const gchar *text, - gint length, + const gchar *text, + gint length, GtkSourceUndoManager *um); static void gtk_source_undo_manager_insert_anchor_handler (GtkTextBuffer *buffer, GtkTextIter *pos, GtkTextChildAnchor *anchor, GtkSourceUndoManager *um); -static void gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer, +static void gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, GtkSourceUndoManager *um); -static void gtk_source_undo_manager_begin_user_action_handler (GtkTextBuffer *buffer, +static void gtk_source_undo_manager_begin_user_action_handler (GtkTextBuffer *buffer, GtkSourceUndoManager *um); static void gtk_source_undo_manager_modified_changed_handler (GtkTextBuffer *buffer, GtkSourceUndoManager *um); static void gtk_source_undo_manager_free_action_list (GtkSourceUndoManager *um); -static void gtk_source_undo_manager_add_action (GtkSourceUndoManager *um, +static void gtk_source_undo_manager_add_action (GtkSourceUndoManager *um, const GtkSourceUndoAction *undo_action); -static void gtk_source_undo_manager_free_first_n_actions (GtkSourceUndoManager *um, +static void gtk_source_undo_manager_free_first_n_actions (GtkSourceUndoManager *um, gint n); static void gtk_source_undo_manager_check_list_size (GtkSourceUndoManager *um); -static gboolean gtk_source_undo_manager_merge_action (GtkSourceUndoManager *um, +static gboolean gtk_source_undo_manager_merge_action (GtkSourceUndoManager *um, const GtkSourceUndoAction *undo_action); static GObjectClass *parent_class = NULL; @@ -216,7 +216,7 @@ klass->can_undo = NULL; klass->can_redo = NULL; - + undo_manager_signals[CAN_UNDO] = g_signal_new ("can_undo", G_OBJECT_CLASS_TYPE (object_class), @@ -269,7 +269,7 @@ g_return_if_fail (object != NULL); g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (object)); - + um = GTK_SOURCE_UNDO_MANAGER (object); g_return_if_fail (um->priv != NULL); @@ -280,19 +280,19 @@ } g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document), - G_CALLBACK (gtk_source_undo_manager_delete_range_handler), + G_CALLBACK (gtk_source_undo_manager_delete_range_handler), um); g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document), - G_CALLBACK (gtk_source_undo_manager_insert_text_handler), + G_CALLBACK (gtk_source_undo_manager_insert_text_handler), um); - + g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document), - G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler), + G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler), um); - + g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document), - G_CALLBACK (gtk_source_undo_manager_begin_user_action_handler), + G_CALLBACK (gtk_source_undo_manager_begin_user_action_handler), um); g_free (um->priv); @@ -311,19 +311,19 @@ um->priv->document = buffer; g_signal_connect (G_OBJECT (buffer), "insert_text", - G_CALLBACK (gtk_source_undo_manager_insert_text_handler), + G_CALLBACK (gtk_source_undo_manager_insert_text_handler), um); g_signal_connect (G_OBJECT (buffer), "insert_child_anchor", - G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler), + G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler), um); g_signal_connect (G_OBJECT (buffer), "delete_range", - G_CALLBACK (gtk_source_undo_manager_delete_range_handler), + G_CALLBACK (gtk_source_undo_manager_delete_range_handler), um); g_signal_connect (G_OBJECT (buffer), "begin_user_action", - G_CALLBACK (gtk_source_undo_manager_begin_user_action_handler), + G_CALLBACK (gtk_source_undo_manager_begin_user_action_handler), um); g_signal_connect (G_OBJECT (buffer), "modified_changed", @@ -332,7 +332,7 @@ return um; } -void +void gtk_source_undo_manager_begin_not_undoable_action (GtkSourceUndoManager *um) { g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); @@ -341,18 +341,18 @@ ++um->priv->running_not_undoable_actions; } -static void +static void gtk_source_undo_manager_end_not_undoable_action_internal (GtkSourceUndoManager *um) { g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); g_return_if_fail (um->priv != NULL); g_return_if_fail (um->priv->running_not_undoable_actions > 0); - + --um->priv->running_not_undoable_actions; } -void +void gtk_source_undo_manager_end_not_undoable_action (GtkSourceUndoManager *um) { g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); @@ -361,26 +361,26 @@ gtk_source_undo_manager_end_not_undoable_action_internal (um); if (um->priv->running_not_undoable_actions == 0) - { + { gtk_source_undo_manager_free_action_list (um); - - um->priv->next_redo = -1; + + um->priv->next_redo = -1; if (um->priv->can_undo) { um->priv->can_undo = FALSE; - g_signal_emit (G_OBJECT (um), - undo_manager_signals [CAN_UNDO], - 0, + g_signal_emit (G_OBJECT (um), + undo_manager_signals [CAN_UNDO], + 0, FALSE); } if (um->priv->can_redo) { um->priv->can_redo = FALSE; - g_signal_emit (G_OBJECT (um), - undo_manager_signals [CAN_REDO], - 0, + g_signal_emit (G_OBJECT (um), + undo_manager_signals [CAN_REDO], + 0, FALSE); } } @@ -395,7 +395,7 @@ return um->priv->can_undo; } -gboolean +gboolean gtk_source_undo_manager_can_redo (const GtkSourceUndoManager *um) { g_return_val_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um), FALSE); @@ -408,31 +408,31 @@ set_cursor (GtkTextBuffer *buffer, gint cursor) { GtkTextIter iter; - + /* Place the cursor at the requested position */ gtk_text_buffer_get_iter_at_offset (buffer, &iter, cursor); gtk_text_buffer_place_cursor (buffer, &iter); } -static void +static void insert_text (GtkTextBuffer *buffer, gint pos, const gchar *text, gint len) { GtkTextIter iter; - + gtk_text_buffer_get_iter_at_offset (buffer, &iter, pos); gtk_text_buffer_insert (buffer, &iter, text, len); } -static void +static void insert_anchor (GtkTextBuffer *buffer, gint pos, GtkTextChildAnchor *anchor) { GtkTextIter iter; - + gtk_text_buffer_get_iter_at_offset (buffer, &iter, pos); gtk_text_buffer_insert_child_anchor (buffer, &iter, anchor); } -static void +static void delete_text (GtkTextBuffer *buffer, gint start, gint end) { GtkTextIter start_iter; @@ -464,7 +464,7 @@ return gtk_text_buffer_get_slice (buffer, &start_iter, &end_iter, TRUE); } -void +void gtk_source_undo_manager_undo (GtkSourceUndoManager *um) { GtkSourceUndoAction *undo_action; @@ -473,13 +473,13 @@ g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); g_return_if_fail (um->priv != NULL); g_return_if_fail (um->priv->can_undo); - + um->priv->modified_undoing_group = FALSE; gtk_source_undo_manager_begin_not_undoable_action (um); do - { + { undo_action = g_list_nth_data (um->priv->actions, um->priv->next_redo + 1); g_return_if_fail (undo_action != NULL); @@ -490,7 +490,7 @@ if (undo_action->order_in_group <= 1) { /* Set modified to TRUE only if the buffer did not change its state from - * "not modified" to "modified" undoing an action (with order_in_group > 1) + * "not modified" to "modified" undoing an action (with order_in_group > 1) * in current group. */ modified = (undo_action->modified && !um->priv->modified_undoing_group); } @@ -499,31 +499,31 @@ { case GTK_SOURCE_UNDO_ACTION_DELETE: insert_text ( - um->priv->document, - undo_action->action.delete.start, + um->priv->document, + undo_action->action.delete.start, undo_action->action.delete.text, strlen (undo_action->action.delete.text)); if (undo_action->action.delete.forward) set_cursor ( - um->priv->document, + um->priv->document, undo_action->action.delete.start); else set_cursor ( - um->priv->document, + um->priv->document, undo_action->action.delete.end); break; - + case GTK_SOURCE_UNDO_ACTION_INSERT: delete_text ( - um->priv->document, - undo_action->action.insert.pos, - undo_action->action.insert.pos + - undo_action->action.insert.chars); + um->priv->document, + undo_action->action.insert.pos, + undo_action->action.insert.pos + + undo_action->action.insert.chars); set_cursor ( - um->priv->document, + um->priv->document, undo_action->action.insert.pos); break; @@ -551,29 +551,29 @@ } gtk_source_undo_manager_end_not_undoable_action_internal (um); - + um->priv->modified_undoing_group = FALSE; if (!um->priv->can_redo) { um->priv->can_redo = TRUE; - g_signal_emit (G_OBJECT (um), - undo_manager_signals [CAN_REDO], - 0, + g_signal_emit (G_OBJECT (um), + undo_manager_signals [CAN_REDO], + 0, TRUE); } if (um->priv->next_redo >= (gint)(g_list_length (um->priv->actions) - 1)) { um->priv->can_undo = FALSE; - g_signal_emit (G_OBJECT (um), - undo_manager_signals [CAN_UNDO], - 0, + g_signal_emit (G_OBJECT (um), + undo_manager_signals [CAN_UNDO], + 0, FALSE); } } -void +void gtk_source_undo_manager_redo (GtkSourceUndoManager *um) { GtkSourceUndoAction *undo_action; @@ -582,7 +582,7 @@ g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); g_return_if_fail (um->priv != NULL); g_return_if_fail (um->priv->can_redo); - + undo_action = g_list_nth_data (um->priv->actions, um->priv->next_redo); g_return_if_fail (undo_action != NULL); @@ -597,29 +597,29 @@ } --um->priv->next_redo; - + switch (undo_action->action_type) { case GTK_SOURCE_UNDO_ACTION_DELETE: delete_text ( - um->priv->document, - undo_action->action.delete.start, - undo_action->action.delete.end); + um->priv->document, + undo_action->action.delete.start, + undo_action->action.delete.end); set_cursor ( um->priv->document, undo_action->action.delete.start); break; - + case GTK_SOURCE_UNDO_ACTION_INSERT: set_cursor ( um->priv->document, undo_action->action.insert.pos); insert_text ( - um->priv->document, - undo_action->action.insert.pos, + um->priv->document, + undo_action->action.insert.pos, undo_action->action.insert.text, undo_action->action.insert.length); @@ -646,7 +646,7 @@ undo_action = NULL; else undo_action = g_list_nth_data (um->priv->actions, um->priv->next_redo); - + } while ((undo_action != NULL) && (undo_action->order_in_group > 1)); if (modified) @@ -689,7 +689,7 @@ g_free (action); } -static void +static void gtk_source_undo_manager_free_action_list (GtkSourceUndoManager *um) { GList *l; @@ -712,18 +712,18 @@ } g_list_free (um->priv->actions); - um->priv->actions = NULL; + um->priv->actions = NULL; } -static void -gtk_source_undo_manager_insert_text_handler (GtkTextBuffer *buffer, +static void +gtk_source_undo_manager_insert_text_handler (GtkTextBuffer *buffer, GtkTextIter *pos, - const gchar *text, - gint length, + const gchar *text, + gint length, GtkSourceUndoManager *um) { GtkSourceUndoAction undo_action; - + if (um->priv->running_not_undoable_actions > 0) return; @@ -766,15 +766,15 @@ gtk_source_undo_manager_add_action (um, &undo_action); } -static void -gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer, +static void +gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer, GtkTextIter *start, - GtkTextIter *end, + GtkTextIter *end, GtkSourceUndoManager *um) { GtkSourceUndoAction undo_action; GtkTextIter insert_iter; - + if (um->priv->running_not_undoable_actions > 0) return; @@ -805,14 +805,14 @@ undo_action.mergeable = TRUE; undo_action.modified = FALSE; - + gtk_source_undo_manager_add_action (um, &undo_action); g_free (undo_action.action.delete.text); } -static void +static void gtk_source_undo_manager_begin_user_action_handler (GtkTextBuffer *buffer, GtkSourceUndoManager *um) { g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); @@ -825,11 +825,11 @@ } static void -gtk_source_undo_manager_add_action (GtkSourceUndoManager *um, +gtk_source_undo_manager_add_action (GtkSourceUndoManager *um, const GtkSourceUndoAction *undo_action) { GtkSourceUndoAction* action; - + if (um->priv->next_redo >= 0) { gtk_source_undo_manager_free_first_n_actions (um, um->priv->next_redo + 1); @@ -845,7 +845,7 @@ if (action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT) action->action.insert.text = g_strndup (undo_action->action.insert.text, undo_action->action.insert.length); else if (action->action_type == GTK_SOURCE_UNDO_ACTION_DELETE) - action->action.delete.text = g_strdup (undo_action->action.delete.text); + action->action.delete.text = g_strdup (undo_action->action.delete.text); else if (action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR) { /* Nothing needs to be done */ @@ -855,16 +855,16 @@ g_free (action); g_return_if_reached (); } - + ++um->priv->actions_in_current_group; action->order_in_group = um->priv->actions_in_current_group; if (action->order_in_group == 1) ++um->priv->num_of_groups; - + um->priv->actions = g_list_prepend (um->priv->actions, action); } - + gtk_source_undo_manager_check_list_size (um); if (!um->priv->can_undo) @@ -880,8 +880,8 @@ } } -static void -gtk_source_undo_manager_free_first_n_actions (GtkSourceUndoManager *um, +static void +gtk_source_undo_manager_free_first_n_actions (GtkSourceUndoManager *um, gint n) { gint i; @@ -904,21 +904,21 @@ um->priv->actions = g_list_delete_link (um->priv->actions, um->priv->actions); - if (um->priv->actions == NULL) + if (um->priv->actions == NULL) return; } } -static void +static void gtk_source_undo_manager_check_list_size (GtkSourceUndoManager *um) { gint undo_levels; - + g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); g_return_if_fail (um->priv != NULL); - + undo_levels = gtk_source_undo_manager_get_max_undo_levels (um); - + if (undo_levels < 1) return; @@ -926,14 +926,14 @@ { GtkSourceUndoAction *undo_action; GList *last; - + last = g_list_last (um->priv->actions); undo_action = (GtkSourceUndoAction*) last->data; - + do { GList *tmp; - + if (undo_action->order_in_group == 1) --um->priv->num_of_groups; @@ -945,32 +945,32 @@ tmp = g_list_previous (last); um->priv->actions = g_list_delete_link (um->priv->actions, last); last = tmp; - g_return_if_fail (last != NULL); + g_return_if_fail (last != NULL); undo_action = (GtkSourceUndoAction*) last->data; - } while ((undo_action->order_in_group > 1) || + } while ((undo_action->order_in_group > 1) || (um->priv->num_of_groups > undo_levels)); - } + } } /** * gtk_source_undo_manager_merge_action: - * @um: a #GtkSourceUndoManager. + * @um: a #GtkSourceUndoManager. * @undo_action: a #GtkSourceUndoAction. - * + * * This function tries to merge the undo action at the top of * the stack with a new undo action. So when we undo for example * typing, we can undo the whole word and not each letter by itself. - * - * Return Value: %TRUE is merge was sucessful, %FALSE otherwise.² + * + * Return Value: %TRUE is merge was successful, %FALSE otherwise.² **/ -static gboolean -gtk_source_undo_manager_merge_action (GtkSourceUndoManager *um, +static gboolean +gtk_source_undo_manager_merge_action (GtkSourceUndoManager *um, const GtkSourceUndoAction *undo_action) { GtkSourceUndoAction *last_action; - + g_return_val_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um), FALSE); g_return_val_if_fail (um->priv != NULL, FALSE); @@ -990,7 +990,7 @@ } if (undo_action->action_type == GTK_SOURCE_UNDO_ACTION_DELETE) - { + { if ((last_action->action.delete.forward != undo_action->action.delete.forward) || ((last_action->action.delete.start != undo_action->action.delete.start) && (last_action->action.delete.start != undo_action->action.delete.end))) @@ -998,14 +998,14 @@ last_action->mergeable = FALSE; return FALSE; } - + if (last_action->action.delete.start == undo_action->action.delete.start) { gchar *str; - + #define L (last_action->action.delete.end - last_action->action.delete.start - 1) #define g_utf8_get_char_at(p,i) g_utf8_get_char(g_utf8_offset_to_pointer((p),(i))) - + /* Deleted with the delete key */ if ((g_utf8_get_char (undo_action->action.delete.text) != ' ') && (g_utf8_get_char (undo_action->action.delete.text) != '\t') && @@ -1015,19 +1015,19 @@ last_action->mergeable = FALSE; return FALSE; } - - str = g_strdup_printf ("%s%s", last_action->action.delete.text, + + str = g_strdup_printf ("%s%s", last_action->action.delete.text, undo_action->action.delete.text); - + g_free (last_action->action.delete.text); - last_action->action.delete.end += (undo_action->action.delete.end - + last_action->action.delete.end += (undo_action->action.delete.end - undo_action->action.delete.start); last_action->action.delete.text = str; } else { gchar *str; - + /* Deleted with the backspace key */ if ((g_utf8_get_char (undo_action->action.delete.text) != ' ') && (g_utf8_get_char (undo_action->action.delete.text) != '\t') && @@ -1038,9 +1038,9 @@ return FALSE; } - str = g_strdup_printf ("%s%s", undo_action->action.delete.text, + str = g_strdup_printf ("%s%s", undo_action->action.delete.text, last_action->action.delete.text); - + g_free (last_action->action.delete.text); last_action->action.delete.start = undo_action->action.delete.start; last_action->action.delete.text = str; @@ -1049,10 +1049,10 @@ else if (undo_action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT) { gchar* str; - + #define I (last_action->action.insert.chars - 1) - - if ((undo_action->action.insert.pos != + + if ((undo_action->action.insert.pos != (last_action->action.insert.pos + last_action->action.insert.chars)) || ((g_utf8_get_char (undo_action->action.insert.text) != ' ') && (g_utf8_get_char (undo_action->action.insert.text) != '\t') && @@ -1064,9 +1064,9 @@ return FALSE; } - str = g_strdup_printf ("%s%s", last_action->action.insert.text, + str = g_strdup_printf ("%s%s", last_action->action.insert.text, undo_action->action.insert.text); - + g_free (last_action->action.insert.text); last_action->action.insert.length += undo_action->action.insert.length; last_action->action.insert.text = str; @@ -1080,7 +1080,7 @@ else /* Unknown action inside undo merge encountered */ g_return_val_if_reached (TRUE); - + return TRUE; } @@ -1098,7 +1098,7 @@ gint max_undo_levels) { gint old_levels; - + g_return_if_fail (um != NULL); g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); @@ -1107,7 +1107,7 @@ if (max_undo_levels < 1) return; - + if (old_levels > max_undo_levels) { /* strip redo actions first */ @@ -1116,7 +1116,7 @@ gtk_source_undo_manager_free_first_n_actions (um, 1); um->priv->next_redo--; } - + /* now remove undo actions if necessary */ gtk_source_undo_manager_check_list_size (um); @@ -1142,7 +1142,7 @@ { GtkSourceUndoAction *action; GList *list; - + g_return_if_fail (GTK_SOURCE_IS_UNDO_MANAGER (um)); g_return_if_fail (um->priv != NULL); @@ -1157,7 +1157,7 @@ action = NULL; if (gtk_text_buffer_get_modified (buffer) == FALSE) - { + { if (action != NULL) action->mergeable = FALSE; @@ -1178,7 +1178,7 @@ return; } - + /* gtk_text_buffer_get_modified (buffer) == TRUE */ g_return_if_fail (um->priv->modified_action == NULL); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtksourceundomanager.h --- a/pidgin/gtksourceundomanager.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtksourceundomanager.h Wed Jan 28 10:23:37 2009 +0000 @@ -4,8 +4,8 @@ * This file is part of GtkSourceView * * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence - * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi - * Copyright (C) 2002, 2003 Paolo Maggi + * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi + * Copyright (C) 2002, 2003 Paolo Maggi * * 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 @@ -19,10 +19,10 @@ * * 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, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02111-1301, USA. * * */ - + #ifndef __GTK_SOURCE_UNDO_MANAGER_H__ #define __GTK_SOURCE_UNDO_MANAGER_H__ @@ -44,7 +44,7 @@ struct _GtkSourceUndoManager { GObject base; - + GtkSourceUndoManagerPrivate *priv; }; @@ -67,14 +67,14 @@ void gtk_source_undo_manager_undo (GtkSourceUndoManager *um); void gtk_source_undo_manager_redo (GtkSourceUndoManager *um); -void gtk_source_undo_manager_begin_not_undoable_action +void gtk_source_undo_manager_begin_not_undoable_action (GtkSourceUndoManager *um); -void gtk_source_undo_manager_end_not_undoable_action +void gtk_source_undo_manager_end_not_undoable_action (GtkSourceUndoManager *um); -gint gtk_source_undo_manager_get_max_undo_levels +gint gtk_source_undo_manager_get_max_undo_levels (GtkSourceUndoManager *um); -void gtk_source_undo_manager_set_max_undo_levels +void gtk_source_undo_manager_set_max_undo_levels (GtkSourceUndoManager *um, gint undo_levels); diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkstatus-icon-theme.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkstatus-icon-theme.c Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,72 @@ +/* + * Status Icon Themes for Pidgin + * + * Pidgin 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 "gtkstatus-icon-theme.h" + +/****************************************************************************** + * Globals + *****************************************************************************/ + +static GObjectClass *parent_class = NULL; + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ + +static void +pidgin_status_icon_theme_finalize(GObject *obj) +{ + parent_class->finalize(obj); +} + +static void +pidgin_status_icon_theme_class_init(PidginStatusIconThemeClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = g_type_class_peek_parent(klass); + + obj_class->finalize = pidgin_status_icon_theme_finalize; +} + +GType +pidgin_status_icon_theme_get_type(void) +{ + static GType type = 0; + if (type == 0) { + static const GTypeInfo info = { + sizeof (PidginStatusIconThemeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)pidgin_status_icon_theme_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PidginStatusIconTheme), + 0, /* n_preallocs */ + NULL, + NULL, /* value table */ + }; + type = g_type_register_static(PIDGIN_TYPE_ICON_THEME, + "PidginStatusIconTheme", &info, 0); + } + return type; +} diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkstatus-icon-theme.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/gtkstatus-icon-theme.h Wed Jan 28 10:23:37 2009 +0000 @@ -0,0 +1,71 @@ +/** + * @file status_icon-theme.h Pidgin Icon Theme Class API + */ + +/* pidgin + * + * Pidgin 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 + */ + +#ifndef PIDGIN_STATUS_ICON_THEME_H +#define PIDGIN_STATUS_ICON_THEME_H + +#include +#include "gtkicon-theme.h" + +/** + * extends PidginIconTheme (gtkicon-theme.h) + * A pidgin status icon theme. + * This object represents a Pidgin status icon theme. + * + * PidginStatusIconTheme is a PidginIconTheme Object. + */ +typedef struct _PidginStatusIconTheme PidginStatusIconTheme; +typedef struct _PidginStatusIconThemeClass PidginStatusIconThemeClass; + +#define PIDGIN_TYPE_STATUS_ICON_THEME (pidgin_status_icon_theme_get_type ()) +#define PIDGIN_STATUS_ICON_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIDGIN_TYPE_STATUS_ICON_THEME, PidginStatusIconTheme)) +#define PIDGIN_STATUS_ICON_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIDGIN_TYPE_STATUS_ICON_THEME, PidginStatusIconThemeClass)) +#define PIDGIN_IS_STATUS_ICON_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIDGIN_TYPE_STATUS_ICON_THEME)) +#define PIDGIN_IS_STATUS_ICON_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIDGIN_TYPE_STATUS_ICON_THEME)) +#define PIDGIN_STATUS_ICON_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIDGIN_TYPE_STATUS_ICON_THEME, PidginStatusIconThemeClass)) + +struct _PidginStatusIconTheme +{ + PidginIconTheme parent; +}; + +struct _PidginStatusIconThemeClass +{ + PidginIconThemeClass parent_class; +}; + +/**************************************************************************/ +/** @name Pidgin Status Icon Theme API */ +/**************************************************************************/ +G_BEGIN_DECLS + +/** + * GObject foo. + * @internal. + */ +GType pidgin_status_icon_theme_get_type(void); + +G_END_DECLS +#endif /* PIDGIN_STATUS_ICON_THEME_H */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkstatusbox.c --- a/pidgin/gtkstatusbox.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkstatusbox.c Wed Jan 28 10:23:37 2009 +0000 @@ -1646,7 +1646,7 @@ pidgin_status_box_popdown (status_box); return TRUE; } else if (ewidget == status_box->toggle_button) { - status_box->popup_in_progress = TRUE; + status_box->popup_in_progress = TRUE; } /* released outside treeview */ @@ -1698,7 +1698,7 @@ gtk_tree_path_free (path); return ret; } - } + } } return FALSE; } @@ -1777,9 +1777,9 @@ status_box->vsep = gtk_vseparator_new(); status_box->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - status_box->store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, + status_box->store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN); - status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, + status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN); gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); @@ -2529,7 +2529,7 @@ { GtkTextBuffer *buffer; GtkTextIter iter; - int wrapped_lines; + int display_lines; int lines; GdkRectangle oneline; int height; @@ -2545,28 +2545,44 @@ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml)); height = 0; - wrapped_lines = 1; + display_lines = 1; gtk_text_buffer_get_start_iter(buffer, &iter); do { gtk_text_view_get_iter_location(GTK_TEXT_VIEW(status_box->imhtml), &iter, &oneline); height += oneline.height; - wrapped_lines++; - if (wrapped_lines > 4) - break; - } while (gtk_text_view_forward_display_line(GTK_TEXT_VIEW(status_box->imhtml), &iter)); + display_lines++; + } while (display_lines <= 4 && + gtk_text_view_forward_display_line(GTK_TEXT_VIEW(status_box->imhtml), &iter)); + + /* + * This check fixes the case where the last character entered is a + * newline (shift+return). For some reason the + * gtk_text_view_forward_display_line() function doesn't treat this + * like a new line, and so we think the input box only needs to be + * two lines instead of three, for example. So we check if the + * last character was a newline and add some extra height if so. + */ + if (display_lines <= 4 + && gtk_text_iter_backward_char(&iter) + && gtk_text_iter_get_char(&iter) == '\n') + { + gtk_text_view_get_iter_location(GTK_TEXT_VIEW(status_box->imhtml), &iter, &oneline); + height += oneline.height; + display_lines++; + } lines = gtk_text_buffer_get_line_count(buffer); /* Show a maximum of 4 lines */ lines = MIN(lines, 4); - wrapped_lines = MIN(wrapped_lines, 4); + display_lines = MIN(display_lines, 4); pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(status_box->imhtml)); pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(status_box->imhtml)); pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(status_box->imhtml)); height += (pad_top + pad_bottom) * lines; - height += (pad_inside) * (wrapped_lines - lines); + height += (pad_inside) * (display_lines - lines); gtk_widget_set_size_request(status_box->vbox, -1, height + PIDGIN_HIG_BOX_SPACE); } diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkthemes.c --- a/pidgin/gtkthemes.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkthemes.c Wed Jan 28 10:23:37 2009 +0000 @@ -83,7 +83,7 @@ { char *theme_dir = NULL, *last_slash = NULL; g_return_if_fail(NULL != file); - + if (!g_file_test(file, G_FILE_TEST_EXISTS)) return; if ((theme_dir = g_strdup(file)) == NULL) return ; @@ -169,12 +169,12 @@ for (wer = theme->list; wer != NULL; wer = theme->list) { while (wer->smileys) { GtkIMHtmlSmiley *uio = wer->smileys->data; - + if (uio->imhtml) { g_signal_handlers_disconnect_matched(uio->imhtml, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, uio); } - + if (uio->icon) g_object_unref(uio->icon); if (g_hash_table_lookup(already_freed, uio->file) == NULL) { diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkutils.c --- a/pidgin/gtkutils.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkutils.c Wed Jan 28 10:23:37 2009 +0000 @@ -56,6 +56,9 @@ #include "signals.h" #include "util.h" +#include "gtkaccount.h" +#include "gtkprefs.h" + #include "gtkconv.h" #include "gtkdialogs.h" #include "gtkimhtml.h" @@ -71,6 +74,7 @@ } AopMenu; static guint accels_save_timer = 0; +static GList *gnome_url_handlers = NULL; static gboolean url_clicked_idle_cb(gpointer data) @@ -80,10 +84,12 @@ return FALSE; } -static void -url_clicked_cb(GtkWidget *w, const char *uri) +static gboolean +url_clicked_cb(GtkIMHtml *unused, GtkIMHtmlLink *link) { + const char *uri = gtk_imhtml_link_get_url(link); g_idle_add(url_clicked_idle_cb, g_strdup(uri)); + return TRUE; } static GtkIMHtmlFuncs gtkimhtml_cbs = { @@ -102,9 +108,6 @@ g_return_if_fail(imhtml != NULL); g_return_if_fail(GTK_IS_IMHTML(imhtml)); - g_signal_connect(G_OBJECT(imhtml), "url_clicked", - G_CALLBACK(url_clicked_cb), NULL); - pidgin_themes_smiley_themeize(imhtml); gtk_imhtml_set_funcs(GTK_IMHTML(imhtml), >kimhtml_cbs); @@ -567,7 +570,7 @@ gtk_widget_show (label); gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - + gtk_container_add(GTK_CONTAINER(item), hbox); gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); @@ -1924,7 +1927,7 @@ #endif /* !NEW_STYLE_COMPLETION */ #ifdef NEW_STYLE_COMPLETION -static gboolean screenname_completion_match_func(GtkEntryCompletion *completion, +static gboolean buddyname_completion_match_func(GtkEntryCompletion *completion, const gchar *key, GtkTreeIter *iter, gpointer user_data) { GtkTreeModel *model; @@ -1957,7 +1960,7 @@ return FALSE; } -static gboolean screenname_completion_match_selected_cb(GtkEntryCompletion *completion, +static gboolean buddyname_completion_match_selected_cb(GtkEntryCompletion *completion, GtkTreeModel *model, GtkTreeIter *iter, PidginCompletionData *data) { GValue val; @@ -1983,22 +1986,22 @@ } static void -add_screenname_autocomplete_entry(GtkListStore *store, const char *buddy_alias, const char *contact_alias, - const PurpleAccount *account, const char *screenname) +add_buddyname_autocomplete_entry(GtkListStore *store, const char *buddy_alias, const char *contact_alias, + const PurpleAccount *account, const char *buddyname) { GtkTreeIter iter; gboolean completion_added = FALSE; - gchar *normalized_screenname; + gchar *normalized_buddyname; gchar *tmp; - tmp = g_utf8_normalize(screenname, -1, G_NORMALIZE_DEFAULT); - normalized_screenname = g_utf8_casefold(tmp, -1); + tmp = g_utf8_normalize(buddyname, -1, G_NORMALIZE_DEFAULT); + normalized_buddyname = g_utf8_casefold(tmp, -1); g_free(tmp); /* There's no sense listing things like: 'xxx "xxx"' - when the screenname and buddy alias match. */ - if (buddy_alias && strcmp(buddy_alias, screenname)) { - char *completion_entry = g_strdup_printf("%s \"%s\"", screenname, buddy_alias); + when the name and buddy alias match. */ + if (buddy_alias && strcmp(buddy_alias, buddyname)) { + char *completion_entry = g_strdup_printf("%s \"%s\"", buddyname, buddy_alias); char *tmp2 = g_utf8_normalize(buddy_alias, -1, G_NORMALIZE_DEFAULT); tmp = g_utf8_casefold(tmp2, -1); @@ -2007,8 +2010,8 @@ gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, completion_entry, - 1, screenname, - 2, normalized_screenname, + 1, buddyname, + 2, normalized_buddyname, 3, tmp, 4, account, -1); @@ -2018,12 +2021,12 @@ } /* There's no sense listing things like: 'xxx "xxx"' - when the screenname and contact alias match. */ - if (contact_alias && strcmp(contact_alias, screenname)) { + when the name and contact alias match. */ + if (contact_alias && strcmp(contact_alias, buddyname)) { /* We don't want duplicates when the contact and buddy alias match. */ if (!buddy_alias || strcmp(contact_alias, buddy_alias)) { char *completion_entry = g_strdup_printf("%s \"%s\"", - screenname, contact_alias); + buddyname, contact_alias); char *tmp2 = g_utf8_normalize(contact_alias, -1, G_NORMALIZE_DEFAULT); tmp = g_utf8_casefold(tmp2, -1); @@ -2032,8 +2035,8 @@ gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, completion_entry, - 1, screenname, - 2, normalized_screenname, + 1, buddyname, + 2, normalized_buddyname, 3, tmp, 4, account, -1); @@ -2044,18 +2047,18 @@ } if (completion_added == FALSE) { - /* Add the buddy's screenname. */ + /* Add the buddy's name. */ gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, - 0, screenname, - 1, screenname, - 2, normalized_screenname, + 0, buddyname, + 1, buddyname, + 2, normalized_buddyname, 3, NULL, 4, account, -1); } - g_free(normalized_screenname); + g_free(normalized_buddyname); } #endif /* NEW_STYLE_COMPLETION */ @@ -2064,8 +2067,8 @@ PidginFilterBuddyCompletionEntryFunc filter_func = data->filter_func; gpointer user_data = data->filter_func_user_data; - /* 1. Don't show buddies because we will have gotten them already. - * 2. The boxes that use this autocomplete code handle only IMs. */ + /* 1. Don't show buddies because we will have gotten them already. + * 2. The boxes that use this autocomplete code handle only IMs. */ if (!set->buddy && set->type == PURPLE_LOG_IM) { PidginBuddyCompletionEntry entry; entry.is_buddy = FALSE; @@ -2073,7 +2076,7 @@ if (filter_func(&entry, user_data)) { #ifdef NEW_STYLE_COMPLETION - add_screenname_autocomplete_entry(data->store, + add_buddyname_autocomplete_entry(data->store, NULL, NULL, set->account, set->name); #else /* Steal the name for the GCompletion. */ @@ -2119,7 +2122,7 @@ if (filter_func(&entry, user_data)) { #ifdef NEW_STYLE_COMPLETION - add_screenname_autocomplete_entry(data->store, + add_buddyname_autocomplete_entry(data->store, ((PurpleContact *)cnode)->alias, purple_buddy_get_contact_alias(entry.entry.buddy), entry.entry.buddy->account, @@ -2150,7 +2153,7 @@ } static void -screenname_autocomplete_destroyed_cb(GtkWidget *widget, gpointer data) +buddyname_autocomplete_destroyed_cb(GtkWidget *widget, gpointer data) { g_free(data); purple_signals_disconnect_by_handle(widget); @@ -2162,15 +2165,17 @@ add_completion_list(data); } - void pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *accountopt, PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data) { PidginCompletionData *data; #ifdef NEW_STYLE_COMPLETION - /* Store the displayed completion value, the screenname, the UTF-8 normalized & casefolded screenname, - * the UTF-8 normalized & casefolded value for comparison, and the account. */ + /* + * Store the displayed completion value, the buddy name, the UTF-8 + * normalized & casefolded buddy name, the UTF-8 normalized & + * casefolded value for comparison, and the account. + */ GtkListStore *store; GtkEntryCompletion *completion; @@ -2191,15 +2196,15 @@ add_completion_list(data); - /* Sort the completion list by screenname. */ + /* Sort the completion list by buddy name */ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 1, GTK_SORT_ASCENDING); completion = gtk_entry_completion_new(); - gtk_entry_completion_set_match_func(completion, screenname_completion_match_func, NULL, NULL); + gtk_entry_completion_set_match_func(completion, buddyname_completion_match_func, NULL, NULL); g_signal_connect(G_OBJECT(completion), "match-selected", - G_CALLBACK(screenname_completion_match_selected_cb), data); + G_CALLBACK(buddyname_completion_match_selected_cb), data); gtk_entry_set_completion(GTK_ENTRY(entry), completion); g_object_unref(completion); @@ -2246,7 +2251,7 @@ purple_signal_connect(purple_accounts_get_handle(), "account-removed", entry, PURPLE_CALLBACK(repopulate_autocomplete), data); - g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(screenname_autocomplete_destroyed_cb), data); + g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(buddyname_autocomplete_destroyed_cb), data); } gboolean @@ -3240,7 +3245,7 @@ style = gtk_widget_get_style(widget); if (!style) return "dim grey"; - + snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x", style->text_aa[GTK_STATE_NORMAL].red >> 8, style->text_aa[GTK_STATE_NORMAL].green >> 8, @@ -3480,3 +3485,198 @@ return pixbuf; } +static void url_copy(GtkWidget *w, gchar *url) +{ + GtkClipboard *clipboard; + + clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clipboard, url, -1); + + clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, url, -1); +} + +static gboolean +link_context_menu(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu) +{ + GtkWidget *img, *item; + const char *url; + + url = gtk_imhtml_link_get_url(link); + + /* Open Link */ + img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU); + item = gtk_image_menu_item_new_with_mnemonic(_("_Open Link")); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); + g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_link_activate), link); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + /* Copy Link Location */ + img = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); + item = gtk_image_menu_item_new_with_mnemonic(_("_Copy Link Location")); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(url_copy), (gpointer)url); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + return TRUE; +} + +static gboolean +copy_email_address(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu) +{ + GtkWidget *img, *item; + const char *text; + char *address; +#define MAILTOSIZE (sizeof("mailto:") - 1) + + text = gtk_imhtml_link_get_url(link); + g_return_val_if_fail(text && strlen(text) > MAILTOSIZE, FALSE); + address = (char*)text + MAILTOSIZE; + + /* Copy Email Address */ + img = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); + item = gtk_image_menu_item_new_with_mnemonic(_("_Copy Email Address")); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(url_copy), address); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + return TRUE; +} + +/* XXX: The following two functions are for demonstration purposes only! */ +static gboolean +open_dialog(GtkIMHtml *imhtml, GtkIMHtmlLink *link) +{ + const char *url; + const char *str; + + url = gtk_imhtml_link_get_url(link); + if (!url || strlen(url) < sizeof("open://")) + return FALSE; + + str = url + sizeof("open://") - 1; + + if (strcmp(str, "accounts") == 0) + pidgin_accounts_window_show(); + else if (strcmp(str, "prefs") == 0) + pidgin_prefs_show(); + else + return FALSE; + return TRUE; +} + +static gboolean +dummy(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu) +{ + return TRUE; +} + +static gboolean +register_gnome_url_handlers(void) +{ + char *tmp; + char *err; + char *c; + char *start; + + tmp = g_find_program_in_path("gconftool-2"); + if (tmp == NULL) + return FALSE; + + tmp = NULL; + if (!g_spawn_command_line_sync("gconftool-2 --all-dirs /desktop/gnome/url-handlers", + &tmp, &err, NULL, NULL)) + { + g_free(tmp); + g_free(err); + g_return_val_if_reached(FALSE); + } + g_free(err); + err = NULL; + + for (c = start = tmp ; *c ; c++) + { + /* Skip leading spaces. */ + if (c == start && *c == ' ') + start = c + 1; + else if (*c == '\n') + { + *c = '\0'; + if (g_str_has_prefix(start, "/desktop/gnome/url-handlers/")) + { + char *cmd; + char *tmp2 = NULL; + char *protocol; + + /* If there is an enabled boolean, honor it. */ + cmd = g_strdup_printf("gconftool-2 -g %s/enabled", start); + if (g_spawn_command_line_sync(cmd, &tmp2, &err, NULL, NULL)) + { + g_free(err); + err = NULL; + if (!strcmp(tmp2, "false\n")) + { + g_free(tmp2); + g_free(cmd); + start = c + 1; + continue; + } + } + g_free(cmd); + g_free(tmp2); + + start += sizeof("/desktop/gnome/url-handlers/") - 1; + + protocol = g_strdup_printf("%s:", start); + gnome_url_handlers = g_list_prepend(gnome_url_handlers, protocol); + gtk_imhtml_class_register_protocol(protocol, url_clicked_cb, link_context_menu); + } + start = c + 1; + } + } + g_free(tmp); + + return (gnome_url_handlers != NULL); +} + +void pidgin_utils_init(void) +{ + gtk_imhtml_class_register_protocol("http://", url_clicked_cb, link_context_menu); + gtk_imhtml_class_register_protocol("https://", url_clicked_cb, link_context_menu); + gtk_imhtml_class_register_protocol("ftp://", url_clicked_cb, link_context_menu); + gtk_imhtml_class_register_protocol("gopher://", url_clicked_cb, link_context_menu); + gtk_imhtml_class_register_protocol("mailto:", url_clicked_cb, copy_email_address); + + /* Example custom URL handler. */ + gtk_imhtml_class_register_protocol("open://", open_dialog, dummy); + + /* If we're under GNOME, try registering the system URL handlers. */ + if (purple_running_gnome()) + register_gnome_url_handlers(); +} + +void pidgin_utils_uninit(void) +{ + gtk_imhtml_class_register_protocol("open://", NULL, NULL); + + /* If we have GNOME handlers registered, unregister them. */ + if (gnome_url_handlers) + { + GList *l; + for (l = gnome_url_handlers ; l ; l = l->next) + { + gtk_imhtml_class_register_protocol((char *)l->data, NULL, NULL); + g_free(l->data); + } + g_list_free(gnome_url_handlers); + gnome_url_handlers = NULL; + return; + } + + gtk_imhtml_class_register_protocol("http://", NULL, NULL); + gtk_imhtml_class_register_protocol("https://", NULL, NULL); + gtk_imhtml_class_register_protocol("ftp://", NULL, NULL); + gtk_imhtml_class_register_protocol("mailto:", NULL, NULL); + gtk_imhtml_class_register_protocol("gopher://", NULL, NULL); +} + diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkutils.h --- a/pidgin/gtkutils.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkutils.h Wed Jan 28 10:23:37 2009 +0000 @@ -136,7 +136,7 @@ * Retrieves the main content box (vbox) from a pidgin dialog window * * @param dialog The dialog window - * @param homogeneous TRUE if all children are to be given equal space allotments. + * @param homogeneous TRUE if all children are to be given equal space allotments. * @param spacing the number of pixels to place by default between children * * @since 2.4.0 @@ -184,8 +184,8 @@ void pidgin_toggle_sensitive(GtkWidget *widget, GtkWidget *to_toggle); /** - * Checks if text has been entered into a GtkTextEntry widget. If - * so, the GTK_RESPONSE_OK on the given dialog is set to TRUE. + * Checks if text has been entered into a GtkTextEntry widget. If + * so, the GTK_RESPONSE_OK on the given dialog is set to TRUE. * Otherwise GTK_RESPONSE_OK is set to FALSE. * * @param entry The text entry widget. @@ -355,7 +355,7 @@ * * @param entry The GtkEntry on which to setup autocomplete. * @param optmenu A menu for accounts, returned by gaim_gtk_account_option_menu_new(). - * If @a optmenu is not @c NULL, it'll be updated when a screenname is chosen + * If @a optmenu is not @c NULL, it'll be updated when a username is chosen * from the autocomplete list. * @param filter_func A function for checking if an autocomplete entry * should be shown. This can be @c NULL. @@ -364,7 +364,7 @@ void pidgin_setup_screenname_autocomplete_with_filter(GtkWidget *entry, GtkWidget *optmenu, PidginFilterBuddyCompletionEntryFunc filter_func, gpointer user_data); /** - * The default filter function for screenname autocomplete. + * The default filter function for username autocomplete. * * @param completion_entry The completion entry to filter. * @param all_accounts If this is @c FALSE, only the autocompletion entries @@ -385,9 +385,9 @@ * @param entry The GtkEntry on which to setup autocomplete. * @param optmenu A menu for accounts, returned by * pidgin_account_option_menu_new(). If @a optmenu is not @c - * NULL, it'll be updated when a screenname is chosen from the + * NULL, it'll be updated when a username is chosen from the * autocomplete list. - * @param all Whether to include screennames from disconnected accounts. + * @param all Whether to include usernames from disconnected accounts. */ void pidgin_setup_screenname_autocomplete(GtkWidget *entry, GtkWidget *optmenu, gboolean all); @@ -473,7 +473,7 @@ char **ret_alias); /** - * Sets an ATK name for a given widget. Also sets the labelled-by + * Sets an ATK name for a given widget. Also sets the labelled-by * and label-for ATK relationships. * * @param w The widget that we want to name. @@ -509,10 +509,10 @@ gboolean *push_in, gpointer data); /** - * A valid GtkMenuPositionFunc. This is used to determine where - * to draw context menus when the menu is activated with the - * keyboard (shift+F10). If the menu is activated with the mouse, - * then you should just use GTK's built-in position function, + * A valid GtkMenuPositionFunc. This is used to determine where + * to draw context menus when the menu is activated with the + * keyboard (shift+F10). If the menu is activated with the mouse, + * then you should just use GTK's built-in position function, * because it does a better job of positioning the menu. * * @param menu The menu we are positioning. @@ -612,13 +612,13 @@ * @param parent The parent window * @param callback The callback to call when the window is closed. If the user chose an icon, the char* argument will point to its path * @param data Data to pass to @a callback - * @return The file dialog + * @return The file dialog */ GtkWidget *pidgin_buddy_icon_chooser_new(GtkWindow *parent, void(*callback)(const char*,gpointer), gpointer data); /** * Converts a buddy icon to the required size and format - * + * * @param plugin The prpl to convert the icon * @param path The path of a file to convert * @param len If not @c NULL, the length of the returned data will be set here. @@ -706,7 +706,7 @@ const gchar *key, GtkTreeIter *iter, gpointer data); /** - * Sets or resets a window to 'urgent,' by setting the URGENT hint in X + * Sets or resets a window to 'urgent,' by setting the URGENT hint in X * or blinking in the win32 taskbar * * @param window The window to draw attention to @@ -792,7 +792,8 @@ * * @param window The window to make transient. * - * @return Whether the window was made transient or not. + * @return Whether the window was made transient or not. + * * @since 2.4.0 */ gboolean pidgin_auto_parent_window(GtkWidget *window); @@ -818,9 +819,24 @@ * @param image A PurpleStoredImage. * * @return A GdkPixbuf created from the stored image. + * * @since 2.5.0 */ -GdkPixbuf * pidgin_pixbuf_from_imgstore(PurpleStoredImage *image); +GdkPixbuf *pidgin_pixbuf_from_imgstore(PurpleStoredImage *image); + +/** + * Initialize some utility functions. + * + * @since 2.6.0 + */ +void pidgin_utils_init(void); + +/** + * Uninitialize some utility functions. + * + * @since 2.6.0 + */ +void pidgin_utils_uninit(void); #endif /* _PIDGINUTILS_H_ */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/gtkwhiteboard.c --- a/pidgin/gtkwhiteboard.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/gtkwhiteboard.c Wed Jan 28 10:23:37 2009 +0000 @@ -857,7 +857,7 @@ { GdkColor color; GtkColorSelectionDialog *dialog; - + dialog = (GtkColorSelectionDialog *)gtk_color_selection_dialog_new(_("Select color")); g_signal_connect(G_OBJECT(dialog->colorsel), "color-changed", diff -r 29f953732186 -r 8c8948b9f602 pidgin/pidgincombobox.c --- a/pidgin/pidgincombobox.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/pidgincombobox.c Wed Jan 28 10:23:37 2009 +0000 @@ -112,7 +112,7 @@ /* While debugging this evil code, I have learned that * there are actually 4 modes to this widget, which can * be characterized as follows - * + * * 1) menu mode, no child added * * tree_view -> NULL @@ -127,9 +127,9 @@ * popup_frame -> NULL * * 2) menu mode, child added - * + * * tree_view -> NULL - * cell_view -> NULL + * cell_view -> NULL * cell_view_frame -> NULL * button -> GtkToggleButton set_parent to combo * box -> NULL @@ -140,7 +140,7 @@ * popup_frame -> NULL * * 3) list mode, no child added - * + * * tree_view -> GtkTreeView, child of popup_frame * cell_view -> GtkCellView, regular child * cell_view_frame -> GtkFrame, set parent to combo @@ -164,7 +164,7 @@ * popup_widget -> tree_view * popup_window -> GtkWindow * popup_frame -> GtkFrame, child of popup_window - * + * */ enum { @@ -285,9 +285,9 @@ gpointer data); /* list */ -static void gtk_combo_box_list_position (GtkComboBox *combo_box, - gint *x, - gint *y, +static void gtk_combo_box_list_position (GtkComboBox *combo_box, + gint *x, + gint *y, gint *width, gint *height); @@ -641,7 +641,7 @@ if (GTK_WIDGET_REALIZED (widget)) { if (combo_box->priv->tree_view && combo_box->priv->cell_view) - gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), + gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), &widget->style->base[GTK_WIDGET_STATE (widget)]); } @@ -694,7 +694,7 @@ gtk_combo_box_check_appearance (combo_box); if (combo_box->priv->tree_view && combo_box->priv->cell_view) - gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), + gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), &widget->style->base[GTK_WIDGET_STATE (widget)]); } @@ -725,7 +725,7 @@ GTK_BIN (container)->child = NULL; gtk_widget_queue_resize (GTK_WIDGET (container)); } - + gtk_widget_set_parent (widget, GTK_WIDGET (container)); GTK_BIN (container)->child = widget; @@ -770,7 +770,7 @@ appears_as_list = FALSE; else appears_as_list = TRUE; - + if (appears_as_list) gtk_combo_box_list_destroy (combo_box); else if (GTK_IS_MENU (combo_box->priv->popup_widget)) @@ -785,7 +785,7 @@ combo_box->priv->cell_view = gtk_cell_view_new (); gtk_widget_set_parent (combo_box->priv->cell_view, GTK_WIDGET (container)); GTK_BIN (container)->child = combo_box->priv->cell_view; - + gtk_widget_show (combo_box->priv->cell_view); gtk_cell_view_set_model (GTK_CELL_VIEW (combo_box->priv->cell_view), combo_box->priv->model); @@ -856,7 +856,7 @@ g_signal_handlers_disconnect_by_func (menu, gtk_combo_box_menu_hide, combo_box); - + combo_box->priv->popup_widget = NULL; } @@ -940,12 +940,12 @@ GdkScreen *screen; gint monitor_num; GdkRectangle monitor; - + /* FIXME: is using the size request here broken? */ child = GTK_BIN (combo_box)->child; - + gdk_window_get_origin (child->window, &sx, &sy); - + if (GTK_WIDGET_NO_WINDOW (child)) { sx += child->allocation.x; @@ -961,20 +961,20 @@ *y = sy; screen = gtk_widget_get_screen (GTK_WIDGET (combo_box)); - monitor_num = gdk_screen_get_monitor_at_window (screen, + monitor_num = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (combo_box)->window); gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); - + if (*x < monitor.x) *x = monitor.x; else if (*x + req.width > monitor.x + monitor.width) *x = monitor.x + monitor.width - req.width; - + if (monitor.y + monitor.height - *y - child->allocation.height >= req.height) *y += child->allocation.height; else if (*y - monitor.y >= req.height) *y -= req.height; - else if (monitor.y + monitor.height - *y - child->allocation.height > *y - monitor.y) + else if (monitor.y + monitor.height - *y - child->allocation.height > *y - monitor.y) *y += child->allocation.height; else *y -= req.height; @@ -1001,7 +1001,7 @@ gint menu_width; g_return_if_fail (GTK_IS_COMBO_BOX (user_data)); - + combo_box = GTK_COMBO_BOX (user_data); widget = GTK_WIDGET (combo_box); @@ -1042,7 +1042,7 @@ /* Clamp the position on screen */ screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget)); - + if (menu_xpos < 0) menu_xpos = 0; else if ((menu_xpos + menu_width) > screen_width) @@ -1066,13 +1066,13 @@ combo_box = GTK_COMBO_BOX (user_data); - if (combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL) + if (combo_box->priv->wrap_width > 0 || combo_box->priv->cell_view == NULL) gtk_combo_box_menu_position_below (menu, x, y, push_in, user_data); else { menu_item = gtk_menu_get_active (GTK_MENU (combo_box->priv->popup_widget)); if (menu_item) - gtk_menu_shell_select_item (GTK_MENU_SHELL (combo_box->priv->popup_widget), + gtk_menu_shell_select_item (GTK_MENU_SHELL (combo_box->priv->popup_widget), menu_item); gtk_combo_box_menu_position_over (menu, x, y, push_in, user_data); @@ -1082,9 +1082,9 @@ #endif /* Gtk 2.2 */ static void -gtk_combo_box_list_position (GtkComboBox *combo_box, - gint *x, - gint *y, +gtk_combo_box_list_position (GtkComboBox *combo_box, + gint *x, + gint *y, gint *width, gint *height) { @@ -1095,7 +1095,7 @@ gint monitor_num; GdkRectangle monitor; #endif - + sample = GTK_BIN (combo_box)->child; *width = sample->allocation.width; @@ -1117,30 +1117,30 @@ *x += sample->allocation.x; *y += sample->allocation.y; } - + #if GTK_CHECK_VERSION(2,2,0) screen = gtk_widget_get_screen (GTK_WIDGET (combo_box)); - monitor_num = gdk_screen_get_monitor_at_window (screen, + monitor_num = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (combo_box)->window); gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); - + if (*x < monitor.x) *x = monitor.x; else if (*x + *width > monitor.x + monitor.width) *x = monitor.x + monitor.width - *width; - + if (*y + sample->allocation.height + *height <= monitor.y + monitor.height) *y += sample->allocation.height; else *y -= *height; #endif /* Gtk 2.2 */ -} +} /** * gtk_combo_box_popup: * @combo_box: a #GtkComboBox - * - * Pops up the menu or dropdown list of @combo_box. + * + * Pops up the menu or dropdown list of @combo_box. * * This function is mostly intended for use by accessibility technologies; * applications should have little use for it. @@ -1151,7 +1151,7 @@ gtk_combo_box_popup (GtkComboBox *combo_box) { gint x, y, width, height; - + g_return_if_fail (GTK_IS_COMBO_BOX (combo_box)); if (GTK_WIDGET_MAPPED (combo_box->priv->popup_widget)) @@ -1172,7 +1172,7 @@ gtk_widget_set_size_request (combo_box->priv->popup_widget, MAX (width, requisition.width), -1); } - + gtk_menu_popup (GTK_MENU (combo_box->priv->popup_widget), NULL, NULL, #if GTK_CHECK_VERSION(2,2,0) @@ -1187,7 +1187,7 @@ gtk_widget_show_all (combo_box->priv->popup_frame); gtk_combo_box_list_position (combo_box, &x, &y, &width, &height); - gtk_widget_set_size_request (combo_box->priv->popup_window, width, -1); + gtk_widget_set_size_request (combo_box->priv->popup_window, width, -1); gtk_window_move (GTK_WINDOW (combo_box->priv->popup_window), x, y); /* popup */ @@ -1217,7 +1217,7 @@ /** * gtk_combo_box_popdown: * @combo_box: a #GtkComboBox - * + * * Hides the menu or dropdown list of @combo_box. * * This function is mostly intended for use by accessibility technologies; @@ -1305,7 +1305,7 @@ GtkRequisition req; if (combo_box->priv->cell_view) - gtk_cell_view_get_size_of_row (GTK_CELL_VIEW (combo_box->priv->cell_view), + gtk_cell_view_get_size_of_row (GTK_CELL_VIEW (combo_box->priv->cell_view), path, &req); else req.width = 0; @@ -1335,7 +1335,7 @@ bin_req.width = MAX (bin_req.width, combo_box->priv->width); gtk_combo_box_check_appearance (combo_box); - + if (!combo_box->priv->tree_view) { /* menu mode */ @@ -1454,10 +1454,10 @@ if (is_rtl) { child.x += req.width; - child.width = MAX(1, allocation->x + allocation->width + child.width = MAX(1, allocation->x + allocation->width - (border_width + 1 + xthickness + 2) - child.x); } - else + else { child.width = child.x; child.x = allocation->x + border_width + 1 + xthickness + 2; @@ -1623,16 +1623,16 @@ GtkComboBox *combo_box = GTK_COMBO_BOX (widget); gint index; gint items; - + index = gtk_combo_box_get_active (combo_box); if (index != -1) { items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL); - + if (event->direction == GDK_SCROLL_UP) index--; - else + else index++; gtk_combo_box_set_active (combo_box, CLAMP (index, 0, items - 1)); @@ -1694,15 +1694,15 @@ GTK_BIN (combo_box)->child->parent); combo_box->priv->box = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (combo_box->priv->button), + gtk_container_add (GTK_CONTAINER (combo_box->priv->button), combo_box->priv->box); combo_box->priv->separator = gtk_vseparator_new (); - gtk_container_add (GTK_CONTAINER (combo_box->priv->box), + gtk_container_add (GTK_CONTAINER (combo_box->priv->box), combo_box->priv->separator); combo_box->priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (combo_box->priv->box), + gtk_container_add (GTK_CONTAINER (combo_box->priv->box), combo_box->priv->arrow); gtk_widget_show_all (combo_box->priv->button); @@ -1792,7 +1792,7 @@ /* unparent will remove our latest ref */ gtk_widget_unparent (combo_box->priv->button); - + combo_box->priv->box = NULL; combo_box->priv->button = NULL; combo_box->priv->arrow = NULL; @@ -1895,17 +1895,17 @@ item = nth->data; if (nth->prev) last = nth->prev->data; - else + else last = NULL; g_list_free (list); gtk_combo_box_item_get_size (combo_box, index, &cols, &rows); - + if (combo_box->priv->col_column == -1 && combo_box->priv->row_column == -1 && last) { - gtk_container_child_get (GTK_CONTAINER (menu), + gtk_container_child_get (GTK_CONTAINER (menu), last, "right_attach", ¤t_col, "top_attach", ¤t_row, @@ -1926,12 +1926,12 @@ current_col = 0; current_row++; } - + if (!menu_occupied (GTK_MENU (menu), current_col, current_col + cols, current_row, current_row + rows)) break; - + current_col++; } } @@ -1949,19 +1949,19 @@ GtkWidget *menu; menu = combo_box->priv->popup_widget; - + /* do nothing unless we are in menu style and realized */ if (combo_box->priv->tree_view || !GTK_IS_MENU_SHELL (menu)) return; - + /* get rid of all children */ list = gtk_container_get_children (GTK_CONTAINER (menu)); - + for (j = g_list_last (list); j; j = j->prev) gtk_container_remove (GTK_CONTAINER (menu), j->data); - + g_list_free (list); - + /* and relayout */ gtk_combo_box_menu_fill (combo_box); } @@ -1980,7 +1980,7 @@ if (event->type == GDK_BUTTON_PRESS && event->button == 1) { combo_box->priv->popup_in_progress = TRUE; - + gtk_menu_set_active (GTK_MENU (combo_box->priv->popup_widget), combo_box->priv->active_item); @@ -2053,7 +2053,7 @@ if (!combo_box->priv->tree_view) gtk_combo_box_menu_row_deleted (model, path, user_data); - + if (index == combo_box->priv->active_item) { gint items = gtk_tree_model_iter_n_children (model, NULL); @@ -2090,7 +2090,7 @@ if (!combo_box->priv->tree_view) gtk_combo_box_menu_rows_reordered (model, path, iter, new_order, user_data); } - + static void gtk_combo_box_model_row_changed (GtkTreeModel *model, GtkTreePath *path, @@ -2103,7 +2103,7 @@ if (index == combo_box->priv->active_item && combo_box->priv->cell_view) gtk_widget_queue_resize (GTK_WIDGET (combo_box->priv->cell_view)); - + if (combo_box->priv->tree_view) gtk_combo_box_list_row_changed (model, path, iter, user_data); else @@ -2174,7 +2174,7 @@ gtk_combo_box_relayout (combo_box); } - + static void gtk_combo_box_menu_row_changed (GtkTreeModel *model, GtkTreePath *path, @@ -2238,12 +2238,12 @@ gtk_frame_set_shadow_type (GTK_FRAME (combo_box->priv->cell_view_frame), GTK_SHADOW_IN); - gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), + gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), >K_WIDGET (combo_box)->style->base[GTK_WIDGET_STATE (combo_box)]); combo_box->priv->box = gtk_event_box_new (); /* - gtk_event_box_set_visible_window (GTK_EVENT_BOX (combo_box->priv->box), + gtk_event_box_set_visible_window (GTK_EVENT_BOX (combo_box->priv->box), FALSE); */ @@ -2253,7 +2253,7 @@ gtk_widget_show_all (combo_box->priv->cell_view_frame); g_signal_connect (combo_box->priv->box, "button_press_event", - G_CALLBACK (gtk_combo_box_list_button_pressed), + G_CALLBACK (gtk_combo_box_list_button_pressed), combo_box); } @@ -2269,7 +2269,7 @@ if (combo_box->priv->model) gtk_tree_view_set_model (GTK_TREE_VIEW (combo_box->priv->tree_view), combo_box->priv->model); - + g_signal_connect (combo_box->priv->tree_view, "button_press_event", G_CALLBACK (gtk_combo_box_list_button_pressed), combo_box); @@ -2494,7 +2494,7 @@ if (combo_box->priv->model) items = gtk_tree_model_iter_n_children (combo_box->priv->model, NULL); - if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) && + if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) && state == GDK_MOD1_MASK) { gtk_combo_box_popup (combo_box); @@ -2502,7 +2502,7 @@ return TRUE; } - switch (event->keyval) + switch (event->keyval) { case GDK_Down: case GDK_KP_Down: @@ -2514,20 +2514,20 @@ break; case GDK_Page_Up: case GDK_KP_Page_Up: - case GDK_Home: + case GDK_Home: case GDK_KP_Home: new_index = 0; break; case GDK_Page_Down: case GDK_KP_Page_Down: - case GDK_End: + case GDK_End: case GDK_KP_End: new_index = items - 1; break; default: return FALSE; } - + if (items > 0) gtk_combo_box_set_active (combo_box, CLAMP (new_index, 0, items - 1)); @@ -2542,14 +2542,14 @@ GtkComboBox *combo_box = GTK_COMBO_BOX (data); guint state = event->state & gtk_accelerator_get_default_mod_mask (); - if ((event->keyval == GDK_Up || event->keyval == GDK_KP_Up) && + if ((event->keyval == GDK_Up || event->keyval == GDK_KP_Up) && state == GDK_MOD1_MASK) { gtk_combo_box_popdown (combo_box); return TRUE; } - + return FALSE; } @@ -2562,35 +2562,35 @@ guint state = event->state & gtk_accelerator_get_default_mod_mask (); if (event->keyval == GDK_Escape || - ((event->keyval == GDK_Up || event->keyval == GDK_KP_Up) && + ((event->keyval == GDK_Up || event->keyval == GDK_KP_Up) && state == GDK_MOD1_MASK)) { /* reset active item -- this is incredibly lame and ugly */ gtk_combo_box_set_active (combo_box, gtk_combo_box_get_active (combo_box)); - + gtk_combo_box_popdown (combo_box); - + return TRUE; } - + if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter || - event->keyval == GDK_space || event->keyval == GDK_KP_Space) + event->keyval == GDK_space || event->keyval == GDK_KP_Space) { gboolean ret = FALSE; GtkTreeIter iter; GtkTreeModel *model = NULL; - + if (combo_box->priv->model) { GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (combo_box->priv->tree_view)); - + ret = gtk_tree_selection_get_selected (sel, &model, &iter); } if (ret) { GtkTreePath *path; - + path = gtk_tree_model_get_path (model, &iter); if (path) { @@ -2600,7 +2600,7 @@ } gtk_combo_box_popdown (combo_box); - + return TRUE; } @@ -2620,7 +2620,7 @@ if (width > combo_box->priv->width) { - if (combo_box->priv->cell_view) + if (combo_box->priv->cell_view) { gtk_widget_set_size_request (combo_box->priv->cell_view, width, -1); gtk_widget_queue_resize (combo_box->priv->cell_view); @@ -2742,11 +2742,11 @@ GtkWidget *menu; GtkComboBox *combo_box; GSList *i; - + g_return_if_fail (GTK_IS_COMBO_BOX (layout)); combo_box = GTK_COMBO_BOX (layout); - + if (combo_box->priv->cell_view) gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo_box->priv->cell_view)); @@ -3082,7 +3082,7 @@ gtk_combo_box_check_appearance (combo_box); gtk_combo_box_relayout (combo_box); - + g_object_notify (G_OBJECT (combo_box), "wrap_width"); } } @@ -3112,9 +3112,9 @@ if (row_span != combo_box->priv->row_column) { combo_box->priv->row_column = row_span; - + gtk_combo_box_relayout (combo_box); - + g_object_notify (G_OBJECT (combo_box), "row_span_column"); } } @@ -3144,7 +3144,7 @@ if (column_span != combo_box->priv->col_column) { combo_box->priv->col_column = column_span; - + gtk_combo_box_relayout (combo_box); g_object_notify (G_OBJECT (combo_box), "column_span_column"); @@ -3191,7 +3191,7 @@ if (combo_box->priv->active_item == index_) return; - + gtk_combo_box_set_active_internal (combo_box, index_); } @@ -3252,9 +3252,9 @@ * gtk_combo_box_get_active_iter: * @combo_box: A #GtkComboBox * @iter: The uninitialized #GtkTreeIter. - * + * * Sets @iter to point to the current active item, if it exists. - * + * * Return value: %TRUE, if @iter was set * * Since: 2.4 @@ -3293,10 +3293,10 @@ * gtk_combo_box_set_active_iter: * @combo_box: A #GtkComboBox * @iter: The #GtkTreeIter. - * - * Sets the current active item to be the one referenced by @iter. + * + * Sets the current active item to be the one referenced by @iter. * @iter must correspond to a path of depth one. - * + * * Since: 2.4 **/ void @@ -3310,7 +3310,7 @@ path = gtk_tree_model_get_path (gtk_combo_box_get_model (combo_box), iter); g_return_if_fail (path != NULL); g_return_if_fail (gtk_tree_path_get_depth (path) == 1); - + gtk_combo_box_set_active (combo_box, gtk_tree_path_get_indices (path)[0]); gtk_tree_path_free (path); } @@ -3320,11 +3320,11 @@ * @combo_box: A #GtkComboBox. * @model: A #GtkTreeModel. * - * Sets the model used by @combo_box to be @model. Will unset a previously set + * Sets the model used by @combo_box to be @model. Will unset a previously set * model (if applicable). If @model is %NULL, then it will unset the model. - * - * Note that this function does not clear the cell renderers, you have to - * call gtk_combo_box_cell_layout_clear() yourself if you need to set up + * + * Note that this function does not clear the cell renderers, you have to + * call gtk_combo_box_cell_layout_clear() yourself if you need to set up * different cell renderers for the new model. * * Since: 2.4 @@ -3345,7 +3345,7 @@ if (model == combo_box->priv->model) return; - + if (combo_box->priv->model) gtk_combo_box_unset_model (combo_box); @@ -3368,7 +3368,7 @@ g_signal_connect (combo_box->priv->model, "row_changed", G_CALLBACK (gtk_combo_box_model_row_changed), combo_box); - + if (combo_box->priv->tree_view) { /* list mode */ @@ -3574,7 +3574,7 @@ { GtkComboBox *combo_box = GTK_COMBO_BOX (object); - gtk_combo_box_popdown (combo_box); + gtk_combo_box_popdown (combo_box); combo_box->priv->destroying = 1; @@ -3589,14 +3589,14 @@ { GtkComboBox *combo_box = GTK_COMBO_BOX (object); GSList *i; - + if (GTK_IS_MENU (combo_box->priv->popup_widget)) { gtk_combo_box_menu_destroy (combo_box); gtk_menu_detach (GTK_MENU (combo_box->priv->popup_widget)); combo_box->priv->popup_widget = NULL; } - + if (GTK_IS_TREE_VIEW (combo_box->priv->tree_view)) gtk_combo_box_list_destroy (combo_box); @@ -3655,13 +3655,13 @@ { GObject *object = G_OBJECT (child); AttachInfo *ai = g_object_get_data (object, ATTACH_INFO_KEY); - + if (!ai) { ai = g_new0 (AttachInfo, 1); g_object_set_data_full (object, ATTACH_INFO_KEY, ai, g_free); } - + return ai; } @@ -3693,25 +3693,25 @@ guint bottom_attach) { GtkMenuShell *menu_shell; - + g_return_if_fail (GTK_IS_MENU (menu)); g_return_if_fail (GTK_IS_MENU_ITEM (child)); - g_return_if_fail (child->parent == NULL || + g_return_if_fail (child->parent == NULL || child->parent == GTK_WIDGET (menu)); g_return_if_fail (left_attach < right_attach); g_return_if_fail (top_attach < bottom_attach); menu_shell = GTK_MENU_SHELL (menu); - + if (!child->parent) { AttachInfo *ai = get_attach_info (child); - + ai->left_attach = left_attach; ai->right_attach = right_attach; ai->top_attach = top_attach; ai->bottom_attach = bottom_attach; - + menu_shell->children = g_list_append (menu_shell->children, child); gtk_widget_set_parent (child, GTK_WIDGET (menu)); @@ -3741,7 +3741,7 @@ /* g_return_val_if_fail (GTK_IS_LIST_STORE (combo_box->priv->model), NULL); */ if (gtk_combo_box_get_active_iter (combo_box, &iter)) - gtk_tree_model_get (gtk_combo_box_get_model(combo_box), &iter, + gtk_tree_model_get (gtk_combo_box_get_model(combo_box), &iter, 0, &text, -1); return text; } diff -r 29f953732186 -r 8c8948b9f602 pidgin/pidginstock.c --- a/pidgin/pidginstock.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/pidginstock.c Wed Jan 28 10:23:37 2009 +0000 @@ -26,17 +26,32 @@ */ #include "internal.h" #include "pidgin.h" +#include "prefs.h" + +#include "gtkicon-theme-loader.h" +#include "theme-manager.h" #include "pidginstock.h" +/************************************************************************** + * Globals + **************************************************************************/ + +static gboolean stock_initted = FALSE; +static GtkIconSize microscopic, extra_small, small, medium, large, huge; + +/************************************************************************** + * Structures + **************************************************************************/ + static struct StockIcon { const char *name; const char *dir; const char *filename; -} const stock_icons[] = -{ +} const stock_icons[] = { + { PIDGIN_STOCK_ACTION, NULL, GTK_STOCK_EXECUTE }, #if GTK_CHECK_VERSION(2,6,0) { PIDGIN_STOCK_ALIAS, NULL, GTK_STOCK_EDIT }, @@ -98,7 +113,7 @@ { PIDGIN_STOCK_EDIT, N_("_Edit"), 0, 0, NULL } }; -static struct SizedStockIcon { +typedef struct { const char *name; const char *dir; const char *filename; @@ -110,19 +125,10 @@ gboolean huge; gboolean rtl; const char *translucent_name; -} const sized_stock_icons [] = { - { PIDGIN_STOCK_STATUS_AVAILABLE, "status", "available.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AVAILABLE_I }, - { PIDGIN_STOCK_STATUS_AWAY, "status", "away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AWAY_I }, - { PIDGIN_STOCK_STATUS_BUSY, "status", "busy.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_BUSY_I }, - { PIDGIN_STOCK_STATUS_CHAT, "status", "chat.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_STATUS_INVISIBLE,"status", "invisible.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_STATUS_XA, "status", "extended-away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, PIDGIN_STOCK_STATUS_XA_I }, - { PIDGIN_STOCK_STATUS_LOGIN, "status", "log-in.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, - { PIDGIN_STOCK_STATUS_LOGOUT, "status", "log-out.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, - { PIDGIN_STOCK_STATUS_OFFLINE, "status", "offline.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_OFFLINE_I }, - { PIDGIN_STOCK_STATUS_PERSON, "status", "person.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_STATUS_MESSAGE, "toolbar", "message-new.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - +} SizedStockIcon; + +const SizedStockIcon sized_stock_icons [] = { + { PIDGIN_STOCK_STATUS_IGNORED, "emblems", "blocked.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_STATUS_FOUNDER, "emblems", "founder.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_STATUS_OPERATOR, "emblems", "operator.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, @@ -175,39 +181,53 @@ { PIDGIN_STOCK_ANIMATION_TYPING4, "animations", "typing4.png",FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_ANIMATION_TYPING5, "animations", "typing5.png",FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_BGCOLOR, "toolbar", "change-bgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_BLOCK, "emblems", "blocked.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_FGCOLOR, "toolbar", "change-fgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_SMILEY, "toolbar", "emote-select.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_FONT_FACE, "toolbar", "font-face.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, "toolbar", "font-size-down.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_PENDING, "tray", "tray-new-im.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_PLUGINS, "toolbar", "plugins.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_UNBLOCK, "toolbar", "unblock.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, "toolbar", "select-avatar.png", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_SEND_FILE, "toolbar", "send-file.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TRANSFER, "toolbar", "transfer.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - - { PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_INVISIBLE, "tray", "tray-invisible.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-new-im.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_EMAIL, "tray", "tray-message.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } + { PIDGIN_STOCK_TOOLBAR_BGCOLOR, "toolbar", "change-bgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_BLOCK, "emblems", "blocked.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_FGCOLOR, "toolbar", "change-fgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_SMILEY, "toolbar", "emote-select.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_FONT_FACE, "toolbar", "font-face.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, "toolbar", "font-size-down.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_PENDING, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_PLUGINS, "toolbar", "plugins.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_UNBLOCK, "toolbar", "unblock.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, "toolbar", "select-avatar.png", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_SEND_FILE, "toolbar", "send-file.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TRANSFER, "toolbar", "transfer.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL } }; -static void -add_sized_icon_common(GtkIconSet *iconset, GtkIconSize sizeid, const char *dir, - gboolean rtl, const char *size, const char *file, - gboolean translucent); +const SizedStockIcon sized_status_icons [] = { + + { PIDGIN_STOCK_STATUS_AVAILABLE, "status", "available.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AVAILABLE_I }, + { PIDGIN_STOCK_STATUS_AWAY, "status", "away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AWAY_I }, + { PIDGIN_STOCK_STATUS_BUSY, "status", "busy.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_BUSY_I }, + { PIDGIN_STOCK_STATUS_CHAT, "status", "chat.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_STATUS_INVISIBLE, "status", "invisible.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_STATUS_XA, "status", "extended-away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, PIDGIN_STOCK_STATUS_XA_I }, + { PIDGIN_STOCK_STATUS_LOGIN, "status", "log-in.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { PIDGIN_STOCK_STATUS_LOGOUT, "status", "log-out.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { PIDGIN_STOCK_STATUS_OFFLINE, "status", "offline.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_OFFLINE_I }, + { PIDGIN_STOCK_STATUS_PERSON, "status", "person.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_STATUS_MESSAGE, "toolbar", "message-new.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + + { PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_INVISIBLE, "tray", "tray-invisible.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-new-im.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_EMAIL, "tray", "tray-message.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } +}; + +/***************************************************************************** + * Private functions + *****************************************************************************/ static gchar * find_file_common(const char *name) @@ -257,16 +277,10 @@ return ret; } -static void -add_sized_icon(GtkIconSet *iconset, GtkIconSize sizeid, const char *dir, - gboolean rtl, const char *size, const char *file) -{ - add_sized_icon_common(iconset, sizeid, dir, rtl, size, file, FALSE); -} /* Altered from do_colorshift in gnome-panel */ static void -do_alphashift (GdkPixbuf *dest, GdkPixbuf *src) +do_alphashift(GdkPixbuf *dest, GdkPixbuf *src) { gint i, j; gint width, height, has_alpha, srcrowstride, destrowstride; @@ -300,28 +314,48 @@ } } -static void -add_translucent_sized_icon(GtkIconSet *iconset, GtkIconSize sizeid, const char *dir, - gboolean rtl, const char *size, const char *file) +static gchar * +find_icon_file(PidginStatusIconTheme *theme, const gchar *size, SizedStockIcon sized_icon, gboolean rtl) { - add_sized_icon_common(iconset, sizeid, dir, rtl, size, file, TRUE); + const gchar *file, *dir; + gchar *file_full = NULL; + gchar *tmp; + + if (theme != NULL) { + file = pidgin_icon_theme_get_icon(PIDGIN_ICON_THEME(theme), sized_icon.name); + dir = purple_theme_get_dir(PURPLE_THEME(theme)); + + if (rtl) + file_full = g_build_filename(dir, size, "rtl", file, NULL); + else + file_full = g_build_filename(dir, size, file, NULL); + + if (g_file_test(file_full, G_FILE_TEST_IS_REGULAR)) + return file_full; + + g_free(file_full); + } + + if (rtl) + tmp = g_build_filename("pixmaps", "pidgin", sized_icon.dir, size, "rtl", sized_icon.filename, NULL); + else + tmp = g_build_filename("pixmaps", "pidgin", sized_icon.dir, size, sized_icon.filename, NULL); + + file_full = find_file_common(tmp); + g_free(tmp); + return file_full; } static void -add_sized_icon_common(GtkIconSet *iconset, GtkIconSize sizeid, const char *dir, - gboolean rtl, const char *size, const char *file, - gboolean translucent) +add_sized_icon(GtkIconSet *iconset, GtkIconSize sizeid, PidginStatusIconTheme *theme, + const char *size, SizedStockIcon sized_icon, gboolean translucent) { - char *filename, *subpath; + char *filename; GtkIconSource *source; GdkPixbuf *pixbuf; - subpath = g_build_filename("pixmaps", "pidgin", dir, size, file, NULL); - filename = find_file_common(subpath); - g_free(subpath); - if (!filename) - return; - + filename = find_icon_file(theme, size, sized_icon, FALSE); + g_return_if_fail(filename != NULL); pixbuf = gdk_pixbuf_new_from_file(filename, NULL); if (translucent) do_alphashift(pixbuf, pixbuf); @@ -329,7 +363,7 @@ source = gtk_icon_source_new(); gtk_icon_source_set_pixbuf(source, pixbuf); gtk_icon_source_set_direction(source, GTK_TEXT_DIR_LTR); - gtk_icon_source_set_direction_wildcarded(source, !rtl); + gtk_icon_source_set_direction_wildcarded(source, !sized_icon.rtl); gtk_icon_source_set_size(source, sizeid); gtk_icon_source_set_size_wildcarded(source, FALSE); gtk_icon_source_set_state_wildcarded(source, TRUE); @@ -349,17 +383,16 @@ g_free(filename); g_object_unref(pixbuf); - if (rtl) { - subpath = g_build_filename("pixmaps", "pidgin", dir, size, "rtl", file, NULL); - filename = find_file_common(subpath); - g_free(subpath); - if (!filename) - return; + if (sized_icon.rtl) { + filename = find_icon_file(theme, size, sized_icon, TRUE); + g_return_if_fail(filename != NULL); pixbuf = gdk_pixbuf_new_from_file(filename, NULL); if (translucent) do_alphashift(pixbuf, pixbuf); + source = gtk_icon_source_new(); gtk_icon_source_set_pixbuf(source, pixbuf); + gtk_icon_source_set_filename(source, filename); gtk_icon_source_set_direction(source, GTK_TEXT_DIR_RTL); gtk_icon_source_set_size(source, sizeid); gtk_icon_source_set_size_wildcarded(source, FALSE); @@ -371,20 +404,90 @@ } } +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +void +pidgin_stock_load_status_icon_theme(PidginStatusIconTheme *theme) +{ + GtkIconFactory *icon_factory; + gint i; + GtkIconSet *normal; + GtkIconSet *translucent = NULL; + GtkWidget *win; + + if (theme != NULL) { + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/status/icon-theme", + purple_theme_get_name(PURPLE_THEME(theme))); + purple_prefs_set_path(PIDGIN_PREFS_ROOT "/status/icon-theme-dir", + purple_theme_get_dir(PURPLE_THEME(theme))); + } + else { + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/status/icon-theme", ""); + purple_prefs_set_path(PIDGIN_PREFS_ROOT "/status/icon-theme-dir", ""); + } + + icon_factory = gtk_icon_factory_new(); + + gtk_icon_factory_add_default(icon_factory); + + win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_realize(win); + + for (i = 0; i < G_N_ELEMENTS(sized_status_icons); i++) + { + normal = gtk_icon_set_new(); + if (sized_status_icons[i].translucent_name) + translucent = gtk_icon_set_new(); + +#define ADD_SIZED_ICON(name, size) if (sized_status_icons[i].name) { \ + add_sized_icon(normal, name, theme, size, sized_status_icons[i], FALSE); \ + if (sized_status_icons[i].translucent_name) \ + add_sized_icon(translucent, name, theme, size, sized_status_icons[i], TRUE); \ + } + ADD_SIZED_ICON(microscopic, "11"); + ADD_SIZED_ICON(extra_small, "16"); + ADD_SIZED_ICON(small, "22"); + ADD_SIZED_ICON(medium, "32"); + ADD_SIZED_ICON(large, "48"); + ADD_SIZED_ICON(huge, "64"); +#undef ADD_SIZED_ICON + + gtk_icon_factory_add(icon_factory, sized_status_icons[i].name, normal); + gtk_icon_set_unref(normal); + + if (sized_status_icons[i].translucent_name) { + gtk_icon_factory_add(icon_factory, sized_status_icons[i].translucent_name, translucent); + gtk_icon_set_unref(translucent); + } + } + + + gtk_widget_destroy(win); + g_object_unref(G_OBJECT(icon_factory)); +} + void pidgin_stock_init(void) { - static gboolean stock_initted = FALSE; GtkIconFactory *icon_factory; size_t i; GtkWidget *win; - GtkIconSize microscopic, extra_small, small, medium, large, huge; + PidginIconThemeLoader *loader; + const gchar *path = NULL; if (stock_initted) return; stock_initted = TRUE; + /* Setup the status icon theme */ + loader = g_object_new(PIDGIN_TYPE_ICON_THEME_LOADER, "type", "status-icon", NULL); + purple_theme_manager_register_type(PURPLE_THEME_LOADER(loader)); + purple_prefs_add_string(PIDGIN_PREFS_ROOT "/status/icon-theme", ""); + purple_prefs_add_path(PIDGIN_PREFS_ROOT "/status/icon-theme-dir", ""); + /* Setup the icon factory. */ icon_factory = gtk_icon_factory_new(); @@ -394,6 +497,7 @@ win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_realize(win); + /* All non-sized icons */ for (i = 0; i < G_N_ELEMENTS(stock_icons); i++) { GtkIconSource *source; @@ -432,7 +536,6 @@ } /* register custom icon sizes */ - microscopic = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC, 11, 11); extra_small = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL, 16, 16); small = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_SMALL, 22, 22); @@ -440,18 +543,13 @@ large = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_LARGE, 48, 48); huge = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_HUGE, 64, 64); + /* All non-status sized icons */ for (i = 0; i < G_N_ELEMENTS(sized_stock_icons); i++) { - GtkIconSet *iconset; - - iconset = gtk_icon_set_new(); + GtkIconSet *iconset = gtk_icon_set_new(); -#define ADD_SIZED_ICON(name, size) do { \ - if (sized_stock_icons[i].name) \ - add_sized_icon(iconset, name, \ - sized_stock_icons[i].dir, sized_stock_icons[i].rtl, \ - size, sized_stock_icons[i].filename); \ - } while (0) +#define ADD_SIZED_ICON(name, size) if (sized_stock_icons[i].name) \ + add_sized_icon(iconset, name, NULL, size, sized_stock_icons[i], FALSE); ADD_SIZED_ICON(microscopic, "11"); ADD_SIZED_ICON(extra_small, "16"); ADD_SIZED_ICON(small, "22"); @@ -462,32 +560,21 @@ gtk_icon_factory_add(icon_factory, sized_stock_icons[i].name, iconset); gtk_icon_set_unref(iconset); - - if (sized_stock_icons[i].translucent_name) { - iconset = gtk_icon_set_new(); - -#define ADD_TRANS_ICON(name, size) do { \ - if (sized_stock_icons[i].name) \ - add_translucent_sized_icon(iconset, name, \ - sized_stock_icons[i].dir, sized_stock_icons[i].rtl, \ - size, sized_stock_icons[i].filename); \ - } while (0) - ADD_TRANS_ICON(microscopic, "11"); - ADD_TRANS_ICON(extra_small, "16"); - ADD_TRANS_ICON(small, "22"); - ADD_TRANS_ICON(medium, "32"); - ADD_TRANS_ICON(large, "48"); - ADD_TRANS_ICON(huge, "64"); -#undef ADD_TRANS_ICON - - gtk_icon_factory_add(icon_factory, sized_stock_icons[i].translucent_name, iconset); - gtk_icon_set_unref(iconset); - } } gtk_widget_destroy(win); g_object_unref(G_OBJECT(icon_factory)); + /* Pre-load Status icon theme - this avoids a bug with displaying the correct icon in the tray, theme is destroyed after*/ + if (purple_prefs_get_string(PIDGIN_PREFS_ROOT "/icon/status/theme") && + (path = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/status/icon-theme-dir"))) { + + PidginStatusIconTheme *theme = PIDGIN_STATUS_ICON_THEME(purple_theme_loader_build(PURPLE_THEME_LOADER(loader), path)); + pidgin_stock_load_status_icon_theme(theme); + g_object_unref(G_OBJECT(theme)); + + } else pidgin_stock_load_status_icon_theme(NULL); + /* Register the stock items. */ gtk_stock_add_static(stock_items, G_N_ELEMENTS(stock_items)); } diff -r 29f953732186 -r 8c8948b9f602 pidgin/pidginstock.h --- a/pidgin/pidginstock.h Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/pidginstock.h Wed Jan 28 10:23:37 2009 +0000 @@ -8,7 +8,7 @@ * Pidgin 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 @@ -24,6 +24,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include +#include "gtkstatus-icon-theme.h" #ifndef _PIDGIN_STOCK_H_ #define _PIDGIN_STOCK_H_ @@ -177,6 +178,14 @@ #define PIDGIN_ICON_SIZE_TANGO_MEDIUM "pidgin-icon-size-tango-medium" #define PIDGIN_ICON_SIZE_TANGO_LARGE "pidgin-icon-size-tango-large" #define PIDGIN_ICON_SIZE_TANGO_HUGE "pidgin-icon-size-tango-huge" + +/** + * Loades all of the icons from the status icon theme into Pidgin stock + * + * @param theme the theme to load, or null to load all the default icons + */ +void pidgin_stock_load_status_icon_theme(PidginStatusIconTheme *theme); + /** * Sets up the purple stock repository. */ diff -r 29f953732186 -r 8c8948b9f602 pidgin/pixmaps/Makefile.am --- a/pidgin/pixmaps/Makefile.am Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/pixmaps/Makefile.am Wed Jan 28 10:23:37 2009 +0000 @@ -488,6 +488,7 @@ tray/32/tray-connecting.png \ tray/32/tray-extended-away.png \ tray/32/tray-invisible.png \ + tray/32/tray-message.png \ tray/32/tray-new-im.png \ tray/32/tray-offline.png \ tray/32/tray-online.png @@ -498,6 +499,7 @@ tray/48/tray-connecting.png \ tray/48/tray-extended-away.png \ tray/48/tray-invisible.png \ + tray/48/tray-message.png \ tray/48/tray-new-im.png \ tray/48/tray-offline.png \ tray/48/tray-online.png @@ -525,7 +527,6 @@ $(PROTOCOLS_16_SCALABLE) \ $(PROTOCOLS_22_SCALABLE) \ $(PROTOCOLS_48_SCALABLE) \ - $(TOOLBAR_11) \ $(TOOLBAR_16_SCALABLE) \ $(TOOLBAR_22_SCALABLE) @@ -553,6 +554,7 @@ $(STATUS_32_RTL) \ $(STATUS_48) \ $(STATUS_48_RTL) \ + $(TOOLBAR_11) \ $(TOOLBAR_16) \ $(TOOLBAR_22) \ $(TRAY_16) \ diff -r 29f953732186 -r 8c8948b9f602 pidgin/pixmaps/art-tools/clean-svg-definitions.sh diff -r 29f953732186 -r 8c8948b9f602 pidgin/plugins/gevolution/gevo-util.c --- a/pidgin/plugins/gevolution/gevo-util.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/plugins/gevolution/gevo-util.c Wed Jan 28 10:23:37 2009 +0000 @@ -27,13 +27,13 @@ void gevo_add_buddy(PurpleAccount *account, const char *group_name, - const char *screenname, const char *alias) + const char *buddy_name, const char *alias) { PurpleConversation *conv = NULL; PurpleBuddy *buddy; PurpleGroup *group; - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, screenname, account); + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy_name, account); if ((group = purple_find_group(group_name)) == NULL) { @@ -41,7 +41,7 @@ purple_blist_add_group(group, NULL); } - buddy = purple_buddy_new(account, screenname, alias); + buddy = purple_buddy_new(account, buddy_name, alias); purple_blist_add_buddy(buddy, NULL, group, NULL); purple_account_add_buddy(account, buddy); diff -r 29f953732186 -r 8c8948b9f602 pidgin/plugins/gevolution/gevolution.c --- a/pidgin/plugins/gevolution/gevolution.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/plugins/gevolution/gevolution.c Wed Jan 28 10:23:37 2009 +0000 @@ -52,7 +52,7 @@ { COLUMN_AUTOADD, COLUMN_ICON, - COLUMN_SCREENNAME, + COLUMN_USERNAME, COLUMN_DATA, NUM_COLUMNS }; @@ -463,11 +463,11 @@ gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", COLUMN_ICON); - /* Screenname */ + /* Username */ renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, - "text", COLUMN_SCREENNAME); + "text", COLUMN_USERNAME); /* Populate */ @@ -489,7 +489,7 @@ purple_account_get_bool(account, "gevo-autoadd", FALSE), COLUMN_ICON, pixbuf, - COLUMN_SCREENNAME, + COLUMN_USERNAME, purple_account_get_username(account), COLUMN_DATA, account, -1); diff -r 29f953732186 -r 8c8948b9f602 pidgin/plugins/gevolution/new_person_dialog.c --- a/pidgin/plugins/gevolution/new_person_dialog.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/plugins/gevolution/new_person_dialog.c Wed Jan 28 10:23:37 2009 +0000 @@ -67,7 +67,7 @@ } static void -screenname_changed_cb(GtkEntry *entry, GevoNewPersonDialog *dialog) +username_changed_cb(GtkEntry *entry, GevoNewPersonDialog *dialog) { gtk_widget_set_sensitive(dialog->add_button, *gtk_entry_get_text(entry) != '\0'); @@ -85,7 +85,7 @@ add_cb(GtkWidget *w, GevoNewPersonDialog *dialog) { EContact *contact = NULL; - const char *screenname; + const char *username; const char *firstname; const char *lastname; const char *email; @@ -96,9 +96,9 @@ char *full_name = NULL; if (dialog->person_only) - screenname = dialog->buddy->name; + username = dialog->buddy->name; else - screenname = gtk_entry_get_text(GTK_ENTRY(dialog->screenname)); + username = gtk_entry_get_text(GTK_ENTRY(dialog->username)); firstname = gtk_entry_get_text(GTK_ENTRY(dialog->firstname)); lastname = gtk_entry_get_text(GTK_ENTRY(dialog->lastname)); @@ -143,7 +143,7 @@ if (!strcmp(im_service, "prpl-oscar")) { - if (isdigit(*screenname)) + if (isdigit(*username)) field = E_CONTACT_IM_ICQ; else field = E_CONTACT_IM_AIM; @@ -163,7 +163,7 @@ if (field > 0) { - GList *list = g_list_append(NULL, g_strdup(screenname)); + GList *list = g_list_append(NULL, g_strdup(username)); e_contact_set(contact, field, list); @@ -203,7 +203,7 @@ group_name = pidgin_text_combo_box_entry_get_text(dialog->group_combo); - gevo_add_buddy(dialog->account, group_name, screenname, full_name); + gevo_add_buddy(dialog->account, group_name, username, full_name); } if (name != NULL) @@ -289,15 +289,15 @@ NULL, dialog); add_pref_box(sg, vbox, _("Account type:"), dialog->accounts_menu); - /* Screen Name */ - dialog->screenname = gtk_entry_new(); - add_pref_box(sg, vbox, _("Username:"), dialog->screenname); + /* Username */ + dialog->username = gtk_entry_new(); + add_pref_box(sg, vbox, _("Username:"), dialog->username); if (username != NULL) - gtk_entry_set_text(GTK_ENTRY(dialog->screenname), username); + gtk_entry_set_text(GTK_ENTRY(dialog->username), username); - g_signal_connect(G_OBJECT(dialog->screenname), "changed", - G_CALLBACK(screenname_changed_cb), dialog); + g_signal_connect(G_OBJECT(dialog->username), "changed", + G_CALLBACK(username_changed_cb), dialog); /* Group */ dialog->group_combo = pidgin_text_combo_box_entry_new(NULL, diff -r 29f953732186 -r 8c8948b9f602 pidgin/plugins/history.c --- a/pidgin/plugins/history.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/plugins/history.c Wed Jan 28 10:23:37 2009 +0000 @@ -62,36 +62,39 @@ return; /* Find buddies for this conversation. */ - buddies = purple_find_buddies(account, name); + buddies = purple_find_buddies(account, name); /* If we found at least one buddy, save the first buddy's alias. */ if (buddies != NULL) alias = purple_buddy_get_contact_alias((PurpleBuddy *)buddies->data); - for (cur = buddies; cur != NULL; cur = cur->next) - { - PurpleBlistNode *node = cur->data; - if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) - { + for (cur = buddies; cur != NULL; cur = cur->next) + { + PurpleBlistNode *node = cur->data; + PurpleBlistNode *prev = purple_blist_node_get_sibling_prev(node); + PurpleBlistNode *next = purple_blist_node_get_sibling_next(node); + if ((node != NULL) && ((prev != NULL) || (next != NULL))) + { PurpleBlistNode *node2; + PurpleBlistNode *parent = purple_blist_node_get_parent(node); + PurpleBlistNode *child = purple_blist_node_get_first_child(parent); alias = purple_buddy_get_contact_alias((PurpleBuddy *)node); /* We've found a buddy that matches this conversation. It's part of a * PurpleContact with more than one PurpleBuddy. Loop through the PurpleBuddies * in the contact and get all the logs. */ - for (node2 = node->parent->child ; node2 != NULL ; node2 = node2->next) + for (node2 = child ; node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2)) { - logs = g_list_concat( - purple_log_get_logs(PURPLE_LOG_IM, + logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, purple_buddy_get_name((PurpleBuddy *)node2), purple_buddy_get_account((PurpleBuddy *)node2)), - logs); + logs); } break; - } - } - g_slist_free(buddies); + } + } + g_slist_free(buddies); if (logs == NULL) logs = purple_log_get_logs(PURPLE_LOG_IM, name, account); @@ -118,7 +121,7 @@ protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml))); gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), - purple_account_get_protocol_name(((PurpleLog*)logs->data)->account)); + purple_account_get_protocol_name(((PurpleLog*)logs->data)->account)); if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)))) gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "
", options); diff -r 29f953732186 -r 8c8948b9f602 pidgin/plugins/perl/common/GtkLog.xs --- a/pidgin/plugins/perl/common/GtkLog.xs Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/plugins/perl/common/GtkLog.xs Wed Jan 28 10:23:37 2009 +0000 @@ -7,9 +7,9 @@ pidgin_log_get_handle() void -pidgin_log_show(type, screenname, account) +pidgin_log_show(type, buddyname, account) Purple::LogType type - const char * screenname + const char * buddyname Purple::Account account void diff -r 29f953732186 -r 8c8948b9f602 pidgin/plugins/ticker/ticker.c --- a/pidgin/plugins/ticker/ticker.c Wed Jan 28 04:27:01 2009 +0000 +++ b/pidgin/plugins/ticker/ticker.c Wed Jan 28 10:23:37 2009 +0000 @@ -91,7 +91,9 @@ PurpleContact *contact = user_data; PurpleBuddy *b = purple_contact_get_priority_buddy(contact); - purple_conversation_new(PURPLE_CONV_TYPE_IM, b->account, b->name); + purple_conversation_new(PURPLE_CONV_TYPE_IM, + purple_buddy_get_account(b), + purple_buddy_get_name(b)); return TRUE; } @@ -217,20 +219,25 @@ static void buddy_ticker_show(void) { - PurpleBuddyList *list = purple_get_blist(); PurpleBlistNode *gnode, *cnode, *bnode; PurpleBuddy *b; - if(!list) - return; - - for(gnode = list->root; gnode; gnode = gnode->next) { + for(gnode = purple_blist_get_root(); + gnode; + gnode = purple_blist_node_get_sibling_next(gnode)) + { if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; - for(cnode = gnode->child; cnode; cnode = cnode->next) { + for(cnode = purple_blist_node_get_first_child(gnode); + cnode; + cnode = purple_blist_node_get_sibling_next(cnode)) + { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; - for(bnode = cnode->child; bnode; bnode = bnode->next) { + for(bnode = purple_blist_node_get_first_child(cnode); + bnode; + bnode = purple_blist_node_get_sibling_next(bnode)) + { if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *)bnode; diff -r 29f953732186 -r 8c8948b9f602 po/POTFILES.in --- a/po/POTFILES.in Wed Jan 28 04:27:01 2009 +0000 +++ b/po/POTFILES.in Wed Jan 28 10:23:37 2009 +0000 @@ -183,6 +183,7 @@ libpurple/status.c libpurple/util.c libpurple/win32/libc_interface.c +libpurple/xmlnode.c pidgin.desktop.in pidgin/eggtrayicon.c pidgin/gtkaccount.c diff -r 29f953732186 -r 8c8948b9f602 po/README --- a/po/README Wed Jan 28 04:27:01 2009 +0000 +++ b/po/README Wed Jan 28 10:23:37 2009 +0000 @@ -1,2 +1,2 @@ -For information on translating Pidgin, Libpurple, and Finch, please see +For information on translating Pidgin, libpurple, and Finch, please see our wiki page at http://developer.pidgin.im/wiki/TipsForTranslators. diff -r 29f953732186 -r 8c8948b9f602 po/et.po --- a/po/et.po Wed Jan 28 04:27:01 2009 +0000 +++ b/po/et.po Wed Jan 28 10:23:37 2009 +0000 @@ -2258,7 +2258,7 @@ #. * summary #. * description msgid "Tests the ciphers that ship with libpurple." -msgstr "Libpurple'ga kaasasolevate Å¡ifrite testimine." +msgstr "libpurple'ga kaasasolevate Å¡ifrite testimine." #. *< type #. *< ui_requirement