Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/Makefile.am,v
retrieving revision 1.53
diff -u -r1.53 Makefile.am
--- Makefile.am	16 Jan 2006 19:58:06 -0000	1.53
+++ Makefile.am	28 Feb 2006 19:22:20 -0000
@@ -100,6 +100,8 @@
 	nautilus-cd-burner.h 	\
 	make-iso.c 		\
 	make-iso.h 		\
+	mkisofs-glue.c		\
+	mkisofs-glue.h		\
 	$(MKDTEMP_FILES) 	\
 	$(NULL)
 
@@ -183,7 +185,11 @@
 	nautilus-burn-features.h		\
 	dvd_plus_rw_utils.cpp			\
 	transport.hxx				\
+	mkisofs-glue.h				\
+	mkisofs-glue.c				\
 	$(NULL)
+
+libnautilus_burn_la_CFLAGS = $(AM_CFLAGS)
 
 if LIBSTDCXX_HACK
 AM_CXXFLAGS = -fno-exceptions -fno-rtti
Index: configure.in
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/configure.in,v
retrieving revision 1.182
diff -u -r1.182 configure.in
--- configure.in	14 Feb 2006 15:06:34 -0000	1.182
+++ configure.in	28 Feb 2006 19:22:20 -0000
@@ -147,7 +147,11 @@
  libnautilus-extension >= $NAUTILUS_REQUIRED eel-2.0 >= $EEL_REQUIRED)
 
 PKG_CHECK_MODULES(BURN,
-  glib-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK_REQUIRED $HAL)
+  glib-2.0 >= $GLIB_REQUIRED dnl
+  gtk+-2.0 >= $GTK_REQUIRED dnl
+  gnome-vfs-2.0 >= $GNOME_VFS_REQUIRED dnl
+  gnome-vfs-module-2.0 >= $GNOME_VFS_REQUIRED dnl
+  $HAL)
 
 AC_CHECK_HEADERS(mntent.h sys/mnttab.h sys/vfstab.h sys/cdio.h)
 
Index: make-iso.c
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/make-iso.c,v
retrieving revision 1.66
diff -u -r1.66 make-iso.c
--- make-iso.c	30 Nov 2005 17:06:11 -0000	1.66
+++ make-iso.c	28 Feb 2006 19:22:20 -0000
@@ -49,6 +49,7 @@
 #include <gtk/gtkmessagedialog.h>
 #include <libgnomevfs/gnome-vfs.h>
 
+#include "mkisofs-glue.h"
 #include "nautilus-cd-burner.h"
 #include "make-iso.h"
 
@@ -139,20 +140,6 @@
 	return TRUE;
 }
 
