Mercurial > audlegacy
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 } |
