[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.13-336-g601293d
Lennart Poettering
gitmailer-noreply at 0pointer.de
Tue Jan 20 18:04:29 PST 2009
This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.
The master branch has been updated
from e8f93b125e0e0776024ae78a2bdd33daf4442326 (commit)
- Log -----------------------------------------------------------------
601293d... implement pactl set-card-profile
996bba7... implement PA_COMMAND_SET_CARD_PROFILE
1375a9a... enable module-card-restore by default
13315a7... add a card profile restore module
c512ebf... minor cleanups
10e5c70... don't restore mute/volume when already set
9661cd0... make pa_card_new_data::active_profile a string
-----------------------------------------------------------------------
Summary of changes:
src/Makefile.am | 8 +
src/daemon/default.pa.in | 1 +
src/modules/module-card-restore.c | 284 +++++++++++++++++++++++++++++++++++
src/modules/module-device-restore.c | 37 ++++--
src/modules/module-stream-restore.c | 6 +-
src/pulsecore/card.c | 34 +++--
src/pulsecore/card.h | 3 +-
src/pulsecore/protocol-native.c | 40 +++++
src/utils/pactl.c | 57 +++++---
9 files changed, 427 insertions(+), 43 deletions(-)
create mode 100644 src/modules/module-card-restore.c
-----------------------------------------------------------------------
commit 9661cd04442e88fa500654a4b7ccea68ede2e123
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 02:46:36 2009 +0100
make pa_card_new_data::active_profile a string
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index af2a178..397c6d7 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -76,6 +76,13 @@ void pa_card_new_data_set_name(pa_card_new_data *data, const char *name) {
data->name = pa_xstrdup(name);
}
+void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile) {
+ pa_assert(data);
+
+ pa_xfree(data->active_profile);
+ data->active_profile = pa_xstrdup(profile);
+}
+
void pa_card_new_data_done(pa_card_new_data *data) {
pa_assert(data);
@@ -92,6 +99,7 @@ void pa_card_new_data_done(pa_card_new_data *data) {
}
pa_xfree(data->name);
+ pa_xfree(data->active_profile);
}
pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
@@ -126,21 +134,27 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
c->sinks = pa_idxset_new(NULL, NULL);
c->sources = pa_idxset_new(NULL, NULL);
+ /* As a minor optimization we just steal the list instead of
+ * copying it here */
c->profiles = data->profiles;
data->profiles = NULL;
- if (!(c->active_profile = data->active_profile))
- if (c->profiles) {
- void *state = NULL;
- pa_card_profile *p;
- while ((p = pa_hashmap_iterate(c->profiles, &state, NULL))) {
- if (!c->active_profile ||
- p->priority > c->active_profile->priority)
+ c->active_profile = NULL;
- c->active_profile = p;
- }
+ if (data->active_profile && c->profiles)
+ c->active_profile = pa_hashmap_get(c->profiles, data->active_profile);
+
+ if (!c->active_profile && c->profiles) {
+ void *state = NULL;
+ pa_card_profile *p;
+
+ while ((p = pa_hashmap_iterate(c->profiles, &state, NULL))) {
+ if (!c->active_profile ||
+ p->priority > c->active_profile->priority)
+
+ c->active_profile = p;
}
- data->active_profile = NULL;
+ }
c->userdata = NULL;
c->set_profile = NULL;
diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h
index 17733c5..9aa8f37 100644
--- a/src/pulsecore/card.h
+++ b/src/pulsecore/card.h
@@ -77,7 +77,7 @@ typedef struct pa_card_new_data {
pa_module *module;
pa_hashmap *profiles;
- pa_card_profile *active_profile;
+ char *active_profile;
pa_bool_t namereg_fail:1;
} pa_card_new_data;
@@ -87,6 +87,7 @@ void pa_card_profile_free(pa_card_profile *c);
pa_card_new_data *pa_card_new_data_init(pa_card_new_data *data);
void pa_card_new_data_set_name(pa_card_new_data *data, const char *name);
+void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile);
void pa_card_new_data_done(pa_card_new_data *data);
pa_card *pa_card_new(pa_core *c, pa_card_new_data *data);
commit 10e5c70286c05afc1a80209a81acad83c59a8961
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 02:47:26 2009 +0100
don't restore mute/volume when already set
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index c0cb0dc..a24c0b3 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -98,14 +98,14 @@ static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct
pa_log_info("Synced.");
}
-static struct entry* read_entry(struct userdata *u, char *name) {
+static struct entry* read_entry(struct userdata *u, const char *name) {
datum key, data;
struct entry *e;
pa_assert(u);
pa_assert(name);
- key.dptr = name;
+ key.dptr = (char*) name;
key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@@ -235,13 +235,22 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *
if ((e = read_entry(u, name))) {
if (u->restore_volume) {
- pa_log_info("Restoring volume for sink %s.", new_data->name);
- pa_sink_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+
+ if (!new_data->volume_is_set) {
+ pa_log_info("Restoring volume for sink %s.", new_data->name);
+ pa_sink_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+ } else
+ pa_log_debug("Not restoring volume for sink %s, because already set.", new_data->name);
+
}
if (u->restore_muted) {
- pa_log_info("Restoring mute state for sink %s.", new_data->name);
- pa_sink_new_data_set_muted(new_data, e->muted);
+
+ if (!new_data->muted_is_set) {
+ pa_log_info("Restoring mute state for sink %s.", new_data->name);
+ pa_sink_new_data_set_muted(new_data, e->muted);
+ } else
+ pa_log_debug("Not restoring mute state for sink %s, because already set.", new_data->name);
}
pa_xfree(e);
@@ -263,13 +272,21 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
if ((e = read_entry(u, name))) {
if (u->restore_volume) {
- pa_log_info("Restoring volume for source %s.", new_data->name);
- pa_source_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+
+ if (!new_data->volume_is_set) {
+ pa_log_info("Restoring volume for source %s.", new_data->name);
+ pa_source_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+ } else
+ pa_log_debug("Not restoring volume for source %s, because already set.", new_data->name);
}
if (u->restore_muted) {
- pa_log_info("Restoring mute state for source %s.", new_data->name);
- pa_source_new_data_set_muted(new_data, e->muted);
+
+ if (!new_data->muted_is_set) {
+ pa_log_info("Restoring mute state for source %s.", new_data->name);
+ pa_source_new_data_set_muted(new_data, e->muted);
+ } else
+ pa_log_debug("Not restoring mute state for source %s, because already set.", new_data->name);
}
pa_xfree(e);
commit c512ebf4ab2b6363b810eb592dec7386ed144c4b
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 02:47:49 2009 +0100
minor cleanups
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index dd54a79..734b2c5 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -137,14 +137,14 @@ static char *get_name(pa_proplist *p, const char *prefix) {
return pa_sprintf_malloc("%s-fallback:%s", prefix, r);
}
-static struct entry* read_entry(struct userdata *u, char *name) {
+static struct entry* read_entry(struct userdata *u, const char *name) {
datum key, data;
struct entry *e;
pa_assert(u);
pa_assert(name);
- key.dptr = name;
+ key.dptr = (char*) name;
key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@@ -266,7 +266,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) &&
!old->muted == !entry.muted &&
- strcmp(old->device, entry.device) == 0) {
+ strncmp(old->device, entry.device, sizeof(entry.device)) == 0) {
pa_xfree(old);
pa_xfree(name);
commit 13315a7e4c58f63e5f03b1aec13d0e79a8ee86af
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 02:49:42 2009 +0100
add a card profile restore module
diff --git a/src/Makefile.am b/src/Makefile.am
index 3151b49..8d1271c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -865,6 +865,7 @@ modlibexec_LTLIBRARIES += \
module-volume-restore.la \
module-device-restore.la \
module-stream-restore.la \
+ module-card-restore.la \
module-default-device-restore.la \
module-always-sink.la \
module-rescue-streams.la \
@@ -1064,6 +1065,7 @@ SYMDEF_FILES = \
modules/module-volume-restore-symdef.h \
modules/module-device-restore-symdef.h \
modules/module-stream-restore-symdef.h \
+ modules/module-card-restore-symdef.h \
modules/module-default-device-restore-symdef.h \
modules/module-always-sink-symdef.h \
modules/module-rescue-streams-symdef.h \
@@ -1343,6 +1345,12 @@ module_stream_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
module_stream_restore_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libpulsecore- at PA_MAJORMINORMICRO@.la -lgdbm libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
module_stream_restore_la_CFLAGS = $(AM_CFLAGS)
+# Card profile restore module
+module_card_restore_la_SOURCES = modules/module-card-restore.c
+module_card_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_card_restore_la_LIBADD = $(AM_LIBADD) libpulsecore- at PA_MAJORMINORMICRO@.la -lgdbm libpulsecommon- at PA_MAJORMINORMICRO@.la libpulse.la
+module_card_restore_la_CFLAGS = $(AM_CFLAGS)
+
# Default sink/source restore module
module_default_device_restore_la_SOURCES = modules/module-default-device-restore.c
module_default_device_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
new file mode 100644
index 0000000..02e973c
--- /dev/null
+++ b/src/modules/module-card-restore.c
@@ -0,0 +1,284 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2006-2008 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,
+ 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
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <gdbm.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/volume.h>
+#include <pulse/timeval.h>
+#include <pulse/util.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-subscribe.h>
+#include <pulsecore/card.h>
+#include <pulsecore/namereg.h>
+
+#include "module-card-restore-symdef.h"
+
+PA_MODULE_AUTHOR("Lennart Poettering");
+PA_MODULE_DESCRIPTION("Automatically restore profile of cards");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+#define SAVE_INTERVAL 10
+
+static const char* const valid_modargs[] = {
+ NULL
+};
+
+struct userdata {
+ pa_core *core;
+ pa_module *module;
+ pa_subscription *subscription;
+ pa_hook_slot *card_new_hook_slot;
+ pa_time_event *save_time_event;
+ GDBM_FILE gdbm_file;
+};
+
+struct entry {
+ char profile[PA_NAME_MAX];
+};
+
+static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
+ struct userdata *u = userdata;
+
+ pa_assert(a);
+ pa_assert(e);
+ pa_assert(tv);
+ pa_assert(u);
+
+ pa_assert(e == u->save_time_event);
+ u->core->mainloop->time_free(u->save_time_event);
+ u->save_time_event = NULL;
+
+ gdbm_sync(u->gdbm_file);
+ pa_log_info("Synced.");
+}
+
+static struct entry* read_entry(struct userdata *u, const char *name) {
+ datum key, data;
+ struct entry *e;
+
+ pa_assert(u);
+ pa_assert(name);
+
+ key.dptr = (char*) name;
+ key.dsize = (int) strlen(name);
+
+ data = gdbm_fetch(u->gdbm_file, key);
+
+ if (!data.dptr)
+ goto fail;
+
+ if (data.dsize != sizeof(struct entry)) {
+ pa_log_warn("Database contains entry for card %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
+ goto fail;
+ }
+
+ e = (struct entry*) data.dptr;
+
+ if (!memchr(e->profile, 0, sizeof(e->profile))) {
+ pa_log_warn("Database contains entry for card %s with missing NUL byte in profile name", name);
+ goto fail;
+ }
+
+ return e;
+
+fail:
+
+ pa_xfree(data.dptr);
+ return NULL;
+}
+
+static void trigger_save(struct userdata *u) {
+ struct timeval tv;
+
+ if (u->save_time_event)
+ return;
+
+ pa_gettimeofday(&tv);
+ tv.tv_sec += SAVE_INTERVAL;
+ u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
+}
+
+static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+ struct userdata *u = userdata;
+ struct entry entry, *old;
+ datum key, data;
+ pa_card *card;
+
+ pa_assert(c);
+ pa_assert(u);
+
+ if (t != (PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_NEW) &&
+ t != (PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE))
+ return;
+
+ memset(&entry, 0, sizeof(entry));
+
+ if (!(card = pa_idxset_get_by_index(c->cards, idx)))
+ return;
+
+ pa_strlcpy(entry.profile, card->active_profile ? card->active_profile->name : "", sizeof(entry.profile));
+
+ if ((old = read_entry(u, card->name))) {
+
+ if (strncmp(old->profile, entry.profile, sizeof(entry.profile)) == 0) {
+ pa_xfree(old);
+ return;
+ }
+
+ pa_xfree(old);
+ }
+
+ key.dptr = card->name;
+ key.dsize = (int) strlen(card->name);
+
+ data.dptr = (void*) &entry;
+ data.dsize = sizeof(entry);
+
+ pa_log_info("Storing profile for card %s.", card->name);
+
+ gdbm_store(u->gdbm_file, key, data, GDBM_REPLACE);
+
+ trigger_save(u);
+}
+
+static pa_hook_result_t card_new_hook_callback(pa_core *c, pa_card_new_data *new_data, struct userdata *u) {
+ struct entry *e;
+
+ pa_assert(new_data);
+
+ if ((e = read_entry(u, new_data->name)) && e->profile) {
+
+ if (!new_data->active_profile) {
+ pa_card_new_data_set_profile(new_data, e->profile);
+ pa_log_info("Restoring profile for card %s.", new_data->name);
+ } else
+ pa_log_debug("Not restoring profile for card %s, because already set.", new_data->name);
+
+ pa_xfree(e);
+ }
+
+ return PA_HOOK_OK;
+}
+
+int pa__init(pa_module*m) {
+ pa_modargs *ma = NULL;
+ struct userdata *u;
+ char *fname, *fn;
+ pa_card *card;
+ uint32_t idx;
+ int gdbm_cache_size;
+
+ pa_assert(m);
+
+ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+ pa_log("Failed to parse module arguments");
+ goto fail;
+ }
+
+ m->userdata = u = pa_xnew(struct userdata, 1);
+ u->core = m->core;
+ u->module = m;
+ u->save_time_event = NULL;
+ u->gdbm_file = NULL;
+
+ u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_CARD, subscribe_callback, u);
+
+ u->card_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CARD_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) card_new_hook_callback, u);
+
+ /* We include the host identifier in the file name because gdbm
+ * files are CPU dependant, and we don't want things to go wrong
+ * if we are on a multiarch system. */
+
+ fn = pa_sprintf_malloc("card-database."CANONICAL_HOST".gdbm");
+ fname = pa_state_path(fn, TRUE);
+ pa_xfree(fn);
+
+ if (!fname)
+ goto fail;
+
+ if (!(u->gdbm_file = gdbm_open(fname, 0, GDBM_WRCREAT|GDBM_NOLOCK, 0600, NULL))) {
+ pa_log("Failed to open volume database '%s': %s", fname, gdbm_strerror(gdbm_errno));
+ pa_xfree(fname);
+ goto fail;
+ }
+
+ /* By default the cache of gdbm is rather large, let's reduce it a bit to save memory */
+ gdbm_cache_size = 10;
+ gdbm_setopt(u->gdbm_file, GDBM_CACHESIZE, &gdbm_cache_size, sizeof(gdbm_cache_size));
+
+ pa_log_info("Sucessfully opened database file '%s'.", fname);
+ pa_xfree(fname);
+
+ for (card = pa_idxset_first(m->core->cards, &idx); card; card = pa_idxset_next(m->core->cards, &idx))
+ subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_NEW, card->index, u);
+
+ pa_modargs_free(ma);
+ return 0;
+
+fail:
+ pa__done(m);
+
+ if (ma)
+ pa_modargs_free(ma);
+
+ return -1;
+}
+
+void pa__done(pa_module*m) {
+ struct userdata* u;
+
+ pa_assert(m);
+
+ if (!(u = m->userdata))
+ return;
+
+ if (u->subscription)
+ pa_subscription_free(u->subscription);
+
+ if (u->card_new_hook_slot)
+ pa_hook_slot_free(u->card_new_hook_slot);
+
+ if (u->save_time_event)
+ u->core->mainloop->time_free(u->save_time_event);
+
+ if (u->gdbm_file)
+ gdbm_close(u->gdbm_file);
+
+ pa_xfree(u);
+}
commit 1375a9a0c2c7141d7ce9a404fa323dc5c3620a16
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 02:50:29 2009 +0100
enable module-card-restore by default
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 7de4c07..d761f5f 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -32,6 +32,7 @@
### Automatically restore the volume of streams and devices
load-module module-device-restore
load-module module-stream-restore
+load-module module-card-restore
### Load audio drivers statically (it's probably better to not load
### these drivers manually, but instead use module-hal-detect --
commit 996bba7522aa0fa4192103ae53ca1980a6a59a52
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 03:04:04 2009 +0100
implement PA_COMMAND_SET_CARD_PROFILE
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index aa541a8..af9c05b 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -256,6 +256,7 @@ static void command_update_stream_sample_rate(pa_pdispatch *pd, uint32_t command
static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_ERROR] = NULL,
@@ -350,6 +351,8 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST] = command_remove_proplist,
[PA_COMMAND_REMOVE_CLIENT_PROPLIST] = command_remove_proplist,
+ [PA_COMMAND_SET_CARD_PROFILE] = command_set_card_profile,
+
[PA_COMMAND_EXTENSION] = command_extension
};
@@ -3989,6 +3992,43 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,
protocol_error(c);
}
+static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+ pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+ uint32_t idx = PA_INVALID_INDEX;
+ const char *name = NULL, *profile = NULL;
+ pa_card *card = NULL;
+
+ pa_native_connection_assert_ref(c);
+ pa_assert(t);
+
+ if (pa_tagstruct_getu32(t, &idx) < 0 ||
+ pa_tagstruct_gets(t, &name) < 0 ||
+ pa_tagstruct_gets(t, &profile) < 0 ||
+ !pa_tagstruct_eof(t)) {
+ protocol_error(c);
+ return;
+ }
+
+ CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+ CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
+
+ if (idx != PA_INVALID_INDEX)
+ card = pa_idxset_get_by_index(c->protocol->core->cards, idx);
+ else
+ card = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_CARD);
+
+ CHECK_VALIDITY(c->pstream, card, tag, PA_ERR_NOENTITY);
+
+ if (pa_card_set_profile(card, profile) < 0) {
+ pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
+ return;
+ }
+
+ pa_pstream_send_simple_ack(c->pstream, tag);
+}
/*** pstream callbacks ***/
commit 601293d346ef4bfc8f2ff80d6c13a0d66d9bdd57
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 21 03:04:19 2009 +0100
implement pactl set-card-profile
diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index ba91f50..0820641 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -45,7 +45,7 @@
static pa_context *context = NULL;
static pa_mainloop_api *mainloop_api = NULL;
-static char *device = NULL, *sample_name = NULL, *sink_name = NULL, *source_name = NULL, *module_name = NULL, *module_args = NULL;
+static char *device = NULL, *sample_name = NULL, *sink_name = NULL, *source_name = NULL, *module_name = NULL, *module_args = NULL, *card_name = NULL, *profile_name = NULL;
static uint32_t sink_input_idx = PA_INVALID_INDEX, source_output_idx = PA_INVALID_INDEX;
static uint32_t module_index;
static int suspend;
@@ -73,6 +73,7 @@ static enum {
UNLOAD_MODULE,
SUSPEND_SINK,
SUSPEND_SOURCE,
+ SET_CARD_PROFILE
} action = NONE;
static void quit(int ret) {
@@ -739,6 +740,10 @@ static void context_state_callback(pa_context *c, void *userdata) {
pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, suspend, simple_callback, NULL));
break;
+ case SET_CARD_PROFILE:
+ pa_operation_unref(pa_context_set_card_profile_by_name(c, card_name, profile_name, simple_callback, NULL));
+ break;
+
default:
assert(0);
}
@@ -763,22 +768,23 @@ static void exit_signal_callback(pa_mainloop_api *m, pa_signal_event *e, int sig
static void help(const char *argv0) {
printf(_("%s [options] stat\n"
- "%s [options] list\n"
- "%s [options] exit\n"
- "%s [options] upload-sample FILENAME [NAME]\n"
- "%s [options] play-sample NAME [SINK]\n"
- "%s [options] remove-sample NAME\n"
- "%s [options] move-sink-input ID SINK\n"
- "%s [options] move-source-output ID SOURCE\n"
- "%s [options] load-module NAME [ARGS ...]\n"
- "%s [options] unload-module ID\n"
- "%s [options] suspend-sink [SINK] 1|0\n"
- "%s [options] suspend-source [SOURCE] 1|0\n\n"
- " -h, --help Show this help\n"
- " --version Show version\n\n"
- " -s, --server=SERVER The name of the server to connect to\n"
- " -n, --client-name=NAME How to call this client on the server\n"),
- argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0);
+ "%s [options] list\n"
+ "%s [options] exit\n"
+ "%s [options] upload-sample FILENAME [NAME]\n"
+ "%s [options] play-sample NAME [SINK]\n"
+ "%s [options] remove-sample NAME\n"
+ "%s [options] move-sink-input ID SINK\n"
+ "%s [options] move-source-output ID SOURCE\n"
+ "%s [options] load-module NAME [ARGS ...]\n"
+ "%s [options] unload-module ID\n"
+ "%s [options] suspend-sink [SINK] 1|0\n"
+ "%s [options] suspend-source [SOURCE] 1|0\n"
+ "%s [options] set-card-profile [CARD] [PROFILE] \n\n"
+ " -h, --help Show this help\n"
+ " --version Show version\n\n"
+ " -s, --server=SERVER The name of the server to connect to\n"
+ " -n, --client-name=NAME How to call this client on the server\n"),
+ argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0);
}
enum { ARG_VERSION = 256 };
@@ -959,7 +965,7 @@ int main(int argc, char *argv[]) {
action = SUSPEND_SINK;
if (argc > optind+3 || optind+1 >= argc) {
- fprintf(stderr, _("You may not specify more than one sink. You have to specify at least one boolean value.\n"));
+ fprintf(stderr, _("You may not specify more than one sink. You have to specify a boolean value.\n"));
goto quit;
}
@@ -972,7 +978,7 @@ int main(int argc, char *argv[]) {
action = SUSPEND_SOURCE;
if (argc > optind+3 || optind+1 >= argc) {
- fprintf(stderr, _("You may not specify more than one source. You have to specify at least one boolean value.\n"));
+ fprintf(stderr, _("You may not specify more than one source. You have to specify a boolean value.\n"));
goto quit;
}
@@ -980,6 +986,17 @@ int main(int argc, char *argv[]) {
if (argc > optind+2)
source_name = pa_xstrdup(argv[optind+1]);
+ } else if (!strcmp(argv[optind], "set-card-profile")) {
+ action = SET_CARD_PROFILE;
+
+ if (argc != optind+3) {
+ fprintf(stderr, _("You have to specify a card name/index and a profile name\n"));
+ goto quit;
+ }
+
+ card_name = pa_xstrdup(argv[optind+1]);
+ profile_name = pa_xstrdup(argv[optind+2]);
+
} else if (!strcmp(argv[optind], "help")) {
help(bn);
ret = 0;
@@ -1041,6 +1058,8 @@ quit:
pa_xfree(source_name);
pa_xfree(module_args);
pa_xfree(client_name);
+ pa_xfree(card_name);
+ pa_xfree(profile_name);
return ret;
}
--
hooks/post-receive
PulseAudio Sound Server
More information about the pulseaudio-commits
mailing list