brasero r978 - in branches/video: . data po src src/plugins/growisofs src/plugins/libburnia



Author: philippr
Date: Sat Jul 12 11:43:40 2008
New Revision: 978
URL: http://svn.gnome.org/viewvc/brasero?rev=978&view=rev

Log:
Ported changes from trunk

Added:
   branches/video/po/da.po
      - copied unchanged from r977, /trunk/po/da.po
   branches/video/po/zh_CN.po
      - copied unchanged from r977, /trunk/po/zh_CN.po
   branches/video/src/scsi-uscsi.c
      - copied unchanged from r977, /trunk/src/scsi-uscsi.c
Modified:
   branches/video/ChangeLog
   branches/video/configure.in
   branches/video/data/brasero.desktop.in.in
   branches/video/po/ChangeLog
   branches/video/po/LINGUAS
   branches/video/po/en_GB.po   (props changed)
   branches/video/po/ja.po
   branches/video/src/Makefile.am
   branches/video/src/brasero-data-project.c
   branches/video/src/brasero-data-tree-model.c
   branches/video/src/brasero-file-node.c
   branches/video/src/brasero-io.c
   branches/video/src/brasero-metadata.h
   branches/video/src/burn-caps.c
   branches/video/src/burn-drive.c
   branches/video/src/burn-job.c
   branches/video/src/burn-medium.c
   branches/video/src/burn-task-ctx.c
   branches/video/src/plugins/growisofs/burn-growisofs.c
   branches/video/src/plugins/libburnia/burn-libburn-common.c
   branches/video/src/plugins/libburnia/burn-libburn.c
   branches/video/src/scsi-sg.c

Modified: branches/video/configure.in
==============================================================================
--- branches/video/configure.in	(original)
+++ branches/video/configure.in	Sat Jul 12 11:43:40 2008
@@ -37,7 +37,6 @@
 AC_PROG_LIBTOOL
 dnl ** reminder: the following set CFLAGS to -O2 -g if empty
 AC_PROG_CC
-AM_PROG_CC_STDC
 AC_HEADER_STDC
 dnl Set PACKAGE_DATA_DIR in config.h.
 if test "x${datadir}" = 'x${prefix}/share'; then
@@ -64,21 +63,29 @@
 AC_SUBST(BRASERO_SCSI_LIBS)
 AC_CHECK_HEADERS([camlib.h],[has_cam="yes"],[has_cam="no"])
 
-if test x"$has_cam" = x"yes"; then
-    BRASERO_SCSI_LIBS="-lcam"
-else
-
 dnl ***************** check for linux sg interface *************
 AC_CHECK_TYPES([sg_io_hdr_t],[has_sg="yes"],[has_sg="no"],
 [#include <sys/types.h>
  #include <scsi/sg.h>])
 
-if test x"$has_sg" = x"no"; then
-	AC_ERROR([Linux sg interface headers could not be found])
-fi
+dnl ***************** check for solaris uscsi interface ********
+AC_CHECK_TYPES([struct uscsi_cmd],[has_uscsi="yes"],[has_uscsi="no"],
+[#include <sys/types.h>
+ #include <sys/scsi/impl/uscsi.h>])
+
+if test x"$has_cam" = x"yes"; then
+    BRASERO_SCSI_LIBS="-lcam"
+elif test x"$has_sg" = x"yes"; then
+	:
+elif test x"$has_uscsi" = x"yes"; then
+	:
+else
+	AC_ERROR([Support Linux SG, FreeBSD CAM, Solaris USCSI. No supported SCSI interface headers could not be found.])
 fi
+
 AM_CONDITIONAL(HAVE_CAM_LIB_H, test x"$has_cam" = "xyes")
 AM_CONDITIONAL(HAVE_SG_IO_HDR_T, test x"$has_sg" = "xyes")
+AM_CONDITIONAL(HAVE_USCSI_H, test x"$has_uscsi" = "xyes")
 
 dnl ***************** LARGE FILE SUPPORT ***********************
 

Modified: branches/video/data/brasero.desktop.in.in
==============================================================================
--- branches/video/data/brasero.desktop.in.in	(original)
+++ branches/video/data/brasero.desktop.in.in	Sat Jul 12 11:43:40 2008
@@ -3,7 +3,6 @@
 _GenericName=Disc Burning Application
 _Comment=Write and copy CD / DVD
 Categories=GNOME;AudioVideo;DiscBurning;
-Encoding=UTF-8
 Exec=brasero %U
 Icon=brasero
 MimeType=application/x-cd-image;application/x-cdrdao-toc;application/x-toc;application/x-cue;application/x-brasero;audio/x-scpls;audio/x-ms-asx;audio/x-mp3-playlist;audio/x-mpegurl;
@@ -15,7 +14,7 @@
 X-GNOME-Bugzilla-Component=general
 X-GNOME-Bugzilla-Version= VERSION@
 
-Actions=BurnImage;OpenProject;
+Actions=BurnImage;OpenProject;OpenPlaylist;
 
 [Desktop Action BurnImage]
 Icon=brasero

Modified: branches/video/po/LINGUAS
==============================================================================
--- branches/video/po/LINGUAS	(original)
+++ branches/video/po/LINGUAS	Sat Jul 12 11:43:40 2008
@@ -1,6 +1,7 @@
 ar
 ca
 cs
+da
 de
 dz
 el
@@ -28,5 +29,6 @@
 sr Latn
 sv
 th
+zh_CN
 zh_HK
 zh_TW

Modified: branches/video/src/Makefile.am
==============================================================================
--- branches/video/src/Makefile.am	(original)
+++ branches/video/src/Makefile.am	Sat Jul 12 11:43:40 2008
@@ -282,6 +282,11 @@
 brasero_SOURCES += scsi-sg.c
 endif
 
+# Solaris's USCSI interface
+if HAVE_USCSI_H
+brasero_SOURCES += scsi-uscsi.c
+endif
+
 brasero_LDADD =	\
 	$(BRASERO_LIBS) $(BRASERO_LIBXML_LIBS)
 

Modified: branches/video/src/brasero-data-project.c
==============================================================================
--- branches/video/src/brasero-data-project.c	(original)
+++ branches/video/src/brasero-data-project.c	Sat Jul 12 11:43:40 2008
@@ -2115,7 +2115,6 @@
 				  width,
 				  name,
 				  num);
-
 	return retval;
 }
 
@@ -2230,6 +2229,47 @@
 	}
 }
 
+static void
+_foreach_joliet_incompatible_make_list_cb (BraseroJolietKey *key,
+					   GSList *nodes,
+					   MakeTrackData *data)
+{
+	GSList *iter;
+
+	/* now exclude all nodes and graft them with a joliet compatible name */
+	for (iter = nodes; iter; iter = iter->next) {
+		BraseroFileNode *node;
+		BraseroGraftPt *graft;
+
+		node = iter->data;
+
+		/* skip grafted nodes (they were already processed). */
+		if (node->is_grafted)
+			continue;
+
+		graft = g_new0 (BraseroGraftPt, 1);
+		graft->path = brasero_data_project_node_to_path (data->project, node, TRUE);
+		if (!node->is_file && data->append_slash) {
+			gchar *tmp;
+
+			/* we need to know if that's a directory or not since if
+			 * it is then mkisofs (but not genisoimage) requires the
+			 * disc path to end with '/'; if there isn't '/' at the 
+			 * end then only the directory contents are added. */
+			tmp = graft->path;
+			graft->path = g_strconcat (graft->path, "/", NULL);
+			g_free (tmp);
+		}
+
+		/* NOTE: here it's not possible to get a created folder here 
+		 * since it would be grafted */
+		graft->uri = brasero_data_project_node_to_uri (data->project, node);
+		data->grafts = g_slist_prepend (data->grafts, graft);
+
+		data->excluded = g_slist_prepend (data->excluded, g_strdup (graft->uri));
+	}
+}
+
 gboolean
 brasero_data_project_get_contents (BraseroDataProject *self,
 				   GSList **grafts,
@@ -2255,6 +2295,14 @@
 			      (GHFunc) _foreach_grafts_make_list_cb,
 			      &callback_data);
 
+	if (joliet_compat) {
+		/* we have to make sure that even the files that are not grafted
+		 * have joliet compatible names. */
+		g_hash_table_foreach (priv->joliet,
+				      (GHFunc) _foreach_joliet_incompatible_make_list_cb,
+				      &callback_data);
+	}
+
 	if (grafts)
 		*grafts = callback_data.grafts;
 

Modified: branches/video/src/brasero-data-tree-model.c
==============================================================================
--- branches/video/src/brasero-data-tree-model.c	(original)
+++ branches/video/src/brasero-data-tree-model.c	Sat Jul 12 11:43:40 2008
@@ -105,7 +105,7 @@
 	g_return_val_if_fail (child->user_data != NULL, FALSE);
 
 	node = child->user_data;
-	if (GPOINTER_TO_INT (child->user_data2) == BRASERO_ROW_BOGUS) {
+	if (child->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 		/* This is a bogus row intended for empty directories
 		 * user_data has the parent empty directory. */
 		iter->user_data2 = GINT_TO_POINTER (BRASERO_ROW_REGULAR);
@@ -141,7 +141,7 @@
 		g_return_val_if_fail (priv->stamp == parent->stamp, FALSE);
 		g_return_val_if_fail (parent->user_data != NULL, FALSE);
 
-		if (GPOINTER_TO_INT (parent->user_data2) == BRASERO_ROW_BOGUS) {
+		if (parent->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 			/* This is a bogus row intended for empty directories,
 			 * it hasn't got children. */
 			return FALSE;
@@ -180,7 +180,7 @@
 	g_return_val_if_fail (priv->stamp == iter->stamp, 0);
 	g_return_val_if_fail (iter->user_data != NULL, 0);
 
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS)
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS))
 		return 0;
 
 	node = iter->user_data;
@@ -207,7 +207,7 @@
 	g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
 	g_return_val_if_fail (iter->user_data != NULL, FALSE);
 
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS) {
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 		/* This is a bogus row intended for empty directories
 		 * it hasn't got children */
 		return FALSE;
@@ -238,11 +238,25 @@
 
 	priv = BRASERO_DATA_TREE_MODEL_PRIVATE (model);
 
+	if (!parent) {
+		BraseroFileNode *root;
+
+		/* This is for the top directory */
+		root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (model));
+		if (!BRASERO_FILE_NODE_CHILDREN (root))
+			return FALSE;
+
+		iter->stamp = priv->stamp;
+		iter->user_data = BRASERO_FILE_NODE_CHILDREN (root);
+		iter->user_data2 = GINT_TO_POINTER (BRASERO_ROW_REGULAR);
+		return TRUE;
+	}
+
 	/* make sure that iter comes from us */
 	g_return_val_if_fail (priv->stamp == parent->stamp, FALSE);
 	g_return_val_if_fail (parent->user_data != NULL, FALSE);
 
-	if (GPOINTER_TO_INT (parent->user_data2) == BRASERO_ROW_BOGUS) {
+	if (parent->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 		iter->user_data = NULL;
 		return FALSE;
 	}
@@ -281,7 +295,7 @@
 	g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
 	g_return_val_if_fail (iter->user_data != NULL, FALSE);
 
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS) {
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 		/* This is a bogus row intended for empty directories
 		 * user_data has the parent empty directory. It hasn't
 		 * got any peer.*/
@@ -291,7 +305,6 @@
 
 	node = iter->user_data;
 	iter->user_data = node->next;
-
 	if (!node->next)
 		return FALSE;
 
@@ -311,7 +324,7 @@
 	/* Check if that's a BOGUS row. In this case that means the parent was
 	 * expanded. Therefore ask vfs to increase its priority if it's loading
 	 * its contents. */
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS) {
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 		/* NOTE: this has to be a directory */
 		/* NOTE: there is no need to check for is_loading case here
 		 * since before showing its BOGUS row the tree will have shown
@@ -368,7 +381,7 @@
 
 	/* if it's a BOGUS row stop here since they are not added to shown list.
 	 * In the same way returns if it is a file. */
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS)
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS))
 		return;
 
 	node = iter->user_data;
