1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
4
* Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
6
* Libbrasero-burn is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* The Libbrasero-burn authors hereby grant permission for non-GPL compatible
12
* GStreamer plugins to be used and distributed together with GStreamer
13
* and Libbrasero-burn. This permission is above and beyond the permissions granted
14
* by the GPL license by which Libbrasero-burn is covered. If you modify this code
15
* you may extend this exception to your version of the code, but you are not
16
* obligated to do so. If you do not wish to do so, delete this exception
17
* statement from your version.
19
* Libbrasero-burn is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU Library General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to:
26
* The Free Software Foundation, Inc.,
27
* 51 Franklin Street, Fifth Floor
28
* Boston, MA 02110-1301, USA.
42
#include <glib-object.h>
43
#include <glib/gstdio.h>
44
#include <glib/gi18n-lib.h>
47
#include <libisofs/libisofs.h>
48
#include <libburn/libburn.h>
50
#include "burn-libburnia.h"
52
#include "brasero-units.h"
53
#include "brasero-plugin-registration.h"
54
#include "burn-libburn-common.h"
55
#include "brasero-track-data.h"
56
#include "brasero-track-image.h"
59
#define BRASERO_TYPE_LIBISOFS (brasero_libisofs_get_type ())
60
#define BRASERO_LIBISOFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), BRASERO_TYPE_LIBISOFS, BraseroLibisofs))
61
#define BRASERO_LIBISOFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), BRASERO_TYPE_LIBISOFS, BraseroLibisofsClass))
62
#define BRASERO_IS_LIBISOFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), BRASERO_TYPE_LIBISOFS))
63
#define BRASERO_IS_LIBISOFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), BRASERO_TYPE_LIBISOFS))
64
#define BRASERO_LIBISOFS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), BRASERO_TYPE_LIBISOFS, BraseroLibisofsClass))
66
BRASERO_PLUGIN_BOILERPLATE (BraseroLibisofs, brasero_libisofs, BRASERO_TYPE_JOB, BraseroJob);
68
struct _BraseroLibisofsPrivate {
69
struct burn_source *libburn_src;
71
/* that's for multisession */
72
BraseroLibburnCtx *ctx;
82
typedef struct _BraseroLibisofsPrivate BraseroLibisofsPrivate;
84
#define BRASERO_LIBISOFS_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_LIBISOFS, BraseroLibisofsPrivate))
86
static GObjectClass *parent_class = NULL;
89
brasero_libisofs_thread_finished (gpointer data)
91
BraseroLibisofs *self = data;
92
BraseroLibisofsPrivate *priv;
94
priv = BRASERO_LIBISOFS_PRIVATE (self);
102
brasero_job_error (BRASERO_JOB (self), error);
106
if (brasero_job_get_fd_out (BRASERO_JOB (self), NULL) != BRASERO_BURN_OK) {
107
BraseroTrackImage *track = NULL;
108
gchar *output = NULL;
111
/* Let's make a track */
112
track = brasero_track_image_new ();
113
brasero_job_get_image_output (BRASERO_JOB (self),
116
brasero_track_image_set_source (track,
119
BRASERO_IMAGE_FORMAT_BIN);
121
brasero_job_get_session_output_size (BRASERO_JOB (self), &blocks, NULL);
122
brasero_track_image_set_block_num (track, blocks);
124
brasero_job_add_track (BRASERO_JOB (self), BRASERO_TRACK (track));
125
g_object_unref (track);
128
brasero_job_finished_track (BRASERO_JOB (self));
132
static BraseroBurnResult
133
brasero_libisofs_write_sector_to_fd (BraseroLibisofs *self,
136
gint bytes_remaining)
138
gint bytes_written = 0;
139
BraseroLibisofsPrivate *priv;
141
priv = BRASERO_LIBISOFS_PRIVATE (self);
143
while (bytes_remaining) {
147
((gchar *) buffer) + bytes_written,
153
if (written != bytes_remaining) {
154
if (errno != EINTR && errno != EAGAIN) {
157
/* unrecoverable error */
158
priv->error = g_error_new (BRASERO_BURN_ERROR,
159
BRASERO_BURN_ERROR_GENERAL,
160
_("Data could not be written (%s)"),
162
return BRASERO_BURN_ERR;
169
bytes_remaining -= written;
170
bytes_written += written;
174
return BRASERO_BURN_OK;
178
brasero_libisofs_write_image_to_fd_thread (BraseroLibisofs *self)
180
const gint sector_size = 2048;
181
BraseroLibisofsPrivate *priv;
182
gint64 written_sectors = 0;
183
BraseroBurnResult result;
184
guchar buf [sector_size];
188
priv = BRASERO_LIBISOFS_PRIVATE (self);
190
brasero_job_set_nonblocking (BRASERO_JOB (self), NULL);
192
brasero_job_set_current_action (BRASERO_JOB (self),
193
BRASERO_BURN_ACTION_CREATING_IMAGE,
197
brasero_job_start_progress (BRASERO_JOB (self), FALSE);
198
brasero_job_get_fd_out (BRASERO_JOB (self), &fd);
200
BRASERO_JOB_LOG (self, "Writing to pipe");
201
read_bytes = priv->libburn_src->read_xt (priv->libburn_src, buf, sector_size);
202
while (priv->libburn_src->read_xt (priv->libburn_src, buf, sector_size) == sector_size) {
206
result = brasero_libisofs_write_sector_to_fd (self,
210
if (result != BRASERO_BURN_OK)
214
brasero_job_set_written_track (BRASERO_JOB (self), written_sectors << 11);
216
read_bytes = priv->libburn_src->read_xt (priv->libburn_src, buf, sector_size);
219
if (read_bytes == -1 && !priv->error)
220
priv->error = g_error_new (BRASERO_BURN_ERROR,
221
BRASERO_BURN_ERROR_GENERAL,
222
"%s", _("Volume could not be created"));
226
brasero_libisofs_write_image_to_file_thread (BraseroLibisofs *self)
228
const gint sector_size = 2048;
229
BraseroLibisofsPrivate *priv;
230
gint64 written_sectors = 0;
231
guchar buf [sector_size];
236
priv = BRASERO_LIBISOFS_PRIVATE (self);
238
brasero_job_get_image_output (BRASERO_JOB (self), &output, NULL);
239
file = fopen (output, "w");
244
priv->error = g_error_new_literal (BRASERO_BURN_ERROR,
245
BRASERO_BURN_ERROR_PERMISSION,
246
_("You do not have the required permission to write at this location"));
248
priv->error = g_error_new_literal (BRASERO_BURN_ERROR,
249
BRASERO_BURN_ERROR_GENERAL,
250
g_strerror (errnum));
254
BRASERO_JOB_LOG (self, "writing to file %s", output);
256
brasero_job_set_current_action (BRASERO_JOB (self),
257
BRASERO_BURN_ACTION_CREATING_IMAGE,
261
priv = BRASERO_LIBISOFS_PRIVATE (self);
262
brasero_job_start_progress (BRASERO_JOB (self), FALSE);
264
read_bytes = priv->libburn_src->read_xt (priv->libburn_src, buf, sector_size);
265
while (read_bytes == sector_size) {
269
if (fwrite (buf, 1, sector_size, file) != sector_size) {
272
priv->error = g_error_new (BRASERO_BURN_ERROR,
273
BRASERO_BURN_ERROR_GENERAL,
274
_("Data could not be written (%s)"),
283
brasero_job_set_written_track (BRASERO_JOB (self), written_sectors << 11);
285
read_bytes = priv->libburn_src->read_xt (priv->libburn_src, buf, sector_size);
288
if (read_bytes == -1 && !priv->error)
289
priv->error = g_error_new (BRASERO_BURN_ERROR,
290
BRASERO_BURN_ERROR_GENERAL,
291
_("Volume could not be created"));
298
brasero_libisofs_thread_started (gpointer data)
300
BraseroLibisofsPrivate *priv;
301
BraseroLibisofs *self;
303
self = BRASERO_LIBISOFS (data);
304
priv = BRASERO_LIBISOFS_PRIVATE (self);
306
BRASERO_JOB_LOG (self, "Entering thread");
307
if (brasero_job_get_fd_out (BRASERO_JOB (self), NULL) == BRASERO_BURN_OK)
308
brasero_libisofs_write_image_to_fd_thread (self);
310
brasero_libisofs_write_image_to_file_thread (self);
312
BRASERO_JOB_LOG (self, "Getting out thread");
315
g_mutex_lock (priv->mutex);
318
priv->thread_id = g_idle_add (brasero_libisofs_thread_finished, self);
321
g_cond_signal (priv->cond);
322
g_mutex_unlock (priv->mutex);
324
g_thread_exit (NULL);
329
static BraseroBurnResult
330
brasero_libisofs_create_image (BraseroLibisofs *self,
333
BraseroLibisofsPrivate *priv;
334
GError *thread_error = NULL;
336
priv = BRASERO_LIBISOFS_PRIVATE (self);
339
return BRASERO_BURN_RUNNING;
341
if (iso_init () < 0) {
344
BRASERO_BURN_ERROR_GENERAL,
345
_("libisofs could not be initialized."));
346
return BRASERO_BURN_ERR;
349
iso_set_msgs_severities ("NEVER", "ALL", "brasero (libisofs)");
351
g_mutex_lock (priv->mutex);
352
priv->thread = g_thread_create (brasero_libisofs_thread_started,
356
g_mutex_unlock (priv->mutex);
358
/* Reminder: this is not necessarily an error as the thread may have finished */
360
// return BRASERO_BURN_ERR;
363
g_propagate_error (error, thread_error);
364
return BRASERO_BURN_ERR;
367
return BRASERO_BURN_OK;
371
brasero_libisofs_create_volume_thread_finished (gpointer data)
373
BraseroLibisofs *self = data;
374
BraseroLibisofsPrivate *priv;
375
BraseroJobAction action;
377
priv = BRASERO_LIBISOFS_PRIVATE (self);
385
brasero_job_error (BRASERO_JOB (self), error);
389
brasero_job_get_action (BRASERO_JOB (self), &action);
390
if (action == BRASERO_JOB_ACTION_IMAGE) {
391
BraseroBurnResult result;
392
GError *error = NULL;
394
result = brasero_libisofs_create_image (self, &error);
396
brasero_job_error (BRASERO_JOB (self), error);
401
brasero_job_finished_track (BRASERO_JOB (self));
406
brasero_libisofs_sort_graft_points (gconstpointer a, gconstpointer b)
408
const BraseroGraftPt *graft_a, *graft_b;
414
/* we only want to know if:
415
* - a is a parent of b (a > b, retval < 0)
416
* - b is a parent of a (b > a, retval > 0). */
417
len_a = strlen (graft_a->path);
418
len_b = strlen (graft_b->path);
420
return len_a - len_b;
424
brasero_libisofs_import_read (IsoDataSource *src, uint32_t lba, uint8_t *buffer)
426
struct burn_drive *d;
430
d = (struct burn_drive*)src->data;
432
result = burn_read_data(d,
433
(off_t) lba * (off_t) 2048,
439
return -1; /* error */
445
brasero_libisofs_import_open (IsoDataSource *src)
451
brasero_libisofs_import_close (IsoDataSource *src)
457
brasero_libisofs_import_free (IsoDataSource *src)
460
static BraseroBurnResult
461
brasero_libisofs_import_last_session (BraseroLibisofs *self,
471
goffset session_block;
472
BraseroLibisofsPrivate *priv;
474
priv = BRASERO_LIBISOFS_PRIVATE (self);
476
priv->ctx = brasero_libburn_common_ctx_new (BRASERO_JOB (self), FALSE, error);
478
return BRASERO_BURN_ERR;
480
result = iso_read_opts_new (&opts, 0);
484
BRASERO_BURN_ERROR_GENERAL,
485
_("Read options could not be created"));
486
return BRASERO_BURN_ERR;
489
src = g_new0 (IsoDataSource, 1);
492
src->read_block = brasero_libisofs_import_read;
493
src->open = brasero_libisofs_import_open;
494
src->close = brasero_libisofs_import_close;
495
src->free_data = brasero_libisofs_import_free;
496
src->data = priv->ctx->drive;
498
brasero_job_get_last_session_address (BRASERO_JOB (self), &session_block);
499
iso_read_opts_set_start_block (opts, session_block);
502
result = iso_image_import (image, src, opts, NULL);
503
iso_data_source_unref (src);
504
iso_read_opts_free (opts);
506
/* release the drive */
508
/* This may not be a good idea ...*/
509
brasero_libburn_common_ctx_free (priv->ctx);
514
BRASERO_JOB_LOG (self, "Import failed 0x%x", result);
517
BRASERO_BURN_ERROR_IMAGE_LAST_SESSION,
518
_("Last session import failed"));
519
return BRASERO_BURN_ERR;
522
/* check is this is a DVD+RW */
523
brasero_job_get_next_writable_address (BRASERO_JOB (self), &start_block);
525
brasero_job_get_media (BRASERO_JOB (self), &media);
526
if (BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS)
527
|| BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_RESTRICTED)
528
|| BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS_DL)) {
529
/* This is specific to overwrite media; the start address is the
530
* size of all the previous data written */
531
BRASERO_JOB_LOG (self, "Growing image (start %i)", start_block);
534
/* set the start block for the multisession image */
535
iso_write_opts_set_ms_block (wopts, start_block);
536
iso_write_opts_set_appendable (wopts, 1);
538
iso_tree_set_replace_mode (image, ISO_REPLACE_ALWAYS);
539
return BRASERO_BURN_OK;
543
brasero_libisofs_create_volume_thread (gpointer data)
545
BraseroLibisofs *self = BRASERO_LIBISOFS (data);
546
BraseroLibisofsPrivate *priv;
547
BraseroTrack *track = NULL;
548
IsoWriteOpts *opts = NULL;
549
IsoImage *image = NULL;
550
BraseroBurnFlag flags;
551
GSList *grafts = NULL;
557
priv = BRASERO_LIBISOFS_PRIVATE (self);
559
if (priv->libburn_src) {
560
burn_source_free (priv->libburn_src);
561
priv->libburn_src = NULL;
564
BRASERO_JOB_LOG (self, "creating volume");
567
brasero_job_get_data_label (BRASERO_JOB (self), &label);
568
if (!iso_image_new (label, &image)) {
569
priv->error = g_error_new (BRASERO_BURN_ERROR,
570
BRASERO_BURN_ERROR_GENERAL, "%s",
571
_("Volume could not be created"));
576
iso_write_opts_new (&opts, 2);
577
iso_write_opts_set_relaxed_vol_atts(opts, 1);
579
brasero_job_get_flags (BRASERO_JOB (self), &flags);
580
if (flags & BRASERO_BURN_FLAG_MERGE) {
581
BraseroBurnResult result;
583
result = brasero_libisofs_import_last_session (self,
587
if (result != BRASERO_BURN_OK) {
592
else if (flags & BRASERO_BURN_FLAG_APPEND) {
595
brasero_job_get_next_writable_address (BRASERO_JOB (self), &start_block);
596
iso_write_opts_set_ms_block (opts, start_block);
599
/* set label but set it after merging so the
600
* new does not get replaced by the former */
601
publisher = g_strdup_printf ("Brasero-%i.%i.%i",
602
BRASERO_MAJOR_VERSION,
603
BRASERO_MINOR_VERSION,
607
iso_image_set_volume_id (image, label);
609
iso_image_set_publisher_id (image, publisher);
610
iso_image_set_data_preparer_id (image, g_get_real_name ());
615
brasero_job_start_progress (BRASERO_JOB (self), FALSE);
617
/* copy the list as we're going to reorder it */
618
brasero_job_get_current_track (BRASERO_JOB (self), &track);
619
grafts = brasero_track_data_get_grafts (BRASERO_TRACK_DATA (track));
620
grafts = g_slist_copy (grafts);
621
grafts = g_slist_sort (grafts, brasero_libisofs_sort_graft_points);
623
/* add global exclusions */
624
for (excluded = brasero_track_data_get_excluded_list (BRASERO_TRACK_DATA (track));
625
excluded; excluded = excluded->next) {
628
uri = excluded->data;
629
local = g_filename_from_uri (uri, NULL, NULL);
630
iso_tree_add_exclude (image, local);
634
for (iter = grafts; iter; iter = iter->next) {
635
BraseroGraftPt *graft;
636
gboolean is_directory;
646
BRASERO_JOB_LOG (self,
647
"Adding graft disc path = %s, URI = %s",
651
/* search for parent node.
652
* NOTE: because of mkisofs/genisoimage, we add a "/" at the end
653
* directories. So make sure there isn't one when getting the
654
* parent path or g_path_get_dirname () will return the same
656
if (g_str_has_suffix (graft->path, G_DIR_SEPARATOR_S)) {
659
/* remove trailing "/" */
660
tmp = g_strdup (graft->path);
661
tmp [strlen (tmp) - 1] = '\0';
662
path_parent = g_path_get_dirname (tmp);
663
path_name = g_path_get_basename (tmp);
669
path_parent = g_path_get_dirname (graft->path);
670
path_name = g_path_get_basename (graft->path);
671
is_directory = FALSE;
674
iso_tree_path_to_node (image, path_parent, &parent);
675
g_free (path_parent);
678
/* an error has occurred, possibly libisofs hasn't been
679
* able to find a parent for this node */
681
priv->error = g_error_new (BRASERO_BURN_ERROR,
682
BRASERO_BURN_ERROR_GENERAL,
683
/* Translators: %s is the path */
684
_("No parent could be found in the tree for the path \"%s\""),
689
BRASERO_JOB_LOG (self, "Found parent");
691
/* add the file/directory to the volume */
696
/* graft->uri can be a path or a URI */
697
if (graft->uri [0] == '/')
698
local_path = g_strdup (graft->uri);
699
else if (g_str_has_prefix (graft->uri, "file://"))
700
local_path = g_filename_from_uri (graft->uri, NULL, NULL);
705
priv->error = g_error_new (BRASERO_BURN_ERROR,
706
BRASERO_BURN_ERROR_FILE_NOT_LOCAL,
707
_("The file is not stored locally"));
712
/* see if the node exists with the same name among the
713
* children of the parent directory. If there is a
714
* sibling destroy it. */
716
iso_dir_get_children (ISO_DIR (parent), &sibling);
719
while (iso_dir_iter_next (sibling, &node) == 1) {
720
const gchar *iso_name;
722
/* check if it has the same name */
723
iso_name = iso_node_get_name (node);
724
if (iso_name && !strcmp (iso_name, path_name))
725
BRASERO_JOB_LOG (self,
726
"Found sibling for %s: removing %x",
728
iso_dir_iter_remove (sibling));
735
/* add directory node */
736
result = iso_tree_add_new_dir (ISO_DIR (parent), path_name, &directory);
738
BRASERO_JOB_LOG (self,
742
priv->error = g_error_new (BRASERO_BURN_ERROR,
743
BRASERO_BURN_ERROR_GENERAL,
744
_("libisofs reported an error while creating directory \"%s\""),
751
result = iso_tree_add_dir_rec (image, directory, local_path);
753
BRASERO_JOB_LOG (self,
757
priv->error = g_error_new (BRASERO_BURN_ERROR,
758
BRASERO_BURN_ERROR_GENERAL,
759
_("libisofs reported an error while adding contents to directory \"%s\" (%x)"),
770
err = iso_tree_add_new_node (image,
776
BRASERO_JOB_LOG (self,
780
priv->error = g_error_new (BRASERO_BURN_ERROR,
781
BRASERO_BURN_ERROR_GENERAL,
782
_("libisofs reported an error while adding file at path \"%s\""),
788
if (iso_node_get_name (node)
789
&& strcmp (iso_node_get_name (node), path_name)) {
790
err = iso_node_set_name (node, path_name);
792
BRASERO_JOB_LOG (self,
796
priv->error = g_error_new (BRASERO_BURN_ERROR,
797
BRASERO_BURN_ERROR_GENERAL,
798
_("libisofs reported an error while adding file at path \"%s\""),
808
else if (iso_tree_add_new_dir (ISO_DIR (parent), path_name, NULL) < 0) {
809
priv->error = g_error_new (BRASERO_BURN_ERROR,
810
BRASERO_BURN_ERROR_GENERAL,
811
_("libisofs reported an error while creating directory \"%s\""),
825
g_slist_free (grafts);
827
if (!priv->error && !priv->cancel) {
829
BraseroImageFS image_fs;
831
image_fs = brasero_track_data_get_fs (BRASERO_TRACK_DATA (track));
833
if ((image_fs & BRASERO_IMAGE_FS_ISO)
834
&& (image_fs & BRASERO_IMAGE_ISO_FS_LEVEL_3))
835
iso_write_opts_set_iso_level (opts, 3);
837
iso_write_opts_set_iso_level (opts, 2);
839
iso_write_opts_set_rockridge (opts, 1);
840
iso_write_opts_set_joliet (opts, (image_fs & BRASERO_IMAGE_FS_JOLIET) != 0);
841
iso_write_opts_set_allow_deep_paths (opts, (image_fs & BRASERO_IMAGE_ISO_FS_DEEP_DIRECTORY) != 0);
843
if (iso_image_create_burn_source (image, opts, &priv->libburn_src) >= 0) {
844
size = priv->libburn_src->get_size (priv->libburn_src);
845
brasero_job_set_output_size_for_current_track (BRASERO_JOB (self),
846
BRASERO_BYTES_TO_SECTORS (size, 2048),
852
iso_write_opts_free (opts);
855
iso_image_unref (image);
858
g_mutex_lock (priv->mutex);
860
/* It is important that the following is done inside the lock; indeed,
861
* if the main loop is idle then that brasero_libisofs_stop_real () can
862
* be called immediatly to stop the plugin while priv->thread is not
864
* As in this callback we check whether the thread is running (which
865
* means that we were cancelled) in some cases it would mean that we
866
* would cancel the libburn_src object and create crippled images. */
868
priv->thread_id = g_idle_add (brasero_libisofs_create_volume_thread_finished, self);
871
g_cond_signal (priv->cond);
872
g_mutex_unlock (priv->mutex);
874
g_thread_exit (NULL);
879
static BraseroBurnResult
880
brasero_libisofs_create_volume (BraseroLibisofs *self, GError **error)
882
BraseroLibisofsPrivate *priv;
883
GError *thread_error = NULL;
885
priv = BRASERO_LIBISOFS_PRIVATE (self);
887
return BRASERO_BURN_RUNNING;
889
if (iso_init () < 0) {
892
BRASERO_BURN_ERROR_GENERAL,
893
_("libisofs could not be initialized."));
894
return BRASERO_BURN_ERR;
897
iso_set_msgs_severities ("NEVER", "ALL", "brasero (libisofs)");
898
g_mutex_lock (priv->mutex);
899
priv->thread = g_thread_create (brasero_libisofs_create_volume_thread,
903
g_mutex_unlock (priv->mutex);
905
/* Reminder: this is not necessarily an error as the thread may have finished */
907
// return BRASERO_BURN_ERR;
909
g_propagate_error (error, thread_error);
910
return BRASERO_BURN_ERR;
913
return BRASERO_BURN_OK;
917
brasero_libisofs_clean_output (BraseroLibisofs *self)
919
BraseroLibisofsPrivate *priv;
921
priv = BRASERO_LIBISOFS_PRIVATE (self);
923
if (priv->libburn_src) {
924
burn_source_free (priv->libburn_src);
925
priv->libburn_src = NULL;
929
g_error_free (priv->error);
934
static BraseroBurnResult
935
brasero_libisofs_start (BraseroJob *job,
938
BraseroLibisofs *self;
939
BraseroJobAction action;
940
BraseroLibisofsPrivate *priv;
942
self = BRASERO_LIBISOFS (job);
943
priv = BRASERO_LIBISOFS_PRIVATE (self);
945
brasero_job_get_action (job, &action);
946
if (action == BRASERO_JOB_ACTION_SIZE) {
947
/* do this to avoid a problem when using
948
* DUMMY flag. libisofs would not generate
950
brasero_libisofs_clean_output (BRASERO_LIBISOFS (job));
951
brasero_job_set_current_action (BRASERO_JOB (self),
952
BRASERO_BURN_ACTION_GETTING_SIZE,
955
return brasero_libisofs_create_volume (self, error);
959
g_error_free (priv->error);
963
/* we need the source before starting anything */
964
if (!priv->libburn_src)
965
return brasero_libisofs_create_volume (self, error);
967
return brasero_libisofs_create_image (self, error);
971
brasero_libisofs_stop_real (BraseroLibisofs *self)
973
BraseroLibisofsPrivate *priv;
975
priv = BRASERO_LIBISOFS_PRIVATE (self);
977
/* Check whether we properly shut down or if we were cancelled */
978
g_mutex_lock (priv->mutex);
980
/* NOTE: this can only happen when we're preparing the volumes
981
* for a multi session disc. At this point we're only running
982
* to get the size of the future volume and we can't race with
983
* libburn plugin that isn't operating at this stage. */
985
brasero_libburn_common_ctx_free (priv->ctx);
989
/* A thread is running. In this context we are probably cancelling */
990
if (priv->libburn_src)
991
priv->libburn_src->cancel (priv->libburn_src);
994
g_cond_wait (priv->cond, priv->mutex);
997
g_mutex_unlock (priv->mutex);
999
if (priv->thread_id) {
1000
g_source_remove (priv->thread_id);
1001
priv->thread_id = 0;
1005
static BraseroBurnResult
1006
brasero_libisofs_stop (BraseroJob *job,
1009
BraseroLibisofs *self;
1011
self = BRASERO_LIBISOFS (job);
1012
brasero_libisofs_stop_real (self);
1013
return BRASERO_BURN_OK;
1017
brasero_libisofs_class_init (BraseroLibisofsClass *klass)
1019
GObjectClass *object_class = G_OBJECT_CLASS (klass);
1020
BraseroJobClass *job_class = BRASERO_JOB_CLASS (klass);
1022
g_type_class_add_private (klass, sizeof (BraseroLibisofsPrivate));
1024
parent_class = g_type_class_peek_parent(klass);
1025
object_class->finalize = brasero_libisofs_finalize;
1027
job_class->start = brasero_libisofs_start;
1028
job_class->stop = brasero_libisofs_stop;
1032
brasero_libisofs_init (BraseroLibisofs *obj)
1034
BraseroLibisofsPrivate *priv;
1036
priv = BRASERO_LIBISOFS_PRIVATE (obj);
1037
priv->mutex = g_mutex_new ();
1038
priv->cond = g_cond_new ();
1042
brasero_libisofs_finalize (GObject *object)
1044
BraseroLibisofs *cobj;
1045
BraseroLibisofsPrivate *priv;
1047
cobj = BRASERO_LIBISOFS (object);
1048
priv = BRASERO_LIBISOFS_PRIVATE (object);
1050
brasero_libisofs_stop_real (cobj);
1051
brasero_libisofs_clean_output (cobj);
1054
g_mutex_free (priv->mutex);
1059
g_cond_free (priv->cond);
1063
/* close libisofs library */
1066
G_OBJECT_CLASS (parent_class)->finalize (object);
1070
brasero_libisofs_export_caps (BraseroPlugin *plugin)
1075
brasero_plugin_define (plugin,
1078
_("Creates disc images from a file selection"),
1079
"Philippe Rouquier",
1082
brasero_plugin_set_flags (plugin,
1084
BRASERO_MEDIUM_CDRW|
1085
BRASERO_MEDIUM_DVDR|
1086
BRASERO_MEDIUM_DVDRW|
1087
BRASERO_MEDIUM_DUAL_L|
1088
BRASERO_MEDIUM_APPENDABLE|
1089
BRASERO_MEDIUM_HAS_AUDIO|
1090
BRASERO_MEDIUM_HAS_DATA,
1091
BRASERO_BURN_FLAG_APPEND|
1092
BRASERO_BURN_FLAG_MERGE,
1093
BRASERO_BURN_FLAG_NONE);
1095
brasero_plugin_set_flags (plugin,
1096
BRASERO_MEDIUM_DVDRW_PLUS|
1097
BRASERO_MEDIUM_RESTRICTED|
1098
BRASERO_MEDIUM_DUAL_L|
1099
BRASERO_MEDIUM_APPENDABLE|
1100
BRASERO_MEDIUM_CLOSED|
1101
BRASERO_MEDIUM_HAS_DATA,
1102
BRASERO_BURN_FLAG_APPEND|
1103
BRASERO_BURN_FLAG_MERGE,
1104
BRASERO_BURN_FLAG_NONE);
1106
output = brasero_caps_image_new (BRASERO_PLUGIN_IO_ACCEPT_FILE|
1107
BRASERO_PLUGIN_IO_ACCEPT_PIPE,
1108
BRASERO_IMAGE_FORMAT_BIN);
1110
input = brasero_caps_data_new (BRASERO_IMAGE_FS_ISO|
1111
BRASERO_IMAGE_ISO_FS_DEEP_DIRECTORY|
1112
BRASERO_IMAGE_ISO_FS_LEVEL_3|
1113
BRASERO_IMAGE_FS_JOLIET);
1114
brasero_plugin_link_caps (plugin, output, input);
1115
g_slist_free (input);
1117
input = brasero_caps_data_new (BRASERO_IMAGE_FS_ISO|
1118
BRASERO_IMAGE_ISO_FS_DEEP_DIRECTORY|
1119
BRASERO_IMAGE_ISO_FS_LEVEL_3|
1120
BRASERO_IMAGE_FS_SYMLINK);
1121
brasero_plugin_link_caps (plugin, output, input);
1122
g_slist_free (input);
1124
g_slist_free (output);
1126
brasero_plugin_register_group (plugin, _(LIBBURNIA_DESCRIPTION));