1
/***************************************************************************
4
* dim jan 22 15:22:52 2006
5
* Copyright 2006 Rouquier Philippe
6
* brasero-app@wanadoo.fr
7
***************************************************************************/
10
* Brasero is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* Brasero is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU Library General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to:
22
* The Free Software Foundation, Inc.,
23
* 51 Franklin Street, Fifth Floor
24
* Boston, MA 02110-1301, USA.
33
#include <sys/types.h>
41
#include <glib-object.h>
42
#include <glib/gi18n-lib.h>
43
#include <glib/gstdio.h>
46
#include <gconf/gconf-client.h>
48
#include "burn-basics.h"
50
#include "burn-process.h"
51
#include "burn-plugin.h"
52
#include "burn-cdrtools.h"
53
#include "burn-cdrecord.h"
55
BRASERO_PLUGIN_BOILERPLATE (BraseroCDRecord, brasero_cdrecord, BRASERO_TYPE_PROCESS, BraseroProcess);
57
struct _BraseroCDRecordPrivate {
58
gint64 current_track_end_pos;
59
gint64 current_track_written;
61
gint current_track_num;
70
typedef struct _BraseroCDRecordPrivate BraseroCDRecordPrivate;
71
#define BRASERO_CD_RECORD_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_CD_RECORD, BraseroCDRecordPrivate))
73
static GObjectClass *parent_class = NULL;
75
#define GCONF_KEY_IMMEDIATE_FLAG "/apps/brasero/config/immed_flag"
76
#define GCONF_KEY_MINBUF_VALUE "/apps/brasero/config/minbuf_value"
78
static BraseroBurnResult
79
brasero_cdrecord_stderr_read (BraseroProcess *process, const gchar *line)
81
BraseroBurnFlag flags;
83
brasero_job_get_flags (BRASERO_JOB (process), &flags);
85
if (strstr (line, "Cannot open SCSI driver.")
86
|| strstr (line, "Operation not permitted. Cannot send SCSI cmd via ioctl")
87
|| strstr (line, "Cannot open or use SCSI driver")) {
88
brasero_job_error (BRASERO_JOB (process),
89
g_error_new (BRASERO_BURN_ERROR,
90
BRASERO_BURN_ERROR_PERMISSION,
91
_("You do not have the required permissions to use this drive")));
93
else if (!(flags & BRASERO_BURN_FLAG_OVERBURN)
94
&& strstr (line, "Data may not fit on current disk")) {
95
/* we don't error out if overburn was chosen */
96
brasero_job_error (BRASERO_JOB (process),
97
g_error_new (BRASERO_BURN_ERROR,
98
BRASERO_BURN_ERROR_MEDIUM_SPACE,
99
_("Not enough space available on the disc")));
101
else if (strstr (line ,"cdrecord: A write error occured")
102
|| strstr (line, "Could not write Lead-in")
103
|| strstr (line, "Cannot fixate disk")) {
104
brasero_job_error (BRASERO_JOB (process),
105
g_error_new (BRASERO_BURN_ERROR,
106
BRASERO_BURN_ERROR_WRITE_MEDIUM,
107
_("An error occured while writing to disc")));
109
else if (strstr (line, "DMA speed too slow") != NULL) {
110
brasero_job_error (BRASERO_JOB (process),
111
g_error_new (BRASERO_BURN_ERROR,
112
BRASERO_BURN_ERROR_SLOW_DMA,
113
_("The system is too slow to write the disc at this speed. Try a lower speed")));
115
else if (strstr (line, "Device or resource busy")) {
116
if (!strstr (line, "retrying in")) {
117
brasero_job_error (BRASERO_JOB (process),
118
g_error_new (BRASERO_BURN_ERROR,
119
BRASERO_BURN_ERROR_DRIVE_BUSY,
120
_("The drive is busy")));
123
else if (strstr (line, "Illegal write mode for this drive")) {
124
/* NOTE : when it happened I had to unlock the
125
* drive with cdrdao and eject it. Should we ? */
126
brasero_job_error (BRASERO_JOB (process),
127
g_error_new (BRASERO_BURN_ERROR,
128
BRASERO_BURN_ERROR_DRIVE_BUSY,
129
_("The drive is busy")));
132
/* REMINDER: these should not be necessary as we checked that already */
134
else if (strstr (line, "cannot write medium - incompatible format") != NULL) {
135
brasero_job_error (BRASERO_JOB (process),
136
g_error_new (BRASERO_BURN_ERROR,
137
BRASERO_BURN_ERROR_INPUT_INVALID,
138
_("The image does not seem to be a proper iso9660 file system")));
140
else if (strstr (line, "This means that we are checking recorded media.") != NULL) {
141
**/ /* NOTE: defer the consequence of this error as it is not always
142
* fatal. So send a warning but don't stop the process. */
143
/** brasero_process_deferred_error (process,
144
g_error_new (BRASERO_BURN_ERROR,
145
BRASERO_BURN_ERROR_MEDIUM_INVALID,
146
_("The disc is already burnt")));
148
else if (strstr (line, "Cannot blank disk, aborting.") != NULL) {
149
brasero_job_error (BRASERO_JOB (process),
150
g_error_new (BRASERO_BURN_ERROR,
151
BRASERO_BURN_ERROR_MEDIUM_INVALID,
152
_("The disc could not be blanked")));
154
else if (strstr (line, "Bad audio track size")) {
155
brasero_job_error (BRASERO_JOB (process),
156
g_error_new (BRASERO_BURN_ERROR,
157
BRASERO_BURN_ERROR_GENERAL,
158
_("The audio tracks are too short or not a multiple of 2352")));
160
else if (strstr (line, "cdrecord: No such file or directory. Cannot open")
161
|| strstr (line, "No tracks specified. Need at least one.")) {
162
brasero_job_error (BRASERO_JOB (process),
163
g_error_new (BRASERO_BURN_ERROR,
164
BRASERO_BURN_ERROR_INPUT,
165
_("The image file cannot be found")));
167
else if (strstr (line, "Inappropriate audio coding")) {
168
brasero_job_error (BRASERO_JOB (process),
169
g_error_new (BRASERO_BURN_ERROR,
170
BRASERO_BURN_ERROR_INPUT_INVALID,
171
_("All audio files must be stereo, 16-bit digital audio with 44100Hz samples")));
173
else if (strstr (line, "No disk / Wrong disk!") != NULL) {
174
brasero_job_error (BRASERO_JOB (process),
175
g_error_new (BRASERO_BURN_ERROR,
176
BRASERO_BURN_ERROR_MEDIA_NONE,
177
_("There seems to be no disc in the drive")));
182
/** For these we'd rather have a message saying "cdrecord failed"
183
* as an internal error occured says nothing/even less
184
else if (strstr (line, "Bad file descriptor. read error on input file")
185
|| strstr (line, "Input buffer error, aborting")) {
186
brasero_job_error (BRASERO_JOB (process),
187
g_error_new (BRASERO_BURN_ERROR,
188
BRASERO_BURN_ERROR_GENERAL,
189
_("An internal error occured")));
194
return BRASERO_BURN_OK;
198
brasero_cdrecord_compute (BraseroCDRecord *cdrecord,
203
gboolean track_num_changed = FALSE;
204
BraseroCDRecordPrivate *priv;
205
gchar *action_string;
210
priv = BRASERO_CD_RECORD_PRIVATE (cdrecord);
214
total = mb_total * 1048576;
216
if (track_num > priv->current_track_num) {
217
track_num_changed = TRUE;
218
priv->current_track_num = track_num;
219
priv->current_track_end_pos += mb_total * 1048576;
222
this_remain = (mb_total - mb_written) * 1048576;
223
bytes = (total - priv->current_track_end_pos) + this_remain;
224
brasero_job_set_written_session (BRASERO_JOB (cdrecord), total - bytes);
226
action_string = g_strdup_printf ("Writing track %02i", track_num);
227
brasero_job_set_current_action (BRASERO_JOB (cdrecord),
228
BRASERO_BURN_ACTION_RECORDING,
231
g_free (action_string);
234
static BraseroBurnResult
235
brasero_cdrecord_stdout_read (BraseroProcess *process, const gchar *line)
238
guint speed_1, speed_2;
239
BraseroCDRecord *cdrecord;
240
BraseroCDRecordPrivate *priv;
241
int mb_written = 0, mb_total = 0, fifo = 0, buf = 0;
243
cdrecord = BRASERO_CD_RECORD (process);
244
priv = BRASERO_CD_RECORD_PRIVATE (cdrecord);
246
if (sscanf (line, "Track %2u: %d of %d MB written (fifo %d%%) [buf %d%%] %d.%dx.",
247
&track, &mb_written, &mb_total, &fifo, &buf, &speed_1, &speed_2) == 7) {
248
gdouble current_rate;
250
current_rate = (gdouble) ((gdouble) speed_1 +
251
(gdouble) speed_2 / 10.0) *
253
brasero_job_set_rate (BRASERO_JOB (cdrecord), current_rate);
255
priv->current_track_written = mb_written * 1048576;
256
brasero_cdrecord_compute (cdrecord,
261
brasero_job_start_progress (BRASERO_JOB (cdrecord), FALSE);
263
else if (sscanf (line, "Track %2u: %d MB written (fifo %d%%) [buf %d%%] %d.%dx.",
264
&track, &mb_written, &fifo, &buf, &speed_1, &speed_2) == 6) {
265
gdouble current_rate;
267
/* this line is printed when cdrecord writes on the fly */
268
current_rate = (gdouble) ((gdouble) speed_1 +
269
(gdouble) speed_2 / 10.0) *
271
brasero_job_set_rate (BRASERO_JOB (cdrecord), current_rate);
273
priv->current_track_written = mb_written * 1048576;
274
if (brasero_job_get_fd_in (BRASERO_JOB (cdrecord), NULL) == BRASERO_BURN_OK) {
277
/* we must ask the imager what is the total size */
278
brasero_job_get_session_output_size (BRASERO_JOB (cdrecord),
281
mb_total = bytes / 1048576;
282
brasero_cdrecord_compute (cdrecord,
288
brasero_job_start_progress (BRASERO_JOB (cdrecord), FALSE);
290
else if (sscanf (line, "Track %*d: %*s %d MB ", &mb_total) == 1) {
292
priv->tracks_total_bytes += mb_total * 1048576;
294
else if (strstr (line, "Formatting media")) {
295
brasero_job_set_current_action (BRASERO_JOB (process),
296
BRASERO_BURN_ACTION_BLANKING,
297
_("Formatting disc"),
300
else if (strstr (line, "Sending CUE sheet")) {
301
BraseroTrackType type;
303
/* See if we are in an audio case which would mean we're writing
305
brasero_job_get_input_type (BRASERO_JOB (cdrecord), &type);
306
brasero_job_set_current_action (BRASERO_JOB (process),
307
BRASERO_BURN_ACTION_RECORDING_CD_TEXT,
308
(type.type == BRASERO_TRACK_TYPE_AUDIO) ? NULL:_("Writing cue sheet"),
311
else if (g_str_has_prefix (line, "Re-load disk and hit <CR>")
312
|| g_str_has_prefix (line, "send SIGUSR1 to continue")) {
313
BraseroBurnAction action = BRASERO_BURN_ACTION_NONE;
315
brasero_job_get_current_action (BRASERO_JOB (process), &action);
317
/* NOTE: There seems to be a BUG somewhere when writing raw images
318
* with clone mode. After disc has been written and fixated cdrecord
319
* asks the media to be reloaded. So we simply ignore this message
320
* and returns that everything went well. Which is indeed the case */
321
if (action == BRASERO_BURN_ACTION_FIXATING) {
322
brasero_job_finished_session (BRASERO_JOB (process));
323
return BRASERO_BURN_OK;
326
brasero_job_error (BRASERO_JOB (process),
327
g_error_new (BRASERO_BURN_ERROR,
328
BRASERO_BURN_ERROR_MEDIUM_NEED_RELOADING,
329
_("The disc needs to be reloaded before being recorded")));
331
else if (g_str_has_prefix (line, "Fixating...")
332
|| g_str_has_prefix (line, "Writing Leadout...")) {
333
brasero_job_set_current_action (BRASERO_JOB (process),
334
BRASERO_BURN_ACTION_FIXATING,
338
else if (g_str_has_prefix (line, "Last chance to quit, ")) {
339
brasero_job_set_dangerous (BRASERO_JOB (process), TRUE);
341
else if (g_str_has_prefix (line, "Blanking PMA, TOC, pregap")
342
|| strstr (line, "Blanking entire disk")) {
345
/* This should not happen */
346
/* else if (strstr (line, "Use tsize= option in SAO mode to specify track size")) */
348
return BRASERO_BURN_OK;
352
brasero_cdrecord_write_inf (BraseroCDRecord *cdrecord,
370
BraseroSongInfo *info;
371
BraseroCDRecordPrivate *priv;
374
priv = BRASERO_CD_RECORD_PRIVATE (cdrecord);
376
/* NOTE: about the .inf files: they should have the exact same path
377
* but the ending suffix file is replaced by inf:
378
* example : /path/to/file.mp3 => /path/to/file.inf */
379
if (brasero_job_get_fd_in (BRASERO_JOB (cdrecord), NULL) != BRASERO_BURN_OK) {
380
gchar *dot, *separator;
382
path = brasero_track_get_audio_source (track, FALSE);
384
dot = strrchr (path, '.');
385
separator = strrchr (path, G_DIR_SEPARATOR);
387
if (dot && dot > separator)
388
path = g_strdup_printf ("%.*s.inf",
392
path = g_strdup_printf ("%s.inf",
395
/* since this file was not returned by brasero_job_get_tmp_file
396
* it won't be erased when session is unrefed so we have to do
398
priv->infs = g_slist_prepend (priv->infs, g_strdup (path));
401
BraseroBurnResult result;
403
/* in this case don't care about the name since stdin is used */
404
result = brasero_job_get_tmp_file (BRASERO_JOB (cdrecord),
408
if (result != BRASERO_BURN_OK)
412
fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
416
BRASERO_JOB_LOG (cdrecord, "writing inf (%s)", path);
418
/* The problem here is that when writing CD-TEXT from .inf files, wodim
419
* uses only one charset (and don't let us specify which one) which is
420
* ISO-8859-1. (NOTE: don't believe the doc claiming it requires ASCII
421
* and see cdrecord/cdtext.c line 309).
422
* So we have to convert our UTF-8 input into such a charset.
423
* NOTE: according to docs ASCII should be used for text packs other
424
* than disc/track title.
425
* It might be good in the end to write and pack CD-TEXT pack data
426
* ourselves so we can set a different charset from English like
427
* Chinese for example. */
428
info = brasero_track_get_audio_info (track);
430
strcpy (buffer, "# created by brasero\n");
431
size = strlen (buffer);
432
b_written = write (fd, buffer, size);
433
if (b_written != size)
436
strcpy (buffer, "MCN=\t\n");
437
size = strlen (buffer);
438
b_written = write (fd, buffer, size);
439
if (b_written != size)
443
string = g_strdup_printf ("ISRC=\t%i\n", info->isrc);
445
string = g_strdup ("ISRC=\t\n");
446
size = strlen (string);
447
b_written = write (fd, string, size);
449
if (b_written != size)
452
strcpy (buffer, "Albumperformer=\t\n");
453
size = strlen (buffer);
454
b_written = write (fd, buffer, size);
455
if (b_written != size)
461
encoded = g_convert_with_fallback (album,
465
"_", /* Fallback for non convertible characters */
469
string = g_strdup_printf ("Albumtitle=\t%s\n", encoded);
473
string = strdup ("Albumtitle=\t\n");
474
size = strlen (string);
475
b_written = write (fd, string, size);
477
if (b_written != size)
483
encoded = g_convert_with_fallback (info->artist,
487
"_", /* Fallback for non convertible characters */
491
string = g_strdup_printf ("Performer=\t%s\n", encoded);
495
string = strdup ("Performer=\t\n");
496
size = strlen (string);
497
b_written = write (fd, string, size);
499
if (b_written != size)
502
if (info->composer) {
505
encoded = g_convert_with_fallback (info->composer,
509
"_", /* Fallback for non convertible characters */
513
string = g_strdup_printf ("Composer=\t%s\n", encoded);
517
string = strdup ("Composer=\t\n");
518
size = strlen (string);
519
b_written = write (fd, string, size);
521
if (b_written != size)
527
encoded = g_convert_with_fallback (info->title,
531
"_", /* Fallback for non convertible characters */
535
string = g_strdup_printf ("Tracktitle=\t%s\n", encoded);
539
string = strdup ("Tracktitle=\t\n");
540
size = strlen (string);
541
b_written = write (fd, string, size);
543
if (b_written != size)
546
string = g_strdup_printf ("Tracknumber=\t%i\n", index);
547
size = strlen (string);
548
b_written = write (fd, string, size);
550
if (b_written != size)
553
string = g_strdup_printf ("Trackstart=\t%i\n", start);
554
size = strlen (string);
555
b_written = write (fd, string, size);
557
if (b_written != size)
561
brasero_track_get_audio_length (track, &length);
562
sectors = BRASERO_DURATION_TO_SECTORS (length);
564
BRASERO_JOB_LOG (cdrecord, "got track length %lli", length);
565
string = g_strdup_printf ("Tracklength=\t%"G_GINT64_FORMAT", 0\n", sectors);
566
size = strlen (string);
567
b_written = write (fd, string, size);
569
if (b_written != size)
572
strcpy (buffer, "Pre-emphasis=\tno\n");
573
size = strlen (buffer);
574
b_written = write (fd, buffer, size);
575
if (b_written != size)
578
strcpy (buffer, "Channels=\t2\n");
579
size = strlen (buffer);
580
b_written = write (fd, buffer, size);
581
if (b_written != size)
584
strcpy (buffer, "Copy_permitted=\tyes\n");
585
size = strlen (buffer);
586
b_written = write (fd, buffer, size);
587
if (b_written != size)
590
strcpy (buffer, "Endianess=\tlittle\n");
591
size = strlen (buffer);
592
b_written = write (fd, buffer, size);
593
if (b_written != size)
596
strcpy (buffer, "Index=\t\t0\n");
597
size = strlen (buffer);
598
b_written = write (fd, buffer, size);
599
if (b_written != size)
602
/* NOTE: -1 here means no pregap */
604
/* K3b does this (possibly to remove silence) */
605
string = g_strdup_printf ("Index0=\t\t%"G_GINT64_FORMAT"\n",
609
string = g_strdup_printf ("Index0=\t\t-1\n");
611
size = strlen (string);
612
b_written = write (fd, string, size);
614
if (b_written != size)
620
g_ptr_array_add (argv, path);
624
return BRASERO_BURN_OK;
635
BRASERO_BURN_ERROR_GENERAL,
636
_("An internal error occured (%s)"),
639
return BRASERO_BURN_ERR;
642
static BraseroBurnResult
643
brasero_cdrecord_write_infs (BraseroCDRecord *cdrecord,
647
BraseroCDRecordPrivate *priv;
648
BraseroBurnResult result;
649
gchar *tmpdir = NULL;
656
priv = BRASERO_CD_RECORD_PRIVATE (cdrecord);
658
brasero_job_get_audio_title (BRASERO_JOB (cdrecord), &album);
659
brasero_job_get_tracks (BRASERO_JOB (cdrecord), &tracks);
663
for (iter = tracks; iter; iter = iter->next) {
668
result = brasero_cdrecord_write_inf (cdrecord,
675
(iter->next == NULL),
677
if (result != BRASERO_BURN_OK)
683
brasero_track_get_audio_length (track, &length);
684
start += BRASERO_DURATION_TO_SECTORS (length);
690
return BRASERO_BURN_OK;
693
static BraseroBurnResult
694
brasero_cdrecord_set_argv_record (BraseroCDRecord *cdrecord,
699
BraseroBurnFlag flags;
700
BraseroTrackType type;
701
BraseroCDRecordPrivate *priv;
703
priv = BRASERO_CD_RECORD_PRIVATE (cdrecord);
705
if (priv->immediate) {
706
g_ptr_array_add (argv, g_strdup ("-immed"));
707
g_ptr_array_add (argv, g_strdup_printf ("minbuf=%i", priv->minbuf));
710
if (brasero_job_get_speed (BRASERO_JOB (cdrecord), &speed) == BRASERO_BURN_OK) {
713
speed_str = g_strdup_printf ("speed=%d", speed);
714
g_ptr_array_add (argv, speed_str);
717
brasero_job_get_flags (BRASERO_JOB (cdrecord), &flags);
718
if (flags & BRASERO_BURN_FLAG_OVERBURN)
719
g_ptr_array_add (argv, g_strdup ("-overburn"));
720
if (flags & BRASERO_BURN_FLAG_BURNPROOF)
721
g_ptr_array_add (argv, g_strdup ("driveropts=burnfree"));
722
if (flags & BRASERO_BURN_FLAG_MULTI)
723
g_ptr_array_add (argv, g_strdup ("-multi"));
725
/* NOTE: This write mode is necessary for all CLONE images burning */
726
if (flags & BRASERO_BURN_FLAG_RAW)
727
g_ptr_array_add (argv, g_strdup ("-raw96r"));
729
/* NOTE1: DAO can't be used if we're appending to a disc */
730
/* NOTE2: CD-text cannot be written in tao mode (which is the default)
731
* NOTE3: when we don't want wodim to use stdin then we give the audio
732
* file on the command line. Otherwise we use the .inf */
733
if (flags & BRASERO_BURN_FLAG_DAO)
734
g_ptr_array_add (argv, g_strdup ("-dao"));
736
brasero_job_get_input_type (BRASERO_JOB (cdrecord), &type);
737
if (brasero_job_get_fd_in (BRASERO_JOB (cdrecord), NULL) == BRASERO_BURN_OK) {
738
BraseroBurnResult result;
742
/* we need to know what is the type of the track (audio / data) */
743
result = brasero_job_get_input_type (BRASERO_JOB (cdrecord), &type);
744
if (result != BRASERO_BURN_OK) {
745
BRASERO_JOB_LOG (cdrecord, "Imager doesn't seem to be ready")
748
BRASERO_BURN_ERROR_GENERAL,
749
_("An internal error occured"));
750
return BRASERO_BURN_ERR;
754
result = brasero_job_get_session_output_size (BRASERO_JOB (cdrecord),
757
if (result != BRASERO_BURN_OK) {
758
BRASERO_JOB_LOG (cdrecord, "The size of the session cannot be retrieved")
761
BRASERO_BURN_ERROR_GENERAL,
762
_("An internal error occured"));
763
return BRASERO_BURN_ERR;
766
/* we create a buffer depending on the size
767
* buffer 4m> < 64m and is 1/25th of size otherwise */
768
buffer_size = sectors * 2352 / 1024 / 1024 / 25;
769
if (buffer_size > 32)
771
else if (buffer_size < 4)
774
g_ptr_array_add (argv, g_strdup_printf ("fs=%im", buffer_size));
775
if (type.type == BRASERO_TRACK_TYPE_IMAGE) {
776
if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_BIN) {
777
g_ptr_array_add (argv, g_strdup_printf ("tsize=%Lis", sectors));
778
g_ptr_array_add (argv, g_strdup ("-data"));
779
g_ptr_array_add (argv, g_strdup ("-nopad"));
780
g_ptr_array_add (argv, g_strdup ("-"));
783
BRASERO_JOB_NOT_SUPPORTED (cdrecord);;
785
else if (type.type == BRASERO_TRACK_TYPE_AUDIO) {
786
g_ptr_array_add (argv, g_strdup ("-swab"));
787
g_ptr_array_add (argv, g_strdup ("-audio"));
788
g_ptr_array_add (argv, g_strdup ("-useinfo"));
789
g_ptr_array_add (argv, g_strdup ("-text"));
791
result = brasero_cdrecord_write_infs (cdrecord,
794
if (result != BRASERO_BURN_OK)
798
BRASERO_JOB_NOT_SUPPORTED (cdrecord);
800
else if (type.type == BRASERO_TRACK_TYPE_AUDIO) {
801
BraseroBurnResult result;
804
g_ptr_array_add (argv, g_strdup ("fs=16m"));
805
g_ptr_array_add (argv, g_strdup ("-audio"));
806
g_ptr_array_add (argv, g_strdup ("-swab"));
807
g_ptr_array_add (argv, g_strdup ("-pad"));
809
g_ptr_array_add (argv, g_strdup ("-useinfo"));
810
g_ptr_array_add (argv, g_strdup ("-text"));
812
result = brasero_cdrecord_write_infs (cdrecord,
815
if (result != BRASERO_BURN_OK)
819
brasero_job_get_tracks (BRASERO_JOB (cdrecord), &tracks);
820
for (; tracks; tracks = tracks->next) {
824
track = tracks->data;
825
path = brasero_track_get_audio_source (track, FALSE);
826
g_ptr_array_add (argv, path);
829
else if (type.type == BRASERO_TRACK_TYPE_IMAGE) {
830
BraseroTrack *track = NULL;
832
brasero_job_get_current_track (BRASERO_JOB (cdrecord), &track);
834
BRASERO_JOB_NOT_READY (cdrecord);
836
if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_NONE) {
839
image_path = brasero_track_get_image_source (track, FALSE);
841
BRASERO_JOB_NOT_READY (cdrecord);
843
g_ptr_array_add (argv, g_strdup ("fs=16m"));
844
g_ptr_array_add (argv, g_strdup ("-data"));
845
g_ptr_array_add (argv, g_strdup ("-nopad"));
846
g_ptr_array_add (argv, image_path);
848
else if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_BIN) {
851
isopath = brasero_track_get_image_source (track, FALSE);
853
BRASERO_JOB_NOT_READY (cdrecord);
855
g_ptr_array_add (argv, g_strdup ("fs=16m"));
856
g_ptr_array_add (argv, g_strdup ("-data"));
857
g_ptr_array_add (argv, g_strdup ("-nopad"));
858
g_ptr_array_add (argv, isopath);
860
else if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_CLONE) {
863
rawpath = brasero_track_get_image_source (track, FALSE);
865
BRASERO_JOB_NOT_READY (cdrecord);
867
g_ptr_array_add (argv, g_strdup ("fs=16m"));
868
g_ptr_array_add (argv, g_strdup ("-clone"));
869
g_ptr_array_add (argv, rawpath);
871
else if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_CUE) {
875
cuepath = brasero_track_get_toc_source (track, FALSE);
877
BRASERO_JOB_NOT_READY (cdrecord);
879
g_ptr_array_add (argv, g_strdup ("fs=16m"));
881
cue_str = g_strdup_printf ("cuefile=%s", cuepath);
882
g_ptr_array_add (argv, cue_str);
886
BRASERO_JOB_NOT_SUPPORTED (cdrecord);
889
BRASERO_JOB_NOT_SUPPORTED (cdrecord);
891
brasero_job_set_current_action (BRASERO_JOB (cdrecord),
892
BRASERO_BURN_ACTION_START_RECORDING,
895
return BRASERO_BURN_OK;
898
static BraseroBurnResult
899
brasero_cdrecord_set_argv_blank (BraseroCDRecord *cdrecord, GPtrArray *argv)
902
BraseroBurnFlag flags;
904
brasero_job_get_flags (BRASERO_JOB (cdrecord), &flags);
905
blank_str = g_strdup_printf ("blank=%s",
906
(flags & BRASERO_BURN_FLAG_FAST_BLANK) ? "fast" : "all");
907
g_ptr_array_add (argv, blank_str);
909
brasero_job_set_current_action (BRASERO_JOB (cdrecord),
910
BRASERO_BURN_ACTION_BLANKING,
913
return BRASERO_BURN_OK;
916
static BraseroBurnResult
917
brasero_cdrecord_set_argv (BraseroProcess *process,
921
BraseroCDRecordPrivate *priv;
922
BraseroCDRecord *cdrecord;
923
BraseroBurnResult result;
924
BraseroJobAction action;
925
BraseroBurnFlag flags;
929
cdrecord = BRASERO_CD_RECORD (process);
930
priv = BRASERO_CD_RECORD_PRIVATE (cdrecord);
932
brasero_job_get_action (BRASERO_JOB (cdrecord), &action);
933
if (action == BRASERO_JOB_ACTION_SIZE)
934
return BRASERO_BURN_NOT_SUPPORTED;
936
g_ptr_array_add (argv, g_strdup ("cdrecord"));
937
g_ptr_array_add (argv, g_strdup ("-v"));
939
#ifdef HAVE_CAM_LIB_H
940
/* FreeBSD like that better */
941
brasero_job_get_bus_target_lun (BRASERO_JOB (cdrecord), &device);
943
brasero_job_get_device (BRASERO_JOB (cdrecord), &device);
946
dev_str = g_strdup_printf ("dev=%s", device);
947
g_ptr_array_add (argv, dev_str);
950
brasero_job_get_flags (BRASERO_JOB (cdrecord), &flags);
951
if (flags & BRASERO_BURN_FLAG_DUMMY)
952
g_ptr_array_add (argv, g_strdup ("-dummy"));
954
if (flags & BRASERO_BURN_FLAG_NOGRACE)
955
g_ptr_array_add (argv, g_strdup ("gracetime=0"));
957
if (action == BRASERO_JOB_ACTION_RECORD)
958
result = brasero_cdrecord_set_argv_record (cdrecord, argv, error);
959
else if (action == BRASERO_JOB_ACTION_ERASE)
960
result = brasero_cdrecord_set_argv_blank (cdrecord, argv);
962
BRASERO_JOB_NOT_SUPPORTED (cdrecord);
967
static BraseroBurnResult
968
brasero_cdrecord_post (BraseroJob *job)
970
BraseroCDRecordPrivate *priv;
973
priv = BRASERO_CD_RECORD_PRIVATE (job);
974
for (iter = priv->infs; iter; iter = iter->next) {
982
g_slist_free (priv->infs);
985
return brasero_job_finished_session (job);
989
brasero_cdrecord_class_init (BraseroCDRecordClass *klass)
991
GObjectClass *object_class = G_OBJECT_CLASS (klass);
992
BraseroProcessClass *process_class = BRASERO_PROCESS_CLASS (klass);
994
g_type_class_add_private (klass, sizeof (BraseroCDRecordPrivate));
996
parent_class = g_type_class_peek_parent (klass);
997
object_class->finalize = brasero_cdrecord_finalize;
999
process_class->stderr_func = brasero_cdrecord_stderr_read;
1000
process_class->stdout_func = brasero_cdrecord_stdout_read;
1001
process_class->set_argv = brasero_cdrecord_set_argv;
1002
process_class->post = brasero_cdrecord_post;
1006
brasero_cdrecord_init (BraseroCDRecord *obj)
1008
GConfClient *client;
1009
BraseroCDRecordPrivate *priv;
1011
/* load our "configuration" */
1012
priv = BRASERO_CD_RECORD_PRIVATE (obj);
1014
client = gconf_client_get_default ();
1015
priv->immediate = gconf_client_get_bool (client,
1016
GCONF_KEY_IMMEDIATE_FLAG,
1018
priv->minbuf = gconf_client_get_int (client,
1019
GCONF_KEY_MINBUF_VALUE,
1021
if (priv->minbuf > 95 || priv->minbuf < 25)
1024
g_object_unref (client);
1028
brasero_cdrecord_finalize (GObject *object)
1030
BraseroCDRecordPrivate *priv;
1033
priv = BRASERO_CD_RECORD_PRIVATE (object);
1035
for (iter = priv->infs; iter; iter = iter->next) {
1043
g_slist_free (priv->infs);
1046
G_OBJECT_CLASS (parent_class)->finalize (object);
1049
static BraseroBurnResult
1050
brasero_cdrecord_export_caps (BraseroPlugin *plugin, gchar **error)
1052
BraseroPluginConfOption *immed, *minbuf;
1053
const BraseroMedia media = BRASERO_MEDIUM_CD|
1054
BRASERO_MEDIUM_WRITABLE|
1055
BRASERO_MEDIUM_REWRITABLE|
1056
BRASERO_MEDIUM_BLANK|
1057
BRASERO_MEDIUM_APPENDABLE|
1058
BRASERO_MEDIUM_HAS_AUDIO|
1059
BRASERO_MEDIUM_HAS_DATA;
1060
const BraseroMedia dvd_media = BRASERO_MEDIUM_DVD|
1061
BRASERO_MEDIUM_PLUS|
1062
BRASERO_MEDIUM_SEQUENTIAL|
1063
BRASERO_MEDIUM_WRITABLE|
1064
BRASERO_MEDIUM_REWRITABLE|
1065
BRASERO_MEDIUM_BLANK|
1066
BRASERO_MEDIUM_UNFORMATTED|
1067
BRASERO_MEDIUM_APPENDABLE|
1068
BRASERO_MEDIUM_HAS_DATA;
1069
const BraseroMedia media_rw = BRASERO_MEDIUM_CD|
1070
BRASERO_MEDIUM_REWRITABLE|
1071
BRASERO_MEDIUM_APPENDABLE|
1072
BRASERO_MEDIUM_CLOSED|
1073
BRASERO_MEDIUM_HAS_AUDIO|
1074
BRASERO_MEDIUM_HAS_DATA|
1075
BRASERO_MEDIUM_BLANK;
1076
BraseroBurnResult result;
1080
/* NOTE: it seems that cdrecord can burn cue files on the fly */
1081
brasero_plugin_define (plugin,
1083
_("Use cdrecord to burn CDs and DVDs"),
1084
"Philippe Rouquier",
1087
/* First see if this plugin can be used */
1088
result = brasero_process_check_path ("cdrecord", error);
1089
if (result != BRASERO_BURN_OK)
1093
input = brasero_caps_image_new (BRASERO_PLUGIN_IO_ACCEPT_PIPE|
1094
BRASERO_PLUGIN_IO_ACCEPT_FILE,
1095
BRASERO_IMAGE_FORMAT_BIN);
1097
/* cdrecord can burn all DVDs (except restricted) when it's ISOs */
1098
output = brasero_caps_disc_new (dvd_media);
1099
brasero_plugin_link_caps (plugin, output, input);
1100
g_slist_free (output);
1103
output = brasero_caps_disc_new (media);
1104
brasero_plugin_link_caps (plugin, output, input);
1105
g_slist_free (input);
1107
input = brasero_caps_audio_new (BRASERO_PLUGIN_IO_ACCEPT_PIPE|
1108
BRASERO_PLUGIN_IO_ACCEPT_FILE,
1109
BRASERO_AUDIO_FORMAT_RAW|
1110
BRASERO_AUDIO_FORMAT_44100|
1111
BRASERO_METADATA_INFO);
1113
brasero_plugin_link_caps (plugin, output, input);
1114
g_slist_free (input);
1116
input = brasero_caps_audio_new (BRASERO_PLUGIN_IO_ACCEPT_PIPE|
1117
BRASERO_PLUGIN_IO_ACCEPT_FILE,
1118
BRASERO_AUDIO_FORMAT_RAW|
1119
BRASERO_AUDIO_FORMAT_44100);
1121
brasero_plugin_link_caps (plugin, output, input);
1122
g_slist_free (output);
1123
g_slist_free (input);
1125
/* for CLONE and CUE type images, we only want blank CD-R(W) */
1126
output = brasero_caps_disc_new (BRASERO_MEDIUM_CD|
1127
BRASERO_MEDIUM_WRITABLE|
1128
BRASERO_MEDIUM_REWRITABLE|
1129
BRASERO_MEDIUM_BLANK);
1131
input = brasero_caps_image_new (BRASERO_PLUGIN_IO_ACCEPT_FILE,
1132
BRASERO_IMAGE_FORMAT_CUE|
1133
BRASERO_IMAGE_FORMAT_CLONE);
1135
brasero_plugin_link_caps (plugin, output, input);
1136
g_slist_free (output);
1137
g_slist_free (input);
1139
/* Blank CD(R)W : don't use standard flags cdrecord fails consistently
1140
* to write a first track of a multisession disc with DAO mode. */
1141
brasero_plugin_set_flags (plugin,
1143
BRASERO_MEDIUM_WRITABLE|
1144
BRASERO_MEDIUM_REWRITABLE|
1145
BRASERO_MEDIUM_BLANK,
1146
BRASERO_BURN_FLAG_DAO|
1147
BRASERO_BURN_FLAG_BURNPROOF|
1148
BRASERO_BURN_FLAG_OVERBURN|
1149
BRASERO_BURN_FLAG_DUMMY|
1150
BRASERO_BURN_FLAG_NOGRACE,
1151
BRASERO_BURN_FLAG_NONE);
1153
brasero_plugin_set_flags (plugin,
1155
BRASERO_MEDIUM_WRITABLE|
1156
BRASERO_MEDIUM_REWRITABLE|
1157
BRASERO_MEDIUM_BLANK,
1158
BRASERO_BURN_FLAG_MULTI|
1159
BRASERO_BURN_FLAG_BURNPROOF|
1160
BRASERO_BURN_FLAG_OVERBURN|
1161
BRASERO_BURN_FLAG_DUMMY|
1162
BRASERO_BURN_FLAG_NOGRACE,
1163
BRASERO_BURN_FLAG_NONE);
1165
/* Apart from DAO it also supports RAW mode to burn CLONE images. This
1166
* is a special mode for which there isn't any DUMMY burn possible */
1167
brasero_plugin_set_flags (plugin,
1169
BRASERO_MEDIUM_WRITABLE|
1170
BRASERO_MEDIUM_REWRITABLE|
1171
BRASERO_MEDIUM_BLANK,
1172
BRASERO_BURN_FLAG_RAW|
1173
BRASERO_BURN_FLAG_BURNPROOF|
1174
BRASERO_BURN_FLAG_OVERBURN|
1175
BRASERO_BURN_FLAG_NOGRACE,
1176
BRASERO_BURN_FLAG_NONE);
1178
/* This is a CDR with data data can be merged or at least appended */
1179
brasero_plugin_set_flags (plugin,
1181
BRASERO_MEDIUM_WRITABLE|
1182
BRASERO_MEDIUM_APPENDABLE|
1183
BRASERO_MEDIUM_HAS_AUDIO|
1184
BRASERO_MEDIUM_HAS_DATA,
1185
BRASERO_BURN_FLAG_APPEND|
1186
BRASERO_BURN_FLAG_MERGE|
1187
BRASERO_BURN_FLAG_BURNPROOF|
1188
BRASERO_BURN_FLAG_OVERBURN|
1189
BRASERO_BURN_FLAG_MULTI|
1190
BRASERO_BURN_FLAG_DUMMY|
1191
BRASERO_BURN_FLAG_NOGRACE,
1192
BRASERO_BURN_FLAG_APPEND);
1194
/* It is a CDRW we want the CD to be either blanked before or appended
1195
* that's why we set MERGE as compulsory. That way if the CD is not
1196
* MERGED we force the blank before writing to avoid appending sessions
1197
* endlessly until there is no free space. */
1198
brasero_plugin_set_flags (plugin,
1200
BRASERO_MEDIUM_REWRITABLE|
1201
BRASERO_MEDIUM_APPENDABLE|
1202
BRASERO_MEDIUM_HAS_AUDIO|
1203
BRASERO_MEDIUM_HAS_DATA,
1204
BRASERO_BURN_FLAG_APPEND|
1205
BRASERO_BURN_FLAG_MERGE|
1206
BRASERO_BURN_FLAG_BURNPROOF|
1207
BRASERO_BURN_FLAG_OVERBURN|
1208
BRASERO_BURN_FLAG_MULTI|
1209
BRASERO_BURN_FLAG_DUMMY|
1210
BRASERO_BURN_FLAG_NOGRACE,
1211
BRASERO_BURN_FLAG_MERGE);
1213
/* DVD-RW cdrecord capabilites are limited to blank media.
1214
* It should not start a multisession disc. */
1215
brasero_plugin_set_flags (plugin,
1217
BRASERO_MEDIUM_SEQUENTIAL|
1218
BRASERO_MEDIUM_WRITABLE|
1219
BRASERO_MEDIUM_REWRITABLE|
1220
BRASERO_MEDIUM_BLANK,
1221
BRASERO_BURN_FLAG_DAO|
1222
BRASERO_BURN_FLAG_BURNPROOF|
1223
BRASERO_BURN_FLAG_OVERBURN|
1224
BRASERO_BURN_FLAG_DUMMY|
1225
BRASERO_BURN_FLAG_NOGRACE,
1226
BRASERO_BURN_FLAG_NONE);
1228
/* DVD+W cdrecord capabilities are limited to blank media */
1229
brasero_plugin_set_flags (plugin,
1230
BRASERO_MEDIUM_DVDR_PLUS|
1231
BRASERO_MEDIUM_BLANK,
1232
BRASERO_BURN_FLAG_DAO|
1233
BRASERO_BURN_FLAG_BURNPROOF|
1234
BRASERO_BURN_FLAG_OVERBURN|
1235
BRASERO_BURN_FLAG_NOGRACE,
1236
BRASERO_BURN_FLAG_NONE);
1238
/* for DVD+RW cdrecord capabilities are limited no MERGE */
1239
brasero_plugin_set_flags (plugin,
1240
BRASERO_MEDIUM_DVDRW_PLUS|
1241
BRASERO_MEDIUM_UNFORMATTED|
1242
BRASERO_MEDIUM_BLANK,
1243
BRASERO_BURN_FLAG_OVERBURN|
1244
BRASERO_BURN_FLAG_NOGRACE,
1245
BRASERO_BURN_FLAG_NONE);
1247
brasero_plugin_set_flags (plugin,
1248
BRASERO_MEDIUM_DVDRW_PLUS|
1249
BRASERO_MEDIUM_APPENDABLE|
1250
BRASERO_MEDIUM_CLOSED|
1251
BRASERO_MEDIUM_HAS_DATA,
1252
BRASERO_BURN_FLAG_OVERBURN|
1253
BRASERO_BURN_FLAG_NOGRACE,
1254
BRASERO_BURN_FLAG_NONE);
1256
/* blanking/formatting caps and flags for +/sequential RW
1257
* NOTE: restricted overwrite DVD-RW can't be formatted.
1258
* moreover DVD+RW are formatted while DVD-RW sequential are blanked.
1260
output = brasero_caps_disc_new (BRASERO_MEDIUM_DVD|
1261
BRASERO_MEDIUM_PLUS|
1262
BRASERO_MEDIUM_REWRITABLE|
1263
BRASERO_MEDIUM_APPENDABLE|
1264
BRASERO_MEDIUM_SEQUENTIAL|
1265
BRASERO_MEDIUM_CLOSED|
1266
BRASERO_MEDIUM_HAS_DATA|
1267
BRASERO_MEDIUM_UNFORMATTED|
1268
BRASERO_MEDIUM_BLANK);
1269
brasero_plugin_blank_caps (plugin, output);
1270
g_slist_free (output);
1272
brasero_plugin_set_blank_flags (plugin,
1273
BRASERO_MEDIUM_DVDRW |
1274
BRASERO_MEDIUM_BLANK|
1275
BRASERO_MEDIUM_CLOSED |
1276
BRASERO_MEDIUM_APPENDABLE|
1277
BRASERO_MEDIUM_HAS_DATA|
1278
BRASERO_MEDIUM_UNFORMATTED,
1279
BRASERO_BURN_FLAG_NOGRACE|
1280
BRASERO_BURN_FLAG_FAST_BLANK,
1281
BRASERO_BURN_FLAG_NONE);
1282
/* again DVD+RW don't support dummy */
1283
brasero_plugin_set_blank_flags (plugin,
1284
BRASERO_MEDIUM_DVDRW_PLUS|
1285
BRASERO_MEDIUM_APPENDABLE|
1286
BRASERO_MEDIUM_HAS_DATA|
1287
BRASERO_MEDIUM_UNFORMATTED|
1288
BRASERO_MEDIUM_BLANK|
1289
BRASERO_MEDIUM_CLOSED,
1290
BRASERO_BURN_FLAG_NOGRACE,
1291
BRASERO_BURN_FLAG_NONE);
1293
/* for blanking (CDRWs) */
1294
output = brasero_caps_disc_new (media_rw);
1295
brasero_plugin_blank_caps (plugin, output);
1296
g_slist_free (output);
1298
brasero_plugin_set_blank_flags (plugin,
1300
BRASERO_BURN_FLAG_NOGRACE|
1301
BRASERO_BURN_FLAG_FAST_BLANK,
1302
BRASERO_BURN_FLAG_NONE);
1304
/* add some configure options */
1305
immed = brasero_plugin_conf_option_new (GCONF_KEY_IMMEDIATE_FLAG,
1306
_("Enable \"-immed\" flag (see cdrecord manual)"),
1307
BRASERO_PLUGIN_OPTION_BOOL);
1308
minbuf = brasero_plugin_conf_option_new (GCONF_KEY_MINBUF_VALUE,
1309
_("Minimum drive buffer fill ratio (in %%)(see cdrecord manual):"),
1310
BRASERO_PLUGIN_OPTION_INT);
1311
brasero_plugin_conf_option_int_set_range (minbuf, 25, 95);
1313
brasero_plugin_conf_option_bool_add_suboption (immed, minbuf);
1314
brasero_plugin_add_conf_option (plugin, immed);
1316
brasero_plugin_register_group (plugin, _(CDRTOOLS_DESCRIPTION));
1318
return BRASERO_BURN_OK;