[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.13-314-ga65c2c7

Lennart Poettering gitmailer-noreply at 0pointer.de
Mon Jan 19 18:25:35 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  d5e895d5cbf9a9a658c66347cb034f1c97133280 (commit)

- Log -----------------------------------------------------------------
a65c2c7... add client API for querying card information
85bc5eb... dump active profile
7aa7a7b... fix destruction when no profiles are defined
9368623... don't divide by zero if no left resp. no right channels are defined
67fcc76... fix profile names to include input/output specifier
b23efc0... add missing eof checks
47a2f9e... Merge commit 'flameeyes/buildfixes-2'
bc41fdb... Include the alsa/ subdirectory for modules in the search path.
bd70e80... Allow to opt-out from building tests.
-----------------------------------------------------------------------

Summary of changes:
 configure.ac                        |    6 +
 src/Makefile.am                     |   14 ++-
 src/map-file                        |    5 +
 src/modules/alsa/module-alsa-card.c |    5 +-
 src/pulse/context.c                 |    3 +-
 src/pulse/introspect.c              |  200 ++++++++++++++++++++++++++++++++++-
 src/pulse/introspect.h              |   48 ++++++++-
 src/pulse/volume.c                  |   11 ++-
 src/pulsecore/card.c                |    8 +-
 src/pulsecore/cli-text.c            |    5 +
 src/pulsecore/native-common.h       |    5 +
 src/pulsecore/protocol-native.c     |   47 ++++++++-
 src/utils/pactl.c                   |   48 ++++++++-
 13 files changed, 388 insertions(+), 17 deletions(-)

-----------------------------------------------------------------------

commit bd70e8053165bdee620356cdff02c3979d7138e7
Author: Diego E. 'Flameeyes' Pettenò <flameeyes at gmail.com>
Date:   Tue Jan 20 00:55:39 2009 +0100

    Allow to opt-out from building tests.
    
    Since the tests are only useful either if you're hacking at pulseaudio as
    a developer, or when running "make check", allow users to opt-out from
    their build.
    
    This for instance allows for Gentoo users not to build the tests when
    installing the ebuild with tests disabled, and also allow for skipping over
    eventually broken tests when trying to get the basic build going on a port.

diff --git a/configure.ac b/configure.ac
index 8586dcd..411a14d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,6 +101,12 @@ for flag in $DESIRED_FLAGS ; do
   CC_CHECK_CFLAGS([$flag], [CFLAGS="$CFLAGS $flag"])
 done
 
+dnl Check whether to build tests by default (as compile-test) or not
+AC_ARG_ENABLE([default-build-tests],
+    AS_HELP_STRING([--disable-default-build-tests], [Build test programs only during make check]))
+
+AM_CONDITIONAL([BUILD_TESTS_DEFAULT], [test "x$enable_default_build_tests" = "xno"])
+
 # Native atomic operation support
 AC_ARG_ENABLE([atomic-arm-linux-helpers],
     AS_HELP_STRING([--disable-atomic-arm-linux-helpers],[use inline asm or libatomic_ops instead]),
diff --git a/src/Makefile.am b/src/Makefile.am
index e8f0a82..fbe9e91 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -253,7 +253,7 @@ TESTS = \
 		lock-autospawn-test \
 		prioq-test
 
-noinst_PROGRAMS = \
+TESTS_BINARIES = \
 		mainloop-test \
 		mcalign-test \
 		pacat-simple \
@@ -293,7 +293,7 @@ if HAVE_SIGXCPU
 #TESTS += \
 #		cpulimit-test \
 #		cpulimit-test2
-noinst_PROGRAMS += \
+TESTS_BINARIES += \
 		cpulimit-test \
 		cpulimit-test2
 endif
@@ -301,10 +301,16 @@ endif
 if HAVE_GLIB20
 TESTS += \
 		mainloop-test-glib
-noinst_PROGRAMS += \
+TESTS_BINARIES += \
 		mainloop-test-glib
 endif
 
+if BUILD_TESTS_DEFAULT
+noinst_PROGRAMS = $(TESTS_BINARIES)
+else
+check_PROGRAMS = $(TESTS_BINARIES)
+endif
+
 mainloop_test_SOURCES = tests/mainloop-test.c
 mainloop_test_CFLAGS = $(AM_CFLAGS)
 mainloop_test_LDADD = $(AM_LDADD) libpulse.la

commit bc41fdb20d04ad7f42d5ff28f32a9b3ff3ca52f3
Author: Diego E. 'Flameeyes' Pettenò <flameeyes at gmail.com>
Date:   Tue Jan 20 00:55:42 2009 +0100

    Include the alsa/ subdirectory for modules in the search path.
    
    Without this, out of tree builds fails.

diff --git a/src/Makefile.am b/src/Makefile.am
index fbe9e91..17e14be 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,8 @@ AM_CFLAGS = \
 	-I$(top_builddir)/src/modules/gconf \
 	-I$(top_srcdir)/src/modules/bluetooth \
 	-I$(top_builddir)/src/modules/bluetooth \
+	-I$(top_srcdir)/src/modules/alsa \
+	-I$(top_builddir)/src/modules/alsa \
 	-I$(top_srcdir)/src/modules/raop \
 	$(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS \
 	$(LTDLINCL) \

commit 47a2f9e3da9a66a308f311340410640f2f4cb28f
Merge: d5e895d... bc41fdb...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 00:55:36 2009 +0100

    Merge commit 'flameeyes/buildfixes-2'


commit b23efc0a4d409792c49110d01377f4d76f3aef25
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 02:15:43 2009 +0100

    add missing eof checks

diff --git a/src/pulse/context.c b/src/pulse/context.c
index 3145d9c..d41e62e 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -366,7 +366,8 @@ int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa
     if (command == PA_COMMAND_ERROR) {
         pa_assert(t);
 
-        if (pa_tagstruct_getu32(t, &err) < 0) {
+        if (pa_tagstruct_getu32(t, &err) < 0 ||
+            !pa_tagstruct_eof(t)) {
             pa_context_fail(c, PA_ERR_PROTOCOL);
             return -1;
         }
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index a49d5df..f1735a7 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2484,7 +2484,9 @@ static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uin
 
     p = pa_proplist_new();
 
-    if (c->version >= 13 && pa_tagstruct_get_proplist(t, p) < 0) {
+    if ((c->version >= 13 && pa_tagstruct_get_proplist(t, p) < 0) ||
+        !pa_tagstruct_eof(t)) {
+
         protocol_error(c);
         pa_proplist_free(p);
         return;

commit 67fcc760930960b5f7494287ce3ad422de31f99c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 03:23:32 2009 +0100

    fix profile names to include input/output specifier

diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 2cc8a15..1e3c0c1 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -90,14 +90,15 @@ static void enumerate_cb(
     struct profile_data *d;
 
     if (sink && source) {
-        n = pa_sprintf_malloc("%s+%s", sink->name, source->name);
+        n = pa_sprintf_malloc("output-%s+input-%s", sink->name, source->name);
         t = pa_sprintf_malloc("Output %s + Input %s", sink->description, source->description);
     } else if (sink) {
-        n = pa_xstrdup(sink->name);
+        n = pa_sprintf_malloc("output-%s", sink->name);
         t = pa_sprintf_malloc("Output %s", sink->description);
     } else {
         pa_assert(source);
         n = pa_xstrdup(source->name);
+        n = pa_sprintf_malloc("input-%s", source->name);
         t = pa_sprintf_malloc("Input %s", source->description);
     }
 

commit 936862362c30c22f42f33bd717b5f915f9c04657
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 03:24:11 2009 +0100

    don't divide by zero if no left resp. no right channels are defined

diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 9191a07..10a44da 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -424,8 +424,15 @@ static void get_avg_lr(const pa_channel_map *map, const pa_cvolume *v, pa_volume
         }
     }
 
-    *l = left / n_left;
-    *r = right / n_right;
+    if (n_left <= 0)
+        *l = PA_VOLUME_NORM;
+    else
+        *l = left / n_left;
+
+    if (n_right <= 0)
+        *r = PA_VOLUME_NORM;
+    else
+        *r = right / n_right;
 }
 
 float pa_cvolume_get_balance(const pa_channel_map *map, const pa_cvolume *v) {

commit 7aa7a7b6ac39371bbc7cd46ddf5d50ffd6e2a965
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 03:24:40 2009 +0100

    fix destruction when no profiles are defined

diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index ec4a50c..8e29f0a 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -165,10 +165,12 @@ void pa_card_free(pa_card *c) {
     pa_assert(pa_idxset_isempty(c->sources));
     pa_idxset_free(c->sources, NULL, NULL);
 
-    while ((profile = pa_hashmap_steal_first(c->profiles)))
-        pa_card_profile_free(profile);
+    if (c->profiles) {
+        while ((profile = pa_hashmap_steal_first(c->profiles)))
+            pa_card_profile_free(profile);
 
-    pa_hashmap_free(c->profiles, NULL, NULL);
+        pa_hashmap_free(c->profiles, NULL, NULL);
+    }
 
     pa_proplist_free(c->proplist);
     pa_xfree(c->driver);

commit 85bc5eb39aa19d0b6fab26d388415a3c066043f0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 03:24:59 2009 +0100

    dump active profile

diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c
index b97c870..f52968d 100644
--- a/src/pulsecore/cli-text.c
+++ b/src/pulsecore/cli-text.c
@@ -145,6 +145,11 @@ char *pa_card_list_to_string(pa_core *c) {
                 pa_strbuf_printf(s, "\t\t%s: %s\n", p->name, p->description);
         }
 
+        if (card->active_profile)
+            pa_strbuf_printf(
+                    s,
+                    "\tactive profile: <%s>\n",
+                    card->active_profile->name);
     }
 
     return pa_strbuf_tostring_free(s);

commit a65c2c73369e6b2ce9350dfb542f5d529de38334
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 20 03:25:29 2009 +0100

    add client API for querying card information

diff --git a/src/map-file b/src/map-file
index 9c9e1c7..042e2ad 100644
--- a/src/map-file
+++ b/src/map-file
@@ -30,6 +30,9 @@ pa_context_exit_daemon;
 pa_context_get_autoload_info_by_index;
 pa_context_get_autoload_info_by_name;
 pa_context_get_autoload_info_list;
+pa_context_get_card_info_by_index;
+pa_context_get_card_info_by_name;
+pa_context_get_card_info_list;
 pa_context_get_client_info;
 pa_context_get_client_info_list;
 pa_context_get_index;
@@ -73,6 +76,8 @@ pa_context_ref;
 pa_context_remove_autoload_by_index;
 pa_context_remove_autoload_by_name;
 pa_context_remove_sample;
+pa_context_set_card_profile_by_index;
+pa_context_set_card_profile_by_name;
 pa_context_set_default_sink;
 pa_context_set_default_source;
 pa_context_set_name;
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c
index a6a228e..c5c9678 100644
--- a/src/pulse/introspect.c
+++ b/src/pulse/introspect.c
@@ -28,8 +28,10 @@
 
 #include <pulse/context.h>
 #include <pulse/gccmacro.h>
+#include <pulse/xmalloc.h>
 
 #include <pulsecore/macro.h>
+#include <pulsecore/core-util.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
@@ -60,7 +62,8 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t t
                pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
                pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
                pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
-               pa_tagstruct_getu32(t, &i.scache_size) < 0) {
+               pa_tagstruct_getu32(t, &i.scache_size) < 0 ||
+               !pa_tagstruct_eof(t)) {
         pa_context_fail(o->context, PA_ERR_PROTOCOL);
         goto finish;
     }
@@ -467,6 +470,201 @@ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t
     return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_cb_t) cb, userdata);
 }
 
+/*** Card info ***/
+
+static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_operation *o = userdata;
+    int eol = 1;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+        eol = -1;
+    } else {
+
+        while (!pa_tagstruct_eof(t)) {
+            pa_card_info i;
+            uint32_t j;
+            const char*ap;
+
+            memset(&i, 0, sizeof(i));
+
+            if (pa_tagstruct_getu32(t, &i.index) < 0 ||
+                pa_tagstruct_gets(t, &i.name) < 0 ||
+                pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
+                pa_tagstruct_gets(t, &i.driver) < 0 ||
+                pa_tagstruct_getu32(t, &i.n_profiles) < 0) {
+
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                goto finish;
+            }
+
+            if (i.n_profiles > 0) {
+                i.profiles = pa_xnew(pa_card_profile_info, i.n_profiles+1);
+
+                for (j = 0; j < i.n_profiles; j++) {
+
+                    if (pa_tagstruct_gets(t, &i.profiles[j].name) < 0 ||
+                        pa_tagstruct_gets(t, &i.profiles[j].description) < 0) {
+
+                        pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                        pa_xfree(i.profiles);
+                        goto finish;
+                    }
+                }
+
+                /* Terminate with an extra NULL entry, just to make sure */
+                i.profiles[j].name = NULL;
+                i.profiles[j].description = NULL;
+            }
+
+            i.proplist = pa_proplist_new();
+
+            if (pa_tagstruct_gets(t, &ap) < 0 ||
+                pa_tagstruct_get_proplist(t, i.proplist) < 0) {
+
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_xfree(i.profiles);
+                pa_proplist_free(i.proplist);
+                goto finish;
+            }
+
+            if (ap) {
+                for (j = 0; j < i.n_profiles; j++)
+                    if (pa_streq(i.profiles[j].name, ap)) {
+                        i.active_profile = &i.profiles[j];
+                        break;
+                    }
+            }
+
+            if (o->callback) {
+                pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
+                cb(o->context, &i, 0, o->userdata);
+            }
+
+            pa_proplist_free(i.proplist);
+            pa_xfree(i.profiles);
+        }
+    }
+
+    if (o->callback) {
+        pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
+        cb(o->context, NULL, eol, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata) {
+    pa_tagstruct *t;
+    pa_operation *o;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert(cb);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_puts(t, NULL);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_card_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char*name, pa_card_info_cb_t cb, void *userdata) {
+    pa_tagstruct *t;
+    pa_operation *o;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert(cb);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, name);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_card_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata) {
+    return pa_context_send_simple_command(c, PA_COMMAND_GET_CARD_INFO_LIST, context_get_card_info_callback, (pa_operation_cb_t) cb, userdata);
+}
+
+pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char*profile, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_puts(t, NULL);
+    pa_tagstruct_puts(t, profile);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char *name, const char*profile, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, name);
+    pa_tagstruct_puts(t, profile);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
 /*** Module info ***/
 
 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h
index 07318c7..972b454 100644
--- a/src/pulse/introspect.h
+++ b/src/pulse/introspect.h
@@ -222,7 +222,7 @@ typedef void (*pa_sink_info_cb_t)(pa_context *c, const pa_sink_info *i, int eol,
 pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata);
 
 /** Get information about a sink by its index */
-pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t id, pa_sink_info_cb_t cb, void *userdata);
+pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata);
 
 /** Get the complete sink list */
 pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata);
