00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00024 #include <gio/gio.h>
00025
00026 #include "application-data.h"
00027 #include "plugins.h"
00028
00029
00030
00031 GList *plugin_list_new (const gchar *plugins_dir)
00032 {
00033 const gchar *filename = NULL;
00034 gchar *pluginname = NULL;
00035 GError *err = NULL;
00036 GFile *file = g_file_new_for_path (plugins_dir);
00037 GFileEnumerator *fileenum = g_file_enumerate_children (file, "standard::name", G_FILE_QUERY_INFO_NONE, NULL, &err);
00038 GFileInfo *current = NULL;
00039 gint len = 0;
00040 GList *list = NULL;
00041
00042 if (err) {
00043 g_warning ("plugin_list_new: Error while trying to read the directory containing plugins (%s)", err->message);
00044 g_clear_error (&err);
00045 return NULL;
00046 }
00047
00048 while ((current = g_file_enumerator_next_file (fileenum, NULL, &err)) != NULL) {
00049 if (err) {
00050 g_warning ("plugin_list_new: Error while reading a file in the plugins directory (%s)", err->message);
00051 g_clear_error (&err);
00052 } else {
00053 filename = g_file_info_get_name (current);
00054 len = g_strrstr (filename, ".so") - filename;
00055
00056 pluginname = g_strndup (filename, len);
00057 list = g_list_prepend (list, plugin_new (plugins_dir, pluginname));
00058
00059 g_free (pluginname);
00060 g_object_unref (current);
00061 }
00062 }
00063
00064 g_object_unref (fileenum);
00065 g_object_unref (file);
00066 return list;
00067 }
00068
00069
00070
00071 void plugin_list_free (GList *list)
00072 {
00073 if (list) {
00074 GList *iter = list;
00075 do {
00076 plugin_free (iter->data);
00077 } while ((iter = g_list_next (iter)) != NULL);
00078 }
00079
00080 g_list_free (list);
00081 }
00082
00083
00084
00085 plugin_t *plugin_new (const gchar *plugins_dir, const gchar *name)
00086 {
00087 plugin_t *pt = g_malloc (sizeof (plugin_t));
00088 gchar *path = g_strdup_printf ("%s/%s.so", plugins_dir, name);
00089 char *err = NULL;
00090
00091 pt->name = g_strdup (name);
00092 pt->handle = dlopen (path, RTLD_NOW);
00093 g_free (path);
00094
00095 err = dlerror ();
00096 if (err) {
00097 g_warning ("plugin_new: %s", err);
00098 return NULL;
00099 }
00100
00101 return pt;
00102 }
00103
00104
00105
00106 void *plugin_get_symbol (plugin_t *pt, const char *symbol_name, gboolean display_warnings)
00107 {
00108 g_return_val_if_fail (pt != NULL, NULL);
00109
00110 char *err = NULL;
00111 void *symbol = NULL;
00112
00113 * (void **) &symbol = dlsym (pt->handle, symbol_name);
00114 err = dlerror ();
00115 if (err) {
00116 if (display_warnings)
00117 g_warning ("plugin_get_symbol: %s", err);
00118 return NULL;
00119 }
00120
00121 return symbol;
00122 }
00123
00124
00125
00126 void plugin_free (plugin_t *pt)
00127 {
00128 dlclose (pt->handle);
00129 g_free (pt->name);
00130 g_free (pt);
00131 }
00132
00133
00134 plugin_t *plugin_list_find_custom_list (GList *list, const gchar *name)
00135 {
00136 GList *iter = list;
00137 plugin_t *pt = NULL;
00138
00139 if (iter) {
00140 do {
00141 pt = iter->data;
00142 if (g_strcmp0 (name, pt->name) == 0)
00143 return pt;
00144 } while ((iter = g_list_next (iter)) != NULL);
00145 }
00146
00147 return NULL;
00148 }
00149
00150
00151
00152 plugin_t *plugin_list_find (const gchar *name)
00153 {
00154 synema_instance_t *inst = synema_instance ();
00155 return (plugin_list_find_custom_list (inst->plugins_list, name));
00156 }
00157
00158
00159
00160 gboolean plugin_exists (const gchar *name)
00161 {
00162 return plugin_list_find (name) != NULL;
00163 }
00164
00165
00166
00167 gchar *plugin_get_display_name (plugin_t *pt)
00168 {
00169 g_return_val_if_fail (pt != NULL, NULL);
00170
00171 gchar *(*func)(frame_t *) = NULL;
00172
00173 *(void **) (&func) = plugin_get_symbol (pt, "get_display_name", TRUE);
00174 if (!func) {
00175 g_warning ("plugin_get_display_name: Failed to get the display name");
00176 return NULL;
00177 }
00178
00179 return func(NULL);
00180 }
00181
00182
00183
00184 GList *plugin_get_time_periods (plugin_t *pt)
00185 {
00186 g_return_val_if_fail (pt != NULL, NULL);
00187
00188 GList *(*func)() = NULL;
00189
00190 *(void **) (&func) = plugin_get_symbol (pt, "build_time_periods", TRUE);
00191 if (!func) {
00192 g_warning ("plugin_get_time_periods: Failed to get the list of time periods");
00193 return NULL;
00194 }
00195
00196 return func();
00197 }