From: Marc-Andr? Lureau <marc-andre.lureau@xxxxxxxxx> While trying to keep ABI compatibility, I introduce a bitfield for the boolean volume_is_absolute. We can't extend the struct because the API is using pa_ext_stream_restore_info data[] directly.. Since TEST is not required before calling any other function, I assume the server side version is at least 1. Volume is absolute will always be FALSE in v1. --- PROTOCOL | 13 +++++++++++++ src/pulse/context.c | 2 ++ src/pulse/ext-stream-restore.c | 18 ++++++++++++++---- src/pulse/ext-stream-restore.h | 4 +++- src/pulse/internal.h | 1 + 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/PROTOCOL b/PROTOCOL index 88166f1..b14b854 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -181,3 +181,16 @@ new messages: PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED + + +### ext-stream-restore v1, implemented by >= 0.9.12 + +First version supported. + +### ext-stream-restore v2, implemented by >= 0.9.16 + +First version supported. + +SUBCOMMAND_WRITE, SUBCOMMAND_READ + + bool absolute at the end diff --git a/src/pulse/context.c b/src/pulse/context.c index bfff0e1..dc80f25 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -168,6 +168,8 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * reset_callbacks(c); + c->ext_stream_restore.version = 1; /* default version, updated by TEST message */ + c->is_local = FALSE; c->server_list = NULL; c->server = NULL; diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c index 63c911f..dde7222 100644 --- a/src/pulse/ext-stream-restore.c +++ b/src/pulse/ext-stream-restore.c @@ -46,7 +46,6 @@ enum { static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - uint32_t version = PA_INVALID_INDEX; pa_assert(pd); pa_assert(o); @@ -59,7 +58,7 @@ static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint3 if (pa_context_handle_error(o->context, command, t, FALSE) < 0) goto finish; - } else if (pa_tagstruct_getu32(t, &version) < 0 || + } else if (pa_tagstruct_getu32(t, &o->context->ext_stream_restore.version) < 0 || !pa_tagstruct_eof(t)) { pa_context_fail(o->context, PA_ERR_PROTOCOL); @@ -68,7 +67,7 @@ static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint3 if (o->callback) { pa_ext_stream_restore_test_cb_t cb = (pa_ext_stream_restore_test_cb_t) o->callback; - cb(o->context, version, o->userdata); + cb(o->context, o->context->ext_stream_restore.version, o->userdata); } finish: @@ -125,6 +124,7 @@ static void ext_stream_restore_read_cb(pa_pdispatch *pd, uint32_t command, uint3 while (!pa_tagstruct_eof(t)) { pa_ext_stream_restore_info i; pa_bool_t mute = FALSE; + pa_bool_t volume_is_absolute = FALSE; memset(&i, 0, sizeof(i)); @@ -138,7 +138,15 @@ static void ext_stream_restore_read_cb(pa_pdispatch *pd, uint32_t command, uint3 goto finish; } - i.mute = (int) mute; + if (o->context->ext_stream_restore.version >= 2 && + pa_tagstruct_get_boolean(t, &volume_is_absolute) < 0) { + + pa_context_fail(o->context, PA_ERR_PROTOCOL); + goto finish; + } + + i.mute = (int) mute; + i.volume_is_absolute = volume_is_absolute; if (o->callback) { pa_ext_stream_restore_read_cb_t cb = (pa_ext_stream_restore_read_cb_t) o->callback; @@ -231,6 +239,8 @@ pa_operation *pa_ext_stream_restore_write( pa_tagstruct_put_cvolume(t, &data->volume); pa_tagstruct_puts(t, data->device); pa_tagstruct_put_boolean(t, data->mute); + if (c->ext_stream_restore.version >= 2) + pa_tagstruct_put_boolean(t, data->volume_is_absolute); } pa_pstream_send_tagstruct(c->pstream, t); diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h index 0b5d8eb..14d984e 100644 --- a/src/pulse/ext-stream-restore.h +++ b/src/pulse/ext-stream-restore.h @@ -24,6 +24,7 @@ #include <pulse/context.h> #include <pulse/version.h> +#include <pulsecore/macro.h> /** \file * @@ -39,7 +40,8 @@ typedef struct pa_ext_stream_restore_info { pa_channel_map channel_map; /**< The channel map for the volume field, if applicable */ pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable and saved */ const char *device; /**< The sink/source of the stream when it was last seen, if applicable and saved */ - int mute; /**< The boolean mute state of the stream when it was last seen, if applicable and saved */ + int mute:1; /**< The boolean mute state of the stream when it was last seen, if applicable and saved */ + pa_bool_t volume_is_absolute:1; /**< True if the volume is absolute, if applicable and saved. \since 0.9.16 */ } pa_ext_stream_restore_info; /** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */ diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 28a989b..3c58c49 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -103,6 +103,7 @@ struct pa_context { struct { pa_ext_stream_restore_subscribe_cb_t callback; void *userdata; + uint32_t version; } ext_stream_restore; }; -- 1.6.2.4