@@ -279,7 +279,7 @@ typedef void (*pa_source_info_cb_t)(pa_context *c, const pa_source_info *i, int
 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata);
 
 /** Get information about a source by its index */
-pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t id, pa_source_info_cb_t cb, void *userdata);
+pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata);
 
 /** Get the complete source list */
 pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata);
@@ -385,6 +385,50 @@ pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_suc
 
 /** @} */
 
+/** @{ \name Cards */
+
+/** Stores information about a specific profile of a card.  Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release. \since 0.9.15 */
+typedef struct pa_card_profile_info {
+    const char *name;                   /**< Name of this profile */
+    const char *description;            /**< Description of this profile */
+} pa_card_profile_info;
+
+/** Stores information about cards. Please note that this structure
+ * can be extended as part of evolutionary API updates at any time in
+ * any new release.  \since 0.9.15 */
+typedef struct pa_card_info {
+    uint32_t index;                      /**< Index of this card */
+    const char *name;                    /**< Name of this card */
+    uint32_t owner_module;               /**< Index of the owning module, or PA_INVALID_INDEX */
+    const char *driver;                  /**< Driver name */
+    uint32_t n_profiles;                 /**< Number of entries in profile array */
+    pa_card_profile_info* profiles;      /**< Array of available profile, or NULL. Array is terminated by an entry with name set to NULL. Number of entries is stored in n_profiles */
+    pa_card_profile_info* active_profile; /**< Pointer to active profile in the array, or NULL */
+    pa_proplist *proplist;               /**< Property list */
+} pa_card_info;
+
+/** Callback prototype for pa_context_get_card_info() and firends \since 0.9.15 */
+typedef void (*pa_card_info_cb_t) (pa_context *c, const pa_card_info*i, int eol, void *userdata);
+
+/** Get information about a card by its index \since 0.9.15 */
+pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata);
+
+/** Get information about a card by its name \since 0.9.15 */
+pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char *name, pa_card_info_cb_t cb, void *userdata);
+
+/** Get the complete card list \since 0.9.15 */
+pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata);
+
+/** Change the profile of a card. \since 0.9.15 */
+pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char*profile, pa_context_success_cb_t cb, void *userdata);
+
+/** Change the profile of a card. \since 0.9.15 */
+pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char*name, const char*profile, pa_context_success_cb_t cb, void *userdata);
+
+/** @} */
+
 /** @{ \name Sink Inputs */
 
 /** Stores information about sink inputs. Please note that this structure
diff --git a/src/pulsecore/native-common.h b/src/pulsecore/native-common.h
index 11643a7..b31a5da 100644
--- a/src/pulsecore/native-common.h
+++ b/src/pulsecore/native-common.h
@@ -152,6 +152,11 @@ enum {
     /* Supported since protocol v14 (0.9.12) */
     PA_COMMAND_EXTENSION,
 