@@ -407,7 +420,7 @@
 
 	node = iter->user_data;
 
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS) {
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS)) {
 		switch (column) {
 		case BRASERO_DATA_TREE_MODEL_NAME:
 			g_value_init (value, G_TYPE_STRING);
@@ -444,6 +457,11 @@
 			g_value_init (value, G_TYPE_BOOLEAN);
 			g_value_set_boolean (value, FALSE);
 			return;
+	
+		case BRASERO_DATA_TREE_MODEL_COLOR:
+			g_value_init (value, G_TYPE_STRING);
+			g_value_set_string (value, NULL);
+			return;
 
 		default:
 			return;
@@ -683,16 +701,10 @@
 	node = iter->user_data;
 
 	/* NOTE: there is only one single node without a name: root */
-	path = gtk_tree_path_new ();
-	for (; node->parent && BRASERO_FILE_NODE_NAME (node); node = node->parent) {
-		guint nth;
-
-		nth = brasero_data_tree_model_node_index (node);
-		gtk_tree_path_prepend_index (path, nth);
-	}
+	path = brasero_data_tree_model_node_to_path (BRASERO_DATA_TREE_MODEL (model), node);
 
 	/* Add index 0 for empty bogus row */
-	if (GPOINTER_TO_INT (iter->user_data2) == BRASERO_ROW_BOGUS)
+	if (iter->user_data2 == GINT_TO_POINTER (BRASERO_ROW_BOGUS))
 		gtk_tree_path_append_index (path, 0);
 
 	return path;
@@ -722,7 +734,6 @@
 		if (!node)
 			return NULL;
 	}
-
 	return node;
 }
 
@@ -1161,7 +1172,7 @@
 	if (BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->reset)
 		BRASERO_DATA_PROJECT_CLASS (brasero_data_tree_model_parent_class)->reset (project, num_nodes);
 }
-guint tintin = 1;
+
 static gboolean
 brasero_data_tree_model_node_added (BraseroDataProject *project,
 				    BraseroFileNode *node,
@@ -1196,7 +1207,6 @@
 	}
 
 	/* Add the row itself */
-	
 	gtk_tree_model_row_inserted (GTK_TREE_MODEL (project),
 				     path,
 				     &iter);
@@ -1224,23 +1234,11 @@
 
 	/* Now see if this is a directory which is empty and needs a BOGUS */
 	if (!node->is_file && !node->is_loading) {
-		/* NOTE: No need to check for the number of children ... */
-
 		/* emit child-toggled. Thanks to bogus rows we only need to emit
 		 * this signal once since a directory will always have a child
 		 * in the tree */
 		path = brasero_data_tree_model_node_to_path (BRASERO_DATA_TREE_MODEL (project), node);
 		gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (project), path, &iter);
-
-		/* add the row */
-		iter.stamp = priv->stamp;
-		iter.user_data = node;
-		iter.user_data2 = GINT_TO_POINTER (BRASERO_ROW_BOGUS);
-
-		gtk_tree_path_append_index (path, 0);
-		gtk_tree_model_row_inserted (GTK_TREE_MODEL (project),
-					     path,
-					     &iter);
 		gtk_tree_path_free (path);
 	}
 

Modified: branches/video/src/brasero-file-node.c
==============================================================================
--- branches/video/src/brasero-file-node.c	(original)
+++ branches/video/src/brasero-file-node.c	Sat Jul 12 11:43:40 2008
@@ -583,7 +583,7 @@
 		return NULL;
 
 	if (g_utf8_validate (name, -1, &invalid))
-		return g_markup_escape_text (name, -1);
+		return NULL;
 
 	retval = g_strdup (name);
 	ptr = retval + (invalid - name);
@@ -596,10 +596,6 @@
 		ptr ++;
 	}
 
-	ptr = retval;
-	retval = g_markup_escape_text (retval, -1);
-	g_free (ptr);
-
 	return retval;
 }
 
@@ -800,7 +796,6 @@
 		g_free (unescaped_name);
 		return name;
 	}
-
 	return unescaped_name;
 }
 

Modified: branches/video/src/brasero-io.c
==============================================================================
--- branches/video/src/brasero-io.c	(original)
+++ branches/video/src/brasero-io.c	Sat Jul 12 11:43:40 2008
@@ -1,22 +1,22 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
- * trunk
+ * brasero
  * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
  * 
- * trunk is free software.
+ * brasero is free software.
  * 
  * You may redistribute it and/or modify it under the terms of the
  * GNU General Public License, as published by the Free Software
  * Foundation; either version 2 of the License, or (at your option)
  * any later version.
  * 
- * trunk is distributed in the hope that it will be useful,
+ * 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 trunk.  If not, write to:
+ * along with brasero.  If not, write to:
  * 	The Free Software Foundation, Inc.,
  * 	51 Franklin Street, Fifth Floor
  * 	Boston, MA  02110-1301, USA.
@@ -41,6 +41,7 @@
 #endif
 
 #include "burn-basics.h"
+#include "burn-debug.h"
 #include "brasero-utils.h"
 
 #include "brasero-io.h"
@@ -579,13 +580,26 @@
 };
 typedef struct _BraseroIOMetadataTask BraseroIOMetadataTask;
 
+struct _BraseroIOMetadataCached {
+	guint64 last_modified;
+	BraseroMetadataInfo *info;
+};
+typedef struct _BraseroIOMetadataCached BraseroIOMetadataCached;
+
 static gint
 brasero_io_metadata_lookup_buffer (gconstpointer a, gconstpointer b)
 {
-	const BraseroMetadataInfo *metadata = a;
+	const BraseroIOMetadataCached *cached = a;
 	const gchar *uri = b;
 
-	return strcmp (uri, metadata->uri);
+	return strcmp (uri, cached->info->uri);
+}
+
+static void
+brasero_io_metadata_cached_free (BraseroIOMetadataCached *cached)
+{
+	brasero_metadata_info_free (cached->info);
+	g_free (cached);
 }
 
 static void
@@ -645,29 +659,37 @@
 	||  !strcmp (mime, "application/octet-stream")))
 		return FALSE;
 
