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