00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023 #include <gtk/gtk.h>
00024
00025 #include <libaudcore/hook.h>
00026
00027 #include "audconfig.h"
00028 #include "config.h"
00029 #include "debug.h"
00030 #include "i18n.h"
00031 #include "interface.h"
00032 #include "plugins.h"
00033 #include "ui_preferences.h"
00034
00035 static Interface *current_interface = NULL;
00036
00037 static InterfaceOps interface_ops = {
00038 .create_prefs_window = create_prefs_window,
00039 .show_prefs_window = show_prefs_window,
00040 .hide_prefs_window = hide_prefs_window,
00041 .destroy_prefs_window = destroy_prefs_window,
00042 .prefswin_page_new = prefswin_page_new,
00043 };
00044
00045 static InterfaceCbs interface_cbs = { NULL };
00046
00047 static gboolean interface_search_cb (PluginHandle * plugin, PluginHandle * *
00048 pluginp)
00049 {
00050 * pluginp = plugin;
00051 return FALSE;
00052 }
00053
00054 PluginHandle * interface_get_default (void)
00055 {
00056 PluginHandle * plugin = NULL;
00057
00058 if (cfg.iface_path == NULL || (plugin = plugin_by_path (cfg.iface_path,
00059 PLUGIN_TYPE_IFACE, cfg.iface_number)) == NULL || ! plugin_get_enabled
00060 (plugin))
00061 {
00062 AUDDBG ("Searching for an interface.\n");
00063 plugin_for_enabled (PLUGIN_TYPE_IFACE, (PluginForEachFunc)
00064 interface_search_cb, & plugin);
00065 if (plugin == NULL)
00066 return NULL;
00067
00068 interface_set_default (plugin);
00069 }
00070
00071 return plugin;
00072 }
00073
00074 void interface_set_default (PluginHandle * plugin)
00075 {
00076 const gchar * path;
00077 gint type;
00078
00079 g_free (cfg.iface_path);
00080 plugin_get_path (plugin, & path, & type, & cfg.iface_number);
00081 cfg.iface_path = g_strdup (path);
00082 }
00083
00084 gboolean interface_load (PluginHandle * plugin)
00085 {
00086 Interface * i = plugin_get_header (plugin);
00087 g_return_val_if_fail (i != NULL, FALSE);
00088
00089 current_interface = i;
00090 i->ops = & interface_ops;
00091 return i->init (& interface_cbs);
00092 }
00093
00094 void interface_unload (void)
00095 {
00096 g_return_if_fail (current_interface != NULL);
00097
00098 if (current_interface->fini != NULL)
00099 current_interface->fini ();
00100
00101 current_interface = NULL;
00102 memset (& interface_cbs, 0, sizeof interface_cbs);
00103 }
00104
00105 void
00106 interface_show_prefs_window(gboolean show)
00107 {
00108 if (interface_cbs.show_prefs_window != NULL)
00109 interface_cbs.show_prefs_window(show);
00110 else
00111 AUDDBG ("Interface didn't register show_prefs_window function.\n");
00112 }
00113
00114
00115
00116
00117
00118
00119 void
00120 interface_run_filebrowser(gboolean play_button)
00121 {
00122 if (interface_cbs.run_filebrowser != NULL)
00123 interface_cbs.run_filebrowser(play_button);
00124 else
00125 AUDDBG ("Interface didn't register run_filebrowser function.\n");
00126 }
00127
00128 void
00129 interface_hide_filebrowser(void)
00130 {
00131 if (interface_cbs.hide_filebrowser != NULL)
00132 interface_cbs.hide_filebrowser();
00133 else
00134 AUDDBG ("Interface didn't register hide_filebrowser function.\n");
00135 }
00136
00137 void
00138 interface_toggle_visibility(void)
00139 {
00140 if (interface_cbs.toggle_visibility != NULL)
00141 interface_cbs.toggle_visibility();
00142 else
00143 AUDDBG ("Interface didn't register toggle_visibility function.\n");
00144 }
00145
00146 void
00147 interface_show_error_message(const gchar * markup)
00148 {
00149 if (interface_cbs.show_error != NULL)
00150 interface_cbs.show_error(markup);
00151 else
00152 AUDDBG ("Interface didn't register show_error function.\n");
00153 }
00154
00155 void
00156 interface_show_jump_to_track(void)
00157 {
00158 if (interface_cbs.show_jump_to_track != NULL)
00159 interface_cbs.show_jump_to_track();
00160 else
00161 AUDDBG ("Interface didn't register show_jump_to_track function.\n");
00162 }
00163
00164 void
00165 interface_hide_jump_to_track(void)
00166 {
00167 if (interface_cbs.hide_jump_to_track != NULL)
00168 interface_cbs.hide_jump_to_track();
00169 else
00170 AUDDBG ("Interface didn't register hide_jump_to_track function.\n");
00171 }
00172
00173 void
00174 interface_show_about_window(gboolean show)
00175 {
00176 if (show == FALSE) {
00177 if (interface_cbs.hide_about_window != NULL)
00178 interface_cbs.hide_about_window();
00179 else
00180 AUDDBG ("Interface didn't register hide_about_window function.\n");
00181 } else {
00182 if (interface_cbs.show_about_window != NULL)
00183 interface_cbs.show_about_window();
00184 else
00185 AUDDBG ("Interface didn't register show_about_window function.\n");
00186 }
00187 }
00188
00189 static gboolean delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle *
00190 plugin)
00191 {
00192 vis_plugin_enable (plugin, FALSE);
00193 return TRUE;
00194 }
00195
00196 void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00197 {
00198 if (interface_cbs.run_gtk_plugin != NULL)
00199 interface_cbs.run_gtk_plugin (widget, plugin_get_name (plugin));
00200 else
00201 {
00202 GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00203 gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin));
00204 gtk_container_add ((GtkContainer *) window, widget);
00205 g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
00206 gtk_widget_show_all (window);
00207 }
00208 }
00209
00210 void interface_remove_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
00211 {
00212 if (interface_cbs.stop_gtk_plugin != NULL)
00213 interface_cbs.stop_gtk_plugin (widget);
00214 else
00215 gtk_widget_destroy (gtk_widget_get_parent (widget));
00216 }
00217
00218 void
00219 interface_toggle_shuffle(void)
00220 {
00221 if (interface_cbs.toggle_shuffle != NULL)
00222 interface_cbs.toggle_shuffle();
00223 else
00224 AUDDBG ("Interface didn't register toggle_shuffle function.\n");
00225 }
00226
00227 void
00228 interface_toggle_repeat(void)
00229 {
00230 if (interface_cbs.toggle_repeat != NULL)
00231 interface_cbs.toggle_repeat();
00232 else
00233 AUDDBG ("Interface didn't register toggle_repeat function.\n");
00234 }
00235
00236 typedef enum {
00237 HOOK_PREFSWIN_SHOW,
00238 HOOK_FILEBROWSER_SHOW,
00239 HOOK_FILEBROWSER_HIDE,
00240 HOOK_TOGGLE_VISIBILITY,
00241 HOOK_SHOW_ERROR,
00242 HOOK_JUMPTOTRACK_SHOW,
00243 HOOK_JUMPTOTRACK_HIDE,
00244 HOOK_ABOUTWIN_SHOW,
00245 HOOK_TOGGLE_SHUFFLE,
00246 HOOK_TOGGLE_REPEAT,
00247 } InterfaceHookID;
00248
00249 void
00250 interface_hook_handler(gpointer hook_data, gpointer user_data)
00251 {
00252 switch (GPOINTER_TO_INT(user_data)) {
00253 case HOOK_PREFSWIN_SHOW:
00254 interface_show_prefs_window(GPOINTER_TO_INT(hook_data));
00255 break;
00256 case HOOK_FILEBROWSER_SHOW:
00257 interface_run_filebrowser(GPOINTER_TO_INT(hook_data));
00258 break;
00259 case HOOK_FILEBROWSER_HIDE:
00260 interface_hide_filebrowser();
00261 break;
00262 case HOOK_TOGGLE_VISIBILITY:
00263 interface_toggle_visibility();
00264 break;
00265 case HOOK_SHOW_ERROR:
00266 interface_show_error_message((const gchar *) hook_data);
00267 break;
00268 case HOOK_JUMPTOTRACK_SHOW:
00269 interface_show_jump_to_track();
00270 break;
00271 case HOOK_JUMPTOTRACK_HIDE:
00272 interface_hide_jump_to_track();
00273 break;
00274 case HOOK_ABOUTWIN_SHOW:
00275 interface_show_about_window(GPOINTER_TO_INT(hook_data));
00276 break;
00277 case HOOK_TOGGLE_SHUFFLE:
00278 interface_toggle_shuffle();
00279 break;
00280 case HOOK_TOGGLE_REPEAT:
00281 interface_toggle_repeat();
00282 break;
00283 default:
00284 break;
00285 }
00286 }
00287
00288 typedef struct {
00289 const gchar *name;
00290 InterfaceHookID id;
00291 } InterfaceHooks;
00292
00293 static InterfaceHooks hooks[] = {
00294 {"prefswin show", HOOK_PREFSWIN_SHOW},
00295 {"filebrowser show", HOOK_FILEBROWSER_SHOW},
00296 {"filebrowser hide", HOOK_FILEBROWSER_HIDE},
00297 {"interface toggle visibility", HOOK_TOGGLE_VISIBILITY},
00298 {"interface show error", HOOK_SHOW_ERROR},
00299 {"interface show jump to track", HOOK_JUMPTOTRACK_SHOW},
00300 {"interface hide jump to track", HOOK_JUMPTOTRACK_HIDE},
00301 {"aboutwin show", HOOK_ABOUTWIN_SHOW},
00302 {"toggle shuffle", HOOK_TOGGLE_SHUFFLE},
00303 {"toggle repeat", HOOK_TOGGLE_REPEAT},
00304 };
00305
00306 void
00307 register_interface_hooks(void)
00308 {
00309 gint i;
00310 for (i=0; i<G_N_ELEMENTS(hooks); i++)
00311 hook_associate(hooks[i].name,
00312 (HookFunction) interface_hook_handler,
00313 GINT_TO_POINTER(hooks[i].id));
00314
00315 }
00316