# HG changeset patch # User Mike Ruprecht # Date 1211864110 0 # Node ID e17dbd941380f93a8477759aec7388795f4430b6 # Parent f47be691e5881cd57c53c60b579184e86148e783# Parent 5f4807116f8cfacfbfe321dc80f12802b8129467 merge of '0685fc29468269a2af68268baa627b09f83339e4' and '8222acabc1382453e8dda5b8d507e4df0f0a91ff' diff -r f47be691e588 -r e17dbd941380 configure.ac --- a/configure.ac Tue May 27 04:54:12 2008 +0000 +++ b/configure.ac Tue May 27 04:55:10 2008 +0000 @@ -724,16 +724,15 @@ dnl ####################################################################### dnl # Check for Farsight dnl ####################################################################### -AC_ARG_ENABLE(farsight2, +AC_ARG_ENABLE(vv, [AC_HELP_STRING([--disable-vv], [compile without voice and video support])], enable_farsight="$enableval", enable_farsight="yes") if test "x$enable_farsight" != "xno"; then - PKG_CHECK_MODULES(FARSIGHT, [farsight2-0.10], [ + PKG_CHECK_MODULES(FARSIGHT, [farsight2-0.10 gstreamer-0.10 gstreamer-plugins-base-0.10 libxml-2.0], [ AC_DEFINE(USE_FARSIGHT, 1, [Use Farsight for voice and video]) AC_SUBST(FARSIGHT_CFLAGS) AC_SUBST(FARSIGHT_LIBS) ], [ - AC_MSG_RESULT(no) enable_farsight="no" ]) fi @@ -755,7 +754,6 @@ AC_SUBST(GSTPROPS_LIBS) AC_SUBST(GSTPROPS_CFLAGS) ], [ - AC_MSG_RESULT(no) enable_gstprops="no" ]) fi diff -r f47be691e588 -r e17dbd941380 finch/gntmedia.c --- a/finch/gntmedia.c Tue May 27 04:54:12 2008 +0000 +++ b/finch/gntmedia.c Tue May 27 04:55:10 2008 +0000 @@ -388,8 +388,6 @@ NULL)); } -#endif /* USE_FARSIGHT */ - static void gntmedia_message_cb(FinchMedia *gntmedia, const char *msg, PurpleConversation *conv) { @@ -456,3 +454,5 @@ G_CALLBACK(finch_new_media), NULL); } +#endif /* USE_FARSIGHT */ + diff -r f47be691e588 -r e17dbd941380 finch/gntui.c --- a/finch/gntui.c Tue May 27 04:54:12 2008 +0000 +++ b/finch/gntui.c Tue May 27 04:55:10 2008 +0000 @@ -92,8 +92,10 @@ finch_roomlist_init(); purple_roomlist_set_ui_ops(finch_roomlist_get_ui_ops()); +#ifdef USE_FARSIGHT /* Media */ finch_media_manager_init(); +#endif gnt_register_action(_("Accounts"), finch_accounts_show_all); gnt_register_action(_("Buddy List"), finch_blist_show); @@ -140,7 +142,9 @@ finch_roomlist_uninit(); purple_roomlist_set_ui_ops(NULL); +#ifdef USE_FARSIGHT finch_media_manager_uninit(); +#endif gnt_quit(); #endif diff -r f47be691e588 -r e17dbd941380 libpurple/media.c --- a/libpurple/media.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/media.c Tue May 27 04:55:10 2008 +0000 @@ -546,7 +546,7 @@ !GST_IS_PROPERTY_PROBE (element) || !(probe = GST_PROPERTY_PROBE (element)) || !(pspec = gst_property_probe_get_property (probe, "device"))) { - purple_debug_info("Found source '%s' (%s) - no device", + purple_debug_info("media", "Found source '%s' (%s) - no device\n", longname, GST_PLUGIN_FEATURE (factory)->name); } else { gint n; @@ -571,6 +571,12 @@ gst_element_set_state (element, GST_STATE_NULL); ret = g_list_append(ret, device); + + name = purple_media_get_device_name(GST_ELEMENT(element), device); + purple_debug_info("media", "Found source '%s' (%s) - device '%s' (%s)\n", + longname, GST_PLUGIN_FEATURE (factory)->name, + name, g_value_get_string(device)); + g_free(name); } } } @@ -704,7 +710,7 @@ gst_element_set_state(pipeline, GST_STATE_PLAYING); } -static void +static gboolean purple_media_add_stream_internal(PurpleMedia *media, FsSession **session, GList **streams, GstElement *src, const gchar *who, FsMediaType type, FsStreamDirection type_direction, const gchar *transmitter) @@ -718,7 +724,18 @@ FsSession *s = NULL; if (!*session) { - *session = fs_conference_new_session(media->priv->conference, type, NULL); + GError *err = NULL; + *session = fs_conference_new_session(media->priv->conference, type, &err); + + if (err != NULL) { + purple_debug_error("media", "Error creating session: %s\n", err->message); + g_error_free(err); + purple_conv_present_error(who, + purple_connection_get_account(purple_media_get_connection(media)), + _("Error creating session.")); + return FALSE; + } + if (src) { GstPad *sinkpad; GstPad *srcpad; @@ -776,9 +793,11 @@ /* change direction */ g_object_set(stream, "direction", type_direction, NULL); } + + return TRUE; } -void +gboolean purple_media_add_stream(PurpleMedia *media, const gchar *who, PurpleMediaStreamType type, const gchar *transmitter) @@ -795,11 +814,13 @@ else type_direction = FS_DIRECTION_NONE; - purple_media_add_stream_internal(media, &media->priv->audio_session, - &media->priv->audio_streams, - media->priv->audio_src, who, - FS_MEDIA_TYPE_AUDIO, type_direction, - transmitter); + if (!purple_media_add_stream_internal(media, &media->priv->audio_session, + &media->priv->audio_streams, + media->priv->audio_src, who, + FS_MEDIA_TYPE_AUDIO, type_direction, + transmitter)) { + return FALSE; + } } if (type & PURPLE_MEDIA_VIDEO) { if (type & PURPLE_MEDIA_SEND_VIDEO && type & PURPLE_MEDIA_RECV_VIDEO) @@ -811,12 +832,15 @@ else type_direction = FS_DIRECTION_NONE; - purple_media_add_stream_internal(media, &media->priv->video_session, - &media->priv->video_streams, - media->priv->video_src, who, - FS_MEDIA_TYPE_VIDEO, type_direction, - transmitter); + if (!purple_media_add_stream_internal(media, &media->priv->video_session, + &media->priv->video_streams, + media->priv->video_src, who, + FS_MEDIA_TYPE_VIDEO, type_direction, + transmitter)) { + return FALSE; + } } + return TRUE; } void diff -r f47be691e588 -r e17dbd941380 libpurple/media.h --- a/libpurple/media.h Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/media.h Tue May 27 04:55:10 2008 +0000 @@ -113,7 +113,7 @@ void purple_media_audio_init_recv(GstElement **recvbin, GstElement **recvlevel); -void purple_media_add_stream(PurpleMedia *media, const gchar *who, +gboolean purple_media_add_stream(PurpleMedia *media, const gchar *who, PurpleMediaStreamType type, const gchar *transmitter); void purple_media_remove_stream(PurpleMedia *media, const gchar *who, PurpleMediaStreamType type); diff -r f47be691e588 -r e17dbd941380 libpurple/mediamanager.c --- a/libpurple/mediamanager.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/mediamanager.c Tue May 27 04:55:10 2008 +0000 @@ -133,13 +133,22 @@ const char *conference_type, const char *remote_user) { + PurpleMedia *media; FsConference *conference = FS_CONFERENCE(gst_element_factory_make(conference_type, NULL)); + GstStateChangeReturn ret = gst_element_set_state(GST_ELEMENT(conference), GST_STATE_READY); - PurpleMedia *media = PURPLE_MEDIA(g_object_new(purple_media_get_type(), - "screenname", remote_user, - "connection", gc, - "farsight-conference", conference, - NULL)); + if (ret == GST_STATE_CHANGE_FAILURE) { + purple_conv_present_error(remote_user, + purple_connection_get_account(gc), + _("Error creating conference.")); + return NULL; + } + + media = PURPLE_MEDIA(g_object_new(purple_media_get_type(), + "screenname", remote_user, + "connection", gc, + "farsight-conference", conference, + NULL)); manager->priv->medias = g_list_append(manager->priv->medias, media); g_signal_emit(manager, purple_media_manager_signals[INIT_MEDIA], 0, media); return media; diff -r f47be691e588 -r e17dbd941380 libpurple/protocols/jabber/google.c --- a/libpurple/protocols/jabber/google.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/protocols/jabber/google.c Tue May 27 04:55:10 2008 +0000 @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include - #include "internal.h" #include "debug.h" #include "mediamanager.h" @@ -32,6 +30,9 @@ #include "presence.h" #include "iq.h" +#ifdef USE_FARSIGHT +#include + typedef struct { char *id; char *initiator; @@ -323,10 +324,12 @@ google_session_handle_candidates(js, session, packet, sess); } } +#endif /* USE_FARSIGHT */ void jabber_google_session_parse(JabberStream *js, xmlnode *packet) { +#ifdef USE_FARSIGHT GoogleSession *session; GoogleSessionId id; @@ -372,6 +375,9 @@ g_hash_table_insert(sessions, &(session->id), session); google_session_parse_iq(js, session, packet); +#else + /* TODO: send proper error response */ +#endif /* USE_FARSIGHT */ } static void diff -r f47be691e588 -r e17dbd941380 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Tue May 27 04:55:10 2008 +0000 @@ -58,7 +58,9 @@ #include "adhoccommands.h" #include "jingle.h" +#ifdef USE_FARSIGHT #include +#endif #define JABBER_CONNECT_STEPS (js->gsc ? 9 : 5) @@ -632,6 +634,10 @@ js->keepalive_timeout = -1; js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain); +#ifdef USE_FARSIGHT + js->sessions = NULL; +#endif + if(!js->user) { purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, @@ -1244,12 +1250,15 @@ #ifdef USE_FARSIGHT /* Close all of the open media sessions on this stream */ - GList *iter = jabber_jingle_session_find_by_js(js); + GList *values = g_hash_table_get_values(js->sessions); + GList *iter = values; for (; iter; iter = iter->next) { JingleSession *session = (JingleSession *)iter->data; purple_media_hangup(session->media); } + + g_list_free(values); #endif /* Don't perform any actions on the ssl connection @@ -2475,15 +2484,25 @@ } } -static void +static gboolean jabber_initiate_media_internal(JingleSession *session, const char *initiator, const char *remote_jid) { PurpleMedia *media = NULL; media = purple_media_manager_create_media(purple_media_manager_get(), session->js->gc, "fsrtpconference", remote_jid); + + if (!media) { + purple_debug_error("jabber", "Couldn't create fsrtpconference\n"); + return FALSE; + } + /* this will need to be changed to "nice" once the libnice transmitter is finished */ - purple_media_add_stream(media, remote_jid, PURPLE_MEDIA_AUDIO, "rawudp"); + if (!purple_media_add_stream(media, remote_jid, PURPLE_MEDIA_AUDIO, "rawudp")) { + purple_debug_error("jabber", "Couldn't create audio stream\n"); + purple_media_reject(media); + return FALSE; + } jabber_jingle_session_set_remote_jid(session, remote_jid); jabber_jingle_session_set_initiator(session, initiator); @@ -2502,6 +2521,8 @@ G_CALLBACK(jabber_session_candidate_pair_established), session); purple_media_ready(media); + + return TRUE; } static void @@ -2572,7 +2593,12 @@ /* set ourselves as initiator */ me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, js->user->resource); - jabber_initiate_media_internal(session, me, jid); + if (!jabber_initiate_media_internal(session, me, jid)) { + g_free(jid); + g_free(me); + jabber_jingle_session_destroy(session); + return NULL; + } g_free(jid); g_free(me); @@ -2625,7 +2651,7 @@ xmlnode *content = xmlnode_get_child(jingle, "content"); const char *sid = xmlnode_get_attrib(jingle, "sid"); const char *action = xmlnode_get_attrib(jingle, "action"); - JingleSession *session = jabber_jingle_session_find_by_id(sid); + JingleSession *session = jabber_jingle_session_find_by_id(js, sid); GList *remote_codecs = NULL; GList *remote_transports = NULL; GList *codec_intersection; @@ -2706,7 +2732,12 @@ JabberIq *result = jabber_iq_new(js, JABBER_IQ_SET); xmlnode *jingle = xmlnode_get_child(packet, "jingle"); const char *sid = xmlnode_get_attrib(jingle, "sid"); - JingleSession *session = jabber_jingle_session_find_by_id(sid); + JingleSession *session = jabber_jingle_session_find_by_id(js, sid); + + if(!session) { + purple_debug_error("jabber", "jabber_handle_session_terminate couldn't find session\n"); + return; + } xmlnode_set_attrib(result->node, "to", jabber_jingle_session_get_remote_jid(session)); @@ -2732,7 +2763,7 @@ xmlnode *transport = xmlnode_get_child(content, "transport"); GList *remote_candidates = jabber_jingle_get_candidates(transport); const char *sid = xmlnode_get_attrib(jingle, "sid"); - JingleSession *session = jabber_jingle_session_find_by_id(sid); + JingleSession *session = jabber_jingle_session_find_by_id(js, sid); if(!session) purple_debug_error("jabber", "jabber_handle_session_candidates couldn't find session\n"); @@ -2757,7 +2788,7 @@ { xmlnode *jingle = xmlnode_get_child(packet, "jingle"); const char *sid = xmlnode_get_attrib(jingle, "sid"); - JingleSession *session = jabber_jingle_session_find_by_id(sid); + JingleSession *session = jabber_jingle_session_find_by_id(js, sid); if (!jabber_jingle_session_is_initiator(session) && session->session_started) { JabberIq *result = jabber_iq_new(js, JABBER_IQ_RESULT); @@ -2799,7 +2830,7 @@ sid = xmlnode_get_attrib(jingle, "sid"); initiator = xmlnode_get_attrib(jingle, "initiator"); - if (jabber_jingle_session_find_by_id(sid)) { + if (jabber_jingle_session_find_by_id(js, sid)) { /* This should only happen if you start a session with yourself */ purple_debug_error("jabber", "Jingle session with id={%s} already exists\n", sid); return; @@ -2822,7 +2853,12 @@ return; } - jabber_initiate_media_internal(session, initiator, initiator); + if (!jabber_initiate_media_internal(session, initiator, initiator)) { + purple_debug_error("jabber", "Couldn't start media session with %s\n", initiator); + jabber_jingle_session_destroy(session); + /* we should create an error iq here */ + return; + } codecs = jabber_jingle_get_codecs(description); diff -r f47be691e588 -r e17dbd941380 libpurple/protocols/jabber/jabber.h --- a/libpurple/protocols/jabber/jabber.h Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.h Tue May 27 04:55:10 2008 +0000 @@ -203,6 +203,11 @@ /* A purple timeout tag for the keepalive */ int keepalive_timeout; + +#ifdef USE_FARSIGHT + /* keep a hash table of JingleSessions */ + GHashTable *sessions; +#endif }; typedef gboolean (JabberFeatureEnabled)(JabberStream *js, const gchar *shortname, const gchar *namespace); diff -r f47be691e588 -r e17dbd941380 libpurple/protocols/jabber/jingle.c --- a/libpurple/protocols/jabber/jingle.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/protocols/jabber/jingle.c Tue May 27 04:55:10 2008 +0000 @@ -30,9 +30,6 @@ #include -/* keep a hash table of JingleSessions */ -static GHashTable *sessions = NULL; - static gboolean jabber_jingle_session_equal(gconstpointer a, gconstpointer b) { @@ -58,13 +55,13 @@ } /* insert it into the hash table */ - if (!sessions) { + if (!js->sessions) { purple_debug_info("jingle", "Creating hash table for sessions\n"); - sessions = g_hash_table_new(g_str_hash, g_str_equal); + js->sessions = g_hash_table_new(g_str_hash, g_str_equal); } purple_debug_info("jingle", "inserting session with key: %s into table\n", sess->id); - g_hash_table_insert(sessions, sess->id, sess); + g_hash_table_insert(js->sessions, sess->id, sess); sess->session_started = FALSE; @@ -102,43 +99,25 @@ void jabber_jingle_session_destroy(JingleSession *sess) { - g_hash_table_remove(sessions, sess->id); + g_hash_table_remove(sess->js->sessions, sess->id); g_free(sess->id); g_free(sess); } JingleSession * -jabber_jingle_session_find_by_id(const char *id) +jabber_jingle_session_find_by_id(JabberStream *js, const char *id) { purple_debug_info("jingle", "find_by_id %s\n", id); - purple_debug_info("jingle", "hash table: %p\n", sessions); + purple_debug_info("jingle", "hash table: %p\n", js->sessions); purple_debug_info("jingle", "hash table size %d\n", - g_hash_table_size(sessions)); - purple_debug_info("jingle", "lookup: %p\n", g_hash_table_lookup(sessions, id)); - return (JingleSession *) g_hash_table_lookup(sessions, id); -} - -GList * -jabber_jingle_session_find_by_js(JabberStream *js) -{ - GList *values = g_hash_table_get_values(sessions); - GList *iter = values; - GList *found = NULL; - - for (; iter; iter = iter->next) { - JingleSession *session = (JingleSession *)iter->data; - if (session->js == js) { - found = g_list_prepend(found, session); - } - } - - g_list_free(values); - return found; + g_hash_table_size(js->sessions)); + purple_debug_info("jingle", "lookup: %p\n", g_hash_table_lookup(js->sessions, id)); + return (JingleSession *) g_hash_table_lookup(js->sessions, id); } JingleSession *jabber_jingle_session_find_by_jid(JabberStream *js, const char *jid) { - GList *values = g_hash_table_get_values(sessions); + GList *values = g_hash_table_get_values(js->sessions); GList *iter = values; for (; iter; iter = iter->next) { diff -r f47be691e588 -r e17dbd941380 libpurple/protocols/jabber/jingle.h --- a/libpurple/protocols/jabber/jingle.h Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/protocols/jabber/jingle.h Tue May 27 04:55:10 2008 +0000 @@ -47,8 +47,7 @@ void jabber_jingle_session_destroy(JingleSession *sess); -JingleSession *jabber_jingle_session_find_by_id(const char *id); -GList *jabber_jingle_session_find_by_js(JabberStream *js); +JingleSession *jabber_jingle_session_find_by_id(JabberStream *js, const char *id); JingleSession *jabber_jingle_session_find_by_jid(JabberStream *js, const char *jid); PurpleMedia *jabber_jingle_session_get_media(const JingleSession *sess); diff -r f47be691e588 -r e17dbd941380 libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Tue May 27 04:55:10 2008 +0000 @@ -116,8 +116,13 @@ jabber_send_attention, /* send_attention */ jabber_attention_types, /* attention_types */ sizeof(PurplePluginProtocolInfo), /* struct_size */ +#ifdef USE_FARSIGHT jabber_initiate_media, /* initiate_media */ jabber_can_do_media /* can_do_media */ +#else + NULL, /* initiate_media */ + NULL /* can_do_media */ +#endif }; static gboolean load_plugin(PurplePlugin *plugin) diff -r f47be691e588 -r e17dbd941380 libpurple/server.c --- a/libpurple/server.c Tue May 27 04:54:12 2008 +0000 +++ b/libpurple/server.c Tue May 27 04:55:10 2008 +0000 @@ -1083,5 +1083,18 @@ return FALSE; } } - -#endif +#else +void * +serv_initiate_media(void *gc, void *who, void *type) +{ + purple_debug_info("serv", "Blank serv_initiate_media called\n"); + return NULL; +} + +void * +serv_can_do_media(void *gc, void *who, void *type) +{ + purple_debug_info("serv", "Blank serv_can_do_media called\n"); + return NULL; +} +#endif /* USE_FARSIGHT */ diff -r f47be691e588 -r e17dbd941380 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Tue May 27 04:54:12 2008 +0000 +++ b/pidgin/gtkconv.c Tue May 27 04:55:10 2008 +0000 @@ -7694,7 +7694,8 @@ purple_conversation_get_name(conv), PURPLE_MEDIA_RECV_AUDIO & PURPLE_MEDIA_SEND_AUDIO); - purple_media_wait(media); + if (media) + purple_media_wait(media); } static void @@ -7827,9 +7828,10 @@ show_protocol_icons_pref_cb, NULL); purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new", hide_new_pref_cb, NULL); - +#ifdef USE_FARSIGHT g_signal_connect(G_OBJECT(purple_media_manager_get()), "init-media", G_CALLBACK(pidgin_conv_new_media_cb), NULL); +#endif /********************************************************************** diff -r f47be691e588 -r e17dbd941380 pidgin/gtkmedia.c --- a/pidgin/gtkmedia.c Tue May 27 04:54:12 2008 +0000 +++ b/pidgin/gtkmedia.c Tue May 27 04:55:10 2008 +0000 @@ -228,7 +228,9 @@ gulong handler_id = g_signal_handler_find(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, G_CALLBACK(level_message_cb), gtkmedia); - g_signal_handler_disconnect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), handler_id); + if (handler_id) + g_signal_handler_disconnect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), + handler_id); } static void diff -r f47be691e588 -r e17dbd941380 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Tue May 27 04:54:12 2008 +0000 +++ b/pidgin/gtkprefs.c Tue May 27 04:55:10 2008 +0000 @@ -1920,9 +1920,9 @@ GList *ret = NULL; for(; devices ; devices = devices->next) { - gchar *name = purple_media_get_device_name(element, devices->data); + gchar *name = purple_media_get_device_name(GST_ELEMENT(element), devices->data); ret = g_list_append(ret, name); - ret = g_list_append(ret, name); + ret = g_list_append(ret, g_value_dup_string(devices->data)); } return ret; @@ -1930,36 +1930,132 @@ /* * Test functions to run video preview - * (this is not really functional right now...) - * */ +static gboolean +preview_video_bus_call(GstBus *bus, GstMessage *msg, gpointer pipeline) +{ + switch(GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: + purple_debug_info("preview-video", "End of Stream\n"); + break; + case GST_MESSAGE_ERROR: { + gchar *debug = NULL; + GError *err = NULL; + + gst_message_parse_error(msg, &err, &debug); + + purple_debug_error("preview-video", "Error: %s\n", err->message); + g_error_free(err); + + if (debug) { + purple_debug_error("preview-video", "details: %s\n", debug); + g_free (debug); + } + break; + } + default: + return TRUE; + } + + gst_element_set_state(pipeline, GST_STATE_NULL); + gst_object_unref(GST_PIPELINE(pipeline)); + return TRUE; +} + static void preview_button_clicked(GtkWidget *widget, gpointer *data) { - GstElement *video = (GstElement *) data; + const char *plugin = purple_prefs_get_string("/purple/media/video/plugin"); + const char *device = purple_prefs_get_string("/purple/media/video/device"); + GstBus *bus; /* create a preview window... */ - GstElement *output = gst_element_factory_make("autovideosink", NULL); GstElement *pipeline = NULL; GError *p_err; - gchar test_pipeline_str[50] = "v4lsrc ! ffmpegcolorspace ! autovideosink"; + gchar *test_pipeline_str = NULL; + + if (strlen(device) > 0) + test_pipeline_str = g_strdup_printf("%s device=\"%s\" !" \ + " ffmpegcolorspace !" \ + " autovideosink", + plugin, device); + else + test_pipeline_str = g_strdup_printf("%s ! ffmpegcolorspace !" \ + " autovideosink", plugin); + pipeline = gst_parse_launch (test_pipeline_str, &p_err); + g_free(test_pipeline_str); + + bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); + gst_bus_add_watch(bus, preview_video_bus_call, pipeline); + gst_object_unref(bus); + gst_element_set_state(pipeline, GST_STATE_PLAYING); } +static void +media_plugin_changed_cb(const gchar *name, PurplePrefType type, + gconstpointer value, gpointer data) +{ + GtkWidget *hbox = data; + GtkWidget *dd = NULL; + GtkWidget *preview_button = NULL; + const char *plugin = value; + const char *device = purple_prefs_get_string("/purple/media/video/device"); + GstElement *video = purple_media_get_element(plugin); + GList *video_devices = purple_media_get_devices(video); + GList *video_items = get_device_items(video, video_devices); + GList *list; + g_list_free(video_devices); + + if (video_items == NULL) { + video_items = g_list_prepend(video_items, g_strdup("")); + video_items = g_list_prepend(video_items, g_strdup("Default")); + } + + if (g_list_find(video_items, device) == NULL) + { + purple_prefs_set_string("/purple/media/video/device", + g_list_next(video_items)->data); + } + + list = gtk_container_get_children(GTK_CONTAINER(hbox)); + + while (list) { + gtk_widget_destroy(list->data); + list = g_list_delete_link(list, list); + } + + dd = pidgin_prefs_dropdown_from_list(hbox, _("_Device:"), PURPLE_PREF_STRING, + "/purple/media/video/device", + video_items); + + gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); + + preview_button = gtk_button_new_with_mnemonic(_("_Preview")); + g_signal_connect(G_OBJECT(preview_button), "clicked", + G_CALLBACK(preview_button_clicked), video); + + gtk_container_add(GTK_CONTAINER(hbox), preview_button); + + gtk_widget_show_all(hbox); +} + static GtkWidget * media_page() { GtkWidget *ret; - GtkWidget *sg; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *dd; GtkWidget *preview_button; - - GstElement *video = purple_media_get_element("v4lsrc"); + GtkSizeGroup *sg; + const char *plugin = purple_prefs_get_string("/purple/media/video/plugin"); + const char *device = purple_prefs_get_string("/purple/media/video/device"); + + GstElement *video = purple_media_get_element(plugin); GstElement *audio = purple_media_get_element("alsasrc"); GList *video_devices = purple_media_get_devices(video); @@ -1971,17 +2067,46 @@ g_list_free(video_devices); g_list_free(audio_devices); + if (video_items == NULL) { + video_items = g_list_prepend(video_items, ""); + video_items = g_list_prepend(video_items, "Default"); + } + + if (g_list_find(video_items, device) == NULL) + { + purple_prefs_set_string("/purple/media/video/device", + g_list_next(video_items)->data); + } + ret = gtk_vbox_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, _("Video Input")); + + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); + dd = pidgin_prefs_dropdown(vbox, _("_Plugin:"), PURPLE_PREF_STRING, + "/purple/media/video/plugin", + _("Default"), "gconfvideosrc", + _("Video4Linux"), "v4lsrc", + _("Video4Linux2"), "v4l2src", + NULL); + + gtk_size_group_add_widget(sg, dd); + gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); + hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); dd = pidgin_prefs_dropdown_from_list(hbox, _("_Device:"), PURPLE_PREF_STRING, "/purple/media/video/device", video_items); + purple_prefs_connect_callback(prefs, "/purple/media/video/plugin", + media_plugin_changed_cb, hbox); + + g_signal_connect_swapped(hbox, "destroy", + G_CALLBACK(purple_prefs_disconnect_by_handle), hbox); + gtk_size_group_add_widget(sg, dd); gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); @@ -1989,8 +2114,8 @@ g_signal_connect(G_OBJECT(preview_button), "clicked", G_CALLBACK(preview_button_clicked), video); - gtk_container_add(hbox, preview_button); - gtk_container_add(vbox, hbox); + gtk_container_add(GTK_CONTAINER(hbox), preview_button); + gtk_container_add(GTK_CONTAINER(vbox), hbox); vbox = pidgin_make_frame (ret, _("Audio Input")); dd = pidgin_prefs_dropdown_from_list(vbox, _("_Device:"), PURPLE_PREF_STRING, @@ -2135,7 +2260,7 @@ prefs_notebook_add_page(_("Smiley Themes"), theme_page(), notebook_page++); prefs_notebook_add_page(_("Sounds"), sound_page(), notebook_page++); -#if USE_FARSIGHT +#ifdef USE_FARSIGHT prefs_notebook_add_page(_("Media"), media_page(), notebook_page++); #endif prefs_notebook_add_page(_("Network"), network_page(), notebook_page++); @@ -2266,6 +2391,7 @@ #ifdef USE_FARSIGHT purple_prefs_add_none("/purple/media"); purple_prefs_add_none("/purple/media/video"); + purple_prefs_add_string("/purple/media/video/plugin", "gconfvideosrc"); purple_prefs_add_string("/purple/media/video/device", ""); purple_prefs_add_none("/purple/media/audio"); purple_prefs_add_string("/purple/media/audio/device", "");