2 * This file is part of DisOrder.
3 * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #include "configuration.h"
37 /* generic plugin support *****************************************************/
40 # define SOSUFFIX ".so"
49 static struct plugin
*plugins
;
51 const struct plugin
*open_plugin(const char *name
,
58 for(pl
= plugins
; pl
&& strcmp(pl
->name
, name
); pl
= pl
->next
)
61 for(n
= 0; n
<= config
->plugins
.n
; ++n
) {
62 byte_xasprintf(&p
, "%s/%s" SOSUFFIX
,
63 n
== config
->plugins
.n ? pkglibdir
: config
->plugins
.s
[n
],
65 if(access(p
, R_OK
) == 0) {
66 h
= dlopen(p
, RTLD_NOW
);
68 error(0, "error opening %s: %s", p
, dlerror());
71 pl
= xmalloc(sizeof *pl
);
73 pl
->name
= xstrdup(name
);
79 (flags
& PLUGIN_FATAL ? fatal
: error
)(0, "cannot find plugin '%s'", name
);
83 function_t
*get_plugin_function(const struct plugin
*pl
,
88 f
= (function_t
*)dlsym(pl
->dlhandle
, symbol
);
90 fatal(0, "error looking up function '%s' in '%s': %s",symbol
, pl
->name
, e
);
94 const void *get_plugin_object(const struct plugin
*pl
,
99 o
= dlsym(pl
->dlhandle
, symbol
);
101 fatal(0, "error looking up object '%s' in '%s': %s", symbol
, pl
->name
, e
);
105 /* specific plugin interfaces *************************************************/
107 typedef long tracklength_fn(const char *track
, const char *path
);
109 long tracklength(const char *track
, const char *path
) {
110 static tracklength_fn
*f
= 0;
113 f
= (tracklength_fn
*)get_plugin_function(open_plugin("tracklength",
115 "disorder_tracklength");
116 return (*f
)(track
, path
);
119 typedef void scan_fn(const char *root
);
121 void scan(const char *module
, const char *root
) {
122 ((scan_fn
*)get_plugin_function(open_plugin(module
, PLUGIN_FATAL
),
123 "disorder_scan"))(root
);
126 typedef int check_fn(const char *root
, const char *path
);
129 int check(const char *module
, const char *root
, const char *path
) {
130 return ((check_fn
*)get_plugin_function(open_plugin(module
, PLUGIN_FATAL
),
131 "disorder_check"))(root
, path
);
134 typedef void notify_play_fn(const char *track
, const char *submitter
);
136 void notify_play(const char *track
,
137 const char *submitter
) {
138 static notify_play_fn
*f
;
141 f
= (notify_play_fn
*)get_plugin_function(open_plugin("notify",
143 "disorder_notify_play");
144 (*f
)(track
, submitter
);
147 typedef void notify_scratch_fn(const char *track
,
148 const char *submitter
,
149 const char *scratcher
,
152 void notify_scratch(const char *track
,
153 const char *submitter
,
154 const char *scratcher
,
156 static notify_scratch_fn
*f
;
159 f
= (notify_scratch_fn
*)get_plugin_function(open_plugin("notify",
161 "disorder_notify_scratch");
162 (*f
)(track
, submitter
, scratcher
, seconds
);
165 typedef void notify_not_scratched_fn(const char *track
,
166 const char *submitter
);
168 void notify_not_scratched(const char *track
,
169 const char *submitter
) {
170 static notify_not_scratched_fn
*f
;
173 f
= (notify_not_scratched_fn
*)get_plugin_function
174 (open_plugin("notify",
176 "disorder_notify_not_scratched");
177 (*f
)(track
, submitter
);
180 typedef void notify_queue_fn(const char *track
,
181 const char *submitter
);
183 void notify_queue(const char *track
,
184 const char *submitter
) {
185 static notify_queue_fn
*f
;
188 f
= (notify_queue_fn
*)get_plugin_function(open_plugin("notify",
190 "disorder_notify_queue");
191 (*f
)(track
, submitter
);
194 void notify_queue_remove(const char *track
,
195 const char *remover
) {
196 static notify_queue_fn
*f
;
199 f
= (notify_queue_fn
*)get_plugin_function(open_plugin("notify",
201 "disorder_notify_queue_remove");
202 (*f
)(track
, remover
);
205 void notify_queue_move(const char *track
,
207 static notify_queue_fn
*f
;
210 f
= (notify_queue_fn
*)get_plugin_function(open_plugin("notify",
212 "disorder_notify_queue_move");
216 void notify_pause(const char *track
, const char *who
) {
217 static notify_queue_fn
*f
;
220 f
= (notify_queue_fn
*)get_plugin_function(open_plugin("notify",
222 "disorder_notify_pause");
226 void notify_resume(const char *track
, const char *who
) {
227 static notify_queue_fn
*f
;
230 f
= (notify_queue_fn
*)get_plugin_function(open_plugin("notify",
232 "disorder_notify_resume");
236 /* player plugin interfaces ***************************************************/
240 unsigned long play_get_type(const struct plugin
*pl
) {
241 return *(const unsigned long *)get_plugin_object(pl
, "disorder_player_type");
246 typedef void *prefork_fn(const char *track
);
248 void *play_prefork(const struct plugin
*pl
,
250 return ((prefork_fn
*)get_plugin_function(pl
,
251 "disorder_play_prefork"))(track
);
256 typedef void play_track_fn(const char *const *parameters
,
261 void play_track(const struct plugin
*pl
,
262 const char *const *parameters
,
266 ((play_track_fn
*)get_plugin_function(pl
,
267 "disorder_play_track"))(parameters
,
275 typedef void cleanup_fn(void *data
);
277 void play_cleanup(const struct plugin
*pl
, void *data
) {
278 ((cleanup_fn
*)get_plugin_function(pl
, "disorder_play_cleanup"))(data
);
283 typedef int pause_fn(long *playedp
, void *data
);
285 int play_pause(const struct plugin
*pl
, long *playedp
, void *data
) {
286 return (((pause_fn
*)get_plugin_function(pl
, "disorder_pause_track"))
292 typedef void resume_fn(void *data
);
294 void play_resume(const struct plugin
*pl
, void *data
) {
295 (((resume_fn
*)get_plugin_function(pl
, "disorder_resume_track"))