brasero r816 - in trunk: . src src/plugins/cdrkit src/plugins/cdrtools src/plugins/checksum src/plugins/libburnia



Author: philippr
Date: Sat May 17 20:16:21 2008
New Revision: 816
URL: http://svn.gnome.org/viewvc/brasero?rev=816&view=rev

Log:
2008-05-17  Philippe Rouquier  <algernon localhost localdomain>

	Lots of bug fixes and patches delayed due to the closing of SVN

	Added multisession/grow images capabilites to libisofs/libburn

	Many improvements to libburn backend

	Fix a problem when retrieving size for multisession images with mkisofs/genisoimage
	
	Added message infrastructure to project and removed libnotify deps
	Now multisession message is displayed like project loading and too little free space

	Make DBus dependency compulsory
	
	No medium reload before checksum now
	One known bug is with tracks with less than 300 sectors.
	That needs further work (reading disc tree structure through read_cd)

	Remove close if successful burning option from burn dialog

	Fix session label potential crash

	Fix libdvdcss plugin appearing in plugin dialog

	* configure.in:
	* src/Makefile.am:
	* src/brasero-async-task-manager.c
	(brasero_async_task_manager_foreach_active_remove):
	* src/brasero-audio-disc.c (brasero_audio_disc_add_ui):
	* src/brasero-burn-dialog.c (brasero_burn_dialog_init),
	(brasero_burn_dialog_finalize), (brasero_burn_dialog_success_run),
	(brasero_burn_dialog_end_session),
	(brasero_burn_dialog_tray_show_dialog_cb):
	* src/brasero-data-disc.c (brasero_data_disc_import_session),
	(brasero_data_disc_import_session_cb),
	(brasero_data_disc_project_loaded_cb),
	(brasero_disc_disc_session_import_response_cb),
	(brasero_data_disc_session_available_cb),
	(brasero_data_disc_clear), (brasero_data_disc_reset),
	(brasero_data_disc_message_response_cb),
	(brasero_data_disc_load_track), (brasero_data_disc_add_ui),
	(brasero_data_disc_init), (brasero_data_disc_finalize):
	* src/brasero-disc-message.c (brasero_disc_message_timeout),
	(brasero_disc_message_set_timeout),
	(brasero_disc_message_button_clicked_cb),
	(brasero_disc_message_add_button),
	(brasero_disc_message_add_close_button), (style_set),
	(brasero_disc_message_init), (brasero_disc_message_finalize),
	(brasero_disc_message_realize):
	* src/brasero-disc-message.h:
	* src/brasero-disc-option-dialog.c
	(brasero_disc_option_dialog_title_widget):
	* src/brasero-disc.c (brasero_disc_add_ui):
	* src/brasero-disc.h:
	* src/brasero-notify.c (brasero_notify_remove_all_messages),
	(brasero_notify_get_message_by_context_id),
	(brasero_notify_message_remove), (brasero_notify_message_add),
	(brasero_notify_button_add), (brasero_notify_init),
	(brasero_notify_finalize), (brasero_notify_class_init),
	(brasero_notify_new):
	* src/brasero-notify.h:
	* src/brasero-project.c (brasero_project_init),
	(brasero_project_error_size_dialog), (brasero_project_check_size),
	(brasero_project_switch):
	* src/brasero-tray.c:
	* src/burn-caps.c (brasero_caps_disc_new_attribute),
	(brasero_caps_disc_new_subtype):
	* src/burn-dbus.c (brasero_inhibit_suspend):
	* src/burn-dbus.h:
	* src/burn-medium.c (brasero_medium_get_next_writable_address),
	(brasero_medium_track_get_info), (brasero_medium_reload_info):
	* src/burn-medium.h:
	* src/burn.c (brasero_burn_record_session), (brasero_burn_check),
	(brasero_burn_record), (brasero_burn_blank):
	* src/main.c (main):
	* src/plugins/cdrkit/burn-genisoimage.c
	(brasero_genisoimage_set_argv_image),
	(brasero_genisoimage_export_caps):
	* src/plugins/cdrtools/burn-mkisofs.c
	(brasero_mkisofs_set_argv_image), (brasero_mkisofs_export_caps):
	* src/plugins/checksum/burn-checksum-image.c
	(brasero_checksum_image_checksum_fd_input):
	* src/plugins/libburnia/Makefile.am:
	* src/plugins/libburnia/burn-libburn-common.c
	(brasero_libburn_common_ctx_free),
	(brasero_libburn_common_ctx_new),
	(brasero_libburn_common_status_changed),
	(brasero_libburn_common_status):
	* src/plugins/libburnia/burn-libburn-common.h:
	* src/plugins/libburnia/burn-libburn.c
	(brasero_libburn_src_free_data), (brasero_libburn_src_get_size),
	(brasero_libburn_src_set_size), (brasero_libburn_src_read_xt),
	(brasero_libburn_create_fd_source), (brasero_libburn_add_fd_track),
	(brasero_libburn_add_file_track),
	(brasero_libburn_setup_session_fd),
	(brasero_libburn_setup_session_file),
	(brasero_libburn_start_record), (brasero_libburn_start_erase),
	(brasero_libburn_stop), (brasero_libburn_clock_tick),
	(brasero_libburn_finalize), (brasero_libburn_export_caps):
	* src/plugins/libburnia/burn-libisofs.c
	(brasero_libisofs_create_image), (brasero_libisofs_import_read),
	(brasero_libisofs_import_open), (brasero_libisofs_import_close),
	(brasero_libisofs_import_free),
	(brasero_libisofs_import_last_session),
	(brasero_libisofs_create_volume_thread),
	(brasero_libisofs_create_volume), (brasero_libisofs_stop_real),
	(brasero_libisofs_clean_output), (brasero_libisofs_export_caps):


Added:
   trunk/src/brasero-notify.c
   trunk/src/brasero-notify.h
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/src/Makefile.am
   trunk/src/brasero-async-task-manager.c
   trunk/src/brasero-audio-disc.c
   trunk/src/brasero-burn-dialog.c
   trunk/src/brasero-data-disc.c
   trunk/src/brasero-disc-message.c
   trunk/src/brasero-disc-message.h
   trunk/src/brasero-disc-option-dialog.c
   trunk/src/brasero-disc.c
   trunk/src/brasero-disc.h
   trunk/src/brasero-project.c
   trunk/src/brasero-tray.c
   trunk/src/burn-caps.c
   trunk/src/burn-dbus.c
   trunk/src/burn-dbus.h
   trunk/src/burn-medium.c
   trunk/src/burn-medium.h
   trunk/src/burn.c
   trunk/src/main.c
   trunk/src/plugins/cdrkit/burn-genisoimage.c
   trunk/src/plugins/cdrtools/burn-mkisofs.c
   trunk/src/plugins/checksum/burn-checksum-image.c
   trunk/src/plugins/libburnia/Makefile.am
   trunk/src/plugins/libburnia/burn-libburn-common.c
   trunk/src/plugins/libburnia/burn-libburn-common.h
   trunk/src/plugins/libburnia/burn-libburn.c
   trunk/src/plugins/libburnia/burn-libisofs.c

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sat May 17 20:16:21 2008
@@ -95,6 +95,8 @@
 GSTREAMER_BASE_REQUIRED=0.10.0
 LIBXML2_REQUIRED=2.6.0
 HAL_REQUIRED=0.5
+DBUS_REQUIRED=0.7.2
+
 GNOME_DOC_INIT
 
 dnl ** used by brasero and one plugin
@@ -137,7 +139,8 @@
 	gtk+-2.0 >= $GTK_REQUIRED		\
 	libgnome-2.0 >= $LIBGNOME_REQUIRED	\
 	libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED	\
-	libxml-2.0 >= $LIBXML2_REQUIRED)
+	libxml-2.0 >= $LIBXML2_REQUIRED	\
+	dbus-glib-1 >= $DBUS_REQUIRED)
 
 AC_SUBST(BRASERO_CFLAGS)
 AC_SUBST(BRASERO_LIBS)
@@ -193,24 +196,25 @@
 AM_CONDITIONAL(BUILD_CDRKIT, test x"$build_cdrkit" = "xyes")
 
 dnl ****************check for libnotify (optional)**************
-LIBNOTIFY_REQUIRED=0.3.0
-
-AC_ARG_ENABLE(libnotify,
-			[  --enable-libnotify		use libnotify if available [[default = yes]]],,
-			[enable_libnotify="yes"])
+dnl disable because not used any more
+dnl LIBNOTIFY_REQUIRED=0.3.0
 
-if test x"$enable_libnotify" = "xyes"; then
-	PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED, build_libnotify=yes, build_libnotify=no)
-else
-	build_libnotify="no"
-fi
-
-if test x"$build_libnotify" = "xyes"; then
-	BRASERO_CFLAGS="$BRASERO_CFLAGS $LIBNOTIFY_CFLAGS"
-	BRASERO_LIBS="$BRASERO_LIBS $LIBNOTIFY_LIBS"
-	AC_DEFINE(HAVE_LIBNOTIFY, 1, [define if you  want to use with libnotify support])
-fi
-AM_CONDITIONAL(HAVE_LIBNOTIFY, test x"$build_libnotify" = "xyes")
+dnl AC_ARG_ENABLE(libnotify,
+dnl			[  --enable-libnotify		use libnotify if available [[default = yes]]],,
+dnl			[enable_libnotify="yes"])
+
+dnl if test x"$enable_libnotify" = "xyes"; then
+dnl	PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED, build_libnotify=yes, build_libnotify=no)
+dnl else
+dnl	build_libnotify="no"
+dnl fi
+
+dnl if test x"$build_libnotify" = "xyes"; then
+dnl	BRASERO_CFLAGS="$BRASERO_CFLAGS $LIBNOTIFY_CFLAGS"
+dnl	BRASERO_LIBS="$BRASERO_LIBS $LIBNOTIFY_LIBS"
+dnl	AC_DEFINE(HAVE_LIBNOTIFY, 1, [define if you  want to use with libnotify support])
+dnl fi
+dnl AM_CONDITIONAL(HAVE_LIBNOTIFY, test x"$build_libnotify" = "xyes")
 
 dnl ****************check for search (optional)**************
 BEAGLE_REQUIRED=0.3.0
@@ -252,27 +256,6 @@
 fi
 AM_CONDITIONAL(BUILD_PLAYLIST, test x"$build_totem" = "xyes")
 
-dnl ****************check for dbus (optional)**************
-DBUS_REQUIRED=0.7.2
-
-AC_ARG_ENABLE(dbus,
-			[  --enable-dbus		build dbus (if Gnome Power Manager is available)[[default = yes]]],,
-			[enable_dbus="yes"])
-
-if test x"$enable_dbus" = "xyes"; then
-	PKG_CHECK_MODULES(DBUS, dbus-glib-1 >= $DBUS_REQUIRED, build_dbus=yes, build_dbus=no)
-else
-	build_dbus="no"
-fi
-
-if test x"$build_dbus" = "xyes"; then
-	BRASERO_CFLAGS="$BRASERO_CFLAGS $DBUS_CFLAGS"
-	BRASERO_LIBS="$BRASERO_LIBS $DBUS_LIBS"
-	AC_DEFINE(BUILD_DBUS, 1, [define if you want to build dbus])
-fi
-AM_CONDITIONAL(BUILD_PLAYLIST, test x"$build_dbus" = "xyes")
-
-
 dnl ****************check for preview (optional)**************
 GSTREAMER_MODULE_REQUIRED=0.10.0
 AC_ARG_ENABLE(preview,
@@ -365,14 +348,14 @@
 echo "$PACKAGE configuration summary:"
 echo "----------------------------------"
 
+dnl 	Build libnotify support : ${build_libnotify}
+
 echo "Version: $BRASERO_VERSION
 	Update caches: ${enable_caches}
 	Build inotify: ${enable_inotify}
 	Build search pane : ${build_beagle}
 	Build playlist pane : ${build_totem}
 	Build Preview pane : ${enable_preview}
-	Build libnotify support : ${build_libnotify}
-	Build dbus support : ${build_dbus}
 	Build cdrtools plugins : ${build_cdrtools}
 	Build cdrkit plugins : ${build_cdrkit}
 	Build libburnia plugins : ${build_libburnia}

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sat May 17 20:16:21 2008
@@ -255,7 +255,9 @@
 	brasero-multi-song-props.h         \
 	brasero-multi-song-props.c         \
 	brasero-rename.h         \
-	brasero-rename.c
+	brasero-rename.c         \
+	brasero-notify.c         \
+	brasero-notify.h
 
 if BUILD_INOTIFY
 brasero_SOURCES += brasero-file-monitor.c brasero-file-monitor.h

Modified: trunk/src/brasero-async-task-manager.c
==============================================================================
--- trunk/src/brasero-async-task-manager.c	(original)
+++ trunk/src/brasero-async-task-manager.c	Sat May 17 20:16:21 2008
@@ -406,12 +406,15 @@
 		}
 	}
 
-	while (tasks) {
+	while (tasks && self->priv->active_tasks) {
+		GSList *next;
+
 		/* Now we wait for all these active tasks to be finished */
 		g_cond_wait (self->priv->task_finished, self->priv->lock);
 
-		for (iter = tasks; iter; iter = iter->next) {
+		for (iter = tasks; iter; iter = next) {
 			ctx = iter->data;
+			next = iter->next;
 
 			if (g_slist_find (self->priv->active_tasks, ctx))
 				continue;
@@ -420,7 +423,6 @@
 
 			/* NOTE: no need to call destroy callback here 
 			 * since it was done in the thread loop. */
-			break;
 		}
 	}
 

Modified: trunk/src/brasero-audio-disc.c
==============================================================================
--- trunk/src/brasero-audio-disc.c	(original)
+++ trunk/src/brasero-audio-disc.c	Sat May 17 20:16:21 2008
@@ -118,7 +118,9 @@
 brasero_audio_disc_reset (BraseroDisc *disc);
 
 static guint
-brasero_audio_disc_add_ui (BraseroDisc *disc, GtkUIManager *manager);
+brasero_audio_disc_add_ui (BraseroDisc *disc,
+			   GtkUIManager *manager,
+			   GtkWidget *message);
 
 static gboolean
 brasero_audio_disc_button_pressed_cb (GtkTreeView *tree,
@@ -493,7 +495,9 @@
 }
 
 static guint
-brasero_audio_disc_add_ui (BraseroDisc *disc, GtkUIManager *manager)
+brasero_audio_disc_add_ui (BraseroDisc *disc,
+			   GtkUIManager *manager,
+			   GtkWidget *message)
 {
 	BraseroAudioDisc *audio_disc;
 	GError *error = NULL;

Modified: trunk/src/brasero-burn-dialog.c
==============================================================================
--- trunk/src/brasero-burn-dialog.c	(original)
+++ trunk/src/brasero-burn-dialog.c	Sat May 17 20:16:21 2008
@@ -78,25 +78,18 @@
 brasero_burn_dialog_tray_show_dialog_cb (BraseroTrayIcon *tray,
 					 gboolean show,
 					 GtkWidget *dialog);
-static void
-brasero_burn_dialog_tray_close_after_cb (BraseroTrayIcon *tray,
-					 gboolean close,
-					 BraseroBurnDialog *dialog);
 
 struct BraseroBurnDialogPrivate {
 	BraseroBurn *burn;
 	BraseroTrackType input;
 	BraseroBurnSession *session;
 
-	GtkWidget *close_check;
 	GtkWidget *progress;
 	GtkWidget *header;
 	GtkWidget *cancel;
 	GtkWidget *image;
 	BraseroTrayIcon *tray;
 
-	gint close_timeout;
-
 	guint is_writing:1;
 };
 
@@ -1064,10 +1057,6 @@
 			  "show-dialog",
 			  G_CALLBACK (brasero_burn_dialog_tray_show_dialog_cb),
 			  obj);
-	g_signal_connect (obj->priv->tray,
-			  "close-after",
-			  G_CALLBACK (brasero_burn_dialog_tray_close_after_cb),
-			  obj);
 
 	alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
 	gtk_widget_show (alignment);
@@ -1104,14 +1093,6 @@
 			    FALSE,
 			    0);
 
-	obj->priv->close_check = gtk_check_button_new_with_mnemonic (_("_Close the application if the burn process is successful"));
-	gtk_widget_show (obj->priv->close_check);
-	gtk_box_pack_end (GTK_BOX (obj->priv->progress),
-			  obj->priv->close_check,
-			  FALSE,
-			  FALSE,
-			  0);
-
 	/* buttons */
 	obj->priv->cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
 	gtk_widget_show (obj->priv->cancel);
@@ -1154,11 +1135,6 @@
 		cobj->priv->tray = NULL;
 	}
 
