Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
interface.c
Go to the documentation of this file.
1 /*
2  * interface.c
3  * Copyright 2010-2011 John Lindgren
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <gtk/gtk.h>
21 #include <pthread.h>
22 
23 #include <libaudcore/hook.h>
24 
25 #include "debug.h"
26 #include "general.h"
27 #include "interface.h"
28 #include "main.h"
29 #include "misc.h"
30 #include "plugin.h"
31 #include "plugins.h"
32 #include "visualization.h"
33 
34 static IfacePlugin *current_interface = NULL;
35 
36 static pthread_mutex_t error_mutex = PTHREAD_MUTEX_INITIALIZER;
37 static GQueue error_queue = G_QUEUE_INIT;
38 static int error_source;
39 
41 {
42  IfacePlugin * i = plugin_get_header (plugin);
43  g_return_val_if_fail (i, FALSE);
44 
45  if (PLUGIN_HAS_FUNC (i, init) && ! i->init ())
46  return FALSE;
47 
49  return TRUE;
50 }
51 
52 void interface_unload (void)
53 {
54  g_return_if_fail (current_interface);
55 
56  if (PLUGIN_HAS_FUNC (current_interface, cleanup))
57  current_interface->cleanup ();
58 
60 }
61 
63 {
64  g_return_if_fail (current_interface);
65 
67  current_interface->show (show);
68 }
69 
71 {
72  g_return_val_if_fail (current_interface, FALSE);
73 
74  if (PLUGIN_HAS_FUNC (current_interface, is_shown))
75  return current_interface->is_shown ();
76  return TRUE;
77 }
78 
80 {
81  g_return_val_if_fail (current_interface, FALSE);
82 
83  if (PLUGIN_HAS_FUNC (current_interface, is_focused))
84  return current_interface->is_focused ();
85  return TRUE;
86 }
87 
88 static bool_t error_idle_func (void * unused)
89 {
90  pthread_mutex_lock (& error_mutex);
91 
92  char * message;
93  while ((message = g_queue_pop_head (& error_queue)))
94  {
95  pthread_mutex_unlock (& error_mutex);
96 
98  current_interface->show_error (message);
99  else
100  fprintf (stderr, "ERROR: %s\n", message);
101 
102  g_free (message);
103 
104  pthread_mutex_lock (& error_mutex);
105  }
106 
107  error_source = 0;
108 
109  pthread_mutex_unlock (& error_mutex);
110  return FALSE;
111 }
112 
113 void interface_show_error (const char * message)
114 {
115  pthread_mutex_lock (& error_mutex);
116 
117  g_queue_push_tail (& error_queue, g_strdup (message));
118 
119  if (! error_source)
120  error_source = g_idle_add (error_idle_func, NULL);
121 
122  pthread_mutex_unlock (& error_mutex);
123 }
124 
125 /*
126  * bool_t play_button
127  * TRUE - open files
128  * FALSE - add files
129  */
131 {
132  g_return_if_fail (current_interface);
133 
134  if (PLUGIN_HAS_FUNC (current_interface, show_filebrowser))
135  current_interface->show_filebrowser (play_button);
136 }
137 
139 {
140  g_return_if_fail (current_interface);
141 
142  if (PLUGIN_HAS_FUNC (current_interface, show_jump_to_track))
143  current_interface->show_jump_to_track ();
144 }
145 
146 static bool_t delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle *
147  plugin)
148 {
149  plugin_enable (plugin, FALSE);
150  return TRUE;
151 }
152 
153 void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
154 {
155  g_return_if_fail (current_interface);
156 
157  if (PLUGIN_HAS_FUNC (current_interface, run_gtk_plugin))
158  current_interface->run_gtk_plugin (widget, plugin_get_name (plugin));
159  else
160  {
161  GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
162  gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin));
163  gtk_window_set_default_size ((GtkWindow *) window, 300, 200);
164  gtk_window_set_has_resize_grip ((GtkWindow *) window, FALSE);
165  gtk_container_add ((GtkContainer *) window, widget);
166  g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
167  gtk_widget_show_all (window);
168  }
169 }
170 
172 {
173  g_return_if_fail (current_interface);
174 
175  if (PLUGIN_HAS_FUNC (current_interface, stop_gtk_plugin))
176  current_interface->stop_gtk_plugin (widget);
177  else
178  gtk_widget_destroy (gtk_widget_get_parent (widget));
179 }
180 
181 void interface_install_toolbar (void * widget)
182 {
183  g_return_if_fail (current_interface);
184 
185  if (PLUGIN_HAS_FUNC (current_interface, install_toolbar))
186  current_interface->install_toolbar (widget);
187  else
188  g_object_ref (widget);
189 }
190 
191 void interface_uninstall_toolbar (void * widget)
192 {
193  g_return_if_fail (current_interface);
194 
195  if (PLUGIN_HAS_FUNC (current_interface, uninstall_toolbar))
196  current_interface->uninstall_toolbar (widget);
197  else
198  g_object_unref (widget);
199 }
200 
202 {
203  * pp = p;
204  return FALSE;
205 }
206 
208 {
209  PluginHandle * p = NULL;
211  return p;
212 }
213 
215 
217 {
218  return current_plugin;
219 }
220 
222 {
223  hook_call ("config save", NULL); /* tell interface to save layout */
224 
225  if (current_plugin != NULL)
226  {
227  AUDDBG ("Unloading plugin widgets.\n");
228  general_cleanup ();
229 
230  AUDDBG ("Unloading visualizers.\n");
231  vis_cleanup ();
232 
233  AUDDBG ("Unloading %s.\n", plugin_get_name (current_plugin));
234  interface_unload ();
235 
236  current_plugin = NULL;
237  }
238 
239  if (plugin != NULL)
240  {
241  AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
242 
243  if (! interface_load (plugin))
244  return FALSE;
245 
246  current_plugin = plugin;
247 
248  AUDDBG ("Loading visualizers.\n");
249  vis_init ();
250 
251  AUDDBG ("Loading plugin widgets.\n");
252  general_init ();
253  }
254 
255  return TRUE;
256 }