1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3 * Libbrasero-burn
4 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
5 *
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.
10 *
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.
18 *
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.
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
37 #include <glib.h>
38 #include <glib-object.h>
39 #include <gmodule.h>
40 #include <glib/gi18n-lib.h>
41
42 #include <gst/gst.h>
43
44 #include <stdio.h>
45
46 #include "brasero-media-private.h"
47
48 #include "brasero-media.h"
49
50 #include "burn-basics.h"
51 #include "burn-debug.h"
52 #include "brasero-plugin.h"
53 #include "brasero-plugin-private.h"
54 #include "brasero-plugin-information.h"
55 #include "brasero-plugin-registration.h"
56 #include "burn-caps.h"
57
58 #define BRASERO_SCHEMA_PLUGINS "org.gnome.brasero.plugins"
59 #define BRASERO_PROPS_PRIORITY_KEY "priority"
60
61 typedef struct _BraseroPluginFlagPair BraseroPluginFlagPair;
62
63 struct _BraseroPluginFlagPair {
64 BraseroPluginFlagPair *next;
65 BraseroBurnFlag supported;
66 BraseroBurnFlag compulsory;
67 };
68
69 struct _BraseroPluginFlags {
70 BraseroMedia media;
71 BraseroPluginFlagPair *pairs;
72 };
73 typedef struct _BraseroPluginFlags BraseroPluginFlags;
74
75 struct _BraseroPluginConfOption {
76 gchar *key;
77 gchar *description;
78 BraseroPluginConfOptionType type;
79
80 union {
81 struct {
82 guint max;
83 guint min;
84 } range;
85
86 GSList *suboptions;
87
88 GSList *choices;
89 } specifics;
90 };
91
92 typedef struct _BraseroPluginPrivate BraseroPluginPrivate;
93 struct _BraseroPluginPrivate
94 {
95 GSettings *settings;
96
97 gboolean active;
98 guint group;
99
100 GSList *options;
101
102 GSList *errors;
103
104 GType type;
105 gchar *path;
106 GModule *handle;
107
108 gchar *name;
109 gchar *display_name;
110 gchar *author;
111 gchar *description;
112 gchar *copyright;
113 gchar *website;
114
115 guint notify_priority;
116 guint priority_original;
117 gint priority;
118
119 GSList *flags;
120 GSList *blank_flags;
121
122 BraseroPluginProcessFlag process_flags;
123
124 guint compulsory:1;
125 };
126
127 static const gchar *default_icon = "gtk-cdrom";
128
129 #define BRASERO_PLUGIN_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_PLUGIN, BraseroPluginPrivate))
130 G_DEFINE_TYPE (BraseroPlugin, brasero_plugin, G_TYPE_TYPE_MODULE);
131
132 enum
133 {
134 PROP_0,
135 PROP_PATH,
136 PROP_PRIORITY
137 };
138
139 enum
140 {
141 LOADED_SIGNAL,
142 ACTIVATED_SIGNAL,
143 LAST_SIGNAL
144 };
145
146 static GTypeModuleClass* parent_class = NULL;
147 static guint plugin_signals [LAST_SIGNAL] = { 0 };
148
149 static void
brasero_plugin_error_free(BraseroPluginError * error)150 brasero_plugin_error_free (BraseroPluginError *error)
151 {
152 g_free (error->detail);
153 g_free (error);
154 }
155
156 void
brasero_plugin_add_error(BraseroPlugin * plugin,BraseroPluginErrorType type,const gchar * detail)157 brasero_plugin_add_error (BraseroPlugin *plugin,
158 BraseroPluginErrorType type,
159 const gchar *detail)
160 {
161 BraseroPluginError *error;
162 BraseroPluginPrivate *priv;
163
164 g_return_if_fail (BRASERO_IS_PLUGIN (plugin));
165
166 priv = BRASERO_PLUGIN_PRIVATE (plugin);
167
168 error = g_new0 (BraseroPluginError, 1);
169 error->detail = g_strdup (detail);
170 error->type = type;
171
172 priv->errors = g_slist_prepend (priv->errors, error);
173 }
174
175 void
brasero_plugin_test_gstreamer_plugin(BraseroPlugin * plugin,const gchar * name)176 brasero_plugin_test_gstreamer_plugin (BraseroPlugin *plugin,
177 const gchar *name)
178 {
179 GstElement *element;
180
181 /* Let's see if we've got the plugins we need */
182 element = gst_element_factory_make (name, NULL);
183 if (!element)
184 brasero_plugin_add_error (plugin,
185 BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN,
186 name);
187 else
188 gst_object_unref (element);
189 }
190
191 void
brasero_plugin_test_app(BraseroPlugin * plugin,const gchar * name,const gchar * version_arg,const gchar * version_format,gint version[3])192 brasero_plugin_test_app (BraseroPlugin *plugin,
193 const gchar *name,
194 const gchar *version_arg,
195 const gchar *version_format,
196 gint version [3])
197 {
198 gchar *standard_output = NULL;
199 gchar *standard_error = NULL;
200 guint major, minor, sub;
201 gchar *prog_path;
202 GPtrArray *argv;
203 gboolean res;
204 int i;
205
206 /* First see if this plugin can be used, i.e. if cdrecord is in
207 * the path */
208 prog_path = g_find_program_in_path (name);
209 if (!prog_path) {
210 brasero_plugin_add_error (plugin,
211 BRASERO_PLUGIN_ERROR_MISSING_APP,
212 name);
213 return;
214 }
215
216 if (!g_file_test (prog_path, G_FILE_TEST_IS_EXECUTABLE)) {
217 g_free (prog_path);
218 brasero_plugin_add_error (plugin,
219 BRASERO_PLUGIN_ERROR_MISSING_APP,
220 name);
221 return;
222 }
223
224 /* make sure that's not a symlink pointing to something with another
225 * name like wodim.
226 * NOTE: we used to test the target and see if it had the same name as
227 * the symlink with GIO. The problem is, when the symlink pointed to
228 * another symlink, then GIO didn't follow that other symlink. And in
229 * the end it didn't work. So forbid all symlink. */
230 if (g_file_test (prog_path, G_FILE_TEST_IS_SYMLINK)) {
231 brasero_plugin_add_error (plugin,
232 BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP,
233 name);
234 g_free (prog_path);
235 return;
236 }
237 /* Make sure it's a regular file */
238 else if (!g_file_test (prog_path, G_FILE_TEST_IS_REGULAR)) {
239 brasero_plugin_add_error (plugin,
240 BRASERO_PLUGIN_ERROR_MISSING_APP,
241 name);
242 g_free (prog_path);
243 return;
244 }
245
246 if (!version_arg) {
247 g_free (prog_path);
248 return;
249 }
250
251 /* Check version */
252 argv = g_ptr_array_new ();
253 g_ptr_array_add (argv, prog_path);
254 g_ptr_array_add (argv, (gchar *) version_arg);
255 g_ptr_array_add (argv, NULL);
256
257 res = g_spawn_sync (NULL,
258 (gchar **) argv->pdata,
259 NULL,
260 0,
261 NULL,
262 NULL,
263 &standard_output,
264 &standard_error,
265 NULL,
266 NULL);
267
268 g_ptr_array_free (argv, TRUE);
269 g_free (prog_path);
270
271 if (!res) {
272 brasero_plugin_add_error (plugin,
273 BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
274 name);
275 return;
276 }
277
278 for (i = 0; i < 3 && version [i] >= 0; i++);
279
280 if ((standard_output && sscanf (standard_output, version_format, &major, &minor, &sub) == i)
281 || (standard_error && sscanf (standard_error, version_format, &major, &minor, &sub) == i)) {
282 if (major < version [0]
283 || (version [1] >= 0 && minor < version [1])
284 || (version [2] >= 0 && sub < version [2]))
285 brasero_plugin_add_error (plugin,
286 BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
287 name);
288 }
289 else
290 brasero_plugin_add_error (plugin,
291 BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
292 name);
293
294 g_free (standard_output);
295 g_free (standard_error);
296 }
297
298 void
brasero_plugin_set_compulsory(BraseroPlugin * self,gboolean compulsory)299 brasero_plugin_set_compulsory (BraseroPlugin *self,
300 gboolean compulsory)
301 {
302 BraseroPluginPrivate *priv;
303
304 priv = BRASERO_PLUGIN_PRIVATE (self);
305 priv->compulsory = compulsory;
306 }
307
308 gboolean
brasero_plugin_get_compulsory(BraseroPlugin * self)309 brasero_plugin_get_compulsory (BraseroPlugin *self)
310 {
311 BraseroPluginPrivate *priv;
312
313 priv = BRASERO_PLUGIN_PRIVATE (self);
314 return priv->compulsory;
315 }
316
317 void
brasero_plugin_set_active(BraseroPlugin * self,gboolean active)318 brasero_plugin_set_active (BraseroPlugin *self, gboolean active)
319 {
320 BraseroPluginPrivate *priv;
321 gboolean was_active;
322 gboolean now_active;
323
324 priv = BRASERO_PLUGIN_PRIVATE (self);
325
326 was_active = brasero_plugin_get_active (self, FALSE);
327 priv->active = active;
328
329 now_active = brasero_plugin_get_active (self, FALSE);
330 if (was_active == now_active)
331 return;
332
333 BRASERO_BURN_LOG ("Plugin %s is %s",
334 brasero_plugin_get_name (self),
335 now_active?"active":"inactive");
336
337 g_signal_emit (self,
338 plugin_signals [ACTIVATED_SIGNAL],
339 0,
340 now_active);
341 }
342
343 gboolean
brasero_plugin_get_active(BraseroPlugin * plugin,gboolean ignore_errors)344 brasero_plugin_get_active (BraseroPlugin *plugin,
345 gboolean ignore_errors)
346 {
347 BraseroPluginPrivate *priv;
348
349 priv = BRASERO_PLUGIN_PRIVATE (plugin);
350
351 if (priv->type == G_TYPE_NONE)
352 return FALSE;
353
354 if (priv->priority < 0)
355 return FALSE;
356
357 if (priv->errors) {
358 if (!ignore_errors)
359 return FALSE;
360 }
361
362 return priv->active;
363 }
364
365 static void
brasero_plugin_cleanup_definition(BraseroPlugin * self)366 brasero_plugin_cleanup_definition (BraseroPlugin *self)
367 {
368 BraseroPluginPrivate *priv;
369
370 priv = BRASERO_PLUGIN_PRIVATE (self);
371
372 g_free (priv->name);
373 priv->name = NULL;
374 g_free (priv->author);
375 priv->author = NULL;
376 g_free (priv->description);
377 priv->description = NULL;
378 g_free (priv->copyright);
379 priv->copyright = NULL;
380 g_free (priv->website);
381 priv->website = NULL;
382 }
383
384 /**
385 * Plugin configure options
386 */
387
388 static void
brasero_plugin_conf_option_choice_pair_free(BraseroPluginChoicePair * pair)389 brasero_plugin_conf_option_choice_pair_free (BraseroPluginChoicePair *pair)
390 {
391 g_free (pair->string);
392 g_free (pair);
393 }
394
395 static void
brasero_plugin_conf_option_free(BraseroPluginConfOption * option)396 brasero_plugin_conf_option_free (BraseroPluginConfOption *option)
397 {
398 if (option->type == BRASERO_PLUGIN_OPTION_BOOL)
399 g_slist_free (option->specifics.suboptions);
400
401 if (option->type == BRASERO_PLUGIN_OPTION_CHOICE) {
402 g_slist_foreach (option->specifics.choices, (GFunc) brasero_plugin_conf_option_choice_pair_free, NULL);
403 g_slist_free (option->specifics.choices);
404 }
405
406 g_free (option->key);
407 g_free (option->description);
408
409 g_free (option);
410 }
411
412 BraseroPluginConfOption *
brasero_plugin_get_next_conf_option(BraseroPlugin * self,BraseroPluginConfOption * current)413 brasero_plugin_get_next_conf_option (BraseroPlugin *self,
414 BraseroPluginConfOption *current)
415 {
416 BraseroPluginPrivate *priv;
417 GSList *node;
418
419 priv = BRASERO_PLUGIN_PRIVATE (self);
420 if (!priv->options)
421 return NULL;
422
423 if (!current)
424 return priv->options->data;
425
426 node = g_slist_find (priv->options, current);
427 if (!node)
428 return NULL;
429
430 if (!node->next)
431 return NULL;
432
433 return node->next->data;
434 }
435
436 BraseroBurnResult
brasero_plugin_conf_option_get_info(BraseroPluginConfOption * option,gchar ** key,gchar ** description,BraseroPluginConfOptionType * type)437 brasero_plugin_conf_option_get_info (BraseroPluginConfOption *option,
438 gchar **key,
439 gchar **description,
440 BraseroPluginConfOptionType *type)
441 {
442 g_return_val_if_fail (option != NULL, BRASERO_BURN_ERR);
443
444 if (key)
445 *key = g_strdup (option->key);
446
447 if (description)
448 *description = g_strdup (option->description);
449
450 if (type)
451 *type = option->type;
452
453 return BRASERO_BURN_OK;
454 }
455
456 BraseroPluginConfOption *
brasero_plugin_conf_option_new(const gchar * key,const gchar * description,BraseroPluginConfOptionType type)457 brasero_plugin_conf_option_new (const gchar *key,
458 const gchar *description,
459 BraseroPluginConfOptionType type)
460 {
461 BraseroPluginConfOption *option;
462
463 g_return_val_if_fail (key != NULL, NULL);
464 g_return_val_if_fail (description != NULL, NULL);
465 g_return_val_if_fail (type != BRASERO_PLUGIN_OPTION_NONE, NULL);
466
467 option = g_new0 (BraseroPluginConfOption, 1);
468 option->key = g_strdup (key);
469 option->description = g_strdup (description);
470 option->type = type;
471
472 return option;
473 }
474
475 BraseroBurnResult
brasero_plugin_add_conf_option(BraseroPlugin * self,BraseroPluginConfOption * option)476 brasero_plugin_add_conf_option (BraseroPlugin *self,
477 BraseroPluginConfOption *option)
478 {
479 BraseroPluginPrivate *priv;
480
481 priv = BRASERO_PLUGIN_PRIVATE (self);
482 priv->options = g_slist_append (priv->options, option);
483
484 return BRASERO_BURN_OK;
485 }
486
487 BraseroBurnResult
brasero_plugin_conf_option_bool_add_suboption(BraseroPluginConfOption * option,BraseroPluginConfOption * suboption)488 brasero_plugin_conf_option_bool_add_suboption (BraseroPluginConfOption *option,
489 BraseroPluginConfOption *suboption)
490 {
491 if (option->type != BRASERO_PLUGIN_OPTION_BOOL)
492 return BRASERO_BURN_ERR;
493
494 option->specifics.suboptions = g_slist_prepend (option->specifics.suboptions,
495 suboption);
496 return BRASERO_BURN_OK;
497 }
498
499 BraseroBurnResult
brasero_plugin_conf_option_int_set_range(BraseroPluginConfOption * option,gint min,gint max)500 brasero_plugin_conf_option_int_set_range (BraseroPluginConfOption *option,
501 gint min,
502 gint max)
503 {
504 if (option->type != BRASERO_PLUGIN_OPTION_INT)
505 return BRASERO_BURN_ERR;
506
507 option->specifics.range.max = max;
508 option->specifics.range.min = min;
509 return BRASERO_BURN_OK;
510 }
511
512 BraseroBurnResult
brasero_plugin_conf_option_choice_add(BraseroPluginConfOption * option,const gchar * string,gint value)513 brasero_plugin_conf_option_choice_add (BraseroPluginConfOption *option,
514 const gchar *string,
515 gint value)
516 {
517 BraseroPluginChoicePair *pair;
518
519 if (option->type != BRASERO_PLUGIN_OPTION_CHOICE)
520 return BRASERO_BURN_ERR;
521
522 pair = g_new0 (BraseroPluginChoicePair, 1);
523 pair->value = value;
524 pair->string = g_strdup (string);
525 option->specifics.choices = g_slist_append (option->specifics.choices, pair);
526
527 return BRASERO_BURN_OK;
528 }
529
530 GSList *
brasero_plugin_conf_option_bool_get_suboptions(BraseroPluginConfOption * option)531 brasero_plugin_conf_option_bool_get_suboptions (BraseroPluginConfOption *option)
532 {
533 if (option->type != BRASERO_PLUGIN_OPTION_BOOL)
534 return NULL;
535 return option->specifics.suboptions;
536 }
537
538 gint
brasero_plugin_conf_option_int_get_max(BraseroPluginConfOption * option)539 brasero_plugin_conf_option_int_get_max (BraseroPluginConfOption *option)
540 {
541 if (option->type != BRASERO_PLUGIN_OPTION_INT)
542 return -1;
543 return option->specifics.range.max;
544 }
545
546 gint
brasero_plugin_conf_option_int_get_min(BraseroPluginConfOption * option)547 brasero_plugin_conf_option_int_get_min (BraseroPluginConfOption *option)
548 {
549 if (option->type != BRASERO_PLUGIN_OPTION_INT)
550 return -1;
551 return option->specifics.range.min;
552 }
553
554 GSList *
brasero_plugin_conf_option_choice_get(BraseroPluginConfOption * option)555 brasero_plugin_conf_option_choice_get (BraseroPluginConfOption *option)
556 {
557 if (option->type != BRASERO_PLUGIN_OPTION_CHOICE)
558 return NULL;
559 return option->specifics.choices;
560 }
561
562 /**
563 * Used to set the caps of plugin
564 */
565
566 void
brasero_plugin_define(BraseroPlugin * self,const gchar * name,const gchar * display_name,const gchar * description,const gchar * author,guint priority)567 brasero_plugin_define (BraseroPlugin *self,
568 const gchar *name,
569 const gchar *display_name,
570 const gchar *description,
571 const gchar *author,
572 guint priority)
573 {
574 BraseroPluginPrivate *priv;
575
576 priv = BRASERO_PLUGIN_PRIVATE (self);
577
578 brasero_plugin_cleanup_definition (self);
579
580 priv->name = g_strdup (name);
581 priv->display_name = g_strdup (display_name);
582 priv->author = g_strdup (author);
583 priv->description = g_strdup (description);
584 priv->priority_original = priority;
585 }
586
587 void
brasero_plugin_set_group(BraseroPlugin * self,gint group_id)588 brasero_plugin_set_group (BraseroPlugin *self,
589 gint group_id)
590 {
591 BraseroPluginPrivate *priv;
592
593 priv = BRASERO_PLUGIN_PRIVATE (self);
594 priv->group = group_id;
595 }
596
597 guint
brasero_plugin_get_group(BraseroPlugin * self)598 brasero_plugin_get_group (BraseroPlugin *self)
599 {
600 BraseroPluginPrivate *priv;
601
602 priv = BRASERO_PLUGIN_PRIVATE (self);
603 return priv->group;
604 }
605
606 /**
607 * brasero_plugin_get_errors:
608 * @plugin: a #BraseroPlugin.
609 *
610 * This function returns a list of all errors that
611 * prevents the plugin from working properly.
612 *
613 * Returns: a #GSList of #BraseroPluginError structures or %NULL.
614 * It must not be freed.
615 **/
616
617 GSList *
brasero_plugin_get_errors(BraseroPlugin * plugin)618 brasero_plugin_get_errors (BraseroPlugin *plugin)
619 {
620 BraseroPluginPrivate *priv;
621
622 g_return_val_if_fail (BRASERO_IS_PLUGIN (plugin), NULL);
623 priv = BRASERO_PLUGIN_PRIVATE (plugin);
624 return priv->errors;
625 }
626
627 gchar *
brasero_plugin_get_error_string(BraseroPlugin * plugin)628 brasero_plugin_get_error_string (BraseroPlugin *plugin)
629 {
630 gchar *error_string = NULL;
631 BraseroPluginPrivate *priv;
632 GString *string;
633 GSList *iter;
634
635 g_return_val_if_fail (BRASERO_IS_PLUGIN (plugin), NULL);
636
637 priv = BRASERO_PLUGIN_PRIVATE (plugin);
638
639 string = g_string_new (NULL);
640 for (iter = priv->errors; iter; iter = iter->next) {
641 BraseroPluginError *error;
642
643 error = iter->data;
644 switch (error->type) {
645 case BRASERO_PLUGIN_ERROR_MISSING_APP:
646 g_string_append_c (string, '\n');
647 g_string_append_printf (string, _("\"%s\" could not be found in the path"), error->detail);
648 break;
649 case BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN:
650 g_string_append_c (string, '\n');
651 g_string_append_printf (string, _("\"%s\" GStreamer plugin could not be found"), error->detail);
652 break;
653 case BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION:
654 g_string_append_c (string, '\n');
655 g_string_append_printf (string, _("The version of \"%s\" is too old"), error->detail);
656 break;
657 case BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP:
658 g_string_append_c (string, '\n');
659 g_string_append_printf (string, _("\"%s\" is a symbolic link pointing to another program"), error->detail);
660 break;
661 case BRASERO_PLUGIN_ERROR_MISSING_LIBRARY:
662 g_string_append_c (string, '\n');
663 g_string_append_printf (string, _("\"%s\" could not be found"), error->detail);
664 break;
665 case BRASERO_PLUGIN_ERROR_LIBRARY_VERSION:
666 g_string_append_c (string, '\n');
667 g_string_append_printf (string, _("The version of \"%s\" is too old"), error->detail);
668 break;
669 case BRASERO_PLUGIN_ERROR_MODULE:
670 g_string_append_c (string, '\n');
671 g_string_append (string, error->detail);
672 break;
673
674 default:
675 break;
676 }
677 }
678
679 error_string = string->str;
680 g_string_free (string, FALSE);
681 return error_string;
682 }
683
684 static BraseroPluginFlags *
brasero_plugin_get_flags(GSList * flags,BraseroMedia media)685 brasero_plugin_get_flags (GSList *flags,
686 BraseroMedia media)
687 {
688 GSList *iter;
689
690 for (iter = flags; iter; iter = iter->next) {
691 BraseroPluginFlags *flags;
692
693 flags = iter->data;
694 if ((media & flags->media) == media)
695 return flags;
696 }
697
698 return NULL;
699 }
700
701 static GSList *
brasero_plugin_set_flags_real(GSList * flags_list,BraseroMedia media,BraseroBurnFlag supported,BraseroBurnFlag compulsory)702 brasero_plugin_set_flags_real (GSList *flags_list,
703 BraseroMedia media,
704 BraseroBurnFlag supported,
705 BraseroBurnFlag compulsory)
706 {
707 BraseroPluginFlags *flags;
708 BraseroPluginFlagPair *pair;
709
710 flags = brasero_plugin_get_flags (flags_list, media);
711 if (!flags) {
712 flags = g_new0 (BraseroPluginFlags, 1);
713 flags->media = media;
714 flags_list = g_slist_prepend (flags_list, flags);
715 }
716 else for (pair = flags->pairs; pair; pair = pair->next) {
717 /* have a look at the BraseroPluginFlagPair to see if there
718 * is an exactly similar pair of flags or at least which
719 * encompasses it to avoid redundancy. */
720 if ((pair->supported & supported) == supported
721 && (pair->compulsory & compulsory) == compulsory)
722 return flags_list;
723 }
724
725 pair = g_new0 (BraseroPluginFlagPair, 1);
726 pair->supported = supported;
727 pair->compulsory = compulsory;
728
729 pair->next = flags->pairs;
730 flags->pairs = pair;
731
732 return flags_list;
733 }
734
735 void
brasero_plugin_set_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag supported,BraseroBurnFlag compulsory)736 brasero_plugin_set_flags (BraseroPlugin *self,
737 BraseroMedia media,
738 BraseroBurnFlag supported,
739 BraseroBurnFlag compulsory)
740 {
741 BraseroPluginPrivate *priv;
742 GSList *list;
743 GSList *iter;
744
745 priv = BRASERO_PLUGIN_PRIVATE (self);
746
747 list = brasero_media_get_all_list (media);
748 for (iter = list; iter; iter = iter->next) {
749 BraseroMedia medium;
750
751 medium = GPOINTER_TO_INT (iter->data);
752 priv->flags = brasero_plugin_set_flags_real (priv->flags,
753 medium,
754 supported,
755 compulsory);
756 }
757 g_slist_free (list);
758 }
759
760 static gboolean
brasero_plugin_get_all_flags(GSList * flags_list,gboolean check_compulsory,BraseroMedia media,BraseroBurnFlag mask,BraseroBurnFlag current,BraseroBurnFlag * supported_retval,BraseroBurnFlag * compulsory_retval)761 brasero_plugin_get_all_flags (GSList *flags_list,
762 gboolean check_compulsory,
763 BraseroMedia media,
764 BraseroBurnFlag mask,
765 BraseroBurnFlag current,
766 BraseroBurnFlag *supported_retval,
767 BraseroBurnFlag *compulsory_retval)
768 {
769 gboolean found;
770 BraseroPluginFlags *flags;
771 BraseroPluginFlagPair *iter;
772 BraseroBurnFlag supported = BRASERO_BURN_FLAG_NONE;
773 BraseroBurnFlag compulsory = (BRASERO_BURN_FLAG_ALL & mask);
774
775 flags = brasero_plugin_get_flags (flags_list, media);
776 if (!flags) {
777 if (supported_retval)
778 *supported_retval = BRASERO_BURN_FLAG_NONE;
779 if (compulsory_retval)
780 *compulsory_retval = BRASERO_BURN_FLAG_NONE;
781 return FALSE;
782 }
783
784 /* Find all sets of flags that support the current flags */
785 found = FALSE;
786 for (iter = flags->pairs; iter; iter = iter->next) {
787 BraseroBurnFlag compulsory_masked;
788
789 if ((current & iter->supported) != current)
790 continue;
791
792 compulsory_masked = (iter->compulsory & mask);
793 if (check_compulsory
794 && (current & compulsory_masked) != compulsory_masked)
795 continue;
796
797 supported |= iter->supported;
798 compulsory &= compulsory_masked;
799 found = TRUE;
800 }
801
802 if (!found) {
803 if (supported_retval)
804 *supported_retval = BRASERO_BURN_FLAG_NONE;
805 if (compulsory_retval)
806 *compulsory_retval = BRASERO_BURN_FLAG_NONE;
807 return FALSE;
808 }
809
810 if (supported_retval)
811 *supported_retval = supported;
812 if (compulsory_retval)
813 *compulsory_retval = compulsory;
814
815 return TRUE;
816 }
817
818 gboolean
brasero_plugin_check_record_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag current)819 brasero_plugin_check_record_flags (BraseroPlugin *self,
820 BraseroMedia media,
821 BraseroBurnFlag current)
822 {
823 BraseroPluginPrivate *priv;
824
825 priv = BRASERO_PLUGIN_PRIVATE (self);
826 current &= BRASERO_PLUGIN_BURN_FLAG_MASK;
827
828 return brasero_plugin_get_all_flags (priv->flags,
829 TRUE,
830 media,
831 BRASERO_PLUGIN_BURN_FLAG_MASK,
832 current,
833 NULL,
834 NULL);
835 }
836
837 gboolean
brasero_plugin_check_image_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag current)838 brasero_plugin_check_image_flags (BraseroPlugin *self,
839 BraseroMedia media,
840 BraseroBurnFlag current)
841 {
842 BraseroPluginPrivate *priv;
843
844 priv = BRASERO_PLUGIN_PRIVATE (self);
845
846 current &= BRASERO_PLUGIN_IMAGE_FLAG_MASK;
847
848 /* If there is no flag that's no use checking anything. If there is no
849 * flag we don't care about the media and therefore it's always possible
850 * NOTE: that's no the case for other operation like burn/blank. */
851 if (current == BRASERO_BURN_FLAG_NONE)
852 return TRUE;
853
854 return brasero_plugin_get_all_flags (priv->flags,
855 TRUE,
856 media,
857 BRASERO_PLUGIN_IMAGE_FLAG_MASK,
858 current,
859 NULL,
860 NULL);
861 }
862
863 gboolean
brasero_plugin_check_media_restrictions(BraseroPlugin * self,BraseroMedia media)864 brasero_plugin_check_media_restrictions (BraseroPlugin *self,
865 BraseroMedia media)
866 {
867 BraseroPluginPrivate *priv;
868
869 priv = BRASERO_PLUGIN_PRIVATE (self);
870
871 /* no restrictions */
872 if (!priv->flags)
873 return TRUE;
874
875 return (brasero_plugin_get_flags (priv->flags, media) != NULL);
876 }
877
878 gboolean
brasero_plugin_get_record_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag current,BraseroBurnFlag * supported,BraseroBurnFlag * compulsory)879 brasero_plugin_get_record_flags (BraseroPlugin *self,
880 BraseroMedia media,
881 BraseroBurnFlag current,
882 BraseroBurnFlag *supported,
883 BraseroBurnFlag *compulsory)
884 {
885 BraseroPluginPrivate *priv;
886 gboolean result;
887
888 priv = BRASERO_PLUGIN_PRIVATE (self);
889 current &= BRASERO_PLUGIN_BURN_FLAG_MASK;
890
891 result = brasero_plugin_get_all_flags (priv->flags,
892 FALSE,
893 media,
894 BRASERO_PLUGIN_BURN_FLAG_MASK,
895 current,
896 supported,
897 compulsory);
898 if (!result)
899 return FALSE;
900
901 if (supported)
902 *supported &= BRASERO_PLUGIN_BURN_FLAG_MASK;
903 if (compulsory)
904 *compulsory &= BRASERO_PLUGIN_BURN_FLAG_MASK;
905
906 return TRUE;
907 }
908
909 gboolean
brasero_plugin_get_image_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag current,BraseroBurnFlag * supported,BraseroBurnFlag * compulsory)910 brasero_plugin_get_image_flags (BraseroPlugin *self,
911 BraseroMedia media,
912 BraseroBurnFlag current,
913 BraseroBurnFlag *supported,
914 BraseroBurnFlag *compulsory)
915 {
916 BraseroPluginPrivate *priv;
917 gboolean result;
918
919 priv = BRASERO_PLUGIN_PRIVATE (self);
920 current &= BRASERO_PLUGIN_IMAGE_FLAG_MASK;
921
922 result = brasero_plugin_get_all_flags (priv->flags,
923 FALSE,
924 media,
925 BRASERO_PLUGIN_IMAGE_FLAG_MASK,
926 current,
927 supported,
928 compulsory);
929 if (!result)
930 return FALSE;
931
932 if (supported)
933 *supported &= BRASERO_PLUGIN_IMAGE_FLAG_MASK;
934 if (compulsory)
935 *compulsory &= BRASERO_PLUGIN_IMAGE_FLAG_MASK;
936
937 return TRUE;
938 }
939
940 void
brasero_plugin_set_blank_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag supported,BraseroBurnFlag compulsory)941 brasero_plugin_set_blank_flags (BraseroPlugin *self,
942 BraseroMedia media,
943 BraseroBurnFlag supported,
944 BraseroBurnFlag compulsory)
945 {
946 BraseroPluginPrivate *priv;
947
948 priv = BRASERO_PLUGIN_PRIVATE (self);
949 priv->blank_flags = brasero_plugin_set_flags_real (priv->blank_flags,
950 media,
951 supported,
952 compulsory);
953 }
954
955 gboolean
brasero_plugin_check_blank_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag current)956 brasero_plugin_check_blank_flags (BraseroPlugin *self,
957 BraseroMedia media,
958 BraseroBurnFlag current)
959 {
960 BraseroPluginPrivate *priv;
961
962 priv = BRASERO_PLUGIN_PRIVATE (self);
963 current &= BRASERO_PLUGIN_BLANK_FLAG_MASK;
964
965 return brasero_plugin_get_all_flags (priv->blank_flags,
966 TRUE,
967 media,
968 BRASERO_PLUGIN_BLANK_FLAG_MASK,
969 current,
970 NULL,
971 NULL);
972 }
973
974 gboolean
brasero_plugin_get_blank_flags(BraseroPlugin * self,BraseroMedia media,BraseroBurnFlag current,BraseroBurnFlag * supported,BraseroBurnFlag * compulsory)975 brasero_plugin_get_blank_flags (BraseroPlugin *self,
976 BraseroMedia media,
977 BraseroBurnFlag current,
978 BraseroBurnFlag *supported,
979 BraseroBurnFlag *compulsory)
980 {
981 BraseroPluginPrivate *priv;
982 gboolean result;
983
984 priv = BRASERO_PLUGIN_PRIVATE (self);
985 current &= BRASERO_PLUGIN_BLANK_FLAG_MASK;
986
987 result = brasero_plugin_get_all_flags (priv->blank_flags,
988 FALSE,
989 media,
990 BRASERO_PLUGIN_BLANK_FLAG_MASK,
991 current,
992 supported,
993 compulsory);
994 if (!result)
995 return FALSE;
996
997 if (supported)
998 *supported &= BRASERO_PLUGIN_BLANK_FLAG_MASK;
999 if (compulsory)
1000 *compulsory &= BRASERO_PLUGIN_BLANK_FLAG_MASK;
1001
1002 return TRUE;
1003 }
1004
1005 void
brasero_plugin_set_process_flags(BraseroPlugin * plugin,BraseroPluginProcessFlag flags)1006 brasero_plugin_set_process_flags (BraseroPlugin *plugin,
1007 BraseroPluginProcessFlag flags)
1008 {
1009 BraseroPluginPrivate *priv;
1010
1011 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1012 priv->process_flags = flags;
1013 }
1014
1015 gboolean
brasero_plugin_get_process_flags(BraseroPlugin * plugin,BraseroPluginProcessFlag * flags)1016 brasero_plugin_get_process_flags (BraseroPlugin *plugin,
1017 BraseroPluginProcessFlag *flags)
1018 {
1019 BraseroPluginPrivate *priv;
1020
1021 g_return_val_if_fail (flags != NULL, FALSE);
1022
1023 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1024 *flags = priv->process_flags;
1025 return TRUE;
1026 }
1027
1028 const gchar *
brasero_plugin_get_name(BraseroPlugin * plugin)1029 brasero_plugin_get_name (BraseroPlugin *plugin)
1030 {
1031 BraseroPluginPrivate *priv;
1032
1033 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1034 return priv->name;
1035 }
1036
1037 const gchar *
brasero_plugin_get_display_name(BraseroPlugin * plugin)1038 brasero_plugin_get_display_name (BraseroPlugin *plugin)
1039 {
1040 BraseroPluginPrivate *priv;
1041
1042 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1043 return priv->display_name ? priv->display_name:priv->name;
1044
1045 }
1046
1047 const gchar *
brasero_plugin_get_author(BraseroPlugin * plugin)1048 brasero_plugin_get_author (BraseroPlugin *plugin)
1049 {
1050 BraseroPluginPrivate *priv;
1051
1052 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1053 return priv->author;
1054 }
1055
1056 const gchar *
brasero_plugin_get_copyright(BraseroPlugin * plugin)1057 brasero_plugin_get_copyright (BraseroPlugin *plugin)
1058 {
1059 BraseroPluginPrivate *priv;
1060
1061 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1062 return priv->copyright;
1063 }
1064
1065 const gchar *
brasero_plugin_get_website(BraseroPlugin * plugin)1066 brasero_plugin_get_website (BraseroPlugin *plugin)
1067 {
1068 BraseroPluginPrivate *priv;
1069
1070 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1071 return priv->website;
1072 }
1073
1074 const gchar *
brasero_plugin_get_description(BraseroPlugin * plugin)1075 brasero_plugin_get_description (BraseroPlugin *plugin)
1076 {
1077 BraseroPluginPrivate *priv;
1078
1079 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1080 return priv->description;
1081 }
1082
1083 const gchar *
brasero_plugin_get_icon_name(BraseroPlugin * plugin)1084 brasero_plugin_get_icon_name (BraseroPlugin *plugin)
1085 {
1086 return default_icon;
1087 }
1088
1089 guint
brasero_plugin_get_priority(BraseroPlugin * self)1090 brasero_plugin_get_priority (BraseroPlugin *self)
1091 {
1092 BraseroPluginPrivate *priv;
1093
1094 priv = BRASERO_PLUGIN_PRIVATE (self);
1095
1096 if (priv->priority > 0)
1097 return priv->priority;
1098
1099 return priv->priority_original;
1100 }
1101
1102 GType
brasero_plugin_get_gtype(BraseroPlugin * self)1103 brasero_plugin_get_gtype (BraseroPlugin *self)
1104 {
1105 BraseroPluginPrivate *priv;
1106
1107 priv = BRASERO_PLUGIN_PRIVATE (self);
1108
1109 if (priv->errors)
1110 return G_TYPE_NONE;
1111
1112 return priv->type;
1113 }
1114
1115 /**
1116 * Function to initialize and load
1117 */
1118
1119 static void
brasero_plugin_unload(GTypeModule * module)1120 brasero_plugin_unload (GTypeModule *module)
1121 {
1122 BraseroPluginPrivate *priv;
1123
1124 priv = BRASERO_PLUGIN_PRIVATE (module);
1125 if (!priv->handle)
1126 return;
1127
1128 g_module_close (priv->handle);
1129 priv->handle = NULL;
1130 }
1131
1132 static gboolean
brasero_plugin_load_real(BraseroPlugin * plugin)1133 brasero_plugin_load_real (BraseroPlugin *plugin)
1134 {
1135 BraseroPluginPrivate *priv;
1136 BraseroPluginRegisterType register_func;
1137
1138 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1139
1140 if (!priv->path)
1141 return FALSE;
1142
1143 if (priv->handle)
1144 return TRUE;
1145
1146 priv->handle = g_module_open (priv->path, G_MODULE_BIND_LAZY);
1147 if (!priv->handle) {
1148 brasero_plugin_add_error (plugin, BRASERO_PLUGIN_ERROR_MODULE, g_module_error ());
1149 BRASERO_BURN_LOG ("Module %s can't be loaded: g_module_open failed ()", priv->name);
1150 return FALSE;
1151 }
1152
1153 if (!g_module_symbol (priv->handle, "brasero_plugin_register", (gpointer) ®ister_func)) {
1154 BRASERO_BURN_LOG ("it doesn't appear to be a valid brasero plugin");
1155 brasero_plugin_unload (G_TYPE_MODULE (plugin));
1156 return FALSE;
1157 }
1158
1159 priv->type = register_func (plugin);
1160 brasero_burn_debug_setup_module (priv->handle);
1161 return TRUE;
1162 }
1163
1164 static gboolean
brasero_plugin_load(GTypeModule * module)1165 brasero_plugin_load (GTypeModule *module)
1166 {
1167 if (!brasero_plugin_load_real (BRASERO_PLUGIN (module)))
1168 return FALSE;
1169
1170 g_signal_emit (BRASERO_PLUGIN (module),
1171 plugin_signals [LOADED_SIGNAL],
1172 0);
1173 return TRUE;
1174 }
1175
1176 static void
brasero_plugin_priority_changed(GSettings * settings,const gchar * key,BraseroPlugin * self)1177 brasero_plugin_priority_changed (GSettings *settings,
1178 const gchar *key,
1179 BraseroPlugin *self)
1180 {
1181 BraseroPluginPrivate *priv;
1182 gboolean is_active;
1183
1184 priv = BRASERO_PLUGIN_PRIVATE (self);
1185
1186 /* At the moment it can only be the priority key */
1187 priv->priority = g_settings_get_int (settings, BRASERO_PROPS_PRIORITY_KEY);
1188
1189 is_active = brasero_plugin_get_active (self, FALSE);
1190
1191 g_object_notify (G_OBJECT (self), "priority");
1192 if (is_active != brasero_plugin_get_active (self, FALSE))
1193 g_signal_emit (self,
1194 plugin_signals [ACTIVATED_SIGNAL],
1195 0,
1196 is_active);
1197 }
1198
1199 typedef void (* BraseroPluginCheckConfig) (BraseroPlugin *plugin);
1200
1201 /**
1202 * brasero_plugin_check_plugin_ready:
1203 * @plugin: a #BraseroPlugin.
1204 *
1205 * Ask a plugin to check whether it can operate.
1206 * brasero_plugin_can_operate () should be called
1207 * afterwards to know whether it can operate or not.
1208 *
1209 **/
1210 void
brasero_plugin_check_plugin_ready(BraseroPlugin * plugin)1211 brasero_plugin_check_plugin_ready (BraseroPlugin *plugin)
1212 {
1213 GModule *handle;
1214 BraseroPluginPrivate *priv;
1215 BraseroPluginCheckConfig function = NULL;
1216
1217 g_return_if_fail (BRASERO_IS_PLUGIN (plugin));
1218 priv = BRASERO_PLUGIN_PRIVATE (plugin);
1219
1220 if (priv->errors) {
1221 g_slist_foreach (priv->errors, (GFunc) brasero_plugin_error_free, NULL);
1222 g_slist_free (priv->errors);
1223 priv->errors = NULL;
1224 }
1225
1226 handle = g_module_open (priv->path, 0);
1227 if (!handle) {
1228 brasero_plugin_add_error (plugin, BRASERO_PLUGIN_ERROR_MODULE, g_module_error ());
1229 BRASERO_BURN_LOG ("Module %s can't be loaded: g_module_open failed ()", priv->name);
1230 return;
1231 }
1232
1233 if (!g_module_symbol (handle, "brasero_plugin_check_config", (gpointer) &function)) {
1234 g_module_close (handle);
1235 BRASERO_BURN_LOG ("Module %s has no check config function", priv->name);
1236 return;
1237 }
1238
1239 function (BRASERO_PLUGIN (plugin));
1240 g_module_close (handle);
1241 }
1242
1243 static void
brasero_plugin_init_real(BraseroPlugin * object)1244 brasero_plugin_init_real (BraseroPlugin *object)
1245 {
1246 GModule *handle;
1247 gchar *settings_path;
1248 BraseroPluginPrivate *priv;
1249 BraseroPluginRegisterType function = NULL;
1250
1251 priv = BRASERO_PLUGIN_PRIVATE (object);
1252
1253 g_type_module_set_name (G_TYPE_MODULE (object), priv->name);
1254
1255 handle = g_module_open (priv->path, 0);
1256 if (!handle) {
1257 brasero_plugin_add_error (object, BRASERO_PLUGIN_ERROR_MODULE, g_module_error ());
1258 BRASERO_BURN_LOG ("Module %s (at %s) can't be loaded: g_module_open failed ()", priv->name, priv->path);
1259 return;
1260 }
1261
1262 if (!g_module_symbol (handle, "brasero_plugin_register", (gpointer) &function)) {
1263 g_module_close (handle);
1264 BRASERO_BURN_LOG ("Module %s can't be loaded: no register function, priv->name", priv->name);
1265 return;
1266 }
1267
1268 priv->type = function (object);
1269 if (priv->type == G_TYPE_NONE) {
1270 g_module_close (handle);
1271 BRASERO_BURN_LOG ("Module %s encountered an error while registering its capabilities", priv->name);
1272 return;
1273 }
1274
1275 /* now see if we need to override the hardcoded priority of the plugin */
1276 settings_path = g_strconcat ("/org/gnome/brasero/plugins/",
1277 priv->name,
1278 G_DIR_SEPARATOR_S,
1279 NULL);
1280 priv->settings = g_settings_new_with_path (BRASERO_SCHEMA_PLUGINS,
1281 settings_path);
1282 g_free (settings_path);
1283
1284 priv->priority = g_settings_get_int (priv->settings, BRASERO_PROPS_PRIORITY_KEY);
1285
1286 /* Make sure a key is created for each plugin */
1287 if (!priv->priority)
1288 g_settings_set_int (priv->settings, BRASERO_PROPS_PRIORITY_KEY, 0);
1289
1290 g_signal_connect (priv->settings,
1291 "changed",
1292 G_CALLBACK (brasero_plugin_priority_changed),
1293 object);
1294
1295 /* Check if it can operate */
1296 brasero_plugin_check_plugin_ready (object);
1297
1298 g_module_close (handle);
1299 }
1300
1301 static void
brasero_plugin_finalize(GObject * object)1302 brasero_plugin_finalize (GObject *object)
1303 {
1304 BraseroPluginPrivate *priv;
1305
1306 priv = BRASERO_PLUGIN_PRIVATE (object);
1307
1308 if (priv->options) {
1309 g_slist_foreach (priv->options, (GFunc) brasero_plugin_conf_option_free, NULL);
1310 g_slist_free (priv->options);
1311 priv->options = NULL;
1312 }
1313
1314 if (priv->handle) {
1315 brasero_plugin_unload (G_TYPE_MODULE (object));
1316 priv->handle = NULL;
1317 }
1318
1319 if (priv->path) {
1320 g_free (priv->path);
1321 priv->path = NULL;
1322 }
1323
1324 g_free (priv->name);
1325 g_free (priv->display_name);
1326 g_free (priv->author);
1327 g_free (priv->description);
1328
1329 g_slist_foreach (priv->flags, (GFunc) g_free, NULL);
1330 g_slist_free (priv->flags);
1331
1332 g_slist_foreach (priv->blank_flags, (GFunc) g_free, NULL);
1333 g_slist_free (priv->blank_flags);
1334
1335 if (priv->settings) {
1336 g_object_unref (priv->settings);
1337 priv->settings = NULL;
1338 }
1339
1340 if (priv->errors) {
1341 g_slist_foreach (priv->errors, (GFunc) brasero_plugin_error_free, NULL);
1342 g_slist_free (priv->errors);
1343 priv->errors = NULL;
1344 }
1345
1346 G_OBJECT_CLASS (parent_class)->finalize (object);
1347 }
1348
1349 static void
brasero_plugin_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1350 brasero_plugin_set_property (GObject *object,
1351 guint prop_id,
1352 const GValue *value,
1353 GParamSpec *pspec)
1354 {
1355 BraseroPlugin *self;
1356 BraseroPluginPrivate *priv;
1357
1358 g_return_if_fail (BRASERO_IS_PLUGIN (object));
1359
1360 self = BRASERO_PLUGIN (object);
1361 priv = BRASERO_PLUGIN_PRIVATE (self);
1362
1363 switch (prop_id)
1364 {
1365 case PROP_PATH:
1366 /* NOTE: this property can only be set once */
1367 priv->path = g_strdup (g_value_get_string (value));
1368 brasero_plugin_init_real (self);
1369 break;
1370 case PROP_PRIORITY:
1371 break;
1372 default:
1373 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1374 break;
1375 }
1376 }
1377
1378 static void
brasero_plugin_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1379 brasero_plugin_get_property (GObject *object,
1380 guint prop_id,
1381 GValue *value,
1382 GParamSpec *pspec)
1383 {
1384 BraseroPlugin *self;
1385 BraseroPluginPrivate *priv;
1386
1387 g_return_if_fail (BRASERO_IS_PLUGIN (object));
1388
1389 self = BRASERO_PLUGIN (object);
1390 priv = BRASERO_PLUGIN_PRIVATE (self);
1391
1392 switch (prop_id)
1393 {
1394 case PROP_PATH:
1395 g_value_set_string (value, priv->path);
1396 break;
1397 case PROP_PRIORITY:
1398 g_value_set_int (value, priv->priority);
1399 break;
1400 default:
1401 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1402 break;
1403 }
1404 }
1405
1406 static void
brasero_plugin_init(BraseroPlugin * object)1407 brasero_plugin_init (BraseroPlugin *object)
1408 {
1409 BraseroPluginPrivate *priv;
1410
1411 priv = BRASERO_PLUGIN_PRIVATE (object);
1412 priv->type = G_TYPE_NONE;
1413 priv->compulsory = TRUE;
1414 }
1415
1416 static void
brasero_plugin_class_init(BraseroPluginClass * klass)1417 brasero_plugin_class_init (BraseroPluginClass *klass)
1418 {
1419 GObjectClass* object_class = G_OBJECT_CLASS (klass);
1420 GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
1421
1422 g_type_class_add_private (klass, sizeof (BraseroPluginPrivate));
1423
1424 object_class->finalize = brasero_plugin_finalize;
1425 object_class->set_property = brasero_plugin_set_property;
1426 object_class->get_property = brasero_plugin_get_property;
1427
1428 module_class->load = brasero_plugin_load;
1429 module_class->unload = brasero_plugin_unload;
1430
1431 g_object_class_install_property (object_class,
1432 PROP_PATH,
1433 g_param_spec_string ("path",
1434 "Path",
1435 "Path for the module",
1436 NULL,
1437 G_PARAM_STATIC_NAME|G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
1438 g_object_class_install_property (object_class,
1439 PROP_PRIORITY,
1440 g_param_spec_int ("priority",
1441 "Priority",
1442 "Priority of the module",
1443 1,
1444 G_MAXINT,
1445 1,
1446 G_PARAM_STATIC_NAME|G_PARAM_READABLE));
1447
1448 plugin_signals [LOADED_SIGNAL] =
1449 g_signal_new ("loaded",
1450 G_OBJECT_CLASS_TYPE (klass),
1451 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
1452 G_STRUCT_OFFSET (BraseroPluginClass, loaded),
1453 NULL, NULL,
1454 g_cclosure_marshal_VOID__VOID,
1455 G_TYPE_NONE, 0);
1456
1457 plugin_signals [ACTIVATED_SIGNAL] =
1458 g_signal_new ("activated",
1459 G_OBJECT_CLASS_TYPE (klass),
1460 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
1461 G_STRUCT_OFFSET (BraseroPluginClass, activated),
1462 NULL, NULL,
1463 g_cclosure_marshal_VOID__BOOLEAN,
1464 G_TYPE_NONE, 1,
1465 G_TYPE_BOOLEAN);
1466 }
1467
1468 BraseroPlugin *
brasero_plugin_new(const gchar * path)1469 brasero_plugin_new (const gchar *path)
1470 {
1471 if (!path)
1472 return NULL;
1473
1474 return BRASERO_PLUGIN (g_object_new (BRASERO_TYPE_PLUGIN,
1475 "path", path,
1476 NULL));
1477 }
1478