# HG changeset patch
# User masca@cpw.pidgin.im
# Date 1279573892 0
# Node ID 47b6eda877236e826558421bcb7afb9d8ffa3d44
# Parent e874875a74a7273703bcb2282cc52a02f7061079# Parent c7fa7c7aca7d194a1072b844c0bb366b9efb9a7b
propagate from branch 'im.pidgin.pidgin' (head 07d0765c444a097af45c2650f54323afb900a07b)
to branch 'im.pidgin.soc.2010.msn-tlc' (head f3998422a4724ab424e4e2328f58fc0504856557)
diff -r c7fa7c7aca7d -r 47b6eda87723 ChangeLog
--- a/ChangeLog Mon Jul 19 21:05:06 2010 +0000
+++ b/ChangeLog Mon Jul 19 21:11:32 2010 +0000
@@ -1,11 +1,17 @@
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
version 2.7.2 (??/??/????):
+ General:
+ * Use silent build rules for automake >1.11. You can enable verbose
+ builds with the --disable-silent-rules configure option, or using
+ make V=1.
+
libpurple:
* Fix the TURN server settings (broken in 2.7.0).
Pidgin:
* Re-focus the input area after clicking the attention toolbar button.
+ * Re-arrange media window to make it more netbook-friendly.
Finch:
* Rebindable 'suggest-next-page' and 'suggest-prev-page' actions for
@@ -21,17 +27,24 @@
a fallback to legacy IQ authentication (broken in 2.7.0).
* Fix a crash when receiving custom emoticons that don't adhere to
the specification.
+ * When initiating a file transfer, don't show resources that are certain
+ to not support file transfers in the resource selection dialog.
+ * Fix connecting to servers using BOSH and authenticating with
+ DIGEST-MD5 when libpurple was built with Cyrus SASL support.
Yahoo/Yahoo JAPAN:
* Renamed "Use account proxy for SSL connections" to "Use account proxy
for HTTP and HTTPS requests" and tied the option to HTTP requests too.
- * Properly detect HTTP proxy server use when the HTTP proxy is the global
- proxy server, an account-level non-HTTP proxy server is configured, and
- the "Use account proxy for HTTP and HTTPS requests" account option is
- turned off. This fixes connecting for some HTTP proxy servers.
- * Fall back to connecting to scsa.msg.yahoo.com (not configurable) if the
- HTTP-based connect server lookup fails. This does not work for Yahoo
- JAPAN accounts.
+ * Properly detect HTTP proxy server use when the HTTP proxy is the
+ global proxy server, an account-level non-HTTP proxy server is
+ configured, and the "Use account proxy for HTTP and HTTPS requests"
+ account option is turned off. This fixes connecting for some HTTP
+ proxy servers.
+ * Fall back to connecting to scsa.msg.yahoo.com (not configurable) if
+ the HTTP-based connect server lookup fails. This does not work for
+ Yahoo JAPAN accounts.
+ * Fix file transfers that get stuck with "Waiting for transfer to
+ begin".
version 2.7.1 (05/29/2010):
General:
diff -r c7fa7c7aca7d -r 47b6eda87723 ChangeLog.API
--- a/ChangeLog.API Mon Jul 19 21:05:06 2010 +0000
+++ b/ChangeLog.API Mon Jul 19 21:11:32 2010 +0000
@@ -7,6 +7,23 @@
called for a protocol that doesn't support the underlying
calls and the caller does not specify a failure callback.
+ Perl:
+ Added:
+ * Exposed log-subsystem signals.
+
+ Pidgin:
+ Changed:
+ * Changing the visibility (gtk_widget_hide/show) of
+ the widgets in the GtkIMHtmlToolbar should now affect
+ the visibility of the entries in the 'lean' view
+ (the default toolbar view).
+
+ libgnt:
+ Added:
+ * gnt_tree_row_get_key, gnt_tree_row_get_next,
+ gnt_tree_row_get_prev, gnt_tree_row_get_child and
+ gnt_tree_row_get_parent.
+
version 2.7.1 (05/29/2010):
* No changes
diff -r c7fa7c7aca7d -r 47b6eda87723 Makefile.am
--- a/Makefile.am Mon Jul 19 21:05:06 2010 +0000
+++ b/Makefile.am Mon Jul 19 21:11:32 2010 +0000
@@ -100,18 +100,18 @@
# creates, and also make sure that the shell command exits
# successfully; the rm -f ensures both
package_revision_raw.txt:
- REAL_BLDDIR=$$PWD/$(top_builddir); \
+ $(AM_V_GEN)REAL_BLDDIR=$$PWD/$(top_builddir); \
(cd $(srcdir) && $$REAL_BLDDIR/mtn --root=. automate get_base_revision_id) 2>/dev/null >$@ \
|| (cd $(srcdir) && mtn --root=. automate get_base_revision_id) 2>/dev/null >$@ \
|| rm -f $@
package_revision.h: package_revision_raw.txt
- if test -f $<; then \
+ $(AM_V_GEN)if test -f $<; then \
echo "#define REVISION \"`cat $<`\"" > $@; \
fi
- if test ! -f $@ -a -f $(srcdir)/$@; then \
+ $(AM_V_at)if test ! -f $@ -a -f $(srcdir)/$@; then \
cp $(srcdir)/$@ $@; \
fi
- test -f $@ || echo "#define REVISION \"unknown\"" > $@
+ $(AM_V_at)test -f $@ || echo "#define REVISION \"unknown\"" > $@
# This is a magic directive copy-and-pasted, then modified, from the
# automake 1.9 manual, section 13.4, "Checking the distribution".
diff -r c7fa7c7aca7d -r 47b6eda87723 configure.ac
--- a/configure.ac Mon Jul 19 21:05:06 2010 +0000
+++ b/configure.ac Mon Jul 19 21:11:32 2010 +0000
@@ -52,10 +52,10 @@
[purple_major_version.purple_minor_version.purple_micro_version])
m4_define([purple_display_version], purple_version[]m4_ifdef([purple_version_suffix],[purple_version_suffix]))
-m4_define([gnt_lt_current], [7])
+m4_define([gnt_lt_current], [8])
m4_define([gnt_major_version], [2])
-m4_define([gnt_minor_version], [7])
-m4_define([gnt_micro_version], [2])
+m4_define([gnt_minor_version], [8])
+m4_define([gnt_micro_version], [0])
m4_define([gnt_version_suffix], [devel])
m4_define([gnt_version],
[gnt_major_version.gnt_minor_version.gnt_micro_version])
@@ -75,6 +75,8 @@
AC_CANONICAL_HOST
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([1.9 -Wno-portability dist-bzip2])
+dnl TODO: Always use AM_SILENT_RULES when we depend on automake >= 1.11
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
PURPLE_MAJOR_VERSION=purple_major_version
PURPLE_MINOR_VERSION=purple_minor_version
@@ -660,6 +662,10 @@
for location in $ac_ncurses_includes $NCURSES_HEADERS /usr/include/ncursesw /usr/include
do
f="$location/ncurses.h"
+ orig_CFLAGS="$CFLAGS"
+ orig_CPPFLAGS="$CPPFLAGS"
+ CFLAGS="$CFLAGS -I$location"
+ CPPFLAGS="$CPPFLAGS -I$location"
AC_CHECK_HEADER($f,[
AC_MSG_CHECKING([if $f supports wide characters])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -678,9 +684,13 @@
fi
found_ncurses_h=yes
+ CFLAGS="$orig_CFLAGS"
+ CPPFLAGS="$orig_CPPFLAGS"
AC_MSG_RESULT([yes])
break
], [
+ CFLAGS="$orig_CFLAGS"
+ CPPFLAGS="$orig_CPPFLAGS"
AC_MSG_RESULT([no])
])
])
diff -r c7fa7c7aca7d -r 47b6eda87723 doc/finch.1.in
--- a/doc/finch.1.in Mon Jul 19 21:05:06 2010 +0000
+++ b/doc/finch.1.in Mon Jul 19 21:11:32 2010 +0000
@@ -59,7 +59,7 @@
Display the version information window.
.SH GNT Shortcuts
-You can use the following shortcuts (see the "\*QWidget Actions\*U" section for a more complete list):
+You can use the following shortcuts (see the "Widget Actions" section for a more complete list):
.TP
.B Alt \+ a
Bring up a list of available actions. You can use this list to access the
@@ -507,6 +507,10 @@
.br
a-/ = help-for-widget
.br
+a-c-j = window-scroll-down
+.br
+a-c-k = window-scroll-up
+.br
# The following action is still incomplete, and doesn't have a default binding
.br
# switch-window-n
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/finch.c
--- a/finch/finch.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/finch.c Mon Jul 19 21:11:32 2010 +0000
@@ -252,6 +252,7 @@
gboolean opt_version = FALSE;
char *opt_config_dir_arg = NULL;
gboolean debug_enabled = FALSE;
+ struct stat st;
struct option long_options[] = {
{"config", required_argument, NULL, 'c'},
@@ -361,6 +362,8 @@
purple_idle_set_ui_ops(finch_idle_get_ui_ops());
path = g_build_filename(purple_user_dir(), "plugins", NULL);
+ if (!g_stat(path, &st))
+ g_mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR);
purple_plugins_add_search_path(path);
g_free(path);
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/gntaccount.c
--- a/finch/gntaccount.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/gntaccount.c Mon Jul 19 21:11:32 2010 +0000
@@ -125,7 +125,8 @@
if (value == NULL || *value == '\0')
{
- purple_notify_error(NULL, _("Error"), _("Account was not added"),
+ purple_notify_error(NULL, _("Error"),
+ dialog->account ? _("Account was not modified") : _("Account was not added"),
_("Username of an account must be non-empty."));
return;
}
@@ -160,8 +161,28 @@
account = dialog->account;
/* Protocol */
- purple_account_set_protocol_id(account, purple_plugin_get_id(plugin));
- purple_account_set_username(account, username->str);
+ if (purple_account_is_disconnected(account)) {
+ purple_account_set_protocol_id(account, purple_plugin_get_id(plugin));
+ purple_account_set_username(account, username->str);
+ } else {
+ const char *old = purple_account_get_protocol_id(account);
+ char *oldprpl;
+ if (strcmp(old, purple_plugin_get_id(plugin))) {
+ purple_notify_error(NULL, _("Error"), _("Account was not modified"),
+ _("The account's protocol cannot be changed while it is connected to the server."));
+ return;
+ }
+
+ oldprpl = g_strdup(purple_normalize(account, purple_account_get_username(account)));
+ if (g_utf8_collate(oldprpl, purple_normalize(account, username->str))) {
+ purple_notify_error(NULL, _("Error"), _("Account was not modified"),
+ _("The account's username cannot be changed while it is connected to the server."));
+ g_free(oldprpl);
+ return;
+ }
+ g_free(oldprpl);
+ purple_account_set_username(account, username->str);
+ }
}
g_string_free(username, TRUE);
@@ -245,6 +266,17 @@
}
}
+ /* In case of a new account, the 'Accounts' window is updated from the account-added
+ * callback. In case of changes in an existing account, we need to explicitly do it
+ * here.
+ */
+ if (dialog->account != NULL && accounts.window) {
+ gnt_tree_change_text(GNT_TREE(accounts.tree), dialog->account,
+ 0, purple_account_get_username(dialog->account));
+ gnt_tree_change_text(GNT_TREE(accounts.tree), dialog->account,
+ 1, purple_account_get_protocol_name(dialog->account));
+ }
+
gnt_widget_destroy(dialog->window);
}
@@ -603,7 +635,7 @@
button = gnt_button_new(_("Cancel"));
gnt_box_add_widget(GNT_BOX(hbox), button);
g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), window);
-
+
button = gnt_button_new(_("Save"));
gnt_box_add_widget(GNT_BOX(hbox), button);
g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(save_account_cb), dialog);
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/gntdebug.c
--- a/finch/gntdebug.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/gntdebug.c Mon Jul 19 21:11:32 2010 +0000
@@ -77,7 +77,10 @@
}
return;
}
- pipe(pipes);
+ if (pipe(pipes)) {
+ readhandle = -1;
+ return;
+ };
dup2(pipes[1], STDERR_FILENO);
stderrch = g_io_channel_unix_new(pipes[0]);
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/gntrequest.c
--- a/finch/gntrequest.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/gntrequest.c Mon Jul 19 21:11:32 2010 +0000
@@ -349,10 +349,9 @@
}
else if (type == PURPLE_REQUEST_FIELD_LIST)
{
- GList *list = NULL;
+ GList *list = NULL, *iter;
if (purple_request_field_list_get_multi_select(field))
{
- GList *iter;
GntWidget *tree = FINCH_GET_DATA(field);
iter = purple_request_field_list_get_items(field);
@@ -361,14 +360,23 @@
const char *text = iter->data;
gpointer key = purple_request_field_list_get_data(field, text);
if (gnt_tree_get_choice(GNT_TREE(tree), key))
- list = g_list_prepend(list, key);
+ list = g_list_prepend(list, (gpointer)text);
}
}
else
{
GntWidget *combo = FINCH_GET_DATA(field);
gpointer data = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
- list = g_list_append(list, data);
+
+ iter = purple_request_field_list_get_items(field);
+ for (; iter; iter = iter->next) {
+ const char *text = iter->data;
+ gpointer key = purple_request_field_list_get_data(field, text);
+ if (key == data) {
+ list = g_list_prepend(list, (gpointer)text);
+ break;
+ }
+ }
}
purple_request_field_list_set_selected(field, list);
@@ -815,7 +823,7 @@
for (list = purple_request_fields_get_groups(allfields); list; list = list->next) {
PurpleRequestFieldGroup *group = list->data;
GList *fields = purple_request_field_group_get_fields(group);
-
+
for (; fields ; fields = fields->next) {
PurpleRequestField *field = fields->data;
PurpleRequestFieldType type = purple_request_field_get_type(field);
@@ -826,6 +834,7 @@
switch (type) {
case PURPLE_REQUEST_FIELD_LIST:
val = purple_request_field_list_get_selected(field)->data;
+ val = purple_request_field_list_get_data(field, val);
break;
case PURPLE_REQUEST_FIELD_BOOLEAN:
val = GINT_TO_POINTER(purple_request_field_bool_get_value(field));
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/gntsound.c
--- a/finch/gntsound.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/gntsound.c Mon Jul 19 21:11:32 2010 +0000
@@ -104,7 +104,8 @@
{PURPLE_SOUND_CHAT_YOU_SAY, N_("You talk in chat"), "send_chat_msg", "send.wav", NULL},
{PURPLE_SOUND_CHAT_SAY, N_("Others talk in chat"), "chat_msg_recv", "receive.wav", NULL},
{PURPLE_SOUND_POUNCE_DEFAULT, NULL, "pounce_default", "alert.wav", NULL},
- {PURPLE_SOUND_CHAT_NICK, N_("Someone says your username in chat"), "nick_said", "alert.wav", NULL}
+ {PURPLE_SOUND_CHAT_NICK, N_("Someone says your username in chat"), "nick_said", "alert.wav", NULL},
+ {PURPLE_SOUND_GOT_ATTENTION, N_("Attention received"), "got_attention", "alert.wav", NULL}
};
const char *
@@ -273,6 +274,14 @@
play_conv_event(conv, event);
}
+static void
+got_attention_cb(PurpleAccount *account, const char *who,
+ PurpleConversation *conv, guint type, PurpleSoundEventID event)
+{
+ play_conv_event(conv, event);
+}
+
+
/*
* We mute sounds for the 10 seconds after you log in so that
* you don't get flooded with sounds when the blist shows all
@@ -300,34 +309,22 @@
static void
initialize_profile(const char *name, PurplePrefType type, gconstpointer val, gpointer null)
{
+ FinchSoundEvent *event;
if (purple_prefs_exists(make_pref("")))
return;
purple_prefs_add_none(make_pref(""));
purple_prefs_add_none(make_pref("/enabled"));
purple_prefs_add_none(make_pref("/file"));
- purple_prefs_add_bool(make_pref("/enabled/login"), FALSE);
- purple_prefs_add_path(make_pref("/file/login"), "");
- purple_prefs_add_bool(make_pref("/enabled/logout"), FALSE);
- purple_prefs_add_path(make_pref("/file/logout"), "");
- purple_prefs_add_bool(make_pref("/enabled/im_recv"), FALSE);
- purple_prefs_add_path(make_pref("/file/im_recv"), "");
- purple_prefs_add_bool(make_pref("/enabled/first_im_recv"), FALSE);
- purple_prefs_add_path(make_pref("/file/first_im_recv"), "");
- purple_prefs_add_bool(make_pref("/enabled/send_im"), FALSE);
- purple_prefs_add_path(make_pref("/file/send_im"), "");
- purple_prefs_add_bool(make_pref("/enabled/join_chat"), FALSE);
- purple_prefs_add_path(make_pref("/file/join_chat"), "");
- purple_prefs_add_bool(make_pref("/enabled/left_chat"), FALSE);
- purple_prefs_add_path(make_pref("/file/left_chat"), "");
- purple_prefs_add_bool(make_pref("/enabled/send_chat_msg"), FALSE);
- purple_prefs_add_path(make_pref("/file/send_chat_msg"), "");
- purple_prefs_add_bool(make_pref("/enabled/chat_msg_recv"), FALSE);
- purple_prefs_add_path(make_pref("/file/chat_msg_recv"), "");
- purple_prefs_add_bool(make_pref("/enabled/nick_said"), FALSE);
- purple_prefs_add_path(make_pref("/file/nick_said"), "");
- purple_prefs_add_bool(make_pref("/enabled/pounce_default"), FALSE);
- purple_prefs_add_path(make_pref("/file/pounce_default"), "");
+
+ for (event = sounds; event - sounds < PURPLE_NUM_SOUNDS; event++) {
+ char pref[512];
+ g_snprintf(pref, sizeof(pref), "/enabled/%s", event->pref);
+ purple_prefs_add_bool(make_pref(pref), FALSE);
+ g_snprintf(pref, sizeof(pref), "/file/%s", event->pref);
+ purple_prefs_add_path(make_pref(pref), "");
+ }
+
purple_prefs_add_bool(make_pref("/conv_focus"), FALSE);
purple_prefs_add_bool(make_pref("/mute"), FALSE);
purple_prefs_add_path(make_pref("/command"), "");
@@ -336,6 +333,25 @@
}
static void
+update_profiles(void)
+{
+ GList *list = finch_sound_get_profiles();
+ for (; list; list = g_list_delete_link(list, list)) {
+ char pname[512];
+
+ /* got_attention was added in libpurple 2.7.0 */
+ g_snprintf(pname, sizeof(pname), FINCH_PREFS_ROOT "/sound/profiles/%s%s",
+ (char *)list->data, "/enabled/got_attention");
+ purple_prefs_add_bool(pname, FALSE);
+ g_snprintf(pname, sizeof(pname), FINCH_PREFS_ROOT "/sound/profiles/%s%s",
+ (char *)list->data, "/file/got_attention");
+ purple_prefs_add_path(pname, "");
+
+ g_free(list->data);
+ }
+}
+
+static void
finch_sound_init(void)
{
void *gnt_sound_handle = finch_sound_get_handle();
@@ -356,7 +372,7 @@
purple_prefs_connect_callback(gnt_sound_handle, FINCH_PREFS_ROOT "/sound/actprofile", initialize_profile, NULL);
purple_prefs_trigger_callback(FINCH_PREFS_ROOT "/sound/actprofile");
-
+
#ifdef USE_GSTREAMER
purple_debug_info("sound", "Initializing sound output drivers.\n");
#if (GST_VERSION_MAJOR > 0 || \
@@ -399,6 +415,11 @@
purple_signal_connect(conv_handle, "received-chat-msg",
gnt_sound_handle, PURPLE_CALLBACK(chat_msg_received_cb),
GINT_TO_POINTER(PURPLE_SOUND_CHAT_SAY));
+ purple_signal_connect(conv_handle, "got-attention",
+ gnt_sound_handle, PURPLE_CALLBACK(got_attention_cb),
+ GINT_TO_POINTER(PURPLE_SOUND_GOT_ATTENTION));
+
+ update_profiles();
}
static void
@@ -577,7 +598,8 @@
if ((event == PURPLE_SOUND_BUDDY_ARRIVE) && mute_login_sounds)
return;
- if (event >= PURPLE_NUM_SOUNDS) {
+ if (event >= PURPLE_NUM_SOUNDS ||
+ event >= G_N_ELEMENTS(sounds)) {
purple_debug_error("sound", "got request for unknown sound: %d\n", event);
return;
}
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/libgnt/configure.ac
--- a/finch/libgnt/configure.ac Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/libgnt/configure.ac Mon Jul 19 21:11:32 2010 +0000
@@ -24,9 +24,9 @@
# Make sure to update ../../configure.ac with libgnt version changes.
#
-m4_define([gnt_lt_current], [7])
+m4_define([gnt_lt_current], [8])
m4_define([gnt_major_version], [2])
-m4_define([gnt_minor_version], [7])
+m4_define([gnt_minor_version], [8])
m4_define([gnt_micro_version], [0])
m4_define([gnt_version_suffix], [devel])
m4_define([gnt_version],
@@ -265,6 +265,10 @@
for location in $ac_ncurses_includes /usr/include/ncursesw /usr/include
do
f="$location/ncurses.h"
+ orig_CFLAGS="$CFLAGS"
+ orig_CPPFLAGS="$CPPFLAGS"
+ CFLAGS="$CFLAGS -I$location"
+ CPPFLAGS="$CPPFLAGS -I$location"
AC_CHECK_HEADER($f,[
AC_MSG_CHECKING([if $f supports wide characters])
AC_TRY_COMPILE([
@@ -283,9 +287,13 @@
fi
found_ncurses_h=yes
+ CFLAGS="$orig_CFLAGS"
+ CPPFLAGS="$orig_CPPFLAGS"
AC_MSG_RESULT([yes])
break
], [
+ CFLAGS="$orig_CFLAGS"
+ CPPFLAGS="$orig_CPPFLAGS"
AC_MSG_RESULT([no])
])
])
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/libgnt/gntcombobox.c
--- a/finch/libgnt/gntcombobox.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/libgnt/gntcombobox.c Mon Jul 19 21:11:32 2010 +0000
@@ -150,12 +150,11 @@
gnt_combo_box_key_pressed(GntWidget *widget, const char *text)
{
GntComboBox *box = GNT_COMBO_BOX(widget);
- if (GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED))
- {
- if (text[1] == 0)
- {
- switch (text[0])
- {
+ gboolean showing = !!GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED);
+
+ if (showing) {
+ if (text[1] == 0) {
+ switch (text[0]) {
case '\r':
case '\t':
case '\n':
@@ -166,8 +165,42 @@
return TRUE;
}
}
- if (gnt_widget_key_pressed(box->dropdown, text))
- return TRUE;
+ }
+
+ if (gnt_widget_key_pressed(box->dropdown, text)) {
+ if (!showing)
+ popup_dropdown(box);
+ return TRUE;
+ }
+
+ {
+#define SEARCH_IN_RANGE(start, end) do { \
+ GntTreeRow *row; \
+ for (row = start; row != end; \
+ row = gnt_tree_row_get_next(tree, row)) { \
+ gpointer key = gnt_tree_row_get_key(tree, row); \
+ GList *list = gnt_tree_get_row_text_list(tree, key); \
+ gboolean found = FALSE; \
+ found = (list->data && g_ascii_strncasecmp(text, list->data, len) == 0); \
+ g_list_foreach(list, (GFunc)g_free, NULL); \
+ g_list_free(list); \
+ if (found) { \
+ if (!showing) \
+ popup_dropdown(box); \
+ gnt_tree_set_selected(tree, key); \
+ return TRUE; \
+ } \
+ } \
+} while (0)
+
+ int len = strlen(text);
+ GntTree *tree = GNT_TREE(box->dropdown);
+ GntTreeRow *current = tree->current;
+
+ SEARCH_IN_RANGE(gnt_tree_row_get_next(tree, current), NULL);
+ SEARCH_IN_RANGE(tree->top, current);
+
+#undef SEARCH_IN_RANGE
}
return FALSE;
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/libgnt/gnttree.c
--- a/finch/libgnt/gnttree.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/libgnt/gnttree.c Mon Jul 19 21:11:32 2010 +0000
@@ -1926,3 +1926,33 @@
return (row && row->parent) ? row->parent->key : NULL;
}
+gpointer gnt_tree_row_get_key(GntTree *tree, GntTreeRow *row)
+{
+ g_return_val_if_fail(row && row->tree == tree, NULL);
+ return row->key;
+}
+
+GntTreeRow * gnt_tree_row_get_next(GntTree *tree, GntTreeRow *row)
+{
+ g_return_val_if_fail(row && row->tree == tree, NULL);
+ return row->next;
+}
+
+GntTreeRow * gnt_tree_row_get_prev(GntTree *tree, GntTreeRow *row)
+{
+ g_return_val_if_fail(row && row->tree == tree, NULL);
+ return row->prev;
+}
+
+GntTreeRow * gnt_tree_row_get_child(GntTree *tree, GntTreeRow *row)
+{
+ g_return_val_if_fail(row && row->tree == tree, NULL);
+ return row->child;
+}
+
+GntTreeRow * gnt_tree_row_get_parent(GntTree *tree, GntTreeRow *row)
+{
+ g_return_val_if_fail(row && row->tree == tree, NULL);
+ return row->parent;
+}
+
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/libgnt/gnttree.h
--- a/finch/libgnt/gnttree.h Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/libgnt/gnttree.h Mon Jul 19 21:11:32 2010 +0000
@@ -222,6 +222,61 @@
GList * gnt_tree_get_row_text_list(GntTree *tree, gpointer key);
/**
+ * Get the key of a row.
+ *
+ * @param tree The tree
+ * @param row The GntTreeRow object
+ *
+ * @return The key of the row.
+ * @since 2.8.0 (gnt), 2.7.2 (pidgin)
+ */
+gpointer gnt_tree_row_get_key(GntTree *tree, GntTreeRow *row);
+
+/**
+ * Get the next row.
+ *
+ * @param tree The tree
+ * @param row The GntTreeRow object
+ *
+ * @return The next row.
+ * @since 2.8.0 (gnt), 2.7.2 (pidgin)
+ */
+GntTreeRow * gnt_tree_row_get_next(GntTree *tree, GntTreeRow *row);
+
+/**
+ * Get the previous row.
+ *
+ * @param tree The tree
+ * @param row The GntTreeRow object
+ *
+ * @return The previous row.
+ * @since 2.8.0 (gnt), 2.7.2 (pidgin)
+ */
+GntTreeRow * gnt_tree_row_get_prev(GntTree *tree, GntTreeRow *row);
+
+/**
+ * Get the child row.
+ *
+ * @param tree The tree
+ * @param row The GntTreeRow object
+ *
+ * @return The child row.
+ * @since 2.8.0 (gnt), 2.7.2 (pidgin)
+ */
+GntTreeRow * gnt_tree_row_get_child(GntTree *tree, GntTreeRow *row);
+
+/**
+ * Get the parent row.
+ *
+ * @param tree The tree
+ * @param row The GntTreeRow object
+ *
+ * @return The parent row.
+ * @since 2.8.0 (gnt), 2.7.2 (pidgin)
+ */
+GntTreeRow * gnt_tree_row_get_parent(GntTree *tree, GntTreeRow *row);
+
+/**
* Get a list of text of the current row.
*
* @param tree The tree
diff -r c7fa7c7aca7d -r 47b6eda87723 finch/libgnt/gntutils.c
--- a/finch/libgnt/gntutils.c Mon Jul 19 21:05:06 2010 +0000
+++ b/finch/libgnt/gntutils.c Mon Jul 19 21:11:32 2010 +0000
@@ -385,7 +385,6 @@
const char *name;
char *content;
xmlNode *ch;
- gboolean processed = FALSE;
char *url = NULL;
gboolean insert_nl_s = FALSE, insert_nl_e = FALSE;
@@ -426,17 +425,14 @@
for (ch = node->children; ch; ch = ch->next) {
if (ch->type == XML_ELEMENT_NODE) {
- processed = TRUE;
util_parse_html_to_tv(ch, tv, flag);
+ } else if (ch->type == XML_TEXT_NODE) {
+ content = (char*)xmlNodeGetContent(ch);
+ gnt_text_view_append_text_with_flags(tv, content, flag);
+ xmlFree(content);
}
}
- if (!processed) {
- content = (char*)xmlNodeGetContent(node);
- gnt_text_view_append_text_with_flags(tv, content, flag);
- xmlFree(content);
- }
-
if (url) {
char *href = g_strdup_printf(" (%s)", url);
gnt_text_view_append_text_with_flags(tv, href, flag);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/Makefile.am
--- a/libpurple/Makefile.am Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/Makefile.am Mon Jul 19 21:11:32 2010 +0000
@@ -170,13 +170,11 @@
purple_builtheaders = purple.h version.h marshallers.h
marshallers.h: marshallers.list
- @echo "Generating marshallers.h"
- $(GLIB_GENMARSHAL) --prefix=purple_smarshal $(srcdir)/marshallers.list --header > marshallers.h
+ $(AM_V_GEN)$(GLIB_GENMARSHAL) --prefix=purple_smarshal $(srcdir)/marshallers.list --header > marshallers.h
marshallers.c: marshallers.list marshallers.h
- @echo "Generating marshallers.c"
- echo "#include \"marshallers.h\"" > marshallers.c
- $(GLIB_GENMARSHAL) --prefix=purple_smarshal $(srcdir)/marshallers.list --body >> marshallers.c
+ $(AM_V_GEN)echo "#include \"marshallers.h\"" > marshallers.c
+ $(AM_V_at)$(GLIB_GENMARSHAL) --prefix=purple_smarshal $(srcdir)/marshallers.list --body >> marshallers.c
if ENABLE_DBUS
@@ -212,16 +210,16 @@
$(srcdir)/protocols/jabber/libxmpp.c
dbus-types.c: dbus-analyze-types.py $(purple_build_coreheaders)
- cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --pattern=PURPLE_DBUS_DEFINE_TYPE\(%s\) > $@
+ $(AM_V_GEN)cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --pattern=PURPLE_DBUS_DEFINE_TYPE\(%s\) > $@
dbus-types.h: dbus-analyze-types.py $(purple_build_coreheaders)
- cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --pattern=PURPLE_DBUS_DECLARE_TYPE\(%s\) > $@
+ $(AM_V_GEN)cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --pattern=PURPLE_DBUS_DECLARE_TYPE\(%s\) > $@
dbus-bindings.c: dbus-analyze-functions.py $(dbus_exported)
- cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py > $@
+ $(AM_V_GEN)cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py > $@
dbus-signals.c: dbus-analyze-signals.py $(dbus_signals)
- cat $(dbus_signals) | $(PYTHON) $(srcdir)/dbus-analyze-signals.py > $@
+ $(AM_V_GEN)cat $(dbus_signals) | $(PYTHON) $(srcdir)/dbus-analyze-signals.py > $@
dbus-server.$(OBJEXT): dbus-bindings.c dbus-signals.c dbus-types.c dbus-types.h
dbus-server.lo: dbus-bindings.c dbus-signals.c dbus-types.c dbus-types.h
@@ -236,11 +234,11 @@
libpurple_client_la_LIBADD = $(DBUS_LIBS)
purple-client-bindings.c: dbus-analyze-functions.py $(dbus_exported)
- cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py --client > $@
+ $(AM_V_GEN)cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py --client > $@
purple-client-bindings.h: dbus-analyze-types.py dbus-analyze-functions.py $(purple_coreheaders) $(addprefix media/, $(purple_mediaheaders)) $(purple_builtheaders) $(dbus_exported)
- cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --keyword=enum --verbatim > $@
- cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py --client --headers >> $@
+ $(AM_V_GEN)cat $(purple_build_coreheaders) | $(PYTHON) $(srcdir)/dbus-analyze-types.py --keyword=enum --verbatim > $@
+ $(AM_V_at)cat $(dbus_build_exported) | $(PYTHON) $(srcdir)/dbus-analyze-functions.py --client --headers >> $@
$(libpurple_client_la_OBJECTS): purple-client-bindings.h purple-client-bindings.c
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/certificate.c
--- a/libpurple/certificate.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/certificate.c Mon Jul 19 21:11:32 2010 +0000
@@ -99,7 +99,8 @@
"that can verify it is currently trusted.");
break;
case PURPLE_CERTIFICATE_NOT_ACTIVATED:
- return _("The certificate is not valid yet.");
+ return _("The certificate is not valid yet. Check that your "
+ "computer's date and time are accurate.");
break;
case PURPLE_CERTIFICATE_EXPIRED:
return _("The certificate has expired and should not be "
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/connection.c
--- a/libpurple/connection.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/connection.c Mon Jul 19 21:11:32 2010 +0000
@@ -516,7 +516,8 @@
account = data;
gc = purple_account_get_connection(account);
- gc->disconnect_timeout = 0;
+ if (gc != NULL)
+ gc->disconnect_timeout = 0;
password = g_strdup(purple_account_get_password(account));
purple_account_disconnect(account);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/plugins/Makefile.mingw
--- a/libpurple/plugins/Makefile.mingw Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/plugins/Makefile.mingw Mon Jul 19 21:11:32 2010 +0000
@@ -55,7 +55,7 @@
$(MAKE) -C $(SSL_PLUGIN) -f $(MINGW_MAKEFILE) install
cp *.dll $(PURPLE_INSTALL_PLUGINS_DIR)
-.c.dll:
+%.dll: %.c $(PURPLE_CONFIG_H) $(PURPLE_VERSION_H)
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@.o -c $<
$(CC) -shared $@.o $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $@
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/plugins/perl/common/Log.xs
--- a/libpurple/plugins/perl/common/Log.xs Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/plugins/perl/common/Log.xs Mon Jul 19 21:11:32 2010 +0000
@@ -27,6 +27,9 @@
newCONSTSUB(flags_stash, (char *)civ->name, newSViv(civ->iv));
}
+Purple::Handle
+purple_log_get_handle()
+
int
purple_log_common_sizer(log)
Purple::Log log
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/auth_cyrus.c
--- a/libpurple/protocols/jabber/auth_cyrus.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/auth_cyrus.c Mon Jul 19 21:11:32 2010 +0000
@@ -36,7 +36,7 @@
{
purple_connection_error_reason(purple_account_get_connection(account),
PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
- _("Server requires plaintext authentication over an unencrypted stream"));
+ _("Server may require plaintext authentication over an unencrypted stream"));
}
static void start_cyrus_wrapper(JabberStream *js)
@@ -240,8 +240,9 @@
* it in plaintext, see if we can turn on
* plaintext auth
*/
+ /* XXX Should we just check for PLAIN/LOGIN being offered mechanisms? */
} else if (!plaintext) {
- char *msg = g_strdup_printf(_("%s requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"),
+ char *msg = g_strdup_printf(_("%s may require plaintext authentication over an unencrypted connection. Allow this and continue authentication?"),
purple_account_get_username(account));
purple_request_yes_no(js->gc, _("Plaintext Authentication"),
_("Plaintext Authentication"),
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/bosh.c
--- a/libpurple/protocols/jabber/bosh.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/bosh.c Mon Jul 19 21:11:32 2010 +0000
@@ -195,6 +195,11 @@
g_free(path);
conn->pipelining = TRUE;
+ if (purple_ip_address_is_valid(host))
+ js->serverFQDN = g_strdup(js->user->domain);
+ else
+ js->serverFQDN = g_strdup(host);
+
if ((user && user[0] != '\0') || (passwd && passwd[0] != '\0')) {
purple_debug_info("jabber", "Ignoring unexpected username and password "
"in BOSH URL.\n");
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/caps.c
--- a/libpurple/protocols/jabber/caps.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/caps.c Mon Jul 19 21:11:32 2010 +0000
@@ -29,6 +29,7 @@
#include "iq.h"
#include "presence.h"
#include "util.h"
+#include "xdata.h"
#define JABBER_CAPS_FILENAME "xmpp-caps.xml"
@@ -41,20 +42,14 @@
static GHashTable *nodetable = NULL; /* char *node -> JabberCapsNodeExts */
static guint save_timer = 0;
-/**
- * Processes a query-node and returns a JabberCapsClientInfo object with all relevant info.
- *
- * @param query A query object.
- * @return A JabberCapsClientInfo object.
- */
-static JabberCapsClientInfo *jabber_caps_parse_client_info(xmlnode *query);
-
/* Free a GList of allocated char* */
static void
free_string_glist(GList *list)
{
- g_list_foreach(list, (GFunc)g_free, NULL);
- g_list_free(list);
+ while (list) {
+ g_free(list->data);
+ list = g_list_delete_link(list, list);
+ }
}
static JabberCapsNodeExts*
@@ -238,15 +233,15 @@
if(!capsdata)
return;
- if (strcmp(capsdata->name, "capabilities") != 0) {
+ if (!g_str_equal(capsdata->name, "capabilities")) {
xmlnode_free(capsdata);
return;
}
- for(client = capsdata->child; client; client = client->next) {
- if(client->type != XMLNODE_TYPE_TAG)
+ for (client = capsdata->child; client; client = client->next) {
+ if (client->type != XMLNODE_TYPE_TAG)
continue;
- if(!strcmp(client->name, "client")) {
+ if (g_str_equal(client->name, "client")) {
JabberCapsClientInfo *value = g_new0(JabberCapsClientInfo, 1);
JabberCapsTuple *key = (JabberCapsTuple*)&value->tuple;
xmlnode *child;
@@ -259,15 +254,15 @@
if (key->hash == NULL)
exts = jabber_caps_find_exts_by_node(key->node);
- for(child = client->child; child; child = child->next) {
- if(child->type != XMLNODE_TYPE_TAG)
+ for (child = client->child; child; child = child->next) {
+ if (child->type != XMLNODE_TYPE_TAG)
continue;
- if(!strcmp(child->name,"feature")) {
+ if (g_str_equal(child->name, "feature")) {
const char *var = xmlnode_get_attrib(child, "var");
if(!var)
continue;
value->features = g_list_append(value->features,g_strdup(var));
- } else if(!strcmp(child->name,"identity")) {
+ } else if (g_str_equal(child->name, "identity")) {
const char *category = xmlnode_get_attrib(child, "category");
const char *type = xmlnode_get_attrib(child, "type");
const char *name = xmlnode_get_attrib(child, "name");
@@ -284,15 +279,15 @@
id->lang = g_strdup(lang);
value->identities = g_list_append(value->identities,id);
- } else if(!strcmp(child->name,"x")) {
+ } else if (g_str_equal(child->name, "x")) {
/* TODO: See #7814 -- this might cause problems if anyone
* ever actually specifies forms. In fact, for this to
* work properly, that bug needs to be fixed in
* xmlnode_from_str, not the output version... */
value->forms = g_list_append(value->forms, xmlnode_copy(child));
- } else if (!strcmp(child->name, "ext") && key->hash != NULL) {
+ } else if (g_str_equal(child->name, "ext") && key->hash != NULL) {
purple_debug_warning("jabber", "Ignoring exts when reading new-style caps\n");
- } else if (!strcmp(child->name, "ext")) {
+ } else if (g_str_equal(child->name, "ext")) {
/* TODO: Do we care about reading in the identities listed here? */
const char *identifier = xmlnode_get_attrib(child, "identifier");
xmlnode *node;
@@ -304,7 +299,7 @@
for (node = child->child; node; node = node->next) {
if (node->type != XMLNODE_TYPE_TAG)
continue;
- if (!strcmp(node->name, "feature")) {
+ if (g_str_equal(node->name, "feature")) {
const char *var = xmlnode_get_attrib(node, "var");
if (!var)
continue;
@@ -463,13 +458,13 @@
* size in jabber_caps_calculate_hash is large enough. The cipher API
* doesn't seem to offer a "Get the hash size" function(?).
*/
- if (!strcmp(userdata->hash, "sha-1")) {
+ if (g_str_equal(userdata->hash, "sha-1")) {
hash = jabber_caps_calculate_hash(info, "sha1");
- } else if (!strcmp(userdata->hash, "md5")) {
+ } else if (g_str_equal(userdata->hash, "md5")) {
hash = jabber_caps_calculate_hash(info, "md5");
}
- if (!hash || strcmp(hash, userdata->ver)) {
+ if (!hash || !g_str_equal(hash, userdata->ver)) {
purple_debug_warning("jabber", "Could not validate caps info from "
"%s. Expected %s, got %s\n",
xmlnode_get_attrib(packet, "from"),
@@ -709,44 +704,6 @@
}
static gint
-jabber_identity_compare(gconstpointer a, gconstpointer b)
-{
- const JabberIdentity *ac;
- const JabberIdentity *bc;
- gint cat_cmp;
- gint typ_cmp;
-
- ac = a;
- bc = b;
-
- if ((cat_cmp = strcmp(ac->category, bc->category)) == 0) {
- if ((typ_cmp = strcmp(ac->type, bc->type)) == 0) {
- if (!ac->lang && !bc->lang) {
- return 0;
- } else if (ac->lang && !bc->lang) {
- return 1;
- } else if (!ac->lang && bc->lang) {
- return -1;
- } else {
- return strcmp(ac->lang, bc->lang);
- }
- } else {
- return typ_cmp;
- }
- } else {
- return cat_cmp;
- }
-}
-
-static gchar *jabber_caps_get_formtype(const xmlnode *x) {
- xmlnode *formtypefield;
- formtypefield = xmlnode_get_child(x, "field");
- while (formtypefield && strcmp(xmlnode_get_attrib(formtypefield, "var"), "FORM_TYPE")) formtypefield = xmlnode_get_next_twin(formtypefield);
- formtypefield = xmlnode_get_child(formtypefield, "value");
- return xmlnode_get_data(formtypefield);;
-}
-
-static gint
jabber_xdata_compare(gconstpointer a, gconstpointer b)
{
const xmlnode *aformtypefield = a;
@@ -755,8 +712,8 @@
char *bformtype;
int result;
- aformtype = jabber_caps_get_formtype(aformtypefield);
- bformtype = jabber_caps_get_formtype(bformtypefield);
+ aformtype = jabber_x_data_get_formtype(aformtypefield);
+ bformtype = jabber_x_data_get_formtype(bformtypefield);
result = strcmp(aformtype, bformtype);
g_free(aformtype);
@@ -764,20 +721,21 @@
return result;
}
-static JabberCapsClientInfo *jabber_caps_parse_client_info(xmlnode *query)
+JabberCapsClientInfo *jabber_caps_parse_client_info(xmlnode *query)
{
xmlnode *child;
JabberCapsClientInfo *info;
- if (!query || strcmp(query->xmlns, NS_DISCO_INFO))
- return 0;
+ if (!query || !g_str_equal(query->name, "query") ||
+ !purple_strequal(query->xmlns, NS_DISCO_INFO))
+ return NULL;
info = g_new0(JabberCapsClientInfo, 1);
for(child = query->child; child; child = child->next) {
if (child->type != XMLNODE_TYPE_TAG)
continue;
- if (!strcmp(child->name,"identity")) {
+ if (g_str_equal(child->name, "identity")) {
/* parse identity */
const char *category = xmlnode_get_attrib(child, "category");
const char *type = xmlnode_get_attrib(child, "type");
@@ -795,13 +753,13 @@
id->lang = g_strdup(lang);
info->identities = g_list_append(info->identities, id);
- } else if (!strcmp(child->name, "feature")) {
+ } else if (g_str_equal(child->name, "feature")) {
/* parse feature */
const char *var = xmlnode_get_attrib(child, "var");
if (var)
info->features = g_list_prepend(info->features, g_strdup(var));
- } else if (!strcmp(child->name, "x")) {
- if (child->xmlns && !strcmp(child->xmlns, "jabber:x:data")) {
+ } else if (g_str_equal(child->name, "x")) {
+ if (purple_strequal(child->xmlns, "jabber:x:data")) {
/* x-data form */
xmlnode *dataform = xmlnode_copy(child);
info->forms = g_list_append(info->forms, dataform);
@@ -848,9 +806,12 @@
static void
append_escaped_string(PurpleCipherContext *context, const gchar *str)
{
- char *tmp = g_markup_escape_text(str, -1);
- purple_cipher_context_append(context, (const guchar *)tmp, strlen(tmp));
- g_free(tmp);
+ if (str && *str) {
+ char *tmp = g_markup_escape_text(str, -1);
+ purple_cipher_context_append(context, (const guchar *)tmp, strlen(tmp));
+ g_free(tmp);
+ }
+
purple_cipher_context_append(context, (const guchar *)"<", 1);
}
@@ -904,7 +865,7 @@
/* concat x-data forms to the verification string */
for(node = info->forms; node; node = node->next) {
xmlnode *data = (xmlnode *)node->data;
- gchar *formtype = jabber_caps_get_formtype(data);
+ gchar *formtype = jabber_x_data_get_formtype(data);
GList *fields = jabber_caps_xdata_get_fields(data);
/* append FORM_TYPE's field value to the verification string */
@@ -965,6 +926,10 @@
}
info.features = features;
+ /* TODO: This copy can go away, I think, since jabber_identities
+ * is pre-sorted, so the sort in calculate_hash should be idempotent.
+ * However, I want to test that. --darkrain
+ */
info.identities = g_list_copy(jabber_identities);
info.forms = NULL;
@@ -989,7 +954,7 @@
for (node = accounts; node; node = node->next) {
PurpleAccount *account = node->data;
const char *prpl_id = purple_account_get_protocol_id(account);
- if (!strcmp("prpl-jabber", prpl_id) && purple_account_is_connected(account)) {
+ if (g_str_equal("prpl-jabber", prpl_id) && purple_account_is_connected(account)) {
PurpleConnection *gc = purple_account_get_connection(account);
jabber_presence_send(gc->proto_data, TRUE);
}
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/caps.h
--- a/libpurple/protocols/jabber/caps.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/caps.h Mon Jul 19 21:11:32 2010 +0000
@@ -115,4 +115,15 @@
*/
void jabber_caps_broadcast_change(void);
+/**
+ * Parse the element from an IQ stanza into a JabberCapsClientInfo
+ * struct.
+ *
+ * Exposed for tests
+ *
+ * @param query The 'query' element from an IQ reply stanza.
+ * @returns A JabberCapsClientInfo struct, or NULL on error
+ */
+JabberCapsClientInfo *jabber_caps_parse_client_info(xmlnode *query);
+
#endif /* PURPLE_JABBER_CAPS_H_ */
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.c Mon Jul 19 21:11:32 2010 +0000
@@ -1962,20 +1962,53 @@
}
}
-void jabber_add_identity(const gchar *category, const gchar *type, const gchar *lang, const gchar *name) {
+gint
+jabber_identity_compare(gconstpointer a, gconstpointer b)
+{
+ const JabberIdentity *ac;
+ const JabberIdentity *bc;
+ gint cat_cmp;
+ gint typ_cmp;
+
+ ac = a;
+ bc = b;
+
+ if ((cat_cmp = strcmp(ac->category, bc->category)) == 0) {
+ if ((typ_cmp = strcmp(ac->type, bc->type)) == 0) {
+ if (!ac->lang && !bc->lang) {
+ return 0;
+ } else if (ac->lang && !bc->lang) {
+ return 1;
+ } else if (!ac->lang && bc->lang) {
+ return -1;
+ } else {
+ return strcmp(ac->lang, bc->lang);
+ }
+ } else {
+ return typ_cmp;
+ }
+ } else {
+ return cat_cmp;
+ }
+}
+
+void jabber_add_identity(const gchar *category, const gchar *type,
+ const gchar *lang, const gchar *name)
+{
GList *identity;
JabberIdentity *ident;
+
/* both required according to XEP-0030 */
g_return_if_fail(category != NULL);
g_return_if_fail(type != NULL);
- for(identity = jabber_identities; identity; identity = identity->next) {
- JabberIdentity *ident = (JabberIdentity*)identity->data;
- if (!strcmp(ident->category, category) &&
- !strcmp(ident->type, type) &&
- ((!ident->lang && !lang) || (ident->lang && lang && !strcmp(ident->lang, lang)))) {
+ /* Check if this identity is already there... */
+ for (identity = jabber_identities; identity; identity = identity->next) {
+ JabberIdentity *id = identity->data;
+ if (g_str_equal(id->category, category) &&
+ g_str_equal(id->type, type) &&
+ purple_strequal(id->lang, lang))
return;
- }
}
ident = g_new0(JabberIdentity, 1);
@@ -1983,7 +2016,8 @@
ident->type = g_strdup(type);
ident->lang = g_strdup(lang);
ident->name = g_strdup(name);
- jabber_identities = g_list_prepend(jabber_identities, ident);
+ jabber_identities = g_list_insert_sorted(jabber_identities, ident,
+ jabber_identity_compare);
}
static void jabber_identities_destroy(void)
@@ -3440,8 +3474,7 @@
for (iter = jb->resources; iter ; iter = g_list_next(iter)) {
JabberBuddyResource *jbr = (JabberBuddyResource *) iter->data;
- if (jabber_resource_has_capability(jbr,
- "http://jabber.org/protocol/si/profile/file-transfer")
+ if (jabber_resource_has_capability(jbr, NS_SI_FILE_TRANSFER)
&& (jabber_resource_has_capability(jbr,
NS_BYTESTREAMS)
|| jabber_resource_has_capability(jbr, NS_IBB))) {
@@ -3743,7 +3776,7 @@
jabber_add_feature("http://jabber.org/protocol/muc", 0);
jabber_add_feature("http://jabber.org/protocol/muc#user", 0);
jabber_add_feature("http://jabber.org/protocol/si", 0);
- jabber_add_feature("http://jabber.org/protocol/si/profile/file-transfer", 0);
+ jabber_add_feature(NS_SI_FILE_TRANSFER, 0);
jabber_add_feature(NS_XHTML_IM, 0);
jabber_add_feature(NS_PING, 0);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/jabber.h
--- a/libpurple/protocols/jabber/jabber.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.h Mon Jul 19 21:11:32 2010 +0000
@@ -303,6 +303,9 @@
/* what kind of additional features as returned from disco#info are supported? */
extern GList *jabber_features;
+/* A sorted list of identities advertised. Use jabber_add_identity to add
+ * so it remains sorted.
+ */
extern GList *jabber_identities;
void jabber_stream_features_parse(JabberStream *js, xmlnode *packet);
@@ -342,6 +345,11 @@
void jabber_add_identity(const gchar *category, const gchar *type, const gchar *lang, const gchar *name);
/**
+ * GCompareFunc for JabberIdentity structs.
+ */
+gint jabber_identity_compare(gconstpointer a, gconstpointer b);
+
+/**
* Returns true if this connection is over a secure (SSL) stream. Use this
* instead of checking js->gsc because BOSH stores its PurpleSslConnection
* members in its own data structure.
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/namespaces.h
--- a/libpurple/protocols/jabber/namespaces.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/namespaces.h Mon Jul 19 21:11:32 2010 +0000
@@ -61,6 +61,9 @@
#define NS_AVATAR_1_1_DATA "urn:xmpp:avatar:data"
#define NS_AVATAR_1_1_METADATA "urn:xmpp:avatar:metadata"
+/* XEP-0096 SI File Transfer */
+#define NS_SI_FILE_TRANSFER "http://jabber.org/protocol/si/profile/file-transfer"
+
/* XEP-0124 Bidirectional-streams Over Synchronous HTTP (BOSH) */
#define NS_BOSH "http://jabber.org/protocol/httpbind"
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/si.c
--- a/libpurple/protocols/jabber/si.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/si.c Mon Jul 19 21:11:32 2010 +0000
@@ -1262,12 +1262,10 @@
xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
jsx->stream_id = jabber_get_next_id(jsx->js);
xmlnode_set_attrib(si, "id", jsx->stream_id);
- xmlnode_set_attrib(si, "profile",
- "http://jabber.org/protocol/si/profile/file-transfer");
+ xmlnode_set_attrib(si, "profile", NS_SI_FILE_TRANSFER);
file = xmlnode_new_child(si, "file");
- xmlnode_set_namespace(file,
- "http://jabber.org/protocol/si/profile/file-transfer");
+ xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER);
xmlnode_set_attrib(file, "name", xfer->filename);
g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
xmlnode_set_attrib(file, "size", buf);
@@ -1488,7 +1486,7 @@
if (jabber_resource_has_capability(jbr, NS_IBB))
jsx->stream_method |= STREAM_METHOD_IBB;
- if (jabber_resource_has_capability(jbr, "http://jabber.org/protocol/si/profile/file-transfer")) {
+ if (jabber_resource_has_capability(jbr, NS_SI_FILE_TRANSFER)) {
jabber_si_xfer_send_request(xfer);
return;
}
@@ -1523,7 +1521,8 @@
JabberBuddy *jb;
JabberBuddyResource *jbr = NULL;
char *resource;
-
+ GList *resources = NULL;
+
if(NULL != (resource = jabber_get_resource(xfer->who))) {
/* they've specified a resource, no need to ask or
* default or anything, just do it */
@@ -1535,7 +1534,22 @@
jb = jabber_buddy_find(jsx->js, xfer->who, TRUE);
- if(!jb || !jb->resources) {
+ if (jb) {
+ GList *l;
+
+ for (l = jb->resources ; l ; l = g_list_next(l)) {
+ jbr = l->data;
+
+ if (!jabber_resource_know_capabilities(jbr) ||
+ (jabber_resource_has_capability(jbr, NS_SI_FILE_TRANSFER)
+ && (jabber_resource_has_capability(jbr, NS_BYTESTREAMS)
+ || jabber_resource_has_capability(jbr, NS_IBB)))) {
+ resources = g_list_append(resources, jbr);
+ }
+ }
+ }
+
+ if (!resources) {
/* no resources online, we're trying to send to someone
* whose presence we're not subscribed to, or
* someone who is offline. Let's inform the user */
@@ -1551,13 +1565,11 @@
purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
g_free(msg);
- } else if(!jb->resources->next) {
+ } else if (g_list_length(resources) == 1) {
/* only 1 resource online (probably our most common case)
* so no need to ask who to send to */
- jbr = jb->resources->data;
-
+ jbr = resources->data;
do_transfer_send(xfer, jbr->name);
-
} else {
/* we've got multiple resources, we need to pick one to send to */
GList *l;
@@ -1565,11 +1577,9 @@
PurpleRequestFields *fields = purple_request_fields_new();
PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
-
- for(l = jb->resources; l; l = l->next)
- {
+
+ for(l = resources; l; l = l->next) {
jbr = l->data;
-
purple_request_field_choice_add(field, jbr->name);
}
@@ -1583,6 +1593,8 @@
g_free(msg);
}
+
+ g_list_free(resources);
} else {
xmlnode *si, *feature, *x, *field, *value;
@@ -1695,7 +1707,7 @@
size_t filesize = 0;
if(!(profile = xmlnode_get_attrib(si, "profile")) ||
- strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer"))
+ strcmp(profile, NS_SI_FILE_TRANSFER))
return;
if(!(stream_id = xmlnode_get_attrib(si, "id")))
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/xdata.c
--- a/libpurple/protocols/jabber/xdata.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/xdata.c Mon Jul 19 21:11:32 2010 +0000
@@ -411,4 +411,30 @@
return handle;
}
+gchar *
+jabber_x_data_get_formtype(const xmlnode *form)
+{
+ xmlnode *field;
+ g_return_val_if_fail(form != NULL, NULL);
+
+ for (field = xmlnode_get_child((xmlnode *)form, "field"); field;
+ field = xmlnode_get_next_twin(field)) {
+ const char *var = xmlnode_get_attrib(field, "var");
+ if (purple_strequal(var, "FORM_TYPE")) {
+ xmlnode *value = xmlnode_get_child(field, "value");
+ if (value)
+ return xmlnode_get_data(value);
+ else
+ /* An interesting corner case... Looking for a second
+ * FORM_TYPE would be more considerate, but I'm in favor
+ * of not helping broken clients.
+ */
+ return NULL;
+ }
+ }
+
+ /* Erm, none found :( */
+ return NULL;
+}
+
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/jabber/xdata.h
--- a/libpurple/protocols/jabber/xdata.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/jabber/xdata.h Mon Jul 19 21:11:32 2010 +0000
@@ -37,4 +37,19 @@
void *jabber_x_data_request(JabberStream *js, xmlnode *packet, jabber_x_data_cb cb, gpointer user_data);
void *jabber_x_data_request_with_actions(JabberStream *js, xmlnode *packet, GList *actions, int defaultaction, jabber_x_data_action_cb cb, gpointer user_data);
+/*
+ * Return the form type (the CDATA of the value child of the FORM_TYPE
+ * field entry.
+ * E.g., for the following, "http://jabber.org/protocol/muc#roominfo".
+ *
+ *
+ * http://jabber.org/protocol/muc#roominfo
+ *
+ *
+ *
+ * @param form The xmlnode for the form (the 'x' element)
+ * @returns The FORM_TYPE. Must be freed by caller.
+ */
+gchar *jabber_x_data_get_formtype(const xmlnode *form);
+
#endif /* PURPLE_JABBER_XDATA_H_ */
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/msn/notification.c
--- a/libpurple/protocols/msn/notification.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/msn/notification.c Mon Jul 19 21:11:32 2010 +0000
@@ -431,7 +431,7 @@
/* add contact to xmlnode */
static void
-msn_add_contact_xml(MsnSession *session, xmlnode *mlNode,const char *passport, MsnListOp list_op, MsnNetwork networkId)
+msn_add_contact_xml(xmlnode *mlNode, const char *passport, MsnListOp list_op, MsnNetwork networkId)
{
xmlnode *d_node,*c_node;
char **tokens;
@@ -565,8 +565,8 @@
adl_node = xmlnode_new("ml");
xmlnode_set_attrib(adl_node, "l", "1");
- msn_add_contact_xml(session, adl_node, passport,
- user->list_op & MSN_LIST_OP_MASK, network);
+ msn_add_contact_xml(adl_node, passport,
+ user->list_op & MSN_LIST_OP_MASK, network);
payload = xmlnode_to_str(adl_node, &payload_len);
msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
g_free(payload);
@@ -622,8 +622,9 @@
}
if (user->networkid != MSN_NETWORK_UNKNOWN) {
- msn_add_contact_xml(session, adl_node, user->passport,
- user->list_op & MSN_LIST_OP_MASK, user->networkid);
+ msn_add_contact_xml(adl_node, user->passport,
+ user->list_op & MSN_LIST_OP_MASK,
+ user->networkid);
/* each ADL command may contain up to 150 contacts */
if (++adl_count % 150 == 0) {
@@ -652,8 +653,7 @@
purple_debug_info("msn", "Adding FQY address, count is %d\n",
session->adl_fqy);
- msn_add_contact_xml(session, fqy_node, user->passport,
- 0, user->networkid);
+ msn_add_contact_xml(fqy_node, user->passport, 0, user->networkid);
/* each FQY command may contain up to 150 contacts, probably */
if (++fqy_count % 150 == 0) {
@@ -696,6 +696,8 @@
xmlnode_free(adl_node);
xmlnode_free(fqy_node);
+ msn_session_activate_login_timeout(session);
+
pc = purple_account_get_connection(session->account);
display_name = purple_connection_get_display_name(pc);
if (display_name
@@ -2255,8 +2257,7 @@
node = xmlnode_new("ml");
node->child = NULL;
- msn_add_contact_xml(session, node, passport,
- addrem->list_op, network);
+ msn_add_contact_xml(node, passport, addrem->list_op, network);
payload = xmlnode_to_str(node, &payload_len);
xmlnode_free(node);
@@ -2286,8 +2287,7 @@
adl_node = xmlnode_new("ml");
adl_node->child = NULL;
- msn_add_contact_xml(notification->session, adl_node, user->passport,
- list_op, user->networkid);
+ msn_add_contact_xml(adl_node, user->passport, list_op, user->networkid);
payload = xmlnode_to_str(adl_node, &payload_len);
xmlnode_free(adl_node);
@@ -2325,8 +2325,7 @@
rml_node = xmlnode_new("ml");
rml_node->child = NULL;
- msn_add_contact_xml(notification->session, rml_node, user->passport,
- list_op, user->networkid);
+ msn_add_contact_xml(rml_node, user->passport, list_op, user->networkid);
payload = xmlnode_to_str(rml_node, &payload_len);
xmlnode_free(rml_node);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/msn/session.c
--- a/libpurple/protocols/msn/session.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/msn/session.c Mon Jul 19 21:11:32 2010 +0000
@@ -134,6 +134,11 @@
if (!session->connected)
return;
+ if (session->login_timeout) {
+ purple_timeout_remove(session->login_timeout);
+ session->login_timeout = 0;
+ }
+
session->connected = FALSE;
while (session->switches != NULL)
@@ -261,6 +266,28 @@
return swboard;
}
+static gboolean
+msn_login_timeout_cb(gpointer data)
+{
+ MsnSession *session = data;
+ /* This forces the login process to finish, even though we haven't heard
+ a response for our FQY requests yet. We'll at least end up online to the
+ people we've already added. The rest will follow later. */
+ msn_session_finish_login(session);
+ session->login_timeout = 0;
+ return FALSE;
+}
+
+void
+msn_session_activate_login_timeout(MsnSession *session)
+{
+ if (!session->logged_in) {
+ session->login_timeout =
+ purple_timeout_add_seconds(MSN_LOGIN_FQY_TIMEOUT,
+ msn_login_timeout_cb, session);
+ }
+}
+
static void
msn_session_sync_users(MsnSession *session)
{
@@ -365,6 +392,9 @@
msg = g_strdup_printf(_("Unable to authenticate: %s"),
(info == NULL ) ?
_("Unknown error") : info);
+ /* Clear the password if it isn't being saved */
+ if (!purple_account_get_remember_password(session->account))
+ purple_account_set_password(session->account, NULL);
break;
case MSN_ERROR_BAD_BLIST:
reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/msn/session.h
--- a/libpurple/protocols/msn/session.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/msn/session.h Mon Jul 19 21:11:32 2010 +0000
@@ -59,6 +59,8 @@
#define MSN_LOGIN_STEPS MSN_LOGIN_STEP_END
+#define MSN_LOGIN_FQY_TIMEOUT 30
+
#include "nexus.h"
#include "notification.h"
#include "oim.h"
@@ -78,6 +80,7 @@
gboolean connected;
gboolean logged_in; /**< A temporal flag to ignore local buddy list adds. */
int adl_fqy; /**< A count of ADL/FQY so status is only changed once. */
+ guint login_timeout; /**< Timeout to force status change if ADL/FQY fail. */
gboolean destroying; /**< A flag that states if the session is being destroyed. */
gboolean http_method;
@@ -208,7 +211,16 @@
const char *info);
/**
- * Sets the current step in the login proccess.
+ * Starts a timeout to initiate finishing login. Sometimes the server ignores
+ * our FQY requests, so this forces ourselves online eventually.
+ *
+ * @param session The MSN session.
+ */
+void
+msn_session_activate_login_timeout(MsnSession *session);
+
+/**
+ * Sets the current step in the login process.
*
* @param session The MSN session.
* @param step The current step.
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/msn/slplink.c
--- a/libpurple/protocols/msn/slplink.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/msn/slplink.c Mon Jul 19 21:11:32 2010 +0000
@@ -221,11 +221,16 @@
slplink->swboard = NULL;
}
- /* The slplink has no slpcalls in it, release it from the DC. */
- if (slplink->slp_calls == NULL && slplink->dc != NULL) {
- slplink->dc->slplink = NULL;
- msn_dc_destroy(slplink->dc);
- slplink->dc = NULL;
+ if (slplink->dc != NULL) {
+ if ((slplink->dc->state != DC_STATE_ESTABLISHED && slplink->dc->slpcall == slpcall)
+ || (slplink->slp_calls == NULL)) {
+ /* The DC is not established and its corresponding slpcall is dead,
+ * or the slplink has no slpcalls in it and no longer needs the DC.
+ */
+ slplink->dc->slplink = NULL;
+ msn_dc_destroy(slplink->dc);
+ slplink->dc = NULL;
+ }
}
}
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/msn/switchboard.c
--- a/libpurple/protocols/msn/switchboard.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/msn/switchboard.c Mon Jul 19 21:11:32 2010 +0000
@@ -647,8 +647,13 @@
else if ((swboard->current_users > 1) ||
(purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
{
+ GList *passport;
/* This is a switchboard used for a chat */
purple_conv_chat_remove_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL);
+
+ passport = g_list_find_custom(swboard->users, user, (GCompareFunc)strcmp);
+ g_free(passport->data);
+ swboard->users = g_list_delete_link(swboard->users, passport);
swboard->current_users--;
if (swboard->current_users == 0)
msn_switchboard_destroy(swboard);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/oscar/oscar.c
--- a/libpurple/protocols/oscar/oscar.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c Mon Jul 19 21:11:32 2010 +0000
@@ -2667,10 +2667,10 @@
g_free(rtfmsg);
}
}
- } else if (args->info.rtfmsg.msgtype == 26)
+ } else if (args->info.rtfmsg.msgtype == 26) {
purple_debug_info("oscar", "Sending X-Status Reply\n");
icq_relay_xstatus(od, userinfo->bn, args->cookie);
-
+ }
}
else
{
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/oscar/util.c
--- a/libpurple/protocols/oscar/util.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/oscar/util.c Mon Jul 19 21:11:32 2010 +0000
@@ -38,8 +38,8 @@
static const char * const msgerrreason[] = {
N_("Invalid error"),
N_("Invalid SNAC"),
- N_("Rate to host"),
- N_("Rate to client"),
+ N_("Server rate limit exceeded"),
+ N_("Client rate limit exceeded"),
N_("Not logged in"),
N_("Service unavailable"),
N_("Service not defined"),
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/protocols/yahoo/yahoo_filexfer.c
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c Mon Jul 19 21:11:32 2010 +0000
@@ -983,8 +983,8 @@
struct yahoo_xfer_data *xd;
struct sockaddr_in *addr;
struct yahoo_packet *pkt;
- long actaddr;
- long a,b,c,d;
+ unsigned long actaddr;
+ unsigned char a,b,c,d;
PurpleConnection *gc;
PurpleAccount *account;
YahooData *yd;
@@ -1018,19 +1018,19 @@
/* TODO:actually, u must try with addr no.1 , if its not working addr no.2 ..... */
addr = hosts->data;
actaddr = addr->sin_addr.s_addr;
- d = actaddr % 256;
- actaddr = (actaddr - d) / 256;
- c = actaddr % 256;
- actaddr = (actaddr - c) / 256;
- b = actaddr % 256;
- actaddr = (actaddr - b) / 256;
- a = actaddr;
+ d = actaddr & 0xff;
+ actaddr >>= 8;
+ c = actaddr & 0xff;
+ actaddr >>= 8;
+ b = actaddr & 0xff;
+ actaddr >>= 8;
+ a = actaddr & 0xff;
if(yd->jp)
xd->port = YAHOOJP_XFER_RELAY_PORT;
else
xd->port = YAHOO_XFER_RELAY_PORT;
- url = g_strdup_printf("%ld.%ld.%ld.%ld", d, c, b, a);
+ url = g_strdup_printf("%u.%u.%u.%u", d, c, b, a);
/* Free the address... */
g_free(hosts->data);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/tests/Makefile.am
--- a/libpurple/tests/Makefile.am Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/tests/Makefile.am Mon Jul 19 21:11:32 2010 +0000
@@ -10,6 +10,7 @@
check_libpurple.c \
tests.h \
test_cipher.c \
+ test_jabber_caps.c \
test_jabber_jutil.c \
test_jabber_scram.c \
test_qq.c \
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/tests/check_libpurple.c
--- a/libpurple/tests/check_libpurple.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/tests/check_libpurple.c Mon Jul 19 21:11:32 2010 +0000
@@ -84,6 +84,7 @@
sr = srunner_create (master_suite());
srunner_add_suite(sr, cipher_suite());
+ srunner_add_suite(sr, jabber_caps_suite());
srunner_add_suite(sr, jabber_jutil_suite());
srunner_add_suite(sr, jabber_scram_suite());
srunner_add_suite(sr, qq_suite());
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/tests/test_jabber_caps.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_jabber_caps.c Mon Jul 19 21:11:32 2010 +0000
@@ -0,0 +1,54 @@
+#include
+
+#include "tests.h"
+#include "../xmlnode.h"
+#include "../protocols/jabber/caps.h"
+
+START_TEST(test_parse_invalid)
+{
+ xmlnode *query;
+
+ fail_unless(NULL == jabber_caps_parse_client_info(NULL));
+
+ /* Something other than a disco#info query */
+ query = xmlnode_new("foo");
+ fail_unless(NULL == jabber_caps_parse_client_info(query));
+ xmlnode_free(query);
+
+ query = xmlnode_new("query");
+ fail_unless(NULL == jabber_caps_parse_client_info(query));
+ xmlnode_set_namespace(query, "jabber:iq:last");
+ fail_unless(NULL == jabber_caps_parse_client_info(query));
+ xmlnode_free(query);
+}
+END_TEST
+
+#define assert_caps_calculate_match(hash_func, hash, str) { \
+ xmlnode *query = xmlnode_from_str((str), -1); \
+ JabberCapsClientInfo *info = jabber_caps_parse_client_info(query); \
+ gchar *got_hash = jabber_caps_calculate_hash(info, (hash_func)); \
+ assert_string_equal_free((hash), got_hash); \
+}
+
+START_TEST(test_calculate_caps)
+{
+ assert_caps_calculate_match("sha1", "GNjxthSckUNvAIoCCJFttjl6VL8=",
+ "urn:xmpp:dataforms:softwareinfoTkabber ( 8.5.5 )ATmega640-16AU");
+}
+END_TEST
+
+Suite *
+jabber_caps_suite(void)
+{
+ Suite *s = suite_create("Jabber Caps Functions");
+
+ TCase *tc = tcase_create("Parsing invalid ndoes");
+ tcase_add_test(tc, test_parse_invalid);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("Calculating from XMLnode");
+ tcase_add_test(tc, test_calculate_caps);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/tests/tests.h
--- a/libpurple/tests/tests.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/tests/tests.h Mon Jul 19 21:11:32 2010 +0000
@@ -9,6 +9,7 @@
/* remember to add the suite to the runner in check_libpurple.c */
Suite * master_suite(void);
Suite * cipher_suite(void);
+Suite * jabber_caps_suite(void);
Suite * jabber_jutil_suite(void);
Suite * jabber_scram_suite(void);
Suite * qq_suite(void);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/upnp.c
--- a/libpurple/upnp.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/upnp.c Mon Jul 19 21:11:32 2010 +0000
@@ -403,6 +403,11 @@
lookup_internal_ip();
}
+ if (dd->inpa > 0)
+ purple_input_remove(dd->inpa);
+ if (dd->tima > 0)
+ purple_timeout_remove(dd->tima);
+
g_free(dd);
}
@@ -506,6 +511,8 @@
if (dd->inpa)
purple_input_remove(dd->inpa);
+ if (dd->tima > 0)
+ purple_timeout_remove(dd->tima);
dd->inpa = 0;
dd->tima = 0;
@@ -610,7 +617,7 @@
/* We have already done all our retries. Make sure that the callback
* doesn't get called before the original function returns */
- purple_timeout_add(10, purple_upnp_discover_timeout, dd);
+ dd->tima = purple_timeout_add(10, purple_upnp_discover_timeout, dd);
}
void
@@ -647,7 +654,7 @@
"purple_upnp_discover(): Failed In sock creation\n");
/* Short circuit the retry attempts */
dd->retry_count = NUM_UDP_ATTEMPTS;
- purple_timeout_add(10, purple_upnp_discover_timeout, dd);
+ dd->tima = purple_timeout_add(10, purple_upnp_discover_timeout, dd);
return;
}
@@ -659,7 +666,7 @@
"purple_upnp_discover(): Failed In gethostbyname\n");
/* Short circuit the retry attempts */
dd->retry_count = NUM_UDP_ATTEMPTS;
- purple_timeout_add(10, purple_upnp_discover_timeout, dd);
+ dd->tima = purple_timeout_add(10, purple_upnp_discover_timeout, dd);
return;
}
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/util.c
--- a/libpurple/util.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/util.c Mon Jul 19 21:11:32 2010 +0000
@@ -3423,7 +3423,7 @@
char **ret_path, char **ret_user, char **ret_passwd)
{
gboolean is_https = FALSE;
- char scan_info[255];
+ const char * scan_info;
char port_str[6];
int f;
const char *at, *slash;
@@ -3431,11 +3431,12 @@
char host[256], path[256], user[256], passwd[256];
int port = 0;
/* hyphen at end includes it in control set */
- static const char addr_ctrl[] = "A-Za-z0-9.-";
- static const char port_ctrl[] = "0-9";
- static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-";
- static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
- static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
+
+#define ADDR_CTRL "A-Za-z0-9.-"
+#define PORT_CTRL "0-9"
+#define PAGE_CTRL "A-Za-z0-9.~_/:*!@&%%?=+^-"
+#define USER_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
+#define PASSWD_CTRL "A-Za-z0-9.~_/*!&%%?=+^-"
g_return_val_if_fail(url != NULL, FALSE);
@@ -3455,37 +3456,32 @@
/* Only care about @ char BEFORE the first / */
at = strchr(url, '@');
slash = strchr(url, '/');
- if ((at != NULL) &&
- (((slash != NULL) && (strlen(at) > strlen(slash))) ||
- (slash == NULL))) {
- g_snprintf(scan_info, sizeof(scan_info),
- "%%255[%s]:%%255[%s]^@", user_ctrl, passwd_ctrl);
+ f = 0;
+ if (at && (!slash || at < slash)) {
+ scan_info = "%255[" USER_CTRL "]:%255[" PASSWD_CTRL "]^@";
f = sscanf(url, scan_info, user, passwd);
- if (f ==1 ) {
+ if (f == 1) {
/* No passwd, possibly just username supplied */
- g_snprintf(scan_info, sizeof(scan_info),
- "%%255[%s]^@", user_ctrl);
+ scan_info = "%255[" USER_CTRL "]^@";
f = sscanf(url, scan_info, user);
- *passwd = '\0';
}
url = at+1; /* move pointer after the @ char */
- } else {
+ }
+
+ if (f < 1) {
*user = '\0';
*passwd = '\0';
- }
-
- g_snprintf(scan_info, sizeof(scan_info),
- "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, page_ctrl);
-
+ } else if (f == 1)
+ *passwd = '\0';
+
+ scan_info = "%255[" ADDR_CTRL "]:%5[" PORT_CTRL "]/%255[" PAGE_CTRL "]";
f = sscanf(url, scan_info, host, port_str, path);
if (f == 1)
{
- g_snprintf(scan_info, sizeof(scan_info),
- "%%255[%s]/%%255[%s]",
- addr_ctrl, page_ctrl);
+ scan_info = "%255[" ADDR_CTRL "]/%255[" PAGE_CTRL "]";
f = sscanf(url, scan_info, host, path);
/* Use the default port */
if (is_https)
@@ -3509,6 +3505,12 @@
if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd);
return ((*host != '\0') ? TRUE : FALSE);
+
+#undef ADDR_CTRL
+#undef PORT_CTRL
+#undef PAGE_CTRL
+#undef USER_CTRL
+#undef PASSWD_CTRL
}
/**
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/xmlnode.c
--- a/libpurple/xmlnode.c Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/xmlnode.c Mon Jul 19 21:11:32 2010 +0000
@@ -223,7 +223,7 @@
const char *
-xmlnode_get_attrib(xmlnode *node, const char *attr)
+xmlnode_get_attrib(const xmlnode *node, const char *attr)
{
xmlnode *x;
@@ -240,9 +240,9 @@
}
const char *
-xmlnode_get_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns)
+xmlnode_get_attrib_with_namespace(const xmlnode *node, const char *attr, const char *xmlns)
{
- xmlnode *x;
+ const xmlnode *x;
g_return_val_if_fail(node != NULL, NULL);
g_return_val_if_fail(attr != NULL, NULL);
diff -r c7fa7c7aca7d -r 47b6eda87723 libpurple/xmlnode.h
--- a/libpurple/xmlnode.h Mon Jul 19 21:05:06 2010 +0000
+++ b/libpurple/xmlnode.h Mon Jul 19 21:11:32 2010 +0000
@@ -205,7 +205,7 @@
*
* @return The value of the attribute.
*/
-const char *xmlnode_get_attrib(xmlnode *node, const char *attr);
+const char *xmlnode_get_attrib(const xmlnode *node, const char *attr);
/**
* Gets a namespaced attribute from a node
@@ -216,7 +216,7 @@
*
* @return The value of the attribute/
*/
-const char *xmlnode_get_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns);
+const char *xmlnode_get_attrib_with_namespace(const xmlnode *node, const char *attr, const char *xmlns);
/**
* Removes an attribute from a node.
diff -r c7fa7c7aca7d -r 47b6eda87723 pidgin/gtkblist.c
--- a/pidgin/gtkblist.c Mon Jul 19 21:05:06 2010 +0000
+++ b/pidgin/gtkblist.c Mon Jul 19 21:11:32 2010 +0000
@@ -3601,11 +3601,12 @@
purple_request_field_list_add_selected(f, _("None"));
/* TODO: rlaager wants this sorted. */
- /* The connection is checked for PURPLE_CONNECTION_SUPPORT_MOODS flag before
- * this function is called for a non-null account. So using
- * PURPLE_PROTOCOL_PLUGIN_HAS_FUNC isn't necessary here */
- for (mood = account ? prpl_info->get_moods(account) : global_moods;
- mood->mood != NULL ; mood++) {
+ /* TODO: darkrain wants it sorted post-translation */
+ if (account && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods))
+ mood = prpl_info->get_moods(account);
+ else
+ mood = global_moods;
+ for ( ; mood->mood != NULL ; mood++) {
char *path;
if (mood->mood == NULL || mood->description == NULL)
diff -r c7fa7c7aca7d -r 47b6eda87723 pidgin/gtkimhtmltoolbar.c
--- a/pidgin/gtkimhtmltoolbar.c Mon Jul 19 21:05:06 2010 +0000
+++ b/pidgin/gtkimhtmltoolbar.c Mon Jul 19 21:11:32 2010 +0000
@@ -1276,6 +1276,15 @@
}
static void
+button_visibility_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
+{
+ if (GTK_WIDGET_VISIBLE(button))
+ gtk_widget_hide(item);
+ else
+ gtk_widget_show(item);
+}
+
+static void
button_sensitiveness_changed(GtkWidget *button, gpointer dontcare, GtkWidget *item)
{
gtk_widget_set_sensitive(item, GTK_WIDGET_IS_SENSITIVE(button));
@@ -1323,6 +1332,7 @@
GtkWidget *insert_menu;
GtkWidget *menuitem;
GtkWidget *sep;
+ GObject *wide_attention_button;
int i;
struct {
const char *label;
@@ -1393,6 +1403,8 @@
gtk_menu_shell_append(GTK_MENU_SHELL(font_menu), menuitem);
g_signal_connect(G_OBJECT(old), "notify::sensitive",
G_CALLBACK(button_sensitiveness_changed), menuitem);
+ g_signal_connect(G_OBJECT(old), "notify::visible",
+ G_CALLBACK(button_visibility_changed), menuitem);
gtk_container_foreach(GTK_CONTAINER(menuitem), (GtkCallback)enable_markup, NULL);
}
@@ -1425,12 +1437,16 @@
gtk_menu_shell_append(GTK_MENU_SHELL(insert_menu), menuitem);
g_signal_connect(G_OBJECT(toolbar->image), "notify::sensitive",
G_CALLBACK(button_sensitiveness_changed), menuitem);
+ g_signal_connect(G_OBJECT(toolbar->image), "notify::visible",
+ G_CALLBACK(button_visibility_changed), menuitem);
menuitem = gtk_menu_item_new_with_mnemonic(_("_Link"));
g_signal_connect_swapped(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_button_clicked), toolbar->link);
gtk_menu_shell_append(GTK_MENU_SHELL(insert_menu), menuitem);
g_signal_connect(G_OBJECT(toolbar->link), "notify::sensitive",
G_CALLBACK(button_sensitiveness_changed), menuitem);
+ g_signal_connect(G_OBJECT(toolbar->link), "notify::visible",
+ G_CALLBACK(button_visibility_changed), menuitem);
menuitem = gtk_menu_item_new_with_mnemonic(_("_Horizontal rule"));
g_signal_connect(G_OBJECT(menuitem), "activate" , G_CALLBACK(insert_hr_cb), toolbar);
@@ -1467,29 +1483,30 @@
gtk_widget_show_all(sep);
/* Attention */
+ wide_attention_button = g_object_get_data(G_OBJECT(toolbar), "attention");
+
attention_button = gtk_button_new();
gtk_button_set_relief(GTK_BUTTON(attention_button), GTK_RELIEF_NONE);
bbox = gtk_hbox_new(FALSE, 3);
gtk_container_add(GTK_CONTAINER(attention_button), bbox);
- image = gtk_image_new_from_stock(PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION,
+ image = gtk_image_new_from_stock(PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION,
gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0);
label = gtk_label_new_with_mnemonic(_("_Attention!"));
gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), attention_button, FALSE, FALSE, 0);
- g_signal_connect_swapped(G_OBJECT(attention_button), "clicked",
- G_CALLBACK(gtk_button_clicked),
- g_object_get_data(G_OBJECT(toolbar), "attention"));
+ g_signal_connect_swapped(G_OBJECT(attention_button), "clicked",
+ G_CALLBACK(gtk_button_clicked), wide_attention_button);
gtk_widget_show_all(attention_button);
-
- g_signal_connect(G_OBJECT(g_object_get_data(G_OBJECT(toolbar), "attention")),
- "notify::sensitive",
+
+ g_signal_connect(wide_attention_button, "notify::sensitive",
G_CALLBACK(button_sensitiveness_changed), attention_button);
+ g_signal_connect(wide_attention_button, "notify::visible",
+ G_CALLBACK(button_visibility_changed), attention_button);
/* set attention button to be greyed out until we get a conversation */
- gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(toolbar), "attention"),
- FALSE);
-
+ gtk_widget_set_sensitive(GTK_WIDGET(wide_attention_button), FALSE);
+
gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(hbox), "lean-view", box);
gtk_widget_show(box);
diff -r c7fa7c7aca7d -r 47b6eda87723 pidgin/gtkmain.c
--- a/pidgin/gtkmain.c Mon Jul 19 21:05:06 2010 +0000
+++ b/pidgin/gtkmain.c Mon Jul 19 21:11:32 2010 +0000
@@ -97,7 +97,6 @@
*/
static const int catch_sig_list[] = {
SIGSEGV,
- SIGHUP,
SIGINT,
SIGTERM,
SIGQUIT,
@@ -223,9 +222,6 @@
}
switch (sig) {
- case SIGHUP:
- purple_debug_warning("sighandler", "Caught signal %d\n", sig);
- break;
#if defined(USE_GSTREAMER) && !defined(GST_CAN_DISABLE_FORKING)
/* By default, gstreamer forks when you initialize it, and waitpids for the
* child. But if libpurple reaps the child rather than leaving it to
@@ -550,6 +546,7 @@
gboolean debug_enabled;
gboolean migration_failed = FALSE;
GList *active_accounts;
+ struct stat st;
struct option long_options[] = {
{"config", required_argument, NULL, 'c'},
@@ -853,6 +850,8 @@
* in user's home directory.
*/
search_path = g_build_filename(purple_user_dir(), "plugins", NULL);
+ if (!g_stat(search_path, &st))
+ g_mkdir(search_path, S_IRUSR | S_IWUSR | S_IXUSR);
purple_plugins_add_search_path(search_path);
g_free(search_path);
purple_plugins_add_search_path(LIBDIR);
diff -r c7fa7c7aca7d -r 47b6eda87723 pidgin/gtkmedia.c
--- a/pidgin/gtkmedia.c Mon Jul 19 21:05:06 2010 +0000
+++ b/pidgin/gtkmedia.c Mon Jul 19 21:11:32 2010 +0000
@@ -333,7 +333,7 @@
gtk_box_pack_start(GTK_BOX(vbox), media->priv->menubar,
FALSE, TRUE, 0);
- media->priv->display = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+ media->priv->display = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
gtk_container_set_border_width(GTK_CONTAINER(media->priv->display),
PIDGIN_HIG_BOX_SPACE);
gtk_box_pack_start(GTK_BOX(vbox), media->priv->display,
@@ -629,29 +629,29 @@
gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display),
recv_widget, TRUE, TRUE, 0);
gtk_widget_show(recv_widget);
- } else
+ } else {
recv_widget = gtkmedia->priv->recv_widget;
+ }
if (gtkmedia->priv->send_widget == NULL
&& type & (PURPLE_MEDIA_SEND_VIDEO |
PURPLE_MEDIA_SEND_AUDIO)) {
send_widget = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
gtk_box_pack_start(GTK_BOX(gtkmedia->priv->display),
- send_widget, TRUE, TRUE, 0);
+ send_widget, FALSE, TRUE, 0);
button_widget = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
- gtk_box_pack_end(GTK_BOX(send_widget), button_widget,
- FALSE, FALSE, 0);
- gtk_widget_show(GTK_WIDGET(button_widget));
+ gtk_box_pack_end(GTK_BOX(recv_widget), button_widget,
+ FALSE, TRUE, 0);
gtk_widget_show(send_widget);
/* Hold button */
gtkmedia->priv->hold =
gtk_toggle_button_new_with_mnemonic("_Hold");
+ gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->hold,
+ FALSE, FALSE, 0);
+ gtk_widget_show(gtkmedia->priv->hold);
g_signal_connect(gtkmedia->priv->hold, "toggled",
G_CALLBACK(pidgin_media_hold_toggled),
gtkmedia);
- gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->hold,
- FALSE, FALSE, 0);
- gtk_widget_show(gtkmedia->priv->hold);
} else {
send_widget = gtkmedia->priv->send_widget;
button_widget = gtkmedia->priv->button_widget;
@@ -663,7 +663,7 @@
GtkWidget *remote_video;
GdkColor color = {0, 0, 0, 0};
- aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE);
+ aspect = gtk_aspect_frame_new(NULL, 0, 0, 4.0/3.0, FALSE);
gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN);
gtk_box_pack_start(GTK_BOX(recv_widget), aspect, TRUE, TRUE, 0);
@@ -683,15 +683,16 @@
gtkmedia->priv->remote_video = remote_video;
}
+
if (type & PURPLE_MEDIA_SEND_VIDEO) {
PidginMediaRealizeData *data;
GtkWidget *aspect;
GtkWidget *local_video;
GdkColor color = {0, 0, 0, 0};
- aspect = gtk_aspect_frame_new(NULL, 0.5, 0.5, 4.0/3.0, FALSE);
+ aspect = gtk_aspect_frame_new(NULL, 0, 0, 4.0/3.0, TRUE);
gtk_frame_set_shadow_type(GTK_FRAME(aspect), GTK_SHADOW_IN);
- gtk_box_pack_start(GTK_BOX(send_widget), aspect, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(send_widget), aspect, FALSE, TRUE, 0);
data = g_new0(PidginMediaRealizeData, 1);
data->gtkmedia = gtkmedia;
@@ -703,44 +704,43 @@
g_signal_connect(G_OBJECT(local_video), "realize",
G_CALLBACK(realize_cb), data);
gtk_container_add(GTK_CONTAINER(aspect), local_video);
- gtk_widget_set_size_request (GTK_WIDGET(local_video), 160, 120);
+ gtk_widget_set_size_request (GTK_WIDGET(local_video), 80, 60);
gtk_widget_show(local_video);
gtk_widget_show(aspect);
gtkmedia->priv->pause =
gtk_toggle_button_new_with_mnemonic(_("_Pause"));
+ gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->pause,
+ FALSE, FALSE, 0);
+ gtk_widget_show(gtkmedia->priv->pause);
g_signal_connect(gtkmedia->priv->pause, "toggled",
G_CALLBACK(pidgin_media_pause_toggled),
gtkmedia);
- gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->pause,
- FALSE, FALSE, 0);
- gtk_widget_show(gtkmedia->priv->pause);
gtkmedia->priv->local_video = local_video;
}
-
if (type & PURPLE_MEDIA_RECV_AUDIO) {
gtk_box_pack_end(GTK_BOX(recv_widget),
pidgin_media_add_audio_widget(gtkmedia,
PURPLE_MEDIA_RECV_AUDIO), FALSE, FALSE, 0);
}
+
if (type & PURPLE_MEDIA_SEND_AUDIO) {
gtkmedia->priv->mute =
gtk_toggle_button_new_with_mnemonic("_Mute");
+ gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->mute,
+ FALSE, FALSE, 0);
+ gtk_widget_show(gtkmedia->priv->mute);
g_signal_connect(gtkmedia->priv->mute, "toggled",
G_CALLBACK(pidgin_media_mute_toggled),
gtkmedia);
- gtk_box_pack_end(GTK_BOX(button_widget), gtkmedia->priv->mute,
- FALSE, FALSE, 0);
- gtk_widget_show(gtkmedia->priv->mute);
- gtk_box_pack_end(GTK_BOX(send_widget),
+ gtk_box_pack_end(GTK_BOX(recv_widget),
pidgin_media_add_audio_widget(gtkmedia,
PURPLE_MEDIA_SEND_AUDIO), FALSE, FALSE, 0);
}
-
if (type & PURPLE_MEDIA_AUDIO &&
gtkmedia->priv->level_handler_id == 0) {
gtkmedia->priv->level_handler_id = g_signal_connect(
@@ -752,8 +752,10 @@
gtkmedia->priv->send_widget = send_widget;
if (recv_widget != NULL)
gtkmedia->priv->recv_widget = recv_widget;
- if (button_widget != NULL)
+ if (button_widget != NULL) {
gtkmedia->priv->button_widget = button_widget;
+ gtk_widget_show(GTK_WIDGET(button_widget));
+ }
if (purple_media_is_initiator(media, sid, NULL) == FALSE) {
if (gtkmedia->priv->timeout_id != 0)
diff -r c7fa7c7aca7d -r 47b6eda87723 pidgin/gtkprefs.c
--- a/pidgin/gtkprefs.c Mon Jul 19 21:05:06 2010 +0000
+++ b/pidgin/gtkprefs.c Mon Jul 19 21:11:32 2010 +0000
@@ -2223,6 +2223,7 @@
gtk_widget_set_sensitive(hbox,
!strcmp(method, "automatic") ||
+ !strcmp(method, "alsa") ||
!strcmp(method, "esd"));
}
#endif /* USE_GSTREAMER */
diff -r c7fa7c7aca7d -r 47b6eda87723 pidgin/plugins/Makefile.mingw
--- a/pidgin/plugins/Makefile.mingw Mon Jul 19 21:05:06 2010 +0000
+++ b/pidgin/plugins/Makefile.mingw Mon Jul 19 21:11:32 2010 +0000
@@ -73,7 +73,7 @@
$(MAKE) -C $(WINPREFS_PLUGIN) -f $(MINGW_MAKEFILE) install
cp *.dll $(PIDGIN_INSTALL_PLUGINS_DIR)
-.c.dll:
+%.dll: %.c $(PURPLE_CONFIG_H) $(PURPLE_VERSION_H)
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@.o -c $<
$(CC) -shared $@.o $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $@