comparison src/audacious/pluginenum.c @ 3437:3092a8b3fe34 trunk

Big plugin system changes (part 1 of who knows, it's still a big mess): - remove plugin_matrix, replacing it with a mowgli.dictionary of all loaded plugins pointing back to their handles - input_is_enabled() craq -> gboolean plugin::enabled (this craq was pointed out by ccr) - consolidate a lot of crap in ui_preferences.c (a LOT more to come) - introduce probably countless loads of bugs and SIGSEGVs. - you WILL need to recompile plugins after this, and some which do not use C99-style struct initialisers will likely fail to build.
author William Pitcock <nenolod@atheme.org>
date Fri, 07 Sep 2007 03:20:28 -0500
parents e21930ccd5a8
children 7043b5c94a94
comparison
equal deleted inserted replaced
3436:a630ecae6708 3437:3092a8b3fe34
29 29
30 #ifndef SHARED_SUFFIX 30 #ifndef SHARED_SUFFIX
31 # define SHARED_SUFFIX G_MODULE_SUFFIX 31 # define SHARED_SUFFIX G_MODULE_SUFFIX
32 #endif 32 #endif
33 33
34 #include "pluginenum.h"
35
36 #include <glib.h> 34 #include <glib.h>
37 #include <gmodule.h> 35 #include <gmodule.h>
38 #include <glib/gprintf.h> 36 #include <glib/gprintf.h>
39 #include <string.h> 37 #include <string.h>
40 38
49 #include "general.h" 47 #include "general.h"
50 #include "input.h" 48 #include "input.h"
51 #include "output.h" 49 #include "output.h"
52 #include "visualization.h" 50 #include "visualization.h"
53 #include "discovery.h" 51 #include "discovery.h"
52
53 #include "pluginenum.h"
54
54 const gchar *plugin_dir_list[] = { 55 const gchar *plugin_dir_list[] = {
55 PLUGINSUBS, 56 PLUGINSUBS,
56 NULL 57 NULL
57 }; 58 };
58 59
59 GHashTable *plugin_matrix = NULL;
60 GList *lowlevel_list = NULL; 60 GList *lowlevel_list = NULL;
61 extern GList *vfs_transports; 61 extern GList *vfs_transports;
62
63 mowgli_dictionary_t *plugin_dict = NULL;
62 64
63 static gint 65 static gint
64 inputlist_compare_func(gconstpointer a, gconstpointer b) 66 inputlist_compare_func(gconstpointer a, gconstpointer b)
65 { 67 {
66 const InputPlugin *ap = a, *bp = b; 68 const InputPlugin *ap = a, *bp = b;
121 } 123 }
122 124
123 static gboolean 125 static gboolean
124 plugin_is_duplicate(const gchar * filename) 126 plugin_is_duplicate(const gchar * filename)
125 { 127 {
126 GList *l; 128 gchar *base_filename = g_path_get_basename(filename);
127 const gchar *basename = g_basename(filename); 129
128 130 if (mowgli_dictionary_retrieve(plugin_dict, base_filename) != NULL)
129 /* FIXME: messy stuff */ 131 {
130 132 g_free(base_filename);
131 for (l = ip_data.input_list; l; l = g_list_next(l)) 133 return TRUE;
132 if (!strcmp(basename, g_basename(INPUT_PLUGIN(l->data)->filename))) 134 }
133 return TRUE; 135
134 136 g_free(base_filename);
135 for (l = op_data.output_list; l; l = g_list_next(l))
136 if (!strcmp(basename, g_basename(OUTPUT_PLUGIN(l->data)->filename)))
137 return TRUE;
138
139 for (l = ep_data.effect_list; l; l = g_list_next(l))
140 if (!strcmp(basename, g_basename(EFFECT_PLUGIN(l->data)->filename)))
141 return TRUE;
142
143 for (l = gp_data.general_list; l; l = g_list_next(l))
144 if (!strcmp(basename, g_basename(GENERAL_PLUGIN(l->data)->filename)))
145 return TRUE;
146
147 for (l = vp_data.vis_list; l; l = g_list_next(l))
148 if (!strcmp(basename, g_basename(VIS_PLUGIN(l->data)->filename)))
149 return TRUE;
150
151 for (l = lowlevel_list; l; l = g_list_next(l))
152 if (!strcmp(basename, g_basename(LOWLEVEL_PLUGIN(l->data)->filename)))
153 return TRUE;
154
155 for (l = dp_data.discovery_list; l; l = g_list_next(l))
156 if (!strcmp(basename, g_basename(DISCOVERY_PLUGIN(l->data)->filename)))
157 return TRUE;
158 137
159 return FALSE; 138 return FALSE;
160 } 139 }
161 140
162 141 gboolean
163 #define PLUGIN_GET_INFO(x) ((PluginGetInfoFunc)(x))() 142 plugin_is_enabled(const gchar *filename)
164 typedef Plugin * (*PluginGetInfoFunc) (void); 143 {
144 Plugin *plugin = mowgli_dictionary_retrieve(plugin_dict, filename);
145
146 if (!plugin)
147 return FALSE;
148
149 return plugin->enabled;
150 }
151
152 void
153 plugin_set_enabled(const gchar *filename, gboolean enabled)
154 {
155 Plugin *plugin = mowgli_dictionary_retrieve(plugin_dict, filename);
156
157 if (!plugin)
158 return;
159
160 plugin->enabled = enabled;
161 }
162
163 Plugin *
164 plugin_get_plugin(const gchar *filename)
165 {
166 return mowgli_dictionary_retrieve(plugin_dict, filename);
167 }
165 168
166 static void 169 static void
167 input_plugin_init(Plugin * plugin) 170 input_plugin_init(Plugin * plugin)
168 { 171 {
169 InputPlugin *p = INPUT_PLUGIN(plugin); 172 InputPlugin *p = INPUT_PLUGIN(plugin);
178 p->set_info_text = input_set_info_text; 181 p->set_info_text = input_set_info_text;
179 p->set_status_buffering = input_set_status_buffering; 182 p->set_status_buffering = input_set_status_buffering;
180 183
181 ip_data.input_list = g_list_append(ip_data.input_list, p); 184 ip_data.input_list = g_list_append(ip_data.input_list, p);
182 185
183 g_hash_table_replace(plugin_matrix, g_path_get_basename(p->filename), 186 p->enabled = TRUE;
184 GINT_TO_POINTER(1)); 187
188 /* XXX: we need something better than p->filename if plugins
189 will eventually provide multiple plugins --nenolod */
190 mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
185 } 191 }
186 192
187 static void 193 static void
188 output_plugin_init(Plugin * plugin) 194 output_plugin_init(Plugin * plugin)
189 { 195 {
190 OutputPlugin *p = OUTPUT_PLUGIN(plugin); 196 OutputPlugin *p = OUTPUT_PLUGIN(plugin);
191 op_data.output_list = g_list_append(op_data.output_list, p); 197 op_data.output_list = g_list_append(op_data.output_list, p);
198
199 mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
192 } 200 }
193 201
194 static void 202 static void
195 effect_plugin_init(Plugin * plugin) 203 effect_plugin_init(Plugin * plugin)
196 { 204 {
197 EffectPlugin *p = EFFECT_PLUGIN(plugin); 205 EffectPlugin *p = EFFECT_PLUGIN(plugin);
198 ep_data.effect_list = g_list_append(ep_data.effect_list, p); 206 ep_data.effect_list = g_list_append(ep_data.effect_list, p);
207
208 mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
199 } 209 }
200 210
201 static void 211 static void
202 general_plugin_init(Plugin * plugin) 212 general_plugin_init(Plugin * plugin)
203 { 213 {
204 GeneralPlugin *p = GENERAL_PLUGIN(plugin); 214 GeneralPlugin *p = GENERAL_PLUGIN(plugin);
205 gp_data.general_list = g_list_append(gp_data.general_list, p); 215 gp_data.general_list = g_list_append(gp_data.general_list, p);
216
217 mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
206 } 218 }
207 219
208 static void 220 static void
209 vis_plugin_init(Plugin * plugin) 221 vis_plugin_init(Plugin * plugin)
210 { 222 {
211 VisPlugin *p = VIS_PLUGIN(plugin); 223 VisPlugin *p = VIS_PLUGIN(plugin);
212 p->disable_plugin = vis_disable_plugin; 224 p->disable_plugin = vis_disable_plugin;
213 vp_data.vis_list = g_list_append(vp_data.vis_list, p); 225 vp_data.vis_list = g_list_append(vp_data.vis_list, p);
226
227 mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
214 } 228 }
215 229
216 static void 230 static void
217 discovery_plugin_init(Plugin * plugin) 231 discovery_plugin_init(Plugin * plugin)
218 { 232 {
219 DiscoveryPlugin *p = DISCOVERY_PLUGIN(plugin); 233 DiscoveryPlugin *p = DISCOVERY_PLUGIN(plugin);
220 dp_data.discovery_list = g_list_append(dp_data.discovery_list, p); 234 dp_data.discovery_list = g_list_append(dp_data.discovery_list, p);
235
236 mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
221 } 237 }
222 238
223 /*******************************************************************/ 239 /*******************************************************************/
224 240
225 static void 241 static void
243 OutputPlugin **op_iter; 259 OutputPlugin **op_iter;
244 EffectPlugin **ep_iter; 260 EffectPlugin **ep_iter;
245 GeneralPlugin **gp_iter; 261 GeneralPlugin **gp_iter;
246 VisPlugin **vp_iter; 262 VisPlugin **vp_iter;
247 DiscoveryPlugin **dp_iter; 263 DiscoveryPlugin **dp_iter;
248
249 264
250 if (header->magic != PLUGIN_MAGIC) 265 if (header->magic != PLUGIN_MAGIC)
251 return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename); 266 return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename);
252 267
253 if (header->api_version != __AUDACIOUS_PLUGIN_API__) 268 if (header->api_version != __AUDACIOUS_PLUGIN_API__)
404 if (!g_module_supported()) { 419 if (!g_module_supported()) {
405 report_error("Module loading not supported! Plugins will not be loaded.\n"); 420 report_error("Module loading not supported! Plugins will not be loaded.\n");
406 return; 421 return;
407 } 422 }
408 423
409 plugin_matrix = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, 424 plugin_dict = mowgli_dictionary_create(g_ascii_strcasecmp);
410 NULL);
411 425
412 #ifndef DISABLE_USER_PLUGIN_DIR 426 #ifndef DISABLE_USER_PLUGIN_DIR
413 scan_plugins(bmp_paths[BMP_PATH_USER_PLUGIN_DIR]); 427 scan_plugins(bmp_paths[BMP_PATH_USER_PLUGIN_DIR]);
414 /* 428 /*
415 * This is in a separate lo 429 * This is in a separate lo
503 lp->init(); 517 lp->init();
504 } 518 }
505 519
506 if (cfg.disabled_iplugins) { 520 if (cfg.disabled_iplugins) {
507 disabled = g_strsplit(cfg.disabled_iplugins, ":", 0); 521 disabled = g_strsplit(cfg.disabled_iplugins, ":", 0);
522
508 while (disabled[i]) { 523 while (disabled[i]) {
509 g_hash_table_replace(plugin_matrix, disabled[i], 524 INPUT_PLUGIN(plugin_get_plugin(disabled))->enabled = FALSE;
510 GINT_TO_POINTER(FALSE));
511 i++; 525 i++;
512 } 526 }
513 527
514 g_free(disabled); 528 g_free(disabled);
515 529
682 { 696 {
683 g_list_free(vfs_transports); 697 g_list_free(vfs_transports);
684 vfs_transports = NULL; 698 vfs_transports = NULL;
685 } 699 }
686 700
687 g_hash_table_destroy( plugin_matrix ); 701 mowgli_dictionary_destroy(plugin_dict, NULL, NULL);
688 } 702 }