summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-08-27 03:55:47 +0200
committerLennart Poettering <lennart@poettering.net>2009-08-27 03:55:47 +0200
commit54d8b7b31e3fbcbe80e20d0aef2bc344d44db81e (patch)
treeb6386ac633a6bb88509591a54935ecb91ba0e779
parenta030f162722d5172be86eb6691d61baffe981b54 (diff)
downloadlibcanberra-54d8b7b31e3fbcbe80e20d0aef2bc344d44db81e.tar.gz
implement ca_context_playing() call
-rw-r--r--gtkdoc/libcanberra-sections.txt1
-rw-r--r--src/alsa.c29
-rw-r--r--src/canberra.h.in1
-rw-r--r--src/common.c29
-rw-r--r--src/driver.h2
-rw-r--r--src/dso.c17
-rw-r--r--src/gstreamer.c28
-rw-r--r--src/multi.c29
-rw-r--r--src/oss.c29
-rw-r--r--src/pulse.c30
10 files changed, 194 insertions, 1 deletions
diff --git a/gtkdoc/libcanberra-sections.txt b/gtkdoc/libcanberra-sections.txt
index 326faa1..60094a0 100644
--- a/gtkdoc/libcanberra-sections.txt
+++ b/gtkdoc/libcanberra-sections.txt
@@ -63,6 +63,7 @@ ca_context_play_full
ca_context_cancel
ca_context_cache
ca_context_cache_full
+ca_context_playing
<SUBSECTION>
ca_strerror
diff --git a/src/alsa.c b/src/alsa.c
index 5f35e8b..e9647c5 100644
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -521,3 +521,32 @@ int driver_cancel(ca_context *c, uint32_t id) {
return CA_SUCCESS;
}
+
+int driver_playing(ca_context *c, uint32_t id, int *playing) {
+ struct private *p;
+ struct outstanding *out;
+
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(c->private, CA_ERROR_STATE);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+
+ p = PRIVATE(c);
+
+ *playing = 0;
+
+ ca_mutex_lock(p->outstanding_mutex);
+
+ for (out = p->outstanding; out; out = out->next) {
+
+ if (out->dead ||
+ out->id != id)
+ continue;
+
+ *playing = 1;
+ break;
+ }
+
+ ca_mutex_unlock(p->outstanding_mutex);
+
+ return CA_SUCCESS;
+}
diff --git a/src/canberra.h.in b/src/canberra.h.in
index 5bf76b2..5bf198a 100644
--- a/src/canberra.h.in
+++ b/src/canberra.h.in
@@ -485,6 +485,7 @@ int ca_context_play(ca_context *c, uint32_t id, ...) __attribute__((sentinel));
int ca_context_cache_full(ca_context *c, ca_proplist *p);
int ca_context_cache(ca_context *c, ...) __attribute__((sentinel));
int ca_context_cancel(ca_context *c, uint32_t id);
+int ca_context_playing(ca_context *c, uint32_t id, int *playing);
const char *ca_strerror(int code);
diff --git a/src/common.c b/src/common.c
index e2548ec..db60aa0 100644
--- a/src/common.c
+++ b/src/common.c
@@ -689,3 +689,32 @@ int ca_parse_cache_control(ca_cache_control_t *control, const char *c) {
return CA_SUCCESS;
}
+
+/**
+ * ca_context_playing:
+ * @c: the context to check if sound is still playing
+ * @id: the id that identify the sounds to check
+ * @playing: a pointer to a boolean that will be updated with the play status
+ *
+ * Check if at least one sound with the specified id is still
+ * playing. Returns 0 in *playing if no sound with this id is playing
+ * anymore or non-zero if there is at least one playing.
+ *
+ * Returns: 0 on success, negative error code on error.
+ * Since: 0.16
+ */
+int ca_context_playing(ca_context *c, uint32_t id, int *playing) {
+ int ret;
+
+ ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED);
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+ ca_mutex_lock(c->mutex);
+ ca_return_val_if_fail_unlock(c->opened, CA_ERROR_STATE, c->mutex);
+
+ ret = driver_playing(c, id, playing);
+
+ ca_mutex_unlock(c->mutex);
+
+ return ret;
+}
diff --git a/src/driver.h b/src/driver.h
index 98b40d7..c843b8d 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -33,4 +33,6 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t
int driver_cancel(ca_context *c, uint32_t id);
int driver_cache(ca_context *c, ca_proplist *p);
+int driver_playing(ca_context *c, uint32_t id, int *playing);
+
#endif
diff --git a/src/dso.c b/src/dso.c
index c9c2a15..97c04d4 100644
--- a/src/dso.c
+++ b/src/dso.c
@@ -42,6 +42,7 @@ struct private_dso {
int (*driver_play)(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t cb, void *userdata);
int (*driver_cancel)(ca_context *c, uint32_t id);
int (*driver_cache)(ca_context *c, ca_proplist *p);
+ int (*driver_playing)(ca_context *c, uint32_t id, int *playing);
};
#define PRIVATE_DSO(c) ((struct private_dso *) ((c)->private_dso))
@@ -257,7 +258,8 @@ int driver_open(ca_context *c) {
!(p->driver_change_props = GET_FUNC_PTR(p->module, driver, "driver_change_props", int, (ca_context *, ca_proplist *, ca_proplist *))) ||
!(p->driver_play = GET_FUNC_PTR(p->module, driver, "driver_play", int, (ca_context*, uint32_t, ca_proplist *, ca_finish_callback_t, void *))) ||
!(p->driver_cancel = GET_FUNC_PTR(p->module, driver, "driver_cancel", int, (ca_context*, uint32_t))) ||
- !(p->driver_cache = GET_FUNC_PTR(p->module, driver, "driver_cache", int, (ca_context*, ca_proplist *)))) {
+ !(p->driver_cache = GET_FUNC_PTR(p->module, driver, "driver_cache", int, (ca_context*, ca_proplist *))) ||
+ !(p->driver_playing = GET_FUNC_PTR(p->module, driver, "driver_playing", int, (ca_context*, uint32_t, int*)))) {
ca_free(driver);
driver_destroy(c);
@@ -361,3 +363,16 @@ int driver_cache(ca_context *c, ca_proplist *pl) {
return p->driver_cache(c, pl);
}
+
+int driver_playing(ca_context *c, uint32_t id, int *playing) {
+ struct private_dso *p;
+
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+
+ p = PRIVATE_DSO(c);
+ ca_return_val_if_fail(p->driver_playing, CA_ERROR_STATE);
+
+ return p->driver_playing(c, id, playing);
+}
diff --git a/src/gstreamer.c b/src/gstreamer.c
index 4173479..5ff835c 100644
--- a/src/gstreamer.c
+++ b/src/gstreamer.c
@@ -552,3 +552,31 @@ int driver_cache(ca_context *c, ca_proplist *proplist) {
return CA_ERROR_NOTSUPPORTED;
}
+
+int driver_playing(ca_context *c, uint32_t id, int *playing) {
+ struct private *p;
+ struct outstanding *out;
+
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(c->private, CA_ERROR_STATE);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+
+ p = PRIVATE(c);
+
+ *playing = 0;
+
+ ca_mutex_lock(p->outstanding_mutex);
+
+ for (out = p->outstanding; out; out = out->next) {
+
+ if (out->id != id || out->pipeline == NULL || out->dead == TRUE)
+ continue;
+
+ *playing = 1;
+ break;
+ }
+
+ ca_mutex_unlock(p->outstanding_mutex);
+
+ return CA_SUCCESS;
+}
diff --git a/src/multi.c b/src/multi.c
index 598b1f2..233e635 100644
--- a/src/multi.c
+++ b/src/multi.c
@@ -330,3 +330,32 @@ int driver_cache(ca_context *c, ca_proplist *proplist) {
return ret;
}
+
+int driver_playing(ca_context *c, uint32_t id, int *playing) {
+ int ret = CA_SUCCESS;
+ struct private *p;
+ struct backend *b;
+
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+ ca_return_val_if_fail(c->private, CA_ERROR_STATE);
+
+ p = PRIVATE(c);
+
+ *playing = 0;
+
+ for (b = p->backends; b; b = b->next) {
+ int r, _playing = 0;
+
+ r = ca_context_playing(b->context, id, &_playing);
+
+ /* We only return the first failure */
+ if (ret == CA_SUCCESS)
+ ret = r;
+
+ if (_playing)
+ *playing = 1;
+ }
+
+ return ret;
+}
diff --git a/src/oss.c b/src/oss.c
index 6135780..eebc2f8 100644
--- a/src/oss.c
+++ b/src/oss.c
@@ -499,3 +499,32 @@ int driver_cancel(ca_context *c, uint32_t id) {
return CA_SUCCESS;
}
+
+int driver_playing(ca_context *c, uint32_t id, int *playing) {
+ struct private *p;
+ struct outstanding *out;
+
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(c->private, CA_ERROR_STATE);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+
+ p = PRIVATE(c);
+
+ *playing = 0;
+
+ ca_mutex_lock(p->outstanding_mutex);
+
+ for (out = p->outstanding; out; out = out->next) {
+
+ if (out->dead ||
+ out->id != id)
+ continue;
+
+ *playing = 1;
+ break;
+ }
+
+ ca_mutex_unlock(p->outstanding_mutex);
+
+ return CA_SUCCESS;
+}
diff --git a/src/pulse.c b/src/pulse.c
index 2a61c8f..2283b68 100644
--- a/src/pulse.c
+++ b/src/pulse.c
@@ -1271,3 +1271,33 @@ finish_unlocked:
return ret;
}
+
+int driver_playing(ca_context *c, uint32_t id, int *playing) {
+ struct private *p;
+ struct outstanding *out;
+
+ ca_return_val_if_fail(c, CA_ERROR_INVALID);
+ ca_return_val_if_fail(c->private, CA_ERROR_STATE);
+ ca_return_val_if_fail(playing, CA_ERROR_INVALID);
+
+ p = PRIVATE(c);
+
+ *playing = 0;
+
+ ca_mutex_lock(p->outstanding_mutex);
+
+ for (out = p->outstanding; out; out = out->next) {
+
+ if (out->type == OUTSTANDING_UPLOAD ||
+ out->id != id ||
+ out->sink_input == PA_INVALID_INDEX)
+ continue;
+
+ *playing = 1;
+ break;
+ }
+
+ ca_mutex_unlock(p->outstanding_mutex);
+
+ return CA_SUCCESS;
+}