Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
Main Page
Related Pages
Classes
Files
File List
File Members
src
audacious
plugin-init.c
Go to the documentation of this file.
1
/*
2
* plugin-init.c
3
* Copyright 2010-2011 John Lindgren
4
*
5
* This file is part of Audacious.
6
*
7
* Audacious is free software: you can redistribute it and/or modify it under
8
* the terms of the GNU General Public License as published by the Free Software
9
* Foundation, version 2 or version 3 of the License.
10
*
11
* Audacious is distributed in the hope that it will be useful, but WITHOUT ANY
12
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License along with
16
* Audacious. If not, see <http://www.gnu.org/licenses/>.
17
*
18
* The Audacious team does not consider modular code linking to Audacious or
19
* using our public API to be a derived work.
20
*/
21
22
#include <errno.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
26
#include <glib.h>
27
28
#include "
debug.h
"
29
#include "
effect.h
"
30
#include "
general.h
"
31
#include "
interface.h
"
32
#include "
main.h
"
33
#include "
output.h
"
34
#include "
plugin.h
"
35
#include "
plugins.h
"
36
#include "
ui_preferences.h
"
37
#include "
visualization.h
"
38
39
static
bool_t
dummy_plugin_start
(
PluginHandle
* p)
40
{
41
return
TRUE
;
42
}
43
44
static
void
dummy_plugin_stop
(
PluginHandle
* p)
45
{
46
}
47
48
static
const
struct
{
49
const
char
*
name
;
50
bool_t
is_managed
,
is_single
;
51
52
union
{
53
struct
{
54
bool_t
(*
start
) (
PluginHandle
*
plugin
);
55
void (*
stop
) (
PluginHandle
*
plugin
);
56
}
m
;
57
58
struct
{
59
PluginHandle
* (* probe) (void);
60
PluginHandle
* (* get_current) (void);
61
bool_t
(*
set_current
) (
PluginHandle
*
plugin
);
62
}
s
;
63
}
u
;
64
}
table
[
PLUGIN_TYPES
] = {
65
[
PLUGIN_TYPE_TRANSPORT
] = {
"transport"
,
TRUE
,
FALSE
, .u.m =
66
{
dummy_plugin_start
,
dummy_plugin_stop
}},
67
[
PLUGIN_TYPE_PLAYLIST
] = {
"playlist"
,
TRUE
,
FALSE
, .u.m = {
dummy_plugin_start
,
68
dummy_plugin_stop
}},
69
[
PLUGIN_TYPE_INPUT
] = {
"input"
,
TRUE
,
FALSE
, .u.m = {
dummy_plugin_start
,
70
dummy_plugin_stop
}},
71
[
PLUGIN_TYPE_EFFECT
] = {
"effect"
,
TRUE
,
FALSE
, .u.m = {
effect_plugin_start
,
72
effect_plugin_stop
}},
73
[
PLUGIN_TYPE_OUTPUT
] = {
"output"
,
TRUE
,
TRUE
, .u.s = {
output_plugin_probe
,
74
output_plugin_get_current
,
output_plugin_set_current
}},
75
[
PLUGIN_TYPE_VIS
] = {
"visualization"
,
TRUE
,
FALSE
, .u.m = {
vis_plugin_start
,
76
vis_plugin_stop
}},
77
[
PLUGIN_TYPE_GENERAL
] = {
"general"
,
TRUE
,
FALSE
, .u.m = {
general_plugin_start
,
78
general_plugin_stop
}},
79
[
PLUGIN_TYPE_IFACE
] = {
"interface"
,
TRUE
,
TRUE
, .u.s = {
iface_plugin_probe
,
80
iface_plugin_get_current
,
iface_plugin_set_current
}}};
81
82
static
bool_t
find_enabled_cb
(
PluginHandle
* p,
PluginHandle
* * pp)
83
{
84
* pp = p;
85
return
FALSE
;
86
}
87
88
static
PluginHandle
*
find_enabled
(
int
type
)
89
{
90
PluginHandle
* p =
NULL
;
91
plugin_for_enabled
(type, (
PluginForEachFunc
)
find_enabled_cb
, & p);
92
return
p;
93
}
94
95
static
void
start_single
(
int
type
)
96
{
97
PluginHandle
* p;
98
99
if
((p =
find_enabled
(type)) !=
NULL
)
100
{
101
AUDDBG
(
"Starting selected %s plugin %s.\n"
,
table
[type].
name
,
102
plugin_get_name
(p));
103
104
if
(
table
[type].
u
.s.set_current (p))
105
return
;
106
107
AUDDBG
(
"%s failed to start.\n"
,
plugin_get_name
(p));
108
plugin_set_enabled
(p,
FALSE
);
109
}
110
111
AUDDBG
(
"Probing for %s plugin.\n"
,
table
[type].
name
);
112
113
if
((p =
table
[type].
u
.s.probe ()) ==
NULL
)
114
{
115
fprintf (stderr,
"FATAL: No %s plugin found.\n"
,
table
[type].name);
116
exit (EXIT_FAILURE);
117
}
118
119
AUDDBG
(
"Starting %s.\n"
,
plugin_get_name
(p));
120
plugin_set_enabled
(p,
TRUE
);
121
122
if
(!
table
[type].
u
.s.set_current (p))
123
{
124
fprintf (stderr,
"FATAL: %s failed to start.\n"
,
plugin_get_name
(p));
125
plugin_set_enabled
(p,
FALSE
);
126
exit (EXIT_FAILURE);
127
}
128
}
129
130
static
bool_t
start_multi_cb
(
PluginHandle
* p,
void
*
type
)
131
{
132
AUDDBG
(
"Starting %s.\n"
,
plugin_get_name
(p));
133
134
if
(!
table
[GPOINTER_TO_INT (type)].
u
.m.start (p))
135
{
136
AUDDBG
(
"%s failed to start; disabling.\n"
,
plugin_get_name
(p));
137
plugin_set_enabled
(p,
FALSE
);
138
}
139
140
return
TRUE
;
141
}
142
143
static
void
start_plugins
(
int
type
)
144
{
145
if
(!
table
[type].
is_managed
)
146
return
;
147
if
(
headless
&& type ==
PLUGIN_TYPE_IFACE
)
148
return
;
149
150
if
(
table
[type].
is_single
)
151
start_single
(type);
152
else
153
plugin_for_enabled
(type, (
PluginForEachFunc
)
start_multi_cb
,
154
GINT_TO_POINTER (type));
155
}
156
157
static
VFSConstructor
*
lookup_transport
(
const
char
* scheme)
158
{
159
PluginHandle
*
plugin
=
transport_plugin_for_scheme
(scheme);
160
if
(! plugin)
161
return
NULL
;
162
163
TransportPlugin * tp =
plugin_get_header
(plugin);
164
return
tp ? tp->vtable :
NULL
;
165
}
166
167
void
start_plugins_one
(
void
)
168
{
169
plugin_system_init
();
170
vfs_set_lookup_func
(
lookup_transport
);
171
172
for
(
int
i = 0; i <
PLUGIN_TYPE_GENERAL
; i ++)
173
start_plugins
(i);
174
}
175
176
void
start_plugins_two
(
void
)
177
{
178
for
(
int
i =
PLUGIN_TYPE_GENERAL
; i <
PLUGIN_TYPES
; i ++)
179
start_plugins
(i);
180
}
181
182
static
bool_t
stop_multi_cb
(
PluginHandle
* p,
void
*
type
)
183
{
184
AUDDBG
(
"Shutting down %s.\n"
,
plugin_get_name
(p));
185
table
[GPOINTER_TO_INT (type)].u.m.stop (p);
186
return
TRUE
;
187
}
188
189
static
void
stop_plugins
(
int
type
)
190
{
191
if
(!
table
[type].
is_managed
)
192
return
;
193
if
(
headless
&& type ==
PLUGIN_TYPE_IFACE
)
194
return
;
195
196
if
(
table
[type].
is_single
)
197
{
198
AUDDBG
(
"Shutting down %s.\n"
,
plugin_get_name
199
(
table
[type].
u
.s.get_current ()));
200
table
[
type
].u.s.set_current (
NULL
);
201
}
202
else
203
plugin_for_enabled
(type, (
PluginForEachFunc
)
stop_multi_cb
,
204
GINT_TO_POINTER (type));
205
}
206
207
void
stop_plugins_two
(
void
)
208
{
209
for
(
int
i =
PLUGIN_TYPES
- 1; i >=
PLUGIN_TYPE_GENERAL
; i --)
210
stop_plugins
(i);
211
}
212
213
void
stop_plugins_one
(
void
)
214
{
215
for
(
int
i =
PLUGIN_TYPE_GENERAL
- 1; i >= 0; i --)
216
stop_plugins
(i);
217
218
vfs_set_lookup_func
(
NULL
);
219
plugin_system_cleanup
();
220
}
221
222
PluginHandle
*
plugin_get_current
(
int
type
)
223
{
224
g_return_val_if_fail (
table
[type].
is_managed
&&
table
[type].
is_single
,
NULL
);
225
return
table
[
type
].u.s.get_current ();
226
}
227
228
static
bool_t
enable_single
(
int
type
,
PluginHandle
* p)
229
{
230
PluginHandle
* old =
table
[
type
].u.s.get_current ();
231
232
AUDDBG
(
"Switching from %s to %s.\n"
,
plugin_get_name
(old),
233
plugin_get_name
(p));
234
plugin_set_enabled
(old,
FALSE
);
235
plugin_set_enabled
(p,
TRUE
);
236
237
if
(
table
[type].
u
.s.set_current (p))
238
return
TRUE
;
239
240
fprintf (stderr,
"%s failed to start; falling back to %s.\n"
,
241
plugin_get_name
(p),
plugin_get_name
(old));
242
plugin_set_enabled
(p,
FALSE
);
243
plugin_set_enabled
(old,
TRUE
);
244
245
if
(
table
[type].
u
.s.set_current (old))
246
return
FALSE
;
247
248
fprintf (stderr,
"FATAL: %s failed to start.\n"
,
plugin_get_name
(old));
249
plugin_set_enabled
(old,
FALSE
);
250
exit (EXIT_FAILURE);
251
}
252
253
static
bool_t
enable_multi
(
int
type
,
PluginHandle
* p,
bool_t
enable)
254
{
255
AUDDBG
(
"%sabling %s.\n"
, enable ?
"En"
:
"Dis"
,
plugin_get_name
(p));
256
plugin_set_enabled
(p, enable);
257
258
if
(enable)
259
{
260
if
(!
table
[type].
u
.m.start (p))
261
{
262
fprintf (stderr,
"%s failed to start.\n"
,
plugin_get_name
(p));
263
plugin_set_enabled
(p,
FALSE
);
264
return
FALSE
;
265
}
266
}
267
else
268
table
[
type
].u.m.stop (p);
269
270
return
TRUE
;
271
}
272
273
bool_t
plugin_enable
(
PluginHandle
*
plugin
,
bool_t
enable)
274
{
275
if
(! enable == !
plugin_get_enabled
(plugin))
276
{
277
AUDDBG
(
"%s is already %sabled.\n"
,
plugin_get_name
(plugin), enable ?
278
"en"
:
"dis"
);
279
return
TRUE
;
280
}
281
282
int
type
=
plugin_get_type
(plugin);
283
g_return_val_if_fail (
table
[type].
is_managed
,
FALSE
);
284
285
if
(
table
[type].
is_single
)
286
{
287
g_return_val_if_fail (enable,
FALSE
);
288
return
enable_single
(type, plugin);
289
}
290
291
return
enable_multi
(type, plugin, enable);
292
}
293
294
/* Miscellaneous plugin-related functions ... */
295
296
PluginHandle
*
plugin_by_widget
(
/* GtkWidget * */
void
* widget)
297
{
298
PluginHandle
* p;
299
if
((p =
vis_plugin_by_widget
(widget)))
300
return
p;
301
if
((p =
general_plugin_by_widget
(widget)))
302
return
p;
303
return
NULL
;
304
}
305
306
int
plugin_send_message
(
PluginHandle
*
plugin
,
const
char
* code,
const
void
*
data
,
int
size)
307
{
308
if
(!
plugin_get_enabled
(plugin))
309
return
ENOSYS;
310
311
Plugin * header =
plugin_get_header
(plugin);
312
if
(! header || !
PLUGIN_HAS_FUNC
(header, take_message))
313
return
ENOSYS;
314
315
return
header->take_message (code, data, size);
316
}
Generated by
1.8.1.1