Update the go-menu when disabling browser in AE.
[gmpc.git] / src / plugin.c
blobe790be90fd437b7deaead99c1b7c0a98ce6a1b65
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2011 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpc.wikia.com/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <string.h>
21 #include <glib.h>
22 #include <gtk/gtk.h>
23 #include <gmodule.h>
24 #include "gmpc-extras.h"
25 #include "main.h"
26 #include "metadata.h"
28 #define PLUGIN_LOG_DOMAIN "Plugin"
30 gmpcPluginParent **plugins = NULL;
31 int num_plugins = 0;
33 gmpcPluginParent *plugin_get_from_id(int id)
35 int pos = plugin_get_pos(id);
36 g_assert_cmpint(pos, <, num_plugins);
37 return plugins[pos];
41 static GQuark plugin_quark(void)
43 return g_quark_from_static_string("gmpc_plugin");
47 int plugin_get_pos(int id)
49 return id & (PLUGIN_ID_MARK - 1);
53 static int plugin_validate(gmpcPlugin * plug, GError ** error)
55 int i;
56 if (plug->name == NULL)
58 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"), _("plugin has no name"));
59 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "pluging has no name: %s", plug->path);
60 return FALSE;
62 for (i = 0; i < num_plugins; i++)
64 if (strcmp(gmpc_plugin_get_name(plugins[i]), plug->name) == 0)
66 g_set_error(error, plugin_quark(), 0, "%s '%s': %s", _("Failed to load plugin"), plug->name,
67 _("plugin with same name already exists"));
68 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "pluging with same name already exists: %s", plug->name);
69 return FALSE;
72 if (plug->set_enabled == NULL || plug->get_enabled == NULL)
74 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
75 _("plugin is missing set/get enable function"));
76 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "%s: set_enabled == NULL || get_enabled == NULL failed",
77 plug->name);
78 return FALSE;
80 if (plug->plugin_type & GMPC_PLUGIN_PL_BROWSER)
82 if (plug->browser == NULL)
84 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
85 _("plugin browser structure is incorrect"));
86 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
87 "%s: plugin_type&GMPC_PLUGIN_PL_BROWSER && plugin->browser != NULL Failed", plug->name);
88 return FALSE;
90 if (plug->browser->cat_key_press != NULL)
92 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
93 _("plugin browser structure is incorrect"));
94 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
95 "Plugin %s implements a cat_key_press event handler that is deprecated", plug->name);
98 if (plug->plugin_type & GMPC_PLUGIN_META_DATA)
100 if (plug->metadata == NULL)
102 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
103 _("plugin metadata structure is incorrect"));
104 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
105 "%s: plugin_type&GMPC_PLUGIN_META_DATA && plugin->metadata != NULL Failed", plug->name);
106 return FALSE;
108 if (plug->metadata->get_priority == NULL)
110 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
111 _("plugin metadata structure is incorrect"));
112 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
113 "%s: plugin_type&GMPC_PLUGIN_META_DATA && plugin->metadata->get_priority != NULL Failed", plug->name);
114 return FALSE;
116 if (plug->metadata->set_priority == NULL)
118 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
119 _("plugin metadata structure is incorrect"));
120 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
121 "%s: plugin_type&GMPC_PLUGIN_META_DATA && plugin->metadata->set_priority != NULL Failed", plug->name);
122 return FALSE;
124 if (plug->metadata->get_image != NULL)
126 g_set_error(error, plugin_quark(), 0, "%s: %s %s", _("Failed to load plugin"), plug->name,
127 _("plugin get_image api is deprecated "));
128 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
129 "%s: plugin_type&GMPC_PLUGIN_META_DATA && plugin->metadata->get_image != NULL was true", plug->name);
130 return FALSE;
132 if (plug->metadata->get_uris != NULL)
134 g_set_error(error, plugin_quark(), 0, "%s: %s %s", _("Failed to load plugin"), plug->name,
135 _("plugin get_uris api is deprecated "));
136 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
137 "%s: plugin_type&GMPC_PLUGIN_META_DATA && plugin->metadata->get_uris != NULL was true", plug->name);
138 return FALSE;
140 if (plug->metadata->get_metadata == NULL)
142 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
143 _("plugin metadata structure is incorrect"));
144 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
145 "%s: plugin_type&GMPC_PLUGIN_META_DATA && plugin->metadata->get_image != NULL Failed", plug->name);
146 return FALSE;
149 /* if there is a browser field, check validity */
150 if (plug->browser)
152 if ((plug->browser->selected && plug->browser->unselected == NULL)
153 || (plug->browser->selected == NULL && plug->browser->unselected))
155 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
156 _("plugin browser structure is incorrect"));
157 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
158 "%s: If a plugin provides a browser pane, it needs both selected and unselected", plug->name);
159 return FALSE;
162 /* if there is a pref window withouth both construct/destroy, give an error */
163 if (plug->pref)
165 if (!(plug->pref->construct && plug->pref->destroy))
167 g_set_error(error, plugin_quark(), 0, "%s: %s", _("Failed to load plugin"),
168 _("plugin preferences structure is incorrect"));
169 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
170 "%s: If a plugin has a preferences pane, it needs both construct and destroy", plug->name);
174 return TRUE;
178 void plugin_add(gmpcPlugin * plug, int plugin, GError ** error)
180 gmpcPluginParent *parent = g_malloc0(sizeof(*parent));
181 parent->old = plug;
182 parent->new = NULL;
183 /* set plugin id */
184 plug->id = num_plugins | ((plugin) ? PLUGIN_ID_MARK : PLUGIN_ID_INTERNALL);
185 /* put it in the list */
186 num_plugins++;
187 plugins = g_realloc(plugins, (num_plugins + 1) * sizeof(gmpcPlugin **));
188 plugins[num_plugins - 1] = parent;
189 plugins[num_plugins] = NULL;
191 //plug->plugin_type&GMPC_PLUGIN_META_DATA)
192 if (gmpc_plugin_is_metadata(parent))
194 meta_data_add_plugin(parent);
199 void plugin_add_new(GmpcPluginBase * plug, int plugin, GError ** error)
201 gmpcPluginParent *parent = g_malloc0(sizeof(*parent));
202 parent->new = plug;
203 parent->old = NULL;
204 /* set plugin id */
205 plug->id = num_plugins | ((plugin) ? PLUGIN_ID_MARK : PLUGIN_ID_INTERNALL);
206 /* put it in the list */
207 num_plugins++;
208 plugins = g_realloc(plugins, (num_plugins + 1) * sizeof(gmpcPlugin **));
209 plugins[num_plugins - 1] = parent;
210 plugins[num_plugins] = NULL;
212 if (plug->plugin_type & GMPC_PLUGIN_META_DATA)
214 meta_data_add_plugin(parent);
219 static int plugin_load(const char *path, const char *file, GError ** error)
221 gpointer function;
222 GModule *handle;
223 int *api_version = 0;
224 gmpcPlugin *plug = NULL;
225 gchar *string = NULL;
226 gchar *full_path = NULL;
227 if (path == NULL)
229 return 1;
231 full_path = g_strdup_printf("%s%c%s", path, G_DIR_SEPARATOR, file);
233 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "plugin_load: trying to load plugin %s", full_path);
235 handle = g_module_open(full_path, G_MODULE_BIND_LOCAL);
236 q_free(full_path);
237 if (!handle)
239 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
240 "plugin_load: module failed to load: %s:%s\n", file, g_module_error());
241 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'", _("Failed to load plugin"), file, g_module_error());
242 return 1;
245 if (g_module_symbol(handle, "plugin_get_type", (gpointer) & function))
247 GmpcPluginBase *new;
248 GType(*get_type) (void);
249 get_type = function;
250 new = g_object_newv(get_type(), 0, NULL);
252 if (!new)
254 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'", _("Failed to create plugin instance"), file,
255 g_module_error());
256 return 1;
258 new->path = g_strdup(path);
259 plugin_add_new(new, 1, error);
260 return 0;
262 if (!g_module_symbol(handle, "plugin_api_version", (gpointer) & api_version))
265 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
266 "plugin_load: symbol failed to bind: %s:%s\n", file, g_module_error());
268 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'", _("Failed to bind symbol in plugin"), file,
269 g_module_error());
271 q_free(string);
272 g_module_close(handle);
273 return 1;
275 if (*api_version != PLUGIN_API_VERSION)
277 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
278 "Plugin '%s' has the wrong api version.\nPlugin api is %i, but we need %i",
279 file, *api_version, PLUGIN_API_VERSION);
281 g_set_error(error, plugin_quark(), 0, _("Plugin %s has wrong api version: %i"), file, *api_version);
283 q_free(string);
284 g_module_close(handle);
285 return 1;
287 if (!g_module_symbol(handle, "plugin", (gpointer) & (plug)))
289 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
290 "plugin_load: symbol failed to bind: %s:%s\n", file, g_module_error());
292 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'", _("Plugin %s has wrong no plugin structure: %s"), file,
293 g_module_error());
294 q_free(string);
295 g_module_close(handle);
296 return 1;
298 if (plug == NULL)
300 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'", _("Plugin %s has wrong no plugin structure: %s"), file,
301 g_module_error());
302 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "%s: plugin load: unknown type of plugin.\n", file);
303 g_module_close(handle);
304 return 1;
306 /* set path, plugins might want this for images and glade files. */
307 plug->path = g_strdup(path);
308 if (!plugin_validate(plug, error))
310 g_module_close(handle);
311 return 1;
313 /* add the plugin to the list */
314 plugin_add(plug, 1, error);
315 return 0;
319 static gboolean __show_plugin_load_error(gpointer data)
321 playlist3_show_error_message(_("One or more plugins failed to load, see help->messages for more information"),
322 ERROR_CRITICAL);
323 return FALSE;
327 void plugin_load_dir(const gchar * path)
329 GDir *dir = g_dir_open(path, 0, NULL);
330 int failure = 0;
331 if (dir)
333 const gchar *dirname = NULL;
334 while ((dirname = g_dir_read_name(dir)) != NULL)
336 gchar *full_path = g_strdup_printf("%s%c%s", path, G_DIR_SEPARATOR, dirname);
337 /* Make sure only to load plugins */
338 if (g_str_has_suffix(dirname, G_MODULE_SUFFIX))
340 GError *error = NULL;
341 if (plugin_load(path, dirname, &error))
343 failure = 1;
344 playlist3_show_error_message(error->message, ERROR_CRITICAL);
345 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
346 "Failed to load plugin: %s: %s\n", dirname, error->message);
347 g_error_free(error);
348 error = NULL;
350 } else
352 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_INFO,
353 "%s not loaded, wrong extention, should be: '%s'", dirname, G_MODULE_SUFFIX);
355 q_free(full_path);
357 g_dir_close(dir);
359 if (failure)
361 gtk_init_add(__show_plugin_load_error, NULL);
367 * gmpcPlugin
370 void gmpc_plugin_destroy(gmpcPluginParent * plug)
372 if (plug->new)
374 g_object_unref(plug->new);
375 return;
377 if (plug->old->destroy)
379 plug->old->destroy();
384 void gmpc_plugin_init(gmpcPluginParent * plug)
386 if (plug->new)
389 return;
391 if (plug->old->init)
393 plug->old->init();
398 void gmpc_plugin_status_changed(gmpcPluginParent * plug, MpdObj * mi, ChangedStatusType what)
400 if (plug->new)
401 return;
402 if (plug->old->mpd_status_changed)
404 plug->old->mpd_status_changed(mi, what, NULL);
409 const char *gmpc_plugin_get_name(gmpcPluginParent * plug)
411 /* if new plugin, use that method */
412 if (plug->new)
414 return gmpc_plugin_base_get_name(plug->new);
416 g_assert(plug->old->name != NULL);
417 return plug->old->name;
421 void gmpc_plugin_save_yourself(gmpcPluginParent * plug)
423 if (plug->new)
425 gmpc_plugin_base_save_yourself(plug->new);
426 return;
428 if (plug->old->save_yourself)
430 plug->old->save_yourself();
435 gboolean gmpc_plugin_get_enabled(gmpcPluginParent * plug)
437 if (plug->new)
439 return gmpc_plugin_base_get_enabled(plug->new);
441 if (plug->old->get_enabled)
443 return plug->old->get_enabled();
445 return TRUE;
449 void gmpc_plugin_set_enabled(gmpcPluginParent * plug, gboolean enabled)
451 if (plug->new)
453 return gmpc_plugin_base_set_enabled(plug->new, enabled);
455 if (plug->old->set_enabled)
457 plug->old->set_enabled(enabled);
462 const gchar *gmpc_plugin_get_translation_domain(gmpcPluginParent * plug)
464 if (plug->new)
466 return plug->new->translation_domain;
468 if (plug->old && plug->old->get_translation_domain)
470 return plug->old->get_translation_domain();
472 return NULL;
476 gchar *gmpc_plugin_get_data_path(gmpcPlugin * plug)
478 #ifdef WIN32
479 gchar *url = g_win32_get_package_installation_directory_of_module(NULL);
480 gchar *retv = g_build_path(G_DIR_SEPARATOR_S, url, "share", "gmpc", "plugins", NULL);
481 return retv; //g_strdup(plug->path);
482 #else
483 int i;
484 const gchar *const *paths = g_get_system_data_dirs();
485 gchar *url = NULL;
486 gchar *homedir = gmpc_get_user_path("");
487 if (strncmp(plug->path, homedir, strlen(homedir)) == 0)
489 url = g_strdup(plug->path);
490 } else
492 /* Ok it is a homedir */
493 url = g_build_path(G_DIR_SEPARATOR_S, PACKAGE_DATA_DIR, "gmpc", "plugins", NULL);
496 g_free(homedir);
498 if (url)
500 if (g_file_test(url, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
502 return url;
504 g_free(url);
505 url = NULL;
508 for (i = 0; paths && paths[i]; i++)
510 url = g_build_filename(paths[i], "gmpc", "plugins", NULL);
511 if (g_file_test(url, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
513 return url;
515 g_free(url);
516 url = NULL;
518 return url;
519 #endif
523 void gmpc_plugin_mpd_connection_changed(gmpcPluginParent * plug, MpdObj * mi, int connected, gpointer data)
525 g_assert(plug != NULL);
527 if (plug->new)
528 return;
529 if (plug->old->mpd_connection_changed != NULL)
531 plug->old->mpd_connection_changed(mi, connected, data);
536 gboolean gmpc_plugin_is_browser(gmpcPluginParent * plug)
538 if (plug->new)
540 return GMPC_PLUGIN_IS_BROWSER_IFACE(plug->new);
542 return ((plug->old->plugin_type & GMPC_PLUGIN_PL_BROWSER) != 0);
546 void gmpc_plugin_browser_unselected(gmpcPluginParent * plug, GtkWidget * container)
548 if (gmpc_plugin_is_browser(plug))
550 if (plug->new)
552 gmpc_plugin_browser_iface_browser_unselected((GmpcPluginBrowserIface *) plug->new,
553 GTK_CONTAINER(container));
554 return;
556 g_assert(plug->old->browser != NULL);
557 g_assert(plug->old->browser->unselected != NULL);
558 plug->old->browser->unselected(container);
563 void gmpc_plugin_browser_selected(gmpcPluginParent * plug, GtkWidget * container)
565 if (gmpc_plugin_is_browser(plug))
567 if (plug->new)
569 gmpc_plugin_browser_iface_browser_selected((GmpcPluginBrowserIface *) plug->new, GTK_CONTAINER(container));
570 return;
572 g_assert(plug->old->browser != NULL);
573 g_assert(plug->old->browser->selected != NULL);
574 plug->old->browser->selected(container);
579 void gmpc_plugin_browser_add(gmpcPluginParent * plug, GtkWidget * cat_tree)
581 if (gmpc_plugin_is_browser(plug))
583 if (plug->new)
585 gmpc_plugin_browser_iface_browser_add((GmpcPluginBrowserIface *) plug->new, cat_tree);
586 return;
588 g_assert(plug->old->browser != NULL);
589 if (plug->old->browser->add)
591 plug->old->browser->add(cat_tree);
597 int gmpc_plugin_browser_cat_right_mouse_menu(gmpcPluginParent * plug, GtkWidget * menu, int type, GtkWidget * tree,
598 GdkEventButton * event)
600 if (gmpc_plugin_is_browser(plug))
602 if (plug->new)
604 if (type == plug->new->id)
605 return gmpc_plugin_browser_iface_browser_option_menu((GmpcPluginBrowserIface *) plug->new,
606 GTK_MENU(menu));
607 return 0;
609 g_assert(plug->old->browser != NULL);
610 if (plug->old->browser->cat_right_mouse_menu != NULL)
612 return plug->old->browser->cat_right_mouse_menu(menu, type, tree, event);
615 return 0;
619 int gmpc_plugin_browser_key_press_event(gmpcPluginParent * plug, GtkWidget * mw, GdkEventKey * event, int type)
621 if (gmpc_plugin_is_browser(plug))
623 if (plug->new)
625 /* not going to be implemented */
626 return 0;
628 g_assert(plug->old->browser != NULL);
629 if (plug->old->browser->key_press_event != NULL)
631 return plug->old->browser->key_press_event(mw, event, type);
634 return 0;
638 int gmpc_plugin_browser_add_go_menu(gmpcPluginParent * plug, GtkWidget * menu)
640 if (gmpc_plugin_is_browser(plug))
642 if (plug->new)
644 return gmpc_plugin_browser_iface_browser_add_go_menu((GmpcPluginBrowserIface *) plug->new, GTK_MENU(menu));
646 g_assert(plug->old->browser != NULL);
647 if (plug->old->browser->add_go_menu != NULL)
649 return plug->old->browser->add_go_menu(menu);
652 return 0;
656 int gmpc_plugin_browser_song_list_option_menu(gmpcPluginParent * plug, GmpcMpdDataTreeview * tree, GtkMenu * menu)
658 if (plug->new)
660 if (GMPC_PLUGIN_IS_SONG_LIST_IFACE(plug->new))
662 return gmpc_plugin_song_list_iface_song_list(GMPC_PLUGIN_SONG_LIST_IFACE(plug->new), GTK_WIDGET(tree),
663 menu);
665 return 0;
667 if (gmpc_plugin_is_browser(plug))
669 g_assert(plug->old->browser != NULL);
670 if (plug->old->browser->song_list_option_menu)
672 return plug->old->browser->song_list_option_menu(tree, menu);
675 return 0;
679 gboolean gmpc_plugin_browser_has_integrate_search(gmpcPluginParent * plug)
681 if (plug->new)
683 return GMPC_PLUGIN_IS_INTEGRATE_SEARCH_IFACE(plug->new);
685 if (gmpc_plugin_is_browser(plug))
687 return plug->old->browser->integrate_search != NULL;
689 return FALSE;
693 MpdData *gmpc_plugin_browser_integrate_search(gmpcPluginParent * plug, const int search_field, const gchar * query,
694 GError ** error)
696 if (!gmpc_plugin_browser_has_integrate_search(plug))
697 return NULL;
698 if (plug->new)
699 return gmpc_plugin_integrate_search_iface_search(GMPC_PLUGIN_INTEGRATE_SEARCH_IFACE(plug->new), search_field,
700 query);
701 return plug->old->browser->integrate_search(search_field, query, error);
705 gboolean gmpc_plugin_browser_integrate_search_field_supported(gmpcPluginParent * plug, const int search_field)
707 if (!gmpc_plugin_browser_has_integrate_search(plug))
708 return FALSE;
710 if (plug->new)
711 return gmpc_plugin_integrate_search_iface_field_supported(GMPC_PLUGIN_INTEGRATE_SEARCH_IFACE(plug->new),
712 search_field);
714 if (plug->old->browser->integrate_search_field_supported == NULL)
715 return TRUE;
716 return plug->old->browser->integrate_search_field_supported(search_field);
720 gboolean gmpc_plugin_has_preferences(gmpcPluginParent * plug)
722 if (plug->new)
724 return GMPC_PLUGIN_IS_PREFERENCES_IFACE(plug->new);
726 return (plug->old->pref != NULL);
730 void gmpc_plugin_preferences_construct(gmpcPluginParent * plug, GtkWidget * wid)
732 if (gmpc_plugin_has_preferences(plug))
734 if (plug->new)
736 gmpc_plugin_preferences_iface_preferences_pane_construct(GMPC_PLUGIN_PREFERENCES_IFACE(plug->new),
737 GTK_CONTAINER(wid));
738 return;
740 g_assert(plug->old->pref != NULL);
741 g_assert(plug->old->pref->construct);
742 plug->old->pref->construct(wid);
747 void gmpc_plugin_preferences_destroy(gmpcPluginParent * plug, GtkWidget * wid)
749 if (gmpc_plugin_has_preferences(plug))
751 if (plug->new)
753 gmpc_plugin_preferences_iface_preferences_pane_destroy(GMPC_PLUGIN_PREFERENCES_IFACE(plug->new),
754 GTK_CONTAINER(wid));
755 return;
757 g_assert(plug->old->pref != NULL);
758 g_assert(plug->old->pref->destroy);
759 plug->old->pref->destroy(wid);
764 gboolean gmpc_plugin_is_internal(gmpcPluginParent * plug)
766 if (plug->new)
768 return (((plug->new->plugin_type) & GMPC_INTERNALL) != 0);
771 return (((plug->old->plugin_type) & GMPC_INTERNALL) != 0);
775 const int *gmpc_plugin_get_version(gmpcPluginParent * plug)
777 if (plug->new)
779 gint length;
780 return (const int *)gmpc_plugin_base_get_version(plug->new, &length);
782 return (const int *)plug->old->version;
786 int gmpc_plugin_get_type(gmpcPluginParent * plug)
788 if (plug->new)
790 return plug->new->plugin_type;
792 return plug->old->plugin_type;
796 int gmpc_plugin_get_id(gmpcPluginParent * plug)
798 if (plug->new)
800 return plug->new->id;
802 return plug->old->id;
806 gboolean gmpc_plugin_is_metadata(gmpcPluginParent * plug)
808 if (plug->new)
810 return GMPC_PLUGIN_IS_META_DATA_IFACE(plug->new);
812 return (plug->old->metadata != NULL);
816 int gmpc_plugin_metadata_get_priority(gmpcPluginParent * plug)
818 if (gmpc_plugin_is_metadata(plug))
820 if (plug->new)
821 return gmpc_plugin_meta_data_iface_get_priority(GMPC_PLUGIN_META_DATA_IFACE(plug->new));
822 return plug->old->metadata->get_priority();
824 return 100;
828 void gmpc_plugin_metadata_set_priority(gmpcPluginParent * plug, int priority)
830 if (gmpc_plugin_is_metadata(plug))
832 if (plug->new)
833 return gmpc_plugin_meta_data_iface_set_priority(GMPC_PLUGIN_META_DATA_IFACE(plug->new), priority);
834 return plug->old->metadata->set_priority(priority);
839 void gmpc_plugin_metadata_query_metadata_list(gmpcPluginParent * plug, mpd_Song * song, MetaDataType type,
840 void (*callback) (GList * uris, gpointer data), gpointer data)
842 if (gmpc_plugin_is_metadata(plug))
844 if (plug->new)
846 gmpc_plugin_meta_data_iface_get_metadata(GMPC_PLUGIN_META_DATA_IFACE(plug->new), song, type, callback,
847 data);
848 return;
850 if (plug->old->metadata->get_metadata)
852 plug->old->metadata->get_metadata(song, type, callback, data);
853 return;
856 callback(NULL, data);
860 gint gmpc_plugin_tool_menu_integration(gmpcPluginParent * plug, GtkMenu * menu)
862 if (plug->new)
864 if (GMPC_PLUGIN_IS_TOOL_MENU_IFACE(plug->new))
866 return gmpc_plugin_tool_menu_iface_tool_menu_integration(GMPC_PLUGIN_TOOL_MENU_IFACE(plug->new), menu);
868 return 0;
870 if (plug->old)
872 if (plug->old->tool_menu_integration)
873 return plug->old->tool_menu_integration(menu);
875 return 0;
878 gboolean gmpc_plugin_has_enabled (gmpcPluginParent *plug)
880 if (plug->new)
882 return TRUE;
884 if(plug->old && plug->old->get_enabled && plug->old->set_enabled) return TRUE;
885 return FALSE;