summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcus <marcus@df743ca5-7f9a-e211-a948-0013205c9059>2008-05-14 10:10:41 +0800
committermarcus <marcus@df743ca5-7f9a-e211-a948-0013205c9059>2008-05-14 10:10:41 +0800
commit5a79bf43b13b13189baa1824b8b3fb029464aa0b (patch)
tree45975c5272e9a8c9f5514c6b91858799ee697cf3
parent02807bdcb78a7514c33a38c18f846b5a6af982af (diff)
downloadmarcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.tar
marcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.tar.gz
marcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.tar.bz2
marcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.tar.lz
marcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.tar.xz
marcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.tar.zst
marcuscom-ports-5a79bf43b13b13189baa1824b8b3fb029464aa0b.zip
Chase the totem-pl-parser shared lib version.
git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@10944 df743ca5-7f9a-e211-a948-0013205c9059
-rw-r--r--audio/rhythmbox-devel/Makefile137
-rw-r--r--audio/rhythmbox-devel/distinfo3
-rw-r--r--audio/rhythmbox-devel/files/patch-configure29
-rw-r--r--audio/rhythmbox-devel/files/patch-plugins_cd-recorder_rb-recorder-gst.c12
-rw-r--r--audio/rhythmbox-devel/files/patch-plugins_daap_rb-daap-src.c26
-rw-r--r--audio/rhythmbox-devel/files/patch-podcast_rb-podcast-parse.h10
-rw-r--r--audio/rhythmbox-devel/pkg-descr5
-rw-r--r--audio/rhythmbox-devel/pkg-plist588
-rw-r--r--audio/rhythmbox/Makefile121
-rw-r--r--audio/rhythmbox/distinfo3
-rw-r--r--audio/rhythmbox/files/patch-plugins_cd-recorder_rb-recorder-gst.c12
-rw-r--r--audio/rhythmbox/files/patch-plugins_daap_rb-daap-src.c26
-rw-r--r--audio/rhythmbox/files/patch-plugins_ipod_rb-ipod-source.c51
-rw-r--r--audio/rhythmbox/files/patch-podcast_rb-podcast-parse.h10
-rw-r--r--audio/rhythmbox/pkg-descr5
-rw-r--r--audio/rhythmbox/pkg-plist442
-rw-r--r--sysutils/brasero/Makefile41
-rw-r--r--sysutils/brasero/distinfo3
-rw-r--r--sysutils/brasero/files/patch-configure264
-rw-r--r--sysutils/brasero/files/patch-src_Makefile.in275
-rw-r--r--sysutils/brasero/files/patch-src_brasero-ncb.h12
-rw-r--r--sysutils/brasero/files/patch-src_burn-job.c31
-rw-r--r--sysutils/brasero/files/patch-src_burn-job.h12
-rw-r--r--sysutils/brasero/files/patch-src_burn-medium-cam.c1928
-rw-r--r--sysutils/brasero/files/patch-src_burn-medium-scsi.c2073
-rw-r--r--sysutils/brasero/files/patch-src_burn-medium.c2073
-rw-r--r--sysutils/brasero/files/patch-src_cam1361
-rw-r--r--sysutils/brasero/files/patch-src_plugins_cdrtools_burn-cdrecord.c11
-rw-r--r--sysutils/brasero/pkg-descr23
-rw-r--r--sysutils/brasero/pkg-plist245
-rw-r--r--x11-toolkits/py-gnome-desktop/Makefile63
-rw-r--r--x11-toolkits/py-gnome-desktop/distinfo3
-rw-r--r--x11-toolkits/py-gnome-desktop/files/patch-gtop_gtop.c20
-rw-r--r--x11-toolkits/py-gnome-desktop/pkg-descr2
-rw-r--r--x11-toolkits/py-gnome-desktop/pkg-plist135
35 files changed, 10055 insertions, 0 deletions
diff --git a/audio/rhythmbox-devel/Makefile b/audio/rhythmbox-devel/Makefile
new file mode 100644
index 000000000..6a896fedf
--- /dev/null
+++ b/audio/rhythmbox-devel/Makefile
@@ -0,0 +1,137 @@
+# New ports collection makefile for: rhythmbox
+# Date created: 17 August 2003
+# Whom: Joe Marcus Clarke <marcus@FreeBSD.org>
+#
+# $FreeBSD$
+# $MCom: ports/audio/rhythmbox-devel/Makefile,v 1.90 2008/03/17 04:31:25 marcus Exp $
+#
+
+PORTNAME= rhythmbox
+PORTVERSION= 0.11.5
+PORTREVISION= 2
+CATEGORIES= audio gnome
+MASTER_SITES= ${MASTER_SITE_GNOME}
+MASTER_SITE_SUBDIR= sources/${PORTNAME}/0.11
+DIST_SUBDIR= gnome2
+
+MAINTAINER= marcus@FreeBSD.org
+COMMENT= Audio player for GNOME
+
+LIB_DEPENDS= musicbrainz.4:${PORTSDIR}/audio/libmusicbrainz \
+ id3tag.0:${PORTSDIR}/audio/libid3tag \
+ totem-plparser.12:${PORTSDIR}/multimedia/totem-pl-parser \
+ dbus-glib-1.2:${PORTSDIR}/devel/dbus-glib \
+ sexy.2:${PORTSDIR}/x11-toolkits/libsexy \
+ soup-2.4.1:${PORTSDIR}/devel/libsoup \
+ gnome-media-profiles.0:${PORTSDIR}/audio/gnome-media
+
+NO_LATEST_LINK= yes
+
+USE_BZIP2= yes
+USE_GETTEXT= yes
+INSTALLS_OMF= yes
+USE_GMAKE= yes
+USE_GNOME= gnomehack intlhack gnomeprefix libgnomeui nautiluscdburner
+WANT_GNOME= yes
+USE_GSTREAMER= flac mp3 gnomevfs gconf jpeg
+USE_AUTOTOOLS= libtool:15
+CONFIGURE_ARGS= --enable-nautilus-menu --with-playback=gstreamer-0-10 \
+ --disable-vala
+INSTALLS_ICONS= yes
+USE_LDCONFIG= yes
+CONFIGURE_ENV= LIBS="-lm" \
+ LDFLAGS="-L${LOCALBASE}/lib" \
+ CPPFLAGS="-I${LOCALBASE}/include"
+
+GCONF_SCHEMAS= rhythmbox.schemas
+
+OPTIONS= DAAP "Enable iTunes music sharing" off \
+ IPOD "Enable iPod support" on \
+ FAAD "Enable FAAD decoder support" off \
+ NOTIFY "Enable libnotify support" on \
+ VORBIS "Enable Ogg/Vorbis support" on \
+ LIRC "Enable Infrared syncing support" off \
+ GECKO_PLUGIN "Enable iTunes browser plugin" on
+# GDA "Enable GDA database storage" off
+
+.include <bsd.port.pre.mk>
+
+.if !defined(WITHOUT_VORBIS)
+USE_GSTREAMER+= vorbis
+.else
+CONFIGURE_ARGS+= --disable-vorbis --disable-vorbistest
+.endif
+
+.if defined(WITH_FAAD)
+USE_GSTREAMER+= faad
+.endif
+
+#.if defined(WITH_GDA)
+#USE_GNOME+= libgda2
+#CONFIGURE_ARGS+=--with-database=libgda
+#.else
+CONFIGURE_ARGS+=--with-database=tree
+#.endif
+
+.if defined(WITH_LIRC)
+LIB_DEPENDS+= lirc_client.1:${PORTSDIR}/comms/lirc
+PLIST_SUB+= LIRC=""
+CONFIGURE_ARGS+=--enable-lirc
+.else
+CONFIGURE_ARGS+=--disable-lirc
+PLIST_SUB+= LIRC="@comment "
+.endif
+
+.if defined(WITH_DAAP)
+CONFIGURE_ARGS+= --enable-daap --with-mdns=avahi
+LIB_DEPENDS+= avahi-client:${PORTSDIR}/net/avahi-app \
+ gnome-keyring:${PORTSDIR}/security/gnome-keyring
+PLIST_SUB+= DAAP=""
+.else
+.if exists(${LOCALBASE}/lib/libavahi-client.a)
+LIB_DEPENDS+= avahi-client:${PORTSDIR}/net/avahi-app
+.endif
+CONFIGURE_ARGS+= --disable-daap
+PLIST_SUB+= DAAP="@comment "
+.endif
+
+.if !defined(WITHOUT_NOTIFY)
+LIB_DEPENDS+= notify.1:${PORTSDIR}/devel/libnotify
+RUN_DEPENDS+= ${LOCALBASE}/libexec/notification-daemon:${PORTSDIR}/deskutils/notification-daemon
+.else
+CONFIGURE_ARGS+= --disable-libnotify
+.endif
+
+.if exists(${LOCALBASE}/libdata/pkgconfig/gst-python-0.10.pc)
+USE_PYTHON= yes
+.include "${PORTSDIR}/Mk/bsd.python.mk"
+USE_GSTREAMER+= python
+CONFIGURE_ARGS+=--enable-python
+PLIST_SUB+= PYTHON=""
+.else
+CONFIGURE_ARGS+=--disable-python
+PLIST_SUB+= PYTHON="@comment "
+.endif
+
+.if !defined(WITHOUT_IPOD)
+LIB_DEPENDS+= gpod.3:${PORTSDIR}/audio/libgpod
+CONFIGURE_ARGS+=--with-ipod
+PLIST_SUB+= IPOD=""
+.else
+CONFIGURE_ARGS+=--without-ipod
+PLIST_SUB+= IPOD="@comment "
+.endif
+
+.if !defined(WITHOUT_GECKO_PLUGIN)
+USE_GECKO= firefox mozilla seamonkey xulrunner<->firefox firefox-devel<->firefox
+.include "${PORTSDIR}/www/mozilla/bsd.gecko.mk"
+CONFIGURE_ARGS+=--enable-browser-plugin \
+ --with-gecko=${GECKO}
+CONFIGURE_ENV+= MOZILLA_PLUGINDIR=${BROWSER_PLUGINS_DIR}
+PLIST_SUB+= GECKO_PLUGIN=""
+.else
+CONFIGURE_ARGS+=--disable-browser-plugin
+PLIST_SUB+= GECKO_PLUGIN="@comment "
+.endif
+
+.include <bsd.port.post.mk>
diff --git a/audio/rhythmbox-devel/distinfo b/audio/rhythmbox-devel/distinfo
new file mode 100644
index 000000000..d5e05a801
--- /dev/null
+++ b/audio/rhythmbox-devel/distinfo
@@ -0,0 +1,3 @@
+MD5 (gnome2/rhythmbox-0.11.5.tar.bz2) = 967440dd984ec724e7e7992d5bd57bbd
+SHA256 (gnome2/rhythmbox-0.11.5.tar.bz2) = 26e9fd040bcd04cf9d98bccfd43fdd4438cad9a1cbc478bdb83dd7b3c3654f35
+SIZE (gnome2/rhythmbox-0.11.5.tar.bz2) = 4485762
diff --git a/audio/rhythmbox-devel/files/patch-configure b/audio/rhythmbox-devel/files/patch-configure
new file mode 100644
index 000000000..cb7075d40
--- /dev/null
+++ b/audio/rhythmbox-devel/files/patch-configure
@@ -0,0 +1,29 @@
+--- configure.orig 2008-03-17 00:11:17.000000000 -0400
++++ configure 2008-03-17 00:26:52.000000000 -0400
+@@ -14152,7 +14152,7 @@ else
+ echo "${ECHO_T}yes" >&6; }
+ have_gio=yes
+ fi
+-if test x$have_gio == "xyes"; then
++if test x$have_gio = "xyes"; then
+
+ cat >>confdefs.h <<\_ACEOF
+ #define HAVE_GIO 1
+@@ -14244,7 +14244,7 @@ echo "$as_me: error: HAL support explici
+ { (exit 1); exit 1; }; }
+ fi
+
+- if test "x$enable_hal" == "xyes"; then
++ if test "x$enable_hal" = "xyes"; then
+
+ cat >>confdefs.h <<\_ACEOF
+ #define HAVE_HAL 1
+@@ -21807,7 +21807,7 @@ echo "${ECHO_T}yes" >&6; }
+ :
+ fi
+ fi
+-MOZILLA_PLUGINDIR="${MOZILLA_PLUGINDIR:="\${libdir}/mozilla/plugins"}"
++MOZILLA_PLUGINDIR="${MOZILLA_PLUGINDIR}"
+
+
+ if test x$enable_browser_plugin = xyes; then
diff --git a/audio/rhythmbox-devel/files/patch-plugins_cd-recorder_rb-recorder-gst.c b/audio/rhythmbox-devel/files/patch-plugins_cd-recorder_rb-recorder-gst.c
new file mode 100644
index 000000000..c70afd0dc
--- /dev/null
+++ b/audio/rhythmbox-devel/files/patch-plugins_cd-recorder_rb-recorder-gst.c
@@ -0,0 +1,12 @@
+--- plugins/cd-recorder/rb-recorder-gst.c.orig Wed Aug 10 20:06:11 2005
++++ plugins/cd-recorder/rb-recorder-gst.c Wed Aug 10 20:06:31 2005
+@@ -25,7 +25,9 @@
+ #include <string.h>
+ #include <math.h>
+ #include <time.h>
++#ifndef __FreeBSD__
+ #include <sys/vfs.h>
++#endif
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
diff --git a/audio/rhythmbox-devel/files/patch-plugins_daap_rb-daap-src.c b/audio/rhythmbox-devel/files/patch-plugins_daap_rb-daap-src.c
new file mode 100644
index 000000000..4d9bb5178
--- /dev/null
+++ b/audio/rhythmbox-devel/files/patch-plugins_daap_rb-daap-src.c
@@ -0,0 +1,26 @@
+--- plugins/daap/rb-daap-src.c.orig Fri Jan 27 21:11:13 2006
++++ plugins/daap/rb-daap-src.c Thu Feb 2 02:07:48 2006
+@@ -34,6 +34,7 @@
+ #include <sys/ioctl.h>
+ #include <netdb.h>
+ #include <unistd.h>
++#include <signal.h>
+ #include <ctype.h>
+
+ #include <libsoup/soup-headers.h>
+@@ -435,7 +436,14 @@ rb_daap_src_write (RBDAAPSrc *src, const
+ size_t bytes_written = 0;
+
+ while (bytes_written < count) {
+- ssize_t wrote = send (src->sock_fd, buf + bytes_written, count - bytes_written, MSG_NOSIGNAL);
++ ssize_t wrote;
++#ifdef MSG_NOSIGNAL
++ wrote = send (src->sock_fd, buf + bytes_written, count - bytes_written, MSG_NOSIGNAL);
++#else
++ signal (SIGPIPE, SIG_IGN);
++ wrote = send (src->sock_fd, buf + bytes_written, count - bytes_written, 0);
++ signal (SIGPIPE, SIG_DFL);
++#endif
+
+ if (wrote < 0) {
+ GST_WARNING ("error while writing: %s", g_strerror (errno));
diff --git a/audio/rhythmbox-devel/files/patch-podcast_rb-podcast-parse.h b/audio/rhythmbox-devel/files/patch-podcast_rb-podcast-parse.h
new file mode 100644
index 000000000..2208b3205
--- /dev/null
+++ b/audio/rhythmbox-devel/files/patch-podcast_rb-podcast-parse.h
@@ -0,0 +1,10 @@
+--- podcast/rb-podcast-parse.h.orig Mon Nov 28 13:51:28 2005
++++ podcast/rb-podcast-parse.h Mon Nov 28 13:51:05 2005
+@@ -22,6 +22,7 @@
+ #ifndef RB_PODCAST_PARSE_H
+ #define RB_PODCAST_PARSE_H
+
++#include <inttypes.h>
+ #include <glib.h>
+
+ typedef struct
diff --git a/audio/rhythmbox-devel/pkg-descr b/audio/rhythmbox-devel/pkg-descr
new file mode 100644
index 000000000..9c4ecf6ca
--- /dev/null
+++ b/audio/rhythmbox-devel/pkg-descr
@@ -0,0 +1,5 @@
+Rhythmbox is an integrated music management application, originally inspired by
+Apple's iTunes. It is free software, designed to work well under the GNOME
+Desktop, and based on the powerful GStreamer media framework.
+
+WWW: http://www.gnome.org/projects/rhythmbox/
diff --git a/audio/rhythmbox-devel/pkg-plist b/audio/rhythmbox-devel/pkg-plist
new file mode 100644
index 000000000..2ba9b876a
--- /dev/null
+++ b/audio/rhythmbox-devel/pkg-plist
@@ -0,0 +1,588 @@
+bin/rhythmbox
+bin/rhythmbox-client
+%%GECKO_PLUGIN%%lib/browser_plugins/librhythmbox-itms-detection-plugin.a
+%%GECKO_PLUGIN%%lib/browser_plugins/librhythmbox-itms-detection-plugin.la
+%%GECKO_PLUGIN%%lib/browser_plugins/librhythmbox-itms-detection-plugin.so
+lib/librhythmbox-core.a
+lib/librhythmbox-core.la
+lib/librhythmbox-core.so
+lib/librhythmbox-core.so.0
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/AmazonCoverArtSearch.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/AmazonCoverArtSearch.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/AmazonCoverArtSearch.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/CoverArtDatabase.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/CoverArtDatabase.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/CoverArtDatabase.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/LocalCoverArtSearch.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/LocalCoverArtSearch.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/LocalCoverArtSearch.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/PodcastCoverArtSearch.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/PodcastCoverArtSearch.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/PodcastCoverArtSearch.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/artdisplay.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/rhythmbox-missing-artwork.svg
+lib/rhythmbox/plugins/audiocd/audiocd-ui.xml
+lib/rhythmbox/plugins/audiocd/audiocd.rb-plugin
+lib/rhythmbox/plugins/audiocd/libaudiocd.a
+lib/rhythmbox/plugins/audiocd/libaudiocd.la
+lib/rhythmbox/plugins/audiocd/libaudiocd.so
+lib/rhythmbox/plugins/audiocd/multiple-album.glade
+lib/rhythmbox/plugins/audioscrobbler/as-icon.png
+lib/rhythmbox/plugins/audioscrobbler/audioscrobbler-prefs.glade
+lib/rhythmbox/plugins/audioscrobbler/audioscrobbler-ui.xml
+lib/rhythmbox/plugins/audioscrobbler/audioscrobbler.rb-plugin
+lib/rhythmbox/plugins/audioscrobbler/libaudioscrobbler.a
+lib/rhythmbox/plugins/audioscrobbler/libaudioscrobbler.la
+lib/rhythmbox/plugins/audioscrobbler/libaudioscrobbler.so
+lib/rhythmbox/plugins/cd-recorder/cd-recorder.rb-plugin
+lib/rhythmbox/plugins/cd-recorder/libcd-recorder.a
+lib/rhythmbox/plugins/cd-recorder/libcd-recorder.la
+lib/rhythmbox/plugins/cd-recorder/libcd-recorder.so
+lib/rhythmbox/plugins/cd-recorder/recorder.glade
+%%DAAP%%lib/rhythmbox/plugins/daap/daap-prefs.glade
+%%DAAP%%lib/rhythmbox/plugins/daap/daap-ui.xml
+%%DAAP%%lib/rhythmbox/plugins/daap/daap.rb-plugin
+%%DAAP%%lib/rhythmbox/plugins/daap/libdaap.a
+%%DAAP%%lib/rhythmbox/plugins/daap/libdaap.la
+%%DAAP%%lib/rhythmbox/plugins/daap/libdaap.so
+lib/rhythmbox/plugins/generic-player/generic-player-ui.xml
+lib/rhythmbox/plugins/generic-player/generic-player.rb-plugin
+lib/rhythmbox/plugins/generic-player/libgeneric-player.a
+lib/rhythmbox/plugins/generic-player/libgeneric-player.la
+lib/rhythmbox/plugins/generic-player/libgeneric-player.so
+%%IPOD%%lib/rhythmbox/plugins/ipod/ipod-ui.xml
+%%IPOD%%lib/rhythmbox/plugins/ipod/ipod.rb-plugin
+%%IPOD%%lib/rhythmbox/plugins/ipod/libipod.a
+%%IPOD%%lib/rhythmbox/plugins/ipod/libipod.la
+%%IPOD%%lib/rhythmbox/plugins/ipod/libipod.so
+lib/rhythmbox/plugins/iradio/iradio-initial.pls
+lib/rhythmbox/plugins/iradio/iradio-ui.xml
+lib/rhythmbox/plugins/iradio/iradio.rb-plugin
+lib/rhythmbox/plugins/iradio/libiradio.a
+lib/rhythmbox/plugins/iradio/libiradio.la
+lib/rhythmbox/plugins/iradio/libiradio.so
+lib/rhythmbox/plugins/iradio/station-properties.glade
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoConfigureDialog.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoConfigureDialog.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoConfigureDialog.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSaxHandler.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSaxHandler.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSaxHandler.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSource.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSource.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSource.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo-loading.glade
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo-prefs.glade
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo_logo.png
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo_logo_medium.png
+%%LIRC%%lib/rhythmbox/plugins/lirc/librblirc.a
+%%LIRC%%lib/rhythmbox/plugins/lirc/librblirc.la
+%%LIRC%%lib/rhythmbox/plugins/lirc/librblirc.so
+%%LIRC%%lib/rhythmbox/plugins/lirc/lirc.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/AstrawebParser.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/AstrawebParser.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/AstrawebParser.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LeoslyricsParser.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LeoslyricsParser.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LeoslyricsParser.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyrcParser.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyrcParser.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyrcParser.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricWikiParser.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricWikiParser.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricWikiParser.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricsConfigureDialog.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricsConfigureDialog.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricsConfigureDialog.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricsParse.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricsParse.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/LyricsParse.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/WinampcnParser.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/WinampcnParser.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/WinampcnParser.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/lyrics-prefs.glade
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/lyrics.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/BuyAlbumHandler.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/BuyAlbumHandler.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/BuyAlbumHandler.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/MagnatuneSource.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/MagnatuneSource.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/MagnatuneSource.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/TrackListHandler.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/TrackListHandler.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/TrackListHandler.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune-loading.glade
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune-prefs.glade
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune-purchase.glade
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune_logo_color_small.png
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune_logo_color_tiny.png
+lib/rhythmbox/plugins/mmkeys/libmmkeys.a
+lib/rhythmbox/plugins/mmkeys/libmmkeys.la
+lib/rhythmbox/plugins/mmkeys/libmmkeys.so
+lib/rhythmbox/plugins/mmkeys/mmkeys.rb-plugin
+lib/rhythmbox/plugins/power-manager/libpower-manager.a
+lib/rhythmbox/plugins/power-manager/libpower-manager.la
+lib/rhythmbox/plugins/power-manager/libpower-manager.so
+lib/rhythmbox/plugins/power-manager/power-manager.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.py
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.pyc
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.pyo
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/rb/Coroutine.py
+%%PYTHON%%lib/rhythmbox/plugins/rb/Coroutine.pyc
+%%PYTHON%%lib/rhythmbox/plugins/rb/Coroutine.pyo
+%%PYTHON%%lib/rhythmbox/plugins/rb/Loader.py
+%%PYTHON%%lib/rhythmbox/plugins/rb/Loader.pyc
+%%PYTHON%%lib/rhythmbox/plugins/rb/Loader.pyo
+%%PYTHON%%lib/rhythmbox/plugins/rb/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/rb/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/rb/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/MediaStore.py
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/MediaStore.pyc
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/MediaStore.pyo
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/UpnpSource.py
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/UpnpSource.pyc
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/UpnpSource.pyo
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/upnp_coherence/coherence.rb-plugin
+lib/rhythmbox/plugins/visualizer/libvisualizer.a
+lib/rhythmbox/plugins/visualizer/libvisualizer.la
+lib/rhythmbox/plugins/visualizer/libvisualizer.so
+lib/rhythmbox/plugins/visualizer/rb-visualizer-glue.h
+lib/rhythmbox/plugins/visualizer/visualizer-controls.glade
+lib/rhythmbox/plugins/visualizer/visualizer-ui.xml
+lib/rhythmbox/plugins/visualizer/visualizer.rb-plugin
+libexec/rhythmbox-metadata
+share/applications/rhythmbox.desktop
+share/dbus-1/services/org.gnome.Rhythmbox.service
+%%DOCSDIR%%/ch01.html
+%%DOCSDIR%%/ch02.html
+%%DOCSDIR%%/ch03.html
+%%DOCSDIR%%/ch04.html
+%%DOCSDIR%%/ch05.html
+%%DOCSDIR%%/ch06.html
+%%DOCSDIR%%/ch07.html
+%%DOCSDIR%%/home.png
+%%DOCSDIR%%/index.html
+%%DOCSDIR%%/index.sgml
+%%DOCSDIR%%/left.png
+%%DOCSDIR%%/rhythmbox-RBCellRendererPixbuf.html
+%%DOCSDIR%%/rhythmbox-RBSource.html
+%%DOCSDIR%%/rhythmbox-eel-gconf-extensions.html
+%%DOCSDIR%%/rhythmbox-rb-cell-renderer-rating.html
+%%DOCSDIR%%/rhythmbox-rb-debug.html
+%%DOCSDIR%%/rhythmbox-rb-dialog.html
+%%DOCSDIR%%/rhythmbox-rb-druid.html
+%%DOCSDIR%%/rhythmbox-rb-entry-view.html
+%%DOCSDIR%%/rhythmbox-rb-enums.html
+%%DOCSDIR%%/rhythmbox-rb-file-helpers.html
+%%DOCSDIR%%/rhythmbox-rb-glade-helpers.html
+%%DOCSDIR%%/rhythmbox-rb-header.html
+%%DOCSDIR%%/rhythmbox-rb-history.html
+%%DOCSDIR%%/rhythmbox-rb-library-source.html
+%%DOCSDIR%%/rhythmbox-rb-metadata.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-linear-loop.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-linear.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-by-age-and-rating.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-by-age.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-by-rating.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-equal-weights.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-shuffle.html
+%%DOCSDIR%%/rhythmbox-rb-play-order.html
+%%DOCSDIR%%/rhythmbox-rb-player.html
+%%DOCSDIR%%/rhythmbox-rb-playlist-manager.html
+%%DOCSDIR%%/rhythmbox-rb-playlist-source-recorder.html
+%%DOCSDIR%%/rhythmbox-rb-playlist-source.html
+%%DOCSDIR%%/rhythmbox-rb-preferences.html
+%%DOCSDIR%%/rhythmbox-rb-property-view.html
+%%DOCSDIR%%/rhythmbox-rb-query-creator.html
+%%DOCSDIR%%/rhythmbox-rb-rating-helper.html
+%%DOCSDIR%%/rhythmbox-rb-rating.html
+%%DOCSDIR%%/rhythmbox-rb-search-entry.html
+%%DOCSDIR%%/rhythmbox-rb-shell-clipboard.html
+%%DOCSDIR%%/rhythmbox-rb-shell-player.html
+%%DOCSDIR%%/rhythmbox-rb-shell-preferences.html
+%%DOCSDIR%%/rhythmbox-rb-shell.html
+%%DOCSDIR%%/rhythmbox-rb-song-display-box.html
+%%DOCSDIR%%/rhythmbox-rb-song-info.html
+%%DOCSDIR%%/rhythmbox-rb-source-header.html
+%%DOCSDIR%%/rhythmbox-rb-sourcelist-model.html
+%%DOCSDIR%%/rhythmbox-rb-sourcelist.html
+%%DOCSDIR%%/rhythmbox-rb-statusbar.html
+%%DOCSDIR%%/rhythmbox-rb-stock-icons.html
+%%DOCSDIR%%/rhythmbox-rb-string-helpers.html
+%%DOCSDIR%%/rhythmbox-rb-tray-icon.html
+%%DOCSDIR%%/rhythmbox-rb-tree-dnd.html
+%%DOCSDIR%%/rhythmbox-rb-tree-model-sort.html
+%%DOCSDIR%%/rhythmbox-rb-util.html
+%%DOCSDIR%%/rhythmbox-rhythmdb-property-model.html
+%%DOCSDIR%%/rhythmbox-rhythmdb-query-model.html
+%%DOCSDIR%%/rhythmbox-rhythmdb-tree.html
+%%DOCSDIR%%/rhythmbox-rhythmdb.html
+%%DOCSDIR%%/rhythmbox.devhelp
+%%DOCSDIR%%/rhythmbox.devhelp2
+%%DOCSDIR%%/right.png
+%%DOCSDIR%%/style.css
+%%DOCSDIR%%/up.png
+share/gnome/help/rhythmbox/C/fdl-appendix.xml
+share/gnome/help/rhythmbox/C/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/C/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/C/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/C/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/C/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/C/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/C/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/C/figures/rb-window-small.png
+share/gnome/help/rhythmbox/C/figures/rb-window.png
+share/gnome/help/rhythmbox/C/legal.xml
+share/gnome/help/rhythmbox/C/rhythmbox.xml
+share/gnome/help/rhythmbox/de/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/de/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/de/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/de/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/de/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/de/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/de/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/de/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/de/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/de/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/de/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/de/figures/rb-window-small.png
+share/gnome/help/rhythmbox/de/figures/rb-window.png
+share/gnome/help/rhythmbox/de/rhythmbox.xml
+share/gnome/help/rhythmbox/el/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/el/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/el/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/el/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/el/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/el/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/el/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/el/figures/rb-window-small.png
+share/gnome/help/rhythmbox/el/figures/rb-window.png
+share/gnome/help/rhythmbox/el/rhythmbox.xml
+share/gnome/help/rhythmbox/es/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/es/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/es/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/es/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/es/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/es/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/es/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/es/figures/rb-window-small.png
+share/gnome/help/rhythmbox/es/figures/rb-window.png
+share/gnome/help/rhythmbox/es/rhythmbox.xml
+share/gnome/help/rhythmbox/fr/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/fr/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/fr/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/fr/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/fr/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/fr/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/fr/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/fr/figures/rb-window-small.png
+share/gnome/help/rhythmbox/fr/figures/rb-window.png
+share/gnome/help/rhythmbox/fr/rhythmbox.xml
+share/gnome/help/rhythmbox/it/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/it/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/it/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/it/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/it/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/it/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/it/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/it/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/it/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/it/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/it/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/it/figures/rb-window-small.png
+share/gnome/help/rhythmbox/it/figures/rb-window.png
+share/gnome/help/rhythmbox/it/rhythmbox.xml
+share/gnome/help/rhythmbox/oc/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/oc/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/oc/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/oc/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/oc/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/oc/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/oc/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/oc/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/oc/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/oc/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/oc/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/oc/figures/rb-window-small.png
+share/gnome/help/rhythmbox/oc/figures/rb-window.png
+share/gnome/help/rhythmbox/oc/rhythmbox.xml
+share/gnome/help/rhythmbox/ru/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/ru/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/ru/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/ru/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/ru/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/ru/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/ru/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/ru/figures/rb-window-small.png
+share/gnome/help/rhythmbox/ru/figures/rb-window.png
+share/gnome/help/rhythmbox/ru/rhythmbox.xml
+share/gnome/help/rhythmbox/sv/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/sv/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/sv/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/sv/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/sv/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/sv/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/sv/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/sv/figures/rb-window-small.png
+share/gnome/help/rhythmbox/sv/figures/rb-window.png
+share/gnome/help/rhythmbox/sv/rhythmbox.xml
+share/gnome/help/rhythmbox/zh_CN/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-window-small.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-window.png
+share/gnome/help/rhythmbox/zh_CN/rhythmbox.xml
+share/icons/hicolor/16x16/apps/rhythmbox.png
+share/icons/hicolor/22x22/apps/rhythmbox.png
+share/icons/hicolor/32x32/apps/rhythmbox.png
+share/icons/hicolor/48x48/apps/rhythmbox.png
+share/icons/hicolor/scalable/apps/rhythmbox.svg
+share/locale/am/LC_MESSAGES/rhythmbox.mo
+share/locale/ar/LC_MESSAGES/rhythmbox.mo
+share/locale/az/LC_MESSAGES/rhythmbox.mo
+share/locale/be/LC_MESSAGES/rhythmbox.mo
+share/locale/be@latin/LC_MESSAGES/rhythmbox.mo
+share/locale/bg/LC_MESSAGES/rhythmbox.mo
+share/locale/ca/LC_MESSAGES/rhythmbox.mo
+share/locale/cs/LC_MESSAGES/rhythmbox.mo
+share/locale/cy/LC_MESSAGES/rhythmbox.mo
+share/locale/da/LC_MESSAGES/rhythmbox.mo
+share/locale/de/LC_MESSAGES/rhythmbox.mo
+share/locale/dz/LC_MESSAGES/rhythmbox.mo
+share/locale/el/LC_MESSAGES/rhythmbox.mo
+share/locale/en_CA/LC_MESSAGES/rhythmbox.mo
+share/locale/en_GB/LC_MESSAGES/rhythmbox.mo
+share/locale/es/LC_MESSAGES/rhythmbox.mo
+share/locale/et/LC_MESSAGES/rhythmbox.mo
+share/locale/eu/LC_MESSAGES/rhythmbox.mo
+share/locale/fi/LC_MESSAGES/rhythmbox.mo
+share/locale/fr/LC_MESSAGES/rhythmbox.mo
+share/locale/ga/LC_MESSAGES/rhythmbox.mo
+share/locale/gl/LC_MESSAGES/rhythmbox.mo
+share/locale/he/LC_MESSAGES/rhythmbox.mo
+share/locale/hi/LC_MESSAGES/rhythmbox.mo
+share/locale/hr/LC_MESSAGES/rhythmbox.mo
+share/locale/hu/LC_MESSAGES/rhythmbox.mo
+share/locale/id/LC_MESSAGES/rhythmbox.mo
+share/locale/is/LC_MESSAGES/rhythmbox.mo
+share/locale/it/LC_MESSAGES/rhythmbox.mo
+share/locale/ja/LC_MESSAGES/rhythmbox.mo
+share/locale/ko/LC_MESSAGES/rhythmbox.mo
+share/locale/lt/LC_MESSAGES/rhythmbox.mo
+share/locale/lv/LC_MESSAGES/rhythmbox.mo
+share/locale/mk/LC_MESSAGES/rhythmbox.mo
+share/locale/ml/LC_MESSAGES/rhythmbox.mo
+share/locale/mn/LC_MESSAGES/rhythmbox.mo
+share/locale/ms/LC_MESSAGES/rhythmbox.mo
+share/locale/nb/LC_MESSAGES/rhythmbox.mo
+share/locale/ne/LC_MESSAGES/rhythmbox.mo
+share/locale/nl/LC_MESSAGES/rhythmbox.mo
+share/locale/oc/LC_MESSAGES/rhythmbox.mo
+share/locale/pa/LC_MESSAGES/rhythmbox.mo
+share/locale/pl/LC_MESSAGES/rhythmbox.mo
+share/locale/ps/LC_MESSAGES/rhythmbox.mo
+share/locale/pt/LC_MESSAGES/rhythmbox.mo
+share/locale/pt_BR/LC_MESSAGES/rhythmbox.mo
+share/locale/ro/LC_MESSAGES/rhythmbox.mo
+share/locale/ru/LC_MESSAGES/rhythmbox.mo
+share/locale/rw/LC_MESSAGES/rhythmbox.mo
+share/locale/sk/LC_MESSAGES/rhythmbox.mo
+share/locale/sr/LC_MESSAGES/rhythmbox.mo
+share/locale/sr@Latn/LC_MESSAGES/rhythmbox.mo
+share/locale/sv/LC_MESSAGES/rhythmbox.mo
+share/locale/th/LC_MESSAGES/rhythmbox.mo
+share/locale/tr/LC_MESSAGES/rhythmbox.mo
+share/locale/uk/LC_MESSAGES/rhythmbox.mo
+share/locale/vi/LC_MESSAGES/rhythmbox.mo
+share/locale/zh_CN/LC_MESSAGES/rhythmbox.mo
+share/locale/zh_HK/LC_MESSAGES/rhythmbox.mo
+share/locale/zh_TW/LC_MESSAGES/rhythmbox.mo
+share/omf/rhythmbox/rhythmbox-C.omf
+share/omf/rhythmbox/rhythmbox-de.omf
+share/omf/rhythmbox/rhythmbox-el.omf
+share/omf/rhythmbox/rhythmbox-es.omf
+share/omf/rhythmbox/rhythmbox-fr.omf
+share/omf/rhythmbox/rhythmbox-it.omf
+share/omf/rhythmbox/rhythmbox-oc.omf
+share/omf/rhythmbox/rhythmbox-ru.omf
+share/omf/rhythmbox/rhythmbox-sv.omf
+share/omf/rhythmbox/rhythmbox-zh_CN.omf
+share/rhythmbox/glade/create-playlist.glade
+share/rhythmbox/glade/general-prefs.glade
+share/rhythmbox/glade/library-prefs.glade
+share/rhythmbox/glade/playback-prefs.glade
+share/rhythmbox/glade/playlist-save.glade
+share/rhythmbox/glade/plugins.glade
+share/rhythmbox/glade/podcast-feed-properties.glade
+share/rhythmbox/glade/podcast-prefs.glade
+share/rhythmbox/glade/podcast-properties.glade
+share/rhythmbox/glade/song-info-multiple.glade
+share/rhythmbox/glade/song-info.glade
+share/rhythmbox/glade/uri-new.glade
+share/rhythmbox/glade/uri.glade
+share/rhythmbox/icons/hicolor/16x16/actions/internet-radio-new.png
+share/rhythmbox/icons/hicolor/16x16/actions/media-eject.png
+share/rhythmbox/icons/hicolor/16x16/actions/playlist-automatic-new.png
+share/rhythmbox/icons/hicolor/16x16/actions/playlist-new.png
+share/rhythmbox/icons/hicolor/16x16/actions/podcast-new.png
+share/rhythmbox/icons/hicolor/16x16/places/library-internet-radio.png
+share/rhythmbox/icons/hicolor/16x16/places/library-podcast.png
+share/rhythmbox/icons/hicolor/16x16/places/playlist-automatic.png
+share/rhythmbox/icons/hicolor/16x16/places/playlist.png
+share/rhythmbox/icons/hicolor/16x16/status/rhythmbox-no-star.png
+share/rhythmbox/icons/hicolor/16x16/status/rhythmbox-notplaying.png
+share/rhythmbox/icons/hicolor/16x16/status/rhythmbox-set-star.png
+share/rhythmbox/icons/hicolor/16x16/status/rhythmbox-unset-star.png
+share/rhythmbox/icons/hicolor/22x22/actions/internet-radio-new.png
+share/rhythmbox/icons/hicolor/22x22/actions/playlist-automatic-new.png
+share/rhythmbox/icons/hicolor/22x22/actions/playlist-new.png
+share/rhythmbox/icons/hicolor/22x22/actions/podcast-new.png
+share/rhythmbox/icons/hicolor/22x22/actions/visualization.png
+share/rhythmbox/icons/hicolor/22x22/places/library-internet-radio.png
+share/rhythmbox/icons/hicolor/22x22/places/library-podcast.png
+share/rhythmbox/icons/hicolor/22x22/places/playlist-automatic.png
+share/rhythmbox/icons/hicolor/22x22/places/playlist.png
+share/rhythmbox/icons/hicolor/22x22/status/rhythmbox-notplaying.png
+share/rhythmbox/icons/hicolor/32x32/actions/internet-radio-new.png
+share/rhythmbox/icons/hicolor/32x32/actions/playlist-automatic-new.png
+share/rhythmbox/icons/hicolor/32x32/actions/playlist-new.png
+share/rhythmbox/icons/hicolor/32x32/places/library-internet-radio.png
+share/rhythmbox/icons/hicolor/32x32/places/playlist-automatic.png
+share/rhythmbox/icons/hicolor/32x32/places/playlist.png
+share/rhythmbox/icons/hicolor/32x32/status/rhythmbox-notplaying.png
+share/rhythmbox/icons/hicolor/scalable/actions/internet-radio-new.svg
+share/rhythmbox/icons/hicolor/scalable/actions/playlist-automatic-new.svg
+share/rhythmbox/icons/hicolor/scalable/actions/playlist-new.svg
+share/rhythmbox/icons/hicolor/scalable/places/library-internet-radio.svg
+share/rhythmbox/icons/hicolor/scalable/places/playlist-automatic.svg
+share/rhythmbox/icons/hicolor/scalable/places/playlist.svg
+share/rhythmbox/icons/hicolor/scalable/status/rhythmbox-notplaying.svg
+share/rhythmbox/playlists.xml
+share/rhythmbox/rhythmbox-ui.xml
+@dirrm share/rhythmbox/icons/hicolor/scalable/status
+@dirrm share/rhythmbox/icons/hicolor/scalable/places
+@dirrm share/rhythmbox/icons/hicolor/scalable/actions
+@dirrm share/rhythmbox/icons/hicolor/scalable
+@dirrm share/rhythmbox/icons/hicolor/32x32/status
+@dirrm share/rhythmbox/icons/hicolor/32x32/places
+@dirrm share/rhythmbox/icons/hicolor/32x32/actions
+@dirrm share/rhythmbox/icons/hicolor/32x32
+@dirrm share/rhythmbox/icons/hicolor/22x22/status
+@dirrm share/rhythmbox/icons/hicolor/22x22/places
+@dirrm share/rhythmbox/icons/hicolor/22x22/actions
+@dirrm share/rhythmbox/icons/hicolor/22x22
+@dirrm share/rhythmbox/icons/hicolor/16x16/status
+@dirrm share/rhythmbox/icons/hicolor/16x16/places
+@dirrm share/rhythmbox/icons/hicolor/16x16/actions
+@dirrm share/rhythmbox/icons/hicolor/16x16
+@dirrm share/rhythmbox/icons/hicolor
+@dirrm share/rhythmbox/icons/
+@dirrm share/rhythmbox/glade
+@dirrm share/rhythmbox
+@dirrm share/omf/rhythmbox
+@dirrm share/gnome/help/rhythmbox/zh_CN/figures
+@dirrm share/gnome/help/rhythmbox/zh_CN
+@dirrm share/gnome/help/rhythmbox/sv/figures
+@dirrm share/gnome/help/rhythmbox/sv
+@dirrm share/gnome/help/rhythmbox/ru/figures
+@dirrm share/gnome/help/rhythmbox/ru
+@dirrm share/gnome/help/rhythmbox/oc/figures
+@dirrm share/gnome/help/rhythmbox/oc
+@dirrm share/gnome/help/rhythmbox/it/figures
+@dirrm share/gnome/help/rhythmbox/it
+@dirrm share/gnome/help/rhythmbox/fr/figures
+@dirrm share/gnome/help/rhythmbox/fr
+@dirrm share/gnome/help/rhythmbox/es/figures
+@dirrm share/gnome/help/rhythmbox/es
+@dirrm share/gnome/help/rhythmbox/el/figures
+@dirrm share/gnome/help/rhythmbox/el
+@dirrm share/gnome/help/rhythmbox/de/figures
+@dirrm share/gnome/help/rhythmbox/de
+@dirrm share/gnome/help/rhythmbox/C/figures
+@dirrm share/gnome/help/rhythmbox/C
+@dirrm share/gnome/help/rhythmbox
+@dirrm %%DOCSDIR%%
+@dirrm lib/rhythmbox/plugins/visualizer
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/upnp_coherence
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/rb
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/python-console
+@dirrm lib/rhythmbox/plugins/power-manager
+@dirrm lib/rhythmbox/plugins/mmkeys
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/magnatune
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/lyrics
+%%LIRC%%@dirrm lib/rhythmbox/plugins/lirc
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/jamendo
+@dirrm lib/rhythmbox/plugins/iradio
+%%IPOD%%@dirrm lib/rhythmbox/plugins/ipod
+@dirrm lib/rhythmbox/plugins/generic-player
+%%DAAP%%@dirrm lib/rhythmbox/plugins/daap
+@dirrm lib/rhythmbox/plugins/cd-recorder
+@dirrm lib/rhythmbox/plugins/audioscrobbler
+@dirrm lib/rhythmbox/plugins/audiocd
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/artdisplay
+@dirrm lib/rhythmbox/plugins
+@dirrm lib/rhythmbox
+@dirrmtry share/applications
+@dirrmtry share/locale/zh_HK/LC_MESSAGES
+@dirrmtry share/locale/zh_HK
+@dirrmtry share/locale/rw/LC_MESSAGES
+@dirrmtry share/locale/rw
+@dirrmtry share/locale/ps/LC_MESSAGES
+@dirrmtry share/locale/ps
+@dirrmtry share/locale/oc/LC_MESSAGES
+@dirrmtry share/locale/oc
+@dirrmtry share/locale/dz/LC_MESSAGES
+@dirrmtry share/locale/dz
+@dirrmtry share/locale/be@latin/LC_MESSAGES
+@dirrmtry share/locale/be@latin
diff --git a/audio/rhythmbox/Makefile b/audio/rhythmbox/Makefile
new file mode 100644
index 000000000..60435c7b2
--- /dev/null
+++ b/audio/rhythmbox/Makefile
@@ -0,0 +1,121 @@
+# New ports collection makefile for: rhythmbox
+# Date created: 17 August 2003
+# Whom: Joe Marcus Clarke <marcus@FreeBSD.org>
+#
+# $FreeBSD$
+# $MCom: ports/audio/rhythmbox/Makefile,v 1.88 2008/01/29 01:37:44 marcus Exp $
+#
+
+PORTNAME= rhythmbox
+PORTVERSION= 0.10.1
+PORTREVISION= 9
+CATEGORIES= audio gnome
+MASTER_SITES= ${MASTER_SITE_GNOME}
+MASTER_SITE_SUBDIR= sources/${PORTNAME}/0.10
+DIST_SUBDIR= gnome2
+
+MAINTAINER= marcus@FreeBSD.org
+COMMENT= Audio player for GNOME
+
+LIB_DEPENDS= musicbrainz.4:${PORTSDIR}/audio/libmusicbrainz \
+ id3tag.0:${PORTSDIR}/audio/libid3tag \
+ totem-plparser.12:${PORTSDIR}/multimedia/totem-pl-parser \
+ dbus-glib-1.2:${PORTSDIR}/devel/dbus-glib \
+ sexy.2:${PORTSDIR}/x11-toolkits/libsexy \
+ soup-2.2.8:${PORTSDIR}/devel/libsoup22 \
+ gnome-media-profiles.0:${PORTSDIR}/audio/gnome-media
+
+USE_BZIP2= yes
+USE_GETTEXT= yes
+INSTALLS_OMF= yes
+USE_GMAKE= yes
+USE_GNOME= gnomehack intlhack gnomeprefix libgnomeui nautiluscdburner
+WANT_GNOME= yes
+USE_GSTREAMER= flac mp3 gnomevfs gconf jpeg
+USE_AUTOTOOLS= libtool:15
+CONFIGURE_ARGS= --enable-nautilus-menu --with-playback=gstreamer-0-10
+INSTALLS_ICONS= yes
+USE_LDCONFIG= yes
+CONFIGURE_ENV= LIBS="-lm" \
+ LDFLAGS="-L${LOCALBASE}/lib" \
+ CPPFLAGS="-I${LOCALBASE}/include"
+
+GCONF_SCHEMAS= rhythmbox.schemas
+
+OPTIONS= DAAP "Enable iTunes music sharing" off \
+ IPOD "Enable iPod support" on \
+ FAAD "Enable FAAD decoder support" off \
+ NOTIFY "Enable libnotify support" on \
+ VORBIS "Enable Ogg/Vorbis support" on \
+ LIRC "Enable Infrared syncing support" off
+# GDA "Enable GDA database storage" off
+
+.include <bsd.port.pre.mk>
+
+.if !defined(WITHOUT_VORBIS)
+USE_GSTREAMER+= vorbis
+.else
+CONFIGURE_ARGS+= --disable-vorbis --disable-vorbistest
+.endif
+
+.if defined(WITH_FAAD)
+USE_GSTREAMER+= faad
+.endif
+
+#.if defined(WITH_GDA)
+#USE_GNOME+= libgda2
+#CONFIGURE_ARGS+=--with-database=libgda
+#.else
+CONFIGURE_ARGS+=--with-database=tree
+#.endif
+
+.if defined(WITH_LIRC)
+LIB_DEPENDS+= lirc_client.1:${PORTSDIR}/comms/lirc
+PLIST_SUB+= LIRC=""
+CONFIGURE_ARGS+=--enable-lirc
+.else
+CONFIGURE_ARGS+=--disable-lirc
+PLIST_SUB+= LIRC="@comment "
+.endif
+
+.if defined(WITH_DAAP)
+CONFIGURE_ARGS+= --enable-daap --with-mdns=avahi
+LIB_DEPENDS+= avahi-client:${PORTSDIR}/net/avahi-app \
+ gnome-keyring:${PORTSDIR}/security/gnome-keyring
+PLIST_SUB+= DAAP=""
+.else
+.if exists(${LOCALBASE}/lib/libavahi-client.a)
+LIB_DEPENDS+= avahi-client:${PORTSDIR}/net/avahi-app
+.endif
+CONFIGURE_ARGS+= --disable-daap
+PLIST_SUB+= DAAP="@comment "
+.endif
+
+.if !defined(WITHOUT_NOTIFY)
+LIB_DEPENDS+= notify.1:${PORTSDIR}/devel/libnotify
+RUN_DEPENDS+= ${LOCALBASE}/libexec/notification-daemon:${PORTSDIR}/deskutils/notification-daemon
+.else
+CONFIGURE_ARGS+= --disable-libnotify
+.endif
+
+.if ${HAVE_GNOME:Mpygtk2}!=""
+USE_PYTHON= yes
+.include "${PORTSDIR}/Mk/bsd.python.mk"
+USE_GNOME+= pygtk2
+CONFIGURE_ARGS+=--enable-python
+PLIST_SUB+= PYTHON=""
+.else
+CONFIGURE_ARGS+=--disable-python
+PLIST_SUB+= PYTHON="@comment "
+.endif
+
+.if !defined(WITHOUT_IPOD)
+LIB_DEPENDS+= gpod.3:${PORTSDIR}/audio/libgpod
+CONFIGURE_ARGS+=--with-ipod
+PLIST_SUB+= IPOD=""
+.else
+CONFIGURE_ARGS+=--without-ipod
+PLIST_SUB+= IPOD="@comment "
+.endif
+
+.include <bsd.port.post.mk>
diff --git a/audio/rhythmbox/distinfo b/audio/rhythmbox/distinfo
new file mode 100644
index 000000000..ddf775466
--- /dev/null
+++ b/audio/rhythmbox/distinfo
@@ -0,0 +1,3 @@
+MD5 (gnome2/rhythmbox-0.10.1.tar.bz2) = 6ab510d54654d2973f91b5d0de54f854
+SHA256 (gnome2/rhythmbox-0.10.1.tar.bz2) = a303076477a9a7b6a226613a6f3b43f4641ce977357c9aa9652932dc0b9bbd16
+SIZE (gnome2/rhythmbox-0.10.1.tar.bz2) = 3408309
diff --git a/audio/rhythmbox/files/patch-plugins_cd-recorder_rb-recorder-gst.c b/audio/rhythmbox/files/patch-plugins_cd-recorder_rb-recorder-gst.c
new file mode 100644
index 000000000..c70afd0dc
--- /dev/null
+++ b/audio/rhythmbox/files/patch-plugins_cd-recorder_rb-recorder-gst.c
@@ -0,0 +1,12 @@
+--- plugins/cd-recorder/rb-recorder-gst.c.orig Wed Aug 10 20:06:11 2005
++++ plugins/cd-recorder/rb-recorder-gst.c Wed Aug 10 20:06:31 2005
+@@ -25,7 +25,9 @@
+ #include <string.h>
+ #include <math.h>
+ #include <time.h>
++#ifndef __FreeBSD__
+ #include <sys/vfs.h>
++#endif
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
diff --git a/audio/rhythmbox/files/patch-plugins_daap_rb-daap-src.c b/audio/rhythmbox/files/patch-plugins_daap_rb-daap-src.c
new file mode 100644
index 000000000..4d9bb5178
--- /dev/null
+++ b/audio/rhythmbox/files/patch-plugins_daap_rb-daap-src.c
@@ -0,0 +1,26 @@
+--- plugins/daap/rb-daap-src.c.orig Fri Jan 27 21:11:13 2006
++++ plugins/daap/rb-daap-src.c Thu Feb 2 02:07:48 2006
+@@ -34,6 +34,7 @@
+ #include <sys/ioctl.h>
+ #include <netdb.h>
+ #include <unistd.h>
++#include <signal.h>
+ #include <ctype.h>
+
+ #include <libsoup/soup-headers.h>
+@@ -435,7 +436,14 @@ rb_daap_src_write (RBDAAPSrc *src, const
+ size_t bytes_written = 0;
+
+ while (bytes_written < count) {
+- ssize_t wrote = send (src->sock_fd, buf + bytes_written, count - bytes_written, MSG_NOSIGNAL);
++ ssize_t wrote;
++#ifdef MSG_NOSIGNAL
++ wrote = send (src->sock_fd, buf + bytes_written, count - bytes_written, MSG_NOSIGNAL);
++#else
++ signal (SIGPIPE, SIG_IGN);
++ wrote = send (src->sock_fd, buf + bytes_written, count - bytes_written, 0);
++ signal (SIGPIPE, SIG_DFL);
++#endif
+
+ if (wrote < 0) {
+ GST_WARNING ("error while writing: %s", g_strerror (errno));
diff --git a/audio/rhythmbox/files/patch-plugins_ipod_rb-ipod-source.c b/audio/rhythmbox/files/patch-plugins_ipod_rb-ipod-source.c
new file mode 100644
index 000000000..2195b06b2
--- /dev/null
+++ b/audio/rhythmbox/files/patch-plugins_ipod_rb-ipod-source.c
@@ -0,0 +1,51 @@
+--- plugins/ipod/rb-ipod-source.c.orig Sun Nov 19 12:12:33 2006
++++ plugins/ipod/rb-ipod-source.c Sun Nov 19 12:28:50 2006
+@@ -695,33 +695,36 @@ hal_udi_is_ipod (const char *udi)
+ char *spider_udi;
+ int vnd_id = 0;
+ int product_id = 0;
++ DBusError phone_error;
++
++ dbus_error_init (&phone_error);
+
+ spider_udi = g_strdup(parent_udi);
+ while (vnd_id == 0 && product_id == 0 && spider_udi != NULL) {
+ char *old_udi = spider_udi;
+ spider_udi = libhal_device_get_property_string (ctx, spider_udi,
+- "info.parent", &error);
+- if (dbus_error_is_set (&error)) {
+- dbus_error_free (&error);
+- dbus_error_init (&error);
++ "info.parent", &phone_error);
++ if (dbus_error_is_set (&phone_error)) {
++ dbus_error_free (&phone_error);
++ dbus_error_init (&phone_error);
+ spider_udi = NULL;
+ break;
+ }
+ g_free(old_udi);
+
+ vnd_id = libhal_device_get_property_int (ctx, spider_udi,
+- "usb.vendor_id", &error);
+- if (dbus_error_is_set(&error)) {
+- dbus_error_free (&error);
+- dbus_error_init (&error);
++ "usb.vendor_id", &phone_error);
++ if (dbus_error_is_set(&phone_error)) {
++ dbus_error_free (&phone_error);
++ dbus_error_init (&phone_error);
+ vnd_id = 0;
+ }
+
+ product_id = libhal_device_get_property_int (ctx, spider_udi,
+- "usb.product_id", &error);
+- if (dbus_error_is_set(&error)) {
+- dbus_error_free (&error);
+- dbus_error_init (&error);
++ "usb.product_id", &phone_error);
++ if (dbus_error_is_set(&phone_error)) {
++ dbus_error_free (&phone_error);
++ dbus_error_init (&phone_error);
+ product_id = 0;
+ }
+ }
diff --git a/audio/rhythmbox/files/patch-podcast_rb-podcast-parse.h b/audio/rhythmbox/files/patch-podcast_rb-podcast-parse.h
new file mode 100644
index 000000000..2208b3205
--- /dev/null
+++ b/audio/rhythmbox/files/patch-podcast_rb-podcast-parse.h
@@ -0,0 +1,10 @@
+--- podcast/rb-podcast-parse.h.orig Mon Nov 28 13:51:28 2005
++++ podcast/rb-podcast-parse.h Mon Nov 28 13:51:05 2005
+@@ -22,6 +22,7 @@
+ #ifndef RB_PODCAST_PARSE_H
+ #define RB_PODCAST_PARSE_H
+
++#include <inttypes.h>
+ #include <glib.h>
+
+ typedef struct
diff --git a/audio/rhythmbox/pkg-descr b/audio/rhythmbox/pkg-descr
new file mode 100644
index 000000000..60afe778d
--- /dev/null
+++ b/audio/rhythmbox/pkg-descr
@@ -0,0 +1,5 @@
+Rhythmbox is an integrated music management application, originally inspired by
+Apple's iTunes. It is free software, designed to work well under the GNOME
+Desktop, and based on the powerful GStreamer media framework.
+
+WWW: http://www.gnome.org/projects/rhythmbox/
diff --git a/audio/rhythmbox/pkg-plist b/audio/rhythmbox/pkg-plist
new file mode 100644
index 000000000..333cc64b0
--- /dev/null
+++ b/audio/rhythmbox/pkg-plist
@@ -0,0 +1,442 @@
+bin/rhythmbox
+bin/rhythmbox-client
+lib/librhythmbox-core.a
+lib/librhythmbox-core.la
+lib/librhythmbox-core.so
+lib/librhythmbox-core.so.0
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/AmazonCoverArtSearch.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/AmazonCoverArtSearch.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/AmazonCoverArtSearch.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/CoverArtDatabase.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/CoverArtDatabase.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/CoverArtDatabase.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/LocalCoverArtSearch.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/LocalCoverArtSearch.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/LocalCoverArtSearch.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/PodcastCoverArtSearch.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/PodcastCoverArtSearch.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/PodcastCoverArtSearch.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/artdisplay.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/artdisplay/rhythmbox-missing-artwork.svg
+lib/rhythmbox/plugins/audiocd/audiocd.rb-plugin
+lib/rhythmbox/plugins/audiocd/libaudiocd.a
+lib/rhythmbox/plugins/audiocd/libaudiocd.la
+lib/rhythmbox/plugins/audiocd/libaudiocd.so
+lib/rhythmbox/plugins/audiocd/multiple-album.glade
+lib/rhythmbox/plugins/audioscrobbler/as-icon.svg
+lib/rhythmbox/plugins/audioscrobbler/audioscrobbler-prefs.glade
+lib/rhythmbox/plugins/audioscrobbler/audioscrobbler-ui.xml
+lib/rhythmbox/plugins/audioscrobbler/audioscrobbler.rb-plugin
+lib/rhythmbox/plugins/audioscrobbler/libaudioscrobbler.a
+lib/rhythmbox/plugins/audioscrobbler/libaudioscrobbler.la
+lib/rhythmbox/plugins/audioscrobbler/libaudioscrobbler.so
+lib/rhythmbox/plugins/cd-recorder/cd-recorder.rb-plugin
+lib/rhythmbox/plugins/cd-recorder/libcd-recorder.a
+lib/rhythmbox/plugins/cd-recorder/libcd-recorder.la
+lib/rhythmbox/plugins/cd-recorder/libcd-recorder.so
+lib/rhythmbox/plugins/cd-recorder/recorder.glade
+%%DAAP%%lib/rhythmbox/plugins/daap/daap-prefs.glade
+%%DAAP%%lib/rhythmbox/plugins/daap/daap-ui.xml
+%%DAAP%%lib/rhythmbox/plugins/daap/daap.rb-plugin
+%%DAAP%%lib/rhythmbox/plugins/daap/libdaap.a
+%%DAAP%%lib/rhythmbox/plugins/daap/libdaap.la
+%%DAAP%%lib/rhythmbox/plugins/daap/libdaap.so
+lib/rhythmbox/plugins/generic-player/generic-player-ui.xml
+lib/rhythmbox/plugins/generic-player/generic-player.rb-plugin
+lib/rhythmbox/plugins/generic-player/libgeneric-player.a
+lib/rhythmbox/plugins/generic-player/libgeneric-player.la
+lib/rhythmbox/plugins/generic-player/libgeneric-player.so
+%%IPOD%%lib/rhythmbox/plugins/ipod/ipod-ui.xml
+%%IPOD%%lib/rhythmbox/plugins/ipod/ipod.rb-plugin
+%%IPOD%%lib/rhythmbox/plugins/ipod/libipod.a
+%%IPOD%%lib/rhythmbox/plugins/ipod/libipod.la
+%%IPOD%%lib/rhythmbox/plugins/ipod/libipod.so
+lib/rhythmbox/plugins/iradio/iradio-initial.pls
+lib/rhythmbox/plugins/iradio/iradio-ui.xml
+lib/rhythmbox/plugins/iradio/iradio.rb-plugin
+lib/rhythmbox/plugins/iradio/libiradio.a
+lib/rhythmbox/plugins/iradio/libiradio.la
+lib/rhythmbox/plugins/iradio/libiradio.so
+lib/rhythmbox/plugins/iradio/station-properties.glade
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoConfigureDialog.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoConfigureDialog.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoConfigureDialog.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSaxHandler.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSaxHandler.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSaxHandler.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSource.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSource.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/JamendoSource.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo-loading.glade
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo-prefs.glade
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo_logo.png
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo_logo_medium.png
+%%PYTHON%%lib/rhythmbox/plugins/jamendo/jamendo_logo_small.png
+%%LIRC%%lib/rhythmbox/plugins/lirc/librblirc.a
+%%LIRC%%lib/rhythmbox/plugins/lirc/librblirc.la
+%%LIRC%%lib/rhythmbox/plugins/lirc/librblirc.so
+%%LIRC%%lib/rhythmbox/plugins/lirc/lirc.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/lyrics.py
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/lyrics.pyc
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/lyrics.pyo
+%%PYTHON%%lib/rhythmbox/plugins/lyrics/lyrics.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/BuyAlbumHandler.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/BuyAlbumHandler.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/BuyAlbumHandler.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/MagnatuneSource.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/MagnatuneSource.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/MagnatuneSource.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/TrackListHandler.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/TrackListHandler.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/TrackListHandler.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/__init__.pyo
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune-loading.glade
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune-prefs.glade
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune-purchase.glade
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune_circle_small.png
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune_logo_color_small.png
+%%PYTHON%%lib/rhythmbox/plugins/magnatune/magnatune_logo_color_tiny.png
+lib/rhythmbox/plugins/mmkeys/libmmkeys.a
+lib/rhythmbox/plugins/mmkeys/libmmkeys.la
+lib/rhythmbox/plugins/mmkeys/libmmkeys.so
+lib/rhythmbox/plugins/mmkeys/mmkeys.rb-plugin
+lib/rhythmbox/plugins/power-manager/libpower-manager.a
+lib/rhythmbox/plugins/power-manager/libpower-manager.la
+lib/rhythmbox/plugins/power-manager/libpower-manager.so
+lib/rhythmbox/plugins/power-manager/power-manager.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.py
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.pyc
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.pyo
+%%PYTHON%%lib/rhythmbox/plugins/python-console/pythonconsole.rb-plugin
+%%PYTHON%%lib/rhythmbox/plugins/rb/Coroutine.py
+%%PYTHON%%lib/rhythmbox/plugins/rb/Coroutine.pyc
+%%PYTHON%%lib/rhythmbox/plugins/rb/Coroutine.pyo
+%%PYTHON%%lib/rhythmbox/plugins/rb/Loader.py
+%%PYTHON%%lib/rhythmbox/plugins/rb/Loader.pyc
+%%PYTHON%%lib/rhythmbox/plugins/rb/Loader.pyo
+%%PYTHON%%lib/rhythmbox/plugins/rb/__init__.py
+%%PYTHON%%lib/rhythmbox/plugins/rb/__init__.pyc
+%%PYTHON%%lib/rhythmbox/plugins/rb/__init__.pyo
+lib/rhythmbox/plugins/visualizer/libvisualizer.a
+lib/rhythmbox/plugins/visualizer/libvisualizer.la
+lib/rhythmbox/plugins/visualizer/libvisualizer.so
+lib/rhythmbox/plugins/visualizer/rb-visualizer-glue.h
+lib/rhythmbox/plugins/visualizer/visualizer-controls.glade
+lib/rhythmbox/plugins/visualizer/visualizer-ui.xml
+lib/rhythmbox/plugins/visualizer/visualizer.rb-plugin
+libexec/rhythmbox-metadata
+share/dbus-1/services/org.gnome.Rhythmbox.service
+%%DOCSDIR%%/ch01.html
+%%DOCSDIR%%/ch02.html
+%%DOCSDIR%%/ch03.html
+%%DOCSDIR%%/ch04.html
+%%DOCSDIR%%/ch05.html
+%%DOCSDIR%%/ch06.html
+%%DOCSDIR%%/ch07.html
+%%DOCSDIR%%/home.png
+%%DOCSDIR%%/index.html
+%%DOCSDIR%%/index.sgml
+%%DOCSDIR%%/left.png
+%%DOCSDIR%%/rhythmbox-RBCellRendererPixbuf.html
+%%DOCSDIR%%/rhythmbox-RBSource.html
+%%DOCSDIR%%/rhythmbox-eel-gconf-extensions.html
+%%DOCSDIR%%/rhythmbox-rb-cell-renderer-rating.html
+%%DOCSDIR%%/rhythmbox-rb-debug.html
+%%DOCSDIR%%/rhythmbox-rb-dialog.html
+%%DOCSDIR%%/rhythmbox-rb-druid.html
+%%DOCSDIR%%/rhythmbox-rb-entry-view.html
+%%DOCSDIR%%/rhythmbox-rb-enums.html
+%%DOCSDIR%%/rhythmbox-rb-file-helpers.html
+%%DOCSDIR%%/rhythmbox-rb-glade-helpers.html
+%%DOCSDIR%%/rhythmbox-rb-header.html
+%%DOCSDIR%%/rhythmbox-rb-history.html
+%%DOCSDIR%%/rhythmbox-rb-library-source.html
+%%DOCSDIR%%/rhythmbox-rb-metadata.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-linear-loop.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-linear.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-by-age-and-rating.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-by-age.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-by-rating.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random-equal-weights.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-random.html
+%%DOCSDIR%%/rhythmbox-rb-play-order-shuffle.html
+%%DOCSDIR%%/rhythmbox-rb-play-order.html
+%%DOCSDIR%%/rhythmbox-rb-player.html
+%%DOCSDIR%%/rhythmbox-rb-playlist-manager.html
+%%DOCSDIR%%/rhythmbox-rb-playlist-source-recorder.html
+%%DOCSDIR%%/rhythmbox-rb-playlist-source.html
+%%DOCSDIR%%/rhythmbox-rb-preferences.html
+%%DOCSDIR%%/rhythmbox-rb-property-view.html
+%%DOCSDIR%%/rhythmbox-rb-query-creator.html
+%%DOCSDIR%%/rhythmbox-rb-rating-helper.html
+%%DOCSDIR%%/rhythmbox-rb-rating.html
+%%DOCSDIR%%/rhythmbox-rb-search-entry.html
+%%DOCSDIR%%/rhythmbox-rb-shell-clipboard.html
+%%DOCSDIR%%/rhythmbox-rb-shell-player.html
+%%DOCSDIR%%/rhythmbox-rb-shell-preferences.html
+%%DOCSDIR%%/rhythmbox-rb-shell.html
+%%DOCSDIR%%/rhythmbox-rb-song-display-box.html
+%%DOCSDIR%%/rhythmbox-rb-song-info.html
+%%DOCSDIR%%/rhythmbox-rb-source-header.html
+%%DOCSDIR%%/rhythmbox-rb-sourcelist-model.html
+%%DOCSDIR%%/rhythmbox-rb-sourcelist.html
+%%DOCSDIR%%/rhythmbox-rb-statusbar.html
+%%DOCSDIR%%/rhythmbox-rb-stock-icons.html
+%%DOCSDIR%%/rhythmbox-rb-string-helpers.html
+%%DOCSDIR%%/rhythmbox-rb-tray-icon.html
+%%DOCSDIR%%/rhythmbox-rb-tree-dnd.html
+%%DOCSDIR%%/rhythmbox-rb-tree-model-sort.html
+%%DOCSDIR%%/rhythmbox-rb-util.html
+%%DOCSDIR%%/rhythmbox-rhythmdb-property-model.html
+%%DOCSDIR%%/rhythmbox-rhythmdb-query-model.html
+%%DOCSDIR%%/rhythmbox-rhythmdb-tree.html
+%%DOCSDIR%%/rhythmbox-rhythmdb.html
+%%DOCSDIR%%/rhythmbox.devhelp
+%%DOCSDIR%%/rhythmbox.devhelp2
+%%DOCSDIR%%/right.png
+%%DOCSDIR%%/style.css
+%%DOCSDIR%%/up.png
+share/applications/rhythmbox.desktop
+share/gnome/help/rhythmbox/C/fdl-appendix.xml
+share/gnome/help/rhythmbox/C/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/C/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/C/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/C/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/C/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/C/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/C/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/C/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/C/figures/rb-window-small.png
+share/gnome/help/rhythmbox/C/figures/rb-window.png
+share/gnome/help/rhythmbox/C/legal.xml
+share/gnome/help/rhythmbox/C/rhythmbox.xml
+share/gnome/help/rhythmbox/el/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/el/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/el/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/el/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/el/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/el/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/el/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/el/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/el/figures/rb-window-small.png
+share/gnome/help/rhythmbox/el/figures/rb-window.png
+share/gnome/help/rhythmbox/el/rhythmbox.xml
+share/gnome/help/rhythmbox/es/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/es/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/es/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/es/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/es/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/es/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/es/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/es/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/es/figures/rb-window-small.png
+share/gnome/help/rhythmbox/es/figures/rb-window.png
+share/gnome/help/rhythmbox/es/rhythmbox.xml
+share/gnome/help/rhythmbox/fr/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/fr/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/fr/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/fr/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/fr/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/fr/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/fr/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/fr/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/fr/figures/rb-window-small.png
+share/gnome/help/rhythmbox/fr/figures/rb-window.png
+share/gnome/help/rhythmbox/fr/rhythmbox.xml
+share/gnome/help/rhythmbox/ru/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/ru/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/ru/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/ru/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/ru/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/ru/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/ru/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/ru/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/ru/figures/rb-window-small.png
+share/gnome/help/rhythmbox/ru/figures/rb-window.png
+share/gnome/help/rhythmbox/ru/rhythmbox.xml
+share/gnome/help/rhythmbox/sv/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/sv/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/sv/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/sv/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/sv/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/sv/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/sv/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/sv/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/sv/figures/rb-window-small.png
+share/gnome/help/rhythmbox/sv/figures/rb-window.png
+share/gnome/help/rhythmbox/sv/rhythmbox.xml
+share/gnome/help/rhythmbox/zh_CN/figures/rb-iradio-main.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-notification-area-menu.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-notification-window.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-notification-zone.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-podcast-main.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-statusbar.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar-prevplaynext.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar-repeat.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar-shuffle.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-toolbar.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-volume-changer.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-window-small.png
+share/gnome/help/rhythmbox/zh_CN/figures/rb-window.png
+share/gnome/help/rhythmbox/zh_CN/rhythmbox.xml
+share/omf/rhythmbox/rhythmbox-C.omf
+share/omf/rhythmbox/rhythmbox-el.omf
+share/omf/rhythmbox/rhythmbox-es.omf
+share/omf/rhythmbox/rhythmbox-fr.omf
+share/omf/rhythmbox/rhythmbox-ru.omf
+share/omf/rhythmbox/rhythmbox-sv.omf
+share/omf/rhythmbox/rhythmbox-zh_CN.omf
+share/rhythmbox/art/about-logo.png
+share/rhythmbox/art/media-eject.png
+share/rhythmbox/art/rhythmbox-no-star.png
+share/rhythmbox/art/rhythmbox-podcast.png
+share/rhythmbox/art/rhythmbox-set-star.png
+share/rhythmbox/art/rhythmbox-tray-icon.png
+share/rhythmbox/art/rhythmbox-unset-star.png
+share/rhythmbox/glade/create-playlist.glade
+share/rhythmbox/glade/druid.glade
+share/rhythmbox/glade/general-prefs.glade
+share/rhythmbox/glade/library-prefs.glade
+share/rhythmbox/glade/playlist-save.glade
+share/rhythmbox/glade/plugins.glade
+share/rhythmbox/glade/podcast-feed-properties.glade
+share/rhythmbox/glade/podcast-prefs.glade
+share/rhythmbox/glade/podcast-properties.glade
+share/rhythmbox/glade/song-info-multiple.glade
+share/rhythmbox/glade/song-info.glade
+share/rhythmbox/glade/uri-new.glade
+share/rhythmbox/glade/uri.glade
+share/rhythmbox/playlists.xml
+share/rhythmbox/rhythmbox-ui.xml
+share/icons/hicolor/48x48/apps/rhythmbox.png
+share/locale/am/LC_MESSAGES/rhythmbox.mo
+share/locale/ar/LC_MESSAGES/rhythmbox.mo
+share/locale/az/LC_MESSAGES/rhythmbox.mo
+share/locale/be/LC_MESSAGES/rhythmbox.mo
+share/locale/bg/LC_MESSAGES/rhythmbox.mo
+share/locale/ca/LC_MESSAGES/rhythmbox.mo
+share/locale/cs/LC_MESSAGES/rhythmbox.mo
+share/locale/cy/LC_MESSAGES/rhythmbox.mo
+share/locale/da/LC_MESSAGES/rhythmbox.mo
+share/locale/de/LC_MESSAGES/rhythmbox.mo
+share/locale/dz/LC_MESSAGES/rhythmbox.mo
+share/locale/el/LC_MESSAGES/rhythmbox.mo
+share/locale/en_CA/LC_MESSAGES/rhythmbox.mo
+share/locale/en_GB/LC_MESSAGES/rhythmbox.mo
+share/locale/es/LC_MESSAGES/rhythmbox.mo
+share/locale/et/LC_MESSAGES/rhythmbox.mo
+share/locale/eu/LC_MESSAGES/rhythmbox.mo
+share/locale/fi/LC_MESSAGES/rhythmbox.mo
+share/locale/fr/LC_MESSAGES/rhythmbox.mo
+share/locale/ga/LC_MESSAGES/rhythmbox.mo
+share/locale/gl/LC_MESSAGES/rhythmbox.mo
+share/locale/he/LC_MESSAGES/rhythmbox.mo
+share/locale/hi/LC_MESSAGES/rhythmbox.mo
+share/locale/hr/LC_MESSAGES/rhythmbox.mo
+share/locale/hu/LC_MESSAGES/rhythmbox.mo
+share/locale/id/LC_MESSAGES/rhythmbox.mo
+share/locale/is/LC_MESSAGES/rhythmbox.mo
+share/locale/it/LC_MESSAGES/rhythmbox.mo
+share/locale/ja/LC_MESSAGES/rhythmbox.mo
+share/locale/ko/LC_MESSAGES/rhythmbox.mo
+share/locale/lt/LC_MESSAGES/rhythmbox.mo
+share/locale/lv/LC_MESSAGES/rhythmbox.mo
+share/locale/mk/LC_MESSAGES/rhythmbox.mo
+share/locale/ml/LC_MESSAGES/rhythmbox.mo
+share/locale/mn/LC_MESSAGES/rhythmbox.mo
+share/locale/ms/LC_MESSAGES/rhythmbox.mo
+share/locale/nb/LC_MESSAGES/rhythmbox.mo
+share/locale/ne/LC_MESSAGES/rhythmbox.mo
+share/locale/nl/LC_MESSAGES/rhythmbox.mo
+share/locale/pa/LC_MESSAGES/rhythmbox.mo
+share/locale/pl/LC_MESSAGES/rhythmbox.mo
+share/locale/pt/LC_MESSAGES/rhythmbox.mo
+share/locale/pt_BR/LC_MESSAGES/rhythmbox.mo
+share/locale/ro/LC_MESSAGES/rhythmbox.mo
+share/locale/ru/LC_MESSAGES/rhythmbox.mo
+share/locale/rw/LC_MESSAGES/rhythmbox.mo
+share/locale/sk/LC_MESSAGES/rhythmbox.mo
+share/locale/sr/LC_MESSAGES/rhythmbox.mo
+share/locale/sr@Latn/LC_MESSAGES/rhythmbox.mo
+share/locale/sv/LC_MESSAGES/rhythmbox.mo
+share/locale/th/LC_MESSAGES/rhythmbox.mo
+share/locale/tr/LC_MESSAGES/rhythmbox.mo
+share/locale/uk/LC_MESSAGES/rhythmbox.mo
+share/locale/vi/LC_MESSAGES/rhythmbox.mo
+share/locale/zh_CN/LC_MESSAGES/rhythmbox.mo
+share/locale/zh_HK/LC_MESSAGES/rhythmbox.mo
+share/locale/zh_TW/LC_MESSAGES/rhythmbox.mo
+@dirrm share/rhythmbox/glade
+@dirrm share/rhythmbox/art
+@dirrm share/rhythmbox
+@dirrm share/omf/rhythmbox
+@dirrm share/gnome/help/rhythmbox/zh_CN/figures
+@dirrm share/gnome/help/rhythmbox/zh_CN
+@dirrm share/gnome/help/rhythmbox/sv/figures
+@dirrm share/gnome/help/rhythmbox/sv
+@dirrm share/gnome/help/rhythmbox/ru/figures
+@dirrm share/gnome/help/rhythmbox/ru
+@dirrm share/gnome/help/rhythmbox/fr/figures
+@dirrm share/gnome/help/rhythmbox/fr
+@dirrm share/gnome/help/rhythmbox/es/figures
+@dirrm share/gnome/help/rhythmbox/es
+@dirrm share/gnome/help/rhythmbox/el/figures
+@dirrm share/gnome/help/rhythmbox/el
+@dirrm share/gnome/help/rhythmbox/C/figures
+@dirrm share/gnome/help/rhythmbox/C
+@dirrm share/gnome/help/rhythmbox
+@dirrm %%DOCSDIR%%
+@dirrm lib/rhythmbox/plugins/visualizer
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/rb
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/python-console
+@dirrm lib/rhythmbox/plugins/power-manager
+@dirrm lib/rhythmbox/plugins/mmkeys
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/magnatune
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/lyrics
+%%LIRC%%@dirrm lib/rhythmbox/plugins/lirc
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/jamendo
+@dirrm lib/rhythmbox/plugins/iradio
+%%IPOD%%@dirrm lib/rhythmbox/plugins/ipod
+@dirrm lib/rhythmbox/plugins/generic-player
+%%DAAP%%@dirrm lib/rhythmbox/plugins/daap
+@dirrm lib/rhythmbox/plugins/cd-recorder
+@dirrm lib/rhythmbox/plugins/audioscrobbler
+@dirrm lib/rhythmbox/plugins/audiocd
+%%PYTHON%%@dirrm lib/rhythmbox/plugins/artdisplay
+@dirrm lib/rhythmbox/plugins
+@dirrm lib/rhythmbox
+@dirrmtry share/applications
+@dirrmtry share/locale/zh_HK/LC_MESSAGES
+@dirrmtry share/locale/zh_HK
+@dirrmtry share/locale/rw/LC_MESSAGES
+@dirrmtry share/locale/rw
+@dirrmtry share/locale/dz/LC_MESSAGES
+@dirrmtry share/locale/dz
diff --git a/sysutils/brasero/Makefile b/sysutils/brasero/Makefile
new file mode 100644
index 000000000..3d0683269
--- /dev/null
+++ b/sysutils/brasero/Makefile
@@ -0,0 +1,41 @@
+# New ports collection makefile for: bonfire
+# Date created: 2006-05-12
+# Whom: Michael Johnson <ahze@FreeBSD.org>
+#
+# $FreeBSD$
+# $MCom: ports/sysutils/brasero/Makefile,v 1.23 2008/02/06 07:11:46 marcus Exp $
+
+PORTNAME= brasero
+PORTVERSION= 0.7.1
+PORTREVISION= 4
+CATEGORIES= sysutils audio multimedia gnome
+MASTER_SITES= ${MASTER_SITE_GNOME}
+MASTER_SITE_SUBDIR= sources/${PORTNAME}/${PORTVERSION:C/^([0-9]+\.[0-9]+).*/\1/}
+DIST_SUBDIR= gnome2
+
+MAINTAINER= gnome@FreeBSD.org
+COMMENT= CD/DVD mastering tool for the GNOME desktop
+
+LIB_DEPENDS= notify.1:${PORTSDIR}/devel/libnotify \
+ totem-plparser.12:${PORTSDIR}/multimedia/totem-pl-parser
+
+USE_GETTEXT= yes
+USE_BZIP2= yes
+GNU_CONFIGURE= yes
+USE_GMAKE= yes
+USE_GNOME= gnomehier nautiluscdburner
+USE_GSTREAMER= gconf core
+INSTALLS_ICONS= yes
+CONFIGURE_ARGS= --disable-inotify \
+ --with-cam
+CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \
+ LDFLAGS="-L${LOCALBASE}/lib"
+
+MAN1= brasero.1
+GCONF_SCHEMAS= brasero.schemas
+
+post-patch:
+ @${REINPLACE_CMD} -e 's|blank-cd:|blank-cd;|g' \
+ ${WRKSRC}/data/brasero.desktop.in.in
+
+.include <bsd.port.mk>
diff --git a/sysutils/brasero/distinfo b/sysutils/brasero/distinfo
new file mode 100644
index 000000000..ba88da57f
--- /dev/null
+++ b/sysutils/brasero/distinfo
@@ -0,0 +1,3 @@
+MD5 (gnome2/brasero-0.7.1.tar.bz2) = 2754fca21c31f00016981cc8fe7c48be
+SHA256 (gnome2/brasero-0.7.1.tar.bz2) = 0ad851ba9f05c2e4ae0778e61c74aee56bbae3a4181b172009698cde03387f5c
+SIZE (gnome2/brasero-0.7.1.tar.bz2) = 1483716
diff --git a/sysutils/brasero/files/patch-configure b/sysutils/brasero/files/patch-configure
new file mode 100644
index 000000000..3f4958a84
--- /dev/null
+++ b/sysutils/brasero/files/patch-configure
@@ -0,0 +1,264 @@
+--- configure.orig 2008-01-24 16:49:00.000000000 -0500
++++ configure 2008-01-24 16:49:16.000000000 -0500
+@@ -885,6 +885,8 @@ BRASERO_BASE_CFLAGS
+ BRASERO_BASE_LIBS
+ BRASERO_CFLAGS
+ BRASERO_LIBS
++WITH_CAM_TRUE
++WITH_CAM_FALSE
+ LIBBURNIA_CFLAGS
+ LIBBURNIA_LIBS
+ BRASERO_LIBBURNIA_CFLAGS
+@@ -1610,6 +1612,7 @@ Optional Packages:
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-tags[=TAGS] include additional configurations [automatic]
++ --with-cam Build with CAM backend instead of Linux SCSI [default = no]
+ --with-gconf-source=sourceaddress Config database for installing schema files.
+ --with-gconf-schema-file-dir=dir Directory for installing schema files.
+
+@@ -4514,7 +4517,7 @@ ia64-*-hpux*)
+ ;;
+ *-*-irix6*)
+ # Find out which ABI we are using.
+- echo '#line 4517 "configure"' > conftest.$ac_ext
++ echo '#line 4520 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+@@ -7252,11 +7255,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:7255: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:7258: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:7259: \$? = $ac_status" >&5
++ echo "$as_me:7262: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -7542,11 +7545,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:7545: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:7548: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:7549: \$? = $ac_status" >&5
++ echo "$as_me:7552: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -7646,11 +7649,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:7649: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:7652: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:7653: \$? = $ac_status" >&5
++ echo "$as_me:7656: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -9997,7 +10000,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+-#line 10000 "configure"
++#line 10003 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -10097,7 +10100,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+-#line 10100 "configure"
++#line 10103 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -12517,11 +12520,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:12520: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:12523: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:12524: \$? = $ac_status" >&5
++ echo "$as_me:12527: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -12621,11 +12624,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:12624: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:12627: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:12628: \$? = $ac_status" >&5
++ echo "$as_me:12631: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -14185,11 +14188,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:14188: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:14191: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:14192: \$? = $ac_status" >&5
++ echo "$as_me:14195: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -14289,11 +14292,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:14292: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:14295: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:14296: \$? = $ac_status" >&5
++ echo "$as_me:14299: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -16478,11 +16481,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:16481: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:16484: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:16485: \$? = $ac_status" >&5
++ echo "$as_me:16488: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -16768,11 +16771,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:16771: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:16774: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:16775: \$? = $ac_status" >&5
++ echo "$as_me:16778: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -16872,11 +16875,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:16875: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:16878: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:16879: \$? = $ac_status" >&5
++ echo "$as_me:16882: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -22350,6 +22353,27 @@ BRASERO_LIBS="$BRASERO_BASE_LIBS $BRASER
+ LIBBURN_REQUIRED=0.4.0
+ LIBISOFS_REQUIRED=0.2.8
+
++
++# Check whether --with-cam was given.
++if test "${with_cam+set}" = set; then
++ withval=$with_cam;
++else
++ with_cam="no"
++fi
++
++
++if text x"$with_cam" = "xyes"; then
++ BRASERO_LIBS="$BRASERO_LIBS -lcam"
++fi
++ if test x"$with_cam" = "xyes"; then
++ WITH_CAM_TRUE=
++ WITH_CAM_FALSE='#'
++else
++ WITH_CAM_TRUE='#'
++ WITH_CAM_FALSE=
++fi
++
++
+ # Check whether --enable-libburnia was given.
+ if test "${enable_libburnia+set}" = set; then
+ enableval=$enable_libburnia;
+@@ -25144,6 +25168,13 @@ echo "$as_me: error: conditional \"am__f
+ Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
++if test -z "${WITH_CAM_TRUE}" && test -z "${WITH_CAM_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"WITH_CAM\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"WITH_CAM\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
+ if test -z "${BUILD_LIBBURNIA_TRUE}" && test -z "${BUILD_LIBBURNIA_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"BUILD_LIBBURNIA\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&5
+@@ -25945,6 +25976,8 @@ BRASERO_BASE_CFLAGS!$BRASERO_BASE_CFLAGS
+ BRASERO_BASE_LIBS!$BRASERO_BASE_LIBS$ac_delim
+ BRASERO_CFLAGS!$BRASERO_CFLAGS$ac_delim
+ BRASERO_LIBS!$BRASERO_LIBS$ac_delim
++WITH_CAM_TRUE!$WITH_CAM_TRUE$ac_delim
++WITH_CAM_FALSE!$WITH_CAM_FALSE$ac_delim
+ LIBBURNIA_CFLAGS!$LIBBURNIA_CFLAGS$ac_delim
+ LIBBURNIA_LIBS!$LIBBURNIA_LIBS$ac_delim
+ BRASERO_LIBBURNIA_CFLAGS!$BRASERO_LIBBURNIA_CFLAGS$ac_delim
+@@ -26019,8 +26052,6 @@ INTLTOOL_UPDATE!$INTLTOOL_UPDATE$ac_deli
+ INTLTOOL_PERL!$INTLTOOL_PERL$ac_delim
+ ALL_LINGUAS!$ALL_LINGUAS$ac_delim
+ SCHEMAS_INSTALL_TRUE!$SCHEMAS_INSTALL_TRUE$ac_delim
+-SCHEMAS_INSTALL_FALSE!$SCHEMAS_INSTALL_FALSE$ac_delim
+-GCONFTOOL!$GCONFTOOL$ac_delim
+ _ACEOF
+
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
+@@ -26062,6 +26093,8 @@ _ACEOF
+ ac_delim='%!_!# '
+ for ac_last_try in false false false false false :; do
+ cat >conf$$subs.sed <<_ACEOF
++SCHEMAS_INSTALL_FALSE!$SCHEMAS_INSTALL_FALSE$ac_delim
++GCONFTOOL!$GCONFTOOL$ac_delim
+ GCONF_SCHEMA_CONFIG_SOURCE!$GCONF_SCHEMA_CONFIG_SOURCE$ac_delim
+ GCONF_SCHEMA_FILE_DIR!$GCONF_SCHEMA_FILE_DIR$ac_delim
+ GCONF_SCHEMAS_INSTALL_TRUE!$GCONF_SCHEMAS_INSTALL_TRUE$ac_delim
+@@ -26070,7 +26103,7 @@ LIBOBJS!$LIBOBJS$ac_delim
+ LTLIBOBJS!$LTLIBOBJS$ac_delim
+ _ACEOF
+
+- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 6; then
++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 8; then
+ break
+ elif $ac_last_try; then
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/sysutils/brasero/files/patch-src_Makefile.in b/sysutils/brasero/files/patch-src_Makefile.in
new file mode 100644
index 000000000..c57255769
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_Makefile.in
@@ -0,0 +1,275 @@
+--- src/Makefile.in.orig 2008-01-24 16:49:38.000000000 -0500
++++ src/Makefile.in 2008-01-24 16:49:47.000000000 -0500
+@@ -45,7 +45,96 @@ CONFIG_CLEAN_FILES =
+ am__installdirs = "$(DESTDIR)$(bindir)"
+ binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+ PROGRAMS = $(bin_PROGRAMS)
++am__brasero_SOURCES_DIST = brasero-marshal.h brasero-marshal.c main.c \
++ brasero-utils.h brasero-utils.c burn-dbus.h burn-dbus.c \
++ brasero-search-entry.c brasero-search-entry.h \
++ brasero-search-beagle.c brasero-search-beagle.h \
++ brasero-mime-filter.c brasero-mime-filter.h brasero-playlist.c \
++ brasero-playlist.h brasero-player.c brasero-player.h \
++ brasero-menu.h brasero-burn-dialog.c brasero-burn-dialog.h \
++ brasero-disc-copy-dialog.c brasero-disc-copy-dialog.h \
++ brasero-blank-dialog.c brasero-blank-dialog.h inotify.h \
++ brasero-metadata.c brasero-metadata.h inotify-syscalls.h \
++ brasero-filtered-window.c brasero-filtered-window.h \
++ brasero-disc.c brasero-disc.h brasero-data-disc.c \
++ brasero-data-disc.h brasero-audio-disc.c brasero-audio-disc.h \
++ brasero-project.c brasero-project.h \
++ brasero-project-type-chooser.c brasero-project-type-chooser.h \
++ brasero-player-bacon.c brasero-player-bacon.h \
++ brasero-progress.c brasero-progress.h \
++ brasero-song-properties.c brasero-song-properties.h \
++ brasero-tray.c brasero-tray.h burn.c burn.h burn-job.c \
++ burn-job.h burn-process.c burn-process.h burn-basics.h \
++ burn-basics.c burn-caps.c burn-caps.h brasero-session.c \
++ brasero-session.h brasero-app.h brasero-uri-container.c \
++ brasero-uri-container.h brasero-project-manager.c \
++ brasero-project-manager.h brasero-layout.c brasero-layout.h \
++ brasero-file-chooser.c brasero-file-chooser.h \
++ brasero-project-size.c brasero-project-size.h burn-session.h \
++ brasero-sum-dialog.c brasero-sum-dialog.h \
++ brasero-tool-dialog.c brasero-tool-dialog.h brasero-ncb.h \
++ brasero-ncb.c burn-task.c burn-task.h brasero-vfs.c \
++ brasero-vfs.h brasero-async-task-manager.c \
++ brasero-async-task-manager.h eggtreemultidnd.c \
++ eggtreemultidnd.h brasero-multi-dnd.c brasero-multi-dnd.h \
++ brasero-image-option-dialog.c brasero-image-option-dialog.h \
++ brasero-disc-option-dialog.c brasero-disc-option-dialog.h \
++ brasero-image-type-chooser.c brasero-image-type-chooser.h \
++ burn-iso9660.c burn-iso9660.h brasero-layout-object.c \
++ brasero-layout-object.h burn-volume.c burn-volume.h \
++ burn-susp.c burn-susp.h burn-iso-field.c burn-iso-field.h \
++ burn-medium.h cam/cam-cdrom.h cam/freebsd_dvd_rw_utils.h \
++ scsi/scsi-base.h scsi/scsi-command.h scsi/scsi-error.h \
++ scsi/scsi-get-configuration.h scsi/scsi-mmc1.h \
++ scsi/scsi-mmc2.h scsi/scsi-opcodes.h \
++ scsi/scsi-read-disc-info.h scsi/scsi-read-toc-pma-atip.h \
++ scsi/scsi-sense-data.h scsi/scsi-sg.h scsi/scsi-utils.h \
++ scsi/scsi-q-subchannel.h scsi/scsi-read-track-information.h \
++ scsi/scsi-get-performance.h scsi/scsi-mmc3.h \
++ scsi/scsi-mode-pages.h scsi/scsi-status-page.h \
++ scsi/scsi-spc1.h scsi/scsi-read-capacity.h \
++ scsi/scsi-read-disc-structure.h scsi/scsi-dvd-structures.h \
++ scsi/scsi-read-format-capacities.h scsi/scsi-command.c \
++ scsi/scsi-get-configuration.c scsi/scsi-read-disc-info.c \
++ scsi/scsi-read-toc-pma-atip.c scsi/scsi-sense-data.c \
++ scsi/scsi-sg.c scsi/scsi-error.c \
++ scsi/scsi-read-track-information.c scsi/scsi-get-performance.c \
++ scsi/scsi-mode-sense.c scsi/scsi-read-capacity.c \
++ scsi/scsi-read-disc-structure.c \
++ scsi/scsi-read-format-capacities.c burn-medium-scsi.c \
++ cam/cam-cdrom.c cam/freebsd_dvd_rw_utils.c burn-medium-cam.c \
++ burn-debug.c burn-debug.h burn-track.h burn-plugin.h \
++ burn-plugin.c burn-plugin-private.h burn-plugin-manager.c \
++ burn-plugin-manager.h burn-task-ctx.h burn-task-item.c \
++ burn-task-item.h burn-task-ctx.c burn-mkisofs-base.c \
++ burn-mkisofs-base.h brasero-drive-selection.h \
++ brasero-drive-selection.c brasero-src-selection.h \
++ brasero-src-selection.c brasero-dest-selection.h \
++ brasero-dest-selection.c brasero-drive-info.c \
++ brasero-drive-info.h brasero-drive-properties.h \
++ brasero-drive-properties.c brasero-image-properties.h \
++ brasero-image-properties.c brasero-xfer.c brasero-xfer.h \
++ burn-session.c burn-track.c brasero-plugin-manager-ui.c \
++ brasero-plugin-manager-ui.h brasero-pref.h brasero-pref.c \
++ brasero-plugin-option.h brasero-plugin-option.c \
++ brasero-split-dialog.h brasero-split-dialog.c \
++ brasero-time-button.h brasero-time-button.c brasero-preview.h \
++ brasero-preview.c burn-image-format.c burn-image-format.h
+ am__objects_1 = brasero-marshal.$(OBJEXT)
++am__objects_2 = scsi-command.$(OBJEXT) \
++ scsi-get-configuration.$(OBJEXT) scsi-read-disc-info.$(OBJEXT) \
++ scsi-read-toc-pma-atip.$(OBJEXT) scsi-sense-data.$(OBJEXT) \
++ scsi-sg.$(OBJEXT) scsi-error.$(OBJEXT) \
++ scsi-read-track-information.$(OBJEXT) \
++ scsi-get-performance.$(OBJEXT) scsi-mode-sense.$(OBJEXT) \
++ scsi-read-capacity.$(OBJEXT) \
++ scsi-read-disc-structure.$(OBJEXT) \
++ scsi-read-format-capacities.$(OBJEXT) \
++ burn-medium-scsi.$(OBJEXT)
++am__objects_3 = cam-cdrom.$(OBJEXT) freebsd_dvd_rw_utils.$(OBJEXT) \
++ burn-medium-cam.$(OBJEXT)
++@WITH_CAM_FALSE@am__objects_4 = $(am__objects_2)
++@WITH_CAM_TRUE@am__objects_4 = $(am__objects_3)
+ am_brasero_OBJECTS = $(am__objects_1) main.$(OBJEXT) \
+ brasero-utils.$(OBJEXT) burn-dbus.$(OBJEXT) \
+ brasero-search-entry.$(OBJEXT) brasero-search-beagle.$(OBJEXT) \
+@@ -72,19 +161,11 @@ am_brasero_OBJECTS = $(am__objects_1) ma
+ brasero-disc-option-dialog.$(OBJEXT) \
+ brasero-image-type-chooser.$(OBJEXT) burn-iso9660.$(OBJEXT) \
+ brasero-layout-object.$(OBJEXT) burn-volume.$(OBJEXT) \
+- burn-susp.$(OBJEXT) burn-iso-field.$(OBJEXT) \
+- burn-medium.$(OBJEXT) scsi-command.$(OBJEXT) \
+- scsi-get-configuration.$(OBJEXT) scsi-read-disc-info.$(OBJEXT) \
+- scsi-read-toc-pma-atip.$(OBJEXT) scsi-sense-data.$(OBJEXT) \
+- scsi-sg.$(OBJEXT) scsi-error.$(OBJEXT) \
+- scsi-read-track-information.$(OBJEXT) \
+- scsi-get-performance.$(OBJEXT) scsi-mode-sense.$(OBJEXT) \
+- scsi-read-capacity.$(OBJEXT) \
+- scsi-read-disc-structure.$(OBJEXT) \
+- scsi-read-format-capacities.$(OBJEXT) burn-debug.$(OBJEXT) \
+- burn-plugin.$(OBJEXT) burn-plugin-manager.$(OBJEXT) \
+- burn-task-item.$(OBJEXT) burn-task-ctx.$(OBJEXT) \
+- burn-mkisofs-base.$(OBJEXT) brasero-drive-selection.$(OBJEXT) \
++ burn-susp.$(OBJEXT) burn-iso-field.$(OBJEXT) $(am__objects_4) \
++ burn-debug.$(OBJEXT) burn-plugin.$(OBJEXT) \
++ burn-plugin-manager.$(OBJEXT) burn-task-item.$(OBJEXT) \
++ burn-task-ctx.$(OBJEXT) burn-mkisofs-base.$(OBJEXT) \
++ brasero-drive-selection.$(OBJEXT) \
+ brasero-src-selection.$(OBJEXT) \
+ brasero-dest-selection.$(OBJEXT) brasero-drive-info.$(OBJEXT) \
+ brasero-drive-properties.$(OBJEXT) \
+@@ -110,7 +191,7 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLF
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+ SOURCES = $(brasero_SOURCES)
+-DIST_SOURCES = $(brasero_SOURCES)
++DIST_SOURCES = $(am__brasero_SOURCES_DIST)
+ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+@@ -316,6 +397,7 @@ INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I./scsi \
++ -I./cam \
+ -I./md5 \
+ -DBRASERO_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+ -DBRASERO_PREFIX=\"$(prefix)\" \
+@@ -327,9 +409,30 @@ INCLUDES = \
+
+ CLEANFILES = $(RECMARSHALFILES)
+ AM_CFLAGS = -g
+-EXTRA_DIST = cd-content-marshal.list
++CAMFILES = cam/cam-cdrom.c \
++ cam/freebsd_dvd_rw_utils.c \
++ burn-medium-cam.c
++
++SCSIFILES = scsi/scsi-command.c \
++ scsi/scsi-get-configuration.c \
++ scsi/scsi-read-disc-info.c \
++ scsi/scsi-read-toc-pma-atip.c \
++ scsi/scsi-sense-data.c \
++ scsi/scsi-sg.c \
++ scsi/scsi-error.c \
++ scsi/scsi-read-track-information.c \
++ scsi/scsi-get-performance.c \
++ scsi/scsi-mode-sense.c \
++ scsi/scsi-read-capacity.c \
++ scsi/scsi-read-disc-structure.c \
++ scsi/scsi-read-format-capacities.c \
++ burn-medium-scsi.c
++
++EXTRA_DIST = cd-content-marshal.list $(CAMFILES) $(SCSIFILES)
+ GLIB_GENMARSHAL = `pkg-config --variable=glib_genmarshal glib-2.0`
+ RECMARSHALFILES = brasero-marshal.h brasero-marshal.c
++@WITH_CAM_FALSE@SCSISOURCES = $(SCSIFILES)
++@WITH_CAM_TRUE@SCSISOURCES = $(CAMFILES)
+ brasero_SOURCES = \
+ $(RECMARSHALFILES) \
+ main.c \
+@@ -435,43 +538,32 @@ brasero_SOURCES = \
+ burn-iso-field.c \
+ burn-iso-field.h \
+ burn-medium.h \
+- burn-medium.c \
++ cam/cam-cdrom.h \
++ cam/freebsd_dvd_rw_utils.h \
+ scsi/scsi-base.h \
+- scsi/scsi-command.c \
+ scsi/scsi-command.h \
+ scsi/scsi-error.h \
+- scsi/scsi-get-configuration.c \
+ scsi/scsi-get-configuration.h \
+ scsi/scsi-mmc1.h \
+ scsi/scsi-mmc2.h \
+ scsi/scsi-opcodes.h \
+- scsi/scsi-read-disc-info.c \
+ scsi/scsi-read-disc-info.h \
+- scsi/scsi-read-toc-pma-atip.c \
+ scsi/scsi-read-toc-pma-atip.h \
+- scsi/scsi-sense-data.c \
+ scsi/scsi-sense-data.h \
+- scsi/scsi-sg.c \
+ scsi/scsi-sg.h \
+ scsi/scsi-utils.h \
+ scsi/scsi-q-subchannel.h \
+- scsi/scsi-error.c \
+- scsi/scsi-read-track-information.c \
+ scsi/scsi-read-track-information.h \
+- scsi/scsi-get-performance.c \
+ scsi/scsi-get-performance.h \
+ scsi/scsi-mmc3.h \
+ scsi/scsi-mode-pages.h \
+- scsi/scsi-mode-sense.c \
+ scsi/scsi-status-page.h \
+ scsi/scsi-spc1.h \
+- scsi/scsi-read-capacity.c \
+ scsi/scsi-read-capacity.h \
+- scsi/scsi-read-disc-structure.c \
+ scsi/scsi-read-disc-structure.h \
+ scsi/scsi-dvd-structures.h \
+- scsi/scsi-read-format-capacities.c \
+ scsi/scsi-read-format-capacities.h \
++ $(SCSISOURCES) \
+ burn-debug.c \
+ burn-debug.h \
+ burn-track.h \
+@@ -647,7 +739,8 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-iso-field.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-iso9660.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-job.Po@am__quote@
+-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-medium.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-medium-cam.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-medium-scsi.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-mkisofs-base.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-plugin-manager.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-plugin.Po@am__quote@
+@@ -660,7 +753,9 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-track.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn-volume.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/burn.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cam-cdrom.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eggtreemultidnd.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freebsd_dvd_rw_utils.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-command.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-error.Po@am__quote@
+@@ -879,6 +974,34 @@ scsi-read-format-capacities.obj: scsi/sc
+ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o scsi-read-format-capacities.obj `if test -f 'scsi/scsi-read-format-capacities.c'; then $(CYGPATH_W) 'scsi/scsi-read-format-capacities.c'; else $(CYGPATH_W) '$(srcdir)/scsi/scsi-read-format-capacities.c'; fi`
+
++cam-cdrom.o: cam/cam-cdrom.c
++@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cam-cdrom.o -MD -MP -MF $(DEPDIR)/cam-cdrom.Tpo -c -o cam-cdrom.o `test -f 'cam/cam-cdrom.c' || echo '$(srcdir)/'`cam/cam-cdrom.c
++@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cam-cdrom.Tpo $(DEPDIR)/cam-cdrom.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cam/cam-cdrom.c' object='cam-cdrom.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cam-cdrom.o `test -f 'cam/cam-cdrom.c' || echo '$(srcdir)/'`cam/cam-cdrom.c
++
++cam-cdrom.obj: cam/cam-cdrom.c
++@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cam-cdrom.obj -MD -MP -MF $(DEPDIR)/cam-cdrom.Tpo -c -o cam-cdrom.obj `if test -f 'cam/cam-cdrom.c'; then $(CYGPATH_W) 'cam/cam-cdrom.c'; else $(CYGPATH_W) '$(srcdir)/cam/cam-cdrom.c'; fi`
++@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cam-cdrom.Tpo $(DEPDIR)/cam-cdrom.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cam/cam-cdrom.c' object='cam-cdrom.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cam-cdrom.obj `if test -f 'cam/cam-cdrom.c'; then $(CYGPATH_W) 'cam/cam-cdrom.c'; else $(CYGPATH_W) '$(srcdir)/cam/cam-cdrom.c'; fi`
++
++freebsd_dvd_rw_utils.o: cam/freebsd_dvd_rw_utils.c
++@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT freebsd_dvd_rw_utils.o -MD -MP -MF $(DEPDIR)/freebsd_dvd_rw_utils.Tpo -c -o freebsd_dvd_rw_utils.o `test -f 'cam/freebsd_dvd_rw_utils.c' || echo '$(srcdir)/'`cam/freebsd_dvd_rw_utils.c
++@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/freebsd_dvd_rw_utils.Tpo $(DEPDIR)/freebsd_dvd_rw_utils.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cam/freebsd_dvd_rw_utils.c' object='freebsd_dvd_rw_utils.o' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freebsd_dvd_rw_utils.o `test -f 'cam/freebsd_dvd_rw_utils.c' || echo '$(srcdir)/'`cam/freebsd_dvd_rw_utils.c
++
++freebsd_dvd_rw_utils.obj: cam/freebsd_dvd_rw_utils.c
++@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT freebsd_dvd_rw_utils.obj -MD -MP -MF $(DEPDIR)/freebsd_dvd_rw_utils.Tpo -c -o freebsd_dvd_rw_utils.obj `if test -f 'cam/freebsd_dvd_rw_utils.c'; then $(CYGPATH_W) 'cam/freebsd_dvd_rw_utils.c'; else $(CYGPATH_W) '$(srcdir)/cam/freebsd_dvd_rw_utils.c'; fi`
++@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/freebsd_dvd_rw_utils.Tpo $(DEPDIR)/freebsd_dvd_rw_utils.Po
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cam/freebsd_dvd_rw_utils.c' object='freebsd_dvd_rw_utils.obj' libtool=no @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freebsd_dvd_rw_utils.obj `if test -f 'cam/freebsd_dvd_rw_utils.c'; then $(CYGPATH_W) 'cam/freebsd_dvd_rw_utils.c'; else $(CYGPATH_W) '$(srcdir)/cam/freebsd_dvd_rw_utils.c'; fi`
++
+ mostlyclean-libtool:
+ -rm -f *.lo
+
diff --git a/sysutils/brasero/files/patch-src_brasero-ncb.h b/sysutils/brasero/files/patch-src_brasero-ncb.h
new file mode 100644
index 000000000..bd5106d64
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_brasero-ncb.h
@@ -0,0 +1,12 @@
+--- src/brasero-ncb.h.orig 2008-01-02 15:01:39.000000000 -0500
++++ src/brasero-ncb.h 2008-01-02 15:02:15.000000000 -0500
+@@ -42,6 +42,9 @@ nautilus_burn_drive_get_drive_type ((dri
+ #define NCB_DRIVE_GET_DEVICE(drive) \
+ nautilus_burn_drive_get_device (drive)
+
++#define NCB_DRIVE_GET_CRECORD_DEVICE(drive) \
++nautilus_burn_drive_get_cdrecord_device (drive)
++
+ #define NCB_DRIVE_GET_LIST(list, recorders, image) \
+ { \
+ NautilusBurnDriveMonitor *monitor; \
diff --git a/sysutils/brasero/files/patch-src_burn-job.c b/sysutils/brasero/files/patch-src_burn-job.c
new file mode 100644
index 000000000..c26d1bb72
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_burn-job.c
@@ -0,0 +1,31 @@
+--- src/burn-job.c.orig 2008-01-02 15:00:34.000000000 -0500
++++ src/burn-job.c 2008-01-02 15:01:15.000000000 -0500
+@@ -1300,6 +1300,28 @@ brasero_job_get_device (BraseroJob *self
+ }
+
+ BraseroBurnResult
++brasero_job_get_cdrecord_device (BraseroJob *self, gchar **device)
++{
++ BraseroBurnSession *session;
++ NautilusBurnDrive *drive;
++ BraseroJobPrivate *priv;
++ const gchar *path;
++
++ BRASERO_JOB_DEBUG (self);
++
++ g_return_val_if_fail (device != NULL, BRASERO_BURN_ERR);
++
++ priv = BRASERO_JOB_PRIVATE (self);
++ session = brasero_task_ctx_get_session (priv->ctx);
++
++ drive = brasero_burn_session_get_burner (session);
++ path = NCB_DRIVE_GET_CRECORD_DEVICE (drive);
++ *device = g_strdup (path);
++
++ return BRASERO_BURN_OK;
++}
++
++BraseroBurnResult
+ brasero_job_get_media (BraseroJob *self, BraseroMedia *media)
+ {
+ BraseroBurnSession *session;
diff --git a/sysutils/brasero/files/patch-src_burn-job.h b/sysutils/brasero/files/patch-src_burn-job.h
new file mode 100644
index 000000000..d73d8e6e2
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_burn-job.h
@@ -0,0 +1,12 @@
+--- src/burn-job.h.orig 2008-01-02 14:59:55.000000000 -0500
++++ src/burn-job.h 2008-01-02 15:00:13.000000000 -0500
+@@ -148,6 +148,9 @@ BraseroBurnResult
+ brasero_job_get_device (BraseroJob *job, gchar **device);
+
+ BraseroBurnResult
++brasero_job_get_cdrecord_device (BraseroJob *job, gchar **device);
++
++BraseroBurnResult
+ brasero_job_get_media (BraseroJob *job, BraseroMedia *media);
+
+ BraseroBurnResult
diff --git a/sysutils/brasero/files/patch-src_burn-medium-cam.c b/sysutils/brasero/files/patch-src_burn-medium-cam.c
new file mode 100644
index 000000000..2db8d00ca
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_burn-medium-cam.c
@@ -0,0 +1,1928 @@
+--- src/burn-medium-cam.c.orig 2008-02-06 01:53:39.000000000 -0500
++++ src/burn-medium-cam.c 2008-02-06 01:56:01.000000000 -0500
+@@ -0,0 +1,1925 @@
++/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
++/*
++ * brasero
++ * Copyright (C) Philippe Rouquier 2007 <bonfire-app@wanadoo.fr>
++ * Joe Marcus Clarke 2007 <marcus@FreeBSD.org>
++ *
++ * 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.
++ *
++ * 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 brasero. If not, write to:
++ * The Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor
++ * Boston, MA 02110-1301, USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <stdlib.h>
++#include <fcntl.h>
++#include <errno.h>
++
++#include <glib.h>
++#include <glib/gi18n-lib.h>
++
++#include <nautilus-burn-drive.h>
++
++#include "burn-basics.h"
++#include "burn-debug.h"
++#include "burn-medium.h"
++#include "cam-cdrom.h"
++#include "scsi-read-format-capacities.h"
++#include "scsi-read-toc-pma-atip.h"
++#include "scsi-get-configuration.h"
++#include "scsi-q-subchannel.h"
++#include "scsi-utils.h"
++#include "freebsd_dvd_rw_utils.h"
++#include "burn-volume.h"
++#include "brasero-ncb.h"
++
++const gchar *icons [] = { "gnome-dev-removable",
++ "gnome-dev-cdrom",
++ "gnome-dev-disc-cdr",
++ "gnome-dev-disc-cdrw",
++ "gnome-dev-disc-dvdrom",
++ "gnome-dev-disc-dvdr",
++ "gnome-dev-disc-dvdrw",
++ "gnome-dev-disc-dvdr-plus",
++ "gnome-dev-disc-dvdram",
++ NULL };
++const gchar *types [] = { N_("file"),
++ N_("CDROM"),
++ N_("CD-R"),
++ N_("CD-RW"),
++ N_("DVDROM"),
++ N_("DVD-R"),
++ N_("DVD-RW"),
++ N_("DVD+R"),
++ N_("DVD+RW"),
++ N_("DVD+R dual layer"),
++ N_("DVD+RW dual layer"),
++ N_("DVD-R dual layer"),
++ N_("DVD-RAM"),
++ N_("Blu-ray disc"),
++ N_("Writable Blu-ray disc"),
++ N_("Rewritable Blu-ray disc"),
++ NULL };
++
++
++typedef struct _BraseroMediumPrivate BraseroMediumPrivate;
++struct _BraseroMediumPrivate
++{
++ gint retry_id;
++
++ GSList * tracks;
++
++ const gchar *type;
++ const gchar *icon;
++
++ gint max_rd;
++ gint max_wrt;
++
++ gint *rd_speeds;
++ gint *wr_speeds;
++
++ gint64 block_num;
++ gint64 block_size;
++
++ guint64 next_wr_add;
++ BraseroMedia info;
++ NautilusBurnDrive * drive;
++};
++
++#define BRASERO_MEDIUM_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_MEDIUM, BraseroMediumPrivate))
++
++enum
++{
++ PROP_0,
++ PROP_DRIVE
++};
++
++static GObjectClass* parent_class = NULL;
++
++const gchar *
++brasero_medium_get_type_string (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->type;
++}
++
++const gchar *
++brasero_medium_get_icon (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->icon;
++}
++
++BraseroMedia
++brasero_medium_get_status (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->info;
++}
++
++GSList *
++brasero_medium_get_tracks (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return g_slist_copy (priv->tracks);
++}
++
++gboolean
++brasero_medium_get_last_data_track_address (BraseroMedium *medium,
++ gint64 *byte,
++ gint64 *sector)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type & BRASERO_MEDIUM_TRACK_DATA)
++ track = current;
++ }
++
++ if (!track) {
++ if (byte)
++ *byte = -1;
++ if (sector)
++ *sector = -1;
++ return FALSE;
++ }
++
++ if (byte)
++ *byte = track->start * priv->block_size;
++
++ if (sector)
++ *sector = track->start;
++
++ return TRUE;
++}
++
++gboolean
++brasero_medium_get_last_data_track_space (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type & BRASERO_MEDIUM_TRACK_DATA)
++ track = current;
++ }
++
++ if (!track) {
++ if (size)
++ *size = -1;
++ if (blocks)
++ *blocks = -1;
++ return FALSE;
++ }
++
++ if (size)
++ *size = track->blocks_num * priv->block_size;
++ if (blocks)
++ *blocks = track->blocks_num;
++
++ return TRUE;
++}
++
++guint
++brasero_medium_get_track_num (BraseroMedium *medium)
++{
++ guint retval = 0;
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type & BRASERO_MEDIUM_TRACK_LEADOUT)
++ break;
++
++ retval ++;
++ }
++
++ return retval;
++}
++
++static BraseroMediumTrack *
++brasero_medium_get_track (BraseroMedium *medium,
++ guint num)
++{
++ guint i = 1;
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type == BRASERO_MEDIUM_TRACK_LEADOUT)
++ break;
++
++ if (i == num)
++ return current;
++
++ i++;
++ }
++
++ return NULL;
++}
++
++gboolean
++brasero_medium_get_track_space (BraseroMedium *medium,
++ guint num,
++ gint64 *size,
++ gint64 *blocks)
++{
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ track = brasero_medium_get_track (medium, num);
++ if (!track) {
++ if (size)
++ *size = -1;
++ if (blocks)
++ *blocks = -1;
++ return FALSE;
++ }
++
++ if (size)
++ *size = track->blocks_num * priv->block_size;
++ if (blocks)
++ *blocks = track->blocks_num;
++
++ return TRUE;
++}
++
++gboolean
++brasero_medium_get_track_address (BraseroMedium *medium,
++ guint num,
++ gint64 *byte,
++ gint64 *sector)
++{
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ track = brasero_medium_get_track (medium, num);
++ if (!track) {
++ if (byte)
++ *byte = -1;
++ if (sector)
++ *sector = -1;
++ return FALSE;
++ }
++
++ if (byte)
++ *byte = track->start * priv->block_size;
++ if (sector)
++ *sector = track->start;
++
++ return TRUE;
++}
++
++gint64
++brasero_medium_get_next_writable_address (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->next_wr_add;
++}
++
++gint64
++brasero_medium_get_max_write_speed (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->max_wrt * 1024;
++}
++
++/**
++ * NOTEs about the following functions:
++ * for all closed media (including ROM types) capacity == size of data and
++ * should be the size of all data on the disc, free space is 0
++ * for all blank -R types capacity == free space and size of data == 0
++ * for all multisession -R types capacity == free space since having the real
++ * capacity of the media would be useless as we can only use this type of media
++ * to append more data
++ * for all -RW types capacity = free space + size of data. Here they can be
++ * appended (use free space) or rewritten (whole capacity).
++ *
++ * Usually:
++ * the free space is the size of the leadout track
++ * the size of data is the sum of track sizes (excluding leadout)
++ * the capacity depends on the media:
++ * for closed discs == sum of track sizes
++ * for multisession discs == free space (leadout size)
++ * for blank discs == (free space) leadout size
++ * for rewritable/blank == use SCSI functions to get capacity (see below)
++ *
++ * In fact we should really need the size of data in DVD+/-RW cases since the
++ * session is always equal to the size of the disc.
++ */
++
++void
++brasero_medium_get_data_size (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ if (!priv->tracks) {
++ /* that's probably because it wasn't possible to retrieve info */
++ if (size)
++ *size = 0;
++
++ if (blocks)
++ *blocks = 0;
++
++ return;
++ }
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *tmp;
++
++ tmp = iter->data;
++ if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT)
++ break;
++
++ track = iter->data;
++ }
++
++ if (size)
++ *size = track ? (track->start + track->blocks_num) * priv->block_size: 0;
++
++ if (blocks)
++ *blocks = track ? track->start + track->blocks_num: 0;
++}
++
++void
++brasero_medium_get_free_space (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ if (!priv->tracks) {
++ /* that's probably because it wasn't possible to retrieve info.
++ * maybe it also happens with unformatted DVD+RW */
++
++ if (priv->info & BRASERO_MEDIUM_CLOSED) {
++ if (size)
++ *size = 0;
++
++ if (blocks)
++ *blocks = 0;
++ }
++ else {
++ if (size)
++ *size = priv->block_num * priv->block_size;
++
++ if (blocks)
++ *blocks = priv->block_num;
++ }
++
++ return;
++ }
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *tmp;
++
++ tmp = iter->data;
++ if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT) {
++ track = iter->data;
++ break;
++ }
++ }
++
++ if (size) {
++ if (!track) {
++ /* No leadout was found so the disc is probably closed:
++ * no free space left. */
++ *size = 0;
++ }
++ else if (track->blocks_num <= 0)
++ *size = (priv->block_num - track->start) * priv->block_size;
++ else
++ *size = track->blocks_num * priv->block_size;
++ }
++
++ if (blocks) {
++ if (!track) {
++ /* No leadout was found so the disc is probably closed:
++ * no free space left. */
++ *blocks = 0;
++ }
++ else if (track->blocks_num <= 0)
++ *blocks = priv->block_num - track->blocks_num;
++ else
++ *blocks = track->blocks_num;
++ }
++}
++
++void
++brasero_medium_get_capacity (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ if (priv->info & BRASERO_MEDIUM_REWRITABLE) {
++ if (size)
++ *size = priv->block_num * priv->block_size;
++
++ if (blocks)
++ *blocks = priv->block_num;
++ }
++ else if (priv->info & BRASERO_MEDIUM_CLOSED)
++ brasero_medium_get_data_size (medium, size, blocks);
++ else
++ brasero_medium_get_free_space (medium, size, blocks);
++}
++
++/**
++ * Function to retrieve the capacity of a media
++ */
++
++static BraseroBurnResult
++brasero_medium_get_capacity_CD_RW (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ unsigned char *atip_data = NULL;
++ unsigned char *desc;
++ BraseroMediumPrivate *priv;
++ int result;
++ int size;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ BRASERO_BURN_LOG ("Retrieving capacity from atip");
++
++ result = brasero_cdrom_read_atip (cdrom, &atip_data);
++
++ if (result != 0) {
++ g_free (atip_data);
++
++ BRASERO_BURN_LOG ("READ ATIP failed (scsi error)");
++ return BRASERO_BURN_ERR;
++ }
++
++ size = (atip_data[0] << 8 | atip_data[1]) - 2;
++
++ /* check the size of the structure: it must be at least 16 bytes long */
++ if (size < 16) {
++ if (size)
++ g_free (atip_data);
++
++ BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
++ return BRASERO_BURN_ERR;
++ }
++
++ desc = atip_data + 8;
++
++ priv->block_num = BRASERO_MSF_TO_LBA (desc[8], desc[9], desc[10]);
++ g_free (atip_data);
++
++ BRASERO_BURN_LOG ("Format capacity %lli %lli",
++ priv->block_num,
++ priv->block_size);
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_capacity_DVD_RW (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ unsigned char *hdr = NULL;
++ unsigned char *current;
++ BraseroMediumPrivate *priv;
++ int result;
++
++ BRASERO_BURN_LOG ("Retrieving format capacity");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_cdrom_read_format_capacities (cdrom, &hdr);
++ if (result != 0) {
++ g_free (hdr);
++
++ BRASERO_BURN_LOG ("READ FORMAT CAPACITIES failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ current = hdr + 5;
++
++ /* see if the media is already formatted */
++ if ((current[4] & 3) != BRASERO_SCSI_DESC_FORMATTED) {
++ int i, max;
++ unsigned char *desc;
++
++ max = (hdr[4] - 8) / 8;
++
++ desc = hdr + 5;
++ for (i = 0; i < max; i ++, desc += 8) {
++ /* search for the correct descriptor */
++ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)) {
++ if ((desc[4] >> 2) == BRASERO_SCSI_DVDRW_PLUS) {
++ priv->block_num = (desc[0] << 24 | desc[1] << 16 | desc[2] << 8 | desc[3]);
++ priv->block_size = (desc[5] << 16 | desc[6] << 8 | desc[7]);
++
++ /* that can happen */
++ if (!priv->block_size)
++ priv->block_size = 2048;
++ break;
++ }
++ }
++ else if ((desc[4] >> 2) == BRASERO_SCSI_BLOCK_SIZE_DEFAULT_AND_DB) {
++ priv->block_num = (desc[0] << 24 | desc[1] << 16 | desc[2] << 8 | desc[3]);
++ priv->block_size = (desc[5] << 16 | desc[6] << 8 | desc[7]);
++ break;
++ }
++ }
++ }
++ else {
++ priv->block_num = (current[0] << 24 | current[1] << 16 | current[2] << 8 | current[3]);
++ priv->block_size = (current[5] << 16 | current[6] << 8 | current[7]);
++ }
++
++ BRASERO_BURN_LOG ("Format capacity %lli %lli",
++ priv->block_num,
++ priv->block_size);
++
++ g_free (hdr);
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_capacity_by_type (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ priv->block_size = 2048;
++
++ if (!(priv->info & BRASERO_MEDIUM_REWRITABLE))
++ return BRASERO_BURN_OK;
++
++ if (priv->info & BRASERO_MEDIUM_CD)
++ brasero_medium_get_capacity_CD_RW (self, cdrom);
++ else
++ brasero_medium_get_capacity_DVD_RW (self, cdrom);
++
++ return BRASERO_BURN_OK;
++}
++
++/**
++ * Functions to retrieve the speed
++ */
++
++static BraseroBurnResult
++brasero_medium_get_speed_mmc3 (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ int size;
++ int num_desc, i;
++ gint max_rd, max_wrt;
++ int result;
++ BraseroMediumPrivate *priv;
++ unsigned char *desc;
++ unsigned char *wrt_perf = NULL;
++
++ BRASERO_BURN_LOG ("Retrieving speed (Get Performance)");
++
++ /* NOTE: this only work if there is RT streaming feature with
++ * wspd bit set to 1. At least an MMC3 drive. */
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_cdrom_get_performance_wrt_spd_desc (cdrom, &wrt_perf);
++
++ if (result != 0) {
++ g_free (wrt_perf);
++
++ BRASERO_BURN_LOG ("GET PERFORMANCE failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ size = 4 + (wrt_perf[0] << 24 | wrt_perf[1] << 16 | wrt_perf[2] << 8 | wrt_perf[3]);
++
++ num_desc = (size - 8) / 16;
++
++ if (num_desc <= 0)
++ goto end;
++
++ priv->rd_speeds = g_new0 (gint, num_desc + 1);
++ priv->wr_speeds = g_new0 (gint, num_desc + 1);
++
++ max_rd = 0;
++ max_wrt = 0;
++
++ desc = wrt_perf + 8;
++ for (i = 0; i < num_desc; i ++, desc += 16) {
++ priv->rd_speeds [i] = (desc[8] << 24 | desc[9] << 16 | desc[10] << 8 || desc[11]);
++ priv->wr_speeds [i] = (desc[12] << 24 | desc[13] << 16 | desc[14] << 8 | desc[15]);
++
++ max_rd = MAX (max_rd, priv->rd_speeds [i]);
++ max_wrt = MAX (max_wrt, priv->wr_speeds [i]);
++ }
++
++ priv->max_rd = max_rd;
++ priv->max_wrt = max_wrt;
++
++end:
++
++ g_free (wrt_perf);
++
++ /* strangely there are so drives (I know one case) which support this
++ * function but don't report any speed. So if our top speed is 0 then
++ * use the other way to get the speed. It was a Teac */
++ if (!priv->max_wrt)
++ return BRASERO_BURN_ERR;
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_page_2A_write_speed_desc (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ BraseroMediumPrivate *priv;
++ int result;
++ char *wspeeds;
++ int rspeed, wspeed;
++
++ BRASERO_BURN_LOG ("Retrieving speed (2A speeds)");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_cdrom_get_read_write_speed (cdrom, &rspeed, &wspeed, &wspeeds);
++
++ if (result != 0) {
++ BRASERO_BURN_LOG ("MODE SENSE failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ if (wspeeds != NULL) {
++ char **speedv;
++ int i;
++
++ speedv = g_strsplit_set (wspeeds, ",", 0);
++ g_free (wspeeds);
++ priv->wr_speeds = g_new0 (gint, g_strv_length (speedv) + 1);
++ for (i = 0; speedv[i] != NULL; i++) {
++ if (*(speedv[i]))
++ priv->wr_speeds[i] = atoi (speedv[i]);
++ }
++ g_strfreev (speedv);
++ }
++
++ priv->max_wrt = wspeed;
++ priv->max_rd = rspeed;
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_page_2A_max_speed (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ BraseroMediumPrivate *priv;
++ int result;
++ int rspeed, wspeed;
++ char *wspeeds;
++
++ BRASERO_BURN_LOG ("Retrieving speed (2A max)");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ result = brasero_cdrom_get_read_write_speed (cdrom, &rspeed, &wspeed, &wspeeds);
++
++ if (result != 0) {
++ BRASERO_BURN_LOG ("MODE SENSE failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ priv->max_rd = rspeed;
++ priv->max_wrt = wspeed;
++
++ g_free (wspeeds);
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_medium_type (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ unsigned char *hdr = NULL;
++ unsigned char *confdesc;
++ BraseroMediumPrivate *priv;
++ BraseroBurnResult result;
++ int profile;
++ int res;
++
++ BRASERO_BURN_LOG ("Retrieving media profile");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ res = brasero_cdrom_get_configuration_feature (cdrom,
++ BRASERO_SCSI_FEAT_REAL_TIME_STREAM,
++ &hdr);
++ if (res != 0) {
++ unsigned char *data = NULL;
++ unsigned char *desc;
++ int size;
++
++ 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. */
++
++ /* 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.
++ */
++ res = brasero_cdrom_read_atip (cdrom, &data);
++ if (res != 0) {
++ /* 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 */
++ size = (data[0] << 8 | data[1]) - 2;
++ if (size < 8) {
++ if (size)
++ g_free (data);
++
++ BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
++ return BRASERO_BURN_ERR;
++ }
++
++ desc = data + 4;
++
++ if ((desc[2] >> 6) & 1) {
++ /* 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);
++ }
++
++ /* retrieve the speed */
++ result = brasero_medium_get_page_2A_max_speed (self, cdrom);
++ return result;
++ }
++
++ profile = (hdr[6] << 8 | hdr[7]);
++
++ switch (profile) {
++ case BRASERO_SCSI_PROF_CDROM:
++ priv->info = BRASERO_MEDIUM_CDROM;
++ priv->type = types [1];
++ priv->icon = icons [1];
++ break;
++
++ case BRASERO_SCSI_PROF_CDR:
++ priv->info = BRASERO_MEDIUM_CDR;
++ priv->type = types [2];
++ priv->icon = icons [2];
++ break;
++
++ case BRASERO_SCSI_PROF_CDRW:
++ priv->info = BRASERO_MEDIUM_CDRW;
++ priv->type = types [3];
++ priv->icon = icons [3];
++ break;
++
++ 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;
++
++ case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
++ priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
++ priv->type = types [6];
++ priv->icon = icons [6];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
++ priv->info = BRASERO_MEDIUM_DVDRW;
++ priv->type = types [6];
++ priv->icon = icons [6];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_R_PLUS:
++ priv->info = BRASERO_MEDIUM_DVDR_PLUS;
++ priv->type = types [7];
++ priv->icon = icons [7];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_RW_PLUS:
++ priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
++ priv->type = types [8];
++ priv->icon = icons [7];
++ break;
++
++ /* WARNING: these types are recognized, no more */
++ case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
++ priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
++ priv->type = types [9];
++ priv->icon = icons [7];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
++ priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
++ priv->type = types [10];
++ priv->icon = icons [7];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
++ priv->info = BRASERO_MEDIUM_DVDR_DL;
++ priv->type = types [11];
++ priv->icon = icons [5];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
++ priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
++ priv->type = types [11];
++ priv->icon = icons [5];
++ 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_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;
++ 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_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;
++ }
++
++ confdesc = hdr + 8;
++
++ /* try all SCSI functions to get write/read speeds in order */
++ if (confdesc[4] >= 4) {
++ unsigned char *stream;
++
++ /* means it's at least an MMC3 drive */
++ stream = confdesc + 5;
++ if ((stream[0] >> 1) & 1) {
++ result = brasero_medium_get_speed_mmc3 (self, cdrom);
++ if (result == BRASERO_BURN_OK)
++ goto end;
++ }
++
++ if ((stream[0] >> 2) & 1) {
++ result = brasero_medium_get_page_2A_write_speed_desc (self, cdrom);
++ if (result == BRASERO_BURN_OK)
++ goto end;
++ }
++ }
++
++ /* fallback for speeds */
++ result = brasero_medium_get_page_2A_max_speed (self, cdrom);
++
++end:
++
++ g_free (hdr);
++
++ if (result != BRASERO_BURN_OK)
++ return result;
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_css_feature (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ unsigned char *hdr = NULL;
++ BraseroMediumPrivate *priv;
++ int result;
++ int size;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ BRASERO_BURN_LOG ("Testing for Css encrypted media");
++ result = brasero_cdrom_get_configuration_feature (cdrom,
++ BRASERO_SCSI_FEAT_DVD_CSS,
++ &hdr);
++ if (result != 0) {
++ g_free (hdr);
++
++ BRASERO_BURN_LOG ("GET CONFIGURATION failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ size = 4 + (hdr[0] << 24 | hdr[1] << 16 | hdr[2] << 8 | hdr[3]);
++
++ if (size < 9 || hdr[12] < 4) {
++ g_free (hdr);
++ return BRASERO_BURN_OK;
++ }
++
++ /* here we just need to see if this feature is current or not */
++ if (hdr[11] & 1) {
++ 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 void
++brasero_medium_set_track_type (BraseroMedium *self,
++ BraseroMediumTrack *track,
++ guchar control)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ if (control & BRASERO_SCSI_TRACK_COPY)
++ track->type |= BRASERO_MEDIUM_TRACK_COPY;
++
++ if (!(control & BRASERO_SCSI_TRACK_DATA)) {
++ track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
++ priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
++
++ if (control & BRASERO_SCSI_TRACK_PREEMP)
++ track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
++
++ if (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 (control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
++ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
++ }
++}
++
++static BraseroBurnResult
++brasero_medium_track_volume_size (BraseroMedium *self,
++ BraseroMediumTrack *track,
++ BRASEROCDROM *cdrom)
++{
++ BraseroMediumPrivate *priv;
++ BraseroBurnResult res;
++ GError *error = NULL;
++ 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 */
++ res = brasero_volume_get_size_fd (brasero_cdrom_get_fd (cdrom),
++ track->start,
++ &nb_blocks,
++ NULL);
++ 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 BraseroBurnResult
++brasero_medium_track_get_info (BraseroMedium *self,
++ BraseroMediumTrack *track,
++ int track_num,
++ BRASEROCDROM *cdrom)
++{
++ unsigned char track_info[48];
++ BraseroMediumPrivate *priv;
++ int result;
++ int size;
++ int next_wrt;
++
++ 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_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_cdrom_read_track_info (cdrom, track_num, track_info, size);
++
++ if (result != 0) {
++ BRASERO_BURN_LOG ("READ TRACK INFO failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ track->blocks_num = (track_info[24] << 24 | track_info[25] << 16 | track_info[26] << 8 | track_info[27]);
++ track->session = (track_info[33] << 8 | track_info[3]);
++
++ /* Now here is a potential bug: we can write tracks (data or not)
++ * shorter than 300 Kio /2 sec but they will be padded to reach this
++ * floor value. That means that is blocks_num is 300 blocks that may
++ * mean that the data length on the track is actually shorter.
++ * So we read the volume descriptor. If it works, good otherwise
++ * use the old value.
++ * That's important for checksuming to have a perfect account of the
++ * data size. */
++ if (track->blocks_num <= 300) {
++ BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
++ brasero_medium_track_volume_size (self, track, cdrom);
++ }
++
++ next_wrt = (track_info[12] << 24 | track_info[13] << 16 | track_info[14] << 7 | track_info[15]);
++
++ if (next_wrt);
++ priv->next_wr_add = next_wrt;
++
++ 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;
++}
++
++/**
++ * return :
++ * 0 when it's not possible to determine (fallback to formatted toc)
++ * -1 for BCD
++ * 1 for HEX */
++static guint
++brasero_medium_check_BCD_use (BraseroMedium *self,
++ BRASEROCDROM *cdrom,
++ unsigned char *desc,
++ guint num)
++{
++ guint i;
++ int size;
++ guint leadout = 0;
++ guint track_num = 0;
++ gboolean use_BCD = TRUE;
++ gboolean use_HEX = TRUE;
++ int result;
++ unsigned char *dptr;
++ unsigned char track_info[48];
++ guint start_BCD, start_LBA, track_start;
++
++ /* first check if all values are valid BCD numbers in the descriptors */
++ dptr = desc;
++ for (i = 0; i < num; i++, dptr += 11) {
++ if ((dptr[1] >> 4) == 1 && dptr[3] <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
++ if (!BRASERO_IS_BCD_VALID (dptr[8])
++ || !BRASERO_IS_BCD_VALID (dptr[9])
++ || !BRASERO_IS_BCD_VALID (dptr[10])) {
++ use_BCD = FALSE;
++ break;
++ }
++ }
++ else if (dptr[3] == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
++ if (!BRASERO_IS_BCD_VALID (dptr[8])
++ || !BRASERO_IS_BCD_VALID (dptr[9])
++ || !BRASERO_IS_BCD_VALID (dptr[10])) {
++ use_BCD = FALSE;
++ break;
++ }
++ }
++ }
++
++ /* then check if there are valid Hex values */
++ dptr = desc;
++ for (i = 0; i < num; i++, dptr += 11) {
++ if ((dptr[i] >> 4) != 1 || dptr[3] > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
++ continue;
++
++ if (dptr[8] > 99
++ || dptr[9] > 59
++ || dptr[10] > 74) {
++ use_HEX = FALSE;
++ break;
++ }
++ }
++
++ if (use_BCD != use_HEX) {
++ if (use_BCD)
++ return -1;
++
++ return 1;
++ }
++
++ /* To check if the drive uses BCD values or HEX values we ask for the
++ * track information that contains also the start for the track but in
++ * HEX values. If values are the same then it works. */
++
++ /* NOTE: there could be another way to do it: get first track, in LBA
++ * and BCD it must be 150. */
++
++ /* First find the first track and get track start address in BCD */
++ BRASERO_BURN_LOG ("Retrieving track information to determine number format");
++
++ dptr = desc;
++ for (i = 0; i < num; i++, dptr += 11) {
++ if ((dptr[1] >> 4) == BRASERO_SCSI_Q_SUB_CHANNEL_LEADIN_MODE5
++ && dptr[3] == BRASERO_SCSI_Q_SUB_CHANNEL_MULTI_NEXT_SESSION) {
++ /* store the leadout number just in case */
++ leadout = i;
++ continue;
++ }
++
++ if ((dptr[1] >> 4) != 1 || dptr[3] > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
++ continue;
++
++ track_num ++;
++
++ start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (dptr[8]),
++ BRASERO_GET_BCD (dptr[9]),
++ BRASERO_GET_BCD (dptr[10]));
++
++ start_LBA = BRASERO_MSF_TO_LBA (dptr[8], dptr[9], dptr[10]);
++
++ BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for track %i", track_num);
++
++ size = 36;
++ start_LBA -= 150;
++ start_BCD -= 150;
++
++ result = brasero_cdrom_read_track_info (cdrom,
++ track_num,
++ track_info,
++ size);
++
++ if (result != 0) {
++ BRASERO_BURN_LOG ("READ TRACK INFO failed");
++ /* Fallback to formatted toc */
++ return 0;
++ }
++
++ track_start = (track_info[8] << 24 | track_info[9] << 16 | track_info[10] << 8 | track_info[11]);
++ BRASERO_BURN_LOG ("comparing DCB %i and LBA %i to real start address %i",
++ start_BCD, start_LBA, track_start);
++
++ /* try to find a conclusive match */
++ if (track_start == start_BCD && track_start != start_LBA)
++ return -1;
++
++ if (track_start == start_LBA && track_start != start_BCD)
++ return 1;
++ }
++
++ /* Our last chance, the leadout.
++ * NOTE: no need to remove 150 sectors here. */
++ dptr = desc + (leadout * 11);
++ start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (dptr[4]),
++ BRASERO_GET_BCD (dptr[5]),
++ BRASERO_GET_BCD (dptr[6]));
++
++ start_LBA = BRASERO_MSF_TO_LBA (dptr[4], dptr[5], dptr[6]);
++
++ BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for leadout");
++
++ size = 36;
++
++ /* leadout number is number of tracks + 1 */
++ result = brasero_cdrom_read_track_info (cdrom,
++ track_num + 1,
++ track_info,
++ size);
++
++ if (result != 0) {
++ BRASERO_BURN_LOG ("READ TRACK INFO failed for leadout");
++ /* Fallback to formatted toc */
++ return 0;
++ }
++
++ track_start = (track_info[8] << 24 | track_info[9] << 16 | track_info[10] << 8 | track_info[11]);
++ BRASERO_BURN_LOG ("comparing DCB %i and LBA %i to real start address %i",
++ start_BCD, start_LBA, track_start);
++
++ /* try to find a conclusive match */
++ if (track_start == start_BCD && track_start != start_LBA)
++ return -1;
++
++ if (track_start == start_LBA && track_start != start_BCD)
++ return 1;
++
++ /* fallback to formatted toc */
++ return 0;
++}
++
++/**
++ * The reason why we use this perhaps more lengthy method is that with
++ * multisession discs, the first track is reported to be two sectors shorter
++ * than it should. As I don't know why and since the following works we use
++ * this one. */
++static BraseroBurnResult
++brasero_medium_get_CD_sessions_info (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ gint use_bcd;
++ GSList *iter;
++ int num, i, size, res;
++ gint leadout_start = 0;
++ BraseroMediumPrivate *priv;
++ unsigned char *desc;
++ unsigned char *toc = NULL;
++
++ BRASERO_BURN_LOG ("Reading Raw Toc");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ res = brasero_cdrom_read_toc_raw (cdrom, 0, &toc);
++ if (res != 0) {
++ BRASERO_BURN_LOG ("READ TOC failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ size = (toc[0] << 8 | toc[1]) - 2;
++ num = size / 11;
++
++ BRASERO_BURN_LOG ("%i track(s) found", num);
++
++ desc = toc + 4;
++ use_bcd = brasero_medium_check_BCD_use (self, cdrom, desc, num);
++ if (!use_bcd) {
++ g_free (toc);
++
++ BRASERO_BURN_LOG ("Fallback to formatted toc");
++ return BRASERO_BURN_ERR;
++ }
++
++ if (use_bcd > 0)
++ use_bcd = 0;
++
++ if (use_bcd) {
++ BRASERO_BURN_LOG ("Using BCD format");
++ }
++ else {
++ BRASERO_BURN_LOG ("Using HEX format");
++ }
++
++ for (i = 0; i < num; i++, desc += 11) {
++ BraseroMediumTrack *track;
++
++ track = NULL;
++ if ((desc[1] >> 4) == 1 && desc[3] <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
++ track = g_new0 (BraseroMediumTrack, 1);
++ track->session = desc[0];
++
++ brasero_medium_set_track_type (self, track, (desc[1] & 15));
++ if (use_bcd)
++ track->start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc[8]),
++ BRASERO_GET_BCD (desc[9]),
++ BRASERO_GET_BCD (desc[10]));
++ else
++ track->start = BRASERO_MSF_TO_LBA (desc[8],
++ desc[9],
++ desc[10]);
++
++ track->start -= 150;
++
++ /* if there are tracks and the last previously added track is in
++ * the same session then set the size */
++ if (priv->tracks) {
++ BraseroMediumTrack *last_track;
++
++ last_track = priv->tracks->data;
++ if (last_track->session == track->session)
++ last_track->blocks_num = track->start - last_track->start;
++ }
++
++ priv->tracks = g_slist_prepend (priv->tracks, track);
++ }
++ else if (desc[3] == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
++ /* NOTE: the leadout session is first in the list. So if
++ * we have tracks in the list set the last session track
++ * size when we reach a new leadout (and therefore a new
++ * session). */
++
++ if (priv->tracks) {
++ BraseroMediumTrack *last_track;
++
++ last_track = priv->tracks->data;
++ last_track->blocks_num = leadout_start - last_track->start;
++ }
++
++ if (use_bcd)
++ leadout_start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc[8]),
++ BRASERO_GET_BCD (desc[9]),
++ BRASERO_GET_BCD (desc[10]));
++ else
++ leadout_start = BRASERO_MSF_TO_LBA (desc[8],
++ desc[9],
++ desc[10]);
++ leadout_start -= 150;
++ }
++ }
++
++ if (priv->tracks) {
++ BraseroMediumTrack *last_track;
++
++ /* set the last found track size */
++ last_track = priv->tracks->data;
++ last_track->blocks_num = leadout_start - last_track->start;
++ }
++
++ /* Add a leadout */
++ if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
++ BraseroMediumTrack *track;
++
++ /* we shouldn't request info on leadout if the disc is closed */
++ track = g_new0 (BraseroMediumTrack, 1);
++ priv->tracks = g_slist_prepend (priv->tracks, track);
++ track->start = leadout_start;
++ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
++
++ brasero_medium_track_get_info (self, track, g_slist_length (priv->tracks), cdrom);
++ }
++
++ priv->tracks = g_slist_reverse (priv->tracks);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *track;
++
++ track = iter->data;
++
++ /* check for tracks less that 300 sectors */
++ if (track->blocks_num <= 300 && track->type != BRASERO_MEDIUM_TRACK_LEADOUT) {
++ BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
++ brasero_medium_track_volume_size (self, track, cdrom);
++ }
++
++ BRASERO_BURN_LOG ("Track %i: type = %i start = %llu size = %llu",
++ g_slist_index (priv->tracks, track),
++ track->type,
++ track->start,
++ track->blocks_num);
++ }
++
++ g_free (toc);
++ 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,
++ BRASEROCDROM *cdrom)
++{
++ int num, i, size, res;
++ gint32 tstart;
++ unsigned char *toc = NULL;
++ unsigned char *desc;
++ BraseroMediumPrivate *priv;
++
++ BRASERO_BURN_LOG ("Reading Toc");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ res = brasero_cdrom_read_toc_formatted (cdrom, 0, &toc);
++ if (res != 0) {
++ g_free (toc);
++
++ BRASERO_BURN_LOG ("READ TOC failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ size = (toc[0] << 8 | toc[1]) - 2;
++
++ num = size / 8; /* Each track description is 8 bytes. */
++
++ BRASERO_BURN_LOG ("%i track(s) found", num);
++
++ for (desc = toc + 4, i = 0; i < num; i ++, desc += 8) {
++ BraseroMediumTrack *track;
++
++ if (desc[2] == BRASERO_SCSI_TRACK_LEADOUT_START)
++ break;
++
++ tstart = (desc[4] << 24 | desc[5] << 16 | desc[6] << 8 | desc[7]);
++
++ track = g_new0 (BraseroMediumTrack, 1);
++ priv->tracks = g_slist_prepend (priv->tracks, track);
++ track->start = tstart;
++
++ /* we shouldn't request info on a track if the disc is closed */
++ brasero_medium_track_get_info (self,
++ track,
++ g_slist_length (priv->tracks),
++ cdrom);
++
++ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_COPY)
++ track->type |= BRASERO_MEDIUM_TRACK_COPY;
++
++ if (!((desc[1] & 15) & BRASERO_SCSI_TRACK_DATA)) {
++ track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
++ priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
++
++ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_PREEMP)
++ track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
++
++ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_4_CHANNELS)
++ track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS;
++ }
++ else 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,
++ cdrom);
++ if (result == BRASERO_BURN_OK) {
++ track->type |= BRASERO_MEDIUM_TRACK_DATA;
++ priv->info |= BRASERO_MEDIUM_HAS_DATA;
++
++ priv->next_wr_add = 0;
++
++ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
++ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
++ }
++ else {
++ priv->tracks = g_slist_remove (priv->tracks, track);
++ g_free (track);
++
++ priv->info |= BRASERO_MEDIUM_BLANK;
++ priv->info &= ~BRASERO_MEDIUM_CLOSED;
++ }
++ }
++ else {
++ track->type |= BRASERO_MEDIUM_TRACK_DATA;
++ priv->info |= BRASERO_MEDIUM_HAS_DATA;
++
++ if ((desc[1] & 15) & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
++ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
++ }
++ }
++
++ /* put the tracks in the right order */
++ priv->tracks = g_slist_reverse (priv->tracks);
++ tstart = (desc[4] << 24 | desc[5] << 16 | desc[6] << 8 | desc[7]);
++
++ 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, tstart);
++ 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 = tstart;
++ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
++
++ brasero_medium_track_get_info (self,
++ track,
++ g_slist_length (priv->tracks),
++ cdrom);
++ }
++
++ g_free (toc);
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_contents (BraseroMedium *self,
++ BRASEROCDROM *cdrom)
++{
++ BraseroBurnResult result;
++ int res;
++ BraseroMediumPrivate *priv;
++ unsigned char buf[32];
++
++ BRASERO_BURN_LOG ("Retrieving media status");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ res = brasero_cdrom_read_disc_information_std (cdrom, buf);
++ if (res != 0) {
++ BRASERO_BURN_LOG ("READ DISC INFORMATION failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ if (buf[2] & 16) /* Erasable */
++ priv->info |= BRASERO_MEDIUM_REWRITABLE;
++
++ if ((buf[2] & 3) == 0) { /* Empty disc */
++ 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,
++ track,
++ 1,
++ cdrom);
++ }
++ goto end;
++ }
++
++ if (buf[2] & 1) { /* Appendable */
++ priv->info |= BRASERO_MEDIUM_APPENDABLE;
++ BRASERO_BURN_LOG ("Appendable media");
++ }
++ else if (buf[2] & 2) { /* Complete */
++ priv->info |= BRASERO_MEDIUM_CLOSED;
++ BRASERO_BURN_LOG ("Closed media");
++ }
++
++ if (priv->info & BRASERO_MEDIUM_CD) {
++ result = brasero_medium_get_CD_sessions_info (self, cdrom);
++ if (result != BRASERO_BURN_OK)
++ result = brasero_medium_get_sessions_info (self, cdrom);
++ }
++ else
++ result = brasero_medium_get_sessions_info (self, cdrom);
++
++ if (result != BRASERO_BURN_OK)
++ goto end;
++
++end:
++
++ return BRASERO_BURN_OK;
++}
++
++static void
++brasero_medium_init_real (BraseroMedium *object, BRASEROCDROM *cdrom)
++{
++ gchar *name;
++ BraseroBurnResult result;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ name = nautilus_burn_drive_get_name_for_display (priv->drive);
++ BRASERO_BURN_LOG ("Initializing information for medium in %s", name);
++ g_free (name);
++
++ result = brasero_medium_get_medium_type (object, cdrom);
++ if (result != BRASERO_BURN_OK)
++ return;
++
++ brasero_medium_get_capacity_by_type (object, cdrom);
++
++ result = brasero_medium_get_contents (object, cdrom);
++ if (result != BRASERO_BURN_OK)
++ return;
++
++ /* assume that css feature is only for DVD-ROM which might be wrong but
++ * some drives wrongly reports that css is enabled for blank DVD+R/W */
++ if (BRASERO_MEDIUM_IS (priv->info, (BRASERO_MEDIUM_DVD|BRASERO_MEDIUM_ROM)))
++ brasero_medium_get_css_feature (object, cdrom);
++
++ BRASERO_BURN_LOG_DISC_TYPE (priv->info, "media is ");
++}
++
++static void
++brasero_medium_try_open (BraseroMedium *self)
++{
++ const gchar *path;
++ BRASEROCDROM *cdrom;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ path = nautilus_burn_drive_get_device (priv->drive);
++
++ BRASERO_BURN_LOG ("Trying to create BRASERCDROM for device %s", path);
++ cdrom = brasero_cdrom_new (path);
++ if (cdrom == NULL) {
++ BRASERO_BURN_LOG ("Creation failed");
++ return;
++ }
++
++ BRASERO_BURN_LOG ("Creation succeeded");
++ brasero_medium_init_real (self, cdrom);
++ brasero_cdrom_free (cdrom);
++}
++
++static void
++brasero_medium_init (BraseroMedium *object)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++ priv->next_wr_add = -1;
++
++ /* we can't do anything here since properties haven't been set yet */
++}
++
++static void
++brasero_medium_finalize (GObject *object)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ if (priv->retry_id) {
++ g_source_remove (priv->retry_id);
++ priv->retry_id = 0;
++ }
++
++ g_free (priv->rd_speeds);
++ priv->rd_speeds = NULL;
++
++ g_free (priv->wr_speeds);
++ priv->wr_speeds = NULL;
++
++ g_slist_foreach (priv->tracks, (GFunc) g_free, NULL);
++ g_slist_free (priv->tracks);
++ priv->tracks = NULL;
++
++ nautilus_burn_drive_unref (priv->drive);
++ priv->drive = NULL;
++
++ G_OBJECT_CLASS (parent_class)->finalize (object);
++}
++
++static void
++brasero_medium_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
++{
++ BraseroMediumPrivate *priv;
++
++ g_return_if_fail (BRASERO_IS_MEDIUM (object));
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ switch (prop_id)
++ {
++ case PROP_DRIVE:
++ priv->drive = g_value_get_object (value);
++ nautilus_burn_drive_ref (priv->drive);
++ brasero_medium_try_open (BRASERO_MEDIUM (object));
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++static void
++brasero_medium_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
++{
++ BraseroMediumPrivate *priv;
++
++ g_return_if_fail (BRASERO_IS_MEDIUM (object));
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ switch (prop_id)
++ {
++ case PROP_DRIVE:
++ nautilus_burn_drive_ref (priv->drive);
++ g_value_set_object (value, priv->drive);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++static void
++brasero_medium_class_init (BraseroMediumClass *klass)
++{
++ GObjectClass* object_class = G_OBJECT_CLASS (klass);
++ parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
++
++ g_type_class_add_private (klass, sizeof (BraseroMediumPrivate));
++
++ object_class->finalize = brasero_medium_finalize;
++ object_class->set_property = brasero_medium_set_property;
++ object_class->get_property = brasero_medium_get_property;
++
++ g_object_class_install_property (object_class,
++ PROP_DRIVE,
++ g_param_spec_object ("drive",
++ "drive",
++ "drive in which medium is inserted",
++ NAUTILUS_BURN_TYPE_DRIVE,
++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
++}
++
++GType
++brasero_medium_get_type (void)
++{
++ static GType our_type = 0;
++
++ if (our_type == 0)
++ {
++ static const GTypeInfo our_info =
++ {
++ sizeof (BraseroMediumClass), /* class_size */
++ (GBaseInitFunc) NULL, /* base_init */
++ (GBaseFinalizeFunc) NULL, /* base_finalize */
++ (GClassInitFunc) brasero_medium_class_init, /* class_init */
++ (GClassFinalizeFunc) NULL, /* class_finalize */
++ NULL /* class_data */,
++ sizeof (BraseroMedium), /* instance_size */
++ 0, /* n_preallocs */
++ (GInstanceInitFunc) brasero_medium_init, /* instance_init */
++ NULL /* value_table */
++ };
++
++ our_type = g_type_register_static (G_TYPE_OBJECT, "BraseroMedium",
++ &our_info, 0);
++ }
++
++ return our_type;
++}
++
++BraseroMedium *
++brasero_medium_new (NautilusBurnDrive *drive)
++{
++ g_return_val_if_fail (drive != NULL, NULL);
++ return BRASERO_MEDIUM (g_object_new (BRASERO_TYPE_MEDIUM,
++ "drive", drive,
++ NULL));
++}
diff --git a/sysutils/brasero/files/patch-src_burn-medium-scsi.c b/sysutils/brasero/files/patch-src_burn-medium-scsi.c
new file mode 100644
index 000000000..974754cde
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_burn-medium-scsi.c
@@ -0,0 +1,2073 @@
+--- src/burn-medium-scsi.c.orig 2008-02-06 01:53:39.000000000 -0500
++++ src/burn-medium-scsi.c 2008-02-06 01:54:19.000000000 -0500
+@@ -0,0 +1,2070 @@
++/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
++/*
++ * brasero
++ * Copyright (C) Philippe Rouquier 2007 <bonfire-app@wanadoo.fr>
++ *
++ * 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.
++ *
++ * 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 brasero. If not, write to:
++ * The Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor
++ * Boston, MA 02110-1301, USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++
++#include <glib.h>
++#include <glib/gi18n-lib.h>
++
++#include <nautilus-burn-drive.h>
++
++#include "burn-basics.h"
++#include "burn-debug.h"
++#include "burn-medium.h"
++#include "scsi-mmc1.h"
++#include "scsi-mmc2.h"
++#include "scsi-mmc3.h"
++#include "scsi-spc1.h"
++#include "scsi-utils.h"
++#include "scsi-mode-pages.h"
++#include "scsi-status-page.h"
++#include "scsi-q-subchannel.h"
++#include "scsi-dvd-structures.h"
++#include "burn-volume.h"
++#include "brasero-ncb.h"
++
++const gchar *icons [] = { "gnome-dev-removable",
++ "gnome-dev-cdrom",
++ "gnome-dev-disc-cdr",
++ "gnome-dev-disc-cdrw",
++ "gnome-dev-disc-dvdrom",
++ "gnome-dev-disc-dvdr",
++ "gnome-dev-disc-dvdrw",
++ "gnome-dev-disc-dvdr-plus",
++ "gnome-dev-disc-dvdram",
++ NULL };
++const gchar *types [] = { N_("file"),
++ N_("CDROM"),
++ N_("CD-R"),
++ N_("CD-RW"),
++ N_("DVDROM"),
++ N_("DVD-R"),
++ N_("DVD-RW"),
++ N_("DVD+R"),
++ N_("DVD+RW"),
++ N_("DVD+R dual layer"),
++ N_("DVD+RW dual layer"),
++ N_("DVD-R dual layer"),
++ N_("DVD-RAM"),
++ N_("Blu-ray disc"),
++ N_("Writable Blu-ray disc"),
++ N_("Rewritable Blu-ray disc"),
++ NULL };
++
++
++typedef struct _BraseroMediumPrivate BraseroMediumPrivate;
++struct _BraseroMediumPrivate
++{
++ gint retry_id;
++
++ GSList * tracks;
++
++ const gchar *type;
++ const gchar *icon;
++
++ gint max_rd;
++ gint max_wrt;
++
++ gint *rd_speeds;
++ gint *wr_speeds;
++
++ gint64 block_num;
++ gint64 block_size;
++
++ guint64 next_wr_add;
++ BraseroMedia info;
++ NautilusBurnDrive * drive;
++};
++
++#define BRASERO_MEDIUM_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_MEDIUM, BraseroMediumPrivate))
++
++/**
++ * Try to open the drive exclusively but don't block; if drive can't be opened
++ * exclusively then retry every second until we're shut or the drive state
++ * changes to not busy.
++ * No exclusive at the moment since when the medium is mounted we can't use excl
++ */
++
++#define OPEN_FLAGS O_RDONLY /*|O_EXCL */|O_NONBLOCK
++#define BUSY_RETRY_TIME 1000
++
++enum
++{
++ PROP_0,
++ PROP_DRIVE
++};
++
++static GObjectClass* parent_class = NULL;
++
++const gchar *
++brasero_medium_get_type_string (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->type;
++}
++
++const gchar *
++brasero_medium_get_icon (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->icon;
++}
++
++BraseroMedia
++brasero_medium_get_status (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->info;
++}
++
++GSList *
++brasero_medium_get_tracks (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return g_slist_copy (priv->tracks);
++}
++
++gboolean
++brasero_medium_get_last_data_track_address (BraseroMedium *medium,
++ gint64 *byte,
++ gint64 *sector)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type & BRASERO_MEDIUM_TRACK_DATA)
++ track = current;
++ }
++
++ if (!track) {
++ if (byte)
++ *byte = -1;
++ if (sector)
++ *sector = -1;
++ return FALSE;
++ }
++
++ if (byte)
++ *byte = track->start * priv->block_size;
++
++ if (sector)
++ *sector = track->start;
++
++ return TRUE;
++}
++
++gboolean
++brasero_medium_get_last_data_track_space (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type & BRASERO_MEDIUM_TRACK_DATA)
++ track = current;
++ }
++
++ if (!track) {
++ if (size)
++ *size = -1;
++ if (blocks)
++ *blocks = -1;
++ return FALSE;
++ }
++
++ if (size)
++ *size = track->blocks_num * priv->block_size;
++ if (blocks)
++ *blocks = track->blocks_num;
++
++ return TRUE;
++}
++
++guint
++brasero_medium_get_track_num (BraseroMedium *medium)
++{
++ guint retval = 0;
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type & BRASERO_MEDIUM_TRACK_LEADOUT)
++ break;
++
++ retval ++;
++ }
++
++ return retval;
++}
++
++static BraseroMediumTrack *
++brasero_medium_get_track (BraseroMedium *medium,
++ guint num)
++{
++ guint i = 1;
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *current;
++
++ current = iter->data;
++ if (current->type == BRASERO_MEDIUM_TRACK_LEADOUT)
++ break;
++
++ if (i == num)
++ return current;
++
++ i++;
++ }
++
++ return NULL;
++}
++
++gboolean
++brasero_medium_get_track_space (BraseroMedium *medium,
++ guint num,
++ gint64 *size,
++ gint64 *blocks)
++{
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ track = brasero_medium_get_track (medium, num);
++ if (!track) {
++ if (size)
++ *size = -1;
++ if (blocks)
++ *blocks = -1;
++ return FALSE;
++ }
++
++ if (size)
++ *size = track->blocks_num * priv->block_size;
++ if (blocks)
++ *blocks = track->blocks_num;
++
++ return TRUE;
++}
++
++gboolean
++brasero_medium_get_track_address (BraseroMedium *medium,
++ guint num,
++ gint64 *byte,
++ gint64 *sector)
++{
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ track = brasero_medium_get_track (medium, num);
++ if (!track) {
++ if (byte)
++ *byte = -1;
++ if (sector)
++ *sector = -1;
++ return FALSE;
++ }
++
++ if (byte)
++ *byte = track->start * priv->block_size;
++ if (sector)
++ *sector = track->start;
++
++ return TRUE;
++}
++
++gint64
++brasero_medium_get_next_writable_address (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->next_wr_add;
++}
++
++gint64
++brasero_medium_get_max_write_speed (BraseroMedium *medium)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++ return priv->max_wrt * 1024;
++}
++
++/**
++ * NOTEs about the following functions:
++ * for all closed media (including ROM types) capacity == size of data and
++ * should be the size of all data on the disc, free space is 0
++ * for all blank -R types capacity == free space and size of data == 0
++ * for all multisession -R types capacity == free space since having the real
++ * capacity of the media would be useless as we can only use this type of media
++ * to append more data
++ * for all -RW types capacity = free space + size of data. Here they can be
++ * appended (use free space) or rewritten (whole capacity).
++ *
++ * Usually:
++ * the free space is the size of the leadout track
++ * the size of data is the sum of track sizes (excluding leadout)
++ * the capacity depends on the media:
++ * for closed discs == sum of track sizes
++ * for multisession discs == free space (leadout size)
++ * for blank discs == (free space) leadout size
++ * for rewritable/blank == use SCSI functions to get capacity (see below)
++ *
++ * In fact we should really need the size of data in DVD+/-RW cases since the
++ * session is always equal to the size of the disc.
++ */
++
++void
++brasero_medium_get_data_size (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ if (!priv->tracks) {
++ /* that's probably because it wasn't possible to retrieve info */
++ if (size)
++ *size = 0;
++
++ if (blocks)
++ *blocks = 0;
++
++ return;
++ }
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *tmp;
++
++ tmp = iter->data;
++ if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT)
++ break;
++
++ track = iter->data;
++ }
++
++ if (size)
++ *size = track ? (track->start + track->blocks_num) * priv->block_size: 0;
++
++ if (blocks)
++ *blocks = track ? track->start + track->blocks_num: 0;
++}
++
++void
++brasero_medium_get_free_space (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ GSList *iter;
++ BraseroMediumPrivate *priv;
++ BraseroMediumTrack *track = NULL;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ if (!priv->tracks) {
++ /* that's probably because it wasn't possible to retrieve info.
++ * maybe it also happens with unformatted DVD+RW */
++
++ if (priv->info & BRASERO_MEDIUM_CLOSED) {
++ if (size)
++ *size = 0;
++
++ if (blocks)
++ *blocks = 0;
++ }
++ else {
++ if (size)
++ *size = priv->block_num * priv->block_size;
++
++ if (blocks)
++ *blocks = priv->block_num;
++ }
++
++ return;
++ }
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *tmp;
++
++ tmp = iter->data;
++ if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT) {
++ track = iter->data;
++ break;
++ }
++ }
++
++ if (size) {
++ if (!track) {
++ /* No leadout was found so the disc is probably closed:
++ * no free space left. */
++ *size = 0;
++ }
++ else if (track->blocks_num <= 0)
++ *size = (priv->block_num - track->start) * priv->block_size;
++ else
++ *size = track->blocks_num * priv->block_size;
++ }
++
++ if (blocks) {
++ if (!track) {
++ /* No leadout was found so the disc is probably closed:
++ * no free space left. */
++ *blocks = 0;
++ }
++ else if (track->blocks_num <= 0)
++ *blocks = priv->block_num - track->blocks_num;
++ else
++ *blocks = track->blocks_num;
++ }
++}
++
++void
++brasero_medium_get_capacity (BraseroMedium *medium,
++ gint64 *size,
++ gint64 *blocks)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (medium);
++
++ if (priv->info & BRASERO_MEDIUM_REWRITABLE) {
++ if (size)
++ *size = priv->block_num * priv->block_size;
++
++ if (blocks)
++ *blocks = priv->block_num;
++ }
++ else if (priv->info & BRASERO_MEDIUM_CLOSED)
++ brasero_medium_get_data_size (medium, size, blocks);
++ else
++ brasero_medium_get_free_space (medium, size, blocks);
++}
++
++/**
++ * Function to retrieve the capacity of a media
++ */
++
++static BraseroBurnResult
++brasero_medium_get_capacity_CD_RW (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ BraseroScsiAtipData *atip_data = NULL;
++ BraseroMediumPrivate *priv;
++ BraseroScsiResult result;
++ int size = 0;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ BRASERO_BURN_LOG ("Retrieving capacity from atip");
++
++ result = brasero_mmc1_read_atip (fd,
++ &atip_data,
++ &size,
++ NULL);
++
++ if (result != BRASERO_SCSI_OK) {
++ BRASERO_BURN_LOG ("READ ATIP failed (scsi error)");
++ return BRASERO_BURN_ERR;
++ }
++
++ /* check the size of the structure: it must be at least 16 bytes long */
++ if (size < 16) {
++ if (size)
++ g_free (atip_data);
++
++ BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
++ return BRASERO_BURN_ERR;
++ }
++
++ priv->block_num = BRASERO_MSF_TO_LBA (atip_data->desc->leadout_mn,
++ atip_data->desc->leadout_sec,
++ atip_data->desc->leadout_frame);
++ g_free (atip_data);
++
++ BRASERO_BURN_LOG ("Format capacity %lli %lli",
++ priv->block_num,
++ priv->block_size);
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_capacity_DVD_RW (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ BraseroScsiFormatCapacitiesHdr *hdr = NULL;
++ BraseroScsiMaxCapacityDesc *current;
++ BraseroMediumPrivate *priv;
++ BraseroScsiResult result;
++ gint size;
++
++ BRASERO_BURN_LOG ("Retrieving format capacity");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_mmc2_read_format_capacities (fd,
++ &hdr,
++ &size,
++ code);
++ if (result != BRASERO_SCSI_OK) {
++ g_free (hdr);
++
++ BRASERO_BURN_LOG ("READ FORMAT CAPACITIES failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ current = hdr->max_caps;
++
++ /* see if the media is already formatted */
++ if (current->type != BRASERO_SCSI_DESC_FORMATTED) {
++ int i, max;
++ BraseroScsiFormattableCapacityDesc *desc;
++
++ max = (hdr->len -
++ sizeof (BraseroScsiMaxCapacityDesc)) /
++ sizeof (BraseroScsiFormattableCapacityDesc);
++
++ desc = hdr->desc;
++ for (i = 0; i < max; i ++, desc ++) {
++ /* search for the correct descriptor */
++ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)) {
++ if (desc->format_type == BRASERO_SCSI_DVDRW_PLUS) {
++ priv->block_num = BRASERO_GET_32 (desc->blocks_num);
++ priv->block_size = BRASERO_GET_24 (desc->type_param);
++
++ /* that can happen */
++ if (!priv->block_size)
++ priv->block_size = 2048;
++ break;
++ }
++ }
++ else if (desc->format_type == BRASERO_SCSI_BLOCK_SIZE_DEFAULT_AND_DB) {
++ priv->block_num = BRASERO_GET_32 (desc->blocks_num);
++ priv->block_size = BRASERO_GET_24 (desc->type_param);
++ break;
++ }
++ }
++ }
++ else {
++ priv->block_num = BRASERO_GET_32 (current->blocks_num);
++ priv->block_size = BRASERO_GET_24 (current->block_size);
++ }
++
++ BRASERO_BURN_LOG ("Format capacity %lli %lli",
++ priv->block_num,
++ priv->block_size);
++
++ g_free (hdr);
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_capacity_by_type (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ priv->block_size = 2048;
++
++ if (!(priv->info & BRASERO_MEDIUM_REWRITABLE))
++ return BRASERO_BURN_OK;
++
++ if (priv->info & BRASERO_MEDIUM_CD)
++ brasero_medium_get_capacity_CD_RW (self, fd, code);
++ else
++ brasero_medium_get_capacity_DVD_RW (self, fd, code);
++
++ return BRASERO_BURN_OK;
++}
++
++/**
++ * Functions to retrieve the speed
++ */
++
++static BraseroBurnResult
++brasero_medium_get_speed_mmc3 (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ int size;
++ int num_desc, i;
++ gint max_rd, max_wrt;
++ BraseroScsiResult result;
++ BraseroMediumPrivate *priv;
++ BraseroScsiWrtSpdDesc *desc;
++ BraseroScsiGetPerfData *wrt_perf = NULL;
++
++ BRASERO_BURN_LOG ("Retrieving speed (Get Performance)");
++
++ /* NOTE: this only work if there is RT streaming feature with
++ * wspd bit set to 1. At least an MMC3 drive. */
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_mmc3_get_performance_wrt_spd_desc (fd,
++ &wrt_perf,
++ &size,
++ code);
++
++ if (result != BRASERO_SCSI_OK) {
++ g_free (wrt_perf);
++
++ BRASERO_BURN_LOG ("GET PERFORMANCE failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ num_desc = (size - sizeof (BraseroScsiGetPerfHdr)) /
++ sizeof (BraseroScsiWrtSpdDesc);
++
++ if (num_desc <= 0)
++ goto end;
++
++ priv->rd_speeds = g_new0 (gint, num_desc + 1);
++ priv->wr_speeds = g_new0 (gint, num_desc + 1);
++
++ max_rd = 0;
++ max_wrt = 0;
++
++ desc = (BraseroScsiWrtSpdDesc*) &wrt_perf->data;
++ for (i = 0; i < num_desc; i ++, desc ++) {
++ priv->rd_speeds [i] = BRASERO_GET_32 (desc->rd_speed);
++ priv->wr_speeds [i] = BRASERO_GET_32 (desc->wr_speed);
++
++ max_rd = MAX (max_rd, priv->rd_speeds [i]);
++ max_wrt = MAX (max_wrt, priv->wr_speeds [i]);
++ }
++
++ priv->max_rd = max_rd;
++ priv->max_wrt = max_wrt;
++
++end:
++
++ g_free (wrt_perf);
++
++ /* strangely there are so drives (I know one case) which support this
++ * function but don't report any speed. So if our top speed is 0 then
++ * use the other way to get the speed. It was a Teac */
++ if (!priv->max_wrt)
++ return BRASERO_BURN_ERR;
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_page_2A_write_speed_desc (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ BraseroScsiStatusPage *page_2A = NULL;
++ BraseroScsiStatusWrSpdDesc *desc;
++ BraseroScsiModeData *data = NULL;
++ BraseroMediumPrivate *priv;
++ BraseroScsiResult result;
++ gint desc_num, i;
++ gint max_wrt = 0;
++ gint max_num;
++ int size = 0;
++
++ BRASERO_BURN_LOG ("Retrieving speed (2A speeds)");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_spc1_mode_sense_get_page (fd,
++ BRASERO_SPC_PAGE_STATUS,
++ &data,
++ &size,
++ code);
++ if (result != BRASERO_SCSI_OK) {
++ g_free (data);
++
++ BRASERO_BURN_LOG ("MODE SENSE failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ page_2A = (BraseroScsiStatusPage *) &data->page;
++
++ /* FIXME: the following is not necessarily true */
++ if (size < sizeof (BraseroScsiStatusPage)) {
++ g_free (data);
++
++ BRASERO_BURN_LOG ("wrong size in page");
++ return BRASERO_BURN_ERR;
++ }
++
++ desc_num = BRASERO_GET_16 (page_2A->wr_speed_desc_num);
++ max_num = size -
++ sizeof (BraseroScsiStatusPage) -
++ sizeof (BraseroScsiModeHdr);
++ max_num /= sizeof (BraseroScsiWrtSpdDesc);
++
++ if (max_num < 0)
++ max_num = 0;
++
++ if (desc_num > max_num)
++ desc_num = max_num;
++
++ priv->wr_speeds = g_new0 (gint, desc_num + 1);
++ desc = page_2A->wr_spd_desc;
++ for (i = 0; i < desc_num; i ++, desc ++) {
++ priv->wr_speeds [i] = BRASERO_GET_16 (desc->speed);
++ max_wrt = MAX (max_wrt, priv->wr_speeds [i]);
++ }
++
++ if (!max_wrt)
++ priv->max_wrt = BRASERO_GET_16 (page_2A->wr_max_speed);
++ else
++ priv->max_wrt = max_wrt;
++
++ priv->max_rd = BRASERO_GET_16 (page_2A->rd_max_speed);
++ g_free (data);
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_page_2A_max_speed (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ BraseroScsiStatusPage *page_2A = NULL;
++ BraseroScsiModeData *data = NULL;
++ BraseroMediumPrivate *priv;
++ BraseroScsiResult result;
++ int size = 0;
++
++ BRASERO_BURN_LOG ("Retrieving speed (2A max)");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ result = brasero_spc1_mode_sense_get_page (fd,
++ BRASERO_SPC_PAGE_STATUS,
++ &data,
++ &size,
++ code);
++ if (result != BRASERO_SCSI_OK) {
++ g_free (data);
++
++ BRASERO_BURN_LOG ("MODE SENSE failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ page_2A = (BraseroScsiStatusPage *) &data->page;
++
++ if (size < 0x14) {
++ g_free (data);
++
++ BRASERO_BURN_LOG ("wrong page size");
++ return BRASERO_BURN_ERR;
++ }
++
++ priv->max_rd = BRASERO_GET_16 (page_2A->rd_max_speed);
++ priv->max_wrt = BRASERO_GET_16 (page_2A->wr_max_speed);
++
++ g_free (data);
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_medium_type (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ BraseroScsiGetConfigHdr *hdr = NULL;
++ BraseroMediumPrivate *priv;
++ BraseroScsiResult result;
++ int size;
++
++ BRASERO_BURN_LOG ("Retrieving media profile");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ result = brasero_mmc2_get_configuration_feature (fd,
++ 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 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. */
++
++ /* 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 (fd,
++ &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);
++ }
++
++ /* retrieve the speed */
++ result = brasero_medium_get_page_2A_max_speed (self,
++ fd,
++ code);
++ return result;
++ }
++
++ 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;
++
++ case BRASERO_SCSI_PROF_CDR:
++ priv->info = BRASERO_MEDIUM_CDR;
++ priv->type = types [2];
++ priv->icon = icons [2];
++ break;
++
++ case BRASERO_SCSI_PROF_CDRW:
++ priv->info = BRASERO_MEDIUM_CDRW;
++ priv->type = types [3];
++ priv->icon = icons [3];
++ break;
++
++ 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;
++
++ case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
++ priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
++ priv->type = types [6];
++ priv->icon = icons [6];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
++ priv->info = BRASERO_MEDIUM_DVDRW;
++ priv->type = types [6];
++ priv->icon = icons [6];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_R_PLUS:
++ priv->info = BRASERO_MEDIUM_DVDR_PLUS;
++ priv->type = types [7];
++ priv->icon = icons [7];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_RW_PLUS:
++ priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
++ priv->type = types [8];
++ priv->icon = icons [7];
++ break;
++
++ /* WARNING: these types are recognized, no more */
++ case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
++ priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
++ priv->type = types [9];
++ priv->icon = icons [7];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
++ priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
++ priv->type = types [10];
++ priv->icon = icons [7];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
++ priv->info = BRASERO_MEDIUM_DVDR_DL;
++ priv->type = types [11];
++ priv->icon = icons [5];
++ break;
++
++ case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
++ priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
++ priv->type = types [11];
++ priv->icon = icons [5];
++ 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_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;
++ 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_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, fd, code);
++ if (result == BRASERO_BURN_OK)
++ goto end;
++ }
++
++ if (stream->mp2a) {
++ result = brasero_medium_get_page_2A_write_speed_desc (self, fd, code);
++ if (result == BRASERO_BURN_OK)
++ goto end;
++ }
++ }
++
++ /* fallback for speeds */
++ result = brasero_medium_get_page_2A_max_speed (self, fd, 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,
++ int fd,
++ 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 (fd,
++ 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 void
++brasero_medium_set_track_type (BraseroMedium *self,
++ BraseroMediumTrack *track,
++ guchar control)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ if (control & BRASERO_SCSI_TRACK_COPY)
++ track->type |= BRASERO_MEDIUM_TRACK_COPY;
++
++ if (!(control & BRASERO_SCSI_TRACK_DATA)) {
++ track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
++ priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
++
++ if (control & BRASERO_SCSI_TRACK_PREEMP)
++ track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
++
++ if (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 (control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
++ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
++ }
++}
++
++static BraseroBurnResult
++brasero_medium_track_volume_size (BraseroMedium *self,
++ BraseroMediumTrack *track,
++ int fd)
++{
++ BraseroMediumPrivate *priv;
++ BraseroBurnResult res;
++ GError *error = NULL;
++ 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 */
++ res = brasero_volume_get_size_fd (fd,
++ track->start,
++ &nb_blocks,
++ NULL);
++ 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 BraseroBurnResult
++brasero_medium_track_get_info (BraseroMedium *self,
++ BraseroMediumTrack *track,
++ int track_num,
++ int fd,
++ 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_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 (fd,
++ 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);
++
++ /* Now here is a potential bug: we can write tracks (data or not)
++ * shorter than 300 Kio /2 sec but they will be padded to reach this
++ * floor value. That means that is blocks_num is 300 blocks that may
++ * mean that the data length on the track is actually shorter.
++ * So we read the volume descriptor. If it works, good otherwise
++ * use the old value.
++ * That's important for checksuming to have a perfect account of the
++ * data size. */
++ if (track->blocks_num <= 300) {
++ BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
++ brasero_medium_track_volume_size (self, track, fd);
++ }
++
++ 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;
++}
++
++/**
++ * return :
++ * 0 when it's not possible to determine (fallback to formatted toc)
++ * -1 for BCD
++ * 1 for HEX */
++static guint
++brasero_medium_check_BCD_use (BraseroMedium *self,
++ int fd,
++ BraseroScsiRawTocDesc *desc,
++ guint num,
++ BraseroScsiErrCode *code)
++{
++ guint i;
++ int size;
++ guint leadout = 0;
++ guint track_num = 0;
++ gboolean use_BCD = TRUE;
++ gboolean use_HEX = TRUE;
++ BraseroScsiResult result;
++ BraseroScsiTrackInfo track_info;
++ guint start_BCD, start_LBA, track_start;
++
++ /* first check if all values are valid BCD numbers in the descriptors */
++ for (i = 0; i < num; i++) {
++ if (desc [i].adr == 1 && desc [i].point <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
++ if (!BRASERO_IS_BCD_VALID (desc [i].p_min)
++ || !BRASERO_IS_BCD_VALID (desc [i].p_sec)
++ || !BRASERO_IS_BCD_VALID (desc [i].p_frame)) {
++ use_BCD = FALSE;
++ break;
++ }
++ }
++ else if (desc [i].point == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
++ if (!BRASERO_IS_BCD_VALID (desc [i].p_min)
++ || !BRASERO_IS_BCD_VALID (desc [i].p_sec)
++ || !BRASERO_IS_BCD_VALID (desc [i].p_frame)) {
++ use_BCD = FALSE;
++ break;
++ }
++ }
++ }
++
++ /* then check if there are valid Hex values */
++ for (i = 0; i < num; i++) {
++ if (desc [i].adr != 1 || desc [i].point > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
++ continue;
++
++ if (desc [i].p_min > 99
++ || desc [i].p_sec > 59
++ || desc [i].p_frame > 74) {
++ use_HEX = FALSE;
++ break;
++ }
++ }
++
++ if (use_BCD != use_HEX) {
++ if (use_BCD)
++ return -1;
++
++ return 1;
++ }
++
++ /* To check if the drive uses BCD values or HEX values we ask for the
++ * track information that contains also the start for the track but in
++ * HEX values. If values are the same then it works. */
++
++ /* NOTE: there could be another way to do it: get first track, in LBA
++ * and BCD it must be 150. */
++
++ /* First find the first track and get track start address in BCD */
++ BRASERO_BURN_LOG ("Retrieving track information to determine number format");
++
++ for (i = 0; i < num; i++) {
++ if (desc [i].adr == BRASERO_SCSI_Q_SUB_CHANNEL_LEADIN_MODE5
++ && desc [i].point == BRASERO_SCSI_Q_SUB_CHANNEL_MULTI_NEXT_SESSION) {
++ /* store the leadout number just in case */
++ leadout = i;
++ continue;
++ }
++
++ if (desc [i].adr != 1 || desc [i].point > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
++ continue;
++
++ track_num ++;
++
++ start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc [i].p_min),
++ BRASERO_GET_BCD (desc [i].p_sec),
++ BRASERO_GET_BCD (desc [i].p_frame));
++
++ start_LBA = BRASERO_MSF_TO_LBA (desc [i].p_min,
++ desc [i].p_sec,
++ desc [i].p_frame);
++
++ BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for track %i", track_num);
++
++ size = 36;
++ start_LBA -= 150;
++ start_BCD -= 150;
++
++ result = brasero_mmc1_read_track_info (fd,
++ track_num,
++ &track_info,
++ &size,
++ code);
++
++ if (result != BRASERO_SCSI_OK) {
++ BRASERO_BURN_LOG ("READ TRACK INFO failed");
++ /* 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);
++
++ /* try to find a conclusive match */
++ if (track_start == start_BCD && track_start != start_LBA)
++ return -1;
++
++ if (track_start == start_LBA && track_start != start_BCD)
++ return 1;
++ }
++
++ /* Our last chance, the leadout.
++ * NOTE: no need to remove 150 sectors here. */
++ start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc [leadout].min),
++ BRASERO_GET_BCD (desc [leadout].sec),
++ BRASERO_GET_BCD (desc [leadout].frame));
++
++ start_LBA = BRASERO_MSF_TO_LBA (desc [leadout].min,
++ desc [leadout].sec,
++ desc [leadout].frame);
++
++ BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for leadout");
++
++ size = 36;
++
++ /* leadout number is number of tracks + 1 */
++ result = brasero_mmc1_read_track_info (fd,
++ track_num + 1,
++ &track_info,
++ &size,
++ code);
++
++ if (result != BRASERO_SCSI_OK) {
++ BRASERO_BURN_LOG ("READ TRACK INFO failed for leadout");
++ /* 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);
++
++ /* try to find a conclusive match */
++ if (track_start == start_BCD && track_start != start_LBA)
++ return -1;
++
++ if (track_start == start_LBA && track_start != start_BCD)
++ return 1;
++
++ /* fallback to formatted toc */
++ return 0;
++}
++
++/**
++ * The reason why we use this perhaps more lengthy method is that with
++ * multisession discs, the first track is reported to be two sectors shorter
++ * than it should. As I don't know why and since the following works we use
++ * this one. */
++static BraseroBurnResult
++brasero_medium_get_CD_sessions_info (BraseroMedium *self,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ gint use_bcd;
++ GSList *iter;
++ int num, i, size;
++ gint leadout_start = 0;
++ BraseroScsiResult result;
++ BraseroMediumPrivate *priv;
++ BraseroScsiRawTocDesc *desc;
++ BraseroScsiRawTocData *toc = NULL;
++
++ BRASERO_BURN_LOG ("Reading Raw Toc");
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++
++ size = 0;
++ result = brasero_mmc1_read_toc_raw (fd,
++ 0,
++ &toc,
++ &size,
++ code);
++ if (result != BRASERO_SCSI_OK) {
++ BRASERO_BURN_LOG ("READ TOC failed");
++ return BRASERO_BURN_ERR;
++ }
++
++ num = (size - sizeof (BraseroScsiRawTocData)) /
++ sizeof (BraseroScsiRawTocDesc);
++
++ BRASERO_BURN_LOG ("%i track(s) found", num);
++
++ desc = toc->desc;
++ use_bcd = brasero_medium_check_BCD_use (self, fd, desc, num, code);
++ if (!use_bcd) {
++ g_free (toc);
++
++ BRASERO_BURN_LOG ("Fallback to formatted toc");
++ return BRASERO_BURN_ERR;
++ }
++
++ if (use_bcd > 0)
++ use_bcd = 0;
++
++ if (use_bcd) {
++ BRASERO_BURN_LOG ("Using BCD format");
++ }
++ else {
++ BRASERO_BURN_LOG ("Using HEX format");
++ }
++
++ for (i = 0; i < num; i++, desc ++) {
++ BraseroMediumTrack *track;
++
++ track = NULL;
++ if (desc->adr == 1 && desc->point <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
++ track = g_new0 (BraseroMediumTrack, 1);
++ track->session = desc->session_num;
++
++ brasero_medium_set_track_type (self, track, desc->control);
++ if (use_bcd)
++ track->start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc->p_min),
++ BRASERO_GET_BCD (desc->p_sec),
++ BRASERO_GET_BCD (desc->p_frame));
++ else
++ track->start = BRASERO_MSF_TO_LBA (desc->p_min,
++ desc->p_sec,
++ desc->p_frame);
++
++ track->start -= 150;
++
++ /* if there are tracks and the last previously added track is in
++ * the same session then set the size */
++ if (priv->tracks) {
++ BraseroMediumTrack *last_track;
++
++ last_track = priv->tracks->data;
++ if (last_track->session == track->session)
++ last_track->blocks_num = track->start - last_track->start;
++ }
++
++ priv->tracks = g_slist_prepend (priv->tracks, track);
++ }
++ else if (desc->point == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
++ /* NOTE: the leadout session is first in the list. So if
++ * we have tracks in the list set the last session track
++ * size when we reach a new leadout (and therefore a new
++ * session). */
++
++ if (priv->tracks) {
++ BraseroMediumTrack *last_track;
++
++ last_track = priv->tracks->data;
++ last_track->blocks_num = leadout_start - last_track->start;
++ }
++
++ if (use_bcd)
++ leadout_start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc->p_min),
++ BRASERO_GET_BCD (desc->p_sec),
++ BRASERO_GET_BCD (desc->p_frame));
++ else
++ leadout_start = BRASERO_MSF_TO_LBA (desc->p_min,
++ desc->p_sec,
++ desc->p_frame);
++ leadout_start -= 150;
++ }
++ }
++
++ if (priv->tracks) {
++ BraseroMediumTrack *last_track;
++
++ /* set the last found track size */
++ last_track = priv->tracks->data;
++ last_track->blocks_num = leadout_start - last_track->start;
++ }
++
++ /* Add a leadout */
++ if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
++ BraseroMediumTrack *track;
++
++ /* we shouldn't request info on leadout if the disc is closed */
++ track = g_new0 (BraseroMediumTrack, 1);
++ priv->tracks = g_slist_prepend (priv->tracks, track);
++ track->start = leadout_start;
++ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
++
++ brasero_medium_track_get_info (self, track, g_slist_length (priv->tracks), fd, code);
++ }
++
++ priv->tracks = g_slist_reverse (priv->tracks);
++
++ for (iter = priv->tracks; iter; iter = iter->next) {
++ BraseroMediumTrack *track;
++
++ track = iter->data;
++
++ /* check for tracks less that 300 sectors */
++ if (track->blocks_num <= 300 && track->type != BRASERO_MEDIUM_TRACK_LEADOUT) {
++ BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
++ brasero_medium_track_volume_size (self, track, fd);
++ }
++
++ BRASERO_BURN_LOG ("Track %i: type = %i start = %llu size = %llu",
++ g_slist_index (priv->tracks, track),
++ track->type,
++ track->start,
++ track->blocks_num);
++ }
++
++ g_free (toc);
++ 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,
++ int fd,
++ BraseroScsiErrCode *code)
++{
++ int num, i, size;
++ 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 (fd,
++ 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);
++
++ 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 */
++ brasero_medium_track_get_info (self,
++ track,
++ g_slist_length (priv->tracks),
++ fd,
++ code);
++
++ 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 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,
++ fd);
++ if (result == BRASERO_BURN_OK) {
++ track->type |= BRASERO_MEDIUM_TRACK_DATA;
++ priv->info |= BRASERO_MEDIUM_HAS_DATA;
++
++ priv->next_wr_add = 0;
++
++ if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
++ track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
++ }
++ else {
++ priv->tracks = g_slist_remove (priv->tracks, track);
++ g_free (track);
++
++ priv->info |= BRASERO_MEDIUM_BLANK;
++ priv->info &= ~BRASERO_MEDIUM_CLOSED;
++ }
++ }
++ 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;
++ }
++ }
++
++ /* 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))
++ brasero_medium_add_DVD_plus_RW_leadout (self, BRASERO_GET_32 (desc->track_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,
++ track,
++ g_slist_length (priv->tracks),
++ fd,
++ code);
++ }
++
++ g_free (toc);
++
++ return BRASERO_BURN_OK;
++}
++
++static BraseroBurnResult
++brasero_medium_get_contents (BraseroMedium *self,
++ int fd,
++ 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 (fd,
++ &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,
++ track,
++ 1,
++ fd,
++ code);
++ }
++ 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 (priv->info & BRASERO_MEDIUM_CD) {
++ result = brasero_medium_get_CD_sessions_info (self, fd, code);
++ if (result != BRASERO_BURN_OK)
++ result = brasero_medium_get_sessions_info (self, fd, code);
++ }
++ else
++ result = brasero_medium_get_sessions_info (self, fd, code);
++
++ if (result != BRASERO_BURN_OK)
++ goto end;
++
++end:
++
++ g_free (info);
++ return BRASERO_BURN_OK;
++}
++
++static void
++brasero_medium_init_real (BraseroMedium *object, int fd)
++{
++ gchar *name;
++ BraseroBurnResult result;
++ BraseroMediumPrivate *priv;
++ BraseroScsiErrCode code = 0;
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ name = nautilus_burn_drive_get_name_for_display (priv->drive);
++ BRASERO_BURN_LOG ("Initializing information for medium in %s", name);
++ g_free (name);
++
++ result = brasero_medium_get_medium_type (object, fd, &code);
++ if (result != BRASERO_BURN_OK)
++ return;
++
++ brasero_medium_get_capacity_by_type (object, fd, &code);
++
++ result = brasero_medium_get_contents (object, fd, &code);
++ if (result != BRASERO_BURN_OK)
++ return;
++
++ /* assume that css feature is only for DVD-ROM which might be wrong but
++ * some drives wrongly reports that css is enabled for blank DVD+R/W */
++ if (BRASERO_MEDIUM_IS (priv->info, (BRASERO_MEDIUM_DVD|BRASERO_MEDIUM_ROM)))
++ brasero_medium_get_css_feature (object, fd, &code);
++
++ BRASERO_BURN_LOG_DISC_TYPE (priv->info, "media is ");
++}
++
++static gboolean
++brasero_medium_retry_open (gpointer object)
++{
++ int fd;
++ const gchar *path;
++ BraseroMedium *self;
++ BraseroMediumPrivate *priv;
++
++ self = BRASERO_MEDIUM (object);
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++ path = nautilus_burn_drive_get_device (priv->drive);
++
++ BRASERO_BURN_LOG ("Retrying to open device %s", path);
++ fd = open (path, OPEN_FLAGS);
++ if (fd < 0) {
++ if (errno == EBUSY
++ || errno == EAGAIN
++ || errno == EWOULDBLOCK) {
++ BRASERO_BURN_LOG ("Device busy");
++ /* we'll retry in a second */
++ return TRUE;
++ }
++
++ BRASERO_BURN_LOG ("Open () failed");
++ priv->info = BRASERO_MEDIUM_UNSUPPORTED;
++ priv->retry_id = 0;
++ return FALSE;
++ }
++
++ BRASERO_BURN_LOG ("Open () succeeded\n");
++ priv->info = BRASERO_MEDIUM_NONE;
++ priv->icon = icons [0];
++
++ priv->retry_id = 0;
++
++ brasero_medium_init_real (self, fd);
++ close (fd);
++
++ return FALSE;
++}
++
++static void
++brasero_medium_try_open (BraseroMedium *self)
++{
++ int fd;
++ const gchar *path;
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (self);
++ path = nautilus_burn_drive_get_device (priv->drive);
++
++ /* the drive might be busy (a burning is going on) so we don't block
++ * but we re-try to open it every second */
++ BRASERO_BURN_LOG ("Trying to open device %s", path);
++ fd = open (path, OPEN_FLAGS);
++ if (fd < 0) {
++ if (errno == EAGAIN
++ || errno == EWOULDBLOCK
++ || errno == EBUSY) {
++ BRASERO_BURN_LOG ("Device busy");
++ priv->info = BRASERO_MEDIUM_BUSY;
++ priv->icon = icons [0];
++
++ priv->retry_id = g_timeout_add (BUSY_RETRY_TIME,
++ brasero_medium_retry_open,
++ self);
++ }
++
++ BRASERO_BURN_LOG ("Open () failed");
++ return;
++ }
++
++ BRASERO_BURN_LOG ("Open () succeeded");
++ brasero_medium_init_real (self, fd);
++ close (fd);
++}
++
++static void
++brasero_medium_init (BraseroMedium *object)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++ priv->next_wr_add = -1;
++
++ /* we can't do anything here since properties haven't been set yet */
++}
++
++static void
++brasero_medium_finalize (GObject *object)
++{
++ BraseroMediumPrivate *priv;
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ if (priv->retry_id) {
++ g_source_remove (priv->retry_id);
++ priv->retry_id = 0;
++ }
++
++ g_free (priv->rd_speeds);
++ priv->rd_speeds = NULL;
++
++ g_free (priv->wr_speeds);
++ priv->wr_speeds = NULL;
++
++ g_slist_foreach (priv->tracks, (GFunc) g_free, NULL);
++ g_slist_free (priv->tracks);
++ priv->tracks = NULL;
++
++ nautilus_burn_drive_unref (priv->drive);
++ priv->drive = NULL;
++
++ G_OBJECT_CLASS (parent_class)->finalize (object);
++}
++
++static void
++brasero_medium_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
++{
++ BraseroMediumPrivate *priv;
++
++ g_return_if_fail (BRASERO_IS_MEDIUM (object));
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ switch (prop_id)
++ {
++ case PROP_DRIVE:
++ priv->drive = g_value_get_object (value);
++ nautilus_burn_drive_ref (priv->drive);
++ brasero_medium_try_open (BRASERO_MEDIUM (object));
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++static void
++brasero_medium_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
++{
++ BraseroMediumPrivate *priv;
++
++ g_return_if_fail (BRASERO_IS_MEDIUM (object));
++
++ priv = BRASERO_MEDIUM_PRIVATE (object);
++
++ switch (prop_id)
++ {
++ case PROP_DRIVE:
++ nautilus_burn_drive_ref (priv->drive);
++ g_value_set_object (value, priv->drive);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++static void
++brasero_medium_class_init (BraseroMediumClass *klass)
++{
++ GObjectClass* object_class = G_OBJECT_CLASS (klass);
++ parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
++
++ g_type_class_add_private (klass, sizeof (BraseroMediumPrivate));
++
++ object_class->finalize = brasero_medium_finalize;
++ object_class->set_property = brasero_medium_set_property;
++ object_class->get_property = brasero_medium_get_property;
++
++ g_object_class_install_property (object_class,
++ PROP_DRIVE,
++ g_param_spec_object ("drive",
++ "drive",
++ "drive in which medium is inserted",
++ NAUTILUS_BURN_TYPE_DRIVE,
++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
++}
++
++GType
++brasero_medium_get_type (void)
++{
++ static GType our_type = 0;
++
++ if (our_type == 0)
++ {
++ static const GTypeInfo our_info =
++ {
++ sizeof (BraseroMediumClass), /* class_size */
++ (GBaseInitFunc) NULL, /* base_init */
++ (GBaseFinalizeFunc) NULL, /* base_finalize */
++ (GClassInitFunc) brasero_medium_class_init, /* class_init */
++ (GClassFinalizeFunc) NULL, /* class_finalize */
++ NULL /* class_data */,
++ sizeof (BraseroMedium), /* instance_size */
++ 0, /* n_preallocs */
++ (GInstanceInitFunc) brasero_medium_init, /* instance_init */
++ NULL /* value_table */
++ };
++
++ our_type = g_type_register_static (G_TYPE_OBJECT, "BraseroMedium",
++ &our_info, 0);
++ }
++
++ return our_type;
++}
++
++BraseroMedium *
++brasero_medium_new (NautilusBurnDrive *drive)
++{
++ g_return_val_if_fail (drive != NULL, NULL);
++ return BRASERO_MEDIUM (g_object_new (BRASERO_TYPE_MEDIUM,
++ "drive", drive,
++ NULL));
++}
diff --git a/sysutils/brasero/files/patch-src_burn-medium.c b/sysutils/brasero/files/patch-src_burn-medium.c
new file mode 100644
index 000000000..accb659e2
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_burn-medium.c
@@ -0,0 +1,2073 @@
+--- src/burn-medium.c.orig 2008-01-27 10:25:14.000000000 -0500
++++ src/burn-medium.c 2008-02-06 01:55:21.000000000 -0500
+@@ -1,2070 +0,0 @@
+-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+-/*
+- * brasero
+- * Copyright (C) Philippe Rouquier 2007 <bonfire-app@wanadoo.fr>
+- *
+- * 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.
+- *
+- * 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 brasero. If not, write to:
+- * The Free Software Foundation, Inc.,
+- * 51 Franklin Street, Fifth Floor
+- * Boston, MA 02110-1301, USA.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-# include <config.h>
+-#endif
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#include <errno.h>
+-
+-#include <glib.h>
+-#include <glib/gi18n-lib.h>
+-
+-#include <nautilus-burn-drive.h>
+-
+-#include "burn-basics.h"
+-#include "burn-debug.h"
+-#include "burn-medium.h"
+-#include "scsi-mmc1.h"
+-#include "scsi-mmc2.h"
+-#include "scsi-mmc3.h"
+-#include "scsi-spc1.h"
+-#include "scsi-utils.h"
+-#include "scsi-mode-pages.h"
+-#include "scsi-status-page.h"
+-#include "scsi-q-subchannel.h"
+-#include "scsi-dvd-structures.h"
+-#include "burn-volume.h"
+-#include "brasero-ncb.h"
+-
+-const gchar *icons [] = { "gnome-dev-removable",
+- "gnome-dev-cdrom",
+- "gnome-dev-disc-cdr",
+- "gnome-dev-disc-cdrw",
+- "gnome-dev-disc-dvdrom",
+- "gnome-dev-disc-dvdr",
+- "gnome-dev-disc-dvdrw",
+- "gnome-dev-disc-dvdr-plus",
+- "gnome-dev-disc-dvdram",
+- NULL };
+-const gchar *types [] = { N_("file"),
+- N_("CDROM"),
+- N_("CD-R"),
+- N_("CD-RW"),
+- N_("DVDROM"),
+- N_("DVD-R"),
+- N_("DVD-RW"),
+- N_("DVD+R"),
+- N_("DVD+RW"),
+- N_("DVD+R dual layer"),
+- N_("DVD+RW dual layer"),
+- N_("DVD-R dual layer"),
+- N_("DVD-RAM"),
+- N_("Blu-ray disc"),
+- N_("Writable Blu-ray disc"),
+- N_("Rewritable Blu-ray disc"),
+- NULL };
+-
+-
+-typedef struct _BraseroMediumPrivate BraseroMediumPrivate;
+-struct _BraseroMediumPrivate
+-{
+- gint retry_id;
+-
+- GSList * tracks;
+-
+- const gchar *type;
+- const gchar *icon;
+-
+- gint max_rd;
+- gint max_wrt;
+-
+- gint *rd_speeds;
+- gint *wr_speeds;
+-
+- gint64 block_num;
+- gint64 block_size;
+-
+- guint64 next_wr_add;
+- BraseroMedia info;
+- NautilusBurnDrive * drive;
+-};
+-
+-#define BRASERO_MEDIUM_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_MEDIUM, BraseroMediumPrivate))
+-
+-/**
+- * Try to open the drive exclusively but don't block; if drive can't be opened
+- * exclusively then retry every second until we're shut or the drive state
+- * changes to not busy.
+- * No exclusive at the moment since when the medium is mounted we can't use excl
+- */
+-
+-#define OPEN_FLAGS O_RDONLY /*|O_EXCL */|O_NONBLOCK
+-#define BUSY_RETRY_TIME 1000
+-
+-enum
+-{
+- PROP_0,
+- PROP_DRIVE
+-};
+-
+-static GObjectClass* parent_class = NULL;
+-
+-const gchar *
+-brasero_medium_get_type_string (BraseroMedium *medium)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- return priv->type;
+-}
+-
+-const gchar *
+-brasero_medium_get_icon (BraseroMedium *medium)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- return priv->icon;
+-}
+-
+-BraseroMedia
+-brasero_medium_get_status (BraseroMedium *medium)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- return priv->info;
+-}
+-
+-GSList *
+-brasero_medium_get_tracks (BraseroMedium *medium)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- return g_slist_copy (priv->tracks);
+-}
+-
+-gboolean
+-brasero_medium_get_last_data_track_address (BraseroMedium *medium,
+- gint64 *byte,
+- gint64 *sector)
+-{
+- GSList *iter;
+- BraseroMediumPrivate *priv;
+- BraseroMediumTrack *track = NULL;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *current;
+-
+- current = iter->data;
+- if (current->type & BRASERO_MEDIUM_TRACK_DATA)
+- track = current;
+- }
+-
+- if (!track) {
+- if (byte)
+- *byte = -1;
+- if (sector)
+- *sector = -1;
+- return FALSE;
+- }
+-
+- if (byte)
+- *byte = track->start * priv->block_size;
+-
+- if (sector)
+- *sector = track->start;
+-
+- return TRUE;
+-}
+-
+-gboolean
+-brasero_medium_get_last_data_track_space (BraseroMedium *medium,
+- gint64 *size,
+- gint64 *blocks)
+-{
+- GSList *iter;
+- BraseroMediumPrivate *priv;
+- BraseroMediumTrack *track = NULL;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *current;
+-
+- current = iter->data;
+- if (current->type & BRASERO_MEDIUM_TRACK_DATA)
+- track = current;
+- }
+-
+- if (!track) {
+- if (size)
+- *size = -1;
+- if (blocks)
+- *blocks = -1;
+- return FALSE;
+- }
+-
+- if (size)
+- *size = track->blocks_num * priv->block_size;
+- if (blocks)
+- *blocks = track->blocks_num;
+-
+- return TRUE;
+-}
+-
+-guint
+-brasero_medium_get_track_num (BraseroMedium *medium)
+-{
+- guint retval = 0;
+- GSList *iter;
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *current;
+-
+- current = iter->data;
+- if (current->type & BRASERO_MEDIUM_TRACK_LEADOUT)
+- break;
+-
+- retval ++;
+- }
+-
+- return retval;
+-}
+-
+-static BraseroMediumTrack *
+-brasero_medium_get_track (BraseroMedium *medium,
+- guint num)
+-{
+- guint i = 1;
+- GSList *iter;
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *current;
+-
+- current = iter->data;
+- if (current->type == BRASERO_MEDIUM_TRACK_LEADOUT)
+- break;
+-
+- if (i == num)
+- return current;
+-
+- i++;
+- }
+-
+- return NULL;
+-}
+-
+-gboolean
+-brasero_medium_get_track_space (BraseroMedium *medium,
+- guint num,
+- gint64 *size,
+- gint64 *blocks)
+-{
+- BraseroMediumPrivate *priv;
+- BraseroMediumTrack *track;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- track = brasero_medium_get_track (medium, num);
+- if (!track) {
+- if (size)
+- *size = -1;
+- if (blocks)
+- *blocks = -1;
+- return FALSE;
+- }
+-
+- if (size)
+- *size = track->blocks_num * priv->block_size;
+- if (blocks)
+- *blocks = track->blocks_num;
+-
+- return TRUE;
+-}
+-
+-gboolean
+-brasero_medium_get_track_address (BraseroMedium *medium,
+- guint num,
+- gint64 *byte,
+- gint64 *sector)
+-{
+- BraseroMediumPrivate *priv;
+- BraseroMediumTrack *track;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- track = brasero_medium_get_track (medium, num);
+- if (!track) {
+- if (byte)
+- *byte = -1;
+- if (sector)
+- *sector = -1;
+- return FALSE;
+- }
+-
+- if (byte)
+- *byte = track->start * priv->block_size;
+- if (sector)
+- *sector = track->start;
+-
+- return TRUE;
+-}
+-
+-gint64
+-brasero_medium_get_next_writable_address (BraseroMedium *medium)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- return priv->next_wr_add;
+-}
+-
+-gint64
+-brasero_medium_get_max_write_speed (BraseroMedium *medium)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+- return priv->max_wrt * 1024;
+-}
+-
+-/**
+- * NOTEs about the following functions:
+- * for all closed media (including ROM types) capacity == size of data and
+- * should be the size of all data on the disc, free space is 0
+- * for all blank -R types capacity == free space and size of data == 0
+- * for all multisession -R types capacity == free space since having the real
+- * capacity of the media would be useless as we can only use this type of media
+- * to append more data
+- * for all -RW types capacity = free space + size of data. Here they can be
+- * appended (use free space) or rewritten (whole capacity).
+- *
+- * Usually:
+- * the free space is the size of the leadout track
+- * the size of data is the sum of track sizes (excluding leadout)
+- * the capacity depends on the media:
+- * for closed discs == sum of track sizes
+- * for multisession discs == free space (leadout size)
+- * for blank discs == (free space) leadout size
+- * for rewritable/blank == use SCSI functions to get capacity (see below)
+- *
+- * In fact we should really need the size of data in DVD+/-RW cases since the
+- * session is always equal to the size of the disc.
+- */
+-
+-void
+-brasero_medium_get_data_size (BraseroMedium *medium,
+- gint64 *size,
+- gint64 *blocks)
+-{
+- GSList *iter;
+- BraseroMediumPrivate *priv;
+- BraseroMediumTrack *track = NULL;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- if (!priv->tracks) {
+- /* that's probably because it wasn't possible to retrieve info */
+- if (size)
+- *size = 0;
+-
+- if (blocks)
+- *blocks = 0;
+-
+- return;
+- }
+-
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *tmp;
+-
+- tmp = iter->data;
+- if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT)
+- break;
+-
+- track = iter->data;
+- }
+-
+- if (size)
+- *size = track ? (track->start + track->blocks_num) * priv->block_size: 0;
+-
+- if (blocks)
+- *blocks = track ? track->start + track->blocks_num: 0;
+-}
+-
+-void
+-brasero_medium_get_free_space (BraseroMedium *medium,
+- gint64 *size,
+- gint64 *blocks)
+-{
+- GSList *iter;
+- BraseroMediumPrivate *priv;
+- BraseroMediumTrack *track = NULL;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- if (!priv->tracks) {
+- /* that's probably because it wasn't possible to retrieve info.
+- * maybe it also happens with unformatted DVD+RW */
+-
+- if (priv->info & BRASERO_MEDIUM_CLOSED) {
+- if (size)
+- *size = 0;
+-
+- if (blocks)
+- *blocks = 0;
+- }
+- else {
+- if (size)
+- *size = priv->block_num * priv->block_size;
+-
+- if (blocks)
+- *blocks = priv->block_num;
+- }
+-
+- return;
+- }
+-
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *tmp;
+-
+- tmp = iter->data;
+- if (tmp->type == BRASERO_MEDIUM_TRACK_LEADOUT) {
+- track = iter->data;
+- break;
+- }
+- }
+-
+- if (size) {
+- if (!track) {
+- /* No leadout was found so the disc is probably closed:
+- * no free space left. */
+- *size = 0;
+- }
+- else if (track->blocks_num <= 0)
+- *size = (priv->block_num - track->start) * priv->block_size;
+- else
+- *size = track->blocks_num * priv->block_size;
+- }
+-
+- if (blocks) {
+- if (!track) {
+- /* No leadout was found so the disc is probably closed:
+- * no free space left. */
+- *blocks = 0;
+- }
+- else if (track->blocks_num <= 0)
+- *blocks = priv->block_num - track->blocks_num;
+- else
+- *blocks = track->blocks_num;
+- }
+-}
+-
+-void
+-brasero_medium_get_capacity (BraseroMedium *medium,
+- gint64 *size,
+- gint64 *blocks)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (medium);
+-
+- if (priv->info & BRASERO_MEDIUM_REWRITABLE) {
+- if (size)
+- *size = priv->block_num * priv->block_size;
+-
+- if (blocks)
+- *blocks = priv->block_num;
+- }
+- else if (priv->info & BRASERO_MEDIUM_CLOSED)
+- brasero_medium_get_data_size (medium, size, blocks);
+- else
+- brasero_medium_get_free_space (medium, size, blocks);
+-}
+-
+-/**
+- * Function to retrieve the capacity of a media
+- */
+-
+-static BraseroBurnResult
+-brasero_medium_get_capacity_CD_RW (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- BraseroScsiAtipData *atip_data = NULL;
+- BraseroMediumPrivate *priv;
+- BraseroScsiResult result;
+- int size = 0;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+-
+- BRASERO_BURN_LOG ("Retrieving capacity from atip");
+-
+- result = brasero_mmc1_read_atip (fd,
+- &atip_data,
+- &size,
+- NULL);
+-
+- if (result != BRASERO_SCSI_OK) {
+- BRASERO_BURN_LOG ("READ ATIP failed (scsi error)");
+- return BRASERO_BURN_ERR;
+- }
+-
+- /* check the size of the structure: it must be at least 16 bytes long */
+- if (size < 16) {
+- if (size)
+- g_free (atip_data);
+-
+- BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
+- return BRASERO_BURN_ERR;
+- }
+-
+- priv->block_num = BRASERO_MSF_TO_LBA (atip_data->desc->leadout_mn,
+- atip_data->desc->leadout_sec,
+- atip_data->desc->leadout_frame);
+- g_free (atip_data);
+-
+- BRASERO_BURN_LOG ("Format capacity %lli %lli",
+- priv->block_num,
+- priv->block_size);
+-
+- return BRASERO_BURN_OK;
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_get_capacity_DVD_RW (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- BraseroScsiFormatCapacitiesHdr *hdr = NULL;
+- BraseroScsiMaxCapacityDesc *current;
+- BraseroMediumPrivate *priv;
+- BraseroScsiResult result;
+- gint size;
+-
+- BRASERO_BURN_LOG ("Retrieving format capacity");
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+- result = brasero_mmc2_read_format_capacities (fd,
+- &hdr,
+- &size,
+- code);
+- if (result != BRASERO_SCSI_OK) {
+- g_free (hdr);
+-
+- BRASERO_BURN_LOG ("READ FORMAT CAPACITIES failed");
+- return BRASERO_BURN_ERR;
+- }
+-
+- current = hdr->max_caps;
+-
+- /* see if the media is already formatted */
+- if (current->type != BRASERO_SCSI_DESC_FORMATTED) {
+- int i, max;
+- BraseroScsiFormattableCapacityDesc *desc;
+-
+- max = (hdr->len -
+- sizeof (BraseroScsiMaxCapacityDesc)) /
+- sizeof (BraseroScsiFormattableCapacityDesc);
+-
+- desc = hdr->desc;
+- for (i = 0; i < max; i ++, desc ++) {
+- /* search for the correct descriptor */
+- if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)) {
+- if (desc->format_type == BRASERO_SCSI_DVDRW_PLUS) {
+- priv->block_num = BRASERO_GET_32 (desc->blocks_num);
+- priv->block_size = BRASERO_GET_24 (desc->type_param);
+-
+- /* that can happen */
+- if (!priv->block_size)
+- priv->block_size = 2048;
+- break;
+- }
+- }
+- else if (desc->format_type == BRASERO_SCSI_BLOCK_SIZE_DEFAULT_AND_DB) {
+- priv->block_num = BRASERO_GET_32 (desc->blocks_num);
+- priv->block_size = BRASERO_GET_24 (desc->type_param);
+- break;
+- }
+- }
+- }
+- else {
+- priv->block_num = BRASERO_GET_32 (current->blocks_num);
+- priv->block_size = BRASERO_GET_24 (current->block_size);
+- }
+-
+- BRASERO_BURN_LOG ("Format capacity %lli %lli",
+- priv->block_num,
+- priv->block_size);
+-
+- g_free (hdr);
+- return BRASERO_BURN_OK;
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_get_capacity_by_type (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+-
+- priv->block_size = 2048;
+-
+- if (!(priv->info & BRASERO_MEDIUM_REWRITABLE))
+- return BRASERO_BURN_OK;
+-
+- if (priv->info & BRASERO_MEDIUM_CD)
+- brasero_medium_get_capacity_CD_RW (self, fd, code);
+- else
+- brasero_medium_get_capacity_DVD_RW (self, fd, code);
+-
+- return BRASERO_BURN_OK;
+-}
+-
+-/**
+- * Functions to retrieve the speed
+- */
+-
+-static BraseroBurnResult
+-brasero_medium_get_speed_mmc3 (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- int size;
+- int num_desc, i;
+- gint max_rd, max_wrt;
+- BraseroScsiResult result;
+- BraseroMediumPrivate *priv;
+- BraseroScsiWrtSpdDesc *desc;
+- BraseroScsiGetPerfData *wrt_perf = NULL;
+-
+- BRASERO_BURN_LOG ("Retrieving speed (Get Performance)");
+-
+- /* NOTE: this only work if there is RT streaming feature with
+- * wspd bit set to 1. At least an MMC3 drive. */
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+- result = brasero_mmc3_get_performance_wrt_spd_desc (fd,
+- &wrt_perf,
+- &size,
+- code);
+-
+- if (result != BRASERO_SCSI_OK) {
+- g_free (wrt_perf);
+-
+- BRASERO_BURN_LOG ("GET PERFORMANCE failed");
+- return BRASERO_BURN_ERR;
+- }
+-
+- num_desc = (size - sizeof (BraseroScsiGetPerfHdr)) /
+- sizeof (BraseroScsiWrtSpdDesc);
+-
+- if (num_desc <= 0)
+- goto end;
+-
+- priv->rd_speeds = g_new0 (gint, num_desc + 1);
+- priv->wr_speeds = g_new0 (gint, num_desc + 1);
+-
+- max_rd = 0;
+- max_wrt = 0;
+-
+- desc = (BraseroScsiWrtSpdDesc*) &wrt_perf->data;
+- for (i = 0; i < num_desc; i ++, desc ++) {
+- priv->rd_speeds [i] = BRASERO_GET_32 (desc->rd_speed);
+- priv->wr_speeds [i] = BRASERO_GET_32 (desc->wr_speed);
+-
+- max_rd = MAX (max_rd, priv->rd_speeds [i]);
+- max_wrt = MAX (max_wrt, priv->wr_speeds [i]);
+- }
+-
+- priv->max_rd = max_rd;
+- priv->max_wrt = max_wrt;
+-
+-end:
+-
+- g_free (wrt_perf);
+-
+- /* strangely there are so drives (I know one case) which support this
+- * function but don't report any speed. So if our top speed is 0 then
+- * use the other way to get the speed. It was a Teac */
+- if (!priv->max_wrt)
+- return BRASERO_BURN_ERR;
+-
+- return BRASERO_BURN_OK;
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_get_page_2A_write_speed_desc (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- BraseroScsiStatusPage *page_2A = NULL;
+- BraseroScsiStatusWrSpdDesc *desc;
+- BraseroScsiModeData *data = NULL;
+- BraseroMediumPrivate *priv;
+- BraseroScsiResult result;
+- gint desc_num, i;
+- gint max_wrt = 0;
+- gint max_num;
+- int size = 0;
+-
+- BRASERO_BURN_LOG ("Retrieving speed (2A speeds)");
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+- result = brasero_spc1_mode_sense_get_page (fd,
+- BRASERO_SPC_PAGE_STATUS,
+- &data,
+- &size,
+- code);
+- if (result != BRASERO_SCSI_OK) {
+- g_free (data);
+-
+- BRASERO_BURN_LOG ("MODE SENSE failed");
+- return BRASERO_BURN_ERR;
+- }
+-
+- page_2A = (BraseroScsiStatusPage *) &data->page;
+-
+- /* FIXME: the following is not necessarily true */
+- if (size < sizeof (BraseroScsiStatusPage)) {
+- g_free (data);
+-
+- BRASERO_BURN_LOG ("wrong size in page");
+- return BRASERO_BURN_ERR;
+- }
+-
+- desc_num = BRASERO_GET_16 (page_2A->wr_speed_desc_num);
+- max_num = size -
+- sizeof (BraseroScsiStatusPage) -
+- sizeof (BraseroScsiModeHdr);
+- max_num /= sizeof (BraseroScsiWrtSpdDesc);
+-
+- if (max_num < 0)
+- max_num = 0;
+-
+- if (desc_num > max_num)
+- desc_num = max_num;
+-
+- priv->wr_speeds = g_new0 (gint, desc_num + 1);
+- desc = page_2A->wr_spd_desc;
+- for (i = 0; i < desc_num; i ++, desc ++) {
+- priv->wr_speeds [i] = BRASERO_GET_16 (desc->speed);
+- max_wrt = MAX (max_wrt, priv->wr_speeds [i]);
+- }
+-
+- if (!max_wrt)
+- priv->max_wrt = BRASERO_GET_16 (page_2A->wr_max_speed);
+- else
+- priv->max_wrt = max_wrt;
+-
+- priv->max_rd = BRASERO_GET_16 (page_2A->rd_max_speed);
+- g_free (data);
+-
+- return BRASERO_BURN_OK;
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_get_page_2A_max_speed (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- BraseroScsiStatusPage *page_2A = NULL;
+- BraseroScsiModeData *data = NULL;
+- BraseroMediumPrivate *priv;
+- BraseroScsiResult result;
+- int size = 0;
+-
+- BRASERO_BURN_LOG ("Retrieving speed (2A max)");
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+-
+- result = brasero_spc1_mode_sense_get_page (fd,
+- BRASERO_SPC_PAGE_STATUS,
+- &data,
+- &size,
+- code);
+- if (result != BRASERO_SCSI_OK) {
+- g_free (data);
+-
+- BRASERO_BURN_LOG ("MODE SENSE failed");
+- return BRASERO_BURN_ERR;
+- }
+-
+- page_2A = (BraseroScsiStatusPage *) &data->page;
+-
+- if (size < 0x14) {
+- g_free (data);
+-
+- BRASERO_BURN_LOG ("wrong page size");
+- return BRASERO_BURN_ERR;
+- }
+-
+- priv->max_rd = BRASERO_GET_16 (page_2A->rd_max_speed);
+- priv->max_wrt = BRASERO_GET_16 (page_2A->wr_max_speed);
+-
+- g_free (data);
+- return BRASERO_BURN_OK;
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_get_medium_type (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- BraseroScsiGetConfigHdr *hdr = NULL;
+- BraseroMediumPrivate *priv;
+- BraseroScsiResult result;
+- int size;
+-
+- BRASERO_BURN_LOG ("Retrieving media profile");
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+- result = brasero_mmc2_get_configuration_feature (fd,
+- 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 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. */
+-
+- /* 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 (fd,
+- &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);
+- }
+-
+- /* retrieve the speed */
+- result = brasero_medium_get_page_2A_max_speed (self,
+- fd,
+- code);
+- return result;
+- }
+-
+- 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;
+-
+- case BRASERO_SCSI_PROF_CDR:
+- priv->info = BRASERO_MEDIUM_CDR;
+- priv->type = types [2];
+- priv->icon = icons [2];
+- break;
+-
+- case BRASERO_SCSI_PROF_CDRW:
+- priv->info = BRASERO_MEDIUM_CDRW;
+- priv->type = types [3];
+- priv->icon = icons [3];
+- break;
+-
+- 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;
+-
+- case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
+- priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
+- priv->type = types [6];
+- priv->icon = icons [6];
+- break;
+-
+- case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
+- priv->info = BRASERO_MEDIUM_DVDRW;
+- priv->type = types [6];
+- priv->icon = icons [6];
+- break;
+-
+- case BRASERO_SCSI_PROF_DVD_R_PLUS:
+- priv->info = BRASERO_MEDIUM_DVDR_PLUS;
+- priv->type = types [7];
+- priv->icon = icons [7];
+- break;
+-
+- case BRASERO_SCSI_PROF_DVD_RW_PLUS:
+- priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
+- priv->type = types [8];
+- priv->icon = icons [7];
+- break;
+-
+- /* WARNING: these types are recognized, no more */
+- case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
+- priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
+- priv->type = types [9];
+- priv->icon = icons [7];
+- break;
+-
+- case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
+- priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
+- priv->type = types [10];
+- priv->icon = icons [7];
+- break;
+-
+- case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
+- priv->info = BRASERO_MEDIUM_DVDR_DL;
+- priv->type = types [11];
+- priv->icon = icons [5];
+- break;
+-
+- case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
+- priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
+- priv->type = types [11];
+- priv->icon = icons [5];
+- 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_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;
+- 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_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, fd, code);
+- if (result == BRASERO_BURN_OK)
+- goto end;
+- }
+-
+- if (stream->mp2a) {
+- result = brasero_medium_get_page_2A_write_speed_desc (self, fd, code);
+- if (result == BRASERO_BURN_OK)
+- goto end;
+- }
+- }
+-
+- /* fallback for speeds */
+- result = brasero_medium_get_page_2A_max_speed (self, fd, 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,
+- int fd,
+- 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 (fd,
+- 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 void
+-brasero_medium_set_track_type (BraseroMedium *self,
+- BraseroMediumTrack *track,
+- guchar control)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+-
+- if (control & BRASERO_SCSI_TRACK_COPY)
+- track->type |= BRASERO_MEDIUM_TRACK_COPY;
+-
+- if (!(control & BRASERO_SCSI_TRACK_DATA)) {
+- track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
+- priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
+-
+- if (control & BRASERO_SCSI_TRACK_PREEMP)
+- track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
+-
+- if (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 (control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
+- track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
+- }
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_track_volume_size (BraseroMedium *self,
+- BraseroMediumTrack *track,
+- int fd)
+-{
+- BraseroMediumPrivate *priv;
+- BraseroBurnResult res;
+- GError *error = NULL;
+- 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 */
+- res = brasero_volume_get_size_fd (fd,
+- track->start,
+- &nb_blocks,
+- NULL);
+- 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 BraseroBurnResult
+-brasero_medium_track_get_info (BraseroMedium *self,
+- BraseroMediumTrack *track,
+- int track_num,
+- int fd,
+- 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_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 (fd,
+- 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);
+-
+- /* Now here is a potential bug: we can write tracks (data or not)
+- * shorter than 300 Kio /2 sec but they will be padded to reach this
+- * floor value. That means that is blocks_num is 300 blocks that may
+- * mean that the data length on the track is actually shorter.
+- * So we read the volume descriptor. If it works, good otherwise
+- * use the old value.
+- * That's important for checksuming to have a perfect account of the
+- * data size. */
+- if (track->blocks_num <= 300) {
+- BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
+- brasero_medium_track_volume_size (self, track, fd);
+- }
+-
+- 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;
+-}
+-
+-/**
+- * return :
+- * 0 when it's not possible to determine (fallback to formatted toc)
+- * -1 for BCD
+- * 1 for HEX */
+-static guint
+-brasero_medium_check_BCD_use (BraseroMedium *self,
+- int fd,
+- BraseroScsiRawTocDesc *desc,
+- guint num,
+- BraseroScsiErrCode *code)
+-{
+- guint i;
+- int size;
+- guint leadout = 0;
+- guint track_num = 0;
+- gboolean use_BCD = TRUE;
+- gboolean use_HEX = TRUE;
+- BraseroScsiResult result;
+- BraseroScsiTrackInfo track_info;
+- guint start_BCD, start_LBA, track_start;
+-
+- /* first check if all values are valid BCD numbers in the descriptors */
+- for (i = 0; i < num; i++) {
+- if (desc [i].adr == 1 && desc [i].point <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
+- if (!BRASERO_IS_BCD_VALID (desc [i].p_min)
+- || !BRASERO_IS_BCD_VALID (desc [i].p_sec)
+- || !BRASERO_IS_BCD_VALID (desc [i].p_frame)) {
+- use_BCD = FALSE;
+- break;
+- }
+- }
+- else if (desc [i].point == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
+- if (!BRASERO_IS_BCD_VALID (desc [i].p_min)
+- || !BRASERO_IS_BCD_VALID (desc [i].p_sec)
+- || !BRASERO_IS_BCD_VALID (desc [i].p_frame)) {
+- use_BCD = FALSE;
+- break;
+- }
+- }
+- }
+-
+- /* then check if there are valid Hex values */
+- for (i = 0; i < num; i++) {
+- if (desc [i].adr != 1 || desc [i].point > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
+- continue;
+-
+- if (desc [i].p_min > 99
+- || desc [i].p_sec > 59
+- || desc [i].p_frame > 74) {
+- use_HEX = FALSE;
+- break;
+- }
+- }
+-
+- if (use_BCD != use_HEX) {
+- if (use_BCD)
+- return -1;
+-
+- return 1;
+- }
+-
+- /* To check if the drive uses BCD values or HEX values we ask for the
+- * track information that contains also the start for the track but in
+- * HEX values. If values are the same then it works. */
+-
+- /* NOTE: there could be another way to do it: get first track, in LBA
+- * and BCD it must be 150. */
+-
+- /* First find the first track and get track start address in BCD */
+- BRASERO_BURN_LOG ("Retrieving track information to determine number format");
+-
+- for (i = 0; i < num; i++) {
+- if (desc [i].adr == BRASERO_SCSI_Q_SUB_CHANNEL_LEADIN_MODE5
+- && desc [i].point == BRASERO_SCSI_Q_SUB_CHANNEL_MULTI_NEXT_SESSION) {
+- /* store the leadout number just in case */
+- leadout = i;
+- continue;
+- }
+-
+- if (desc [i].adr != 1 || desc [i].point > BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START)
+- continue;
+-
+- track_num ++;
+-
+- start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc [i].p_min),
+- BRASERO_GET_BCD (desc [i].p_sec),
+- BRASERO_GET_BCD (desc [i].p_frame));
+-
+- start_LBA = BRASERO_MSF_TO_LBA (desc [i].p_min,
+- desc [i].p_sec,
+- desc [i].p_frame);
+-
+- BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for track %i", track_num);
+-
+- size = 36;
+- start_LBA -= 150;
+- start_BCD -= 150;
+-
+- result = brasero_mmc1_read_track_info (fd,
+- track_num,
+- &track_info,
+- &size,
+- code);
+-
+- if (result != BRASERO_SCSI_OK) {
+- BRASERO_BURN_LOG ("READ TRACK INFO failed");
+- /* 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);
+-
+- /* try to find a conclusive match */
+- if (track_start == start_BCD && track_start != start_LBA)
+- return -1;
+-
+- if (track_start == start_LBA && track_start != start_BCD)
+- return 1;
+- }
+-
+- /* Our last chance, the leadout.
+- * NOTE: no need to remove 150 sectors here. */
+- start_BCD = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc [leadout].min),
+- BRASERO_GET_BCD (desc [leadout].sec),
+- BRASERO_GET_BCD (desc [leadout].frame));
+-
+- start_LBA = BRASERO_MSF_TO_LBA (desc [leadout].min,
+- desc [leadout].sec,
+- desc [leadout].frame);
+-
+- BRASERO_BURN_LOG ("Comparing to track information from READ TRACK INFO for leadout");
+-
+- size = 36;
+-
+- /* leadout number is number of tracks + 1 */
+- result = brasero_mmc1_read_track_info (fd,
+- track_num + 1,
+- &track_info,
+- &size,
+- code);
+-
+- if (result != BRASERO_SCSI_OK) {
+- BRASERO_BURN_LOG ("READ TRACK INFO failed for leadout");
+- /* 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);
+-
+- /* try to find a conclusive match */
+- if (track_start == start_BCD && track_start != start_LBA)
+- return -1;
+-
+- if (track_start == start_LBA && track_start != start_BCD)
+- return 1;
+-
+- /* fallback to formatted toc */
+- return 0;
+-}
+-
+-/**
+- * The reason why we use this perhaps more lengthy method is that with
+- * multisession discs, the first track is reported to be two sectors shorter
+- * than it should. As I don't know why and since the following works we use
+- * this one. */
+-static BraseroBurnResult
+-brasero_medium_get_CD_sessions_info (BraseroMedium *self,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- gint use_bcd;
+- GSList *iter;
+- int num, i, size;
+- gint leadout_start = 0;
+- BraseroScsiResult result;
+- BraseroMediumPrivate *priv;
+- BraseroScsiRawTocDesc *desc;
+- BraseroScsiRawTocData *toc = NULL;
+-
+- BRASERO_BURN_LOG ("Reading Raw Toc");
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+-
+- size = 0;
+- result = brasero_mmc1_read_toc_raw (fd,
+- 0,
+- &toc,
+- &size,
+- code);
+- if (result != BRASERO_SCSI_OK) {
+- BRASERO_BURN_LOG ("READ TOC failed");
+- return BRASERO_BURN_ERR;
+- }
+-
+- num = (size - sizeof (BraseroScsiRawTocData)) /
+- sizeof (BraseroScsiRawTocDesc);
+-
+- BRASERO_BURN_LOG ("%i track(s) found", num);
+-
+- desc = toc->desc;
+- use_bcd = brasero_medium_check_BCD_use (self, fd, desc, num, code);
+- if (!use_bcd) {
+- g_free (toc);
+-
+- BRASERO_BURN_LOG ("Fallback to formatted toc");
+- return BRASERO_BURN_ERR;
+- }
+-
+- if (use_bcd > 0)
+- use_bcd = 0;
+-
+- if (use_bcd) {
+- BRASERO_BURN_LOG ("Using BCD format");
+- }
+- else {
+- BRASERO_BURN_LOG ("Using HEX format");
+- }
+-
+- for (i = 0; i < num; i++, desc ++) {
+- BraseroMediumTrack *track;
+-
+- track = NULL;
+- if (desc->adr == 1 && desc->point <= BRASERO_SCSI_Q_SUB_CHANNEL_TRACK_START) {
+- track = g_new0 (BraseroMediumTrack, 1);
+- track->session = desc->session_num;
+-
+- brasero_medium_set_track_type (self, track, desc->control);
+- if (use_bcd)
+- track->start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc->p_min),
+- BRASERO_GET_BCD (desc->p_sec),
+- BRASERO_GET_BCD (desc->p_frame));
+- else
+- track->start = BRASERO_MSF_TO_LBA (desc->p_min,
+- desc->p_sec,
+- desc->p_frame);
+-
+- track->start -= 150;
+-
+- /* if there are tracks and the last previously added track is in
+- * the same session then set the size */
+- if (priv->tracks) {
+- BraseroMediumTrack *last_track;
+-
+- last_track = priv->tracks->data;
+- if (last_track->session == track->session)
+- last_track->blocks_num = track->start - last_track->start;
+- }
+-
+- priv->tracks = g_slist_prepend (priv->tracks, track);
+- }
+- else if (desc->point == BRASERO_SCSI_Q_SUB_CHANNEL_LEADOUT_START) {
+- /* NOTE: the leadout session is first in the list. So if
+- * we have tracks in the list set the last session track
+- * size when we reach a new leadout (and therefore a new
+- * session). */
+-
+- if (priv->tracks) {
+- BraseroMediumTrack *last_track;
+-
+- last_track = priv->tracks->data;
+- last_track->blocks_num = leadout_start - last_track->start;
+- }
+-
+- if (use_bcd)
+- leadout_start = BRASERO_MSF_TO_LBA (BRASERO_GET_BCD (desc->p_min),
+- BRASERO_GET_BCD (desc->p_sec),
+- BRASERO_GET_BCD (desc->p_frame));
+- else
+- leadout_start = BRASERO_MSF_TO_LBA (desc->p_min,
+- desc->p_sec,
+- desc->p_frame);
+- leadout_start -= 150;
+- }
+- }
+-
+- if (priv->tracks) {
+- BraseroMediumTrack *last_track;
+-
+- /* set the last found track size */
+- last_track = priv->tracks->data;
+- last_track->blocks_num = leadout_start - last_track->start;
+- }
+-
+- /* Add a leadout */
+- if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
+- BraseroMediumTrack *track;
+-
+- /* we shouldn't request info on leadout if the disc is closed */
+- track = g_new0 (BraseroMediumTrack, 1);
+- priv->tracks = g_slist_prepend (priv->tracks, track);
+- track->start = leadout_start;
+- track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+-
+- brasero_medium_track_get_info (self, track, g_slist_length (priv->tracks), fd, code);
+- }
+-
+- priv->tracks = g_slist_reverse (priv->tracks);
+-
+- for (iter = priv->tracks; iter; iter = iter->next) {
+- BraseroMediumTrack *track;
+-
+- track = iter->data;
+-
+- /* check for tracks less that 300 sectors */
+- if (track->blocks_num <= 300 && track->type != BRASERO_MEDIUM_TRACK_LEADOUT) {
+- BRASERO_BURN_LOG ("300 sectors size. Checking for real size");
+- brasero_medium_track_volume_size (self, track, fd);
+- }
+-
+- BRASERO_BURN_LOG ("Track %i: type = %i start = %llu size = %llu",
+- g_slist_index (priv->tracks, track),
+- track->type,
+- track->start,
+- track->blocks_num);
+- }
+-
+- g_free (toc);
+- 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,
+- int fd,
+- BraseroScsiErrCode *code)
+-{
+- int num, i, size;
+- 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 (fd,
+- 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);
+-
+- 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 */
+- brasero_medium_track_get_info (self,
+- track,
+- g_slist_length (priv->tracks),
+- fd,
+- code);
+-
+- 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 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,
+- fd);
+- if (result == BRASERO_BURN_OK) {
+- track->type |= BRASERO_MEDIUM_TRACK_DATA;
+- priv->info |= BRASERO_MEDIUM_HAS_DATA;
+-
+- priv->next_wr_add = 0;
+-
+- if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
+- track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
+- }
+- else {
+- priv->tracks = g_slist_remove (priv->tracks, track);
+- g_free (track);
+-
+- priv->info |= BRASERO_MEDIUM_BLANK;
+- priv->info &= ~BRASERO_MEDIUM_CLOSED;
+- }
+- }
+- 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;
+- }
+- }
+-
+- /* 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))
+- brasero_medium_add_DVD_plus_RW_leadout (self, BRASERO_GET_32 (desc->track_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,
+- track,
+- g_slist_length (priv->tracks),
+- fd,
+- code);
+- }
+-
+- g_free (toc);
+-
+- return BRASERO_BURN_OK;
+-}
+-
+-static BraseroBurnResult
+-brasero_medium_get_contents (BraseroMedium *self,
+- int fd,
+- 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 (fd,
+- &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,
+- track,
+- 1,
+- fd,
+- code);
+- }
+- 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 (priv->info & BRASERO_MEDIUM_CD) {
+- result = brasero_medium_get_CD_sessions_info (self, fd, code);
+- if (result != BRASERO_BURN_OK)
+- result = brasero_medium_get_sessions_info (self, fd, code);
+- }
+- else
+- result = brasero_medium_get_sessions_info (self, fd, code);
+-
+- if (result != BRASERO_BURN_OK)
+- goto end;
+-
+-end:
+-
+- g_free (info);
+- return BRASERO_BURN_OK;
+-}
+-
+-static void
+-brasero_medium_init_real (BraseroMedium *object, int fd)
+-{
+- gchar *name;
+- BraseroBurnResult result;
+- BraseroMediumPrivate *priv;
+- BraseroScsiErrCode code = 0;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (object);
+-
+- name = nautilus_burn_drive_get_name_for_display (priv->drive);
+- BRASERO_BURN_LOG ("Initializing information for medium in %s", name);
+- g_free (name);
+-
+- result = brasero_medium_get_medium_type (object, fd, &code);
+- if (result != BRASERO_BURN_OK)
+- return;
+-
+- brasero_medium_get_capacity_by_type (object, fd, &code);
+-
+- result = brasero_medium_get_contents (object, fd, &code);
+- if (result != BRASERO_BURN_OK)
+- return;
+-
+- /* assume that css feature is only for DVD-ROM which might be wrong but
+- * some drives wrongly reports that css is enabled for blank DVD+R/W */
+- if (BRASERO_MEDIUM_IS (priv->info, (BRASERO_MEDIUM_DVD|BRASERO_MEDIUM_ROM)))
+- brasero_medium_get_css_feature (object, fd, &code);
+-
+- BRASERO_BURN_LOG_DISC_TYPE (priv->info, "media is ");
+-}
+-
+-static gboolean
+-brasero_medium_retry_open (gpointer object)
+-{
+- int fd;
+- const gchar *path;
+- BraseroMedium *self;
+- BraseroMediumPrivate *priv;
+-
+- self = BRASERO_MEDIUM (object);
+- priv = BRASERO_MEDIUM_PRIVATE (object);
+- path = nautilus_burn_drive_get_device (priv->drive);
+-
+- BRASERO_BURN_LOG ("Retrying to open device %s", path);
+- fd = open (path, OPEN_FLAGS);
+- if (fd < 0) {
+- if (errno == EBUSY
+- || errno == EAGAIN
+- || errno == EWOULDBLOCK) {
+- BRASERO_BURN_LOG ("Device busy");
+- /* we'll retry in a second */
+- return TRUE;
+- }
+-
+- BRASERO_BURN_LOG ("Open () failed");
+- priv->info = BRASERO_MEDIUM_UNSUPPORTED;
+- priv->retry_id = 0;
+- return FALSE;
+- }
+-
+- BRASERO_BURN_LOG ("Open () succeeded\n");
+- priv->info = BRASERO_MEDIUM_NONE;
+- priv->icon = icons [0];
+-
+- priv->retry_id = 0;
+-
+- brasero_medium_init_real (self, fd);
+- close (fd);
+-
+- return FALSE;
+-}
+-
+-static void
+-brasero_medium_try_open (BraseroMedium *self)
+-{
+- int fd;
+- const gchar *path;
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (self);
+- path = nautilus_burn_drive_get_device (priv->drive);
+-
+- /* the drive might be busy (a burning is going on) so we don't block
+- * but we re-try to open it every second */
+- BRASERO_BURN_LOG ("Trying to open device %s", path);
+- fd = open (path, OPEN_FLAGS);
+- if (fd < 0) {
+- if (errno == EAGAIN
+- || errno == EWOULDBLOCK
+- || errno == EBUSY) {
+- BRASERO_BURN_LOG ("Device busy");
+- priv->info = BRASERO_MEDIUM_BUSY;
+- priv->icon = icons [0];
+-
+- priv->retry_id = g_timeout_add (BUSY_RETRY_TIME,
+- brasero_medium_retry_open,
+- self);
+- }
+-
+- BRASERO_BURN_LOG ("Open () failed");
+- return;
+- }
+-
+- BRASERO_BURN_LOG ("Open () succeeded");
+- brasero_medium_init_real (self, fd);
+- close (fd);
+-}
+-
+-static void
+-brasero_medium_init (BraseroMedium *object)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (object);
+- priv->next_wr_add = -1;
+-
+- /* we can't do anything here since properties haven't been set yet */
+-}
+-
+-static void
+-brasero_medium_finalize (GObject *object)
+-{
+- BraseroMediumPrivate *priv;
+-
+- priv = BRASERO_MEDIUM_PRIVATE (object);
+-
+- if (priv->retry_id) {
+- g_source_remove (priv->retry_id);
+- priv->retry_id = 0;
+- }
+-
+- g_free (priv->rd_speeds);
+- priv->rd_speeds = NULL;
+-
+- g_free (priv->wr_speeds);
+- priv->wr_speeds = NULL;
+-
+- g_slist_foreach (priv->tracks, (GFunc) g_free, NULL);
+- g_slist_free (priv->tracks);
+- priv->tracks = NULL;
+-
+- nautilus_burn_drive_unref (priv->drive);
+- priv->drive = NULL;
+-
+- G_OBJECT_CLASS (parent_class)->finalize (object);
+-}
+-
+-static void
+-brasero_medium_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+-{
+- BraseroMediumPrivate *priv;
+-
+- g_return_if_fail (BRASERO_IS_MEDIUM (object));
+-
+- priv = BRASERO_MEDIUM_PRIVATE (object);
+-
+- switch (prop_id)
+- {
+- case PROP_DRIVE:
+- priv->drive = g_value_get_object (value);
+- nautilus_burn_drive_ref (priv->drive);
+- brasero_medium_try_open (BRASERO_MEDIUM (object));
+- break;
+- default:
+- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+- break;
+- }
+-}
+-
+-static void
+-brasero_medium_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+-{
+- BraseroMediumPrivate *priv;
+-
+- g_return_if_fail (BRASERO_IS_MEDIUM (object));
+-
+- priv = BRASERO_MEDIUM_PRIVATE (object);
+-
+- switch (prop_id)
+- {
+- case PROP_DRIVE:
+- nautilus_burn_drive_ref (priv->drive);
+- g_value_set_object (value, priv->drive);
+- break;
+- default:
+- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+- break;
+- }
+-}
+-
+-static void
+-brasero_medium_class_init (BraseroMediumClass *klass)
+-{
+- GObjectClass* object_class = G_OBJECT_CLASS (klass);
+- parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+-
+- g_type_class_add_private (klass, sizeof (BraseroMediumPrivate));
+-
+- object_class->finalize = brasero_medium_finalize;
+- object_class->set_property = brasero_medium_set_property;
+- object_class->get_property = brasero_medium_get_property;
+-
+- g_object_class_install_property (object_class,
+- PROP_DRIVE,
+- g_param_spec_object ("drive",
+- "drive",
+- "drive in which medium is inserted",
+- NAUTILUS_BURN_TYPE_DRIVE,
+- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+-}
+-
+-GType
+-brasero_medium_get_type (void)
+-{
+- static GType our_type = 0;
+-
+- if (our_type == 0)
+- {
+- static const GTypeInfo our_info =
+- {
+- sizeof (BraseroMediumClass), /* class_size */
+- (GBaseInitFunc) NULL, /* base_init */
+- (GBaseFinalizeFunc) NULL, /* base_finalize */
+- (GClassInitFunc) brasero_medium_class_init, /* class_init */
+- (GClassFinalizeFunc) NULL, /* class_finalize */
+- NULL /* class_data */,
+- sizeof (BraseroMedium), /* instance_size */
+- 0, /* n_preallocs */
+- (GInstanceInitFunc) brasero_medium_init, /* instance_init */
+- NULL /* value_table */
+- };
+-
+- our_type = g_type_register_static (G_TYPE_OBJECT, "BraseroMedium",
+- &our_info, 0);
+- }
+-
+- return our_type;
+-}
+-
+-BraseroMedium *
+-brasero_medium_new (NautilusBurnDrive *drive)
+-{
+- g_return_val_if_fail (drive != NULL, NULL);
+- return BRASERO_MEDIUM (g_object_new (BRASERO_TYPE_MEDIUM,
+- "drive", drive,
+- NULL));
+-}
diff --git a/sysutils/brasero/files/patch-src_cam b/sysutils/brasero/files/patch-src_cam
new file mode 100644
index 000000000..febbbd1c3
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_cam
@@ -0,0 +1,1361 @@
+diff -rupN cam.orig/freebsd_dvd_rw_utils.h cam/freebsd_dvd_rw_utils.h
+--- /dev/null 1969-12-31 19:00:00.000000000 -0500
++++ src/cam/freebsd_dvd_rw_utils.h 2008-01-24 16:52:25.000000000 -0500
+@@ -0,0 +1,49 @@
++//
++// This is part of dvd+rw-tools by Andy Polyakov <appro@fy.chalmers.se>
++//
++// Use-it-on-your-own-risk, GPL bless...
++//
++// For further details see http://fy.chalmers.se/~appro/linux/DVD+RW/
++//
++
++#ifndef FREEBSD_DVD_RW_UTILS_H
++#define FREEBSD_DVD_RW_UTILS_H
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <glib.h>
++
++#include "cam-cdrom.h"
++
++#define DRIVE_CDROM_CAPS_DVDRW 1
++#define DRIVE_CDROM_CAPS_DVDPLUSR 2
++#define DRIVE_CDROM_CAPS_DVDPLUSRW 4
++#define DRIVE_CDROM_CAPS_DVDPLUSRWDL 8
++#define DRIVE_CDROM_CAPS_DVDPLUSRDL 16
++#define DRIVE_CDROM_CAPS_BDROM 32
++#define DRIVE_CDROM_CAPS_BDR 64
++#define DRIVE_CDROM_CAPS_BDRE 128
++#define DRIVE_CDROM_CAPS_HDDVDROM 256
++#define DRIVE_CDROM_CAPS_HDDVDR 512
++#define DRIVE_CDROM_CAPS_HDDVDRW 1024
++
++int brasero_cdrom_get_dvd_r_rw_profile (BRASEROCDROM *cdrom);
++int brasero_cdrom_get_read_write_speed (BRASEROCDROM *cdrom, int *read_speed, int *write_speed, char **write_speeds);
++int brasero_cdrom_get_disc_capacity_for_type (BRASEROCDROM *cdrom, int type, guint64 *capacity);
++int brasero_cdrom_get_disc_type (BRASEROCDROM *cdrom);
++int brasero_cdrom_read_disc_information_std (BRASEROCDROM *cdrom, unsigned char *buf);
++int brasero_cdrom_disc_is_appendable (BRASEROCDROM *cdrom);
++int brasero_cdrom_disc_is_rewritable (BRASEROCDROM *cdrom);
++int brasero_cdrom_read_atip (BRASEROCDROM *cdrom, unsigned char **buf);
++int brasero_cdrom_read_format_capacities (BRASEROCDROM *cdrom, unsigned char **buf);
++int brasero_cdrom_get_performance_wrt_spd_desc (BRASEROCDROM *cdrom, unsigned char **buf);
++int brasero_cdrom_get_configuration_feature (BRASEROCDROM *cdrom, int feature, unsigned char **buf);
++int brasero_cdrom_read_track_info (BRASEROCDROM *cdrom, int track_num, unsigned char *buf, int size);
++int brasero_cdrom_read_toc_raw (BRASEROCDROM *cdrom, int track_num, unsigned char **buf);
++int brasero_cdrom_read_toc_formatted (BRASEROCDROM *cdrom, int track_num, unsigned char **buf);
++int brasero_read_disc_information_std (BRASEROCDROM *cdrom, unsigned char *buf);
++int brasero_cdrom_read_format_capacities (BRASEROCDROM *cdrom, unsigned char **buf);
++
++#endif /* FREEBSD_DVD_RW_UTILS_H */
+--- /dev/null 2008-02-03 02:26:39.000000000 -0500
++++ src/cam/cam-cdrom.h 2008-02-03 11:32:23.000000000 -0500
+@@ -0,0 +1,68 @@
++/***************************************************************************
++ * CVSID: $Id: patch-src_cam,v 1.3 2008-05-14 02:10:40 marcus Exp $
++ *
++ * hfp-cdrom.h : SCSI CD-ROM abstraction layer
++ *
++ * Copyright (C) 2006 Jean-Yves Lefort <jylefort@FreeBSD.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ **************************************************************************/
++
++#ifndef _BRASERO_CDROM_H
++#define _BRASERO_CDROM_H
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <glib.h>
++
++#include <sys/types.h>
++
++typedef struct _BRASEROCDROM BRASEROCDROM;
++
++typedef enum
++{
++ BRASERO_CDROM_DIRECTION_NONE,
++ BRASERO_CDROM_DIRECTION_IN,
++ BRASERO_CDROM_DIRECTION_OUT
++} BRASEROCDROMDirection;
++
++/* ATAPI/SCSI commands */
++enum
++{
++ BRASERO_CDROM_TEST_UNIT_READY = 0x00,
++ BRASERO_CDROM_GET_EVENT_STATUS_NOTIFICATION = 0x4a,
++ BRASERO_CDROM_MODE_SENSE_BIG = 0x5a
++};
++
++BRASEROCDROM *brasero_cdrom_new (const char *path);
++
++gboolean brasero_cdrom_send_ccb (BRASEROCDROM *cdrom,
++ const char *ccb,
++ int ccb_len,
++ BRASEROCDROMDirection direction,
++ void *data,
++ int len,
++ char **err);
++
++gboolean brasero_cdrom_test_unit_ready (BRASEROCDROM *cdrom);
++
++int brasero_cdrom_get_fd (BRASEROCDROM *cdrom);
++
++void brasero_cdrom_free (BRASEROCDROM *cdrom);
++
++#endif /* _BRASERO_CDROM_H */
+--- /dev/null 2008-02-03 13:11:45.000000000 -0500
++++ src/cam/cam-cdrom.c 2008-02-03 13:24:53.000000000 -0500
+@@ -0,0 +1,156 @@
++/***************************************************************************
++ * CVSID: $Id: patch-src_cam,v 1.3 2008-05-14 02:10:40 marcus Exp $
++ *
++ * cam-cdrom.c : SCSI CD-ROM abstraction layer
++ *
++ * Copyright (C) 2006 Jean-Yves Lefort <jylefort@FreeBSD.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ **************************************************************************/
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <string.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <sys/ioctl.h>
++#include <sys/types.h>
++#include <sys/ata.h>
++#include <stdio.h>
++#include <camlib.h>
++#include <cam/scsi/scsi_message.h>
++#include <glib.h>
++
++#include "cam-cdrom.h"
++
++struct _BRASEROCDROM
++{
++ struct cam_device *cam; /* for SCSI drives */
++ int fd;
++};
++
++BRASEROCDROM *
++brasero_cdrom_new (const char *path)
++{
++ BRASEROCDROM *cdrom = NULL;
++ struct cam_device *cam;
++ int fd;
++
++ g_assert(path != NULL);
++
++ /* brasero_open_device() fails unless we use O_RDWR */
++ cam = cam_open_device(path, O_RDWR);
++ fd = open(path, O_RDONLY | O_NONBLOCK);
++ if (cam && fd > -1)
++ {
++ cdrom = g_new0(BRASEROCDROM, 1);
++ cdrom->cam = cam;
++ cdrom->fd = fd;
++ }
++
++ return cdrom;
++}
++
++gboolean
++brasero_cdrom_send_ccb (BRASEROCDROM *cdrom,
++ const char *ccb,
++ int ccb_len,
++ BRASEROCDROMDirection direction,
++ void *data,
++ int len,
++ char **err)
++{
++ int timeout;
++
++ g_assert(cdrom != NULL);
++ g_assert(ccb != NULL);
++ g_assert(direction == BRASERO_CDROM_DIRECTION_NONE
++ || direction == BRASERO_CDROM_DIRECTION_IN
++ || direction == BRASERO_CDROM_DIRECTION_OUT);
++ g_assert(direction == BRASERO_CDROM_DIRECTION_NONE || data != NULL);
++
++ timeout = 10;
++
++ union ccb cam_ccb;
++ static int scsi_direction[] = { CAM_DIR_NONE, CAM_DIR_IN, CAM_DIR_OUT };
++
++ memset(&cam_ccb, 0, sizeof(cam_ccb));
++
++ cam_ccb.ccb_h.path_id = cdrom->cam->path_id;
++ cam_ccb.ccb_h.target_id = cdrom->cam->target_id;
++ cam_ccb.ccb_h.target_lun = cdrom->cam->target_lun;
++
++ cam_fill_csio(&cam_ccb.csio,
++ 1,
++ NULL,
++ scsi_direction[direction],
++ MSG_SIMPLE_Q_TAG,
++ data,
++ len,
++ sizeof(cam_ccb.csio.sense_data),
++ ccb_len,
++ timeout * 1000);
++
++ memcpy(cam_ccb.csio.cdb_io.cdb_bytes, ccb, 16);
++
++ if (cam_send_ccb(cdrom->cam, &cam_ccb) == -1)
++ {
++ if (err)
++ *err = g_strdup_printf("cam_send_ccb() failure: %s", g_strerror(errno));
++ }
++ if ((cam_ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
++ {
++ if (err)
++ *err = g_strdup_printf("CCB request failed with status %i", cam_ccb.ccb_h.status & CAM_STATUS_MASK);
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++gboolean
++brasero_cdrom_test_unit_ready (BRASEROCDROM *cdrom)
++{
++ static char ccb[16] = { BRASERO_CDROM_TEST_UNIT_READY };
++
++ g_assert(cdrom != NULL);
++
++ return brasero_cdrom_send_ccb(cdrom, ccb, 6, BRASERO_CDROM_DIRECTION_NONE, NULL, 0, NULL);
++}
++
++int
++brasero_cdrom_get_fd (BRASEROCDROM *cdrom)
++{
++ g_assert(cdrom != NULL);
++
++ return (cdrom->fd);
++}
++
++void
++brasero_cdrom_free (BRASEROCDROM *cdrom)
++{
++ g_assert(cdrom != NULL);
++
++ if (cdrom->cam)
++ cam_close_device(cdrom->cam);
++
++ close(cdrom->fd);
++
++ g_free(cdrom);
++}
+--- /dev/null 2008-02-03 13:11:45.000000000 -0500
++++ src/cam/freebsd_dvd_rw_utils.c 2008-02-03 13:30:36.000000000 -0500
+@@ -0,0 +1,1075 @@
++/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
++ *
++ * This is part of dvd+rw-tools by Andy Polyakov <appro@fy.chalmers.se>
++ *
++ * Use-it-on-your-own-risk, GPL bless...
++ *
++ * For further details see http://fy.chalmers.se/~appro/linux/DVD+RW/
++*/
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <sys/types.h>
++
++#include <glib.h>
++
++#include "freebsd_dvd_rw_utils.h"
++
++typedef enum {
++ NONE = BRASERO_CDROM_DIRECTION_NONE,
++ READ = BRASERO_CDROM_DIRECTION_IN,
++ WRITE = BRASERO_CDROM_DIRECTION_OUT
++} Direction;
++
++typedef struct ScsiCommand ScsiCommand;
++
++struct ScsiCommand {
++ BRASEROCDROM *cdrom;
++ char ccb[16];
++ int len;
++};
++
++static ScsiCommand *
++scsi_command_new_from_cdrom (BRASEROCDROM *cdrom)
++{
++ ScsiCommand *cmd;
++
++ cmd = g_new0 (ScsiCommand, 1);
++ cmd->cdrom = cdrom;
++
++ return cmd;
++}
++
++static void
++scsi_command_free (ScsiCommand * cmd)
++{
++ free (cmd);
++}
++
++static void
++scsi_command_init (ScsiCommand * cmd, size_t i, int arg)
++{
++ cmd->ccb[i] = arg;
++ if (i == 0 || i >= cmd->len)
++ cmd->len = i + 1;
++}
++
++static int
++scsi_command_transport (ScsiCommand * cmd, Direction dir, void *buf,
++ size_t sz)
++{
++ if (brasero_cdrom_send_ccb(cmd->cdrom, cmd->ccb, cmd->len, dir, buf, sz, NULL))
++ return 0;
++ else
++ return -1;
++}
++
++int
++brasero_cdrom_get_dvd_r_rw_profile (BRASEROCDROM *cdrom)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ unsigned char page[20];
++ unsigned char *list;
++ int i, len;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x46);
++ scsi_command_init (cmd, 1, 2);
++ scsi_command_init (cmd, 8, 8);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, page, 8)) {
++ /* GET CONFIGURATION failed */
++ scsi_command_free (cmd);
++ return -1;
++ }
++
++ /* See if it's 2 gen drive by checking if DVD+R profile is an option */
++ len = 4 + (page[0] << 24 | page[1] << 16 | page[2] << 8 | page[3]);
++ if (len > 264) {
++ scsi_command_free (cmd);
++ /* insane profile list length */
++ return -1;
++ }
++
++ list = g_new (unsigned char, len);
++
++ scsi_command_init (cmd, 0, 0x46);
++ scsi_command_init (cmd, 1, 2);
++ scsi_command_init (cmd, 7, len >> 8);
++ scsi_command_init (cmd, 8, len);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, list, len)) {
++ /* GET CONFIGURATION failed */
++ scsi_command_free (cmd);
++ free (list);
++ return -1;
++ }
++
++ for (i = 12; i < list[11]; i += 4) {
++ int profile = (list[i] << 8 | list[i + 1]);
++ /* 0x13: DVD-RW Restricted Overwrite
++ * 0x14: DVD-RW Sequential
++ * 0x1B: DVD+R
++ * 0x1A: DVD+RW
++ * 0x2A: DVD+RW DL
++ * 0x2B: DVD+R DL
++ * 0x40: BD-ROM
++ * 0x41: BD-R SRM
++ * 0x42: BD-R RRM
++ * 0x43: BD-RE
++ * 0x50: HD DVD-ROM
++ * 0x51: HD DVD-R
++ * 0x52: HD DVD-Rewritable
++ */
++
++ switch (profile) {
++ case 0x13:
++ case 0x14:
++ retval |= DRIVE_CDROM_CAPS_DVDRW;
++ break;
++ case 0x1B:
++ retval |= DRIVE_CDROM_CAPS_DVDPLUSR;
++ break;
++ case 0x1A:
++ retval |= DRIVE_CDROM_CAPS_DVDPLUSRW;
++ break;
++ case 0x2A:
++ retval |= DRIVE_CDROM_CAPS_DVDPLUSRWDL;
++ break;
++ case 0x2B:
++ retval |= DRIVE_CDROM_CAPS_DVDPLUSRDL;
++ break;
++ case 0x40:
++ retval |= DRIVE_CDROM_CAPS_BDROM;
++ break;
++ case 0x41:
++ case 0x42:
++ retval |= DRIVE_CDROM_CAPS_BDR;
++ break;
++ case 0x43:
++ retval |= DRIVE_CDROM_CAPS_BDRE;
++ break;
++ case 0x50:
++ retval |= DRIVE_CDROM_CAPS_HDDVDROM;
++ break;
++ case 0x51:
++ retval |= DRIVE_CDROM_CAPS_HDDVDR;
++ break;
++ case 0x52:
++ retval |= DRIVE_CDROM_CAPS_HDDVDRW;
++ break;
++ default:
++ break;
++ }
++ }
++
++ scsi_command_free (cmd);
++ free (list);
++
++ return retval;
++
++}
++
++static unsigned char *
++pull_page2a_from_cdrom (BRASEROCDROM *cdrom)
++{
++ ScsiCommand *cmd;
++ unsigned char header[12], *page2A;
++ unsigned int len, bdlen;
++
++ g_return_val_if_fail (cdrom != NULL, NULL);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x5A); /* MODE SENSE */
++ scsi_command_init (cmd, 1, 0x08); /* Disable Block Descriptors */
++ scsi_command_init (cmd, 2, 0x2A); /* Capabilities and Mechanical Status */
++ scsi_command_init (cmd, 8, sizeof (header)); /* header only to start with */
++ scsi_command_init (cmd, 9, 0);
++
++ if (scsi_command_transport (cmd, READ, header, sizeof (header))) {
++ /* MODE SENSE failed */
++ scsi_command_free (cmd);
++ return NULL;
++ }
++
++ len = (header[0] << 8 | header[1]) + 2;
++ bdlen = header[6] << 8 | header[7];
++
++ /* should never happen as we set "DBD" above */
++ if (bdlen) {
++ if (len < (8 + bdlen + 30)) {
++ /* LUN impossible to bear with */
++ scsi_command_free (cmd);
++ return NULL;
++ }
++ } else if (len < (8 + 2 + (unsigned int) header[9])) {
++ /* SANYO does this. */
++ len = 8 + 2 + header[9];
++ }
++
++ page2A = g_new (unsigned char, len);
++ if (page2A == NULL) {
++ /* ENOMEM */
++ scsi_command_free (cmd);
++ return NULL;
++ }
++
++ scsi_command_init (cmd, 0, 0x5A); /* MODE SENSE */
++ scsi_command_init (cmd, 1, 0x08); /* Disable Block Descriptors */
++ scsi_command_init (cmd, 2, 0x2A); /* Capabilities and Mechanical Status */
++ scsi_command_init (cmd, 7, len >> 8);
++ scsi_command_init (cmd, 8, len); /* Real length */
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, page2A, len)) {
++ /* MODE SENSE failed */
++ scsi_command_free (cmd);
++ free (page2A);
++ return NULL;
++ }
++
++ scsi_command_free (cmd);
++
++ len -= 2;
++ /* paranoia */
++ if (len < ((unsigned int) page2A[0] << 8 | page2A[1])) {
++ page2A[0] = len >> 8;
++ page2A[1] = len;
++ }
++
++ return page2A;
++}
++
++static int
++int_compare (const void *a, const void *b)
++{
++ /* descending order */
++ return *((int *) b) - *((int *) a);
++}
++
++/* gets the list of supported write speeds. in the event
++ * that anything goes wrong, returns NULL.
++ */
++static char *
++get_write_speeds (const unsigned char *p, int length, int max_speed)
++{
++ char *result, *str;
++ int nr_records;
++ int *tmpspeeds;
++ int i, j;
++
++ result = NULL;
++
++ /* paranoia */
++ if (length < 32)
++ return NULL;
++
++ nr_records = p[30] << 8 | p[31];
++
++ /* paranoia */
++ if (length < 32 + 4 * nr_records)
++ return NULL;
++
++ tmpspeeds = g_new (int, nr_records);
++
++ for (i = 0; i < nr_records; i++)
++ {
++ tmpspeeds[i] = p[4*i + 34] << 8 | p[4*i + 35];
++
++ /* i'm not sure how likely this is to show up, but it's
++ * definitely wrong. if we see it, abort.
++ */
++ if (tmpspeeds[i] == 0)
++ goto free_tmpspeeds;
++ }
++
++ /* sort */
++ qsort (tmpspeeds, nr_records, sizeof (int), int_compare);
++
++ /* uniq */
++ for (i = j = 0; i < nr_records; i++)
++ {
++ tmpspeeds[j] = tmpspeeds[i];
++
++ /* make sure we don't look past the end of the array */
++ if (i >= (nr_records - 1) || tmpspeeds[i+1] != tmpspeeds[i])
++ j++;
++ }
++
++ /* j is now the number of unique entries in the array */
++ if (j == 0)
++ /* no entries? this isn't right. */
++ goto free_tmpspeeds;
++
++ /* sanity check: the first item in the descending order
++ * list ought to be the highest speed as detected through
++ * other means
++ */
++ if (tmpspeeds[0] != max_speed)
++ /* sanity check failed. */
++ goto free_tmpspeeds;
++
++ /* our values are 16-bit. 8 bytes per value
++ * is more than enough including space for
++ * ',' and '\0'. we know j is not zero.
++ */
++ result = str = g_new (char, 8 * j);
++
++ for (i = 0; i < j; i++)
++ {
++ if (i > 0)
++ *(str++) = ',';
++
++ str += sprintf (str, "%d", tmpspeeds[i]);
++ }
++
++free_tmpspeeds:
++ free (tmpspeeds);
++
++ return result;
++}
++
++int
++brasero_cdrom_get_read_write_speed (BRASEROCDROM *cdrom, int *read_speed, int *write_speed, char **write_speeds)
++{
++ unsigned char *page2A;
++ int len, hlen;
++ unsigned char *p;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ *read_speed = 0;
++ *write_speed = 0;
++ *write_speeds = NULL;
++
++ page2A = pull_page2a_from_cdrom (cdrom);
++ if (page2A == NULL) {
++ printf ("Failed to get Page 2A\n");
++ /* Failed to get Page 2A */
++ return -1;
++ }
++
++ len = (page2A[0] << 8 | page2A[1]) + 2;
++ hlen = 8 + (page2A[6] << 8 | page2A[7]);
++ p = page2A + hlen;
++
++ /* Values guessed from the cd_mode_page_2A struct
++ * in cdrecord's libscg/scg/scsireg.h */
++ if (len < (hlen + 30) || p[1] < (30 - 2)) {
++ /* no MMC-3 "Current Write Speed" present,
++ * try to use the MMC-2 one */
++ if (len < (hlen + 20) || p[1] < (20 - 2))
++ *write_speed = 0;
++ else
++ *write_speed = p[18] << 8 | p[19];
++ } else {
++ *write_speed = p[28] << 8 | p[29];
++ }
++
++ if (len >= hlen+9)
++ *read_speed = p[8] << 8 | p[9];
++ else
++ *read_speed = 0;
++
++ *write_speeds = get_write_speeds (p, len, *write_speed);
++
++ free (page2A);
++
++ return 0;
++}
++
++
++static int
++get_disc_capacity_cd (BRASEROCDROM *cdrom, guint64 *size)
++{
++ ScsiCommand *cmd;
++ int retval;
++ guint64 block_size;
++ guint64 num_blocks;
++ unsigned char header [8];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ retval = -1;
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++ scsi_command_init (cmd, 0, 0x25);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 8)) {
++ /* READ CDROM CAPACITY failed */
++ goto done;
++ }
++
++ num_blocks = (header [0] << 24) | (header [1] << 16) | (header [2] << 8) | header [3];
++ num_blocks++;
++ block_size = header [4] << 24 | header [5] << 16 | header [6] << 8 | header [7];
++
++ if (size) {
++ *size = num_blocks * block_size;
++ }
++ retval = 0;
++
++ done:
++ scsi_command_free (cmd);
++
++ return retval;
++}
++
++static int
++get_disc_capacity_cdr (BRASEROCDROM *cdrom, guint64 *size)
++{
++ ScsiCommand *cmd;
++ int retval;
++ guint64 secs;
++ unsigned char toc [8];
++ unsigned char *atip;
++ int len;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ retval = -1;
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++ /* READ_TOC */
++ scsi_command_init (cmd, 0, 0x43);
++ /* FMT_ATIP */
++ scsi_command_init (cmd, 2, 4 & 0x0F);
++ scsi_command_init (cmd, 6, 0);
++ scsi_command_init (cmd, 8, 4);
++ scsi_command_init (cmd, 9, 0);
++
++ if (scsi_command_transport (cmd, READ, toc, 4)) {
++ /* READ TOC failed */
++ goto done;
++ }
++
++ len = 2 + (toc [0] << 8 | toc [1]);
++
++ atip = g_new (unsigned char, len);
++
++ scsi_command_init (cmd, 0, 0x43);
++ scsi_command_init (cmd, 2, 4 & 0x0F);
++ scsi_command_init (cmd, 6, 0);
++ scsi_command_init (cmd, 7, len >> 8);
++ scsi_command_init (cmd, 8, len);
++ scsi_command_init (cmd, 9, 0);
++
++ if (scsi_command_transport (cmd, READ, atip, len)) {
++ /* READ TOC failed */
++ free (atip);
++ goto done;
++ }
++
++ secs = atip [12] * 60 + atip [13] + (atip [14] / 75 + 1);
++
++ if (size) {
++ *size = (1 + secs * 7 / 48) * 1024 * 1024;
++ }
++ retval = 0;
++
++ free (atip);
++ done:
++ scsi_command_free (cmd);
++
++ return retval;
++}
++
++static int
++get_disc_capacity_dvdr_from_type (BRASEROCDROM *cdrom, int type, guint64 *size)
++{
++ ScsiCommand *cmd;
++ unsigned char formats [260];
++ unsigned char buf [32];
++ guint64 blocks;
++ guint64 nwa;
++ int i;
++ int len;
++ int obligatory;
++ int retval;
++ int next_track;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ retval = -1;
++ blocks = 0;
++ next_track = 1;
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ retry:
++ if (type == 0x1A || type == 0x14 || type == 0x13 || type == 0x12) {
++
++ /* READ FORMAT CAPACITIES */
++ scsi_command_init (cmd, 0, 0x23);
++ scsi_command_init (cmd, 8, 12);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, formats, 12)) {
++ /* READ FORMAT CAPACITIES failed */
++ goto done;
++ }
++
++ len = formats [3];
++ if (len & 7 || len < 16) {
++ /* Length isn't sane */
++ goto done;
++ }
++
++ scsi_command_init (cmd, 0, 0x23);
++ scsi_command_init (cmd, 7, (4 + len) >> 8);
++ scsi_command_init (cmd, 8, (4 + len) & 0xFF);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, formats, 4 + len)) {
++ /* READ FORMAT CAPACITIES failed */
++ goto done;
++ }
++
++ if (len != formats [3]) {
++ /* Parameter length inconsistency */
++ goto done;
++ }
++ }
++
++ obligatory = 0x00;
++
++ switch (type) {
++ case 0x1A: /* DVD+RW */
++ obligatory = 0x26;
++ case 0x13: /* DVD-RW Restricted Overwrite */
++ case 0x14: /* DVD-RW Sequential */
++ for (i = 8, len = formats [3]; i < len; i += 8) {
++ if ((formats [4 + i + 4] >> 2) == obligatory) {
++ break;
++ }
++ }
++
++ if (i == len) {
++ /* Can't find obligatory format descriptor */
++ goto done;
++ }
++
++ blocks = formats [4 + i + 0] << 24;
++ blocks |= formats [4 + i + 1] << 16;
++ blocks |= formats [4 + i + 2] << 8;
++ blocks |= formats [4 + i + 3];
++ nwa = formats [4 + 5] << 16 | formats [4 + 6] << 8 | formats [4 + 7];
++ if (nwa > 2048) {
++ blocks *= nwa / 2048;
++ } else if (nwa < 2048) {
++ blocks /= 2048 / nwa;
++ }
++
++ retval = 0;
++ break;
++
++ case 0x12: /* DVD-RAM */
++
++ blocks = formats [4 + 0] << 24;
++ blocks |= formats [4 + 1] << 16;
++ blocks |= formats [4 + 2] << 8;
++ blocks |= formats [4 + 3];
++ nwa = formats [4 + 5] << 16 | formats [4 + 6] << 8 | formats [4 + 7];
++ if (nwa > 2048) {
++ blocks *= nwa / 2048;
++ } else if (nwa < 2048) {
++ blocks /= 2048 / nwa;
++ }
++
++ retval = 0;
++ break;
++
++ case 0x11: /* DVD-R */
++ case 0x1B: /* DVD+R */
++ case 0x2B: /* DVD+R Double Layer */
++ case 0x41: /* BD-R SRM */
++
++ /* READ TRACK INFORMATION */
++ scsi_command_init (cmd, 0, 0x52);
++ scsi_command_init (cmd, 1, 1);
++ scsi_command_init (cmd, 4, next_track >> 8);
++ scsi_command_init (cmd, 5, next_track & 0xFF);
++ scsi_command_init (cmd, 8, sizeof (buf));
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, buf, sizeof (buf))) {
++ /* READ TRACK INFORMATION failed */
++ if (next_track > 0) {
++ goto done;
++ } else {
++ next_track = 1;
++ goto retry;
++ }
++ }
++
++ blocks = buf [24] << 24;
++ blocks |= buf [25] << 16;
++ blocks |= buf [26] << 8;
++ blocks |= buf [27];
++
++ retval = 0;
++ break;
++ case 0x43: /* DB-RE */
++ /* Pull the formatted capacity */
++ blocks = formats [4 + 0] << 24;
++ blocks |= formats [4 + 1] << 16;
++ blocks |= formats [4 + 2] << 8;
++ blocks |= formats [4 + 3];
++ break;
++ default:
++ blocks = 0;
++ break;
++ }
++
++ done:
++ scsi_command_free (cmd);
++
++ if (size) {
++ *size = blocks * 2048;
++ }
++
++ return retval;
++}
++
++int
++brasero_cdrom_get_disc_capacity_for_type (BRASEROCDROM *cdrom, int type, guint64 *size)
++{
++ int retval;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ retval = -1;
++
++ switch (type) {
++ case 0x8:
++ retval = get_disc_capacity_cd (cdrom, size);
++ break;
++ case 0x9:
++ case 0xa:
++ retval = get_disc_capacity_cdr (cdrom, size);
++ break;
++ case 0x10:
++ retval = get_disc_capacity_cd (cdrom, size);
++ break;
++ case 0x11:
++ case 0x13:
++ case 0x14:
++ case 0x1B:
++ case 0x2B:
++ case 0x1A:
++ case 0x12:
++ case 0x41:
++ case 0x43:
++ retval = get_disc_capacity_dvdr_from_type (cdrom, type, size);
++ break;
++ default:
++ retval = -1;
++ }
++
++ return retval;
++}
++
++int
++brasero_cdrom_get_disc_type (BRASEROCDROM *cdrom)
++{
++ ScsiCommand *cmd;
++ int retval = -1;
++ unsigned char header[8];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x46);
++ scsi_command_init (cmd, 1, 1);
++ scsi_command_init (cmd, 8, 8);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 8)) {
++ /* GET CONFIGURATION failed */
++ scsi_command_free (cmd);
++ return -1;
++ }
++
++ retval = (header[6]<<8)|(header[7]);
++
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_get_configuration_feature (BRASEROCDROM *cdrom,
++ int feature,
++ unsigned char **buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ int len;
++ unsigned char header[8];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x46);
++ scsi_command_init (cmd, 1, 2);
++ scsi_command_init (cmd, 2, feature >> 8);
++ scsi_command_init (cmd, 3, feature);
++ scsi_command_init (cmd, 8, 8);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 8)) {
++ scsi_command_free (cmd);
++ return -1;
++ }
++
++ len = 4 + (header[0] << 24 | header[1] << 16 | header[2] << 8 | header[3]);
++ if (len > 264) {
++ scsi_command_free (cmd);
++ return -1;
++ }
++
++ *buf = g_new (unsigned char, len);
++
++ scsi_command_init (cmd, 0, 0x46);
++ scsi_command_init (cmd, 1, 2);
++ scsi_command_init (cmd, 2, feature >> 8);
++ scsi_command_init (cmd, 3, feature);
++ scsi_command_init (cmd, 7, len >> 8);
++ scsi_command_init (cmd, 8, len);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, *buf, len)) {
++ g_free (*buf);
++ *buf = NULL;
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++
++ return retval;
++}
++
++int
++brasero_cdrom_read_disc_information_std (BRASEROCDROM *cdrom,
++ unsigned char *buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ /* see section 5.19 of MMC-3 from http://www.t10.org/drafts.htm#mmc3 */
++ scsi_command_init (cmd, 0, 0x51); /* READ_DISC_INFORMATION */
++ scsi_command_init (cmd, 8, 32);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, buf, 32)) {
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_read_track_info (BRASEROCDROM *cdrom,
++ int track_num,
++ unsigned char *buf,
++ int size)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x52);
++ scsi_command_init (cmd, 1, 1);
++ scsi_command_init (cmd, 4, track_num >> 8);
++ scsi_command_init (cmd, 5, track_num & 0xFF);
++ scsi_command_init (cmd, 8, size);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, buf, size)) {
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_read_toc_formatted (BRASEROCDROM *cdrom,
++ int track_num,
++ unsigned char **buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ int len;
++ unsigned char header[4];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x43);
++ scsi_command_init (cmd, 2, 0);
++ scsi_command_init (cmd, 6, track_num);
++ scsi_command_init (cmd, 8, 4);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 4)) {
++ scsi_command_free (cmd);
++ *buf = NULL;
++ return -1;
++ }
++
++ len = (header[0] << 8 | header[1]) + 2;
++
++ *buf = g_malloc0 (len);
++
++ scsi_command_init (cmd, 8, len);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, *buf, len)) {
++ g_free (*buf);
++ *buf = NULL;
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_read_toc_raw (BRASEROCDROM *cdrom,
++ int track_num,
++ unsigned char **buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ int len;
++ unsigned char header[4];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x43);
++ scsi_command_init (cmd, 2, 2);
++ scsi_command_init (cmd, 6, track_num);
++ scsi_command_init (cmd, 8, 4);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 4)) {
++ scsi_command_free (cmd);
++ *buf = NULL;
++ return -1;
++ }
++
++ len = (header[0] << 8 | header[1]) + 2;
++
++ *buf = g_malloc0 (len);
++
++ scsi_command_init (cmd, 8, len);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, *buf, len)) {
++ g_free (*buf);
++ *buf = NULL;
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_read_atip (BRASEROCDROM *cdrom,
++ unsigned char **buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ int len;
++ unsigned char header[4];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x43);
++ scsi_command_init (cmd, 2, 4);
++ scsi_command_init (cmd, 6, 0);
++ scsi_command_init (cmd, 8, 4);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 4)) {
++ scsi_command_free (cmd);
++ *buf = NULL;
++ return -1;
++ }
++
++ len = (header[0] << 8 | header[1]) + 2;
++
++ *buf = g_malloc0 (len);
++
++ scsi_command_init (cmd, 8, len);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, *buf, len)) {
++ g_free (*buf);
++ *buf = NULL;
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_read_format_capacities (BRASEROCDROM *cdrom,
++ unsigned char **buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ int len;
++ unsigned char header[12];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0x23);
++ scsi_command_init (cmd, 8, 12);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 12)) {
++ /* READ FORMAT CAPACITIES failed */
++ return -1;
++ }
++
++ len = header [3];
++ if (len & 7 || len < 16) {
++ /* Length isn't sane */
++ return -1;
++ }
++
++ *buf = g_new (unsigned char, len + 4);
++
++ scsi_command_init (cmd, 0, 0x23);
++ scsi_command_init (cmd, 7, (4 + len) >> 8);
++ scsi_command_init (cmd, 8, (4 + len) & 0xFF);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, *buf, 4 + len)) {
++ /* READ FORMAT CAPACITIES failed */
++ g_free (*buf);
++ *buf = NULL;
++ retval = -1;
++ }
++
++ return retval;
++}
++
++int
++brasero_cdrom_get_performance_wrt_spd_desc (BRASEROCDROM *cdrom,
++ unsigned char **buf)
++{
++ ScsiCommand *cmd;
++ int retval = 0;
++ int len;
++ int desc_num;
++ unsigned char header[8];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++ g_return_val_if_fail (buf != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ scsi_command_init (cmd, 0, 0xac);
++ scsi_command_init (cmd, 8, 0);
++ scsi_command_init (cmd, 9, 0);
++ scsi_command_init (cmd, 10, 3);
++ scsi_command_init (cmd, 11, 0);
++ if (scsi_command_transport (cmd, READ, header, 8)) {
++ scsi_command_free (cmd);
++ *buf = NULL;
++ return -1;
++ }
++
++ len = (header[0] << 24 | header[1] << 16 | header[2] << 8 | header[3]) + 4;
++ if (len > 2048) {
++ len = 2048;
++ }
++
++ desc_num = (len - 8) / 12;
++
++ *buf = g_malloc0 (len);
++
++ scsi_command_init (cmd, 8, desc_num >> 8);
++ scsi_command_init (cmd, 9, desc_num);
++ scsi_command_init (cmd, 11, 0);
++ if (scsi_command_transport (cmd, READ, *buf, len)) {
++ g_free (*buf);
++ *buf = NULL;
++ retval = -1;
++ }
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_disc_is_appendable (BRASEROCDROM *cdrom)
++{
++ ScsiCommand *cmd;
++ int retval = -1;
++ unsigned char header[32];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ /* see section 5.19 of MMC-3 from http://www.t10.org/drafts.htm#mmc3 */
++ scsi_command_init (cmd, 0, 0x51); /* READ_DISC_INFORMATION */
++ scsi_command_init (cmd, 8, 32);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 32)) {
++ /* READ_DISC_INFORMATION failed */
++ scsi_command_free (cmd);
++ return 0;
++ }
++
++ retval = ((header[2]&0x03) == 0x01);
++
++ scsi_command_free (cmd);
++ return retval;
++}
++
++int
++brasero_cdrom_disc_is_rewritable (BRASEROCDROM *cdrom)
++{
++ ScsiCommand *cmd;
++ int retval = -1;
++ unsigned char header[32];
++
++ g_return_val_if_fail (cdrom != NULL, -1);
++
++ cmd = scsi_command_new_from_cdrom (cdrom);
++
++ /* see section 5.19 of MMC-3 from http://www.t10.org/drafts.htm#mmc3 */
++ scsi_command_init (cmd, 0, 0x51); /* READ_DISC_INFORMATION */
++ scsi_command_init (cmd, 8, 32);
++ scsi_command_init (cmd, 9, 0);
++ if (scsi_command_transport (cmd, READ, header, 32)) {
++ /* READ_DISC_INFORMATION failed */
++ scsi_command_free (cmd);
++ return 0;
++ }
++
++ retval = ((header[2]&0x10) != 0);
++
++ scsi_command_free (cmd);
++ return retval;
++}
diff --git a/sysutils/brasero/files/patch-src_plugins_cdrtools_burn-cdrecord.c b/sysutils/brasero/files/patch-src_plugins_cdrtools_burn-cdrecord.c
new file mode 100644
index 000000000..583807240
--- /dev/null
+++ b/sysutils/brasero/files/patch-src_plugins_cdrtools_burn-cdrecord.c
@@ -0,0 +1,11 @@
+--- src/plugins/cdrtools/burn-cdrecord.c.orig 2008-01-02 14:59:18.000000000 -0500
++++ src/plugins/cdrtools/burn-cdrecord.c 2008-01-02 14:59:27.000000000 -0500
+@@ -899,7 +899,7 @@ brasero_cdrecord_set_argv (BraseroProces
+ g_ptr_array_add (argv, g_strdup ("cdrecord"));
+ g_ptr_array_add (argv, g_strdup ("-v"));
+
+- brasero_job_get_device (BRASERO_JOB (cdrecord), &device);
++ brasero_job_get_cdrecord_device (BRASERO_JOB (cdrecord), &device);
+ dev_str = g_strdup_printf ("dev=%s", device);
+ g_ptr_array_add (argv, dev_str);
+ g_free (device);
diff --git a/sysutils/brasero/pkg-descr b/sysutils/brasero/pkg-descr
new file mode 100644
index 000000000..2e6f14b59
--- /dev/null
+++ b/sysutils/brasero/pkg-descr
@@ -0,0 +1,23 @@
+CD/DVD mastering tool for the gnome desktop. It has been designed to be
+simple and easy to use.
+
+Features:
+Data CD/DVD:
+- supports edition of discs contents
+- can burn data CD/DVD on the fly
+- supports multisession
+- supports joliet extension
+- can write the image to the hard drive
+Audio CD:
+- write CD-TEXT information (automatically found thanks to gstreamer)
+- supports the edition of CD-TEXT information
+- can burn audio CD on the fly
+- can use all audio files handled by Gstreamer local installation
+- can search for audio files inside dropped folders
+CD/DVD copy:
+- can copy a CD/DVD to the hard drive
+- can copy DVD and CD on the fly
+- supports single-session data DVD
+- supports any kind of CD
+
+WWW: http://perso.wanadoo.fr/bonfire/
diff --git a/sysutils/brasero/pkg-plist b/sysutils/brasero/pkg-plist
new file mode 100644
index 000000000..acbe2314b
--- /dev/null
+++ b/sysutils/brasero/pkg-plist
@@ -0,0 +1,245 @@
+bin/brasero
+lib/brasero/plugins/libbrasero-cdrdao.la
+lib/brasero/plugins/libbrasero-cdrdao.so
+lib/brasero/plugins/libbrasero-cdrecord.la
+lib/brasero/plugins/libbrasero-cdrecord.so
+lib/brasero/plugins/libbrasero-dvdcss.la
+lib/brasero/plugins/libbrasero-dvdcss.so
+lib/brasero/plugins/libbrasero-dvdrwformat.la
+lib/brasero/plugins/libbrasero-dvdrwformat.so
+lib/brasero/plugins/libbrasero-genisoimage.la
+lib/brasero/plugins/libbrasero-genisoimage.so
+lib/brasero/plugins/libbrasero-growisofs.la
+lib/brasero/plugins/libbrasero-growisofs.so
+lib/brasero/plugins/libbrasero-local-track.la
+lib/brasero/plugins/libbrasero-local-track.so
+lib/brasero/plugins/libbrasero-md5sum-file.la
+lib/brasero/plugins/libbrasero-md5sum-file.so
+lib/brasero/plugins/libbrasero-md5sum.la
+lib/brasero/plugins/libbrasero-md5sum.so
+lib/brasero/plugins/libbrasero-mkisofs.la
+lib/brasero/plugins/libbrasero-mkisofs.so
+lib/brasero/plugins/libbrasero-readcd.la
+lib/brasero/plugins/libbrasero-readcd.so
+lib/brasero/plugins/libbrasero-readom.la
+lib/brasero/plugins/libbrasero-readom.so
+lib/brasero/plugins/libbrasero-toc2cue.la
+lib/brasero/plugins/libbrasero-toc2cue.so
+lib/brasero/plugins/libbrasero-transcode.la
+lib/brasero/plugins/libbrasero-transcode.so
+lib/brasero/plugins/libbrasero-wodim.la
+lib/brasero/plugins/libbrasero-wodim.so
+share/applications/brasero.desktop
+%%DATADIR%%/icons/hicolor/16x16/actions/insert-pause.png
+%%DATADIR%%/icons/hicolor/16x16/actions/iso-image-burn.png
+%%DATADIR%%/icons/hicolor/16x16/actions/iso-image-new.png
+%%DATADIR%%/icons/hicolor/16x16/actions/media-optical-audio-new.png
+%%DATADIR%%/icons/hicolor/16x16/actions/media-optical-blank.png
+%%DATADIR%%/icons/hicolor/16x16/actions/media-optical-burn.png
+%%DATADIR%%/icons/hicolor/16x16/actions/media-optical-copy.png
+%%DATADIR%%/icons/hicolor/16x16/actions/media-optical-data-new.png
+%%DATADIR%%/icons/hicolor/16x16/actions/transform-crop-and-resize.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-00.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-05.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-10.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-100.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-15.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-20.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-25.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-30.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-35.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-40.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-45.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-50.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-55.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-60.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-65.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-70.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-75.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-80.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-85.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-90.png
+%%DATADIR%%/icons/hicolor/16x16/status/brasero-disc-95.png
+%%DATADIR%%/icons/hicolor/22x22/actions/insert-pause.png
+%%DATADIR%%/icons/hicolor/22x22/actions/iso-image-burn.png
+%%DATADIR%%/icons/hicolor/22x22/actions/iso-image-new.png
+%%DATADIR%%/icons/hicolor/22x22/actions/media-optical-audio-new.png
+%%DATADIR%%/icons/hicolor/22x22/actions/media-optical-blank.png
+%%DATADIR%%/icons/hicolor/22x22/actions/media-optical-burn.png
+%%DATADIR%%/icons/hicolor/22x22/actions/media-optical-copy.png
+%%DATADIR%%/icons/hicolor/22x22/actions/media-optical-data-new.png
+%%DATADIR%%/icons/hicolor/22x22/actions/transform-crop-and-resize.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-00.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-05.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-10.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-100.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-15.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-20.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-25.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-30.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-35.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-40.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-45.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-50.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-55.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-60.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-65.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-70.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-75.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-80.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-85.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-90.png
+%%DATADIR%%/icons/hicolor/22x22/status/brasero-disc-95.png
+%%DATADIR%%/icons/hicolor/24x24/actions/insert-pause.png
+%%DATADIR%%/icons/hicolor/24x24/actions/iso-image-burn.png
+%%DATADIR%%/icons/hicolor/24x24/actions/iso-image-new.png
+%%DATADIR%%/icons/hicolor/24x24/actions/media-optical-audio-new.png
+%%DATADIR%%/icons/hicolor/24x24/actions/media-optical-blank.png
+%%DATADIR%%/icons/hicolor/24x24/actions/media-optical-burn.png
+%%DATADIR%%/icons/hicolor/24x24/actions/media-optical-copy.png
+%%DATADIR%%/icons/hicolor/24x24/actions/media-optical-data-new.png
+%%DATADIR%%/icons/hicolor/24x24/actions/transform-crop-and-resize.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-00.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-05.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-10.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-100.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-15.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-20.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-25.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-30.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-35.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-40.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-45.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-50.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-55.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-60.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-65.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-70.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-75.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-80.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-85.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-90.png
+%%DATADIR%%/icons/hicolor/24x24/status/brasero-disc-95.png
+%%DATADIR%%/icons/hicolor/32x32/actions/insert-pause.png
+%%DATADIR%%/icons/hicolor/32x32/actions/iso-image-burn.png
+%%DATADIR%%/icons/hicolor/32x32/actions/iso-image-new.png
+%%DATADIR%%/icons/hicolor/32x32/actions/media-optical-audio-new.png
+%%DATADIR%%/icons/hicolor/32x32/actions/media-optical-blank.png
+%%DATADIR%%/icons/hicolor/32x32/actions/media-optical-burn.png
+%%DATADIR%%/icons/hicolor/32x32/actions/media-optical-copy.png
+%%DATADIR%%/icons/hicolor/32x32/actions/media-optical-data-new.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-00.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-05.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-10.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-100.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-15.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-20.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-25.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-30.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-35.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-40.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-45.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-50.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-55.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-60.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-65.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-70.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-75.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-80.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-85.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-90.png
+%%DATADIR%%/icons/hicolor/32x32/status/brasero-disc-95.png
+%%DATADIR%%/icons/hicolor/scalable/actions/insert-pause.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/iso-image-burn.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/iso-image-new.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/media-optical-audio-new.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/media-optical-blank.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/media-optical-burn.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/media-optical-copy.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/media-optical-data-new.svg
+%%DATADIR%%/icons/hicolor/scalable/actions/transform-crop-and-resize.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-00.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-05.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-10.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-100.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-15.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-20.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-25.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-30.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-35.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-40.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-45.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-50.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-55.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-60.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-65.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-70.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-75.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-80.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-85.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-90.svg
+%%DATADIR%%/icons/hicolor/scalable/status/brasero-disc-95.svg
+%%DATADIR%%/logo.png
+share/icons/hicolor/16x16/apps/brasero.png
+share/icons/hicolor/22x22/apps/brasero.png
+share/icons/hicolor/24x24/apps/brasero.png
+share/icons/hicolor/32x32/apps/brasero.png
+share/icons/hicolor/48x48/apps/brasero.png
+share/icons/hicolor/scalable/apps/brasero.svg
+share/locale/ar/LC_MESSAGES/brasero.mo
+share/locale/ca/LC_MESSAGES/brasero.mo
+share/locale/cs/LC_MESSAGES/brasero.mo
+share/locale/de/LC_MESSAGES/brasero.mo
+share/locale/dz/LC_MESSAGES/brasero.mo
+share/locale/en_GB/LC_MESSAGES/brasero.mo
+share/locale/es/LC_MESSAGES/brasero.mo
+share/locale/fi/LC_MESSAGES/brasero.mo
+share/locale/fr/LC_MESSAGES/brasero.mo
+share/locale/gl/LC_MESSAGES/brasero.mo
+share/locale/he/LC_MESSAGES/brasero.mo
+share/locale/hu/LC_MESSAGES/brasero.mo
+share/locale/it/LC_MESSAGES/brasero.mo
+share/locale/ja/LC_MESSAGES/brasero.mo
+share/locale/lt/LC_MESSAGES/brasero.mo
+share/locale/mk/LC_MESSAGES/brasero.mo
+share/locale/nb/LC_MESSAGES/brasero.mo
+share/locale/oc/LC_MESSAGES/brasero.mo
+share/locale/pa/LC_MESSAGES/brasero.mo
+share/locale/pl/LC_MESSAGES/brasero.mo
+share/locale/pt/LC_MESSAGES/brasero.mo
+share/locale/pt_BR/LC_MESSAGES/brasero.mo
+share/locale/ru/LC_MESSAGES/brasero.mo
+share/locale/sl/LC_MESSAGES/brasero.mo
+share/locale/sr/LC_MESSAGES/brasero.mo
+share/locale/sr@Latn/LC_MESSAGES/brasero.mo
+share/locale/sv/LC_MESSAGES/brasero.mo
+share/mime/packages/brasero.xml
+@dirrm %%DATADIR%%/icons/hicolor/16x16/status
+@dirrm %%DATADIR%%/icons/hicolor/16x16/actions
+@dirrm %%DATADIR%%/icons/hicolor/16x16
+@dirrm %%DATADIR%%/icons/hicolor/22x22/status
+@dirrm %%DATADIR%%/icons/hicolor/22x22/actions
+@dirrm %%DATADIR%%/icons/hicolor/22x22
+@dirrm %%DATADIR%%/icons/hicolor/24x24/status
+@dirrm %%DATADIR%%/icons/hicolor/24x24/actions
+@dirrm %%DATADIR%%/icons/hicolor/24x24
+@dirrm %%DATADIR%%/icons/hicolor/32x32/status
+@dirrm %%DATADIR%%/icons/hicolor/32x32/actions
+@dirrm %%DATADIR%%/icons/hicolor/32x32
+@dirrm %%DATADIR%%/icons/hicolor/scalable/status
+@dirrm %%DATADIR%%/icons/hicolor/scalable/actions
+@dirrm %%DATADIR%%/icons/hicolor/scalable
+@dirrm %%DATADIR%%/icons/hicolor
+@dirrm %%DATADIR%%/icons
+@dirrm %%DATADIR%%
+@dirrmtry share/applications
+@dirrm lib/brasero/plugins
+@dirrm lib/brasero
+@exec %%LOCALBASE%%/bin/update-mime-database %D/share/mime
+@unexec %%LOCALBASE%%/bin/update-mime-database %D/share/mime
+@exec %%LOCALBASE%%/bin/update-desktop-database > /dev/null || /usr/bin/true
+@unexec %%LOCALBASE%%/bin/update-desktop-database > /dev/null || /usr/bin/true
+@dirrmtry share/locale/oc/LC_MESSAGES
+@dirrmtry share/locale/oc
+@dirrmtry share/locale/dz/LC_MESSAGES
+@dirrmtry share/locale/dz
diff --git a/x11-toolkits/py-gnome-desktop/Makefile b/x11-toolkits/py-gnome-desktop/Makefile
new file mode 100644
index 000000000..7d06f8abf
--- /dev/null
+++ b/x11-toolkits/py-gnome-desktop/Makefile
@@ -0,0 +1,63 @@
+# New ports collection makefile for: py-gnome-desktop
+# Date created: 20 January 2006
+# Whom: Joe Marcus Clarke <marcus@FreeBSD.org>
+#
+# $FreeBSD$
+# $MCom: ports/x11-toolkits/py-gnome-desktop/Makefile,v 1.72 2008/03/09 21:58:25 mezz Exp $
+#
+
+PORTNAME= gnome
+PORTVERSION= 2.22.0
+PORTREVISION= 1
+CATEGORIES= x11-toolkits python gnome
+MASTER_SITES= ${MASTER_SITE_GNOME}
+MASTER_SITE_SUBDIR= sources/gnome-python-desktop/${PORTVERSION:C/^([0-9]+\.[0-9]+).*/\1/}
+PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
+PKGNAMESUFFIX= -desktop
+DISTNAME= gnome-python-desktop-${PORTVERSION}
+DIST_SUBDIR= gnome2
+
+MAINTAINER= gnome@FreeBSD.org
+COMMENT= A set of Python bindings used by modules in the GNOME Desktop
+
+BUILD_DEPENDS= bug-buddy:${PORTSDIR}/devel/bug-buddy
+LIB_DEPENDS= gtop-2.0.7:${PORTSDIR}/devel/libgtop \
+ totem-plparser.12:${PORTSDIR}/multimedia/totem-pl-parser \
+ gnome-media-profiles.0:${PORTSDIR}/audio/gnome-media \
+ gnome-keyring:${PORTSDIR}/security/gnome-keyring
+RUN_DEPENDS= bug-buddy:${PORTSDIR}/devel/bug-buddy
+
+USE_BZIP2= yes
+USE_GMAKE= yes
+USE_PYTHON= yes
+USE_GNOME= gnomehack libgnomeprintui gnomepanel gnomedesktop \
+ gtksourceview libwnck nautiluscdburner pygnome2 metacity \
+ evolutiondataserver
+GNU_CONFIGURE= yes
+CONFIGURE_ARGS= --enable-metacity
+CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \
+ LDFLAGS="-L${LOCALBASE}/lib"
+
+EG_SRC_DIR= ${WRKSRC}/examples
+EG_DST_DIR= ${PREFIX}/share/examples/py-gnome
+.if !defined(NOPORTDOCS)
+DOCSDIR= ${PREFIX}/share/doc/py-gnome-desktop
+.else
+DOCSDIR= ${WRKSRC}/share/doc/py-gnome-desktop
+.endif
+
+.include <bsd.port.pre.mk>
+
+post-patch:
+ @${FIND} ${WRKSRC}/docs -name Makefile.in | ${XARGS} ${REINPLACE_CMD} \
+ -e 's|^HTML_DIR =.*|HTML_DIR = ${DOCSDIR}|g'
+
+.if !defined(NOPORTDOCS)
+post-install:
+ ${MKDIR} ${EG_DST_DIR}
+ ${TAR} -C ${EG_SRC_DIR} -cf - . | ${TAR} -C ${EG_DST_DIR} -xf -
+ ${CHOWN} -R ${BINOWN}:${BINGRP} ${EG_DST_DIR}
+ ${CHMOD} -R go-w ${EG_DST_DIR}
+.endif
+
+.include <bsd.port.post.mk>
diff --git a/x11-toolkits/py-gnome-desktop/distinfo b/x11-toolkits/py-gnome-desktop/distinfo
new file mode 100644
index 000000000..ccb42e48d
--- /dev/null
+++ b/x11-toolkits/py-gnome-desktop/distinfo
@@ -0,0 +1,3 @@
+MD5 (gnome2/gnome-python-desktop-2.22.0.tar.bz2) = 504877a973f6abc0788283232cd703cb
+SHA256 (gnome2/gnome-python-desktop-2.22.0.tar.bz2) = 116213b0b0fc3f1fa6771589eab86ccdf5d5024c30a987f3b912da0902be9d37
+SIZE (gnome2/gnome-python-desktop-2.22.0.tar.bz2) = 571816
diff --git a/x11-toolkits/py-gnome-desktop/files/patch-gtop_gtop.c b/x11-toolkits/py-gnome-desktop/files/patch-gtop_gtop.c
new file mode 100644
index 000000000..05db58a4c
--- /dev/null
+++ b/x11-toolkits/py-gnome-desktop/files/patch-gtop_gtop.c
@@ -0,0 +1,20 @@
+--- gtop/gtop.c.orig Wed May 18 00:54:59 2005
++++ gtop/gtop.c Wed May 18 00:54:12 2005
+@@ -44,6 +44,7 @@
+
+ #include <sys/types.h>
+ #include <sys/socket.h>
++#include <netinet/in.h>
+ #include <arpa/inet.h>
+
+
+@@ -1316,8 +1317,8 @@ build_siglist(void)
+
+ for(i = 0; i < len; ++i)
+ {
+- p = &glibtop_sys_siglist[i];
+ PyObject* d;
++ p = &glibtop_sys_siglist[i];
+
+ d = PyDict_New();
+ my_dict_add_and_decref(d, "number", PyI_L(p->number));
diff --git a/x11-toolkits/py-gnome-desktop/pkg-descr b/x11-toolkits/py-gnome-desktop/pkg-descr
new file mode 100644
index 000000000..cbc8cc5d8
--- /dev/null
+++ b/x11-toolkits/py-gnome-desktop/pkg-descr
@@ -0,0 +1,2 @@
+GnomePythonDesktop provides python interfacing modules for some GNOME
+libraries part of the GNOME Desktop.
diff --git a/x11-toolkits/py-gnome-desktop/pkg-plist b/x11-toolkits/py-gnome-desktop/pkg-plist
new file mode 100644
index 000000000..cdc0b502b
--- /dev/null
+++ b/x11-toolkits/py-gnome-desktop/pkg-plist
@@ -0,0 +1,135 @@
+%%PYTHON_SITELIBDIR%%/gtk-2.0/bugbuddy.py
+%%PYTHON_SITELIBDIR%%/gtk-2.0/bugbuddy.pyc
+%%PYTHON_SITELIBDIR%%/gtk-2.0/bugbuddy.pyo
+%%PYTHON_SITELIBDIR%%/gtk-2.0/evolution/__init__.py
+%%PYTHON_SITELIBDIR%%/gtk-2.0/evolution/ebook.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/evolution/ebook.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/evolution/ecal.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/evolution/ecal.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnome/applet.py
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnome/applet.pyc
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnome/applet.pyo
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeapplet.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeapplet.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomedesktop/__init__.py
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomedesktop/__init__.pyc
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomedesktop/__init__.pyo
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomedesktop/_gnomedesktop.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomedesktop/_gnomedesktop.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomekeyring.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomekeyring.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/__init__.py
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/__init__.pyc
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/__init__.pyo
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/_print.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/_print.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/ui.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint/ui.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gtksourceview.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gtksourceview.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gtop.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/gtop.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/mediaprofiles.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/mediaprofiles.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/metacity.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/metacity.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/nautilusburn.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/nautilusburn.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/rsvg.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/rsvg.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/totem/__init__.py
+%%PYTHON_SITELIBDIR%%/gtk-2.0/totem/__init__.pyc
+%%PYTHON_SITELIBDIR%%/gtk-2.0/totem/__init__.pyo
+%%PYTHON_SITELIBDIR%%/gtk-2.0/totem/plparser.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/totem/plparser.so
+%%PYTHON_SITELIBDIR%%/gtk-2.0/wnck.la
+%%PYTHON_SITELIBDIR%%/gtk-2.0/wnck.so
+libdata/pkgconfig/gnome-python-desktop-2.0.pc
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/class-gnomeprintconfig.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/class-gnomeprintcontext.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/class-gnomeprintfont.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/class-gnomeprintfontface.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/class-gnomeprintglyphlist.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/class-gnomeprintjob.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/gnomeprint-class-reference.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/index.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/index.sgml
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprint/pygnomeprint.devhelp
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuidialog.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuifontdialog.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuifontpreview.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuifontselection.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuijobpreview.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuipaperselector.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/class-gnomeprintuipreview.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/gnomeprintui-class-reference.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/index.html
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/index.sgml
+%%PORTDOCS%%%%DOCSDIR%%/pygnomeprintui/pygnomeprintui.devhelp
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcebuffer.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcelanguage.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcelanguagesmanager.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcemarker.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourceprintjob.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcestylescheme.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcetag.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcetagstyle.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourcetagtable.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/class-gtksourceview.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/gtksourceview-class-reference.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/index.html
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/index.sgml
+%%PORTDOCS%%%%DOCSDIR%%/pygtksourceview/pygtksourceview.devhelp
+%%PORTDOCS%%share/examples/py-gnome/applet/GNOME_PythonAppletSample.server
+%%PORTDOCS%%share/examples/py-gnome/applet/README
+%%PORTDOCS%%share/examples/py-gnome/applet/applet.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/README
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_01.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_02.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_03.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_04.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_05.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_06.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_08.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_09.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_10.glade
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_10.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/example_11.py
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/sample-image.png
+%%PORTDOCS%%share/examples/py-gnome/gnomeprint/test-print.py
+%%PORTDOCS%%share/examples/py-gnome/gtksourceview/test-widget.py
+%%PORTDOCS%%share/examples/py-gnome/keyring-async.py
+%%PORTDOCS%%share/examples/py-gnome/keyring.py
+%%PORTDOCS%%share/examples/py-gnome/mediaprofiles/profiles.py
+%%PORTDOCS%%share/examples/py-gnome/nautilusburn/blank_disc.py
+%%PORTDOCS%%share/examples/py-gnome/nautilusburn/drive_selection.py
+%%PORTDOCS%%share/examples/py-gnome/nautilusburn/write_iso.py
+%%PORTDOCS%%share/examples/py-gnome/rsvg/rsvg-cairo.py
+%%PORTDOCS%%share/examples/py-gnome/wnck_example.py
+share/pygtk/2.0/defs/_gnomedesktop.defs
+share/pygtk/2.0/defs/applet.defs
+share/pygtk/2.0/defs/art.defs
+share/pygtk/2.0/defs/ebook.defs
+share/pygtk/2.0/defs/gnomekeyring.defs
+share/pygtk/2.0/defs/gtksourceview.defs
+share/pygtk/2.0/defs/mediaprofiles.defs
+share/pygtk/2.0/defs/metacity.defs
+share/pygtk/2.0/defs/nautilus_burn.defs
+share/pygtk/2.0/defs/print.defs
+share/pygtk/2.0/defs/printui.defs
+share/pygtk/2.0/defs/wnck.defs
+%%PORTDOCS%%@dirrm share/examples/py-gnome/rsvg
+%%PORTDOCS%%@dirrm share/examples/py-gnome/nautilusburn
+%%PORTDOCS%%@dirrm share/examples/py-gnome/mediaprofiles
+%%PORTDOCS%%@dirrm share/examples/py-gnome/gtksourceview
+%%PORTDOCS%%@dirrm share/examples/py-gnome/gnomeprint
+%%PORTDOCS%%@dirrm share/examples/py-gnome/applet
+%%PORTDOCS%%@dirrmtry share/examples/py-gnome
+%%PORTDOCS%%@dirrm %%DOCSDIR%%/pygtksourceview
+%%PORTDOCS%%@dirrm %%DOCSDIR%%/pygnomeprintui
+%%PORTDOCS%%@dirrm %%DOCSDIR%%/pygnomeprint
+%%PORTDOCS%%@dirrm %%DOCSDIR%%
+@dirrm %%PYTHON_SITELIBDIR%%/gtk-2.0/totem
+@dirrm %%PYTHON_SITELIBDIR%%/gtk-2.0/gnomeprint
+@dirrm %%PYTHON_SITELIBDIR%%/gtk-2.0/gnomedesktop
+@dirrm %%PYTHON_SITELIBDIR%%/gtk-2.0/evolution