~ubuntu-branches/ubuntu/maverick/brasero/maverick

« back to all changes in this revision

Viewing changes to libbrasero-burn/burn-plugin.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2009-11-26 16:20:01 UTC
  • mto: This revision was merged to the branch mainline in revision 58.
  • Revision ID: james.westby@ubuntu.com-20091126162001-5iw2jzxdx8l31okz
Tags: upstream-2.29.2
ImportĀ upstreamĀ versionĀ 2.29.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <glib.h>
38
38
#include <glib-object.h>
39
39
#include <gmodule.h>
 
40
#include <glib/gi18n-lib.h>
 
41
 
 
42
#include <gst/gst.h>
40
43
 
41
44
#include <gconf/gconf-client.h>
42
45
 
93
96
 
94
97
        GSList *options;
95
98
 
96
 
        gchar *error;
 
99
        GSList *errors;
97
100
 
98
101
        GType type;
99
102
        gchar *path;
139
142
static GTypeModuleClass* parent_class = NULL;
140
143
static guint plugin_signals [LAST_SIGNAL] = { 0 };
141
144
 
 
145
static void
 
146
brasero_plugin_error_free (BraseroPluginError *error)
 
147
{
 
148
        g_free (error->detail);
 
149
        g_free (error);
 
150
}
 
151
 
 
152
void
 
153
brasero_plugin_add_error (BraseroPlugin *plugin,
 
154
                          BraseroPluginErrorType type,
 
155
                          const gchar *detail)
 
156
{
 
157
        BraseroPluginError *error;
 
158
        BraseroPluginPrivate *priv;
 
159
 
 
160
        g_return_if_fail (BRASERO_IS_PLUGIN (plugin));
 
161
 
 
162
        priv = BRASERO_PLUGIN_PRIVATE (plugin);
 
163
 
 
164
        error = g_new0 (BraseroPluginError, 1);
 
165
        error->detail = g_strdup (detail);
 
166
        error->type = type;
 
167
 
 
168
        priv->errors = g_slist_prepend (priv->errors, error);
 
169
}
 
170
 
 
171
void
 
172
brasero_plugin_test_gstreamer_plugin (BraseroPlugin *plugin,
 
173
                                      const gchar *name)
 
174
{
 
175
        GstElement *element;
 
176
 
 
177
        /* Let's see if we've got the plugins we need */
 
178
        element = gst_element_factory_make (name, NULL);
 
179
        if (!element)
 
180
                brasero_plugin_add_error (plugin,
 
181
                                          BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN,
 
182
                                          name);
 
183
        else
 
184
                gst_object_unref (element);
 
185
}
 
186
 
 
187
void
 
188
brasero_plugin_test_app (BraseroPlugin *plugin,
 
189
                         const gchar *name,
 
190
                         const gchar *version_arg,
 
191
                         const gchar *version_format,
 
192
                         gint version [3])
 
