1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 * Brasero
4 * Copyright (C) Philippe Rouquier 2005-2010 <bonfire-app@wanadoo.fr>
5 *
6 * Brasero 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.
10 *
11 * brasero is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with brasero. If not, write to:
18 * The Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <glib.h>
28
29 #include "brasero-drive-settings.h"
30 #include "brasero-session.h"
31 #include "brasero-session-helper.h"
32 #include "brasero-drive-properties.h"
33
34 typedef struct _BraseroDriveSettingsPrivate BraseroDriveSettingsPrivate;
35 struct _BraseroDriveSettingsPrivate
36 {
37 BraseroMedia dest_media;
38 BraseroDrive *dest_drive;
39 BraseroTrackType *src_type;
40
41 GSettings *settings;
42 GSettings *config_settings;
43 BraseroBurnSession *session;
44 };
45
46 #define BRASERO_DRIVE_SETTINGS_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_DRIVE_SETTINGS, BraseroDriveSettingsPrivate))
47
48 #define BRASERO_SCHEMA_DRIVES "org.gnome.brasero.drives"
49 #define BRASERO_DRIVE_PROPERTIES_PATH "/org/gnome/brasero/drives/"
50 #define BRASERO_PROPS_FLAGS "flags"
51 #define BRASERO_PROPS_SPEED "speed"
52
53 #define BRASERO_SCHEMA_CONFIG "org.gnome.brasero.config"
54 #define BRASERO_PROPS_TMP_DIR "tmpdir"
55
56 #define BRASERO_DEST_SAVED_FLAGS (BRASERO_DRIVE_PROPERTIES_FLAGS|BRASERO_BURN_FLAG_MULTI)
57
58 G_DEFINE_TYPE (BraseroDriveSettings, brasero_drive_settings, G_TYPE_OBJECT);
59
60 static GVariant *
brasero_drive_settings_set_mapping_speed(const GValue * value,const GVariantType * variant_type,gpointer user_data)61 brasero_drive_settings_set_mapping_speed (const GValue *value,
62 const GVariantType *variant_type,
63 gpointer user_data)
64 {
65 return g_variant_new_int32 (g_value_get_int64 (value) / 1000);
66 }
67
68 static gboolean
brasero_drive_settings_get_mapping_speed(GValue * value,GVariant * variant,gpointer user_data)69 brasero_drive_settings_get_mapping_speed (GValue *value,
70 GVariant *variant,
71 gpointer user_data)
72 {
73 if (!g_variant_get_int32 (variant)) {
74 BraseroDriveSettingsPrivate *priv;
75 BraseroMedium *medium;
76 BraseroDrive *drive;
77
78 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (user_data);
79 drive = brasero_burn_session_get_burner (priv->session);
80 medium = brasero_drive_get_medium (drive);
81
82 /* Must not be NULL since we only bind when a medium is available */
83 g_assert (medium != NULL);
84
85 g_value_set_int64 (value, brasero_medium_get_max_write_speed (medium));
86 }
87 else
88 g_value_set_int64 (value, g_variant_get_int32 (variant) * 1000);
89
90 return TRUE;
91 }
92
93 static GVariant *
brasero_drive_settings_set_mapping_flags(const GValue * value,const GVariantType * variant_type,gpointer user_data)94 brasero_drive_settings_set_mapping_flags (const GValue *value,
95 const GVariantType *variant_type,
96 gpointer user_data)
97 {
98 return g_variant_new_int32 (g_value_get_int (value) & BRASERO_DEST_SAVED_FLAGS);
99 }
100
101 static gboolean
brasero_drive_settings_get_mapping_flags(GValue * value,GVariant * variant,gpointer user_data)102 brasero_drive_settings_get_mapping_flags (GValue *value,
103 GVariant *variant,
104 gpointer user_data)
105 {
106 BraseroBurnFlag flags;
107 BraseroBurnFlag current_flags;
108 BraseroDriveSettingsPrivate *priv;
109
110 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (user_data);
111
112 flags = g_variant_get_int32 (variant);
113 if (brasero_burn_session_same_src_dest_drive (priv->session)) {
114 /* Special case */
115 if (flags == 1) {
116 flags = BRASERO_BURN_FLAG_EJECT|
117 BRASERO_BURN_FLAG_BURNPROOF;
118 }
119 else
120 flags &= BRASERO_DEST_SAVED_FLAGS;
121
122 flags |= BRASERO_BURN_FLAG_BLANK_BEFORE_WRITE|
123 BRASERO_BURN_FLAG_FAST_BLANK;
124 }
125 /* This is for the default value when the user has never used it */
126 else if (flags == 1) {
127 BraseroTrackType *source;
128
129 flags = BRASERO_BURN_FLAG_EJECT|
130 BRASERO_BURN_FLAG_BURNPROOF;
131
132 source = brasero_track_type_new ();
133 brasero_burn_session_get_input_type (BRASERO_BURN_SESSION (priv->session), source);
134
135 if (!brasero_track_type_get_has_medium (source))
136 flags |= BRASERO_BURN_FLAG_NO_TMP_FILES;
137
138 brasero_track_type_free (source);
139 }
140 else
141 flags &= BRASERO_DEST_SAVED_FLAGS;
142
143 current_flags = brasero_burn_session_get_flags (BRASERO_BURN_SESSION (priv->session));
144 current_flags &= (~BRASERO_DEST_SAVED_FLAGS);
145
146 g_value_set_int (value, flags|current_flags);
147 return TRUE;
148 }
149
150 static void
brasero_drive_settings_bind_session(BraseroDriveSettings * self)151 brasero_drive_settings_bind_session (BraseroDriveSettings *self)
152 {
153 BraseroDriveSettingsPrivate *priv;
154 gchar *display_name;
155 gchar *path;
156 gchar *tmp;
157
158 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (self);
159
160 /* Get the drive name: it's done this way to avoid escaping */
161 tmp = brasero_drive_get_display_name (priv->dest_drive);
162 display_name = g_strdup_printf ("drive-%u", g_str_hash (tmp));
163 g_free (tmp);
164
165 if (brasero_track_type_get_has_medium (priv->src_type))
166 path = g_strdup_printf ("%s%s/disc-%i/",
167 BRASERO_DRIVE_PROPERTIES_PATH,
168 display_name,
169 priv->dest_media);
170 else if (brasero_track_type_get_has_data (priv->src_type))
171 path = g_strdup_printf ("%s%s/data-%i/",
172 BRASERO_DRIVE_PROPERTIES_PATH,
173 display_name,
174 priv->dest_media);
175 else if (brasero_track_type_get_has_image (priv->src_type))
176 path = g_strdup_printf ("%s%s/image-%i/",
177 BRASERO_DRIVE_PROPERTIES_PATH,
178 display_name,
179 priv->dest_media);
180 else if (brasero_track_type_get_has_stream (priv->src_type))
181 path = g_strdup_printf ("%s%s/audio-%i/",
182 BRASERO_DRIVE_PROPERTIES_PATH,
183 display_name,
184 priv->dest_media);
185 else {
186 g_free (display_name);
187 return;
188 }
189 g_free (display_name);
190
191 priv->settings = g_settings_new_with_path (BRASERO_SCHEMA_DRIVES, path);
192 g_free (path);
193
194 g_settings_bind_with_mapping (priv->settings, BRASERO_PROPS_SPEED,
195 priv->session, "speed", G_SETTINGS_BIND_DEFAULT,
196 brasero_drive_settings_get_mapping_speed,
197 brasero_drive_settings_set_mapping_speed,
198 self,
199 NULL);
200
201 g_settings_bind_with_mapping (priv->settings, BRASERO_PROPS_FLAGS,
202 priv->session, "flags", G_SETTINGS_BIND_DEFAULT,
203 brasero_drive_settings_get_mapping_flags,
204 brasero_drive_settings_set_mapping_flags,
205 self,
206 NULL);
207 }
208
209 static void
brasero_drive_settings_unbind_session(BraseroDriveSettings * self)210 brasero_drive_settings_unbind_session (BraseroDriveSettings *self)
211 {
212 BraseroDriveSettingsPrivate *priv;
213
214 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (self);
215
216 if (priv->settings) {
217 brasero_track_type_free (priv->src_type);
218 priv->src_type = NULL;
219
220 g_object_unref (priv->dest_drive);
221 priv->dest_drive = NULL;
222
223 priv->dest_media = BRASERO_MEDIUM_NONE;
224
225 g_settings_unbind (priv->settings, "speed");
226 g_settings_unbind (priv->settings, "flags");
227
228 g_object_unref (priv->settings);
229 priv->settings = NULL;
230 }
231 }
232
233 static void
brasero_drive_settings_rebind_session(BraseroDriveSettings * self)234 brasero_drive_settings_rebind_session (BraseroDriveSettings *self)
235 {
236 BraseroDriveSettingsPrivate *priv;
237 BraseroTrackType *type;
238 BraseroMedia new_media;
239 BraseroMedium *medium;
240 BraseroDrive *drive;
241
242 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (self);
243
244 /* See if we really need to do that:
245 * - check the source type has changed
246 * - check the output type has changed */
247 drive = brasero_burn_session_get_burner (priv->session);
248 medium = brasero_drive_get_medium (drive);
249 type = brasero_track_type_new ();
250
251 if (!drive
252 || !medium
253 || brasero_drive_is_fake (drive)
254 || !BRASERO_MEDIUM_VALID (brasero_medium_get_status (medium))
255 || brasero_burn_session_get_input_type (BRASERO_BURN_SESSION (priv->session), type) != BRASERO_BURN_OK) {
256 brasero_drive_settings_unbind_session (self);
257 return;
258 }
259
260 new_media = BRASERO_MEDIUM_TYPE (brasero_medium_get_status (medium));
261
262 if (priv->dest_drive == drive
263 && priv->dest_media == new_media
264 && priv->src_type && brasero_track_type_equal (priv->src_type, type)) {
265 brasero_track_type_free (type);
266 return;
267 }
268
269 brasero_track_type_free (priv->src_type);
270 priv->src_type = type;
271
272 if (priv->dest_drive)
273 g_object_unref (priv->dest_drive);
274
275 priv->dest_drive = g_object_ref (drive);
276
277 priv->dest_media = new_media;
278
279 brasero_drive_settings_bind_session (self);
280 }
281
282 static void
brasero_drive_settings_output_changed_cb(BraseroBurnSession * session,BraseroMedium * former_medium,BraseroDriveSettings * self)283 brasero_drive_settings_output_changed_cb (BraseroBurnSession *session,
284 BraseroMedium *former_medium,
285 BraseroDriveSettings *self)
286 {
287 brasero_drive_settings_rebind_session (self);
288 }
289
290 static void
brasero_drive_settings_track_added_cb(BraseroBurnSession * session,BraseroTrack * track,BraseroDriveSettings * self)291 brasero_drive_settings_track_added_cb (BraseroBurnSession *session,
292 BraseroTrack *track,
293 BraseroDriveSettings *self)
294 {
295 brasero_drive_settings_rebind_session (self);
296 }
297
298 static void
brasero_drive_settings_track_removed_cb(BraseroBurnSession * session,BraseroTrack * track,guint former_position,BraseroDriveSettings * self)299 brasero_drive_settings_track_removed_cb (BraseroBurnSession *session,
300 BraseroTrack *track,
301 guint former_position,
302 BraseroDriveSettings *self)
303 {
304 brasero_drive_settings_rebind_session (self);
305 }
306
307 static void
brasero_drive_settings_unset_session(BraseroDriveSettings * self)308 brasero_drive_settings_unset_session (BraseroDriveSettings *self)
309 {
310 BraseroDriveSettingsPrivate *priv;
311
312 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (self);
313
314 brasero_drive_settings_unbind_session (self);
315
316 if (priv->session) {
317 g_signal_handlers_disconnect_by_func (priv->session,
318 brasero_drive_settings_track_added_cb,
319 self);
320 g_signal_handlers_disconnect_by_func (priv->session,
321 brasero_drive_settings_track_removed_cb,
322 self);
323 g_signal_handlers_disconnect_by_func (priv->session,
324 brasero_drive_settings_output_changed_cb,
325 self);
326
327 g_settings_unbind (priv->config_settings, "tmpdir");
328 g_object_unref (priv->config_settings);
329
330 g_object_unref (priv->session);
331 priv->session = NULL;
332 }
333 }
334
335 void
brasero_drive_settings_set_session(BraseroDriveSettings * self,BraseroBurnSession * session)336 brasero_drive_settings_set_session (BraseroDriveSettings *self,
337 BraseroBurnSession *session)
338 {
339 BraseroDriveSettingsPrivate *priv;
340
341 priv = BRASERO_DRIVE_SETTINGS_PRIVATE (self);
342
343 brasero_drive_settings_unset_session (self);
344
345 priv->session = g_object_ref (session);
346 g_signal_connect (session,
347 "track-added",
348 G_CALLBACK (brasero_drive_settings_track_added_cb),
349 self);
350 g_signal_connect (session,
351 "track-removed",
352 G_CALLBACK (brasero_drive_settings_track_removed_cb),
353 self);
354 g_signal_connect (session,
355 "output-changed",
356 G_CALLBACK (brasero_drive_settings_output_changed_cb),
357 self);
358 brasero_drive_settings_rebind_session (self);
359
360 priv->config_settings = g_settings_new (BRASERO_SCHEMA_CONFIG);
361 g_settings_bind (priv->config_settings,
362 BRASERO_PROPS_TMP_DIR, session,
363 "tmpdir", G_SETTINGS_BIND_DEFAULT);
364 }
365
366 static void
brasero_drive_settings_init(BraseroDriveSettings * object)367 brasero_drive_settings_init (BraseroDriveSettings *object)
368 { }
369
370 static void
brasero_drive_settings_finalize(GObject * object)371 brasero_drive_settings_finalize (GObject *object)
372 {
373 brasero_drive_settings_unset_session (BRASERO_DRIVE_SETTINGS (object));
374 G_OBJECT_CLASS (brasero_drive_settings_parent_class)->finalize (object);
375 }
376
377 static void
brasero_drive_settings_class_init(BraseroDriveSettingsClass * klass)378 brasero_drive_settings_class_init (BraseroDriveSettingsClass *klass)
379 {
380 GObjectClass* object_class = G_OBJECT_CLASS (klass);
381
382 g_type_class_add_private (klass, sizeof (BraseroDriveSettingsPrivate));
383
384 object_class->finalize = brasero_drive_settings_finalize;
385 }
386
387 BraseroDriveSettings *
brasero_drive_settings_new(void)388 brasero_drive_settings_new (void)
389 {
390 return g_object_new (BRASERO_TYPE_DRIVE_SETTINGS, NULL);
391 }
392
393