Mercurial > pidgin
diff libpurple/mediamanager.c @ 26402:081a819bc710
Hide and gobjectify PurpleMediaElementInfo.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Thu, 02 Apr 2009 00:11:49 +0000 |
parents | 84d09c6499f1 |
children | 86c5499f36e8 |
line wrap: on
line diff
--- a/libpurple/mediamanager.c Wed Apr 01 23:43:38 2009 +0000 +++ b/libpurple/mediamanager.c Thu Apr 02 00:11:49 2009 +0000 @@ -42,6 +42,8 @@ typedef struct _PurpleMediaManagerPrivate PurpleMediaManagerPrivate; /** @copydoc _PurpleMediaOutputWindow */ typedef struct _PurpleMediaOutputWindow PurpleMediaOutputWindow; +/** @copydoc _PurpleMediaManagerPrivate */ +typedef struct _PurpleMediaElementInfoPrivate PurpleMediaElementInfoPrivate; /** The media manager class. */ struct _PurpleMediaManagerClass @@ -83,6 +85,7 @@ }; #define PURPLE_MEDIA_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA_MANAGER, PurpleMediaManagerPrivate)) +#define PURPLE_MEDIA_ELEMENT_INFO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA_ELEMENT_INFO, PurpleMediaElementInfoPrivate)) static void purple_media_manager_class_init (PurpleMediaManagerClass *klass); static void purple_media_manager_init (PurpleMediaManager *media); @@ -98,15 +101,6 @@ }; static guint purple_media_manager_signals[LAST_SIGNAL] = {0}; -enum { - PROP_0, - PROP_FARSIGHT_SESSION, - PROP_NAME, - PROP_CONNECTION, - PROP_MIC_ELEMENT, - PROP_SPEAKER_ELEMENT, -}; - GType purple_media_manager_get_type() { @@ -166,7 +160,9 @@ g_object_unref(priv->medias->data); } for (; priv->elements; priv->elements = - g_list_delete_link(priv->elements, priv->elements)); + g_list_delete_link(priv->elements, priv->elements)) { + g_object_unref(priv->elements->data); + } parent_class->finalize(media); } @@ -375,6 +371,7 @@ #ifdef USE_VV GstElement *ret = NULL; PurpleMediaElementInfo *info = NULL; + PurpleMediaElementType element_type; if (type & PURPLE_MEDIA_SEND_AUDIO) info = manager->priv->audio_src; @@ -388,20 +385,24 @@ if (info == NULL) return NULL; - if (info->type & PURPLE_MEDIA_ELEMENT_UNIQUE && - info->type & PURPLE_MEDIA_ELEMENT_SRC) { + element_type = purple_media_element_info_get_element_type(info); + + if (element_type & PURPLE_MEDIA_ELEMENT_UNIQUE && + element_type & PURPLE_MEDIA_ELEMENT_SRC) { GstElement *tee; GstPad *pad; GstPad *ghost; + gchar *id = purple_media_element_info_get_id(info); ret = gst_bin_get_by_name(GST_BIN( purple_media_manager_get_pipeline( - manager)), info->id); + manager)), id); if (ret == NULL) { GstElement *bin, *fakesink; - ret = info->create(media, session_id, participant); - bin = gst_bin_new(info->id); + ret = purple_media_element_info_call_create(info, + media, session_id, participant); + bin = gst_bin_new(id); tee = gst_element_factory_make("tee", "tee"); gst_bin_add_many(GST_BIN(bin), ret, tee, NULL); gst_element_link(ret, tee); @@ -421,6 +422,7 @@ gst_bin_add(GST_BIN(purple_media_manager_get_pipeline( manager)), ret); } + g_free(id); tee = gst_bin_get_by_name(GST_BIN(ret), "tee"); pad = gst_element_get_request_pad(tee, "src%d"); @@ -432,7 +434,8 @@ gst_pad_set_active(ghost, TRUE); gst_element_add_pad(ret, ghost); } else { - ret = info->create(media, session_id, participant); + ret = purple_media_element_info_call_create(info, + media, session_id, participant); } if (ret == NULL) @@ -456,9 +459,14 @@ iter = manager->priv->elements; for (; iter; iter = g_list_next(iter)) { - PurpleMediaElementInfo *info = iter->data; - if (!strcmp(info->id, id)) - return info; + gchar *element_id = + purple_media_element_info_get_id(iter->data); + if (!strcmp(element_id, id)) { + g_free(element_id); + g_object_ref(iter->data); + return iter->data; + } + g_free(element_id); } #endif @@ -470,11 +478,21 @@ PurpleMediaElementInfo *info) { #ifdef USE_VV + PurpleMediaElementInfo *info2; + gchar *id; + g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE); g_return_val_if_fail(info != NULL, FALSE); - if (purple_media_manager_get_element_info(manager, info->id) != NULL) + id = purple_media_element_info_get_id(info); + info2 = purple_media_manager_get_element_info(manager, id); + g_free(id); + + if (info2 != NULL) { + g_object_unref(info2); return FALSE; + } + g_object_unref(info2); manager->priv->elements = g_list_prepend(manager->priv->elements, info); @@ -495,8 +513,10 @@ info = purple_media_manager_get_element_info(manager, id); - if (info == NULL) + if (info == NULL) { + g_object_unref(info); return FALSE; + } if (manager->priv->audio_src == info) manager->priv->audio_src = NULL; @@ -509,6 +529,7 @@ manager->priv->elements = g_list_remove( manager->priv->elements, info); + g_object_unref(info); return TRUE; #else return FALSE; @@ -520,30 +541,40 @@ PurpleMediaElementInfo *info) { #ifdef USE_VV + PurpleMediaElementInfo *info2; + PurpleMediaElementType type; gboolean ret = FALSE; + gchar *id; g_return_val_if_fail(PURPLE_IS_MEDIA_MANAGER(manager), FALSE); g_return_val_if_fail(info != NULL, FALSE); - if (purple_media_manager_get_element_info(manager, info->id) == NULL) - purple_media_manager_register_element(manager, info); + id = purple_media_element_info_get_id(info); + info2 = purple_media_manager_get_element_info(manager, id); + g_free(id); - if (info->type & PURPLE_MEDIA_ELEMENT_SRC) { - if (info->type & PURPLE_MEDIA_ELEMENT_AUDIO) { + if (info2 == NULL) + purple_media_manager_register_element(manager, info); + g_object_unref(info2); + + type = purple_media_element_info_get_element_type(info); + + if (type & PURPLE_MEDIA_ELEMENT_SRC) { + if (type & PURPLE_MEDIA_ELEMENT_AUDIO) { manager->priv->audio_src = info; ret = TRUE; } - if (info->type & PURPLE_MEDIA_ELEMENT_VIDEO) { + if (type & PURPLE_MEDIA_ELEMENT_VIDEO) { manager->priv->video_src = info; ret = TRUE; } } - if (info->type & PURPLE_MEDIA_ELEMENT_SINK) { - if (info->type & PURPLE_MEDIA_ELEMENT_AUDIO) { + if (type & PURPLE_MEDIA_ELEMENT_SINK) { + if (type & PURPLE_MEDIA_ELEMENT_AUDIO) { manager->priv->audio_sink = info; ret = TRUE; } - if (info->type & PURPLE_MEDIA_ELEMENT_VIDEO) { + if (type & PURPLE_MEDIA_ELEMENT_VIDEO) { manager->priv->video_sink = info; ret = TRUE; } @@ -803,3 +834,266 @@ #endif } + +/* + * PurpleMediaElementType + */ + +GType +purple_media_element_type_get_type() +{ + static GType type = 0; + if (type == 0) { + static const GFlagsValue values[] = { + { PURPLE_MEDIA_ELEMENT_NONE, + "PURPLE_MEDIA_ELEMENT_NONE", "none" }, + { PURPLE_MEDIA_ELEMENT_AUDIO, + "PURPLE_MEDIA_ELEMENT_AUDIO", "audio" }, + { PURPLE_MEDIA_ELEMENT_VIDEO, + "PURPLE_MEDIA_ELEMENT_VIDEO", "video" }, + { PURPLE_MEDIA_ELEMENT_AUDIO_VIDEO, + "PURPLE_MEDIA_ELEMENT_AUDIO_VIDEO", + "audio-video" }, + { PURPLE_MEDIA_ELEMENT_NO_SRCS, + "PURPLE_MEDIA_ELEMENT_NO_SRCS", "no-srcs" }, + { PURPLE_MEDIA_ELEMENT_ONE_SRC, + "PURPLE_MEDIA_ELEMENT_ONE_SRC", "one-src" }, + { PURPLE_MEDIA_ELEMENT_MULTI_SRC, + "PURPLE_MEDIA_ELEMENT_MULTI_SRC", + "multi-src" }, + { PURPLE_MEDIA_ELEMENT_REQUEST_SRC, + "PURPLE_MEDIA_ELEMENT_REQUEST_SRC", + "request-src" }, + { PURPLE_MEDIA_ELEMENT_NO_SINKS, + "PURPLE_MEDIA_ELEMENT_NO_SINKS", "no-sinks" }, + { PURPLE_MEDIA_ELEMENT_ONE_SINK, + "PURPLE_MEDIA_ELEMENT_ONE_SINK", "one-sink" }, + { PURPLE_MEDIA_ELEMENT_MULTI_SINK, + "PURPLE_MEDIA_ELEMENT_MULTI_SINK", + "multi-sink" }, + { PURPLE_MEDIA_ELEMENT_REQUEST_SINK, + "PURPLE_MEDIA_ELEMENT_REQUEST_SINK", + "request-sink" }, + { PURPLE_MEDIA_ELEMENT_UNIQUE, + "PURPLE_MEDIA_ELEMENT_UNIQUE", "unique" }, + { PURPLE_MEDIA_ELEMENT_SRC, + "PURPLE_MEDIA_ELEMENT_SRC", "src" }, + { PURPLE_MEDIA_ELEMENT_SINK, + "PURPLE_MEDIA_ELEMENT_SINK", "sink" }, + { 0, NULL, NULL } + }; + type = g_flags_register_static( + "PurpleMediaElementType", values); + } + return type; +} + +/* + * PurpleMediaElementInfo + */ + +struct _PurpleMediaElementInfoClass +{ + GObjectClass parent_class; +}; + +struct _PurpleMediaElementInfo +{ + GObject parent; +}; + +struct _PurpleMediaElementInfoPrivate +{ + gchar *id; + gchar *name; + PurpleMediaElementType type; + PurpleMediaElementCreateCallback create; +}; + +enum { + PROP_0, + PROP_ID, + PROP_NAME, + PROP_TYPE, + PROP_CREATE_CB, +}; + +static void +purple_media_element_info_init(PurpleMediaElementInfo *info) +{ + PurpleMediaElementInfoPrivate *priv = + PURPLE_MEDIA_ELEMENT_INFO_GET_PRIVATE(info); + priv->id = NULL; + priv->name = NULL; + priv->type = PURPLE_MEDIA_ELEMENT_NONE; + priv->create = NULL; +} + +static void +purple_media_element_info_finalize(GObject *info) +{ + PurpleMediaElementInfoPrivate *priv = + PURPLE_MEDIA_ELEMENT_INFO_GET_PRIVATE(info); + g_free(priv->id); + g_free(priv->name); +} + +static void +purple_media_element_info_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + PurpleMediaElementInfoPrivate *priv; + g_return_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(object)); + + priv = PURPLE_MEDIA_ELEMENT_INFO_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ID: + g_free(priv->id); + priv->id = g_value_dup_string(value); + break; + case PROP_NAME: + g_free(priv->name); + priv->name = g_value_dup_string(value); + break; + case PROP_TYPE: { + priv->type = g_value_get_flags(value); + break; + } + case PROP_CREATE_CB: + priv->create = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( + object, prop_id, pspec); + break; + } +} + +static void +purple_media_element_info_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + PurpleMediaElementInfoPrivate *priv; + g_return_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(object)); + + priv = PURPLE_MEDIA_ELEMENT_INFO_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ID: + g_value_set_string(value, priv->id); + break; + case PROP_NAME: + g_value_set_string(value, priv->name); + break; + case PROP_TYPE: + g_value_set_flags(value, priv->type); + break; + case PROP_CREATE_CB: + g_value_set_pointer(value, priv->create); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( + object, prop_id, pspec); + break; + } +} + +static void +purple_media_element_info_class_init(PurpleMediaElementInfoClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*)klass; + + gobject_class->finalize = purple_media_element_info_finalize; + gobject_class->set_property = purple_media_element_info_set_property; + gobject_class->get_property = purple_media_element_info_get_property; + + g_object_class_install_property(gobject_class, PROP_ID, + g_param_spec_string("id", + "ID", + "The unique identifier of the element.", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_NAME, + g_param_spec_string("name", + "Name", + "The friendly/display name of this element.", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_TYPE, + g_param_spec_flags("type", + "Element Type", + "The type of element this is.", + PURPLE_TYPE_MEDIA_ELEMENT_TYPE, + PURPLE_MEDIA_ELEMENT_NONE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, PROP_CREATE_CB, + g_param_spec_pointer("create-cb", + "Create Callback", + "The function called to create this element.", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_type_class_add_private(klass, sizeof(PurpleMediaElementInfoPrivate)); +} + +G_DEFINE_TYPE(PurpleMediaElementInfo, + purple_media_element_info, G_TYPE_OBJECT); + +gchar * +purple_media_element_info_get_id(PurpleMediaElementInfo *info) +{ +#ifdef USE_VV + gchar *id; + g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), NULL); + g_object_get(info, "id", &id, NULL); + return id; +#else + return NULL; +#endif +} + +gchar * +purple_media_element_info_get_name(PurpleMediaElementInfo *info) +{ +#ifdef USE_VV + gchar *name; + g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), NULL); + g_object_get(info, "name", &name, NULL); + return name; +#else + return NULL; +#endif +} + +PurpleMediaElementType +purple_media_element_info_get_element_type(PurpleMediaElementInfo *info) +{ +#ifdef USE_VV + PurpleMediaElementType type; + g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), + PURPLE_MEDIA_ELEMENT_NONE); + g_object_get(info, "type", &type, NULL); + return type; +#else + return PURPLE_MEDIA_ELEMENT_NONE; +#endif +} + +GstElement * +purple_media_element_info_call_create(PurpleMediaElementInfo *info, + PurpleMedia *media, const gchar *session_id, + const gchar *participant) +{ +#ifdef USE_VV + PurpleMediaElementCreateCallback create; + g_return_val_if_fail(PURPLE_IS_MEDIA_ELEMENT_INFO(info), NULL); + g_object_get(info, "create-cb", &create, NULL); + if (create) + return create(media, session_id, participant); +#endif + return NULL; +} +