00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <libheraia.h>
00030
00031 static heraia_plugin_t *get_plugin_handle(heraia_struct_t *main_struct, heraia_plugin_t *plugin,
00032 const gchar *full_filename, const gchar *filename);
00033 static heraia_plugin_t *get_plugin_init_symbol(heraia_struct_t *main_struct, heraia_plugin_t *plugin);
00034 static void init_plugin(heraia_struct_t *main_struct, heraia_plugin_t *plugin, const gchar *filename, guint plugins_nb);
00035 static void load_one_plugin(heraia_struct_t *main_struct, const gchar *filename, guint plugins_nb);
00036
00037
00038
00039
00040
00041
00042
00043 gboolean plugin_capable(void)
00044 {
00045 return g_module_supported();
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 heraia_plugin_t *new_plugin(void)
00057 {
00058 heraia_plugin_t *new = NULL;
00059
00060 new = (heraia_plugin_t *) g_malloc0(sizeof(heraia_plugin_t));
00061
00062 new->state = PLUGIN_STATE_NEW;
00063 new->handle = NULL;
00064 new->path = NULL;
00065 new->filename = NULL;
00066 new->info = (plugin_info_t *) g_malloc0(sizeof(plugin_info_t));
00067 new->filter = (plugin_filter_t *) g_malloc0(sizeof(plugin_filter_t));
00068 new->error = NULL;
00069 new->extra = NULL;
00070
00071
00072 new->init_proc = NULL;
00073
00074 new->quit_proc = NULL;
00075
00076 new->run_proc = NULL;
00077
00078 return new;
00079
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 void free_plugin(heraia_plugin_t *plugin)
00089 {
00090 if (plugin != NULL)
00091 {
00092 if (plugin->handle != NULL)
00093 {
00094 g_module_close(plugin->handle);
00095 }
00096
00097 if (plugin->info != NULL)
00098 {
00099 g_free(plugin->info->name);
00100 g_free(plugin->info->version);
00101 g_free(plugin->info->summary);
00102 g_free(plugin->info->description);
00103 g_free(plugin->info->author);
00104 g_free(plugin->info->homepage);
00105 g_free(plugin->info);
00106 }
00107
00108 if (plugin->filter != NULL)
00109 {
00110 g_free(plugin->filter->extensions);
00111 g_free(plugin->filter);
00112 }
00113
00114 g_free(plugin->path);
00115 g_free(plugin->filename);
00116 g_free(plugin->error);
00117 g_free(plugin->extra);
00118
00119 g_free(plugin);
00120 }
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static heraia_plugin_t *get_plugin_handle(heraia_struct_t *main_struct, heraia_plugin_t *plugin,
00136 const gchar *full_filename, const gchar *filename)
00137 {
00138 if (plugin != NULL)
00139 {
00140
00141 plugin->handle = g_module_open(full_filename, G_MODULE_BIND_MASK);
00142
00143 if (plugin->handle == NULL)
00144 {
00145 log_message(main_struct, G_LOG_LEVEL_WARNING, "Could not open plugin %s - %s", filename, g_module_error());
00146 }
00147 }
00148
00149 return plugin;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 static heraia_plugin_t *get_plugin_init_symbol(heraia_struct_t *main_struct, heraia_plugin_t *plugin)
00161 {
00162 heraia_plugin_t *(*heraia_plugin_init)(heraia_plugin_t *);
00163 gboolean get_symbol = FALSE;
00164
00165 if (plugin != NULL && plugin->handle != NULL)
00166 {
00167 get_symbol = g_module_symbol(plugin->handle, "heraia_plugin_init", (gpointer *)(&heraia_plugin_init));
00168
00169 if (get_symbol == FALSE)
00170 {
00171 log_message(main_struct, G_LOG_LEVEL_WARNING, "%s", g_module_error());
00172 free_plugin(plugin);
00173 return NULL;
00174 }
00175 else
00176 {
00177
00178 plugin = heraia_plugin_init(plugin);
00179 return plugin;
00180 }
00181 }
00182 else
00183 {
00184 free_plugin(plugin);
00185 return NULL;
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 static void init_plugin(heraia_struct_t *main_struct, heraia_plugin_t *plugin, const gchar *filename, guint plugins_nb)
00200 {
00201 if (plugin != NULL)
00202 {
00203 plugin->info->id = plugins_nb;
00204 main_struct->plugins_list = g_list_append(main_struct->plugins_list, plugin);
00205 log_message(main_struct, G_LOG_LEVEL_INFO, "plugin %s loaded.", filename);
00206
00207 plugin->init_proc(main_struct);
00208
00209 if (plugin->info->type == HERAIA_PLUGIN_ACTION)
00210 {
00211 add_entry_to_plugins_menu(main_struct, plugin);
00212 }
00213
00214 }
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 static void load_one_plugin(heraia_struct_t *main_struct, const gchar *filename, guint plugins_nb)
00226 {
00227 const gchar *full_filename = NULL;
00228 heraia_plugin_t *plugin = NULL;
00229 gchar *ext = g_strdup_printf(".%s", G_MODULE_SUFFIX);
00230
00231 full_filename = g_build_filename(PLUGINS_DIR, filename, NULL);
00232
00233
00234 if ( (g_file_test(full_filename, G_FILE_TEST_IS_DIR) == FALSE) &&
00235 (strcmp(strrchr(filename, '.'), ext) == 0)
00236 )
00237 {
00238 plugin = new_plugin();
00239 plugin->path = g_strdup_printf("%s", PLUGINS_DIR);
00240 plugin->filename = g_strdup_printf("%s", filename);
00241
00242 plugin = get_plugin_handle(main_struct, plugin, full_filename, filename);
00243 plugin = get_plugin_init_symbol(main_struct, plugin);
00244
00245 init_plugin(main_struct, plugin, filename, plugins_nb);
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256 void load_plugins(heraia_struct_t *main_struct)
00257 {
00258 GDir *plugins_dir = NULL;
00259 GError *error = NULL;
00260 const gchar *filename = NULL;
00261 unsigned int plugins_nb = 0;
00262
00263
00264
00265 plugins_dir = g_dir_open(PLUGINS_DIR, 0, &error);
00266
00267 if (plugins_dir == NULL)
00268 {
00269 log_message(main_struct, G_LOG_LEVEL_WARNING, "%s", error->message);
00270 g_error_free(error);
00271 }
00272 else
00273 {
00274 while ((filename = g_dir_read_name(plugins_dir)) != NULL)
00275 {
00276 if (g_str_has_suffix(filename, "libheraia.so") == FALSE)
00277 {
00278 load_one_plugin(main_struct, filename, ++plugins_nb);
00279 }
00280 }
00281 g_dir_close(plugins_dir);
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 void add_entry_to_plugins_menu(heraia_struct_t *main_struct, heraia_plugin_t *plugin)
00294 {
00295 if (plugin != NULL && plugin->info != NULL && plugin->info->name != NULL)
00296 {
00297
00298 plugin->cmi_entry = GTK_CHECK_MENU_ITEM(gtk_check_menu_item_new_with_label(plugin->info->name));
00299
00300
00301 gtk_menu_shell_append(GTK_MENU_SHELL(heraia_get_widget(main_struct->xmls->main, "plugins_menu")), GTK_WIDGET(plugin->cmi_entry));
00302
00303
00304 g_signal_connect(G_OBJECT(plugin->cmi_entry), "toggled", G_CALLBACK(plugin->run_proc), main_struct);
00305
00306
00307 gtk_widget_show(GTK_WIDGET(plugin->cmi_entry));
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 heraia_plugin_t *find_plugin_by_name(GList *plugins_list, gchar *name)
00321 {
00322 GList *list = g_list_first(plugins_list);
00323 heraia_plugin_t *plugin = NULL;
00324 gboolean stop = FALSE;
00325
00326 while (list != NULL && stop != TRUE)
00327 {
00328 plugin = (heraia_plugin_t *) list->data;
00329 if (plugin != NULL && plugin->info != NULL)
00330 {
00331 if (strcmp(plugin->info->name, name) == 0)
00332 stop = TRUE;
00333 }
00334 list = list->next;
00335 }
00336
00337 if (stop == TRUE)
00338 return plugin;
00339 else
00340 return NULL;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 gboolean load_plugin_xml(heraia_struct_t *main_struct, heraia_plugin_t *plugin)
00354 {
00355 gchar *filename = NULL;
00356
00357 filename = g_strdup_printf("%s.gtkbuilder", plugin->info->name);
00358
00359 plugin->xml = load_xml_file(main_struct->location_list, filename);
00360
00361 g_free(filename);
00362
00363 if (plugin->xml == NULL)
00364 return FALSE;
00365 else
00366 return TRUE;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375 void refresh_all_plugins(heraia_struct_t *main_struct)
00376 {
00377
00378 GList *list = g_list_first(main_struct->plugins_list);
00379 heraia_plugin_t *plugin = NULL;
00380
00381 while (list != NULL)
00382 {
00383 plugin = (heraia_plugin_t *) list->data;
00384
00385 if (plugin != NULL && plugin->refresh_proc != NULL)
00386 {
00387 plugin->refresh_proc(main_struct, list->data);
00388 }
00389
00390 list = list->next;
00391 }
00392 }