00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00130
00131
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);
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 }