+    /* Supported since protocol v15 (0.9.15*/
+    PA_COMMAND_GET_CARD_INFO,
+    PA_COMMAND_GET_CARD_INFO_LIST,
+    PA_COMMAND_SET_CARD_PROFILE,
+
     PA_COMMAND_MAX
 };
 
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index f1735a7..87cf583 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -283,6 +283,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_GET_SINK_INFO] = command_get_info,
     [PA_COMMAND_GET_SOURCE_INFO] = command_get_info,
     [PA_COMMAND_GET_CLIENT_INFO] = command_get_info,
+    [PA_COMMAND_GET_CARD_INFO] = command_get_info,
     [PA_COMMAND_GET_MODULE_INFO] = command_get_info,
     [PA_COMMAND_GET_SINK_INPUT_INFO] = command_get_info,
     [PA_COMMAND_GET_SOURCE_OUTPUT_INFO] = command_get_info,
@@ -291,6 +292,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_GET_SOURCE_INFO_LIST] = command_get_info_list,
     [PA_COMMAND_GET_MODULE_INFO_LIST] = command_get_info_list,
     [PA_COMMAND_GET_CLIENT_INFO_LIST] = command_get_info_list,
+    [PA_COMMAND_GET_CARD_INFO_LIST] = command_get_info_list,
     [PA_COMMAND_GET_SINK_INPUT_INFO_LIST] = command_get_info_list,
     [PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST] = command_get_info_list,
     [PA_COMMAND_GET_SAMPLE_INFO_LIST] = command_get_info_list,