193
{
 
194
        gchar *standard_output = NULL;
 
195
        gchar *standard_error = NULL;
 
196
        guint major, minor, sub;
 
197
        gchar *prog_path;
 
198
        GPtrArray *argv;
 
199
        gboolean res;
 
200
        int i;
 
201
 
 
202
        /* First see if this plugin can be used, i.e. if cdrecord is in
 
203
         * the path */
 
204
        prog_path = g_find_program_in_path (name);
 
205
        if (!prog_path) {
 
206
                brasero_plugin_add_error (plugin,
 
207
                                          BRASERO_PLUGIN_ERROR_MISSING_APP,
 
208
                                          name);
 
209
                return;
 
210
        }
 
211
 
 
212
        if (!g_file_test (prog_path, G_FILE_TEST_IS_EXECUTABLE)) {
 
213
                g_free (prog_path);
 
214
                brasero_plugin_add_error (plugin,
 
215
                                          BRASERO_PLUGIN_ERROR_MISSING_APP,
 
216
                                          name);
 
217
                return;
 
218
        }
 
219
 
 
220
        /* make sure that's not a symlink pointing to something with another
 
221
         * name like wodim.
 
222
         * NOTE: we used to test the target and see if it had the same name as
 
223
         * the symlink with GIO. The problem is, when the symlink pointed to
 
224
         * another symlink, then GIO didn't follow that other symlink. And in
 
225
         * the end it didn't work. So forbid all symlink. */
 
226
        if (g_file_test (prog_path, G_FILE_TEST_IS_SYMLINK)) {
 
227
                brasero_plugin_add_error (plugin,
 
228
                                          BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP,
 
229
                                          name);
 
230
                g_free (prog_path);
 
231
                return;
 
232
        }
 
233
        /* Make sure it's a regular file */
 
234
        else if (!g_file_test (prog_path, G_FILE_TEST_IS_REGULAR)) {
 
235
                brasero_plugin_add_error (plugin,
 
236
                                          BRASERO_PLUGIN_ERROR_MISSING_APP,
 
237
                                          name);
 
238
                g_free (prog_path);
 
239
                return;
 
240
        }
 
241
 
 
242
        if (!version_arg) {
 
243
                g_free (prog_path);
 
244
                return;
 
245
        }
 
246
 
 
247
        /* Check version */
 
248
        argv = g_ptr_array_new ();
 
249
        g_ptr_array_add (argv, prog_path);
 
250
        g_ptr_array_add (argv, (gchar *) version_arg);
 
251
        g_ptr_array_add (argv, NULL);
 
252
 
 
253
        res = g_spawn_sync (NULL,
 
254
                            (gchar **) argv->pdata,
 
255
                            NULL,
 
256
                            0,
 
257
                            NULL,
 
258
                            NULL,
 
259
                            &standard_output,
 
260
                            &standard_error,
 
261
                            NULL,
 
262
                            NULL);
 
263
 
 
264
        g_ptr_array_free (argv, TRUE);
 
265
        g_free (prog_path);
 
266
 
 
267
        if (!res) {
 
268
                brasero_plugin_add_error (plugin,
 
269
                                          BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
 
270
                                          name);
 
271
                return;
 
272
        }
 
273
 
 
274
        for (i = 0; i < 3 && version [i] >= 0; i++);
 
275
 
 
276
        if ((standard_output && sscanf (standard_output, version_format, &major, &minor, &sub) == i)
 
277
        ||  (standard_error && sscanf (standard_error, version_format, &major, &minor, &sub) == i)) {
 
278
                if (major < version [0]
 
279
                ||  (version [1] >= 0 && minor < version [1])
 
280
                ||  (version [2] >= 0 && sub < version [2]))
 
281
                        brasero_plugin_add_error (plugin,
 
282
                                                  BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
 
283
                                                  name);
 
284
        }
 
285
        else
 
286
                brasero_plugin_add_error (plugin,
 
287
                                          BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION,
 
288
                                          name);
 
289
 
 
290
        g_free (standard_output);
 
291
        g_free (standard_error);
 
292
}
 
293
 
142
294
void
143
295
brasero_plugin_set_compulsory (BraseroPlugin *self,
144
296
                               gboolean compulsory)
167
319
 
168
320
        priv = BRASERO_PLUGIN_PRIVATE (self);
169
321
 
170
 
        was_active = brasero_plugin_get_active (self);
 
322
        was_active = brasero_plugin_get_active (self, FALSE);
171
323
        priv->active = active;
172
324
 
173
 
        now_active = brasero_plugin_get_active (self);
 
325
        now_active = brasero_plugin_get_active (self, FALSE);
174
326
        if (was_active == now_active)
175
327
                return;
176
328
 
185
337
}
186
338
 
187
339
gboolean
188
 
brasero_plugin_get_active (BraseroPlugin *self)
 
340
brasero_plugin_get_active (BraseroPlugin *plugin,
 
341
                           gboolean ignore_errors)
189
342
{
190
343
        BraseroPluginPrivate *priv;
191
344
 
192
 
        priv = BRASERO_PLUGIN_PRIVATE (self);
 
345
        priv = BRASERO_PLUGIN_PRIVATE (plugin);
 
346
 
 
347
        if (priv->type == G_TYPE_NONE)
 
348
                return FALSE;
193
349
 
194
350
        if (priv->priority < 0)
195
351
                return FALSE;
196
352
 
197
 
        if (priv->type == G_TYPE_NONE)
198
 
                return FALSE;
 
353
        if (priv->errors) {
 
354
                if (!ignore_errors)
 
355
                        return FALSE;
 
356
        }
199
357
 
200
358
        return priv->active;
201
359
}
217
375
        priv->copyright = NULL;
