gtk/pidgin/libpurple-gst1.patch
2014-10-24 15:55:16 +00:00

2219 lines
74 KiB
Diff

diff --git a/configure.ac b/configure.ac
index 7575d49..e132f9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,8 +114,11 @@ AC_DISABLE_STATIC
AC_PROG_LIBTOOL
LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
+AC_PROG_INTLTOOL
PKG_PROG_PKG_CONFIG
AC_FUNC_ALLOCA
+GETTEXT_PACKAGE=pidgin
+AC_SUBST(GETTEXT_PACKAGE)
dnl Check for Sun compiler
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
@@ -300,9 +303,9 @@ dnl #######################################################################
AC_ARG_ENABLE(nls, AC_HELP_STRING([--disable-nls], [disable installation of translation files]), enable_i18n="$enableval", enable_i18n=yes)
if test x$enable_i18n = xyes; then
- AC_PROG_INTLTOOL
- GETTEXT_PACKAGE=pidgin
- AC_SUBST(GETTEXT_PACKAGE)
+dnl AC_PROG_INTLTOOL
+dnl GETTEXT_PACKAGE=pidgin
+dnl AC_SUBST(GETTEXT_PACKAGE)
ALL_LINGUAS="af am ar ast az be@latin bg bn bn_IN bs ca ca@valencia cs da de dz el en_AU en_CA en_GB eo es et eu fa fi fr ga gl gu he hi hr hu hy id it ja ka km kn ko ku lo lt mai mhr mk mn mr ms_MY my_MM nb ne nl nn oc or pa pl pt_BR pt ps ro ru si sk sl sq sr sr@latin sv sw ta te th tr uk ur vi xh zh_CN zh_HK zh_TW"
AM_GLIB_GNU_GETTEXT
@@ -739,42 +742,102 @@ AM_GCONF_SOURCE_2
dnl #######################################################################
dnl # Check for GStreamer
dnl #######################################################################
-dnl
-dnl TODO: Depend on gstreamer >= 0.10.10, and remove the conditional use of
-dnl gst_registry_fork_set_enabled.
AC_ARG_ENABLE(gstreamer,
[AC_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])],
enable_gst="$enableval", enable_gst="yes")
+AC_ARG_WITH(gstreamer, [AC_HELP_STRING([--with-gstreamer=<version>],
+ [compile with GStreamer 0.10 or 1.0 interface (default: auto)])],
+ with_gstreamer="$withval", with_gstreamer="auto")
if test "x$enable_gst" != "xno"; then
- PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
- AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
- AC_SUBST(GSTREAMER_CFLAGS)
- AC_SUBST(GSTREAMER_LIBS)
- AC_CHECK_LIB(gstreamer-0.10, gst_registry_fork_set_enabled,
- [ AC_DEFINE(GST_CAN_DISABLE_FORKING, [],
- [Define if gst_registry_fork_set_enabled exists])],
- [], [$GSTREAMER_LIBS])
- ], [
- AC_MSG_RESULT(no)
- enable_gst="no"
- if test "x$force_deps" = "xyes" ; then
- AC_MSG_ERROR([
+ if test "x$with_gstreamer" == "xauto"; then
+ PKG_CHECK_MODULES(GSTREAMER, [gstreamer-1.0], [
+ AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
+ with_gstreamer="1.0"
+ AC_SUBST(GSTREAMER_CFLAGS)
+ AC_SUBST(GSTREAMER_LIBS)
+ dnl Check whether forking stuff is required for this version.
+ ], [
+ PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
+ AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
+ with_gstreamer="0.10"
+ AC_SUBST(GSTREAMER_CFLAGS)
+ AC_SUBST(GSTREAMER_LIBS)
+ ], [
+ AC_MSG_RESULT(no)
+ enable_gst="no"
+ if test "x$force_deps" = "xyes" ; then
+ AC_MSG_ERROR([
GStreamer development headers not found.
Use --disable-gstreamer if you do not need GStreamer (sound) support.
])
- fi])
+ fi
+ ])
+ ])
+ elif test "x$with_gstreamer" == "x1.0"; then
+ PKG_CHECK_MODULES(GSTREAMER, [gstreamer-1.0], [
+ AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer 1.0 for playing sounds])
+ AC_SUBST(GSTREAMER_CFLAGS)
+ AC_SUBST(GSTREAMER_LIBS)
+ ], [
+ AC_MSG_RESULT(no)
+ enable_gst="no"
+ if test "x$force_deps" = "xyes" ; then
+ AC_MSG_ERROR([
+GStreamer development headers not found.
+Use --disable-gstreamer if you do not need GStreamer (sound) support.
+])
+ fi
+ ])
+ elif test "x$with_gstreamer" == "x0.10"; then
+ PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
+ AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer 0.10 for playing sounds])
+ AC_SUBST(GSTREAMER_CFLAGS)
+ AC_SUBST(GSTREAMER_LIBS)
+ ], [
+ AC_MSG_RESULT(no)
+ enable_gst="no"
+ if test "x$force_deps" = "xyes" ; then
+ AC_MSG_ERROR([
+GStreamer development headers not found.
+Use --disable-gstreamer if you do not need GStreamer (sound) support.
+])
+ fi
+ ])
+ else
+ AC_MSG_ERROR([--with-gstreamer must specify one of 0.10, 1.0 or auto.])
+ fi
+fi
+
+dnl #######################################################################
+dnl # Check for GStreamer Video
+dnl #######################################################################
+if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x1.0"; then
+ AC_ARG_ENABLE(gstreamer-video,
+ [AC_HELP_STRING([--disable-gstreamer-video], [compile without GStreamer 1.0 Video Overlay support])],
+ enable_gstvideo="$enableval", enable_gstvideo="yes")
+ if test "x$enable_gstvideo" != "xno"; then
+ PKG_CHECK_MODULES(GSTVIDEO, [gstreamer-video-1.0], [
+ AC_DEFINE(USE_GSTVIDEO, 1, [Use GStreamer Video Overlay support])
+ AC_SUBST(GSTVIDEO_CFLAGS)
+ AC_SUBST(GSTVIDEO_LIBS)
+ ], [
+ enable_gstvideo="no"
+ ])
+ fi
+else
+ enable_gstvideo="no"
fi
dnl #######################################################################
dnl # Check for GStreamer Interfaces
dnl #######################################################################
-if test "x$enable_gst" != "xno"; then
+if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x0.10"; then
AC_ARG_ENABLE(gstreamer-interfaces,
- [AC_HELP_STRING([--disable-gstreamer-interfaces], [compile without GStreamer interface support])],
+ [AC_HELP_STRING([--disable-gstreamer-interfaces], [compile without GStreamer 0.10 interface support])],
enable_gstinterfaces="$enableval", enable_gstinterfaces="yes")
if test "x$enable_gstinterfaces" != "xno"; then
PKG_CHECK_MODULES(GSTINTERFACES, [gstreamer-interfaces-0.10], [
- AC_DEFINE(USE_GSTINTERFACES, 1, [Use GStreamer interfaces for X overlay support])
+ AC_DEFINE(USE_GSTINTERFACES, 1, [Use GStreamer 0.10 interfaces for X overlay support])
AC_SUBST(GSTINTERFACES_CFLAGS)
AC_SUBST(GSTINTERFACES_LIBS)
], [
@@ -792,20 +855,29 @@ AC_ARG_ENABLE(farstream,
[AC_HELP_STRING([--disable-farstream], [compile without farstream support])],
enable_farstream="$enableval", enable_farstream="yes")
if test "x$enable_farstream" != "xno"; then
- PKG_CHECK_MODULES(FARSTREAM, [farstream-0.1], [
- AC_SUBST(FARSTREAM_CFLAGS)
- AC_SUBST(FARSTREAM_LIBS)
- ], [
- # Try farsight.
- PKG_CHECK_MODULES(FARSTREAM, [farsight2-0.10 >= 0.0.9], [
- AC_DEFINE(HAVE_FARSIGHT, 1, [Use Farsight instead of Farstream])
+ if test "x$with_gstreamer" == "x1.0"; then
+ PKG_CHECK_MODULES(FARSTREAM, [farstream-0.2], [
AC_SUBST(FARSTREAM_CFLAGS)
AC_SUBST(FARSTREAM_LIBS)
- ], [
+ ], [
enable_farstream="no"
])
- ])
- fi
+ else
+ PKG_CHECK_MODULES(FARSTREAM, [farstream-0.1], [
+ AC_SUBST(FARSTREAM_CFLAGS)
+ AC_SUBST(FARSTREAM_LIBS)
+ ], [
+ # Try farsight.
+ PKG_CHECK_MODULES(FARSTREAM, [farsight2-0.10 >= 0.0.9], [
+ AC_DEFINE(HAVE_FARSIGHT, 1, [Use Farsight instead of Farstream])
+ AC_SUBST(FARSTREAM_CFLAGS)
+ AC_SUBST(FARSTREAM_LIBS)
+ ], [
+ enable_farstream="no"
+ ])
+ ])
+ fi
+fi
dnl #######################################################################
dnl # Check for Voice and Video support
@@ -814,7 +886,9 @@ AC_ARG_ENABLE(vv,
[AC_HELP_STRING([--disable-vv], [compile without voice and video support])],
enable_vv="$enableval", enable_vv="yes")
if test "x$enable_vv" != "xno"; then
- if test "x$enable_gstreamer" != "xno" -a "x$enable_gstinterfaces" != "xno" -a "x$enable_farstream" != "xno"; then
+ if test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x1.0" -a "x$enable_gstvideo" != "xno" -a "x$enable_farstream" != "xno"; then
+ AC_DEFINE(USE_VV, 1, [Use voice and video])
+ elif test "x$enable_gst" != "xno" -a "x$with_gstreamer" == "x0.10" -a "x$enable_gstinterfaces" != "xno" -a "x$enable_farstream" != "xno"; then
AC_DEFINE(USE_VV, 1, [Use voice and video])
else
enable_vv="no"
@@ -827,7 +901,7 @@ Or use --disable-vv if you do not need voice/video support.
fi
fi
fi
-AM_CONDITIONAL(USE_VV, test "x$enable_gstreamer" != "xno" -a "x$enable_gstinterfaces" != "xno" -a "x$enable_farstream" != "xno")
+AM_CONDITIONAL(USE_VV, test "x$enable_vv" != "xno")
dnl #######################################################################
dnl # Check for Internationalized Domain Name support
@@ -2642,6 +2716,7 @@ echo Protocols to build dynamically : $DYNAMIC_PRPLS
echo Protocols to link statically.. : $STATIC_PRPLS
echo
echo Build with GStreamer support.. : $enable_gst
+echo Build for GStreamer version... : $with_gstreamer
echo Build with D-Bus support...... : $enable_dbus
echo Build with voice and video.... : $enable_vv
if test "x$enable_dbus" = "xyes" ; then
diff --git a/doc/pidgin.1.in b/doc/pidgin.1.in
index 5edbc78..ac696b1 100644
--- a/doc/pidgin.1.in
+++ b/doc/pidgin.1.in
@@ -1,4 +1,4 @@
-Ri.\" Copyright (c) 2000, Dennis Ristuccia <dennis@dennisr.net>
+.\" Copyright (c) 2000, Dennis Ristuccia <dennis@dennisr.net>
.\"
.\" This is free documentation; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
diff --git a/finch/gntsound.c b/finch/gntsound.c
index 296fee1..935d450 100644
--- a/finch/gntsound.c
+++ b/finch/gntsound.c
@@ -553,7 +553,11 @@ finch_sound_play_file(const char *filename)
return;
}
+#if GST_CHECK_VERSION(1,0,0)
play = gst_element_factory_make("playbin", "play");
+#else
+ play = gst_element_factory_make("playbin2", "play");
+#endif
if (play == NULL) {
return;
diff --git a/finch/libgnt/wms/Makefile.am b/finch/libgnt/wms/Makefile.am
index b72069a..65b9383 100644
--- a/finch/libgnt/wms/Makefile.am
+++ b/finch/libgnt/wms/Makefile.am
@@ -23,8 +23,7 @@ irssi_la_LIBADD = \
s_la_SOURCES = s.c
s_la_LIBADD = \
$(GLIB_LIBS) \
- ../libgnt.la \
- $(top_builddir)/libpurple/libpurple.la
+ ../libgnt.la
EXTRA_DIST =
diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
index 1447d5c..c9397a6 100644
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -308,6 +308,7 @@ libpurple_la_LIBADD = \
$(INTLLIBS) \
$(FARSTREAM_LIBS) \
$(GSTREAMER_LIBS) \
+ $(GSTVIDEO_LIBS) \
$(GSTINTERFACES_LIBS) \
$(IDN_LIBS) \
ciphers/libpurple-ciphers.la \
@@ -324,6 +325,7 @@ AM_CPPFLAGS = \
$(LIBXML_CFLAGS) \
$(FARSTREAM_CFLAGS) \
$(GSTREAMER_CFLAGS) \
+ $(GSTVIDEO_CFLAGS) \
$(GSTINTERFACES_CFLAGS) \
$(IDN_CFLAGS) \
$(NETWORKMANAGER_CFLAGS)
diff --git a/libpurple/connection.c b/libpurple/connection.c
index 9e0055f..fdf1c64 100644
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -42,6 +42,10 @@
#define KEEPALIVE_INTERVAL 30
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
static GList *connections = NULL;
static GList *connections_connecting = NULL;
static PurpleConnectionUiOps *connection_ui_ops = NULL;
@@ -154,6 +158,9 @@ _purple_connection_new(PurpleAccount *account, gboolean regist, const char *pass
purple_signal_emit(purple_connections_get_handle(), "signing-on", gc);
+ /* Re-read resolv.conf and friends in case DNS servers have changed */
+ res_init();
+
if (regist)
{
purple_debug_info("connection", "Registering. gc = %p\n", gc);
diff --git a/libpurple/core.c b/libpurple/core.c
index c07fc35..1dcdf54 100644
--- a/libpurple/core.c
+++ b/libpurple/core.c
@@ -407,8 +407,8 @@ gboolean
purple_core_migrate(void)
{
const char *user_dir = purple_user_dir();
- char *old_user_dir = g_strconcat(purple_home_dir(),
- G_DIR_SEPARATOR_S ".gaim", NULL);
+ char *old_user_dir = g_strconcat(g_get_home_dir(),
+ G_DIR_SEPARATOR_S ".purple", NULL);
char *status_file;
FILE *fp;
GDir *dir;
@@ -421,9 +421,13 @@ purple_core_migrate(void)
if (!g_file_test(old_user_dir, G_FILE_TEST_EXISTS))
{
- /* ~/.gaim doesn't exist, so there's nothing to migrate. */
- g_free(old_user_dir);
- return TRUE;
+ old_user_dir = g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S ".gaim", NULL);
+ if (!g_file_test(old_user_dir, G_FILE_TEST_EXISTS))
+ {
+ /* ~/.gaim doesn't exist, so there's nothing to migrate. */
+ g_free(old_user_dir);
+ return TRUE;
+ }
}
status_file = g_strconcat(user_dir, G_DIR_SEPARATOR_S "migrating", NULL);
@@ -514,8 +518,7 @@ purple_core_migrate(void)
logs_dir = g_build_filename(user_dir, "logs", NULL);
- if (purple_strequal(link, "../.purple/logs") ||
- purple_strequal(link, logs_dir))
+ if (purple_strequal(link, logs_dir))
{
/* If the symlink points to the new directory, we're
* likely just trying again after a failed migration,
@@ -612,7 +615,8 @@ purple_core_migrate(void)
if (g_file_test(icons_name, G_FILE_TEST_IS_DIR))
{
if (!move_and_symlink_dir(icons_name, icons_entry,
- name, new_icons_dir, "../../.purple/icons"))
+ name, new_icons_dir,
+ g_strconcat(user_dir, G_DIR_SEPARATOR_S "icons", NULL)))
{
g_free(icons_name);
g_free(new_icons_dir);
@@ -637,7 +641,7 @@ purple_core_migrate(void)
else
{
/* All other directories are moved and symlinked. */
- if (!move_and_symlink_dir(name, entry, old_user_dir, user_dir, "../.purple"))
+ if (!move_and_symlink_dir(name, entry, old_user_dir, user_dir, user_dir))
{
g_free(name);
g_dir_close(dir);
diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
index 2195de6..1489463 100644
--- a/libpurple/media/backend-fs2.c
+++ b/libpurple/media/backend-fs2.c
@@ -179,9 +179,10 @@ static void
purple_media_backend_fs2_init(PurpleMediaBackendFs2 *self)
{}
-static gboolean
-event_probe_cb(GstPad *srcpad, GstEvent *event, gboolean release_pad)
+static GstPadProbeReturn
+event_probe_cb(GstPad *srcpad, GstPadProbeInfo *info, gpointer unused)
{
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
if (GST_EVENT_TYPE(event) == GST_EVENT_CUSTOM_DOWNSTREAM
&& gst_event_has_name(event, "purple-unlink-tee")) {
@@ -189,22 +190,23 @@ event_probe_cb(GstPad *srcpad, GstEvent *event, gboolean release_pad)
gst_pad_unlink(srcpad, gst_pad_get_peer(srcpad));
- gst_pad_remove_event_probe(srcpad,
+ gst_pad_remove_probe(srcpad,
g_value_get_uint(gst_structure_get_value(s, "handler-id")));
if (g_value_get_boolean(gst_structure_get_value(s, "release-pad")))
gst_element_release_request_pad(GST_ELEMENT_PARENT(srcpad), srcpad);
- return FALSE;
+ return GST_PAD_PROBE_DROP;
}
- return TRUE;
+ return GST_PAD_PROBE_OK;
}
static void
unlink_teepad_dynamic(GstPad *srcpad, gboolean release_pad)
{
- guint id = gst_pad_add_event_probe(srcpad, G_CALLBACK(event_probe_cb), NULL);
+ guint id = gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+ event_probe_cb, NULL, NULL);
if (GST_IS_GHOST_PAD(srcpad))
srcpad = gst_ghost_pad_get_target(GST_GHOST_PAD(srcpad));
@@ -793,9 +795,12 @@ gst_msg_db_to_percent(GstMessage *msg, gchar *value_name)
gdouble value_db;
gdouble percent;
- list = gst_structure_get_value(
- gst_message_get_structure(msg), value_name);
+ list = gst_structure_get_value(gst_message_get_structure(msg), value_name);
+#if GST_CHECK_VERSION(1,0,0)
+ value = g_value_array_get_nth(g_value_get_boxed(list), 0);
+#else
value = gst_value_list_get_value(list, 0);
+#endif
value_db = g_value_get_double(value);
percent = pow(10, value_db / 20);
return (percent > 1.0) ? 1.0 : percent;
@@ -809,11 +814,12 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
static guint level_id = 0;
+ const GstStructure *structure = gst_message_get_structure(msg);
if (level_id == 0)
level_id = g_signal_lookup("level", PURPLE_TYPE_MEDIA);
- if (gst_structure_has_name(msg->structure, "level")) {
+ if (gst_structure_has_name(structure, "level")) {
GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
gchar *name;
gchar *participant = NULL;
@@ -868,12 +874,12 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
return;
#ifdef HAVE_FARSIGHT
- if (gst_structure_has_name(msg->structure, "farsight-error")) {
+ if (gst_structure_has_name(structure, "farsight-error")) {
#else
- if (gst_structure_has_name(msg->structure, "farstream-error")) {
+ if (gst_structure_has_name(structure, "farstream-error")) {
#endif
FsError error_no;
- gst_structure_get_enum(msg->structure, "error-no",
+ gst_structure_get_enum(structure, "error-no",
FS_TYPE_ERROR, (gint*)&error_no);
switch (error_no) {
case FS_ERROR_NO_CODECS:
@@ -910,7 +916,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
#endif
error_no,
gst_structure_get_string(
- msg->structure, "error-msg"));
+ structure, "error-msg"));
break;
}
@@ -924,7 +930,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
#endif
purple_media_end(priv->media, NULL, NULL);
}
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-new-local-candidate")) {
#else
@@ -939,9 +945,9 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
PurpleMediaBackendFs2Stream *media_stream;
gchar *name;
- value = gst_structure_get_value(msg->structure, "stream");
+ value = gst_structure_get_value(structure, "stream");
stream = g_value_get_object(value);
- value = gst_structure_get_value(msg->structure, "candidate");
+ value = gst_structure_get_value(structure, "candidate");
local_candidate = g_value_get_boxed(value);
session = get_session_from_fs_stream(self, stream);
@@ -963,7 +969,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
g_signal_emit_by_name(self, "new-candidate",
session->id, name, candidate);
g_object_unref(candidate);
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-local-candidates-prepared")) {
#else
@@ -975,7 +981,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
PurpleMediaBackendFs2Session *session;
gchar *name;
- value = gst_structure_get_value(msg->structure, "stream");
+ value = gst_structure_get_value(structure, "stream");
stream = g_value_get_object(value);
session = get_session_from_fs_stream(self, stream);
@@ -985,7 +991,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
g_signal_emit_by_name(self, "candidates-prepared",
session->id, name);
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-new-active-candidate-pair")) {
#else
@@ -1000,13 +1006,11 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
PurpleMediaCandidate *lcandidate, *rcandidate;
gchar *name;
- value = gst_structure_get_value(msg->structure, "stream");
+ value = gst_structure_get_value(structure, "stream");
stream = g_value_get_object(value);
- value = gst_structure_get_value(msg->structure,
- "local-candidate");
+ value = gst_structure_get_value(structure, "local-candidate");
local_candidate = g_value_get_boxed(value);
- value = gst_structure_get_value(msg->structure,
- "remote-candidate");
+ value = gst_structure_get_value(structure, "remote-candidate");
remote_candidate = g_value_get_boxed(value);
g_object_get(stream, "participant", &participant, NULL);
@@ -1023,7 +1027,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
g_object_unref(lcandidate);
g_object_unref(rcandidate);
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-recv-codecs-changed")) {
#else
@@ -1033,7 +1037,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
GList *codecs;
FsCodec *codec;
- value = gst_structure_get_value(msg->structure, "codecs");
+ value = gst_structure_get_value(structure, "codecs");
codecs = g_value_get_boxed(value);
codec = codecs->data;
@@ -1044,7 +1048,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
"farstream-recv-codecs-changed: %s\n",
#endif
codec->encoding_name);
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-component-state-changed")) {
#else
@@ -1055,9 +1059,9 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
guint component;
const gchar *state;
- value = gst_structure_get_value(msg->structure, "state");
+ value = gst_structure_get_value(structure, "state");
fsstate = g_value_get_enum(value);
- value = gst_structure_get_value(msg->structure, "component");
+ value = gst_structure_get_value(structure, "component");
component = g_value_get_uint(value);
switch (fsstate) {
@@ -1092,7 +1096,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
#endif
"component: %u state: %s\n",
component, state);
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-send-codec-changed")) {
#else
@@ -1102,7 +1106,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
FsCodec *codec;
gchar *codec_str;
- value = gst_structure_get_value(msg->structure, "codec");
+ value = gst_structure_get_value(structure, "codec");
codec = g_value_get_boxed(value);
codec_str = fs_codec_to_string(codec);
@@ -1115,7 +1119,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
codec_str);
g_free(codec_str);
- } else if (gst_structure_has_name(msg->structure,
+ } else if (gst_structure_has_name(structure,
#ifdef HAVE_FARSIGHT
"farsight-codecs-changed")) {
#else
@@ -1125,7 +1129,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
FsSession *fssession;
GList *sessions;
- value = gst_structure_get_value(msg->structure, "session");
+ value = gst_structure_get_value(structure, "session");
fssession = g_value_get_object(value);
sessions = g_hash_table_get_values(priv->sessions);
@@ -1569,7 +1573,11 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id,
srcpad = gst_element_get_static_pad(session->srcvalve, "src");
g_object_set(volume, "volume", input_volume, NULL);
} else {
+#if GST_CHECK_VERSION(1,0,0)
+ srcpad = gst_element_get_request_pad(session->tee, "src_%u");
+#else
srcpad = gst_element_get_request_pad(session->tee, "src%d");
+#endif
}
purple_debug_info("backend-fs2", "connecting pad: %s\n",
@@ -1787,14 +1795,10 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
* audioresample ! audioconvert ! realsink
*/
stream->queue = gst_element_factory_make("queue", NULL);
- stream->volume = gst_element_factory_make(
- "volume", NULL);
- g_object_set(stream->volume, "volume",
- output_volume, NULL);
- stream->level = gst_element_factory_make(
- "level", NULL);
- stream->src = gst_element_factory_make(
- "liveadder", NULL);
+ stream->volume = gst_element_factory_make("volume", NULL);
+ g_object_set(stream->volume, "volume", output_volume, NULL);
+ stream->level = gst_element_factory_make("level", NULL);
+ stream->src = gst_element_factory_make("liveadder", NULL);
sink = purple_media_manager_get_element(
purple_media_get_manager(priv->media),
PURPLE_MEDIA_RECV_AUDIO, priv->media,
@@ -1813,10 +1817,12 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
gst_element_link(stream->queue, stream->volume);
sink = stream->queue;
} else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) {
- stream->src = gst_element_factory_make(
- "fsfunnel", NULL);
- sink = gst_element_factory_make(
- "fakesink", NULL);
+#if GST_CHECK_VERSION(1,0,0)
+ stream->src = gst_element_factory_make("funnel", NULL);
+#else
+ stream->src = gst_element_factory_make("fsfunnel", NULL);
+#endif
+ sink = gst_element_factory_make("fakesink", NULL);
g_object_set(G_OBJECT(sink), "async", FALSE, NULL);
gst_bin_add(GST_BIN(priv->confbin), sink);
gst_element_set_state(sink, GST_STATE_PLAYING);
@@ -1830,7 +1836,11 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
gst_element_link_many(stream->src, stream->tee, sink, NULL);
}
+#if GST_CHECK_VERSION(1,0,0)
+ sinkpad = gst_element_get_request_pad(stream->src, "sink_%u");
+#else
sinkpad = gst_element_get_request_pad(stream->src, "sink%d");
+#endif
gst_pad_link(srcpad, sinkpad);
gst_object_unref(sinkpad);
diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c
index 7bf2e30..ce06699 100644
--- a/libpurple/mediamanager.c
+++ b/libpurple/mediamanager.c
@@ -44,7 +44,11 @@
#else
#include <farstream/fs-element-added-notifier.h>
#endif
+#if GST_CHECK_VERSION(1,0,0)
+#include <gst/video/videooverlay.h>
+#else
#include <gst/interfaces/xoverlay.h>
+#endif
/** @copydoc _PurpleMediaManagerPrivate */
typedef struct _PurpleMediaManagerPrivate PurpleMediaManagerPrivate;
@@ -270,8 +274,11 @@ purple_media_manager_get_pipeline(PurpleMediaManager *manager)
gst_bus_add_signal_watch(GST_BUS(bus));
g_signal_connect(G_OBJECT(bus), "message",
G_CALLBACK(pipeline_bus_call), manager);
- gst_bus_set_sync_handler(bus,
- gst_bus_sync_signal_handler, NULL);
+#if GST_CHECK_VERSION(1,0,0)
+ gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL, NULL);
+#else
+ gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL);
+#endif
gst_object_unref(bus);
filename = g_build_filename(purple_user_dir(),
@@ -401,20 +408,31 @@ request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data)
{
GstElement *parent = GST_ELEMENT_PARENT(pad);
GstIterator *iter;
+#if GST_CHECK_VERSION(1,0,0)
+ GValue tmp = G_VALUE_INIT;
+#endif
GstPad *remaining_pad;
GstIteratorResult result;
- gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad);
+ gst_element_release_request_pad(parent, pad);
iter = gst_element_iterate_src_pads(parent);
+#if GST_CHECK_VERSION(1,0,0)
+ result = gst_iterator_next(iter, &tmp);
+#else
result = gst_iterator_next(iter, (gpointer)&remaining_pad);
+#endif
if (result == GST_ITERATOR_DONE) {
gst_element_set_locked_state(parent, TRUE);
gst_element_set_state(parent, GST_STATE_NULL);
gst_bin_remove(GST_BIN(GST_ELEMENT_PARENT(parent)), parent);
} else if (result == GST_ITERATOR_OK) {
+#if GST_CHECK_VERSION(1,0,0)
+ remaining_pad = g_value_get_object(&tmp);
+ g_value_reset(&tmp);
+#endif
gst_object_unref(remaining_pad);
}
@@ -452,7 +470,11 @@ purple_media_manager_get_video_caps(PurpleMediaManager *manager)
{
#ifdef USE_VV
if (manager->priv->video_caps == NULL)
+#if GST_CHECK_VERSION(1,0,0)
+ manager->priv->video_caps = gst_caps_from_string("video/x-raw,"
+#else
manager->priv->video_caps = gst_caps_from_string("video/x-raw-yuv,"
+#endif
"width=[250,352], height=[200,288], framerate=[1/1,20/1]");
return manager->priv->video_caps;
#else
@@ -535,7 +557,11 @@ purple_media_manager_get_element(PurpleMediaManager *manager,
g_free(id);
tee = gst_bin_get_by_name(GST_BIN(ret), "tee");
+#if GST_CHECK_VERSION(1,0,0)
+ pad = gst_element_get_request_pad(tee, "src_%u");
+#else
pad = gst_element_get_request_pad(tee, "src%d");
+#endif
gst_object_unref(tee);
ghost = gst_ghost_pad_new(NULL, pad);
gst_object_unref(pad);
@@ -726,9 +752,12 @@ window_id_cb(GstBus *bus, GstMessage *msg, PurpleMediaOutputWindow *ow)
{
GstElement *sink;
- if (GST_MESSAGE_TYPE(msg) != GST_MESSAGE_ELEMENT ||
- !gst_structure_has_name(msg->structure,
- "prepare-xwindow-id"))
+ if (GST_MESSAGE_TYPE(msg) != GST_MESSAGE_ELEMENT
+#if GST_CHECK_VERSION(1,0,0)
+ || !gst_is_video_overlay_prepare_window_handle_message(msg))
+#else
+ || !gst_structure_has_name(msg->structure, "prepare-xwindow-id"))
+#endif
return;
sink = GST_ELEMENT(GST_MESSAGE_SRC(msg));
@@ -742,8 +771,16 @@ window_id_cb(GstBus *bus, GstMessage *msg, PurpleMediaOutputWindow *ow)
| G_SIGNAL_MATCH_DATA, 0, 0, NULL,
window_id_cb, ow);
- gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(
- GST_MESSAGE_SRC(msg)), ow->window_id);
+#if GST_CHECK_VERSION(1,0,0)
+ gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC(msg)),
+ ow->window_id);
+#elif GST_CHECK_VERSION(0,10,31)
+ gst_x_overlay_set_window_handle(GST_X_OVERLAY(GST_MESSAGE_SRC(msg)),
+ ow->window_id);
+#else
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(msg)),
+ ow->window_id);
+#endif
}
#endif
@@ -768,17 +805,19 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
(participant == ow->participant)) &&
!strcmp(session_id, ow->session_id)) {
GstBus *bus;
- GstElement *queue, *colorspace;
+ GstElement *queue, *convert;
GstElement *tee = purple_media_get_tee(media,
session_id, participant);
if (tee == NULL)
continue;
- queue = gst_element_factory_make(
- "queue", NULL);
- colorspace = gst_element_factory_make(
- "ffmpegcolorspace", NULL);
+ queue = gst_element_factory_make("queue", NULL);
+#if GST_CHECK_VERSION(1,0,0)
+ convert = gst_element_factory_make("videoconvert", NULL);
+#else
+ convert = gst_element_factory_make("ffmpegcolorspace", NULL);
+#endif
ow->sink = purple_media_manager_get_element(
manager, PURPLE_MEDIA_RECV_VIDEO,
ow->media, ow->session_id,
@@ -799,7 +838,7 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
}
gst_bin_add_many(GST_BIN(GST_ELEMENT_PARENT(tee)),
- queue, colorspace, ow->sink, NULL);
+ queue, convert, ow->sink, NULL);
bus = gst_pipeline_get_bus(GST_PIPELINE(
manager->priv->pipeline));
@@ -808,10 +847,10 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
gst_object_unref(bus);
gst_element_set_state(ow->sink, GST_STATE_PLAYING);
- gst_element_set_state(colorspace, GST_STATE_PLAYING);
+ gst_element_set_state(convert, GST_STATE_PLAYING);
gst_element_set_state(queue, GST_STATE_PLAYING);
- gst_element_link(colorspace, ow->sink);
- gst_element_link(queue, colorspace);
+ gst_element_link(convert, ow->sink);
+ gst_element_link(queue, convert);
gst_element_link(tee, queue);
}
}
diff --git a/libpurple/protocols/jabber/Makefile.am b/libpurple/protocols/jabber/Makefile.am
index 9fdd3a9..368a57f 100644
--- a/libpurple/protocols/jabber/Makefile.am
+++ b/libpurple/protocols/jabber/Makefile.am
@@ -113,8 +113,7 @@ pkg_LTLIBRARIES = libjabber.la libxmpp.la
libjabber_la_SOURCES = $(JABBERSOURCES)
libjabber_la_LIBADD = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)\
$(FARSIGHT_LIBS) \
- $(GSTREAMER_LIBS) \
- $(GSTINTERFACES_LIBS)
+ $(GSTREAMER_LIBS)
libxmpp_la_SOURCES = libxmpp.c
libxmpp_la_LIBADD = libjabber.la
@@ -129,5 +128,4 @@ AM_CPPFLAGS = \
$(IDN_CFLAGS) \
$(LIBXML_CFLAGS) \
$(FARSIGHT_CFLAGS) \
- $(GSTREAMER_CFLAGS) \
- $(GSTINTERFACES_CFLAGS)
+ $(GSTREAMER_CFLAGS)
diff --git a/libpurple/protocols/oscar/flap_connection.c b/libpurple/protocols/oscar/flap_connection.c
index 3aa6297..939b40f 100644
--- a/libpurple/protocols/oscar/flap_connection.c
+++ b/libpurple/protocols/oscar/flap_connection.c
@@ -334,6 +334,8 @@ flap_connection_new(OscarData *od, int type)
{
FlapConnection *conn;
+ static const guint FlapLoginSeqs[] = { 5695, 23595, 23620, 23049, 0x2886, 0x2493, 23620, 23049, 2853, 17372, 1255, 1796, 1657, 13606, 1930, 23918, 31234, 30120, 0x1BEA, 0x5342, 0x30CC, 0x2294, 0x5697,0x25FA, 0x3303, 0x078A, 0x0FC5, 0x25D6, 0x26EE,0x7570, 0x7F33, 0x4E94, 0x07C9, 0x7339, 0x42A8 };
+
conn = g_new0(FlapConnection, 1);
conn->od = od;
conn->buffer_outgoing = purple_circ_buffer_new(0);
@@ -342,6 +344,9 @@ flap_connection_new(OscarData *od, int type)
conn->type = type;
conn->rateclass_members = g_hash_table_new(g_direct_hash, g_direct_equal);
+ g_random_set_seed(time(NULL));
+ conn->seqnum_out = FlapLoginSeqs[g_random_int_range(0, (sizeof FlapLoginSeqs) / (sizeof FlapLoginSeqs[0]))] - 1;
+
od->oscar_connections = g_slist_prepend(od->oscar_connections, conn);
return conn;
diff --git a/libpurple/protocols/oscar/oscarcommon.h b/libpurple/protocols/oscar/oscarcommon.h
index a0647df..4e74377 100644
--- a/libpurple/protocols/oscar/oscarcommon.h
+++ b/libpurple/protocols/oscar/oscarcommon.h
@@ -45,7 +45,7 @@
#define OSCAR_NO_ENCRYPTION "no_encryption"
#ifndef _WIN32
-#define OSCAR_DEFAULT_CUSTOM_ENCODING "ISO-8859-1"
+#define OSCAR_DEFAULT_CUSTOM_ENCODING "CP1251"
#else
#define OSCAR_DEFAULT_CUSTOM_ENCODING oscar_get_locale_charset()
#endif
diff --git a/libpurple/proxy.c b/libpurple/proxy.c
index e6fb573..83cab38 100644
--- a/libpurple/proxy.c
+++ b/libpurple/proxy.c
@@ -129,6 +129,14 @@ purple_proxy_info_set_type(PurpleProxyInfo *info, PurpleProxyType type)
}
void
+purple_proxy_info_set_auth(PurpleProxyInfo *info, PurpleProxyAuth auth)
+{
+ g_return_if_fail(info != NULL);
+
+ info->auth = auth;
+}
+
+void
purple_proxy_info_set_host(PurpleProxyInfo *info, const char *host)
{
g_return_if_fail(info != NULL);
@@ -171,6 +179,14 @@ purple_proxy_info_get_type(const PurpleProxyInfo *info)
return info->type;
}
+PurpleProxyAuth
+purple_proxy_info_get_auth(const PurpleProxyInfo *info)
+{
+ g_return_val_if_fail(info != NULL, PURPLE_PROXY_AUTH_UNKNOWN);
+
+ return info->auth;
+}
+
const char *
purple_proxy_info_get_host(const PurpleProxyInfo *info)
{
@@ -288,7 +304,7 @@ purple_gnome_proxy_get_parameter(guint8 parameter, guint8 gnome_version)
static PurpleProxyInfo *
purple_gnome_proxy_get_info(void)
{
- static PurpleProxyInfo info = {0, NULL, 0, NULL, NULL};
+ static PurpleProxyInfo info = {0, 0, NULL, 0, NULL, NULL};
gboolean use_same_proxy = FALSE;
gchar *tmp;
guint8 gnome_version = GNOME3_CMDS;
@@ -448,7 +464,7 @@ purple_win32_proxy_get_info(void)
{
static LPFNWINHTTPGETIEPROXYCONFIG MyWinHttpGetIEProxyConfig = NULL;
static gboolean loaded = FALSE;
- static PurpleProxyInfo info = {0, NULL, 0, NULL, NULL};
+ static PurpleProxyInfo info = {0, 0, NULL, 0, NULL, NULL};
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy_config;
@@ -572,13 +588,8 @@ purple_proxy_connect_data_destroy(PurpleProxyConnectData *connect_data)
if (connect_data->query_data != NULL)
purple_dnsquery_destroy(connect_data->query_data);
-
while (connect_data->hosts != NULL)
{
- /* Discard the length... */
- connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
- /* Free the address... */
- g_free(connect_data->hosts->data);
connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
}
@@ -630,6 +641,11 @@ purple_proxy_connect_data_disconnect(PurpleProxyConnectData *connect_data, const
g_free(connect_data->read_buffer);
connect_data->read_buffer = NULL;
+ if (connect_data->hosts != NULL) {
+ connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
+ connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
+ }
+
if (error_message != NULL)
{
purple_debug_error("proxy", "Connection attempt failed: %s\n",
@@ -1056,7 +1072,6 @@ http_canread(gpointer data, gint source, PurpleInputCondition cond)
_("HTTP proxy connection error %d"), status);
return;
}
- *username = '\0';
/* Is there a message? */
if (*header_end == ' ') {
@@ -1064,6 +1079,7 @@ http_canread(gpointer data, gint source, PurpleInputCondition cond)
char *tmp = (char*) header;
guint8 *nonce;
+ *username = '\0';
header_end++;
username++;
while(*tmp != '\r' && *tmp != '\0') tmp++;
@@ -1074,11 +1090,20 @@ http_canread(gpointer data, gint source, PurpleInputCondition cond)
hostname,
domain, nonce, NULL);
username--;
- } else /* Empty message */
- response = purple_ntlm_gen_type1(hostname, domain);
-
- *username = '\\';
-
+ *username = '\\';
+ } else { /* Empty message */
+ if (purple_proxy_info_get_auth(connect_data->gpi) != PURPLE_PROXY_AUTH_NTLM) {
+ purple_proxy_info_set_auth(connect_data->gpi,PURPLE_PROXY_AUTH_NTLM);
+ /* place some trash to the begin of the GSList,
+ * it will be removed in purple_proxy_connect_data_disconnect(),
+ * so, next attempt to connect will be done to the same proxy host */
+ connect_data->hosts = g_slist_prepend(connect_data->hosts, g_strdup("") );
+ connect_data->hosts = g_slist_prepend(connect_data->hosts, g_strdup("") );
+ }
+ purple_proxy_connect_data_disconnect_formatted(connect_data,
+ _("HTTP proxy connection error %d"), status);
+ return;
+ }
request = g_strdup_printf(
"CONNECT %s:%d HTTP/1.1\r\n"
"Host: %s:%d\r\n"
@@ -1091,28 +1116,17 @@ http_canread(gpointer data, gint source, PurpleInputCondition cond)
g_free(response);
} else if (g_strrstr((const char *)connect_data->read_buffer, "Proxy-Authenticate: Basic") != NULL) {
- gchar *t1, *t2;
- const char *username, *password;
-
- username = purple_proxy_info_get_username(connect_data->gpi);
- password = purple_proxy_info_get_password(connect_data->gpi);
-
- t1 = g_strdup_printf("%s:%s",
- username ? username : "",
- password ? password : "");
- t2 = purple_base64_encode((guchar *)t1, strlen(t1));
- g_free(t1);
-
- request = g_strdup_printf(
- "CONNECT %s:%d HTTP/1.1\r\n"
- "Host: %s:%d\r\n"
- "Proxy-Authorization: Basic %s\r\n",
- connect_data->host, connect_data->port,
- connect_data->host, connect_data->port,
- t2);
-
- g_free(t2);
-
+ if (purple_proxy_info_get_auth(connect_data->gpi) != PURPLE_PROXY_AUTH_BASIC) {
+ purple_proxy_info_set_auth(connect_data->gpi,PURPLE_PROXY_AUTH_BASIC);
+ /* place some trash to the begin of the GSList,
+ * it will be removed in purple_proxy_connect_data_disconnect(),
+ * so, next attempt to connect will be done to the same proxy host */
+ connect_data->hosts = g_slist_prepend(connect_data->hosts, g_strdup("") );
+ connect_data->hosts = g_slist_prepend(connect_data->hosts, g_strdup("") );
+ }
+ purple_proxy_connect_data_disconnect_formatted(connect_data,
+ _("HTTP proxy connection error %d"), status);
+ return;
} else {
purple_proxy_connect_data_disconnect_formatted(connect_data,
_("HTTP proxy connection error %d"), status);
@@ -1201,6 +1215,43 @@ http_start_connect_tunneling(PurpleProxyConnectData *connect_data) {
g_free(t2);
}
+ if (purple_proxy_info_get_username(connect_data->gpi) != NULL
+ && purple_proxy_info_get_auth(connect_data->gpi) != 0)
+ {
+ char *t1, *t2, *ntlm_type1, hostname[256];
+ switch(purple_proxy_info_get_auth(connect_data->gpi)) {
+ case PURPLE_PROXY_AUTH_BASIC:
+ t1 = g_strdup_printf("%s:%s",
+ purple_proxy_info_get_username(connect_data->gpi),
+ purple_proxy_info_get_password(connect_data->gpi) ?
+ purple_proxy_info_get_password(connect_data->gpi) : "");
+ t2 = purple_base64_encode((const guchar *)t1, strlen(t1));
+ g_free(t1);
+ g_string_append_printf(request,
+ "Proxy-Authorization: Basic %s\r\n"
+ "Proxy-Connection: Keep-Alive\r\n",
+ t2);
+ g_free(t2);
+ break;
+ case PURPLE_PROXY_AUTH_NTLM:
+
+ ret = gethostname(hostname, sizeof(hostname));
+ hostname[sizeof(hostname) - 1] = '\0';
+ if (ret < 0 || hostname[0] == '\0') {
+ purple_debug_warning("proxy", "gethostname() failed -- is your hostname set?");
+ strcpy(hostname, "localhost");
+ }
+ ntlm_type1 = purple_ntlm_gen_type1(hostname, "");
+ g_string_append_printf(request,
+ "Proxy-Authorization: NTLM %s\r\n"
+ "Proxy-Connection: Keep-Alive\r\n",
+ ntlm_type1);
+ g_free(ntlm_type1);
+ break;
+ default:
+ break;
+ }
+ }
g_string_append(request, "\r\n");
connect_data->write_buf_len = request->len;
@@ -2169,9 +2220,8 @@ static void try_connect(PurpleProxyConnectData *connect_data)
char ipaddr[INET6_ADDRSTRLEN];
addrlen = GPOINTER_TO_INT(connect_data->hosts->data);
- connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
- addr = connect_data->hosts->data;
- connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
+ addr = connect_data->hosts->next->data;
+
#ifdef HAVE_INET_NTOP
if (addr->sa_family == AF_INET)
inet_ntop(addr->sa_family, &((struct sockaddr_in *)addr)->sin_addr,
@@ -2216,8 +2266,6 @@ static void try_connect(PurpleProxyConnectData *connect_data)
default:
break;
}
-
- g_free(addr);
}
static void
diff --git a/libpurple/proxy.h b/libpurple/proxy.h
index cf91ee8..56f6336 100644
--- a/libpurple/proxy.h
+++ b/libpurple/proxy.h
@@ -44,13 +44,21 @@ typedef enum
} PurpleProxyType;
+typedef enum
+{
+ PURPLE_PROXY_AUTH_UNKNOWN = 0,
+ PURPLE_PROXY_AUTH_BASIC,
+ PURPLE_PROXY_AUTH_NTLM
+} PurpleProxyAuth;
+
/**
* Information on proxy settings.
*/
typedef struct
{
PurpleProxyType type; /**< The proxy type. */
-
+ PurpleProxyAuth auth; /**< Auth type on the proxy. */
+
char *host; /**< The host. */
int port; /**< The port number. */
char *username; /**< The username. */
@@ -97,6 +105,14 @@ void purple_proxy_info_destroy(PurpleProxyInfo *info);
void purple_proxy_info_set_type(PurpleProxyInfo *info, PurpleProxyType type);
/**
+ * Sets the type of auth for proxy.
+ *
+ * @param info The proxy information.
+ * @param auth The proxy auth type.
+ */
+void purple_proxy_info_set_auth(PurpleProxyInfo *info, PurpleProxyAuth auth);
+
+/**
* Sets the proxy host.
*
* @param info The proxy information.
@@ -138,6 +154,15 @@ void purple_proxy_info_set_password(PurpleProxyInfo *info, const char *password)
PurpleProxyType purple_proxy_info_get_type(const PurpleProxyInfo *info);
/**
+ * Returns the proxy's auth type.
+ *
+ * @param info The proxy information.
+ *
+ * @return The auth.
+ */
+PurpleProxyAuth purple_proxy_info_get_auth(const PurpleProxyInfo *info);
+
+/**
* Returns the proxy's host.
*
* @param info The proxy information.
diff --git a/libpurple/util.c b/libpurple/util.c
index 9b9dd2b..74a6ebf 100644
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -2499,7 +2499,7 @@ const char *
purple_home_dir(void)
{
#ifndef _WIN32
- return g_get_home_dir();
+ return g_get_user_config_dir();
#else
return wpurple_data_dir();
#endif
@@ -2512,7 +2512,7 @@ purple_user_dir(void)
if (custom_user_dir != NULL)
return custom_user_dir;
else if (!user_dir)
- user_dir = g_build_filename(purple_home_dir(), ".purple", NULL);
+ user_dir = g_build_filename(purple_home_dir(), "purple", NULL);
return user_dir;
}
diff --git a/pidgin/Makefile.am b/pidgin/Makefile.am
index b6a5bd4..d2d871c 100644
--- a/pidgin/Makefile.am
+++ b/pidgin/Makefile.am
@@ -152,13 +152,14 @@ pidgin_LDADD = \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(GSTREAMER_LIBS) \
+ $(GSTVIDEO_LIBS) \
$(XSS_LIBS) \
$(SM_LIBS) \
$(INTLLIBS) \
$(GTKSPELL_LIBS) \
$(LIBXML_LIBS) \
$(GTK_LIBS) \
- $(top_builddir)/libpurple/libpurple.la
+ $(top_builddir)/libpurple/libpurple.la -lm
if USE_INTERNAL_LIBGADU
INTGG_CFLAGS = -DUSE_INTERNAL_LIBGADU
diff --git a/pidgin/gtkmain.c b/pidgin/gtkmain.c
index 6e828fc..b035825 100644
--- a/pidgin/gtkmain.c
+++ b/pidgin/gtkmain.c
@@ -88,10 +88,6 @@ static const int catch_sig_list[] = {
SIGINT,
SIGTERM,
SIGQUIT,
- SIGCHLD,
-#if defined(USE_GSTREAMER) && !defined(GST_CAN_DISABLE_FORKING)
- SIGALRM,
-#endif
-1
};
@@ -136,29 +132,6 @@ static int signal_sockets[2];
static void sighandler(int sig);
-/*
- * This child process reaping stuff is currently only used for processes that
- * were forked to play sounds. It's not needed for forked DNS child, which
- * have their own waitpid() call. It might be wise to move this code into
- * gtksound.c.
- */
-static void
-clean_pid(void)
-{
- int status;
- pid_t pid;
-
- do {
- pid = waitpid(-1, &status, WNOHANG);
- } while (pid != 0 && pid != (pid_t)-1);
-
- if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
- char errmsg[BUFSIZ];
- snprintf(errmsg, sizeof(errmsg), "Warning: waitpid() returned %d", pid);
- perror(errmsg);
- }
-}
-
static void sighandler(int sig)
{
ssize_t written;
@@ -209,33 +182,8 @@ mainloop_sighandler(GIOChannel *source, GIOCondition cond, gpointer data)
return FALSE;
}
- switch (sig) {
-#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
- * gstreamer, gstreamer's initialization fails. So, we wait a second before
- * reaping child processes, to give gst a chance to reap it if it wants to.
- *
- * This is not needed in later gstreamers, which let us disable the forking.
- * And, it breaks the world on some Real Unices.
- */
- case SIGCHLD:
- /* Restore signal catching */
- signal(SIGCHLD, sighandler);
- alarm(1);
- break;
- case SIGALRM:
-#else
- case SIGCHLD:
-#endif
- clean_pid();
- /* Restore signal catching */
- signal(SIGCHLD, sighandler);
- break;
- default:
- purple_debug_warning("sighandler", "Caught signal %d\n", sig);
- purple_core_quit();
- }
+ purple_debug_warning("sighandler", "Caught signal %d\n", sig);
+ purple_core_quit();
return TRUE;
}
diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c
index d91a951..78e0000 100644
--- a/pidgin/gtkmedia.c
+++ b/pidgin/gtkmedia.c
@@ -38,11 +38,15 @@
#ifdef USE_VV
#include "media-gst.h"
-#ifdef _WIN32
+#ifdef GDK_WINDOWING_WIN32
#include <gdk/gdkwin32.h>
#endif
-
-#include <gst/interfaces/xoverlay.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+#include <gdk/gdkquartz.h>
+#endif
#define PIDGIN_TYPE_MEDIA (pidgin_media_get_type())
#define PIDGIN_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PIDGIN_TYPE_MEDIA, PidginMedia))
@@ -555,13 +559,25 @@ realize_cb_cb(PidginMediaRealizeData *data)
}
if (window) {
- gulong window_id;
-#ifdef _WIN32
- window_id = GDK_WINDOW_HWND(window);
-#elif defined(HAVE_X11)
- window_id = GDK_WINDOW_XWINDOW(window);
-#else
-# error "Unsupported windowing system"
+ gulong window_id = 0;
+#ifdef GDK_WINDOWING_WIN32
+ if (GDK_IS_WIN32_WINDOW(window))
+ window_id = GDK_WINDOW_HWND(window);
+ else
+#endif
+#ifdef GDK_WINDOWING_X11
+ window_id = GDK_WINDOW_XWINDOW(window);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ if (GDK_IS_QUARTZ_WINDOW(window))
+ window_id = (gulong)gdk_quartz_window_get_nsview(window);
+ else
+#endif
+ g_warning("Unsupported GDK backend");
+#if !(defined(GDK_WINDOWING_WIN32) \
+ || defined(GDK_WINDOWING_X11) \
+ || defined(GDK_WINDOWING_QUARTZ))
+# error "Unsupported GDK windowing system"
#endif
purple_media_set_output_window(priv->media, data->session_id,
@@ -1082,6 +1098,10 @@ create_default_video_src(PurpleMedia *media,
src = gst_element_factory_make("dshowvideosrc", NULL);
if (src == NULL)
src = gst_element_factory_make("autovideosrc", NULL);
+#elif defined(__APPLE__)
+ src = gst_element_factory_make("osxvideosrc", NULL);
+ if (src == NULL)
+ src = gst_element_factory_make("autovideosrc", NULL);
#else
src = gst_element_factory_make("gconfvideosrc", NULL);
if (src == NULL)
@@ -1136,6 +1156,8 @@ create_default_audio_src(PurpleMedia *media,
src = gst_element_factory_make("osssrc", NULL);
if (src == NULL)
src = gst_element_factory_make("dshowaudiosrc", NULL);
+ if (src == NULL)
+ src = gst_element_factory_make("osxaudiosrc", NULL);
if (src == NULL) {
purple_debug_error("gtkmedia", "Unable to find a suitable "
"element for the default audio source.\n");
diff --git a/pidgin/gtkprefs.c b/pidgin/gtkprefs.c
index 54381f6..caa7b12 100644
--- a/pidgin/gtkprefs.c
+++ b/pidgin/gtkprefs.c
@@ -56,6 +56,24 @@
#include "gtkthemes.h"
#include "gtkutils.h"
#include "pidginstock.h"
+#if USE_VV
+#include "media-gst.h"
+#if GST_CHECK_VERSION(1,0,0)
+#include <gst/video/videooverlay.h>
+#else
+#include <gst/interfaces/xoverlay.h>
+#include <gst/interfaces/propertyprobe.h>
+#endif
+#ifdef GDK_WINDOWING_WIN32
+#include <gdk/gdkwin32.h>
+#endif
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+#include <gdk/gdkquartz.h>
+#endif
+#endif
#define PROXYHOST 0
#define PROXYPORT 1
@@ -97,6 +115,60 @@ static GtkListStore *prefs_blist_themes;
static GtkListStore *prefs_status_icon_themes;
static GtkListStore *prefs_smiley_themes;
+#if USE_VV
+
+static const gchar *AUDIO_SRC_PLUGINS[] = {
+ "alsasrc", "ALSA",
+ /* "esdmon", "ESD", ? */
+ "osssrc", "OSS",
+ "pulsesrc", "PulseAudio",
+ "sndiosrc", "sndio",
+ /* "audiotestsrc wave=silence", "Silence", */
+ "audiotestsrc", "Test Sound",
+ NULL
+};
+
+static const gchar *AUDIO_SINK_PLUGINS[] = {
+ "alsasink", "ALSA",
+ "artsdsink", "aRts",
+ "esdsink", "ESD",
+ "osssink", "OSS",
+ "pulsesink", "PulseAudio",
+ "sndiosink", "sndio",
+ NULL
+};
+
+static const gchar *VIDEO_SRC_PLUGINS[] = {
+ "videotestsrc", "Test Input",
+ "dshowvideosrc","DirectDraw",
+ "ksvideosrc", "KS Video",
+ "qcamsrc", "Quickcam",
+ "v4lsrc", "Video4Linux",
+ "v4l2src", "Video4Linux2",
+ "v4lmjpegsrc", "Video4Linux MJPEG",
+ NULL
+};
+
+static const gchar *VIDEO_SINK_PLUGINS[] = {
+ /* "aasink", "AALib", Didn't work for me */
+ "directdrawsink","DirectDraw",
+ "glimagesink", "OpenGL",
+ "ximagesink", "X Window System",
+ "xvimagesink", "X Window System (Xv)",
+ NULL
+};
+
+typedef struct {
+ GtkWidget *level;
+ GtkWidget *threshold;
+ GtkWidget *volume;
+} BusCbCtx;
+
+static GstElement *voice_pipeline;
+static GstElement *video_pipeline;
+
+#endif
+
/*
* PROTOTYPES
*/
@@ -2742,6 +2814,617 @@ away_page(void)
return ret;
}
+#if USE_VV
+static GList *
+get_vv_element_devices(const gchar *element_name)
+{
+ GList *ret = NULL;
+ GstElement *element;
+ GObjectClass *klass;
+#if !GST_CHECK_VERSION(1,0,0)
+ GstPropertyProbe *probe;
+ const GParamSpec *pspec;
+#endif
+
+ ret = g_list_prepend(ret, (gpointer)_("Default"));
+ ret = g_list_prepend(ret, "");
+
+ if (!strcmp(element_name, "<custom>") || (*element_name == '\0')) {
+ return g_list_reverse(ret);
+ }
+
+ element = gst_element_factory_make(element_name, "test");
+ if (!element) {
+ purple_debug_info("vvconfig", "'%s' - unable to find element\n",
+ element_name);
+ return g_list_reverse(ret);
+ }
+
+ klass = G_OBJECT_GET_CLASS (element);
+ if (!klass) {
+ purple_debug_info("vvconfig", "'%s' - unable to find GObject Class\n",
+ element_name);
+ return g_list_reverse(ret);
+ }
+
+#if GST_CHECK_VERSION(1,0,0)
+ purple_debug_info("vvconfig", "'%s' - no device\n", element_name);
+#else
+ if (!g_object_class_find_property(klass, "device") ||
+ !GST_IS_PROPERTY_PROBE(element) ||
+ !(probe = GST_PROPERTY_PROBE(element)) ||
+ !(pspec = gst_property_probe_get_property(probe, "device"))) {
+ purple_debug_info("vvconfig", "'%s' - no device\n", element_name);
+ } else {
+ gint n;
+ GValueArray *array;
+
+ /* Set autoprobe[-fps] to FALSE to avoid delays when probing. */
+ if (g_object_class_find_property(klass, "autoprobe")) {
+ g_object_set(G_OBJECT(element), "autoprobe", FALSE, NULL);
+ if (g_object_class_find_property(klass, "autoprobe-fps")) {
+ g_object_set(G_OBJECT(element), "autoprobe-fps", FALSE, NULL);
+ }
+ }
+
+ array = gst_property_probe_probe_and_get_values(probe, pspec);
+ if (array == NULL) {
+ purple_debug_info("vvconfig", "'%s' has no devices\n", element_name);
+ return g_list_reverse(ret);
+ }
+
+ for (n = 0; n < array->n_values; ++n) {
+ GValue *device;
+ const gchar *name;
+ const gchar *device_name;
+
+ device = g_value_array_get_nth(array, n);
+ g_object_set_property(G_OBJECT(element), "device", device);
+ if (gst_element_set_state(element, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
+ purple_debug_warning("vvconfig", "Error changing state of %s\n",
+ element_name);
+ continue;
+ }
+
+ g_object_get(G_OBJECT(element), "device-name", &name, NULL);
+ device_name = g_value_get_string(device);
+ if (name == NULL)
+ name = _("Unknown");
+ purple_debug_info("vvconfig", "Found device %s : %s for %s\n",
+ device_name, name, element_name);
+ ret = g_list_prepend(ret, (gpointer)name);
+ ret = g_list_prepend(ret, (gpointer)device_name);
+ gst_element_set_state(element, GST_STATE_NULL);
+ }
+ }
+#endif
+ gst_object_unref(element);
+
+ return g_list_reverse(ret);
+}
+
+static GList *
+get_vv_element_plugins(const gchar **plugins)
+{
+ GList *ret = NULL;
+
+ ret = g_list_prepend(ret, (gpointer)_("Default"));
+ ret = g_list_prepend(ret, "");
+ for (; plugins[0] && plugins[1]; plugins += 2) {
+#if GST_CHECK_VERSION(1,0,0)
+ if (gst_registry_check_feature_version(gst_registry_get(),
+ plugins[0], 0, 0, 0)) {
+#else
+ if (gst_default_registry_check_feature_version(plugins[0], 0, 0, 0)) {
+#endif
+ ret = g_list_prepend(ret, (gpointer)plugins[1]);
+ ret = g_list_prepend(ret, (gpointer)plugins[0]);
+ }
+ }
+
+ return g_list_reverse(ret);
+}
+
+static void
+vv_plugin_changed_cb(const gchar *name, PurplePrefType type,
+ gconstpointer value, gpointer data)
+{
+ GtkWidget *vbox = data;
+ GtkSizeGroup *sg;
+ GtkWidget *widget;
+ gchar *pref;
+ GList *devices;
+
+ sg = g_object_get_data(G_OBJECT(vbox), "size-group");
+ widget = g_object_get_data(G_OBJECT(vbox), "device-hbox");
+ gtk_widget_destroy(widget);
+
+ pref = g_strdup(name);
+ strcpy(pref + strlen(pref) - strlen("plugin"), "device");
+ devices = get_vv_element_devices(value);
+ if (g_list_find_custom(devices, purple_prefs_get_string(pref),
+ (GCompareFunc)strcmp) == NULL)
+ purple_prefs_set_string(pref, g_list_next(devices)->data);
+ widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"),
+ PURPLE_PREF_STRING, pref, devices);
+ g_list_free(devices);
+ gtk_size_group_add_widget(sg, widget);
+ gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5);
+
+ g_object_set_data(G_OBJECT(vbox), "device-hbox",
+ gtk_widget_get_parent(widget));
+ g_signal_connect_swapped(widget, "destroy", G_CALLBACK(g_free), pref);
+}
+
+static void
+make_vv_frame(GtkWidget *parent, GtkSizeGroup *sg,
+ const gchar *name, const gchar **plugin_strs,
+ const gchar *plugin_pref, const gchar *device_pref)
+{
+ GtkWidget *vbox, *widget;
+ GList *plugins, *devices;
+
+ vbox = pidgin_make_frame(parent, name);
+
+ /* Setup plugin preference */
+ plugins = get_vv_element_plugins(plugin_strs);
+ widget = pidgin_prefs_dropdown_from_list(vbox, _("_Plugin"),
+ PURPLE_PREF_STRING, plugin_pref,
+ plugins);
+ g_list_free(plugins);
+ gtk_size_group_add_widget(sg, widget);
+ gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5);
+
+ /* Setup device preference */
+ devices = get_vv_element_devices(purple_prefs_get_string(plugin_pref));
+ if (g_list_find_custom(devices, purple_prefs_get_string(device_pref),
+ (GCompareFunc)strcmp) == NULL)
+ purple_prefs_set_string(device_pref, g_list_next(devices)->data);
+ widget = pidgin_prefs_dropdown_from_list(vbox, _("_Device"),
+ PURPLE_PREF_STRING, device_pref,
+ devices);
+ g_list_free(devices);
+ gtk_size_group_add_widget(sg, widget);
+ gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5);
+
+ widget = gtk_widget_get_parent(widget);
+ g_object_set_data(G_OBJECT(vbox), "size-group", sg);
+ g_object_set_data(G_OBJECT(vbox), "device-hbox", widget);
+ purple_prefs_connect_callback(vbox, plugin_pref, vv_plugin_changed_cb,
+ vbox);
+ g_signal_connect_swapped(vbox, "destroy",
+ G_CALLBACK(purple_prefs_disconnect_by_handle), vbox);
+}
+
+static GstElement *
+create_test_element(const char *type, const char *dir, PurpleMediaElementInfo *info)
+{
+ char *tmp;
+ const gchar *plugin;
+ const gchar *device;
+ GstElement *ret;
+
+ tmp = g_strdup_printf(PIDGIN_PREFS_ROOT "/vvconfig/%s/%s/plugin", type, dir);
+ plugin = purple_prefs_get_string(tmp);
+ g_free(tmp);
+
+ tmp = g_strdup_printf(PIDGIN_PREFS_ROOT "/vvconfig/%s/%s/device", type, dir);
+ device = purple_prefs_get_string(tmp);
+ g_free(tmp);
+
+ if (plugin[0] == '\0')
+ return purple_media_element_info_call_create(info, NULL, NULL, NULL);
+
+ ret = gst_element_factory_make(plugin, NULL);
+ if (device[0] != '\0')
+ g_object_set(G_OBJECT(ret), "device", device, NULL);
+ if (!strcmp(plugin, "videotestsrc"))
+ g_object_set(G_OBJECT(ret), "is-live", 1, NULL);
+
+ return ret;
+}
+
+static void
+vv_test_switch_page_cb(GtkNotebook *notebook, GtkWidget *page, guint num, gpointer data)
+{
+ GtkWidget *test = data;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(test), FALSE);
+}
+
+static GstElement *
+create_voice_pipeline(void)
+{
+ PurpleMediaManager *manager;
+ PurpleMediaElementInfo *audio_src, *audio_sink;
+ GstElement *pipeline;
+ GstElement *src, *sink;
+ GstElement *volume;
+ GstElement *level;
+ GstElement *valve;
+
+ manager = purple_media_manager_get();
+ audio_src = purple_media_manager_get_active_element(manager,
+ PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SRC);
+ audio_sink = purple_media_manager_get_active_element(manager,
+ PURPLE_MEDIA_ELEMENT_AUDIO | PURPLE_MEDIA_ELEMENT_SINK);
+
+ pipeline = gst_pipeline_new("voicetest");
+ src = create_test_element("audio", "src", audio_src);
+ sink = create_test_element("audio", "sink", audio_sink);
+ volume = gst_element_factory_make("volume", "volume");
+ level = gst_element_factory_make("level", "level");
+ valve = gst_element_factory_make("valve", "valve");
+
+ gst_bin_add_many(GST_BIN(pipeline), src, volume, level, valve, sink, NULL);
+ gst_element_link_many(src, volume, level, valve, sink, NULL);
+
+ gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
+
+ return pipeline;
+}
+
+static void
+on_volume_change_cb(GtkWidget *w, GstBin *pipeline)
+{
+ GstElement *volume;
+
+ g_return_if_fail(pipeline != NULL);
+
+ volume = gst_bin_get_by_name(pipeline, "volume");
+ g_object_set(volume, "volume",
+ gtk_scale_button_get_value(GTK_SCALE_BUTTON(w)) * 10.0, NULL);
+}
+
+static gdouble
+gst_msg_db_to_percent(GstMessage *msg, gchar *value_name)
+{
+ const GValue *list;
+ const GValue *value;
+ gdouble value_db;
+ gdouble percent;
+
+ list = gst_structure_get_value(gst_message_get_structure(msg), value_name);
+#if GST_CHECK_VERSION(1,0,0)
+ value = g_value_array_get_nth(g_value_get_boxed(list), 0);
+#else
+ value = gst_value_list_get_value(list, 0);
+#endif
+ value_db = g_value_get_double(value);
+ percent = pow(10, value_db / 20);
+ return (percent > 1.0) ? 1.0 : percent;
+}
+
+static gboolean
+gst_bus_cb(GstBus *bus, GstMessage *msg, BusCbCtx *ctx)
+{
+ if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT &&
+ gst_structure_has_name(gst_message_get_structure(msg), "level")) {
+
+ GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
+ gchar *name = gst_element_get_name(src);
+
+ if (!strcmp(name, "level")) {
+ gdouble percent;
+ gdouble threshold;
+ GstElement *valve;
+
+ percent = gst_msg_db_to_percent(msg, "rms");
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ctx->level), percent);
+
+ percent = gst_msg_db_to_percent(msg, "decay");
+ threshold = gtk_range_get_value(GTK_RANGE(ctx->threshold)) / 100.0;
+ valve = gst_bin_get_by_name(GST_BIN(GST_ELEMENT_PARENT(src)), "valve");
+ g_object_set(valve, "drop", (percent < threshold), NULL);
+ g_object_set(ctx->level, "text",
+ (percent < threshold) ? _("DROP") : " ", NULL);
+ }
+
+ g_free(name);
+ }
+
+ return TRUE;
+}
+
+static void
+voice_test_destroy_cb(GtkWidget *w, gpointer data)
+{
+ if (!voice_pipeline)
+ return;
+
+ gst_element_set_state(voice_pipeline, GST_STATE_NULL);
+ gst_object_unref(voice_pipeline);
+ voice_pipeline = NULL;
+}
+
+static void
+toggle_voice_test_cb(GtkToggleButton *test, gpointer data)
+{
+ BusCbCtx *ctx = data;
+ GstBus *bus;
+
+ if (gtk_toggle_button_get_active(test)) {
+ gtk_widget_set_sensitive(ctx->level, TRUE);
+ voice_pipeline = create_voice_pipeline();
+ bus = gst_pipeline_get_bus(GST_PIPELINE(voice_pipeline));
+ gst_bus_add_signal_watch(bus);
+ g_signal_connect(bus, "message", G_CALLBACK(gst_bus_cb), ctx);
+ gst_object_unref(bus);
+
+ g_signal_connect(ctx->volume, "value-changed",
+ G_CALLBACK(on_volume_change_cb), voice_pipeline);
+ g_signal_connect(test, "destroy",
+ G_CALLBACK(voice_test_destroy_cb), NULL);
+ g_signal_connect(prefsnotebook, "switch-page",
+ G_CALLBACK(vv_test_switch_page_cb), test);
+ } else {
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ctx->level), 0.0);
+ gtk_widget_set_sensitive(ctx->level, FALSE);
+ g_object_disconnect(ctx->volume, "any-signal::value-changed",
+ G_CALLBACK(on_volume_change_cb), voice_pipeline,
+ NULL);
+ g_object_disconnect(test, "any-signal::destroy",
+ G_CALLBACK(voice_test_destroy_cb), NULL,
+ NULL);
+ g_object_disconnect(prefsnotebook, "any-signal::switch-page",
+ G_CALLBACK(vv_test_switch_page_cb), test,
+ NULL);
+ voice_test_destroy_cb(NULL, NULL);
+ }
+}
+
+static void
+scale_value_changed_cb(GtkScaleButton *button, gpointer data)
+{
+ const char *pref = data;
+ purple_prefs_set_int(pref,
+ gtk_scale_button_get_value(GTK_SCALE_BUTTON(button)) * 100);
+}
+
+static void
+threshold_value_changed_cb(GtkScale *scale, GtkWidget *label)
+{
+ int value;
+ char *tmp;
+
+ value = (int)gtk_range_get_value(GTK_RANGE(scale));
+ tmp = g_strdup_printf(_("Silence threshold: %d%%"), value);
+ gtk_label_set_label(GTK_LABEL(label), tmp);
+ g_free(tmp);
+
+ purple_prefs_set_int("/purple/media/audio/silence_threshold", value);
+}
+
+static void
+make_voice_test(GtkWidget *vbox)
+{
+ GtkWidget *test;
+ GtkWidget *hbox;
+ GtkWidget *label;
+ GtkWidget *level;
+ GtkWidget *volume;
+ GtkWidget *threshold;
+ BusCbCtx *ctx;
+ char *tmp;
+
+ label = gtk_label_new(NULL);
+ gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ label = gtk_label_new(_("Volume:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ volume = gtk_volume_button_new();
+ gtk_box_pack_start(GTK_BOX(hbox), volume, TRUE, TRUE, 0);
+ gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume),
+ purple_prefs_get_int("/purple/media/audio/volume/input") / 100.0);
+ g_signal_connect(volume, "value-changed",
+ G_CALLBACK(scale_value_changed_cb),
+ "/purple/media/audio/volume/input");
+
+ tmp = g_strdup_printf(_("Silence threshold: %d%%"),
+ purple_prefs_get_int("/purple/media/audio/silence_threshold"));
+ label = gtk_label_new(tmp);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ g_free(tmp);
+ threshold = gtk_hscale_new_with_range(0, 100, 1);
+ gtk_box_pack_start(GTK_BOX(vbox), threshold, FALSE, FALSE, 0);
+ gtk_range_set_value(GTK_RANGE(threshold),
+ purple_prefs_get_int("/purple/media/audio/silence_threshold"));
+ gtk_scale_set_draw_value(GTK_SCALE(threshold), FALSE);
+ g_signal_connect(threshold, "value-changed",
+ G_CALLBACK(threshold_value_changed_cb), label);
+
+ test = gtk_toggle_button_new_with_label(_("Test Audio"));
+ gtk_box_pack_start(GTK_BOX(vbox), test, FALSE, FALSE, 0);
+
+ level = gtk_progress_bar_new();
+ gtk_box_pack_start(GTK_BOX(vbox), level, FALSE, FALSE, 0);
+ gtk_widget_set_sensitive(level, FALSE);
+
+ ctx = g_new(BusCbCtx, 1);
+ ctx->volume = volume;
+ ctx->level = level;
+ ctx->threshold = threshold;
+ g_signal_connect(test, "toggled",
+ G_CALLBACK(toggle_voice_test_cb), ctx);
+}
+
+static GstElement *
+create_video_pipeline(void)
+{
+ PurpleMediaManager *manager;
+ PurpleMediaElementInfo *video_src, *video_sink;
+ GstElement *pipeline;
+ GstElement *src, *sink;
+
+ manager = purple_media_manager_get();
+ video_src = purple_media_manager_get_active_element(manager,
+ PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SRC);
+ video_sink = purple_media_manager_get_active_element(manager,
+ PURPLE_MEDIA_ELEMENT_VIDEO | PURPLE_MEDIA_ELEMENT_SINK);
+
+ pipeline = gst_pipeline_new("videotest");
+ src = create_test_element("video", "src", video_src);
+ sink = create_test_element("video", "sink", video_sink);
+
+ gst_bin_add_many(GST_BIN(pipeline), src, sink, NULL);
+ gst_element_link_many(src, sink, NULL);
+
+ gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
+
+ return pipeline;
+}
+
+static void
+video_test_destroy_cb(GtkWidget *w, gpointer data)
+{
+ if (!video_pipeline)
+ return;
+
+ gst_element_set_state(video_pipeline, GST_STATE_NULL);
+ gst_object_unref(video_pipeline);
+ video_pipeline = NULL;
+}
+
+static void
+window_id_cb(GstBus *bus, GstMessage *msg, gulong window_id)
+{
+ if (GST_MESSAGE_TYPE(msg) != GST_MESSAGE_ELEMENT
+#if GST_CHECK_VERSION(1,0,0)
+ || !gst_is_video_overlay_prepare_window_handle_message(msg))
+#else
+ || !gst_structure_has_name(msg->structure, "prepare-xwindow-id"))
+#endif
+ return;
+
+ g_signal_handlers_disconnect_matched(bus,
+ G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, window_id_cb,
+ (gpointer)window_id);
+
+#if GST_CHECK_VERSION(1,0,0)
+ gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC(msg)),
+ window_id);
+#elif GST_CHECK_VERSION(0,10,31)
+ gst_x_overlay_set_window_handle(GST_X_OVERLAY(GST_MESSAGE_SRC(msg)),
+ window_id);
+#else
+ gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(msg)),
+ window_id);
+#endif
+}
+
+static void
+toggle_video_test_cb(GtkToggleButton *test, gpointer data)
+{
+ GtkWidget *video = data;
+ GstBus *bus;
+
+ if (gtk_toggle_button_get_active(test)) {
+ GdkWindow *window = gtk_widget_get_window(video);
+ gulong window_id = 0;
+#ifdef GDK_WINDOWING_WIN32
+ if (GDK_IS_WIN32_WINDOW(window))
+ window_id = GDK_WINDOW_HWND(window);
+ else
+#endif
+#ifdef GDK_WINDOWING_X11
+ window_id = GDK_WINDOW_XWINDOW(window);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ if (GDK_IS_QUARTZ_WINDOW(window))
+ window_id = (gulong)gdk_quartz_window_get_nsview(window);
+ else
+#endif
+ g_warning("Unsupported GDK backend");
+#if !(defined(GDK_WINDOWING_WIN32) \
+ || defined(GDK_WINDOWING_X11) \
+ || defined(GDK_WINDOWING_QUARTZ))
+# error "Unsupported GDK windowing system"
+#endif
+
+ video_pipeline = create_video_pipeline();
+ bus = gst_pipeline_get_bus(GST_PIPELINE(video_pipeline));
+#if GST_CHECK_VERSION(1,0,0)
+ gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL, NULL);
+#else
+ gst_bus_set_sync_handler(bus, gst_bus_sync_signal_handler, NULL);
+#endif
+ g_signal_connect(bus, "sync-message::element",
+ G_CALLBACK(window_id_cb), (gpointer)window_id);
+ gst_object_unref(bus);
+
+ g_signal_connect(test, "destroy",
+ G_CALLBACK(video_test_destroy_cb), NULL);
+ g_signal_connect(prefsnotebook, "switch-page",
+ G_CALLBACK(vv_test_switch_page_cb), test);
+ } else {
+ g_object_disconnect(test, "any-signal::destroy",
+ G_CALLBACK(video_test_destroy_cb), NULL,
+ NULL);
+ g_object_disconnect(prefsnotebook, "any-signal::switch-page",
+ G_CALLBACK(vv_test_switch_page_cb), test,
+ NULL);
+ video_test_destroy_cb(NULL, NULL);
+ }
+}
+
+static void
+make_video_test(GtkWidget *vbox)
+{
+ GtkWidget *test;
+ GtkWidget *video;
+ GdkColor color = {0, 0, 0, 0};
+
+ video = gtk_drawing_area_new();
+ gtk_box_pack_start(GTK_BOX(vbox), video, TRUE, TRUE, 0);
+ gtk_widget_modify_bg(video, GTK_STATE_NORMAL, &color);
+ gtk_widget_set_size_request(GTK_WIDGET(video), 240, 180);
+
+ test = gtk_toggle_button_new_with_label(_("Test Video"));
+ gtk_box_pack_start(GTK_BOX(vbox), test, FALSE, FALSE, 0);
+
+ g_signal_connect(test, "toggled",
+ G_CALLBACK(toggle_video_test_cb), video);
+}
+
+static GtkWidget *
+vv_page(void)
+{
+ GtkWidget *ret;
+ GtkWidget *vbox;
+ GtkSizeGroup *sg;
+
+ ret = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
+ gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
+
+ sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+ vbox = pidgin_make_frame(ret, _("Audio"));
+ make_vv_frame(vbox, sg, _("Input"), AUDIO_SRC_PLUGINS,
+ PIDGIN_PREFS_ROOT "/vvconfig/audio/src/plugin",
+ PIDGIN_PREFS_ROOT "/vvconfig/audio/src/device");
+ make_vv_frame(vbox, sg, _("Output"), AUDIO_SINK_PLUGINS,
+ PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/plugin",
+ PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/device");
+ make_voice_test(vbox);
+
+ vbox = pidgin_make_frame(ret, _("Video"));
+ make_vv_frame(vbox, sg, _("Input"), VIDEO_SRC_PLUGINS,
+ PIDGIN_PREFS_ROOT "/vvconfig/video/src/plugin",
+ PIDGIN_PREFS_ROOT "/vvconfig/video/src/device");
+ make_vv_frame(vbox, sg, _("Output"), VIDEO_SINK_PLUGINS,
+ PIDGIN_PREFS_ROOT "/vvconfig/video/sink/plugin",
+ PIDGIN_PREFS_ROOT "/vvconfig/video/sink/device");
+ make_video_test(vbox);
+
+ gtk_widget_show_all(ret);
+
+ return ret;
+}
+#endif
+
static int
prefs_notebook_add_page(const char *text, GtkWidget *page, int ind)
{
@@ -2768,6 +3451,9 @@ prefs_notebook_init(void)
prefs_notebook_add_page(_("Sounds"), sound_page(), notebook_page++);
prefs_notebook_add_page(_("Status / Idle"), away_page(), notebook_page++);
prefs_notebook_add_page(_("Themes"), theme_page(), notebook_page++);
+#if USE_VV
+ prefs_notebook_add_page(_("Voice/Video"), vv_page(), notebook_page++);
+#endif
}
void
@@ -2891,6 +3577,26 @@ pidgin_prefs_init(void)
purple_prefs_connect_callback(&prefs, PIDGIN_PREFS_ROOT "/smileys/theme",
smiley_theme_pref_cb, NULL);
+#if USE_VV
+ /* Voice/Video */
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/audio");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/audio/src");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/src/plugin", "");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/src/device", "");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/audio/sink");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/plugin", "");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/device", "");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/video");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/video/src");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/video/src/plugin", "");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/video/src/device", "");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/video");
+ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig/video/sink");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/video/sink/plugin", "");
+ purple_prefs_add_string(PIDGIN_PREFS_ROOT "/vvconfig/video/sink/device", "");
+#endif
+
pidgin_prefs_update_old();
}
@@ -2987,4 +3693,42 @@ pidgin_prefs_update_old(void)
PIDGIN_PREFS_ROOT "/conversations/im/x");
purple_prefs_rename(PIDGIN_PREFS_ROOT "/conversations/y",
PIDGIN_PREFS_ROOT "/conversations/im/y");
+
+ /* Fixup vvconfig plugin prefs */
+ if (purple_prefs_exists("/plugins/core/vvconfig/audio/src/plugin")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/src/plugin",
+ purple_prefs_get_string("/plugins/core/vvconfig/audio/src/plugin"));
+ }
+ if (purple_prefs_exists("/plugins/core/vvconfig/audio/src/device")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/src/device",
+ purple_prefs_get_string("/plugins/core/vvconfig/audio/src/device"));
+ }
+ if (purple_prefs_exists("/plugins/core/vvconfig/audio/sink/plugin")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/plugin",
+ purple_prefs_get_string("/plugins/core/vvconfig/audio/sink/plugin"));
+ }
+ if (purple_prefs_exists("/plugins/core/vvconfig/audio/sink/device")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/audio/sink/device",
+ purple_prefs_get_string("/plugins/core/vvconfig/audio/sink/device"));
+ }
+ if (purple_prefs_exists("/plugins/core/vvconfig/video/src/plugin")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/video/src/plugin",
+ purple_prefs_get_string("/plugins/core/vvconfig/video/src/plugin"));
+ }
+ if (purple_prefs_exists("/plugins/core/vvconfig/video/src/device")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/video/src/device",
+ purple_prefs_get_string("/plugins/core/vvconfig/video/src/device"));
+ }
+ if (purple_prefs_exists("/plugins/gtk/vvconfig/video/sink/plugin")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/video/sink/plugin",
+ purple_prefs_get_string("/plugins/gtk/vvconfig/video/sink/plugin"));
+ }
+ if (purple_prefs_exists("/plugins/gtk/vvconfig/video/sink/device")) {
+ purple_prefs_set_string(PIDGIN_PREFS_ROOT "/vvconfig/video/sink/device",
+ purple_prefs_get_string("/plugins/gtk/vvconfig/video/sink/device"));
+ }
+
+ purple_prefs_remove("/plugins/core/vvconfig");
+ purple_prefs_remove("/plugins/gtk/vvconfig");
}
+
diff --git a/pidgin/gtksound.c b/pidgin/gtksound.c
index e8e96d5..ee61885 100644
--- a/pidgin/gtksound.c
+++ b/pidgin/gtksound.c
@@ -319,9 +319,6 @@ pidgin_sound_init(void)
#ifdef USE_GSTREAMER
purple_debug_info("sound", "Initializing sound output drivers.\n");
-#ifdef GST_CAN_DISABLE_FORKING
- gst_registry_fork_set_enabled (FALSE);
-#endif
if ((gst_init_failed = !gst_init_check(NULL, NULL, &error))) {
purple_notify_error(NULL, _("GStreamer Failure"),
_("GStreamer failed to initialize."),
@@ -530,7 +527,11 @@ pidgin_sound_play_file(const char *filename)
return;
}
+#if GST_CHECK_VERSION(1,0,0)
play = gst_element_factory_make("playbin", "play");
+#else
+ play = gst_element_factory_make("playbin2", "play");
+#endif
if (play == NULL) {
return;
diff --git a/pidgin/pidgin.h b/pidgin/pidgin.h
index 3319f1e..51ff366 100644
--- a/pidgin/pidgin.h
+++ b/pidgin/pidgin.h
@@ -29,10 +29,6 @@
#include <gtk/gtk.h>
-#ifdef GDK_WINDOWING_X11
-# include <gdk/gdkx.h>
-#endif
-
#ifdef _WIN32
# include "gtkwin32dep.h"
#endif
diff --git a/pidgin/plugins/Makefile.am b/pidgin/plugins/Makefile.am
index 3bb8c22..a877767 100644
--- a/pidgin/plugins/Makefile.am
+++ b/pidgin/plugins/Makefile.am
@@ -70,10 +70,6 @@ plugin_LTLIBRARIES = \
timestamp_format.la \
xmppconsole.la
-if USE_VV
-plugin_LTLIBRARIES += vvconfig.la
-endif
-
if ENABLE_UNITY
plugin_LTLIBRARIES += unity.la
endif