-	/* seek in the buffer if we have already explored these metadata */
+	/* Seek in the buffer if we have already explored these metadata. Check 
+	 * the info last modified time in case a result should be updated. */
 	node = g_queue_find_custom (priv->meta_buffer,
 				    uri,
 				    brasero_io_metadata_lookup_buffer);
 	if (node) {
-		if (flags & BRASERO_METADATA_FLAG_SNAPHOT) {
-			BraseroMetadataInfo *saved;
+		guint64 last_modified;
+		BraseroIOMetadataCached *cached;
 
-			saved = node->data;
-			if (saved->snapshot) {
-				brasero_metadata_info_copy (meta_info, node->data);
+		cached = node->data;
+		last_modified = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+		if (last_modified == cached->last_modified) {
+			if (flags & BRASERO_METADATA_FLAG_SNAPHOT) {
+				/* If there isn't any snapshot retry */
+				if (cached->info->snapshot) {
+					brasero_metadata_info_copy (meta_info, cached->info);
+					return TRUE;
+				}
+			}
+			else {
+				brasero_metadata_info_copy (meta_info, cached->info);
 				return TRUE;
 			}
-
-			/* remove it from the queue since we can't keep the same
-			 * URI twice */
-			g_queue_remove (priv->meta_buffer, saved);
-			brasero_metadata_info_free (saved);
-		}
-		else {
-			brasero_metadata_info_copy (meta_info, node->data);
-			return TRUE;
 		}
+
+		/* remove it from the queue since we can't keep the same
+		 * URI twice */
+		brasero_metadata_info_free (node->data);
+		g_queue_remove (priv->meta_buffer, node->data);
+
+		BRASERO_BURN_LOG ("Updating cache information for %s", uri);
 	}
 
 	/* grab an available metadata (NOTE: there should always be at least one
@@ -693,15 +715,18 @@
 	if (result) {
 		/* see if we should add it to the buffer */
 		if (meta_info->has_audio || meta_info->has_video) {
-			BraseroMetadataInfo *copy;
+			BraseroIOMetadataCached *cached;
 
-			copy = g_new0 (BraseroMetadataInfo, 1);
-			brasero_metadata_set_info (metadata, copy);
+			cached = g_new0 (BraseroIOMetadataCached, 1);
+			cached->last_modified = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
 
-			g_queue_push_head (priv->meta_buffer, copy);
+			cached->info = g_new0 (BraseroMetadataInfo, 1);
+			brasero_metadata_set_info (metadata, cached->info);
+
+			g_queue_push_head (priv->meta_buffer, cached);
 			if (g_queue_get_length (priv->meta_buffer) > MAX_BUFFERED_META) {
-				meta_info = g_queue_pop_tail (priv->meta_buffer);
-				brasero_metadata_info_free (meta_info);
+				cached = g_queue_pop_tail (priv->meta_buffer);
+				brasero_io_metadata_cached_free (cached);
 			}
 		}
 	}
@@ -717,85 +742,61 @@
  * Used to get information about files
  */
 
-static BraseroAsyncTaskResult
-brasero_io_get_file_info_thread (BraseroAsyncTaskManager *manager,
-				 GCancellable *cancel,
-				 gpointer callback_data)
+static GFileInfo *
+brasero_io_get_file_info_thread_real (BraseroAsyncTaskManager *manager,
+				      GCancellable *cancel,
+				      const gchar *uri,
+				      BraseroIOFlags options,
+				      GError **error)
 {
 	gchar attributes [256] = {G_FILE_ATTRIBUTE_STANDARD_NAME ","
 				  G_FILE_ATTRIBUTE_STANDARD_SIZE ","
 				  G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
 				  G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
 				  G_FILE_ATTRIBUTE_STANDARD_TYPE};
-	BraseroIOJob *job = callback_data;
-	gchar *file_uri = NULL;
-	GError *error = NULL;
 	GFileInfo *info;
 	GFile *file;
 
-	if (job->options & BRASERO_IO_INFO_CHECK_PARENT_SYMLINK) {
-		/* If we want to make sure a directory is not added twice we have to make sure
-		 * that it doesn't have a symlink as parent otherwise "/home/Foo/Bar" with Foo
-		 * as a symlink pointing to /tmp would be seen as a different file from /tmp/Bar 
-		 * It would be much better if we could use the inode numbers provided by gnome_vfs
-		 * unfortunately they are guint64 and can't be used in hash tables as keys.
-		 * Therefore we check parents up to root to see if there are symlinks and if so
-		 * we get a path without symlinks in it. This is done only for local file */
-		file_uri = brasero_io_check_for_parent_symlink (job->uri, cancel);
-	}
-
-	if (g_cancellable_is_cancelled (cancel)) {
-		g_free (file_uri);
+	if (g_cancellable_is_cancelled (cancel))
 		return BRASERO_ASYNC_TASK_FINISHED;
-	}
 	
-	if (job->options & BRASERO_IO_INFO_PERM)
+	if (options & BRASERO_IO_INFO_PERM)
 		strcat (attributes, "," G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
-	if (job->options & BRASERO_IO_INFO_MIME)
+	if (options & BRASERO_IO_INFO_MIME)
 		strcat (attributes, "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
-	if (job->options & BRASERO_IO_INFO_ICON)
+	if (options & BRASERO_IO_INFO_ICON)
 		strcat (attributes, "," G_FILE_ATTRIBUTE_STANDARD_ICON);
 
-	file = g_file_new_for_uri (file_uri?file_uri:job->uri);
+	/* if retrieving metadata we need this one to check if a possible result
+	 * in cache should be updated or used */
+	if (options & BRASERO_IO_INFO_METADATA)
+		strcat (attributes, "," G_FILE_ATTRIBUTE_STANDARD_SIZE);
+
+	file = g_file_new_for_uri (uri);
 	info = g_file_query_info (file,
 				  attributes,
 				  G_FILE_QUERY_INFO_NONE,	/* follow symlinks */
 				  cancel,
-				  &error);
-	if (error) {
-		brasero_io_return_result (BRASERO_IO (manager),
-					  job->base,
-					  file_uri?file_uri:job->uri,
-					  NULL,
-					  error,
-					  job->callback_data);
-		g_free (file_uri);
+				  error);
+	if (!info) {
 		g_object_unref (file);
-		return BRASERO_ASYNC_TASK_FINISHED;
+		return NULL;
 	}
 
 	if (g_file_info_get_is_symlink (info)) {
 		GFile *parent;
 
 		parent = g_file_get_parent (file);
-		if (!brasero_io_check_symlink_target (parent, info, file_uri?file_uri:job->uri)) {
-			error = g_error_new (BRASERO_ERROR,
-					     BRASERO_ERROR_SYMLINK_LOOP,
-					     _("recursive symbolic link"));
+		if (!brasero_io_check_symlink_target (parent, info, uri)) {
+			g_set_error (error,
+				     BRASERO_ERROR,
+				     BRASERO_ERROR_SYMLINK_LOOP,
+				     _("recursive symbolic link"));
 
-			/* since we checked for the existence of the file
-			 * an error means a looping symbolic link */
-			brasero_io_return_result (BRASERO_IO (manager),
-						  job->base,
-						  file_uri?file_uri:job->uri,
-						  NULL,
-						  error,
-						  job->callback_data);
-			g_free (file_uri);
 			g_object_unref (info);
 			g_object_unref (file);
 			g_object_unref (parent);
-			return BRASERO_ASYNC_TASK_FINISHED;
+			return NULL;
 		}
 		g_object_unref (parent);
 	}
@@ -804,16 +805,16 @@
 	/* see if we are supposed to get metadata for this file (provided it's
 	 * an audio file of course). */
 	if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY
-	&&  job->options & BRASERO_IO_INFO_METADATA) {
+	&&  options & BRASERO_IO_INFO_METADATA) {
 		BraseroMetadataInfo metadata = { NULL };
 		gboolean result;
 
 		result = brasero_io_get_metadata_info (BRASERO_IO (manager),
 						       cancel,
-						       file_uri?file_uri:job->uri,
+						       uri,
 						       info,
-						       ((job->options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
-						       ((job->options & BRASERO_IO_INFO_METADATA_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0),
+						       ((options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
+						       ((options & BRASERO_IO_INFO_METADATA_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0),
 						       &metadata);
 
 		if (result)
@@ -822,13 +823,47 @@
 		brasero_metadata_info_clear (&metadata);
 	}
 
+	return info;
+}
+
+static BraseroAsyncTaskResult
+brasero_io_get_file_info_thread (BraseroAsyncTaskManager *manager,
+				 GCancellable *cancel,
+				 gpointer callback_data)
+{
+	BraseroIOJob *job = callback_data;
+	gchar *file_uri = NULL;
+	GError *error = NULL;
+	GFileInfo *info;
+
+	if (job->options & BRASERO_IO_INFO_CHECK_PARENT_SYMLINK) {
+		/* If we want to make sure a directory is not added twice we have to make sure
+		 * that it doesn't have a symlink as parent otherwise "/home/Foo/Bar" with Foo
+		 * as a symlink pointing to /tmp would be seen as a different file from /tmp/Bar 
+		 * It would be much better if we could use the inode numbers provided by gnome_vfs
+		 * unfortunately they are guint64 and can't be used in hash tables as keys.
+		 * Therefore we check parents up to root to see if there are symlinks and if so
+		 * we get a path without symlinks in it. This is done only for local file */
+		file_uri = brasero_io_check_for_parent_symlink (job->uri, cancel);
+	}
+
+	if (g_cancellable_is_cancelled (cancel)) {
+		g_free (file_uri);
+		return BRASERO_ASYNC_TASK_FINISHED;
+	}
+
+	info = brasero_io_get_file_info_thread_real (manager,
+						     cancel,
+						     file_uri?file_uri:job->uri,
+						     job->options,
+						     &error);
+
 	brasero_io_return_result (BRASERO_IO (manager),
 				  job->base,
 				  file_uri?file_uri:job->uri,
 				  info,
-				  NULL,
+				  error,
 				  job->callback_data);
-	g_free (file_uri);
 
 	return BRASERO_ASYNC_TASK_FINISHED;
 }
@@ -906,9 +941,13 @@
 
 static void
 brasero_io_start_end_playlist_cb (TotemPlParser *parser,
-				  const gchar *title,
+				  const gchar *uri,
+				  GHashTable *metadata,
 				  BraseroIOPlaylist *data)
 {
+	const gchar *title;
+
+	title = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_TITLE);
 	if (!title)
 		return;
 
@@ -926,11 +965,11 @@
 
 	parser = totem_pl_parser_new ();
 	g_signal_connect (parser,
-			  "playlist-start",
+			  "playlist-started",
 			  G_CALLBACK (brasero_io_start_end_playlist_cb),
 			  playlist);
 	g_signal_connect (parser,
-			  "playlist-end",
+			  "playlist-ended",
 			  G_CALLBACK (brasero_io_start_end_playlist_cb),
 			  playlist);
 	g_signal_connect (parser,
@@ -976,7 +1015,6 @@
 					  NULL,
 					  error,
 					  job->callback_data);
-
 		return BRASERO_ASYNC_TASK_FINISHED;
 	}
 
@@ -985,7 +1023,17 @@
 
 	/* that's finished; Send the title */
 	info = g_file_info_new ();
-	g_file_info_set_attribute_string (info, BRASERO_IO_PLAYLIST_TITLE, data.title ? data.title:_("No title"));
+	g_file_info_set_attribute_boolean (info,
+					   BRASERO_IO_IS_PLAYLIST,
+					   TRUE);
+	g_file_info_set_attribute_uint32 (info,
+					  BRASERO_IO_PLAYLIST_ENTRIES_NUM,
+					  g_slist_length (data.uris));
+	if (data.title)
+		g_file_info_set_attribute_string (info,
+						  BRASERO_IO_PLAYLIST_TITLE,
+						  data.title);
+
 	brasero_io_return_result (BRASERO_IO (manager),
 				  job->base,
 				  job->uri,
@@ -993,16 +1041,32 @@
 				  NULL,
 				  job->callback_data);
 
-	/* Now get information about each file in the list */
+	/* Now get information about each file in the list. 
+	 * Reverse order of list to get a correct order for entries. */
+	data.uris = g_slist_reverse (data.uris);
 	for (iter = data.uris; iter; iter = iter->next) {
 		gchar *child;
+		GFileInfo *child_info;
 
 		child = iter->data;
-		brasero_io_new_file_info_job (BRASERO_IO (manager),
-					      child,
-					      job->base,
-					      job->options,
-					      job->callback_data);
+		if (g_cancellable_is_cancelled (cancel))
+			break;
+
+		child_info = brasero_io_get_file_info_thread_real (manager,
+								   cancel,
+								   child,
+								   job->options,
+								   NULL);
+
+		if (!child_info)
+			continue;
+
+		brasero_io_return_result (BRASERO_IO (manager),
+					  job->base,
+					  child,
+					  child_info,
+					  NULL,
+					  job->callback_data);
 	}
 
 	brasero_io_playlist_clear (&data);
@@ -1543,6 +1607,9 @@
 		}
 
 		child = g_file_get_child (file, name);
+		if (!child)
+			continue;
+
 		child_uri = g_file_get_uri (child);
 
 		/* special case for symlinks */
@@ -2266,10 +2333,10 @@
 	priv->metadatas = NULL;
 
 	if (priv->meta_buffer) {
-		BraseroMetadataInfo *metadata;
+		BraseroIOMetadataCached *cached;
 
-		while ((metadata = g_queue_pop_head (priv->meta_buffer)) != NULL)
-			brasero_metadata_info_free (metadata);
+		while ((cached = g_queue_pop_head (priv->meta_buffer)) != NULL)
+			brasero_io_metadata_cached_free (cached);
 
 		g_queue_free (priv->meta_buffer);
 		priv->meta_buffer = NULL;

Modified: branches/video/src/brasero-metadata.h
==============================================================================
--- branches/video/src/brasero-metadata.h	(original)
+++ branches/video/src/brasero-metadata.h	Sat Jul 12 11:43:40 2008
@@ -71,9 +71,9 @@
 
 	GdkPixbuf *snapshot;
 
-	gboolean is_seekable;
-	gboolean has_audio;
-	gboolean has_video;
+	guint is_seekable:1;
+	guint has_audio:1;
+	guint has_video:1;
 } BraseroMetadataInfo;
 
 void

Modified: branches/video/src/burn-caps.c
==============================================================================
--- branches/video/src/burn-caps.c	(original)
+++ branches/video/src/burn-caps.c	Sat Jul 12 11:43:40 2008
@@ -90,6 +90,13 @@
 	return NULL;								\
 }
 
+#define BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES(session)			\
+{										\
+	brasero_burn_session_log (session, "Unsupported type of task operation"); \
+	BRASERO_BURN_LOG ("Unsupported type of task operation");		\
+	return BRASERO_BURN_NOT_SUPPORTED;					\
+}
+
 #define BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_ERROR(session, error)		\
 {										\
 	if (error)								\
@@ -1188,6 +1195,24 @@
 	return retval;
 }
 
+static gboolean
+brasero_burn_caps_flags_check_for_drive (BraseroBurnSession *session)
+{
+	BraseroDrive *drive;
+	BraseroBurnFlag flags;
+
+	drive = brasero_burn_session_get_burner (session);
+	if (!drive)
+		return TRUE;
+
+	flags = brasero_burn_session_get_flags (session);
+	if (!brasero_drive_has_safe_burn (drive)
+	&&  !(flags & BRASERO_BURN_FLAG_BURNPROOF))
+		return FALSE;
+
+	return TRUE;
+}
+
 GSList *
 brasero_burn_caps_new_task (BraseroBurnCaps *self,
 			    BraseroBurnSession *session,
@@ -1241,6 +1266,9 @@
 				    "Input set =");
 
 	session_flags = brasero_burn_session_get_flags (session);
+	if (!brasero_burn_caps_flags_check_for_drive (session))
+		BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG (session);
+
 	list = brasero_caps_find_best_link (last_caps,
 					    self->priv->group_id,
 					    NULL,
@@ -1835,6 +1863,9 @@
 	BraseroTrackType output;
 	BraseroPluginIOFlag io_flags;
 
+	if (!brasero_burn_caps_flags_check_for_drive (session))
+		BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
+
 	if (!brasero_burn_session_is_dest_file (session)) {
 		output.type = BRASERO_TRACK_TYPE_DISC;
 		output.subtype.media = brasero_burn_session_get_dest_media (session);
@@ -1879,6 +1910,9 @@
 	BraseroTrackType input;
 	BraseroPluginIOFlag io_flags;
 
+	if (!brasero_burn_caps_flags_check_for_drive (session))
+		BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
+
 	/* Here flags don't matter as we don't record anything.
 	 * Even the IOFlags since that can be checked later with
 	 * brasero_burn_caps_get_flags.
@@ -1996,6 +2030,9 @@
 	if (brasero_burn_session_same_src_dest_drive (session))
 		return brasero_burn_caps_is_session_supported_same_src_dest (self, session);
 
+	if (!brasero_burn_caps_flags_check_for_drive (session))
+		BRASERO_BURN_CAPS_NOT_SUPPORTED_LOG_RES (session);
+
 	/* Here flags don't matter as we don't record anything.
 	 * Even the IOFlags since that can be checked later with
 	 * brasero_burn_caps_get_flags. */
@@ -2212,6 +2249,22 @@
 	return retval;
 }
 
+static BraseroBurnFlag
+brasero_burn_caps_flags_update_for_drive (BraseroBurnFlag flags,
+					  BraseroBurnSession *session)
+{
+	BraseroDrive *drive;
+
+	drive = brasero_burn_session_get_burner (session);
+	if (!drive)
+		return flags;
+
+	if (!brasero_drive_has_safe_burn (drive))
+		flags &= ~BRASERO_BURN_FLAG_BURNPROOF;
+
+	return flags;
+}
+
 static BraseroBurnResult
 brasero_caps_get_flags_for_disc (BraseroBurnFlag session_flags,
 				 BraseroMedia media,
@@ -2314,6 +2367,11 @@
 	session_flags = brasero_burn_session_get_flags (session);
 	BRASERO_BURN_LOG_FLAGS (session_flags, "FLAGS (session):");
 
+	if (!brasero_burn_caps_flags_check_for_drive (session)) {
+		BRASERO_BURN_LOG ("Session flags not supported");
+		return BRASERO_BURN_ERR;
+	}
+
 	/* sanity check:
 	 * - MERGE and BLANK are not possible together.
 	 *   MERGE wins (always)
@@ -2475,6 +2533,8 @@
 		compulsory_flags |= blank_compulsory;
 	}
 
+	supported_flags = brasero_burn_caps_flags_update_for_drive (supported_flags, session);
+
 	if (supported)
 		*supported = supported_flags;
 
@@ -3076,6 +3136,9 @@
 			/* This is only for above types */
 			retval = brasero_caps_disc_lookup_or_create (retval,
 								     media|
+								     BRASERO_MEDIUM_BLANK);
+			retval = brasero_caps_disc_lookup_or_create (retval,
+								     media|
 								     BRASERO_MEDIUM_BLANK|
 								     (type & BRASERO_MEDIUM_UNFORMATTED));
 		}

Modified: branches/video/src/burn-drive.c
==============================================================================
--- branches/video/src/burn-drive.c	(original)
+++ branches/video/src/burn-drive.c	Sat Jul 12 11:43:40 2008
@@ -43,6 +43,14 @@
 
 #include "scsi-mmc1.h"
 
+#if defined(HAVE_STRUCT_USCSI_CMD)
+#define DEVICE_MODEL	"info.product"
+#define BLOCK_DEVICE	"block.solaris.raw_device"
+#else
+#define DEVICE_MODEL	"storage.model"
+#define BLOCK_DEVICE	"block.device"
+#endif
+
 typedef struct _BraseroDrivePrivate BraseroDrivePrivate;
 struct _BraseroDrivePrivate
 {
@@ -269,7 +277,7 @@
 	ctx = brasero_drive_get_hal_context ();
 	return libhal_device_get_property_string (ctx,
 						  priv->udi,
-						  "storage.model",
+	  					  DEVICE_MODEL,
 						  NULL);
 }
 
@@ -408,7 +416,7 @@
 
 	ctx = brasero_drive_get_hal_context ();
 
-	priv->path = libhal_device_get_property_string (ctx, priv->udi, "block.device", NULL);
+	priv->path = libhal_device_get_property_string (ctx, priv->udi, BLOCK_DEVICE, NULL);
 	if (priv->path [0] == '\0') {
 		g_free (priv->path);
 		priv->path = NULL;

Modified: branches/video/src/burn-job.c
==============================================================================
--- branches/video/src/burn-job.c	(original)
+++ branches/video/src/burn-job.c	Sat Jul 12 11:43:40 2008
@@ -1661,8 +1661,10 @@
 	if (priv->next)
 		return BRASERO_BURN_ERR;
 
-	if (progress < 0.0 || progress > 1.0)
+	if (progress < 0.0 || progress > 1.0) {
+		BRASERO_JOB_LOG (self, "Tried to set an insane progress value (%lf)", progress);
 		return BRASERO_BURN_ERR;
+	}
 
 	return brasero_task_ctx_set_progress (priv->ctx, progress);
 }
@@ -1802,7 +1804,8 @@
 	BRASERO_JOB_DEBUG (self);
 
 	priv = BRASERO_JOB_PRIVATE (self);
-	brasero_task_ctx_set_dangerous (priv->ctx, value);
+	if (priv->ctx)
+		brasero_task_ctx_set_dangerous (priv->ctx, value);
 }
 
 /**

Modified: branches/video/src/burn-medium.c
==============================================================================
--- branches/video/src/burn-medium.c	(original)
+++ branches/video/src/burn-medium.c	Sat Jul 12 11:43:40 2008
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 /*
  * brasero
- * Copyright (C) Philippe Rouquier 2007 <bonfire-app wanadoo fr>
+ * Copyright (C) Philippe Rouquier 2007-2008 <bonfire-app wanadoo fr>
  * 
  * brasero is free software.
  * 
@@ -141,6 +141,9 @@
 {
 	BraseroMediumPrivate *priv;
 
+	if (!medium)
+		return NULL;
+
 	priv = BRASERO_MEDIUM_PRIVATE (medium);
 	return priv->icon;
 }
@@ -871,426 +874,151 @@
 	return BRASERO_BURN_OK;
 }
 
+/**
+ * Functions to get information about disc contents
+ */
+
 static BraseroBurnResult
-brasero_medium_get_medium_type (BraseroMedium *self,
-				BraseroDeviceHandle *handle,
-				BraseroScsiErrCode *code)
+brasero_medium_track_volume_size (BraseroMedium *self,
+				  BraseroMediumTrack *track,
+				  BraseroDeviceHandle *handle)
 {
-	BraseroScsiGetConfigHdr *hdr = NULL;
 	BraseroMediumPrivate *priv;
-	BraseroScsiResult result;
-	int size;
+	BraseroBurnResult res;
+	GError *error = NULL;
+	BraseroVolSrc *vol;
+	gint64 nb_blocks;
 
-	BRASERO_BURN_LOG ("Retrieving media profile");
+	if (!track)
+		return BRASERO_BURN_ERR;
 
 	priv = BRASERO_MEDIUM_PRIVATE (self);
-	result = brasero_mmc2_get_configuration_feature (handle,
-							 BRASERO_SCSI_FEAT_REAL_TIME_STREAM,
-							 &hdr,
-							 &size,
-							 code);
-	if (result != BRASERO_SCSI_OK) {
-		BraseroScsiAtipData *data = NULL;
-		int size = 0;
 
-		BRASERO_BURN_LOG ("GET CONFIGURATION failed");
+	/* This is a special case. For DVD+RW and DVD-RW in restricted
+	 * mode, there is only one session that takes the whole disc size
+	 * once formatted. That doesn't necessarily means they have data
+	 * Note also that they are reported as complete though you can
+	 * still add data (with growisofs). It is nevertheless on the 
+	 * condition that the fs is valid.
+	 * So we check if their first and only volume is valid. 
+	 * That's also used when the track size is reported a 300 Kio
+	 * see below */
+	vol = brasero_volume_source_open_device_handle (handle, NULL);
+	res = brasero_volume_get_size (vol,
+				       track->start,
+				       &nb_blocks,
+				       NULL);
+	brasero_volume_source_close (vol);
 
-		/* This could be a MMC1 drive since this command was
-		 * introduced in MMC2 and is supported onward. So it
-		 * has to be a CD (R/RW). The rest of the information
-		 * will be provided by read_disc_information. */
+	if (!res) {
+		BRASERO_BURN_LOG ("Failed to retrieve the volume size: %s",
+				  error && error->message ? 
+				  error->message:"unknown error");
 
-		/* The only thing here left to determine is if that's a WRITABLE
-		 * or a REWRITABLE. To determine that information, we need to
-		 * read TocPmaAtip. It if fails that's a ROM, if it succeeds.
-		 * No need to set error code since we consider that it's a ROM
-		 * if a failure happens. */
-		result = brasero_mmc1_read_atip (handle,
-						 &data,
-						 &size,
-						 NULL);
-		if (result != BRASERO_SCSI_OK) {
-			/* CDROM */
-			priv->info = BRASERO_MEDIUM_CDROM;
-			priv->type = types [1];
-			priv->icon = icons [1];
-		}
-		else {
-			/* check the size of the structure: it must be at least 8 bytes long */
-			if (size < 8) {
-				if (size)
-					g_free (data);
+		if (error)
+			g_error_free (error);
+		return BRASERO_BURN_ERR;
+	}
 
-				BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
-				return BRASERO_BURN_ERR;
-			}
+	track->blocks_num = nb_blocks;
+	return BRASERO_BURN_OK;
+}
 
-			if (data->desc->erasable) {
-				/* CDRW */
-				priv->info = BRASERO_MEDIUM_CDRW;
-				priv->type = types [3];
-				priv->icon = icons [3];
-			}
-			else {
-				/* CDR */
-				priv->info = BRASERO_MEDIUM_CDR;
-				priv->type = types [2];
-				priv->icon = icons [2];
-			}
+static gboolean
+brasero_medium_track_written_SAO (BraseroDeviceHandle *handle,
+				  int track_num,
+				  int track_start)
+{
+	unsigned char buffer [2048];
+	BraseroScsiResult result;
 
-			g_free (data);
-		}
+	BRASERO_BURN_LOG ("Checking for TDBs in track pregap.");
 
-		/* retrieve the speed */
-		result = brasero_medium_get_page_2A_max_speed (self,
-							       handle,
-							       code);
-		return result;
-	}
+	/* The two following sectors are readable */
+	result = brasero_mmc1_read_block (handle,
+					  TRUE,
+					  BRASERO_SCSI_BLOCK_TYPE_ANY,
+					  BRASERO_SCSI_BLOCK_HEADER_NONE,
+					  BRASERO_SCSI_BLOCK_NO_SUBCHANNEL,
+					  track_start - 1,
+					  1,
+					  buffer,
+					  sizeof (buffer),
+					  NULL);
 
-	switch (BRASERO_GET_16 (hdr->current_profile)) {
-	case BRASERO_SCSI_PROF_CDROM:
-		priv->info = BRASERO_MEDIUM_CDROM;
-		priv->type = types [1];
-		priv->icon = icons [1];
-		break;
+	if (result == BRASERO_SCSI_OK) {
+		int i;
 
-	case BRASERO_SCSI_PROF_CDR:
-		priv->info = BRASERO_MEDIUM_CDR;
-		priv->type = types [2];
-		priv->icon = icons [2];
-		break;
+		if (buffer [0] != 'T' || buffer [1] != 'D' || buffer [2] != 'I') {
+			BRASERO_BURN_LOG ("Track was probably recorded in SAO mode - no TDB.");
+			return TRUE;
+		}
 
-	case BRASERO_SCSI_PROF_CDRW:
-		priv->info = BRASERO_MEDIUM_CDRW;
-		priv->type = types [3];
-		priv->icon = icons [3];
-		break;
+		/* Find the TDU (16 bytes) for the track (there can be for other tracks).
+		 * i must be < 128 = ((2048 - 8 (size TDB)) / 16 (size TDU). */
+		for (i = 0; i < 128; i ++) {
+			if (BRASERO_GET_BCD (buffer [8 + i * 16]) != track_num)
+				break;
+		}
 
-	case BRASERO_SCSI_PROF_DVD_ROM:
-		priv->info = BRASERO_MEDIUM_DVD_ROM;
-		priv->type = types [4];
-		priv->icon = icons [4];
-		break;
+		if (i >= 128) {
+			BRASERO_BURN_LOG ("No appropriate TDU for track");
+			return TRUE;
+		}
 
-	case BRASERO_SCSI_PROF_DVD_R:
-		priv->info = BRASERO_MEDIUM_DVDR;
-		priv->type = types [5];
-		priv->icon = icons [5];
-		break;
+		if (buffer [8 + i * 16] == 0x80 || buffer [8 + i * 16] == 0x00) {
+			BRASERO_BURN_LOG ("Track was recorded in TAO mode.");
+			return FALSE;
+		}
 
-	case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
-		priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
-		priv->type = types [6];
-		priv->icon = icons [6];
-		break;
+		BRASERO_BURN_LOG ("Track was recorded in Packet mode.");
+		return FALSE;
+	}
 
-	case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
-		priv->info = BRASERO_MEDIUM_DVDRW;
-		priv->type = types [6];
-		priv->icon = icons [6];
-		break;
+	BRASERO_BURN_LOG ("No pregap. That track must have been recorded in SAO mode.");
+	return TRUE;
+}
 
-	case BRASERO_SCSI_PROF_DVD_R_PLUS:
-		priv->info = BRASERO_MEDIUM_DVDR_PLUS;
-		priv->type = types [7];
-		priv->icon = icons [7];
-		break;
+static BraseroBurnResult
+brasero_medium_track_get_info (BraseroMedium *self,
+			       gboolean multisession,
+			       BraseroMediumTrack *track,
+			       int track_num,
+			       BraseroDeviceHandle *handle,
+			       BraseroScsiErrCode *code)
+{
+	BraseroScsiTrackInfo track_info;
+	BraseroMediumPrivate *priv;
+	BraseroScsiResult result;
+	int size;
 
-	case BRASERO_SCSI_PROF_DVD_RW_PLUS:
-		priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
-		priv->type = types [8];
-		priv->icon = icons [7];
-		break;
+	BRASERO_BURN_LOG ("Retrieving track information for %i", track_num);
 
-	case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
-		priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
-		priv->type = types [9];
-		priv->icon = icons [7];
-		break;
+	priv = BRASERO_MEDIUM_PRIVATE (self);
 
-	case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
-		priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
-		priv->type = types [10];
-		priv->icon = icons [7];
-		break;
+	/* at this point we know the type of the disc that's why we set the 
+	 * size according to this type. That may help to avoid outrange address
+	 * errors. */
+	if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVD_DL|BRASERO_MEDIUM_WRITABLE))
+		size = 48;
+	else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_PLUS|BRASERO_MEDIUM_WRITABLE))
+		size = 40;
+	else
+		size = 36;
 
-	case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
-		priv->info = BRASERO_MEDIUM_DVDR_DL;
-		priv->type = types [11];
-		priv->icon = icons [5];
-		break;
+	result = brasero_mmc1_read_track_info (handle,
+					       track_num,
+					       &track_info,
+					       &size,
+					       code);
 
-	case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
-		priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
-		priv->type = types [11];
-		priv->icon = icons [5];
-		break;
+	if (result != BRASERO_SCSI_OK) {
+		BRASERO_BURN_LOG ("READ TRACK INFO failed");
+		return BRASERO_BURN_ERR;
+	}
 
-	/* WARNING: these types are recognized, no more */
-	case BRASERO_SCSI_PROF_BD_ROM:
-		priv->info = BRASERO_MEDIUM_BD_ROM;
-		priv->type = types [13];
-		priv->icon = icons [4];
-		break;
-
-	case BRASERO_SCSI_PROF_BR_R_SEQUENTIAL:
-		priv->info = BRASERO_MEDIUM_BDR_SRM;
-		priv->type = types [14];
-		priv->icon = icons [5];
-		break;
-
-	case BRASERO_SCSI_PROF_BR_R_RANDOM:
-		priv->info = BRASERO_MEDIUM_BDR_RANDOM;
-		priv->type = types [14];
-		priv->icon = icons [5];
-		break;
-
-	case BRASERO_SCSI_PROF_BD_RW:
-		priv->info = BRASERO_MEDIUM_BDRW;
-		priv->type = types [15];
-		priv->icon = icons [6];
-		break;
-
-	case BRASERO_SCSI_PROF_DVD_RAM:
-		priv->info = BRASERO_MEDIUM_DVD_RAM;
-		priv->type = types [12];
-		priv->icon = icons [8];
-		break;
-	
-	case BRASERO_SCSI_PROF_NON_REMOVABLE:
-	case BRASERO_SCSI_PROF_REMOVABLE:
-	case BRASERO_SCSI_PROF_MO_ERASABLE:
-	case BRASERO_SCSI_PROF_MO_WRITE_ONCE:
-	case BRASERO_SCSI_PROF_MO_ADVANCED_STORAGE:
-	case BRASERO_SCSI_PROF_DDCD_ROM:
-	case BRASERO_SCSI_PROF_DDCD_R:
-	case BRASERO_SCSI_PROF_DDCD_RW:
-	case BRASERO_SCSI_PROF_HD_DVD_ROM:
-	case BRASERO_SCSI_PROF_HD_DVD_R:
-	case BRASERO_SCSI_PROF_HD_DVD_RAM:
-		priv->info = BRASERO_MEDIUM_UNSUPPORTED;
-		priv->icon = icons [0];
-		g_free (hdr);
-		return BRASERO_BURN_NOT_SUPPORTED;
-	}
-
-	/* try all SCSI functions to get write/read speeds in order */
-	if (hdr->desc->add_len >= sizeof (BraseroScsiRTStreamDesc)) {
-		BraseroScsiRTStreamDesc *stream;
-
-		/* means it's at least an MMC3 drive */
-		stream = (BraseroScsiRTStreamDesc *) hdr->desc->data;
-		if (stream->wrt_spd) {
-			result = brasero_medium_get_speed_mmc3 (self, handle, code);
-			if (result == BRASERO_BURN_OK)
-				goto end;
-		}
-
-		if (stream->mp2a) {
-			result = brasero_medium_get_page_2A_write_speed_desc (self, handle, code);
-			if (result == BRASERO_BURN_OK)
-				goto end;
-		}
-	}
-
-	/* fallback for speeds */
-	result = brasero_medium_get_page_2A_max_speed (self, handle, code);
-
-end:
-
-	g_free (hdr);
-
-	if (result != BRASERO_BURN_OK)
-		return result;
-
-	return BRASERO_BURN_OK;
-}
-
-static BraseroBurnResult
-brasero_medium_get_css_feature (BraseroMedium *self,
-				BraseroDeviceHandle *handle,
-				BraseroScsiErrCode *code)
-{
-	BraseroScsiGetConfigHdr *hdr = NULL;
-	BraseroMediumPrivate *priv;
-	BraseroScsiResult result;
-	int size;
-
-	priv = BRASERO_MEDIUM_PRIVATE (self);
-
-	BRASERO_BURN_LOG ("Testing for Css encrypted media");
-	result = brasero_mmc2_get_configuration_feature (handle,
-							 BRASERO_SCSI_FEAT_DVD_CSS,
-							 &hdr,
-							 &size,
-							 code);
-	if (result != BRASERO_SCSI_OK) {
-		g_free (hdr);
-
-		BRASERO_BURN_LOG ("GET CONFIGURATION failed");
-		return BRASERO_BURN_ERR;
-	}
-
-	if (hdr->desc->add_len < sizeof (BraseroScsiDVDCssDesc)) {
-		g_free (hdr);
-		return BRASERO_BURN_OK;
-	}
-
-	/* here we just need to see if this feature is current or not */
-	if (hdr->desc->current) {
-		priv->info |= BRASERO_MEDIUM_PROTECTED;
-		BRASERO_BURN_LOG ("media is Css protected");
-	}
-
-	g_free (hdr);
-	return BRASERO_BURN_OK;
-}
-
-/**
- * Functions to get information about disc contents
- */
-
-static BraseroBurnResult
-brasero_medium_track_volume_size (BraseroMedium *self,
-				  BraseroMediumTrack *track,
-				  BraseroDeviceHandle *handle)
-{
-	BraseroMediumPrivate *priv;
-	BraseroBurnResult res;
-	GError *error = NULL;
-	BraseroVolSrc *vol;
-	gint64 nb_blocks;
-
-	if (!track)
-		return BRASERO_BURN_ERR;
-
-	priv = BRASERO_MEDIUM_PRIVATE (self);
-
-	/* This is a special case. For DVD+RW and DVD-RW in restricted
-	 * mode, there is only one session that takes the whole disc size
-	 * once formatted. That doesn't necessarily means they have data
-	 * Note also that they are reported as complete though you can
-	 * still add data (with growisofs). It is nevertheless on the 
-	 * condition that the fs is valid.
-	 * So we check if their first and only volume is valid. 
-	 * That's also used when the track size is reported a 300 Kio
-	 * see below */
-	vol = brasero_volume_source_open_device_handle (handle, NULL);
-	res = brasero_volume_get_size (vol,
-				       track->start,
-				       &nb_blocks,
-				       NULL);
-	brasero_volume_source_close (vol);
-	if (!res) {
-		BRASERO_BURN_LOG ("Failed to retrieve the volume size: %s",
-				  error && error->message ? 
-				  error->message:"unknown error");
-
-		if (error)
-			g_error_free (error);
-		return BRASERO_BURN_ERR;
-	}
-
-	track->blocks_num = nb_blocks;
-	return BRASERO_BURN_OK;
-}
-
-static gboolean
-brasero_medium_track_written_SAO (BraseroDeviceHandle *handle,
-				  int track_num,
-				  int track_start)
-{
-	unsigned char buffer [2048];
-	BraseroScsiResult result;
-
-	BRASERO_BURN_LOG ("Checking for TDBs in track pregap.");
-
-	/* The two following sectors are readable */
-	result = brasero_mmc1_read_block (handle,
-					  TRUE,
-					  BRASERO_SCSI_BLOCK_TYPE_ANY,
-					  BRASERO_SCSI_BLOCK_HEADER_NONE,
-					  BRASERO_SCSI_BLOCK_NO_SUBCHANNEL,
-					  track_start - 1,
-					  1,
-					  buffer,
-					  sizeof (buffer),
-					  NULL);
-
-	if (result == BRASERO_SCSI_OK) {
-		int i;
-
-		if (buffer [0] != 'T' || buffer [1] != 'D' || buffer [2] != 'I') {
-			BRASERO_BURN_LOG ("Track was probably recorded in SAO mode - no TDB.");
-			return TRUE;
-		}
-
-		/* Find the TDU (16 bytes) for the track (there can be for other tracks).
-		 * i must be < 128 = ((2048 - 8 (size TDB)) / 16 (size TDU). */
-		for (i = 0; i < 128; i ++) {
-			if (BRASERO_GET_BCD (buffer [8 + i * 16]) != track_num)
-				break;
-		}
-
-		if (i >= 128) {
-			BRASERO_BURN_LOG ("No appropriate TDU for track");
-			return TRUE;
-		}
-
-		if (buffer [8 + i * 16] == 0x80 || buffer [8 + i * 16] == 0x00) {
-			BRASERO_BURN_LOG ("Track was recorded in TAO mode.");
-			return FALSE;
-		}
-
-		BRASERO_BURN_LOG ("Track was recorded in Packet mode.");
-		return FALSE;
-	}
-
-	BRASERO_BURN_LOG ("No pregap. That track must have been recorded in SAO mode.");
-	return TRUE;
-}
-
-static BraseroBurnResult
-brasero_medium_track_get_info (BraseroMedium *self,
-			       gboolean multisession,
-			       BraseroMediumTrack *track,
-			       int track_num,
-			       BraseroDeviceHandle *handle,
-			       BraseroScsiErrCode *code)
-{
-	BraseroScsiTrackInfo track_info;
-	BraseroMediumPrivate *priv;
-	BraseroScsiResult result;
-	int size;
-
-	BRASERO_BURN_LOG ("Retrieving track information for %i", track_num);
-
-	priv = BRASERO_MEDIUM_PRIVATE (self);
-
-	/* at this point we know the type of the disc that's why we set the 
-	 * size according to this type. That may help to avoid outrange address
-	 * errors. */
-	if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVD_DL|BRASERO_MEDIUM_WRITABLE))
-		size = 48;
-	else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_PLUS|BRASERO_MEDIUM_WRITABLE))
-		size = 40;
-	else
-		size = 36;
-
-	result = brasero_mmc1_read_track_info (handle,
-					       track_num,
-					       &track_info,
-					       &size,
-					       code);
-
-	if (result != BRASERO_SCSI_OK) {
-		BRASERO_BURN_LOG ("READ TRACK INFO failed");
-		return BRASERO_BURN_ERR;
-	}
-
-	track->blocks_num = BRASERO_GET_32 (track_info.track_size);
-	track->session = BRASERO_SCSI_SESSION_NUM (track_info);
+	track->blocks_num = BRASERO_GET_32 (track_info.track_size);
+	track->session = BRASERO_SCSI_SESSION_NUM (track_info);
 
 	if (track->blocks_num <= 300) {
 		/* Now here is a potential bug: we can write tracks (data or
@@ -1359,37 +1087,294 @@
 		if (result == BRASERO_SCSI_OK) {
 			BRASERO_BURN_LOG ("Following two sectors are readable.");
 
-			if (brasero_medium_track_written_SAO (handle, track_num, track->start)) {
-				track->blocks_num += 2;
-				BRASERO_BURN_LOG ("Correcting track size (now %i)", track->blocks_num);
-			}
+			if (brasero_medium_track_written_SAO (handle, track_num, track->start)) {
+				track->blocks_num += 2;
+				BRASERO_BURN_LOG ("Correcting track size (now %i)", track->blocks_num);
+			}
+		}
+		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);
+
+	BRASERO_BURN_LOG ("Track %i (session %i): type = %i start = %llu size = %llu",
+			  track_num,
+			  track->session,
+			  track->type,
+			  track->start,
+			  track->blocks_num);
+
+	return BRASERO_BURN_OK;
+}
+
+/**
+ * NOTE: for DVD-R multisession we lose 28688 blocks for each session
+ * so the capacity is the addition of all session sizes + 28688 for each
+ * For all multisession DVD-/+R and CDR-RW the remaining size is given 
+ * in the leadout. One exception though with DVD+/-RW.
+ */
+
+static void
+brasero_medium_add_DVD_plus_RW_leadout (BraseroMedium *self,
+					gint32 start)
+{
+	BraseroMediumTrack *leadout;
+	BraseroMediumPrivate *priv;
+
+	priv = BRASERO_MEDIUM_PRIVATE (self);
+
+	leadout = g_new0 (BraseroMediumTrack, 1);
+	priv->tracks = g_slist_append (priv->tracks, leadout);
+
+	leadout->start = start;
+	leadout->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+
+	/* we fabricate the leadout here. We don't really need one in 
+	 * fact since it is always at the last sector whatever the
+	 * amount of data written. So we need in fact to read the file
+	 * system and get the last sector from it. Hopefully it won't be
+	 * buggy */
+	priv->next_wr_add = 0;
+
+	leadout->blocks_num = priv->block_num;
+	if (g_slist_length (priv->tracks) > 1) {
+		BraseroMediumTrack *track;
+
+		track = priv->tracks->data;
+		leadout->blocks_num -= ((track->blocks_num > 300) ? track->blocks_num : 300);
+	}
+	BRASERO_BURN_LOG ("Adding fabricated leadout start = %llu length = %llu",
+			  leadout->start,
+			  leadout->blocks_num);
+}
+
+static BraseroBurnResult
+brasero_medium_get_sessions_info (BraseroMedium *self,
+				  BraseroDeviceHandle *handle,
+				  BraseroScsiErrCode *code)
+{
+	int num, i, size;
+	gboolean multisession;
+	BraseroScsiResult result;
+	BraseroScsiTocDesc *desc;
+	BraseroMediumPrivate *priv;
+	BraseroScsiFormattedTocData *toc = NULL;
+
+	BRASERO_BURN_LOG ("Reading Toc");
+
+	priv = BRASERO_MEDIUM_PRIVATE (self);
+	result = brasero_mmc1_read_toc_formatted (handle,
+						  0,
+						  &toc,
+						  &size,
+						  code);
+	if (result != BRASERO_SCSI_OK) {
+		g_free (toc);
+
+		BRASERO_BURN_LOG ("READ TOC failed");
+		return BRASERO_BURN_ERR;
+	}
+
+	num = (size - sizeof (BraseroScsiFormattedTocData)) /
+	       sizeof (BraseroScsiTocDesc);
+
+	/* remove 1 for leadout */
+	multisession = (priv->info & BRASERO_MEDIUM_APPENDABLE) || (num -1) != 1;
+
+	BRASERO_BURN_LOG ("%i track(s) found", num);
+
+	desc = toc->desc;
+	for (i = 0; i < num; i ++, desc ++) {
+		BraseroMediumTrack *track;
+
+		if (desc->track_num == BRASERO_SCSI_TRACK_LEADOUT_START)
+			break;
+
+		track = g_new0 (BraseroMediumTrack, 1);
+		priv->tracks = g_slist_prepend (priv->tracks, track);
+		track->start = BRASERO_GET_32 (desc->track_start);
+
+		/* we shouldn't request info on a track if the disc is closed */
+		if (desc->control & BRASERO_SCSI_TRACK_COPY)
+			track->type |= BRASERO_MEDIUM_TRACK_COPY;
+
+		if (!(desc->control & BRASERO_SCSI_TRACK_DATA)) {
+			track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
+			priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
+
+			if (desc->control & BRASERO_SCSI_TRACK_PREEMP)
+				track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
+
+			if (desc->control & BRASERO_SCSI_TRACK_4_CHANNELS)
+				track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS;
+		}
+		else {
+			track->type |= BRASERO_MEDIUM_TRACK_DATA;
+			priv->info |= BRASERO_MEDIUM_HAS_DATA;
+
+			if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
+				track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
+		}
+
+		brasero_medium_track_get_info (self,
+					       multisession,
+					       track,
+					       g_slist_length (priv->tracks),
+					       handle,
+					       code);
+
+		if (desc->control & BRASERO_SCSI_TRACK_COPY)
+			track->type |= BRASERO_MEDIUM_TRACK_COPY;
+
+		if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+		||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
+			BraseroBurnResult result;
+
+			/* a special case for these two kinds of media (DVD+RW)
+			 * which have only one track: the first. */
+			result = brasero_medium_track_volume_size (self, 
+								   track,
+								   handle);
+			if (result != BRASERO_BURN_OK) {
+				priv->tracks = g_slist_remove (priv->tracks, track);
+				g_free (track);
+
+				priv->info |= BRASERO_MEDIUM_BLANK;
+				priv->info &= ~(BRASERO_MEDIUM_CLOSED|
+					        BRASERO_MEDIUM_HAS_DATA);
+
+				BRASERO_BURN_LOG ("Empty first session.");
+			}
+			else
+				priv->next_wr_add = 0;
+		}
+	}
+
+	/* put the tracks in the right order */
+	priv->tracks = g_slist_reverse (priv->tracks);
+
+	if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+	||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
+		gint32 start;
+
+		/* It starts where the other one finishes */
+		if (priv->tracks)
+			start = BRASERO_GET_32 (desc->track_start);
+		else
+			start = 0;
+
+		brasero_medium_add_DVD_plus_RW_leadout (self, start);
+	}
+	else if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
+		BraseroMediumTrack *track;
+
+		/* we shouldn't request info on leadout if the disc is closed
+		 * (except for DVD+/- (restricted) RW (see above) */
+		track = g_new0 (BraseroMediumTrack, 1);
+		priv->tracks = g_slist_append (priv->tracks, track);
+		track->start = BRASERO_GET_32 (desc->track_start);
+		track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+
+		brasero_medium_track_get_info (self,
+					       FALSE,
+					       track,
+					       g_slist_length (priv->tracks),
+					       handle,
+					       code);
+	}
+
+	g_free (toc);
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_medium_get_contents (BraseroMedium *self,
+			     BraseroDeviceHandle *handle,
+			     BraseroScsiErrCode *code)
+{
+	int size;
+	BraseroScsiResult result;
+	BraseroMediumPrivate *priv;
+	BraseroScsiDiscInfoStd *info = NULL;
+
+	BRASERO_BURN_LOG ("Retrieving media status");
+
+	priv = BRASERO_MEDIUM_PRIVATE (self);
+
+	result = brasero_mmc1_read_disc_information_std (handle,
+							 &info,
+							 &size,
+							 code);
+	if (result != BRASERO_SCSI_OK) {
+		g_free (info);
+	
+		BRASERO_BURN_LOG ("READ DISC INFORMATION failed");
+		return BRASERO_BURN_ERR;
+	}
+
+	if (info->erasable)
+		priv->info |= BRASERO_MEDIUM_REWRITABLE;
+
+	if (info->status == BRASERO_SCSI_DISC_EMPTY) {
+		BraseroMediumTrack *track;
+
+		BRASERO_BURN_LOG ("Empty media");
+
+		priv->info |= BRASERO_MEDIUM_BLANK;
+		priv->block_size = 2048;
+
+		if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+		||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED))
+			brasero_medium_add_DVD_plus_RW_leadout (self, 0);
+		else {
+			track = g_new0 (BraseroMediumTrack, 1);
+			track->start = 0;
+			track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+			priv->tracks = g_slist_prepend (priv->tracks, track);
+			
+			brasero_medium_track_get_info (self,
+						       FALSE,
+						       track,
+						       1,
+						       handle,
+						       code);
 		}