-	if (cobj->priv->close_timeout) {
-		g_source_remove (cobj->priv->close_timeout);
-		cobj->priv->close_timeout = 0;
-	}
-
 	if (cobj->priv->session) {
 		g_object_unref (cobj->priv->session);
 		cobj->priv->session = NULL;
@@ -1576,34 +1552,12 @@
 	gtk_widget_destroy (message);
 }
 
-static gboolean
-brasero_burn_dialog_success_timeout (BraseroBurnDialog *dialog)
-{
-	gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-	dialog->priv->close_timeout = 0;
-
-	return FALSE;
-}
-
 static void
 brasero_burn_dialog_success_run (BraseroBurnDialog *dialog)
 {
 	gint answer;
 
-	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->close_check))) {
-		dialog->priv->close_timeout = g_timeout_add (TIMEOUT,
-							     (GSourceFunc) brasero_burn_dialog_success_timeout,
-							     dialog);
-	}
-
 	answer = gtk_dialog_run (GTK_DIALOG (dialog));
-
-	/* remove the timeout if need be */
-	if (dialog->priv->close_timeout) {
-		g_source_remove (dialog->priv->close_timeout);
-		dialog->priv->close_timeout = 0;
-	}
-
 	if (answer == GTK_RESPONSE_CLOSE) {
 		GtkWidget *contents;
 		GtkWidget *window;
@@ -1757,8 +1711,6 @@
 				 BraseroBurnResult result,
 				 GError *error)
 {
-	gboolean close_dialog;
-
 	if (dialog->priv->burn) {
 		g_object_unref (dialog->priv->burn);
 		dialog->priv->burn = NULL;
@@ -1768,10 +1720,8 @@
 
 	if (result == BRASERO_BURN_CANCEL) {
 		/* nothing to do */
-		close_dialog = FALSE;
 	}
 	else if (error || result != BRASERO_BURN_OK) {
-		close_dialog = FALSE;
 		brasero_burn_dialog_notify_error (dialog, error);
 	}
 	else {
@@ -1789,10 +1739,9 @@
 		}
 
 		brasero_burn_dialog_notify_success (dialog);
-		close_dialog = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->close_check));
 	}
 
-	return close_dialog;
+	return FALSE;
 }
 
 gboolean
@@ -1958,11 +1907,3 @@
 	else
 		gtk_widget_hide (dialog);
 }
-
-static void
-brasero_burn_dialog_tray_close_after_cb (BraseroTrayIcon *tray,
-					 gboolean close,
-					 BraseroBurnDialog *dialog)
-{
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->close_check), close);
-}

Modified: trunk/src/brasero-data-disc.c
==============================================================================
--- trunk/src/brasero-data-disc.c	(original)
+++ trunk/src/brasero-data-disc.c	Sat May 17 20:16:21 2008
@@ -48,13 +48,6 @@
 #include <gtk/gtknotebook.h>
 #include <gtk/gtksizegroup.h>
 
-#ifdef HAVE_LIBNOTIFY
-
-#include <libnotify/notification.h>
-
-#endif
-
-
 #include "eggtreemultidnd.h"
 #include "baobab-cell-renderer-progress.h"
 
@@ -69,6 +62,7 @@
 #include "brasero-utils.h"
 #include "brasero-disc-message.h"
 #include "brasero-rename.h"
+#include "brasero-notify.h"
 
 #include "burn-debug.h"
 #include "burn-basics.h"
@@ -83,6 +77,7 @@
 	GtkWidget *filter;
 	BraseroDataProject *project;
 	GtkWidget *notebook;
+
 	GtkWidget *message;
 
 	GtkUIManager *manager;
@@ -93,19 +88,10 @@
 
 	BraseroFileNode *selected;
 
-#ifdef HAVE_LIBNOTIFY
-
-	NotifyNotification *notification;
-
-#endif
-
 	GSList *load_errors;
 
 	guint loading;
 
-	GSList *libnotify;
-	guint libnotify_id;
-
 	guint editing:1;
 	guint reject_files:1;
 
@@ -212,129 +198,6 @@
 					        brasero_data_disc_iface_disc_init));
 
 /**
- * Notifications
- */
-
-struct _BraseroNotification {
-	gchar *primary;
-	gchar *secondary;
-	GtkWidget *widget;
-};
-typedef struct _BraseroNotification BraseroNotification;
-
-static void
-brasero_data_disc_notification_free (BraseroNotification *notification)
-{
-	g_free (notification->primary);
-	g_free (notification->secondary);
-	g_object_unref (notification->widget);
-	g_free (notification);
-}
-
-#ifdef HAVE_LIBNOTIFY
-
-static void
-brasero_data_disc_notification_closed (NotifyNotification *notification,
-				       BraseroDataDisc *disc)
-{
-	BraseroDataDiscPrivate *priv;
-
-	priv = BRASERO_DATA_DISC_PRIVATE (disc);
-
-	g_object_unref (notification);
-	priv->notification = NULL;
-}
-
-#endif
-
-static gboolean
-brasero_data_disc_notify_user_real (gpointer data)
-{
-	BraseroNotification *notification;
-	BraseroDataDiscPrivate *priv;
-	BraseroDataDisc *disc;
-
-	disc = data;
-	priv = BRASERO_DATA_DISC_PRIVATE (disc);
-
-	if (!priv->libnotify) {
-		priv->libnotify_id = 0;
-		return FALSE;
-	}
-
-	notification = priv->libnotify->data;
-
-#ifdef HAVE_LIBNOTIFY
-
-	GtkWidget *toplevel;
-
-	/* see if we should notify the user. What we want to avoid is to have
-	 * two notifications at the same time */
-	NotifyNotification *notify;
-
-	/* see if the previous notification has finished to be displayed */
-	if (priv->notification)
-		return TRUE;
-
-	/* is the widget ready and is the toplevel window active */
-	toplevel = gtk_widget_get_toplevel (notification->widget);
-	if (!GTK_WIDGET_REALIZED (notification->widget)
-	||  !gtk_window_has_toplevel_focus (GTK_WINDOW (toplevel)))
-		return TRUE;
-
-	/* Good to go */
-	notify = notify_notification_new (notification->primary,
-					  notification->secondary,
-					  NULL,
-					  notification->widget);
-	notify_notification_set_timeout (notify, 5000);
-	g_signal_connect (notify,
-			  "closed",
-			  G_CALLBACK (brasero_data_disc_notification_closed),
-			  disc);
-	notify_notification_show (notify, NULL);
-	priv->notification = notify;
-
-#endif
-
-	priv->libnotify = g_slist_remove (priv->libnotify, notification);
-	brasero_data_disc_notification_free (notification);
-
-	return TRUE;
-}
-
-static void
-brasero_data_disc_notify_user (BraseroDataDisc *disc,
-			       const gchar *primary_message,
-			       const gchar *secondary_message,
-			       GtkWidget *focus)
-{
-	BraseroNotification *notification;
-	BraseroDataDiscPrivate *priv;
-
-	priv = BRASERO_DATA_DISC_PRIVATE (disc);
-
-	/* if the widget doesn't even exist, no need to display a notification */
-	if (!focus)
-		return;
-
-	/* we delay notifications since they are sometimes generated just before
-	 * a widget is shown and therefore appear in the right corner and not 
-	 * focused on the widget */
-	notification = g_new0 (BraseroNotification, 1);
-	notification->primary = g_strdup (primary_message);
-	notification->secondary = g_strdup (secondary_message);
-	notification->widget = focus;
-	g_object_ref (focus);
-
-	priv->libnotify = g_slist_prepend (priv->libnotify, notification);
-	if (!priv->libnotify_id)
-		priv->libnotify_id = g_timeout_add (500,
-						    brasero_data_disc_notify_user_real,
-						    disc);
-}
-
-/**
  * Actions callbacks
  */
 
@@ -362,25 +225,49 @@
 	gtk_widget_destroy (dialog);
 }
 
-static void
-brasero_data_disc_import_session_cb (GtkToggleAction *action,
-				     BraseroDataDisc *disc)
+static gboolean
+brasero_data_disc_import_session (BraseroDataDisc *disc,
+				  gboolean import)
 {
 	BraseroDataDiscPrivate *priv;
 
 	priv = BRASERO_DATA_DISC_PRIVATE (disc);
-	if (gtk_toggle_action_get_active (action)) {
+
+	if (import) {
 		GError *error = NULL;
 
 		if (!brasero_data_session_add_last (BRASERO_DATA_SESSION (priv->project), &error)) {
-			gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
 			brasero_data_disc_import_failure_dialog (disc, error);
+			return FALSE;
 		}
-		else
-			gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 1);
+
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 1);
+		return TRUE;
+	}
+
+	brasero_data_session_remove_last (BRASERO_DATA_SESSION (priv->project));
+	return FALSE;
+}
+
+static void
+brasero_data_disc_import_session_cb (GtkToggleAction *action,
+				     BraseroDataDisc *disc)
+{
+	BraseroDataDiscPrivate *priv;
+	gboolean res;
+
+	priv = BRASERO_DATA_DISC_PRIVATE (disc);
+
+	brasero_notify_message_remove (BRASERO_NOTIFY (priv->message), BRASERO_NOTIFY_CONTEXT_MULTISESSION);
+
+	res = brasero_data_disc_import_session (disc, gtk_toggle_action_get_active (action));
+
+	/* make sure the button reflects the current state */
+	if (gtk_toggle_action_get_active (action) != res) {
+		g_signal_handlers_block_by_func (action, brasero_data_disc_import_session_cb, disc);
+		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), res);
+		g_signal_handlers_unblock_by_func (action, brasero_data_disc_import_session_cb, disc);
 	}
-	else
-		brasero_data_session_remove_last (BRASERO_DATA_SESSION (priv->project));
 }
 
 static BraseroFileNode *
