summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/todo3
-rw-r--r--polyp/autoload.c70
-rw-r--r--polyp/autoload.h9
-rw-r--r--polyp/cli-command.c4
-rw-r--r--polyp/cli-text.c5
-rw-r--r--polyp/core.c2
-rw-r--r--polyp/core.h2
-rw-r--r--polyp/pactl.c3
-rw-r--r--polyp/polyplib-introspect.c77
-rw-r--r--polyp/polyplib-introspect.h18
-rw-r--r--polyp/protocol-native.c54
11 files changed, 204 insertions, 43 deletions
diff --git a/doc/todo b/doc/todo
index fa97b4a3..1ffdee49 100644
--- a/doc/todo
+++ b/doc/todo
@@ -1,6 +1,6 @@
*** $Id$ ***
-*** 0.6 ****
+*** 0.7 ****
- per-channel volume
- unix socket directories include user name
- add sample directory
@@ -9,7 +9,6 @@
- improve module-oss-mmap latency measurement
- filter capture data in client through alignment
- add radio module
-- make autoload list use idxset
- add sync API
- make most buffer sizes dependant on the sample type
diff --git a/polyp/autoload.c b/polyp/autoload.c
index 12cd1f91..d6207962 100644
--- a/polyp/autoload.c
+++ b/polyp/autoload.c
@@ -45,6 +45,14 @@ static void entry_free(struct pa_autoload_entry *e) {
pa_xfree(e);
}
+static void entry_remove_and_free(struct pa_autoload_entry *e) {
+ assert(e && e->core);
+
+ pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL);
+ pa_hashmap_remove(e->core->autoload_hashmap, e->name);
+ entry_free(e);
+}
+
static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name) {
struct pa_autoload_entry *e = NULL;
assert(c && name);
@@ -64,12 +72,16 @@ static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name)
pa_hashmap_put(c->autoload_hashmap, e->name, e);
- pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, PA_INVALID_INDEX);
+ if (!c->autoload_idxset)
+ c->autoload_idxset = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ pa_idxset_put(c->autoload_idxset, e, &e->index);
+
+ pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, e->index);
return e;
}
-int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument) {
+int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument, uint32_t *index) {
struct pa_autoload_entry *e = NULL;
assert(c && name && module && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE));
@@ -79,18 +91,32 @@ int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type typ
e->module = pa_xstrdup(module);
e->argument = pa_xstrdup(argument);
e->type = type;
+
+ if (index)
+ *index = e->index;
+
return 0;
}
-int pa_autoload_remove(struct pa_core *c, const char*name, enum pa_namereg_type type) {
+int pa_autoload_remove_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type) {
struct pa_autoload_entry *e;
assert(c && name && type);
- if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)))
+ if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type)
return -1;
- pa_hashmap_remove(c->autoload_hashmap, e->name);
- entry_free(e);
+ entry_remove_and_free(e);
+ return 0;
+}
+
+int pa_autoload_remove_by_index(struct pa_core *c, uint32_t index) {
+ struct pa_autoload_entry *e;
+ assert(c && index != PA_IDXSET_INVALID);
+
+ if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, index)))
+ return -1;
+
+ entry_remove_and_free(e);
return 0;
}
@@ -117,12 +143,38 @@ void pa_autoload_request(struct pa_core *c, const char *name, enum pa_namereg_ty
static void free_func(void *p, void *userdata) {
struct pa_autoload_entry *e = p;
+ pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL);
entry_free(e);
}
void pa_autoload_free(struct pa_core *c) {
- if (!c->autoload_hashmap)
- return;
+ if (c->autoload_hashmap) {
+ pa_hashmap_free(c->autoload_hashmap, free_func, NULL);
+ c->autoload_hashmap = NULL;
+ }
+
+ if (c->autoload_idxset) {
+ pa_idxset_free(c->autoload_idxset, NULL, NULL);
+ c->autoload_idxset = NULL;
+ }
+}
+
+const struct pa_autoload_entry* pa_autoload_get_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type) {
+ struct pa_autoload_entry *e;
+ assert(c && name);
+
+ if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type)
+ return NULL;
- pa_hashmap_free(c->autoload_hashmap, free_func, NULL);
+ return e;
+}
+
+const struct pa_autoload_entry* pa_autoload_get_by_index(struct pa_core *c, uint32_t index) {
+ struct pa_autoload_entry *e;
+ assert(c && index != PA_IDXSET_INVALID);
+
+ if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, index)))
+ return NULL;
+
+ return e;
}
diff --git a/polyp/autoload.h b/polyp/autoload.h
index f80b1f0d..ec7d38f1 100644
--- a/polyp/autoload.h
+++ b/polyp/autoload.h
@@ -26,15 +26,20 @@
struct pa_autoload_entry {
struct pa_core *core;
+ uint32_t index;
char *name;
enum pa_namereg_type type;
int in_action;
char *module, *argument;
};
-int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument);
+int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument, uint32_t *index);
void pa_autoload_free(struct pa_core *c);
-int pa_autoload_remove(struct pa_core *c, const char*name, enum pa_namereg_type type);
+int pa_autoload_remove_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type);
+int pa_autoload_remove_by_index(struct pa_core *c, uint32_t index);
void pa_autoload_request(struct pa_core *c, const char *name, enum pa_namereg_type type);
+const struct pa_autoload_entry* pa_autoload_get_by_name(struct pa_core *c, const char*name, enum pa_namereg_type type);
+const struct pa_autoload_entry* pa_autoload_get_by_index(struct pa_core *c, uint32_t index);
+
#endif
diff --git a/polyp/cli-command.c b/polyp/cli-command.c
index 39ea9cc1..62981b4d 100644
--- a/polyp/cli-command.c
+++ b/polyp/cli-command.c
@@ -570,7 +570,7 @@ static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t
return -1;
}
- pa_autoload_add(c, a, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, b, pa_tokenizer_get(t, 3));
+ pa_autoload_add(c, a, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, b, pa_tokenizer_get(t, 3), NULL);
return 0;
}
@@ -584,7 +584,7 @@ static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer
return -1;
}
- if (pa_autoload_remove(c, name, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) {
+ if (pa_autoload_remove_by_name(c, name, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) {
pa_strbuf_puts(buf, "Failed to remove autload entry\n");
return -1;
}
diff --git a/polyp/cli-text.c b/polyp/cli-text.c
index f9bc6c7a..c08b0d9c 100644
--- a/polyp/cli-text.c
+++ b/polyp/cli-text.c
@@ -243,7 +243,7 @@ char *pa_scache_list_to_string(struct pa_core *c) {
}
pa_strbuf_printf(
- s, " name: <%s>\n\tindex: <%i>\n\tsample_spec: <%s>\n\tlength: <%u>\n\tduration: <%0.1fs>\n\tvolume: <0x%04x>\n\tlazy: %s\n\tfilename: %s\n",
+ s, " name: <%s>\n\tindex: <%u>\n\tsample_spec: <%s>\n\tlength: <%u>\n\tduration: <%0.1fs>\n\tvolume: <0x%04x>\n\tlazy: %s\n\tfilename: %s\n",
e->name,
e->index,
ss,
@@ -273,9 +273,10 @@ char *pa_autoload_list_to_string(struct pa_core *c) {
while ((e = pa_hashmap_iterate(c->autoload_hashmap, &state))) {
pa_strbuf_printf(
- s, " name: <%s>\n\ttype: <%s>\n\tmodule_name: <%s>\n\targuments: <%s>\n",
+ s, " name: <%s>\n\ttype: <%s>\n\tindex: <%u>\n\tmodule_name: <%s>\n\targuments: <%s>\n",
e->name,
e->type == PA_NAMEREG_SOURCE ? "source" : "sink",
+ e->index,
e->module,
e->argument);
diff --git a/polyp/core.c b/polyp/core.c
index cf2d383c..c53d2e4e 100644
--- a/polyp/core.c
+++ b/polyp/core.c
@@ -56,7 +56,7 @@ struct pa_core* pa_core_new(struct pa_mainloop_api *m) {
c->modules = NULL;
c->namereg = NULL;
c->scache = NULL;
-
+ c->autoload_idxset = NULL;
c->autoload_hashmap = NULL;
c->default_sample_spec.format = PA_SAMPLE_S16NE;
diff --git a/polyp/core.h b/polyp/core.h
index 62959d0a..c457c3fd 100644
--- a/polyp/core.h
+++ b/polyp/core.h
@@ -31,7 +31,7 @@
struct pa_core {
struct pa_mainloop_api *mainloop;
- struct pa_idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;
+ struct pa_idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache, *autoload_idxset;
struct pa_hashmap *namereg, *autoload_hashmap;
diff --git a/polyp/pactl.c b/polyp/pactl.c
index fbedc6fa..29c06f91 100644
--- a/polyp/pactl.c
+++ b/polyp/pactl.c
@@ -437,11 +437,12 @@ static void get_autoload_info_callback(struct pa_context *c, const struct pa_aut
printf("\n");
nl = 1;
- printf("*** Autoload Entry ***\n"
+ printf("*** Autoload Entry #%u ***\n"
"Name: %s\n"
"Type: %s\n"
"Module: %s\n"
"Argument: %s\n",
+ i->index,
i->name,
i->type == PA_AUTOLOAD_SINK ? "sink" : "source",
i->module,
diff --git a/polyp/polyplib-introspect.c b/polyp/polyplib-introspect.c
index 267af95b..af5fd168 100644
--- a/polyp/polyplib-introspect.c
+++ b/polyp/polyplib-introspect.c
@@ -823,7 +823,8 @@ static void context_get_autoload_info_callback(struct pa_pdispatch *pd, uint32_t
while (!pa_tagstruct_eof(t)) {
struct pa_autoload_info i;
- if (pa_tagstruct_gets(t, &i.name) < 0 ||
+ if (pa_tagstruct_getu32(t, &i.index) < 0 ||
+ pa_tagstruct_gets(t, &i.name) < 0 ||
pa_tagstruct_getu32(t, &i.type) < 0 ||
pa_tagstruct_gets(t, &i.module) < 0 ||
pa_tagstruct_gets(t, &i.argument) < 0) {
@@ -848,7 +849,7 @@ finish:
pa_operation_unref(o);
}
-struct pa_operation* pa_context_get_autoload_info(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
+struct pa_operation* pa_context_get_autoload_info_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
struct pa_tagstruct *t;
struct pa_operation *o;
uint32_t tag;
@@ -869,10 +870,58 @@ struct pa_operation* pa_context_get_autoload_info(struct pa_context *c, const ch
return pa_operation_ref(o);
}
+struct pa_operation* pa_context_get_autoload_info_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
+ struct pa_tagstruct *t;
+ struct pa_operation *o;
+ uint32_t tag;
+ assert(c && cb && index != PA_INVALID_INDEX);
+
+ o = pa_operation_new(c, NULL);
+ o->callback = cb;
+ o->userdata = userdata;
+
+ t = pa_tagstruct_new(NULL, 0);
+ pa_tagstruct_putu32(t, PA_COMMAND_GET_AUTOLOAD_INFO);
+ pa_tagstruct_putu32(t, tag = c->ctag++);
+ pa_tagstruct_putu32(t, index);
+ pa_pstream_send_tagstruct(c->pstream, t);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, o);
+
+ return pa_operation_ref(o);
+}
+
struct pa_operation* pa_context_get_autoload_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, cb, userdata);
}
+static void context_add_autoload_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+ struct pa_operation *o = userdata;
+ uint32_t index;
+ assert(pd && o && o->context && o->ref >= 1);
+
+ if (command != PA_COMMAND_REPLY) {
+ if (pa_context_handle_error(o->context, command, t) < 0)
+ goto finish;
+
+ index = PA_INVALID_INDEX;
+ } else if (pa_tagstruct_getu32(t, &index) ||
+ !pa_tagstruct_eof(t)) {
+ pa_context_fail(o->context, PA_ERROR_PROTOCOL);
+ goto finish;
+ }
+
+ if (o->callback) {
+ void (*cb)(struct pa_context *s, uint32_t index, void *userdata) = o->callback;
+ cb(o->context, index, o->userdata);
+ }
+
+
+finish:
+ pa_operation_done(o);
+ pa_operation_unref(o);
+}
+
+
struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, const char *module, const char*argument, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) {
struct pa_operation *o;
struct pa_tagstruct *t;
@@ -891,12 +940,12 @@ struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *n
pa_tagstruct_puts(t, module);
pa_tagstruct_puts(t, argument);
pa_pstream_send_tagstruct(c->pstream, t);
- pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_add_autoload_callback, o);
return pa_operation_ref(o);
}
-struct pa_operation* pa_context_remove_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) {
+struct pa_operation* pa_context_remove_autoload_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) {
struct pa_operation *o;
struct pa_tagstruct *t;
uint32_t tag;
@@ -916,3 +965,23 @@ struct pa_operation* pa_context_remove_autoload(struct pa_context *c, const char
return pa_operation_ref(o);
}
+
+struct pa_operation* pa_context_remove_autoload_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata) {
+ struct pa_operation *o;
+ struct pa_tagstruct *t;
+ uint32_t tag;
+ assert(c && index != PA_INVALID_INDEX);
+
+ o = pa_operation_new(c, NULL);
+ o->callback = cb;
+ o->userdata = userdata;
+
+ t = pa_tagstruct_new(NULL, 0);
+ pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_AUTOLOAD);
+ pa_tagstruct_putu32(t, tag = c->ctag++);
+ pa_tagstruct_putu32(t, index);
+ pa_pstream_send_tagstruct(c->pstream, t);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
+
+ return pa_operation_ref(o);
+}
diff --git a/polyp/polyplib-introspect.h b/polyp/polyplib-introspect.h
index 9e6c31b2..f4dbd185 100644
--- a/polyp/polyplib-introspect.h
+++ b/polyp/polyplib-introspect.h
@@ -234,23 +234,31 @@ enum pa_autoload_type {
/** Stores information about autoload entries. \since 0.5 */
struct pa_autoload_info {
+ uint32_t index; /**< Index of this autoload entry */
const char *name; /**< Name of the sink or source */
enum pa_autoload_type type; /**< Type of the autoload entry */
const char *module; /**< Module name to load */
const char *argument; /**< Argument string for module */
};
-/** Get info about a specific autoload entry. \since 0.5 */
-struct pa_operation* pa_context_get_autoload_info(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata);
+/** Get info about a specific autoload entry. \since 0.6 */
+struct pa_operation* pa_context_get_autoload_info_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata);
+
+/** Get info about a specific autoload entry. \since 0.6 */
+struct pa_operation* pa_context_get_autoload_info_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata);
/** Get the complete list of autoload entries. \since 0.5 */
struct pa_operation* pa_context_get_autoload_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_autoload_info *i, int is_last, void *userdata), void *userdata);
/** Add a new autoload entry. \since 0.5 */
-struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, const char *module, const char*argument, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata);
+struct pa_operation* pa_context_add_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, const char *module, const char*argument, void (*cb)(struct pa_context *c, int index, void *userdata), void* userdata);
+
+/** Remove an autoload entry. \since 0.6 */
+struct pa_operation* pa_context_remove_autoload_by_name(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata);
+
+/** Remove an autoload entry. \since 0.6 */
+struct pa_operation* pa_context_remove_autoload_by_index(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata);
-/** Remove an autoload entry. \since 0.5 */
-struct pa_operation* pa_context_remove_autoload(struct pa_context *c, const char *name, enum pa_autoload_type type, void (*cb)(struct pa_context *c, int success, void *userdata), void* userdata);
PA_C_DECL_END
diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c
index 31ab4ab8..7af8bdda 100644
--- a/polyp/protocol-native.c
+++ b/polyp/protocol-native.c
@@ -1729,6 +1729,8 @@ static void command_add_autoload(struct pa_pdispatch *pd, uint32_t command, uint
struct connection *c = userdata;
const char *name, *module, *argument;
uint32_t type;
+ uint32_t index;
+ struct pa_tagstruct *reply;
assert(c && t);
if (pa_tagstruct_gets(t, &name) < 0 || !name ||
@@ -1745,22 +1747,30 @@ static void command_add_autoload(struct pa_pdispatch *pd, uint32_t command, uint
return;
}
- if (pa_autoload_add(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, module, argument) < 0) {
+ if (pa_autoload_add(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, module, argument, &index) < 0) {
pa_pstream_send_error(c->pstream, tag, PA_ERROR_EXIST);
return;
}
- pa_pstream_send_simple_ack(c->pstream, tag);
+ reply = pa_tagstruct_new(NULL, 0);
+ pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
+ pa_tagstruct_putu32(reply, tag);
+ pa_tagstruct_putu32(reply, index);
+ pa_pstream_send_tagstruct(c->pstream, reply);
}
static void command_remove_autoload(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
struct connection *c = userdata;
- const char *name;
- uint32_t type;
+ const char *name = NULL;
+ uint32_t type, index = PA_IDXSET_INVALID;
+ int r;
assert(c && t);
- if (pa_tagstruct_gets(t, &name) < 0 || !name ||
- pa_tagstruct_getu32(t, &type) < 0 || type > 1 ||
+ if ((pa_tagstruct_getu32(t, &index) < 0 &&
+ (pa_tagstruct_gets(t, &name) < 0 ||
+ pa_tagstruct_getu32(t, &type) < 0)) ||
+ (!name && index == PA_IDXSET_INVALID) ||
+ (name && type > 1) ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
@@ -1771,7 +1781,12 @@ static void command_remove_autoload(struct pa_pdispatch *pd, uint32_t command, u
return;
}
- if (pa_autoload_remove(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) {
+ if (name)
+ r = pa_autoload_remove_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE);
+ else
+ r = pa_autoload_remove_by_index(c->protocol->core, index);
+
+ if (r < 0) {
pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY);
return;
}
@@ -1779,8 +1794,10 @@ static void command_remove_autoload(struct pa_pdispatch *pd, uint32_t command, u
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void autoload_fill_tagstruct(struct pa_tagstruct *t, struct pa_autoload_entry *e) {
+static void autoload_fill_tagstruct(struct pa_tagstruct *t, const struct pa_autoload_entry *e) {
assert(t && e);
+
+ pa_tagstruct_putu32(t, e->index);
pa_tagstruct_puts(t, e->name);
pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1);
pa_tagstruct_puts(t, e->module);
@@ -1789,14 +1806,17 @@ static void autoload_fill_tagstruct(struct pa_tagstruct *t, struct pa_autoload_e
static void command_get_autoload_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
struct connection *c = userdata;
- struct pa_autoload_entry *a = NULL;
- uint32_t type;
+ const struct pa_autoload_entry *a = NULL;
+ uint32_t type, index;
const char *name;
struct pa_tagstruct *reply;
assert(c && t);
-
- if (pa_tagstruct_gets(t, &name) < 0 || name ||
- pa_tagstruct_getu32(t, &type) < 0 || type > 1 ||
+
+ if ((pa_tagstruct_getu32(t, &index) < 0 &&
+ (pa_tagstruct_gets(t, &name) < 0 ||
+ pa_tagstruct_getu32(t, &type) < 0)) ||
+ (!name && index == PA_IDXSET_INVALID) ||
+ (name && type > 1) ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
@@ -1807,7 +1827,13 @@ static void command_get_autoload_info(struct pa_pdispatch *pd, uint32_t command,
return;
}
- if (!c->protocol->core->autoload_hashmap || !(a = pa_hashmap_get(c->protocol->core->autoload_hashmap, name)) || (a->type == PA_NAMEREG_SINK && type != 0) || (a->type == PA_NAMEREG_SOURCE && type != 1)) {
+
+ if (name)
+ a = pa_autoload_get_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE);
+ else
+ a = pa_autoload_get_by_index(c->protocol->core, index);
+
+ if (!a) {
pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY);
return;
}