218
376
        g_free (priv->website);
219
377
        priv->website = NULL;
220
 
        if (priv->error) {
221
 
                g_free (priv->error);
222
 
                priv->error = NULL;
223
 
        }
224
378
}
225
379
 
226
380
/**
480
634
        return priv->group;
481
635
}
482
636
 
483
 
const gchar *
484
 
brasero_plugin_get_error (BraseroPlugin *self)
485
 
{
486
 
        BraseroPluginPrivate *priv;
487
 
 
488
 
        priv = BRASERO_PLUGIN_PRIVATE (self);
489
 
        return priv->error;
 
637
/**
 
638
 * brasero_plugin_get_errors:
 
639
 * @plugin: a #BraseroPlugin.
 
640
 *
 
641
 * This function returns a list of all errors that
 
642
 * prevents the plugin from working properly.
 
643
 *
 
644
 * Returns: a #GSList of #BraseroPluginError structures or %NULL.
 
645
 * It must not be freed.
 
646
 **/
 
647
 
 
648
GSList *
 
649
brasero_plugin_get_errors (BraseroPlugin *plugin)
 
650
{
 
651
        BraseroPluginPrivate *priv;
 
652
 
 
653
        g_return_val_if_fail (BRASERO_IS_PLUGIN (plugin), NULL);
 
654
        priv = BRASERO_PLUGIN_PRIVATE (plugin);
 
655
        return priv->errors;
 
656
}
 
657
 
 
658
gchar *
 
659
brasero_plugin_get_error_string (BraseroPlugin *plugin)
 
660
{
 
661
        gchar *error_string = NULL;
 
662
        BraseroPluginPrivate *priv;
 
663
        GString *string;
 
664
        GSList *iter;
 
665
 
 
666
        g_return_val_if_fail (BRASERO_IS_PLUGIN (plugin), NULL);
 
667
 
 
668
        priv = BRASERO_PLUGIN_PRIVATE (plugin);
 
669
 
 
670
        string = g_string_new (NULL);
 
671
        for (iter = priv->errors; iter; iter = iter->next) {
 
672
                BraseroPluginError *error;
 
673
 
 
674
                error = iter->data;
 
675
                switch (error->type) {
 
676
                        case BRASERO_PLUGIN_ERROR_MISSING_APP:
 
677
                                g_string_append_c (string, '\n');
 
678
                                g_string_append_printf (string, _("\"%s\" could not be found in the path"), error->detail);
 
679
                                break;
 
680
                        case BRASERO_PLUGIN_ERROR_MISSING_GSTREAMER_PLUGIN:
 
681
                                g_string_append_c (string, '\n');
 
682
                                g_string_append_printf (string, _("\"%s\" Gstreamer plugin could not be found"), error->detail);
 
683
                                break;
 
684
                        case BRASERO_PLUGIN_ERROR_WRONG_APP_VERSION:
 
685
                                g_string_append_c (string, '\n');
 
686
                                g_string_append_printf (string, _("The version of \"%s\" is too old"), error->detail);
 
687
                                break;
 
688
                        case BRASERO_PLUGIN_ERROR_SYMBOLIC_LINK_APP:
 
689
                                g_string_append_c (string, '\n');
 
690
                                g_string_append_printf (string, _("\"%s\" is a symbolic link pointing to another program"), error->detail);
 
691
                                break;
 
692
                        case BRASERO_PLUGIN_ERROR_MISSING_LIBRARY:
 
693
                                g_string_append_c (string, '\n');
 
694
                                g_string_append_printf (string, _("\"%s\" could not be found"), error->detail);
 
695
                                break;
 
696
                        case BRASERO_PLUGIN_ERROR_LIBRARY_VERSION:
 
697
                                g_string_append_c (string, '\n');
 
698
                                g_string_append_printf (string, _("The version of \"%s\" is too old"), error->detail);
 
699
                                break;
 
700
                        case BRASERO_PLUGIN_ERROR_MODULE:
 
701
                                g_string_append_c (string, '\n');
 
702
                                g_string_append (string, error->detail);
 
703
                                break;
 
704
 
 
705
                        default:
 
706
                                break;
 
707
                }
 
708
        }
 
709
 
 
710
        error_string = string->str;
 
711
        g_string_free (string, FALSE);
 
712
        return error_string;
490
713
}
491
714
 
