# HG changeset patch # User Elliott Sales de Andrade # Date 1329984803 0 # Node ID 4f8626d4ef63a914beb26e219be4e5f05b233920 # Parent 4ae0c82b158db4af61ea273a3a44d8351b9bc279# Parent 3f81e3c3064c9a29597b01cca6969a01d984151d propagate from branch 'im.pidgin.pidgin' (head deb06ab6aa118efb674f1a8434ff529e67b28809) to branch 'im.pidgin.cpw.qulogic.gtk3' (head 34c3103eabae4a4c23439048d383f73c94dfd23e) diff -r 4ae0c82b158d -r 4f8626d4ef63 ChangeLog --- a/ChangeLog Sat Jan 21 12:02:41 2012 +0000 +++ b/ChangeLog Thu Feb 23 08:13:23 2012 +0000 @@ -1,14 +1,12 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul version 3.0.0 (??/??/????): - libpurple: - * Support new connection states and signals for NetworkManager 0.9+. - (Dan Williams) (#13859) + Finch: + * Support the conversation-extended signal for extending the + conversation menu. (Howard Chu) (#14818) AIM and ICQ: * Make buddy list management code more efficient. (Oliver) (#4816) - * Don't try to format ICQ usernames entered as email addresses. - Gets rid of an "Unable to format username" error at login. (#13883) Bonjour: * Support file transfers up to ~9 EiB. @@ -26,6 +24,8 @@ MSN: * Fix file transfer with older Mac MSN clients. * Support file transfers up to ~9 EiB. + * Support new protocol version MSNP18. (#14753) + * Fix messages to offline contacts. (#14302) MXit: * Remove all reference to Hidden Number. @@ -45,6 +45,35 @@ * The Voice/Video Settings plugin supports using the sndio GStreamer backends. (Brad Smith) (#14414) +version 2.10.2 (02/22/2012): + General: + * Fix compilation when using binutils 2.22 and new GDK pixbuf. (#14799) + * Fix compilation of the MXit protocol plugin with GLib 2.31. (#14773) + + Pidgin: + * Add support for the GNOME3 Network dialog. (#13882) + * Fix rare crash. (#14392) + * Add support for the GNOME3 Default Application dialog for configuring + the Browser. + + libpurple: + * Support new connection states and signals for NetworkManager 0.9+. + (Dan Williams) (#13859) + + AIM and ICQ: + * Allow signing on with usernames containing periods and + underscores. (#13500) + * Allow adding buddies containing periods and underscores. (#13500) + * Don't try to format ICQ usernames entered as email addresses. + Gets rid of an "Unable to format username" error at login. (#13883) + + MSN: + * Fix possible crashes caused by not validating incoming messages as + UTF-8. (Thijs Alkemade) (#14884) + + Windows-Specific Changes: + * Fix compilation of the Bonjour protocol plugin. (#14802) + version 2.10.1 (12/06/2011): Finch: * Fix compilation on OpenBSD. diff -r 4ae0c82b158d -r 4f8626d4ef63 ChangeLog.API --- a/ChangeLog.API Sat Jan 21 12:02:41 2012 +0000 +++ b/ChangeLog.API Thu Feb 23 08:13:23 2012 +0000 @@ -201,8 +201,8 @@ * purple_txt_cancel * purple_txt_resolve_account * purple_util_fetch_url_len. Use purple_util_fetch_url, instead. - * purple_util_fetch_url_request_len. Use purple_util_fetch_url_request, - instead. + * purple_util_fetch_url_request_len. Use + * purple_util_fetch_url_request, instead. * purple_util_fetch_url_request_len_with_account. Use purple_util_fetch_url_request, instead. * PurpleConnectionUiOps.report_disconnect_reason diff -r 4ae0c82b158d -r 4f8626d4ef63 finch/Makefile.am --- a/finch/Makefile.am Sat Jan 21 12:02:41 2012 +0000 +++ b/finch/Makefile.am Thu Feb 23 08:13:23 2012 +0000 @@ -27,6 +27,7 @@ gntidle.c \ gntlog.c \ gntmedia.c \ + gntmenuutil.c \ gntnotify.c \ gntplugin.c \ gntpounce.c \ @@ -49,6 +50,7 @@ gntidle.h \ gntlog.h \ gntmedia.h \ + gntmenuutil.h \ gntnotify.h \ gntplugin.h \ gntpounce.h \ diff -r 4ae0c82b158d -r 4f8626d4ef63 finch/gntblist.c --- a/finch/gntblist.c Sat Jan 21 12:02:41 2012 +0000 +++ b/finch/gntblist.c Thu Feb 23 08:13:23 2012 +0000 @@ -50,6 +50,7 @@ #include "gntmenu.h" #include "gntmenuitem.h" #include "gntmenuitemcheck.h" +#include "gntmenuutil.h" #include "gntpounce.h" #include "gntstyle.h" #include "gnttree.h" @@ -1072,46 +1073,6 @@ } static void -context_menu_callback(GntMenuItem *item, gpointer data) -{ - PurpleMenuAction *action = data; - PurpleBlistNode *node = ggblist->cnode; - if (action) { - void (*callback)(PurpleBlistNode *, gpointer); - callback = (void (*)(PurpleBlistNode *, gpointer)) - purple_menu_action_get_callback(action); - if (callback) - callback(node, purple_menu_action_get_data(action)); - else - return; - } -} - -static void -gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer parent) -{ - GList *list; - GntMenuItem *item; - - if (action == NULL) - return; - - item = gnt_menuitem_new(purple_menu_action_get_label(action)); - if (purple_menu_action_get_callback(action)) - gnt_menuitem_set_callback(GNT_MENU_ITEM(item), context_menu_callback, action); - gnt_menu_add_item(menu, GNT_MENU_ITEM(item)); - - list = purple_menu_action_get_children(action); - - if (list) { - GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP); - gnt_menuitem_set_submenu(item, GNT_MENU(sub)); - for (; list; list = list->next) - gnt_append_menu_action(GNT_MENU(sub), list->data, action); - } -} - -static void append_proto_menu(GntMenu *menu, PurpleConnection *gc, PurpleBlistNode *node) { GList *list; @@ -1127,9 +1088,7 @@ if (!act) continue; purple_menu_action_set_data(act, node); - gnt_append_menu_action(menu, act, NULL); - g_signal_connect_swapped(G_OBJECT(menu), "destroy", - G_CALLBACK(purple_menu_action_free), act); + gnt_append_menu_action(menu, act, node); } } @@ -1139,8 +1098,6 @@ { PurpleMenuAction *action = purple_menu_action_new(label, callback, data, NULL); gnt_append_menu_action(menu, action, NULL); - g_signal_connect_swapped(G_OBJECT(menu), "destroy", - G_CALLBACK(purple_menu_action_free), action); } static void @@ -1379,9 +1336,7 @@ for (iter = purple_blist_node_get_extended_menu(node); iter; iter = g_list_delete_link(iter, iter)) { - gnt_append_menu_action(menu, iter->data, NULL); - g_signal_connect_swapped(G_OBJECT(menu), "destroy", - G_CALLBACK(purple_menu_action_free), iter->data); + gnt_append_menu_action(menu, iter->data, node); } } diff -r 4ae0c82b158d -r 4f8626d4ef63 finch/gntconv.c --- a/finch/gntconv.c Sat Jan 21 12:02:41 2012 +0000 +++ b/finch/gntconv.c Thu Feb 23 08:13:23 2012 +0000 @@ -52,6 +52,7 @@ #include "gntmenu.h" #include "gntmenuitem.h" #include "gntmenuitemcheck.h" +#include "gntmenuutil.h" #include "gntstyle.h" #include "gnttextview.h" #include "gnttree.h" @@ -404,6 +405,30 @@ } static void +gg_extended_menu(FinchConv *ggc) +{ + GntWidget *sub; + GList *list; + + sub = gnt_menu_new(GNT_MENU_POPUP); + gnt_menuitem_set_submenu(ggc->plugins, GNT_MENU(sub)); + + for (list = purple_conversation_get_extended_menu(ggc->active_conv); + list; list = g_list_delete_link(list, list)) + { + gnt_append_menu_action(GNT_MENU(sub), list->data, ggc->active_conv); + } +} + +static void +conv_updated(PurpleConversation *conv, PurpleConvUpdateType type) +{ + if (type == PURPLE_CONV_UPDATE_FEATURES) { + gg_extended_menu(purple_conversation_get_ui_data(conv)); + } +} + +static void clear_scrollback_cb(GntMenuItem *item, gpointer ggconv) { FinchConv *ggc = ggconv; @@ -595,6 +620,12 @@ } static void +plugin_changed_cb(PurplePlugin *p, gpointer data) +{ + gg_extended_menu(data); +} + +static void gg_create_menu(FinchConv *ggc) { GntWidget *menu, *sub; @@ -665,6 +696,12 @@ !(ggc->flags & FINCH_CONV_NO_SOUND)); gnt_menu_add_item(GNT_MENU(sub), item); gnt_menuitem_set_callback(item, toggle_sound_cb, ggc); + + item = gnt_menuitem_new(_("Plugins")); + gnt_menu_add_item(GNT_MENU(menu), item); + ggc->plugins = item; + + gg_extended_menu(ggc); } static void @@ -876,6 +913,11 @@ purple_signal_connect(purple_cmds_get_handle(), "cmd-removed", ggc, G_CALLBACK(cmd_removed_cb), ggc); + purple_signal_connect(purple_plugins_get_handle(), "plugin-load", ggc, + PURPLE_CALLBACK(plugin_changed_cb), ggc); + purple_signal_connect(purple_plugins_get_handle(), "plugin-unload", ggc, + PURPLE_CALLBACK(plugin_changed_cb), ggc); + g_free(title); gnt_box_give_focus_to_child(GNT_BOX(ggc->window), ggc->entry); g_signal_connect(G_OBJECT(ggc->window), "gained-focus", G_CALLBACK(gained_focus_cb), ggc); @@ -1475,6 +1517,8 @@ PURPLE_CALLBACK(chat_left_cb), NULL); purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history", finch_conv_get_handle(), PURPLE_CALLBACK(cleared_message_history_cb), NULL); + purple_signal_connect(purple_conversations_get_handle(), "conversation-updated", finch_conv_get_handle(), + PURPLE_CALLBACK(conv_updated), NULL); purple_signal_connect(purple_blist_get_handle(), "buddy-signed-on", finch_conv_get_handle(), PURPLE_CALLBACK(buddy_signed_on_off), NULL); purple_signal_connect(purple_blist_get_handle(), "buddy-signed-off", finch_conv_get_handle(), diff -r 4ae0c82b158d -r 4f8626d4ef63 finch/gntconv.h --- a/finch/gntconv.h Sat Jan 21 12:02:41 2012 +0000 +++ b/finch/gntconv.h Thu Feb 23 08:13:23 2012 +0000 @@ -59,6 +59,7 @@ GntWidget *tv; /* text-view */ GntWidget *menu; GntWidget *info; + GntMenuItem *plugins; FinchConversationFlag flags; union diff -r 4ae0c82b158d -r 4f8626d4ef63 finch/gntmenuutil.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/finch/gntmenuutil.c Thu Feb 23 08:13:23 2012 +0000 @@ -0,0 +1,79 @@ +/** + * @file gntmenuutil.c GNT Menu Utility Functions + * @ingroup finch + */ + +/* finch + * + * Finch 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 "finch.h" + +#include "gnt.h" +#include "gntmenu.h" +#include "gntmenuitem.h" +#include "gntmenuutil.h" + +static void +context_menu_callback(GntMenuItem *item, gpointer data) +{ + PurpleMenuAction *action = data; + if (action) { + void (*callback)(gpointer, gpointer); + callback = (void (*)(gpointer, gpointer)) + purple_menu_action_get_callback(action); + if (callback) { + gpointer ctx = g_object_get_data(G_OBJECT(item), "menuctx"); + callback(ctx, purple_menu_action_get_data(action)); + } + } +} + +void +gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer ctx) +{ + GList *list; + GntMenuItem *item; + + if (action == NULL) + return; + + item = gnt_menuitem_new(purple_menu_action_get_label(action)); + if (purple_menu_action_get_callback(action)) { + gnt_menuitem_set_callback(item, context_menu_callback, action); + g_object_set_data(G_OBJECT(item), "menuctx", ctx); + } + gnt_menu_add_item(menu, item); + + list = purple_menu_action_get_children(action); + + if (list) { + GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP); + gnt_menuitem_set_submenu(item, GNT_MENU(sub)); + for (; list; list = g_list_delete_link(list, list)) + gnt_append_menu_action(GNT_MENU(sub), list->data, action); + purple_menu_action_set_children(action, NULL); + } + + g_signal_connect_swapped(G_OBJECT(menu), "destroy", + G_CALLBACK(purple_menu_action_free), action); +} + diff -r 4ae0c82b158d -r 4f8626d4ef63 finch/gntmenuutil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/finch/gntmenuutil.h Thu Feb 23 08:13:23 2012 +0000 @@ -0,0 +1,49 @@ +/** + * @file gntmenuutil.h GNT Menu Utility Functions + * @ingroup finch + */ + +/* finch + * + * Finch 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 _GNT_MENUUTIL_H +#define _GNT_MENUUTIL_H + +#include +#include + +/*************************************************************************** + * @name GNT Menu Utility Functions + ***************************************************************************/ +/*@{*/ + +/** + * Add a PurpleMenuAction to a GntMenu. + * + * @param menu the GntMenu to add to + * @param action the PurpleMenuAction to add + * @param ctx the callback context, passed as the first argument to + * the PurpleMenuAction's PurpleCallback function. + */ +void gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer ctx); + +/*@}*/ + +#endif diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/blist.c --- a/libpurple/blist.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/blist.c Thu Feb 23 08:13:23 2012 +0000 @@ -2908,6 +2908,17 @@ return node->type; } +gboolean +purple_blist_node_has_setting(PurpleBlistNode* node, const char *key) +{ + g_return_val_if_fail(node != NULL, FALSE); + g_return_val_if_fail(node->settings != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + + /* Boxed type, so it won't ever be NULL, so no need for _extended */ + return (g_hash_table_lookup(node->settings, key) != NULL); +} + void purple_blist_node_set_bool(PurpleBlistNode* node, const char *key, gboolean data) { diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/blist.h --- a/libpurple/blist.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/blist.h Thu Feb 23 08:13:23 2012 +0000 @@ -1052,6 +1052,16 @@ void purple_blist_request_add_group(void); /** + * Checks whether a named setting exists for a node in the buddy list + * + * @param node The node to check from which to check settings + * @param key The identifier of the data + * + * @return TRUE if a value exists, or FALSE if there is no setting + */ +gboolean purple_blist_node_has_setting(PurpleBlistNode *node, const char *key); + +/** * Associates a boolean with a node in the buddy list * * @param node The node to associate the data with diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/jabber/caps.c --- a/libpurple/protocols/jabber/caps.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/jabber/caps.c Thu Feb 23 08:13:23 2012 +0000 @@ -888,7 +888,8 @@ field->values); } } else { - g_list_free_full(field->values, g_free); + g_list_foreach(field->values, (GFunc) g_free, NULL); + g_list_free(field->values); } g_free(field->var); diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/contact.c --- a/libpurple/protocols/msn/contact.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/contact.c Thu Feb 23 08:13:23 2012 +0000 @@ -740,6 +740,20 @@ } passportName = xmlnode_get_child(contactInfo, "passportName"); + if (passportName != NULL) { + xmlnode *messenger_user; + /* ignore non-messenger contacts */ + if ((messenger_user = xmlnode_get_child(contactInfo, "isMessengerUser"))) { + char *is_messenger_user = xmlnode_get_data(messenger_user); + + if (is_messenger_user && !strcmp(is_messenger_user, "false")) { + passportName = NULL; + } + + g_free(is_messenger_user); + } + } + if (passportName == NULL) { xmlnode *emailsNode, *contactEmailNode, *emailNode; xmlnode *messengerEnabledNode; @@ -773,19 +787,6 @@ } } } else { - xmlnode *messenger_user; - /* ignore non-messenger contacts */ - if ((messenger_user = xmlnode_get_child(contactInfo, "isMessengerUser"))) { - char *is_messenger_user = xmlnode_get_data(messenger_user); - - if (is_messenger_user && !strcmp(is_messenger_user, "false")) { - g_free(is_messenger_user); - continue; - } - - g_free(is_messenger_user); - } - passport = xmlnode_get_data(passportName); } @@ -864,6 +865,21 @@ g_free(alias); } +static void +msn_parse_addressbook_circles(MsnSession *session, xmlnode *node) +{ + xmlnode *ticket; + + /* TODO: Parse groups */ + + ticket = xmlnode_get_child(node, "CircleTicket"); + if (ticket) { + char *data = xmlnode_get_data(ticket); + msn_notification_send_circle_auth(session, data); + g_free(data); + } +} + static gboolean msn_parse_addressbook(MsnSession *session, xmlnode *node) { @@ -871,6 +887,7 @@ xmlnode *groups; xmlnode *contacts; xmlnode *abNode; + xmlnode *circleNode; xmlnode *fault; if ((fault = xmlnode_get_child(node, "Body/Fault"))) { @@ -897,7 +914,7 @@ return FALSE; } - result = xmlnode_get_child(node, "Body/ABFindAllResponse/ABFindAllResult"); + result = xmlnode_get_child(node, "Body/ABFindContactsPagedResponse/ABFindContactsPagedResult"); if (result == NULL) { purple_debug_misc("msn", "Received no address book update\n"); return TRUE; @@ -906,7 +923,7 @@ /* I don't see this "groups" tag documented on msnpiki, need to find out if they are really there, and update msnpiki */ /*Process Group List*/ - groups = xmlnode_get_child(result, "groups"); + groups = xmlnode_get_child(result, "Groups"); if (groups != NULL) { msn_parse_addressbook_groups(session, groups); } @@ -931,12 +948,12 @@ /*Process contact List*/ purple_debug_info("msn", "Process contact list...\n"); - contacts = xmlnode_get_child(result, "contacts"); + contacts = xmlnode_get_child(result, "Contacts"); if (contacts != NULL) { msn_parse_addressbook_contacts(session, contacts); } - abNode = xmlnode_get_child(result, "ab"); + abNode = xmlnode_get_child(result, "Ab"); if (abNode != NULL) { xmlnode *node2; char *tmp = NULL; @@ -954,6 +971,11 @@ g_free(tmp); } + circleNode = xmlnode_get_child(result, "CircleResult"); + if (circleNode != NULL) { + msn_parse_addressbook_circles(session, circleNode); + } + return TRUE; } diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/contact.h --- a/libpurple/protocols/msn/contact.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/contact.h Thu Feb 23 08:13:23 2012 +0000 @@ -62,7 +62,7 @@ #define MSN_APPLICATION_ID "CFE80F9D-180F-4399-82AB-413F33A1FA11" -#define MSN_CONTACT_SERVER "omega.contacts.msn.com" +#define MSN_CONTACT_SERVER "local-bay.contacts.msn.com" /* Get Contact List */ @@ -142,11 +142,13 @@ "" /* Get AddressBook */ -#define MSN_GET_ADDRESS_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABFindAll" +#define MSN_GET_ADDRESS_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABFindContactsPaged" #define MSN_GET_ADDRESS_FULL_TIME "0001-01-01T00:00:00.0000000-08:00" #define MSN_GET_ADDRESS_UPDATE_XML \ - "true"\ - "%s" + ""\ + "true"\ + "%s"\ + "" #define MSN_GET_GLEAM_UPDATE_XML \ "%s"\ @@ -171,11 +173,11 @@ ""\ ""\ ""\ - ""\ - "00000000-0000-0000-0000-000000000000"\ + ""\ "Full"\ + "AB AllGroups CircleResult"\ "%s"\ - ""\ + ""\ ""\ "" diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/msn.c Thu Feb 23 08:13:23 2012 +0000 @@ -1223,7 +1223,7 @@ m = g_list_append(m, act); m = g_list_append(m, NULL); - if (session->enable_mpop && session->protocol_ver >= 16) + if (session->enable_mpop) { act = purple_plugin_action_new(_("View Locations..."), msn_show_locations); @@ -1571,89 +1571,68 @@ return 0; } - if (msn_user_is_online(account, who) || - msn_user_is_yahoo(account, who) || - swboard != NULL) { - /*User online or have a swboard open because it's invisible - * and sent us a message,then send Online Instant Message*/ - - if (msglen + strlen(msgformat) + strlen(VERSION) > 1564) - { - g_free(msgformat); - g_free(msgtext); - - return -E2BIG; - } - - msg = msn_message_new_plain(msgtext); - msg->remote_user = g_strdup(who); - msn_message_set_header(msg, "X-MMS-IM-Format", msgformat); - + if (msglen + strlen(msgformat) + strlen(VERSION) > 1564) + { g_free(msgformat); g_free(msgtext); - purple_debug_info("msn", "prepare to send online Message\n"); - if (g_ascii_strcasecmp(who, username)) - { - if (flags & PURPLE_MESSAGE_AUTO_RESP) { - msn_message_set_flag(msg, 'U'); - } - if (msn_user_is_yahoo(account, who)) { - /*we send the online and offline Message to Yahoo User via UBM*/ - purple_debug_info("msn", "send to Yahoo User\n"); - uum_send_msg(session, msg); - } else { - purple_debug_info("msn", "send via switchboard\n"); - msn_send_im_message(session, msg); - } + return -E2BIG; + } + + msg = msn_message_new_plain(msgtext); + msg->remote_user = g_strdup(who); + msn_message_set_header(msg, "X-MMS-IM-Format", msgformat); + + g_free(msgformat); + g_free(msgtext); + + purple_debug_info("msn", "prepare to send online Message\n"); + if (g_ascii_strcasecmp(who, username)) + { + if (flags & PURPLE_MESSAGE_AUTO_RESP) { + msn_message_set_flag(msg, 'U'); + } + + if (msn_user_is_yahoo(account, who) || !(msn_user_is_online(account, who) || swboard != NULL)) { + /*we send the online and offline Message to Yahoo User via UBM*/ + purple_debug_info("msn", "send to Yahoo User\n"); + msn_notification_send_uum(session, msg); + } else { + purple_debug_info("msn", "send via switchboard\n"); + msn_send_im_message(session, msg); } - else - { - char *body_str, *body_enc, *pre, *post; - const char *format; - MsnIMData *imdata = g_new0(MsnIMData, 1); - /* - * In MSN, you can't send messages to yourself, so - * we'll fake like we received it ;) - */ - body_str = msn_message_to_string(msg); - body_enc = g_markup_escape_text(body_str, -1); - g_free(body_str); - - format = msn_message_get_header_value(msg, "X-MMS-IM-Format"); - msn_parse_format(format, &pre, &post); - body_str = g_strdup_printf("%s%s%s", pre ? pre : "", - body_enc ? body_enc : "", post ? post : ""); - g_free(body_enc); - g_free(pre); - g_free(post); - - serv_got_typing_stopped(gc, who); - imdata->gc = gc; - imdata->who = who; - imdata->msg = body_str; - imdata->flags = flags & ~PURPLE_MESSAGE_SEND; - imdata->when = time(NULL); - purple_timeout_add(0, msn_send_me_im, imdata); - } - - msn_message_unref(msg); - } else { - /*send Offline Instant Message,only to MSN Passport User*/ - char *friendname; - - purple_debug_info("msn", "prepare to send offline Message\n"); - - friendname = msn_encode_mime(purple_account_get_username(account)); - msn_oim_prep_send_msg_info(session->oim, - purple_account_get_username(account), - friendname, who, msgtext); - msn_oim_send_msg(session->oim); - - g_free(msgformat); - g_free(msgtext); - g_free(friendname); } + else + { + char *body_str, *body_enc, *pre, *post; + const char *format; + MsnIMData *imdata = g_new0(MsnIMData, 1); + /* + * In MSN, you can't send messages to yourself, so + * we'll fake like we received it ;) + */ + body_str = msn_message_to_string(msg); + body_enc = g_markup_escape_text(body_str, -1); + g_free(body_str); + + format = msn_message_get_header_value(msg, "X-MMS-IM-Format"); + msn_parse_format(format, &pre, &post); + body_str = g_strdup_printf("%s%s%s", pre ? pre : "", + body_enc ? body_enc : "", post ? post : ""); + g_free(body_enc); + g_free(pre); + g_free(post); + + serv_got_typing_stopped(gc, who); + imdata->gc = gc; + imdata->who = who; + imdata->msg = body_str; + imdata->flags = flags & ~PURPLE_MESSAGE_SEND; + imdata->when = time(NULL); + purple_timeout_add(0, msn_send_me_im, imdata); + } + + msn_message_unref(msg); return 1; } diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/msn.h --- a/libpurple/protocols/msn/msn.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/msn.h Thu Feb 23 08:13:23 2012 +0000 @@ -115,10 +115,10 @@ #define MSN_SERVER "messenger.hotmail.com" #define MSN_HTTPCONN_SERVER "gateway.messenger.hotmail.com" #define MSN_PORT 1863 -#define WLM_PROT_VER 16 +#define WLM_PROT_VER 18 -#define WLM_MAX_PROTOCOL 16 -#define WLM_MIN_PROTOCOL 15 +#define WLM_MAX_PROTOCOL 18 +#define WLM_MIN_PROTOCOL 18 #define MSN_TYPING_RECV_TIMEOUT 6 #define MSN_TYPING_SEND_TIMEOUT 4 diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/msnutils.c --- a/libpurple/protocols/msn/msnutils.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/msnutils.c Thu Feb 23 08:13:23 2012 +0000 @@ -490,6 +490,21 @@ *ret_port = port; } +void +msn_parse_user(const char *str, char **ret_user, int *ret_network) +{ + char **tokens; + + tokens = g_strsplit(str, ":", 2); + + *ret_network = atoi(tokens[0]); + *ret_user = tokens[1]; + + g_free(tokens[0]); + /* tokens[1] is returned */ + g_free(tokens); +} + gboolean msn_email_is_valid(const char *passport) { diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/msnutils.h --- a/libpurple/protocols/msn/msnutils.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/msnutils.h Thu Feb 23 08:13:23 2012 +0000 @@ -76,6 +76,15 @@ void msn_parse_socket(const char *str, char **ret_host, int *ret_port); /** + * Parses a user name + * + * @param str A network:username string. + * @param ret_user Return of the user's passport. + * @param ret_network Return of the user's network. + */ +void msn_parse_user(const char *str, char **ret_user, int *ret_network); + +/** * Verify if the email is a vaild passport. * * @param passport The email diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/nexus.c --- a/libpurple/protocols/msn/nexus.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/nexus.c Thu Feb 23 08:13:23 2012 +0000 @@ -44,9 +44,8 @@ {"messenger.msn.com", "?id=507"}, /* Authentication for receiving OIMs. */ {"contacts.msn.com", "MBI"}, /* Authentication for the Contact server. */ {"messengersecure.live.com", "MBI_SSL"}, /* Authentication for sending OIMs. */ - {"spaces.live.com", "MBI"}, /* Authentication for the Windows Live Spaces */ - {"livecontacts.live.com", "MBI"}, /* Live Contacts API, a simplified version of the Contacts SOAP service */ {"storage.live.com", "MBI"}, /* Storage REST API */ + {"sup.live.com", "MBI"}, /* What's New service */ }; /************************************************************************** diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/nexus.h --- a/libpurple/protocols/msn/nexus.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/nexus.h Thu Feb 23 08:13:23 2012 +0000 @@ -36,9 +36,8 @@ MSN_AUTH_MESSENGER_WEB = 1, MSN_AUTH_CONTACTS = 2, MSN_AUTH_LIVE_SECURE = 3, - MSN_AUTH_SPACES = 4, - MSN_AUTH_LIVE_CONTACTS = 5, - MSN_AUTH_STORAGE = 6 + MSN_AUTH_STORAGE = 4, + MSN_AUTH_WHATSNEW = 5 } MsnAuthDomains; #define MSN_SSO_SERVER "login.live.com" diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/notification.c Thu Feb 23 08:13:23 2012 +0000 @@ -164,10 +164,7 @@ msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END); - if (session->protocol_ver >= 16) - trans = msn_transaction_new(cmdproc, "USR", "SSO S %s %s %s", ticket, response, session->guid); - else - trans = msn_transaction_new(cmdproc, "USR", "SSO S %s %s", ticket, response); + trans = msn_transaction_new(cmdproc, "USR", "SSO S %s %s %s", ticket, response, session->guid); msn_cmdproc_send_trans(cmdproc, trans); } @@ -359,23 +356,34 @@ /*send Message to Yahoo Messenger*/ void -uum_send_msg(MsnSession *session,MsnMessage *msg) +msn_notification_send_uum(MsnSession *session, MsnMessage *msg) { MsnCmdProc *cmdproc; MsnTransaction *trans; char *payload; gsize payload_len; int type; + MsnUser *user; + int network; + + g_return_if_fail(msg != NULL); cmdproc = session->notification->cmdproc; - g_return_if_fail(msg != NULL); + payload = msn_message_gen_payload(msg, &payload_len); + type = msg->type; + user = msn_userlist_find_user(session->userlist, msg->remote_user); + if (user) + network = msn_user_get_network(user); + else + network = MSN_NETWORK_PASSPORT; + purple_debug_info("msn", "send UUM, payload{%s}, strlen:%" G_GSIZE_FORMAT ", len:%" G_GSIZE_FORMAT "\n", payload, strlen(payload), payload_len); - type = msg->type; - trans = msn_transaction_new(cmdproc, "UUM", "%s 32 %d %" G_GSIZE_FORMAT, - msg->remote_user, type, payload_len); + + trans = msn_transaction_new(cmdproc, "UUM", "%s %d %d %" G_GSIZE_FORMAT, + msg->remote_user, network, type, payload_len); msn_transaction_set_payload(trans, payload, strlen(payload)); msn_cmdproc_send_trans(cmdproc, trans); } @@ -390,10 +398,7 @@ * command and we are processing it */ if (cmd->payload == NULL) { cmdproc->last_cmd->payload_cb = msg_cmd_post; - if (cmdproc->session->protocol_ver >= 16) - cmd->payload_len = atoi(cmd->params[5]); - else - cmd->payload_len = atoi(cmd->params[3]); + cmd->payload_len = atoi(cmd->params[5]); } else { g_return_if_fail(cmd->payload_cb != NULL); @@ -1042,7 +1047,7 @@ networkid = atoi(cmd->params[3]); friendly = g_strdup(purple_url_decode(cmd->params[4])); clientid = strtoul(cmd->params[5], &extcap_str, 10); - if (session->protocol_ver >= 16 && extcap_str && *extcap_str) + if (extcap_str && *extcap_str) extcaps = strtoul(extcap_str+1, NULL, 10); else extcaps = 0; @@ -1056,7 +1061,7 @@ networkid = atoi(cmd->params[3]); friendly = g_strdup(purple_url_decode(cmd->params[4])); clientid = strtoul(cmd->params[5], &extcap_str, 10); - if (session->protocol_ver >= 16 && extcap_str && *extcap_str) + if (extcap_str && *extcap_str) extcaps = strtoul(extcap_str+1, NULL, 10); else extcaps = 0; @@ -1069,7 +1074,7 @@ networkid = atoi(cmd->params[3]); friendly = g_strdup(purple_url_decode(cmd->params[4])); clientid = strtoul(cmd->params[5], &extcap_str, 10); - if (session->protocol_ver >= 16 && extcap_str && *extcap_str) + if (extcap_str && *extcap_str) extcaps = strtoul(extcap_str+1, NULL, 10); else extcaps = 0; @@ -1077,7 +1082,7 @@ /* MSNP8+ with Display Picture object */ friendly = g_strdup(purple_url_decode(cmd->params[3])); clientid = strtoul(cmd->params[4], &extcap_str, 10); - if (session->protocol_ver >= 16 && extcap_str && *extcap_str) + if (extcap_str && *extcap_str) extcaps = strtoul(extcap_str+1, NULL, 10); else extcaps = 0; @@ -1087,7 +1092,7 @@ /* MSNP8+ without Display Picture object */ friendly = g_strdup(purple_url_decode(cmd->params[3])); clientid = strtoul(cmd->params[4], &extcap_str, 10); - if (session->protocol_ver >= 16 && extcap_str && *extcap_str) + if (extcap_str && *extcap_str) extcaps = strtoul(extcap_str+1, NULL, 10); else extcaps = 0; @@ -1250,15 +1255,15 @@ MsnObject *msnobj; unsigned long clientid, extcaps; char *extcap_str; + char *passport; int networkid; - const char *state, *passport, *friendly; + const char *state, *friendly; session = cmdproc->session; - state = cmd->params[0]; - passport = cmd->params[1]; - networkid = atoi(cmd->params[2]); - friendly = purple_url_decode(cmd->params[3]); + state = cmd->params[0]; + msn_parse_user(cmd->params[1], &passport, &networkid); + friendly = purple_url_decode(cmd->params[2]); user = msn_userlist_find_user(session->userlist, passport); if (user == NULL) return; @@ -1268,9 +1273,9 @@ msn_update_contact(session, passport, MSN_UPDATE_DISPLAY, friendly); } - if (cmd->param_count == 6) + if (cmd->param_count == 5) { - msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[5])); + msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[4])); msn_user_set_object(user, msnobj); } else @@ -1278,8 +1283,8 @@ msn_user_set_object(user, NULL); } - clientid = strtoul(cmd->params[4], &extcap_str, 10); - if (session->protocol_ver >= 16 && extcap_str && *extcap_str) + clientid = strtoul(cmd->params[3], &extcap_str, 10); + if (extcap_str && *extcap_str) extcaps = strtoul(extcap_str+1, NULL, 10); else extcaps = 0; @@ -1292,6 +1297,8 @@ msn_user_set_state(user, state); msn_user_update(user); + + g_free(passport); } #if 0 @@ -1705,22 +1712,27 @@ { MsnSession *session; MsnUser *user; - const char *passport; + char *passport; + int network; xmlnode *payloadNode; char *psm_str, *str; session = cmdproc->session; - passport = cmd->params[0]; + msn_parse_user(cmd->params[0], &passport, &network); user = msn_userlist_find_user(session->userlist, passport); + if (user == NULL) { - char *str = g_strndup(payload, len); + str = g_strndup(payload, len); purple_debug_info("msn", "unknown user %s, payload is %s\n", passport, str); + g_free(passport); g_free(str); return; } + g_free(passport); + /* Free any existing media info for this user */ if (user->extinfo) { g_free(user->extinfo->media_album); @@ -1767,7 +1779,7 @@ { purple_debug_misc("msn", "UBX received.\n"); cmdproc->last_cmd->payload_cb = ubx_cmd_post; - cmd->payload_len = atoi(cmd->params[2]); + cmd->payload_len = atoi(cmd->params[1]); } static void @@ -1812,10 +1824,7 @@ epDataNode = xmlnode_new("EndpointData"); capNode = xmlnode_new_child(epDataNode, "Capabilities"); - if (session->protocol_ver >= 16) - caps = g_strdup_printf("%d:%02d", MSN_CLIENT_ID_CAPABILITIES, MSN_CLIENT_ID_EXT_CAPS); - else - caps = g_strdup_printf("%d", MSN_CLIENT_ID_CAPABILITIES); + caps = g_strdup_printf("%d:%02d", MSN_CLIENT_ID_CAPABILITIES, MSN_CLIENT_ID_EXT_CAPS); xmlnode_insert_data(capNode, caps, -1); g_free(caps); @@ -1942,6 +1951,22 @@ msn_cmdproc_send_trans(cmdproc, trans); } +void +msn_notification_send_circle_auth(MsnSession *session, const char *ticket) +{ + MsnTransaction *trans; + MsnCmdProc *cmdproc; + char *encoded; + + cmdproc = session->notification->cmdproc; + + encoded = purple_base64_encode((guchar *)ticket, strlen(ticket)); + trans = msn_transaction_new(cmdproc, "USR", "SHA A %s", encoded); + msn_cmdproc_send_trans(cmdproc, trans); + + g_free(encoded); +} + /************************************************************************** * Message Types **************************************************************************/ diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/notification.h --- a/libpurple/protocols/msn/notification.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/notification.h Thu Feb 23 08:13:23 2012 +0000 @@ -76,8 +76,6 @@ } MsnUnifiedNotificationType; -void uum_send_msg(MsnSession *session, MsnMessage *msg); - void msn_notification_end(void); void msn_notification_init(void); @@ -97,6 +95,8 @@ void msn_notification_disconnect(MsnNotification *notification); void msn_notification_dump_contact(MsnSession *session); +void msn_notification_send_uum(MsnSession *session, MsnMessage *msg); + void msn_notification_send_uux(MsnSession *session, const char *payload); void msn_notification_send_uux_endpointdata(MsnSession *session); @@ -108,6 +108,8 @@ MsnUnifiedNotificationType type, const char *payload); +void msn_notification_send_circle_auth(MsnSession *session, const char *ticket); + /** * Closes a notification. * diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/oim.c --- a/libpurple/protocols/msn/oim.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/oim.c Thu Feb 23 08:13:23 2012 +0000 @@ -606,11 +606,12 @@ const char *date; const char *from; const char *boundary; - char *decode_msg = NULL; + char *decode_msg = NULL, *clean_msg = NULL; gsize body_len; char **tokens; char *passport = NULL; time_t stamp; + const char *charset = NULL; message = msn_message_new(MSN_MSG_UNKNOWN); @@ -638,6 +639,8 @@ type = msn_message_get_content_type(multipart); if (type && !strcmp(type, "text/plain")) { decode_msg = (char *)purple_base64_decode(multipart->body, &body_len); + charset = msn_message_get_charset(multipart); + msn_message_unref(multipart); break; } @@ -654,6 +657,46 @@ } } else { decode_msg = (char *)purple_base64_decode(message->body, &body_len); + charset = msn_message_get_charset(message); + } + + if (charset && !((strncasecmp(charset, "UTF-8", 5) == 0) || (strncasecmp(charset, "UTF8", 4) == 0))) { + clean_msg = g_convert(decode_msg, body_len, "UTF-8", charset, NULL, NULL, NULL); + + if (!clean_msg) { + char *clean = purple_utf8_salvage(decode_msg); + + purple_debug_error("msn", "Failed to convert charset from %s to UTF-8 for OIM message: %s\n", charset, clean); + + clean_msg = g_strdup_printf(_("%s (There was an error receiving this message. " + "Converting the encoding from %s to UTF-8 failed.)"), + clean, charset); + g_free(clean); + } + + g_free(decode_msg); + + } else if (!g_utf8_validate(decode_msg, body_len, NULL)) { + char *clean = purple_utf8_salvage(decode_msg); + + purple_debug_error("msn", "Received an OIM message that is not UTF-8," + " and no encoding specified: %s\n", clean); + + if (charset) { + clean_msg = g_strdup_printf(_("%s (There was an error receiving this message." + " The charset was %s, but it was not valid UTF-8.)"), + clean, charset); + } else { + clean_msg = g_strdup_printf(_("%s (There was an error receiving this message." + " The charset was missing, but it was not valid UTF-8.)"), + clean); + } + + g_free(clean); + g_free(decode_msg); + + } else { + clean_msg = decode_msg; } from = msn_message_get_header_value(message, "X-OIM-originatingSource"); @@ -695,7 +738,7 @@ purple_debug_info("msn", "oim Date:{%s},passport{%s}\n", date, passport); - serv_got_im(purple_account_get_connection(rdata->oim->session->account), passport, decode_msg, 0, + serv_got_im(purple_account_get_connection(rdata->oim->session->account), passport, clean_msg, 0, stamp); /*Now get the oim message ID from the oim_list. @@ -704,7 +747,7 @@ msn_oim_post_delete_msg(rdata); g_free(passport); - g_free(decode_msg); + g_free(clean_msg); msn_message_unref(message); } diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/session.c --- a/libpurple/protocols/msn/session.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/session.c Thu Feb 23 08:13:23 2012 +0000 @@ -491,11 +491,10 @@ msn_session_sync_users(session); } - if (session->protocol_ver >= 16) { - /* TODO: Send this when updating status instead? */ - msn_notification_send_uux_endpointdata(session); - msn_notification_send_uux_private_endpointdata(session); - } + /* TODO: Send this when updating status instead? */ + msn_notification_send_uux_endpointdata(session); + msn_notification_send_uux_private_endpointdata(session); + msn_change_status(session); } diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/state.c --- a/libpurple/protocols/msn/state.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/state.c Thu Feb 23 08:13:23 2012 +0000 @@ -186,7 +186,7 @@ statusline_stripped = purple_markup_strip_html(statusline); media = create_media_string(presence); g_free(session->psm); - session->psm = msn_build_psm(statusline_stripped, media, session->protocol_ver >= 16 ? session->guid : NULL, session->protocol_ver); + session->psm = msn_build_psm(statusline_stripped, media, session->guid, session->protocol_ver); payload = session->psm; @@ -245,10 +245,8 @@ if (msnobj == NULL) { - if (session->protocol_ver >= 16) - trans = msn_transaction_new(cmdproc, "CHG", "%s %u:%02u 0", state_text, caps, MSN_CLIENT_ID_EXT_CAPS); - else - trans = msn_transaction_new(cmdproc, "CHG", "%s %u", state_text, caps); + trans = msn_transaction_new(cmdproc, "CHG", "%s %u:%02u 0", state_text, + caps, MSN_CLIENT_ID_EXT_CAPS); } else { @@ -256,12 +254,9 @@ msnobj_str = msn_object_to_string(msnobj); - if (session->protocol_ver >= 16) - trans = msn_transaction_new(cmdproc, "CHG", "%s %u:%02u %s", state_text, - caps, MSN_CLIENT_ID_EXT_CAPS, purple_url_encode(msnobj_str)); - else - trans = msn_transaction_new(cmdproc, "CHG", "%s %u %s", state_text, - caps, purple_url_encode(msnobj_str)); + trans = msn_transaction_new(cmdproc, "CHG", "%s %u:%02u %s", state_text, + caps, MSN_CLIENT_ID_EXT_CAPS, + purple_url_encode(msnobj_str)); g_free(msnobj_str); } diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/switchboard.c --- a/libpurple/protocols/msn/switchboard.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/switchboard.c Thu Feb 23 08:13:23 2012 +0000 @@ -707,10 +707,7 @@ ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { purple_debug_misc("msn", "get UBM...\n"); - if (cmdproc->session->protocol_ver >= 16) - cmd->payload_len = atoi(cmd->params[5]); - else - cmd->payload_len = atoi(cmd->params[3]); + cmd->payload_len = atoi(cmd->params[5]); cmdproc->last_cmd->payload_cb = msg_cmd_post; } @@ -867,12 +864,9 @@ swboard = cmdproc->data; g_return_if_fail(swboard != NULL); - if (servconn->session->protocol_ver >= 16) - username = g_strdup_printf("%s;{%s}", - purple_account_get_username(account), - servconn->session->guid); - else - username = g_strdup(purple_account_get_username(account)); + username = g_strdup_printf("%s;{%s}", + purple_account_get_username(account), + servconn->session->guid); if (msn_switchboard_is_invited(swboard)) { diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/msn/user.c --- a/libpurple/protocols/msn/user.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/msn/user.c Thu Feb 23 08:13:23 2012 +0000 @@ -699,6 +699,14 @@ return NULL; } +MsnNetwork +msn_user_get_network(const MsnUser *user) +{ + g_return_val_if_fail(user != NULL, MSN_NETWORK_UNKNOWN); + + return user->networkid; +} + MsnObject * msn_user_get_object(const MsnUser *user) { diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/oscar/family_feedbag.c --- a/libpurple/protocols/oscar/family_feedbag.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Thu Feb 23 08:13:23 2012 +0000 @@ -769,7 +769,7 @@ * @param od The oscar odion. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_cleanlist(OscarData *od) +static int aim_ssi_cleanlist(OscarData *od) { struct aim_ssi_item *cur, *next; @@ -971,7 +971,7 @@ aim_ssi_itemlist_del(&od->ssi.local, del); /* Modify the parent group */ - aim_ssi_itemlist_rebuildgroup(&od->ssi.local, group); + aim_ssi_itemlist_rebuildgroup(&od->ssi.local, NULL); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -1336,6 +1336,9 @@ for (cur=od->ssi.official.data; cur; cur=cur->next) aim_ssi_itemlist_add(&od->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data); + /* Clean the buddy list */ + aim_ssi_cleanlist(od); + od->ssi.received_data = TRUE; if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/oscar/family_icbm.c --- a/libpurple/protocols/oscar/family_icbm.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Thu Feb 23 08:13:23 2012 +0000 @@ -650,6 +650,9 @@ GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL; ByteStream hdrbs; + g_return_if_fail(bn != NULL); + g_return_if_fail(ip != NULL); + conn = flap_connection_findbygroup(od, SNAC_FAMILY_ICBM); if (conn == NULL) return; diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/oscar/oscar.c Thu Feb 23 08:13:23 2012 +0000 @@ -3924,9 +3924,6 @@ purple_debug_info("oscar", "ssi: syncing local list and server list\n"); - /* Clean the buddy list */ - aim_ssi_cleanlist(od); - /*** Begin code for pruning buddies from local list if they're not in server list ***/ /* Buddies */ diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/oscar/oscar.h Thu Feb 23 08:13:23 2012 +0000 @@ -940,7 +940,6 @@ 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); int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny); int aim_ssi_setpresence(OscarData *od, guint32 presence); diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/oscar/peer.c --- a/libpurple/protocols/oscar/peer.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/oscar/peer.c Thu Feb 23 08:13:23 2012 +0000 @@ -656,6 +656,7 @@ char *tmp; FlapConnection *bos_conn; const char *listener_ip; + const guchar *ip_atoi; unsigned short listener_port; conn = data; @@ -690,11 +691,28 @@ listener_ip = purple_network_get_my_ip(bos_conn->gsc->fd); else listener_ip = purple_network_get_my_ip(bos_conn->fd); + + ip_atoi = purple_network_ip_atoi(listener_ip); + if (ip_atoi == NULL) { + /* Could not convert IP to 4 byte array--weird, but this does + happen for some users (#4829, Adium #15839). Maybe they're + connecting with IPv6...? Maybe through a proxy? */ + purple_debug_error("oscar", "Can't ask peer to connect to us " + "because purple_network_ip_atoi(%s) returned NULL. " + "fd=%d. is_ssl=%d\n", + listener_ip ? listener_ip : "(null)", + bos_conn->gsc ? bos_conn->gsc->fd : bos_conn->fd, + bos_conn->gsc ? 1 : 0); + peer_connection_trynext(conn); + return; + } + listener_port = purple_network_get_port_from_fd(conn->listenerfd); + if (conn->type == OSCAR_CAPABILITY_DIRECTIM) { aim_im_sendch2_odc_requestdirect(od, - conn->cookie, conn->bn, purple_network_ip_atoi(listener_ip), + conn->cookie, conn->bn, ip_atoi, listener_port, ++conn->lastrequestnumber); /* Print a message to a local conversation window */ @@ -706,15 +724,6 @@ } else if (conn->type == OSCAR_CAPABILITY_SENDFILE) { - const guchar *ip_atoi = purple_network_ip_atoi(listener_ip); - if (ip_atoi == NULL) { - purple_debug_error("oscar", "Cannot send file. atoi(%s) failed.\n" - "Other possibly useful information: fd = %d, port = %d\n", - listener_ip ? listener_ip : "(null!)", conn->listenerfd, - listener_port); - purple_xfer_cancel_local(conn->xfer); - return; - } aim_im_sendch2_sendfile_requestdirect(od, conn->cookie, conn->bn, ip_atoi, diff -r 4ae0c82b158d -r 4f8626d4ef63 libpurple/protocols/oscar/util.c --- a/libpurple/protocols/oscar/util.c Sat Jan 21 12:02:41 2012 +0000 +++ b/libpurple/protocols/oscar/util.c Thu Feb 23 08:13:23 2012 +0000 @@ -141,12 +141,12 @@ if (purple_email_is_valid(name)) return TRUE; - /* Normal AIM usernames can't start with a number */ - if (isdigit(name[0])) + /* Normal AIM usernames can't start with a number, period or underscore */ + if (isalnum(name[0]) == 0) return FALSE; for (i = 0; name[i] != '\0'; i++) { - if (!isalnum(name[i]) && (name[i] != ' ')) + if (!isalnum(name[i]) && name[i] != ' ' && name[i] != '.' && name[i] != '_') return FALSE; } diff -r 4ae0c82b158d -r 4f8626d4ef63 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat Jan 21 12:02:41 2012 +0000 +++ b/pidgin/gtkconv.c Thu Feb 23 08:13:23 2012 +0000 @@ -5797,7 +5797,7 @@ if (convnode == NULL || !purple_blist_node_get_bool(convnode, "gtk-mute-sound")) gtkconv->make_sound = TRUE; - if (convnode != NULL) { + if (convnode != NULL && purple_blist_node_has_setting(convnode, "enable-logging")) { gboolean logging = purple_blist_node_get_bool(convnode, "enable-logging"); purple_conversation_set_logging(conv, logging); } @@ -8257,6 +8257,7 @@ add_message_history_to_gtkconv(gpointer data) { PidginConversation *gtkconv = data; + GtkWebView *webview = GTK_WEBVIEW(gtkconv->webview); int count = 0; int timer = gtkconv->attach.timer; time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); @@ -8266,7 +8267,8 @@ while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ PurpleConvMessage *msg = gtkconv->attach.current->data; if (!im && when && when < purple_conversation_message_get_timestamp(msg)) { - gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "

