source: roaraudio/include/libroar/roardl.h @ 5578:c6268709a23b

Last change on this file since 5578:c6268709a23b was 5578:c6268709a23b, checked in by phi, 12 years ago

provide a macro for fn registrations within plugins

File size: 20.0 KB
Line 
1//roardl.h:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of libroar 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 *  libroar 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 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#ifndef _LIBROARROARDL_H_
37#define _LIBROARROARDL_H_
38
39#include "libroar.h"
40
41#define ROAR_DL_FLAG_DEFAULTS          -1
42#define ROAR_DL_FLAG_PLUGIN            -2
43#define ROAR_DL_FLAG_NONE               0x0000
44#define ROAR_DL_FLAG_STATIC             0x0001 /* plugins are linked statically -lfoo */
45#define ROAR_DL_FLAG_LAZY               0x0002
46#define ROAR_DL_FLAG_PLUGINPATH         0x0004 /* Use plugin search path */
47
48#define ROAR_DL_HANDLE_DEFAULT          ((struct roar_dl_lhandle*)(void*)0)
49#define ROAR_DL_HANDLE_NEXT             ((struct roar_dl_lhandle*)(void*)1)
50#define ROAR_DL_HANDLE_LIBROAR          ((struct roar_dl_lhandle*)(void*)2)
51#define ROAR_DL_HANDLE_APPLICATION      ((struct roar_dl_lhandle*)(void*)3)
52
53#define ROAR_DL_FN_DSTR                 0 /* VIO and DSTR drivers */
54#define ROAR_DL_FN_CDRIVER              1 /* Client drivers, libroareio */
55#define ROAR_DL_FN_TRANSCODER           2 /* Transcoder, libroardsp */
56#define ROAR_DL_FN_DRIVER               3 /* Driver, roard? */
57#define ROAR_DL_FN_SOURCE               4 /* Sources, roard? */
58#define ROAR_DL_FN_FILTER               5 /* Filter, libroardsp */
59#define ROAR_DL_FN_FF                   6 /* file format??? */
60#define ROAR_DL_FN_AUTH                 7 /* Auth */
61#define ROAR_DL_FN_BRIDGE               8 /* Bridges, roard? */
62#define ROAR_DL_FN_ROARDSCHED           9 /* Like appsched, but roard specific, old */
63#define ROAR_DL_FN_APPSCHED            10 /* AppSched, old interface */
64#define ROAR_DL_FN_PROTO               11 /* Protocols, roard? */
65#define ROAR_DL_FN_NOTIFY              12 /* ??? */
66#define ROAR_DL_FN_INIT                13 /* global plugin instance init. should be avoided */
67#define ROAR_DL_FN_REGFN               14 /* FN Registrations */
68#define ROAR_DL_FN_APPLICATION         15 /* Application specific stuff */
69//#define ROAR_DL_FN_               9
70#define ROAR_DL_FN_MAX                 24
71
72#define ROAR_DL_LIBPARA_VERSION         1
73#define ROAR_DL_LIBNAME_VERSION         0
74#define ROAR_DL_LIBINST_VERSION         1
75#define ROAR_DL_LIBDEP_VERSION          0
76
77#define ROAR_DL_PLUGIN(lib) struct roar_dl_libraryinst *                                          \
78                             _##lib##_roaraudio_library_init(struct roar_dl_librarypara * para);  \
79                            struct roar_dl_libraryinst *                                          \
80                             _roaraudio_library_init(struct roar_dl_librarypara * para) {         \
81                              return _##lib##_roaraudio_library_init(para);                       \
82                            }                                                                     \
83                            struct roar_dl_libraryinst *                                          \
84                             _##lib##_roaraudio_library_init(struct roar_dl_librarypara * para)   \
85
86#define ROAR_DL_PLUGIN_START(xlib) ROAR_DL_PLUGIN(xlib) {                                         \
87                                     static int _inited = 0;                                      \
88                                     static struct roar_dl_libraryinst lib;                       \
89                                     static struct roar_dl_libraryname libname;                   \
90                                     (void)para;                                                  \
91                                     if ( _inited )                                               \
92                                      return &lib;                                                \
93                                     if ( para != NULL &&                                         \
94                                          (para->version != ROAR_DL_LIBPARA_VERSION ||            \
95                                           para->len < sizeof(struct roar_dl_librarypara)) ) {    \
96                                      /* we should set ROAR_ERROR_NSVERSION here but can not */   \
97                                      /* because that would require the plugin to be linked */    \
98                                      /* aginst libroar */                                        \
99                                      return NULL;                                                \
100                                     }                                                            \
101                                     memset(&lib, 0, sizeof(lib));                                \
102                                     lib.version = ROAR_DL_LIBINST_VERSION;                       \
103                                     lib.len     = sizeof(lib);                                   \
104                                     memset(&libname, 0, sizeof(libname));                        \
105                                     libname.version = ROAR_DL_LIBNAME_VERSION;                   \
106                                     libname.len     = sizeof(libname);                           \
107                                     libname.name = #xlib;                                        \
108                                     lib.libname  = &libname;                                     \
109                                     do
110
111#define ROAR_DL_PLUGIN_END          while(0);                                                     \
112                                    _inited = 1;                                                  \
113                                    return &lib;                                                  \
114                                   }
115
116// general stuff:
117#define ROAR_DL_PLUGIN_ABORT_LOADING(err) roar_err_set((err)); return NULL
118#define ROAR_DL_PLUGIN_CHECK_VERSIONS(app,abi) (((lib.host_appname = (app))    != NULL) | \
119                                                ((lib.host_abiversion = (abi)) != NULL) )
120// should we keep this macro at all? Is it helpfull at all?
121// if a plugin can handle multiple hosts it needs to call roar_dl_para_check_version() itself anyway.
122#define ROAR_DL_PLUGIN_CHECK_VERSIONS_NOW(app,abi) if ( roar_dl_para_check_version(para, (app), (abi)) == -1 ) return NULL
123
124// register stuff:
125#define ROAR_DL_PLUGIN_REG(fn, funcptr) (lib.func[(fn)] = (funcptr))
126#define ROAR_DL_PLUGIN_REG_UNLOAD(func) (lib.unload = (func))
127#define ROAR_DL_PLUGIN_REG_APPSCHED(sched) (lib.appsched = (sched))
128#define ROAR_DL_PLUGIN_REG_GLOBAL_DATA(ptr,init) lib.global_data_len = sizeof((init)); \
129                                                 lib.global_data_init = &(init);       \
130                                                 lib.global_data_pointer = (void*)&(ptr)
131#define ROAR_DL_PLUGIN_REG_LIBDEP(deps) (((lib.libdep = (deps)) == NULL) ? \
132                                           (ssize_t)-1 : \
133                                           (ssize_t)(lib.libdep_len = sizeof((deps))/sizeof(struct roar_dl_librarydep)))
134
135#define ROAR_DL_PLUGIN_REG_FN(subtype,obj,version)  roar_dl_register_fn(NULL, -1, (subtype), &(obj), sizeof((obj)), (version), ROAR_DL_FNREG_OPT_NONE)
136
137// meta data stuff:
138#define ROAR_DL_PLUGIN_META_PRODUCT(x)      (libname.libname     = (x))
139#define ROAR_DL_PLUGIN_META_PRODUCT_NV(name,vendor)      ROAR_DL_PLUGIN_META_PRODUCT(name " <" vendor ">")
140#define ROAR_DL_PLUGIN_META_PRODUCT_NIV_REAL(name,id,vendor)  ROAR_DL_PLUGIN_META_PRODUCT(name " <" #id "/" vendor ">")
141#define ROAR_DL_PLUGIN_META_PRODUCT_NIV(name,id,vendor)  ROAR_DL_PLUGIN_META_PRODUCT_NIV_REAL(name,id,vendor)
142#define ROAR_DL_PLUGIN_META_VERSION(x)      (libname.libversion  = (x))
143#define ROAR_DL_PLUGIN_META_ABI(x)          (libname.abiversion  = (x))
144#define ROAR_DL_PLUGIN_META_DESC(x)         (libname.description = (x))
145#define ROAR_DL_PLUGIN_META_CONTACT(x)      (libname.contact = (x))
146#define ROAR_DL_PLUGIN_META_CONTACT_FL(first,last)        ROAR_DL_PLUGIN_META_CONTACT(first " " last)
147#define ROAR_DL_PLUGIN_META_CONTACT_FLE(first,last,email) ROAR_DL_PLUGIN_META_CONTACT(first " " last " <" email ">")
148#define ROAR_DL_PLUGIN_META_CONTACT_FLNE(first,last,nick,email) ROAR_DL_PLUGIN_META_CONTACT(first " \"" nick "\" " last " <" email ">")
149#define ROAR_DL_PLUGIN_META_AUTHORS(x)      (libname.authors = (x))
150#define ROAR_DL_PLUGIN_META_LICENSE(x)      (libname.license = (x))
151#define ROAR_DL_PLUGIN_META_LICENSE_TAG(x)  ROAR_DL_PLUGIN_META_LICENSE(ROAR_LICENSE_ ## x)
152
153enum roar_dl_loadercmd {
154 ROAR_DL_LOADER_NOOP = 0,
155 ROAR_DL_LOADER_PRELOAD,
156 ROAR_DL_LOADER_LOAD,
157 ROAR_DL_LOADER_POSTLOAD,
158 ROAR_DL_LOADER_PREUNLOAD,
159 ROAR_DL_LOADER_UNLOAD,
160 ROAR_DL_LOADER_POSTUNLOAD
161};
162
163struct roar_plugincontainer;
164
165struct roar_dl_librarypara {
166 int version;               // version of this struct type (must be ROAR_DL_LIBPARA_VERSION)
167 size_t len;                // Length of this struct type (must be sizeof(struct roar_dl_librarypara)
168
169 size_t refc;               // Reference counter.
170
171 size_t argc;               // number of elements in argv
172 struct roar_keyval * argv; // Parameter for the plugin
173 void * args_store;         // Storage area for argv's data.
174                            // If not NULL this and argv will be freed.
175                            // If NULL argv will be left untouched.
176
177 void * binargv;            // A pointer with binary data arguments.
178                            // This can be used to pass any non-string data to
179                            // the plugin. Normally this is NULL or the pointer
180                            // to a struct with members of whatever is needed.
181
182 const char * appname;      // application name in common format:
183                            // Product/Version <VendorID/VendorName> (comments)
184                            // Version and comment are optional and should be avoided.
185                            // When no vendor ID is registered use <VendorName>.
186                            // The VendorName MUST NOT contain a slash and SHOULD
187                            // be as unique as possible.
188                            // Examples: roard <0/RoarAudio>, MyAPP <myapp.org>,
189                            //           AnAPP <Musterman GbR>
190 const char * abiversion;   // The ABI version. For libraries this should be the SONAME.
191                            // For applications this should be the version of the release
192                            // which introduced the current ABI.
193                            // Examples: libroar2, 0.5.1
194 struct roar_notify_core * notifycore;
195 struct roar_plugincontainer * container;
196 int (*loader)(struct roar_dl_librarypara * lhandle, void * loader_userdata, enum roar_dl_loadercmd cmd, void * argp);
197 void * loader_userdata;
198};
199
200struct roar_dl_libraryname {
201 int      version;
202 size_t   len;
203 const char * name;        //Format: shortname
204 const char * libname;     //This is the same as appname in struct roar_dl_librarypara.
205                           //Format: Product <VendorID/VendorName> (comments)
206 const char * libversion;  //This is the pure version number of the library.
207 const char * abiversion;  //This is the same as abiversion in struct roar_dl_librarypara.
208                           //Format: Version
209 const char * description; //Free form.
210 const char * contact;     //Format: first ["']nick["'] last (comment) <email>/OpenPGPkey/Phone/Room
211 const char * authors;     //Other authors as free form.
212 const char * license;     //Format: LicenseName-Version (options)
213                           //Examples: GPL-3.0, LGPL-2.1, LGPL-3.0 (or later).
214};
215
216struct roar_dl_librarydep {
217 int      version;
218 size_t   len;
219 uint32_t flags;
220 const char * name;
221 const char * libname;
222 const char * abiversion;
223};
224
225#define ROAR_DL_DEP(__flags,__name,__libname,__abiversion) \
226                                                   {.version    = ROAR_DL_LIBDEP_VERSION,            \
227                                                    .len        = sizeof(struct roar_dl_librarydep), \
228                                                    .flags      = __flags,                           \
229                                                    .name       = __name,                            \
230                                                    .libname    = __libname,                         \
231                                                    .abiversion = __abiversion}
232
233struct roar_dl_libraryinst {
234 int      version;
235 size_t   len;
236 int    (*unload)(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib);
237 int    (*func[ROAR_DL_FN_MAX])(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib);
238 struct roar_dl_libraryname * libname;
239 size_t  global_data_len;
240 void *  global_data_init;
241 void ** global_data_pointer;
242 struct roar_dl_librarydep * libdep;
243 size_t libdep_len;
244 struct roar_dl_appsched * appsched;
245 const char * host_appname;
246 const char * host_abiversion;
247};
248
249struct roar_dl_appsched {
250 int (*init)  (struct roar_dl_librarypara * para);
251 int (*free)  (struct roar_dl_librarypara * para);
252 int (*update)(struct roar_dl_librarypara * para);
253 int (*tick)  (struct roar_dl_librarypara * para);
254 int (*wait)  (struct roar_dl_librarypara * para);
255};
256
257enum roar_dl_appsched_trigger {
258 ROAR_DL_APPSCHED_INIT = 1,
259#define ROAR_DL_APPSCHED_INIT ROAR_DL_APPSCHED_INIT
260 ROAR_DL_APPSCHED_FREE,
261#define ROAR_DL_APPSCHED_FREE ROAR_DL_APPSCHED_FREE
262 ROAR_DL_APPSCHED_UPDATE,
263#define ROAR_DL_APPSCHED_UPDATE ROAR_DL_APPSCHED_UPDATE
264 ROAR_DL_APPSCHED_TICK,
265#define ROAR_DL_APPSCHED_TICK ROAR_DL_APPSCHED_TICK
266 ROAR_DL_APPSCHED_WAIT
267#define ROAR_DL_APPSCHED_WAIT ROAR_DL_APPSCHED_WAIT
268};
269
270// parameter functions:
271struct roar_dl_librarypara * roar_dl_para_new(const char * args, void * binargv,
272                                              const char * appname, const char * abiversion);
273int roar_dl_para_ref                    (struct roar_dl_librarypara * para);
274int roar_dl_para_unref                  (struct roar_dl_librarypara * para);
275int roar_dl_para_check_version          (struct roar_dl_librarypara * para,
276                                         const char * appname, const char * abiversion);
277
278// 'core' dynamic loader functions.
279struct roar_dl_lhandle * roar_dl_open   (const char * filename, int flags,
280                                         int ra_init, struct roar_dl_librarypara * para);
281int                      roar_dl_ref    (struct roar_dl_lhandle * lhandle);
282int                      roar_dl_unref  (struct roar_dl_lhandle * lhandle);
283#define roar_dl_close(x) roar_dl_unref((x))
284
285void                   * roar_dl_getsym (struct roar_dl_lhandle * lhandle, const char * sym, int type);
286
287int                      roar_dl_ra_init(struct roar_dl_lhandle * lhandle,
288                                         const char * prefix,
289                                         struct roar_dl_librarypara * para);
290
291const char *             roar_dl_errstr (struct roar_dl_lhandle * lhandle);
292
293// getting meta data:
294struct roar_dl_librarypara       * roar_dl_getpara(struct roar_dl_lhandle * lhandle);
295const struct roar_dl_libraryname * roar_dl_getlibname(struct roar_dl_lhandle * lhandle);
296
297// context switching:
298// _restore() is to switch from main to library context. _store() is to store library context
299// and switch back to main context.
300int                      roar_dl_context_restore(struct roar_dl_lhandle * lhandle);
301int                      roar_dl_context_store(struct roar_dl_lhandle * lhandle);
302
303// appsched:
304int                      roar_dl_appsched_trigger(struct roar_dl_lhandle * lhandle, enum roar_dl_appsched_trigger trigger);
305
306// FN Registration:
307
308// Actions objects can emit:
309enum roar_dl_fnreg_action {
310 ROAR_DL_FNREG   = 1, // The object is been registered
311 ROAR_DL_FNUNREG = 2  // The object is been unregistered
312};
313
314// Callback for registering/unregistering objects:
315struct roar_dl_fnreg {
316 int fn;          // Filter: The FN of the registering object or -1 for any.
317 int subtype;     // Filter: The subtype of the registering object or -1 for any.
318 int version;     // Filter: The version of the registering object or -1 for any.
319 int (*callback)( // Callback to call on register/unregister.
320   enum roar_dl_fnreg_action action, // The action happening
321   int fn,                           // The FN of the object
322   int subtype,                      // The subtype of the object
323   const void * object,              // Pointer to the object
324   size_t objectlen,                 // Length of the object
325   int version,                      // Version of the object
326   int options,                      // Object Options.
327   void * userdata,                  // User data for the callback.
328   struct roar_dl_lhandle * lhandle  // The registering handle.
329                                     // This is valid until the object is unregistered.
330                                     // Only roar_dl_context_restore() and roar_dl_context_store()
331                                     // may be used on this object. Result of all other functions
332                                     // is undefined.
333 );
334 void * userdata; // The user data pointer passed to the callback.
335};
336
337// Parameters for FNREG registration:
338#define ROAR_DL_FNREG_SUBTYPE  0
339#define ROAR_DL_FNREG_VERSION  0
340#define ROAR_DL_FNREG_SIZE     sizeof(struct roar_dl_fnreg)
341
342
343// Common protocol interface:
344struct roar_dl_proto {
345 const int proto;
346 const char * description;
347 const int flags;
348 int (*set_proto)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen);
349 int (*unset_proto)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen);
350 int (*handle)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen);
351 int (*flush)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen);
352 int (*flushed)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen);
353 int (*status)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen);
354};
355
356#define ROAR_DL_PROTO_FLAGS_NONE         0
357
358#define ROAR_DL_PROTO_STATUS_RX_READY    0x0001
359#define ROAR_DL_PROTO_STATUS_TX_READY    0x0002
360#define ROAR_DL_PROTO_STATUS_WAIT_NOTIFY 0x0004
361
362// Parameters for FNREG registration:
363#define ROAR_DL_PROTO_SUBTYPE  1 /* 0 = roard */
364#define ROAR_DL_PROTO_VERSION  0
365#define ROAR_DL_PROTO_SIZE     sizeof(struct roar_dl_proto)
366
367// Reg FN:
368
369// Options:
370#define ROAR_DL_FNREG_OPT_NONE 0   /* no options */
371
372// Register an FN.
373int                      roar_dl_register_fn(struct roar_dl_lhandle * lhandle, int fn, int subtype, const void * object, size_t objectlen, int version, int options);
374
375// Unregister FN for the given plugin.
376// This should not be called directly and is called internally when needed.
377int                      roar_dl_unregister_fn(struct roar_dl_lhandle * lhandle);
378
379#endif
380
381//ll
Note: See TracBrowser for help on using the repository browser.