diff libpurple/media.c @ 26486:217574ec2a34

Hide and gobjectify PurpleMediaCodec.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Thu, 02 Apr 2009 04:06:07 +0000
parents f0de2405c2f1
children 2d332d327a0e
line wrap: on
line diff
--- a/libpurple/media.c	Thu Apr 02 01:12:23 2009 +0000
+++ b/libpurple/media.c	Thu Apr 02 04:06:07 2009 +0000
@@ -45,6 +45,10 @@
 typedef struct _PurpleMediaSession PurpleMediaSession;
 /** @copydoc _PurpleMediaStream */
 typedef struct _PurpleMediaStream PurpleMediaStream;
+/** @copydoc _PurpleMediaCodecClass */
+typedef struct _PurpleMediaCodecClass PurpleMediaCodecClass;
+/** @copydoc _PurpleMediaCodecPrivate */
+typedef struct _PurpleMediaCodecPrivate PurpleMediaCodecPrivate;
 
 /** The media class */
 struct _PurpleMediaClass
@@ -115,6 +119,7 @@
 
 #ifdef USE_VV
 #define PURPLE_MEDIA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA, PurpleMediaPrivate))
+#define PURPLE_MEDIA_CODEC_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MEDIA_CODEC, PurpleMediaCodecPrivate))
 
 static void purple_media_class_init (PurpleMediaClass *klass);
 static void purple_media_init (PurpleMedia *media);
@@ -159,6 +164,39 @@
 };
 #endif
 
+
+/*
+ * PurpleMediaElementType
+ */
+
+GType
+purple_media_session_type_get_type()
+{
+	static GType type = 0;
+	if (type == 0) {
+		static const GFlagsValue values[] = {
+			{ PURPLE_MEDIA_NONE,
+				"PURPLE_MEDIA_NONE", "none" },
+			{ PURPLE_MEDIA_RECV_AUDIO,
+				"PURPLE_MEDIA_RECV_AUDIO", "recv-audio" },
+			{ PURPLE_MEDIA_SEND_AUDIO,
+				"PURPLE_MEDIA_SEND_AUDIO", "send-audio" },
+			{ PURPLE_MEDIA_RECV_VIDEO,
+				"PURPLE_MEDIA_RECV_VIDEO", "recv-video" },
+			{ PURPLE_MEDIA_SEND_VIDEO,
+				"PURPLE_MEDIA_SEND_VIDEO", "send-audio" },
+			{ PURPLE_MEDIA_AUDIO,
+				"PURPLE_MEDIA_AUDIO", "audio" },
+			{ PURPLE_MEDIA_VIDEO,
+				"PURPLE_MEDIA_VIDEO", "video" },
+			{ 0, NULL, NULL }
+		};
+		type = g_flags_register_static(
+				"PurpleMediaSessionType", values);
+	}
+	return type;
+}
+
 GType
 purple_media_get_type()
 {
@@ -749,46 +787,284 @@
 }
 #endif
 
