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 #include <pthread.h>
00025 
00026 #include <libaudcore/hook.h>
00027 
00028 #include "debug.h"
00029 #include "general.h"
00030 #include "interface.h"
00031 #include "main.h"
00032 #include "misc.h"
00033 #include "plugin.h"
00034 #include "plugins.h"
00035 #include "visualization.h"
00036 
00037 static IfacePlugin *current_interface = NULL;
00038 
00039 static pthread_mutex_t error_mutex = PTHREAD_MUTEX_INITIALIZER;
00040 static GQueue error_queue = G_QUEUE_INIT;
00041 static int error_source;
00042 
00043 bool_t interface_load (PluginHandle * plugin)
00044 {
00045     IfacePlugin * i = plugin_get_header (plugin);
00046     g_return_val_if_fail (i, FALSE);
00047 
00048     if (PLUGIN_HAS_FUNC (i, init) && ! i->init ())
00049         return FALSE;
00050 
00051     current_interface = i;
00052     return TRUE;
00053 }
00054 
00055 void interface_unload (void)
00056 {
00057     g_return_if_fail (current_interface);
00058 
00059     if (PLUGIN_HAS_FUNC (current_interface, cleanup))
00060         current_interface->cleanup ();
00061 
00062     current_interface = NULL;
00063 }
00064 
00065 void interface_show (bool_t show)
00066 {
00067     g_return_if_fail (current_interface);
00068 
00069     if (PLUGIN_HAS_FUNC (current_interface, show))
00070         current_interface->show (show);
00071 }
00072 
00073 bool_t interface_is_shown (void)
00074 {
00075     g_return_val_if_fail (current_interface, FALSE);
00076 
00077     if (PLUGIN_HAS_FUNC (current_interface, is_shown))
00078         return current_interface->is_shown ();
00079     return TRUE;
00080 }
00081 
00082 bool_t interface_is_focused (void)
00083 {
00084     g_return_val_if_fail (current_interface, FALSE);
00085 
00086     if (PLUGIN_HAS_FUNC (current_interface, is_focused))
00087         return current_interface->is_focused ();
00088     return TRUE;
00089 }
00090 
00091 static bool_t error_idle_func (void * unused)
00092 {
00093     pthread_mutex_lock (& error_mutex);
00094 
00095     char * message;
00096     while ((message = g_queue_pop_head (& error_queue)))
00097     {
00098         pthread_mutex_unlock (& error_mutex);
00099 
00100         if (current_interface && PLUGIN_HAS_FUNC (current_interface, show_error))
00101             current_interface->show_error (message);
00102         else
00103             fprintf (stderr, "ERROR: %s\n", message);
00104 
00105         g_free (message);
00106 
00107         pthread_mutex_lock (& error_mutex);
00108     }
00109 
00110     error_source = 0;
00111 
00112     pthread_mutex_unlock (& error_mutex);
00113     return FALSE;
00114 }
00115 
00116 void interface_show_error (const char * message)
00117 {
00118     pthread_mutex_lock (& error_mutex);
00119 
00120     g_queue_push_tail (& error_queue, g_strdup (message));
00121 
00122     if (! error_source)
00123         error_source = g_idle_add (error_idle_func, NULL);
00124 
00125     pthread_mutex_unlock (& error_mutex);
00126 }
00127 
00128 /*
00129  * bool_t play_button
00130  *       TRUE  - open files
00131  *       FALSE - add files
00132  */
00133 void interface_show_filebrowser (bool_t play_button)
00134 {
00135     g_return_if_fail (current_interface);
00136 
00137     if (PLUGIN_HAS_FUNC (current_interface, show_filebrowser))
00138         current_interface->show_filebrowser (play_button);
00139 }
00140 
00141 void interface_show_jump_to_track (void)
00142 {
00143     g_return_if_fail (current_interface);
00144 
00145     if (PLUGIN_HAS_FUNC (current_interface, show_jump_to_track))
00146         current_interface->show_jump_to_track ();
00147 }
00148 
00149 static bool_t delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle *
00150  plugin)
00151 {
00152     plugin_enable (plugin, FALSE);
00153     return TRUE;
00154 }
00155 
00156 void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00157 {
00158     g_return_if_fail (current_interface);
00159 
00160     if (PLUGIN_HAS_FUNC (current_interface, run_gtk_plugin))
00161         current_interface->run_gtk_plugin (widget, plugin_get_name (plugin));
00162     else
00163     {
00164         GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00165         gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin));
00166         gtk_window_set_default_size ((GtkWindow *) window, 300, 200);
00167         gtk_container_add ((GtkContainer *) window, widget);
00168         g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
00169         gtk_widget_show_all (window);
00170     }
00171 }
00172 
00173 void interface_remove_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00174 {
00175     g_return_if_fail (current_interface);
00176 
00177     if (PLUGIN_HAS_FUNC (current_interface, stop_gtk_plugin))
00178         current_interface->stop_gtk_plugin (widget);
00179     else
00180         gtk_widget_destroy (gtk_widget_get_parent (widget));
00181 }
00182 
00183 void interface_install_toolbar (void * widget)
00184 {
00185     g_return_if_fail (current_interface);
00186 
00187     if (PLUGIN_HAS_FUNC (current_interface, install_toolbar))
00188         current_interface->install_toolbar (widget);
00189     else
00190         g_object_ref (widget);
00191 }
00192 
00193 void interface_uninstall_toolbar (void * widget)
00194 {
00195     g_return_if_fail (current_interface);
00196 
00197     if (PLUGIN_HAS_FUNC (current_interface, uninstall_toolbar))
00198         current_interface->uninstall_toolbar (widget);
00199     else
00200         g_object_unref (widget);
00201 }
00202 
00203 static bool_t probe_cb (PluginHandle * p, PluginHandle * * pp)
00204 {
00205     * pp = p;
00206     return FALSE;
00207 }
00208 
00209 PluginHandle * iface_plugin_probe (void)
00210 {
00211     PluginHandle * p = NULL;
00212     plugin_for_each (PLUGIN_TYPE_IFACE, (PluginForEachFunc) probe_cb, & p);
00213     return p;
00214 }
00215 
00216 static PluginHandle * current_plugin = NULL;
00217 
00218 PluginHandle * iface_plugin_get_current (void)
00219 {
00220     return current_plugin;
00221 }
00222 
00223 bool_t iface_plugin_set_current (PluginHandle * plugin)
00224 {
00225     hook_call ("config save", NULL); /* tell interface to save layout */
00226 
00227     if (current_plugin != NULL)
00228     {
00229         AUDDBG ("Unloading plugin widgets.\n");
00230         general_cleanup ();
00231 
00232         AUDDBG ("Unloading visualizers.\n");
00233         vis_cleanup ();
00234 
00235         AUDDBG ("Unloading %s.\n", plugin_get_name (current_plugin));
00236         interface_unload ();
00237 
00238         current_plugin = NULL;
00239     }
00240 
00241     if (plugin != NULL)
00242     {
00243         AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
00244 
00245         if (! interface_load (plugin))
00246             return FALSE;
00247 
00248         current_plugin = plugin;
00249 
00250         AUDDBG ("Loading visualizers.\n");
00251         vis_init ();
00252 
00253         AUDDBG ("Loading plugin widgets.\n");
00254         general_init ();
00255     }
00256 
00257     return TRUE;
00258 }