}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t new_state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
pa_sink_state_t old_state;
struct userdata *u;
}
/* Called from main context */
-static int source_set_state_cb(pa_source *s, pa_source_state_t new_state) {
+static int source_set_state_cb(pa_source *s, pa_source_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
pa_source_state_t old_state;
struct userdata *u;
}
/* Called from main context */
-static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
+static int source_set_state_cb(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_source_assert_ref(s);
}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
return pa_source_process_msg(o, code, data, offset, chunk);;
}
-static int ca_sink_set_state(pa_sink *s, pa_sink_state_t state) {
+static int ca_sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
coreaudio_sink *sink = s->userdata;
switch (state) {
return 0;
}
-static int ca_source_set_state(pa_source *s, pa_source_state_t state) {
+static int ca_source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) {
coreaudio_source *source = s->userdata;
switch (state) {
}
/* Called from main context */
-static int sink_set_state(pa_sink *sink, pa_sink_state_t state) {
+static int sink_set_state(pa_sink *sink, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(sink);
pa_assert_se(u = sink->userdata);
+ /* It may be that only the suspend cause is changing, in which
+ * case there's nothing to do. */
+ if (state == u->sink->state)
+ return 0;
+
/* Please note that in contrast to the ALSA modules we call
* suspend/unsuspend from main context here! */
}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
}
/* Called from main context */
-static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
}
/* Called from main context */
-static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
+static int source_set_state_cb(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_source_assert_ref(s);
}
/* Called from main context */
-static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
u = s->userdata;
+ /* It may be that only the suspend cause is changing, in which
+ * case there's nothing to do. */
+ if (state == s->state)
+ return 0;
+
switch ((pa_sink_state_t) state) {
case PA_SINK_SUSPENDED:
}
/* Called from main context */
-static int source_set_state(pa_source *s, pa_source_state_t state) {
+static int source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_source_assert_ref(s);
u = s->userdata;
+ /* It may be that only the suspend cause is changing, in which
+ * case there's nothing to do. */
+ if (state == s->state)
+ return 0;
+
switch ((pa_source_state_t) state) {
case PA_SOURCE_SUSPENDED:
}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
}
/* Called from main context */
-static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
+static int source_set_state_cb(pa_source *s, pa_source_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_source_assert_ref(s);
}
/* Called from main context */
-static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) {
struct userdata *u;
pa_sink_assert_ref(s);
* cause, or it might just add unnecessary complexity, given that the
* current approach of not setting any suspend cause works well enough. */
- if (s->set_state && state_changed) {
- ret = s->set_state(s, state);
+ if (s->set_state) {
+ ret = s->set_state(s, state, suspend_cause);
/* set_state() is allowed to fail only when resuming. */
pa_assert(ret >= 0 || resuming);
}
pa_assert(resuming);
if (s->set_state)
- s->set_state(s, PA_SINK_SUSPENDED);
+ s->set_state(s, PA_SINK_SUSPENDED, 0);
}
if (suspend_cause_changed) {
/* Called when the main loop requests a state change. Called from
* main loop context. If returns -1 the state change will be
- * inhibited */
- int (*set_state)(pa_sink *s, pa_sink_state_t state); /* may be NULL */
+ * inhibited. This will also be called even if only the suspend cause
+ * changes.
+ *
+ * s->state and s->suspend_cause haven't been updated yet when this is
+ * called, so the callback can get the old state through those variables.
+ *
+ * If set_state() is successful, the IO thread will be notified with the
+ * SET_STATE message. The message handler is allowed to fail, in which
+ * case the old state is restored, and set_state() is called again. */
+ int (*set_state)(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause); /* may be NULL */
/* Sink drivers that support hardware volume may set this
* callback. This is called when the current volume needs to be
* cause, or it might just add unnecessary complexity, given that the
* current approach of not setting any suspend cause works well enough. */
- if (s->set_state && state_changed) {
- ret = s->set_state(s, state);
+ if (s->set_state) {
+ ret = s->set_state(s, state, suspend_cause);
/* set_state() is allowed to fail only when resuming. */
pa_assert(ret >= 0 || resuming);
}
pa_assert(resuming);
if (s->set_state)
- s->set_state(s, PA_SOURCE_SUSPENDED);
+ s->set_state(s, PA_SOURCE_SUSPENDED, 0);
}
if (suspend_cause_changed) {
/* Called when the main loop requests a state change. Called from
* main loop context. If returns -1 the state change will be
- * inhibited */
- int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */
+ * inhibited. This will also be called even if only the suspend cause
+ * changes.
+ *
+ * s->state and s->suspend_cause haven't been updated yet when this is
+ * called, so the callback can get the old state through those variables.
+ *
+ * If set_state() is successful, the IO thread will be notified with the
+ * SET_STATE message. The message handler is allowed to fail, in which
+ * case the old state is restored, and set_state() is called again. */
+ int (*set_state)(pa_source *source, pa_source_state_t state, pa_suspend_cause_t suspend_cause); /* may be NULL */
/* Called when the volume is queried. Called from main loop
* context. If this is NULL a PA_SOURCE_MESSAGE_GET_VOLUME message