-		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);
+		goto end;
 	}
 
+	if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
+		priv->info |= BRASERO_MEDIUM_APPENDABLE;
+		BRASERO_BURN_LOG ("Appendable media");
+	}
+	else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
+		priv->info |= BRASERO_MEDIUM_CLOSED;
+		BRASERO_BURN_LOG ("Closed media");
+	}
 
-	if (track_info.next_wrt_address_valid)
-		priv->next_wr_add = BRASERO_GET_32 (track_info.next_wrt_address);
+	result = brasero_medium_get_sessions_info (self, handle, code);
 
-	BRASERO_BURN_LOG ("Track %i (session %i): type = %i start = %llu size = %llu",
-			  track_num,
-			  track->session,
-			  track->type,
-			  track->start,
-			  track->blocks_num);
+end:
 
-	return BRASERO_BURN_OK;
+	g_free (info);
+	return result;
 }
 
 #if 0
 
+/**
+ * These are special routines for old CD-R(W) drives that don't conform to MMC
+ */
+
 static void
 brasero_medium_set_track_type (BraseroMedium *self,
 			       BraseroMediumTrack *track,
@@ -1520,6 +1505,7 @@
 		start_LBA -= 150;
 		start_BCD -= 150;
 
+/*
 		result = brasero_mmc1_read_track_info (handle,
 						       track_num,
 						       &track_info,
@@ -1528,10 +1514,10 @@
 
 		if (result != BRASERO_SCSI_OK) {
 			BRASERO_BURN_LOG ("READ TRACK INFO failed");
-			/* Fallback to formatted toc */
-			return 0;
+*/			/* Fallback to formatted toc */
+/*			return 0;
 		}
-
+*/
 		track_start = BRASERO_GET_32 (track_info.start_lba);
 		BRASERO_BURN_LOG ("comparing DCB %i and LBA %i to real start address %i",
 				  start_BCD, start_LBA, track_start);
@@ -1753,255 +1739,377 @@
 
 #endif
 
-/**
- * NOTE: for DVD-R multisession we lose 28688 blocks for each session
- * so the capacity is the addition of all session sizes + 28688 for each
- * For all multisession DVD-/+R and CDR-RW the remaining size is given 
- * in the leadout. One exception though with DVD+/-RW.
- */
-
-static void
-brasero_medium_add_DVD_plus_RW_leadout (BraseroMedium *self,
-					gint32 start)
+static BraseroBurnResult
+brasero_medium_old_drive_get_disc_info (BraseroMedium *self,
+					BraseroDeviceHandle *handle,
+					BraseroScsiErrCode *code)
 {
-	BraseroMediumTrack *leadout;
+	int size;
+	BraseroScsiResult result;
 	BraseroMediumPrivate *priv;
+	BraseroScsiDiscInfoStd *info = NULL;
+
+	BRASERO_BURN_LOG ("Retrieving media status for old drive");
 
 	priv = BRASERO_MEDIUM_PRIVATE (self);
 
-	leadout = g_new0 (BraseroMediumTrack, 1);
-	priv->tracks = g_slist_append (priv->tracks, leadout);
+	result = brasero_mmc1_read_disc_information_std (handle,
+							 &info,
+							 &size,
+							 code);
+	if (result != BRASERO_SCSI_OK) {
+		g_free (info);
+	
+		BRASERO_BURN_LOG ("READ DISC INFORMATION failed for old drive");
+		return BRASERO_BURN_ERR;
+	}
 
-	leadout->start = start;
-	leadout->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+	/* Try to identify the type: can only be CDROM CDR CDRW.
+	 * NOTE: since there is no way to distinguish a CDROM and a closed CDR 
+	 * if the disc is closed we set it as CDROM (except if it's RW). */
+	if (info->erasable)
+		priv->info = BRASERO_MEDIUM_CDRW;
+	else if (info->status == BRASERO_SCSI_DISC_FINALIZED)
+		priv->info = BRASERO_MEDIUM_CDROM;
+	else
+		priv->info = BRASERO_MEDIUM_CDR;
 
-	/* we fabricate the leadout here. We don't really need one in 
-	 * fact since it is always at the last sector whatever the
-	 * amount of data written. So we need in fact to read the file
-	 * system and get the last sector from it. Hopefully it won't be
-	 * buggy */
-	priv->next_wr_add = 0;
+	if (info->status == BRASERO_SCSI_DISC_EMPTY) {
+		priv->info |= BRASERO_MEDIUM_BLANK;
+		priv->block_size = 2048;
+		priv->next_wr_add = 0;
+		BRASERO_BURN_LOG ("Empty media (old drive)");
+	}
+	else if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
+		priv->info |= BRASERO_MEDIUM_APPENDABLE;
+		priv->block_size = 2048;
+		priv->next_wr_add = 0;
+		BRASERO_BURN_LOG ("Appendable media (old drive)");
+	}
+	else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
+		priv->info |= BRASERO_MEDIUM_CLOSED;
+		BRASERO_BURN_LOG ("Closed media (old drive)");
+	}
 