@@ -694,37 +581,44 @@
 				     BraseroDataDisc *self)
 {
 	BraseroDataDiscPrivate *priv;
+	GtkWidget *message;
 
 	priv = BRASERO_DATA_DISC_PRIVATE (self);
 
+	message = brasero_notify_get_message_by_context_id (BRASERO_NOTIFY (priv->message), BRASERO_NOTIFY_CONTEXT_LOADING);
+	if (!message)
+		return;
+
 	if (loading > 0) {
 		/* we're not done yet update progress. */
-		brasero_disc_message_set_progress (BRASERO_DISC_MESSAGE (priv->message),
+		brasero_disc_message_set_progress (BRASERO_DISC_MESSAGE (message),
 						   (gdouble) (priv->loading - loading) / (gdouble) priv->loading);
 		return;
 	}
 
 	priv->loading = 0;
 	if (priv->load_errors) {
-		brasero_disc_message_remove_buttons (BRASERO_DISC_MESSAGE (priv->message));
+		brasero_disc_message_remove_buttons (BRASERO_DISC_MESSAGE (message));
 
-		brasero_disc_message_set_primary (BRASERO_DISC_MESSAGE (priv->message),
+		brasero_disc_message_set_primary (BRASERO_DISC_MESSAGE (message),
 						  _("The contents of the project changed since it was saved:"));
-		brasero_disc_message_set_secondary (BRASERO_DISC_MESSAGE (priv->message),
+		brasero_disc_message_set_secondary (BRASERO_DISC_MESSAGE (message),
 						    _("Do you want to continue or discard it?"));
 
-		brasero_disc_message_set_image (BRASERO_DISC_MESSAGE (priv->message),GTK_STOCK_DIALOG_WARNING);
-		brasero_disc_message_set_progress_active (BRASERO_DISC_MESSAGE (priv->message), FALSE);
-		brasero_disc_message_add_button (BRASERO_DISC_MESSAGE (priv->message),
-						 _("_Discard"),
-						 _("Press if you want to discard the current modified project"),
-						 GTK_RESPONSE_CANCEL);
-		brasero_disc_message_add_button (BRASERO_DISC_MESSAGE (priv->message),
-						 _("_Continue"),
-						 _("Press if you want to continue with the current modified project"),
-						 GTK_RESPONSE_OK);
+		brasero_disc_message_set_image (BRASERO_DISC_MESSAGE (message),GTK_STOCK_DIALOG_WARNING);
+		brasero_disc_message_set_progress_active (BRASERO_DISC_MESSAGE (message), FALSE);
+		brasero_notify_button_add (BRASERO_NOTIFY (priv->message),
+					   BRASERO_DISC_MESSAGE (message),
+					   _("_Discard"),
+					   _("Press if you want to discard the current modified project"),
+					   GTK_RESPONSE_CANCEL);
+		brasero_notify_button_add (BRASERO_NOTIFY (priv->message),
+					   BRASERO_DISC_MESSAGE (message),
+					   _("_Continue"),
+					   _("Press if you want to continue with the current modified project"),
+					   GTK_RESPONSE_OK);
 
-		brasero_disc_message_add_errors (BRASERO_DISC_MESSAGE (priv->message),
+		brasero_disc_message_add_errors (BRASERO_DISC_MESSAGE (message),
 						 priv->load_errors);
 		g_slist_foreach (priv->load_errors, (GFunc) g_free , NULL);
 		g_slist_free (priv->load_errors);
@@ -734,7 +628,7 @@
 		gtk_widget_set_sensitive (GTK_WIDGET (priv->tree), TRUE);
 		gtk_widget_set_sensitive (GTK_WIDGET (priv->filter), TRUE);
 
-		gtk_widget_hide (priv->message);
+		gtk_widget_destroy (message);
 	}
 
 	priv->loading = FALSE;
@@ -1092,6 +986,28 @@
 }
 
 static void
+brasero_disc_disc_session_import_response_cb (GtkButton *button,
+					      GtkResponseType response,
+					      BraseroDataDisc *self)
+{
+	gboolean res;
+	GtkAction *action;
+	BraseroDataDiscPrivate *priv;
+
+	if (response != GTK_RESPONSE_OK)
+		return;
+
+	priv = BRASERO_DATA_DISC_PRIVATE (self);
+	res = brasero_data_disc_import_session (self, TRUE);
+
+	action = gtk_action_group_get_action (priv->disc_group, "ImportSession");
+
+	g_signal_handlers_block_by_func (action, brasero_data_disc_import_session_cb, self);
+	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), res);
+	g_signal_handlers_unblock_by_func (action, brasero_data_disc_import_session_cb, self);
+}
+
+static void
 brasero_data_disc_session_available_cb (BraseroDataSession *session,
 					gboolean multisession,
 					BraseroDataDisc *self)
@@ -1103,17 +1019,29 @@
 	action = gtk_action_group_get_action (priv->disc_group, "ImportSession");
 
 	if (multisession) {
-		GtkWidget *widget;
+		GtkWidget *message;
 
 		gtk_action_set_sensitive (action, TRUE);
-		widget = gtk_ui_manager_get_widget (priv->manager,
-						    "/Toolbar/DiscButtonPlaceholder/ImportSession");
-		brasero_data_disc_notify_user (self,
-					       _("A multisession disc is inserted:"),
-					       _("Click here to import its contents"),
-					       widget);
+		message = brasero_notify_message_add (BRASERO_NOTIFY (priv->message),
+						      _("A multisession disc is inserted:"),
+						      _("Do you want to import its contents?"),
+						      10000,
+						      BRASERO_NOTIFY_CONTEXT_MULTISESSION);
+
+		brasero_disc_message_set_image (BRASERO_DISC_MESSAGE (message), GTK_STOCK_DIALOG_INFO);
+
+		brasero_notify_button_add (BRASERO_NOTIFY (priv->message),
+					   BRASERO_DISC_MESSAGE (message),
+					   _("_Import Session"),
+					   _("Click here to import its contents"),
+					   GTK_RESPONSE_OK);
+		g_signal_connect (BRASERO_DISC_MESSAGE (message),
+				  "response",
+				  G_CALLBACK (brasero_disc_disc_session_import_response_cb),
+				  self);
 	}
 	else {
+		brasero_notify_message_remove (BRASERO_NOTIFY (priv->message), BRASERO_NOTIFY_CONTEXT_MULTISESSION);
 		gtk_action_set_sensitive (action, FALSE);
 		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
 	}
@@ -1152,6 +1080,9 @@
 	priv->G2_files = FALSE;
 	priv->deep_directory = FALSE;
 
+	brasero_notify_message_remove (BRASERO_NOTIFY (priv->message), BRASERO_NOTIFY_CONTEXT_LOADING);
+	brasero_notify_message_remove (BRASERO_NOTIFY (priv->message), BRASERO_NOTIFY_CONTEXT_MULTISESSION);
+
 	brasero_data_project_reset (priv->project);
 	brasero_file_filtered_clear (BRASERO_FILE_FILTERED (priv->filter));
 	brasero_disc_size_changed (disc, 0);
@@ -1161,9 +1092,17 @@
 brasero_data_disc_reset (BraseroDisc *disc)
 {
 	BraseroDataDiscPrivate *priv;
+	GtkAction *action;
 
 	priv = BRASERO_DATA_DISC_PRIVATE (disc);
 
+	action = gtk_action_group_get_action (priv->disc_group, "ImportSession");
+	if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
+		g_signal_handlers_block_by_func (action, brasero_data_disc_import_session_cb, disc);
+		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
+		g_signal_handlers_unblock_by_func (action, brasero_data_disc_import_session_cb, disc);
+	}
+
 	if (priv->load_errors) {
 		g_slist_foreach (priv->load_errors, (GFunc) g_free , NULL);
 		g_slist_free (priv->load_errors);
@@ -1178,19 +1117,6 @@
 
 	brasero_file_filtered_clear (BRASERO_FILE_FILTERED (priv->filter));
 
-	if (priv->libnotify) {
-		g_slist_foreach (priv->libnotify,
-				 (GFunc) brasero_data_disc_notification_free,
-				 NULL);
-		g_slist_free (priv->libnotify);
-		priv->libnotify = NULL;
-	}
-
-	if (priv->libnotify_id) {
-		g_source_remove (priv->libnotify_id);
-		priv->libnotify_id = 0;
-	}
-
 	brasero_disc_size_changed (disc, 0);
 	gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 0);
 }
@@ -1403,7 +1329,6 @@
 
 	priv = BRASERO_DATA_DISC_PRIVATE (self);
 
-	gtk_widget_hide (priv->message);
 	gtk_widget_set_sensitive (GTK_WIDGET (priv->tree), TRUE);
 	gtk_widget_set_sensitive (GTK_WIDGET (priv->filter), TRUE);
 
@@ -1419,11 +1344,12 @@
 			      BraseroDiscTrack *track)
 {
 	BraseroDataDiscPrivate *priv;
+	GtkWidget *message;
 	GSList *iter;
 
 	priv = BRASERO_DATA_DISC_PRIVATE (disc);
 
-	/* First add the restored files */
+	/* Firstadd the restored files */
 	for (iter = track->contents.data.restored; iter; iter = iter->next) {
 		gchar *uri;
 
@@ -1442,15 +1368,21 @@
 		return BRASERO_DISC_OK;
 	}
 
-	brasero_disc_message_set_primary (BRASERO_DISC_MESSAGE (priv->message), _("Please, wait while the project is loading."));
-	brasero_disc_message_set_image (BRASERO_DISC_MESSAGE (priv->message),GTK_STOCK_DIALOG_INFO);
-	brasero_disc_message_set_progress (BRASERO_DISC_MESSAGE (priv->message), 0.0);
-	brasero_disc_message_add_button (BRASERO_DISC_MESSAGE (priv->message),
-					 _("_Cancel Loading"),
-					 _("Press if you want to cancel current project loading"),
-					 GTK_RESPONSE_CANCEL);
-	gtk_widget_show (priv->message);
-	g_signal_connect (priv->message,
+	message = brasero_notify_message_add (BRASERO_NOTIFY (priv->message),
+					      _("Please, wait while the project is loading."),
+					      NULL,
+					      -1,
+					      BRASERO_NOTIFY_CONTEXT_LOADING);
+
+	brasero_disc_message_set_image (BRASERO_DISC_MESSAGE (message),GTK_STOCK_DIALOG_INFO);
+	brasero_disc_message_set_progress (BRASERO_DISC_MESSAGE (message), 0.0);
+
+	brasero_notify_button_add (BRASERO_NOTIFY (priv->message),
+				   BRASERO_DISC_MESSAGE (message),
+				   _("_Cancel Loading"),
+				   _("Press if you want to cancel current project loading"),
+				   GTK_RESPONSE_CANCEL);
+	g_signal_connect (message,
 			  "response",
 			  G_CALLBACK (brasero_data_disc_message_response_cb),
 			  disc);
@@ -1509,7 +1441,9 @@
 }
 
 static guint
-brasero_data_disc_add_ui (BraseroDisc *disc, GtkUIManager *manager)
+brasero_data_disc_add_ui (BraseroDisc *disc,
+			  GtkUIManager *manager,
+			  GtkWidget *message)
 {
 	BraseroDataDiscPrivate *priv;
 	GError *error = NULL;
@@ -1518,6 +1452,14 @@
 
 	priv = BRASERO_DATA_DISC_PRIVATE (disc);
 
+	if (priv->message) {
+		g_object_unref (priv->message);
+		priv->message = NULL;
+	}
+
+	priv->message = message;
+	g_object_ref (message);
+
 	if (!priv->disc_group) {
 		priv->disc_group = gtk_action_group_new (BRASERO_DISC_ACTION);
 		gtk_action_group_set_translation_domain (priv->disc_group, GETTEXT_PACKAGE);
@@ -2041,10 +1983,6 @@
 
 	gtk_box_set_spacing (GTK_BOX (object), 0);
 
-	/* message area */
-	priv->message = brasero_disc_message_new ();
-	gtk_box_pack_start (GTK_BOX (object), priv->message, FALSE, TRUE, 0);
-
 	/* the information displayed about how to use this tree */
 	priv->notebook = brasero_disc_get_use_info_notebook ();
 	gtk_widget_show (priv->notebook);
@@ -2291,25 +2229,17 @@
 
 	priv = BRASERO_DATA_DISC_PRIVATE (object);
 
+	if (priv->message) {
+		g_object_unref (priv->message);
+		priv->message = NULL;
+	}
+
 	if (priv->load_errors) {
 		g_slist_foreach (priv->load_errors, (GFunc) g_free , NULL);
 		g_slist_free (priv->load_errors);
 		priv->load_errors = NULL;
 	}
 
-	if (priv->libnotify) {
-		g_slist_foreach (priv->libnotify,
-				 (GFunc) brasero_data_disc_notification_free,
-				 NULL);
-		g_slist_free (priv->libnotify);
-		priv->libnotify = NULL;
-	}
-
-	if (priv->libnotify_id) {
-		g_source_remove (priv->libnotify_id);
-		priv->libnotify_id = 0;
-	}
-
 	G_OBJECT_CLASS (brasero_data_disc_parent_class)->finalize (object);
 }
 

Modified: trunk/src/brasero-disc-message.c
==============================================================================
--- trunk/src/brasero-disc-message.c	(original)
+++ trunk/src/brasero-disc-message.c	Sat May 17 20:16:21 2008
@@ -31,6 +31,8 @@
 
 #include <gdk/gdkkeysyms.h>
 
+#include <gtk/gtkstock.h>
+#include <gtk/gtkalignment.h>
 #include <gtk/gtkbindings.h>
 #include <gtk/gtkbin.h>
 #include <gtk/gtkhbox.h>
@@ -70,12 +72,14 @@
 
 	GtkWidget *image;
 
+	GtkWidget *main_box;
 	GtkWidget *button_box;
 	GtkWidget *text_box;
 
 	guint context;
 
 	guint id;
+	guint timeout;
 
 	guint changing_style:1;
 };
@@ -101,6 +105,41 @@
 	NUM_COL
 };
 
+static gboolean
+brasero_disc_message_timeout (gpointer data)
+{
+	BraseroDiscMessagePrivate *priv;
+
+	priv = BRASERO_DISC_MESSAGE_PRIVATE (data);
+	priv->timeout = 0;
+
+	g_signal_emit (data,
+		       disc_message_signals [RESPONSE],
+		       0,
+		       GTK_RESPONSE_DELETE_EVENT);
+
+	gtk_widget_destroy (GTK_WIDGET (data));
+	return FALSE;
+}
+
+void
+brasero_disc_message_set_timeout (BraseroDiscMessage *self,
+				  guint mseconds)
+{
+	BraseroDiscMessagePrivate *priv;
+
+	priv = BRASERO_DISC_MESSAGE_PRIVATE (self);
+
+	if (priv->timeout) {
+		g_source_remove (priv->timeout);
+		priv->timeout = 0;
+	}
+
+	if (mseconds > 0)
+		priv->timeout = g_timeout_add (mseconds,
+					       brasero_disc_message_timeout,
+					       self);
+}
 
 void
 brasero_disc_message_set_context (BraseroDiscMessage *self,
@@ -214,10 +253,13 @@
 		       disc_message_signals [RESPONSE],
 		       0, 
 		       GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), RESPONSE_TYPE)));
+
+	gtk_widget_destroy (GTK_WIDGET (self));
 }
 
 void
 brasero_disc_message_add_button (BraseroDiscMessage *self,
+				 GtkSizeGroup *group,
 				 const gchar *text,
 				 const gchar *tooltip,
 				 GtkResponseType response)
@@ -228,6 +270,7 @@
 	priv = BRASERO_DISC_MESSAGE_PRIVATE (self);
 
 	button = gtk_button_new_with_mnemonic (text);
+	gtk_size_group_add_widget (group, button);
 	gtk_size_group_add_widget (priv->group, button);
 	gtk_widget_set_tooltip_text (button, tooltip);
 	gtk_widget_show (button);
@@ -247,6 +290,45 @@
 }
 
 void
+brasero_disc_message_add_close_button (BraseroDiscMessage *self)
+{
+	GtkWidget *button;
+	GtkWidget *alignment;
+	BraseroDiscMessagePrivate *priv;
+
+	priv = BRASERO_DISC_MESSAGE_PRIVATE (self);
+
+	button = gtk_button_new ();
+	gtk_size_group_add_widget (priv->group, button);
+
+	alignment = gtk_alignment_new (1.0, 0.0, 0.0, 0.0);
+	gtk_widget_show (alignment);
+	gtk_container_add (GTK_CONTAINER (alignment), button);
+
+	gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+	gtk_button_set_image (GTK_BUTTON (button),
+			      gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON));
+
+	gtk_widget_set_tooltip_text (button, _("Close this notification window"));
+	gtk_widget_show (button);
+	g_signal_connect (button,
+			  "clicked",
+			  G_CALLBACK (brasero_disc_message_button_clicked_cb),
+			  self);
+
+	g_object_set_data (G_OBJECT (button),
+			   RESPONSE_TYPE,
+			   GINT_TO_POINTER (GTK_RESPONSE_CLOSE));
+
+	gtk_box_pack_start (GTK_BOX (priv->main_box),
+			    alignment,
+			    FALSE,
+			    TRUE,
+			    0);
+	gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+void
 brasero_disc_message_remove_buttons (BraseroDiscMessage *self)
 {
 	BraseroDiscMessagePrivate *priv;
@@ -376,28 +458,13 @@
 /**
  * Two following functions are Cut and Pasted from gedit-message-area.c
  */
-static GtkStyle *
-brasero_disc_message_get_style (void)
-{
-	GtkWidget *window;
-	GtkStyle *style;
-
-	/* This is a hack needed to use the tooltip background color */
-	window = gtk_window_new (GTK_WINDOW_POPUP);
-	gtk_widget_set_name (window, "gtk-tooltip");
-	gtk_widget_ensure_style (window);
-	style = gtk_widget_get_style (window);
-	g_object_ref (style);
-	gtk_widget_destroy (window);
-	return style;
-}
-
 static void
 style_set (GtkWidget        *widget,
 	   GtkStyle         *prev_style,
 	   BraseroDiscMessage *self)
 {
 	BraseroDiscMessagePrivate *priv;
+	GtkWidget *window;
 	GtkStyle *style;
 
 	priv = BRASERO_DISC_MESSAGE_PRIVATE (self);
@@ -405,13 +472,18 @@
 	if (priv->changing_style)
 		return;
 
-	style = brasero_disc_message_get_style ();
+	window = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_widget_set_name (window, "gtk-tooltip");
+	gtk_widget_ensure_style (window);
+	style = gtk_widget_get_style (window);
 
 	priv->changing_style = TRUE;
 	gtk_widget_set_style (GTK_WIDGET (self), style);
 	priv->changing_style = FALSE;
 
-	g_object_unref (style);
+	gtk_widget_destroy (window);
+
+//	gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
 
 	gtk_widget_queue_draw (GTK_WIDGET (self));
 }
@@ -426,6 +498,7 @@
 	GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (object), GTK_NO_WINDOW);
 
 	main_box = gtk_hbox_new (FALSE, 12);
+	priv->main_box = main_box;
 	gtk_widget_show (main_box);
 	gtk_container_set_border_width (GTK_CONTAINER (main_box), 8);
 	gtk_container_add (GTK_CONTAINER (object), main_box);
@@ -471,6 +544,11 @@
 		priv->id = 0;
 	}
 
+	if (priv->timeout) {
+		g_source_remove (priv->timeout);
+		priv->timeout = 0;
+	}
+
 	g_object_unref (priv->group);
 	priv->group = NULL;
 
