1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * Libbrasero-media
4  * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
5  *
6  * Libbrasero-media 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  * The Libbrasero-media authors hereby grant permission for non-GPL compatible
12  * GStreamer plugins to be used and distributed together with GStreamer
13  * and Libbrasero-media. This permission is above and beyond the permissions granted
14  * by the GPL license by which Libbrasero-media 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.
18  *
19  * Libbrasero-media 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.
23  *
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.
29  */
30 
31 #ifdef HAVE_CONFIG_H
32 #  include <config.h>
33 #endif
34 
35 #include <string.h>
36 #include <stdio.h>
37 
38 #include <glib.h>
39 #include <glib/gi18n-lib.h>
40 
41 #include "brasero-media.h"
42 #include "brasero-media-private.h"
43 
44 static gboolean debug = 0;
45 
46 #define BRASERO_MEDIUM_TRUE_RANDOM_WRITABLE(media)				\
47 	(BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_RESTRICTED) ||		\
48 	 BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS) ||		\
49 	 BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVD_RAM) || 			\
50 	 BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_BDRE))
51 
52 static const GOptionEntry options [] = {
53 	{ "brasero-media-debug", 0, 0, G_OPTION_ARG_NONE, &debug,
54 	  N_("Display debug statements on stdout for Brasero media library"),
55 	  NULL },
56 	{ NULL }
57 };
58 
59 void
brasero_media_library_set_debug(gboolean value)60 brasero_media_library_set_debug (gboolean value)
61 {
62 	debug = value;
63 }
64 
65 static GSList *
brasero_media_add_to_list(GSList * retval,BraseroMedia media)66 brasero_media_add_to_list (GSList *retval,
67 			   BraseroMedia media)
68 {
69 	retval = g_slist_prepend (retval, GINT_TO_POINTER (media));
70 	return retval;
71 }
72 
73 static GSList *
brasero_media_new_status(GSList * retval,BraseroMedia media,BraseroMedia type)74 brasero_media_new_status (GSList *retval,
75 			  BraseroMedia media,
76 			  BraseroMedia type)
77 {
78 	if ((type & BRASERO_MEDIUM_BLANK)
79 	&& !(media & BRASERO_MEDIUM_ROM)) {
80 		/* If media is blank there is no other possible property. */
81 		retval = brasero_media_add_to_list (retval,
82 						    media|
83 						    BRASERO_MEDIUM_BLANK);
84 
85 		/* NOTE about BR-R they can be "formatted" but they are never
86 		 * unformatted since by default they'll be used as sequential.
87 		 * We don't consider DVD-RW as unformatted as in this case
88 		 * they are treated as DVD-RW in sequential mode and therefore
89 		 * don't require any formatting. */
90 		if (!(media & BRASERO_MEDIUM_RAM)
91 		&&   (BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS)
92 		||    BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_BD|BRASERO_MEDIUM_REWRITABLE))) {
93 			if (type & BRASERO_MEDIUM_UNFORMATTED)
94 				retval = brasero_media_add_to_list (retval,
95 								    media|
96 								    BRASERO_MEDIUM_BLANK|
97 								    BRASERO_MEDIUM_UNFORMATTED);
98 		}
99 	}
100 
101 	if (type & BRASERO_MEDIUM_CLOSED) {
102 		if (media & (BRASERO_MEDIUM_DVD|BRASERO_MEDIUM_BD))
103 			retval = brasero_media_add_to_list (retval,
104 							    media|
105 							    BRASERO_MEDIUM_CLOSED|
106 							    (type & BRASERO_MEDIUM_HAS_DATA)|
107 							    (type & BRASERO_MEDIUM_PROTECTED));
108 		else {
109 			if (type & BRASERO_MEDIUM_HAS_AUDIO)
110 				retval = brasero_media_add_to_list (retval,
111 								    media|
112 								    BRASERO_MEDIUM_CLOSED|
113 								    BRASERO_MEDIUM_HAS_AUDIO);
114 			if (type & BRASERO_MEDIUM_HAS_DATA)
115 				retval = brasero_media_add_to_list (retval,
116 								    media|
117 								    BRASERO_MEDIUM_CLOSED|
118 								    BRASERO_MEDIUM_HAS_DATA);
119 			if (BRASERO_MEDIUM_IS (type, BRASERO_MEDIUM_HAS_AUDIO|BRASERO_MEDIUM_HAS_DATA))
120 				retval = brasero_media_add_to_list (retval,
121 								    media|
122 								    BRASERO_MEDIUM_CLOSED|
123 								    BRASERO_MEDIUM_HAS_DATA|
124 								    BRASERO_MEDIUM_HAS_AUDIO);
125 		}
126 	}
127 
128 	if ((type & BRASERO_MEDIUM_APPENDABLE)
129 	&& !(media & BRASERO_MEDIUM_ROM)
130 	&& !BRASERO_MEDIUM_TRUE_RANDOM_WRITABLE (media)) {
131 		if (media & (BRASERO_MEDIUM_BD|BRASERO_MEDIUM_DVD))
132 			retval = brasero_media_add_to_list (retval,
133 							    media|
134 							    BRASERO_MEDIUM_APPENDABLE|
135 							    BRASERO_MEDIUM_HAS_DATA);
136 		else {
137 			if (type & BRASERO_MEDIUM_HAS_AUDIO)
138 				retval = brasero_media_add_to_list (retval,
139 								    media|
140 								    BRASERO_MEDIUM_APPENDABLE|
141 								    BRASERO_MEDIUM_HAS_AUDIO);
142 			if (type & BRASERO_MEDIUM_HAS_DATA)
143 				retval = brasero_media_add_to_list (retval,
144 								    media|
145 								    BRASERO_MEDIUM_APPENDABLE|
146 								    BRASERO_MEDIUM_HAS_DATA);
147 			if (BRASERO_MEDIUM_IS (type, BRASERO_MEDIUM_HAS_AUDIO|BRASERO_MEDIUM_HAS_DATA))
148 				retval = brasero_media_add_to_list (retval,
149 								    media|
150 								    BRASERO_MEDIUM_HAS_DATA|
151 								    BRASERO_MEDIUM_APPENDABLE|
152 								    BRASERO_MEDIUM_HAS_AUDIO);
153 		}
154 	}
155 
156 	return retval;
157 }
158 
159 static GSList *
brasero_media_new_attribute(GSList * retval,BraseroMedia media,BraseroMedia type)160 brasero_media_new_attribute (GSList *retval,
161 			     BraseroMedia media,
162 			     BraseroMedia type)
163 {
164 	/* NOTE: never reached by BDs, ROMs (any) or Restricted Overwrite
165 	 * and DVD- dual layer */
166 
167 	/* NOTE: there is no dual layer DVD-RW */
168 	if (type & BRASERO_MEDIUM_REWRITABLE)
169 		retval = brasero_media_new_status (retval,
170 						   media|BRASERO_MEDIUM_REWRITABLE,
171 						   type);
172 
173 	if (type & BRASERO_MEDIUM_WRITABLE)
174 		retval = brasero_media_new_status (retval,
175 						   media|BRASERO_MEDIUM_WRITABLE,
176 						   type);
177 
178 	return retval;
179 }
180 
181 static GSList *
brasero_media_new_subtype(GSList * retval,BraseroMedia media,BraseroMedia type)182 brasero_media_new_subtype (GSList *retval,
183 			   BraseroMedia media,
184 			   BraseroMedia type)
185 {
186 	if (media & BRASERO_MEDIUM_BD) {
187 		/* There seems to be Dual layers BDs as well */
188 
189 		if (type & BRASERO_MEDIUM_ROM) {
190 			retval = brasero_media_new_status (retval,
191 							   media|
192 							   BRASERO_MEDIUM_ROM,
193 							   type);
194 			if (type & BRASERO_MEDIUM_DUAL_L)
195 				retval = brasero_media_new_status (retval,
196 								   media|
197 								   BRASERO_MEDIUM_ROM|
198 								   BRASERO_MEDIUM_DUAL_L,
199 								   type);
200 		}
201 
202 		if (type & BRASERO_MEDIUM_RANDOM) {
203 			retval = brasero_media_new_status (retval,
204 							   media|
205 							   BRASERO_MEDIUM_RANDOM|
206 							   BRASERO_MEDIUM_WRITABLE,
207 							   type);
208 			if (type & BRASERO_MEDIUM_DUAL_L)
209 				retval = brasero_media_new_status (retval,
210 								   media|
211 								   BRASERO_MEDIUM_RANDOM|
212 								   BRASERO_MEDIUM_WRITABLE|
213 								   BRASERO_MEDIUM_DUAL_L,
214 								   type);
215 		}
216 
217 		if (type & BRASERO_MEDIUM_SRM) {
218 			retval = brasero_media_new_status (retval,
219 							   media|
220 							   BRASERO_MEDIUM_SRM|
221 							   BRASERO_MEDIUM_WRITABLE,
222 							   type);
223 			if (type & BRASERO_MEDIUM_DUAL_L)
224 				retval = brasero_media_new_status (retval,
225 								   media|
226 								   BRASERO_MEDIUM_SRM|
227 								   BRASERO_MEDIUM_WRITABLE|
228 								   BRASERO_MEDIUM_DUAL_L,
229 								   type);
230 		}
231 
232 		if (type & BRASERO_MEDIUM_POW) {
233 			retval = brasero_media_new_status (retval,
234 							   media|
235 							   BRASERO_MEDIUM_POW|
236 							   BRASERO_MEDIUM_WRITABLE,
237 							   type);
238 			if (type & BRASERO_MEDIUM_DUAL_L)
239 				retval = brasero_media_new_status (retval,
240 								   media|
241 								   BRASERO_MEDIUM_POW|
242 								   BRASERO_MEDIUM_WRITABLE|
243 								   BRASERO_MEDIUM_DUAL_L,
244 								   type);
245 		}
246 
247 		/* BD-RE */
248 		if (type & BRASERO_MEDIUM_REWRITABLE) {
249 			retval = brasero_media_new_status (retval,
250 							   media|
251 							   BRASERO_MEDIUM_REWRITABLE,
252 							   type);
253 			if (type & BRASERO_MEDIUM_DUAL_L)
254 				retval = brasero_media_new_status (retval,
255 								   media|
256 								   BRASERO_MEDIUM_REWRITABLE|
257 								   BRASERO_MEDIUM_DUAL_L,
258 								   type);
259 		}
260 	}
261 
262 	if (media & BRASERO_MEDIUM_DVD) {
263 		/* There is no such thing as DVD-RW DL nor DVD-RAM DL*/
264 
265 		/* The following is always a DVD-R dual layer */
266 		if (type & BRASERO_MEDIUM_JUMP)
267 			retval = brasero_media_new_status (retval,
268 							   media|
269 							   BRASERO_MEDIUM_JUMP|
270 							   BRASERO_MEDIUM_DUAL_L|
271 							   BRASERO_MEDIUM_WRITABLE,
272 							   type);
273 
274 		if (type & BRASERO_MEDIUM_SEQUENTIAL) {
275 			retval = brasero_media_new_attribute (retval,
276 							      media|
277 							      BRASERO_MEDIUM_SEQUENTIAL,
278 							      type);
279 
280 			/* This one has to be writable only, no RW */
281 			if (type & BRASERO_MEDIUM_DUAL_L)
282 				retval = brasero_media_new_status (retval,
283 								   media|
284 								   BRASERO_MEDIUM_SEQUENTIAL|
285 								   BRASERO_MEDIUM_WRITABLE|
286 								   BRASERO_MEDIUM_DUAL_L,
287 								   type);
288 		}
289 
290 		/* Restricted Overwrite media are always rewritable */
291 		if (type & BRASERO_MEDIUM_RESTRICTED)
292 			retval = brasero_media_new_status (retval,
293 							   media|
294 							   BRASERO_MEDIUM_RESTRICTED|
295 							   BRASERO_MEDIUM_REWRITABLE,
296 							   type);
297 
298 		if (type & BRASERO_MEDIUM_PLUS) {
299 			retval = brasero_media_new_attribute (retval,
300 							      media|
301 							      BRASERO_MEDIUM_PLUS,
302 							      type);
303 
304 			if (type & BRASERO_MEDIUM_DUAL_L)
305 				retval = brasero_media_new_attribute (retval,
306 								      media|
307 								      BRASERO_MEDIUM_PLUS|
308 								      BRASERO_MEDIUM_DUAL_L,
309 								      type);
310 
311 		}
312 
313 		if (type & BRASERO_MEDIUM_ROM) {
314 			retval = brasero_media_new_status (retval,
315 							   media|
316 							   BRASERO_MEDIUM_ROM,
317 							   type);
318 
319 			if (type & BRASERO_MEDIUM_DUAL_L)
320 				retval = brasero_media_new_status (retval,
321 								   media|
322 								   BRASERO_MEDIUM_ROM|
323 								   BRASERO_MEDIUM_DUAL_L,
324 								   type);
325 		}
326 
327 		/* RAM media are always rewritable */
328 		if (type & BRASERO_MEDIUM_RAM)
329 			retval = brasero_media_new_status (retval,
330 							   media|
331 							   BRASERO_MEDIUM_RAM|
332 							   BRASERO_MEDIUM_REWRITABLE,
333 							   type);
334 	}
335 
336 	return retval;
337 }
338 
339 GSList *
brasero_media_get_all_list(BraseroMedia type)340 brasero_media_get_all_list (BraseroMedia type)
341 {
342 	GSList *retval = NULL;
343 
344 	if (type & BRASERO_MEDIUM_FILE)
345 		retval = brasero_media_add_to_list (retval, BRASERO_MEDIUM_FILE);
346 
347 	if (type & BRASERO_MEDIUM_CD) {
348 		if (type & BRASERO_MEDIUM_ROM)
349 			retval = brasero_media_new_status (retval,
350 							   BRASERO_MEDIUM_CD|
351 							   BRASERO_MEDIUM_ROM,
352 							   type);
353 
354 		retval = brasero_media_new_attribute (retval,
355 						      BRASERO_MEDIUM_CD,
356 						      type);
357 	}
358 
359 	if (type & BRASERO_MEDIUM_DVD)
360 		retval = brasero_media_new_subtype (retval,
361 						    BRASERO_MEDIUM_DVD,
362 						    type);
363 
364 
365 	if (type & BRASERO_MEDIUM_BD)
366 		retval = brasero_media_new_subtype (retval,
367 						    BRASERO_MEDIUM_BD,
368 						    type);
369 
370 	return retval;
371 }
372 
373 GQuark
brasero_media_quark(void)374 brasero_media_quark (void)
375 {
376 	static GQuark quark = 0;
377 
378 	if (!quark)
379 		quark = g_quark_from_static_string ("BraseroMediaError");
380 
381 	return quark;
382 }
383 
384 void
brasero_media_to_string(BraseroMedia media,gchar * buffer)385 brasero_media_to_string (BraseroMedia media,
386 			 gchar *buffer)
387 {
388 	if (media & BRASERO_MEDIUM_FILE)
389 		strcat (buffer, "file ");
390 
391 	if (media & BRASERO_MEDIUM_CD)
392 		strcat (buffer, "CD ");
393 
394 	if (media & BRASERO_MEDIUM_DVD)
395 		strcat (buffer, "DVD ");
396 
397 	if (media & BRASERO_MEDIUM_RAM)
398 		strcat (buffer, "RAM ");
399 
400 	if (media & BRASERO_MEDIUM_BD)
401 		strcat (buffer, "BD ");
402 
403 	if (media & BRASERO_MEDIUM_DUAL_L)
404 		strcat (buffer, "DL ");
405 
406 	/* DVD subtypes */
407 	if (media & BRASERO_MEDIUM_PLUS)
408 		strcat (buffer, "+ ");
409 
410 	if (media & BRASERO_MEDIUM_SEQUENTIAL)
411 		strcat (buffer, "- (sequential) ");
412 
413 	if (media & BRASERO_MEDIUM_RESTRICTED)
414 		strcat (buffer, "- (restricted) ");
415 
416 	if (media & BRASERO_MEDIUM_JUMP)
417 		strcat (buffer, "- (jump) ");
418 
419 	/* BD subtypes */
420 	if (media & BRASERO_MEDIUM_SRM)
421 		strcat (buffer, "SRM ");
422 
423 	if (media & BRASERO_MEDIUM_POW)
424 		strcat (buffer, "POW ");
425 
426 	if (media & BRASERO_MEDIUM_RANDOM)
427 		strcat (buffer, "RANDOM ");
428 
429 	/* discs attributes */
430 	if (media & BRASERO_MEDIUM_REWRITABLE)
431 		strcat (buffer, "RW ");
432 
433 	if (media & BRASERO_MEDIUM_WRITABLE)
434 		strcat (buffer, "W ");
435 
436 	if (media & BRASERO_MEDIUM_ROM)
437 		strcat (buffer, "ROM ");
438 
439 	/* status of the disc */
440 	if (media & BRASERO_MEDIUM_CLOSED)
441 		strcat (buffer, "closed ");
442 
443 	if (media & BRASERO_MEDIUM_BLANK)
444 		strcat (buffer, "blank ");
445 
446 	if (media & BRASERO_MEDIUM_APPENDABLE)
447 		strcat (buffer, "appendable ");
448 
449 	if (media & BRASERO_MEDIUM_PROTECTED)
450 		strcat (buffer, "protected ");
451 
452 	if (media & BRASERO_MEDIUM_HAS_DATA)
453 		strcat (buffer, "with data ");
454 
455 	if (media & BRASERO_MEDIUM_HAS_AUDIO)
456 		strcat (buffer, "with audio ");
457 
458 	if (media & BRASERO_MEDIUM_UNFORMATTED)
459 		strcat (buffer, "Unformatted ");
460 }
461 
462 /**
463  * brasero_media_get_option_group:
464  *
465  * Returns a GOptionGroup for the commandline arguments recognized by libbrasero-media.
466  * You should add this to your GOptionContext if your are using g_option_context_parse ()
467  * to parse your commandline arguments.
468  *
469  * Return value: a #GOptionGroup *
470  **/
471 GOptionGroup *
brasero_media_get_option_group(void)472 brasero_media_get_option_group (void)
473 {
474 	GOptionGroup *group;
475 
476 	group = g_option_group_new ("brasero-media",
477 				    N_("Brasero optical media library"),
478 				    N_("Display options for Brasero media library"),
479 				    NULL,
480 				    NULL);
481 	g_option_group_add_entries (group, options);
482 	return group;
483 }
484 
485 void
brasero_media_message(const gchar * location,const gchar * format,...)486 brasero_media_message (const gchar *location,
487 		       const gchar *format,
488 		       ...)
489 {
490 	va_list arg_list;
491 	gchar *format_real;
492 
493 	if (!debug)
494 		return;
495 
496 	format_real = g_strdup_printf ("BraseroMedia: (at %s) %s\n",
497 				       location,
498 				       format);
499 
500 	va_start (arg_list, format);
501 	vprintf (format_real, arg_list);
502 	va_end (arg_list);
503 
504 	g_free (format_real);
505 }
506 
507 #include <gtk/gtk.h>
508 
509 #include "brasero-medium-monitor.h"
510 
511 static BraseroMediumMonitor *default_monitor = NULL;
512 
513 /**
514  * brasero_media_library_start:
515  *
516  * Initialize the library.
517  *
518  * You should call this function before using any other from the library.
519  *
520  * Rename to: init
521  **/
522 void
brasero_media_library_start(void)523 brasero_media_library_start (void)
524 {
525 	if (default_monitor) {
526 		g_object_ref (default_monitor);
527 		return;
528 	}
529 
530 	BRASERO_MEDIA_LOG ("Initializing Brasero-media %i.%i.%i",
531 	                    BRASERO_MAJOR_VERSION,
532 	                    BRASERO_MINOR_VERSION,
533 	                    BRASERO_SUB);
534 
535 #if defined(HAVE_STRUCT_USCSI_CMD)
536 	/* Work around: because on OpenSolaris brasero posiblely be run
537 	 * as root for a user with 'Primary Administrator' profile,
538 	 * a root dbus session will be autospawned at that time.
539 	 * This fix is to work around
540 	 * http://bugzilla.gnome.org/show_bug.cgi?id=526454
541 	 */
542 	g_setenv ("DBUS_SESSION_BUS_ADDRESS", "autolaunch:", TRUE);
543 #endif
544 
545 	/* Initialize external libraries (threads... */
546 	if (!g_thread_supported ())
547 		g_thread_init (NULL);
548 
549 	/* Initialize i18n */
550 	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
551 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
552 
553 	/* Initialize icon-theme */
554 	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
555 					   BRASERO_DATADIR "/icons");
556 
557 	/* Take a reference for the monitoring library */
558 	default_monitor = brasero_medium_monitor_get_default ();
559 }
560 
561 /**
562  * brasero_media_library_stop:
563  *
564  * De-initialize the library once you do not need the library anymore.
565  *
566  * Rename to: deinit
567  **/
568 void
brasero_media_library_stop(void)569 brasero_media_library_stop (void)
570 {
571 	g_object_unref (default_monitor);
572 	default_monitor = NULL;
573 }
574