-	leadout->blocks_num = priv->block_num;
-	if (g_slist_length (priv->tracks) > 1) {
-		BraseroMediumTrack *track;
+	/* get the contents */
+	result = brasero_medium_get_sessions_info (self, handle, code);
+	return result;
+}
 
-		track = priv->tracks->data;
-		leadout->blocks_num -= ((track->blocks_num > 300) ? track->blocks_num : 300);
+static BraseroBurnResult
+brasero_medium_check_old_drive (BraseroMedium *self,
+				BraseroDeviceHandle *handle,
+				BraseroScsiErrCode *code)
+{
+	gchar *model;
+	BraseroMediumPrivate *priv;
+
+	priv = BRASERO_MEDIUM_PRIVATE (self);
+
+	model = brasero_drive_get_display_name (priv->drive);
+	if (!model)
+		return BRASERO_BURN_ERR;
+
+	if (!strcmp (model, "CD-R55S")) {
+		g_free (model);
+		priv->max_rd = BRASERO_SPEED_TO_RATE_CD (12);
+		priv->max_wrt = BRASERO_SPEED_TO_RATE_CD (4);
+		return brasero_medium_old_drive_get_disc_info (self,
+							       handle,
+							       code);
 	}
-	BRASERO_BURN_LOG ("Adding fabricated leadout start = %llu length = %llu",
-			  leadout->start,
-			  leadout->blocks_num);
+
+	BRASERO_BURN_LOG ("Not an old drive model");
+
+	return BRASERO_BURN_ERR;
 }
 