@@ -527,7 +605,6 @@
 {
 	GdkWindowAttr attributes;
 	gint attributes_mask;
-	GtkStyle *style;
 
 	attributes.window_type = GDK_WINDOW_CHILD;
 	attributes.x = widget->allocation.x;
@@ -546,12 +623,8 @@
 					 attributes_mask);
 	gdk_window_set_user_data (widget->window, widget);
 
-	style = brasero_disc_message_get_style ();
-	widget->style = gtk_style_attach (style, widget->window);
-	g_object_unref (style);
+	widget->style = gtk_style_attach (widget->style, widget->window);
     
-	gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
-
 	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 }
 

Modified: trunk/src/brasero-disc-message.h
==============================================================================
--- trunk/src/brasero-disc-message.h	(original)
+++ trunk/src/brasero-disc-message.h	Sat May 17 20:16:21 2008
@@ -78,10 +78,14 @@
 				   gdouble progress);
 void
 brasero_disc_message_add_button (BraseroDiscMessage *message,
+				 GtkSizeGroup *group,
 				 const gchar *text,
 				 const gchar *tooltip,
 				 GtkResponseType type);
 void
+brasero_disc_message_add_close_button (BraseroDiscMessage *message);
+
+void
 brasero_disc_message_remove_buttons (BraseroDiscMessage *message);
 
 void
@@ -91,6 +95,10 @@
 brasero_disc_message_remove_errors (BraseroDiscMessage *message);
 
 void
+brasero_disc_message_set_timeout (BraseroDiscMessage *message,
+				  guint mseconds);
+
+void
 brasero_disc_message_set_context (BraseroDiscMessage *message,
 				  guint context_id);
 

Modified: trunk/src/brasero-disc-option-dialog.c
==============================================================================
--- trunk/src/brasero-disc-option-dialog.c	(original)
+++ trunk/src/brasero-disc-option-dialog.c	Sat May 17 20:16:21 2008
@@ -628,9 +628,8 @@
 
 	title_str = brasero_disc_option_dialog_get_default_label (dialog);
 	gtk_entry_set_text (GTK_ENTRY (priv->label), title_str);
-	g_free (title_str);
-
 	brasero_burn_session_set_label (priv->session, title_str);
+	g_free (title_str);
 
 	brasero_burn_session_get_input_type (priv->session, &type);
 	if (type.type == BRASERO_TRACK_TYPE_DATA)

Modified: trunk/src/brasero-disc.c
==============================================================================
--- trunk/src/brasero-disc.c	(original)
+++ trunk/src/brasero-disc.c	Sat May 17 20:16:21 2008
@@ -318,7 +318,7 @@
 }
 
 guint
-brasero_disc_add_ui (BraseroDisc *disc, GtkUIManager *manager)
+brasero_disc_add_ui (BraseroDisc *disc, GtkUIManager *manager, GtkWidget *message)
 {
 	BraseroDiscIface *iface;
 
@@ -330,7 +330,7 @@
 
 	iface = BRASERO_DISC_GET_IFACE (disc);
 	if (iface->add_ui)
-		return (* iface->add_ui) (disc, manager);
+		return (* iface->add_ui) (disc, manager, message);
 
 	return 0;
 }

Modified: trunk/src/brasero-disc.h
==============================================================================
--- trunk/src/brasero-disc.h	(original)
+++ trunk/src/brasero-disc.h	Sat May 17 20:16:21 2008
@@ -136,7 +136,8 @@
 	void			(*reset)		(BraseroDisc *disc);
 
 	guint			(*add_ui)		(BraseroDisc *disc,
-							 GtkUIManager *manager);
+							 GtkUIManager *manager,
+							 GtkWidget *message);
 
 	void			(*set_drive)		(BraseroDisc *disc,
 							 BraseroDrive *drive);
@@ -145,7 +146,9 @@
 GType brasero_disc_get_type ();
 
 guint
-brasero_disc_add_ui (BraseroDisc *disc, GtkUIManager *manager);
+brasero_disc_add_ui (BraseroDisc *disc,
+		     GtkUIManager *manager,
+		     GtkWidget *message);
 
 BraseroDiscResult
 brasero_disc_add_uri (BraseroDisc *disc, const gchar *escaped_uri);

Added: trunk/src/brasero-notify.c
==============================================================================
--- (empty file)
+++ trunk/src/brasero-notify.c	Sat May 17 20:16:21 2008
@@ -0,0 +1,210 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ * 
+ * brasero 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 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <glib.h>
+
+#include <gtk/gtk.h>
+
+#include "brasero-notify.h"
+#include "brasero-disc-message.h"
+
+struct _BraseroNotifyPrivate
+{
+	GtkSizeGroup *message;
+	GtkSizeGroup *button;
+};
+
+typedef struct _BraseroNotifyPrivate BraseroNotifyPrivate;
+
+#define BRASERO_NOTIFY_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_NOTIFY, BraseroNotifyPrivate))
+
+G_DEFINE_TYPE (BraseroNotify, brasero_notify, GTK_TYPE_VBOX);
+
+void
+brasero_notify_remove_all_messages (BraseroNotify *self)
+{
+	GList *children;
+	GList *iter;
+
+	GDK_THREADS_ENTER ();
+
+	children = gtk_container_get_children (GTK_CONTAINER (self));
+	for (iter = children; iter; iter = iter->next) {
+		GtkWidget *widget;
+
+		widget = iter->data;
+		gtk_widget_destroy (widget);
+	}
+	g_list_free (children);
+
+	GDK_THREADS_LEAVE ();
+}
+
+GtkWidget *
+brasero_notify_get_message_by_context_id (BraseroNotify *self,
+					  guint context_id)
+{
+	GtkWidget *retval = NULL;
+	GList *children;
+	GList *iter;
+
+	GDK_THREADS_ENTER ();
+
+	children = gtk_container_get_children (GTK_CONTAINER (self));
+	for (iter = children; iter; iter = iter->next) {
+		GtkWidget *widget;
+
+		widget = iter->data;
+		if (brasero_disc_message_get_context (BRASERO_DISC_MESSAGE (widget)) == context_id) {
+			retval = widget;
+			break;
+		}
+	}
+	g_list_free (children);
+
+	GDK_THREADS_LEAVE ();
+
+	return retval;
+}
+
+void
+brasero_notify_message_remove (BraseroNotify *self,
+			       guint context_id)
+{
+	BraseroNotifyPrivate *priv;
+	GList *children;
+	GList *iter;
+
+	priv = BRASERO_NOTIFY_PRIVATE (self);
+
+	GDK_THREADS_ENTER ();
+
+	children = gtk_container_get_children (GTK_CONTAINER (self));
+	for (iter = children; iter; iter = iter->next) {
+		GtkWidget *widget;
+
+		widget = iter->data;
+		if (brasero_disc_message_get_context (BRASERO_DISC_MESSAGE (widget)) == context_id) {
+			gtk_widget_destroy (widget);
+			break;
+		}
+	}
+	g_list_free (children);
+
+	GDK_THREADS_LEAVE ();
+}
+
+GtkWidget *
+brasero_notify_message_add (BraseroNotify *self,
+			    const gchar *primary,
+			    const gchar *secondary,
+			    gint timeout,
+			    guint context_id)
+{
+	BraseroNotifyPrivate *priv;
+	GtkWidget *message;
+
+	priv = BRASERO_NOTIFY_PRIVATE (self);
+
+	GDK_THREADS_ENTER ();
+
+	brasero_notify_message_remove (self, context_id);
+
+	message = brasero_disc_message_new ();
+	gtk_size_group_add_widget (priv->message, message);
+	brasero_disc_message_set_context (BRASERO_DISC_MESSAGE (message), context_id);
+	brasero_disc_message_set_primary (BRASERO_DISC_MESSAGE (message), primary);
+	brasero_disc_message_set_secondary (BRASERO_DISC_MESSAGE (message), secondary);
+	if (timeout > 0)
+		brasero_disc_message_set_timeout (BRASERO_DISC_MESSAGE (message), timeout);
+
+	gtk_widget_show (message);
+	gtk_box_pack_start (GTK_BOX (self), message, FALSE, TRUE, 0);
+
+	GDK_THREADS_LEAVE ();
+
+	return message;
+}
+
+void
+brasero_notify_button_add (BraseroNotify *self,
+			   BraseroDiscMessage *message,
+			   const gchar *text,
+			   const gchar *tooltip,
+			   GtkResponseType response)
+{
+	BraseroNotifyPrivate *priv;
+
+	priv = BRASERO_NOTIFY_PRIVATE (self);
+	brasero_disc_message_add_button (BRASERO_DISC_MESSAGE (message),
+					 priv->button,
+					 text,
+					 tooltip,
+					 response);
+}
+
+static void
+brasero_notify_init (BraseroNotify *object)
+{
+	BraseroNotifyPrivate *priv;
+
+	priv = BRASERO_NOTIFY_PRIVATE (object);
+	priv->button = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
+	priv->message = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
+}
+
+static void
+brasero_notify_finalize (GObject *object)
+{
+	BraseroNotifyPrivate *priv;
+
+	priv = BRASERO_NOTIFY_PRIVATE (object);
+
+	if (priv->button) {
+		g_object_unref (priv->button);
+		priv->button = NULL;
+	}
+
+	if (priv->message) {
+		g_object_unref (priv->message);
+		priv->message = NULL;
+	}
+	
+	G_OBJECT_CLASS (brasero_notify_parent_class)->finalize (object);
+}
+
+static void
+brasero_notify_class_init (BraseroNotifyClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (BraseroNotifyPrivate));
+
+	object_class->finalize = brasero_notify_finalize;
+}
+
+GtkWidget *
+brasero_notify_new (void)
+{
+	return g_object_new (BRASERO_TYPE_NOTIFY, NULL);
+}

Added: trunk/src/brasero-notify.h
==============================================================================
--- (empty file)
+++ trunk/src/brasero-notify.h	Sat May 17 20:16:21 2008
@@ -0,0 +1,88 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ * 
+ * brasero 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 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BRASERO_NOTIFY_H_
+#define _BRASERO_NOTIFY_H_
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+
+#include "brasero-disc-message.h"
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_NOTIFY             (brasero_notify_get_type ())
+#define BRASERO_NOTIFY(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_NOTIFY, BraseroNotify))
+#define BRASERO_NOTIFY_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_NOTIFY, BraseroNotifyClass))
+#define BRASERO_IS_NOTIFY(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_NOTIFY))
+#define BRASERO_IS_NOTIFY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_NOTIFY))
+#define BRASERO_NOTIFY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_NOTIFY, BraseroNotifyClass))
+
+typedef struct _BraseroNotifyClass BraseroNotifyClass;
+typedef struct _BraseroNotify BraseroNotify;
+
+struct _BraseroNotifyClass
+{
+	GtkVBoxClass parent_class;
+};
+
+struct _BraseroNotify
+{
+	GtkVBox parent_instance;
+};
+
+typedef enum {
+	BRASERO_NOTIFY_CONTEXT_NONE		= 0,
+	BRASERO_NOTIFY_CONTEXT_SIZE		= 1,
+	BRASERO_NOTIFY_CONTEXT_LOADING		= 2,
+	BRASERO_NOTIFY_CONTEXT_MULTISESSION	= 3,
+} BraseroNotifyContextId;
+
+GType brasero_notify_get_type (void) G_GNUC_CONST;
+
+GtkWidget *brasero_notify_new (void);
+
+GtkWidget *
+brasero_notify_message_add (BraseroNotify *notify,
+			    const gchar *primary,
+			    const gchar *secondary,
+			    gint timeout,
+			    guint context_id);
+void
+brasero_notify_button_add (BraseroNotify *notify,
+			   BraseroDiscMessage *message,
+			   const gchar *text,
+			   const gchar *tooltip,
+			   GtkResponseType response);
+
+void
+brasero_notify_message_remove (BraseroNotify *notify,
+			       guint context_id);
+
+void
+brasero_notify_remove_all_messages (BraseroNotify *notify);
+
+GtkWidget *
+brasero_notify_get_message_by_context_id (BraseroNotify *notify,
+					  guint context_id);
+
+G_END_DECLS
+
+#endif /* _BRASERO_NOTIFY_H_ */

Modified: trunk/src/brasero-project.c
==============================================================================
--- trunk/src/brasero-project.c	(original)
+++ trunk/src/brasero-project.c	Sat May 17 20:16:21 2008
@@ -78,6 +78,7 @@
 #include "brasero-layout-object.h"
 #include "brasero-disc-message.h"
 #include "brasero-file-chooser.h"
+#include "brasero-notify.h"
 
 static void brasero_project_class_init (BraseroProjectClass *klass);
 static void brasero_project_init (BraseroProject *sp);
@@ -257,13 +258,6 @@
 
 #define BRASERO_PROJECT_VERSION "0.2"
 
-typedef enum {
-	BRASERO_PROJECT_MESSAGE_NONE 		= 0,
-	BRASERO_PROJECT_MESSAGE_SIZE 		= 1,
-	BRASERO_PROJECT_MESSAGE_PROJECT		= 2,
-	BRASERO_PROJECT_MESSAGE_STATUS		= 3
-} BraseroProjectMessageType;
-
 GType
 brasero_project_get_type ()
 {
@@ -398,7 +392,7 @@
 			  G_CALLBACK (brasero_project_focus_changed_cb),
 			  NULL);
 
-	obj->priv->message = gtk_vbox_new (FALSE, 12);
+	obj->priv->message = brasero_notify_new ();
 	gtk_box_pack_start (GTK_BOX (obj), obj->priv->message, FALSE, TRUE, 0);
 	gtk_widget_show (obj->priv->message);
 
@@ -524,69 +518,17 @@
 
 /********************************** size ***************************************/
 static void
-brasero_project_message_remove_all (BraseroProject *project)
-{
-	GList *children;
-	GList *iter;
-
-	children = gtk_container_get_children (GTK_CONTAINER (project->priv->message));
-	for (iter = children; iter; iter = iter->next) {
-		GtkWidget *widget;
-
-		widget = iter->data;
-		gtk_widget_destroy (widget);
-	}
-	g_list_free (children);
-}
-
-static void
-brasero_project_message_remove (BraseroProject *project,
-				guint context_id)
-{
-	GList *children;
-	GList *iter;
-
-	children = gtk_container_get_children (GTK_CONTAINER (project->priv->message));
-	for (iter = children; iter; iter = iter->next) {
-		GtkWidget *widget;
-
-		widget = iter->data;
-		if (brasero_disc_message_get_context (BRASERO_DISC_MESSAGE (widget)) == context_id) {
-			gtk_widget_destroy (widget);
-			break;
-		}
-	}
-	g_list_free (children);
-}
-
-static GtkWidget *
-brasero_project_message (BraseroProject *project,
-			 const gchar *primary,
-			 const gchar *secondary,
-			 guint context_id)
+brasero_project_error_size_dialog (BraseroProject *project)
 {
 	GtkWidget *message;
 
-	brasero_project_message_remove (project, context_id);
-
-	message = brasero_disc_message_new ();
-	brasero_disc_message_set_context (BRASERO_DISC_MESSAGE (message), context_id);
-	brasero_disc_message_set_primary (BRASERO_DISC_MESSAGE (message), primary);
-	brasero_disc_message_set_secondary (BRASERO_DISC_MESSAGE (message), secondary);
-	gtk_widget_show (message);
-	gtk_box_pack_start (GTK_BOX (project->priv->message), message, FALSE, TRUE, 0);
-
-	return message;
-}
-
-
-static void
-brasero_project_error_size_dialog (BraseroProject *project)
-{
-	brasero_project_message (project,
-				 _("Please, delete some files from the project."),
-				 _("The size of the project is too large for the disc even with the overburn option."),
-				 BRASERO_PROJECT_MESSAGE_SIZE);
+	message = brasero_notify_message_add (BRASERO_NOTIFY (project->priv->message),
+					      _("Please, delete some files from the project."),
+					      _("The size of the project is too large for the disc even with the overburn option."),
+					      -1,
+					      BRASERO_NOTIFY_CONTEXT_SIZE);
+	brasero_disc_message_set_image (BRASERO_DISC_MESSAGE (message), GTK_STOCK_DIALOG_WARNING);
+	brasero_disc_message_add_close_button (BRASERO_DISC_MESSAGE (message));
 }
 
 static gboolean
