changeset 31568:e9b9d6ba2cff

merge of 'b37e581d0bfe6efa24595ece99a284dd51c08d78' and 'ddda3b9ca9b6cf8b06736f8b59b92683511117df'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 09 Jan 2011 04:54:17 +0000
parents 4b66ef54f6a3 (diff) d143f52ae28e (current diff)
children 98b37f61379c
files
diffstat 15 files changed, 144 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Thu Jan 06 05:52:19 2011 +0000
+++ b/COPYRIGHT	Sun Jan 09 04:54:17 2011 +0000
@@ -94,6 +94,7 @@
 Matěj Cepl
 Cerulean Studios, LLC
 Jonathan Champ
+Markos Chandras
 Matthew Chapman
 Christophe Chapuis
 Patrick Cheung
@@ -262,6 +263,7 @@
 F.W. Kong
 Konstantin Korikov
 Cole Kowalski
+Nikita Kozlov
 Matt Kramer
 Gary Kramlich
 Jan Kratochvil
@@ -540,6 +542,7 @@
 Andrew Victor
 Jorge Villaseñor (Masca)
 Bjoern Voigt
+Peter Volkov
 Wan Hing Wah
 Philip Walford
 Nathan Walp
--- a/ChangeLog	Thu Jan 06 05:52:19 2011 +0000
+++ b/ChangeLog	Sun Jan 09 04:54:17 2011 +0000
@@ -1,6 +1,15 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
 version 2.7.10 (??/??/????):
