if (inputs) {
if (u->sink)
- pa_sink_move_all_finish(u->sink, inputs);
+ pa_sink_move_all_finish(u->sink, inputs, FALSE);
else
pa_sink_move_all_fail(inputs);
}
if (outputs) {
if (u->source)
- pa_source_move_all_finish(u->source, outputs);
+ pa_source_move_all_finish(u->source, outputs, FALSE);
else
pa_source_move_all_fail(outputs);
}
pa_cvolume cv;
pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume);
pa_cvolume_set(&cv, si->sample_spec.channels, r->volume);
- pa_sink_input_set_volume(si, &cv);
+ pa_sink_input_set_volume(si, &cv, TRUE);
}
}
}
}
while ((i = pa_idxset_first(sink->inputs, NULL))) {
- if (pa_sink_input_move_to(i, target) < 0) {
+ if (pa_sink_input_move_to(i, target, FALSE) < 0) {
pa_log_warn("Failed to move sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
return PA_HOOK_OK;
}
pa_assert(target != source);
while ((o = pa_idxset_first(source->outputs, NULL))) {
- if (pa_source_output_move_to(o, target) < 0) {
+ if (pa_source_output_move_to(o, target, FALSE) < 0) {
pa_log_warn("Failed to move source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
return PA_HOOK_OK;
}
if (u->restore_muted) {
pa_log_info("Restoring mute state for sink input %s.", name);
- pa_sink_input_set_mute(si, e->muted);
+ pa_sink_input_set_mute(si, e->muted, TRUE);
}
if (u->restore_device &&
(s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
pa_log_info("Restoring device for stream %s.", name);
- pa_sink_input_move_to(si, s);
+ pa_sink_input_move_to(si, s, TRUE);
}
}
(s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
pa_log_info("Restoring device for stream %s.", name);
- pa_source_output_move_to(so, s);
+ pa_source_output_move_to(so, s, TRUE);
}
}
}
}
pa_cvolume_set(&cvolume, si->sample_spec.channels, volume);
- pa_sink_input_set_volume(si, &cvolume);
+ pa_sink_input_set_volume(si, &cvolume, TRUE);
return 0;
}
return -1;
}
- pa_sink_input_set_mute(si, mute);
+ pa_sink_input_set_mute(si, mute, TRUE);
return 0;
}
return -1;
}
- if (pa_sink_input_move_to(si, sink) < 0) {
+ if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
pa_strbuf_puts(buf, "Moved failed.\n");
return -1;
}
return -1;
}
- if (pa_source_output_move_to(so, source) < 0) {
+ if (pa_source_output_move_to(so, source, TRUE) < 0) {
pa_strbuf_puts(buf, "Moved failed.\n");
return -1;
}
volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
volume.channels = 2;
- pa_sink_input_set_volume(conn->sink_input, &volume);
+ pa_sink_input_set_volume(conn->sink_input, &volume, TRUE);
ok = 1;
} else
ok = 0;
else if (source)
pa_source_set_volume(source, &volume);
else if (si)
- pa_sink_input_set_volume(si, &volume);
+ pa_sink_input_set_volume(si, &volume, TRUE);
pa_pstream_send_simple_ack(c->pstream, tag);
}
else if (source)
pa_source_set_mute(source, mute);
else if (si)
- pa_sink_input_set_mute(si, mute);
+ pa_sink_input_set_mute(si, mute, TRUE);
pa_pstream_send_simple_ack(c->pstream, tag);
}
CHECK_VALIDITY(c->pstream, si && sink, tag, PA_ERR_NOENTITY);
- if (pa_sink_input_move_to(si, sink) < 0) {
+ if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
return;
}
CHECK_VALIDITY(c->pstream, so && source, tag, PA_ERR_NOENTITY);
- if (pa_source_output_move_to(so, source) < 0) {
+ if (pa_source_output_move_to(so, source, TRUE) < 0) {
pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
return;
}
pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
- if (!data->sink)
+ if (!data->sink) {
data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
+ data->save_sink = FALSE;
+ }
pa_return_null_if_fail(data->sink);
pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_UNLINKED);
} else
pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels);
+ data->save_volume = FALSE;
+
} else if (!data->virtual_volume_is_absolute) {
/* When the 'absolute' bool is set then we'll treat the volume
i->virtual_volume = data->virtual_volume;
i->soft_volume = data->soft_volume;
+ i->save_volume = data->save_volume;
+ i->save_sink = data->save_sink;
+ i->save_muted = data->save_muted;
i->muted = data->muted;
}
/* Called from main context */
-void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
+void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save) {
pa_sink_input_assert_ref(i);
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
pa_assert(volume);
return;
i->virtual_volume = *volume;
+ i->save_volume = save;
if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
pa_cvolume new_volume;
}
/* Called from main context */
-void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute) {
+void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
pa_assert(i);
pa_sink_input_assert_ref(i);
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
return;
i->muted = mute;
+ i->save_muted = save;
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
}
/* Called from main context */
-int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest) {
+int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
pa_resampler *new_resampler;
pa_sink_input_assert_ref(i);
return -1;
i->sink = dest;
+ i->save_sink = save;
pa_idxset_put(dest->inputs, i, NULL);
if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
}
/* Called from main context */
-int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
+int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
pa_sink_input_assert_ref(i);
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
pa_assert(i->sink);
if (pa_sink_input_start_move(i) < 0)
return -1;
- if (pa_sink_input_finish_move(i, dest) < 0)
+ if (pa_sink_input_finish_move(i, dest, save) < 0)
return -1;
return 0;
pa_sink_input *sync_prev, *sync_next;
pa_cvolume virtual_volume, soft_volume;
- pa_bool_t muted;
+ pa_bool_t muted:1;
+
+ /* if TRUE then the source we are connected to and/or the volume
+ * set is worth remembering, i.e. was explicitly chosen by the
+ * user and not automatically. module-stream-restore looks for
+ * this.*/
+ pa_bool_t save_sink:1, save_volume:1, save_muted:1;
pa_resample_method_t requested_resample_method, actual_resample_method;
pa_bool_t muted_is_set:1;
pa_bool_t virtual_volume_is_absolute:1;
+
+ pa_bool_t save_sink:1, save_volume:1, save_muted:1;
} pa_sink_input_new_data;
pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency);
-void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume);
+void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save);
const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i);
-void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute);
+void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save);
pa_bool_t pa_sink_input_get_mute(pa_sink_input *i);
pa_bool_t pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p);
pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);
-int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest);
+int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save);
pa_bool_t pa_sink_input_may_move(pa_sink_input *i); /* may this sink input move at all? */
pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest); /* may this sink input move to this sink? */
* first the detaching from the old sink, then the attaching to the
* new sink */
int pa_sink_input_start_move(pa_sink_input *i);
-int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest);
+int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save);
pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i);
}
/* Called from main context */
-void pa_sink_move_all_finish(pa_sink *s, pa_queue *q) {
+void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {
pa_sink_input *i;
pa_sink_assert_ref(s);
pa_assert(q);
while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
- if (pa_sink_input_finish_move(i, s) < 0)
+ if (pa_sink_input_finish_move(i, s, save) < 0)
pa_sink_input_unlink(i);
pa_sink_input_unref(i);
/* Moves all inputs away, and stores them in pa_queue */
pa_queue *pa_sink_move_all_start(pa_sink *s);
-void pa_sink_move_all_finish(pa_sink *s, pa_queue *q);
+void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save);
void pa_sink_move_all_fail(pa_queue *q);
/*** To be called exclusively by the sink driver, from IO context */
pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
- if (!data->source)
+ if (!data->source) {
data->source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE);
+ data->save_source = FALSE;
+ }
pa_return_null_if_fail(data->source);
pa_return_null_if_fail(pa_source_get_state(data->source) != PA_SOURCE_UNLINKED);
o->source = data->source;
o->client = data->client;
-
o->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
o->requested_resample_method = data->resample_method;
o->sample_spec = data->sample_spec;
o->direct_on_input = data->direct_on_input;
+ o->save_source = data->save_source;
+
reset_callbacks(o);
o->userdata = NULL;
}
/* Called from main context */
-int pa_source_output_finish_move(pa_source_output *o, pa_source *dest) {
+int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save) {
pa_resampler *new_resampler;
pa_source_output_assert_ref(o);
return -1;
o->source = dest;
+ o->save_source = save;
pa_idxset_put(o->source->outputs, o, NULL);
if (pa_source_output_get_state(o) == PA_SOURCE_OUTPUT_CORKED)
}
/* Called from main context */
-int pa_source_output_move_to(pa_source_output *o, pa_source *dest) {
+int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save) {
pa_source_output_assert_ref(o);
pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
if (pa_source_output_start_move(o) < 0)
return -1;
- if (pa_source_output_finish_move(o, dest) < 0)
+ if (pa_source_output_finish_move(o, dest, save) < 0)
return -1;
return 0;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
+ /* if TRUE then the source we are connected to is worth
+ * remembering, i.e. was explicitly chosen by the user and not
+ * automatically. module-stream-restore looks for this.*/
+ pa_bool_t save_source:1;
+
pa_resample_method_t requested_resample_method, actual_resample_method;
/* Pushes a new memchunk into the output. Called from IO thread
pa_bool_t sample_spec_is_set:1;
pa_bool_t channel_map_is_set:1;
+
+ pa_bool_t save_source:1;
} pa_source_output_new_data;
pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
pa_bool_t pa_source_output_may_move(pa_source_output *o);
pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest);
-int pa_source_output_move_to(pa_source_output *o, pa_source *dest);
+int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save);
/* The same as pa_source_output_move_to() but in two seperate steps,
* first the detaching from the old source, then the attaching to the
* new source */
int pa_source_output_start_move(pa_source_output *o);
-int pa_source_output_finish_move(pa_source_output *o, pa_source *dest);
+int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save);
#define pa_source_output_get_state(o) ((o)->state)
}
/* Called from main context */
-void pa_source_move_all_finish(pa_source *s, pa_queue *q) {
+void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {
pa_source_output *o;
pa_source_assert_ref(s);
pa_assert(q);
while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
- if (pa_source_output_finish_move(o, s) < 0)
+ if (pa_source_output_finish_move(o, s, save) < 0)
pa_source_output_unlink(o);
pa_source_output_unref(o);
/* Moves all inputs away, and stores them in pa_queue */
pa_queue *pa_source_move_all_start(pa_source *s);
-void pa_source_move_all_finish(pa_source *s, pa_queue *q);
+void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save);
void pa_source_move_all_fail(pa_queue *q);
/*** To be called exclusively by the source driver, from IO context */