@@ -638,7 +580,7 @@
 						    &overburn);
 
 	if (result) {
-		brasero_project_message_remove (project, BRASERO_PROJECT_MESSAGE_SIZE);
+		brasero_notify_message_remove (BRASERO_NOTIFY (project->priv->message), BRASERO_NOTIFY_CONTEXT_SIZE);
 		project->priv->oversized = 0;
 		goto end;
 	}
@@ -653,7 +595,7 @@
 	}
 
 	if (overburn) {
-		brasero_project_message_remove (project, BRASERO_PROJECT_MESSAGE_SIZE);
+		brasero_notify_message_remove (BRASERO_NOTIFY (project->priv->message), BRASERO_NOTIFY_CONTEXT_SIZE);
 		project->priv->oversized = 0;
 		goto end;
 	}
@@ -1161,7 +1103,8 @@
 	if (audio) {
 		project->priv->current = BRASERO_DISC (project->priv->audio);
 		project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
-							       project->priv->manager);
+							       project->priv->manager,
+							       project->priv->message);
 
 		gtk_notebook_set_current_page (GTK_NOTEBOOK (project->priv->discs), 0);
 		brasero_project_size_set_context (BRASERO_PROJECT_SIZE (project->priv->size_display), TRUE);
@@ -1169,13 +1112,14 @@
 	else {
 		project->priv->current = BRASERO_DISC (project->priv->data);
 		project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
-							       project->priv->manager);
+							       project->priv->manager,
+							       project->priv->message);
 
 		gtk_notebook_set_current_page (GTK_NOTEBOOK (project->priv->discs), 1);
 		brasero_project_size_set_context (BRASERO_PROJECT_SIZE (project->priv->size_display), FALSE);
 	}
 
-	brasero_project_message_remove_all (project);
+	brasero_notify_message_remove (BRASERO_NOTIFY (project->priv->message), BRASERO_NOTIFY_CONTEXT_SIZE);
 
 	/* update the menus */
 	action = gtk_action_group_get_action (project->priv->project_group, "Add");

Modified: trunk/src/brasero-tray.c
==============================================================================
--- trunk/src/brasero-tray.c	(original)
+++ trunk/src/brasero-tray.c	Sat May 17 20:16:21 2008
@@ -60,10 +60,9 @@
 
 static void
 brasero_tray_icon_cancel_cb (GtkAction *action, BraseroTrayIcon *tray);
+
 static void
 brasero_tray_icon_show_cb (GtkAction *action, BraseroTrayIcon *tray);
-static void
-brasero_tray_icon_close_toggled_cb (GtkToggleAction *action, BraseroTrayIcon *tray);
 
 struct BraseroTrayIconPrivate {
 	BraseroBurnAction action;
@@ -93,8 +92,6 @@
 };
 
 static GtkToggleActionEntry toggle_entries[] = {
-	{"Close", NULL, N_("Close if successful"), NULL, N_("Display file chooser"),
-	 G_CALLBACK (brasero_tray_icon_close_toggled_cb), FALSE},
 	{"Show", NULL, N_("Show dialog"), NULL, N_("Show dialog"),
 	 G_CALLBACK (brasero_tray_icon_show_cb), TRUE,},
 };
@@ -104,8 +101,6 @@
 	"<popup action='ContextMenu'>"
 		"<menuitem action='Cancel'/>"
 		"<menuitem action='Show'/>"
-		"<separator/>"
-		"<menuitem action='Close'/>"
 	"</popup>"
 	"</ui>"
 };
@@ -398,20 +393,6 @@
 	brasero_tray_icon_change_show_dialog_state (tray);
 }
 
-static void
-brasero_tray_icon_close_toggled_cb (GtkToggleAction *action,
-				    BraseroTrayIcon *tray)
-{
-	gboolean active;
-
-	active = gtk_toggle_action_get_active (action);
-
-	g_signal_emit (tray,
-		       brasero_tray_icon_signals [CLOSE_AFTER_SIGNAL],
-		       0,
-		       active);
-}
-
 void
 brasero_tray_icon_set_show_dialog (BraseroTrayIcon *tray, gboolean show)
 {

Modified: trunk/src/burn-caps.c
==============================================================================
--- trunk/src/burn-caps.c	(original)
+++ trunk/src/burn-caps.c	Sat May 17 20:16:21 2008
@@ -3033,11 +3033,7 @@
 						       media|BRASERO_MEDIUM_WRITABLE,
 						       type);
 
-	if ((type & BRASERO_MEDIUM_ROM)
-	&& !(media & BRASERO_MEDIUM_RESTRICTED)
-	&& !(media & BRASERO_MEDIUM_SEQUENTIAL)
-	&& !(media & BRASERO_MEDIUM_PLUS)
-	&& !(media & BRASERO_MEDIUM_JUMP))
+	if (type & BRASERO_MEDIUM_ROM)
 		retval = brasero_caps_disc_new_status (retval,
 						       media|BRASERO_MEDIUM_ROM,
 						       type);
@@ -3080,6 +3076,10 @@
 			retval = brasero_caps_disc_new_attribute (retval,
 								  media|BRASERO_MEDIUM_PLUS,
 								  type);
+		if (type & BRASERO_MEDIUM_ROM)
+			retval = brasero_caps_disc_new_status (retval,
+							       media|BRASERO_MEDIUM_ROM,
+							       type);
 	}
 
 	if (media & BRASERO_MEDIUM_DVD_DL) {
@@ -3097,6 +3097,11 @@
 			retval = brasero_caps_disc_new_attribute (retval,
 								  media|BRASERO_MEDIUM_PLUS,
 								  type);
+
+		if (type & BRASERO_MEDIUM_ROM)
+			retval = brasero_caps_disc_new_status (retval,
+							       media|BRASERO_MEDIUM_ROM,
+							       type);
 	}
 
 	return retval;

Modified: trunk/src/burn-dbus.c
==============================================================================
--- trunk/src/burn-dbus.c	(original)
+++ trunk/src/burn-dbus.c	Sat May 17 20:16:21 2008
@@ -2,8 +2,6 @@
 #  include <config.h>
 #endif
 
-#ifdef BUILD_DBUS
-
 #include <glib.h>
 #include <dbus/dbus-glib.h>
 #include "burn-dbus.h"
@@ -106,5 +104,3 @@
 
 	return cookie;
 }
-
-#endif

Modified: trunk/src/burn-dbus.h
==============================================================================
--- trunk/src/burn-dbus.h	(original)
+++ trunk/src/burn-dbus.h	Sat May 17 20:16:21 2008
@@ -1,9 +1,8 @@
+
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
-#ifdef BUILD_DBUS
-
 #include <glib.h>
 #include <dbus/dbus-glib.h>
 
@@ -13,4 +12,3 @@
 gint
 brasero_inhibit_suspend (const char *reason);
 
-#endif

Modified: trunk/src/burn-medium.c
==============================================================================
--- trunk/src/burn-medium.c	(original)
+++ trunk/src/burn-medium.c	Sat May 17 20:16:21 2008
@@ -86,7 +86,7 @@
 {
 	gint retry_id;
 
-	GSList * tracks;
+	GSList *tracks;
 
 	const gchar *type;
 	const gchar *icon;
@@ -104,7 +104,7 @@
 
 	guint64 next_wr_add;
 	BraseroMedia info;
-	BraseroDrive * drive;
+	BraseroDrive *drive;
 };
 
 #define BRASERO_MEDIUM_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_MEDIUM, BraseroMediumPrivate))
@@ -346,6 +346,24 @@
 	BraseroMediumPrivate *priv;
 
 	priv = BRASERO_MEDIUM_PRIVATE (medium);
+
+	/* There is one exception to this with closed DVD+RW/DVD-RW restricted */
+	if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+	||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)
+	||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS_DL)) {
+		BraseroMediumTrack *first;
+
+		/* These are always writable so give the next address after the 
+		 * last volume. */
+		if (!priv->tracks)
+			return 0;
+
+		first = priv->tracks->data;
+
+		/* round to the nearest 16th block */
+		return (((first->start + first->blocks_num) + 15) / 16) * 16;
+	}
+
 	return priv->next_wr_add;
 }
 
@@ -1341,6 +1359,13 @@
 		else
 			BRASERO_BURN_LOG ("Detected runouts");
 	}
+	else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+	     ||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS_DL)
+	     ||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
+		BRASERO_BURN_LOG ("DVD+RW (DL) or DVD-RW (restricted overwrite) checking volume size");
+		brasero_medium_track_volume_size (self, track, handle);
+	}
+
 
 	if (track_info.next_wrt_address_valid)
 		priv->next_wr_add = BRASERO_GET_32 (track_info.next_wrt_address);
@@ -2088,6 +2113,40 @@
 	brasero_device_handle_close (handle);
 }
 
+void
+brasero_medium_reload_info (BraseroMedium *self)
+{
+	BraseroMediumPrivate *priv;
+
+	priv = BRASERO_MEDIUM_PRIVATE (self);
+
+	priv->max_rd = 0;
+	priv->max_wrt = 0;
+	priv->block_num = 0;
+	priv->block_size = 0;
+	priv->next_wr_add = -1;
+	priv->type = NULL;
+	priv->icon = NULL;
+	priv->info = BRASERO_MEDIUM_NONE;
+
+	if (priv->retry_id) {
+		g_source_remove (priv->retry_id);
+		priv->retry_id = 0;
+	}
+
+	g_free (priv->rd_speeds);
+	priv->rd_speeds = NULL;
+
+	g_free (priv->wr_speeds);
+	priv->wr_speeds = NULL;
+
+	g_slist_foreach (priv->tracks, (GFunc) g_free, NULL);
+	g_slist_free (priv->tracks);
+	priv->tracks = NULL;
+
+	brasero_medium_try_open (self);
+}
+
 static void
 brasero_medium_init_file (BraseroMedium *self)
 {

Modified: trunk/src/burn-medium.h
==============================================================================
--- trunk/src/burn-medium.h	(original)
+++ trunk/src/burn-medium.h	Sat May 17 20:16:21 2008
@@ -196,6 +196,8 @@
 	guint64 blocks_num;
 };
 typedef struct _BraseroMediumTrack BraseroMediumTrack;
+void
+brasero_medium_reload_info (BraseroMedium *self);
 
 BraseroMedia
 brasero_medium_get_status (BraseroMedium *medium);

Modified: trunk/src/burn.c
==============================================================================
--- trunk/src/burn.c	(original)
+++ trunk/src/burn.c	Sat May 17 20:16:21 2008
@@ -47,10 +47,7 @@
 #include "burn-caps.h"
 #include "burn-volume-obj.h"
 #include "burn-drive.h"
-
-#ifdef BUILD_DBUS
-  #include "burn-dbus.h"
-#endif
+#include "burn-dbus.h"
 
 G_DEFINE_TYPE (BraseroBurn, brasero_burn, G_TYPE_OBJECT);
 
@@ -68,9 +65,7 @@
 	BraseroDrive *src;
 	BraseroDrive *dest;
 
-#ifdef BUILD_DBUS
 	gint appcookie;
-#endif
 
 	guint src_locked:1;
 	guint dest_locked:1;
@@ -136,8 +131,6 @@
 
 static GObjectClass *parent_class = NULL;
 
-#ifdef BUILD_DBUS
-
 static void
 brasero_burn_powermanagement (BraseroBurn *self,
 			      gboolean wake)
@@ -150,8 +143,6 @@
 		brasero_uninhibit_suspend (priv->appcookie); 
 }
 