+/*
+ * PurpleMediaCodec
+ */
+
+struct _PurpleMediaCodecClass
+{
+	GObjectClass parent_class;
+};
+
+struct _PurpleMediaCodec
+{
+	GObject parent;
+};
+
+struct _PurpleMediaCodecPrivate
+{
+	gint id;
+	char *encoding_name;
+	PurpleMediaSessionType media_type;
+	guint clock_rate;
+	guint channels;
+	GList *optional_params;
+};
+
+enum {
+	PROP_CODEC_0,
+	PROP_ID,
+	PROP_ENCODING_NAME,
+	PROP_MEDIA_TYPE,
+	PROP_CLOCK_RATE,
+	PROP_CHANNELS,
+	PROP_OPTIONAL_PARAMS,
+};
+
+static void
+purple_media_codec_init(PurpleMediaCodec *info)
+{
+	PurpleMediaCodecPrivate *priv =
+			PURPLE_MEDIA_CODEC_GET_PRIVATE(info);
+	priv->encoding_name = NULL;
+	priv->optional_params = NULL;
+}
+
+static void
+purple_media_codec_finalize(GObject *info)
+{
+	PurpleMediaCodecPrivate *priv =
+			PURPLE_MEDIA_CODEC_GET_PRIVATE(info);
+	g_free(priv->encoding_name);
+	for (; priv->optional_params; priv->optional_params =
+			g_list_delete_link(priv->optional_params,
+			priv->optional_params)) {
+		g_free(priv->optional_params->data);
+	}
+}
+
+static void
+purple_media_codec_set_property (GObject *object, guint prop_id,
+		const GValue *value, GParamSpec *pspec)
+{
+	PurpleMediaCodecPrivate *priv;
+	g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object));
+
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object);
+
+	switch (prop_id) {
+		case PROP_ID:
+			priv->id = g_value_get_uint(value);
+			break;
+		case PROP_ENCODING_NAME:
+			g_free(priv->encoding_name);
+			priv->encoding_name = g_value_dup_string(value);
+			break;
+		case PROP_MEDIA_TYPE:
+			priv->media_type = g_value_get_flags(value);
+			break;
+		case PROP_CLOCK_RATE:
+			priv->clock_rate = g_value_get_uint(value);
+			break;
+		case PROP_CHANNELS:
+			priv->channels = g_value_get_uint(value);
+			break;
+		case PROP_OPTIONAL_PARAMS:
+			priv->optional_params = g_value_get_pointer(value);
+			break;
+		default:	
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(
+					object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_media_codec_get_property (GObject *object, guint prop_id,
+		GValue *value, GParamSpec *pspec)
+{
+	PurpleMediaCodecPrivate *priv;
+	g_return_if_fail(PURPLE_IS_MEDIA_CODEC(object));
+	
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(object);
+
+	switch (prop_id) {
+		case PROP_ID:
+			g_value_set_uint(value, priv->id);
+			break;
+		case PROP_ENCODING_NAME:
+			g_value_set_string(value, priv->encoding_name);
+			break;
+		case PROP_MEDIA_TYPE:
+			g_value_set_flags(value, priv->media_type);
+			break;
+		case PROP_CLOCK_RATE:
+			g_value_set_uint(value, priv->clock_rate);
+			break;
+		case PROP_CHANNELS:
+			g_value_set_uint(value, priv->channels);
+			break;
+		case PROP_OPTIONAL_PARAMS:
+			g_value_set_pointer(value, priv->optional_params);
+			break;
+		default:	
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(
+					object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_media_codec_class_init(PurpleMediaCodecClass *klass)
+{
+	GObjectClass *gobject_class = (GObjectClass*)klass;
+	
+	gobject_class->finalize = purple_media_codec_finalize;
+	gobject_class->set_property = purple_media_codec_set_property;
+	gobject_class->get_property = purple_media_codec_get_property;
+
+	g_object_class_install_property(gobject_class, PROP_ID,
+			g_param_spec_uint("id",
+			"ID",
+			"The numeric identifier of the codec.",
+			0, G_MAXUINT, 0,
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+	g_object_class_install_property(gobject_class, PROP_ENCODING_NAME,
+			g_param_spec_string("encoding-name",
+			"Encoding Name",
+			"The name of the codec.",
+			NULL,
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+	g_object_class_install_property(gobject_class, PROP_MEDIA_TYPE,
+			g_param_spec_flags("media-type",
+			"Media Type",
+			"Whether this is an audio of video codec.",
+			PURPLE_TYPE_MEDIA_SESSION_TYPE,
+			PURPLE_MEDIA_NONE,
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+	g_object_class_install_property(gobject_class, PROP_CLOCK_RATE,
+			g_param_spec_uint("clock-rate",
+			"Create Callback",
+			"The function called to create this element.",
+			0, G_MAXUINT, 0,
+			G_PARAM_READWRITE));
+
+	g_object_class_install_property(gobject_class, PROP_CHANNELS,
+			g_param_spec_uint("channels",
+			"Channels",
+			"The number of channels in this codec.",
+			0, G_MAXUINT, 0,
+			G_PARAM_READWRITE));
+	g_object_class_install_property(gobject_class, PROP_OPTIONAL_PARAMS,
+			g_param_spec_pointer("optional-params",
+			"Optional Params",
+			"A list of optional parameters for the codec.",
+			G_PARAM_READWRITE));
+
+	g_type_class_add_private(klass, sizeof(PurpleMediaCodecPrivate));
+}
+
+G_DEFINE_TYPE(PurpleMediaCodec,
+		purple_media_codec, G_TYPE_OBJECT);
+
+guint
+purple_media_codec_get_id(PurpleMediaCodec *codec)
+{
+	guint id;
+	g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0);
+	g_object_get(codec, "id", &id, NULL);
+	return id;
+}
+
+gchar *
+purple_media_codec_get_encoding_name(PurpleMediaCodec *codec)
+{
+	gchar *name;
+	g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL);
+	g_object_get(codec, "encoding-name", &name, NULL);
+	return name;
+}
+
+guint
+purple_media_codec_get_clock_rate(PurpleMediaCodec *codec)
+{
+	guint clock_rate;
+	g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0);
+	g_object_get(codec, "clock-rate", &clock_rate, NULL);
+	return clock_rate;
+}
+
+guint
+purple_media_codec_get_channels(PurpleMediaCodec *codec)
+{
+	guint channels;
+	g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), 0);
+	g_object_get(codec, "channels", &channels, NULL);
+	return channels;
+}
+
+GList *
+purple_media_codec_get_optional_parameters(PurpleMediaCodec *codec)
+{
+	GList *optional_params;
+	g_return_val_if_fail(PURPLE_IS_MEDIA_CODEC(codec), NULL);
+	g_object_get(codec, "optional-params", &optional_params, NULL);
+	return optional_params;
+}
+
 void
 purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec,
 		const gchar *name, const gchar *value)
 {
+	PurpleMediaCodecPrivate *priv;
 	PurpleKeyValuePair *new_param;
 
 	g_return_if_fail(codec != NULL);
 	g_return_if_fail(name != NULL && value != NULL);
 
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec);
+
 	new_param = g_new0(PurpleKeyValuePair, 1);
 	new_param->key = g_strdup(name);
 	new_param->value = g_strdup(value);
-	codec->optional_params = g_list_append(
-			codec->optional_params, new_param);
+	priv->optional_params = g_list_append(
+			priv->optional_params, new_param);
 }
 
 void
 purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec,
 		PurpleKeyValuePair *param)
 {
+	PurpleMediaCodecPrivate *priv;
+
 	g_return_if_fail(codec != NULL && param != NULL);
 
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec);
+
 	g_free(param->key);
 	g_free(param->value);
 	g_free(param);
 
-	codec->optional_params =
-			g_list_remove(codec->optional_params, param);
+	priv->optional_params =
+			g_list_remove(priv->optional_params, param);
 }
 
 PurpleKeyValuePair *
 purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec,
 		const gchar *name, const gchar *value)
 {
+	PurpleMediaCodecPrivate *priv;
 	GList *iter;
 
 	g_return_val_if_fail(codec != NULL, NULL);
 	g_return_val_if_fail(name != NULL, NULL);
 
-	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec);
+
+	for (iter = priv->optional_params; iter; iter = g_list_next(iter)) {
 		PurpleKeyValuePair *param = iter->data;
 		if (!g_ascii_strcasecmp(param->key, name) &&
 				(value == NULL ||
@@ -803,29 +1079,32 @@
 purple_media_codec_new(int id, const char *encoding_name,
 		PurpleMediaSessionType media_type, guint clock_rate)
 {
-	PurpleMediaCodec *codec = g_new0(PurpleMediaCodec, 1);
-
-	codec->id = id;
-	codec->encoding_name = g_strdup(encoding_name);
-	codec->media_type = media_type;
-	codec->clock_rate = clock_rate;
+	PurpleMediaCodec *codec =
+			g_object_new(PURPLE_TYPE_MEDIA_CODEC,
+			"id", id,
+			"encoding_name", encoding_name,
+			"media_type", media_type,
+			"clock-rate", clock_rate, NULL);
 	return codec;
 }
 
 static PurpleMediaCodec *
 purple_media_codec_copy(PurpleMediaCodec *codec)
 {
+	PurpleMediaCodecPrivate *priv;
 	PurpleMediaCodec *new_codec;
 	GList *iter;
 
 	if (codec == NULL)
 		return NULL;
 
-	new_codec = purple_media_codec_new(codec->id, codec->encoding_name,
-			codec->media_type, codec->clock_rate);
-	new_codec->channels = codec->channels;
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec);
 
-	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+	new_codec = purple_media_codec_new(priv->id, priv->encoding_name,
+			priv->media_type, priv->clock_rate);
+	g_object_set(codec, "channels", priv->channels, NULL);
+
+	for (iter = priv->optional_params; iter; iter = g_list_next(iter)) {
 		PurpleKeyValuePair *param =
 				(PurpleKeyValuePair*)iter->data;
 		purple_media_codec_add_optional_parameter(new_codec,
@@ -835,40 +1114,25 @@
 	return new_codec;
 }
 
-static void
-purple_media_codec_free(PurpleMediaCodec *codec)
-{
-	if (codec == NULL)
-		return;
-
-	g_free(codec->encoding_name);
-
-	for (; codec->optional_params; codec->optional_params =
-			g_list_delete_link(codec->optional_params,
-			codec->optional_params)) {
-		purple_media_codec_remove_optional_parameter(codec,
-				codec->optional_params->data);
-	}
-
-	g_free(codec);
-}
-
 #ifdef USE_VV
 static FsCodec *
 purple_media_codec_to_fs(const PurpleMediaCodec *codec)
 {
+	PurpleMediaCodecPrivate *priv;
 	FsCodec *new_codec;
 	GList *iter;
 
 	if (codec == NULL)
 		return NULL;
 
-	new_codec = fs_codec_new(codec->id, codec->encoding_name,
-			purple_media_to_fs_media_type(codec->media_type),
-			codec->clock_rate);
-	new_codec->channels = codec->channels;
+	priv = PURPLE_MEDIA_CODEC_GET_PRIVATE(codec);
 
-	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
+	new_codec = fs_codec_new(priv->id, priv->encoding_name,
+			purple_media_to_fs_media_type(priv->media_type),
+			priv->clock_rate);
+	new_codec->channels = priv->channels;
+
+	for (iter = priv->optional_params; iter; iter = g_list_next(iter)) {
 		PurpleKeyValuePair *param = (PurpleKeyValuePair*)iter->data;
 		fs_codec_add_optional_parameter(new_codec,
 				param->key, param->value);
@@ -889,7 +1153,7 @@
 	new_codec = purple_media_codec_new(codec->id, codec->encoding_name,
 			purple_media_from_fs(codec->media_type,
 			FS_DIRECTION_BOTH), codec->clock_rate);
-	new_codec->channels = codec->channels;
+	g_object_set(new_codec, "channels", codec->channels, NULL);
 
 	for (iter = codec->optional_params; iter; iter = g_list_next(iter)) {
 		FsCodecParameter *param = (FsCodecParameter*)iter->data;
@@ -952,9 +1216,8 @@
 	GList *new_list = NULL;
 
 	for (; codecs; codecs = g_list_next(codecs)) {
-		new_list = g_list_prepend(new_list, g_boxed_copy(
-				PURPLE_TYPE_MEDIA_CODEC,
-				codecs->data));
+		new_list = g_list_prepend(new_list,
+				purple_media_codec_copy(codecs->data));
 	}
 
 	new_list = g_list_reverse(new_list);
@@ -966,24 +1229,10 @@
 {
 	for (; codecs; codecs =
 			g_list_delete_link(codecs, codecs)) {
-		g_boxed_free(PURPLE_TYPE_MEDIA_CODEC,
-				codecs->data);
+		g_object_unref(codecs->data);
 	}
 }
 
-GType
-purple_media_codec_get_type()
-{
-	static GType type = 0;
-
-	if (type == 0) {
-		type = g_boxed_type_register_static("PurpleMediaCodec",
-				(GBoxedCopyFunc)purple_media_codec_copy,
-				(GBoxedFreeFunc)purple_media_codec_free);
-	}
-	return type;
-}
-
 #ifdef USE_VV
 static PurpleMediaSession*
 purple_media_get_session(PurpleMedia *media, const gchar *sess_id)