+	General:
+	* Force video sources to all have the same capabilities.  This reduces the
+	  number of times video must be scaled down, saving CPU time. (Jakub Adam)
+	  (half of #13095)
+	* Starting multiple video calls and ending one no longer causes the other
+	  calls to stop sending audio and video. (Jakub Adam) (#12758)
+	* Perl bindings now respect LDFLAGS. (Peter Volkov, Markos Chandras)
+	  (#12638)
+
 	IRC:
 	* Don't send ISON messages longer than 512 bytes. (Jeffrey Honig) (#9692)
 
@@ -8,11 +17,14 @@
 	* Stop sending audio when placing a call on hold. (Jakub Adam) (#13032)
 	* Stop translating gpointers to ints in the dbus API.  This removes
 	  functions from the dbus API.  (The openSUSE Project) (#12507)
+	* Fix D-Bus introspection calls that omit the interface parameter.  (Tom
+	  Samstag) (#13073)
 
 	Pidgin:
 	* Support using the Page Up and Page Down keys on the numeric keypad in
 	  the conversation window.  (Ryan Flegel) (#13127)
 	* Fix a few memory leaks. (Nader Morshed) (#13162)
+	* Support rendering strikethrough when received as in-line CSS. (#13168)
 
 	Plugins:
 	* The Voice/Video Settings plugin no longer resets selected devices to
@@ -25,6 +37,10 @@
 	QQ:
 	* QQ2008 is now the default protocol version. (Michael Terry) (#11635)
 
+	XMPP:
+	* Don't crash when receiving an unexpected/invalid jingle transport type.
+	  (Nikita Kozlov) (#13136)
+
 	Yahoo!/Yahoo! JAPAN:
 	* Fix a crash when an account disconnects before a p2p session is
 	  completely set up. (Jan Kaluza) (#12432)
--- a/libpurple/dbus-analyze-signals.py	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/dbus-analyze-signals.py	Sun Jan 09 04:54:17 2011 +0000
@@ -32,7 +32,7 @@
         continue
 
     signal = nameregex.sub(lambda x:x.group()[1].upper(), '-'+signal)
-    print "\"<signal name='%s'>\\n\""%signal
+    print "\"    <signal name='%s'>\\n\""%signal
 
     args = marshal.split('_')
     # ['purple', 'marshal', <return type>, '', args...]
@@ -52,9 +52,9 @@
                 type = 't'
             elif arg == "BOOLEAN":
                 type = 'b'
-            print "\"<arg type='%s'/>\\n\""%type
+            print "\"      <arg type='%s'/>\\n\""%type
 
-    print "\"</signal>\\n\""
+    print "\"    </signal>\\n\""
 
 print ";"
 
--- a/libpurple/dbus-server.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/dbus-server.c	Sun Jan 09 04:54:17 2011 +0000
@@ -501,7 +501,9 @@
 
 	g_string_append(str, "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n");
 	g_string_append_printf(str, "<node name='%s'>\n", DBUS_PATH_PURPLE);
-	g_string_append_printf(str, "<interface name='%s'>\n", DBUS_INTERFACE_PURPLE);
+	g_string_append(str, "  <interface name='org.freedesktop.DBus.Introspectable'>\n    <method name='Introspect'>\n      <arg name='data' direction='out' type='s'/>\n    </method>\n  </interface>\n\n");
+
+	g_string_append_printf(str, "  <interface name='%s'>\n", DBUS_INTERFACE_PURPLE);
 
 	bindings_list = NULL;
 	purple_signal_emit(purple_dbus_get_handle(), "dbus-introspect", &bindings_list);
@@ -517,7 +519,7 @@
 		{
 			const char *text;
 
-			g_string_append_printf(str, "<method name='%s'>\n", bindings[i].name);
+			g_string_append_printf(str, "    <method name='%s'>\n", bindings[i].name);
 
 			text = bindings[i].parameters;
 			while (*text)
@@ -529,10 +531,10 @@
 				name = dbus_gettext(&text);
 
 				g_string_append_printf(str,
-						"<arg name='%s' type='%s' direction='%s'/>\n",
+						"      <arg name='%s' type='%s' direction='%s'/>\n",
 						name, type, direction);
 			}
-			g_string_append(str, "</method>\n");
+			g_string_append(str, "    </method>\n");
 		}
 	}
 
@@ -549,7 +551,7 @@
 	}
 	g_string_append(str, signals);
 
-	g_string_append(str, "</interface>\n</node>\n");
+	g_string_append(str, "  </interface>\n</node>\n");
 
 	reply = dbus_message_new_method_return(message);
 	dbus_message_append_args(reply, DBUS_TYPE_STRING, &(str->str),
@@ -568,10 +570,8 @@
 			"dbus-method-called", connection, message))
 		return DBUS_HANDLER_RESULT_HANDLED;
 
-	if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
-			dbus_message_has_path(message, DBUS_PATH_PURPLE) &&
-			dbus_message_has_interface(message, DBUS_INTERFACE_INTROSPECTABLE) &&
-			dbus_message_has_member(message, "Introspect"))
+	if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect") &&
+			dbus_message_has_path(message, DBUS_PATH_PURPLE))
 	{
 		DBusMessage *reply;
 		reply = purple_dbus_introspect(message);
--- a/libpurple/media/backend-fs2.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/media/backend-fs2.c	Sun Jan 09 04:54:17 2011 +0000
@@ -126,6 +126,8 @@
 	GstElement *src;
 	GstElement *tee;
 
+	GstPad *srcpad;
+
 	PurpleMediaSessionType type;
 };
 
@@ -168,6 +170,22 @@
 		pipeline = purple_media_manager_get_pipeline(
 				purple_media_get_manager(priv->media));
 
+		/* All connections to media sources should be blocked before confbin is
+		 * removed, to prevent freezing of any other simultaneously running
+		 * media calls. */
+		if (priv->sessions) {
+			GList *sessions = g_hash_table_get_values(priv->sessions);
+			for (; sessions; sessions =
+					g_list_delete_link(sessions, sessions)) {
+				PurpleMediaBackendFs2Session *session = sessions->data;
+				if (session->srcpad) {
+					gst_pad_set_blocked(session->srcpad, TRUE);
+					gst_object_unref(session->srcpad);
+					session->srcpad = NULL;
+				}
+			}
+		}
+
 		gst_element_set_locked_state(priv->confbin, TRUE);
 		gst_element_set_state(GST_ELEMENT(priv->confbin),
 				GST_STATE_NULL);
@@ -1258,6 +1276,7 @@
 			session_type_to_fs_stream_direction(type);
 	GstElement *src;
 	GstPad *sinkpad, *srcpad;
+	GstPad *ghost = NULL;
 
 	if ((type_direction & FS_DIRECTION_SEND) == 0)
 		return TRUE;
@@ -1297,7 +1316,7 @@
 	if (GST_ELEMENT_PARENT(priv->confbin)
 			== GST_ELEMENT_PARENT(session->src)) {
 		GstPad *pad = gst_element_get_static_pad(session->tee, "sink");
-		GstPad *ghost = gst_ghost_pad_new(NULL, pad);
+		ghost = gst_ghost_pad_new(NULL, pad);
 		gst_object_unref(pad);
 		gst_pad_set_active(ghost, TRUE);
 		gst_element_add_pad(priv->confbin, ghost);
@@ -1305,6 +1324,8 @@
 
 	gst_element_set_state(session->tee, GST_STATE_PLAYING);
 	gst_element_link(session->src, priv->confbin);
+	if (ghost)
+		session->srcpad = gst_pad_get_peer(ghost);
 
 	g_object_get(session->session, "sink-pad", &sinkpad, NULL);
 	if (session->type & PURPLE_MEDIA_SEND_AUDIO) {
--- a/libpurple/mediamanager.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/mediamanager.c	Sun Jan 09 04:54:17 2011 +0000
@@ -81,6 +81,7 @@
 	GList *output_windows;
 	gulong next_output_window_id;
 	GType backend_type;
+	GstCaps *video_caps;
 
 	PurpleMediaElementInfo *video_src;
 	PurpleMediaElementInfo *video_sink;
@@ -191,6 +192,8 @@
 			g_list_delete_link(priv->elements, priv->elements)) {
 		g_object_unref(priv->elements->data);
 	}
+	if (priv->video_caps)
+		gst_caps_unref(priv->video_caps);
 	parent_class->finalize(media);
 }
 #endif
@@ -397,6 +400,8 @@
 	GstIteratorResult result;
 
 	gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad);
+	gst_pad_set_blocked(pad, FALSE);
+
 	iter = gst_element_iterate_src_pads(parent);
 
 	result = gst_iterator_next(iter, (gpointer)&remaining_pad);
@@ -414,6 +419,20 @@
 #endif
 
 #ifdef USE_GSTREAMER
+
+static GstCaps *
+purple_media_manager_get_video_caps(PurpleMediaManager *manager)
+{
+#ifdef USE_VV
+	if (manager->priv->video_caps == NULL)
+		manager->priv->video_caps = gst_caps_from_string("video/x-raw-yuv,"
+			"width=[250,352], height=[200,288], framerate=[1/1,20/1]");
+	return manager->priv->video_caps;
+#else
+	return NULL;
+#endif
+}
+
 GstElement *
 purple_media_manager_get_element(PurpleMediaManager *manager,
 		PurpleMediaSessionType type, PurpleMedia *media,
@@ -456,7 +475,21 @@
 			bin = gst_bin_new(id);
 			tee = gst_element_factory_make("tee", "tee");
 			gst_bin_add_many(GST_BIN(bin), ret, tee, NULL);
-			gst_element_link(ret, tee);
+
+			if (type & PURPLE_MEDIA_SEND_VIDEO) {
+				GstElement *videoscale;
+				GstElement *capsfilter;
+
+				videoscale = gst_element_factory_make("videoscale", NULL);
+				capsfilter = gst_element_factory_make("capsfilter", "prpl_video_caps");
+
+				g_object_set(G_OBJECT(capsfilter),
+					"caps", purple_media_manager_get_video_caps(manager), NULL);
+
+				gst_bin_add_many(GST_BIN(bin), videoscale, capsfilter, NULL);
+				gst_element_link_many(ret, videoscale, capsfilter, tee, NULL);
+			} else
+				gst_element_link(ret, tee);
 
 			/*
 			 * This shouldn't be necessary, but it stops it from
--- a/libpurple/plugins/perl/common/Makefile.PL.in	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/plugins/perl/common/Makefile.PL.in	Sun Jan 09 04:54:17 2011 +0000
@@ -10,6 +10,7 @@
       (ABSTRACT_FROM    => '@srcdir@/Purple.pm', # finds $ABSTRACT
        AUTHOR           => 'Purple <http://pidgin.im/>') : ()),
     'DEFINE'            => '@DEBUG_CFLAGS@',
+    'dynamic_lib'       => { 'OTHERLDFLAGS' => '@LDFLAGS@' },
     'INC'               => '-I. -I@srcdir@ -I@top_srcdir@ -I@top_srcdir@/libpurple @GLIB_CFLAGS@',
     'OBJECT'            => '$(O_FILES)', # link all the C files too
 #    'OPTIMIZE'          => '-g', # For debugging
--- a/libpurple/protocols/jabber/jingle/content.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/protocols/jabber/jingle/content.c	Sun Jan 09 04:54:17 2011 +0000
@@ -384,6 +384,8 @@
 	const gchar *name = xmlnode_get_attrib(content, "name");
 	JingleTransport *transport =
 			jingle_transport_parse(xmlnode_get_child(content, "transport"));
+	if (transport == NULL)
+		return NULL;
 
 	if (senders == NULL)
 		senders = "both";
--- a/libpurple/protocols/jabber/jingle/jingle.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/protocols/jabber/jingle/jingle.c	Sun Jan 09 04:54:17 2011 +0000
@@ -42,6 +42,9 @@
 GType
 jingle_get_type(const gchar *type)
 {
+	if (type == NULL)
+		return G_TYPE_NONE;
+
 	if (!strcmp(type, JINGLE_TRANSPORT_RAWUDP))
 		return JINGLE_TYPE_RAWUDP;
 	else if (!strcmp(type, JINGLE_TRANSPORT_ICEUDP))
--- a/libpurple/protocols/jabber/jingle/transport.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/libpurple/protocols/jabber/jingle/transport.c	Sun Jan 09 04:54:17 2011 +0000
@@ -159,8 +159,12 @@
 JingleTransport *
 jingle_transport_parse(xmlnode *transport)
 {
-	const gchar *type = xmlnode_get_namespace(transport);
-	return JINGLE_TRANSPORT_CLASS(g_type_class_ref(jingle_get_type(type)))->parse(transport);
+	const gchar *type_name = xmlnode_get_namespace(transport);
+	GType type = jingle_get_type(type_name);
+	if (type == G_TYPE_NONE)
+		return NULL;
+	
+	return JINGLE_TRANSPORT_CLASS(g_type_class_ref(type))->parse(transport);
 }
 
 xmlnode *
--- a/pidgin/gtkimhtml.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/pidgin/gtkimhtml.c	Sun Jan 09 04:54:17 2011 +0000
@@ -99,6 +99,18 @@
 	gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu);
 } GtkIMHtmlProtocol;
 
+typedef struct _GtkIMHtmlFontDetail {
+	gushort size;
+	gchar *face;
+	gchar *fore;
+	gchar *back;
+	gchar *bg;
+	gchar *sml;
+	gboolean underline;
+	gboolean strike;
+	gshort bold;
+} GtkIMHtmlFontDetail;
+
 static gboolean
 gtk_text_view_drag_motion (GtkWidget        *widget,
                            GdkDragContext   *context,
@@ -3191,6 +3203,19 @@
 						    gtk_imhtml_toggle_underline(imhtml);
 						    font->underline = 1;
 						}
+
+						if (oldfont)
+						{
+						    font->strike = oldfont->strike;
+						}
+						if (textdec && font->strike != 1
+							&& g_ascii_strcasecmp(textdec, "line-through") == 0
+							&& (imhtml->format_functions & GTK_IMHTML_STRIKE)
+							&& !(options & GTK_IMHTML_NO_FORMATTING))
+						{
+						    gtk_imhtml_toggle_strike(imhtml);
+						    font->strike = 1;
+						}
 						g_free(textdec);
 
 						if (oldfont)
@@ -3243,6 +3268,8 @@
 							gtk_imhtml_font_set_size(imhtml, 3);
 							if (font->underline && !(options & GTK_IMHTML_NO_FORMATTING))
 							    gtk_imhtml_toggle_underline(imhtml);
+							if (font->strike && !(options & GTK_IMHTML_NO_FORMATTING))
+							    gtk_imhtml_toggle_strike(imhtml);
 							if (font->bold && !(options & GTK_IMHTML_NO_FORMATTING))
 								gtk_imhtml_toggle_bold(imhtml);
 							if (!(options & GTK_IMHTML_NO_FONTS))
@@ -3255,14 +3282,17 @@
 						else
 						{
 
-						    if ((font->size != oldfont->size) && !(options & GTK_IMHTML_NO_SIZES))
+							if ((font->size != oldfont->size) && !(options & GTK_IMHTML_NO_SIZES))
 							    gtk_imhtml_font_set_size(imhtml, oldfont->size);
 
 							if ((font->underline != oldfont->underline) && !(options & GTK_IMHTML_NO_FORMATTING))
 							    gtk_imhtml_toggle_underline(imhtml);
 
+							if ((font->strike != oldfont->strike) && !(options & GTK_IMHTML_NO_FORMATTING))
+							    gtk_imhtml_toggle_strike(imhtml);
+
 							if (((font->bold && !oldfont->bold) || (oldfont->bold && !font->bold)) && !(options & GTK_IMHTML_NO_FORMATTING))
-								gtk_imhtml_toggle_bold(imhtml);
+							    gtk_imhtml_toggle_bold(imhtml);
 
 							if (font->face && (!oldfont->face || strcmp(font->face, oldfont->face) != 0) && !(options & GTK_IMHTML_NO_FONTS))
 							    gtk_imhtml_toggle_fontface(imhtml, oldfont->face);
@@ -3271,7 +3301,7 @@
 							    gtk_imhtml_toggle_forecolor(imhtml, oldfont->fore);
 
 							if (font->back && (!oldfont->back || strcmp(font->back, oldfont->back) != 0) && !(options & GTK_IMHTML_NO_COLOURS))
-						      gtk_imhtml_toggle_backcolor(imhtml, oldfont->back);
+							    gtk_imhtml_toggle_backcolor(imhtml, oldfont->back);
 						}
 
 						g_free (font->face);
--- a/pidgin/gtkimhtml.h	Thu Jan 06 05:52:19 2011 +0000
+++ b/pidgin/gtkimhtml.h	Sun Jan 09 04:54:17 2011 +0000
@@ -50,7 +50,9 @@
 
 typedef struct _GtkIMHtml			GtkIMHtml;
 typedef struct _GtkIMHtmlClass		GtkIMHtmlClass;
+#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_)
 typedef struct _GtkIMHtmlFontDetail	GtkIMHtmlFontDetail;	/* The five elements contained in a FONT tag */
+#endif
 typedef struct _GtkSmileyTree		GtkSmileyTree;
 typedef struct _GtkIMHtmlSmiley		GtkIMHtmlSmiley;
 typedef struct _GtkIMHtmlScalable	GtkIMHtmlScalable;
@@ -162,6 +164,8 @@
 	GList *protocols; /* List of GtkIMHtmlProtocol's */
 };
 
+#if !(defined PIDGIN_DISABLE_DEPRECATED) && !(defined _PIDGIN_GTKIMHTML_C_)
+/** @deprecated as of 2.7.10 */
 struct _GtkIMHtmlFontDetail {
 	gushort size;
 	gchar *face;
@@ -172,6 +176,7 @@
 	gboolean underline;
 	gshort bold;
 };
+#endif
 
 struct _GtkSmileyTree {
 	GString *values;
--- a/pidgin/gtkimhtmltoolbar.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Sun Jan 09 04:54:17 2011 +0000
@@ -1251,7 +1251,7 @@
 	for (iter = 0; buttons[iter].stock; iter++) {
 		if (buttons[iter].stock[0]) {
 			button = pidgin_pixbuf_toolbar_button_from_stock(buttons[iter].stock);
-			g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(button_activate_on_click), toolbar);
+			g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(gtk_imhtmltoolbar_popup_menu), toolbar);
 			g_signal_connect(G_OBJECT(button), "clicked",
 					 G_CALLBACK(buttons[iter].callback), toolbar);
 			*(buttons[iter].button) = button;
@@ -1262,7 +1262,7 @@
 	}
 	/* create the attention button (this is a bit hacky to not break ABI) */
 	button = pidgin_pixbuf_toolbar_button_from_stock(PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION);
-	g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(button_activate_on_click), toolbar);
+	g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(gtk_imhtmltoolbar_popup_menu), toolbar);
 	g_signal_connect(G_OBJECT(button), "clicked",
 		G_CALLBACK(send_attention_cb), toolbar);
 	g_object_set_data(G_OBJECT(toolbar), "attention", button);
@@ -1471,7 +1471,7 @@
 	label = gtk_label_new_with_mnemonic(_("_Smile!"));
 	gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
 	gtk_box_pack_start(GTK_BOX(box), smiley_button, FALSE, FALSE, 0);
-	g_signal_connect(G_OBJECT(smiley_button), "button-press-event", G_CALLBACK(button_activate_on_click), toolbar);
+	g_signal_connect(G_OBJECT(smiley_button), "button-press-event", G_CALLBACK(gtk_imhtmltoolbar_popup_menu), toolbar);
 	g_signal_connect_swapped(G_OBJECT(smiley_button), "clicked", G_CALLBACK(gtk_button_clicked), toolbar->smiley);
 	gtk_widget_show_all(smiley_button);
 
--- a/pidgin/gtkmedia.c	Thu Jan 06 05:52:19 2011 +0000
+++ b/pidgin/gtkmedia.c	Sun Jan 09 04:54:17 2011 +0000
@@ -932,10 +932,9 @@
 create_default_video_src(PurpleMedia *media,
 		const gchar *session_id, const gchar *participant)
 {
-	GstElement *sendbin, *src, *videoscale, *capsfilter;
+	GstElement *sendbin, *src;
 	GstPad *pad;
 	GstPad *ghost;
-	GstCaps *caps;
 
 #ifdef _WIN32
 	/* autovideosrc doesn't pick ksvideosrc for some reason */
@@ -960,19 +959,10 @@
 	}
 
 	sendbin = gst_bin_new("pidgindefaultvideosrc");
-	videoscale = gst_element_factory_make("videoscale", NULL);
-	capsfilter = gst_element_factory_make("capsfilter", NULL);
 
-	/* It was recommended to set the size <= 352x288 and framerate <= 20 */
-	caps = gst_caps_from_string("video/x-raw-yuv , width=[250,352] , "
-			"height=[200,288] , framerate=[1/1,20/1]");
-	g_object_set(G_OBJECT(capsfilter), "caps", caps, NULL);
+	gst_bin_add(GST_BIN(sendbin), src);
 
-	gst_bin_add_many(GST_BIN(sendbin), src,
-			videoscale, capsfilter, NULL);
-	gst_element_link_many(src, videoscale, capsfilter, NULL);
-
-	pad = gst_element_get_static_pad(capsfilter, "src");
+	pad = gst_element_get_static_pad(src, "src");
 	ghost = gst_ghost_pad_new("ghostsrc", pad);
 	gst_object_unref(pad);
 	gst_element_add_pad(sendbin, ghost);
--- a/pidgin/plugins/perl/common/Makefile.PL.in	Thu Jan 06 05:52:19 2011 +0000
+++ b/pidgin/plugins/perl/common/Makefile.PL.in	Sun Jan 09 04:54:17 2011 +0000
@@ -9,6 +9,7 @@
       ('ABSTRACT_FROM' => '@srcdir@/Pidgin.pm', # finds $ABSTRACT
        'AUTHOR'        => 'Pidgin <http://pidgin.im/>') :  ()),
     'DEFINE'        => '@DEBUG_CFLAGS@',
+    'dynamic_lib'       => { 'OTHERLDFLAGS' => '@LDFLAGS@' },
     'INC'           => '-I. -I@srcdir@ -I@top_srcdir@ -I@top_srcdir@/libpurple -I@top_srcdir@/pidgin @GTK_CFLAGS@',
     'OBJECT'        => '$(O_FILES)', # link all the C files too
     'TYPEMAPS'      => ["@top_srcdir@/libpurple/plugins/perl/common/typemap"],