# HG changeset patch # User Sadrul Habib Chowdhury # Date 1180122682 0 # Node ID 2f8d773562684e18baefb159aa73c0d44c74aba9 # Parent 74f14da7b5abf5a56cf81adce5c1da24dfa35121# Parent fe8a1051aa0aceb3f076dc9292b73d3b73013fac merge of '2f10c41a04555ebc895ec5168c3c2996c738cbd9' and '4b489c7fd0ca6d775558656ce19ba53d7209bb26' diff -r 74f14da7b5ab -r 2f8d77356268 configure.ac --- a/configure.ac Fri May 25 18:27:41 2007 +0000 +++ b/configure.ac Fri May 25 19:51:22 2007 +0000 @@ -46,7 +46,7 @@ m4_define([purple_lt_current], [0]) m4_define([purple_major_version], [2]) m4_define([purple_minor_version], [0]) -m4_define([purple_micro_version], [2) +m4_define([purple_micro_version], [2]) m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) diff -r 74f14da7b5ab -r 2f8d77356268 libpurple/plugins/ssl/ssl-gnutls.c --- a/libpurple/plugins/ssl/ssl-gnutls.c Fri May 25 18:27:41 2007 +0000 +++ b/libpurple/plugins/ssl/ssl-gnutls.c Fri May 25 19:51:22 2007 +0000 @@ -123,6 +123,18 @@ gnutls_data->handshake_handler = purple_input_add(gsc->fd, PURPLE_INPUT_READ, ssl_gnutls_handshake_cb, gsc); + /* Orborde asks: Why are we configuring a callback, then + immediately calling it? + + Answer: gnutls_handshake (up in handshake_cb) needs to be called + once in order to get the ball rolling on the SSL connection. + Once it has done so, only then will the server reply, triggering + the callback. + + Since the logic driving gnutls_handshake is the same with the first + and subsequent calls, we'll just fire the callback immediately to + accomplish this. + */ ssl_gnutls_handshake_cb(gsc, gsc->fd, PURPLE_INPUT_READ); } diff -r 74f14da7b5ab -r 2f8d77356268 libpurple/protocols/jabber/message.c --- a/libpurple/protocols/jabber/message.c Fri May 25 18:27:41 2007 +0000 +++ b/libpurple/protocols/jabber/message.c Fri May 25 19:51:22 2007 +0000 @@ -544,7 +544,6 @@ char *buf; char *xhtml; char *resource; - char *c; if(!who || !msg) return 0; diff -r 74f14da7b5ab -r 2f8d77356268 libpurple/sslconn.h --- a/libpurple/sslconn.h Fri May 25 18:27:41 2007 +0000 +++ b/libpurple/sslconn.h Fri May 25 19:51:22 2007 +0000 @@ -170,6 +170,7 @@ /** * Adds an input watcher for the specified SSL connection. + * Once the SSL handshake is complete, use this to watch for actual data across it. * * @param gsc The SSL connection handle. * @param func The callback function. diff -r 74f14da7b5ab -r 2f8d77356268 pidgin/gtkutils.c --- a/pidgin/gtkutils.c Fri May 25 18:27:41 2007 +0000 +++ b/pidgin/gtkutils.c Fri May 25 19:51:22 2007 +0000 @@ -61,6 +61,11 @@ #include "gtkthemes.h" #include "gtkutils.h" +typedef struct { + GtkWidget *menu; + gint default_item; +} AopMenu; + static guint accels_save_timer = 0; static gboolean @@ -431,66 +436,66 @@ return vbox; } +static gpointer +aop_option_menu_get_selected(GtkWidget *optmenu, GtkWidget **p_item) +{ + GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); + GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu)); + if (p_item) + (*p_item) = item; + return g_object_get_data(G_OBJECT(item), "aop_per_item_data"); +} + static void -protocol_menu_cb(GtkWidget *optmenu, GCallback cb) +aop_menu_cb(GtkWidget *optmenu, GCallback cb) { - GtkWidget *menu; GtkWidget *item; - const char *protocol; - gpointer user_data; - - menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); - item = gtk_menu_get_active(GTK_MENU(menu)); - - protocol = g_object_get_data(G_OBJECT(item), "protocol"); - - if (!strcmp(protocol, "prpl-fake")) - protocol = g_object_get_data(G_OBJECT(item), "real_protocol"); - - if (!strcmp(protocol, g_object_get_data(G_OBJECT(optmenu), "last_protocol"))) - return; - - user_data = (g_object_get_data(G_OBJECT(optmenu), "user_data")); - g_object_set_data(G_OBJECT(optmenu), "last_protocol", (gpointer)protocol); - - if (cb != NULL) - ((void (*)(GtkWidget *, const char *, gpointer))cb)(item, protocol, - user_data); + gpointer per_item_data; + + per_item_data = aop_option_menu_get_selected(optmenu, &item); + + if (cb != NULL) { + ((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data")); + } } static GtkWidget * -pidgin_protocol_option_menu_item(GtkWidget *menu, GtkSizeGroup *sg, GtkWidget *image, - const char *name, const char *id) +aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data) { GtkWidget *item; GtkWidget *hbox; + GtkWidget *image; GtkWidget *label; - /* Create the item. */ item = gtk_menu_item_new(); - - /* Create the hbox. */ + gtk_widget_show(item); + hbox = gtk_hbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(item), hbox); gtk_widget_show(hbox); - gtk_size_group_add_widget(sg, image); - - gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + /* Create the image */ + if (pixbuf == NULL) + image = gtk_image_new(); + else + image = gtk_image_new_from_pixbuf(pixbuf); gtk_widget_show(image); - /* Create the label. */ - label = gtk_label_new(name); + if (sg) + gtk_size_group_add_widget(sg, image); + + /* Create the label */ + label = gtk_label_new (lbl); + gtk_widget_show (label); gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + 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); - gtk_widget_show(label); - - g_object_set_data(G_OBJECT(item), "protocol", (gpointer)id); - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - gtk_widget_show(item); - pidgin_set_accessible_label (item, label); + + g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data); + + pidgin_set_accessible_label(item, label); return item; } @@ -528,35 +533,77 @@ return pixbuf; } -GtkWidget * -pidgin_protocol_option_menu_new(const char *id, GCallback cb, - gpointer user_data) +static GtkWidget * +aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data) +{ + GtkWidget *optmenu; + + optmenu = gtk_option_menu_new(); + gtk_widget_show(optmenu); + gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), aop_menu->menu); + + if (aop_menu->default_item != -1) + gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), aop_menu->default_item); + + g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", aop_menu, (GDestroyNotify)g_free); + g_object_set_data(G_OBJECT(optmenu), "user_data", user_data); + + g_signal_connect(G_OBJECT(optmenu), "changed", G_CALLBACK(aop_menu_cb), cb); + + return optmenu; +} + +static void +aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu) { + if (gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu))) + gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu)); + + gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), new_aop_menu->menu); + + if (new_aop_menu->default_item != -1) + gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), new_aop_menu->default_item); + + g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free); +} + +static void +aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data) +{ + guint idx; + GList *llItr = NULL; + + for (idx = 0, llItr = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))->children; + llItr != NULL; + llItr = llItr->next, idx++) { + if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) { + gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx); + break; + } + } +} + +static AopMenu * +create_protocols_menu(const char *default_proto_id) +{ + AopMenu *aop_menu = NULL; PurplePluginProtocolInfo *prpl_info; PurplePlugin *plugin; - GtkWidget *optmenu; - GtkWidget *menu; - GdkPixbuf *pixbuf; - GtkWidget *image; + GdkPixbuf *pixbuf = NULL; + GtkSizeGroup *sg; GList *p; - GtkSizeGroup *sg; - char *filename; - int i, selected_index = -1; const char *gtalk_name = NULL; + int i; + + aop_menu = g_malloc0(sizeof(AopMenu)); + aop_menu->default_item = -1; + aop_menu->menu = gtk_menu_new(); + gtk_widget_show(aop_menu->menu); + sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); if (purple_find_prpl("prpl-jabber")) gtalk_name = _("Google Talk"); - optmenu = gtk_option_menu_new(); - gtk_widget_show(optmenu); - - g_object_set_data(G_OBJECT(optmenu), "user_data", user_data); - - menu = gtk_menu_new(); - gtk_widget_show(menu); - - sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - for (p = purple_plugins_get_protocols(), i = 0; p != NULL; p = p->next, i++) { @@ -564,125 +611,83 @@ plugin = (PurplePlugin *)p->data; prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); - if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) - { - GtkWidget *gtalk_item; - - filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", - "16", "google-talk.png", NULL); + if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { + char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", + "16", "google-talk.png", NULL); pixbuf = gdk_pixbuf_new_from_file(filename, NULL); g_free(filename); + gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), + aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber")); if (pixbuf) - image = gtk_image_new_from_pixbuf(pixbuf); - else - image = gtk_image_new(); - - gtalk_item = pidgin_protocol_option_menu_item(menu, sg, image, gtalk_name, "prpl-fake"); - g_object_set_data(G_OBJECT(gtalk_item), "real_protocol", "prpl-jabber"); - i++; + g_object_unref(pixbuf); gtalk_name = NULL; } - /* Load the image. */ pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), + aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id)); + if (pixbuf) - image = gtk_image_new_from_pixbuf(pixbuf); - else - image = gtk_image_new(); - - pidgin_protocol_option_menu_item(menu, sg, image, plugin->info->name, plugin->info->id); - - if (id != NULL && !strcmp(plugin->info->id, id)) - { - g_object_set_data(G_OBJECT(optmenu), "last_protocol", plugin->info->id); - selected_index = i; - } - else if (i == 0) - { - /* Ensure we set the protocol even if id is NULL or can't be found. */ - g_object_set_data(G_OBJECT(optmenu), "last_protocol", plugin->info->id); - } - - if (pixbuf) - g_object_unref(G_OBJECT(pixbuf)); + g_object_unref(pixbuf); + + if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id)) + aop_menu->default_item = i; } - gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu); - - if (selected_index != -1) - gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), selected_index); - - g_signal_connect(G_OBJECT(optmenu), "changed", - G_CALLBACK(protocol_menu_cb), cb); - g_object_unref(sg); - return optmenu; + return aop_menu; +} + +GtkWidget * +pidgin_protocol_option_menu_new(const char *id, GCallback cb, + gpointer user_data) +{ + return aop_option_menu_new(create_protocols_menu(id), cb, user_data); } PurpleAccount * pidgin_account_option_menu_get_selected(GtkWidget *optmenu) { - GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); - GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu)); - return g_object_get_data(G_OBJECT(item), "account"); + return (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL); } -static void -account_menu_cb(GtkWidget *optmenu, GCallback cb) -{ - GtkWidget *menu; - GtkWidget *item; - PurpleAccount *account; - gpointer user_data; - - menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); - item = gtk_menu_get_active(GTK_MENU(menu)); - - account = g_object_get_data(G_OBJECT(item), "account"); - user_data = g_object_get_data(G_OBJECT(optmenu), "user_data"); - - if (cb != NULL) - ((void (*)(GtkWidget *, PurpleAccount *, gpointer))cb)(item, account, - user_data); -} - -static void -create_account_menu(GtkWidget *optmenu, PurpleAccount *default_account, +static AopMenu * +create_account_menu(PurpleAccount *default_account, PurpleFilterAccountFunc filter_func, gboolean show_all) { + AopMenu *aop_menu = NULL; PurpleAccount *account; - GtkWidget *menu; - GtkWidget *item; - GtkWidget *image; - GtkWidget *hbox; - GtkWidget *label; - GdkPixbuf *pixbuf; + GdkPixbuf *pixbuf = NULL; GList *list; + GList *p; GtkSizeGroup *sg; + int i; char buf[256]; - int i, selected_index = -1; if (show_all) list = purple_accounts_get_all(); else list = purple_connections_get_all(); - menu = gtk_menu_new(); - gtk_widget_show(menu); - + aop_menu = g_malloc0(sizeof(AopMenu)); + aop_menu->default_item = -1; + aop_menu->menu = gtk_menu_new(); + gtk_widget_show(aop_menu->menu); sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - for (i = 0; list != NULL; list = list->next, i++) { + for (p = list, i = 0; p != NULL; p = p->next, i++) { + PurplePluginProtocolInfo *prpl_info = NULL; + PurplePlugin *plugin; if (show_all) - account = (PurpleAccount *)list->data; + account = (PurpleAccount *)p->data; else { - PurpleConnection *gc = (PurpleConnection *)list->data; + PurpleConnection *gc = (PurpleConnection *)p->data; account = purple_connection_get_account(gc); } @@ -692,32 +697,15 @@ continue; } - /* Create the item. */ - item = gtk_menu_item_new(); - - /* Create the hbox. */ - hbox = gtk_hbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(item), hbox); - gtk_widget_show(hbox); + plugin = purple_find_prpl(purple_account_get_protocol_id(account)); pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); - if (pixbuf != NULL) { + if (pixbuf) { if (purple_account_is_disconnected(account) && show_all && purple_connections_get_all()) gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); - - image = gtk_image_new_from_pixbuf(pixbuf); - - g_object_unref(G_OBJECT(pixbuf)); } - else - image = gtk_image_new(); - - gtk_size_group_add_widget(sg, image); - - gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); - gtk_widget_show(image); if (purple_account_get_alias(account)) { g_snprintf(buf, sizeof(buf), "%s (%s) (%s)", @@ -730,54 +718,33 @@ purple_account_get_protocol_name(account)); } - /* Create the label. */ - label = gtk_label_new(buf); - gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - g_object_set_data(G_OBJECT(item), "account", account); - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - gtk_widget_show(item); - pidgin_set_accessible_label (item, label); - - if (default_account != NULL && account == default_account) - selected_index = i; + gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), + aop_menu_item_new(sg, pixbuf, buf, account)); + + if (pixbuf) + g_object_unref(pixbuf); + + if (default_account && account == default_account) + aop_menu->default_item = i; } g_object_unref(sg); - gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu); - - /* Set the place we should be at. */ - if (selected_index != -1) - gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), selected_index); + return aop_menu; } static void regenerate_account_menu(GtkWidget *optmenu) { - GtkWidget *menu; - GtkWidget *item; gboolean show_all; PurpleAccount *account; PurpleFilterAccountFunc filter_func; - menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); - item = gtk_menu_get_active(GTK_MENU(menu)); - account = g_object_get_data(G_OBJECT(item), "account"); - - show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), - "show_all")); - - filter_func = g_object_get_data(G_OBJECT(optmenu), - "filter_func"); - - gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu)); - - create_account_menu(optmenu, account, filter_func, show_all); + account = (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL); + show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), "show_all")); + filter_func = g_object_get_data(G_OBJECT(optmenu), "filter_func"); + + aop_option_menu_replace_menu(optmenu, create_account_menu(account, filter_func, show_all)); } static void @@ -804,28 +771,7 @@ void pidgin_account_option_menu_set_selected(GtkWidget *optmenu, PurpleAccount *account) { - GtkWidget *menu; - GtkWidget *item; - gboolean show_all; - PurpleAccount *curaccount; - PurpleFilterAccountFunc filter_func; - - menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); - item = gtk_menu_get_active(GTK_MENU(menu)); - curaccount = g_object_get_data(G_OBJECT(item), "account"); - - if (account == curaccount) - return; - - show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), - "show_all")); - - filter_func = g_object_get_data(G_OBJECT(optmenu), - "filter_func"); - - gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu)); - - create_account_menu(optmenu, account, filter_func, show_all); + aop_option_menu_select_by_data(optmenu, account); } GtkWidget * @@ -837,8 +783,7 @@ GtkWidget *optmenu; /* Create the option menu */ - optmenu = gtk_option_menu_new(); - gtk_widget_show(optmenu); + optmenu = aop_option_menu_new(create_account_menu(default_account, filter_func, show_all), cb, user_data); g_signal_connect(G_OBJECT(optmenu), "destroy", G_CALLBACK(account_menu_destroyed_cb), NULL); @@ -860,15 +805,7 @@ /* Set some data. */ g_object_set_data(G_OBJECT(optmenu), "user_data", user_data); g_object_set_data(G_OBJECT(optmenu), "show_all", GINT_TO_POINTER(show_all)); - g_object_set_data(G_OBJECT(optmenu), "filter_func", - filter_func); - - /* Create and set the actual menu. */ - create_account_menu(optmenu, default_account, filter_func, show_all); - - /* And now the last callback. */ - g_signal_connect(G_OBJECT(optmenu), "changed", - G_CALLBACK(account_menu_cb), cb); + g_object_set_data(G_OBJECT(optmenu), "filter_func", filter_func); return optmenu; } @@ -951,15 +888,6 @@ g_free(filename); } -void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name) -{ - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); - purple_notify_userinfo(conn, name, info, NULL, NULL); - purple_notify_user_info_destroy(info); - serv_get_info(conn, name); -} - gboolean pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts, PurpleAccount **ret_account, char **ret_protocol, @@ -1656,16 +1584,17 @@ } + GdkPixbuf * pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) { PurplePlugin *prpl; + g_return_val_if_fail(account != NULL, NULL); prpl = purple_find_prpl(purple_account_get_protocol_id(account)); if (prpl == NULL) return NULL; - return pidgin_create_prpl_icon_from_prpl(prpl, size, account); } @@ -1687,8 +1616,10 @@ gpointer object) { GtkWidget *menuitem; - if (act == NULL) + + if (act == NULL) { return pidgin_separator(menu); + } if (act->children == NULL) { menuitem = gtk_menu_item_new_with_mnemonic(act->label); @@ -1888,21 +1819,8 @@ if (account == NULL) return TRUE; - if (optmenu != NULL) { - GList *items; - guint index = 0; - pidgin_account_option_menu_set_selected(optmenu, account); - items = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))->children; - - do { - if (account == g_object_get_data(G_OBJECT(items->data), "account")) { - /* Set the account in the GUI. */ - gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), index); - return TRUE; - } - index++; - } while ((items = items->next) != NULL); - } + if (optmenu != NULL) + aop_option_menu_select_by_data(optmenu, account); return TRUE; }