-#endif
-
 BraseroBurn *
 brasero_burn_new ()
 {
@@ -1938,6 +1929,7 @@
 	BraseroBurnPrivate *priv;
 	BraseroBurnResult result;
 	GError *ret_error = NULL;
+	BraseroMedium *medium;
 	GSList *tracks;
 
 	priv = BRASERO_BURN_PRIVATE (burn);
@@ -2039,11 +2031,12 @@
 	 * unlock/eject step. A better way would be to have a system call to 
 	 * force a re-load. */
 
-	result = brasero_burn_eject_dest_media (burn, error);
+/*	result = brasero_burn_eject_dest_media (burn, error);
 	if (result != BRASERO_BURN_OK)
 		return result;
 
 	priv->dest = NULL;
+*/
 
 	if (type == BRASERO_CHECKSUM_MD5
 	||  type == BRASERO_CHECKSUM_SHA1
@@ -2087,16 +2080,19 @@
 	brasero_track_unref (track);
 
 	/* reload media */
-	result = brasero_burn_lock_checksum_media (burn, error);
+/*	result = brasero_burn_lock_checksum_media (burn, error);
 	if (result != BRASERO_BURN_OK)
 		return result;
-
-	/* this may be necessary for the drive to settle down and possibly be 
-	 * mounted by gnome-volume-manager (just temporarily) */
+*/
+	/* this may be necessary for the drive to settle down */
+	/* and possibly be mounted by gnome-volume-manager (just temporarily) */
 	result = brasero_burn_sleep (burn, 5000);
 	if (result != BRASERO_BURN_OK)
 		return result;
 
+	medium = brasero_drive_get_medium (priv->dest);
+	brasero_medium_reload_info (medium);
+
 	if (type == BRASERO_CHECKSUM_MD5
 	||  type == BRASERO_CHECKSUM_SHA1
 	||  type == BRASERO_CHECKSUM_SHA256) {
@@ -2166,18 +2162,13 @@
 			return result;
 	}
 
-#ifdef BUILD_DBUS
 	brasero_burn_powermanagement (self, TRUE);
-#endif
 
 	result = brasero_burn_check_real (self, track, error);
 
 	brasero_burn_unlock_medias (self);
 
-
-#ifdef BUILD_DBUS
 	brasero_burn_powermanagement (self, FALSE);
-#endif
 
 	/* no need to check the result of the comparison, it's set in session */
 	priv->session = NULL;
@@ -2294,9 +2285,7 @@
 	g_object_ref (session);
 	priv->session = session;
 
-#ifdef BUILD_DBUS
 	brasero_burn_powermanagement (burn, TRUE);
-#endif
 
 	/* say to the whole world we started */
 	brasero_burn_action_changed_real (burn, BRASERO_BURN_ACTION_PREPARING);
@@ -2387,9 +2376,7 @@
 	else
 		BRASERO_BURN_DEBUG (burn, "Session successfully finished");
 
-#ifdef BUILD_DBUS
 	brasero_burn_powermanagement (burn, FALSE);
-#endif
 
 	/* release session */
 	g_object_unref (priv->session);
@@ -2448,9 +2435,7 @@
 	g_object_ref (session);
 	priv->session = session;
 
-#ifdef BUILD_DBUS
 	brasero_burn_powermanagement (burn, TRUE);
-#endif
 
 	/* we wait for the insertion of a media and lock it */
 	result = brasero_burn_lock_rewritable_media (burn, error);
@@ -2489,9 +2474,7 @@
 		brasero_burn_action_changed_real (burn, BRASERO_BURN_ACTION_FINISHED);
 
 
-#ifdef BUILD_DBUS
 	brasero_burn_powermanagement (burn, FALSE);
-#endif
 
 	/* release session */
 	g_object_unref (priv->session);

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Sat May 17 20:16:21 2008
@@ -42,10 +42,6 @@
 
 #include <gconf/gconf-client.h>
 
-#ifdef HAVE_LIBNOTIFY
-#include <libnotify/notify.h>
-#endif
-
 #include "brasero-app.h"
 #include "brasero-menu.h"
 #include "brasero-jacket-edit.h"
@@ -810,10 +806,6 @@
 	if (!g_thread_supported ())
 		g_thread_init (NULL);
 
-#ifdef HAVE_LIBNOTIFY
-	notify_init (PACKAGE);
-#endif
-
 	gst_init (&argc, &argv);
 
 	brasero_burn_set_debug (debug);

Modified: trunk/src/plugins/cdrkit/burn-genisoimage.c
==============================================================================
--- trunk/src/plugins/cdrkit/burn-genisoimage.c	(original)
+++ trunk/src/plugins/cdrkit/burn-genisoimage.c	Sat May 17 20:16:21 2008
@@ -295,19 +295,6 @@
 	g_ptr_array_add (argv, g_strdup ("-exclude-list"));
 	g_ptr_array_add (argv, excluded_path);
 
-	brasero_job_get_action (BRASERO_JOB (genisoimage), &action);
-	if (action == BRASERO_JOB_ACTION_SIZE) {
-		g_ptr_array_add (argv, g_strdup ("-quiet"));
-		g_ptr_array_add (argv, g_strdup ("-print-size"));
-
-		brasero_job_set_current_action (BRASERO_JOB (genisoimage),
-						BRASERO_BURN_ACTION_GETTING_SIZE,
-						NULL,
-						FALSE);
-		brasero_job_start_progress (BRASERO_JOB (genisoimage), FALSE);
-		return BRASERO_BURN_OK;
-	}
-
 	brasero_job_get_data_label (BRASERO_JOB (genisoimage), &label);
 	if (label) {
 		g_ptr_array_add (argv, g_strdup ("-V"));
@@ -361,6 +348,19 @@
 		}
 	}
 
+	brasero_job_get_action (BRASERO_JOB (genisoimage), &action);
+	if (action == BRASERO_JOB_ACTION_SIZE) {
+		g_ptr_array_add (argv, g_strdup ("-quiet"));
+		g_ptr_array_add (argv, g_strdup ("-print-size"));
+
+		brasero_job_set_current_action (BRASERO_JOB (genisoimage),
+						BRASERO_BURN_ACTION_GETTING_SIZE,
+						NULL,
+						FALSE);
+		brasero_job_start_progress (BRASERO_JOB (genisoimage), FALSE);
+		return BRASERO_BURN_OK;
+	}
+
 	if (brasero_job_get_fd_out (BRASERO_JOB (genisoimage), NULL) != BRASERO_BURN_OK) {
 		gchar *output = NULL;
 
@@ -495,6 +495,7 @@
 				  BRASERO_MEDIUM_DVDRW|
 				  BRASERO_MEDIUM_DVD_DL|
 				  BRASERO_MEDIUM_DVDR_PLUS|
+				  BRASERO_MEDIUM_RESTRICTED|
 				  BRASERO_MEDIUM_APPENDABLE|
 				  BRASERO_MEDIUM_HAS_AUDIO|
 				  BRASERO_MEDIUM_HAS_DATA,

Modified: trunk/src/plugins/cdrtools/burn-mkisofs.c
==============================================================================
--- trunk/src/plugins/cdrtools/burn-mkisofs.c	(original)
+++ trunk/src/plugins/cdrtools/burn-mkisofs.c	Sat May 17 20:16:21 2008
@@ -287,19 +287,6 @@
 	g_ptr_array_add (argv, g_strdup ("-exclude-list"));
 	g_ptr_array_add (argv, excluded_path);
 
-	brasero_job_get_action (BRASERO_JOB (mkisofs), &action);
-	if (action == BRASERO_JOB_ACTION_SIZE) {
-		g_ptr_array_add (argv, g_strdup ("-quiet"));
-		g_ptr_array_add (argv, g_strdup ("-print-size"));
-
-		brasero_job_set_current_action (BRASERO_JOB (mkisofs),
-						BRASERO_BURN_ACTION_GETTING_SIZE,
-						NULL,
-						FALSE);
-		brasero_job_start_progress (BRASERO_JOB (mkisofs), FALSE);
-		return BRASERO_BURN_OK;
-	}
-
 	brasero_job_get_data_label (BRASERO_JOB (mkisofs), &label);
 	if (label) {
 		g_ptr_array_add (argv, g_strdup ("-V"));
@@ -359,6 +346,19 @@
 		}
 	}
 
+	brasero_job_get_action (BRASERO_JOB (mkisofs), &action);
+	if (action == BRASERO_JOB_ACTION_SIZE) {
+		g_ptr_array_add (argv, g_strdup ("-quiet"));
+		g_ptr_array_add (argv, g_strdup ("-print-size"));
+
+		brasero_job_set_current_action (BRASERO_JOB (mkisofs),
+						BRASERO_BURN_ACTION_GETTING_SIZE,
+						NULL,
+						FALSE);
+		brasero_job_start_progress (BRASERO_JOB (mkisofs), FALSE);
+		return BRASERO_BURN_OK;
+	}
+
 	if (brasero_job_get_fd_out (BRASERO_JOB (mkisofs), NULL) != BRASERO_BURN_OK) {
 		gchar *output = NULL;
 
@@ -491,6 +491,7 @@
 				  BRASERO_MEDIUM_DVDR|
 				  BRASERO_MEDIUM_DVDRW|
 				  BRASERO_MEDIUM_DVDR_PLUS|
+				  BRASERO_MEDIUM_RESTRICTED|
 				  BRASERO_MEDIUM_DVD_DL|
 				  BRASERO_MEDIUM_APPENDABLE|
 				  BRASERO_MEDIUM_HAS_AUDIO|

Modified: trunk/src/plugins/checksum/burn-checksum-image.c
==============================================================================
--- trunk/src/plugins/checksum/burn-checksum-image.c	(original)
+++ trunk/src/plugins/checksum/burn-checksum-image.c	Sat May 17 20:16:21 2008
@@ -233,7 +233,7 @@
 
 	priv = BRASERO_CHECKSUM_IMAGE_PRIVATE (self);
 
-	BRASERO_JOB_LOG (self, "Starting checksum generation live (size = %i)", priv->total);
+	BRASERO_JOB_LOG (self, "Starting checksum generation live (size = %lli)", priv->total);
 	result = brasero_job_set_nonblocking (BRASERO_JOB (self), error);
 	if (result != BRASERO_BURN_OK)
 		return result;

Modified: trunk/src/plugins/libburnia/Makefile.am
==============================================================================
--- trunk/src/plugins/libburnia/Makefile.am	(original)
+++ trunk/src/plugins/libburnia/Makefile.am	Sat May 17 20:16:21 2008
@@ -31,7 +31,8 @@
 #libisofs (apparently libisofs needs one libburn function)
 libisofsdir = $(libdir)/brasero/plugins
 libisofs_LTLIBRARIES = libbrasero-libisofs.la
-libbrasero_libisofs_la_SOURCES = burn-libisofs.c burn-libisofs.h \
+libbrasero_libisofs_la_SOURCES = burn-libisofs.c burn-libisofs.h	\
+	burn-libburn-common.c burn-libburn-common.h			\
 	burn-libburnia.h 
 libbrasero_libisofs_la_LIBADD = $(BRASERO_BASE_LIBS) $(BRASERO_LIBBURNIA_LIBS)
 libbrasero_libisofs_la_LDFLAGS = -module -avoid-version

Modified: trunk/src/plugins/libburnia/burn-libburn-common.c
==============================================================================
--- trunk/src/plugins/libburnia/burn-libburn-common.c	(original)
+++ trunk/src/plugins/libburnia/burn-libburn-common.c	Sat May 17 20:16:21 2008
@@ -78,10 +78,6 @@
 	}
 
 	g_free (ctx);
-
-	/* Since the library is not needed any more call burn_finish ().
-	 * NOTE: it itself calls burn_abort (). */
-	burn_finish ();
 }
 
 BraseroLibburnCtx *
@@ -113,7 +109,7 @@
 	/* that's for debugging */
 	burn_set_verbosity (666);
 
-	/* we just want to scan the drive proposed by NCB drive */
+	/* we just want to scan the drive proposed by drive */
 	brasero_job_get_device (job, &device);
 
 	res = burn_drive_convert_fs_adr (device, libburn_device);
@@ -187,7 +183,8 @@
 		case BURN_DRIVE_WRITING:
 			/* we ignore it if it happens after leadout */
 			if (ctx->status == BURN_DRIVE_WRITING_LEADOUT
-			||  ctx->status == BURN_DRIVE_CLOSING_TRACK)
+			||  ctx->status == BURN_DRIVE_CLOSING_TRACK
+			||  ctx->status == BURN_DRIVE_CLOSING_SESSION)
 				return TRUE;
 
 			if (ctx->status == BURN_DRIVE_WRITING_LEADIN
@@ -210,6 +207,7 @@
 
 		case BURN_DRIVE_WRITING_LEADOUT: 	/* DAO */
 		case BURN_DRIVE_CLOSING_TRACK:		/* TAO */
+		case BURN_DRIVE_CLOSING_SESSION:	/* Multisession end */
 			ctx->sectors += ctx->track_sectors;
 			ctx->track_sectors = progress->sectors;
 
@@ -224,20 +222,7 @@
 			break;
 
 		case BURN_DRIVE_IDLE:
-			/* FIXME: that's where a track is returned */
-			/* Double check that everything went well */
-			/* FIXME: activate that code next time
-			if (!burn_drive_wrote_well (ctx->drive)) {
-				brasero_job_error (BRASERO_JOB (self),
-						   g_error_new (BRASERO_BURN_ERROR,
-								BRASERO_BURN_ERROR_GENERAL,
-								_("an unknown error occured")));
-			} */
-
-			brasero_job_set_dangerous (BRASERO_JOB (self), FALSE);
-			brasero_job_finished_session (BRASERO_JOB (self));
-
-			/* we must return here since job may not exist any more */
+			/* That's the end of activity */
 			return FALSE;
 
 		case BURN_DRIVE_SPAWNING:
@@ -254,7 +239,8 @@
 			break;
 
 		default:
-			return FALSE;
+			BRASERO_JOB_LOG (self, "Unknown drive state (%i)", status);
+			return TRUE;
 	}
 
 	ctx->status = status;
@@ -265,7 +251,7 @@
 	return TRUE;
 }
 
-void
+BraseroBurnResult
 brasero_libburn_common_status (BraseroJob *self,
 			       BraseroLibburnCtx *ctx)
 {
@@ -274,10 +260,10 @@
 
 	/* see if there is any pending message */
 	if (!brasero_libburn_common_process_message (self))
-		return;
+		return BRASERO_BURN_ERR;
 
 	if (!ctx->drive)
-		return;
+		return BRASERO_BURN_ERR;
 
 	status = burn_drive_get_status (ctx->drive, &progress);
 
@@ -291,7 +277,7 @@
 								 status,
 								 &progress);
 		if (!running)
-			return;
+			return BRASERO_BURN_OK;
 	}
 
 	if (status == BURN_DRIVE_IDLE
@@ -302,11 +288,15 @@
 
 		ctx->track_num = progress.track;
 		ctx->track_sectors = progress.sectors;
-		return;
+		return BRASERO_BURN_RETRY;
 	}
 