492
715
static BraseroPluginFlags *
582
805
 
583
806
        flags = brasero_plugin_get_flags (flags_list, media);
584
807
        if (!flags) {
585
 
 
586
808
                if (supported_retval)
587
809
                        *supported_retval = BRASERO_BURN_FLAG_NONE;
588
810
                if (compulsory_retval)
907
1129
        BraseroPluginPrivate *priv;
908
1130
 
909
1131
        priv = BRASERO_PLUGIN_PRIVATE (self);
 
1132
 
 
1133
        if (priv->errors)
 
1134
                return G_TYPE_NONE;
 
1135
 
910
1136
        return priv->type;
911
1137
}
912
1138
 
930
1156
static gboolean
931
1157
brasero_plugin_load_real (BraseroPlugin *plugin) 
932
1158
{
933
 
        gchar *error = NULL;
934
1159
        BraseroPluginPrivate *priv;
935
1160
        BraseroPluginRegisterType register_func;
936
1161
 
944
1169
 
945
1170
        priv->handle = g_module_open (priv->path, G_MODULE_BIND_LAZY);
946
1171
        if (!priv->handle) {
947
 
                priv->error = g_strdup (g_module_error ());
 
1172
                brasero_plugin_add_error (plugin, BRASERO_PLUGIN_ERROR_MODULE, g_module_error ());
 
1173
                BRASERO_BURN_LOG ("Module %s can't be loaded: g_module_open failed ()", priv->name);
948
1174
                return FALSE;
949
1175
        }
950
1176
 
954
1180
                return FALSE;
955
1181
        }
956
1182
 
957
 
        priv->type = register_func (plugin, &error);
958
 
        if (error) {
959
 
                if (priv->error)
960
 
                        g_free (priv->error);
961
 
                priv->error = error;
962
 
        }
963
 
 
 
1183
        priv->type = register_func (plugin);
964
1184
        brasero_burn_debug_setup_module (priv->handle);
965
1185
        return TRUE;
966
1186
}
999
1219
        else
1000
1220
                priv->priority = gconf_value_get_int (value);
1001
1221
 
1002
 
        is_active = brasero_plugin_get_active (self);
 
1222
        is_active = brasero_plugin_get_active (self, FALSE);
1003
1223
 
1004
1224
        g_object_notify (G_OBJECT (self), "priority");
1005
 
        if (is_active != brasero_plugin_get_active (self))
 
1225
        if (is_active != brasero_plugin_get_active (self, FALSE))
1006
1226
                g_signal_emit (self,
1007
1227
                               plugin_signals [ACTIVATED_SIGNAL],
1008
1228
                               0,
1009
 
                               brasero_plugin_get_active (self));
 
1229
                               is_active);
 
1230
}
 
1231
 
 
1232
typedef void    (* BraseroPluginCheckConfig)    (BraseroPlugin *plugin);
 
1233
 
 
1234
/**
 
1235
 * brasero_plugin_check_plugin_ready:
 
1236
 * @plugin: a #BraseroPlugin.
 
1237
 *
 
1238
 * Ask a plugin to check whether it can operate.
 
1239
 * brasero_plugin_can_operate () should be called
 
1240
 * afterwards to know whether it can operate or not.
 
1241
 *
 
1242
 **/
 
1243
void
 
1244
brasero_plugin_check_plugin_ready (BraseroPlugin *plugin)
 
