[pulseaudio-discuss] [PATCH 3/4] stream-restore: introduce TEST_VERSION & send/receive volume_is_absolute
Marc-André Lureau
marcandre.lureau at gmail.com
Thu May 7 14:45:36 PDT 2009
From: Marc-André Lureau <marc-andre.lureau at nokia.com>
---
PROTOCOL | 4 ++-
src/modules/module-stream-restore.c | 67 ++++++++++++++++++++++++++---------
src/pulse/ext-stream-restore.c | 10 ++++--
3 files changed, 60 insertions(+), 21 deletions(-)
diff --git a/PROTOCOL b/PROTOCOL
index b14b854..5538f63 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -189,7 +189,9 @@ First version supported.
### ext-stream-restore v2, implemented by >= 0.9.16
-First version supported.
+new message:
+
+ SUBCOMMAND_TEST_VERSION
SUBCOMMAND_WRITE, SUBCOMMAND_READ
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 6a03ad0..60cd7e1 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -71,6 +71,11 @@ static const char* const valid_modargs[] = {
NULL
};
+struct connection_info {
+ uint32_t ext_version;
+ pa_bool_t subscribed;
+};
+
struct userdata {
pa_core *core;
pa_module *module;
@@ -88,7 +93,7 @@ struct userdata {
pa_bool_t restore_muted:1;
pa_native_protocol *protocol;
- pa_idxset *subscribed;
+ pa_hashmap *connections;
};
#define ENTRY_VERSION 3
@@ -109,7 +114,8 @@ enum {
SUBCOMMAND_WRITE,
SUBCOMMAND_DELETE,
SUBCOMMAND_SUBSCRIBE,
- SUBCOMMAND_EVENT
+ SUBCOMMAND_EVENT,
+ SUBCOMMAND_TEST_VERSION
};
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
@@ -212,12 +218,16 @@ fail:
static void trigger_save(struct userdata *u) {
struct timeval tv;
+ void *state = NULL;
+ struct connection_info *i;
pa_native_connection *c;
- uint32_t idx;
- for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(u->subscribed, &idx)) {
+ while ((i = pa_hashmap_iterate(u->connections, &state, (const void **)&c))) {
pa_tagstruct *t;
+ if (!i->subscribed)
+ continue;
+
t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
pa_tagstruct_putu32(t, 0);
@@ -598,13 +608,19 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
struct userdata *u;
uint32_t command;
pa_tagstruct *reply = NULL;
+ struct connection_info *i;
pa_assert(p);
pa_assert(m);
pa_assert(c);
pa_assert(t);
- u = m->userdata;
+ pa_assert_se(u = m->userdata);
+
+ if (!(i = pa_hashmap_get(u->connections, c))) {
+ i = pa_xnew0(struct connection_info, 1);
+ pa_hashmap_put(u->connections, c, i);
+ }
if (pa_tagstruct_getu32(t, &command) < 0)
goto fail;
@@ -618,6 +634,20 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
if (!pa_tagstruct_eof(t))
goto fail;
+ /* If the client use SUBCOMMAND_TEST, we assume he is
+ using v1, unless we already have a version */
+ if (i->ext_version == 0)
+ i->ext_version = 1;
+
+ pa_tagstruct_putu32(reply, EXT_VERSION);
+ break;
+ }
+
+ case SUBCOMMAND_TEST_VERSION: {
+ if (pa_tagstruct_getu32(t, &i->ext_version) < 0 ||
+ !pa_tagstruct_eof(t))
+ goto fail;
+
pa_tagstruct_putu32(reply, EXT_VERSION);
break;
}
@@ -648,7 +678,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
pa_tagstruct_put_cvolume(reply, e->volume_valid ? &e->volume : pa_cvolume_init(&r));
pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
- if (c->version >= 16) /* FIXME: should be client side extension version */
+ if (i->ext_version >= 2)
pa_tagstruct_put_boolean(reply, e->volume_is_absolute_valid ? e->volume_is_absolute : FALSE);
pa_xfree(e);
@@ -695,14 +725,12 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
pa_tagstruct_get_boolean(t, &muted) < 0)
goto fail;
- if (c->version >= 16) {
+ if (i->ext_version >= 2) {
if (pa_tagstruct_get_boolean(t, &volume_is_absolute) < 0)
goto fail;
entry.volume_is_absolute = volume_is_absolute;
entry.volume_is_absolute_valid = TRUE;
-
- goto fail;
}
if (!name || !*name)
@@ -768,10 +796,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
!pa_tagstruct_eof(t))
goto fail;
- if (enabled)
- pa_idxset_put(u->subscribed, c, NULL);
- else
- pa_idxset_remove_by_data(u->subscribed, c, NULL);
+ i->subscribed = enabled;
break;
}
@@ -792,11 +817,15 @@ fail:
}
static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
+ struct connection_info *i;
+
pa_assert(p);
pa_assert(c);
pa_assert(u);
- pa_idxset_remove_by_data(u->subscribed, c, NULL);
+ i = pa_hashmap_remove(u->connections, c);
+ pa_xfree(i);
+
return PA_HOOK_OK;
}
@@ -835,7 +864,7 @@ int pa__init(pa_module*m) {
u->restore_volume = restore_volume;
u->restore_muted = restore_muted;
u->gdbm_file = NULL;
- u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ u->connections = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
u->protocol = pa_native_protocol_get(m->core);
pa_native_protocol_install_ext(u->protocol, m, extension_cb);
@@ -894,6 +923,10 @@ fail:
return -1;
}
+static void free_connection_info(void *p, void *userdata) {
+ pa_xfree(p);
+}
+
void pa__done(pa_module*m) {
struct userdata* u;
@@ -926,8 +959,8 @@ void pa__done(pa_module*m) {
pa_native_protocol_unref(u->protocol);
}
- if (u->subscribed)
- pa_idxset_free(u->subscribed, NULL, NULL);
+ if (u->connections)
+ pa_hashmap_free(u->connections, free_connection_info, NULL);
pa_xfree(u);
}
diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c
index dde7222..bcef315 100644
--- a/src/pulse/ext-stream-restore.c
+++ b/src/pulse/ext-stream-restore.c
@@ -35,13 +35,16 @@
#include "ext-stream-restore.h"
+#define EXT_VERSION 2
+
enum {
- SUBCOMMAND_TEST,
+ SUBCOMMAND_TEST, /* deprecated since v2, use SUBCOMMAND_TEST_VERSION instead */
SUBCOMMAND_READ,
SUBCOMMAND_WRITE,
SUBCOMMAND_DELETE,
SUBCOMMAND_SUBSCRIBE,
- SUBCOMMAND_EVENT
+ SUBCOMMAND_EVENT,
+ SUBCOMMAND_TEST_VERSION
};
static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -96,7 +99,8 @@ pa_operation *pa_ext_stream_restore_test(
t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
pa_tagstruct_putu32(t, PA_INVALID_INDEX);
pa_tagstruct_puts(t, "module-stream-restore");
- pa_tagstruct_putu32(t, SUBCOMMAND_TEST);
+ pa_tagstruct_putu32(t, SUBCOMMAND_TEST_VERSION);
+ pa_tagstruct_putu32(t, EXT_VERSION);
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_stream_restore_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
--
1.6.2.4
More information about the pulseaudio-discuss
mailing list