diff options
Diffstat (limited to 'src/modules/module-lirc.c')
| -rw-r--r-- | src/modules/module-lirc.c | 166 |
1 files changed, 80 insertions, 86 deletions
diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index a93a3b92..15f3442d 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -1,18 +1,18 @@ -/* $Id$ */ - /*** This file is part of PulseAudio. - + + Copyright 2005-2006 Lennart Poettering + PulseAudio 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + PulseAudio 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 PulseAudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 @@ -24,12 +24,12 @@ #endif #include <stdio.h> -#include <assert.h> #include <unistd.h> #include <string.h> -#include <lirc/lirc_client.h> #include <stdlib.h> +#include <lirc/lirc_client.h> + #include <pulse/xmalloc.h> #include <pulsecore/module.h> @@ -37,18 +37,22 @@ #include <pulsecore/namereg.h> #include <pulsecore/sink.h> #include <pulsecore/modargs.h> +#include <pulsecore/macro.h> #include "module-lirc-symdef.h" -PA_MODULE_AUTHOR("Lennart Poettering") -PA_MODULE_DESCRIPTION("LIRC volume control") -PA_MODULE_VERSION(PACKAGE_VERSION) -PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name>") +PA_MODULE_AUTHOR("Lennart Poettering"); +PA_MODULE_DESCRIPTION("LIRC volume control"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(TRUE); +PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name> volume_limit=<volume limit> volume_step=<volume change step>"); static const char* const valid_modargs[] = { "config", "sink", "appname", + "volume_limit", + "volume_step", NULL, }; @@ -59,34 +63,35 @@ struct userdata { char *sink_name; pa_module *module; float mute_toggle_save; + pa_volume_t volume_limit; + pa_volume_t volume_step; }; -static int lirc_in_use = 0; - -static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) { +static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; char *name = NULL, *code = NULL; - assert(io); - assert(u); + + pa_assert(io); + pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { - pa_log(__FILE__": lost connection to LIRC daemon."); + pa_log("Lost connection to LIRC daemon."); goto fail; } - + if (events & PA_IO_EVENT_INPUT) { char *c; - + if (lirc_nextcode(&code) != 0 || !code) { - pa_log(__FILE__": lirc_nextcode() failed."); + pa_log("lirc_nextcode() failed."); goto fail; } - + c = pa_xstrdup(code); c[strcspn(c, "\n\r")] = 0; - pa_log_debug(__FILE__": raw IR code '%s'", c); + pa_log_debug("Raw IR code '%s'", c); pa_xfree(c); - + while (lirc_code2char(u->config, code, &name) == 0 && name) { enum { INVALID, @@ -96,9 +101,9 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC RESET, MUTE_TOGGLE } volchange = INVALID; - - pa_log_info(__FILE__": translated IR code '%s'", name); - + + pa_log_info("Translated IR code '%s'", name); + if (strcasecmp(name, "volume-up") == 0) volchange = UP; else if (strcasecmp(name, "volume-down") == 0) @@ -109,58 +114,42 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC volchange = MUTE_TOGGLE; else if (strcasecmp(name, "reset") == 0) volchange = RESET; - + if (volchange == INVALID) - pa_log_warn(__FILE__": recieved unknown IR code '%s'", name); + pa_log_warn("Received unknown IR code '%s'", name); else { pa_sink *s; - - if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK, 1))) - pa_log(__FILE__": failed to get sink '%s'", u->sink_name); - else { - int i; - pa_cvolume cv = *pa_sink_get_volume(s, PA_MIXER_HARDWARE); -#define DELTA (PA_VOLUME_NORM/20) + if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) + pa_log("Failed to get sink '%s'", u->sink_name); + else { + pa_cvolume cv = *pa_sink_get_volume(s, FALSE); switch (volchange) { case UP: - for (i = 0; i < cv.channels; i++) { - cv.values[i] += DELTA; - - if (cv.values[i] > PA_VOLUME_NORM) - cv.values[i] = PA_VOLUME_NORM; - } - - pa_sink_set_volume(s, PA_MIXER_HARDWARE, &cv); + pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit); + pa_sink_set_volume(s, &cv, TRUE, TRUE); break; - + case DOWN: - for (i = 0; i < cv.channels; i++) { - if (cv.values[i] >= DELTA) - cv.values[i] -= DELTA; - else - cv.values[i] = PA_VOLUME_MUTED; - } - - pa_sink_set_volume(s, PA_MIXER_HARDWARE, &cv); + pa_cvolume_dec(&cv, u->volume_step); + pa_sink_set_volume(s, &cv, TRUE, TRUE); break; - + case MUTE: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, 0); + pa_sink_set_mute(s, TRUE, TRUE); break; - + case RESET: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, 1); + pa_sink_set_mute(s, FALSE, TRUE); break; - - case MUTE_TOGGLE: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, !pa_sink_get_mute(s, PA_MIXER_HARDWARE)); + case MUTE_TOGGLE: + pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE), TRUE); break; case INVALID: - ; + pa_assert_not_reached(); } } } @@ -170,55 +159,63 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC pa_xfree(code); return; - + fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; - pa_module_unload_request(u->module); + pa_module_unload_request(u->module, TRUE); - free(code); + pa_xfree(code); } - -int pa__init(pa_core *c, pa_module*m) { + +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - assert(c && m); + pa_volume_t volume_limit = PA_CLAMP_VOLUME(PA_VOLUME_NORM*3/2); + pa_volume_t volume_step = PA_VOLUME_NORM/20; + + pa_assert(m); - if (lirc_in_use) { - pa_log(__FILE__": module-lirc may no be loaded twice."); - return -1; - } - if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log(__FILE__": Failed to parse module arguments"); + pa_log("Failed to parse module arguments"); goto fail; } - m->userdata = u = pa_xmalloc(sizeof(struct userdata)); + if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) { + pa_log("Failed to parse volume limit"); + goto fail; + } + + if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) { + pa_log("Failed to parse volume step"); + goto fail; + } + + m->userdata = u = pa_xnew(struct userdata, 1); u->module = m; u->io = NULL; u->config = NULL; u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); u->lirc_fd = -1; u->mute_toggle_save = 0; + u->volume_limit = PA_CLAMP_VOLUME(volume_limit); + u->volume_step = PA_CLAMP_VOLUME(volume_step); if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) { - pa_log(__FILE__": lirc_init() failed."); + pa_log("lirc_init() failed."); goto fail; } if (lirc_readconfig((char*) pa_modargs_get_value(ma, "config", NULL), &u->config, NULL) < 0) { - pa_log(__FILE__": lirc_readconfig() failed."); + pa_log("lirc_readconfig() failed."); goto fail; } - - u->io = c->mainloop->io_new(c->mainloop, u->lirc_fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_callback, u); - lirc_in_use = 1; + u->io = m->core->mainloop->io_new(m->core->mainloop, u->lirc_fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_callback, u); pa_modargs_free(ma); - + return 0; fail: @@ -226,14 +223,13 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(m); if (!(u = m->userdata)) return; @@ -249,6 +245,4 @@ void pa__done(pa_core *c, pa_module*m) { pa_xfree(u->sink_name); pa_xfree(u); - - lirc_in_use = 0; } |