1245
{
 
1246
        GModule *handle;
 
1247
        BraseroPluginPrivate *priv;
 
1248
        BraseroPluginCheckConfig function = NULL;
 
1249
 
 
1250
        g_return_if_fail (BRASERO_IS_PLUGIN (plugin));
 
1251
        priv = BRASERO_PLUGIN_PRIVATE (plugin);
 
1252
 
 
1253
        if (priv->errors) {
 
1254
                g_slist_foreach (priv->errors, (GFunc) brasero_plugin_error_free, NULL);
 
1255
                g_slist_free (priv->errors);
 
1256
                priv->errors = NULL;
 
1257
        }
 
1258
 
 
1259
        handle = g_module_open (priv->path, 0);
 
1260
        if (!handle) {
 
1261
                brasero_plugin_add_error (plugin, BRASERO_PLUGIN_ERROR_MODULE, g_module_error ());
 
1262
                BRASERO_BURN_LOG ("Module %s can't be loaded: g_module_open failed ()", priv->name);
 
1263
                return;
 
1264
        }
 
1265
 
 
1266
        if (!g_module_symbol (handle, "brasero_plugin_check_config", (gpointer) &function)) {
 
1267
                g_module_close (handle);
 
1268
                BRASERO_BURN_LOG ("Module %s has no check config function", priv->name);
 
1269
                return;
 
1270
        }
 
1271
 
 
1272
        function (BRASERO_PLUGIN (plugin));
 
1273
        g_module_close (handle);
1010
1274
}
1011
1275
 
1012
1276
static void
1018
1282
        GConfClient *client;
1019
1283
        gchar *priority_path;
1020
1284
        BraseroPluginPrivate *priv;
1021
 
        BraseroPluginRegisterType function;
 
1285
        BraseroPluginRegisterType function = NULL;
1022
1286
 
1023
1287
        priv = BRASERO_PLUGIN_PRIVATE (object);
1024
1288
 
1025
1289
        g_type_module_set_name (G_TYPE_MODULE (object), priv->name);
1026
1290
 
1027
 
        handle = g_module_open (priv->name, 0);
 
1291
        handle = g_module_open (priv->path, 0);
1028
1292
        if (!handle) {
1029
 
                BRASERO_BURN_LOG ("Module can't be loaded: g_module_open failed");
 
1293
                brasero_plugin_add_error (object, BRASERO_PLUGIN_ERROR_MODULE, g_module_error ());
 
1294
                BRASERO_BURN_LOG ("Module %s (at %s) can't be loaded: g_module_open failed ()", priv->name, priv->path);
1030
1295
                return;
1031
1296
        }
1032
1297
 
1033
1298
        if (!g_module_symbol (handle, "brasero_plugin_register", (gpointer) &function)) {
1034
1299
                g_module_close (handle);
1035
 
                BRASERO_BURN_LOG ("Module can't be loaded: no register function");
 
1300
                BRASERO_BURN_LOG ("Module %s can't be loaded: no register function, priv->name", priv->name);
1036
1301
                return;
1037
1302
        }
1038
1303
 
1039
 
        priv->type = function (BRASERO_PLUGIN (object), &priv->error);
 
1304
        priv->type = function (object);
1040
1305
        if (priv->type == G_TYPE_NONE) {
1041
1306
                g_module_close (handle);
1042
 
                BRASERO_BURN_LOG ("Module encountered an error while registering its capabilities:\n%s",
1043
 
                                  priv->error ? priv->error:"unknown error");
 
1307
                BRASERO_BURN_LOG ("Module %s encountered an error while registering its capabilities", priv->name);
1044
1308
                return;
1045
1309
        }
1046
1310
 
1047
 
        BRASERO_BURN_LOG ("Module %s successfully loaded", priv->name);
1048
 
        g_module_close (handle);
1049
 
 
1050
1311
        /* now see if we need to override the hardcoded priority of the plugin */
1051
1312
        client = gconf_client_get_default ();
1052
1313
        priority_path = brasero_plugin_get_gconf_priority_key (object);
1078
1339
        /* No need to emit notify:: here */
1079
1340
        g_free (priority_path);
1080
1341
        g_object_unref (client);
 
1342
 
 
1343
        /* Check if it can operate */
 
1344
        brasero_plugin_check_plugin_ready (object);
 
1345
 
 
1346
        g_module_close (handle);
1081
1347
}
1082
1348
 
1083
1349
static void
1122
1388
                g_object_unref (client);
1123
1389
        }
1124
1390
 
1125
 
        if (priv->error) {
1126
 
                g_free (priv->error);
1127
 
                priv->error = NULL;
 
1391
        if (priv->errors) {
 
1392
                g_slist_foreach (priv->errors, (GFunc) brasero_plugin_error_free, NULL);
 
1393
                g_slist_free (priv->errors);
 
1394
                priv->errors = NULL;
1128
1395
        }
1129
1396
 
1130
1397
        G_OBJECT_CLASS (parent_class)->finalize (object);