source: roaraudio/roard/plugins.c @ 5826:edb28d83ca21

Last change on this file since 5826:edb28d83ca21 was 5823:f9f70dbaa376, checked in by phi, 11 years ago

updated copyright

File size: 7.7 KB
Line 
1//plugins.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2013
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "roard.h"
27
28#define MAX_PLUGINS    8
29
30static struct _roard_plugin {
31 struct roar_dl_lhandle     * lhandle;
32} g_plugins[MAX_PLUGINS];
33static struct _roard_plugin * _pp = NULL;
34
35static int _plugins_inited = 0;
36
37static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle);
38static const struct roar_dl_fnreg _plugin_callbacks = {
39 .fn = -1,
40 .subtype = -1,
41 .version = -1,
42 .callback = plugin_callback,
43 .userdata = NULL
44};
45
46static struct _roard_plugin * _find_free(void) {
47 int i;
48
49 ROAR_DBG("_find_free(void) = ?");
50
51 for (i = 0; i < MAX_PLUGINS; i++) {
52  if ( g_plugins[i].lhandle == NULL ) {
53   memset(&(g_plugins[i]), 0, sizeof(struct _roard_plugin));
54   ROAR_DBG("_find_free(void) = %p // i=%i", &(g_plugins[i]), i);
55   return &(g_plugins[i]);
56  }
57 }
58
59 ROAR_DBG("_find_free(void) = NULL");
60 return NULL;
61}
62
63int plugins_preinit  (void) {
64 ROAR_DBG("plugins_preinit(void) = ?");
65
66 memset(g_plugins, 0, sizeof(g_plugins));
67
68#ifdef DEBUG
69 print_pluginlist(FORMAT_NATIVE);
70#endif
71
72 ROAR_DBG("plugins_preinit(void) = 0");
73 return 0;
74}
75
76static inline void plugins_delete(struct _roard_plugin * plugin) {
77 ROAR_DBG("plugins_delete(plugin=%p) = ?", plugin);
78
79 roar_dl_appsched_trigger(plugin->lhandle, ROAR_DL_APPSCHED_FREE);
80
81 roar_dl_close(plugin->lhandle);
82 memset(plugin, 0, sizeof(struct _roard_plugin));
83 plugin->lhandle = NULL;
84}
85
86static int plugins_init_one(struct _roard_plugin * plugin) {
87 if ( plugin == NULL )
88  return -1;
89
90 ROAR_DBG("plugins_init_one(plugin=%p) = ?", plugin);
91
92 _pp = plugin;
93
94 if ( roar_dl_ra_init(plugin->lhandle, NULL, NULL) == -1 ) {
95  ROAR_WARN("plugins_init(void): Can not RA init lib at %p: %s", plugin->lhandle, roar_error2str(roar_error));
96  plugins_delete(plugin);
97  return -1;
98 }
99
100 roar_dl_appsched_trigger(plugin->lhandle, ROAR_DL_APPSCHED_INIT);
101
102 _pp = NULL;
103
104 return 0;
105}
106
107int plugins_init  (void) {
108 size_t i;
109
110 ROAR_DBG("plugins_init(void) = ?");
111
112#ifdef DEBUG
113 print_pluginlist(FORMAT_NATIVE);
114#endif
115
116 if ( _plugins_inited ) {
117  ROAR_DBG("plugins_init(void) = -1 // error=BUSY");
118  roar_err_set(ROAR_ERROR_BUSY);
119  return -1;
120 }
121
122 ROAR_DL_RFNREG(ROAR_DL_HANDLE_APPLICATION, _plugin_callbacks);
123
124 for (i = 0; i < MAX_PLUGINS; i++) {
125  if ( g_plugins[i].lhandle != NULL ) {
126   plugins_init_one(&(g_plugins[i]));
127  }
128 }
129
130 _plugins_inited = 1;
131
132#ifdef DEBUG
133 print_pluginlist(FORMAT_NATIVE);
134#endif
135
136 ROAR_DBG("plugins_init(void) = 0");
137 return 0;
138}
139
140int plugins_free  (void) {
141 int i;
142
143 ROAR_DBG("plugins_free(void) = ?");
144
145 for (i = 0; i < MAX_PLUGINS; i++) {
146  if ( g_plugins[i].lhandle != NULL ) {
147   plugins_delete(&(g_plugins[i]));
148  }
149 }
150
151 return plugins_preinit();
152}
153
154int plugins_update   (void) {
155 int ret = 0;
156 int i;
157
158 for (i = 0; i < MAX_PLUGINS; i++) {
159  if ( g_plugins[i].lhandle != NULL ) {
160   if ( roar_dl_appsched_trigger(g_plugins[i].lhandle, ROAR_DL_APPSCHED_UPDATE) == -1 )
161    if ( roar_error != ROAR_ERROR_NOENT )
162     ret = -1;
163  }
164 }
165
166 return ret;
167}
168
169int plugins_load  (const char * filename, const char * args) {
170 struct _roard_plugin * next = _find_free();
171 struct roar_dl_librarypara * para;
172
173 ROAR_DBG("plugins_load(filename=\"%s\", args=\"%s\") = ?", filename, args);
174
175 if ( next == NULL )
176  return -1;
177
178 if ( (para = roar_dl_para_new(args, NULL, ROARD_DL_APPNAME, ROARD_DL_ABIVERSION)) == NULL ) {
179  ROAR_WARN("Can not load plugin (allocate para set): %s: %s", filename, roar_error2str(roar_error));
180  return -1;
181 }
182
183 next->lhandle = roar_dl_open(filename, ROAR_DL_FLAG_PLUGIN, 0 /* we delay this until plugins_init() */, para);
184 roar_dl_para_unref(para);
185
186 if ( next->lhandle == NULL ) {
187  ROAR_ERR("plugins_load(filename='%s'): can not load plugin: %s", filename, roar_dl_errstr(NULL));
188  return -1;
189 }
190
191 if ( _plugins_inited )
192  return plugins_init_one(next);
193
194 return 0;
195}
196
197void print_pluginlist(enum output_format format) {
198 const struct roar_dl_libraryname * libname;
199 struct _roard_plugin * p;
200 size_t i;
201
202 switch (format) {
203  case FORMAT_NATIVE:
204    printf("  Name\n");
205    printf("   Attributes\n");
206    printf("-----------------------------------------------------\n");
207   break;
208  case FORMAT_WIKI:
209  case FORMAT_CSV:
210  default:
211    roar_err_set(ROAR_ERROR_NOTSUP);
212    return;
213 }
214
215 for (i = 0; i < MAX_PLUGINS; i++) {
216  p = &(g_plugins[i]);
217  if ( p->lhandle == NULL )
218   continue;
219
220  libname = roar_dl_getlibname(p->lhandle);
221  if ( libname == NULL ) {
222  } else {
223   printf("  %s\n", libname->libname);
224   printf("   Flags:       %s\n", "");
225   if ( libname->description != NULL )
226    printf("   Description: %s\n", libname->description);
227   if ( libname->contact != NULL )
228    printf("   Contact:     %s\n", libname->contact);
229  }
230 }
231}
232
233static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle) {
234
235 (void)options, (void)userdata;
236
237 ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = ?", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
238
239 switch (fn) {
240  case ROAR_DL_FN_PROTO:
241    if ( subtype != ROAR_DL_PROTO_SUBTYPE ) {
242     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=TYPEMM", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
243
244     roar_err_set(ROAR_ERROR_TYPEMM);
245     return -1;
246    }
247    if ( objectlen != ROAR_DL_PROTO_SIZE ) {
248     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADLIB", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
249     roar_err_set(ROAR_ERROR_BADLIB);
250     return -1;
251    }
252    if ( version != ROAR_DL_PROTO_VERSION ) {
253     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADVERSION", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
254     roar_err_set(ROAR_ERROR_BADVERSION);
255     return -1;
256    }
257    switch (action) {
258     case ROAR_DL_FNREG:
259       return clients_register_proto_common(object, lhandle);
260      break;
261     case ROAR_DL_FNUNREG:
262       return clients_unregister_proto(((const struct roard_proto *)object)->proto);
263      break;
264    }
265   break;
266 }
267
268 ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=NOTSUP", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle);
269 roar_err_set(ROAR_ERROR_NOTSUP);
270 return -1;
271}
272
273//ll
Note: See TracBrowser for help on using the repository browser.