1
/***************************************************************************
4
* dim jan 22 15:38:18 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.
37
#include <glib-object.h>
38
#include <glib/gi18n-lib.h>
39
#include <glib/gstdio.h>
42
#include <gconf/gconf-client.h>
44
#include "burn-cdrdao-common.h"
45
#include "burn-cdrdao.h"
46
#include "burn-basics.h"
47
#include "burn-plugin.h"
49
#include "burn-process.h"
50
#include "brasero-drive.h"
51
#include "brasero-medium.h"
53
BRASERO_PLUGIN_BOILERPLATE (BraseroCdrdao, brasero_cdrdao, BRASERO_TYPE_PROCESS, BraseroProcess);
55
struct _BraseroCdrdaoPrivate {
58
typedef struct _BraseroCdrdaoPrivate BraseroCdrdaoPrivate;
59
#define BRASERO_CDRDAO_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_CDRDAO, BraseroCdrdaoPrivate))
61
static GObjectClass *parent_class = NULL;
63
#define GCONF_KEY_RAW_FLAG "/apps/brasero/config/raw_flag"
66
brasero_cdrdao_read_stderr_image (BraseroCdrdao *cdrdao, const gchar *line)
68
int min, sec, sub, s1;
70
if (sscanf (line, "%d:%d:%d", &min, &sec, &sub) == 3) {
71
guint64 secs = min * 60 + sec;
73
brasero_job_set_written_track (BRASERO_JOB (cdrdao), secs * 75 * 2352);
75
brasero_job_start_progress (BRASERO_JOB (cdrdao), FALSE);
77
else if (sscanf (line, "Leadout %*s %*d %d:%d:%*d(%i)", &min, &sec, &s1) == 3) {
78
BraseroJobAction action;
80
brasero_job_get_action (BRASERO_JOB (cdrdao), &action);
81
if (action == BRASERO_JOB_ACTION_SIZE) {
82
/* get the number of sectors. As we added -raw sector = 2352 bytes */
83
brasero_job_set_output_size_for_current_track (BRASERO_JOB (cdrdao), s1, (gint64) s1 * 2352ULL);
84
brasero_job_finished_session (BRASERO_JOB (cdrdao));
87
else if (strstr (line, "Copying audio tracks")) {
88
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
89
BRASERO_BURN_ACTION_DRIVE_COPY,
90
_("Copying audio track"),
93
else if (strstr (line, "Copying data track")) {
94
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
95
BRASERO_BURN_ACTION_DRIVE_COPY,
96
_("Copying data track"),
106
brasero_cdrdao_read_stderr_record (BraseroCdrdao *cdrdao, const gchar *line)
108
int fifo, track, min, sec;
109
guint written, total;
111
if (sscanf (line, "Wrote %u of %u (Buffers %d%% %*s", &written, &total, &fifo) >= 2) {
112
brasero_job_set_dangerous (BRASERO_JOB (cdrdao), TRUE);
114
brasero_job_set_written_session (BRASERO_JOB (cdrdao), written * 1048576);
115
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
116
BRASERO_BURN_ACTION_RECORDING,
120
brasero_job_start_progress (BRASERO_JOB (cdrdao), FALSE);
122
else if (sscanf (line, "Wrote %*s blocks. Buffer fill min") == 1) {
123
/* this is for fixating phase */
124
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
125
BRASERO_BURN_ACTION_FIXATING,
129
else if (sscanf (line, "Analyzing track %d %*s start %d:%d:%*d, length %*d:%*d:%*d", &track, &min, &sec) == 3) {
132
string = g_strdup_printf (_("Analysing track %02i"), track);
133
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
134
BRASERO_BURN_ACTION_ANALYSING,
139
else if (sscanf (line, "%d:%d:%*d", &min, &sec) == 2) {
141
guint64 secs = min * 60 + sec;
144
brasero_job_start_progress (BRASERO_JOB (cdrdao), FALSE);
146
written = secs * 75 * 2352;
147
brasero_job_set_written_session (BRASERO_JOB (cdrdao), written);
149
else if (strstr (line, "Writing track")) {
150
brasero_job_set_dangerous (BRASERO_JOB (cdrdao), TRUE);
152
else if (strstr (line, "Writing finished successfully")
153
|| strstr (line, "On-the-fly CD copying finished successfully")) {
154
brasero_job_set_dangerous (BRASERO_JOB (cdrdao), FALSE);
156
else if (strstr (line, "Blanking disk...")) {
157
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
158
BRASERO_BURN_ACTION_BLANKING,
161
brasero_job_start_progress (BRASERO_JOB (cdrdao), FALSE);
162
brasero_job_set_dangerous (BRASERO_JOB (cdrdao), TRUE);
166
gchar *cuepath = NULL;
167
BraseroTrack *track = NULL;
168
BraseroJobAction action;
170
/* Try to catch error could not find cue file */
172
/* Track could be NULL here if we're simply blanking a medium */
173
brasero_job_get_action (BRASERO_JOB (cdrdao), &action);
174
if (action == BRASERO_JOB_ACTION_ERASE)
177
brasero_job_get_current_track (BRASERO_JOB (cdrdao), &track);
181
cuepath = brasero_track_get_toc_source (track, FALSE);
186
if (!strstr (line, cuepath)
187
&& !strstr (line, "ERROR: Could not find input file")) {
192
name = g_path_get_basename (cuepath);
195
brasero_job_error (BRASERO_JOB (cdrdao),
196
g_error_new (BRASERO_BURN_ERROR,
197
BRASERO_BURN_ERROR_FILE_NOT_FOUND,
198
/* Translators: %s is a filename */
199
_("\"%s\" could not be found"),
207
static BraseroBurnResult
208
brasero_cdrdao_read_stderr (BraseroProcess *process, const gchar *line)
210
BraseroCdrdao *cdrdao;
211
gboolean result = FALSE;
212
BraseroJobAction action;
214
cdrdao = BRASERO_CDRDAO (process);
216
brasero_job_get_action (BRASERO_JOB (cdrdao), &action);
217
if (action == BRASERO_JOB_ACTION_RECORD
218
|| action == BRASERO_JOB_ACTION_ERASE)
219
result = brasero_cdrdao_read_stderr_record (cdrdao, line);
220
else if (action == BRASERO_JOB_ACTION_IMAGE
221
|| action == BRASERO_JOB_ACTION_SIZE)
222
result = brasero_cdrdao_read_stderr_image (cdrdao, line);
225
return BRASERO_BURN_OK;
227
if (strstr (line, "Cannot setup device")) {
228
brasero_job_error (BRASERO_JOB (cdrdao),
229
g_error_new (BRASERO_BURN_ERROR,
230
BRASERO_BURN_ERROR_DRIVE_BUSY,
231
_("The drive is busy")));
233
else if (strstr (line, "Illegal command")) {
234
brasero_job_error (BRASERO_JOB (cdrdao),
235
g_error_new (BRASERO_BURN_ERROR,
236
BRASERO_BURN_ERROR_GENERAL,
237
_("Your version of cdrdao does not seem to be supported by libbrasero")));
239
else if (strstr (line, "Operation not permitted. Cannot send SCSI")) {
240
brasero_job_error (BRASERO_JOB (cdrdao),
241
g_error_new (BRASERO_BURN_ERROR,
242
BRASERO_BURN_ERROR_PERMISSION,
243
_("You do not have the required permissions to use this drive")));
246
return BRASERO_BURN_OK;
250
brasero_cdrdao_set_argv_device (BraseroCdrdao *cdrdao,
253
gchar *device = NULL;
255
g_ptr_array_add (argv, g_strdup ("--device"));
257
#ifdef HAVE_CAM_LIB_H
258
/* FreeBSD like that better */
259
brasero_job_get_bus_target_lun (BRASERO_JOB (cdrdao), &device);
261
brasero_job_get_device (BRASERO_JOB (cdrdao), &device);
264
g_ptr_array_add (argv, device);
268
brasero_cdrdao_set_argv_common_rec (BraseroCdrdao *cdrdao,
271
BraseroBurnFlag flags;
275
brasero_job_get_flags (BRASERO_JOB (cdrdao), &flags);
276
if (flags & BRASERO_BURN_FLAG_DUMMY)
277
g_ptr_array_add (argv, g_strdup ("--simulate"));
279
g_ptr_array_add (argv, g_strdup ("--speed"));
281
brasero_job_get_speed (BRASERO_JOB (cdrdao), &speed);
282
speed_str = g_strdup_printf ("%d", speed);
283
g_ptr_array_add (argv, speed_str);
285
if (flags & BRASERO_BURN_FLAG_OVERBURN)
286
g_ptr_array_add (argv, g_strdup ("--overburn"));
287
if (flags & BRASERO_BURN_FLAG_MULTI)
288
g_ptr_array_add (argv, g_strdup ("--multi"));
292
brasero_cdrdao_set_argv_common (BraseroCdrdao *cdrdao,
295
BraseroBurnFlag flags;
297
brasero_job_get_flags (BRASERO_JOB (cdrdao), &flags);
299
/* cdrdao manual says it is a similar option to gracetime */
300
if (flags & BRASERO_BURN_FLAG_NOGRACE)
301
g_ptr_array_add (argv, g_strdup ("-n"));
303
g_ptr_array_add (argv, g_strdup ("-v"));
304
g_ptr_array_add (argv, g_strdup ("2"));
307
static BraseroBurnResult
308
brasero_cdrdao_set_argv_record (BraseroCdrdao *cdrdao,
311
BraseroTrackType type;
312
BraseroCdrdaoPrivate *priv;
314
priv = BRASERO_CDRDAO_PRIVATE (cdrdao);
316
g_ptr_array_add (argv, g_strdup ("cdrdao"));
318
brasero_job_get_input_type (BRASERO_JOB (cdrdao), &type);
319
if (type.type == BRASERO_TRACK_TYPE_DISC) {
321
BraseroBurnFlag flags;
324
g_ptr_array_add (argv, g_strdup ("copy"));
325
brasero_cdrdao_set_argv_device (cdrdao, argv);
326
brasero_cdrdao_set_argv_common (cdrdao, argv);
327
brasero_cdrdao_set_argv_common_rec (cdrdao, argv);
329
brasero_job_get_flags (BRASERO_JOB (cdrdao), &flags);
330
if (flags & BRASERO_BURN_FLAG_NO_TMP_FILES)
331
g_ptr_array_add (argv, g_strdup ("--on-the-fly"));
334
g_ptr_array_add (argv, g_strdup ("--driver generic-mmc-raw"));
336
g_ptr_array_add (argv, g_strdup ("--source-device"));
338
brasero_job_get_current_track (BRASERO_JOB (cdrdao), &track);
339
drive = brasero_track_get_drive_source (track);
341
#ifdef HAVE_CAM_LIB_H
342
/* FreeBSD like that better */
343
g_ptr_array_add (argv, brasero_drive_get_bus_target_lun_string (drive));
345
g_ptr_array_add (argv, g_strdup (brasero_drive_get_device (drive)));
349
else if (type.type == BRASERO_TRACK_TYPE_IMAGE) {
353
brasero_job_get_current_track (BRASERO_JOB (cdrdao), &track);
355
if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_CUE) {
358
cuepath = brasero_track_get_toc_source (track, FALSE);
359
parent = g_path_get_dirname (cuepath);
360
brasero_process_set_working_directory (BRASERO_PROCESS (cdrdao), parent);
363
else if (type.subtype.img_format == BRASERO_IMAGE_FORMAT_CDRDAO)
364
cuepath = brasero_track_get_toc_source (track, FALSE);
366
BRASERO_JOB_NOT_SUPPORTED (cdrdao);
369
BRASERO_JOB_NOT_READY (cdrdao);
371
g_ptr_array_add (argv, g_strdup ("write"));
373
brasero_cdrdao_set_argv_device (cdrdao, argv);
374
brasero_cdrdao_set_argv_common (cdrdao, argv);
375
brasero_cdrdao_set_argv_common_rec (cdrdao, argv);
377
g_ptr_array_add (argv, cuepath);
380
BRASERO_JOB_NOT_SUPPORTED (cdrdao);
382
brasero_job_set_use_average_rate (BRASERO_JOB (cdrdao), TRUE);
383
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
384
BRASERO_BURN_ACTION_START_RECORDING,
387
return BRASERO_BURN_OK;
390
static BraseroBurnResult
391
brasero_cdrdao_set_argv_blank (BraseroCdrdao *cdrdao,
394
BraseroBurnFlag flags;
396
g_ptr_array_add (argv, g_strdup ("cdrdao"));
397
g_ptr_array_add (argv, g_strdup ("blank"));
399
brasero_cdrdao_set_argv_device (cdrdao, argv);
400
brasero_cdrdao_set_argv_common (cdrdao, argv);
402
g_ptr_array_add (argv, g_strdup ("--blank-mode"));
403
brasero_job_get_flags (BRASERO_JOB (cdrdao), &flags);
404
if (!(flags & BRASERO_BURN_FLAG_FAST_BLANK))
405
g_ptr_array_add (argv, g_strdup ("full"));
407
g_ptr_array_add (argv, g_strdup ("minimal"));
409
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
410
BRASERO_BURN_ACTION_BLANKING,
414
return BRASERO_BURN_OK;
417
static BraseroBurnResult
418
brasero_cdrdao_set_argv_image (BraseroCdrdao *cdrdao,
422
gchar *image = NULL, *toc = NULL;
423
BraseroBurnResult result;
425
BraseroJobAction action;
426
BraseroTrackType output;
429
g_ptr_array_add (argv, g_strdup ("cdrdao"));
430
g_ptr_array_add (argv, g_strdup ("read-cd"));
431
g_ptr_array_add (argv, g_strdup ("--device"));
433
brasero_job_get_current_track (BRASERO_JOB (cdrdao), &track);
434
drive = brasero_track_get_drive_source (track);
436
#ifdef HAVE_CAM_LIB_H
437
/* FreeBSD like that better */
438
g_ptr_array_add (argv, brasero_drive_get_bus_target_lun_string (drive));
440
g_ptr_array_add (argv, g_strdup (brasero_drive_get_device (drive)));
443
g_ptr_array_add (argv, g_strdup ("--read-raw"));
445
/* This is done so that if a cue file is required we first generate
446
* a temporary toc file that will be later converted to a cue file.
447
* The datafile is written where it should be from the start. */
448
brasero_job_get_output_type (BRASERO_JOB (cdrdao), &output);
449
if (output.subtype.img_format == BRASERO_IMAGE_FORMAT_CDRDAO) {
450
result = brasero_job_get_image_output (BRASERO_JOB (cdrdao),
453
if (result != BRASERO_BURN_OK)
457
result = brasero_job_get_image_output (BRASERO_JOB (cdrdao),
460
if (result != BRASERO_BURN_OK)
463
result = brasero_job_get_tmp_file (BRASERO_JOB (cdrdao),
467
if (result != BRASERO_BURN_OK)
471
/* it's safe to remove them: session/task make sure they don't exist
472
* when there is the proper flag whether it be tmp or real output. */
478
brasero_job_get_action (BRASERO_JOB (cdrdao), &action);
479
if (action == BRASERO_JOB_ACTION_SIZE) {
480
brasero_job_set_current_action (BRASERO_JOB (cdrdao),
481
BRASERO_BURN_ACTION_GETTING_SIZE,
484
brasero_job_start_progress (BRASERO_JOB (cdrdao), FALSE);
487
g_ptr_array_add (argv, g_strdup ("--datafile"));
488
g_ptr_array_add (argv, image);
490
g_ptr_array_add (argv, g_strdup ("-v"));
491
g_ptr_array_add (argv, g_strdup ("2"));
493
g_ptr_array_add (argv, toc);
495
brasero_job_set_use_average_rate (BRASERO_JOB (cdrdao), TRUE);
497
return BRASERO_BURN_OK;
500
static BraseroBurnResult
501
brasero_cdrdao_set_argv (BraseroProcess *process,
505
BraseroCdrdao *cdrdao;
506
BraseroJobAction action;
508
cdrdao = BRASERO_CDRDAO (process);
510
/* sets the first argv */
511
brasero_job_get_action (BRASERO_JOB (cdrdao), &action);
512
if (action == BRASERO_JOB_ACTION_RECORD)
513
return brasero_cdrdao_set_argv_record (cdrdao, argv);
514
else if (action == BRASERO_JOB_ACTION_ERASE)
515
return brasero_cdrdao_set_argv_blank (cdrdao, argv);
516
else if (action == BRASERO_JOB_ACTION_IMAGE)
517
return brasero_cdrdao_set_argv_image (cdrdao, argv, error);
518
else if (action == BRASERO_JOB_ACTION_SIZE) {
519
BraseroTrackDataType input;
522
brasero_job_get_current_track (BRASERO_JOB (cdrdao), &track);
523
input = brasero_track_get_type (track, NULL);
524
if (input == BRASERO_TRACK_TYPE_DISC) {
527
brasero_track_get_disc_data_size (track, §ors, NULL);
529
/* cdrdao won't get a track size under 300 sectors */
533
brasero_job_set_output_size_for_current_track (BRASERO_JOB (cdrdao),
538
return BRASERO_BURN_NOT_SUPPORTED;
540
return BRASERO_BURN_NOT_RUNNING;
543
BRASERO_JOB_NOT_SUPPORTED (cdrdao);
547
brasero_cdrdao_class_init (BraseroCdrdaoClass *klass)
549
GObjectClass *object_class = G_OBJECT_CLASS (klass);
550
BraseroProcessClass *process_class = BRASERO_PROCESS_CLASS (klass);
552
g_type_class_add_private (klass, sizeof (BraseroCdrdaoPrivate));
554
parent_class = g_type_class_peek_parent(klass);
555
object_class->finalize = brasero_cdrdao_finalize;
557
process_class->stderr_func = brasero_cdrdao_read_stderr;
558
process_class->set_argv = brasero_cdrdao_set_argv;
559
process_class->post = brasero_job_finished_session;
563
brasero_cdrdao_init (BraseroCdrdao *obj)
566
BraseroCdrdaoPrivate *priv;
568
/* load our "configuration" */
569
priv = BRASERO_CDRDAO_PRIVATE (obj);
571
client = gconf_client_get_default ();
572
priv->use_raw = gconf_client_get_bool (client,
576
g_object_unref (client);
580
brasero_cdrdao_finalize (GObject *object)
582
G_OBJECT_CLASS (parent_class)->finalize (object);
585
static BraseroBurnResult
586
brasero_cdrdao_export_caps (BraseroPlugin *plugin, gchar **error)
590
BraseroBurnResult result;
591
BraseroPluginConfOption *use_raw;
592
const BraseroMedia media_w = BRASERO_MEDIUM_CD|
593
BRASERO_MEDIUM_WRITABLE|
594
BRASERO_MEDIUM_REWRITABLE|
595
BRASERO_MEDIUM_BLANK;
596
const BraseroMedia media_rw = BRASERO_MEDIUM_CD|
597
BRASERO_MEDIUM_REWRITABLE|
598
BRASERO_MEDIUM_APPENDABLE|
599
BRASERO_MEDIUM_CLOSED|
600
BRASERO_MEDIUM_HAS_DATA|
601
BRASERO_MEDIUM_HAS_AUDIO|
602
BRASERO_MEDIUM_BLANK;
604
brasero_plugin_define (plugin,
606
_("Use cdrdao to copy and burn CDs"),
610
/* First see if this plugin can be used */
611
result = brasero_process_check_path ("cdrdao", error);
612
if (result != BRASERO_BURN_OK)
615
/* that's for cdrdao images: CDs only as input */
616
input = brasero_caps_disc_new (BRASERO_MEDIUM_CD|
618
BRASERO_MEDIUM_WRITABLE|
619
BRASERO_MEDIUM_REWRITABLE|
620
BRASERO_MEDIUM_APPENDABLE|
621
BRASERO_MEDIUM_CLOSED|
622
BRASERO_MEDIUM_HAS_AUDIO|
623
BRASERO_MEDIUM_HAS_DATA);
625
/* an image can be created ... */
626
output = brasero_caps_image_new (BRASERO_PLUGIN_IO_ACCEPT_FILE,
627
BRASERO_IMAGE_FORMAT_CDRDAO);
629
brasero_plugin_link_caps (plugin, output, input);
630
g_slist_free (output);
633
output = brasero_caps_disc_new (media_w);
634
brasero_plugin_link_caps (plugin, output, input);
635
g_slist_free (input);
637
/* cdrdao can also record these types of images to a disc */
638
input = brasero_caps_image_new (BRASERO_PLUGIN_IO_ACCEPT_FILE,
639
BRASERO_IMAGE_FORMAT_CDRDAO|
640
BRASERO_IMAGE_FORMAT_CUE);
642
brasero_plugin_link_caps (plugin, output, input);
643
g_slist_free (output);
644
g_slist_free (input);
646
/* cdrdao is used to burn images so it can't APPEND and the disc must
647
* have been blanked before (it can't overwrite)
648
* NOTE: BRASERO_MEDIUM_FILE is needed here because of restriction API
649
* when we output an image. */
650
brasero_plugin_set_flags (plugin,
653
BRASERO_BURN_FLAG_DAO|
654
BRASERO_BURN_FLAG_BURNPROOF|
655
BRASERO_BURN_FLAG_OVERBURN|
656
BRASERO_BURN_FLAG_DUMMY|
657
BRASERO_BURN_FLAG_NOGRACE,
658
BRASERO_BURN_FLAG_NONE);
660
/* cdrdao can also blank */
661
output = brasero_caps_disc_new (media_rw);
662
brasero_plugin_blank_caps (plugin, output);
663
g_slist_free (output);
665
brasero_plugin_set_blank_flags (plugin,
667
BRASERO_BURN_FLAG_NOGRACE|
668
BRASERO_BURN_FLAG_FAST_BLANK,
669
BRASERO_BURN_FLAG_NONE);
671
use_raw = brasero_plugin_conf_option_new (GCONF_KEY_RAW_FLAG,
672
_("Enable \"--driver generic-mmc-raw\" flag (see cdrdao manual)"),
673
BRASERO_PLUGIN_OPTION_BOOL);
675
brasero_plugin_add_conf_option (plugin, use_raw);
677
brasero_plugin_register_group (plugin, _(CDRDAO_DESCRIPTION));
678
return BRASERO_BURN_OK;