Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
interface.c
Go to the documentation of this file.
00001 /*
00002  * Audacious2
00003  * Copyright (c) 2008 William Pitcock <nenolod@dereferenced.org>
00004  * Copyright (c) 2008-2009 Tomasz Moń <desowin@gmail.com>
00005  * Copyright (c) 2010-2011 John Lindgren <john.lindgren@tds.net>
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; under version 3 of the License.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses>.
00018  *
00019  * The Audacious team does not consider modular code linking to
00020  * Audacious or using our public API to be a derived work.
00021  */
00022 
00023 #include <gtk/gtk.h>
00024 
00025 #include <libaudcore/hook.h>
00026 
00027 #include "debug.h"
00028 #include "general.h"
00029 #include "interface.h"
00030 #include "plugin.h"
00031 #include "plugins.h"
00032 #include "visualization.h"
00033 
00034 static IfacePlugin *current_interface = NULL;
00035 
00036 gboolean interface_load (PluginHandle * plugin)
00037 {
00038     IfacePlugin * i = plugin_get_header (plugin);
00039     g_return_val_if_fail (i, FALSE);
00040 
00041     if (PLUGIN_HAS_FUNC (i, init) && ! i->init ())
00042         return FALSE;
00043 
00044     current_interface = i;
00045     return TRUE;
00046 }
00047 
00048 void interface_unload (void)
00049 {
00050     g_return_if_fail (current_interface);
00051 
00052     if (PLUGIN_HAS_FUNC (current_interface, cleanup))
00053         current_interface->cleanup ();
00054 
00055     current_interface = NULL;
00056 }
00057 
00058 void interface_show (gboolean show)
00059 {
00060     g_return_if_fail (current_interface);
00061 
00062     if (PLUGIN_HAS_FUNC (current_interface, show))
00063         current_interface->show (show);
00064 }
00065 
00066 gboolean interface_is_shown (void)
00067 {
00068     g_return_val_if_fail (current_interface, FALSE);
00069 
00070     if (PLUGIN_HAS_FUNC (current_interface, is_shown))
00071         return current_interface->is_shown ();
00072     return TRUE;
00073 }
00074 
00075 gboolean interface_is_focused (void)
00076 {
00077     g_return_val_if_fail (current_interface, FALSE);
00078 
00079     if (PLUGIN_HAS_FUNC (current_interface, is_focused))
00080         return current_interface->is_focused ();
00081     return TRUE;
00082 }
00083 
00084 void interface_show_error (const gchar * markup)
00085 {
00086     g_return_if_fail (current_interface);
00087 
00088     if (PLUGIN_HAS_FUNC (current_interface, show_error))
00089         current_interface->show_error (markup);
00090 }
00091 
00092 /*
00093  * gboolean play_button
00094  *       TRUE  - open files
00095  *       FALSE - add files
00096  */
00097 void interface_show_filebrowser (gboolean play_button)
00098 {
00099     g_return_if_fail (current_interface);
00100 
00101     if (PLUGIN_HAS_FUNC (current_interface, show_filebrowser))
00102         current_interface->show_filebrowser (play_button);
00103 }
00104 
00105 void interface_show_jump_to_track (void)
00106 {
00107     g_return_if_fail (current_interface);
00108 
00109     if (PLUGIN_HAS_FUNC (current_interface, show_jump_to_track))
00110         current_interface->show_jump_to_track ();
00111 }
00112 
00113 static gboolean delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle *
00114  plugin)
00115 {
00116     plugin_enable (plugin, FALSE);
00117     return TRUE;
00118 }
00119 
00120 void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00121 {
00122     g_return_if_fail (current_interface);
00123 
00124     if (PLUGIN_HAS_FUNC (current_interface, run_gtk_plugin))
00125         current_interface->run_gtk_plugin (widget, plugin_get_name (plugin));
00126     else
00127     {
00128         GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00129         gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin));
00130         gtk_container_add ((GtkContainer *) window, widget);
00131         g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
00132         gtk_widget_show_all (window);
00133     }
00134 }
00135 
00136 void interface_remove_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00137 {
00138     g_return_if_fail (current_interface);
00139 
00140     if (PLUGIN_HAS_FUNC (current_interface, stop_gtk_plugin))
00141         current_interface->stop_gtk_plugin (widget);
00142     else
00143         gtk_widget_destroy (gtk_widget_get_parent (widget));
00144 }
00145 
00146 void interface_install_toolbar (void * widget)
00147 {
00148     g_return_if_fail (current_interface);
00149 
00150     if (PLUGIN_HAS_FUNC (current_interface, install_toolbar))
00151         current_interface->install_toolbar (widget);
00152     else
00153         g_object_ref (widget);
00154 }
00155 
00156 void interface_uninstall_toolbar (void * widget)
00157 {
00158     g_return_if_fail (current_interface);
00159 
00160     if (PLUGIN_HAS_FUNC (current_interface, uninstall_toolbar))
00161         current_interface->uninstall_toolbar (widget);
00162     else
00163         g_object_unref (widget);
00164 }
00165 
00166 typedef enum {
00167     HOOK_SHOW,
00168     HOOK_SHOW_TOGGLE,
00169     HOOK_SHOW_ERROR,
00170     HOOK_SHOW_JUMPTOTRACK,
00171     HOOK_SHOW_FILEBROWSER,
00172 } IfaceHookID;
00173 
00174 void interface_hook_handler (void * hook_data, void * user_data)
00175 {
00176     switch (GPOINTER_TO_INT (user_data))
00177     {
00178     case HOOK_SHOW:
00179         interface_show (GPOINTER_TO_INT (hook_data));
00180         break;
00181     case HOOK_SHOW_TOGGLE:
00182         interface_show (! (interface_is_shown () && interface_is_focused ()));
00183         break;
00184     case HOOK_SHOW_ERROR:
00185         interface_show_error (hook_data);
00186         break;
00187     case HOOK_SHOW_FILEBROWSER:
00188         interface_show_filebrowser (GPOINTER_TO_INT (hook_data));
00189         break;
00190     case HOOK_SHOW_JUMPTOTRACK:
00191         interface_show_jump_to_track ();
00192         break;
00193     }
00194 }
00195 
00196 typedef struct {
00197     const gchar *name;
00198     IfaceHookID id;
00199 } IfaceHooks;
00200 
00201 static IfaceHooks hooks[] = {
00202     {"interface show", HOOK_SHOW},
00203     {"interface toggle visibility", HOOK_SHOW_TOGGLE},
00204     {"interface show error", HOOK_SHOW_ERROR},
00205     {"interface show filebrowser", HOOK_SHOW_FILEBROWSER},
00206     {"interface show jump to track", HOOK_SHOW_JUMPTOTRACK},
00207 };
00208 
00209 void
00210 register_interface_hooks(void)
00211 {
00212     gint i;
00213     for (i=0; i<G_N_ELEMENTS(hooks); i++)
00214         hook_associate(hooks[i].name,
00215                        (HookFunction) interface_hook_handler,
00216                        GINT_TO_POINTER(hooks[i].id));
00217 
00218 }
00219 
00220 static gboolean probe_cb (PluginHandle * p, PluginHandle * * pp)
00221 {
00222     * pp = p;
00223     return FALSE;
00224 }
00225 
00226 PluginHandle * iface_plugin_probe (void)
00227 {
00228     PluginHandle * p = NULL;
00229     plugin_for_each (PLUGIN_TYPE_IFACE, (PluginForEachFunc) probe_cb, & p);
00230     return p;
00231 }
00232 
00233 static PluginHandle * current_plugin = NULL;
00234 
00235 PluginHandle * iface_plugin_get_current (void)
00236 {
00237     return current_plugin;
00238 }
00239 
00240 gboolean iface_plugin_set_current (PluginHandle * plugin)
00241 {
00242     hook_call ("config save", NULL); /* tell interface to save layout */
00243 
00244     if (current_plugin != NULL)
00245     {
00246         AUDDBG ("Unloading plugin widgets.\n");
00247         general_cleanup ();
00248 
00249         AUDDBG ("Unloading visualizers.\n");
00250         vis_cleanup ();
00251 
00252         AUDDBG ("Unloading %s.\n", plugin_get_name (current_plugin));
00253         interface_unload ();
00254 
00255         current_plugin = NULL;
00256     }
00257 
00258     if (plugin != NULL)
00259     {
00260         AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
00261 
00262         if (! interface_load (plugin))
00263             return FALSE;
00264 
00265         current_plugin = plugin;
00266 
00267         AUDDBG ("Loading visualizers.\n");
00268         vis_init ();
00269 
00270         AUDDBG ("Loading plugin widgets.\n");
00271         general_init ();
00272     }
00273 
00274     return TRUE;
00275 }