void xvd_update_volume (XvdInstance *i, XvdVolStepDirection d) { pa_operation *op = NULL; if (!i || !i->pulse_context) { g_warning ("xvd_update_volume: pulseaudio context is null"); return; } if (pa_context_get_state (i->pulse_context) != PA_CONTEXT_READY) { g_warning ("xvd_update_volume: pulseaudio context isn't ready"); return; } if (i->sink_index == PA_INVALID_INDEX) { g_warning ("xvd_update_volume: undefined sink"); return; } /* backup */ old_volume = i->volume; switch (d) { case XVD_UP: pa_cvolume_inc_clamp (&i->volume, XVD_PA_VOLUME_STEP(i->vol_step), PA_VOLUME_NORM); break; case XVD_DOWN: pa_cvolume_dec (&i->volume, XVD_PA_VOLUME_STEP(i->vol_step)); break; default: g_warning ("xvd_update_volume: invalid direction"); return; break; } op = pa_context_set_sink_volume_by_index (i->pulse_context, i->sink_index, &i->volume, xvd_notify_volume_callback, i); if (!op) { g_warning ("xvd_update_volume: failed"); return; } pa_operation_unref (op); }
void pulseaudio_volume(menu_info_item_t* mii, int inc) { g_debug("pulseaudio_volume(%s, %i)", mii->name, inc); /* increment/decrement in 2% steps */ pa_cvolume* volume; if(inc < 0) volume = pa_cvolume_dec(mii->volume, -inc * PA_VOLUME_NORM / 50); else if(inc > 0) { int volume_max = mii->menu_info->menu_infos->settings.volume_max; if(volume_max > 0) volume = pa_cvolume_inc_clamp(mii->volume, inc * PA_VOLUME_NORM / 50, PA_VOLUME_NORM * volume_max / 100); else volume = pa_cvolume_inc(mii->volume, inc * PA_VOLUME_NORM / 50); } else return; pa_operation* o = NULL; switch(mii->menu_info->type) { case MENU_SERVER: case MENU_MODULE: /* nothing to do here */ break; case MENU_SINK: o = pa_context_set_sink_volume_by_index(context, mii->index, volume, pulseaudio_set_volume_success_cb, mii); break; case MENU_SOURCE: o = pa_context_set_source_volume_by_index(context, mii->index, volume, pulseaudio_set_volume_success_cb, mii); break; case MENU_INPUT: o = pa_context_set_sink_input_volume(context, mii->index, volume, pulseaudio_set_volume_success_cb, mii); break; case MENU_OUTPUT: o = pa_context_set_source_output_volume(context, mii->index, volume, pulseaudio_set_volume_success_cb, mii); break; } if(o) pa_operation_unref(o); }
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; pa_assert(io); pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { 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("lirc_nextcode() failed."); goto fail; } c = pa_xstrdup(code); c[strcspn(c, "\n\r")] = 0; pa_log_debug("Raw IR code '%s'", c); pa_xfree(c); while (lirc_code2char(u->config, code, &name) == 0 && name) { enum { INVALID, UP, DOWN, MUTE, RESET, MUTE_TOGGLE } volchange = INVALID; pa_log_info("Translated IR code '%s'", name); if (strcasecmp(name, "volume-up") == 0) volchange = UP; else if (strcasecmp(name, "volume-down") == 0) volchange = DOWN; else if (strcasecmp(name, "mute") == 0) volchange = MUTE; else if (strcasecmp(name, "mute-toggle") == 0) volchange = MUTE_TOGGLE; else if (strcasecmp(name, "reset") == 0) volchange = RESET; if (volchange == INVALID) 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))) pa_log("Failed to get sink '%s'", u->sink_name); else { pa_cvolume cv = *pa_sink_get_volume(s, FALSE); switch (volchange) { case UP: pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit); pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case DOWN: pa_cvolume_dec(&cv, u->volume_step); pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case MUTE: pa_sink_set_mute(s, TRUE, TRUE); break; case RESET: pa_sink_set_mute(s, FALSE, TRUE); break; case MUTE_TOGGLE: pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE), TRUE); break; case INVALID: pa_assert_not_reached(); } } } } } pa_xfree(code); return; fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; pa_module_unload_request(u->module, TRUE); pa_xfree(code); }
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; pa_assert(io); pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { pa_log("Lost connection to evdev device."); goto fail; } if (events & PA_IO_EVENT_INPUT) { struct input_event ev; if (pa_loop_read(u->fd, &ev, sizeof(ev), &u->fd_type) <= 0) { pa_log("Failed to read from event device: %s", pa_cstrerror(errno)); goto fail; } if (ev.type == EV_KEY && (ev.value == 1 || ev.value == 2)) { 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; } if (volchange != INVALID) { pa_sink *s; 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: pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit); pa_sink_set_volume(s, &cv, true, true); break; case DOWN: 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, false), true); break; case INVALID: pa_assert_not_reached(); } } } } } return; fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; pa_module_unload_request(u->module, true); }