@@ -2740,6 +2742,31 @@ static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_c
         pa_tagstruct_put_proplist(t, client->proplist);
 }
 
+static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_card *card) {
+    void *state = NULL;
+    pa_card_profile *p;
+
+    pa_assert(t);
+    pa_assert(card);
+
+    pa_tagstruct_putu32(t, card->index);
+    pa_tagstruct_puts(t, card->name);
+    pa_tagstruct_putu32(t, card->module ? card->module->index : PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, card->driver);
+
+    pa_tagstruct_putu32(t, card->profiles ? pa_hashmap_size(card->profiles) : 0);
+
+    if (card->profiles) {
+        while ((p = pa_hashmap_iterate(card->profiles, &state, NULL))) {
+            pa_tagstruct_puts(t, p->name);
+            pa_tagstruct_puts(t, p->description);
+        }
+    }
+
+    pa_tagstruct_puts(t, card->active_profile ? card->active_profile->name : NULL);
+    pa_tagstruct_put_proplist(t, card->proplist);
+}
+
 static void module_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_module *module) {
     pa_assert(t);
     pa_assert(module);
@@ -2839,6 +2866,8 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
     pa_sink *sink = NULL;
     pa_source *source = NULL;
     pa_client *client = NULL;
+    pa_card *card = NULL;
+    pa_core *core = NULL;
     pa_module *module = NULL;
     pa_sink_input *si = NULL;
     pa_source_output *so = NULL;
@@ -2851,6 +2880,7 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
 
     if (pa_tagstruct_getu32(t, &idx) < 0 ||
         (command != PA_COMMAND_GET_CLIENT_INFO &&
+         command != PA_COMMAND_GET_CARD_INFO &&
          command != PA_COMMAND_GET_MODULE_INFO &&
          command != PA_COMMAND_GET_SINK_INPUT_INFO &&
          command != PA_COMMAND_GET_SOURCE_OUTPUT_INFO &&
@@ -2876,6 +2906,11 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
             source = pa_idxset_get_by_index(c->protocol->core->sources, idx);
         else
             source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE);
+    } else if (command == PA_COMMAND_GET_CARD_INFO) {
+        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);
     } else if (command == PA_COMMAND_GET_CLIENT_INFO)
         client = pa_idxset_get_by_index(c->protocol->core->clients, idx);
     else if (command == PA_COMMAND_GET_MODULE_INFO)
