Cleanups
[gmpc.git] / src / plugin.c
blob6b06f6a016f1a9e980f6f7346d262023c55464c8
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
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];
40 static GQuark plugin_quark(void)
42 return g_quark_from_static_string("gmpc_plugin");
45 int plugin_get_pos(int id)
47 return id & (PLUGIN_ID_MARK - 1);
51 typedef struct _Blacklist {
52 const char *plugin_name;
53 const char *reason;
54 }Blacklist;
56 static const int num_blacklisted_plugins = 7;
57 static Blacklist blacklist[] =
59 {"Lyrdb.com lyric source", "Plugin is intergrated into GMPC"},
60 {"Extra Playlist View", "Plugin is intergrated into GMPC"},
61 {"Statistics", "Plugin is intergrated into GMPC"},
62 {"DiscoGS Artist and Album Image Fetcher", "Plugin is intergrated into GMPC"},
63 {"Last FM metadata fetcher", "Plugin is intergrated into GMPC"},
64 {"Fullscreen Info", "Plugin is intergrated into GMPC"},
65 {"WikiPedia", "Plugin ddos'es Wikipedia"}
68 static int plugin_manager_blacklist(gmpcPluginParent *p, GError **error)
70 int i;
71 const char *name = gmpc_plugin_get_name(p);
72 g_assert(name != NULL);
73 for(i = 0; i<num_blacklisted_plugins; i++) {
74 if(strcmp(name, blacklist[i].plugin_name) == 0) {
75 g_set_error(error, plugin_quark(), 0,
76 "pluging has with name: %s is blacklisted: '%s'", name,
77 blacklist[i].reason);
78 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
79 "pluging has with name: %s is blacklisted: '%s'", name,
80 blacklist[i].reason);
81 return TRUE;
84 return FALSE;
87 static int plugin_validate(gmpcPlugin * plug, GError ** error)
89 int i;
90 if (plug->name == NULL)
92 g_set_error(error, plugin_quark(), 0, "%s: %s",
93 _("Failed to load plugin"), _("plugin has no name"));
94 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
95 "pluging has no name: %s", plug->path);
96 return FALSE;
98 for (i = 0; i < num_plugins; i++)
100 if (strcmp(gmpc_plugin_get_name(plugins[i]), plug->name) == 0)
102 g_set_error(error, plugin_quark(), 0, "%s '%s': %s",
103 _("Failed to load plugin"), plug->name,
104 _("plugin with same name already exists"));
105 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
106 "pluging with same name already exists: %s", plug->name);
107 return FALSE;
110 if (plug->set_enabled == NULL || plug->get_enabled == NULL)
112 g_set_error(error, plugin_quark(), 0, "%s: %s",
113 _("Failed to load plugin"),
114 _("plugin is missing set/get enable function"));
115 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
116 "%s: set_enabled == NULL || get_enabled == NULL failed",
117 plug->name);
118 return FALSE;
120 if (plug->plugin_type & GMPC_PLUGIN_PL_BROWSER)
122 if (plug->browser == NULL)
124 g_set_error(error, plugin_quark(), 0, "%s: %s",
125 _("Failed to load plugin"),
126 _("plugin browser structure is incorrect"));
127 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
128 "%s: plugin_type&GMPC_PLUGIN_PL_BROWSER && plugin->browser != NULL Failed",
129 plug->name);
130 return FALSE;
133 /* if there is a browser field, check validity */
134 if (plug->browser)
136 if ((plug->browser->selected && plug->browser->unselected == NULL)
137 || (plug->browser->selected == NULL && plug->browser->unselected))
139 g_set_error(error, plugin_quark(), 0, "%s: %s",
140 _("Failed to load plugin"),
141 _("plugin browser structure is incorrect"));
142 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
143 "%s: If a plugin provides a browser pane, it needs both selected and unselected",
144 plug->name);
145 return FALSE;
148 /* if there is a pref window withouth both construct/destroy, give an error */
149 if (plug->pref)
151 if (!(plug->pref->construct && plug->pref->destroy))
153 g_set_error(error, plugin_quark(), 0, "%s: %s",
154 _("Failed to load plugin"),
155 _("plugin preferences structure is incorrect"));
156 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
157 "%s: If a plugin has a preferences pane, it needs both construct and destroy",
158 plug->name);
162 return TRUE;
165 void plugin_add(gmpcPlugin * plug, int plugin, GError ** error)
167 gmpcPluginParent *parent = g_malloc0(sizeof(*parent));
168 parent->old = plug;
169 parent->new = NULL;
172 if(plugin_manager_blacklist(parent, error))
174 if(error && *error != NULL)
176 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
177 "%s: Not loading plugin.",
178 plug->name);
180 return ;
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;
192 void plugin_add_new(GmpcPluginBase * plug, int plugin, GError ** error)
194 gmpcPluginParent *parent = g_malloc0(sizeof(*parent));
195 parent->new = plug;
196 parent->old = NULL;
198 if(plugin_manager_blacklist(parent, error))
200 return;
202 /* set plugin id */
203 plug->id = num_plugins | ((plugin) ? PLUGIN_ID_MARK : PLUGIN_ID_INTERNALL);
204 /* put it in the list */
205 num_plugins++;
206 plugins = g_realloc(plugins, (num_plugins + 1) * sizeof(gmpcPlugin **));
207 plugins[num_plugins - 1] = parent;
208 plugins[num_plugins] = NULL;
211 static int plugin_load(const char *path, const char *file, GError ** error)
213 gpointer function;
214 GModule *handle;
215 int *api_version = 0;
216 gmpcPlugin *plug = NULL;
217 gchar *string = NULL;
218 gchar *full_path = NULL;
219 if (path == NULL)
221 return 1;
223 full_path = g_strdup_printf("%s%c%s", path, G_DIR_SEPARATOR, file);
225 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
226 "plugin_load: trying to load plugin %s", full_path);
228 handle = g_module_open(full_path, G_MODULE_BIND_LOCAL);
229 q_free(full_path);
230 if (!handle)
232 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
233 "plugin_load: module failed to load: %s:%s\n", file,
234 g_module_error());
235 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
236 _("Failed to load plugin"), file, g_module_error());
237 return 1;
240 if (g_module_symbol(handle, "plugin_get_type", (gpointer) & function))
242 GmpcPluginBase *new;
243 GType(*get_type) (void);
244 get_type = function;
245 new = g_object_newv(get_type(), 0, NULL);
247 if (!new)
249 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
250 _("Failed to create plugin instance"), file,
251 g_module_error());
252 return 1;
254 new->path = g_strdup(path);
255 plugin_add_new(new, 1, error);
256 return 0;
258 if (!g_module_symbol
259 (handle, "plugin_api_version", (gpointer) & api_version))
262 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
263 "plugin_load: symbol failed to bind: %s:%s\n", file,
264 g_module_error());
266 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
267 _("Failed to bind symbol in plugin"), file,
268 g_module_error());
270 q_free(string);
271 g_module_close(handle);
272 return 1;
274 if (*api_version != PLUGIN_API_VERSION)
276 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
277 "Plugin '%s' has the wrong api version.\nPlugin api is %i, but we need %i",
278 file, *api_version, PLUGIN_API_VERSION);
280 g_set_error(error, plugin_quark(), 0,
281 _("Plugin %s has wrong api version: %i"), file,
282 *api_version);
284 q_free(string);
285 g_module_close(handle);
286 return 1;
288 if (!g_module_symbol(handle, "plugin", (gpointer) & (plug)))
290 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
291 "plugin_load: symbol failed to bind: %s:%s\n", file,
292 g_module_error());
294 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
295 _("Plugin %s has wrong no plugin structure: %s"), file,
296 g_module_error());
297 q_free(string);
298 g_module_close(handle);
299 return 1;
301 if (plug == NULL)
303 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
304 _("Plugin %s has wrong no plugin structure: %s"), file,
305 g_module_error());
306 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
307 "%s: plugin load: unknown type of plugin.\n", file);
308 g_module_close(handle);
309 return 1;
311 /* set path, plugins might want this for images and glade files. */
312 plug->path = g_strdup(path);
313 if (!plugin_validate(plug, error))
315 g_module_close(handle);
316 return 1;
318 /* add the plugin to the list */
319 plugin_add(plug, 1, error);
320 return 0;
323 static gboolean __show_plugin_load_error(gpointer data)
325 playlist3_show_error_message(_
326 ("One or more plugins failed to load, see help->messages for more information"),
327 ERROR_CRITICAL);
328 return FALSE;
331 void plugin_load_dir(const gchar * path)
333 GDir *dir = g_dir_open(path, 0, NULL);
334 int failure = 0;
335 if (dir)
337 const gchar *dirname = NULL;
338 while ((dirname = g_dir_read_name(dir)) != NULL)
340 gchar *full_path =
341 g_strdup_printf("%s%c%s", path, G_DIR_SEPARATOR, dirname);
342 /* Make sure only to load plugins */
343 if (g_str_has_suffix(dirname, G_MODULE_SUFFIX))
345 GError *error = NULL;
346 if (plugin_load(path, dirname, &error))
348 failure = 1;
349 playlist3_show_error_message(error->message,
350 ERROR_CRITICAL);
351 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
352 "Failed to load plugin: %s: %s\n", dirname,
353 error->message);
354 g_error_free(error);
355 error = NULL;
357 } else
359 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_INFO,
360 "%s not loaded, wrong extension, should be: '%s'",
361 dirname, G_MODULE_SUFFIX);
363 q_free(full_path);
365 g_dir_close(dir);
367 if (failure)
369 // TODO
370 g_idle_add(__show_plugin_load_error, NULL);
371 //gtk_init_add(__show_plugin_load_error, NULL);
376 * gmpcPlugin
379 void gmpc_plugin_destroy(gmpcPluginParent * plug)
381 if (plug->new)
383 g_object_unref(plug->new);
384 return;
386 if (plug->old->destroy)
388 plug->old->destroy();
392 void gmpc_plugin_init(gmpcPluginParent * plug)
394 if (plug->new)
396 return;
398 if (plug->old->init)
400 plug->old->init();
404 void gmpc_plugin_status_changed(gmpcPluginParent * plug, MpdObj * mi,
405 ChangedStatusType what)
407 if (plug->new)
408 return;
409 if (plug->old->mpd_status_changed)
411 plug->old->mpd_status_changed(mi, what, NULL);
415 const char *gmpc_plugin_get_name(gmpcPluginParent * plug)
417 /* if new plugin, use that method */
418 if (plug->new)
420 return gmpc_plugin_base_get_name(plug->new);
422 g_assert(plug->old->name != NULL);
423 return plug->old->name;
426 void gmpc_plugin_save_yourself(gmpcPluginParent * plug)
428 if (plug->new)
430 gmpc_plugin_base_save_yourself(plug->new);
431 return;
433 if (plug->old->save_yourself)
435 plug->old->save_yourself();
439 gboolean gmpc_plugin_get_enabled(const gmpcPluginParent * plug)
441 if (plug->new)
443 return gmpc_plugin_base_get_enabled(plug->new);
445 if (plug->old->get_enabled)
447 return plug->old->get_enabled();
449 return TRUE;
452 void gmpc_plugin_set_enabled(gmpcPluginParent * plug, gboolean enabled)
454 if (plug->new)
456 return gmpc_plugin_base_set_enabled(plug->new, enabled);
458 if (plug->old->set_enabled)
460 plug->old->set_enabled(enabled);
464 const gchar *gmpc_plugin_get_translation_domain(gmpcPluginParent * plug)
466 if (plug->new)
468 return plug->new->translation_domain;
470 if (plug->old && plug->old->get_translation_domain)
472 return plug->old->get_translation_domain();
474 return NULL;
477 gchar *gmpc_plugin_get_data_path(gmpcPlugin * plug)
479 #ifdef WIN32
480 gchar *url = g_win32_get_package_installation_directory_of_module(NULL);
481 gchar *retv =
482 g_build_path(G_DIR_SEPARATOR_S, url, "share", "gmpc", "plugins", NULL);
483 return retv; //g_strdup(plug->path);
484 #else
485 int i;
486 const gchar *const *paths = g_get_system_data_dirs();
487 gchar *url = NULL;
488 gchar *homedir = gmpc_get_user_path("");
489 if (strncmp(plug->path, homedir, strlen(homedir)) == 0)
491 url = g_strdup(plug->path);
492 } else
494 /* Ok it is a homedir */
495 url =
496 g_build_path(G_DIR_SEPARATOR_S, PACKAGE_DATA_DIR, "gmpc", "plugins",
497 NULL);
500 g_free(homedir);
502 if (url)
504 if (g_file_test(url, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
506 return url;
508 g_free(url);
509 url = NULL;
512 for (i = 0; paths && paths[i]; i++)
514 url = g_build_filename(paths[i], "gmpc", "plugins", NULL);
515 if (g_file_test(url, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
517 return url;
519 g_free(url);
520 url = NULL;
522 return url;
523 #endif
526 void gmpc_plugin_mpd_connection_changed(gmpcPluginParent * plug, MpdObj * mi,
527 int connected, gpointer data)
529 g_assert(plug != NULL);
531 if (plug->new)
532 return;
533 if (plug->old->mpd_connection_changed != NULL)
535 plug->old->mpd_connection_changed(mi, connected, data);
538 gboolean gmpc_plugin_is_sidebar(gmpcPluginParent *plug)
540 g_assert(plug != NULL);
541 if(plug->new)
543 return GMPC_PLUGIN_IS_SIDEBAR_IFACE(plug->new);
545 return FALSE;
547 void gmpc_plugin_sidebar_init(gmpcPluginParent *plug)
549 if(gmpc_plugin_is_sidebar(plug))
551 gmpc_sidebar_plugins_init(GMPC_PLUGIN_SIDEBAR_IFACE(plug->new));
555 void gmpc_plugin_sidebar_set_state(gmpcPluginParent *plug, GmpcPluginSidebarState state)
557 if(gmpc_plugin_is_sidebar(plug))
559 gmpc_plugin_sidebar_iface_sidebar_set_state(GMPC_PLUGIN_SIDEBAR_IFACE(plug->new), state);
563 gboolean gmpc_plugin_is_browser(gmpcPluginParent * plug)
565 if (plug->new)
567 return GMPC_PLUGIN_IS_BROWSER_IFACE(plug->new);
569 return ((plug->old->plugin_type & GMPC_PLUGIN_PL_BROWSER) != 0);
572 void gmpc_plugin_browser_unselected(gmpcPluginParent * plug,
573 GtkWidget * container)
575 if (gmpc_plugin_is_browser(plug))
577 if (plug->new)
579 gmpc_plugin_browser_iface_browser_unselected((GmpcPluginBrowserIface
580 *) plug->new,
581 GTK_CONTAINER
582 (container));
583 return;
585 g_assert(plug->old->browser != NULL);
586 g_assert(plug->old->browser->unselected != NULL);
587 plug->old->browser->unselected(container);
591 void gmpc_plugin_browser_selected(gmpcPluginParent * plug,
592 GtkWidget * container)
594 if (gmpc_plugin_is_browser(plug))
596 if (plug->new)
598 gmpc_plugin_browser_iface_browser_selected((GmpcPluginBrowserIface
599 *) plug->new,
600 GTK_CONTAINER
601 (container));
602 return;
604 g_assert(plug->old->browser != NULL);
605 g_assert(plug->old->browser->selected != NULL);
606 plug->old->browser->selected(container);
610 void gmpc_plugin_browser_add(gmpcPluginParent * plug, GtkWidget * cat_tree)
612 if (gmpc_plugin_is_browser(plug))
614 if (plug->new)
616 gmpc_plugin_browser_iface_browser_add((GmpcPluginBrowserIface *)
617 plug->new, cat_tree);
618 return;
620 g_assert(plug->old->browser != NULL);
621 if (plug->old->browser->add)
623 plug->old->browser->add(cat_tree);
628 int gmpc_plugin_browser_cat_right_mouse_menu(gmpcPluginParent * plug,
629 GtkWidget * menu, int type,
630 GtkWidget * tree,
631 GdkEventButton * event)
633 if (gmpc_plugin_is_browser(plug))
635 if (plug->new)
637 if (type == plug->new->id)
638 return
639 gmpc_plugin_browser_iface_browser_option_menu((GmpcPluginBrowserIface *) plug->new, GTK_MENU(menu));
640 return 0;
642 g_assert(plug->old->browser != NULL);
643 if (plug->old->browser->cat_right_mouse_menu != NULL)
645 return plug->old->browser->cat_right_mouse_menu(menu, type, tree,
646 event);
649 return 0;
652 int gmpc_plugin_browser_key_press_event(gmpcPluginParent * plug, GtkWidget * mw,
653 GdkEventKey * event, int type)
655 if (gmpc_plugin_is_browser(plug))
657 if (plug->new)
659 /* not going to be implemented */
660 return 0;
662 g_assert(plug->old->browser != NULL);
663 if (plug->old->browser->key_press_event != NULL)
665 return plug->old->browser->key_press_event(mw, event, type);
668 return 0;
671 int gmpc_plugin_browser_add_go_menu(gmpcPluginParent * plug, GtkWidget * menu)
673 if (gmpc_plugin_is_browser(plug))
675 if (plug->new)
677 return
678 gmpc_plugin_browser_iface_browser_add_go_menu((GmpcPluginBrowserIface *) plug->new, GTK_MENU(menu));
680 g_assert(plug->old->browser != NULL);
681 if (plug->old->browser->add_go_menu != NULL)
683 return plug->old->browser->add_go_menu(menu);
686 return 0;
689 int gmpc_plugin_browser_song_list_option_menu(gmpcPluginParent * plug,
690 GmpcMpdDataTreeview * tree,
691 GtkMenu * menu)
693 if (plug->new)
695 if (GMPC_PLUGIN_IS_SONG_LIST_IFACE(plug->new))
697 return
698 gmpc_plugin_song_list_iface_song_list
699 (GMPC_PLUGIN_SONG_LIST_IFACE(plug->new), GTK_WIDGET(tree),
700 menu);
702 return 0;
704 if (gmpc_plugin_is_browser(plug))
706 g_assert(plug->old->browser != NULL);
707 if (plug->old->browser->song_list_option_menu)
709 return plug->old->browser->song_list_option_menu(tree, menu);
712 return 0;
715 gboolean gmpc_plugin_browser_has_integrate_search(gmpcPluginParent * plug)
717 if (plug->new)
719 return GMPC_PLUGIN_IS_INTEGRATE_SEARCH_IFACE(plug->new);
721 if (gmpc_plugin_is_browser(plug))
723 return plug->old->browser->integrate_search != NULL;
725 return FALSE;
728 MpdData *gmpc_plugin_browser_integrate_search(gmpcPluginParent * plug,
729 const int search_field,
730 const gchar * query,
731 GError ** error)
733 if (!gmpc_plugin_browser_has_integrate_search(plug))
734 return NULL;
735 if (plug->new)
736 return
737 gmpc_plugin_integrate_search_iface_search
738 (GMPC_PLUGIN_INTEGRATE_SEARCH_IFACE(plug->new), search_field,
739 query);
740 return plug->old->browser->integrate_search(search_field, query, error);
743 gboolean gmpc_plugin_browser_integrate_search_field_supported(gmpcPluginParent *
744 plug,
745 const int
746 search_field)
748 if (!gmpc_plugin_browser_has_integrate_search(plug))
749 return FALSE;
751 if (plug->new)
752 return
753 gmpc_plugin_integrate_search_iface_field_supported
754 (GMPC_PLUGIN_INTEGRATE_SEARCH_IFACE(plug->new), search_field);
756 if (plug->old->browser->integrate_search_field_supported == NULL)
757 return TRUE;
758 return plug->old->browser->integrate_search_field_supported(search_field);
761 gboolean gmpc_plugin_has_preferences(gmpcPluginParent * plug)
763 if (plug->new)
765 return GMPC_PLUGIN_IS_PREFERENCES_IFACE(plug->new);
767 return (plug->old->pref != NULL);
770 void gmpc_plugin_preferences_construct(gmpcPluginParent * plug, GtkWidget * wid)
772 if (gmpc_plugin_has_preferences(plug))
774 if (plug->new)
776 gmpc_plugin_preferences_iface_preferences_pane_construct
777 (GMPC_PLUGIN_PREFERENCES_IFACE(plug->new), GTK_CONTAINER(wid));
778 return;
780 g_assert(plug->old->pref != NULL);
781 g_assert(plug->old->pref->construct);
782 plug->old->pref->construct(wid);
786 void gmpc_plugin_preferences_destroy(gmpcPluginParent * plug, GtkWidget * wid)
788 if (gmpc_plugin_has_preferences(plug))
790 if (plug->new)
792 gmpc_plugin_preferences_iface_preferences_pane_destroy
793 (GMPC_PLUGIN_PREFERENCES_IFACE(plug->new), GTK_CONTAINER(wid));
794 return;
796 g_assert(plug->old->pref != NULL);
797 g_assert(plug->old->pref->destroy);
798 plug->old->pref->destroy(wid);
802 gboolean gmpc_plugin_is_internal(gmpcPluginParent * plug)
804 if (plug->new)
806 return (((plug->new->plugin_type) & GMPC_INTERNALL) != 0);
809 return (((plug->old->plugin_type) & GMPC_INTERNALL) != 0);
812 const int *gmpc_plugin_get_version(gmpcPluginParent * plug)
814 if (plug->new)
816 gint length;
817 return (const int *)gmpc_plugin_base_get_version(plug->new, &length);
819 return (const int *)plug->old->version;
822 int gmpc_plugin_get_type(gmpcPluginParent * plug)
824 if (plug->new)
826 return plug->new->plugin_type;
828 return plug->old->plugin_type;
831 int gmpc_plugin_get_id(gmpcPluginParent * plug)
833 if (plug->new)
835 return plug->new->id;
837 return plug->old->id;
840 gint gmpc_plugin_tool_menu_integration(gmpcPluginParent * plug, GtkMenu * menu)
842 if (plug->new)
844 if (GMPC_PLUGIN_IS_TOOL_MENU_IFACE(plug->new))
846 return
847 gmpc_plugin_tool_menu_iface_tool_menu_integration
848 (GMPC_PLUGIN_TOOL_MENU_IFACE(plug->new), menu);
850 return 0;
852 if (plug->old)
854 if (plug->old->tool_menu_integration)
855 return plug->old->tool_menu_integration(menu);
857 return 0;
860 gboolean gmpc_plugin_has_enabled(gmpcPluginParent * plug)
862 if (plug->new)
864 return TRUE;
866 if (plug->old && plug->old->get_enabled && plug->old->set_enabled)
867 return TRUE;
868 return FALSE;