static gchar*
rb_disc_recorder_plugin_write_audio_project (const gchar 	*name,
					     GtkTreeModel       *model,
					     GError		**error)
{
        GtkTreeIter iter;
	xmlTextWriter *project;
	xmlDocPtr doc = NULL;
	xmlSaveCtxt *save;
	gint success;
    	gchar *path;
	int fd;
	int use_errno = 0;

        if (! gtk_tree_model_get_iter_first (model, &iter)) {
                g_set_error (error,
                             RB_RECORDER_ERROR,
                             RB_RECORDER_ERROR_GENERAL,
                             _("Unable to build an audio track list"));
                return NULL;
        }

	/* get a temporary path */
	path = g_build_filename (g_get_tmp_dir (), "brasero-tmp-project-XXXXXX",  NULL);
	fd = g_mkstemp (path);
	if (fd == -1) {
		g_set_error (error,
                 	     RB_RECORDER_ERROR,
                     	     RB_RECORDER_ERROR_GENERAL,
                    	     _("Unable to write audio project file %s: %s"),
			     path,
			     g_strerror (errno));
		rb_debug ("g_mkstemp failed");

		g_free (path);
		return NULL;
	}

	project = xmlNewTextWriterDoc (&doc, 0);
	if (!project) {
		g_remove (path);
		g_free (path);
		close (fd);

		g_set_error (error,
                 	     RB_RECORDER_ERROR,
                     	     RB_RECORDER_ERROR_GENERAL,
                    	     _("Unable to write audio project"));

		return NULL;
	}

	xmlTextWriterSetIndent (project, 1);
	xmlTextWriterSetIndentString (project, (xmlChar *) "\t");

	success = xmlTextWriterStartDocument (project,
					      NULL,
					      "UTF8",
					      NULL);
	if (success < 0)
		goto error;

	success = xmlTextWriterStartElement (project, (xmlChar *) "braseroproject");
	if (success < 0)
		goto error;

	/* write the name of the version */
	success = xmlTextWriterWriteElement (project,
					     (xmlChar *) "version",
					     (xmlChar *) "0.2");
	if (success < 0)
		goto error;

	if (name) {
		success = xmlTextWriterWriteElement (project,
						     (xmlChar *) "label",
						     (xmlChar *) name);
		if (success < 0)
			goto error;
	}

	success = xmlTextWriterStartElement (project, (xmlChar *) "track");
	if (success < 0)
		goto error;

	success = xmlTextWriterStartElement (project, (xmlChar *) "audio");
	if (success < 0)
		goto error;

        do {
		RhythmDBEntry  *entry;
		const char *str;
		xmlChar *escaped;

		gtk_tree_model_get (model, &iter, 0, &entry, -1);

		str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
		escaped = (xmlChar *) g_uri_escape_string (str, NULL, FALSE);
		success = xmlTextWriterWriteElement (project,
						    (xmlChar *) "uri",
						     escaped);
		g_free (escaped);

		if (success == -1)
			goto error;

		/* start of the song always 0 */
		success = xmlTextWriterWriteElement (project,
						     (xmlChar *) "start",
						     (xmlChar *) "0");
		if (success == -1)
			goto error;

		/* end of the song = duration (in seconds while brasero likes it
		 * in nanoseconds =( ) */
		/* Disable this for the moment and let brasero check the size
		 * itself. In case the user chooses on the fly burning we need
		 * a more precise duration or we'd end up burning the track
		 * incompletely or with a big padding */
		/*
		end = g_strdup_printf ("%"G_GINT64_FORMAT, (gint64) (song->duration * 1000000000LL));
		success = xmlTextWriterWriteElement (project,
						     (xmlChar *) "end",
						     (xmlChar *) end);

		g_free (end);
		if (success == -1)
			goto error;
		*/

		str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE);
		if (str) {
			escaped = (xmlChar *) g_uri_escape_string (str, NULL, FALSE);
			success = xmlTextWriterWriteElement (project,
							    (xmlChar *) "title",
							     escaped);
			g_free (escaped);

			if (success == -1)
				goto error;
		}

		str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
		if (str) {
			escaped = (xmlChar *) g_uri_escape_string (str, NULL, FALSE);
			success = xmlTextWriterWriteElement (project,
							    (xmlChar *) "artist",
							     escaped);
			g_free (escaped);

			if (success == -1)
				goto error;
		}

		/*
		if (song->composer) {
			escaped = (unsigned char *) g_uri_escape_string (song->composer, NULL, FALSE);
			success = xmlTextWriterWriteElement (project,
							    (xmlChar *) "composer",
							     escaped);
			g_free (escaped);

			if (success == -1)
				goto error;
		}
		*/
        } while (gtk_tree_model_iter_next (model, &iter));

	success = xmlTextWriterEndElement (project); /* audio */
	if (success < 0)
		goto error;

	success = xmlTextWriterEndElement (project); /* track */
	if (success < 0)
		goto error;

	success = xmlTextWriterEndElement (project); /* braseroproject */
	if (success < 0)
		goto error;

	success = xmlTextWriterEndDocument (project);
	if (success < 0)
		goto end_error;

	xmlFreeTextWriter (project);

	save = xmlSaveToFd (fd, "UTF8", XML_SAVE_FORMAT);
	if (save == NULL)
		goto save_error;

	if (xmlSaveDoc (save, doc) == -1)
		goto save_error;

	if (xmlSaveClose (save) == -1) {
		use_errno = errno;
		rb_debug ("xmlSaveClose failed");
		goto save_error;
	}

	xmlFreeDoc (doc);

	if (close (fd) == -1) {
		use_errno = errno;
		rb_debug ("close() failed");
		goto save_error;
	}

	return path;