"); + gtk_webview_append_html(webview, "

"); + gtk_webview_scroll_to_end(webview, TRUE); g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); } pidgin_conv_write_conv( @@ -8313,7 +8315,8 @@ purple_conversation_message_get_flags(msg), purple_conversation_message_get_timestamp(msg)); } - gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "

"); + gtk_webview_append_html(webview, "

"); + gtk_webview_scroll_to_end(webview, TRUE); g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); } diff -r 4ae0c82b158d -r 4f8626d4ef63 pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Sat Jan 21 12:02:41 2012 +0000 +++ b/pidgin/gtkdialogs.c Thu Feb 23 08:13:23 2012 +0000 @@ -78,8 +78,6 @@ {"Hylke Bons", N_("artist"), "hylkebons@gmail.com"}, {"Sadrul Habib Chowdhury", NULL, NULL}, {"Mark 'KingAnt' Doliner", NULL, "mark@kingant.net"}, - {"Casey Harkins", NULL, NULL}, - {"Ivan Komarov", NULL, "ivan.komarov@pidgin.im"}, {"Gary 'grim' Kramlich", NULL, "grim@pidgin.im"}, {"Richard 'rlaager' Laager", NULL, "rlaager@pidgin.im"}, {"Marcus 'malu' Lundblad", NULL, NULL}, @@ -112,12 +110,14 @@ {"Herman Bloggs", N_("win32 port"), "herman@bluedigits.com"}, {"Thomas Butter", NULL, NULL}, /* feel free to not translate this */ - {N_("Ka-Hing Cheung"), NULL, NULL}, + {N_("Ka-Hing Cheung"), NULL, NULL}, {"Jim Duchek", N_("maintainer"), "jim@linuxpimps.com"}, {"Sean Egan", NULL, "sean.egan@gmail.com"}, {"Rob Flynn", N_("maintainer"), NULL}, {"Adam Fritzler", N_("libfaim maintainer"), NULL}, {"Christian 'ChipX86' Hammond", N_("webmaster"), NULL}, + {"Casey Harkins", NULL, NULL}, + {"Ivan Komarov", NULL, "ivan.komarov@pidgin.im"}, /* If "lazy bum" translates literally into a serious insult, use something else or omit it. */ {"Syd Logan", N_("hacker and designated driver [lazy bum]"), NULL}, {"Christopher 'siege' O'Brien", NULL, "taliesein@users.sf.net"}, @@ -142,33 +142,34 @@ {NULL, NULL, NULL} }; -/* Order: Code, then Alphabetical by Last Name */ +/* Order: Code, then Alphabetical by Last Name + Use NULL language and code for secondary translators. */ static const struct translator translators[] = { {N_("Afrikaans"), "af", "Samuel Murray", "afrikaans@gmail.com"}, - {N_("Afrikaans"), "af", "Friedel Wolff", "friedel@translate.org.za"}, + {NULL, NULL, "Friedel Wolff", "friedel@translate.org.za"}, {N_("Arabic"), "ar", "Khaled Hosny", "khaledhosny@eglug.org"}, {N_("Assamese"), "as", "Amitakhya Phukan", "aphukan@fedoraproject.org"}, {N_("Belarusian Latin"), "be@latin", "Ihar Hrachyshka", "ihar.hrachyshka@gmail.com"}, {N_("Bulgarian"), "bg", "Vladimira Girginova", "missing@here.is"}, - {N_("Bulgarian"), "bg", "Vladimir (Kaladan) Petkov", "kaladan@gmail.com"}, + {NULL, NULL, "Vladimir (Kaladan) Petkov", "kaladan@gmail.com"}, {N_("Bengali"), "bn", "Israt Jahan", "israt@ankur.org.bd"}, - {N_("Bengali"), "bn", "Jamil Ahmed", "jamil@bengalinux.org"}, - {N_("Bengali"), "bn", "Samia Nimatullah", "mailsamia2001@yahoo.com"}, + {NULL, NULL, "Jamil Ahmed", "jamil@bengalinux.org"}, + {NULL, NULL, "Samia Nimatullah", "mailsamia2001@yahoo.com"}, {N_("Bengali-India"), "bn_IN", "Runa Bhattacharjee", "runab@fedoraproject.org"}, {N_("Bosnian"), "bs", "Lejla Hadzialic", "lejlah@gmail.com"}, {N_("Catalan"), "ca", "Josep Puigdemont", "josep.puigdemont@gmail.com"}, {N_("Valencian-Catalan"), "ca@valencia", "Toni Hermoso", "toniher@softcatala.org"}, - {N_("Valencian-Catalan"), "ca@valencia", "Josep Puigdemont", "tradgnome@softcatala.org"}, + {NULL, NULL, "Josep Puigdemont", "tradgnome@softcatala.org"}, {N_("Czech"), "cs", "David Vachulka", "david@konstrukce-cad.com"}, {N_("Danish"), "da", "Morten Brix Pedersen", "morten@wtf.dk"}, - {N_("Danish"), "da", "Peter Bach", "bach.peter@gmail.com"}, + {NULL, NULL, "Peter Bach", "bach.peter@gmail.com"}, {N_("German"), "de", "Björn Voigt", "bjoern@cs.tu-berlin.de"}, - {N_("German"), "de", "Jochen Kemnade", "jochenkemnade@web.de"}, + {NULL, NULL, "Jochen Kemnade", "jochenkemnade@web.de"}, {N_("Dzongkha"), "dz", "Norbu", "nor_den@hotmail.com"}, - {N_("Dzongkha"), "dz", "Jurmey Rabgay", "jur_gay@yahoo.com"}, - {N_("Dzongkha"), "dz", "Wangmo Sherpa", "rinwanshe@yahoo.com"}, + {NULL, NULL, "Jurmey Rabgay", "jur_gay@yahoo.com"}, + {NULL, NULL, "Wangmo Sherpa", "rinwanshe@yahoo.com"}, {N_("Greek"), "el", "Katsaloulis Panayotis", "panayotis@panayotis.com"}, - {N_("Greek"), "el", "Bouklis Panos", "panos@echidna-band.com"}, + {NULL, NULL, "Bouklis Panos", "panos@echidna-band.com"}, {N_("Australian English"), "en_AU", "Peter Lawler", "trans@six-by-nine.com.au"}, {N_("British English"), "en_GB", "Phil Hannent", "phil@hannent.co.uk"}, {N_("Canadian English"), "en_CA", "Adam Weinberger", "adamw@gnome.org"}, @@ -177,18 +178,18 @@ {N_("Estonian"), "et", "Ivar Smolin", "okul@linux.ee"}, {N_("Basque"), "eu", "Mikel Pascual Aldabaldetreku", "mikel.paskual@gmail.com"}, {N_("Persian"), "fa", "Elnaz Sarbar", "elnaz@farsiweb.info"}, - {N_("Persian"), "fa", "Meelad Zakaria", "meelad@farsiweb.info"}, - {N_("Persian"), "fa", "Roozbeh Pournader ", "roozbeh@farsiweb.info"}, + {NULL, NULL, "Meelad Zakaria", "meelad@farsiweb.info"}, + {NULL, NULL, "Roozbeh Pournader ", "roozbeh@farsiweb.info"}, {N_("Finnish"), "fi", "Timo Jyrinki", "timo.jyrinki@iki.fi"}, {N_("French"), "fr", "Éric Boumaour", "zongo_fr@users.sourceforge.net"}, {N_("Irish"), "ga", "Aaron Kearns", "ajkearns6@gmail.com"}, {N_("Galician"), "gl", "Mar Castro", "mariamarcp@gmail.com"}, - {N_("Galician"), "gl", "Frco. Javier Rial", "fjrial@cesga.es"}, + {NULL, NULL, "Frco. Javier Rial", "fjrial@cesga.es"}, {N_("Gujarati"), "gu", "Ankit Patel", "ankit_patel@users.sf.net"}, - {N_("Gujarati"), "gu", N_("Gujarati Language Team"), "indianoss-gujarati@lists.sourceforge.net"}, + {NULL, NULL, N_("Gujarati Language Team"), "indianoss-gujarati@lists.sourceforge.net"}, {N_("Hebrew"), "he", "Shalom Craimer", "scraimer@gmail.com"}, {N_("Hindi"), "hi", "Sangeeta Kumari", "sangeeta_0975@yahoo.com"}, - {N_("Hindi"), "hi", "Rajesh Ranjan", "rajeshkajha@yahoo.com"}, + {NULL, NULL, "Rajesh Ranjan", "rajeshkajha@yahoo.com"}, {N_("Croatian"), "hr", "Sabina Drempetić", "bina91991@googlemail.com"}, {N_("Hungarian"), "hu", "Kelemen Gábor", "kelemeng@gnome.hu"}, {N_("Armenian"), "hy", "David Avsharyan", "avsharyan@gmail.com"}, @@ -200,15 +201,15 @@ {N_("Kannada"), "kn", N_("Kannada Translation team"), "translation@sampada.info"}, {N_("Korean"), "ko", "Sushizang", "sushizang@empal.com"}, {N_("Kurdish"), "ku", "Erdal Ronahi", "erdal.ronahi@gmail.com"}, - {N_("Kurdish"), "ku", "Amed Ç. Jiyan", "amedcj@hotmail.com"}, - {N_("Kurdish"), "ku", "Rizoyê Xerzî", "rizoxerzi@hotmail.com"}, + {NULL, NULL, "Amed Ç. Jiyan", "amedcj@hotmail.com"}, + {NULL, NULL, "Rizoyê Xerzî", "rizoxerzi@hotmail.com"}, {N_("Lao"), "lo", "Anousak Souphavah", "anousak@gmail.com"}, {N_("Maithili"), "mai", "Sangeeta Kumari", "sangeeta_0975@yahoo.com"}, - {N_("Maithili"), "mai", "Rajesh Ranjan", "rajeshkajha@yahoo.com"}, + {NULL, NULL, "Rajesh Ranjan", "rajeshkajha@yahoo.com"}, {N_("Meadow Mari"), "mhr", "David Preece", "davidpreece1@gmail.com"}, {N_("Macedonian"), "mk", "Arangel Angov ", "arangel@linux.net.mk"}, - {N_("Macedonian"), "mk", "Ivana Kirkovska", "ivana.kirkovska@gmail.com"}, - {N_("Macedonian"), "mk", "Jovan Naumovski", "jovan@lugola.net"}, + {NULL, NULL, "Ivana Kirkovska", "ivana.kirkovska@gmail.com"}, + {NULL, NULL, "Jovan Naumovski", "jovan@lugola.net"}, {N_("Malayalam"), "ml", "Ani Peter", "apeter@redhat.com"}, {N_("Mongolian"), "mn", "gooyo", NULL}, {N_("Marathi"), "mr", "Sandeep Shedmake", "sandeep.shedmake@gmail.com"}, @@ -225,20 +226,20 @@ {N_("Portuguese-Brazil"), "pt_BR", "Rodrigo Luiz Marques Flores", "rodrigomarquesflores@gmail.com"}, {N_("Pashto"), "ps", "Kashif Masood", "masudmails@yahoo.com"}, {N_("Romanian"), "ro", "Mișu Moldovan", "dumol@gnome.org"}, - {N_("Romanian"), "ro", "Andrei Popescu", "andreimpopescu@gmail.com"}, + {NULL, NULL, "Andrei Popescu", "andreimpopescu@gmail.com"}, {N_("Russian"), "ru", "Антон Самохвалов", "samant.ua@mail.ru"}, {N_("Slovak"), "sk", "Jozef Káčer", "quickparser@gmail.com"}, - {N_("Slovak"), "sk", "loptosko", "loptosko@gmail.com"}, + {NULL, NULL, "loptosko", "loptosko@gmail.com"}, {N_("Slovenian"), "sl", "Martin Srebotnjak", "miles@filmsi.net"}, {N_("Albanian"), "sq", "Besnik Bleta", "besnik@programeshqip.org"}, {N_("Serbian"), "sr", "Miloš Popović", "gpopac@gmail.com"}, - {N_("Serbian"), "sr@Latn", "Miloš Popović", "gpopac@gmail.com"}, + {N_("Serbian Latin"), "sr@latin", "Miloš Popović", "gpopac@gmail.com"}, {N_("Sinhala"), "si", "Danishka Navin", "snavin@redhat.com"}, - {N_("Sinhala"), "si", "Yajith Ajantha Dayarathna", "yajith@gmail.com"}, + {NULL, NULL, "Yajith Ajantha Dayarathna", "yajith@gmail.com"}, {N_("Swedish"), "sv", "Peter Hjalmarsson", "xake@telia.com"}, {N_("Swahili"), "sw", "Paul Msegeya", "msegeya@gmail.com"}, {N_("Tamil"), "ta", "I. Felix", "ifelix25@gmail.com"}, - {N_("Tamil"), "ta", "Viveka Nathan K", "vivekanathan@users.sourceforge.net"}, + {NULL, NULL, "Viveka Nathan K", "vivekanathan@users.sourceforge.net"}, {N_("Telugu"), "te", "Krishnababu Krottapalli", "krottapalli@ymail.com"}, {N_("Thai"), "th", "Isriya Paireepairit", "markpeak@gmail.com"}, {N_("Turkish"), "tr", "Serdar Soytetir", "tulliana@gmail.com"}, @@ -247,10 +248,10 @@ {N_("Vietnamese"), "vi", N_("T.M.Thanh and the Gnome-Vi Team"), "gnomevi-list@lists.sf.net"}, {N_("Simplified Chinese"), "zh_CN", "Aron Xu", "happyaron.xu@gmail.com"}, {N_("Hong Kong Chinese"), "zh_HK", "Abel Cheung", "abelindsay@gmail.com"}, - {N_("Hong Kong Chinese"), "zh_HK", "Ambrose C. Li", "acli@ada.dhs.org"}, - {N_("Hong Kong Chinese"), "zh_HK", "Paladin R. Liu", "paladin@ms1.hinet.net"}, + {NULL, NULL, "Ambrose C. Li", "acli@ada.dhs.org"}, + {NULL, NULL, "Paladin R. Liu", "paladin@ms1.hinet.net"}, {N_("Traditional Chinese"), "zh_TW", "Ambrose C. Li", "acli@ada.dhs.org"}, - {N_("Traditional Chinese"), "zh_TW", "Paladin R. Liu", "paladin@ms1.hinet.net"}, + {NULL, NULL, "Paladin R. Liu", "paladin@ms1.hinet.net"}, {NULL, NULL, NULL, NULL} }; @@ -260,67 +261,71 @@ {N_("Arabic"), "ar", "Mohamed Magdy", "alnokta@yahoo.com"}, {N_("Bulgarian"), "bg", "Hristo Todorov", NULL}, {N_("Bengali"), "bn", "INDRANIL DAS GUPTA", "indradg@l2c2.org"}, - {N_("Bengali"), "bn", "Tisa Nafisa", "tisa_nafisa@yahoo.com"}, + {NULL, NULL, "Tisa Nafisa", "tisa_nafisa@yahoo.com"}, {N_("Catalan"), "ca", "JM Pérez Cáncer", NULL}, - {N_("Catalan"), "ca", "Robert Millan", NULL}, + {NULL, NULL, "Robert Millan", NULL}, {N_("Czech"), "cs", "Honza Král", NULL}, - {N_("Czech"), "cs", "Miloslav Trmac", "mitr@volny.cz"}, - {N_("German"), "de", "Daniel Seifert, Karsten Weiss", NULL}, + {NULL, NULL, "Miloslav Trmac", "mitr@volny.cz"}, + {N_("German"), "de", "Daniel Seifert", NULL}, + {NULL, NULL, "Karsten Weiss", NULL}, {N_("British English"), "en_GB", "Luke Ross", "luke@lukeross.name"}, {N_("Spanish"), "es", "JM Pérez Cáncer", NULL}, - {N_("Spanish"), "es", "Nicolás Lichtmaier", NULL}, - {N_("Spanish"), "es", "Amaya Rodrigo", NULL}, - {N_("Spanish"), "es", "Alejandro G Villar", NULL}, + {NULL, NULL, "Nicolás Lichtmaier", NULL}, + {NULL, NULL, "Amaya Rodrigo", NULL}, + {NULL, NULL, "Alejandro G Villar", NULL}, {N_("Basque"), "eu", "Iñaki Larrañaga Murgoitio", "dooteo@zundan.com"}, - {N_("Basque"), "eu", "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"}, + {NULL, NULL, "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"}, {N_("Finnish"), "fi", "Arto Alakulju", NULL}, - {N_("Finnish"), "fi", "Tero Kuusela", NULL}, + {NULL, NULL, "Tero Kuusela", NULL}, {N_("French"), "fr", "Sébastien François", NULL}, - {N_("French"), "fr", "Stéphane Pontier", NULL}, - {N_("French"), "fr", "Stéphane Wirtel", NULL}, - {N_("French"), "fr", "Loïc Jeannin", NULL}, + {NULL, NULL, "Stéphane Pontier", NULL}, + {NULL, NULL, "Stéphane Wirtel", NULL}, + {NULL, NULL, "Loïc Jeannin", NULL}, {N_("Galician"), "gl", "Ignacio Casal Quinteiro", NULL}, {N_("Hebrew"), "he", "Pavel Bibergal", NULL}, {N_("Hindi"), "hi", "Ravishankar Shrivastava", NULL}, {N_("Hungarian"), "hu", "Zoltan Sutto", NULL}, {N_("Italian"), "it", "Salvatore di Maggio", NULL}, {N_("Japanese"), "ja", "Takashi Aihana", NULL}, - {N_("Japanese"), "ja", "Ryosuke Kutsuna", NULL}, - {N_("Japanese"), "ja", "Taku Yasui", NULL}, - {N_("Japanese"), "ja", "Junichi Uekawa", NULL}, + {NULL, NULL, "Ryosuke Kutsuna", NULL}, + {NULL, NULL, "Taku Yasui", NULL}, + {NULL, NULL, "Junichi Uekawa", NULL}, {N_("Georgian"), "ka", "Temuri Doghonadze", NULL}, - {N_("Korean"), "ko", "Sang-hyun S, A Ho-seok Lee", NULL}, - {N_("Korean"), "ko", "Kyeong-uk Son", NULL}, + {N_("Korean"), "ko", "Sang-hyun S", NULL}, + {NULL, NULL, "A Ho-seok Lee", NULL}, + {NULL, NULL, "Kyeong-uk Son", NULL}, {N_("Lithuanian"), "lt", "Laurynas Biveinis", "laurynas.biveinis@gmail.com"}, - {N_("Lithuanian"), "lt", "Gediminas Čičinskas", NULL}, - {N_("Lithuanian"), "lt", "Andrius Štikonas", NULL}, + {NULL, NULL, "Gediminas Čičinskas", NULL}, + {NULL, NULL, "Andrius Štikonas", NULL}, {N_("Macedonian"), "mk", "Tomislav Markovski", NULL}, {N_("Bokmål Norwegian"), "nb", "Hallvard Glad", "hallvard.glad@gmail.com"}, - {N_("Bokmål Norwegian"), "nb", "Petter Johan Olsen", NULL}, - {N_("Bokmål Norwegian"), "nb", "Espen Stefansen", "espenas@gmail.com"}, + {NULL, NULL, "Petter Johan Olsen", NULL}, + {NULL, NULL, "Espen Stefansen", "espenas@gmail.com"}, {N_("Dutch, Flemish"), "nl", "Vincent van Adrighem", "V.vanAdrighem@dirck.mine.nu"}, {N_("Polish"), "pl", "Emil Nowak", "emil5@go2.pl"}, - {N_("Polish"), "pl", "Paweł Godlewski", "pawel@bajk.pl"}, - {N_("Polish"), "pl", "Krzysztof Foltman", "krzysztof@foltman.com"}, - {N_("Polish"), "pl", "Piotr Makowski", NULL}, - {N_("Polish"), "pl", "Przemysław Sułek", NULL}, + {NULL, NULL, "Paweł Godlewski", "pawel@bajk.pl"}, + {NULL, NULL, "Krzysztof Foltman", "krzysztof@foltman.com"}, + {NULL, NULL, "Piotr Makowski", NULL}, + {NULL, NULL, "Przemysław Sułek", NULL}, {N_("Portuguese-Brazil"), "pt_BR", "Maurício de Lemos Rodrigues Collares Neto", "mauricioc@gmail.com"}, {N_("Russian"), "ru", "Dmitry Beloglazov", "dmaa@users.sf.net"}, - {N_("Russian"), "ru", "Alexandre Prokoudine", NULL}, - {N_("Russian"), "ru", "Sergey Volozhanin", NULL}, + {NULL, NULL, "Alexandre Prokoudine", NULL}, + {NULL, NULL, "Sergey Volozhanin", NULL}, {N_("Slovak"), "sk", "Daniel Režný", NULL}, - {N_("Slovak"), "sk", "helix84", NULL}, - {N_("Slovak"), "sk", "Richard Golier", NULL}, + {NULL, NULL, "helix84", NULL}, + {NULL, NULL, "Richard Golier", NULL}, {N_("Slovenian"), "sl", "Matjaz Horvat", NULL}, {N_("Serbian"), "sr", "Danilo Šegan", "dsegan@gmx.net"}, - {N_("Serbian"), "sr", "Aleksandar Urosevic", "urke@users.sourceforge.net"}, + {NULL, NULL, "Aleksandar Urosevic", "urke@users.sourceforge.net"}, {N_("Swedish"), "sv", "Tore Lundqvist", NULL}, - {N_("Swedish"), "sv", "Christian Rose", NULL}, + {NULL, NULL, "Christian Rose", NULL}, {N_("Telugu"), "te", "Mr. Subbaramaih", "info.gist@cdac.in"}, {N_("Turkish"), "tr", "Ahmet Alp BALKAN", NULL}, - {N_("Simplified Chinese"), "zh_CN", "Hashao, Rocky S. Lee", NULL}, - {N_("Simplified Chinese"), "zh_CN", "Funda Wang", "fundawang@linux.net.cn"}, - {N_("Traditional Chinese"), "zh_TW", "Hashao, Rocky S. Lee", NULL}, + {N_("Simplified Chinese"), "zh_CN", "Hashao", NULL}, + {NULL, NULL, "Rocky S. Lee", NULL}, + {NULL, NULL, "Funda Wang", "fundawang@linux.net.cn"}, + {N_("Traditional Chinese"), "zh_TW", "Hashao", NULL}, + {NULL, NULL, "Rocky S. Lee", NULL}, {NULL, NULL, NULL, NULL} }; @@ -329,13 +334,14 @@ { for (; list->name != NULL; list++) { if (list->email != NULL) { - g_string_append_printf(str, " %s%s%s%s
", - list->email, _(list->name), + g_string_append_printf(str, + "
  • %s%s%s%s
  • ", + list->email, list->email, _(list->name), list->role ? " (" : "", list->role ? _(list->role) : "", list->role ? ")" : ""); } else { - g_string_append_printf(str, " %s%s%s%s
    ", + g_string_append_printf(str, "
  • %s%s%s%s
  • ", _(list->name), list->role ? " (" : "", list->role ? _(list->role) : "", @@ -347,18 +353,18 @@ static void add_translators(GString *str, const struct translator *list) { - for (; list->language != NULL; list++) { + for (; list->name != NULL; list++) { + if (list->language && list->abbr) { + g_string_append_printf(str, "
    %s (%s)
    ", + _(list->language), list->abbr); + } if (list->email != NULL) { - g_string_append_printf(str, " %s (%s) - %s
    ", - _(list->language), - list->abbr, - list->email, + g_string_append_printf(str, + "
    %s
    ", + list->email, list->email, _(list->name)); } else { - g_string_append_printf(str, " %s (%s) - %s
    ", - _(list->language), - list->abbr, - _(list->name)); + g_string_append_printf(str, "
    %s
    ", _(list->name)); } } } @@ -456,8 +462,6 @@ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); gtk_webview_append_html(GTK_WEBVIEW(webview), string->str); - /* TODO WEBKIT: This doesn't seem to stay at the top. */ - webkit_web_view_move_cursor(WEBKIT_WEB_VIEW(webview), GTK_MOVEMENT_BUFFER_ENDS, -1); button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE, G_CALLBACK(destroy_win), win); @@ -491,37 +495,45 @@ str = g_string_sized_new(4096); g_string_append_printf(str, - "
    %s %s
    (libpurple %s)" - "
    %s

    ", PIDGIN_NAME, DISPLAY_VERSION, + "

    %s %s

    " + "(libpurple %s)
    %s
    ", + PIDGIN_NAME, DISPLAY_VERSION, purple_core_get_version(), REVISION); g_string_append_printf(str, - _("%s is a messaging client based on libpurple which is capable of " + _("

    %s is a messaging client based on libpurple which is capable of " "connecting to multiple messaging services at once. %s is written " "in C using GTK+. %s is released, and may be modified and " "redistributed, under the terms of the GPL version 2 (or later). " "A copy of the GPL is distributed with %s. %s is copyrighted by " "its contributors, a list of whom is also distributed with %s. " - "There is no warranty for %s.

    "), PIDGIN_NAME, PIDGIN_NAME, + "There is no warranty for %s.

    "), PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME); g_string_append_printf(str, - _("Helpful Resources
    \tWebsite
    \tFrequently Asked " - "Questions
    \tIRC Channel: #pidgin on irc.freenode.net
    " - "\tXMPP MUC: devel@conference.pidgin.im

    "), PURPLE_WEBSITE, + _("

    Helpful Resources

    " + ""), + PURPLE_WEBSITE, PURPLE_WEBSITE, + "http://developer.pidgin.im/wiki/FAQ", "http://developer.pidgin.im/wiki/FAQ"); g_string_append_printf(str, - _("Help from other Pidgin users is " - "available by e-mailing support@pidgin.im
    " - "This is a public mailing list! " - "(archive)
    " + _("

    Help from other Pidgin users is available " + "by e-mailing %s.
    " + "This is a public mailing list! " + "(archive)
    " "We can't help with third-party protocols or plugins!
    " - "This list's primary language is English. You are " - "welcome to post in another language, but the responses may " - "be less helpful.
    ")); + "This list's primary language is English. You " + "are welcome to post in another language, but the responses may " + "be less helpful.

    "), + "support@pidgin.im", "support@pidgin.im", + "http://pidgin.im/pipermail/support/", + "http://pidgin.im/pipermail/support/"); tmp = g_strdup_printf(_("About %s"), PIDGIN_NAME); about = pidgin_build_help_dialog(tmp, "about", str); @@ -543,175 +555,179 @@ str = g_string_sized_new(4096); g_string_append_printf(str, - "%s %s (libpurple %s)
    %s

    ", PIDGIN_NAME, DISPLAY_VERSION, purple_core_get_version(), REVISION); + "

    %s %s

    " + "(libpurple %s)
    %s
    ", + PIDGIN_NAME, DISPLAY_VERSION, purple_core_get_version(), REVISION); - g_string_append_printf(str, "%s
    ", _("Build Information")); + g_string_append_printf(str, "

    %s

    ", _("Build Information")); - /* The following primarly intented for user/developer interaction and thus - ought not be translated */ + /* The following is primarily intended for user/developer interaction and + thus ought not be translated */ #ifdef CONFIG_ARGS /* win32 build doesn't use configure */ - g_string_append(str, " Arguments to ./configure: " CONFIG_ARGS "
    "); + g_string_append(str, "
    Arguments to ./configure:
    " CONFIG_ARGS "
    "); #endif #ifndef _WIN32 #ifdef DEBUG - g_string_append(str, " Print debugging messages: Yes
    "); + g_string_append(str, "
    Print debugging messages:
    Yes
    "); #else - g_string_append(str, " Print debugging messages: No
    "); + g_string_append(str, "
    Print debugging messages:
    No
    "); #endif #endif #ifdef PURPLE_PLUGINS - g_string_append(str, " Plugins: Enabled
    "); + g_string_append(str, "
    Plugins:
    Enabled
    "); #else - g_string_append(str, " Plugins: Disabled
    "); + g_string_append(str, "
    Plugins:
    Disabled
    "); #endif #ifdef HAVE_SSL - g_string_append(str, " SSL: SSL support is present.
    "); + g_string_append(str, "
    SSL:
    SSL support is present.
    "); #else - g_string_append(str, " SSL: SSL support was NOT compiled!
    "); + g_string_append(str, "
    SSL:
    SSL support was NOT compiled!
    "); #endif /* This might be useful elsewhere too, but it is particularly useful for - * debugging stuff known to be GTK+/Glib bugs on Windows */ + * debugging stuff known to be GTK+/GLib bugs on Windows */ #ifdef _WIN32 - g_string_append_printf(str, " GTK+ Runtime: %u.%u.%u
    " - " Glib Runtime: %u.%u.%u
    ", + g_string_append_printf(str, "
    GTK+ Runtime:
    %u.%u.%u
    " + "
    GLib Runtime:
    %u.%u.%u
    ", gtk_major_version, gtk_minor_version, gtk_micro_version, glib_major_version, glib_minor_version, glib_micro_version); #endif -g_string_append(str, "
    Library Support
    "); + g_string_append(str, "

    Library Support

    "); #ifdef HAVE_CYRUS_SASL - g_string_append_printf(str, " Cyrus SASL: Enabled
    "); + g_string_append_printf(str, "
    Cyrus SASL:
    Enabled
    "); #else - g_string_append_printf(str, " Cyrus SASL: Disabled
    "); + g_string_append_printf(str, "
    Cyrus SASL:
    Disabled
    "); #endif #ifndef _WIN32 #ifdef HAVE_DBUS - g_string_append_printf(str, " D-Bus: Enabled
    "); + g_string_append_printf(str, "
    D-Bus:
    Enabled
    "); #else - g_string_append_printf(str, " D-Bus: Disabled
    "); + g_string_append_printf(str, "
    D-Bus:
    Disabled
    "); #endif #ifdef HAVE_EVOLUTION_ADDRESSBOOK - g_string_append_printf(str, " Evolution Addressbook: Enabled
    "); + g_string_append_printf(str, "
    Evolution Addressbook:
    Enabled
    "); #else - g_string_append_printf(str, " Evolution Addressbook: Disabled
    "); + g_string_append_printf(str, "
    Evolution Addressbook:
    Disabled
    "); #endif #endif #if defined(_WIN32) || defined(USE_INTERNAL_LIBGADU) - g_string_append(str, " Gadu-Gadu library (libgadu): Internal
    "); + g_string_append(str, "
    Gadu-Gadu library (libgadu):
    Internal
    "); #else #ifdef HAVE_LIBGADU - g_string_append(str, " Gadu-Gadu library (libgadu): Enabled
    "); + g_string_append(str, "
    Gadu-Gadu library (libgadu):
    Enabled
    "); #else - g_string_append(str, " Gadu-Gadu library (libgadu): Disabled
    "); + g_string_append(str, "
    Gadu-Gadu library (libgadu):
    Disabled
    "); #endif #endif #ifdef USE_GTKSPELL - g_string_append(str, " GtkSpell: Enabled
    "); + g_string_append(str, "
    GtkSpell:
    Enabled
    "); #else - g_string_append(str, " GtkSpell: Disabled
    "); + g_string_append(str, "
    GtkSpell:
    Disabled
    "); #endif #ifdef HAVE_GNUTLS - g_string_append(str, " GnuTLS: Enabled
    "); + g_string_append(str, "
    GnuTLS:
    Enabled
    "); #else - g_string_append(str, " GnuTLS: Disabled
    "); + g_string_append(str, "
    GnuTLS:
    Disabled
    "); #endif #ifndef _WIN32 #ifdef USE_GSTREAMER - g_string_append(str, " GStreamer: Enabled
    "); + g_string_append(str, "
    GStreamer:
    Enabled
    "); #else - g_string_append(str, " GStreamer: Disabled
    "); + g_string_append(str, "
    GStreamer:
    Disabled
    "); #endif #endif #ifndef _WIN32 #ifdef ENABLE_MONO - g_string_append(str, " Mono: Enabled
    "); + g_string_append(str, "
    Mono:
    Enabled
    "); #else - g_string_append(str, " Mono: Disabled
    "); + g_string_append(str, "
    Mono:
    Disabled
    "); #endif #endif #ifndef _WIN32 #ifdef HAVE_NETWORKMANAGER - g_string_append(str, " NetworkManager: Enabled
    "); + g_string_append(str, "
    NetworkManager:
    Enabled
    "); #else - g_string_append(str, " NetworkManager: Disabled
    "); + g_string_append(str, "
    NetworkManager:
    Disabled
    "); #endif #endif #ifdef HAVE_NSS - g_string_append(str, " Network Security Services (NSS): Enabled
    "); + g_string_append(str, "
    Network Security Services (NSS):
    Enabled
    "); #else - g_string_append(str, " Network Security Services (NSS): Disabled
    "); + g_string_append(str, "
    Network Security Services (NSS):
    Disabled
    "); #endif -if (purple_plugins_find_with_id("core-perl") != NULL) - g_string_append(str, " Perl: Enabled
    "); -else - g_string_append(str, " Perl: Disabled
    "); + if (purple_plugins_find_with_id("core-perl") != NULL) + g_string_append(str, "
    Perl:
    Enabled
    "); + else + g_string_append(str, "
    Perl:
    Disabled
    "); -if (purple_plugins_find_with_id("core-tcl") != NULL) { - g_string_append(str, " Tcl: Enabled
    "); + if (purple_plugins_find_with_id("core-tcl") != NULL) { + g_string_append(str, "
    Tcl:
    Enabled
    "); #ifdef HAVE_TK - g_string_append(str, " Tk: Enabled
    "); + g_string_append(str, "
    Tk:
    Enabled
    "); #else - g_string_append(str, " Tk: Disabled
    "); + g_string_append(str, "
    Tk:
    Disabled
    "); #endif -} else { - g_string_append(str, " Tcl: Disabled
    "); - g_string_append(str, " Tk: Disabled
    "); -} + } else { + g_string_append(str, "
    Tcl:
    Disabled
    "); + g_string_append(str, "
    Tk:
    Disabled
    "); + } #ifdef USE_IDN - g_string_append(str, " UTF-8 DNS (IDN): Enabled
    "); + g_string_append(str, "
    UTF-8 DNS (IDN):
    Enabled
    "); #else - g_string_append(str, " UTF-8 DNS (IDN): Disabled
    "); + g_string_append(str, "
    UTF-8 DNS (IDN):
    Disabled
    "); #endif #ifdef USE_VV - g_string_append(str, " Voice and Video: Enabled
    "); + g_string_append(str, "
    Voice and Video:
    Enabled
    "); #else - g_string_append(str, " Voice and Video: Disabled
    "); + g_string_append(str, "
    Voice and Video:
    Disabled
    "); #endif #ifndef _WIN32 #ifdef USE_SM - g_string_append(str, " X Session Management: Enabled
    "); + g_string_append(str, "
    X Session Management:
    Enabled
    "); #else - g_string_append(str, " X Session Management: Disabled
    "); + g_string_append(str, "
    X Session Management:
    Disabled
    "); #endif #ifdef USE_SCREENSAVER - g_string_append(str, " XScreenSaver: Enabled
    "); + g_string_append(str, "
    XScreenSaver:
    Enabled
    "); #else - g_string_append(str, " XScreenSaver: Disabled
    "); + g_string_append(str, "
    XScreenSaver:
    Disabled
    "); #endif #ifdef LIBZEPHYR_EXT - g_string_append(str, " Zephyr library (libzephyr): External
    "); + g_string_append(str, "
    Zephyr library (libzephyr):
    External
    "); #else - g_string_append(str, " Zephyr library (libzephyr): Internal
    "); + g_string_append(str, "
    Zephyr library (libzephyr):
    Internal
    "); #endif #ifdef ZEPHYR_USES_KERBEROS - g_string_append(str, " Zephyr uses Kerberos: Yes
    "); + g_string_append(str, "
    Zephyr uses Kerberos:
    Yes
    "); #else - g_string_append(str, " Zephyr uses Kerberos: No
    "); + g_string_append(str, "
    Zephyr uses Kerberos:
    No
    "); #endif #endif + g_string_append(str, "
    "); + /* End of not to be translated section */ tmp = g_strdup_printf(_("%s Build Information"), PIDGIN_NAME); @@ -734,27 +750,28 @@ str = g_string_sized_new(4096); /* Current Developers */ - g_string_append_printf(str, "%s:
    ", + g_string_append_printf(str, "

    %s

      ", _("Current Developers")); add_developers(str, developers); - g_string_append(str, "
      "); + g_string_append(str, "
    "); /* Crazy Patch Writers */ - g_string_append_printf(str, "%s:
    ", + g_string_append_printf(str, "

    %s

      ", _("Crazy Patch Writers")); add_developers(str, patch_writers); - g_string_append(str, "
      "); + g_string_append(str, "
    "); /* Retired Developers */ - g_string_append_printf(str, "%s:
    ", + g_string_append_printf(str, "

    %s

      ", _("Retired Developers")); add_developers(str, retired_developers); - g_string_append(str, "
      "); + g_string_append(str, "
    "); /* Retired Crazy Patch Writers */ - g_string_append_printf(str, "%s:
    ", + g_string_append_printf(str, "

    %s

      ", _("Retired Crazy Patch Writers")); add_developers(str, retired_patch_writers); + g_string_append(str, "
    "); tmp = g_strdup_printf(_("%s Developer Information"), PIDGIN_NAME); developer_info = pidgin_build_help_dialog(tmp, "developer_info", str); @@ -776,15 +793,16 @@ str = g_string_sized_new(4096); /* Current Translators */ - g_string_append_printf(str, "%s:
    ", + g_string_append_printf(str, "

    %s

    ", _("Current Translators")); add_translators(str, translators); - g_string_append(str, "
    "); + g_string_append(str, "
    "); /* Past Translators */ - g_string_append_printf(str, "%s:
    ", + g_string_append_printf(str, "

    %s

    ", _("Past Translators")); add_translators(str, past_translators); + g_string_append(str, "
    "); tmp = g_strdup_printf(_("%s Translator Information"), PIDGIN_NAME); translator_info = pidgin_build_help_dialog(tmp, "translator_info", str); @@ -805,14 +823,14 @@ str = g_string_sized_new(4096); - g_string_append_printf(str, "%s
    ", - _("Plugin Information")); + g_string_append_printf(str, "

    %s

    ", _("Plugin Information")); for(l = purple_plugins_get_all(); l; l = l->next) { plugin = (PurplePlugin *)l->data; pname = g_markup_escape_text(purple_plugin_get_name(plugin), -1); - pauthor = g_markup_escape_text(purple_plugin_get_author(plugin), -1); + if ((pauthor = (char *)purple_plugin_get_author(plugin)) != NULL) + pauthor = g_markup_escape_text(pauthor, -1); pver = purple_plugin_get_version(plugin); pwebsite = purple_plugin_get_homepage(plugin); pid = purple_plugin_get_id(plugin); @@ -820,22 +838,29 @@ ploaded = purple_plugin_is_loaded(plugin); g_string_append_printf(str, - "%s
    " - "\tAuthor: %s
    \tVersion: %s
    " - "\tWebsite: %s
    \tID String: %s
    " - "\tLoadable: %s
    \tLoaded: %s
    " - "
    ", pname, pauthor ? pauthor : "(null)", + "
    %s
    " + "Author: %s
    " + "Version: %s
    " + "Website: %s
    " + "ID String: %s
    " + "Loadable: %s
    " + "Loaded: %s" + "

    ", + pname, pauthor ? pauthor : "(null)", pver, pwebsite, pid, - punloadable ? "No" : "Yes", + punloadable ? "No" : "Yes", ploaded ? "Yes" : "No"); + + g_free(pname); + g_free(pauthor); } + g_string_append(str, "
    "); + plugins_info = pidgin_build_help_dialog(title, "plugins_info", str); g_signal_connect(G_OBJECT(plugins_info), "destroy", G_CALLBACK(gtk_widget_destroyed), &plugins_info); g_free(title); - g_free(pname); - g_free(pauthor); } static void diff -r 4ae0c82b158d -r 4f8626d4ef63 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Sat Jan 21 12:02:41 2012 +0000 +++ b/pidgin/gtkprefs.c Thu Feb 23 08:13:23 2012 +0000 @@ -1859,11 +1859,11 @@ #ifndef _WIN32 static void -browser_button_clicked_cb(GtkWidget *button, gpointer null) +browser_button_clicked_cb(GtkWidget *button, gchar *path) { GError *err = NULL; - if (g_spawn_command_line_async ("gnome-default-applications-properties", &err)) + if (g_spawn_command_line_async(path, &err)) return; purple_notify_error(NULL, NULL, _("Cannot start browser configuration program."), err->message); @@ -2134,8 +2134,8 @@ vbox = pidgin_make_frame (ret, _("Browser Selection")); - if(purple_running_gnome()) { - gchar *path = g_find_program_in_path("gnome-default-applications-properties"); + if (purple_running_gnome()) { + gchar *path; hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); label = gtk_label_new(_("Browser preferences are configured in GNOME preferences")); @@ -2145,19 +2145,28 @@ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); gtk_container_add(GTK_CONTAINER(vbox), hbox); - if(path == NULL) { + path = g_find_program_in_path("gnome-control-center"); + if (path != NULL) { + gchar *tmp = g_strdup_printf("%s info", path); + g_free(path); + path = tmp; + } else { + path = g_find_program_in_path("gnome-default-applications-properties"); + } + + if (path == NULL) { label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), _("Browser configuration program was not found.")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); } else { browser_button = gtk_button_new_with_mnemonic(_("Configure _Browser")); - g_signal_connect(G_OBJECT(browser_button), "clicked", - G_CALLBACK(browser_button_clicked_cb), NULL); + g_signal_connect_data(G_OBJECT(browser_button), "clicked", + G_CALLBACK(browser_button_clicked_cb), path, + (GClosureNotify)g_free, 0); gtk_box_pack_start(GTK_BOX(hbox), browser_button, FALSE, FALSE, 0); } - g_free(path); gtk_widget_show_all(ret); } else { sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); diff -r 4ae0c82b158d -r 4f8626d4ef63 pidgin/gtkwebview.c --- a/pidgin/gtkwebview.c Sat Jan 21 12:02:41 2012 +0000 +++ b/pidgin/gtkwebview.c Thu Feb 23 08:13:23 2012 +0000 @@ -579,7 +579,6 @@ char *script = g_strdup_printf("document.write(%s)", escaped); webkit_web_view_execute_script(WEBKIT_WEB_VIEW(webview), script); priv->empty = FALSE; - gtk_webview_scroll_to_end(webview, TRUE); g_free(script); g_free(escaped); } diff -r 4ae0c82b158d -r 4f8626d4ef63 pidgin/plugins/disco/gtkdisco.c --- a/pidgin/plugins/disco/gtkdisco.c Sat Jan 21 12:02:41 2012 +0000 +++ b/pidgin/plugins/disco/gtkdisco.c Thu Feb 23 08:13:23 2012 +0000 @@ -462,6 +462,8 @@ gtk_tree_model_get_value(GTK_TREE_MODEL(pdl->model), &iter, SERVICE_COLUMN, &val); service = g_value_get_pointer(&val); + if (!service) + return FALSE; switch (service->type) { case XMPP_DISCO_SERVICE_TYPE_UNSET: