summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-08-12 23:25:28 +0000
committerLennart Poettering <lennart@poettering.net>2004-08-12 23:25:28 +0000
commit886041aab88930108953af0e9e14b39ec9d03809 (patch)
treef7934a57e25048c75dedf84ef6bed2e3aefdf7f0
parentcbfaf40b45f712c1cdcc6b7cb694f907ce0e7f8f (diff)
add more subscription events
add support for clients/modules in native protocol git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@115 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r--polyp/cli-command.c2
-rw-r--r--polyp/module.c3
-rw-r--r--polyp/native-common.h2
-rwxr-xr-xpolyp/polypaudio.pa6
-rw-r--r--polyp/polyplib.c162
-rw-r--r--polyp/polyplib.h19
-rw-r--r--polyp/protocol-native.c57
-rw-r--r--polyp/sink.c9
-rw-r--r--polyp/sink.h2
9 files changed, 248 insertions, 14 deletions
diff --git a/polyp/cli-command.c b/polyp/cli-command.c
index 6386d4e4..1d454f2a 100644
--- a/polyp/cli-command.c
+++ b/polyp/cli-command.c
@@ -300,7 +300,7 @@ static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t,
return -1;
}
- sink->volume = (uint32_t) volume;
+ pa_sink_set_volume(sink, (uint32_t) volume);
return 0;
}
diff --git a/polyp/module.c b/polyp/module.c
index 849afca4..1deb7cde 100644
--- a/polyp/module.c
+++ b/polyp/module.c
@@ -218,6 +218,9 @@ void pa_module_unload_request(struct pa_core *c, struct pa_module *m) {
void pa_module_set_used(struct pa_module*m, int used) {
assert(m);
+ if (m->n_used != used)
+ pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_CHANGE, m->index);
+
if (m->n_used != used && used == 0)
time(&m->last_used_time);
diff --git a/polyp/native-common.h b/polyp/native-common.h
index 5e69c805..4d5ab53d 100644
--- a/polyp/native-common.h
+++ b/polyp/native-common.h
@@ -55,7 +55,9 @@ enum {
PA_COMMAND_GET_SOURCE_INFO,
PA_COMMAND_GET_SOURCE_INFO_LIST,
PA_COMMAND_GET_MODULE_INFO,
+ PA_COMMAND_GET_MODULE_INFO_LIST,
PA_COMMAND_GET_CLIENT_INFO,
+ PA_COMMAND_GET_CLIENT_INFO_LIST,
PA_COMMAND_GET_SINK_INPUT_INFO,
PA_COMMAND_GET_SOURCE_OUTPUT_INFO,
PA_COMMAND_GET_SAMPLE_INFO,
diff --git a/polyp/polypaudio.pa b/polyp/polypaudio.pa
index d57f8127..9f8cf860 100755
--- a/polyp/polypaudio.pa
+++ b/polyp/polypaudio.pa
@@ -24,7 +24,7 @@
#load module-alsa-source device=plughw:1,0
#load module-oss device="/dev/dsp" sink_name=output source_name=input
#load module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
-#load module-pipe-sink
+load module-pipe-sink
# Load audio drivers automatically on access
@@ -32,8 +32,8 @@
#autoload_source_add input module-oss device="/dev/dsp" sink_name=output source_name=input
#autoload_sink_add output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#autoload_source_add input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
-autoload_sink_add output module-alsa-sink sink_name=output
-autoload_source_add input module-alsa-source source_name=input
+#autoload_sink_add output module-alsa-sink sink_name=output
+#autoload_source_add input module-alsa-source source_name=input
# Load several protocols
load module-esound-protocol-tcp
diff --git a/polyp/polyplib.c b/polyp/polyplib.c
index b77d24ea..35001d3d 100644
--- a/polyp/polyplib.c
+++ b/polyp/polyplib.c
@@ -102,6 +102,12 @@ struct pa_context {
void *subscribe_userdata;
enum pa_subscription_mask subscribe_mask;
+ void (*get_client_info_callback)(struct pa_context*c, const struct pa_client_info* i, int is_last, void *userdata);
+ void *get_client_info_userdata;
+
+ void (*get_module_info_callback)(struct pa_context*c, const struct pa_module_info* i, int is_last, void *userdata);
+ void *get_module_info_userdata;
+
uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
};
@@ -209,6 +215,12 @@ struct pa_context *pa_context_new(struct pa_mainloop_api *mainloop, const char *
c->subscribe_callback = NULL;
c->subscribe_userdata = NULL;
+ c->get_client_info_callback = NULL;
+ c->get_client_info_userdata = NULL;
+
+ c->get_module_info_callback = NULL;
+ c->get_module_info_userdata = NULL;
+
pa_check_for_sigpipe();
return c;
}
@@ -1386,3 +1398,153 @@ void pa_context_get_source_info_by_index(struct pa_context *c, uint32_t index, v
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, c);
}
+
+static void context_get_client_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+ struct pa_context *c = userdata;
+ assert(pd && c);
+
+ if (command != PA_COMMAND_REPLY) {
+ if (handle_error(c, command, t) < 0) {
+ context_dead(c);
+ return;
+ }
+
+ if (c->get_client_info_callback)
+ c->get_client_info_callback(c, NULL, 0, c->get_client_info_userdata);
+ return;
+ }
+
+ while (!pa_tagstruct_eof(t)) {
+ struct pa_client_info i;
+
+ if (pa_tagstruct_getu32(t, &i.index) < 0 ||
+ pa_tagstruct_gets(t, &i.name) < 0 ||
+ pa_tagstruct_gets(t, &i.protocol_name) < 0 ||
+ pa_tagstruct_getu32(t, &i.owner_module) < 0) {
+ c->error = PA_ERROR_PROTOCOL;
+ context_dead(c);
+ return;
+ }
+
+ if (c->get_client_info_callback)
+ c->get_client_info_callback(c, &i, 0, c->get_client_info_userdata);
+ }
+
+ if (c->get_client_info_callback)
+ c->get_client_info_callback(c, NULL, 1, c->get_client_info_userdata);
+}
+
+
+void pa_context_get_client_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata) {
+ struct pa_tagstruct *t;
+ uint32_t tag;
+ assert(c);
+
+ c->get_client_info_callback = cb;
+ c->get_client_info_userdata = userdata;
+
+ if (!cb)
+ return;
+
+ t = pa_tagstruct_new(NULL, 0);
+ assert(t);
+ pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_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_client_info_callback, c);
+}
+
+void pa_context_get_client_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata) {
+ struct pa_tagstruct *t;
+ uint32_t tag;
+ assert(c);
+
+ c->get_client_info_callback = cb;
+ c->get_client_info_userdata = userdata;
+
+ if (!cb)
+ return;
+
+ t = pa_tagstruct_new(NULL, 0);
+ assert(t);
+ pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_INFO_LIST);
+ pa_tagstruct_putu32(t, tag = c->ctag++);
+ pa_pstream_send_tagstruct(c->pstream, t);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, c);
+}
+
+static void context_get_module_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+ struct pa_context *c = userdata;
+ assert(pd && c);
+
+ if (command != PA_COMMAND_REPLY) {
+ if (handle_error(c, command, t) < 0) {
+ context_dead(c);
+ return;
+ }
+
+ if (c->get_module_info_callback)
+ c->get_module_info_callback(c, NULL, 0, c->get_module_info_userdata);
+ return;
+ }
+
+ while (!pa_tagstruct_eof(t)) {
+ struct pa_module_info i;
+
+ if (pa_tagstruct_getu32(t, &i.index) < 0 ||
+ pa_tagstruct_gets(t, &i.name) < 0 ||
+ pa_tagstruct_gets(t, &i.argument) < 0 ||
+ pa_tagstruct_getu32(t, &i.n_used) < 0 ||
+ pa_tagstruct_getu32(t, &i.auto_unload) < 0) {
+ c->error = PA_ERROR_PROTOCOL;
+ context_dead(c);
+ return;
+ }
+
+ if (c->get_module_info_callback)
+ c->get_module_info_callback(c, &i, 0, c->get_module_info_userdata);
+ }
+
+ if (c->get_module_info_callback)
+ c->get_module_info_callback(c, NULL, 1, c->get_module_info_userdata);
+}
+
+void pa_context_get_module_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata) {
+ struct pa_tagstruct *t;
+ uint32_t tag;
+ assert(c);
+
+ c->get_module_info_callback = cb;
+ c->get_module_info_userdata = userdata;
+
+ if (!cb)
+ return;
+
+ t = pa_tagstruct_new(NULL, 0);
+ assert(t);
+ pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_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_module_info_callback, c);
+}
+
+void pa_context_get_module_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata) {
+ struct pa_tagstruct *t;
+ uint32_t tag;
+ assert(c);
+
+ c->get_module_info_callback = cb;
+ c->get_module_info_userdata = userdata;
+
+ if (!cb)
+ return;
+
+ t = pa_tagstruct_new(NULL, 0);
+ assert(t);
+ pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_INFO_LIST);
+ pa_tagstruct_putu32(t, tag = c->ctag++);
+ pa_pstream_send_tagstruct(c->pstream, t);
+ pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, c);
+}
diff --git a/polyp/polyplib.h b/polyp/polyplib.h
index 8708cd72..590b978f 100644
--- a/polyp/polyplib.h
+++ b/polyp/polyplib.h
@@ -141,6 +141,25 @@ struct pa_server_info {
void pa_context_get_server_info(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_server_info*i, void *userdata), void *userdata);
+struct pa_module_info {
+ uint32_t index;
+ const char*name, *argument;
+ uint32_t n_used, auto_unload;
+};
+
+void pa_context_get_module_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata);
+void pa_context_get_module_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata);
+
+struct pa_client_info {
+ uint32_t index;
+ const char *name;
+ uint32_t owner_module;
+ const char *protocol_name;
+};
+
+void pa_context_get_client_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata);
+void pa_context_get_client_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata);
+
void pa_context_subscribe(struct pa_context *c, enum pa_subscription_mask m, void (*cb)(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata), void *userdata);
#ifdef __cplusplus
diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c
index caaa1396..247851fc 100644
--- a/polyp/protocol-native.c
+++ b/polyp/protocol-native.c
@@ -159,8 +159,12 @@ static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_REMOVE_SAMPLE] = { command_remove_sample },
[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_MODULE_INFO] = { command_get_info },
[PA_COMMAND_GET_SINK_INFO_LIST] = { command_get_info_list },
[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_SERVER_INFO] = { command_get_server_info },
[PA_COMMAND_SUBSCRIBE] = { command_subscribe },
};
@@ -964,11 +968,30 @@ static void source_fill_tagstruct(struct pa_tagstruct *t, struct pa_source *sour
pa_tagstruct_puts(t, source->monitor_of ? source->monitor_of->name : "");
}
+static void client_fill_tagstruct(struct pa_tagstruct *t, struct pa_client *client) {
+ assert(t && client);
+ pa_tagstruct_putu32(t, client->index);
+ pa_tagstruct_puts(t, client->name);
+ pa_tagstruct_puts(t, client->protocol_name);
+ pa_tagstruct_putu32(t, client->owner ? client->owner->index : (uint32_t) -1);
+}
+
+static void module_fill_tagstruct(struct pa_tagstruct *t, struct pa_module *module) {
+ assert(t && module);
+ pa_tagstruct_putu32(t, module->index);
+ pa_tagstruct_puts(t, module->name);
+ pa_tagstruct_puts(t, module->argument ? module->argument : "");
+ pa_tagstruct_putu32(t, module->n_used);
+ pa_tagstruct_putu32(t, module->auto_unload);
+}
+
static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
struct connection *c = userdata;
uint32_t index;
struct pa_sink *sink = NULL;
struct pa_source *source = NULL;
+ struct pa_client *client = NULL;
+ struct pa_module *module = NULL;
const char *name;
struct pa_tagstruct *reply;
assert(c && t);
@@ -990,15 +1013,19 @@ static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t
sink = pa_idxset_get_by_index(c->protocol->core->sinks, index);
else
sink = pa_namereg_get(c->protocol->core, *name ? name : NULL, PA_NAMEREG_SINK, 1);
- } else {
- assert(command == PA_COMMAND_GET_SOURCE_INFO);
+ } else if (command == PA_COMMAND_GET_SOURCE_INFO) {
if (index != (uint32_t) -1)
source = pa_idxset_get_by_index(c->protocol->core->sources, index);
else
source = pa_namereg_get(c->protocol->core, *name ? name : NULL, PA_NAMEREG_SOURCE, 1);
+ } else if (command == PA_COMMAND_GET_CLIENT_INFO)
+ client = pa_idxset_get_by_index(c->protocol->core->clients, index);
+ else {
+ assert(command == PA_COMMAND_GET_MODULE_INFO);
+ module = pa_idxset_get_by_index(c->protocol->core->modules, index);
}
-
- if (!sink && !source) {
+
+ if (!sink && !source && !client && !module) {
pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY);
return;
}
@@ -1009,8 +1036,12 @@ static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t
pa_tagstruct_putu32(reply, tag);
if (sink)
sink_fill_tagstruct(reply, sink);
- else
+ else if (source)
source_fill_tagstruct(reply, source);
+ else if (client)
+ client_fill_tagstruct(reply, client);
+ else
+ module_fill_tagstruct(reply, module);
pa_pstream_send_tagstruct(c->pstream, reply);
}
@@ -1039,17 +1070,25 @@ static void command_get_info_list(struct pa_pdispatch *pd, uint32_t command, uin
if (command == PA_COMMAND_GET_SINK_INFO_LIST)
i = c->protocol->core->sinks;
- else {
- assert(command == PA_COMMAND_GET_SOURCE_INFO_LIST);
+ else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
i = c->protocol->core->sources;
+ else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
+ i = c->protocol->core->clients;
+ else {
+ assert(command == PA_COMMAND_GET_MODULE_INFO_LIST);
+ i = c->protocol->core->modules;
}
for (p = pa_idxset_first(i, &index); p; p = pa_idxset_next(i, &index)) {
if (command == PA_COMMAND_GET_SINK_INFO_LIST)
sink_fill_tagstruct(reply, p);
- else {
- assert(command == PA_COMMAND_GET_SOURCE_INFO_LIST);
+ else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
source_fill_tagstruct(reply, p);
+ else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
+ client_fill_tagstruct(reply, p);
+ else {
+ assert(command == PA_COMMAND_GET_MODULE_INFO_LIST);
+ module_fill_tagstruct(reply, p);
}
}
diff --git a/polyp/sink.c b/polyp/sink.c
index 7e0e15cd..d9a3ae86 100644
--- a/polyp/sink.c
+++ b/polyp/sink.c
@@ -276,10 +276,17 @@ uint32_t pa_sink_get_latency(struct pa_sink *s) {
return s->get_latency(s);
}
-
void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m) {
sink->owner = m;
if (sink->monitor_source)
pa_source_set_owner(sink->monitor_source, m);
}
+
+void pa_sink_set_volume(struct pa_sink *sink, uint32_t volume) {
+ assert(sink);
+ if (sink->volume != volume) {
+ pa_subscription_post(sink->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, sink->index);
+ sink->volume = volume;
+ }
+}
diff --git a/polyp/sink.h b/polyp/sink.h
index 400d5d04..2aa5d611 100644
--- a/polyp/sink.h
+++ b/polyp/sink.h
@@ -62,4 +62,6 @@ void pa_sink_notify(struct pa_sink*s);
void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m);
+void pa_sink_set_volume(struct pa_sink *sink, uint32_t volume);
+
#endif