X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/c17545108b33162fb186f797b8a408511e9252f4..fa499dad06ba6558111cdef64c18f2401e803cff:/polyp/module-x11-bell.c diff --git a/polyp/module-x11-bell.c b/polyp/module-x11-bell.c index 2414e36b..c3987704 100644 --- a/polyp/module-x11-bell.c +++ b/polyp/module-x11-bell.c @@ -1,3 +1,28 @@ +/* $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 Lesser 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 Lesser 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 @@ -12,20 +37,24 @@ #include "modargs.h" #include "xmalloc.h" #include "namereg.h" +#include "log.h" +#include "x11wrap.h" +#include "module-x11-bell-symdef.h" -struct x11_source { - struct pa_io_event *io_event; - struct x11_source *next; -}; +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("X11 Bell interceptor") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE("sink= sample= display=") struct userdata { struct pa_core *core; - Display *display; - struct x11_source *x11_sources; int xkb_event_base; - char *sink_name; char *scache_item; + Display *display; + + struct pa_x11_wrapper *x11_wrapper; + struct pa_x11_client *x11_client; }; static const char* const valid_modargs[] = { @@ -40,50 +69,33 @@ static int ring_bell(struct userdata *u, int percent) { assert(u); if (!(s = pa_namereg_get(u->core, u->sink_name, PA_NAMEREG_SINK, 1))) { - fprintf(stderr, __FILE__": Invalid sink\n"); - return -1; - } - - if (pa_scache_play_item(u->core, u->scache_item, s, percent*2) < 0) { - fprintf(stderr, __FILE__": Failed to play sample\n"); + pa_log(__FILE__": Invalid sink\n"); return -1; } + pa_scache_play_item(u->core, u->scache_item, s, percent*2); return 0; } -static void io_callback(struct pa_mainloop_api*a, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) { +static int x11_event_callback(struct pa_x11_wrapper *w, XEvent *e, void *userdata) { + XkbBellNotifyEvent *bne; struct userdata *u = userdata; - assert(u); - - while (XPending(u->display)) { - XEvent e; - XkbBellNotifyEvent *bne; - XNextEvent(u->display, &e); - - if (((XkbEvent*) &e)->any.xkb_type != XkbBellNotify) - continue; - - bne = ((XkbBellNotifyEvent*) &e); - - if (ring_bell(u, bne->percent) < 0) { - fprintf(stderr, __FILE__": Ringing bell failed, reverting to X11 device bell.\n"); - XkbForceDeviceBell(u->display, bne->device, bne->bell_class, bne->bell_id, bne->percent); - } - } -} + assert(w && e && u && u->x11_wrapper == w); + + if (((XkbEvent*) e)->any.xkb_type != XkbBellNotify) + return 0; -static void new_io_source(struct userdata *u, int fd) { - struct x11_source *s; + bne = (XkbBellNotifyEvent*) e; - s = pa_xmalloc(sizeof(struct x11_source)); - s->io_event = u->core->mainloop->io_new(u->core->mainloop, fd, PA_IO_EVENT_INPUT, io_callback, u); - assert(s->io_event); - s->next = u->x11_sources; - u->x11_sources = s; + if (ring_bell(u, bne->percent) < 0) { + pa_log(__FILE__": Ringing bell failed, reverting to X11 device bell.\n"); + XkbForceDeviceBell(pa_x11_wrapper_get_display(w), bne->device, bne->bell_class, bne->bell_id, bne->percent); + } + + return 1; } -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; @@ -91,37 +103,35 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { assert(c && m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - fprintf(stderr, __FILE__": failed to parse module arguments\n"); + pa_log(__FILE__": failed to parse module arguments\n"); goto fail; } m->userdata = u = pa_xmalloc(sizeof(struct userdata)); u->core = c; - u->display = NULL; - u->x11_sources = NULL; u->scache_item = pa_xstrdup(pa_modargs_get_value(ma, "sample", "x11-bell")); u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); + u->x11_client = NULL; - if (!(u->display = XOpenDisplay(pa_modargs_get_value(ma, "display", NULL)))) { - fprintf(stderr, __FILE__": XOpenDisplay() failed\n"); + if (!(u->x11_wrapper = pa_x11_wrapper_get(c, pa_modargs_get_value(ma, "display", NULL)))) goto fail; - } - - new_io_source(u, ConnectionNumber(u->display)); + u->display = pa_x11_wrapper_get_display(u->x11_wrapper); + major = XkbMajorVersion; minor = XkbMinorVersion; if (!XkbLibraryVersion(&major, &minor)) { - fprintf(stderr, __FILE__": XkbLibraryVersion() failed\n"); + pa_log(__FILE__": XkbLibraryVersion() failed\n"); goto fail; } major = XkbMajorVersion; minor = XkbMinorVersion; + if (!XkbQueryExtension(u->display, NULL, &u->xkb_event_base, NULL, &major, &minor)) { - fprintf(stderr, __FILE__": XkbQueryExtension() failed\n"); + pa_log(__FILE__": XkbQueryExtension() failed\n"); goto fail; } @@ -130,6 +140,8 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { XkbSetAutoResetControls(u->display, XkbAudibleBellMask, &auto_ctrls, &auto_values); XkbChangeEnabledControls(u->display, XkbUseCoreKbd, XkbAudibleBellMask, 0); + u->x11_client = pa_x11_client_new(u->x11_wrapper, x11_event_callback, u); + pa_modargs_free(ma); return 0; @@ -138,25 +150,22 @@ 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); - while (u->x11_sources) { - struct x11_source *s = u->x11_sources; - u->x11_sources = u->x11_sources->next; - c->mainloop->io_free(s->io_event); - pa_xfree(s); - } - pa_xfree(u->scache_item); pa_xfree(u->sink_name); - - if (u->display) - XCloseDisplay(u->display); + + if (u->x11_client) + pa_x11_client_free(u->x11_client); + + if (u->x11_wrapper) + pa_x11_wrapper_unref(u->x11_wrapper); + pa_xfree(u); }