+/**
+ * Some identification functions
+ */
+
 static BraseroBurnResult
-brasero_medium_get_sessions_info (BraseroMedium *self,
-				  BraseroDeviceHandle *handle,
-				  BraseroScsiErrCode *code)
+brasero_medium_get_medium_type (BraseroMedium *self,
+				BraseroDeviceHandle *handle,
+				BraseroScsiErrCode *code)
 {
-	int num, i, size;
-	gboolean multisession;
-	BraseroScsiResult result;
-	BraseroScsiTocDesc *desc;
+	BraseroScsiGetConfigHdr *hdr = NULL;
 	BraseroMediumPrivate *priv;
-	BraseroScsiFormattedTocData *toc = NULL;
+	BraseroScsiResult result;
+	int size;
 
-	BRASERO_BURN_LOG ("Reading Toc");
+	BRASERO_BURN_LOG ("Retrieving media profile");
 
 	priv = BRASERO_MEDIUM_PRIVATE (self);
-	result = brasero_mmc1_read_toc_formatted (handle,
-						  0,
-						  &toc,
-						  &size,
-						  code);
+	result = brasero_mmc2_get_configuration_feature (handle,
+							 BRASERO_SCSI_FEAT_REAL_TIME_STREAM,
+							 &hdr,
+							 &size,
+							 code);
 	if (result != BRASERO_SCSI_OK) {
-		g_free (toc);
+		BraseroScsiAtipData *data = NULL;
+		int size = 0;
 
-		BRASERO_BURN_LOG ("READ TOC failed");
-		return BRASERO_BURN_ERR;
+		BRASERO_BURN_LOG ("GET CONFIGURATION failed");
+
+		/* This could be a MMC1 drive since this command was
+		 * introduced in MMC2 and is supported onward. So it
+		 * has to be a CD (R/RW). The rest of the information
+		 * will be provided by read_disc_information. */
+
+		/* retrieve the speed */
+		result = brasero_medium_get_page_2A_max_speed (self,
+							       handle,
+							       code);
+
+		/* If this fails it means that this drive is probably older than
+		 * MMC1 spec or does not conform to it. Try our last chance. */
+		if (result != BRASERO_BURN_OK)
+			return brasero_medium_check_old_drive (self,
+							       handle,
+							       code);
+
+		/* The only thing here left to determine is if that's a WRITABLE
+		 * or a REWRITABLE. To determine that information, we need to
+		 * read TocPmaAtip. It if fails that's a ROM, if it succeeds.
+		 * No need to set error code since we consider that it's a ROM
+		 * if a failure happens. */
+		result = brasero_mmc1_read_atip (handle,
+						 &data,
+						 &size,
+						 NULL);
+		if (result != BRASERO_SCSI_OK) {
+			/* CDROM */
+			priv->info = BRASERO_MEDIUM_CDROM;
+			priv->type = types [1];
+			priv->icon = icons [1];
+		}
+		else {
+			/* check the size of the structure: it must be at least 8 bytes long */
+			if (size < 8) {
+				if (size)
+					g_free (data);
+
+				BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
+				return BRASERO_BURN_ERR;
+			}
+
+			if (data->desc->erasable) {
+				/* CDRW */
+				priv->info = BRASERO_MEDIUM_CDRW;
+				priv->type = types [3];
+				priv->icon = icons [3];
+			}
+			else {
+				/* CDR */
+				priv->info = BRASERO_MEDIUM_CDR;
+				priv->type = types [2];
+				priv->icon = icons [2];
+			}
+
+			g_free (data);
+		}
+
+		return result;
 	}
 
-	num = (size - sizeof (BraseroScsiFormattedTocData)) /
-	       sizeof (BraseroScsiTocDesc);
+	switch (BRASERO_GET_16 (hdr->current_profile)) {
+	case BRASERO_SCSI_PROF_CDROM:
+		priv->info = BRASERO_MEDIUM_CDROM;
+		priv->type = types [1];
+		priv->icon = icons [1];
+		break;
 
-	/* remove 1 for leadout */
-	multisession = (priv->info & BRASERO_MEDIUM_APPENDABLE) || (num -1) != 1;
+	case BRASERO_SCSI_PROF_CDR:
+		priv->info = BRASERO_MEDIUM_CDR;
+		priv->type = types [2];
+		priv->icon = icons [2];
+		break;
 
-	BRASERO_BURN_LOG ("%i track(s) found", num);
+	case BRASERO_SCSI_PROF_CDRW:
+		priv->info = BRASERO_MEDIUM_CDRW;
+		priv->type = types [3];
+		priv->icon = icons [3];
+		break;
 
-	desc = toc->desc;
-	for (i = 0; i < num; i ++, desc ++) {
-		BraseroMediumTrack *track;
+	case BRASERO_SCSI_PROF_DVD_ROM:
+		priv->info = BRASERO_MEDIUM_DVD_ROM;
+		priv->type = types [4];
+		priv->icon = icons [4];
+		break;
+
+	case BRASERO_SCSI_PROF_DVD_R:
+		priv->info = BRASERO_MEDIUM_DVDR;
+		priv->type = types [5];
+		priv->icon = icons [5];
+		break;
 
-		if (desc->track_num == BRASERO_SCSI_TRACK_LEADOUT_START)
-			break;
+	case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
+		priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
+		priv->type = types [6];
+		priv->icon = icons [6];
+		break;
 
-		track = g_new0 (BraseroMediumTrack, 1);
-		priv->tracks = g_slist_prepend (priv->tracks, track);
-		track->start = BRASERO_GET_32 (desc->track_start);
+	case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
+		priv->info = BRASERO_MEDIUM_DVDRW;
+		priv->type = types [6];
+		priv->icon = icons [6];
+		break;
 
-		/* we shouldn't request info on a track if the disc is closed */
-		if (desc->control & BRASERO_SCSI_TRACK_COPY)
-			track->type |= BRASERO_MEDIUM_TRACK_COPY;
+	case BRASERO_SCSI_PROF_DVD_R_PLUS:
+		priv->info = BRASERO_MEDIUM_DVDR_PLUS;
+		priv->type = types [7];
+		priv->icon = icons [7];
+		break;
 
-		if (!(desc->control & BRASERO_SCSI_TRACK_DATA)) {
-			track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
-			priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
+	case BRASERO_SCSI_PROF_DVD_RW_PLUS:
+		priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
+		priv->type = types [8];
+		priv->icon = icons [7];
+		break;
 
-			if (desc->control & BRASERO_SCSI_TRACK_PREEMP)
-				track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
+	case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
+		priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
+		priv->type = types [9];
+		priv->icon = icons [7];
+		break;
 
-			if (desc->control & BRASERO_SCSI_TRACK_4_CHANNELS)
-				track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS;
-		}
-		else {
-			track->type |= BRASERO_MEDIUM_TRACK_DATA;
-			priv->info |= BRASERO_MEDIUM_HAS_DATA;
+	case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
+		priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
+		priv->type = types [10];
+		priv->icon = icons [7];
+		break;
 
-			if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
-				track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
-		}
+	case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
+		priv->info = BRASERO_MEDIUM_DVDR_DL;
+		priv->type = types [11];
+		priv->icon = icons [5];
+		break;
 
-		brasero_medium_track_get_info (self,
-					       multisession,
-					       track,
-					       g_slist_length (priv->tracks),
-					       handle,
-					       code);
+	case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
+		priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
+		priv->type = types [11];
+		priv->icon = icons [5];
+		break;
 
-		if (desc->control & BRASERO_SCSI_TRACK_COPY)
-			track->type |= BRASERO_MEDIUM_TRACK_COPY;
+	/* WARNING: these types are recognized, no more */
+	case BRASERO_SCSI_PROF_BD_ROM:
+		priv->info = BRASERO_MEDIUM_BD_ROM;
+		priv->type = types [13];
+		priv->icon = icons [4];
+		break;
 
-		if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
-		||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
-			BraseroBurnResult result;
+	case BRASERO_SCSI_PROF_BR_R_SEQUENTIAL:
+		priv->info = BRASERO_MEDIUM_BDR_SRM;
+		priv->type = types [14];
+		priv->icon = icons [5];
+		break;
 
-			/* a special case for these two kinds of media (DVD+RW)
-			 * which have only one track: the first. */
-			result = brasero_medium_track_volume_size (self, 
-								   track,
-								   handle);
-			if (result != BRASERO_BURN_OK) {
-				priv->tracks = g_slist_remove (priv->tracks, track);
-				g_free (track);
+	case BRASERO_SCSI_PROF_BR_R_RANDOM:
+		priv->info = BRASERO_MEDIUM_BDR_RANDOM;
+		priv->type = types [14];
+		priv->icon = icons [5];
+		break;
 
-				priv->info |= BRASERO_MEDIUM_BLANK;
-				priv->info &= ~(BRASERO_MEDIUM_CLOSED|
-						BRASERO_MEDIUM_HAS_DATA);
-			}
-			else
-				priv->next_wr_add = 0;
-		}
-	}
+	case BRASERO_SCSI_PROF_BD_RW:
+		priv->info = BRASERO_MEDIUM_BDRW;
+		priv->type = types [15];
+		priv->icon = icons [6];
+		break;
 
-	/* put the tracks in the right order */
-	priv->tracks = g_slist_reverse (priv->tracks);
+	case BRASERO_SCSI_PROF_DVD_RAM:
+		priv->info = BRASERO_MEDIUM_DVD_RAM;
+		priv->type = types [12];
+		priv->icon = icons [8];
+		break;
+	
+	case BRASERO_SCSI_PROF_NON_REMOVABLE:
+	case BRASERO_SCSI_PROF_REMOVABLE:
+	case BRASERO_SCSI_PROF_MO_ERASABLE:
+	case BRASERO_SCSI_PROF_MO_WRITE_ONCE:
+	case BRASERO_SCSI_PROF_MO_ADVANCED_STORAGE:
+	case BRASERO_SCSI_PROF_DDCD_ROM:
+	case BRASERO_SCSI_PROF_DDCD_R:
+	case BRASERO_SCSI_PROF_DDCD_RW:
+	case BRASERO_SCSI_PROF_HD_DVD_ROM:
+	case BRASERO_SCSI_PROF_HD_DVD_R:
+	case BRASERO_SCSI_PROF_HD_DVD_RAM:
+		priv->info = BRASERO_MEDIUM_UNSUPPORTED;
+		priv->icon = icons [0];
+		g_free (hdr);
+		return BRASERO_BURN_NOT_SUPPORTED;
+	}
 