-	if (status != BURN_DRIVE_ERASING
-	&&  status != BURN_DRIVE_FORMATTING) {
+	if (status == BURN_DRIVE_CLOSING_SESSION
+	||  status == BURN_DRIVE_WRITING_LEADOUT) {
+		brasero_job_set_progress (self, 1.0);
+	}
+	else if (status != BURN_DRIVE_ERASING
+	     &&  status != BURN_DRIVE_FORMATTING) {
 		gint64 cur_sector;
 
 		if (ctx->track_num != progress.track) {
@@ -338,4 +328,5 @@
 	}
 
 	brasero_job_start_progress (self, FALSE);
+	return BRASERO_BURN_RETRY;
 }

Modified: trunk/src/plugins/libburnia/burn-libburn-common.h
==============================================================================
--- trunk/src/plugins/libburnia/burn-libburn-common.h	(original)
+++ trunk/src/plugins/libburnia/burn-libburn-common.h	Sat May 17 20:16:21 2008
@@ -60,7 +60,7 @@
 void
 brasero_libburn_common_ctx_free (BraseroLibburnCtx *ctx);
 
-void
+BraseroBurnResult
 brasero_libburn_common_status (BraseroJob *job,
 			       BraseroLibburnCtx *ctx);
 

Modified: trunk/src/plugins/libburnia/burn-libburn.c
==============================================================================
--- trunk/src/plugins/libburnia/burn-libburn.c	(original)
+++ trunk/src/plugins/libburnia/burn-libburn.c	Sat May 17 20:16:21 2008
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <glib.h>
 #include <glib-object.h>
@@ -42,6 +43,7 @@
 
 #include "burn-basics.h"
 #include "burn-job.h"
+#include "burn-debug.h"
 #include "burn-plugin.h"
 #include "burn-libburn-common.h"
 #include "burn-libburnia.h"
@@ -49,8 +51,14 @@
 
 BRASERO_PLUGIN_BOILERPLATE (BraseroLibburn, brasero_libburn, BRASERO_TYPE_JOB, BraseroJob);
 
+#define BRASERO_PVD_SIZE	32 * 2048
+
 struct _BraseroLibburnPrivate {
 	BraseroLibburnCtx *ctx;
+
+	/* This buffer is used to capture Primary Volume Descriptor for
+	 * for overwrite media so as to "grow" the latter. */
+	unsigned char *pvd;
 };
 typedef struct _BraseroLibburnPrivate BraseroLibburnPrivate;
 
@@ -67,6 +75,143 @@
 
 static GObjectClass *parent_class = NULL;
 
+struct _BraseroLibburnSrcData {
+	int fd;
+	off_t size;
+
+	/* That's for the primary volume descriptor used for overwrite media */
+	int pvd_size;						/* in blocks */
+	unsigned char *pvd;
+
+	int read_pvd:1;
+};
+typedef struct _BraseroLibburnSrcData BraseroLibburnSrcData;
+
+static void
+brasero_libburn_src_free_data (struct burn_source *src)
+{
+	BraseroLibburnSrcData *data;
+
+	data = src->data;
+	close (data->fd);
+	g_free (data);
+}
+
+static off_t
+brasero_libburn_src_get_size (struct burn_source *src)
+{
+	BraseroLibburnSrcData *data;
+
+	data = src->data;
+	return data->size;
+}
+
+static int
+brasero_libburn_src_set_size (struct burn_source *src,
+			      off_t size)
+{
+	BraseroLibburnSrcData *data;
+
+	data = src->data;
+	data->size = size;
+	return 1;
+}
+
+/**
+ * This is a copy from burn-volume.c
+ */
+
+struct _BraseroVolDesc {
+	guchar type;
+	gchar id			[5];
+	guchar version;
+};
+typedef struct _BraseroVolDesc BraseroVolDesc;
+
+static int
+brasero_libburn_src_read_xt (struct burn_source *src,
+			     unsigned char *buffer,
+			     int size)
+{
+	int total;
+	BraseroLibburnSrcData *data;
+
+	data = src->data;
+
+	total = 0;
+	while (total < size) {
+		int bytes;
+
+		bytes = read (data->fd, buffer + total, size - total);
+		if (bytes < 0)
+			return -1;
+
+		if (!bytes)
+			break;
+
+		total += bytes;
+	}
+
+	/* copy the primary volume descriptor if a buffer is provided */
+	if (data->pvd
+	&& !data->read_pvd
+	&&  data->pvd_size < BRASERO_PVD_SIZE) {
+		unsigned char *current_pvd;
+		int i;
+
+		current_pvd = data->pvd + data->pvd_size;
+
+		/* read volume descriptors until we reach the end of the
+		 * buffer or find a volume descriptor set end. */
+		for (i = 0; (i << 11) < size && data->pvd_size + (i << 11) < BRASERO_PVD_SIZE; i ++) {
+			BraseroVolDesc *desc;
+
+			/* No need to check the first 16 blocks */
+			if ((data->pvd_size >> 11) + i < 16)
+				continue;
+
+			desc = (BraseroVolDesc *) (buffer + sizeof (BraseroVolDesc) * i);
+			if (desc->type == 255) {
+				data->read_pvd = 1;
+				BRASERO_BURN_LOG ("found volume descriptor set end");
+				break;
+			}
+		}
+
+		memcpy (current_pvd, buffer, i << 11);
+		data->pvd_size += i << 11;
+	}
+
+	return total;
+}
+
+static struct burn_source *
+brasero_libburn_create_fd_source (int fd,
+				  int size,
+				  unsigned char *pvd)
+{
+	struct burn_source *src;
+	BraseroLibburnSrcData *data;
+
+	data = g_new0 (BraseroLibburnSrcData, 1);
+	data->fd = fd;
+	data->size = size;
+	data->pvd = pvd;
+
+	/* FIXME: this could be wrapped into a fifo source to get a smoother
+	 * data delivery. But that means another thread ... */
+	src = g_new0 (struct burn_source, 1);
+	src->version = 1;
+	src->refcount = 1;
+	src->read_xt = brasero_libburn_src_read_xt;
+	src->get_size = brasero_libburn_src_get_size;
+	src->set_size = brasero_libburn_src_set_size;
+	src->free_data = brasero_libburn_src_free_data;
+	src->data = data;
+
+	return src;
+}
+
 static BraseroBurnResult
 brasero_libburn_add_track (struct burn_session *session,
 			   struct burn_track *track,
@@ -98,6 +243,7 @@
 			      int fd,
 			      gint mode,
 			      gint64 size,
+			      unsigned char *pvd,
 			      GError **error)
 {
 	struct burn_source *src;
@@ -107,7 +253,7 @@
 	track = burn_track_create ();
 	burn_track_define_data (track, 0, 0, 0, mode);
 
-	src = burn_fd_source_new (fd, -1, size);
+	src = brasero_libburn_create_fd_source (fd, size, pvd);
 	result = brasero_libburn_add_track (session, track, src, mode, error);
 
 	burn_source_free (src);
@@ -117,6 +263,28 @@
 }
 
 static BraseroBurnResult
+brasero_libburn_add_file_track (struct burn_session *session,
+				const gchar *path,
+				gint mode,
+				off_t size,
+				unsigned char *pvd,
+				GError **error)
+{
+	int fd;
+
+	fd = open (path, O_RDONLY);
+	if (fd == -1) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     strerror (errno));
+		return BRASERO_BURN_ERR;
+	}
+
+	return brasero_libburn_add_fd_track (session, fd, mode, size, pvd, error);
+}
+
+static BraseroBurnResult
 brasero_libburn_setup_session_fd (BraseroLibburn *self,
 			          struct burn_session *session,
 			          GError **error)
@@ -124,8 +292,11 @@
 	int fd;
 	gint64 size;
 	BraseroTrackType type;
+	BraseroLibburnPrivate *priv;
 	BraseroBurnResult result = BRASERO_BURN_OK;
 
+	priv = BRASERO_LIBBURN_PRIVATE (self);
+
 	brasero_job_get_fd_in (BRASERO_JOB (self), &fd);
 
 	/* need to find out what type of track the imager will output */
@@ -147,6 +318,7 @@
 							       fd,
 							       mode,
 							       size,
+							       priv->pvd,
 							       error);
 			break;
 		}
@@ -169,6 +341,7 @@
 								       dup (fd),
 								       BURN_AUDIO,
 								       size,
+								       priv->pvd,
 								       error);
 				if (result != BRASERO_BURN_OK)
 					return result;
@@ -184,39 +357,16 @@
 }
 
 static BraseroBurnResult
-brasero_libburn_add_file_track (struct burn_session *session,
-				const gchar *path,
-				gint mode,
-				off_t size,
-				GError **error)
-{
-	struct burn_source *src;
-	struct burn_track *track;
-	BraseroBurnResult result;
-
-	track = burn_track_create ();
-	burn_track_define_data (track, 0, 0, 0, mode);
-
-	src = burn_file_source_new (path, NULL);
-	result = brasero_libburn_add_track (session, track, src, mode, error);
-
-	if (size > 0)
-		burn_track_set_default_size (track, size);
-
-	burn_source_free (src);
-	burn_track_free (track);
-
-	return result;
-}
-
-static BraseroBurnResult
 brasero_libburn_setup_session_file (BraseroLibburn *self, 
 				    struct burn_session *session,
 				    GError **error)
 {
+	BraseroLibburnPrivate *priv;
 	BraseroBurnResult result;
 	GSList *tracks = NULL;
 
+	priv = BRASERO_LIBBURN_PRIVATE (self);
+
 	/* create the track(s) */
 	result = BRASERO_BURN_OK;
 	brasero_job_get_tracks (BRASERO_JOB (self), &tracks);
@@ -234,6 +384,7 @@
 								 audiopath,
 								 BURN_AUDIO,
 								 -1,
+								 priv->pvd,
 								 error);
 			if (result != BRASERO_BURN_OK)
 				break;
@@ -260,6 +411,7 @@
 								 imagepath,
 								 mode,
 								 -1,
+								 priv->pvd,
 								 error);
 		}
 		else
@@ -304,22 +456,25 @@
 brasero_libburn_start_record (BraseroLibburn *self,
 			      GError **error)
 {
-	int profile;
 	guint64 rate;
-	char prof_name [80];
+	BraseroMedia media;
 	BraseroBurnFlag flags;
 	BraseroBurnResult result;
 	BraseroLibburnPrivate *priv;
 	struct burn_write_opts *opts;
 
 	priv = BRASERO_LIBBURN_PRIVATE (self);
-	if (burn_disc_get_profile (priv->ctx->drive, &profile, prof_name) < 0) {
-		g_set_error (error,
-			     BRASERO_BURN_ERROR,
-			     BRASERO_BURN_ERROR_GENERAL,
-			     _("no profile available for the medium"));
-		return BRASERO_BURN_ERR;
-	}
+
+	/* if appending a DVD+-RW get PVD */
+	brasero_job_get_flags (BRASERO_JOB (self), &flags);
+	brasero_job_get_media (BRASERO_JOB (self), &media);
+
+	if (flags & (BRASERO_BURN_FLAG_MERGE|BRASERO_BURN_FLAG_APPEND)
+	&& (BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS)
+	||  BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_RESTRICTED)
+	||  BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS_DL))
+	&& (media & BRASERO_MEDIUM_HAS_DATA))
+		priv->pvd = g_new0 (unsigned char, BRASERO_PVD_SIZE);
 
 	result = brasero_libburn_create_disc (self, &priv->ctx->disc, error);
 	if (result != BRASERO_BURN_OK)
@@ -332,18 +487,29 @@
 	opts = burn_write_opts_new (priv->ctx->drive);
 	burn_write_opts_set_perform_opc (opts, 0);
 
-	brasero_job_get_flags (BRASERO_JOB (self), &flags);
-	if (profile != BRASERO_SCSI_PROF_DVD_RW_RESTRICTED
-	&&  profile != BRASERO_SCSI_PROF_DVD_RW_PLUS
-	&& (flags & BRASERO_BURN_FLAG_DAO))
+	if (!BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS)
+	&&  !BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_RESTRICTED)
+	&&  !BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS_DL)
+	&&  (flags & BRASERO_BURN_FLAG_DAO))
 		burn_write_opts_set_write_type (opts,
 						BURN_WRITE_SAO,
 						BURN_BLOCK_SAO);
-	else
+	else {
 		burn_write_opts_set_write_type (opts,
 						BURN_WRITE_TAO,
 						BURN_BLOCK_MODE1);
 
+		/* we also set the start block to write from if MERGE is set */
+		if (flags & BRASERO_BURN_FLAG_MERGE) {
+			gint64 address = 0;
+
+			brasero_job_get_next_writable_address (BRASERO_JOB (self), &address);
+
+			BRASERO_JOB_LOG (self, "Starting to write at block = %lli and byte %lli", address, address * 2048);
+			burn_write_opts_set_start_byte (opts, address * 2048);
+		}
+	}
+
 	burn_write_opts_set_underrun_proof (opts, (flags & BRASERO_BURN_FLAG_BURNPROOF) != 0);
 	burn_write_opts_set_multi (opts, (flags & BRASERO_BURN_FLAG_MULTI) != 0);
 	burn_write_opts_set_simulate (opts, (flags & BRASERO_BURN_FLAG_DUMMY) != 0);
@@ -436,6 +602,7 @@
 					       fd,
 					       BURN_MODE1,
 					       65536,		/* 32 blocks */
+					       priv->pvd,
 					       error);
 	close (fd);
 
@@ -526,6 +693,11 @@
 		priv->ctx = NULL;
 	}
 
+	if (priv->pvd) {
+		g_free (priv->pvd);
+		priv->pvd = NULL;
+	}
+
 	if (BRASERO_JOB_CLASS (parent_class)->stop)
 		BRASERO_JOB_CLASS (parent_class)->stop (job, error);
 
@@ -536,9 +708,56 @@
 brasero_libburn_clock_tick (BraseroJob *job)
 {
 	BraseroLibburnPrivate *priv;
+	BraseroBurnResult result;
+	int ret;
 
 	priv = BRASERO_LIBBURN_PRIVATE (job);
-	brasero_libburn_common_status (job, priv->ctx);
+	result = brasero_libburn_common_status (job, priv->ctx);
+
+	if (result != BRASERO_BURN_OK)
+		return BRASERO_BURN_OK;
+
+	/* Double check that everything went well */
+	if (!burn_drive_wrote_well (priv->ctx->drive)) {
+		brasero_job_error (job,
+				   g_error_new (BRASERO_BURN_ERROR,
+						BRASERO_BURN_ERROR_GENERAL,
+						_("an unknown error occured")));
+	}
+
+	/* That's finished */
+	if (!priv->pvd) {
+		brasero_job_set_dangerous (job, FALSE);
+		brasero_job_finished_session (job);
+		return BRASERO_BURN_OK;
+	}
+
+	/* In case we append data to a DVD+RW or DVD-RW
+	 * (restricted overwrite) medium , we're not
+	 * done since we need to overwrite the primary
+	 * volume descriptor at sector 0.
+	 * NOTE: This is a synchronous call but given the size of the buffer
+	 * that shouldn't block.
+	 * NOTE 2: in source we read the volume descriptors until we reached
+	 * either the end of the buffer or the volume descriptor set end. That's
+	 * kind of useless since for a DVD 16 blocks are written at a time. */
+	BRASERO_JOB_LOG (job, "Starting to overwrite primary volume descriptor");
+	ret = burn_random_access_write (priv->ctx->drive,
+					0,
+					(char*)priv->pvd,
+					BRASERO_PVD_SIZE,
+					0);
+	if (ret != 1) {
+		brasero_job_error (job,
+				   g_error_new (BRASERO_BURN_ERROR,
+						BRASERO_BURN_ERROR_GENERAL,
+						_("an unknown error occured")));
+		return BRASERO_BURN_OK;
+	}
+
+	brasero_job_set_dangerous (job, FALSE);
+	brasero_job_finished_session (job);
+
 	return BRASERO_BURN_OK;
 }
 
@@ -578,6 +797,10 @@
 		priv->ctx = NULL;
 	}
 
+	/* Since the library is not needed any more call burn_finish ().
+	 * NOTE: it itself calls burn_abort (). */
+	burn_finish ();
+
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -605,10 +828,14 @@
 					  BRASERO_MEDIUM_HAS_DATA|
 					  BRASERO_MEDIUM_BLANK;
 	const BraseroMedia media_dvd_rw_plus = BRASERO_MEDIUM_DVD|
+					       BRASERO_MEDIUM_DVD_DL|
 					       BRASERO_MEDIUM_PLUS|
 					       BRASERO_MEDIUM_RESTRICTED|
 					       BRASERO_MEDIUM_REWRITABLE|
-					       BRASERO_MEDIUM_BLANK;
+					       BRASERO_MEDIUM_BLANK|
+					       BRASERO_MEDIUM_APPENDABLE|
+					       BRASERO_MEDIUM_CLOSED|
+					       BRASERO_MEDIUM_HAS_DATA;
 	GSList *output;
 	GSList *input;
 
@@ -772,34 +999,94 @@
 	brasero_plugin_link_caps (plugin, output, input);
 	g_slist_free (output);
 
-	/* NOTE: libburn can't append anything to DVDRW+ and restricted
-	 * moreover DVD+ R/RW don't have a dummy mode. */
+	/* for DVD+/- restricted */
+	output = brasero_caps_disc_new (media_dvd_rw_plus);
+	brasero_plugin_link_caps (plugin, output, input);
+	g_slist_free (output);
+	g_slist_free (input);
+
+	/* for DVD-RW restricted overwrite */
 	brasero_plugin_set_flags (plugin,
-				  BRASERO_MEDIUM_DVDRW_RESTRICTED|
+				  BRASERO_MEDIUM_DVD|
+				  BRASERO_MEDIUM_RESTRICTED|
+				  BRASERO_MEDIUM_REWRITABLE|
 				  BRASERO_MEDIUM_BLANK,
-				/*  BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE| */
 				  BRASERO_BURN_FLAG_DAO|
+				  BRASERO_BURN_FLAG_MULTI|
 				  BRASERO_BURN_FLAG_BURNPROOF|
 				  BRASERO_BURN_FLAG_OVERBURN|
 				  BRASERO_BURN_FLAG_DUMMY|
-				  BRASERO_BURN_FLAG_NOGRACE,
-				  BRASERO_BURN_FLAG_NONE);
+				  BRASERO_BURN_FLAG_NOGRACE|
+				  BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE,
+				  BRASERO_BURN_FLAG_MULTI);
+
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_DVD|
+				  BRASERO_MEDIUM_RESTRICTED|
+				  BRASERO_MEDIUM_REWRITABLE|
+				  BRASERO_MEDIUM_APPENDABLE|
+				  BRASERO_MEDIUM_CLOSED|
+				  BRASERO_MEDIUM_HAS_DATA,
+				  BRASERO_BURN_FLAG_BURNPROOF|
+				  BRASERO_BURN_FLAG_OVERBURN|
+				  BRASERO_BURN_FLAG_MULTI|
+				  BRASERO_BURN_FLAG_DUMMY|
+				  BRASERO_BURN_FLAG_NOGRACE|
+				  BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE,
+				  BRASERO_BURN_FLAG_MULTI);
+
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_DVD|
+				  BRASERO_MEDIUM_RESTRICTED|
+				  BRASERO_MEDIUM_REWRITABLE|
+				  BRASERO_MEDIUM_APPENDABLE|
+				  BRASERO_MEDIUM_CLOSED|
+				  BRASERO_MEDIUM_HAS_DATA,
+				  BRASERO_BURN_FLAG_BURNPROOF|
+				  BRASERO_BURN_FLAG_OVERBURN|
+				  BRASERO_BURN_FLAG_MULTI|
+				  BRASERO_BURN_FLAG_DUMMY|
+				  BRASERO_BURN_FLAG_NOGRACE|
+				  BRASERO_BURN_FLAG_MERGE,
+				  BRASERO_BURN_FLAG_MULTI);
 
