From a9ca9c4a3bd8c3c03fe5d30cd2694cf891f5bbc1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Sep 2004 23:17:38 +0000 Subject: add modinfo support git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@191 fefdeb5f-60dc-0310-8127-8f9354f1896f --- doc/todo | 4 +- polyp/Makefile.am | 13 +++- polyp/cmdline.c | 10 +-- polyp/cmdline.h | 2 +- polyp/main.c | 10 +-- polyp/modinfo.c | 84 +++++++++++++++++++++++++ polyp/modinfo.h | 37 +++++++++++ polyp/module-alsa-sink.c | 10 ++- polyp/module-alsa-source.c | 10 ++- polyp/module-cli.c | 8 ++- polyp/module-native-protocol-fd.c | 8 ++- polyp/module-oss-mmap.c | 10 ++- polyp/module-oss.c | 8 ++- polyp/module-pipe-sink.c | 10 ++- polyp/module-pipe-source.c | 10 ++- polyp/module-protocol-stub.c | 18 +++++- polyp/module-sine.c | 12 +++- polyp/module-x11-bell.c | 11 +++- polyp/module.c | 30 ++++++--- polyp/module.h | 16 +++-- polyp/pamodinfo.c | 126 ++++++++++++++++++++++++++++++++++++++ 21 files changed, 390 insertions(+), 57 deletions(-) create mode 100644 polyp/modinfo.c create mode 100644 polyp/modinfo.h create mode 100644 polyp/pamodinfo.c diff --git a/doc/todo b/doc/todo index a6e3dd90..c9be66ab 100644 --- a/doc/todo +++ b/doc/todo @@ -8,6 +8,7 @@ module load/unload kill client/... autoload management + rename streams/contexts - more complete pactl - add sample directory - config file for command line arguments @@ -17,7 +18,8 @@ - per-channel volume - extend pa_usec_t to 64 bit - make use of network latency in all apps -- rename streams/contexts +- fix or work around libtool bug +- merge pa_context_connect_* ** later *** - xmlrpc/http diff --git a/polyp/Makefile.am b/polyp/Makefile.am index 448eb277..9cb8c4ba 100644 --- a/polyp/Makefile.am +++ b/polyp/Makefile.am @@ -23,7 +23,7 @@ polypconfdir=$(sysconfdir)/polyp modlibdir=$(libdir)/polypaudio-@PA_MAJORMINOR@ AM_CFLAGS=-D_GNU_SOURCE -I$(top_srcdir) $(PTHREAD_CFLAGS) -AM_CFLAGS+=-DDLSEARCHDIR=\"$(modlibdir)\" +AM_CFLAGS+=-DDLSEARCHPATH=\"$(modlibdir)\" AM_CFLAGS+=-DDEFAULT_CONFIG_FILE=\"$(polypconfdir)/polypaudio.pa\" AM_CFLAGS+=-DPOLYPAUDIO_BINARY=\"$(bindir)/polypaudio\" @@ -31,7 +31,7 @@ AM_LDADD=$(PTHREAD_LIBS) -lm AM_LIBADD=$(PTHREAD_LIBS) -lm EXTRA_DIST = polypaudio.pa depmod.py esdcompat.sh.in -bin_PROGRAMS = polypaudio pacat pactl +bin_PROGRAMS = polypaudio pacat pactl pamodinfo bin_SCRIPTS = esdcompat.sh noinst_PROGRAMS = mainloop-test mainloop-test-glib mainloop-test-glib12 pacat-simple parec-simple cpulimit-test cpulimit-test2 @@ -148,13 +148,20 @@ polypaudio_SOURCES = idxset.c idxset.h \ sound-file-stream.c sound-file-stream.h \ cpulimit.c cpulimit.h \ log.c log.h \ - gcc-printf.h + gcc-printf.h \ + modinfo.c modinfo.h polypaudio_CFLAGS = $(AM_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) polypaudio_INCLUDES = $(INCLTDL) polypaudio_LDADD = $(AM_LDADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) polypaudio_LDFLAGS=-export-dynamic +pamodinfo_SOURCES = log.c log.h pamodinfo.c pamodinfo.h modinfo.c modinfo.h util.c util.h xmalloc.c xmalloc.h +pamodinfo_CFLAGS = $(AM_CFLAGS) +pamodinfo_INCLUDES = $(INCLTDL) +pamodinfo_LDADD = $(AM_LDADD) $(LIBLTDL) +pamodinfo_LDFLAGS=-export-dynamic + libprotocol_simple_la_SOURCES = protocol-simple.c protocol-simple.h libprotocol_simple_la_LDFLAGS = -avoid-version libprotocol_simple_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la diff --git a/polyp/cmdline.c b/polyp/cmdline.c index e6f4101d..b4d58f1f 100644 --- a/polyp/cmdline.c +++ b/polyp/cmdline.c @@ -102,7 +102,7 @@ struct pa_cmdline* pa_cmdline_parse(int argc, char * const argv []) { cmdline->fail = cmdline->auto_log_target = 1; cmdline->quit_after_last_client_time = -1; cmdline->log_target = -1; - cmdline->dl_searchdir = NULL; + cmdline->dl_search_path = NULL; buf = pa_strbuf_new(); assert(buf); @@ -149,9 +149,9 @@ struct pa_cmdline* pa_cmdline_parse(int argc, char * const argv []) { cmdline->quit_after_last_client_time = atoi(optarg); break; case 'p': - if (cmdline->dl_searchdir) - pa_xfree(cmdline->dl_searchdir); - cmdline->dl_searchdir = pa_xstrdup(optarg); + if (cmdline->dl_search_path) + pa_xfree(cmdline->dl_search_path); + cmdline->dl_search_path = pa_xstrdup(optarg); break; case 'l': if (!strcmp(optarg, "syslog")) { @@ -192,6 +192,6 @@ fail: void pa_cmdline_free(struct pa_cmdline *cmd) { assert(cmd); pa_xfree(cmd->cli_commands); - pa_xfree(cmd->dl_searchdir); + pa_xfree(cmd->dl_search_path); pa_xfree(cmd); } diff --git a/polyp/cmdline.h b/polyp/cmdline.h index bf909c84..5dfe2e0d 100644 --- a/polyp/cmdline.h +++ b/polyp/cmdline.h @@ -36,7 +36,7 @@ struct pa_cmdline { quit_after_last_client_time, auto_log_target; char *cli_commands; - char *dl_searchdir; + char *dl_search_path; enum pa_log_target log_target; }; diff --git a/polyp/main.c b/polyp/main.c index 2131877d..0218f396 100644 --- a/polyp/main.c +++ b/polyp/main.c @@ -181,11 +181,11 @@ int main(int argc, char *argv[]) { r = lt_dlinit(); assert(r == 0); - if (cmdline->dl_searchdir) - lt_dladdsearchdir(cmdline->dl_searchdir); - -#ifdef DLSEARCHDIR - lt_dladdsearchdir(DLSEARCHDIR); + if (cmdline->dl_search_path) + lt_dlsetsearchpath(cmdline->dl_search_path); +#ifdef DLSEARCHPATH + else + lt_dlsetsearchpath(DLSEARCHPATH); #endif mainloop = pa_mainloop_new(); diff --git a/polyp/modinfo.c b/polyp/modinfo.c new file mode 100644 index 00000000..2847c63c --- /dev/null +++ b/polyp/modinfo.c @@ -0,0 +1,84 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + polypaudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "xmalloc.h" +#include "util.h" +#include "modinfo.h" +#include "log.h" + +#define PA_SYMBOL_AUTHOR "pa__get_author" +#define PA_SYMBOL_DESCRIPTION "pa__get_description" +#define PA_SYMBOL_USAGE "pa__get_usage" +#define PA_SYMBOL_VERSION "pa__get_version" + +struct pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl) { + struct pa_modinfo *i; + const char* (*func)(void); + assert(dl); + + i = pa_xmalloc0(sizeof(struct pa_modinfo)); + + if ((func = (const char* (*)(void)) lt_dlsym(dl, PA_SYMBOL_AUTHOR))) + i->author = pa_xstrdup(func()); + + if ((func = (const char* (*)(void)) lt_dlsym(dl, PA_SYMBOL_DESCRIPTION))) + i->description = pa_xstrdup(func()); + + if ((func = (const char* (*)(void)) lt_dlsym(dl, PA_SYMBOL_USAGE))) + i->usage = pa_xstrdup(func()); + + if ((func = (const char* (*)(void)) lt_dlsym(dl, PA_SYMBOL_VERSION))) + i->version = pa_xstrdup(func()); + + return i; +} + +struct pa_modinfo *pa_modinfo_get_by_name(const char *name) { + lt_dlhandle dl; + struct pa_modinfo *i; + assert(name); + + if (!(dl = lt_dlopenext(name))) { + pa_log(__FILE__": Failed to open module \"%s\": %s\n", name, lt_dlerror()); + return NULL; + } + + i = pa_modinfo_get_by_handle(dl); + lt_dlclose(dl); + + return i; +} + +void pa_modinfo_free(struct pa_modinfo *i) { + assert(i); + pa_xfree(i->author); + pa_xfree(i->description); + pa_xfree(i->usage); + pa_xfree(i->version); + pa_xfree(i); +} diff --git a/polyp/modinfo.h b/polyp/modinfo.h new file mode 100644 index 00000000..40b535ce --- /dev/null +++ b/polyp/modinfo.h @@ -0,0 +1,37 @@ +#ifndef foomodinfohfoo +#define foomodinfohfoo + +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + polypaudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +struct pa_modinfo { + char *author; + char *description; + char *usage; + char *version; +}; + +struct pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl); +struct pa_modinfo *pa_modinfo_get_by_name(const char *name); + +void pa_modinfo_free(struct pa_modinfo *i); + +#endif diff --git a/polyp/module-alsa-sink.c b/polyp/module-alsa-sink.c index 9c75ff98..73c46ea0 100644 --- a/polyp/module-alsa-sink.c +++ b/polyp/module-alsa-sink.c @@ -40,6 +40,10 @@ #include "xmalloc.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("ALSA Sink") +PA_MODULE_VERSION(PACKAGE_VERSION) + struct userdata { snd_pcm_t *pcm_handle; struct pa_sink *sink; @@ -156,7 +160,7 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) { return pa_bytes_to_usec(frames * u->frame_size, &s->sample_spec); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_modargs *ma = NULL; int ret = -1; struct userdata *u = NULL; @@ -237,12 +241,12 @@ finish: fail: if (u) - pa_module_done(c, m); + pa__done(c, m); goto finish; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); diff --git a/polyp/module-alsa-source.c b/polyp/module-alsa-source.c index 520b6830..3ef54b17 100644 --- a/polyp/module-alsa-source.c +++ b/polyp/module-alsa-source.c @@ -40,6 +40,10 @@ #include "xmalloc.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("ALSA Source") +PA_MODULE_VERSION(PACKAGE_VERSION) + struct userdata { snd_pcm_t *pcm_handle; struct pa_source *source; @@ -139,7 +143,7 @@ static void io_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, do_read(u); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_modargs *ma = NULL; int ret = -1; struct userdata *u = NULL; @@ -216,12 +220,12 @@ finish: fail: if (u) - pa_module_done(c, m); + pa__done(c, m); goto finish; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); diff --git a/polyp/module-cli.c b/polyp/module-cli.c index 9a08a00d..35b69cb6 100644 --- a/polyp/module-cli.c +++ b/polyp/module-cli.c @@ -33,6 +33,10 @@ #include "sioman.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("Command line interface") +PA_MODULE_VERSION(PACKAGE_VERSION) + static void eof_cb(struct pa_cli*c, void *userdata) { struct pa_module *m = userdata; assert(c && m); @@ -40,7 +44,7 @@ static void eof_cb(struct pa_cli*c, void *userdata) { pa_module_unload_request(m->core, m); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_iochannel *io; assert(c && m); @@ -66,7 +70,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { return 0; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { assert(c && m); pa_cli_free(m->userdata); diff --git a/polyp/module-native-protocol-fd.c b/polyp/module-native-protocol-fd.c index 632a3d71..c1ea6975 100644 --- a/polyp/module-native-protocol-fd.c +++ b/polyp/module-native-protocol-fd.c @@ -33,6 +33,10 @@ #include "protocol-native.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("Native protocol autospawn helper") +PA_MODULE_VERSION(PACKAGE_VERSION) + static const char* const valid_modargs[] = { "fd", "public", @@ -40,7 +44,7 @@ static const char* const valid_modargs[] = { NULL, }; -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_iochannel *io; struct pa_modargs *ma; int fd, r = -1; @@ -72,7 +76,7 @@ finish: return r; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { assert(c && m); pa_protocol_native_free(m->userdata); diff --git a/polyp/module-oss-mmap.c b/polyp/module-oss-mmap.c index 953871d1..4ffc56ef 100644 --- a/polyp/module-oss-mmap.c +++ b/polyp/module-oss-mmap.c @@ -47,6 +47,10 @@ #include "xmalloc.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("OSS Sink/Source (mmap)") +PA_MODULE_VERSION(PACKAGE_VERSION) + struct userdata { struct pa_sink *sink; struct pa_source *source; @@ -214,7 +218,7 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) { return pa_bytes_to_usec(u->out_fill, &s->sample_spec); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; const char *p; @@ -362,7 +366,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { return 0; fail: - pa_module_done(c, m); + pa__done(c, m); if (ma) pa_modargs_free(ma); @@ -370,7 +374,7 @@ fail: return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); diff --git a/polyp/module-oss.c b/polyp/module-oss.c index 95deca9c..75d72e50 100644 --- a/polyp/module-oss.c +++ b/polyp/module-oss.c @@ -46,6 +46,10 @@ #include "xmalloc.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("OSS Sink/Source") +PA_MODULE_VERSION(PACKAGE_VERSION) + struct userdata { struct pa_sink *sink; struct pa_source *source; @@ -171,7 +175,7 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) { return pa_bytes_to_usec(arg, &s->sample_spec); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; const char *p; @@ -300,7 +304,7 @@ fail: return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); diff --git a/polyp/module-pipe-sink.c b/polyp/module-pipe-sink.c index a5a7877f..1aaf3b6a 100644 --- a/polyp/module-pipe-sink.c +++ b/polyp/module-pipe-sink.c @@ -41,6 +41,10 @@ #include "xmalloc.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("UNIX pipe sink") +PA_MODULE_VERSION(PACKAGE_VERSION) + #define DEFAULT_FIFO_NAME "/tmp/music.output" #define DEFAULT_SINK_NAME "fifo_output" @@ -117,7 +121,7 @@ static void io_callback(struct pa_iochannel *io, void*userdata) { do_write(u); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct userdata *u = NULL; struct stat st; const char *p; @@ -196,12 +200,12 @@ fail: if (fd >= 0) close(fd); - pa_module_done(c, m); + pa__done(c, m); return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); diff --git a/polyp/module-pipe-source.c b/polyp/module-pipe-source.c index baed06a5..a226d44e 100644 --- a/polyp/module-pipe-source.c +++ b/polyp/module-pipe-source.c @@ -41,6 +41,10 @@ #include "xmalloc.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("UNIX pipe source") +PA_MODULE_VERSION(PACKAGE_VERSION) + #define DEFAULT_FIFO_NAME "/tmp/music.input" #define DEFAULT_SOURCE_NAME "fifo_input" @@ -102,7 +106,7 @@ static void io_callback(struct pa_iochannel *io, void*userdata) { do_read(u); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct userdata *u = NULL; struct stat st; const char *p; @@ -176,12 +180,12 @@ fail: if (fd >= 0) close(fd); - pa_module_done(c, m); + pa__done(c, m); return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); diff --git a/polyp/module-protocol-stub.c b/polyp/module-protocol-stub.c index 686e2129..fe9e12a1 100644 --- a/polyp/module-protocol-stub.c +++ b/polyp/module-protocol-stub.c @@ -37,6 +37,16 @@ #include "modargs.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_VERSION(PACKAGE_VERSION) + +#ifdef USE_TCP_SOCKETS +#define SOCKET_DESCRIPTION "(TCP sockets)" +#else +#define SOCKET_DESCRIPTION "(UNIX sockets)" +#endif + + #if defined(USE_PROTOCOL_SIMPLE) #include "protocol-simple.h" #define protocol_new pa_protocol_simple_new @@ -44,6 +54,7 @@ #define IPV4_PORT 4711 #define UNIX_SOCKET "/tmp/polypaudio/simple" #define MODULE_ARGUMENTS "rate", "format", "channels", "sink", "source", "playback", "record", + PA_MODULE_DESCRIPTION("Simple protocol "SOCKET_DESCRIPTION) #elif defined(USE_PROTOCOL_CLI) #include "protocol-cli.h" #define protocol_new pa_protocol_cli_new @@ -51,6 +62,7 @@ #define IPV4_PORT 4712 #define UNIX_SOCKET "/tmp/polypaudio/cli" #define MODULE_ARGUMENTS + PA_MODULE_DESCRIPTION("Command line interface protocol "SOCKET_DESCRIPTION) #elif defined(USE_PROTOCOL_NATIVE) #include "protocol-native.h" #define protocol_new pa_protocol_native_new @@ -58,6 +70,7 @@ #define IPV4_PORT 4713 #define UNIX_SOCKET "/tmp/polypaudio/native" #define MODULE_ARGUMENTS "public", "cookie", + PA_MODULE_DESCRIPTION("Native protocol "SOCKET_DESCRIPTION) #elif defined(USE_PROTOCOL_ESOUND) #include "protocol-esound.h" #include "esound.h" @@ -66,6 +79,7 @@ #define IPV4_PORT ESD_DEFAULT_PORT #define UNIX_SOCKET ESD_UNIX_SOCKET_NAME #define MODULE_ARGUMENTS "sink", "source", "public", "cookie", + PA_MODULE_DESCRIPTION("EsounD protocol "SOCKET_DESCRIPTION) #else #error "Broken build system" #endif @@ -126,7 +140,7 @@ static struct pa_socket_server *create_socket_server(struct pa_core *c, struct p return s; } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_socket_server *s; struct pa_modargs *ma = NULL; int ret = -1; @@ -154,7 +168,7 @@ finish: return ret; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { assert(c && m); protocol_free(m->userdata); diff --git a/polyp/module-sine.c b/polyp/module-sine.c index 868f63c6..98e0dc28 100644 --- a/polyp/module-sine.c +++ b/polyp/module-sine.c @@ -34,6 +34,11 @@ #include "namereg.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("Sine wave generator") +PA_MODULE_USAGE("sink= frequency=") +PA_MODULE_VERSION(PACKAGE_VERSION) + struct userdata { struct pa_core *core; struct pa_sink_input *sink_input; @@ -89,7 +94,7 @@ static void calc_sine(float *f, size_t l, float freq) { f[i] = (float) sin((double) i/l*M_PI*2*freq)/2; } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct pa_modargs *ma = NULL; struct userdata *u; struct pa_sink *sink; @@ -147,11 +152,11 @@ fail: if (ma) pa_modargs_free(ma); - pa_module_done(c, m); + pa__done(c, m); return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u = m->userdata; assert(c && m); @@ -164,3 +169,4 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) { pa_memblock_unref(u->memblock); pa_xfree(u); } + diff --git a/polyp/module-x11-bell.c b/polyp/module-x11-bell.c index d8ec978b..ae69f9cb 100644 --- a/polyp/module-x11-bell.c +++ b/polyp/module-x11-bell.c @@ -39,6 +39,11 @@ #include "namereg.h" #include "log.h" +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("X11 Bell interceptor") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE("sink= sample= display=") + struct x11_source { struct pa_io_event *io_event; struct x11_source *next; @@ -105,7 +110,7 @@ static void new_io_source(struct userdata *u, int fd) { u->x11_sources = s; } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct userdata *u = NULL; struct pa_modargs *ma = NULL; int major, minor; @@ -160,11 +165,11 @@ fail: if (ma) pa_modargs_free(ma); if (m->userdata) - pa_module_done(c, m); + pa__done(c, m); return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u = m->userdata; assert(c && m && u); diff --git a/polyp/module.c b/polyp/module.c index 6eec499b..c66faeb8 100644 --- a/polyp/module.c +++ b/polyp/module.c @@ -35,6 +35,9 @@ #include "subscribe.h" #include "log.h" +#define PA_SYMBOL_INIT "pa__init" +#define PA_SYMBOL_DONE "pa__done" + #define UNLOAD_POLL_TIME 10 static void timeout_callback(struct pa_mainloop_api *m, struct pa_time_event*e, const struct timeval *tv, void *userdata) { @@ -58,21 +61,25 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char if (c->disallow_module_loading) goto fail; - pa_log(__FILE__": Trying to load \"%s\" with argument \"%s\".\n", name, argument); - m = pa_xmalloc(sizeof(struct pa_module)); m->name = pa_xstrdup(name); m->argument = pa_xstrdup(argument); - if (!(m->dl = lt_dlopenext(name))) + if (!(m->dl = lt_dlopenext(name))) { + pa_log(__FILE__": Failed to open module \"%s\": %s\n", name, lt_dlerror()); goto fail; + } - if (!(m->init = (int (*)(struct pa_core *c, struct pa_module*m)) lt_dlsym(m->dl, "pa_module_init"))) + if (!(m->init = (int (*)(struct pa_core *c, struct pa_module*m)) lt_dlsym(m->dl, PA_SYMBOL_INIT))) { + pa_log(__FILE__": Failed to load module \"%s\": symbol \""PA_SYMBOL_INIT"\" not found.\n", name); goto fail; + } - if (!(m->done = (void (*)(struct pa_core *c, struct pa_module*m)) lt_dlsym(m->dl, "pa_module_done"))) + if (!(m->done = (void (*)(struct pa_core *c, struct pa_module*m)) lt_dlsym(m->dl, PA_SYMBOL_DONE))) { + pa_log(__FILE__": Failed to load module \"%s\": symbol \""PA_SYMBOL_DONE"\" not found.\n", name); goto fail; + } m->userdata = NULL; m->core = c; @@ -80,8 +87,10 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char m->auto_unload = 0; assert(m->init); - if (m->init(c, m) < 0) + if (m->init(c, m) < 0) { + pa_log(__FILE__": Failed to load module \"%s\" (argument: \"%s\"): initialization failed.\n", name, argument ? argument : ""); goto fail; + } if (!c->modules) c->modules = pa_idxset_new(NULL, NULL); @@ -98,7 +107,7 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char r = pa_idxset_put(c->modules, m, &m->index); assert(r >= 0 && m->index != PA_IDXSET_INVALID); - pa_log(__FILE__": Loaded \"%s\" (index: #%u) with argument \"%s\".\n", m->name, m->index, m->argument); + pa_log(__FILE__": Loaded \"%s\" (index: #%u; argument: \"%s\").\n", m->name, m->index, m->argument ? m->argument : ""); pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_NEW, m->index); @@ -106,8 +115,6 @@ struct pa_module* pa_module_load(struct pa_core *c, const char *name, const char fail: - pa_log(__FILE__": Failed to load \"%s\" with argument \"%s\".\n", name, argument); - if (m) { pa_xfree(m->argument); pa_xfree(m->name); @@ -239,3 +246,8 @@ void pa_module_set_used(struct pa_module*m, int used) { m->n_used = used; } +struct pa_modinfo *pa_module_get_info(struct pa_module *m) { + assert(m); + + return pa_modinfo_get_by_handle(m->dl); +} diff --git a/polyp/module.h b/polyp/module.h index acc08c3e..663e0246 100644 --- a/polyp/module.h +++ b/polyp/module.h @@ -26,6 +26,7 @@ #include #include "core.h" +#include "modinfo.h" struct pa_module { struct pa_core *core; @@ -53,10 +54,17 @@ void pa_module_unload_unused(struct pa_core *c); void pa_module_unload_request(struct pa_core *c, struct pa_module *m); -/* These to following prototypes are for module entrypoints and not implemented by the core */ -int pa_module_init(struct pa_core *c, struct pa_module*m); -void pa_module_done(struct pa_core *c, struct pa_module*m); - void pa_module_set_used(struct pa_module*m, int used); +/* prototypes for the module's entry points */ +int pa__init(struct pa_core *c, struct pa_module*m); +void pa__done(struct pa_core *c, struct pa_module*m); + +#define PA_MODULE_AUTHOR(s) const char *pa__get_author(void) { return s; } +#define PA_MODULE_DESCRIPTION(s) const char *pa__get_description(void) { return s; } +#define PA_MODULE_USAGE(s) const char *pa__get_usage(void) { return s; } +#define PA_MODULE_VERSION(s) const char *pa__get_version(void) { return s; } + +struct pa_modinfo *pa_module_get_info(struct pa_module *m); + #endif diff --git a/polyp/pamodinfo.c b/polyp/pamodinfo.c new file mode 100644 index 00000000..6eb147f0 --- /dev/null +++ b/polyp/pamodinfo.c @@ -0,0 +1,126 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + polypaudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "modinfo.h" + +#define PREFIX "module-" + +static int verbose = 0; + +static void short_info(const char *name, const char *path, struct pa_modinfo *i) { + assert(name && i); + printf("%-40s%s\n", name, i->description ? i->description : "n/a"); +} + +static void long_info(const char *name, const char *path, struct pa_modinfo *i) { + assert(name && i); + static int nl = 0; + + if (nl) + printf("\n"); + + nl = 1; + + printf("Name: %s\n", name); + + if (!i->description && !i->version && !i->author && !i->usage) + printf("No module information available\n"); + else { + if (i->version) + printf("Version: %s\n", i->version); + if (i->description) + printf("Description: %s\n", i->description); + if (i->author) + printf("Author: %s\n", i->author); + if (i->usage) + printf("Usage: %s\n", i->usage); + } + + if (path) + printf("Path: %s\n", path); +} + +static void show_info(const char *name, const char *path, void (*info)(const char *name, const char *path, struct pa_modinfo*i)) { + struct pa_modinfo *i; + + if ((i = pa_modinfo_get_by_name(path ? path : name))) { + info(name, path, i); + pa_modinfo_free(i); + } +} + +static int callback(const char *path, lt_ptr data) { + const char *e; + + if ((e = (const char*) strrchr(path, '/'))) + e++; + else + e = path; + + if (strlen(e) > sizeof(PREFIX)-1 && !strncmp(e, PREFIX, sizeof(PREFIX)-1)) + show_info(e, path, verbose ? long_info : short_info); + + return 0; +} + +int main(int argc, char *argv[]) { + int r = lt_dlinit(); + char *path = NULL; + int c; + assert(r == 0); + + while ((c = getopt(argc, argv, "p:v")) != -1) { + switch (c) { + case 'p': + path = optarg; + break; + case 'v': + verbose = 1; + break; + default: + return 1; + } + } + + if (path) + lt_dlsetsearchpath(path); +#ifdef DLSEARCHPATH + else + lt_dlsetsearchpath(DLSEARCHPATH); +#endif + + if (argc > optind) + show_info(argv[optind], NULL, long_info); + else + lt_dlforeachfile(NULL, callback, NULL); + + lt_dlexit(); +} -- cgit