-	if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
-	||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
-		gint32 start;
+	/* try all SCSI functions to get write/read speeds in order */
+	if (hdr->desc->add_len >= sizeof (BraseroScsiRTStreamDesc)) {
+		BraseroScsiRTStreamDesc *stream;
 
-		/* It starts where the other one finishes */
-		if (priv->tracks)
-			start = BRASERO_GET_32 (desc->track_start);
-		else
-			start = 0;
+		/* means it's at least an MMC3 drive */
+		stream = (BraseroScsiRTStreamDesc *) hdr->desc->data;
+		if (stream->wrt_spd) {
+			result = brasero_medium_get_speed_mmc3 (self, handle, code);
+			if (result == BRASERO_BURN_OK)
+				goto end;
+		}
 
-		brasero_medium_add_DVD_plus_RW_leadout (self, start);
+		if (stream->mp2a) {
+			result = brasero_medium_get_page_2A_write_speed_desc (self, handle, code);
+			if (result == BRASERO_BURN_OK)
+				goto end;
+		}
 	}
-	else if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
-		BraseroMediumTrack *track;
 
-		/* we shouldn't request info on leadout if the disc is closed
-		 * (except for DVD+/- (restricted) RW (see above) */
-		track = g_new0 (BraseroMediumTrack, 1);
-		priv->tracks = g_slist_append (priv->tracks, track);
-		track->start = BRASERO_GET_32 (desc->track_start);
-		track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+	/* fallback for speeds */
+	result = brasero_medium_get_page_2A_max_speed (self, handle, code);
 
-		brasero_medium_track_get_info (self,
-					       FALSE,
-					       track,
-					       g_slist_length (priv->tracks),
-					       handle,
-					       code);
-	}
+end:
 
-	g_free (toc);
+	g_free (hdr);
+
+	if (result != BRASERO_BURN_OK)
+		return result;
 
 	return BRASERO_BURN_OK;
 }
 
 static BraseroBurnResult
-brasero_medium_get_contents (BraseroMedium *self,
-			     BraseroDeviceHandle *handle,
-			     BraseroScsiErrCode *code)
+brasero_medium_get_css_feature (BraseroMedium *self,
+				BraseroDeviceHandle *handle,
+				BraseroScsiErrCode *code)
 {
-	int size;
-	BraseroScsiResult result;
+	BraseroScsiGetConfigHdr *hdr = NULL;
 	BraseroMediumPrivate *priv;
-	BraseroScsiDiscInfoStd *info = NULL;
-
-	BRASERO_BURN_LOG ("Retrieving media status");
+	BraseroScsiResult result;
+	int size;
 
 	priv = BRASERO_MEDIUM_PRIVATE (self);
 
-	result = brasero_mmc1_read_disc_information_std (handle,
-							 &info,
+	BRASERO_BURN_LOG ("Testing for Css encrypted media");
+	result = brasero_mmc2_get_configuration_feature (handle,
+							 BRASERO_SCSI_FEAT_DVD_CSS,
+							 &hdr,
 							 &size,
 							 code);
 	if (result != BRASERO_SCSI_OK) {
-		g_free (info);
-	
-		BRASERO_BURN_LOG ("READ DISC INFORMATION failed");
+		g_free (hdr);
+
+		BRASERO_BURN_LOG ("GET CONFIGURATION failed");
 		return BRASERO_BURN_ERR;
 	}
 
-	if (info->erasable)
-		priv->info |= BRASERO_MEDIUM_REWRITABLE;
-
-	if (info->status == BRASERO_SCSI_DISC_EMPTY) {
-		BraseroMediumTrack *track;
-
-		BRASERO_BURN_LOG ("Empty media");
-
-		priv->info |= BRASERO_MEDIUM_BLANK;
-		priv->block_size = 2048;
-
-		if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
-		||  BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED))
-			brasero_medium_add_DVD_plus_RW_leadout (self, 0);
-		else {
-			track = g_new0 (BraseroMediumTrack, 1);
-			track->start = 0;
-			track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
-			priv->tracks = g_slist_prepend (priv->tracks, track);
-			
-			brasero_medium_track_get_info (self,
-						       FALSE,
-						       track,
-						       1,
-						       handle,
-						       code);
-		}
-		goto end;
+	if (hdr->desc->add_len < sizeof (BraseroScsiDVDCssDesc)) {
+		g_free (hdr);
+		return BRASERO_BURN_OK;
 	}
 
-	if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
-		priv->info |= BRASERO_MEDIUM_APPENDABLE;
-		BRASERO_BURN_LOG ("Appendable media");
-	}
-	else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
-		priv->info |= BRASERO_MEDIUM_CLOSED;
-		BRASERO_BURN_LOG ("Closed media");
+	/* here we just need to see if this feature is current or not */
+	if (hdr->desc->current) {
+		priv->info |= BRASERO_MEDIUM_PROTECTED;
+		BRASERO_BURN_LOG ("media is Css protected");
 	}
 
