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 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 <string.h>
00024 #include <gtk/gtk.h>
00025 
00026 #include <libaudcore/hook.h>
00027 
00028 #include "audconfig.h"
00029 #include "config.h"
00030 #include "debug.h"
00031 #include "general.h"
00032 #include "i18n.h"
00033 #include "interface.h"
00034 #include "misc.h"
00035 #include "plugins.h"
00036 #include "ui_preferences.h"
00037 #include "visualization.h"
00038 
00039 static Iface *current_interface = NULL;
00040 
00041 static IfaceOps interface_ops = {
00042     .create_prefs_window = create_prefs_window,
00043     .show_prefs_window = show_prefs_window,
00044     .hide_prefs_window = hide_prefs_window,
00045     .destroy_prefs_window = destroy_prefs_window,
00046     .prefswin_page_new = prefswin_page_new,
00047 };
00048 
00049 static IfaceCbs interface_cbs = { NULL };
00050 
00051 gboolean interface_load (PluginHandle * plugin)
00052 {
00053     Iface * i = (Iface *) plugin_get_header (plugin);
00054     g_return_val_if_fail (i != NULL, FALSE);
00055 
00056     current_interface = i;
00057     i->ops = & interface_ops;
00058     return i->init (& interface_cbs);
00059 }
00060 
00061 void interface_unload (void)
00062 {
00063     g_return_if_fail (current_interface != NULL);
00064 
00065     if (current_interface->fini != NULL)
00066         current_interface->fini ();
00067 
00068     current_interface = NULL;
00069     memset (& interface_cbs, 0, sizeof interface_cbs);
00070 }
00071 
00072 void
00073 interface_show_prefs_window(gboolean show)
00074 {
00075     if (interface_cbs.show_prefs_window != NULL)
00076         interface_cbs.show_prefs_window(show);
00077     else
00078         AUDDBG ("Interface didn't register show_prefs_window function.\n");
00079 }
00080 
00081 /*
00082  * gboolean play_button
00083  *       TRUE  - open files
00084  *       FALSE - add files
00085  */
00086 void
00087 interface_run_filebrowser(gboolean play_button)
00088 {
00089     if (interface_cbs.run_filebrowser != NULL)
00090         interface_cbs.run_filebrowser(play_button);
00091     else
00092         AUDDBG ("Interface didn't register run_filebrowser function.\n");
00093 }
00094 
00095 void
00096 interface_hide_filebrowser(void)
00097 {
00098     if (interface_cbs.hide_filebrowser != NULL)
00099         interface_cbs.hide_filebrowser();
00100     else
00101         AUDDBG ("Interface didn't register hide_filebrowser function.\n");
00102 }
00103 
00104 void
00105 interface_toggle_visibility(void)
00106 {
00107     if (interface_cbs.toggle_visibility != NULL)
00108         interface_cbs.toggle_visibility();
00109     else
00110         AUDDBG ("Interface didn't register toggle_visibility function.\n");
00111 }
00112 
00113 void
00114 interface_show_error_message(const gchar * markup)
00115 {
00116     if (interface_cbs.show_error != NULL)
00117         interface_cbs.show_error(markup);
00118     else
00119         AUDDBG ("Interface didn't register show_error function.\n");
00120 }
00121 
00122 void
00123 interface_show_jump_to_track(void)
00124 {
00125     if (interface_cbs.show_jump_to_track != NULL)
00126         interface_cbs.show_jump_to_track();
00127     else
00128         AUDDBG ("Interface didn't register show_jump_to_track function.\n");
00129 }
00130 
00131 void
00132 interface_hide_jump_to_track(void)
00133 {
00134     if (interface_cbs.hide_jump_to_track != NULL)
00135         interface_cbs.hide_jump_to_track();
00136     else
00137         AUDDBG ("Interface didn't register hide_jump_to_track function.\n");
00138 }
00139 
00140 void
00141 interface_show_about_window(gboolean show)
00142 {
00143     if (show == FALSE) {
00144         if (interface_cbs.hide_about_window != NULL)
00145             interface_cbs.hide_about_window();
00146         else
00147             AUDDBG ("Interface didn't register hide_about_window function.\n");
00148     } else {
00149         if (interface_cbs.show_about_window != NULL)
00150             interface_cbs.show_about_window();
00151         else
00152             AUDDBG ("Interface didn't register show_about_window function.\n");
00153     }
00154 }
00155 
00156 static gboolean delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle *
00157  plugin)
00158 {
00159     plugin_enable (plugin, FALSE);
00160     return TRUE;
00161 }
00162 
00163 void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00164 {
00165     if (interface_cbs.run_gtk_plugin != NULL)
00166         interface_cbs.run_gtk_plugin (widget, plugin_get_name (plugin));
00167     else
00168     {
00169         GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00170         gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin));
00171         gtk_container_add ((GtkContainer *) window, widget);
00172         g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
00173         gtk_widget_show_all (window);
00174     }
00175 }
00176 
00177 void interface_remove_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00178 {
00179     if (interface_cbs.stop_gtk_plugin != NULL)
00180         interface_cbs.stop_gtk_plugin (widget);
00181     else
00182         gtk_widget_destroy (gtk_widget_get_parent (widget));
00183 }
00184 
00185 void
00186 interface_install_toolbar(void *widget)
00187 {
00188     if (interface_cbs.install_toolbar != NULL)
00189         interface_cbs.install_toolbar(widget);
00190     else
00191         AUDDBG ("Interface didn't register install_toolbar function.\n");
00192 }
00193 
00194 void
00195 interface_uninstall_toolbar(void *widget)
00196 {
00197     if (interface_cbs.uninstall_toolbar != NULL)
00198         interface_cbs.uninstall_toolbar(widget);
00199     else
00200         AUDDBG ("Interface didn't register uninstall_toolbar function.\n");
00201 }
00202 
00203 void
00204 interface_toggle_shuffle(void)
00205 {
00206     if (interface_cbs.toggle_shuffle != NULL)
00207         interface_cbs.toggle_shuffle();
00208     else
00209         AUDDBG ("Interface didn't register toggle_shuffle function.\n");
00210 }
00211 
00212 void
00213 interface_toggle_repeat(void)
00214 {
00215     if (interface_cbs.toggle_repeat != NULL)
00216         interface_cbs.toggle_repeat();
00217     else
00218         AUDDBG ("Interface didn't register toggle_repeat function.\n");
00219 }
00220 
00221 typedef enum {
00222     HOOK_PREFSWIN_SHOW,
00223     HOOK_FILEBROWSER_SHOW,
00224     HOOK_FILEBROWSER_HIDE,
00225     HOOK_TOGGLE_VISIBILITY,
00226     HOOK_SHOW_ERROR,
00227     HOOK_JUMPTOTRACK_SHOW,
00228     HOOK_JUMPTOTRACK_HIDE,
00229     HOOK_ABOUTWIN_SHOW,
00230     HOOK_TOGGLE_SHUFFLE,
00231     HOOK_TOGGLE_REPEAT,
00232 } IfaceHookID;
00233 
00234 void
00235 interface_hook_handler(gpointer hook_data, gpointer user_data)
00236 {
00237     switch (GPOINTER_TO_INT(user_data)) {
00238         case HOOK_PREFSWIN_SHOW:
00239             interface_show_prefs_window(GPOINTER_TO_INT(hook_data));
00240             break;
00241         case HOOK_FILEBROWSER_SHOW:
00242             interface_run_filebrowser(GPOINTER_TO_INT(hook_data));
00243             break;
00244         case HOOK_FILEBROWSER_HIDE:
00245             interface_hide_filebrowser();
00246             break;
00247         case HOOK_TOGGLE_VISIBILITY:
00248             interface_toggle_visibility();
00249             break;
00250         case HOOK_SHOW_ERROR:
00251             interface_show_error_message((const gchar *) hook_data);
00252             break;
00253         case HOOK_JUMPTOTRACK_SHOW:
00254             interface_show_jump_to_track();
00255             break;
00256         case HOOK_JUMPTOTRACK_HIDE:
00257             interface_hide_jump_to_track();
00258             break;
00259         case HOOK_ABOUTWIN_SHOW:
00260             interface_show_about_window(GPOINTER_TO_INT(hook_data));
00261             break;
00262         case HOOK_TOGGLE_SHUFFLE:
00263             interface_toggle_shuffle();
00264             break;
00265         case HOOK_TOGGLE_REPEAT:
00266             interface_toggle_repeat();
00267             break;
00268         default:
00269             break;
00270     }
00271 }
00272 
00273 typedef struct {
00274     const gchar *name;
00275     IfaceHookID id;
00276 } IfaceHooks;
00277 
00278 static IfaceHooks hooks[] = {
00279     {"prefswin show", HOOK_PREFSWIN_SHOW},
00280     {"filebrowser show", HOOK_FILEBROWSER_SHOW},
00281     {"filebrowser hide", HOOK_FILEBROWSER_HIDE},
00282     {"interface toggle visibility", HOOK_TOGGLE_VISIBILITY},
00283     {"interface show error", HOOK_SHOW_ERROR},
00284     {"interface show jump to track", HOOK_JUMPTOTRACK_SHOW},
00285     {"interface hide jump to track", HOOK_JUMPTOTRACK_HIDE},
00286     {"aboutwin show", HOOK_ABOUTWIN_SHOW},
00287     {"toggle shuffle", HOOK_TOGGLE_SHUFFLE},
00288     {"toggle repeat", HOOK_TOGGLE_REPEAT},
00289 };
00290 
00291 void
00292 register_interface_hooks(void)
00293 {
00294     gint i;
00295     for (i=0; i<G_N_ELEMENTS(hooks); i++)
00296         hook_associate(hooks[i].name,
00297                        (HookFunction) interface_hook_handler,
00298                        GINT_TO_POINTER(hooks[i].id));
00299 
00300 }
00301 
00302 static gboolean probe_cb (PluginHandle * p, PluginHandle * * pp)
00303 {
00304     * pp = p;
00305     return FALSE;
00306 }
00307 
00308 PluginHandle * iface_plugin_probe (void)
00309 {
00310     PluginHandle * p = NULL;
00311     plugin_for_each (PLUGIN_TYPE_IFACE, (PluginForEachFunc) probe_cb, & p);
00312     return p;
00313 }
00314 
00315 static PluginHandle * current_plugin = NULL;
00316 
00317 PluginHandle * iface_plugin_get_current (void)
00318 {
00319     return current_plugin;
00320 }
00321 
00322 gboolean iface_plugin_set_current (PluginHandle * plugin)
00323 {
00324     if (current_plugin != NULL)
00325     {
00326         AUDDBG ("Unloading plugin widgets.\n");
00327         general_cleanup ();
00328 
00329         AUDDBG ("Unloading visualizers.\n");
00330         vis_cleanup ();
00331 
00332         AUDDBG ("Unloading %s.\n", plugin_get_name (current_plugin));
00333         interface_unload ();
00334 
00335         current_plugin = NULL;
00336     }
00337 
00338     if (plugin != NULL)
00339     {
00340         AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
00341 
00342         if (! interface_load (plugin))
00343             return FALSE;
00344 
00345         current_plugin = plugin;
00346 
00347         AUDDBG ("Loading visualizers.\n");
00348         vis_init ();
00349 
00350         AUDDBG ("Loading plugin widgets.\n");
00351         general_init ();
00352     }
00353 
00354     return TRUE;
00355 }