error:
	/* cleanup */
	xmlTextWriterEndDocument (project);

end_error:
	xmlFreeTextWriter (project);

save_error:
	if (use_errno != 0) {
		g_set_error (error,
			     RB_RECORDER_ERROR,
			     RB_RECORDER_ERROR_GENERAL,
			     _("Unable to write audio project file %s: %s"),
			     path,
			     g_strerror (use_errno));
	} else {
		g_set_error (error,
			     RB_RECORDER_ERROR,
			     RB_RECORDER_ERROR_GENERAL,
			     _("Unable to write audio project"));
	}

	g_remove (path);
	g_free (path);
	close (fd);

	return NULL;
}
static char*
idol_disc_recorder_plugin_write_video_project (IdolDiscRecorderPlugin *pi,
						char **error)
{
	xmlTextWriter *project;
	xmlDocPtr doc = NULL;
	xmlSaveCtxt *save;
	xmlChar *escaped;
	gint success;
	char *title, *path, *uri;
	int fd;

	/* get a temporary path */
	path = g_build_filename (g_get_tmp_dir (), "brasero-tmp-project-XXXXXX",  NULL);
	fd = g_mkstemp (path);
	if (!fd) {
		g_free (path);

		*error = g_strdup (_("Unable to write a project."));
		return NULL;
	}

	project = xmlNewTextWriterDoc (&doc, 0);
	if (!project) {
		g_remove (path);
		g_free (path);
		close (fd);

		*error = g_strdup (_("Unable to write a project."));
		return NULL;
	}

	xmlTextWriterSetIndent (project, 1);
	xmlTextWriterSetIndentString (project, (xmlChar *) "\t");

	success = xmlTextWriterStartDocument (project,
					      NULL,
					      "UTF8",
					      NULL);
	if (success < 0)
		goto error;

	success = xmlTextWriterStartElement (project, (xmlChar *) "braseroproject");
	if (success < 0)
		goto error;

	/* write the name of the version */
	success = xmlTextWriterWriteElement (project,
					     (xmlChar *) "version",
					     (xmlChar *) "0.2");
	if (success < 0)
		goto error;

	title = idol_get_short_title (pi->idol);
	if (title) {
		success = xmlTextWriterWriteElement (project,
						     (xmlChar *) "label",
						     (xmlChar *) title);
		g_free (title);

		if (success < 0)
			goto error;
	}

	success = xmlTextWriterStartElement (project, (xmlChar *) "track");
	if (success < 0)
		goto error;

	success = xmlTextWriterStartElement (project, (xmlChar *) "video");
	if (success < 0)
		goto error;

	uri = idol_get_current_mrl (pi->idol);
	escaped = (unsigned char *) g_uri_escape_string (uri, NULL, FALSE);
	g_free (uri);

	success = xmlTextWriterWriteElement (project,
					     (xmlChar *) "uri",
					     escaped);
	g_free (escaped);
	if (success == -1)
		goto error;

	/* start of the song always 0 */
	success = xmlTextWriterWriteElement (project,
					     (xmlChar *) "start",
					     (xmlChar *) "0");
	if (success == -1)
		goto error;

	success = xmlTextWriterEndElement (project); /* video */
	if (success < 0)
		goto error;

	success = xmlTextWriterEndElement (project); /* track */
	if (success < 0)
		goto error;

	success = xmlTextWriterEndElement (project); /* braseroproject */
	if (success < 0)
		goto error;

	xmlTextWriterEndDocument (project);
	xmlFreeTextWriter (project);

	save = xmlSaveToFd (fd, "UTF8", XML_SAVE_FORMAT);
	xmlSaveDoc (save, doc);
	xmlSaveClose (save);

	xmlFreeDoc (doc);
	close (fd);

	return path;

error:

	/* cleanup */
	xmlTextWriterEndDocument (project);
	xmlFreeTextWriter (project);

	g_remove (path);
	g_free (path);
	close (fd);

	*error = g_strdup (_("Unable to write a project."));
	return NULL;
}
Esempio n. 3
0
gboolean set_menu_contents( GtkTreeModel *model )
{
	g_assert( GTK_IS_TREE_MODEL( model ) );

	gboolean return_value = FALSE;
        GtkTreeIter iter;

	xmlBufferPtr buffer;
	xmlTextWriterPtr writer;

	gchar *user_home_dir = NULL;
	gchar *user_menu_conf_file = NULL;
	gchar *user_menu_dir = NULL;

	FILE *fp;

	/* Initialize libxml */
	LIBXML_TEST_VERSION

	/* OK, let's go! */
	buffer = xmlBufferCreate();
	
	if ( buffer == NULL ) {
		g_warning( "set_menu_contents: failed to create xml buffer." );
		return FALSE;
	}

	writer = xmlNewTextWriterMemory( buffer, 0 );

	if ( writer == NULL ) {
		g_warning( "set_menu_contents: failed to create xml writer." );
		xmlBufferFree( buffer );
		xmlCleanupParser();
		return FALSE;
	}

	if ( xmlTextWriterStartDocument( writer, NULL, "UTF-8", NULL ) < 0 ) {
		g_warning( "set_menu_contents: failed to start the document." );
		goto cleanup_and_exit;

	}

        gtk_tree_model_get_iter_first (model, &iter);
        if ( xmlTextWriterStartElement( writer,
                                        BAD_CAST "Menu" ) < 0 ) {
               g_warning ( "set_menu_contents: failed to write root element");
               goto cleanup_and_exit;
        }

	if ( write_menu_conf( writer, GTK_TREE_STORE( model ), &iter ) == FALSE ) {
		g_warning( "set_menu_contents: failed to write menu conf." );
		goto cleanup_and_exit;
	}
        if ( xmlTextWriterEndElement( writer ) < 0 ) {
               g_warning ( "set_menu_contents: failed to write root element");
               goto cleanup_and_exit;
        }

        xmlTextWriterSetIndent( writer, 1 );

	/* End the document */
	if ( xmlTextWriterEndDocument( writer ) ) {
		g_warning( "et_menu_contents: failed to end the document." );
		goto cleanup_and_exit;
	} else {
		xmlFreeTextWriter( writer );
		writer = NULL;
	}

	user_home_dir = getenv( "HOME" );
	user_menu_conf_file = g_build_filename(
			user_home_dir, USER_MENU_DIR, MENU_FILE, NULL );

	/* Make sure we have the directory for user's menu file */
	user_menu_dir = g_path_get_dirname( user_menu_conf_file );
	
	if ( g_mkdir_with_parents( user_menu_dir, 0755  ) < 0 ) {
		g_warning( "set_menu_contents: "
				"failed to create directory '%s'.",
				user_menu_dir );
		goto cleanup_and_exit;
	}
	
	/* Always write to the user specific file */
	fp = fopen(user_menu_conf_file, "w");

	if (fp == NULL) {
		g_warning( "set_menu_contents: failed to open '%s' for writing.",
				user_menu_conf_file );
		goto cleanup_and_exit;
	} else {
		g_debug( "set_menu_contents: writing to '%s'.", user_menu_conf_file );
		return_value = TRUE;
	}

    fprintf(fp, "%s", (const char *) buffer->content);
	fclose(fp);


	cleanup_and_exit:

	if ( writer ) {
		xmlFreeTextWriter( writer );
	}

	xmlBufferFree( buffer );
	xmlCleanupParser();

	if ( user_menu_conf_file ) {
		g_free( user_menu_conf_file );
	}

	if ( user_menu_dir ) {
		g_free( user_menu_dir );
	}
	
	return return_value;
}
Esempio n. 4
0
static char * create_resource_list_xml(const LinphoneFriendList *list) {
	char *xml_content = NULL;
	MSList *elem;
	xmlBufferPtr buf;
	xmlTextWriterPtr writer;
	int err;

	if (ms_list_size(list->friends) <= 0) return NULL;

	buf = xmlBufferCreate();
	if (buf == NULL) {
		ms_error("%s: Error creating the XML buffer", __FUNCTION__);
		return NULL;
	}
	writer = xmlNewTextWriterMemory(buf, 0);
	if (writer == NULL) {
		ms_error("%s: Error creating the XML writer", __FUNCTION__);
		return NULL;
	}

	xmlTextWriterSetIndent(writer,1);
	err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
	if (err >= 0) {
		err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"resource-lists", (const xmlChar *)"urn:ietf:params:xml:ns:resource-lists");
	}
	if (err >= 0) {
		err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"xsi",
						    NULL, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance");
	}

	if (err>= 0) {
		err = xmlTextWriterStartElement(writer, (const xmlChar *)"list");
	}
	for (elem = list->friends; elem != NULL; elem = elem->next) {
		LinphoneFriend *friend = (LinphoneFriend *)elem->data;
		char *uri = linphone_address_as_string_uri_only(friend->uri);
		if (err >= 0) {
			err = xmlTextWriterStartElement(writer, (const xmlChar *)"entry");
		}
		if (err >= 0) {
			err = xmlTextWriterWriteAttribute(writer, (const xmlChar *)"uri", (const xmlChar *)uri);
		}
		if (err >= 0) {
			/* Close the "entry" element. */
			err = xmlTextWriterEndElement(writer);
		}
		if (uri) ms_free(uri);
	}
	if (err >= 0) {
		/* Close the "list" element. */
		err = xmlTextWriterEndElement(writer);
	}

	if (err >= 0) {
		/* Close the "resource-lists" element. */
		err = xmlTextWriterEndElement(writer);
	}
	if (err >= 0) {
		err = xmlTextWriterEndDocument(writer);
	}
	if (err > 0) {
		/* xmlTextWriterEndDocument returns the size of the content. */
		xml_content = ms_strdup((char *)buf->content);
	}
	xmlFreeTextWriter(writer);
	xmlBufferFree(buf);

	return xml_content;
}
Esempio n. 5
0
static int
ephy_node_db_write_to_xml_valist (EphyNodeDb *db,
                                  const xmlChar *filename,
                                  const xmlChar *root,
                                  const xmlChar *version,
                                  const xmlChar *comment,
                                  EphyNode *first_node,
                                  va_list argptr)
{
    xmlTextWriterPtr writer;
    EphyNode *node;
    int ret;

    LOG ("Saving node db to %s", filename);

    START_PROFILER ("Saving node db")

    /* FIXME: do we want to turn compression on ? */
    writer = xmlNewTextWriterFilename ((const char *)filename, 0);
    if (writer == NULL)
    {
        return -1;
    }

    ret = xmlTextWriterSetIndent (writer, 1);
    if (ret < 0) goto out;

    ret = xmlTextWriterSetIndentString (writer, (const xmlChar *)"  ");
    if (ret < 0) goto out;

    ret = xmlTextWriterStartDocument (writer, "1.0", NULL, NULL);
    if (ret < 0) goto out;

    ret = xmlTextWriterStartElement (writer, root);
    if (ret < 0) goto out;

    ret = xmlTextWriterWriteAttribute (writer, (const xmlChar *)"version", version);
    if (ret < 0) goto out;

    if (comment != NULL)
    {
        ret = xmlTextWriterWriteComment (writer, comment);
        if (ret < 0) goto out;
    }

    node = first_node;
    while (node != NULL)
    {
        GPtrArray *children;
        EphyNodeFilterFunc filter;
        gpointer user_data;
        int i;

        filter = va_arg (argptr, EphyNodeFilterFunc);
        user_data = va_arg (argptr, gpointer);

        children = ephy_node_get_children (node);
        for (i = 0; i < children->len; i++)
        {
            EphyNode *kid;

            kid = g_ptr_array_index (children, i);

            if (!filter || filter (kid, user_data))
            {
                ret = ephy_node_write_to_xml (kid, writer);
                if (ret < 0) break;
            }
        }
        if (ret < 0) break;

        node = va_arg (argptr, EphyNode *);
    }
    if (ret < 0) goto out;

    ret = xmlTextWriterEndElement (writer); /* root */
    if (ret < 0) goto out;

    ret = xmlTextWriterEndDocument (writer);
    if (ret < 0) goto out;

out:
    xmlFreeTextWriter (writer);

    STOP_PROFILER ("Saving node db")

    return ret >= 0 ? 0 : -1;
}
Esempio n. 6
0
int main( int argc, const char* argv[] )
{
#ifdef WIN32
     _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
    int ret=-1;
    time_t start_time=time(NULL);
    FILE *file=NULL;
    int writer_indent=0;
    pbool_t reader_mce=PTRUE;
    const char *fileName=NULL;
    for(int i=1;i<argc;i++) {
        if ((0==xmlStrcmp(_X("--understands"), _X(argv[i])) || 0==xmlStrcmp(_X("-u"), _X(argv[i]))) && i+1<argc) {
            i++; // skip namespace, registered later when parser was created.
        } else if ((0==xmlStrcmp(_X("--out"), _X(argv[i])) || 0==xmlStrcmp(_X("--out"), _X(argv[i]))) && i+1<argc && NULL==file) {
            const char *filename=argv[++i];
            file=fopen(filename, "w");
        } else if (0==xmlStrcmp(_X("--indent"), _X(argv[i]))) {
            writer_indent=1;
        } else if (0==xmlStrcmp(_X("--raw"), _X(argv[i]))) {
            reader_mce=PFALSE;
        } else if (NULL==fileName) {
            fileName=argv[i];
        } else {
            fprintf(stderr, "IGNORED: %s\n", argv[i]);
        }
    }
    xmlTextWriter *writer=xmlNewTextWriterFile(file);
    if (NULL==fileName || NULL==writer) {
        printf("mcepp [--understands NAMESPACE] [--out FILENAME] [--indent] [--raw] [FILENAME | - ]\n\n");
        printf("Sample: mcepp sample.xml\n");
    } else {
        xmlInitParser();
        xmlTextWriterSetIndent(writer, writer_indent);
        mceTextReader_t mceTextReader;
        mceTextReaderInit(&mceTextReader, ('-'==fileName[0] && 0==fileName[1]?xmlReaderForFd(0, NULL, NULL, 0):xmlReaderForFile(fileName, NULL, 0)));
        mceTextReaderDisableMCE(&mceTextReader, !reader_mce);
        for(int i=1;i<argc;i++) {
            if ((0==xmlStrcmp(_X("--understands"), _X(argv[i])) || 0==xmlStrcmp(_X("-u"), _X(argv[i]))) && i+1<argc) {
                const xmlChar *ns=_X(argv[++i]);
                mceTextReaderUnderstandsNamespace(&mceTextReader, ns);
            }
        }

        if (-1==mceTextReaderDump(&mceTextReader, writer, PFALSE)) {
            ret=mceTextReaderGetError(&mceTextReader);
        } else {
            ret=0;
        }
        mceTextReaderCleanup(&mceTextReader);
        xmlCleanupParser();
    }
    if (NULL!=writer) xmlFreeTextWriter(writer);
    if (NULL!=file) fclose(file);
    time_t end_time=time(NULL);
    fprintf(stderr, "time %.2lfsec\n", difftime(end_time, start_time));
#ifdef WIN32
    OPC_ASSERT(!_CrtDumpMemoryLeaks());
#endif
    return ret;
}
Esempio n. 7
0
static RejillaBurnResult
rejilla_vcd_imager_generate_xml_file (RejillaProcess *process,
				      const gchar *path,
				      GError **error)
{
	RejillaVcdImagerPrivate *priv;
	GSList *tracks = NULL;
	xmlTextWriter *xml;
	gchar buffer [64];
	gint success;
	GSList *iter;
	gchar *name;
	gint i;

	REJILLA_JOB_LOG (process, "Creating (S)VCD layout xml file (%s)", path);

	xml = xmlNewTextWriterFilename (path, 0);
	if (!xml)
		return REJILLA_BURN_ERR;

	priv = REJILLA_VCD_IMAGER_PRIVATE (process);

	xmlTextWriterSetIndent (xml, 1);
	xmlTextWriterSetIndentString (xml, (xmlChar *) "\t");

	success = xmlTextWriterStartDocument (xml,
					      NULL,
					      "UTF8",
					      NULL);
	if (success < 0)
		goto error;

	success = xmlTextWriterWriteDTD (xml,
					(xmlChar *) "videocd",
					(xmlChar *) "-//GNU//DTD VideoCD//EN",
					(xmlChar *) "http://www.gnu.org/software/vcdimager/videocd.dtd",
					(xmlChar *) NULL);
	if (success < 0)
		goto error;

	/* let's start */
	success = xmlTextWriterStartElement (xml, (xmlChar *) "videocd");
	if (success < 0)
		goto error;

	success = xmlTextWriterWriteAttribute (xml,
					       (xmlChar *) "xmlns",
					       (xmlChar *) "http://www.gnu.org/software/vcdimager/1.0/");
	if (success < 0)
		goto error;

	if (priv->svcd)
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "class",
						       (xmlChar *) "svcd");
	else
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "class",
						       (xmlChar *) "vcd");

	if (success < 0)
		goto error;

	if (priv->svcd)
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "version",
						       (xmlChar *) "1.0");
	else
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "version",
						       (xmlChar *) "2.0");
	if (success < 0)
		goto error;

	/* info part */
	success = xmlTextWriterStartElement (xml, (xmlChar *) "info");
	if (success < 0)
		goto error;

	/* name of the volume */
	name = NULL;
	rejilla_job_get_audio_title (REJILLA_JOB (process), &name);
	success = xmlTextWriterWriteElement (xml,
					     (xmlChar *) "album-id",
					     (xmlChar *) name);
	g_free (name);
	if (success < 0)
		goto error;

	/* number of CDs */
	success = xmlTextWriterWriteElement (xml,
					     (xmlChar *) "volume-count",
					     (xmlChar *) "1");
	if (success < 0)
		goto error;

	/* CD number */
	success = xmlTextWriterWriteElement (xml,
					     (xmlChar *) "volume-number",
					     (xmlChar *) "1");
	if (success < 0)
		goto error;

	/* close info part */
	success = xmlTextWriterEndElement (xml);
	if (success < 0)
		goto error;

	/* Primary Volume descriptor */
	success = xmlTextWriterStartElement (xml, (xmlChar *) "pvd");
	if (success < 0)
		goto error;

	/* NOTE: no need to convert a possible non compliant name as this will 
	 * be done by vcdimager. */
	name = NULL;
	rejilla_job_get_audio_title (REJILLA_JOB (process), &name);
	success = xmlTextWriterWriteElement (xml,
					     (xmlChar *) "volume-id",
					     (xmlChar *) name);
	g_free (name);
	if (success < 0)
		goto error;

	/* Makes it CD-i compatible */
	success = xmlTextWriterWriteElement (xml,
					     (xmlChar *) "system-id",
					     (xmlChar *) "CD-RTOS CD-BRIDGE");
	if (success < 0)
		goto error;

	/* Close Primary Volume descriptor */
	success = xmlTextWriterEndElement (xml);
	if (success < 0)
		goto error;

	/* the tracks */
	success = xmlTextWriterStartElement (xml, (xmlChar *) "sequence-items");
	if (success < 0)
		goto error;

	/* get all tracks */
	rejilla_job_get_tracks (REJILLA_JOB (process), &tracks);
	priv->num_tracks = g_slist_length (tracks);
	for (i = 0, iter = tracks; iter; iter = iter->next, i++) {
		RejillaTrack *track;
		gchar *video;

		track = iter->data;
		success = xmlTextWriterStartElement (xml, (xmlChar *) "sequence-item");
		if (success < 0)
			goto error;

		video = rejilla_track_stream_get_source (REJILLA_TRACK_STREAM (track), FALSE);
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "src",
						       (xmlChar *) video);
		g_free (video);

		if (success < 0)
			goto error;

		sprintf (buffer, "track-%i", i);
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "id",
						       (xmlChar *) buffer);
		if (success < 0)
			goto error;

		/* close sequence-item */
		success = xmlTextWriterEndElement (xml);
		if (success < 0)
			goto error;
	}

	/* sequence-items */
	success = xmlTextWriterEndElement (xml);
	if (success < 0)
		goto error;

	/* the navigation */
	success = xmlTextWriterStartElement (xml, (xmlChar *) "pbc");
	if (success < 0)
		goto error;

	/* get all tracks */
	rejilla_job_get_tracks (REJILLA_JOB (process), &tracks);
	for (i = 0, iter = tracks; iter; iter = iter->next, i++) {
		RejillaTrack *track;

		track = iter->data;

		sprintf (buffer, "playlist-%i", i);
		success = xmlTextWriterStartElement (xml, (xmlChar *) "playlist");
		if (success < 0)
			goto error;

		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "id",
						       (xmlChar *) buffer);
		if (success < 0)
			goto error;

		success = xmlTextWriterWriteElement (xml,
						     (xmlChar *) "wait",
						     (xmlChar *) "0");
		if (success < 0)
			goto error;

		success = xmlTextWriterStartElement (xml, (xmlChar *) "play-item");
		if (success < 0)
			goto error;

		sprintf (buffer, "track-%i", i);
		success = xmlTextWriterWriteAttribute (xml,
						       (xmlChar *) "ref",
						       (xmlChar *) buffer);
		if (success < 0)
			goto error;

		/* play-item */
		success = xmlTextWriterEndElement (xml);
		if (success < 0)
			goto error;

		/* playlist */
		success = xmlTextWriterEndElement (xml);
		if (success < 0)
			goto error;
	}

	/* pbc */
	success = xmlTextWriterEndElement (xml);
	if (success < 0)
		goto error;

	/* close videocd */
	success = xmlTextWriterEndElement (xml);
	if (success < 0)
		goto error;

	xmlTextWriterEndDocument (xml);
	xmlFreeTextWriter (xml);

	return REJILLA_BURN_OK;

error:

	REJILLA_JOB_LOG (process, "Error");

	/* close everything */
	xmlTextWriterEndDocument (xml);
	xmlFreeTextWriter (xml);

	/* FIXME: get the error */

	return REJILLA_BURN_ERR;
}