Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
plugin-init.c
Go to the documentation of this file.
1 /*
2  * plugin-init.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 <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 
24 #include <glib.h>
25 
26 #include "debug.h"
27 #include "effect.h"
28 #include "general.h"
29 #include "interface.h"
30 #include "main.h"
31 #include "output.h"
32 #include "plugin.h"
33 #include "plugins.h"
34 #include "ui_preferences.h"
35 #include "visualization.h"
36 
37 static const struct {
38  const char * name;
40 
41  union {
42  struct {
44  void (* stop) (PluginHandle * plugin);
45  } m;
46 
47  struct {
48  PluginHandle * (* probe) (void);
49  PluginHandle * (* get_current) (void);
51  } s;
52  } u;
53 } table[PLUGIN_TYPES] = {
54  [PLUGIN_TYPE_TRANSPORT] = {"transport", FALSE, .u.m = {NULL, NULL}},
55  [PLUGIN_TYPE_PLAYLIST] = {"playlist", FALSE, .u.m = {NULL, NULL}},
56  [PLUGIN_TYPE_INPUT] = {"input", FALSE, .u.m = {NULL, NULL}},
58  [PLUGIN_TYPE_OUTPUT] = {"output", TRUE, .u.s = {output_plugin_probe,
60  [PLUGIN_TYPE_VIS] = {"visualization", FALSE, .u.m = {vis_plugin_start, vis_plugin_stop}},
62  [PLUGIN_TYPE_IFACE] = {"interface", TRUE, .u.s = {iface_plugin_probe,
64 
65 static bool_t find_enabled_cb (PluginHandle * p, void * pp)
66 {
67  * (PluginHandle * *) pp = p;
68  return FALSE;
69 }
70 
72 {
73  PluginHandle * p = NULL;
75  return p;
76 }
77 
78 static void start_single (int type)
79 {
80  PluginHandle * p;
81 
82  if ((p = find_enabled (type)) != NULL)
83  {
84  AUDDBG ("Starting selected %s plugin %s.\n", table[type].name,
85  plugin_get_name (p));
86 
87  if (table[type].u.s.set_current (p))
88  return;
89 
90  AUDDBG ("%s failed to start.\n", plugin_get_name (p));
92  }
93 
94  AUDDBG ("Probing for %s plugin.\n", table[type].name);
95 
96  if ((p = table[type].u.s.probe ()) == NULL)
97  {
98  fprintf (stderr, "FATAL: No %s plugin found.\n", table[type].name);
99  exit (EXIT_FAILURE);
100  }
101 
102  AUDDBG ("Starting %s.\n", plugin_get_name (p));
104 
105  if (! table[type].u.s.set_current (p))
106  {
107  fprintf (stderr, "FATAL: %s failed to start.\n", plugin_get_name (p));
109  exit (EXIT_FAILURE);
110  }
111 }
112 
114 {
115  AUDDBG ("Starting %s.\n", plugin_get_name (p));
116 
117  if (! table[GPOINTER_TO_INT (type)].u.m.start (p))
118  {
119  AUDDBG ("%s failed to start; disabling.\n", plugin_get_name (p));
121  }
122 
123  return TRUE;
124 }
125 
126 static void start_plugins (int type)
127 {
128  if (headless && type == PLUGIN_TYPE_IFACE)
129  return;
130 
131  if (table[type].is_single)
132  start_single (type);
133  else
134  {
135  if (table[type].u.m.start)
136  plugin_for_enabled (type, start_multi_cb, GINT_TO_POINTER (type));
137  }
138 }
139 
140 static VFSConstructor * lookup_transport (const char * scheme)
141 {
143  if (! plugin)
144  return NULL;
145 
146  TransportPlugin * tp = plugin_get_header (plugin);
147  return tp ? tp->vtable : NULL;
148 }
149 
150 void start_plugins_one (void)
151 {
154 
155  for (int i = 0; i < PLUGIN_TYPE_GENERAL; i ++)
156  start_plugins (i);
157 }
158 
159 void start_plugins_two (void)
160 {
161  for (int i = PLUGIN_TYPE_GENERAL; i < PLUGIN_TYPES; i ++)
162  start_plugins (i);
163 }
164 
165 static bool_t misc_cleanup_cb (PluginHandle * p, void * unused)
166 {
168  return TRUE;
169 }
170 
171 static bool_t stop_multi_cb (PluginHandle * p, void * type)
172 {
173  AUDDBG ("Shutting down %s.\n", plugin_get_name (p));
174  table[GPOINTER_TO_INT (type)].u.m.stop (p);
175  return TRUE;
176 }
177 
178 static void stop_plugins (int type)
179 {
180  if (headless && type == PLUGIN_TYPE_IFACE)
181  return;
182 
183  plugin_for_enabled (type, misc_cleanup_cb, GINT_TO_POINTER (type));
184 
185  if (table[type].is_single)
186  {
187  AUDDBG ("Shutting down %s.\n", plugin_get_name
188  (table[type].u.s.get_current ()));
189  table[type].u.s.set_current (NULL);
190  }
191  else
192  {
193  if (table[type].u.m.stop)
194  plugin_for_enabled (type, stop_multi_cb, GINT_TO_POINTER (type));
195  }
196 }
197 
198 void stop_plugins_two (void)
199 {
200  for (int i = PLUGIN_TYPES - 1; i >= PLUGIN_TYPE_GENERAL; i --)
201  stop_plugins (i);
202 }
203 
204 void stop_plugins_one (void)
205 {
206  for (int i = PLUGIN_TYPE_GENERAL - 1; i >= 0; i --)
207  stop_plugins (i);
208 
211 }
212 
214 {
215  g_return_val_if_fail (table[type].is_single, NULL);
216  return table[type].u.s.get_current ();
217 }
218 
220 {
221  PluginHandle * old = table[type].u.s.get_current ();
222 
223  plugin_misc_cleanup (old);
224 
225  AUDDBG ("Switching from %s to %s.\n", plugin_get_name (old),
226  plugin_get_name (p));
227  plugin_set_enabled (old, FALSE);
229 
230  if (table[type].u.s.set_current (p))
231  return TRUE;
232 
233  fprintf (stderr, "%s failed to start; falling back to %s.\n",
234  plugin_get_name (p), plugin_get_name (old));
236  plugin_set_enabled (old, TRUE);
237 
238  if (table[type].u.s.set_current (old))
239  return FALSE;
240 
241  fprintf (stderr, "FATAL: %s failed to start.\n", plugin_get_name (old));
242  plugin_set_enabled (old, FALSE);
243  exit (EXIT_FAILURE);
244 }
245 
246 static bool_t enable_multi (int type, PluginHandle * p, bool_t enable)
247 {
248  if (! enable)
250 
251  AUDDBG ("%sabling %s.\n", enable ? "En" : "Dis", plugin_get_name (p));
252  plugin_set_enabled (p, enable);
253 
254  if (enable)
255  {
256  if (table[type].u.m.start && ! table[type].u.m.start (p))
257  {
258  fprintf (stderr, "%s failed to start.\n", plugin_get_name (p));
260  return FALSE;
261  }
262  }
263  else
264  {
265  if (table[type].u.m.stop)
266  table[type].u.m.stop (p);
267  }
268 
269  return TRUE;
270 }
271 
273 {
274  if (! enable == ! plugin_get_enabled (plugin))
275  return TRUE;
276 
277  int type = plugin_get_type (plugin);
278 
279  if (table[type].is_single)
280  {
281  g_return_val_if_fail (enable, FALSE);
282  return enable_single (type, plugin);
283  }
284 
285  return enable_multi (type, plugin, enable);
286 }
287 
288 /* Miscellaneous plugin-related functions ... */
289 
290 PluginHandle * plugin_by_widget (/* GtkWidget * */ void * widget)
291 {
292  PluginHandle * p;
293  if ((p = vis_plugin_by_widget (widget)))
294  return p;
295  if ((p = general_plugin_by_widget (widget)))
296  return p;
297  return NULL;
298 }
299 
300 int plugin_send_message (PluginHandle * plugin, const char * code, const void * data, int size)
301 {
302  if (! plugin_get_enabled (plugin))
303  return ENOSYS;
304 
305  Plugin * header = plugin_get_header (plugin);
306  if (! header || ! PLUGIN_HAS_FUNC (header, take_message))
307  return ENOSYS;
308 
309  return header->take_message (code, data, size);
310 }
311 
313 {
314  g_return_if_fail (plugin_get_enabled (plugin));
315  Plugin * header = plugin_get_header (plugin);
316  g_return_if_fail (header);
317 
318  if (PLUGIN_HAS_FUNC (header, about))
319  header->about ();
320  else if (PLUGIN_HAS_FUNC (header, about_text))
321  plugin_make_about_window (plugin);
322 }
323 
325 {
326  g_return_if_fail (plugin_get_enabled (plugin));
327  Plugin * header = plugin_get_header (plugin);
328  g_return_if_fail (header);
329 
330  if (PLUGIN_HAS_FUNC (header, configure))
331  header->configure ();
332  else if (PLUGIN_HAS_FUNC (header, prefs))
333  plugin_make_config_window (plugin);
334 }
static VFSConstructor * lookup_transport(const char *scheme)
Definition: plugin-init.c:140
bool_t plugin_get_enabled(PluginHandle *plugin)
static void start_plugins(int type)
Definition: plugin-init.c:126
bool_t vis_plugin_start(PluginHandle *plugin)
bool_t effect_plugin_start(PluginHandle *plugin)
Definition: effect.c:233
void plugin_set_enabled(PluginHandle *plugin, bool_t enabled)
static const struct @17 table[PLUGIN_TYPES]
bool_t(* start)(PluginHandle *plugin)
Definition: plugin-init.c:43
void stop_plugins_two(void)
Definition: plugin-init.c:198
static PluginHandle * find_enabled(int type)
Definition: plugin-init.c:71
PluginHandle * output_plugin_get_current(void)
Definition: output.c:595
static bool_t start_multi_cb(PluginHandle *p, void *type)
Definition: plugin-init.c:113
static void start_single(int type)
Definition: plugin-init.c:78
void stop_plugins_one(void)
Definition: plugin-init.c:204
PluginHandle * iface_plugin_probe(void)
Definition: interface.c:209
void plugin_make_config_window(PluginHandle *plugin)
void plugin_system_cleanup(void)
Definition: pluginenum.c:204
#define PLUGIN_HAS_FUNC(p, func)
Definition: plugin.h:515
static bool_t find_enabled_cb(PluginHandle *p, void *pp)
Definition: plugin-init.c:65
type
Definition: plugins-api.h:41
const VFSConstructor * vtable
Definition: plugin.h:130
PluginHandle * plugin_get_current(int type)
Definition: plugin-init.c:213
#define FALSE
Definition: core.h:35
static bool_t stop_multi_cb(PluginHandle *p, void *type)
Definition: plugin-init.c:171
PluginHandle * plugin_by_widget(void *widget)
Definition: plugin-init.c:290
void effect_plugin_stop(PluginHandle *plugin)
Definition: effect.c:245
PluginHandle * general_plugin_by_widget(void *widget)
Definition: general.c:148
Index Index bool_t
Definition: playlist-api.h:122
#define AUDDBG(...)
Definition: debug.h:30
bool_t general_plugin_start(PluginHandle *plugin)
Definition: general.c:122
void plugin_misc_cleanup(PluginHandle *plugin)
void plugin_do_configure(PluginHandle *plugin)
Definition: plugin-init.c:324
const void * plugin_get_header(PluginHandle *plugin)
const char * name
Definition: plugin-init.c:38
void general_plugin_stop(PluginHandle *plugin)
Definition: general.c:136
#define NULL
Definition: core.h:27
void vis_plugin_stop(PluginHandle *plugin)
bool_t headless
Definition: main.c:53
EXPORT void vfs_set_lookup_func(VFSConstructor *(*func)(const char *scheme))
Definition: vfs.c:54
static void stop_plugins(int type)
Definition: plugin-init.c:178
#define TRUE
Definition: core.h:37
static bool_t misc_cleanup_cb(PluginHandle *p, void *unused)
Definition: plugin-init.c:165
bool_t plugin_enable(PluginHandle *plugin, bool_t enable)
Definition: plugin-init.c:272
void plugin_system_init(void)
Definition: pluginenum.c:165
int plugin_send_message(PluginHandle *plugin, const char *code, const void *data, int size)
Definition: plugin-init.c:300
bool_t output_plugin_set_current(PluginHandle *plugin)
Definition: output.c:600
static bool_t enable_single(int type, PluginHandle *p)
Definition: plugin-init.c:219
PluginHandle * transport_plugin_for_scheme(const char *scheme)
void plugin_do_about(PluginHandle *plugin)
Definition: plugin-init.c:312
void(* stop)(PluginHandle *plugin)
Definition: plugin-init.c:44
void plugin_make_about_window(PluginHandle *plugin)
bool_t(* set_current)(PluginHandle *plugin)
Definition: plugin-init.c:50
PluginHandle * vis_plugin_by_widget(void *widget)
struct @17::@18::@19 m
void start_plugins_one(void)
Definition: plugin-init.c:150
void plugin_for_enabled(int type, PluginForEachFunc func, void *data)
bool_t iface_plugin_set_current(PluginHandle *plugin)
Definition: interface.c:223
void data PluginHandle plugin
Definition: plugins-api.h:54
static bool_t enable_multi(int type, PluginHandle *p, bool_t enable)
Definition: plugin-init.c:246
PluginHandle * iface_plugin_get_current(void)
Definition: interface.c:218
struct @17::@18::@20 s
bool_t is_single
Definition: plugin-init.c:39
PluginHandle * output_plugin_probe(void)
Definition: output.c:588
const char * plugin_get_name(PluginHandle *plugin)
void start_plugins_two(void)
Definition: plugin-init.c:159
int plugin_get_type(PluginHandle *plugin)
union @17::@18 u