-	/* FIXME: can libburn do like growisofs (overwrite / avoid blanking)? */
+	/* for DVD+RW */
 	brasero_plugin_set_flags (plugin,
 				  BRASERO_MEDIUM_DVDRW_PLUS|
+				  BRASERO_MEDIUM_DVD_DL|
 				  BRASERO_MEDIUM_BLANK,
+				  BRASERO_BURN_FLAG_MULTI|
 				  BRASERO_BURN_FLAG_DAO|
-				/*  BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE| */
 				  BRASERO_BURN_FLAG_BURNPROOF|
 				  BRASERO_BURN_FLAG_OVERBURN|
 				  BRASERO_BURN_FLAG_NOGRACE,
-				  BRASERO_BURN_FLAG_NONE);
+				  BRASERO_BURN_FLAG_MULTI);
 
-	output = brasero_caps_disc_new (media_dvd_rw_plus);
-	brasero_plugin_link_caps (plugin, output, input);
-	g_slist_free (output);
-	g_slist_free (input);
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_DVDRW_PLUS|
+				  BRASERO_MEDIUM_DVD_DL|
+				  BRASERO_MEDIUM_APPENDABLE|
+				  BRASERO_MEDIUM_CLOSED|
+				  BRASERO_MEDIUM_HAS_DATA,
+				  BRASERO_BURN_FLAG_BURNPROOF|
+				  BRASERO_BURN_FLAG_OVERBURN|
+				  BRASERO_BURN_FLAG_MULTI|
+				  BRASERO_BURN_FLAG_NOGRACE|
+				  BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE,
+				  BRASERO_BURN_FLAG_MULTI);
+
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_DVDRW_PLUS|
+				  BRASERO_MEDIUM_DVD_DL|
+				  BRASERO_MEDIUM_APPENDABLE|
+				  BRASERO_MEDIUM_CLOSED|
+				  BRASERO_MEDIUM_HAS_DATA,
+				  BRASERO_BURN_FLAG_BURNPROOF|
+				  BRASERO_BURN_FLAG_OVERBURN|
+				  BRASERO_BURN_FLAG_MULTI|
+				  BRASERO_BURN_FLAG_NOGRACE|
+				  BRASERO_BURN_FLAG_MERGE,
+				  BRASERO_BURN_FLAG_MULTI);
 
 	/* add blank caps */
 	output = brasero_caps_disc_new (BRASERO_MEDIUM_CD|

Modified: trunk/src/plugins/libburnia/burn-libisofs.c
==============================================================================
--- trunk/src/plugins/libburnia/burn-libisofs.c	(original)
+++ trunk/src/plugins/libburnia/burn-libisofs.c	Sat May 17 20:16:21 2008
@@ -46,12 +46,16 @@
 #include "burn-libisofs.h"
 #include "burn-job.h"
 #include "burn-plugin.h"
+#include "burn-libburn-common.h"
 
 BRASERO_PLUGIN_BOILERPLATE (BraseroLibisofs, brasero_libisofs, BRASERO_TYPE_JOB, BraseroJob);
 
 struct _BraseroLibisofsPrivate {
 	struct burn_source *libburn_src;
 
+	/* that's for multisession */
+	BraseroLibburnCtx *ctx;
+
 	GError *error;
 	GThread *thread;
 	guint thread_id;
@@ -288,7 +292,6 @@
 		return BRASERO_BURN_ERR;
 	}
 
-	/* This is a crash */
 	iso_set_msgs_severities ("NEVER", "ALL", "brasero (libisofs)");
 
 	priv->thread = g_thread_create (brasero_libisofs_thread_started,
@@ -354,17 +357,137 @@
 	return len_a - len_b;
 }
 
+static int 
+brasero_libisofs_import_read (IsoDataSource *src, uint32_t lba, uint8_t *buffer)
+{
+	struct burn_drive *d;
+	off_t data_count;
+	gint result;
+
+	d = (struct burn_drive*)src->data;
+
+	result = burn_read_data(d,
+				(off_t) lba * (off_t) 2048,
+				(char*)buffer, 
+				2048,
+				&data_count,
+				0);
+	if (result < 0 )
+		return -1; /* error */
+
+	return 1;
+}
+
+static int
+brasero_libisofs_import_open (IsoDataSource *src)
+{
+	return 1;
+}
+
+static int
+brasero_libisofs_import_close (IsoDataSource *src)
+{
+	return 1;
+}
+    
+static void 
+brasero_libisofs_import_free (IsoDataSource *src)
+{ }
+
+static BraseroBurnResult
+brasero_libisofs_import_last_session (BraseroLibisofs *self,
+				      IsoImage *image,
+				      IsoWriteOpts *wopts,
+				      GError **error)
+{
+	int result;
+	IsoReadOpts *opts;
+	BraseroMedia media;
+	IsoDataSource *src;
+	gint64 start_block;
+	gint64 session_block;
+	BraseroLibisofsPrivate *priv;
+
+	priv = BRASERO_LIBISOFS_PRIVATE (self);
+
+	priv->ctx = brasero_libburn_common_ctx_new (BRASERO_JOB (self), error);
+	if (!priv->ctx)
+		return BRASERO_BURN_ERR;
+
+	src = g_new0 (IsoDataSource, 1);
+	src->version = 0;
+	src->refcount = 1;
+	src->read_block = brasero_libisofs_import_read;
+	src->open = brasero_libisofs_import_open;
+	src->close = brasero_libisofs_import_close;
+	src->free_data = brasero_libisofs_import_free;
+	src->data = priv->ctx->drive;
+
+	result = iso_read_opts_new (&opts, 0);
+	if (result < 0) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("No read options could be created."));
+		return BRASERO_BURN_ERR;
+	}
+
+	brasero_job_get_last_session_address (BRASERO_JOB (self), &session_block);
+	iso_read_opts_set_start_block (opts, session_block);
+
+	/* import image */
+	result = iso_image_import (image, src, opts, NULL);
+	iso_data_source_unref (src);
+	iso_read_opts_free (opts);
+
+	/* release the drive */
+	if (priv->ctx) {
+		/* This may not be a good idea ...*/
+		brasero_libburn_common_ctx_free (priv->ctx);
+		priv->ctx = NULL;
+	}
+
+	if (result < 0) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("Image import failed."));	
+		return BRASERO_BURN_ERR;
+	}
+
+	/* check is this is a DVD+RW */
+	brasero_job_get_next_writable_address (BRASERO_JOB (self), &start_block);
+
+	brasero_job_get_media (BRASERO_JOB (self), &media);
+	if (BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS)
+	||  BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_RESTRICTED)
+	||  BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS_DL)) {
+		/* This is specific to overwrite media; the start address is the
+		 * size of all the previous data written */
+		BRASERO_JOB_LOG (self, "Growing image (start %i)", start_block);
+	}
+
+	/* set the start block for the multisession image */
+	iso_write_opts_set_ms_block (wopts, start_block);
+	iso_write_opts_set_appendable (wopts, 1);
+
+	iso_tree_set_replace_mode (image, ISO_REPLACE_ALWAYS);
+	return BRASERO_BURN_OK;
+}
+
 static gpointer
 brasero_libisofs_create_volume_thread (gpointer data)
 {
 	BraseroLibisofs *self = BRASERO_LIBISOFS (data);
 	BraseroLibisofsPrivate *priv;
 	BraseroTrack *track = NULL;
+	IsoWriteOpts *opts = NULL;
+	IsoImage *image = NULL;
+	BraseroBurnFlag flags;
 	GSList *grafts = NULL;
 	gchar *label = NULL;
 	gchar *publisher;
 	GSList *excluded;
-	IsoImage *image;
 	GSList *iter;
 
 	priv = BRASERO_LIBISOFS_PRIVATE (self);
@@ -400,6 +523,27 @@
 	g_free (publisher);
 	g_free (label);
 
+	iso_write_opts_new (&opts, 2);
+
+	brasero_job_get_flags (BRASERO_JOB (self), &flags);
+	if (flags & BRASERO_BURN_FLAG_MERGE) {
+		BraseroBurnResult result;
+
+		result = brasero_libisofs_import_last_session (self,
+							       image,
+							       opts,
+							       &priv->error);
+		if (result != BRASERO_BURN_OK)
+			goto end;
+	}
+	else if (flags & BRASERO_BURN_FLAG_APPEND) {
+		gint64 start_block;
+
+		brasero_job_get_next_writable_address (BRASERO_JOB (self), &start_block);
+		iso_write_opts_set_ms_block (opts, start_block);
+	}
+
+
 	brasero_job_start_progress (BRASERO_JOB (self), FALSE);
 
 	/* copy the list as we're going to reorder it */
@@ -411,10 +555,12 @@
 	/* add global exclusions */
 	for (excluded = brasero_track_get_data_excluded_source (track, FALSE);
 	     excluded; excluded = excluded->next) {
-		gchar *uri;
+		gchar *uri, *local;
 
 		uri = excluded->data;
-		iso_tree_add_exclude (image, g_filename_from_uri (uri, NULL, NULL));
+		local = g_filename_from_uri (uri, NULL, NULL);
+		iso_tree_add_exclude (image, local);
+		g_free (local);
 	}
 
 	for (iter = grafts; iter; iter = iter->next) {
@@ -553,10 +699,8 @@
 	if (!priv->error && !priv->cancel) {
 		gint64 size;
 		BraseroTrackType type;
-		IsoWriteOpts *opts = NULL;
 
 		brasero_track_get_type (track, &type);
-		iso_write_opts_new (&opts, 0);
 
 		if ((type.subtype.fs_type & BRASERO_IMAGE_FS_ISO)
 		&&  (type.subtype.fs_type & BRASERO_IMAGE_ISO_FS_LEVEL_3))
@@ -565,12 +709,8 @@
 			iso_write_opts_set_iso_level (opts, 2);
 
 		iso_write_opts_set_rockridge (opts, 1);
-
-		if (type.subtype.img_format & BRASERO_IMAGE_FS_JOLIET)
-			iso_write_opts_set_joliet (opts, 1);
-
-		if (type.subtype.fs_type & BRASERO_IMAGE_ISO_FS_DEEP_DIRECTORY)
-			iso_write_opts_set_allow_deep_paths (opts, 1);
+		iso_write_opts_set_joliet (opts, (type.subtype.img_format & BRASERO_IMAGE_FS_JOLIET) != 0);
+		iso_write_opts_set_allow_deep_paths (opts, (type.subtype.fs_type & BRASERO_IMAGE_ISO_FS_DEEP_DIRECTORY) != 0);
 
 		if (iso_image_create_burn_source (image, opts, &priv->libburn_src) >= 0) {
 			size = priv->libburn_src->get_size (priv->libburn_src);
@@ -578,10 +718,14 @@
 								       BRASERO_SIZE_TO_SECTORS (size, 2048),
 								       size);
 		}
-		iso_image_unref (image);
-		iso_write_opts_free (opts);
 	}
 
+	if (opts)
+		iso_write_opts_free (opts);
+
+	if (image)
+		iso_image_unref (image);
+
 	if (!priv->cancel)
 		priv->thread_id = g_idle_add (brasero_libisofs_create_volume_thread_finished, self);
 
@@ -608,9 +752,7 @@
 		return BRASERO_BURN_ERR;
 	}
 
-	/* This is a crash */
 	iso_set_msgs_severities ("NEVER", "ALL", "brasero (libisofs)");
-
 	priv->thread = g_thread_create (brasero_libisofs_create_volume_thread,
 					self,
 					TRUE,
@@ -655,6 +797,18 @@
 
 	priv = BRASERO_LIBISOFS_PRIVATE (self);
 
+	/* NOTE: this can only happen when we're preparing the volumes for a
+	 * multi session disc. At this point we're only running to get the size
+	 * of the future volume and we can't race with libburn plugin that isn't
+	 * operating at this stage. */
+	if (priv->ctx) {
+		brasero_libburn_common_ctx_free (priv->ctx);
+		priv->ctx = NULL;
+	}
+
+	if (priv->libburn_src)
+		priv->libburn_src->cancel (priv->libburn_src);
+
 	if (priv->thread) {
 		priv->cancel = 1;
 		g_thread_join (priv->thread);
@@ -670,8 +824,6 @@
 		g_error_free (priv->error);
 		priv->error = NULL;
 	}
-
-	iso_finish ();
 }
 
 static BraseroBurnResult
@@ -714,6 +866,13 @@
 		burn_source_free (priv->libburn_src);
 		priv->libburn_src = NULL;
 	}
+
+	/* Since the library is not needed any more call burn_finish ().
+	 * NOTE: it itself calls burn_abort (). */
+	burn_finish ();
+
+	/* close libisofs library */
+	iso_finish ();
 }
 
 static void
@@ -741,6 +900,30 @@
 			       "Philippe Rouquier",
 			       0);
 
+	/* NOTE: we don't include DVDRW+ DVDRW- restricted in here */
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_CDR|
+				  BRASERO_MEDIUM_CDRW|
+				  BRASERO_MEDIUM_DVDR|
+				  BRASERO_MEDIUM_DVDRW|
+				  BRASERO_MEDIUM_DVD_DL|
+				  BRASERO_MEDIUM_APPENDABLE|
+				  BRASERO_MEDIUM_HAS_AUDIO|
+				  BRASERO_MEDIUM_HAS_DATA,
+				  BRASERO_BURN_FLAG_APPEND|
+				  BRASERO_BURN_FLAG_MERGE,
+				  BRASERO_BURN_FLAG_NONE);
+
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_DVDRW_PLUS|
+				  BRASERO_MEDIUM_RESTRICTED|
+				  BRASERO_MEDIUM_DVD_DL|
+				  BRASERO_MEDIUM_APPENDABLE|
+				  BRASERO_MEDIUM_CLOSED|
+				  BRASERO_MEDIUM_HAS_DATA,
+				  BRASERO_BURN_FLAG_MERGE,
+				  BRASERO_BURN_FLAG_NONE);
+
 	output = brasero_caps_image_new (BRASERO_PLUGIN_IO_ACCEPT_FILE|
 					 BRASERO_PLUGIN_IO_ACCEPT_PIPE,
 					 BRASERO_IMAGE_FORMAT_BIN);



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