-struct mkisofs_output {
-	GMainLoop  *loop;
-	GString    *line;
-	GString    *line_stderr;
-	time_t      start_time;
-	int         result;
-	int         pid;
-	const char *filename;
-	guint64     iso_size;
-	GList      *rates;
-	GError     *error;
-	gboolean    debug;
-};
-
 struct mkisofs_output *mkisofs_output_ptr;
 
 /**
@@ -172,175 +159,6 @@
 	}
 }
 
-static void
-write_all (int   fd,
-	   char *buf,
-	   int   len)
-{
-	int bytes;
-	int res;
-	
-	bytes = 0;
-	while (bytes < len) {
-		res = write (fd, buf + bytes, len - bytes);
-		if (res <= 0) {
-			return;
-		}
-		bytes += res;
-	}
-	return;
-}
-
-static void
-copy_file (const char *source,
-	   const char *dest)
-{
-	int         sfd, dfd;
-	struct stat stat_buf;
-	char        buffer [1024 * 8];
-	ssize_t     len;
-
-	if (link (source, dest) == 0) {
-		return;
-	}
-	
-	if (g_stat (source, &stat_buf) != 0) {
-		g_warning ("Trying to copy nonexisting file\n");
-		return;
-	}
-
-	sfd = g_open (source, O_RDONLY, 0);
-	if (sfd == -1) {
-		g_warning ("Can't copy file (open source failed)\n");
-		return;
-	}
-	
-	dfd = g_open (dest, O_WRONLY | O_CREAT, stat_buf.st_mode);
-	if (dfd == -1) {
-		close (sfd);
-		g_warning ("Can't copy file (open dest '%s' failed)\n", dest);
-		perror ("error:");
-		return;
-	}
-
-	while ( (len = read (sfd, &buffer, sizeof (buffer))) > 0) {
-		write_all (dfd, buffer, len);
-	}
-	close (dfd);
-	close (sfd);
-}
-
-static char *
-escape_path (const char *str)
-{
-	char       *escaped, *d;
-	const char *s;
-	int         len;
-	
-	s = str;
-	len = 1;
-	while (*s != 0) {
-		if (*s == '\\' ||
-		    *s == '=') {
-			len++;
-		}
-		
-		len++;
-		s++;
-	}
-	
-	escaped = g_malloc (len);
-	
-	s = str;
-	d = escaped;
-	while (*s != 0) {
-		if (*s == '\\' ||
-		    *s == '=') {
-			*d++ = '\\';
-		}
-		
-		*d++ = *s++;
-	}
-	*d = 0;
-	
-	return escaped;
-}
-
-static gboolean
-dir_is_empty (const char *virtual_path)
-{
-	GnomeVFSFileInfo        *info;
-	GnomeVFSDirectoryHandle *handle;
-	GnomeVFSResult           result;
-	char                    *escaped_path, *uri;
-	gboolean                 found_file;
-	
-	escaped_path = gnome_vfs_escape_path_string (virtual_path);
-	uri = g_strconcat ("burn:///", escaped_path, NULL);
-	g_free (escaped_path);
-	
-	result = gnome_vfs_directory_open (&handle, uri, GNOME_VFS_FILE_INFO_DEFAULT);
-	g_free (uri);
-
-	if (result != GNOME_VFS_OK) {
-		return TRUE;
-	}
-
-	info = gnome_vfs_file_info_new ();
-
-	found_file = FALSE;
-	
-	while (TRUE) {
-		result = gnome_vfs_directory_read_next (handle, info);
-		if (result != GNOME_VFS_OK)
-			break;
-
-		/* Skip "." and "..".  */
-		if (info->name [0] == '.'
-		    && (info->name [1] == 0
-			|| (info->name [1] == '.' && info->name [2] == 0))) {
-			gnome_vfs_file_info_clear (info);
-			continue;
-		}
-		
-		found_file = TRUE;
-		break;
-	}
-
-	gnome_vfs_directory_close (handle);
-	gnome_vfs_file_info_unref (info);
-
-	return !found_file;
-}
-
-static char *
-get_backing_file (const char *virtual_path)
-{
-	GnomeVFSHandle *handle;
-	GnomeVFSResult  res;
-	char           *escaped_path, *uri;
-	char           *mapping;
-
-	escaped_path = gnome_vfs_escape_path_string (virtual_path);
-	uri = g_strconcat ("burn:///", escaped_path, NULL);
-	g_free (escaped_path);
-	/* warning, this can hang on fifos etc */
-	res = gnome_vfs_open (&handle,
-			      uri,
-			      GNOME_VFS_OPEN_READ);
-	g_free (uri);
-	if (res == GNOME_VFS_OK) {
-		res =  gnome_vfs_file_control (handle,
-					       "mapping:get_mapping",
-					       &mapping);
-		gnome_vfs_close	(handle);
-		if (res == GNOME_VFS_OK) {
-			return mapping;
-		}
-	}
-	return NULL;
-}
-
 static gboolean
 ask_disable_joliet (GtkWindow *parent)
 {
@@ -360,222 +178,6 @@
 	return (res == GTK_RESPONSE_OK);
 }
 
