diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/map-file | 5 | ||||
| -rw-r--r-- | src/pulse/introspect.c | 200 | ||||
| -rw-r--r-- | src/pulse/introspect.h | 48 | ||||
| -rw-r--r-- | src/pulsecore/native-common.h | 5 | ||||
| -rw-r--r-- | src/pulsecore/protocol-native.c | 43 | ||||
| -rw-r--r-- | src/utils/pactl.c | 48 | 
6 files changed, 344 insertions, 5 deletions
| diff --git a/src/map-file b/src/map-file index 9c9e1c7c..042e2adb 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 a6a228ec..c5c96784 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 07318c72..972b454c 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 11643a72..b31a5da1 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 f1735a78..87cf5838 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 dbc9ba71..75b46d2d 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: | 
