[brasero] Integrate brasero more closely with PackageKit



commit ec52b8cb5da8958b394603d2b82e81638841aea3
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date:   Sun Nov 1 15:29:38 2009 +0100

    Integrate brasero more closely with PackageKit
    Now every time a plugin cannot work properly because an app or a lib or a Gstreamer plugin is not installed brasero will be notified and try to download the required component

 libbrasero-burn/Makefile.am                  |    2 +-
 libbrasero-burn/brasero-burn.c               |    3 +-
 libbrasero-burn/brasero-caps-session.c       |  697 ++++++++++++++------------
 libbrasero-burn/brasero-enums.h              |   11 +
 libbrasero-burn/brasero-plugin-information.h |   20 +-
 libbrasero-burn/brasero-plugin-private.h     |    3 -
 libbrasero-burn/brasero-plugin.h             |   19 -
 libbrasero-burn/brasero-session-cfg.c        |   12 +-
 libbrasero-burn/brasero-session.c            |   38 +-
 libbrasero-burn/brasero-session.h            |   31 +-
 libbrasero-burn/brasero-status-dialog.c      |    3 +
 libbrasero-burn/burn-basics.c                |    3 +-
 libbrasero-burn/burn-caps.c                  |   11 +-
 libbrasero-burn/burn-caps.h                  |    2 +-
 libbrasero-burn/burn-plugin-manager.c        |   35 +--
 libbrasero-burn/burn-plugin-manager.h        |    2 -
 libbrasero-burn/burn-plugin.c                |   71 ++--
 libbrasero-utils/Makefile.am                 |    4 +-
 libbrasero-utils/brasero-metadata.c          |    5 +-
 libbrasero-utils/brasero-pk.c                |  379 ++++++++++++++
 libbrasero-utils/brasero-pk.h                |   81 +++
 src/brasero-player-bacon.c                   |    2 +-
 src/brasero-plugin-manager-ui.c              |    8 +-
 src/brasero-project.c                        |  134 +++++-
 24 files changed, 1082 insertions(+), 494 deletions(-)
---
diff --git a/libbrasero-burn/Makefile.am b/libbrasero-burn/Makefile.am
index 83e9d12..8162a24 100644
--- a/libbrasero-burn/Makefile.am
+++ b/libbrasero-burn/Makefile.am
@@ -195,7 +195,7 @@ libbrasero_burn_la_SOURCES = 		\
 	brasero-video-options.c                 \
 	brasero-session-span.h                 \
 	brasero-session-span.c                 \
-	brasero-plugin-private.h
+	brasero-plugin-private.h                 
 
 if BUILD_INOTIFY
 libbrasero_burn_la_SOURCES += brasero-file-monitor.c brasero-file-monitor.h