-struct mkisofs_state {
-	FILE    *graft_file;
-	char    *emptydir;
-	int      depth;
-	char    *tmpdir;
-	char    *copy_to_dir;
-	int      copy_depth;
-	GList   *remove_files;
-	gboolean found_file;
-};
-
-static void
-graft_file_end_dir_visitor (struct mkisofs_state *state)
-{
-	char *last_slash;
-	
-	if (state->copy_depth > 0) {
-		state->copy_depth--;
-		if (state->copy_depth == 0) {
-			g_free (state->copy_to_dir);
-			state->copy_to_dir = NULL;
-		} else {
-			last_slash = strrchr (state->copy_to_dir, G_DIR_SEPARATOR);
-			if (last_slash != NULL) {
-				*last_slash = 0;
-			}
-		}
-	}
-}
-
-/* FIXME: This should probably be an inline */
-static gboolean
-file_info_is_allowed (GnomeVFSFileInfo *info)
-{
-	g_return_val_if_fail (info != NULL, FALSE);
-
-	/* only allow regular,directory,symlink files */
-	if (info->type != GNOME_VFS_FILE_TYPE_REGULAR
-	    && info->type != GNOME_VFS_FILE_TYPE_DIRECTORY
-	    && info->type != GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) {
-		return FALSE;
-	} else if (info->type == GNOME_VFS_FILE_TYPE_REGULAR
-		   && !(info->permissions & GNOME_VFS_PERM_ACCESS_READABLE)) {
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-graft_file_visitor (const char           *rel_path,
-		    GnomeVFSFileInfo     *info,
-		    struct mkisofs_state *state,
-		    gboolean             *recurse)
-{
-	char *mapping, *path1, *path2;
-	char *new_copy_dir;
-	char *copy_path;
-
-	*recurse = TRUE;
-
-	if (! file_info_is_allowed (info)) {
-		g_warning ("Skipping file: %s", rel_path);
-		return TRUE;
-	}
-
-	if (state->copy_to_dir != NULL) {
-		if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
-			new_copy_dir = g_build_filename (state->copy_to_dir,
-							 info->name,
-							 NULL);
-			g_free (state->copy_to_dir);
-			state->copy_to_dir = new_copy_dir;
-			g_mkdir (state->copy_to_dir, 0777);
-			state->remove_files = g_list_prepend (state->remove_files, g_strdup (state->copy_to_dir));
-			state->copy_depth++;
-		} else {
-			copy_path = g_build_filename (state->copy_to_dir, info->name, NULL);
-			mapping = get_backing_file (rel_path);
-			if (mapping != NULL) {
-				copy_file (mapping, copy_path);
-				state->remove_files = g_list_prepend (state->remove_files, g_strdup (copy_path));
-			}
-		}
-		return TRUE;
-	}
-	
-	if (info->type != GNOME_VFS_FILE_TYPE_DIRECTORY) {
-		mapping = get_backing_file (rel_path);
-		if (mapping != NULL) {
-			path1 = escape_path (rel_path);
-			path2 = escape_path (mapping);
-			state->found_file = TRUE;
-			fprintf (state->graft_file, "%s=%s\n", path1, path2);
-			g_free (path1);
-			g_free (path2);
-			g_free (mapping);
-		}
-	} else {
-		if (dir_is_empty (rel_path)) {
-			path1 = escape_path (rel_path);
-			path2 = escape_path (state->emptydir);
-			state->found_file = TRUE;
-			fprintf (state->graft_file, "%s/=%s\n", path1, path2);
-			g_free (path1);
-			g_free (path2);
-		} else if (state->depth >= 6) {
-			new_copy_dir = g_build_filename (state->tmpdir, "subdir.XXXXXX", NULL);
-			copy_path = mkdtemp (new_copy_dir);
-			if (copy_path != NULL) {
-				state->remove_files = g_list_prepend (state->remove_files, g_strdup (copy_path));
-				state->copy_depth = 1;
-				state->copy_to_dir = copy_path;
-				path1 = escape_path (rel_path);
-				path2 = escape_path (copy_path);
-				state->found_file = TRUE;
-				fprintf (state->graft_file, "%s/=%s\n", path1, path2);
-				g_free (path1);
-				g_free (path2);
-			} else {
-				g_free (new_copy_dir);
-				g_warning ("Couldn't create temp subdir\n");
-				*recurse = FALSE;
-			}
-		} 
-	}
-
-	return TRUE;
-}
-	
-static void
-create_graft_file (GnomeVFSURI          *uri,
-		   const char           *prefix,
-		   struct mkisofs_state *state)
-{
-	GnomeVFSFileInfo        *info;
-	GnomeVFSDirectoryHandle *handle;
-	GnomeVFSResult           result;
-	gboolean                 stop;
-
-	profile_start ("start", NULL);
-
-	result = gnome_vfs_directory_open_from_uri (&handle,
-						    uri,
-						    GNOME_VFS_FILE_INFO_DEFAULT
-						    | GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS);
-	if (result != GNOME_VFS_OK)
-		return;
-
-	info = gnome_vfs_file_info_new ();
-
-	stop = FALSE;
-	while (! stop) {
-		char    *rel_path;
-		gboolean recurse;
-
-		result = gnome_vfs_directory_read_next (handle, info);
-		if (result != GNOME_VFS_OK)
-			break;
-
-		/* Skip "." and "..".  */
-		if (info->name [0] == '.'
-		    && (info->name [1] == 0
-			|| (info->name [1] == '.' && info->name [2] == 0))) {
-			gnome_vfs_file_info_clear (info);
-			continue;
-		}
-
-		if (prefix == NULL)
-			rel_path = g_strdup (info->name);
-		else
-			rel_path = g_strconcat (prefix, info->name, NULL);
-
-		recurse = FALSE;
-		stop = ! graft_file_visitor (rel_path, info, state, &recurse);
-		
-		if (! stop
-		    && recurse
-		    && info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
-			GnomeVFSURI *new_uri;
-			char        *new_prefix;
-
-			if (prefix == NULL)
-				new_prefix = g_strconcat (info->name, "/",
-							  NULL);
-			else
-				new_prefix = g_strconcat (prefix, info->name,
-							  "/", NULL);
-
-			new_uri = gnome_vfs_uri_append_file_name (uri, info->name);
-
-			state->depth++;
-			create_graft_file (new_uri,
-					   new_prefix,
-					   state);
-			state->depth--;
-			graft_file_end_dir_visitor (state);
-
-			gnome_vfs_uri_unref (new_uri);
-			g_free (new_prefix);
-		}
-
-		g_free (rel_path);
-
-		gnome_vfs_file_info_clear (info);
-
-		if (stop)
-			break;
-	}
-
-	gnome_vfs_directory_close (handle);
-	gnome_vfs_file_info_unref (info);
-
-	profile_end ("end", NULL);
-}
-
 static gboolean  
 mkisofs_stdout_read (GIOChannel   *source,
 		     GIOCondition  condition,
@@ -933,25 +535,6 @@
 	return res;
 }
 
-/* this is an ugly hack until utf8/iconv support is added into upstream mkisofs */
-static gboolean
-ncb_mkisofs_supports_utf8 (void)
-{
-	char    *standard_error;
-	gboolean supported;
-	gboolean res;
-
-	res = g_spawn_command_line_sync ("mkisofs -input-charset utf8", NULL, &standard_error, NULL, NULL);
-	if (res && !g_strrstr (standard_error, "Unknown charset"))
-		supported = TRUE;
-	else
-		supported = FALSE;
-
-	g_free (standard_error);
-
-	return supported;
-}
-
 static gboolean
 start_async_with_watch (char        **args,
 			GPid         *ppid,
@@ -1158,8 +741,6 @@
 	GnomeVFSURI          *uri;
 	char                 *filelist = NULL;
 	struct mkisofs_state  state = {NULL};
-	char                 *tempdir;
-	GList                *l;
 	int                   stdout_pipe, stderr_pipe;
 	int                   i;
 	GError               *sub_error;
@@ -1193,55 +774,18 @@
 	mkisofs_output.error = NULL;
 	mkisofs_output.debug = flags & NAUTILUS_BURN_IMAGE_CREATE_DEBUG;
 
-	dirname = g_strdup_printf ("iso-%s.XXXXXX", g_get_user_name ());
-	tempdir = g_build_filename (g_get_tmp_dir (), dirname, NULL);
-	g_free (dirname);
-	state.tmpdir = mkdtemp (tempdir);
-
 	mkisofs_output.result = NAUTILUS_BURN_RECORDER_RESULT_ERROR;
 
-	if (state.tmpdir == 0) {
-		mkisofs_output.error = g_error_new (NAUTILUS_BURN_ISO_ERROR,
-						    NAUTILUS_BURN_ISO_ERROR_GENERAL,
-						    _("Unable to create temporary directory: %s."),
-						    g_strerror (errno));
-		goto cleanup;
-	}
-	
-	state.emptydir = g_build_filename (state.tmpdir, "emptydir", NULL);
-	g_mkdir (state.emptydir, 0777);
-	state.remove_files = g_list_prepend (state.remove_files, g_strdup (state.emptydir));
-
-	filelist = g_build_filename (state.tmpdir, "filelist", NULL);
-
-	state.graft_file = fopen (filelist, "w");
-	if (state.graft_file == NULL) {
-		mkisofs_output.error = g_error_new (NAUTILUS_BURN_ISO_ERROR, 
-						    NAUTILUS_BURN_ISO_ERROR_GENERAL,
-						    _("Unable to create temporary file: %s."),
-						    g_strerror (errno));
-		goto cleanup;
-	}
-	
 	uri = gnome_vfs_uri_new ("burn:///");
-	state.found_file = FALSE;
 
 	profile_start ("start", "creating file list");
-	create_graft_file (uri, NULL, &state);
+	filelist = create_graft_file (uri, NULL, &state, &mkisofs_output);
 	profile_end ("end", "creating file list");
 
 	gnome_vfs_uri_unref (uri);
 
-	fclose (state.graft_file);
-	state.remove_files = g_list_prepend (state.remove_files, g_strdup (filelist));
-
-	if (!state.found_file) {
-		mkisofs_output.error = g_error_new_literal (NAUTILUS_BURN_ISO_ERROR, 
-							    NAUTILUS_BURN_ISO_ERROR_GENERAL,
-							    _("There are no files to write to disc."));
-		mkisofs_output.result = NAUTILUS_BURN_RECORDER_RESULT_ERROR;
+	if (! filelist)
 		goto cleanup;
-	}
 
 	has_utf8_support = ncb_mkisofs_supports_utf8 ();
 
@@ -1421,16 +965,9 @@
 	mkisofs_output_ptr = NULL;
 
  cleanup:
-	for (l = state.remove_files; l != NULL; l = l->next) {
-		g_remove ((char *)l->data);
-		g_free (l->data);
-	}
-	g_list_free (state.remove_files);
-	
 	g_free (filelist);
-	g_free (state.emptydir);
-	g_rmdir (tempdir);
-	g_free (tempdir);
+	graft_file_cleanup (&state);
+
 	nautilus_burn_progress_set_image_spinning (FALSE);
 
 	if (mkisofs_output.result == NAUTILUS_BURN_RECORDER_RESULT_ERROR) {
Index: make-iso.h
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/make-iso.h,v
retrieving revision 1.17
diff -u -r1.17 make-iso.h
--- make-iso.h	7 Nov 2005 17:57:10 -0000	1.17
+++ make-iso.h	28 Feb 2006 19:22:21 -0000
@@ -24,6 +24,9 @@
  *          William Jon McCann <mccann@jhu.edu>
  */
 
+#ifndef __MAKE_ISO_H
+#define __MAKE_ISO_H
+
 #include <glib/gerror.h>
 
 G_BEGIN_DECLS
@@ -38,6 +41,7 @@
 } NautilusBurnIsoError;
 
 typedef enum {
+	NAUTILUS_BURN_IMAGE_TYPE_NO_IMAGE,
 	NAUTILUS_BURN_IMAGE_TYPE_UNKNOWN,
 	NAUTILUS_BURN_IMAGE_TYPE_ISO9660,
 	NAUTILUS_BURN_IMAGE_TYPE_BINCUE
@@ -67,3 +71,5 @@
 					    GError                     **error);
 
 G_END_DECLS
+
+#endif /* __MAKE_ISO_H */
Index: nautilus-burn-recorder.c
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/nautilus-burn-recorder.c,v
retrieving revision 1.40
diff -u -r1.40 nautilus-burn-recorder.c
--- nautilus-burn-recorder.c	14 Feb 2006 20:37:24 -0000	1.40
+++ nautilus-burn-recorder.c	28 Feb 2006 19:22:21 -0000
@@ -51,6 +51,10 @@
 
 #include "nautilus-burn-recorder.h"
 #include "nautilus-burn-recorder-marshal.h"
+#include "nautilus-cd-burner.h"
+#include "make-iso.h"
+#include "mkisofs-glue.h"
+
 
 #define CDR_SPEED 153600
 #define DVD_SPEED 1385000
@@ -218,7 +222,13 @@
 		g_free (track->contents.cue.filename);
 		break;
 	case NAUTILUS_BURN_RECORDER_TRACK_TYPE_DATA:
-		g_free (track->contents.data.filename);
+		/* track->contents is a union, thus we must free
+		 * iso.filename OR data.graftfile */
+		if (track->contents.iso.filename != NULL) {
+			g_free (track->contents.iso.filename);
+		} else {
+			g_free (track->contents.data.graftfile);
+		}
 		break;
 	case NAUTILUS_BURN_RECORDER_TRACK_TYPE_AUDIO:
 		g_free (track->contents.audio.filename);
@@ -597,6 +607,7 @@
 		       gpointer               data)
 {
 	NautilusBurnRecorder *recorder = data;
+	char		     *pos      = NULL;
 
 	if (line && process->debug) {
 		g_print ("growisofs stderr: %s", line);
@@ -641,8 +652,42 @@
 	} else if (strstr (line, ":-(") != NULL || strstr (line, "FATAL") != NULL) {
 		process->last_error = g_strdup (_("Unhandled error, aborting"));
 		process->result = NAUTILUS_BURN_RECORDER_RESULT_ERROR;
+	} else if ((pos = strstr (line, "estimate finish"))) {
+			char	fraction_str [7];
+			double	fraction;
+
+			if (sscanf (line, "%6c%% done, estimate finish",
+				    fraction_str) == 1) {
+				long secs = -1;
+
+				fraction_str [6] = 0;
+				fraction = g_strtod (fraction_str, NULL);
+
+				if (!process->changed_text) {
+					g_signal_emit (recorder,
+						       nautilus_burn_recorder_table_signals [ACTION_CHANGED], 0,
+						       NAUTILUS_BURN_RECORDER_ACTION_WRITING,
+						       NAUTILUS_BURN_RECORDER_MEDIA_DVD);
+				}
+
+				if (pos) {
+					struct tm tm;
+					time_t    t_finish;
+
+					pos += strlen ("estimate finish ");
+					/* mkisofs uses ctime for format time string */
+					strptime (pos, "%a %b %d %H:%M:%S %Y", &tm);
+					t_finish = mktime (&tm);
+					secs = difftime (t_finish, time (NULL));
+				}
+				g_signal_emit (recorder,
+					       nautilus_burn_recorder_table_signals [PROGRESS_CHANGED], 0,
+					       fraction / 100.0, secs);
+
+			}
 	}
 
+
 	return TRUE;
 }
 
@@ -1270,6 +1315,8 @@
 	char                      *speed_str, *dev_str;
 	NautilusBurnRecorderTrack *t;
 	int                        result;
+	char			  *image_str	= NULL;
+	gboolean		   on_the_fly	= FALSE;
 
 	if (g_list_length (tracks) != 1) {
 		g_warning ("Can only use growisofs on a single track");
@@ -1298,11 +1345,43 @@
 		g_ptr_array_add (argv, "-use-the-force-luke=tty");
 	}
 
+	on_the_fly = ((flags & NAUTILUS_BURN_RECORDER_WRITE_ON_THE_FLY) != 0) ;
+
+	if (on_the_fly) {
+		g_ptr_array_add (argv, "-graft-points");
+
+		g_ptr_array_add (argv, "-path-list");
+
+		g_ptr_array_add (argv, t->contents.data.graftfile);
+	} else {
+		image_str = g_strdup_printf ("=%s", t->contents.iso.filename);
+	}
+
 	g_ptr_array_add (argv, "-Z");
 
-	dev_str = g_strdup_printf ("%s=%s", drive->device, t->contents.data.filename);
+	dev_str = g_strdup_printf ("%s%s", drive->device,
+					   (on_the_fly) ? "" : image_str);
+	g_free (image_str);
+
 	g_ptr_array_add (argv, dev_str);
 
+	/* mkisofs options */
+	if (on_the_fly) {
+		gboolean has_utf8_support = ncb_mkisofs_supports_utf8 ();
+
+		g_ptr_array_add (argv, "-r");
+		if (t->contents.data.flags & NAUTILUS_BURN_IMAGE_CREATE_JOLIET) {
+			g_ptr_array_add (argv, "-J");
+		}
+		if (has_utf8_support) {
+			g_ptr_array_add (argv, "-input-charset");
+			g_ptr_array_add (argv, "utf8");
+		}
+
+		g_ptr_array_add (argv, "-V");
+		g_ptr_array_add (argv, (char *) t->contents.data.label);
+	}
+
 	g_ptr_array_add (argv, NULL);
 
 	result = nautilus_burn_recorder_run_process (recorder,
@@ -1510,7 +1589,7 @@
 			case NAUTILUS_BURN_RECORDER_TRACK_TYPE_DATA:
 				g_ptr_array_add (argv, "-data");
 				g_ptr_array_add (argv, "-nopad");
-				g_ptr_array_add (argv, track->contents.data.filename);
+				g_ptr_array_add (argv, track->contents.iso.filename);
 				break;
 			case NAUTILUS_BURN_RECORDER_TRACK_TYPE_AUDIO:
 				g_ptr_array_add (argv, "-copy");
Index: nautilus-burn-recorder.h
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/nautilus-burn-recorder.h,v
retrieving revision 1.8
diff -u -r1.8 nautilus-burn-recorder.h
--- nautilus-burn-recorder.h	14 Sep 2005 13:57:51 -0000	1.8
+++ nautilus-burn-recorder.h	28 Feb 2006 19:22:21 -0000
@@ -28,6 +28,7 @@
 
 #include <glib-object.h>
 #include <nautilus-burn-drive.h>
+#include "make-iso.h"
 
 G_BEGIN_DECLS
 
@@ -74,6 +75,11 @@
 		} audio;
 		struct {
 			char *filename;
+		} iso;
+		struct {
+			char				*graftfile;
+			const char			*label;
+			NautilusBurnImageCreateFlags	 flags;
 		} data;
 		struct {
 			char *filename;
@@ -89,7 +95,8 @@
 	NAUTILUS_BURN_RECORDER_WRITE_DISC_AT_ONCE	= 1 << 3,
 	NAUTILUS_BURN_RECORDER_WRITE_DEBUG		= 1 << 4,
 	NAUTILUS_BURN_RECORDER_WRITE_OVERBURN		= 1 << 5,
-	NAUTILUS_BURN_RECORDER_WRITE_BURNPROOF		= 1 << 6
+	NAUTILUS_BURN_RECORDER_WRITE_BURNPROOF		= 1 << 6,
+	NAUTILUS_BURN_RECORDER_WRITE_ON_THE_FLY		= 1 << 7
 } NautilusBurnRecorderWriteFlags;
 
 typedef enum {
Index: nautilus-cd-burner.c
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/nautilus-cd-burner.c,v
retrieving revision 1.180
diff -u -r1.180 nautilus-cd-burner.c
--- nautilus-cd-burner.c	10 Feb 2006 17:11:15 -0000	1.180
+++ nautilus-cd-burner.c	28 Feb 2006 19:22:22 -0000
@@ -45,7 +45,7 @@
 
 #include "nautilus-burn-drive-selection.h"
 #include "nautilus-cd-burner.h"
-#include "make-iso.h"
+#include "mkisofs-glue.h"
 
 #define MAX_ISO_NAME_LEN  32
 #define RESPONSE_OVERBURN 1
@@ -1368,13 +1368,18 @@
 	NautilusBurnImageType          image_type   = NAUTILUS_BURN_IMAGE_TYPE_UNKNOWN;
 	char                          *str;
 	int                            fd;
-	int                            res      = NAUTILUS_BURN_RECORDER_RESULT_ERROR;
+	int                            res	    = NAUTILUS_BURN_RECORDER_RESULT_ERROR;
 	gboolean                       try_overburn = FALSE;
+	gboolean		       on_the_fly   = TRUE;
 	NautilusBurnDrive             *source_drive;
 	const char                    *source_iso;
 	const char                    *source_cue;
 	gint64                         burn_size;
-	NautilusBurnMediaType          media_type = NAUTILUS_BURN_MEDIA_TYPE_UNKNOWN;
+	NautilusBurnMediaType          media_type   = NAUTILUS_BURN_MEDIA_TYPE_UNKNOWN;
+	NautilusBurnImageCreateFlags   image_flags  = 0;
+	struct mkisofs_state	       state	    = { NULL };
+	char			      *graftfile    = NULL;
+	GConfClient		      *gc;
 
 	source_drive = burn_data->source_drive;
 	source_iso   = burn_data->source_iso;
@@ -1383,6 +1388,8 @@
 
 	filename = NULL;
 
+	gc = gconf_client_get_default ();
+
 	if (drive->type == NAUTILUS_BURN_DRIVE_TYPE_FILE) {
 		char *disc_name = NULL;
 
@@ -1396,12 +1403,9 @@
 			return NAUTILUS_BURN_RECORDER_RESULT_CANCEL;
 	} else {
 		if (source_iso == NULL) {
-			GConfClient *gc;
 			char        *path;
 
-			gc = gconf_client_get_default ();
 			path = gconf_client_get_string (gc, "/apps/nautilus-cd-burner/temp_iso_dir", NULL);
-			g_object_unref (gc);
 			if (path != NULL && path[0] != '\0') {
 				filename = g_build_filename (path, "image.iso.XXXXXX", NULL);
 				fd = g_mkstemp (filename);
@@ -1446,14 +1450,16 @@
 	/* update the description now that we may know the media type */
 	update_progress_dialog_disc_type (drive, burn_data, media_type);
 
-	if (source_iso == NULL
-	    && source_cue == NULL) {
-		NautilusBurnImageCreateFlags image_flags = 0;
+	if (debug)
+		image_flags |= NAUTILUS_BURN_IMAGE_CREATE_DEBUG;
+	if (1)
+		image_flags |= NAUTILUS_BURN_IMAGE_CREATE_JOLIET;
+
+
+	on_the_fly = gconf_client_get_bool (gc, "/apps/nautilus-cd-burner/burn_dvd_on_the_fly", NULL);
 
-		if (debug)
-			image_flags |= NAUTILUS_BURN_IMAGE_CREATE_DEBUG;
-		if (1)
-			image_flags |= NAUTILUS_BURN_IMAGE_CREATE_JOLIET;
+	if (source_iso == NULL
+	    && source_cue == NULL && ! on_the_fly) {
 
 		cancel = CANCEL_MAKE_ISO;
 
@@ -1547,6 +1553,21 @@
 		toc_filename = g_strdup (source_cue);
 	} else if (source_iso) {
 		image_type = NAUTILUS_BURN_IMAGE_TYPE_ISO9660;
+	} else if (on_the_fly) {
+		GnomeVFSURI		*uri;
+		struct mkisofs_output	 mkisofs_output;
+
+		memset (&mkisofs_output, 0, sizeof (mkisofs_output));
+		mkisofs_output.error = NULL;
+		mkisofs_output.result = NAUTILUS_BURN_RECORDER_RESULT_ERROR;
+
+		uri = gnome_vfs_uri_new ("burn:///");
+
+		graftfile = create_graft_file (uri, NULL, &state, &mkisofs_output);
+
+		gnome_vfs_uri_unref (uri);
+
+		image_type = NAUTILUS_BURN_IMAGE_TYPE_NO_IMAGE;
 	}
 
 	if (drive->type == NAUTILUS_BURN_DRIVE_TYPE_FILE) {
@@ -1574,9 +1595,15 @@
 			/* TODO: make sure cue exists */
 			track->contents.cue.filename = g_strdup (toc_filename);
 			break;
+		case NAUTILUS_BURN_IMAGE_TYPE_NO_IMAGE:
+			track->type = NAUTILUS_BURN_RECORDER_TRACK_TYPE_DATA;
+			track->contents.data.graftfile = g_strdup (graftfile);
+			track->contents.data.flags = image_flags;
+			track->contents.data.label = label;
+			break;
 		case NAUTILUS_BURN_IMAGE_TYPE_ISO9660:
 			track->type = NAUTILUS_BURN_RECORDER_TRACK_TYPE_DATA;
-			track->contents.data.filename = g_strdup (filename);
+			track->contents.iso.filename = g_strdup (filename);
 			break;
 		default:
 			break;
@@ -1595,6 +1622,9 @@
 		if (overburn || try_overburn) {
 			record_flags |= NAUTILUS_BURN_RECORDER_WRITE_OVERBURN;
 		}
+		if (on_the_fly) {
+			record_flags |= NAUTILUS_BURN_RECORDER_WRITE_ON_THE_FLY;
+		}
 		if (1) {
 			record_flags |= NAUTILUS_BURN_RECORDER_WRITE_BURNPROOF;
 		}
@@ -1619,10 +1649,18 @@
 		if (source_iso == NULL) {
 			nautilus_burn_progress_temp_files_add (filename);
 		}
+
+		if (on_the_fly) {
+			graft_file_cleanup (&state);
+			g_free (graftfile);
+
+			g_free (track->contents.data.graftfile);
+		}
 	}
 
  out:
 	g_free (filename);
+	g_object_unref (gc);
 
 	return res;
 }
Index: ncb.schemas.in
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/ncb.schemas.in,v
retrieving revision 1.6
diff -u -r1.6 ncb.schemas.in
--- ncb.schemas.in	29 Jul 2004 22:17:21 -0000	1.6
+++ ncb.schemas.in	28 Feb 2006 19:22:22 -0000
@@ -64,5 +64,17 @@
 	</locale>
        </schema>
 
+      <schema>
+        <key>/schemas/apps/nautilus-cd-burner/burn_dvd_on_the_fly</key>
+	<applyto>/apps/nautilus-cd-burner/burn_dvd_on_the_fly</applyto>
+	<owner>nautilus-cd-burner</owner>
+	<type>bool</type>
+	<default>true</default>
+	<locale name="C">
+	  <short>Enable on the fly writing for DVDs</short>
+	  <long>Whether to burn DVDs on the fly (ie. without creating a temporary image).</long>
+	</locale>
+       </schema>
+
   </schemalist>
 </gconfschemafile>