-	result = brasero_medium_get_sessions_info (self, handle, code);
-
-end:
-
-	g_free (info);
-	return result;
+	g_free (hdr);
+	return BRASERO_BURN_OK;
 }
 
 static void

Modified: branches/video/src/burn-task-ctx.c
==============================================================================
--- branches/video/src/burn-task-ctx.c	(original)
+++ branches/video/src/burn-task-ctx.c	Sat Jul 12 11:43:40 2008
@@ -60,13 +60,15 @@
 	/* keep track of time */
 	GTimer *timer;
 	gint64 first_written;
+	gdouble first_progress;
 
 	/* used for immediate rate */
-	gint64 current_written;
 	gdouble current_elapsed;
-	gint64 last_written;
 	gdouble last_elapsed;
 
+	gint64 last_written;
+	gdouble last_progress;
+
 	/* used for remaining time */
 	GSList *times;
 	gdouble total_time;
@@ -167,10 +169,11 @@
 	priv->track_bytes = -1;
 	priv->session_bytes = -1;
 	priv->written_changed = 0;
-	priv->current_written = 0;
+
 	priv->current_elapsed = 0;
 	priv->last_written = 0;
 	priv->last_elapsed = 0;
+	priv->last_progress = 0;
 
 	if (priv->times) {
 		g_slist_free (priv->times);
@@ -299,6 +302,7 @@
 
 	priv->session_bytes += priv->track_bytes;
 	priv->track_bytes = 0;
+	priv->last_written = 0;
 
 	if (priv->current_track)
 		brasero_track_unref (priv->current_track);
@@ -413,10 +417,12 @@
 	if (!priv->timer) {
 		priv->timer = g_timer_new ();
 		priv->first_written = priv->session_bytes + priv->track_bytes;
+		priv->first_progress = priv->progress;
 	}
 	else if (force) {
 		g_timer_start (priv->timer);
 		priv->first_written = priv->session_bytes + priv->track_bytes;
+		priv->first_progress = priv->progress;
 	}
 
 	return BRASERO_BURN_OK;
@@ -563,22 +569,23 @@
 
 	priv = BRASERO_TASK_CTX_PRIVATE (self);
 
-	priv->track_bytes = written;
 	priv->written_changed = 1;
 
-	if (priv->use_average_rate)
+	if (priv->use_average_rate) {
+		priv->track_bytes = written;
 		return BRASERO_BURN_OK;
+	}
 
 	if (priv->timer)
 		elapsed = g_timer_elapsed (priv->timer, NULL);
 
 	if ((elapsed - priv->last_elapsed) > 0.5) {
-		priv->last_written = priv->current_written;
+		priv->last_written = priv->track_bytes;
 		priv->last_elapsed = priv->current_elapsed;
-		priv->current_written = written;
 		priv->current_elapsed = elapsed;
 	}
 
+	priv->track_bytes = written;
 	return BRASERO_BURN_OK;
 }
 
@@ -601,14 +608,36 @@
 			       gdouble progress)
 {
 	BraseroTaskCtxPrivate *priv;
+	gdouble elapsed;
 
 	g_return_val_if_fail (BRASERO_IS_TASK_CTX (self), BRASERO_BURN_ERR);
 
 	priv = BRASERO_TASK_CTX_PRIVATE (self);
 
 	priv->progress_changed = 1;
-	priv->progress = progress;
 
+	if (priv->use_average_rate) {
+		priv->progress = progress;
+		return BRASERO_BURN_OK;
+	}
+
+	/* here we prefer to use track written bytes instead of progress.
+	 * NOTE: usually plugins will return only one information. */
+	if (priv->last_written) {
+		priv->progress = progress;
+		return BRASERO_BURN_OK;
+	}
+
+	if (priv->timer)
+		elapsed = g_timer_elapsed (priv->timer, NULL);
+
+	if ((elapsed - priv->last_elapsed) > 0.5) {
+		priv->last_progress = priv->progress;
+		priv->last_elapsed = priv->current_elapsed;
+		priv->current_elapsed = elapsed;
+	}
+
+	priv->progress = progress;
 	return BRASERO_BURN_OK;
 }
 
@@ -678,7 +707,7 @@
 	if (priv->current_action != BRASERO_BURN_ACTION_RECORDING
 	&&  priv->current_action != BRASERO_BURN_ACTION_DRIVE_COPY) {
 		*rate = -1;
-		return BRASERO_BURN_OK;
+		return BRASERO_BURN_NOT_SUPPORTED;
 	}
 
 	if (priv->rate) {
@@ -689,18 +718,30 @@
 	if (priv->use_average_rate) {
 		gdouble elapsed;
 
-		if ((priv->session_bytes + priv->track_bytes) <= 0 || !priv->timer)
+		if (!priv->timer)
 			return BRASERO_BURN_NOT_READY;
 
 		elapsed = g_timer_elapsed (priv->timer, NULL);
-		*rate = (gdouble) ((priv->session_bytes + priv->track_bytes) - priv->first_written) / elapsed;
+
+		if ((priv->session_bytes + priv->track_bytes) > 0)
+			*rate = (gdouble) ((priv->session_bytes + priv->track_bytes) - priv->first_written) / elapsed;
+		else if (priv->progress > 0.0)
+			*rate = (gdouble) (priv->progress - priv->first_progress) * priv->size / elapsed;
+		else
+			return BRASERO_BURN_NOT_READY;
 	}
 	else {
-		if (!priv->last_written)
+		if (priv->last_written > 0) {			
+			*rate = (gdouble) (priv->track_bytes - priv->last_written) /
+				(gdouble) (priv->current_elapsed - priv->last_elapsed);
+		}
+		else if (priv->last_progress > 0.0) {
+			*rate = (gdouble)  priv->size *
+				(gdouble) (priv->progress - priv->last_progress) /
+				(gdouble) (priv->current_elapsed - priv->last_elapsed);
+		}
+		else
 			return BRASERO_BURN_NOT_READY;
-			
-		*rate = (gdouble) (priv->current_written - priv->last_written) /
-			(gdouble) (priv->current_elapsed - priv->last_elapsed);
 	}
 
 	return BRASERO_BURN_OK;
@@ -891,6 +932,7 @@
 		priv->timer = NULL;
 	}
 	priv->first_written = 0;
+	priv->first_progress = 0.0;
 
 	g_mutex_lock (priv->lock);
 

Modified: branches/video/src/plugins/growisofs/burn-growisofs.c
==============================================================================
--- branches/video/src/plugins/growisofs/burn-growisofs.c	(original)
+++ branches/video/src/plugins/growisofs/burn-growisofs.c	Sat Jul 12 11:43:40 2008
@@ -107,12 +107,12 @@
 {
 	int perc_1, perc_2;
 
-	if (sscanf (line, " %2d.%1d%% done, estimate finish", &perc_1, &perc_2) == 2) {
+	if (sscanf (line, " %2d.%2d%% done, estimate finish", &perc_1, &perc_2) == 2) {
 		gdouble fraction;
 		BraseroBurnAction action;
 
 		fraction = (gdouble) ((gdouble) perc_1 +
-			   ((gdouble) perc_2 / (gdouble) 10.0)) /
+			   ((gdouble) perc_2 / (gdouble) 100.0)) /
 			   (gdouble) 100.0;
 
 		brasero_job_set_progress (BRASERO_JOB (process), fraction);
@@ -120,8 +120,10 @@
 		brasero_job_get_current_action (BRASERO_JOB (process), &action);
 		if (action == BRASERO_BURN_ACTION_BLANKING
 		&&  fraction >= 0.01) {
-			/* we nullified 1% (more than 65536) that's enough. A 
-			 * signal SIGTERM will be sent. */
+			/* we nullified 1% of the medium (more than 65536)
+			 * that's enough to make the filesystem unusable and
+			 * looking blank. A signal SIGTERM will be sent to stop
+			 * us. */
 			brasero_job_finished_session (BRASERO_JOB (process));
 			return BRASERO_BURN_OK;
 		}

Modified: branches/video/src/plugins/libburnia/burn-libburn-common.c
==============================================================================
--- branches/video/src/plugins/libburnia/burn-libburn-common.c	(original)
+++ branches/video/src/plugins/libburnia/burn-libburn-common.c	Sat Jul 12 11:43:40 2008
@@ -99,15 +99,8 @@
 		return NULL;
 	}
 
-	/* apparently this is needed to properly shutdown a drive on aborting.
-	 * I'm not sure about this one since glib also sets up signal handlers. */
-	//burn_set_signal_handling ("brasero : ", NULL, 0);
-
-	/* We want all types of messages: this might change in the future */
-	burn_msgs_set_severities ("ALL", "ALL", "brasero (libburn):");
-
-	/* that's for debugging */
-	burn_set_verbosity (666);
+	/* We want all types of messages but not them printed */
+	burn_msgs_set_severities ("ALL", "NEVER", "");
 
 	/* we just want to scan the drive proposed by drive */
 	brasero_job_get_device (job, &device);
@@ -148,27 +141,30 @@
 	char err_sev [80];
 	char err_txt [BURN_MSGS_MESSAGE_LEN] = {0};
 
-	ret = burn_msgs_obtain ("FATAL",
+	/* Get all messages, indicating an error */
+	memset (err_txt, 0, sizeof (err_txt));
+	ret = burn_msgs_obtain ("ALL",
 				&err_code,
 				err_txt,
 				&err_errno,
 				err_sev);
-
 	if (ret == 0)
-	        return TRUE;
+		return TRUE;
 
-	if (ret < 0) {
-		error = g_error_new (BRASERO_BURN_ERROR,
-				     BRASERO_BURN_ERROR_GENERAL,
-				     err_txt);
-		brasero_job_error (BRASERO_JOB (self), error);
-		return FALSE;
+	if (strcmp ("FATAL", err_sev)
+	&&  strcmp ("ABORT", err_sev)) {
+		/* libburn didn't reported any FATAL message but maybe it did
+		 * report some debugging output */
+		BRASERO_JOB_LOG (self, err_txt);
+	        return TRUE;
 	}
 
-	BRASERO_JOB_LOG (self,
-			 _("(%s) libburn tried to say something"),
-		         err_txt);
-	return TRUE;
+	BRASERO_JOB_LOG (self, "Libburn reported an error %s", err_txt);
+	error = g_error_new (BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     err_txt);
+	brasero_job_error (BRASERO_JOB (self), error);
+	return FALSE;
 }
 
 static gboolean

Modified: branches/video/src/plugins/libburnia/burn-libburn.c
==============================================================================
--- branches/video/src/plugins/libburnia/burn-libburn.c	(original)
+++ branches/video/src/plugins/libburnia/burn-libburn.c	Sat Jul 12 11:43:40 2008
@@ -341,7 +341,7 @@
 								       dup (fd),
 								       BURN_AUDIO,
 								       size,
-								       priv->pvd,
+								       NULL,
 								       error);
 				if (result != BRASERO_BURN_OK)
 					return result;
@@ -378,13 +378,17 @@
 		brasero_track_get_type (track, &type);
 		if (type.type == BRASERO_TRACK_TYPE_AUDIO) {
 			gchar *audiopath;
+			gint64 size;
 
 			audiopath = brasero_track_get_audio_source (track, FALSE);
+			brasero_track_get_audio_length (track, &size);
+			size = BRASERO_DURATION_TO_BYTES (size);
+
 			result = brasero_libburn_add_file_track (session,
 								 audiopath,
 								 BURN_AUDIO,
-								 -1,
-								 priv->pvd,
+								 size,
+								 NULL,
 								 error);
 			if (result != BRASERO_BURN_OK)
 				break;
@@ -723,6 +727,7 @@
 				   g_error_new (BRASERO_BURN_ERROR,
 						BRASERO_BURN_ERROR_GENERAL,
 						_("an unknown error occured")));
+		return BRASERO_BURN_OK;
 	}
 
 	/* That's finished */

Modified: branches/video/src/scsi-sg.c
==============================================================================
--- branches/video/src/scsi-sg.c	(original)
+++ branches/video/src/scsi-sg.c	Sat Jul 12 11:43:40 2008
@@ -110,8 +110,6 @@
 				  buffer,
 				  size);
 
-	/* for the time being only sg driver is supported */
-
 	/* NOTE on SG_IO: only for TEST UNIT READY, REQUEST/MODE SENSE, INQUIRY,
 	 * READ CAPACITY, READ BUFFER, READ and LOG SENSE are allowed with it */
 	res = ioctl (cmd->handle->fd, SG_IO, &transport);



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