@@ -2892,7 +2927,7 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
             sce = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SAMPLE);
     }
 
-    if (!sink && !source && !client && !module && !si && !so && !sce) {
+    if (!sink && !source && !client && !card && !module && !si && !so && !sce) {
         pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
         return;
     }
@@ -2904,6 +2939,8 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
         source_fill_tagstruct(c, reply, source);
     else if (client)
         client_fill_tagstruct(c, reply, client);
+    else if (client)
+        card_fill_tagstruct(c, reply, card);
     else if (module)
         module_fill_tagstruct(c, reply, module);
     else if (si)
@@ -2940,6 +2977,8 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
         i = c->protocol->core->sources;
     else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
         i = c->protocol->core->clients;
+    else if (command == PA_COMMAND_GET_CARD_INFO_LIST)
+        i = c->protocol->core->cards;
     else if (command == PA_COMMAND_GET_MODULE_INFO_LIST)
         i = c->protocol->core->modules;
     else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST)
@@ -2959,6 +2998,8 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
                 source_fill_tagstruct(c, reply, p);
             else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
                 client_fill_tagstruct(c, reply, p);
+            else if (command == PA_COMMAND_GET_CARD_INFO_LIST)
+                card_fill_tagstruct(c, reply, p);
             else if (command == PA_COMMAND_GET_MODULE_INFO_LIST)
                 module_fill_tagstruct(c, reply, p);
             else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST)
diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index dbc9ba7..75b46d2 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -384,6 +384,51 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int
     pa_xfree(pl);
 }
 
+static void get_card_info_callback(pa_context *c, const pa_card_info *i, int is_last, void *userdata) {
+    char t[32];
+    char *pl;
+
+    if (is_last < 0) {
+        fprintf(stderr, _("Failed to get card information: %s\n"), pa_strerror(pa_context_errno(c)));
+        complete_action();
+        return;
+    }
+
+    if (is_last) {
+        complete_action();
+        return;
+    }
+
+    assert(i);
+
+    if (nl)
+        printf("\n");
+    nl = 1;
+
+    snprintf(t, sizeof(t), "%u", i->owner_module);
+
+    printf(_("Card #%u\n"
+             "\tName: %s\n"
+             "\tDriver: %s\n"
+             "\tOwner Module: %s\n"
+             "\tProperties:\n\t\t%s\n"),
+           i->index,
+           i->name,
+           pa_strnull(i->driver),
+           i->owner_module != PA_INVALID_INDEX ? t : _("n/a"),
+           pl = pa_proplist_to_string_sep(i->proplist, "\n\t\t"));
+
+    if (i->profiles) {
+        pa_card_profile_info *p;
+
+        printf(_("\tProfiles:\n"));
+        for (p = i->profiles; p->name; p++)
+            printf("\t\t%s: %s\n", p->name, p->description);
+    }
+
+    pa_xfree(pl);
+}
+
 static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, int is_last, void *userdata) {
     char t[32], k[32], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
     char *pl;
@@ -649,7 +694,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
                     break;
 
                 case LIST:
-                    actions = 7;
+                    actions = 8;
                     pa_operation_unref(pa_context_get_module_info_list(c, get_module_info_callback, NULL));
                     pa_operation_unref(pa_context_get_sink_info_list(c, get_sink_info_callback, NULL));
                     pa_operation_unref(pa_context_get_source_info_list(c, get_source_info_callback, NULL));
@@ -657,6 +702,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
                     pa_operation_unref(pa_context_get_source_output_info_list(c, get_source_output_info_callback, NULL));
                     pa_operation_unref(pa_context_get_client_info_list(c, get_client_info_callback, NULL));
                     pa_operation_unref(pa_context_get_sample_info_list(c, get_sample_info_callback, NULL));
+                    pa_operation_unref(pa_context_get_card_info_list(c, get_card_info_callback, NULL));
                     break;
 
                 case MOVE_SINK_INPUT:

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list