X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/432b4e5f7d9ea722d13bbe4c117a4f9b78091e4f..a67318f8affc4973507811946708bc17e63f1ec7:/src/modules/module-mmkbd-evdev.c diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 3f012b7f..9ab7eb97 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -5,7 +5,7 @@ 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 @@ -47,25 +47,16 @@ PA_MODULE_AUTHOR("Lennart Poettering"); PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev"); PA_MODULE_VERSION(PACKAGE_VERSION); -PA_MODULE_LOAD_ONCE(FALSE); -PA_MODULE_USAGE("device= sink="); +PA_MODULE_LOAD_ONCE(false); +PA_MODULE_USAGE("device= sink= volume_limit= volume_step="); #define DEFAULT_DEVICE "/dev/input/event0" -/* - * This isn't defined in older kernel headers and there is no way of - * detecting it. - */ -struct _input_id { - __u16 bustype; - __u16 vendor; - __u16 product; - __u16 version; -}; - static const char* const valid_modargs[] = { "device", "sink", + "volume_limit", + "volume_step", NULL, }; @@ -74,6 +65,8 @@ struct userdata { pa_io_event *io; char *sink_name; pa_module *module; + pa_volume_t volume_limit; + pa_volume_t volume_step; }; static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { @@ -96,57 +89,54 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event } if (ev.type == EV_KEY && (ev.value == 1 || ev.value == 2)) { - enum { INVALID, UP, DOWN, MUTE_TOGGLE } volchange = INVALID; + enum { + INVALID, + UP, + DOWN, + MUTE_TOGGLE + } volchange = INVALID; pa_log_debug("Key code=%u, value=%u", ev.code, ev.value); switch (ev.code) { - case KEY_VOLUMEDOWN: volchange = DOWN; break; - case KEY_VOLUMEUP: volchange = UP; break; - case KEY_MUTE: volchange = MUTE_TOGGLE; break; + case KEY_VOLUMEDOWN: + volchange = DOWN; + break; + + case KEY_VOLUMEUP: + volchange = UP; + break; + + case KEY_MUTE: + volchange = MUTE_TOGGLE; + break; } if (volchange != INVALID) { pa_sink *s; - if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK, 1))) + 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 { - int i; - pa_cvolume cv = *pa_sink_get_volume(s); - -#define DELTA (PA_VOLUME_NORM/20) + 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, &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, &cv); + pa_cvolume_dec(&cv, u->volume_step); + pa_sink_set_volume(s, &cv, true, true); break; case MUTE_TOGGLE: - - pa_sink_set_mute(s, !pa_sink_get_mute(s)); + pa_sink_set_mute(s, !pa_sink_get_mute(s, false), true); break; case INVALID: - ; + pa_assert_not_reached(); } } } @@ -159,7 +149,7 @@ fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; - pa_module_unload_request(u->module, TRUE); + pa_module_unload_request(u->module, true); } #define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) @@ -169,9 +159,11 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; int version; - struct _input_id input_id; + struct input_id input_id; char name[256]; uint8_t evtype_bitmask[EV_MAX/8 + 1]; + pa_volume_t volume_limit = PA_VOLUME_NORM*3/2; + pa_volume_t volume_step = PA_VOLUME_NORM/20; pa_assert(m); @@ -180,15 +172,27 @@ int pa__init(pa_module*m) { goto fail; } - m->userdata = u = pa_xnew(struct userdata,1); + 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->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); u->fd = -1; u->fd_type = 0; + u->volume_limit = PA_CLAMP_VOLUME(volume_limit); + u->volume_step = PA_CLAMP_VOLUME(volume_step); - if ((u->fd = open(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY)) < 0) { - pa_log("failed to open evdev device: %s", pa_cstrerror(errno)); + if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) { + pa_log("Failed to open evdev device: %s", pa_cstrerror(errno)); goto fail; } @@ -199,7 +203,7 @@ int pa__init(pa_module*m) { pa_log_info("evdev driver version %i.%i.%i", version >> 16, (version >> 8) & 0xff, version & 0xff); - if(ioctl(u->fd, EVIOCGID, &input_id)) { + if (ioctl(u->fd, EVIOCGID, &input_id)) { pa_log("EVIOCGID failed: %s", pa_cstrerror(errno)); goto fail; } @@ -208,7 +212,7 @@ int pa__init(pa_module*m) { input_id.vendor, input_id.product, input_id.version, input_id.bustype); memset(name, 0, sizeof(name)); - if(ioctl(u->fd, EVIOCGNAME(sizeof(name)), name) < 0) { + if (ioctl(u->fd, EVIOCGNAME(sizeof(name)), name) < 0) { pa_log("EVIOCGNAME failed: %s", pa_cstrerror(errno)); goto fail; }