diff --git a/libbrasero-burn/brasero-burn.c b/libbrasero-burn/brasero-burn.c
index 6c0b82d..d398aa1 100644
--- a/libbrasero-burn/brasero-burn.c
+++ b/libbrasero-burn/brasero-burn.c
@@ -823,8 +823,7 @@ brasero_burn_lock_dest_media (BraseroBurn *burn,
 	 * We use quite a strict checking though as
 	 * from now on we require plugins to be
 	 * ready. */
-	brasero_burn_session_set_check_flags (priv->session, 0);
-	result = brasero_burn_session_supported (priv->session);
+	result = brasero_burn_session_can_burn (priv->session, FALSE);
 	if (result != BRASERO_BURN_OK) {
 		BRASERO_BURN_LOG ("Inserted media is not supported");
 		result = BRASERO_BURN_NEED_RELOAD;
diff --git a/libbrasero-burn/brasero-caps-session.c b/libbrasero-burn/brasero-caps-session.c
index a721897..f028d7e 100644
--- a/libbrasero-burn/brasero-caps-session.c
+++ b/libbrasero-burn/brasero-caps-session.c
@@ -58,7 +58,7 @@
 
 static BraseroBurnResult
 brasero_burn_caps_get_blanking_flags_real (BraseroBurnCaps *caps,
-                                           BraseroSessionCheckFlags support_flags,
+                                           gboolean ignore_errors,
 					   BraseroMedia media,
 					   BraseroBurnFlag session_flags,
 					   BraseroBurnFlag *supported,
@@ -66,7 +66,6 @@ brasero_burn_caps_get_blanking_flags_real (BraseroBurnCaps *caps,
 {
 	GSList *iter;
 	gboolean supported_media;
-	BraseroPluginActiveFlags plugin_flags;
 	BraseroBurnFlag supported_flags = BRASERO_BURN_FLAG_NONE;
 	BraseroBurnFlag compulsory_flags = BRASERO_BURN_FLAG_ALL;
 
@@ -80,18 +79,18 @@ brasero_burn_caps_get_blanking_flags_real (BraseroBurnCaps *caps,
 		return BRASERO_BURN_NOT_SUPPORTED;
 	}
 
-	plugin_flags = (support_flags & BRASERO_SESSION_CHECK_IGNORE_PLUGIN_ERRORS)? BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS:0;
-
 	supported_media = FALSE;
 	for (iter = caps->priv->caps_list; iter; iter = iter->next) {
+		BraseroMedia caps_media;
 		BraseroCaps *caps;
 		GSList *links;
 
 		caps = iter->data;
-		if (caps->type.type != BRASERO_TRACK_TYPE_DISC)
+		if (!brasero_track_type_get_has_medium (&caps->type))
 			continue;
 
-		if ((media & caps->type.subtype.media) != media)
+		caps_media = brasero_track_type_get_medium_type (&caps->type);
+		if ((media & caps_media) != media)
 			continue;
 
 		for (links = caps->links; links; links = links->next) {
@@ -113,7 +112,7 @@ brasero_burn_caps_get_blanking_flags_real (BraseroBurnCaps *caps,
 				BraseroBurnFlag compulsory_plugin;
 
 				plugin = plugins->data;
-				if (!brasero_plugin_get_active (plugin, plugin_flags))
+				if (!brasero_plugin_get_active (plugin, ignore_errors))
 					continue;
 
 				if (!brasero_plugin_get_blank_flags (plugin,
@@ -200,7 +199,7 @@ brasero_burn_session_get_blank_flags (BraseroBurnSession *session,
 
 	self = brasero_burn_caps_get_default ();
 	result = brasero_burn_caps_get_blanking_flags_real (self,
-	                                                    brasero_burn_session_get_check_flags (session),
+	                                                    brasero_burn_session_get_strict_support (session) == FALSE,
 							    media,
 							    session_flags,
 							    supported,
@@ -212,12 +211,11 @@ brasero_burn_session_get_blank_flags (BraseroBurnSession *session,
 
 static BraseroBurnResult
 brasero_burn_caps_can_blank_real (BraseroBurnCaps *self,
-                                  BraseroSessionCheckFlags support_flags,
-				  BraseroMedia media,
+                                  gboolean ignore_plugin_errors,
+                                  BraseroMedia media,
 				  BraseroBurnFlag flags)
 {
 	GSList *iter;
-	BraseroPluginActiveFlags plugin_flags;
 
 	BRASERO_BURN_LOG_DISC_TYPE (media, "Testing blanking caps for");
 	if (media == BRASERO_MEDIUM_NONE) {
@@ -235,7 +233,6 @@ brasero_burn_caps_can_blank_real (BraseroBurnCaps *self,
 		return BRASERO_BURN_NOT_SUPPORTED;
 	}
 
-	plugin_flags = (support_flags & BRASERO_SESSION_CHECK_IGNORE_PLUGIN_ERRORS)? BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS:0;
 	for (iter = self->priv->caps_list; iter; iter = iter->next) {
 		BraseroCaps *caps;
 		GSList *links;
@@ -267,7 +264,7 @@ brasero_burn_caps_can_blank_real (BraseroBurnCaps *self,
 				BraseroPlugin *plugin;
 
 				plugin = plugins->data;
-				if (!brasero_plugin_get_active (plugin, plugin_flags))
+				if (!brasero_plugin_get_active (plugin, ignore_plugin_errors))
 					continue;
 
 				if (brasero_plugin_check_blank_flags (plugin, media, flags)) {
@@ -304,7 +301,6 @@ brasero_burn_session_can_blank (BraseroBurnSession *session)
 	BraseroBurnFlag flags;
 	BraseroBurnCaps *self;
 	BraseroBurnResult result;
-	BraseroSessionCheckFlags support_flags;
 
 	self = brasero_burn_caps_get_default ();
 
@@ -318,9 +314,8 @@ brasero_burn_session_can_blank (BraseroBurnSession *session)
 	}
 
 	flags = brasero_burn_session_get_flags (session);
-	support_flags = brasero_burn_session_get_check_flags (session);
 	result = brasero_burn_caps_can_blank_real (self,
-	                                           support_flags,
+	                                           brasero_burn_session_get_strict_support (session) == FALSE,
 	                                           media,
 	                                           flags);
 	g_object_unref (self);
@@ -330,7 +325,7 @@ brasero_burn_session_can_blank (BraseroBurnSession *session)
 
 static void
 brasero_caps_link_get_record_flags (BraseroCapsLink *link,
-                                    BraseroPluginActiveFlags plugin_flags,
+                                    gboolean ignore_plugin_errors,
 				    BraseroMedia media,
 				    BraseroBurnFlag session_flags,
 				    BraseroBurnFlag *supported,
@@ -349,7 +344,7 @@ brasero_caps_link_get_record_flags (BraseroCapsLink *link,
 		BraseroBurnFlag plugin_compulsory;
 
 		plugin = iter->data;
-		if (!brasero_plugin_get_active (plugin, plugin_flags))
+		if (!brasero_plugin_get_active (plugin, ignore_plugin_errors))
 			continue;
 
 		result = brasero_plugin_get_record_flags (plugin,
@@ -369,7 +364,7 @@ brasero_caps_link_get_record_flags (BraseroCapsLink *link,
 
 static void
 brasero_caps_link_get_data_flags (BraseroCapsLink *link,
-                                  BraseroPluginActiveFlags plugin_flags,
+                                  gboolean ignore_plugin_errors,
 				  BraseroMedia media,
 				  BraseroBurnFlag session_flags,
 				  BraseroBurnFlag *supported)
@@ -384,7 +379,7 @@ brasero_caps_link_get_data_flags (BraseroCapsLink *link,
 		BraseroBurnFlag plugin_compulsory;
 
 		plugin = iter->data;
-		if (!brasero_plugin_get_active (plugin, plugin_flags))
+		if (!brasero_plugin_get_active (plugin, ignore_plugin_errors))
 			continue;
 
 		result = brasero_plugin_get_image_flags (plugin,
@@ -398,7 +393,7 @@ brasero_caps_link_get_data_flags (BraseroCapsLink *link,
 
 static gboolean
 brasero_caps_link_check_data_flags (BraseroCapsLink *link,
-                                    BraseroPluginActiveFlags plugin_flags,
+                                    gboolean ignore_plugin_errors,
 				    BraseroBurnFlag session_flags,
 				    BraseroMedia media)
 {
@@ -419,7 +414,7 @@ brasero_caps_link_check_data_flags (BraseroCapsLink *link,
 		BraseroPlugin *plugin;
 
 		plugin = iter->data;
-		if (!brasero_plugin_get_active (plugin, plugin_flags))
+		if (!brasero_plugin_get_active (plugin, ignore_plugin_errors))
 			continue;
 
 		result = brasero_plugin_check_image_flags (plugin,
@@ -434,7 +429,7 @@ brasero_caps_link_check_data_flags (BraseroCapsLink *link,
 
 static gboolean
 brasero_caps_link_check_record_flags (BraseroCapsLink *link,
-                                      BraseroPluginActiveFlags plugin_flags,
+                                      gboolean ignore_plugin_errors,
 				      BraseroBurnFlag session_flags,
 				      BraseroMedia media)
 {
@@ -453,7 +448,7 @@ brasero_caps_link_check_record_flags (BraseroCapsLink *link,
 		BraseroPlugin *plugin;
 
 		plugin = iter->data;
-		if (!brasero_plugin_get_active (plugin, plugin_flags))
+		if (!brasero_plugin_get_active (plugin, ignore_plugin_errors))
 			continue;
 
 		result = brasero_plugin_check_record_flags (plugin,
@@ -468,7 +463,7 @@ brasero_caps_link_check_record_flags (BraseroCapsLink *link,
 
 static gboolean
 brasero_caps_link_check_media_restrictions (BraseroCapsLink *link,
-                                            BraseroPluginActiveFlags plugin_flags,
+                                            gboolean ignore_plugin_errors,
 					    BraseroMedia media)
 {
 	GSList *iter;
@@ -479,7 +474,7 @@ brasero_caps_link_check_media_restrictions (BraseroCapsLink *link,
 		BraseroPlugin *plugin;
 
 		plugin = iter->data;
-		if (!brasero_plugin_get_active (plugin, plugin_flags))
+		if (!brasero_plugin_get_active (plugin, ignore_plugin_errors))
 			continue;
 
 		result = brasero_plugin_check_media_restrictions (plugin, media);
@@ -490,16 +485,81 @@ brasero_caps_link_check_media_restrictions (BraseroCapsLink *link,
 	return FALSE;
 }
 
-static gboolean
+static BraseroBurnResult
+brasero_caps_report_plugin_error (BraseroPlugin *plugin,
+                                  BraseroForeachPluginErrorCb callback,
+                                  gpointer user_data)
+{
+	GSList *errors;
+
+	errors = brasero_plugin_get_errors (plugin);
+	if (!errors)
+		return BRASERO_BURN_ERR;
+
+	do {
+		BraseroPluginError *error;
+		BraseroBurnResult result;
+
+		error = errors->data;
+		result = callback (error->type, error->detail, user_data);
+		if (result == BRASERO_BURN_RETRY) {
+			/* Something has been done
+			 * to fix the error like an install
+			 * so reload the errors */
+			brasero_plugin_check_plugin_ready (plugin);
+			errors = brasero_plugin_get_errors (plugin);
+			continue;
+		}
+
+		if (result != BRASERO_BURN_OK)
+			return result;
+
+		errors = errors->next;
+	} while (errors);
+
+	return BRASERO_BURN_OK;
+}
+
+struct _BraseroFindLinkCtx {
+	BraseroMedia media;
+	BraseroTrackType *input;
+	BraseroPluginIOFlag io_flags;
+	BraseroBurnFlag session_flags;
+
+	BraseroForeachPluginErrorCb callback;
+	gpointer user_data;
+
+	guint ignore_plugin_errors:1;
+	guint check_session_flags:1;
+};
+typedef struct _BraseroFindLinkCtx BraseroFindLinkCtx;
+
+static void
+brasero_caps_find_link_set_ctx (BraseroBurnSession *session,
+                                BraseroFindLinkCtx *ctx,
+                                BraseroTrackType *input)
+{
+	ctx->input = input;
+
+	if (ctx->check_session_flags)
+		ctx->session_flags = brasero_burn_session_get_flags (session);
+
+	if (BRASERO_BURN_SESSION_NO_TMP_FILE (session))
+		ctx->io_flags = BRASERO_PLUGIN_IO_ACCEPT_PIPE;
+	else
+		ctx->io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
+
+	if (!ctx->callback)
+		ctx->ignore_plugin_errors = (brasero_burn_session_get_strict_support (session) == FALSE);
+	else
+		ctx->ignore_plugin_errors = TRUE;
+}
+
+static BraseroBurnResult
 brasero_caps_find_link (BraseroCaps *caps,
-			BraseroBurnFlag session_flags,
-			BraseroSessionCheckFlags support_flags,
-			BraseroMedia media,
-			BraseroTrackType *input,
-			BraseroPluginIOFlag io_flags)
+                        BraseroFindLinkCtx *ctx)
 {
 	GSList *iter;
-	BraseroPluginActiveFlags plugin_check_flags = 0;
 
 	BRASERO_BURN_LOG_WITH_TYPE (&caps->type, BRASERO_PLUGIN_IO_NONE, "find_link");
 
@@ -515,11 +575,9 @@ brasero_caps_find_link (BraseroCaps *caps,
 	 *   input
 	 */
 
-	plugin_check_flags = ((support_flags & BRASERO_SESSION_CHECK_IGNORE_PLUGIN_ERRORS)? BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS:0);
-
 	for (iter = caps->links; iter; iter = iter->next) {
 		BraseroCapsLink *link;
-		gboolean result;
+		BraseroBurnResult result;
 
 		link = iter->data;
 
@@ -527,47 +585,53 @@ brasero_caps_find_link (BraseroCaps *caps,
 			continue;
 
 		/* check that the link has some active plugin */
-		if (!brasero_caps_link_active (link, plugin_check_flags))
+		if (!brasero_caps_link_active (link, ctx->ignore_plugin_errors))
 			continue;
 
 		/* since this link contains recorders, check that at least one
 		 * of them can handle the record flags */
-		if ((support_flags & BRASERO_SESSION_CHECK_USE_FLAGS)
+		if (ctx->check_session_flags
 		&&  brasero_track_type_get_has_medium (&caps->type)
-		&& !brasero_caps_link_check_record_flags (link, plugin_check_flags, session_flags, media))
+		&& !brasero_caps_link_check_record_flags (link, ctx->ignore_plugin_errors, ctx->session_flags, ctx->media))
 			continue;
 
 		/* first see if that's the perfect fit:
 		 * - it must have the same caps (type + subtype)
 		 * - it must have the proper IO */
-		if (link->caps->type.type == BRASERO_TRACK_TYPE_DATA) {
-			if ((support_flags & BRASERO_SESSION_CHECK_USE_FLAGS)
-			&& !brasero_caps_link_check_data_flags (link, plugin_check_flags, session_flags, media))
+		if (brasero_track_type_get_has_data (&link->caps->type)) {
+			if (ctx->check_session_flags
+			&& !brasero_caps_link_check_data_flags (link, ctx->ignore_plugin_errors, ctx->session_flags, ctx->media))
 				continue;
 		}
-		else if (!brasero_caps_link_check_media_restrictions (link, plugin_check_flags, media))
+		else if (!brasero_caps_link_check_media_restrictions (link, ctx->ignore_plugin_errors, ctx->media))
 			continue;
 
 		if ((link->caps->flags & BRASERO_PLUGIN_IO_ACCEPT_FILE)
-		&&   brasero_caps_is_compatible_type (link->caps, input))
-			return TRUE;
+		&&   brasero_caps_is_compatible_type (link->caps, ctx->input)) {
+			if (ctx->callback) {
+				BraseroPlugin *plugin;
+
+				/* If we are supposed to report/signal that the plugin
+				 * could be used but only if some more elements are 
+				 * installed */
+				plugin = brasero_caps_link_need_download (link);
+				if (plugin)
+					return brasero_caps_report_plugin_error (plugin, ctx->callback, ctx->user_data);
+			}
+			return BRASERO_BURN_OK;
+		}
 
 		/* we can't go further than a DISC type */
-		if (link->caps->type.type == BRASERO_TRACK_TYPE_DISC)
+		if (brasero_track_type_get_has_medium (&link->caps->type))
 			continue;
 
-		if ((link->caps->flags & io_flags) == BRASERO_PLUGIN_IO_NONE)
+		if ((link->caps->flags & ctx->io_flags) == BRASERO_PLUGIN_IO_NONE)
 			continue;
 
 		/* try to see where the inputs of this caps leads to */
-		result = brasero_caps_find_link (link->caps,
-						 session_flags,
-						 support_flags,
-						 media,
-						 input,
-						 io_flags);
-		if (result) {
-			if (support_flags & BRASERO_SESSION_CHECK_SIGNAL_PLUGIN_ERRORS) {
+		result = brasero_caps_find_link (link->caps, ctx);
+		if (result == BRASERO_BURN_OK) {
+			if (ctx->callback) {
 				BraseroPlugin *plugin;
 
 				/* If we are supposed to report/signal that the plugin
@@ -575,71 +639,52 @@ brasero_caps_find_link (BraseroCaps *caps,
 				 * installed */
 				plugin = brasero_caps_link_need_download (link);
 				if (plugin)
-					brasero_plugin_need_download (plugin);
+					return brasero_caps_report_plugin_error (plugin, ctx->callback, ctx->user_data);
 			}
-
-			return TRUE;
+			return BRASERO_BURN_OK;
 		}
 	}
 
-	return FALSE;
+	return BRASERO_BURN_NOT_SUPPORTED;
 }
 
-static gboolean
+static BraseroBurnResult
 brasero_caps_try_output (BraseroBurnCaps *self,
-			 BraseroBurnFlag session_flags,
-			 BraseroSessionCheckFlags support_flags,
-			 BraseroTrackType *output,
-			 BraseroTrackType *input,
-			 BraseroPluginIOFlag flags)
+                         BraseroFindLinkCtx *ctx,
+                         BraseroTrackType *output)
 {
 	BraseroCaps *caps;
-	BraseroMedia media;
 
 	/* here we search the start caps */
 	caps = brasero_burn_caps_find_start_caps (self, output);
 	if (!caps) {
 		BRASERO_BURN_LOG ("No caps available");
-		return FALSE;
+		return BRASERO_BURN_NOT_SUPPORTED;
 	}
 
-	if (output->type == BRASERO_TRACK_TYPE_DISC)
-		media = output->subtype.media;
+	/* Here flags don't matter as we don't record anything.
+	 * Even the IOFlags since that can be checked later with
+	 * brasero_burn_caps_get_flags. */
+	if (brasero_track_type_get_has_medium (output))
+		ctx->media = brasero_track_type_get_medium_type (output);
 	else
-		media = BRASERO_MEDIUM_FILE;
-
-	return brasero_caps_find_link (caps,
-				       session_flags,
-				       support_flags,
-				       media,
-				       input,
-				       flags);
+		ctx->media = BRASERO_MEDIUM_FILE;
+
+	return brasero_caps_find_link (caps, ctx);
 }
 
-static gboolean
+static BraseroBurnResult
 brasero_caps_try_output_with_blanking (BraseroBurnCaps *self,
-				       BraseroBurnSession *session,
-				       BraseroTrackType *output,
-				       BraseroTrackType *input,
-				       BraseroPluginIOFlag io_flags)
+                                       BraseroBurnSession *session,
+                                       BraseroFindLinkCtx *ctx,
+                                       BraseroTrackType *output)
 {
 	gboolean result;
-	BraseroMedia media;
 	BraseroCaps *last_caps;
-	BraseroSessionCheckFlags support_flags;
-	BraseroBurnFlag session_flags = BRASERO_BURN_FLAG_NONE;
-
-	support_flags = brasero_burn_session_get_check_flags (session);
-	if (support_flags & BRASERO_SESSION_CHECK_USE_FLAGS)
-		session_flags = brasero_burn_session_get_flags (session);
-
-	result = brasero_caps_try_output (self,
-					  session_flags,
-					  support_flags,
-					  output,
-					  input,
-					  io_flags);
-	if (result)
+
+	result = brasero_caps_try_output (self, ctx, output);
+	if (result == BRASERO_BURN_OK
+	||  result == BRASERO_BURN_CANCEL)
 		return result;
 
 	/* we reached this point in two cases:
@@ -653,7 +698,7 @@ brasero_caps_try_output_with_blanking (BraseroBurnCaps *self,
 	 * then write on its own. Basically that works only with
 	 * overwrite formatted discs, DVD+RW, ...) */
 	if (!brasero_track_type_get_has_medium (output))
-		return FALSE;
+		return BRASERO_BURN_NOT_SUPPORTED;
 
 	/* output is a disc try with initial blanking */
 	BRASERO_BURN_LOG ("Support for input/output failed.");
@@ -661,33 +706,28 @@ brasero_caps_try_output_with_blanking (BraseroBurnCaps *self,
 	/* apparently nothing can be done to reach our goal. Maybe that
 	 * is because we first have to blank the disc. If so add a blank 
 	 * task to the others as a first step */
-	if (((support_flags & BRASERO_SESSION_CHECK_USE_FLAGS)
-	&& !(session_flags & BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE))
+	if ((ctx->check_session_flags
+	&& !(ctx->session_flags & BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE))
 	||   brasero_burn_session_can_blank (session) != BRASERO_BURN_OK)
-		return FALSE;
+		return BRASERO_BURN_NOT_SUPPORTED;
 
 	BRASERO_BURN_LOG ("Trying with initial blanking");
 
 	/* retry with the same disc type but blank this time */
-	media = output->subtype.media;
-	media &= ~(BRASERO_MEDIUM_CLOSED|
-		   BRASERO_MEDIUM_APPENDABLE|
-		   BRASERO_MEDIUM_UNFORMATTED|
-		   BRASERO_MEDIUM_HAS_DATA|
-		   BRASERO_MEDIUM_HAS_AUDIO);
-	media |= BRASERO_MEDIUM_BLANK;
-	brasero_track_type_set_medium_type (output, media);
+	ctx->media = brasero_track_type_get_medium_type (output);
+	ctx->media &= ~(BRASERO_MEDIUM_CLOSED|
+	                BRASERO_MEDIUM_APPENDABLE|
+	                BRASERO_MEDIUM_UNFORMATTED|
+	                BRASERO_MEDIUM_HAS_DATA|
+	                BRASERO_MEDIUM_HAS_AUDIO);
+	ctx->media |= BRASERO_MEDIUM_BLANK;
+	brasero_track_type_set_medium_type (output, ctx->media);
 
 	last_caps = brasero_burn_caps_find_start_caps (self, output);
 	if (!last_caps)
-		return FALSE;
-
-	return brasero_caps_find_link (last_caps,
-				       session_flags,
-				       support_flags,
-				       media,
-				       input,
-				       io_flags);
+		return BRASERO_BURN_NOT_SUPPORTED;
+
+	return brasero_caps_find_link (last_caps, ctx);
 }
 
 /**
@@ -710,48 +750,44 @@ brasero_caps_try_output_with_blanking (BraseroBurnCaps *self,
 
 BraseroBurnResult
 brasero_burn_session_input_supported (BraseroBurnSession *session,
-				      BraseroTrackType *input)
+				      BraseroTrackType *input,
+                                      gboolean check_flags)
 {
-	gboolean result;
 	BraseroBurnCaps *self;
+	BraseroBurnResult result;
 	BraseroTrackType output;
-	BraseroPluginIOFlag io_flags;
-	BraseroSessionCheckFlags support_flags;
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
 
 	result = brasero_burn_session_get_output_type (session, &output);
 	if (result != BRASERO_BURN_OK)
-		BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
+		return result;
 
 	BRASERO_BURN_LOG_TYPE (input, "Checking support for input");
 	BRASERO_BURN_LOG_TYPE (&output, "and output");
 
-	support_flags = brasero_burn_session_get_check_flags (session);
-	if (support_flags & BRASERO_SESSION_CHECK_USE_FLAGS) {
+	ctx.check_session_flags = check_flags;
+	brasero_caps_find_link_set_ctx (session, &ctx, input);
+
+	if (check_flags) {
 		result = brasero_check_flags_for_drive (brasero_burn_session_get_burner (session),
-							brasero_burn_session_get_flags (session));
+							ctx.session_flags);
 
 		if (!result)
 			BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
 
-		BRASERO_BURN_LOG_FLAGS (brasero_burn_session_get_flags (session), "with flags");
+		BRASERO_BURN_LOG_FLAGS (ctx.session_flags, "with flags");
 	}
 
-	if (BRASERO_BURN_SESSION_NO_TMP_FILE (session))
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_PIPE;
-	else
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
-
 	self = brasero_burn_caps_get_default ();
 	result = brasero_caps_try_output_with_blanking (self,
 							session,
-							&output,
-							input,
-							io_flags);
+	                                                &ctx,
+							&output);
 	g_object_unref (self);
 
-	if (!result) {
+	if (result != BRASERO_BURN_OK) {
 		BRASERO_BURN_LOG_TYPE (input, "Input not supported");
-		return BRASERO_BURN_NOT_SUPPORTED;
+		return result;
 	}
 
 	return BRASERO_BURN_OK;
@@ -771,12 +807,10 @@ BraseroBurnResult
 brasero_burn_session_output_supported (BraseroBurnSession *session,
 				       BraseroTrackType *output)
 {
-	gboolean result;
 	BraseroBurnCaps *self;
 	BraseroTrackType input;
-	BraseroPluginIOFlag io_flags;
-
-	self = brasero_burn_caps_get_default ();
+	BraseroBurnResult result;
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
 
 	/* Here, we can't check if the drive supports the flags since the output
 	 * is hypothetical. There is no real medium. So forget the following :
@@ -785,29 +819,23 @@ brasero_burn_session_output_supported (BraseroBurnSession *session,
 	 * The only thing we could do would be to check some known forbidden 
 	 * flags for some media provided the output type is DISC. */
 
-	/* Here flags don't matter as we don't record anything. Even the IOFlags
-	 * since that can be checked later with brasero_burn_caps_get_flags. */
-	if (BRASERO_BURN_SESSION_NO_TMP_FILE (session))
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_PIPE;
-	else
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
-
 	brasero_burn_session_get_input_type (session, &input);
+	brasero_caps_find_link_set_ctx (session, &ctx, &input);
+
 	BRASERO_BURN_LOG_TYPE (output, "Checking support for output");
 	BRASERO_BURN_LOG_TYPE (&input, "and input");
 	BRASERO_BURN_LOG_FLAGS (brasero_burn_session_get_flags (session), "with flags");
 	
+	self = brasero_burn_caps_get_default ();
 	result = brasero_caps_try_output_with_blanking (self,
 							session,
-							output,
-							&input,
-							io_flags);
-
+	                                                &ctx,
+							output);
 	g_object_unref (self);
 
-	if (!result) {
+	if (result != BRASERO_BURN_OK) {
 		BRASERO_BURN_LOG_TYPE (output, "Output not supported");
-		return BRASERO_BURN_NOT_SUPPORTED;
+		return result;
 	}
 
 	return BRASERO_BURN_OK;
@@ -821,39 +849,36 @@ brasero_burn_session_output_supported (BraseroBurnSession *session,
 static BraseroBurnResult
 brasero_burn_caps_is_session_supported_same_src_dest (BraseroBurnCaps *self,
 						      BraseroBurnSession *session,
+                                                      BraseroFindLinkCtx *ctx,
                                                       BraseroTrackType *tmp_type)
 {
 	GSList *iter;
-	gboolean supported;
 	BraseroDrive *burner;
 	BraseroTrackType input;
+	BraseroBurnResult result;
 	BraseroTrackType output;
 	BraseroImageFormat format;
-	BraseroBurnFlag session_flags;
-	BraseroSessionCheckFlags support_flags;
 
 	BRASERO_BURN_LOG ("Checking disc copy support with same source and destination");
 
 	/* To determine if a CD/DVD can be copied using the same source/dest,
 	 * we first determine if can be imaged and then if this image can be 
 	 * burnt to whatever medium type. */
+	brasero_caps_find_link_set_ctx (session, ctx, &input);
+	ctx->io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
+
 	memset (&input, 0, sizeof (BraseroTrackType));
 	brasero_burn_session_get_input_type (session, &input);
 	BRASERO_BURN_LOG_TYPE (&input, "input");
 
-	support_flags = brasero_burn_session_get_check_flags (session);
-	if (support_flags & BRASERO_SESSION_CHECK_USE_FLAGS) {
+	if (ctx->check_session_flags) {
 		/* NOTE: DAO can be a problem. So just in case remove it. It is
 		 * not really useful in this context. What we want here is to
 		 * know whether a medium can be used given the input; only 1
 		 * flag is important here (MERGE) and can have consequences. */
-		session_flags = brasero_burn_session_get_flags (session);
-		session_flags &= ~BRASERO_BURN_FLAG_DAO;
-
-		BRASERO_BURN_LOG_FLAGS (session_flags, "flags");
+		ctx->session_flags &= ~BRASERO_BURN_FLAG_DAO;
+		BRASERO_BURN_LOG_FLAGS (ctx->session_flags, "flags");
 	}
-	else
-		session_flags = BRASERO_BURN_FLAG_NONE;
 
 	burner = brasero_burn_session_get_burner (session);
 
@@ -866,57 +891,55 @@ brasero_burn_caps_is_session_supported_same_src_dest (BraseroBurnCaps *self,
 	                                      BRASERO_METADATA_INFO);
 
 	BRASERO_BURN_LOG_TYPE (&output, "Testing stream type");
-	supported = brasero_caps_try_output (self,
-	                                     session_flags,
-	                                     support_flags,
-	                                     &output,
-	                                     &input,
-	                                     BRASERO_PLUGIN_IO_ACCEPT_FILE);
-	if (supported) {
+	result = brasero_caps_try_output (self, ctx, &output);
+	if (result == BRASERO_BURN_CANCEL)
+		return result;
+
+	if (result == BRASERO_BURN_OK) {
 		BRASERO_BURN_LOG ("Stream type seems to be supported as output");
 
 		/* This format can be used to create an image. Check if can be
 		 * burnt now. Just find at least one medium. */
 		for (iter = self->priv->caps_list; iter; iter = iter->next) {
+			BraseroBurnResult result;
+			BraseroMedia media;
 			BraseroCaps *caps;
-			gboolean result;
 
 			caps = iter->data;
 
-			if (caps->type.type != BRASERO_TRACK_TYPE_DISC)
+			if (!brasero_track_type_get_has_medium (&caps->type))
 				continue;
 
+			media = brasero_track_type_get_medium_type (&caps->type);
 			/* Audio is only supported by CDs */
-			if ((caps->type.subtype.media & BRASERO_MEDIUM_CD) == 0)
+			if ((media & BRASERO_MEDIUM_CD) == 0)
 				continue;
 
 			/* This type of disc cannot be burnt; skip them */
-			if (caps->type.subtype.media & BRASERO_MEDIUM_ROM)
+			if (media & BRASERO_MEDIUM_ROM)
 				continue;
 
 			/* Make sure this is supported by the drive */
-			if (!brasero_drive_can_write_media (burner, caps->type.subtype.media))
+			if (!brasero_drive_can_write_media (burner, media))
 				continue;
 
-			result = brasero_caps_find_link (caps,
-							 support_flags,
-							 session_flags,
-							 caps->type.subtype.media,
-							 &output,
-							 BRASERO_PLUGIN_IO_ACCEPT_FILE);
-
-			BRASERO_BURN_LOG_DISC_TYPE (caps->type.subtype.media,
+			ctx->media = media;
+			result = brasero_caps_find_link (caps, ctx);
+			BRASERO_BURN_LOG_DISC_TYPE (media,
 						    "Tested medium (%s)",
-						    result ? "working":"not working");
+						    result == BRASERO_BURN_OK ? "working":"not working");
 
-			if (result) {
+			if (result == BRASERO_BURN_OK) {
 				if (tmp_type) {
-					tmp_type->type = BRASERO_TRACK_TYPE_STREAM;
-					tmp_type->subtype.stream_format = output.subtype.stream_format;
+					brasero_track_type_set_has_stream (tmp_type);
+					brasero_track_type_set_stream_format (tmp_type, brasero_track_type_get_stream_format (&output));
 				}
 					
 				return BRASERO_BURN_OK;
 			}
+
+			if (result == BRASERO_BURN_CANCEL)
+				return result;
 		}
 	}
 	else
@@ -934,60 +957,59 @@ brasero_burn_caps_is_session_supported_same_src_dest (BraseroBurnCaps *self,
 		/* Don't need to try blanking here (saves
 		 * a few lines of debug) since that is an 
 		 * image */
-		supported = brasero_caps_try_output (self,
-		                                     session_flags,
-		                                     support_flags,
-		                                     &output,
-		                                     &input,
-		                                     BRASERO_PLUGIN_IO_ACCEPT_FILE);
-		if (!supported)
+		result = brasero_caps_try_output (self, ctx, &output);
+		if (result == BRASERO_BURN_CANCEL)
+			return result;
+
+		if (result != BRASERO_BURN_OK)
 			continue;
 
 		/* This format can be used to create an image. Check if can be
 		 * burnt now. Just find at least one medium. */
 		for (iter = self->priv->caps_list; iter; iter = iter->next) {
+			BraseroBurnResult result;
+			BraseroMedia media;
 			BraseroCaps *caps;
-			gboolean result;
 
 			caps = iter->data;
 
-			if (caps->type.type != BRASERO_TRACK_TYPE_DISC)
+			if (!brasero_track_type_get_has_medium (&caps->type))
 				continue;
 
+			media = brasero_track_type_get_medium_type (&caps->type);
+
 			/* This type of disc cannot be burnt; skip them */
-			if (caps->type.subtype.media & BRASERO_MEDIUM_ROM)
+			if (media & BRASERO_MEDIUM_ROM)
 				continue;
 
 			/* These three types only work with CDs. Skip the rest. */
-			if ((output.subtype.img_format == BRASERO_IMAGE_FORMAT_CDRDAO
-			||   output.subtype.img_format == BRASERO_IMAGE_FORMAT_CLONE
-			||   output.subtype.img_format == BRASERO_IMAGE_FORMAT_CUE)
-			&& (caps->type.subtype.media & BRASERO_MEDIUM_CD) == 0)
+			if ((format == BRASERO_IMAGE_FORMAT_CDRDAO
+			||   format == BRASERO_IMAGE_FORMAT_CLONE
+			||   format == BRASERO_IMAGE_FORMAT_CUE)
+			&& (media & BRASERO_MEDIUM_CD) == 0)
 				continue;
 
 			/* Make sure this is supported by the drive */
-			if (!brasero_drive_can_write_media (burner, caps->type.subtype.media))
+			if (!brasero_drive_can_write_media (burner, media))
 				continue;
 
-			result = brasero_caps_find_link (caps,
-							 support_flags,
-							 session_flags,
-							 caps->type.subtype.media,
-							 &output,
-							 BRASERO_PLUGIN_IO_ACCEPT_FILE);
-
-			BRASERO_BURN_LOG_DISC_TYPE (caps->type.subtype.media,
+			ctx->media = media;
+			result = brasero_caps_find_link (caps, ctx);
+			BRASERO_BURN_LOG_DISC_TYPE (media,
 						    "Tested medium (%s)",
-						    result ? "working":"not working");
+						    result == BRASERO_BURN_OK ? "working":"not working");
 
-			if (result) {
+			if (result == BRASERO_BURN_OK) {
 				if (tmp_type) {
-					tmp_type->type = BRASERO_TRACK_TYPE_IMAGE;
-					tmp_type->subtype.img_format = brasero_track_type_get_image_format (&output);
+					brasero_track_type_set_has_image (tmp_type);
+					brasero_track_type_set_image_format (tmp_type, brasero_track_type_get_image_format (&output));
 				}
 					
 				return BRASERO_BURN_OK;
 			}
+
+			if (result == BRASERO_BURN_CANCEL)
+				return result;
 		}
 	}
 
@@ -998,49 +1020,36 @@ BraseroBurnResult
 brasero_burn_session_get_tmp_image_type_same_src_dest (BraseroBurnSession *session,
                                                        BraseroTrackType *image_type)
 {
-	BraseroBurnResult result;
 	BraseroBurnCaps *self;
+	BraseroBurnResult result;
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
+
+	g_return_val_if_fail (BRASERO_IS_BURN_SESSION (session), BRASERO_BURN_ERR);
 
 	self = brasero_burn_caps_get_default ();
 	result = brasero_burn_caps_is_session_supported_same_src_dest (self,
 	                                                               session,
+	                                                               &ctx,
 	                                                               image_type);
 	g_object_unref (self);
 	return result;
 }
 
-/**
- * brasero_burn_session_supported:
- * @session: a #BraseroBurnSession
- * @flags: a #BraseroSessionCheckFlags
- *
- * Given the various parameters stored in @session, this
- * function checks whether the data contained in @session
- * can be burnt to the medium in the #BraseroDrive (set 
- * through brasero_burn_session_set_burner ()).
- * If @flags determine the behavior of this function.
- *
- * Return value: a #BraseroBurnResult.
- * BRASERO_BURN_OK if it is possible.
- * BRASERO_BURN_ERR otherwise.
- **/
-
-BraseroBurnResult
-brasero_burn_session_supported (BraseroBurnSession *session)
+static BraseroBurnResult
+brasero_burn_session_supported (BraseroBurnSession *session,
+                                BraseroFindLinkCtx *ctx)
 {
 	gboolean result;
 	BraseroBurnCaps *self;
 	BraseroTrackType input;
 	BraseroTrackType output;
-	BraseroPluginIOFlag io_flags;
-	BraseroSessionCheckFlags support_flags;
 
 	/* Special case */
 	if (brasero_burn_session_same_src_dest_drive (session)) {
 		BraseroBurnResult res;
 
 		self = brasero_burn_caps_get_default ();
-		res = brasero_burn_caps_is_session_supported_same_src_dest (self, session, NULL);
+		res = brasero_burn_caps_is_session_supported_same_src_dest (self, session, ctx, NULL);
 		g_object_unref (self);
 
 		return res;
@@ -1051,42 +1060,32 @@ brasero_burn_session_supported (BraseroBurnSession *session)
 		BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
 
 	brasero_burn_session_get_input_type (session, &input);
+	brasero_caps_find_link_set_ctx (session, ctx, &input);
 
 	BRASERO_BURN_LOG_TYPE (&output, "Checking support for session. Ouput is ");
 	BRASERO_BURN_LOG_TYPE (&input, "and input is ");
 
-	support_flags = brasero_burn_session_get_check_flags (session);
-	if (support_flags & BRASERO_SESSION_CHECK_USE_FLAGS) {
-		result = brasero_check_flags_for_drive (brasero_burn_session_get_burner (session),
-							brasero_burn_session_get_flags (session));
-
+	if (ctx->check_session_flags) {
+		result = brasero_check_flags_for_drive (brasero_burn_session_get_burner (session), ctx->session_flags);
 		if (!result)
 			BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
 
-		BRASERO_BURN_LOG_FLAGS (brasero_burn_session_get_flags (session), "with flags");
+		BRASERO_BURN_LOG_FLAGS (ctx->session_flags, "with flags");
 	}
 
-	/* Here flags don't matter as we don't record anything.
-	 * Even the IOFlags since that can be checked later with
-	 * brasero_burn_caps_get_flags. */
-	if (BRASERO_BURN_SESSION_NO_TMP_FILE (session))
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_PIPE;
-	else
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
-
 	self = brasero_burn_caps_get_default ();
 	result = brasero_caps_try_output_with_blanking (self,
 							session,
-							&output,
-							&input,
-							io_flags);
+	                                                ctx,
+							&output);
 	g_object_unref (self);
 
-	if (!result) {
+	if (result != BRASERO_BURN_OK) {
 		BRASERO_BURN_LOG_TYPE (&output, "Session not supported");
-		return BRASERO_BURN_NOT_SUPPORTED;
+		return result;
 	}
 
+	BRASERO_BURN_LOG_TYPE (&output, "Session supported");
 	return BRASERO_BURN_OK;
 }
 
@@ -1095,9 +1094,11 @@ brasero_burn_session_supported (BraseroBurnSession *session)
  * @session: a #BraseroBurnSession
  * @use_flags: a #gboolean
  *
- * This is now just a wrapper around brasero_burn_session_supported ().
- *
- * Deprecated since 2.29.2
+ * Given the various parameters stored in @session, this
+ * function checks whether the data contained in @session
+ * can be burnt to the medium in the #BraseroDrive (set 
+ * through brasero_burn_session_set_burner ()).
+ * If @flags determine the behavior of this function.
  *
  * Return value: a #BraseroBurnResult.
  * BRASERO_BURN_OK if it is possible.
@@ -1106,9 +1107,43 @@ brasero_burn_session_supported (BraseroBurnSession *session)
 
 BraseroBurnResult
 brasero_burn_session_can_burn (BraseroBurnSession *session,
-			       gboolean use_flags)
+			       gboolean check_flags)
+{
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
+
+	g_return_val_if_fail (BRASERO_IS_BURN_SESSION (session), BRASERO_BURN_ERR);
+
+	ctx.check_session_flags = check_flags;
+
+	return brasero_burn_session_supported (session, &ctx);
+}
+
+/**
+ * brasero_session_foreach_plugin_error:
+ * @session: a #BraseroBurnSession.
+ * @callback: a #BraseroSessionPluginErrorCb.
+ * @user_data: a #gpointer. The data passed to @callback.
+ *
+ * Call @callback for each error in plugins.
+ *
+ * Return value: a #BraseroBurnResult.
+ * BRASERO_BURN_OK if it is possible.
+ * BRASERO_BURN_ERR otherwise.
+ **/
+
+BraseroBurnResult
+brasero_session_foreach_plugin_error (BraseroBurnSession *session,
+                                      BraseroForeachPluginErrorCb callback,
+                                      gpointer user_data)
 {
-	return brasero_burn_session_supported (session);
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
+
+	g_return_val_if_fail (BRASERO_IS_BURN_SESSION (session), BRASERO_BURN_ERR);
+
+	ctx.callback = callback;
+	ctx.user_data = user_data;
+	
+	return brasero_burn_session_supported (session, &ctx);
 }
 
 /**
@@ -1125,8 +1160,7 @@ BraseroMedia
 brasero_burn_session_get_required_media_type (BraseroBurnSession *session)
 {
 	BraseroMedia required_media = BRASERO_MEDIUM_NONE;
-	BraseroBurnFlag session_flags;
-	BraseroPluginIOFlag io_flags;
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
 	BraseroTrackType input;
 	BraseroBurnCaps *self;
 	GSList *iter;
@@ -1134,12 +1168,12 @@ brasero_burn_session_get_required_media_type (BraseroBurnSession *session)
 	if (brasero_burn_session_is_dest_file (session))
 		return BRASERO_MEDIUM_FILE;
 
-	self = brasero_burn_caps_get_default ();
-
 	/* we try to determine here what type of medium is allowed to be burnt
 	 * to whether a CD or a DVD. Appendable, blank are not properties being
 	 * determined here. We just want it to be writable in a broad sense. */
+	ctx.check_session_flags = TRUE;
 	brasero_burn_session_get_input_type (session, &input);
+	brasero_caps_find_link_set_ctx (session, &ctx, &input);
 	BRASERO_BURN_LOG_TYPE (&input, "Determining required media type for input");
 
 	/* NOTE: BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE is a problem here since it
@@ -1147,42 +1181,35 @@ brasero_burn_session_get_required_media_type (BraseroBurnSession *session)
 	 * case remove them. They are not really useful in this context. What we
 	 * want here is to know which media can be used given the input; only 1
 	 * flag is important here (MERGE) and can have consequences. */
-	session_flags = brasero_burn_session_get_flags (session);
-	session_flags &= ~BRASERO_BURN_FLAG_DAO;
-
-	BRASERO_BURN_LOG_FLAGS (session_flags, "and flags");
-
-	if (BRASERO_BURN_SESSION_NO_TMP_FILE (session))
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_PIPE;
-	else
-		io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
+	ctx.session_flags &= ~BRASERO_BURN_FLAG_DAO;
+	BRASERO_BURN_LOG_FLAGS (ctx.session_flags, "and flags");
 
+	self = brasero_burn_caps_get_default ();
 	for (iter = self->priv->caps_list; iter; iter = iter->next) {
 		BraseroCaps *caps;
 		gboolean result;
 
 		caps = iter->data;
 
-		if (caps->type.type != BRASERO_TRACK_TYPE_DISC)
+		if (!brasero_track_type_get_has_medium (&caps->type))
 			continue;
 
 		/* Put BRASERO_MEDIUM_NONE so we can always succeed */
-		result = brasero_caps_find_link (caps,
-						 session_flags,
-						 TRUE,
-						 BRASERO_MEDIUM_NONE,
-						 &input,
-						 io_flags);
-
+		result = brasero_caps_find_link (caps, &ctx);
 		BRASERO_BURN_LOG_DISC_TYPE (caps->type.subtype.media,
 					    "Tested (%s)",
-					    result ? "working":"not working");
+					    result == BRASERO_BURN_OK ? "working":"not working");
 
-		if (!result)
+		if (result == BRASERO_BURN_CANCEL) {
+			g_object_unref (self);
+			return result;
+		}
+
+		if (result != BRASERO_BURN_OK)
 			continue;
 
 		/* This caps work, add its subtype */
-		required_media |= caps->type.subtype.media;
+		required_media |= brasero_track_type_get_medium_type (&caps->type);
 	}
 
 	/* filter as we are only interested in these */
@@ -1335,7 +1362,7 @@ brasero_burn_session_get_default_output_format (BraseroBurnSession *session)
 
 static BraseroPluginIOFlag
 brasero_caps_get_flags (BraseroCaps *caps,
-                        BraseroSessionCheckFlags check_flags,
+                        gboolean ignore_plugin_errors,
 			BraseroBurnFlag session_flags,
 			BraseroMedia media,
 			BraseroTrackType *input,
@@ -1344,11 +1371,8 @@ brasero_caps_get_flags (BraseroCaps *caps,
 			BraseroBurnFlag *compulsory)
 {
 	GSList *iter;
-	BraseroPluginActiveFlags plugin_flags;
 	BraseroPluginIOFlag retval = BRASERO_PLUGIN_IO_NONE;
 
-	plugin_flags = (check_flags & BRASERO_SESSION_CHECK_IGNORE_PLUGIN_ERRORS)? BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS:0;
-
 	/* First we must know if this link leads somewhere. It must 
 	 * accept the already existing flags. If it does, see if it 
 	 * accepts the input and if not, if one of its ancestors does */
@@ -1365,14 +1389,14 @@ brasero_caps_get_flags (BraseroCaps *caps,
 			continue;
 
 		/* check that the link has some active plugin */
-		if (!brasero_caps_link_active (link, plugin_flags))
+		if (!brasero_caps_link_active (link, ignore_plugin_errors))
 			continue;
 
 		if (brasero_track_type_get_has_medium (&caps->type)) {
 			BraseroBurnFlag tmp;
 
 			brasero_caps_link_get_record_flags (link,
-			                                    plugin_flags,
+			                                    ignore_plugin_errors,
 							    media,
 							    session_flags,
 							    &rec_supported,
@@ -1389,7 +1413,7 @@ brasero_caps_get_flags (BraseroCaps *caps,
 			BraseroBurnFlag tmp;
 
 			brasero_caps_link_get_data_flags (link,
-			                                  plugin_flags,
+			                                  ignore_plugin_errors,
 							  media,
 							  session_flags,
 						    	  &data_supported);
@@ -1402,7 +1426,7 @@ brasero_caps_get_flags (BraseroCaps *caps,
 			if ((tmp & data_supported) != tmp)
 				continue;
 		}
-		else if (!brasero_caps_link_check_media_restrictions (link, plugin_flags, media))
+		else if (!brasero_caps_link_check_media_restrictions (link, ignore_plugin_errors, media))
 			continue;
 
 		/* see if that's the perfect fit */
@@ -1428,7 +1452,7 @@ brasero_caps_get_flags (BraseroCaps *caps,
 
 		/* try to see where the inputs of this caps leads to */
 		io_flags = brasero_caps_get_flags (link->caps,
-		                                   check_flags,
+		                                   ignore_plugin_errors,
 						   session_flags,
 						   media,
 						   input,
@@ -1515,7 +1539,7 @@ brasero_burn_caps_flags_update_for_drive (BraseroBurnSession *session,
 
 static BraseroBurnResult
 brasero_caps_get_flags_for_disc (BraseroBurnCaps *self,
-                                 BraseroSessionCheckFlags check_flags,
+                                 gboolean ignore_plugin_errors,
 				 BraseroBurnFlag session_flags,
 				 BraseroMedia media,
 				 BraseroTrackType *input,
@@ -1543,7 +1567,7 @@ brasero_caps_get_flags_for_disc (BraseroBurnCaps *self,
 				    "FLAGS: trying caps");
 
 	io_flags = brasero_caps_get_flags (caps,
-	                                   check_flags,
+	                                   ignore_plugin_errors,
 					   session_flags,
 					   media,
 					   input,
@@ -1599,12 +1623,10 @@ brasero_burn_caps_get_flags_for_medium (BraseroBurnCaps *self,
 {
 	BraseroBurnResult result;
 	gboolean can_blank = FALSE;
-	BraseroSessionCheckFlags check_flags;
 
 	/* See if medium is supported out of the box */
-	check_flags = brasero_burn_session_get_check_flags (session);
 	result = brasero_caps_get_flags_for_disc (self,
-	                                          check_flags,
+	                                          brasero_burn_session_get_strict_support (session) == FALSE,
 						  session_flags,
 						  media,
 						  input,
@@ -1614,7 +1636,7 @@ brasero_burn_caps_get_flags_for_medium (BraseroBurnCaps *self,
 	/* see if we can add BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE. Add it when:
 	 * - media can be blanked, it has audio or data and we're not merging
 	 * - media is not formatted and it can be blanked/formatted */
-	if (brasero_burn_caps_can_blank_real (self, check_flags, media, session_flags) == BRASERO_BURN_OK)
+	if (brasero_burn_caps_can_blank_real (self, brasero_burn_session_get_strict_support (session) == FALSE, media, session_flags) == BRASERO_BURN_OK)
 		can_blank = TRUE;
 	else if (session_flags & BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE)
 		return BRASERO_BURN_NOT_SUPPORTED;
@@ -1655,7 +1677,7 @@ brasero_burn_caps_get_flags_for_medium (BraseroBurnCaps *self,
 			   BRASERO_MEDIUM_HAS_AUDIO);
 		media |= BRASERO_MEDIUM_BLANK;
 		result = brasero_caps_get_flags_for_disc (self,
-		                                          check_flags,
+		                                          brasero_burn_session_get_strict_support (session) == FALSE,
 							  session_flags,
 							  media,
 							  input,
@@ -1683,7 +1705,7 @@ brasero_burn_caps_get_flags_for_medium (BraseroBurnCaps *self,
 
 			/* need to add blanking flags */
 			brasero_burn_caps_get_blanking_flags_real (self,
-			                                           check_flags,
+			                                           brasero_burn_session_get_strict_support (session) == FALSE,
 								   media,
 								   session_flags,
 								   &blank_supported,
@@ -1738,7 +1760,9 @@ brasero_burn_caps_get_flags_same_src_dest_for_types (BraseroBurnCaps *self,
 {
 	GSList *iter;
 	gboolean type_supported;
+	BraseroBurnResult result;
 	BraseroBurnFlag session_flags;
+	BraseroFindLinkCtx ctx = { 0, NULL, 0, };
 	BraseroBurnFlag supported_final = BRASERO_BURN_FLAG_NONE;
 	BraseroBurnFlag compulsory_final = BRASERO_BURN_FLAG_ALL;
 
@@ -1747,17 +1771,15 @@ brasero_burn_caps_get_flags_same_src_dest_for_types (BraseroBurnCaps *self,
 	 * is possible. */
 	BRASERO_BURN_LOG_TYPE (output, "Testing temporary image format");
 
+	brasero_caps_find_link_set_ctx (session, &ctx, input);
+	ctx.io_flags = BRASERO_PLUGIN_IO_ACCEPT_FILE;
+
 	/* Here there is no need to try blanking as there
 	 * is no disc (saves a few debug lines) */
-	type_supported = brasero_caps_try_output (self,
-	                                          BRASERO_BURN_FLAG_NONE,
-	                                          FALSE,
-	                                          output,
-	                                          input,
-	                                          BRASERO_PLUGIN_IO_ACCEPT_FILE);
-	if (!type_supported) {
+	result = brasero_caps_try_output (self, &ctx, output);
+	if (result != BRASERO_BURN_OK) {
 		BRASERO_BURN_LOG_TYPE (output, "Format not supported");
-		return FALSE;
+		return result;
 	}
 
 	session_flags = brasero_burn_session_get_flags (session);
@@ -1769,17 +1791,20 @@ brasero_burn_caps_get_flags_same_src_dest_for_types (BraseroBurnCaps *self,
 		BraseroBurnFlag compulsory;
 		BraseroBurnFlag supported;
 		BraseroBurnResult result;
+		BraseroMedia media;
 		BraseroCaps *caps;
 
 		caps = iter->data;
-		if (caps->type.type != BRASERO_TRACK_TYPE_DISC)
+		if (!brasero_track_type_get_has_medium (&caps->type))
 			continue;
 
+		media = brasero_track_type_get_medium_type (&caps->type);
+
 		/* This type of disc cannot be burnt; skip them */
-		if (caps->type.subtype.media & BRASERO_MEDIUM_ROM)
+		if (media & BRASERO_MEDIUM_ROM)
 			continue;
 
-		if ((caps->type.subtype.media & BRASERO_MEDIUM_CD) == 0) {
+		if ((media & BRASERO_MEDIUM_CD) == 0) {
 			if (brasero_track_type_get_has_image (output)) {
 				BraseroImageFormat format;
 
@@ -1799,9 +1824,9 @@ brasero_burn_caps_get_flags_same_src_dest_for_types (BraseroBurnCaps *self,
 		compulsory = BRASERO_BURN_FLAG_NONE;
 
 		result = brasero_caps_get_flags_for_disc (self,
-		                                          brasero_burn_session_get_check_flags (session),
+		                                          brasero_burn_session_get_strict_support (session) == FALSE,
 		                                          session_flags,
-		                                          caps->type.subtype.media,
+		                                          media,
 							  output,
 							  &supported,
 							  &compulsory);
@@ -1816,11 +1841,11 @@ brasero_burn_caps_get_flags_same_src_dest_for_types (BraseroBurnCaps *self,
 
 	BRASERO_BURN_LOG_TYPE (output, "Format supported %i", type_supported);
 	if (!type_supported)
-		return FALSE;
+		return BRASERO_BURN_NOT_SUPPORTED;
 
 	*supported_ret = supported_final;
 	*compulsory_ret = compulsory_final;
-	return type_supported;
+	return BRASERO_BURN_OK;
 }
 
 static BraseroBurnResult
@@ -1830,8 +1855,9 @@ brasero_burn_caps_get_flags_same_src_dest (BraseroBurnCaps *self,
 					   BraseroBurnFlag *compulsory_ret)
 {
 	BraseroTrackType input;
-	BraseroTrackType output;
+	BraseroBurnResult result;
 	gboolean copy_supported;
+	BraseroTrackType output;
 	BraseroImageFormat format;
 	BraseroBurnFlag session_flags;
 	BraseroBurnFlag supported_final = BRASERO_BURN_FLAG_NONE;
@@ -1859,18 +1885,22 @@ brasero_burn_caps_get_flags_same_src_dest (BraseroBurnCaps *self,
 	brasero_track_type_set_stream_format (&output,
 	                                      BRASERO_AUDIO_FORMAT_RAW|
 	                                      BRASERO_METADATA_INFO);
-	copy_supported = brasero_burn_caps_get_flags_same_src_dest_for_types (self,
-	                                                                      session,
-	                                                                      &input,
-	                                                                      &output,
-	                                                                      &supported_final,
-	                                                                      &compulsory_final);
+
+	result = brasero_burn_caps_get_flags_same_src_dest_for_types (self,
+	                                                              session,
+	                                                              &input,
+	                                                              &output,
+	                                                              &supported_final,
+	                                                              &compulsory_final);
+	if (result == BRASERO_BURN_CANCEL)
+		return result;
+
+	copy_supported = (result == BRASERO_BURN_OK);
 
 	/* Check flags for all available format */
 	format = BRASERO_IMAGE_FORMAT_CDRDAO;
 	brasero_track_type_set_has_image (&output);
 	for (; format > BRASERO_IMAGE_FORMAT_NONE; format >>= 1) {
-		gboolean format_supported;
 		BraseroBurnFlag supported;
 		BraseroBurnFlag compulsory;
 
@@ -1883,13 +1913,16 @@ brasero_burn_caps_get_flags_same_src_dest (BraseroBurnCaps *self,
 
 		supported = BRASERO_BURN_FLAG_NONE;
 		compulsory = BRASERO_BURN_FLAG_NONE;
-		format_supported = brasero_burn_caps_get_flags_same_src_dest_for_types (self,
-		                                                                        session,
-		                                                                        &input,
-		                                                                        &output,
-		                                                                        &supported,
-		                                                                        &compulsory);
-		if (!format_supported)
+		result = brasero_burn_caps_get_flags_same_src_dest_for_types (self,
+		                                                              session,
+		                                                              &input,
+		                                                              &output,
+		                                                              &supported,
+		                                                              &compulsory);
+		if (result == BRASERO_BURN_CANCEL)
+			return result;
+
+		if (result != BRASERO_BURN_OK)
 			continue;
 
 		copy_supported = TRUE;
diff --git a/libbrasero-burn/brasero-enums.h b/libbrasero-burn/brasero-enums.h
index b413ee6..f5f7cb1 100644
--- a/libbrasero-burn/brasero-enums.h
+++ b/libbrasero-burn/brasero-enums.h
@@ -170,6 +170,17 @@ typedef enum {
 	BRASERO_IMAGE_FORMAT_CLONE,
 } BraseroImageFormat; 
 
+typedef enum {
+	BRASERO_PLUGIN_ERROR_NONE					= 0,
+	BRASERO_PLUGIN_ERROR_MODULE,
+	BRASERO_PLUGIN_ERROR_MISSING_APP,
+	BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
+	BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP,
+	BRASERO_PLUGIN_ERROR_MISSING_LIBRARY,
+	BRASERO_PLUGIN_ERROR_LIBRARY_VERSION,
+	BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN,
+} BraseroPluginErrorType;
+
 G_END_DECLS
 
 #endif
diff --git a/libbrasero-burn/brasero-plugin-information.h b/libbrasero-burn/brasero-plugin-information.h
index 5862c20..5b1bbdb 100644
--- a/libbrasero-burn/brasero-plugin-information.h
+++ b/libbrasero-burn/brasero-plugin-information.h
@@ -42,14 +42,9 @@ G_BEGIN_DECLS
 void
 brasero_plugin_set_active (BraseroPlugin *plugin, gboolean active);
 
-typedef enum {
-	BRASERO_PLUGIN_ACTIVE_NONE,
-	BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS,
-} BraseroPluginActiveFlags;
-
 gboolean
 brasero_plugin_get_active (BraseroPlugin *plugin,
-                           BraseroPluginActiveFlags flags);
+                           gboolean ignore_errors);
 
 const gchar *
 brasero_plugin_get_name (BraseroPlugin *plugin);
@@ -75,8 +70,17 @@ brasero_plugin_get_icon_name (BraseroPlugin *plugin);
 gchar *
 brasero_plugin_get_gconf_priority_key (BraseroPlugin *plugin);
 
-const gchar *
-brasero_plugin_get_error (BraseroPlugin *plugin);
+typedef struct _BraseroPluginError BraseroPluginError;
+struct _BraseroPluginError {
+	BraseroPluginErrorType type;
+	gchar *detail;
+};
+
+GSList *
+brasero_plugin_get_errors (BraseroPlugin *plugin);
+
+gchar *
+brasero_plugin_get_error_string (BraseroPlugin *plugin);
 
 gboolean
 brasero_plugin_get_compulsory (BraseroPlugin *plugin);
diff --git a/libbrasero-burn/brasero-plugin-private.h b/libbrasero-burn/brasero-plugin-private.h
index 8203756..5ab402a 100644
--- a/libbrasero-burn/brasero-plugin-private.h
+++ b/libbrasero-burn/brasero-plugin-private.h
@@ -88,9 +88,6 @@ brasero_plugin_check_media_restrictions (BraseroPlugin *plugin,
 void
 brasero_plugin_check_plugin_ready (BraseroPlugin *plugin);
 
-void
-brasero_plugin_need_download (BraseroPlugin *plugin);
-
 G_END_DECLS
 
 #endif
diff --git a/libbrasero-burn/brasero-plugin.h b/libbrasero-burn/brasero-plugin.h
index 2338079..aa53110 100644
--- a/libbrasero-burn/brasero-plugin.h
+++ b/libbrasero-burn/brasero-plugin.h
@@ -51,7 +51,6 @@ struct _BraseroPluginClass {
 	GTypeModuleClass parent_class;
 
 	/* Signals */
-	void	(* errors)	(BraseroPlugin *plugin);
 	void	(* loaded)	(BraseroPlugin *plugin);
 	void	(* activated)	(BraseroPlugin *plugin,
 			                  gboolean active);
@@ -92,24 +91,6 @@ typedef enum {
 	BRASERO_PLUGIN_RUN_AFTER_TARGET		= 1 << 2,
 } BraseroPluginProcessFlag;
 
-typedef enum {
-	BRASERO_PLUGIN_ERROR_NONE					= 0,
-	BRASERO_PLUGIN_ERROR_MODULE,
-	BRASERO_PLUGIN_ERROR_MISSING_APP,
-	BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
-	BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP,
-	BRASERO_PLUGIN_ERROR_MISSING_LIBRARY,
-	BRASERO_PLUGIN_ERROR_LIBRARY_VERSION,
-	BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN,
-} BraseroPluginErrorType;
-
-typedef struct _BraseroPluginError BraseroPluginError;
-
-struct _BraseroPluginError {
-	BraseroPluginErrorType type;
-	gchar *detail;
-};
-
 G_END_DECLS
 
 #endif /* _BURN_PLUGIN_H_ */
diff --git a/libbrasero-burn/brasero-session-cfg.c b/libbrasero-burn/brasero-session-cfg.c
index 87e0b49..443861b 100644
--- a/libbrasero-burn/brasero-session-cfg.c
+++ b/libbrasero-burn/brasero-session-cfg.c
@@ -1152,7 +1152,7 @@ brasero_session_cfg_update (BraseroSessionCfg *self)
 			brasero_track_type_set_stream_format (source,
 							      BRASERO_METADATA_INFO|
 							      brasero_track_type_get_stream_format (source));
-			result = brasero_burn_session_input_supported (BRASERO_BURN_SESSION (self), source);
+			result = brasero_burn_session_input_supported (BRASERO_BURN_SESSION (self), source, FALSE);
 			if (result == BRASERO_BURN_OK) {
 				priv->CD_TEXT_modified = FALSE;
 
@@ -1166,11 +1166,11 @@ brasero_session_cfg_update (BraseroSessionCfg *self)
 				brasero_track_type_set_stream_format (source,
 								      (~BRASERO_METADATA_INFO) &
 								      brasero_track_type_get_stream_format (source));
-				result = brasero_burn_session_input_supported (BRASERO_BURN_SESSION (self), source);
+				result = brasero_burn_session_input_supported (BRASERO_BURN_SESSION (self), source, FALSE);
 			}
 		}
 		else {
-			result = brasero_burn_session_supported (BRASERO_BURN_SESSION (self));
+			result = brasero_burn_session_can_burn (BRASERO_BURN_SESSION (self), FALSE);
 
 			if (result != BRASERO_BURN_OK
 			&& (brasero_track_type_get_stream_format (source) & BRASERO_METADATA_INFO)) {
@@ -1182,7 +1182,7 @@ brasero_session_cfg_update (BraseroSessionCfg *self)
 								      (~BRASERO_METADATA_INFO) &
 								      brasero_track_type_get_stream_format (source));
 
-				result = brasero_burn_session_input_supported (BRASERO_BURN_SESSION (self), source);
+				result = brasero_burn_session_input_supported (BRASERO_BURN_SESSION (self), source, FALSE);
 
 				BRASERO_BURN_LOG ("Tested support without Metadata information (result %d)", result);
 				if (result == BRASERO_BURN_OK) {
@@ -1238,7 +1238,7 @@ brasero_session_cfg_update (BraseroSessionCfg *self)
 			BRASERO_BURN_LOG ("Temporary image type %i", format);
 		}
 		else {
-			result = brasero_burn_session_supported (BRASERO_BURN_SESSION (self));
+			result = brasero_burn_session_can_burn (BRASERO_BURN_SESSION (self), FALSE);
 			format = brasero_burn_session_get_output_format (BRASERO_BURN_SESSION (self));
 			priv->CD_TEXT_modified = (format & (BRASERO_IMAGE_FORMAT_CDRDAO|BRASERO_IMAGE_FORMAT_CUE)) == 0;
 		}
@@ -1246,7 +1246,7 @@ brasero_session_cfg_update (BraseroSessionCfg *self)
 	else {
 		/* Don't use flags as they'll be adapted later. */
 		priv->CD_TEXT_modified = FALSE;
-		result = brasero_burn_session_supported (BRASERO_BURN_SESSION (self));
+		result = brasero_burn_session_can_burn (BRASERO_BURN_SESSION (self), FALSE);
 	}
 
 	if (result != BRASERO_BURN_OK) {
diff --git a/libbrasero-burn/brasero-session.c b/libbrasero-burn/brasero-session.c
index 3bb978c..2697986 100644
--- a/libbrasero-burn/brasero-session.c
+++ b/libbrasero-burn/brasero-session.c
@@ -110,10 +110,10 @@ struct _BraseroBurnSessionPrivate {
 	guint dest_added_sig;
 	guint dest_removed_sig;
 
-	BraseroSessionCheckFlags check_flags;
-
 	GSList *tracks;
 	GSList *pile_tracks;
+
+	guint strict_checks:1;
 };
 typedef struct _BraseroBurnSessionPrivate BraseroBurnSessionPrivate;
 
@@ -249,59 +249,55 @@ brasero_burn_session_free_tracks (BraseroBurnSession *self)
 }
 
 /**
- * brasero_burn_session_set_check_flags:
+ * brasero_burn_session_set_strict_support:
  * @session: a #BraseroBurnSession.
  * @flags: a #BraseroSessionCheckFlags
  *
  * For the following functions:
- * brasero_burn_session_get_flags ()
  * brasero_burn_session_supported ()
  * brasero_burn_session_input_supported ()
  * brasero_burn_session_output_supported ()
  * brasero_burn_session_can_blank ()
- * brasero_burn_session_get_blank_flags ()
- * this function sets a few parameters describing
- * how tests/checks should be performed.
+ * this function sets whether these functions will
+ * ignore the plugins with errors (%TRUE).
  */
 
 void
-brasero_burn_session_set_check_flags (BraseroBurnSession *session,
-                                           BraseroSessionCheckFlags flags)
+brasero_burn_session_set_strict_support (BraseroBurnSession *session,
+                                         gboolean strict_checks)
 {
 	BraseroBurnSessionPrivate *priv;
 
 	g_return_if_fail (BRASERO_IS_BURN_SESSION (session));
 
 	priv = BRASERO_BURN_SESSION_PRIVATE (session);
-	priv->check_flags = flags;
+	priv->strict_checks = strict_checks;
 }
 
 /**
- * brasero_burn_session_get_check_flags:
+ * brasero_burn_session_get_strict_support:
  * @session: a #BraseroBurnSession.
  *
  * For the following functions:
- * brasero_burn_session_get_flags ()
- * brasero_burn_session_supported ()
+ * brasero_burn_session_can_burn ()
  * brasero_burn_session_input_supported ()
  * brasero_burn_session_output_supported ()
  * brasero_burn_session_can_blank ()
- * brasero_burn_session_get_blank_flags ()
- * this function gets a few parameters describing
- * how tests/checks should be performed.
+ * this function gets whether the checks will 
+ * ignore the plugins with errors (return %TRUE).
  *
- * Returns:  #BraseroSessionCheckFlags
+ * Returns:  #gboolean
  */
 
-BraseroSessionCheckFlags
-brasero_burn_session_get_check_flags (BraseroBurnSession *session)
+gboolean
+brasero_burn_session_get_strict_support (BraseroBurnSession *session)
 {
 	BraseroBurnSessionPrivate *priv;
 
-	g_return_val_if_fail (BRASERO_IS_BURN_SESSION (session), BRASERO_SESSION_CHECK_NONE);
+	g_return_val_if_fail (BRASERO_IS_BURN_SESSION (session), FALSE);
 
 	priv = BRASERO_BURN_SESSION_PRIVATE (session);
-	return priv->check_flags;
+	return priv->strict_checks;
 }
 
 /**
diff --git a/libbrasero-burn/brasero-session.h b/libbrasero-burn/brasero-session.h
index 90cede7..aeb9191 100644
--- a/libbrasero-burn/brasero-session.h
+++ b/libbrasero-burn/brasero-session.h
@@ -40,7 +40,6 @@
 #include <brasero-status.h>
 #include <brasero-track.h>
 
-
 G_BEGIN_DECLS
 
 #define BRASERO_TYPE_BURN_SESSION         (brasero_burn_session_get_type ())
@@ -248,29 +247,33 @@ brasero_burn_session_get_blank_flags (BraseroBurnSession *session,
  * Used to test the possibilities offered for a given session
  */
 
-typedef enum {
-	BRASERO_SESSION_CHECK_NONE					= 0,
-	BRASERO_SESSION_CHECK_USE_FLAGS,
-	BRASERO_SESSION_CHECK_IGNORE_PLUGIN_ERRORS,
-	BRASERO_SESSION_CHECK_SIGNAL_PLUGIN_ERRORS
-} BraseroSessionCheckFlags;
-
 void
-brasero_burn_session_set_check_flags (BraseroBurnSession *session,
-                                           BraseroSessionCheckFlags flags);
+brasero_burn_session_set_strict_support (BraseroBurnSession *session,
+                                         gboolean strict_check);
 
-BraseroSessionCheckFlags
-brasero_burn_session_get_check_flags (BraseroBurnSession *session);
+gboolean
+brasero_burn_session_get_strict_support (BraseroBurnSession *session);
 
 BraseroBurnResult
 brasero_burn_session_can_blank (BraseroBurnSession *session);
 
 BraseroBurnResult
-brasero_burn_session_supported (BraseroBurnSession *session);
+brasero_burn_session_can_burn (BraseroBurnSession *session,
+                               gboolean check_flags);
+
+typedef BraseroBurnResult	(* BraseroForeachPluginErrorCb)	(BraseroPluginErrorType type,
+		                                                         const gchar *detail,
+		                                                         gpointer user_data);
+
+BraseroBurnResult
+brasero_session_foreach_plugin_error (BraseroBurnSession *session,
+                                      BraseroForeachPluginErrorCb callback,
+                                      gpointer user_data);
 
 BraseroBurnResult
 brasero_burn_session_input_supported (BraseroBurnSession *session,
-				      BraseroTrackType *input);
+				      BraseroTrackType *input,
+                                      gboolean check_flags);
 
 BraseroBurnResult
 brasero_burn_session_output_supported (BraseroBurnSession *session,
diff --git a/libbrasero-burn/brasero-status-dialog.c b/libbrasero-burn/brasero-status-dialog.c
index 896ba49..a717fa0 100644
--- a/libbrasero-burn/brasero-status-dialog.c
+++ b/libbrasero-burn/brasero-status-dialog.c
@@ -144,6 +144,9 @@ brasero_status_dialog_update (BraseroStatusDialog *self,
 static void
 brasero_status_dialog_session_ready (BraseroStatusDialog *dialog)
 {
+	BraseroStatusDialogPrivate *priv;
+
+	priv = BRASERO_STATUS_DIALOG_PRIVATE (dialog);
 	gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 }
 
diff --git a/libbrasero-burn/burn-basics.c b/libbrasero-burn/burn-basics.c
index 0001127..f2da09a 100644
--- a/libbrasero-burn/burn-basics.c
+++ b/libbrasero-burn/burn-basics.c
@@ -436,7 +436,8 @@ brasero_burn_library_get_media_capabilities (BraseroMedia media)
 			BraseroPlugin *plugin;
 
 			plugin = plugins->data;
-			if (brasero_plugin_get_active (plugin, BRASERO_PLUGIN_ACTIVE_NONE)) {
+			/* Ignore plugin errors */
+			if (brasero_plugin_get_active (plugin, TRUE)) {
 				/* this link is valid */
 				active = TRUE;
 				break;
diff --git a/libbrasero-burn/burn-caps.c b/libbrasero-burn/burn-caps.c
index 0da71db..b330190 100644
--- a/libbrasero-burn/burn-caps.c
+++ b/libbrasero-burn/burn-caps.c
@@ -69,7 +69,7 @@ brasero_caps_link_free (BraseroCapsLink *link)
 
 gboolean
 brasero_caps_link_active (BraseroCapsLink *link,
-                          BraseroPluginActiveFlags plugin_flags)
+                          gboolean ignore_plugin_errors)
 {
 	GSList *iter;
 
@@ -79,7 +79,7 @@ brasero_caps_link_active (BraseroCapsLink *link,
 		BraseroPlugin *plugin;
 
 		plugin = iter->data;
-		if (brasero_plugin_get_active (plugin, plugin_flags))
+		if (brasero_plugin_get_active (plugin, ignore_plugin_errors))
 			return TRUE;
 	}
 
@@ -103,10 +103,10 @@ brasero_caps_link_need_download (BraseroCapsLink *link)
 		 * error then that means that the link
 		 * can be followed without additional
 		 * download. */
-		if (brasero_plugin_get_active (plugin, BRASERO_PLUGIN_ACTIVE_NONE))
+		if (brasero_plugin_get_active (plugin, FALSE))
 			return NULL;
 
-		if (brasero_plugin_get_active (plugin, BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS)) {
+		if (brasero_plugin_get_active (plugin, TRUE)) {
 			if (!plugin_ret)
 				plugin_ret = plugin;
 			else if (brasero_plugin_get_priority (plugin) > brasero_plugin_get_priority (plugin_ret))
@@ -147,7 +147,8 @@ brasero_caps_has_active_input (BraseroCaps *caps,
 		if (link->caps != input)
 			continue;
 
-		if (brasero_caps_link_active (link, BRASERO_PLUGIN_ACTIVE_NONE))
+		/* Ignore plugin errors */
+		if (brasero_caps_link_active (link, TRUE))
 			return TRUE;
 	}
 
diff --git a/libbrasero-burn/burn-caps.h b/libbrasero-burn/burn-caps.h
index 7cf93e7..2a09a3f 100644
--- a/libbrasero-burn/burn-caps.h
+++ b/libbrasero-burn/burn-caps.h
@@ -99,7 +99,7 @@ brasero_caps_link_need_download (BraseroCapsLink *link);
 
 gboolean
 brasero_caps_link_active (BraseroCapsLink *link,
-                          BraseroPluginActiveFlags check_flags);
+                          gboolean ignore_plugin_errors);
 
 gboolean
 brasero_burn_caps_is_input (BraseroBurnCaps *self,
diff --git a/libbrasero-burn/burn-plugin-manager.c b/libbrasero-burn/burn-plugin-manager.c
index d4106c6..2124008 100644
--- a/libbrasero-burn/burn-plugin-manager.c
+++ b/libbrasero-burn/burn-plugin-manager.c
@@ -74,7 +74,6 @@ G_DEFINE_TYPE (BraseroPluginManager, brasero_plugin_manager, G_TYPE_OBJECT);
 
 enum
 {
-	PLUGIN_ERROR_SIGNAL,
 	CAPS_CHANGED_SIGNAL,
 	LAST_SIGNAL
 };
@@ -329,19 +328,6 @@ brasero_plugin_manager_plugin_state_changed (BraseroPlugin *plugin,
 		       0);
 }
 
-static void
-brasero_plugin_manager_plugin_error (BraseroPlugin *plugin,
-                                     BraseroPluginManager *manager)
-{
-	BraseroPluginManagerPrivate *priv;
-
-	priv = BRASERO_PLUGIN_MANAGER_PRIVATE (manager);
-	g_signal_emit (manager,
-	               caps_signals [PLUGIN_ERROR_SIGNAL],
-	               0,
-	               plugin);
-}
-
 #if 0
 
 /**
@@ -501,15 +487,14 @@ brasero_plugin_manager_init (BraseroPluginManager *self)
 		}
 
 		if (brasero_plugin_get_gtype (plugin) == G_TYPE_NONE) {
-			BRASERO_BURN_LOG ("Load failure, no GType was returned %s",
-					  brasero_plugin_get_error (plugin));
+			gchar *error_string;
+
+			error_string = brasero_plugin_get_error_string (plugin);
+			BRASERO_BURN_LOG ("Load failure, no GType was returned %s", error_string);
+			g_free (error_string);
 		}
 
 		g_signal_connect (plugin,
-		                  "errors",
-		                  G_CALLBACK (brasero_plugin_manager_plugin_error),
-		                  self);
-		g_signal_connect (plugin,
 		                  "activated",
 		                  G_CALLBACK (brasero_plugin_manager_plugin_state_changed),
 		                  self);
@@ -564,16 +549,6 @@ brasero_plugin_manager_class_init (BraseroPluginManagerClass *klass)
 		              NULL, NULL,
 		              g_cclosure_marshal_VOID__VOID,
 		              G_TYPE_NONE, 0);
-	caps_signals [PLUGIN_ERROR_SIGNAL] =
-		g_signal_new ("plugin_error",
-		              G_OBJECT_CLASS_TYPE (klass),
-		              G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
-		              0,
-		              NULL, NULL,
-		              g_cclosure_marshal_VOID__OBJECT,
-		              G_TYPE_NONE,
-		              1,
-		              BRASERO_TYPE_PLUGIN);
 }
 
 BraseroPluginManager *
diff --git a/libbrasero-burn/burn-plugin-manager.h b/libbrasero-burn/burn-plugin-manager.h
index 4e46708..fe2c550 100644
--- a/libbrasero-burn/burn-plugin-manager.h
+++ b/libbrasero-burn/burn-plugin-manager.h
@@ -55,8 +55,6 @@ struct _BraseroPluginManagerClass
 
 	/* <Signals>*/
 	void	(*caps_changed)	(BraseroPluginManager *manager);
-	void	(*plugin_error)	(BraseroPluginManager *manager,
-			                    BraseroPlugin *plugin);
 };
 
 struct _BraseroPluginManager
diff --git a/libbrasero-burn/burn-plugin.c b/libbrasero-burn/burn-plugin.c
index 53ba8e9..7193eca 100644
--- a/libbrasero-burn/burn-plugin.c
+++ b/libbrasero-burn/burn-plugin.c
@@ -136,7 +136,6 @@ enum
 {
 	LOADED_SIGNAL,
 	ACTIVATED_SIGNAL,
-	ERRORS_SIGNAL,
 	LAST_SIGNAL
 };
 
@@ -262,10 +261,10 @@ brasero_plugin_set_active (BraseroPlugin *self, gboolean active)
 
 	priv = BRASERO_PLUGIN_PRIVATE (self);
 
-	was_active = brasero_plugin_get_active (self, BRASERO_PLUGIN_ACTIVE_NONE);
+	was_active = brasero_plugin_get_active (self, FALSE);
 	priv->active = active;
 
-	now_active = brasero_plugin_get_active (self, BRASERO_PLUGIN_ACTIVE_NONE);
+	now_active = brasero_plugin_get_active (self, FALSE);
 	if (was_active == now_active)
 		return;
 
@@ -281,7 +280,7 @@ brasero_plugin_set_active (BraseroPlugin *self, gboolean active)
 
 gboolean
 brasero_plugin_get_active (BraseroPlugin *plugin,
-                           BraseroPluginActiveFlags flags)
+                           gboolean ignore_errors)
 {
 	BraseroPluginPrivate *priv;
 
@@ -294,7 +293,7 @@ brasero_plugin_get_active (BraseroPlugin *plugin,
 		return FALSE;
 
 	if (priv->errors) {
-		if ((flags & BRASERO_PLUGIN_ACTIVE_IGNORE_ERRORS) == 0)
+		if (!ignore_errors)
 			return FALSE;
 	}
 
@@ -577,8 +576,29 @@ brasero_plugin_get_group (BraseroPlugin *self)
 	return priv->group;
 }
 
-const gchar *
-brasero_plugin_get_error (BraseroPlugin *plugin)
+/**
+ * brasero_plugin_get_errors:
+ * @plugin: a #BraseroPlugin.
+ *
+ * This function returns a list of all errors that
+ * prevents the plugin from working properly.
+ *
+ * Returns : a #GSList of #BraseroPluginError structures or %NULL.
+ * It must not be freed.
+ **/
+
+GSList *
+brasero_plugin_get_errors (BraseroPlugin *plugin)
+{
+	BraseroPluginPrivate *priv;
+
+	g_return_val_if_fail (BRASERO_IS_PLUGIN (plugin), NULL);
+	priv = BRASERO_PLUGIN_PRIVATE (plugin);
+	return priv->errors;
+}
+
+gchar *
+brasero_plugin_get_error_string (BraseroPlugin *plugin)
 {
 	gchar *error_string = NULL;
 	BraseroPluginPrivate *priv;
@@ -1051,6 +1071,7 @@ brasero_plugin_get_gtype (BraseroPlugin *self)
 	BraseroPluginPrivate *priv;
 
 	priv = BRASERO_PLUGIN_PRIVATE (self);
+
 	if (priv->errors)
 		return G_TYPE_NONE;
 
@@ -1140,38 +1161,16 @@ brasero_plugin_priority_changed (GConfClient *client,
 	else
 		priv->priority = gconf_value_get_int (value);
 
-	is_active = brasero_plugin_get_active (self, BRASERO_PLUGIN_ACTIVE_NONE);
+	is_active = brasero_plugin_get_active (self, FALSE);
 
 	g_object_notify (G_OBJECT (self), "priority");
-	if (is_active != brasero_plugin_get_active (self, BRASERO_PLUGIN_ACTIVE_NONE))
+	if (is_active != brasero_plugin_get_active (self, FALSE))
 		g_signal_emit (self,
 			       plugin_signals [ACTIVATED_SIGNAL],
 			       0,
 			       is_active);
 }
 
-/**
- * brasero_plugin_need_download:
- * @plugin: a #BraseroPlugin.
- *
- * This is mostly used internally and sends a 
- * signal to report that a plugin needs additional
- * applications/libraries/... to work.
- *
- **/
-
-void
-brasero_plugin_need_download (BraseroPlugin *plugin)
-{
-	BraseroPluginPrivate *priv;
-
-	g_return_if_fail (BRASERO_IS_PLUGIN (plugin));
-	priv = BRASERO_PLUGIN_PRIVATE (plugin);
-	g_signal_emit (plugin,
-	               plugin_signals [ERRORS_SIGNAL],
-	               0);
-}
-
 typedef void	(* BraseroPluginCheckConfig)	(BraseroPlugin *plugin);
 
 /**
@@ -1462,16 +1461,6 @@ brasero_plugin_class_init (BraseroPluginClass *klass)
 		              g_cclosure_marshal_VOID__BOOLEAN,
 		              G_TYPE_NONE, 1,
 			      G_TYPE_BOOLEAN);
-
-	plugin_signals [ERRORS_SIGNAL] =
-		g_signal_new ("errors",
-		              G_OBJECT_CLASS_TYPE (klass),
-		              G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
-		              G_STRUCT_OFFSET (BraseroPluginClass, errors),
-		              NULL, NULL,
-		              g_cclosure_marshal_VOID__VOID,
-		              G_TYPE_NONE, 0,
-			      G_TYPE_NONE);
 }
 
 BraseroPlugin *
diff --git a/libbrasero-utils/Makefile.am b/libbrasero-utils/Makefile.am
index 1c4f94c..656518b 100644
--- a/libbrasero-utils/Makefile.am
+++ b/libbrasero-utils/Makefile.am
@@ -58,7 +58,9 @@ libbrasero_utils_la_SOURCES =		\
 	brasero-io.c        \
 	brasero-io.h        \
 	brasero-metadata.c        \
-	brasero-metadata.h
+	brasero-metadata.h        \
+	brasero-pk.c        \
+	brasero-pk.h
 
 # EXTRA_DIST =			\
 #	libbrasero-utils.symbols
diff --git a/libbrasero-utils/brasero-metadata.c b/libbrasero-utils/brasero-metadata.c
index ee8f4db..95ae1fc 100644
--- a/libbrasero-utils/brasero-metadata.c
+++ b/libbrasero-utils/brasero-metadata.c
@@ -1093,6 +1093,7 @@ brasero_metadata_install_missing_plugins (BraseroMetadata *self)
 		 * - is being downloaded
 		 * If so don't do anything. */
 		detail = gst_missing_plugin_message_get_installer_detail (iter->data);
+
 		download = brasero_metadata_is_downloading (detail);
 		if (download) {
 			download->objects = g_slist_prepend (download->objects, self);
@@ -1181,10 +1182,10 @@ brasero_metadata_bus_messages (GstBus *bus,
 
 		/* here we just want to check if that's a missing codec */
 		if ((priv->flags & BRASERO_METADATA_FLAG_MISSING)
-		     &&   gst_is_missing_plugin_message (msg))
+		&&   gst_is_missing_plugin_message (msg))
 			priv->missing_plugins = g_slist_prepend (priv->missing_plugins, gst_message_ref (msg));
 		else if (!strcmp (gst_structure_get_name (msg->structure), "level")
-		     &&   gst_structure_has_field (msg->structure, "peak")) {
+		&&   gst_structure_has_field (msg->structure, "peak")) {
 			const GValue *value;
 			const GValue *list;
 			gdouble peak;
diff --git a/libbrasero-utils/brasero-pk.c b/libbrasero-utils/brasero-pk.c
new file mode 100644
index 0000000..7536e52
--- /dev/null
+++ b/libbrasero-utils/brasero-pk.c
@@ -0,0 +1,379 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Libbrasero-burn
+ * Copyright (C) Luis Medinas 2008 <lmedinas gmail com>
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ *
+ * Libbrasero-burn is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Libbrasero-burn authors hereby grant permission for non-GPL compatible
+ * GStreamer plugins to be used and distributed together with GStreamer
+ * and Libbrasero-burn. This permission is above and beyond the permissions granted
+ * by the GPL license by which Libbrasero-burn is covered. If you modify this code
+ * you may extend this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ * 
+ * Libbrasero-burn is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/utsname.h>
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <dbus/dbus-glib.h>
+
+#include <gst/pbutils/install-plugins.h>
+#include <gst/pbutils/missing-plugins.h>
+
+#include "brasero-misc.h"
+#include "brasero-pk.h"
+
+static GSList *already_tested = NULL;
+
+typedef struct _BraseroPKPrivate BraseroPKPrivate;
+struct _BraseroPKPrivate
+{
+	DBusGConnection *connection;
+	DBusGProxy *proxy;
+	DBusGProxyCall *call;
+
+	GMainLoop *loop;
+	gboolean res;
+};
+
+#define BRASERO_PK_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_PK, BraseroPKPrivate))
+
+G_DEFINE_TYPE (BraseroPK, brasero_pk, G_TYPE_OBJECT);
+
+static void
+brasero_pk_install_missing_files_result (DBusGProxy *proxy,
+                                         DBusGProxyCall *call,
+                                         gpointer user_data)
+{
+	GError *error = NULL;
+	BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (user_data);
+
+	priv->call = NULL;
+	priv->res = dbus_g_proxy_end_call (proxy,
+	                                   call,
+	                                   &error,
+	                                   G_TYPE_INVALID);
+	if (!priv->res) {
+		BRASERO_UTILS_LOG ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_main_loop_quit (priv->loop);
+}
+
+static void
+brasero_pk_install_gst_plugin_result (GstInstallPluginsReturn res,
+                                      gpointer user_data)
+{
+	BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (user_data);
+
+	switch (res) {
+	case GST_INSTALL_PLUGINS_SUCCESS:
+		priv->res = TRUE;
+		break;
+
+	case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
+	case GST_INSTALL_PLUGINS_USER_ABORT:
+
+	case GST_INSTALL_PLUGINS_NOT_FOUND:
+	case GST_INSTALL_PLUGINS_ERROR:
+	case GST_INSTALL_PLUGINS_CRASHED:
+	default:
+		priv->res = FALSE;
+		break;
+	}
+
+	g_main_loop_quit (priv->loop);
+}
+
+static void
+brasero_pk_cancelled (GCancellable *cancel,
+                      BraseroPK *package)
+{
+	BraseroPKPrivate *priv = BRASERO_PK_PRIVATE (package);
+
+	priv->res = FALSE;
+	g_main_loop_quit (priv->loop);
+}
+
+static gboolean
+brasero_pk_wait_for_call_end (BraseroPK *package,
+                              GCancellable *cancel)
+{
+	BraseroPKPrivate *priv;
+	GMainLoop *loop;
+	gulong sig_int;
+
+	priv = BRASERO_PK_PRIVATE (package);
+
+	loop = g_main_loop_new (NULL, FALSE);
+	priv->loop = loop;
+
+	sig_int = g_signal_connect (cancel,
+	                            "cancelled",
+	                            G_CALLBACK (brasero_pk_cancelled),
+	                            loop);
+
+	GDK_THREADS_LEAVE ();
+	g_main_loop_run (loop);
+	GDK_THREADS_ENTER ();
+
+	g_signal_handler_disconnect (cancel, sig_int);
+
+	g_main_loop_unref (loop);
+	priv->loop = NULL;
+
+	return priv->res;
+}
+
+static gboolean
+brasero_pk_connect (BraseroPK *package)
+{
+	BraseroPKPrivate *priv;
+	GError *error = NULL;
+
+	priv = BRASERO_PK_PRIVATE (package);
+
+	/* check dbus connections, exit if not valid */
+	priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if (priv->connection == NULL) {
+		BRASERO_UTILS_LOG ("%s", error->message);
+		return FALSE;
+	}
+
+	/* get a connection */
+	priv->proxy = dbus_g_proxy_new_for_name (priv->connection,
+	                                         "org.freedesktop.PackageKit",
+	                                         "/org/freedesktop/PackageKit",
+	                                         "org.freedesktop.PackageKit.Modify");
+	if (priv->proxy == NULL) {
+		BRASERO_UTILS_LOG ("Cannot connect to session service");
+		return FALSE;
+	}
+
+	/* don't timeout, as dbus-glib sets the timeout ~25 seconds */
+	dbus_g_proxy_set_default_timeout (priv->proxy, INT_MAX);
+
+	return TRUE;
+}
+
+gboolean
+brasero_pk_install_gstreamer_plugin (BraseroPK *package,
+                                     const gchar *element_name,
+                                     int xid,
+                                    GCancellable *cancel)
+{
+	GstInstallPluginsContext *context;
+	GPtrArray *gst_plugins = NULL;
+	GstInstallPluginsReturn status;
+	gboolean res = FALSE;
+	gchar *detail;
+
+	gst_plugins = g_ptr_array_new ();
+	detail = gst_missing_element_installer_detail_new (element_name);
+	g_ptr_array_add (gst_plugins, detail);
+	g_ptr_array_add (gst_plugins, NULL);
+
+	context = gst_install_plugins_context_new ();
+	gst_install_plugins_context_set_xid (context, xid);
+	status = gst_install_plugins_async ((gchar **) gst_plugins->pdata,
+	                                    context,
+	                                    brasero_pk_install_gst_plugin_result,
+	                                    package);
+
+	if (status == GST_INSTALL_PLUGINS_SUCCESS)
+		res = brasero_pk_wait_for_call_end (package, cancel);
+
+	gst_install_plugins_context_free (context);
+	g_strfreev ((gchar **) gst_plugins->pdata);
+	g_ptr_array_free (gst_plugins, FALSE);
+
+	return res;
+}
+
+static gboolean
+brasero_pk_install_file_requirement (BraseroPK *package,
+                                     GPtrArray *missing_files,
+                                     int xid,
+                                    GCancellable *cancel)
+{
+	BraseroPKPrivate *priv;
+
+	priv = BRASERO_PK_PRIVATE (package);
+
+	if (!brasero_pk_connect (package))
+		return FALSE;
+
+	priv->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, "InstallProvideFiles",
+							   brasero_pk_install_missing_files_result,
+	                                                   package,
+							   NULL,
+							   INT_MAX,
+							   G_TYPE_UINT, xid,
+							   G_TYPE_STRV, missing_files->pdata,
+							   G_TYPE_STRING, "hide-finished,hide-warnings",
+							   G_TYPE_INVALID);
+
+	return brasero_pk_wait_for_call_end (package, cancel);
+}
+
+gboolean
+brasero_pk_install_missing_app (BraseroPK *package,
+                                const gchar *file_name,
+                                int xid,
+                                GCancellable *cancel)
+{
+	gchar *path;
+	gboolean res;
+	GPtrArray *missing_files;
+
+	path = g_build_path (G_DIR_SEPARATOR_S,
+	                     "/usr/bin/",
+	                     file_name,
+	                     NULL);
+
+	if (g_slist_find_custom (already_tested, path, (GCompareFunc) g_strcmp0)) {
+		g_free (path);
+		return FALSE;
+	}
+	already_tested = g_slist_prepend (already_tested, g_strdup (path));
+
+	missing_files = g_ptr_array_new ();
+	g_ptr_array_add (missing_files, path);
+	g_ptr_array_add (missing_files, NULL);
+
+	res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
+
+	g_strfreev ((gchar **) missing_files->pdata);
+	g_ptr_array_free (missing_files, FALSE);
+
+	return res;
+}
+
+/**
+ * pk_gst_get_arch_suffix:
+ *
+ * Return value: something other than blank if we are running on 64 bit.
+ **/
+static gboolean
+pk_gst_is_x64_arch (void)
+{
+	gint retval;
+	struct utsname buf;
+
+	retval = uname (&buf);
+
+	/* did we get valid value? */
+	if (retval != 0 || buf.machine == NULL) {
+		g_warning ("PackageKit: cannot get machine type");
+		return FALSE;
+	}
+
+	/* 64 bit machines */
+	if (g_strcmp0 (buf.machine, "x86_64") == 0)
+		return TRUE;
+
+	/* 32 bit machines and unrecognized arch */
+	return FALSE;
+}
+
+gboolean
+brasero_pk_install_missing_library (BraseroPK *package,
+                                    const gchar *library_name,
+                                    int xid,
+                                    GCancellable *cancel)
+{
+	gchar *path;
+	gboolean res;
+	GPtrArray *missing_files;
+
+	if (pk_gst_is_x64_arch ())
+		path = g_strdup_printf ("/usr/lib64/%s", library_name);
+	else
+		path = g_strdup_printf ("/usr/lib/%s", library_name);
+
+	if (g_slist_find_custom (already_tested, path, (GCompareFunc) g_strcmp0)) {
+		g_free (path);
+		return FALSE;
+	}
+	already_tested = g_slist_prepend (already_tested, g_strdup (path));
+
+	missing_files = g_ptr_array_new ();
+	g_ptr_array_add (missing_files, path);
+	g_ptr_array_add (missing_files, NULL);
+
+	res = brasero_pk_install_file_requirement (package, missing_files, xid, cancel);
+
+	g_strfreev ((gchar **) missing_files->pdata);
+	g_ptr_array_free (missing_files, FALSE);
+
+	return res;
+}
+
+static void
+brasero_pk_init (BraseroPK *object)
+{}
+
+static void
+brasero_pk_finalize (GObject *object)
+{
+	BraseroPKPrivate *priv;
+
+	priv = BRASERO_PK_PRIVATE (object);
+
+	if (priv->call)
+		dbus_g_proxy_cancel_call (priv->proxy, priv->call);
+
+	if (priv->loop)
+		g_main_loop_quit (priv->loop);
+
+	if (priv->proxy) {
+		g_object_unref (priv->proxy);
+		priv->proxy = NULL;
+	}
+
+	if (priv->connection) {
+		dbus_g_connection_unref (priv->connection);
+		priv->connection = NULL;
+	}
+
+	G_OBJECT_CLASS (brasero_pk_parent_class)->finalize (object);
+}
+
+static void
+brasero_pk_class_init (BraseroPKClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (BraseroPKPrivate));
+
+	object_class->finalize = brasero_pk_finalize;
+}
+
+BraseroPK *
+brasero_pk_new (void)
+{
+	return g_object_new (BRASERO_TYPE_PK, NULL);
+}
diff --git a/libbrasero-utils/brasero-pk.h b/libbrasero-utils/brasero-pk.h
new file mode 100644
index 0000000..a7242e8
--- /dev/null
+++ b/libbrasero-utils/brasero-pk.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Libbrasero-burn
+ * Copyright (C) Luis Medinas 2008 <lmedinas gmail com>
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ *
+ * Libbrasero-burn is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Libbrasero-burn authors hereby grant permission for non-GPL compatible
+ * GStreamer plugins to be used and distributed together with GStreamer
+ * and Libbrasero-burn. This permission is above and beyond the permissions granted
+ * by the GPL license by which Libbrasero-burn is covered. If you modify this code
+ * you may extend this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ * 
+ * Libbrasero-burn is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _BRASERO_PK_H_
+#define _BRASERO_PK_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_PK             (brasero_pk_get_type ())
+#define BRASERO_PK(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_PK, BraseroPK))
+#define BRASERO_PK_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_PK, BraseroPKClass))
+#define BRASERO_IS_PK(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_PK))
+#define BRASERO_IS_PK_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_PK))
+#define BRASERO_PK_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_PK, BraseroPKClass))
+
+typedef struct _BraseroPKClass BraseroPKClass;
+typedef struct _BraseroPK BraseroPK;
+
+struct _BraseroPKClass
+{
+	GObjectClass parent_class;
+};
+
+struct _BraseroPK
+{
+	GObject parent_instance;
+};
+
+GType brasero_pk_get_type (void) G_GNUC_CONST;
+
+BraseroPK *brasero_pk_new (void);
+
+gboolean
+brasero_pk_install_gstreamer_plugin (BraseroPK *package,
+                                     const gchar *element_name,
+                                     int xid,
+                                     GCancellable *cancel);
+gboolean
+brasero_pk_install_missing_app (BraseroPK *package,
+                                const gchar *file_name,
+                                int xid,
+                                GCancellable *cancel);
+gboolean
+brasero_pk_install_missing_library (BraseroPK *package,
+                                    const gchar *library_name,
+                                    int xid,
+                                    GCancellable *cancel);
+
+G_END_DECLS
+
+#endif /* _BRASERO_PK_H_ */
diff --git a/src/brasero-player-bacon.c b/src/brasero-player-bacon.c
index 86caed9..f38903b 100644
--- a/src/brasero-player-bacon.c
+++ b/src/brasero-player-bacon.c
@@ -723,7 +723,7 @@ brasero_player_bacon_setup_pipe (BraseroPlayerBacon *bacon)
 	return;
 
 error:
-	g_warning ("player creation error");
+	g_message ("player creation error");
 	brasero_player_bacon_clear_pipe (bacon);
 	g_signal_emit (bacon,
 		       brasero_player_bacon_signals [STATE_CHANGED_SIGNAL],
diff --git a/src/brasero-plugin-manager-ui.c b/src/brasero-plugin-manager-ui.c
index 58c6193..705814a 100644
--- a/src/brasero-plugin-manager-ui.c
+++ b/src/brasero-plugin-manager-ui.c
@@ -205,6 +205,7 @@ plugin_manager_ui_view_info_cell_cb (GtkTreeViewColumn *tree_column,
 				     gpointer           data)
 {
 	BraseroPlugin *plugin;
+	gchar *error_string;
 	gchar *text;
 	
 	g_return_if_fail (tree_model != NULL);
@@ -217,13 +218,16 @@ plugin_manager_ui_view_info_cell_cb (GtkTreeViewColumn *tree_column,
 	if (!plugin)
 		return;
 
-	if (brasero_plugin_get_error (plugin))
+	error_string = brasero_plugin_get_error_string (plugin);
+	if (error_string) {
 		text = g_markup_printf_escaped ("<b>%s</b>\n%s\n<i>%s</i>",
 						/* Use the translated name of 
 						 * the plugin. */
 						_(brasero_plugin_get_name (plugin)),
 						brasero_plugin_get_description (plugin),
-						brasero_plugin_get_error (plugin));
+						error_string);
+		g_free (error_string);
+	}
 	else
 		text = g_markup_printf_escaped ("<b>%s</b>\n%s",
 						/* Use the translated name of 
diff --git a/src/brasero-project.c b/src/brasero-project.c
index 4dd1f6f..aa36265 100644
--- a/src/brasero-project.c
+++ b/src/brasero-project.c
@@ -37,6 +37,7 @@
 #include <gio/gio.h>
 
 #include <gtk/gtk.h>
+#include <gdk/gdkx.h>
 
 #include <gst/gst.h>
 
@@ -44,6 +45,7 @@
 
 #include "brasero-misc.h"
 #include "brasero-jacket-edit.h"
+#include "brasero-pk.h"
 
 #include "brasero-tags.h"
 #include "brasero-session.h"
@@ -165,6 +167,8 @@ struct BraseroProjectPrivate {
 
 	BraseroURIContainer *current_source;
 
+	GCancellable *cancel;
+
 	GtkWidget *chooser;
 	gulong selected_id;
 	gulong activated_id;
@@ -1191,6 +1195,11 @@ brasero_project_finalize (GObject *object)
 	BraseroProject *cobj;
 	cobj = BRASERO_PROJECT(object);
 
+	if (cobj->priv->cancel) {
+		g_cancellable_cancel (cobj->priv->cancel);
+		cobj->priv->cancel = NULL;
+	}
+
 	if (cobj->priv->session) {
 		g_object_unref (cobj->priv->session);
 		cobj->priv->session = NULL;
@@ -1319,6 +1328,124 @@ brasero_project_check_status (BraseroProject *project)
         return (response == GTK_RESPONSE_OK)? BRASERO_BURN_OK:BRASERO_BURN_CANCEL;
 }
 
+static BraseroBurnResult
+brasero_project_install_missing (BraseroPluginErrorType type,
+                                 const gchar *detail,
+                                 gpointer user_data)
+{
+	BraseroProject *project = BRASERO_PROJECT (user_data);
+	GCancellable *cancel;
+	BraseroPK *package;
+	GtkWidget *parent;
+	gboolean res;
+	int xid = 0;
+
+	/* Get the xid */
+	parent = gtk_widget_get_toplevel (GTK_WIDGET (project));
+	xid = gdk_x11_drawable_get_xid (GDK_DRAWABLE (GTK_WIDGET (parent)->window));
+
+	package = brasero_pk_new ();
+	cancel = g_cancellable_new ();
+	project->priv->cancel = cancel;
+	switch (type) {
+		case BRASERO_PLUGIN_ERROR_MISSING_APP:
+			res = brasero_pk_install_missing_app (package, detail, xid, cancel);
+			break;
+
+		case BRASERO_PLUGIN_ERROR_MISSING_LIBRARY:
+			res = brasero_pk_install_missing_library (package, detail, xid, cancel);
+			break;
+
+		case BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN:
+			res = brasero_pk_install_gstreamer_plugin (package, detail, xid, cancel);
+			break;
+
+		default:
+			res = FALSE;
+			break;
+	}
+
+	if (package) {
+		g_object_unref (package);
+		package = NULL;
+	}
+
+	if (g_cancellable_is_cancelled (cancel)) {
+		g_object_unref (cancel);
+		return BRASERO_BURN_CANCEL;
+	}
+
+	project->priv->cancel = NULL;
+	g_object_unref (cancel);
+
+	if (!res)
+		return BRASERO_BURN_ERR;
+
+	return BRASERO_BURN_RETRY;
+}
+
+static BraseroBurnResult
+brasero_project_list_missing (BraseroPluginErrorType type,
+                              const gchar *detail,
+                              gpointer user_data)
+{
+	GString *string = user_data;
+
+	if (type == BRASERO_PLUGIN_ERROR_MISSING_APP) {
+		g_string_append_c (string, '\n');
+		/* Translators: %s is the name of a missing application */
+		g_string_append_printf (string, _("%s (application)"), detail);
+	}
+	else if (type == BRASERO_PLUGIN_ERROR_MISSING_LIBRARY) {
+		g_string_append_c (string, '\n');
+		/* Translators: %s is the name of a missing library */
+		g_string_append_printf (string, _("%s (library)"), detail);
+	}
+	else if (type == BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN) {
+		g_string_append_c (string, '\n');
+		/* Translators: %s is the name of a missing Gstreamer plugin */
+		g_string_append_printf (string, _("%s (Gstreamer plugin)"), detail);
+	}
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_project_check_plugins_not_ready (BraseroProject *project,
+                                         BraseroBurnSession *session)
+{
+	BraseroBurnResult result;
+	GtkWidget *parent;
+	GString *string;
+
+	parent = gtk_widget_get_toplevel (GTK_WIDGET (project));
+	gtk_widget_set_sensitive (parent, FALSE);
+
+	result = brasero_session_foreach_plugin_error (session,
+	                                               brasero_project_install_missing,
+	                                               project);
+	if (result == BRASERO_BURN_CANCEL)
+		return result;
+
+	gtk_widget_set_sensitive (parent, TRUE);
+
+	if (result == BRASERO_BURN_OK)
+		return result;
+
+	string = g_string_new (_("Please install the following manually and try again:"));
+	brasero_session_foreach_plugin_error (session,
+	                                      brasero_project_list_missing,
+	                                      string);
+
+	brasero_utils_message_dialog (parent,
+	                              _("All required applications and libraries are not installed."),
+	                              string->str,
+	                              GTK_MESSAGE_ERROR);
+	g_string_free (string, TRUE);
+
+	return BRASERO_BURN_ERR;
+}
+
 /******************************** burning **************************************/
 static void
 brasero_project_setup_session (BraseroProject *project,
@@ -1483,6 +1610,10 @@ brasero_project_burn (BraseroProject *project)
 	if (brasero_project_check_status (project) != BRASERO_BURN_OK)
 		return;
 
+	/* Check that we are not missing any plugin */
+	if (brasero_project_check_plugins_not_ready (project, BRASERO_BURN_SESSION (project->priv->session)) != BRASERO_BURN_OK)
+		return;
+
 	if (!brasero_burn_session_is_dest_file (BRASERO_BURN_SESSION (project->priv->session)))
 		res = brasero_project_drive_properties (project);
 	else
@@ -1614,8 +1745,7 @@ brasero_project_new_session (BraseroProject *project,
 	else
 		project->priv->session = brasero_session_cfg_new ();
 
-	brasero_burn_session_set_check_flags (BRASERO_BURN_SESSION (project->priv->session),
-	                                      BRASERO_SESSION_CHECK_IGNORE_PLUGIN_ERRORS);
+	brasero_burn_session_set_strict_support (BRASERO_BURN_SESSION (project->priv->session), FALSE);
 
 	/* NOTE: "is-valid" is emitted whenever there is a change in the
 	 * contents of the session. So no need to connect to track-added, ... */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]