Update vala version.
[gmpc.git] / src / plugin.c
blob4033b41b0a36ccc488577cfc8bc25bc7a6cee4c2
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 Blacklist blacklist[] =
58 {"Lyrdb.com lyric source", "Plugin is integrated into GMPC"},
59 {"Extra Playlist View", "Plugin is integrated into GMPC"},
60 {"Statistics", "Plugin is integrated into GMPC"},
61 {"DiscoGS Artist and Album Image Fetcher", "Plugin is integrated into GMPC"},
62 {"Last FM metadata fetcher", "Plugin is integrated into GMPC"},
63 {"Fullscreen Info", "Plugin is integrated into GMPC"},
64 {"WikiPedia", "Plugin ddos'es Wikipedia"},
65 {"Libnotify Plugin", "Plugin is integrated into GMPC"}
67 static const int num_blacklisted_plugins = sizeof(blacklist)/sizeof(Blacklist);
69 static int plugin_manager_blacklist(gmpcPluginParent *p, GError **error)
71 int i;
72 const char *name = gmpc_plugin_get_name(p);
73 g_assert(name != NULL);
74 for(i = 0; i<num_blacklisted_plugins; i++) {
75 if(strcmp(name, blacklist[i].plugin_name) == 0) {
76 g_set_error(error, plugin_quark(), 0,
77 "pluging has with name: %s is blacklisted: '%s'", name,
78 blacklist[i].reason);
79 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
80 "pluging has with name: %s is blacklisted: '%s'", name,
81 blacklist[i].reason);
82 return TRUE;
85 return FALSE;
88 static int plugin_validate(gmpcPlugin * plug, GError ** error)
90 int i;
91 if (plug->name == NULL)
93 g_set_error(error, plugin_quark(), 0, "%s: %s",
94 _("Failed to load plugin"), _("plugin has no name"));
95 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
96 "pluging has no name: %s", plug->path);
97 return FALSE;
99 for (i = 0; i < num_plugins; i++)
101 if (strcmp(gmpc_plugin_get_name(plugins[i]), plug->name) == 0)
103 g_set_error(error, plugin_quark(), 0, "%s '%s': %s",
104 _("Failed to load plugin"), plug->name,
105 _("plugin with same name already exists"));
106 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
107 "pluging with same name already exists: %s", plug->name);
108 return FALSE;
111 if (plug->set_enabled == NULL || plug->get_enabled == NULL)
113 g_set_error(error, plugin_quark(), 0, "%s: %s",
114 _("Failed to load plugin"),
115 _("plugin is missing set/get enable function"));
116 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
117 "%s: set_enabled == NULL || get_enabled == NULL failed",
118 plug->name);
119 return FALSE;
121 if (plug->plugin_type & GMPC_PLUGIN_PL_BROWSER)
123 if (plug->browser == NULL)
125 g_set_error(error, plugin_quark(), 0, "%s: %s",
126 _("Failed to load plugin"),
127 _("plugin browser structure is incorrect"));
128 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
129 "%s: plugin_type&GMPC_PLUGIN_PL_BROWSER && plugin->browser != NULL Failed",
130 plug->name);
131 return FALSE;
134 /* if there is a browser field, check validity */
135 if (plug->browser)
137 if ((plug->browser->selected && plug->browser->unselected == NULL)
138 || (plug->browser->selected == NULL && plug->browser->unselected))
140 g_set_error(error, plugin_quark(), 0, "%s: %s",
141 _("Failed to load plugin"),
142 _("plugin browser structure is incorrect"));
143 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
144 "%s: If a plugin provides a browser pane, it needs both selected and unselected",
145 plug->name);
146 return FALSE;
149 /* if there is a pref window withouth both construct/destroy, give an error */
150 if (plug->pref)
152 if (!(plug->pref->construct && plug->pref->destroy))
154 g_set_error(error, plugin_quark(), 0, "%s: %s",
155 _("Failed to load plugin"),
156 _("plugin preferences structure is incorrect"));
157 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
158 "%s: If a plugin has a preferences pane, it needs both construct and destroy",
159 plug->name);
163 return TRUE;
166 void plugin_add(gmpcPlugin * plug, int plugin, GError ** error)
168 gmpcPluginParent *parent = g_malloc0(sizeof(*parent));
169 parent->old = plug;
170 parent->new = NULL;
173 if(plugin_manager_blacklist(parent, error))
175 if(error && *error != NULL)
177 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
178 "%s: Not loading plugin.",
179 plug->name);
181 return ;
184 /* set plugin id */
185 plug->id = num_plugins | ((plugin) ? PLUGIN_ID_MARK : PLUGIN_ID_INTERNALL);
186 /* put it in the list */
187 num_plugins++;
188 plugins = g_realloc(plugins, (num_plugins + 1) * sizeof(gmpcPlugin **));
189 plugins[num_plugins - 1] = parent;
190 plugins[num_plugins] = NULL;
193 void plugin_add_new(GmpcPluginBase * plug, int plugin, GError ** error)
195 gmpcPluginParent *parent = g_malloc0(sizeof(*parent));
196 parent->new = plug;
197 parent->old = NULL;
199 if(plugin_manager_blacklist(parent, error))
201 return;
203 /* set plugin id */
204 plug->id = num_plugins | ((plugin) ? PLUGIN_ID_MARK : PLUGIN_ID_INTERNALL);
205 /* put it in the list */
206 num_plugins++;
207 plugins = g_realloc(plugins, (num_plugins + 1) * sizeof(gmpcPlugin **));
208 plugins[num_plugins - 1] = parent;
209 plugins[num_plugins] = NULL;
212 static int plugin_load(const char *path, const char *file, GError ** error)
214 gpointer function;
215 GModule *handle;
216 int *api_version = 0;
217 gmpcPlugin *plug = NULL;
218 gchar *string = NULL;
219 gchar *full_path = NULL;
220 if (path == NULL)
222 return 1;
224 full_path = g_strdup_printf("%s%c%s", path, G_DIR_SEPARATOR, file);
226 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
227 "plugin_load: trying to load plugin %s", full_path);
229 handle = g_module_open(full_path, G_MODULE_BIND_LOCAL);
230 q_free(full_path);
231 if (!handle)
233 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
234 "plugin_load: module failed to load: %s:%s\n", file,
235 g_module_error());
236 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
237 _("Failed to load plugin"), file, g_module_error());
238 return 1;
241 if (g_module_symbol(handle, "plugin_get_type", (gpointer) & function))
243 GmpcPluginBase *new;
244 GType(*get_type) (void);
245 get_type = function;
246 new = g_object_newv(get_type(), 0, NULL);
248 if (!new)
250 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
251 _("Failed to create plugin instance"), file,
252 g_module_error());
253 return 1;
255 new->path = g_strdup(path);
256 plugin_add_new(new, 1, error);
257 return 0;
259 if (!g_module_symbol
260 (handle, "plugin_api_version", (gpointer) & api_version))
263 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
264 "plugin_load: symbol failed to bind: %s:%s\n", file,
265 g_module_error());
267 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
268 _("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,
282 _("Plugin %s has wrong api version: %i"), file,
283 *api_version);
285 q_free(string);
286 g_module_close(handle);
287 return 1;
289 if (!g_module_symbol(handle, "plugin", (gpointer) & (plug)))
291 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
292 "plugin_load: symbol failed to bind: %s:%s\n", file,
293 g_module_error());
295 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
296 _("Plugin %s has wrong no plugin structure: %s"), file,
297 g_module_error());
298 q_free(string);
299 g_module_close(handle);
300 return 1;
302 if (plug == NULL)
304 g_set_error(error, plugin_quark(), 0, "%s %s: '%s'",
305 _("Plugin %s has wrong no plugin structure: %s"), file,
306 g_module_error());
307 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
308 "%s: plugin load: unknown type of plugin.\n", file);
309 g_module_close(handle);
310 return 1;
312 /* set path, plugins might want this for images and glade files. */
313 plug->path = g_strdup(path);
314 if (!plugin_validate(plug, error))
316 g_module_close(handle);
317 return 1;
319 /* add the plugin to the list */
320 plugin_add(plug, 1, error);
321 return 0;
324 static gboolean __show_plugin_load_error(gpointer data)
326 playlist3_show_error_message(_
327 ("One or more plugins failed to load, see help->messages for more information"),
328 ERROR_CRITICAL);
329 return FALSE;
332 void plugin_load_dir(const gchar * path)
334 GDir *dir = g_dir_open(path, 0, NULL);
335 int failure = 0;
336 if (dir)
338 const gchar *dirname = NULL;
339 while ((dirname = g_dir_read_name(dir)) != NULL)
341 gchar *full_path =
342 g_strdup_printf("%s%c%s", path, G_DIR_SEPARATOR, dirname);
343 /* Make sure only to load plugins */
344 if (g_str_has_suffix(dirname, G_MODULE_SUFFIX))
346 GError *error = NULL;
347 if (plugin_load(path, dirname, &error))
349 failure = 1;
350 playlist3_show_error_message(error->message,
351 ERROR_CRITICAL);
352 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
353 "Failed to load plugin: %s: %s\n", dirname,
354 error->message);
355 g_error_free(error);
356 error = NULL;
358 } else
360 g_log(PLUGIN_LOG_DOMAIN, G_LOG_LEVEL_INFO,
361 "%s not loaded, wrong extension, should be: '%s'",
362 dirname, G_MODULE_SUFFIX);
364 q_free(full_path);
366 g_dir_close(dir);
368 if (failure)
370 // TODO
371 g_idle_add(__show_plugin_load_error, NULL);
372 //gtk_init_add(__show_plugin_load_error, NULL);
377 * gmpcPlugin
380 void gmpc_plugin_destroy(gmpcPluginParent * plug)
382 if (plug->new)
384 g_object_unref(plug->new);
385 return;
387 if (plug->old->destroy)
389 plug->old->destroy();
393 void gmpc_plugin_init(gmpcPluginParent * plug)
395 if (plug->new)
397 return;
399 if (plug->old->init)
401 plug->old->init();
405 void gmpc_plugin_status_changed(gmpcPluginParent * plug, MpdObj * mi,
406 ChangedStatusType what)
408 if (plug->new)
409 return;
410 if (plug->old->mpd_status_changed)
412 plug->old->mpd_status_changed(mi, what, NULL);
416 const char *gmpc_plugin_get_name(gmpcPluginParent * plug)
418 /* if new plugin, use that method */
419 if (plug->new)
421 return gmpc_plugin_base_get_name(plug->new);
423 g_assert(plug->old->name != NULL);
424 return plug->old->name;
427 void gmpc_plugin_save_yourself(gmpcPluginParent * plug)
429 if (plug->new)
431 gmpc_plugin_base_save_yourself(plug->new);
432 return;
434 if (plug->old->save_yourself)
436 plug->old->save_yourself();
440 gboolean gmpc_plugin_get_enabled(const gmpcPluginParent * plug)
442 if (plug->new)
444 return gmpc_plugin_base_get_enabled(plug->new);
446 if (plug->old->get_enabled)
448 return plug->old->get_enabled();
450 return TRUE;
453 void gmpc_plugin_set_enabled(gmpcPluginParent * plug, gboolean enabled)
455 if (plug->new)
457 return gmpc_plugin_base_set_enabled(plug->new, enabled);
459 if (plug->old->set_enabled)
461 plug->old->set_enabled(enabled);
465 const gchar *gmpc_plugin_get_translation_domain(gmpcPluginParent * plug)
467 if (plug->new)
469 return plug->new->translation_domain;
471 if (plug->old && plug->old->get_translation_domain)
473 return plug->old->get_translation_domain();
475 return NULL;
478 gchar *gmpc_plugin_get_data_path(gmpcPlugin * plug)
480 #ifdef WIN32
481 gchar *url = g_win32_get_package_installation_directory_of_module(NULL);
482 gchar *retv =
483 g_build_path(G_DIR_SEPARATOR_S, url, "share", "gmpc", "plugins", NULL);
484 return retv; //g_strdup(plug->path);
485 #else
486 int i;
487 const gchar *const *paths = g_get_system_data_dirs();
488 gchar *url = NULL;
489 gchar *homedir = gmpc_get_user_path("");
490 if (strncmp(plug->path, homedir, strlen(homedir)) == 0)
492 url = g_strdup(plug->path);
493 } else
495 /* Ok it is a homedir */
496 url =
497 g_build_path(G_DIR_SEPARATOR_S, PACKAGE_DATA_DIR, "gmpc", "plugins",
498 NULL);
501 g_free(homedir);
503 if (url)
505 if (g_file_test(url, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
507 return url;
509 g_free(url);
510 url = NULL;
513 for (i = 0; paths && paths[i]; i++)
515 url = g_build_filename(paths[i], "gmpc", "plugins", NULL);
516 if (g_file_test(url, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
518 return url;
520 g_free(url);
521 url = NULL;
523 return url;
524 #endif
527 void gmpc_plugin_mpd_connection_changed(gmpcPluginParent * plug, MpdObj * mi,
528 int connected, gpointer data)
530 g_assert(plug != NULL);
532 if (plug->new)
533 return;
534 if (plug->old->mpd_connection_changed != NULL)
536 plug->old->mpd_connection_changed(mi, connected, data);
539 gboolean gmpc_plugin_is_sidebar(gmpcPluginParent *plug)
541 g_assert(plug != NULL);
542 if(plug->new)
544 return GMPC_PLUGIN_IS_SIDEBAR_IFACE(plug->new);
546 return FALSE;
548 void gmpc_plugin_sidebar_init(gmpcPluginParent *plug)
550 if(gmpc_plugin_is_sidebar(plug))
552 gmpc_sidebar_plugins_init(GMPC_PLUGIN_SIDEBAR_IFACE(plug->new));
556 void gmpc_plugin_sidebar_set_state(gmpcPluginParent *plug, GmpcPluginSidebarState state)
558 if(gmpc_plugin_is_sidebar(plug))
560 gmpc_plugin_sidebar_iface_sidebar_set_state(GMPC_PLUGIN_SIDEBAR_IFACE(plug->new), state);
564 gboolean gmpc_plugin_is_browser(gmpcPluginParent * plug)
566 if (plug->new)
568 return GMPC_PLUGIN_IS_BROWSER_IFACE(plug->new);
570 return ((plug->old->plugin_type & GMPC_PLUGIN_PL_BROWSER) != 0);
573 void gmpc_plugin_browser_unselected(gmpcPluginParent * plug,
574 GtkWidget * container)
576 if (gmpc_plugin_is_browser(plug))
578 if (plug->new)
580 gmpc_plugin_browser_iface_browser_unselected((GmpcPluginBrowserIface
581 *) plug->new,
582 GTK_CONTAINER
583 (container));
584 return;
586 g_assert(plug->old->browser != NULL);
587 g_assert(plug->old->browser->unselected != NULL);
588 plug->old->browser->unselected(container);
592 void gmpc_plugin_browser_selected(gmpcPluginParent * plug,
593 GtkWidget * container)
595 if (gmpc_plugin_is_browser(plug))
597 if (plug->new)
599 gmpc_plugin_browser_iface_browser_selected((GmpcPluginBrowserIface
600 *) plug->new,
601 GTK_CONTAINER
602 (container));
603 return;
605 g_assert(plug->old->browser != NULL);
606 g_assert(plug->old->browser->selected != NULL);
607 plug->old->browser->selected(container);
611 void gmpc_plugin_browser_add(gmpcPluginParent * plug, GtkWidget * cat_tree)
613 if (gmpc_plugin_is_browser(plug))
615 if (plug->new)
617 gmpc_plugin_browser_iface_browser_add((GmpcPluginBrowserIface *)
618 plug->new, cat_tree);
619 return;
621 g_assert(plug->old->browser != NULL);
622 if (plug->old->browser->add)
624 plug->old->browser->add(cat_tree);
629 int gmpc_plugin_browser_cat_right_mouse_menu(gmpcPluginParent * plug,
630 GtkWidget * menu, int type,
631 GtkWidget * tree,
632 GdkEventButton * event)
634 if (gmpc_plugin_is_browser(plug))
636 if (plug->new)
638 if (type == plug->new->id)
639 return
640 gmpc_plugin_browser_iface_browser_option_menu((GmpcPluginBrowserIface *) plug->new, GTK_MENU(menu));
641 return 0;
643 g_assert(plug->old->browser != NULL);
644 if (plug->old->browser->cat_right_mouse_menu != NULL)
646 return plug->old->browser->cat_right_mouse_menu(menu, type, tree,
647 event);
650 return 0;
653 int gmpc_plugin_browser_key_press_event(gmpcPluginParent * plug, GtkWidget * mw,
654 GdkEventKey * event, int type)
656 if (gmpc_plugin_is_browser(plug))
658 if (plug->new)
660 /* not going to be implemented */
661 return 0;
663 g_assert(plug->old->browser != NULL);
664 if (plug->old->browser->key_press_event != NULL)
666 return plug->old->browser->key_press_event(mw, event, type);
669 return 0;
672 int gmpc_plugin_browser_add_go_menu(gmpcPluginParent * plug, GtkWidget * menu)
674 if (gmpc_plugin_is_browser(plug))
676 if (plug->new)
678 return
679 gmpc_plugin_browser_iface_browser_add_go_menu((GmpcPluginBrowserIface *) plug->new, GTK_MENU(menu));
681 g_assert(plug->old->browser != NULL);
682 if (plug->old->browser->add_go_menu != NULL)
684 return plug->old->browser->add_go_menu(menu);
687 return 0;
690 int gmpc_plugin_browser_song_list_option_menu(gmpcPluginParent * plug,
691 GtkTreeView * tree,
692 GtkMenu * menu)
694 if (plug->new)
696 if (GMPC_PLUGIN_IS_SONG_LIST_IFACE(plug->new))
698 return
699 gmpc_plugin_song_list_iface_song_list
700 (GMPC_PLUGIN_SONG_LIST_IFACE(plug->new), GTK_WIDGET(tree),
701 menu);
703 return 0;
705 if (gmpc_plugin_is_browser(plug))
707 g_assert(plug->old->browser != NULL);
708 if (plug->old->browser->song_list_option_menu)
710 return plug->old->browser->song_list_option_menu(tree, menu);
713 return 0;
716 gboolean gmpc_plugin_browser_has_integrate_search(gmpcPluginParent * plug)
718 if (plug->new)
720 return GMPC_PLUGIN_IS_INTEGRATE_SEARCH_IFACE(plug->new);
722 if (gmpc_plugin_is_browser(plug))
724 return plug->old->browser->integrate_search != NULL;
726 return FALSE;
729 MpdData *gmpc_plugin_browser_integrate_search(gmpcPluginParent * plug,
730 const int search_field,
731 const gchar * query,
732 GError ** error)
734 if (!gmpc_plugin_browser_has_integrate_search(plug))
735 return NULL;
736 if (plug->new)
737 return
738 gmpc_plugin_integrate_search_iface_search
739 (GMPC_PLUGIN_INTEGRATE_SEARCH_IFACE(plug->new), search_field,
740 query);
741 return plug->old->browser->integrate_search(search_field, query, error);
744 gboolean gmpc_plugin_browser_integrate_search_field_supported(gmpcPluginParent *
745 plug,
746 const int
747 search_field)
749 if (!gmpc_plugin_browser_has_integrate_search(plug))
750 return FALSE;
752 if (plug->new)
753 return
754 gmpc_plugin_integrate_search_iface_field_supported
755 (GMPC_PLUGIN_INTEGRATE_SEARCH_IFACE(plug->new), search_field);
757 if (plug->old->browser->integrate_search_field_supported == NULL)
758 return TRUE;
759 return plug->old->browser->integrate_search_field_supported(search_field);
762 gboolean gmpc_plugin_has_preferences(gmpcPluginParent * plug)
764 if (plug->new)
766 return GMPC_PLUGIN_IS_PREFERENCES_IFACE(plug->new);
768 return (plug->old->pref != NULL);
771 void gmpc_plugin_preferences_construct(gmpcPluginParent * plug, GtkWidget * wid)
773 if (gmpc_plugin_has_preferences(plug))
775 if (plug->new)
777 gmpc_plugin_preferences_iface_preferences_pane_construct
778 (GMPC_PLUGIN_PREFERENCES_IFACE(plug->new), GTK_CONTAINER(wid));
779 return;
781 g_assert(plug->old->pref != NULL);
782 g_assert(plug->old->pref->construct);
783 plug->old->pref->construct(wid);
787 void gmpc_plugin_preferences_destroy(gmpcPluginParent * plug, GtkWidget * wid)
789 if (gmpc_plugin_has_preferences(plug))
791 if (plug->new)
793 gmpc_plugin_preferences_iface_preferences_pane_destroy
794 (GMPC_PLUGIN_PREFERENCES_IFACE(plug->new), GTK_CONTAINER(wid));
795 return;
797 g_assert(plug->old->pref != NULL);
798 g_assert(plug->old->pref->destroy);
799 plug->old->pref->destroy(wid);
803 gboolean gmpc_plugin_is_internal(gmpcPluginParent * plug)
805 if (plug->new)
807 return (((plug->new->plugin_type) & GMPC_INTERNALL) != 0);
810 return (((plug->old->plugin_type) & GMPC_INTERNALL) != 0);
813 const int *gmpc_plugin_get_version(gmpcPluginParent * plug)
815 if (plug->new)
817 gint length;
818 return (const int *)gmpc_plugin_base_get_version(plug->new, &length);
820 return (const int *)plug->old->version;
823 int gmpc_plugin_get_type(gmpcPluginParent * plug)
825 if (plug->new)
827 return plug->new->plugin_type;
829 return plug->old->plugin_type;
832 int gmpc_plugin_get_id(gmpcPluginParent * plug)
834 if (plug->new)
836 return plug->new->id;
838 return plug->old->id;
841 gint gmpc_plugin_tool_menu_integration(gmpcPluginParent * plug, GtkMenu * menu)
843 if (plug->new)
845 if (GMPC_PLUGIN_IS_TOOL_MENU_IFACE(plug->new))
847 return
848 gmpc_plugin_tool_menu_iface_tool_menu_integration
849 (GMPC_PLUGIN_TOOL_MENU_IFACE(plug->new), menu);
851 return 0;
853 if (plug->old)
855 if (plug->old->tool_menu_integration)
856 return plug->old->tool_menu_integration(menu);
858 return 0;
861 gboolean gmpc_plugin_has_enabled(gmpcPluginParent * plug)
863 if (plug->new)
865 return TRUE;
867 if (plug->old && plug->old->get_enabled && plug->old->set_enabled)
868 return TRUE;
869 return FALSE;