From d22b71af47b44c1c1d84195743c34b589e6ab19c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 20 Feb 2010 00:47:45 +0100 Subject: src: reindent for 8ch indenting I am slowly moving all my projects to kernel-inspired 8ch indenting. This will break patches that haven't been merged yet, which I am aware of, but OTOH in times of git's --ignore-space-change shouldn't be too problematic. Yes, I am aware that reindenting like this sucks, but I cannot stand 4ch indenting anymore. Sorry. --- src/alsa.c | 660 ++++++++--------- src/cache.c | 748 +++++++++---------- src/cache.h | 26 +- src/canberra-gtk-module.c | 1326 ++++++++++++++++----------------- src/canberra-gtk-play.c | 256 +++---- src/canberra-gtk.c | 510 ++++++------- src/canberra-gtk.h | 2 + src/canberra.h.in | 48 +- src/common.c | 502 ++++++------- src/common.h | 22 +- src/driver-order.c | 14 +- src/driver-order.h | 2 + src/driver.h | 2 + src/dso.c | 450 ++++++------ src/fork-detect.c | 32 +- src/fork-detect.h | 2 + src/gstreamer.c | 819 ++++++++++----------- src/llist.h | 124 ++-- src/macro.c | 10 +- src/macro.h | 130 ++-- src/malloc.c | 84 +-- src/malloc.h | 2 + src/multi.c | 416 +++++------ src/mutex-posix.c | 48 +- src/mutex.h | 2 + src/null.c | 46 +- src/oss.c | 612 ++++++++-------- src/proplist.c | 412 +++++------ src/proplist.h | 14 +- src/pulse.c | 1776 +++++++++++++++++++++++---------------------- src/read-sound-file.c | 232 +++--- src/read-sound-file.h | 48 +- src/read-vorbis.c | 234 +++--- src/read-vorbis.h | 2 + src/read-wav.c | 426 +++++------ src/read-wav.h | 2 + src/sound-theme-spec.c | 1206 +++++++++++++++--------------- src/sound-theme-spec.h | 2 + src/test-canberra.c | 125 ++-- 39 files changed, 5727 insertions(+), 5647 deletions(-) diff --git a/src/alsa.c b/src/alsa.c index e9647c5..d982203 100644 --- a/src/alsa.c +++ b/src/alsa.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -40,513 +42,513 @@ struct private; struct outstanding { - CA_LLIST_FIELDS(struct outstanding); - ca_bool_t dead; - uint32_t id; - ca_finish_callback_t callback; - void *userdata; - ca_sound_file *file; - snd_pcm_t *pcm; - int pipe_fd[2]; - ca_context *context; + CA_LLIST_FIELDS(struct outstanding); + ca_bool_t dead; + uint32_t id; + ca_finish_callback_t callback; + void *userdata; + ca_sound_file *file; + snd_pcm_t *pcm; + int pipe_fd[2]; + ca_context *context; }; struct private { - ca_theme_data *theme; - ca_mutex *outstanding_mutex; - ca_bool_t signal_semaphore; - sem_t semaphore; - ca_bool_t semaphore_allocated; - CA_LLIST_HEAD(struct outstanding, outstanding); + ca_theme_data *theme; + ca_mutex *outstanding_mutex; + ca_bool_t signal_semaphore; + sem_t semaphore; + ca_bool_t semaphore_allocated; + CA_LLIST_HEAD(struct outstanding, outstanding); }; #define PRIVATE(c) ((struct private *) ((c)->private)) static void outstanding_free(struct outstanding *o) { - ca_assert(o); + ca_assert(o); - if (o->pipe_fd[1] >= 0) - close(o->pipe_fd[1]); + if (o->pipe_fd[1] >= 0) + close(o->pipe_fd[1]); - if (o->pipe_fd[0] >= 0) - close(o->pipe_fd[0]); + if (o->pipe_fd[0] >= 0) + close(o->pipe_fd[0]); - if (o->file) - ca_sound_file_close(o->file); + if (o->file) + ca_sound_file_close(o->file); - if (o->pcm) - snd_pcm_close(o->pcm); + if (o->pcm) + snd_pcm_close(o->pcm); - ca_free(o); + ca_free(o); } int driver_open(ca_context *c) { - struct private *p; + struct private *p; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "alsa"), CA_ERROR_NODRIVER); - ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "alsa"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); - if (!(c->private = p = ca_new0(struct private, 1))) - return CA_ERROR_OOM; + if (!(c->private = p = ca_new0(struct private, 1))) + return CA_ERROR_OOM; - if (!(p->outstanding_mutex = ca_mutex_new())) { - driver_destroy(c); - return CA_ERROR_OOM; - } + if (!(p->outstanding_mutex = ca_mutex_new())) { + driver_destroy(c); + return CA_ERROR_OOM; + } - if (sem_init(&p->semaphore, 0, 0) < 0) { - driver_destroy(c); - return CA_ERROR_OOM; - } + if (sem_init(&p->semaphore, 0, 0) < 0) { + driver_destroy(c); + return CA_ERROR_OOM; + } - p->semaphore_allocated = TRUE; + p->semaphore_allocated = TRUE; - return CA_SUCCESS; + return CA_SUCCESS; } int driver_destroy(ca_context *c) { - struct private *p; - struct outstanding *out; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - if (p->outstanding_mutex) { - ca_mutex_lock(p->outstanding_mutex); + if (p->outstanding_mutex) { + ca_mutex_lock(p->outstanding_mutex); - /* Tell all player threads to terminate */ - for (out = p->outstanding; out; out = out->next) { + /* Tell all player threads to terminate */ + for (out = p->outstanding; out; out = out->next) { - if (out->dead) - continue; + if (out->dead) + continue; - out->dead = TRUE; + out->dead = TRUE; - if (out->callback) - out->callback(c, out->id, CA_ERROR_DESTROYED, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_ERROR_DESTROYED, out->userdata); - /* This will cause the thread to wakeup and terminate */ - if (out->pipe_fd[1] >= 0) { - close(out->pipe_fd[1]); - out->pipe_fd[1] = -1; - } - } + /* This will cause the thread to wakeup and terminate */ + if (out->pipe_fd[1] >= 0) { + close(out->pipe_fd[1]); + out->pipe_fd[1] = -1; + } + } + + if (p->semaphore_allocated) { + /* Now wait until all players are destroyed */ + p->signal_semaphore = TRUE; + while (p->outstanding) { + ca_mutex_unlock(p->outstanding_mutex); + sem_wait(&p->semaphore); + ca_mutex_lock(p->outstanding_mutex); + } + } - if (p->semaphore_allocated) { - /* Now wait until all players are destroyed */ - p->signal_semaphore = TRUE; - while (p->outstanding) { ca_mutex_unlock(p->outstanding_mutex); - sem_wait(&p->semaphore); - ca_mutex_lock(p->outstanding_mutex); - } + ca_mutex_free(p->outstanding_mutex); } - ca_mutex_unlock(p->outstanding_mutex); - ca_mutex_free(p->outstanding_mutex); - } - - if (p->theme) - ca_theme_data_free(p->theme); + if (p->theme) + ca_theme_data_free(p->theme); - if (p->semaphore_allocated) - sem_destroy(&p->semaphore); + if (p->semaphore_allocated) + sem_destroy(&p->semaphore); - ca_free(p); + ca_free(p); - c->private = NULL; + c->private = NULL; - snd_config_update_free_global(); + snd_config_update_free_global(); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_device(ca_context *c, const char *device) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(changed, CA_ERROR_INVALID); - ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_cache(ca_context *c, ca_proplist *proplist) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; } static int translate_error(int error) { - switch (error) { + switch (error) { case -ENODEV: case -ENOENT: - return CA_ERROR_NOTFOUND; + return CA_ERROR_NOTFOUND; case -EACCES: case -EPERM: - return CA_ERROR_ACCESS; + return CA_ERROR_ACCESS; case -ENOMEM: - return CA_ERROR_OOM; + return CA_ERROR_OOM; case -EBUSY: - return CA_ERROR_NOTAVAILABLE; + return CA_ERROR_NOTAVAILABLE; case -EINVAL: - return CA_ERROR_INVALID; + return CA_ERROR_INVALID; case -ENOSYS: - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; default: - if (ca_debug()) - fprintf(stderr, "Got unhandled error from ALSA: %s\n", snd_strerror(error)); - return CA_ERROR_IO; - } + if (ca_debug()) + fprintf(stderr, "Got unhandled error from ALSA: %s\n", snd_strerror(error)); + return CA_ERROR_IO; + } } static const snd_pcm_format_t sample_type_table[] = { #ifdef WORDS_BIGENDIAN - [CA_SAMPLE_S16NE] = SND_PCM_FORMAT_S16_BE, - [CA_SAMPLE_S16RE] = SND_PCM_FORMAT_S16_LE, + [CA_SAMPLE_S16NE] = SND_PCM_FORMAT_S16_BE, + [CA_SAMPLE_S16RE] = SND_PCM_FORMAT_S16_LE, #else - [CA_SAMPLE_S16NE] = SND_PCM_FORMAT_S16_LE, - [CA_SAMPLE_S16RE] = SND_PCM_FORMAT_S16_BE, + [CA_SAMPLE_S16NE] = SND_PCM_FORMAT_S16_LE, + [CA_SAMPLE_S16RE] = SND_PCM_FORMAT_S16_BE, #endif - [CA_SAMPLE_U8] = SND_PCM_FORMAT_U8 + [CA_SAMPLE_U8] = SND_PCM_FORMAT_U8 }; static int open_alsa(ca_context *c, struct outstanding *out) { - struct private *p; - int ret; - snd_pcm_hw_params_t *hwparams; - unsigned rate; + struct private *p; + int ret; + snd_pcm_hw_params_t *hwparams; + unsigned rate; - snd_pcm_hw_params_alloca(&hwparams); + snd_pcm_hw_params_alloca(&hwparams); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - ca_return_val_if_fail(out, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(out, CA_ERROR_INVALID); - /* In ALSA we need to open different devices for doing - * multichannel audio. This cnnot be done in a backend-independant - * wa, hence we limit ourselves to mono/stereo only. */ - ca_return_val_if_fail(ca_sound_file_get_nchannels(out->file) <= 2, CA_ERROR_NOTSUPPORTED); + /* In ALSA we need to open different devices for doing + * multichannel audio. This cnnot be done in a backend-independant + * wa, hence we limit ourselves to mono/stereo only. */ + ca_return_val_if_fail(ca_sound_file_get_nchannels(out->file) <= 2, CA_ERROR_NOTSUPPORTED); - p = PRIVATE(c); + p = PRIVATE(c); - if ((ret = snd_pcm_open(&out->pcm, c->device ? c->device : "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) - goto finish; + if ((ret = snd_pcm_open(&out->pcm, c->device ? c->device : "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) + goto finish; - if ((ret = snd_pcm_hw_params_any(out->pcm, hwparams)) < 0) - goto finish; + if ((ret = snd_pcm_hw_params_any(out->pcm, hwparams)) < 0) + goto finish; - if ((ret = snd_pcm_hw_params_set_access(out->pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) - goto finish; + if ((ret = snd_pcm_hw_params_set_access(out->pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + goto finish; - if ((ret = snd_pcm_hw_params_set_format(out->pcm, hwparams, sample_type_table[ca_sound_file_get_sample_type(out->file)])) < 0) - goto finish; + if ((ret = snd_pcm_hw_params_set_format(out->pcm, hwparams, sample_type_table[ca_sound_file_get_sample_type(out->file)])) < 0) + goto finish; - rate = ca_sound_file_get_rate(out->file); - if ((ret = snd_pcm_hw_params_set_rate_near(out->pcm, hwparams, &rate, 0)) < 0) - goto finish; + rate = ca_sound_file_get_rate(out->file); + if ((ret = snd_pcm_hw_params_set_rate_near(out->pcm, hwparams, &rate, 0)) < 0) + goto finish; - if ((ret = snd_pcm_hw_params_set_channels(out->pcm, hwparams, ca_sound_file_get_nchannels(out->file))) < 0) - goto finish; + if ((ret = snd_pcm_hw_params_set_channels(out->pcm, hwparams, ca_sound_file_get_nchannels(out->file))) < 0) + goto finish; - if ((ret = snd_pcm_hw_params(out->pcm, hwparams)) < 0) - goto finish; + if ((ret = snd_pcm_hw_params(out->pcm, hwparams)) < 0) + goto finish; - if ((ret = snd_pcm_prepare(out->pcm)) < 0) - goto finish; + if ((ret = snd_pcm_prepare(out->pcm)) < 0) + goto finish; - return CA_SUCCESS; + return CA_SUCCESS; finish: - return translate_error(ret); + return translate_error(ret); } #define BUFSIZE (16*1024) static void* thread_func(void *userdata) { - struct outstanding *out = userdata; - int ret; - void *data, *d = NULL; - size_t fs, data_size; - size_t nbytes = 0; - struct pollfd *pfd = NULL; - nfds_t n_pfd; - struct private *p; - - p = PRIVATE(out->context); - - pthread_detach(pthread_self()); - - fs = ca_sound_file_frame_size(out->file); - data_size = (BUFSIZE/fs)*fs; - - if (!(data = ca_malloc(data_size))) { - ret = CA_ERROR_OOM; - goto finish; - } - - if ((ret = snd_pcm_poll_descriptors_count(out->pcm)) < 0) { - ret = translate_error(ret); - goto finish; - } - - n_pfd = (nfds_t) ret + 1; - if (!(pfd = ca_new(struct pollfd, n_pfd))) { - ret = CA_ERROR_OOM; - goto finish; - } - - if ((ret = snd_pcm_poll_descriptors(out->pcm, pfd+1, (unsigned) n_pfd-1)) < 0) { - ret = translate_error(ret); - goto finish; - } - - pfd[0].fd = out->pipe_fd[0]; - pfd[0].events = POLLIN; - pfd[0].revents = 0; - - for (;;) { - unsigned short revents; - snd_pcm_sframes_t sframes; - - if (out->dead) - break; - - if (poll(pfd, n_pfd, -1) < 0) { - ret = CA_ERROR_SYSTEM; - goto finish; + struct outstanding *out = userdata; + int ret; + void *data, *d = NULL; + size_t fs, data_size; + size_t nbytes = 0; + struct pollfd *pfd = NULL; + nfds_t n_pfd; + struct private *p; + + p = PRIVATE(out->context); + + pthread_detach(pthread_self()); + + fs = ca_sound_file_frame_size(out->file); + data_size = (BUFSIZE/fs)*fs; + + if (!(data = ca_malloc(data_size))) { + ret = CA_ERROR_OOM; + goto finish; } - /* We have been asked to shut down */ - if (pfd[0].revents) - break; + if ((ret = snd_pcm_poll_descriptors_count(out->pcm)) < 0) { + ret = translate_error(ret); + goto finish; + } - if ((ret = snd_pcm_poll_descriptors_revents(out->pcm, pfd+1, (unsigned) n_pfd-1, &revents)) < 0) { - ret = translate_error(ret); - goto finish; + n_pfd = (nfds_t) ret + 1; + if (!(pfd = ca_new(struct pollfd, n_pfd))) { + ret = CA_ERROR_OOM; + goto finish; } - if (revents != POLLOUT) { + if ((ret = snd_pcm_poll_descriptors(out->pcm, pfd+1, (unsigned) n_pfd-1)) < 0) { + ret = translate_error(ret); + goto finish; + } - switch (snd_pcm_state(out->pcm)) { + pfd[0].fd = out->pipe_fd[0]; + pfd[0].events = POLLIN; + pfd[0].revents = 0; - case SND_PCM_STATE_XRUN: + for (;;) { + unsigned short revents; + snd_pcm_sframes_t sframes; - if ((ret = snd_pcm_recover(out->pcm, -EPIPE, 1)) != 0) { - ret = translate_error(ret); + if (out->dead) + break; + + if (poll(pfd, n_pfd, -1) < 0) { + ret = CA_ERROR_SYSTEM; goto finish; - } - break; + } - case SND_PCM_STATE_SUSPENDED: + /* We have been asked to shut down */ + if (pfd[0].revents) + break; - if ((ret = snd_pcm_recover(out->pcm, -ESTRPIPE, 1)) != 0) { + if ((ret = snd_pcm_poll_descriptors_revents(out->pcm, pfd+1, (unsigned) n_pfd-1, &revents)) < 0) { ret = translate_error(ret); goto finish; - } - break; + } - default: + if (revents != POLLOUT) { - snd_pcm_drop(out->pcm); + switch (snd_pcm_state(out->pcm)) { - if ((ret = snd_pcm_prepare(out->pcm)) < 0) { - ret = translate_error(ret); - goto finish; - } - break; - } + case SND_PCM_STATE_XRUN: - continue; - } + if ((ret = snd_pcm_recover(out->pcm, -EPIPE, 1)) != 0) { + ret = translate_error(ret); + goto finish; + } + break; - if (nbytes <= 0) { + case SND_PCM_STATE_SUSPENDED: - nbytes = data_size; + if ((ret = snd_pcm_recover(out->pcm, -ESTRPIPE, 1)) != 0) { + ret = translate_error(ret); + goto finish; + } + break; - if ((ret = ca_sound_file_read_arbitrary(out->file, data, &nbytes)) < 0) - goto finish; + default: - d = data; - } + snd_pcm_drop(out->pcm); - if (nbytes <= 0) { - snd_pcm_drain(out->pcm); - break; - } + if ((ret = snd_pcm_prepare(out->pcm)) < 0) { + ret = translate_error(ret); + goto finish; + } + break; + } - if ((sframes = snd_pcm_writei(out->pcm, d, nbytes/fs)) < 0) { + continue; + } - if ((ret = snd_pcm_recover(out->pcm, (int) sframes, 1)) < 0) { - ret = translate_error(ret); - goto finish; - } + if (nbytes <= 0) { - continue; - } + nbytes = data_size; + + if ((ret = ca_sound_file_read_arbitrary(out->file, data, &nbytes)) < 0) + goto finish; - nbytes -= (size_t) sframes*fs; - d = (uint8_t*) d + (size_t) sframes*fs; - } + d = data; + } - ret = CA_SUCCESS; + if (nbytes <= 0) { + snd_pcm_drain(out->pcm); + break; + } + + if ((sframes = snd_pcm_writei(out->pcm, d, nbytes/fs)) < 0) { + + if ((ret = snd_pcm_recover(out->pcm, (int) sframes, 1)) < 0) { + ret = translate_error(ret); + goto finish; + } + + continue; + } + + nbytes -= (size_t) sframes*fs; + d = (uint8_t*) d + (size_t) sframes*fs; + } + + ret = CA_SUCCESS; finish: - ca_free(data); - ca_free(pfd); + ca_free(data); + ca_free(pfd); - if (!out->dead) - if (out->callback) - out->callback(out->context, out->id, ret, out->userdata); + if (!out->dead) + if (out->callback) + out->callback(out->context, out->id, ret, out->userdata); - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - if (!p->outstanding && p->signal_semaphore) - sem_post(&p->semaphore); + if (!p->outstanding && p->signal_semaphore) + sem_post(&p->semaphore); - outstanding_free(out); + outstanding_free(out); - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return NULL; + return NULL; } int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { - struct private *p; - struct outstanding *out = NULL; - int ret; - pthread_t thread; + struct private *p; + struct outstanding *out = NULL; + int ret; + pthread_t thread; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - if (!(out = ca_new0(struct outstanding, 1))) { - ret = CA_ERROR_OOM; - goto finish; - } - - out->context = c; - out->id = id; - out->callback = cb; - out->userdata = userdata; - out->pipe_fd[0] = out->pipe_fd[1] = -1; - - if (pipe(out->pipe_fd) < 0) { - ret = CA_ERROR_SYSTEM; - goto finish; - } + if (!(out = ca_new0(struct outstanding, 1))) { + ret = CA_ERROR_OOM; + goto finish; + } - if ((ret = ca_lookup_sound(&out->file, NULL, &p->theme, c->props, proplist)) < 0) - goto finish; + out->context = c; + out->id = id; + out->callback = cb; + out->userdata = userdata; + out->pipe_fd[0] = out->pipe_fd[1] = -1; - if ((ret = open_alsa(c, out)) < 0) - goto finish; + if (pipe(out->pipe_fd) < 0) { + ret = CA_ERROR_SYSTEM; + goto finish; + } - /* OK, we're ready to go, so let's add this to our list */ - ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + if ((ret = ca_lookup_sound(&out->file, NULL, &p->theme, c->props, proplist)) < 0) + goto finish; - if (pthread_create(&thread, NULL, thread_func, out) < 0) { - ret = CA_ERROR_OOM; + if ((ret = open_alsa(c, out)) < 0) + goto finish; + /* OK, we're ready to go, so let's add this to our list */ ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); ca_mutex_unlock(p->outstanding_mutex); - goto finish; - } + if (pthread_create(&thread, NULL, thread_func, out) < 0) { + ret = CA_ERROR_OOM; - ret = CA_SUCCESS; + ca_mutex_lock(p->outstanding_mutex); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); + + goto finish; + } + + ret = CA_SUCCESS; finish: - /* We keep the outstanding struct around if we need clean up later to */ - if (ret != CA_SUCCESS) - outstanding_free(out); + /* We keep the outstanding struct around if we need clean up later to */ + if (ret != CA_SUCCESS) + outstanding_free(out); - return ret; + return ret; } int driver_cancel(ca_context *c, uint32_t id) { - struct private *p; - struct outstanding *out; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = out->next) { + for (out = p->outstanding; out; out = out->next) { - if (out->id != id) - continue; + if (out->id != id) + continue; - if (out->dead) - continue; + if (out->dead) + continue; - out->dead = TRUE; + out->dead = TRUE; - if (out->callback) - out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); - /* This will cause the thread to wakeup and terminate */ - if (out->pipe_fd[1] >= 0) { - close(out->pipe_fd[1]); - out->pipe_fd[1] = -1; + /* This will cause the thread to wakeup and terminate */ + if (out->pipe_fd[1] >= 0) { + close(out->pipe_fd[1]); + out->pipe_fd[1] = -1; + } } - } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_playing(ca_context *c, uint32_t id, int *playing) { - struct private *p; - struct outstanding *out; + 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); + 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); + p = PRIVATE(c); - *playing = 0; + *playing = 0; - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = out->next) { + for (out = p->outstanding; out; out = out->next) { - if (out->dead || - out->id != id) - continue; + if (out->dead || + out->id != id) + continue; - *playing = 1; - break; - } + *playing = 1; + break; + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; } diff --git a/src/cache.c b/src/cache.c index 3579323..bf2d2a0 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -49,174 +51,174 @@ static ca_mutex *mutex = NULL; static struct tdb_context *database = NULL; static void allocate_mutex_once(void) { - mutex = ca_mutex_new(); + mutex = ca_mutex_new(); } static int allocate_mutex(void) { - static pthread_once_t once = PTHREAD_ONCE_INIT; + static pthread_once_t once = PTHREAD_ONCE_INIT; - if (pthread_once(&once, allocate_mutex_once) != 0) - return CA_ERROR_OOM; + if (pthread_once(&once, allocate_mutex_once) != 0) + return CA_ERROR_OOM; - if (!mutex) - return CA_ERROR_OOM; + if (!mutex) + return CA_ERROR_OOM; - return 0; + return 0; } static int get_cache_home(char **e) { - const char *env, *subdir; - char *r; - - ca_return_val_if_fail(e, CA_ERROR_INVALID); - - if ((env = getenv("XDG_CACHE_HOME")) && *env == '/') - subdir = ""; - else if ((env = getenv("HOME")) && *env == '/') - subdir = "/.cache"; - else { - *e = NULL; - return CA_SUCCESS; - } + const char *env, *subdir; + char *r; + + ca_return_val_if_fail(e, CA_ERROR_INVALID); + + if ((env = getenv("XDG_CACHE_HOME")) && *env == '/') + subdir = ""; + else if ((env = getenv("HOME")) && *env == '/') + subdir = "/.cache"; + else { + *e = NULL; + return CA_SUCCESS; + } - if (!(r = ca_new(char, strlen(env) + strlen(subdir) + 1))) - return CA_ERROR_OOM; + if (!(r = ca_new(char, strlen(env) + strlen(subdir) + 1))) + return CA_ERROR_OOM; - sprintf(r, "%s%s", env, subdir); - *e = r; + sprintf(r, "%s%s", env, subdir); + *e = r; - return CA_SUCCESS; + return CA_SUCCESS; } static int sensible_gethostbyname(char *n, size_t l) { - if (gethostname(n, l) < 0) - return -1; + if (gethostname(n, l) < 0) + return -1; - n[l-1] = 0; + n[l-1] = 0; - if (strlen(n) >= l-1) { - errno = ENAMETOOLONG; - return -1; - } + if (strlen(n) >= l-1) { + errno = ENAMETOOLONG; + return -1; + } - if (!n[0]) { - errno = ENOENT; - return -1; - } + if (!n[0]) { + errno = ENOENT; + return -1; + } - return 0; + return 0; } static int get_machine_id(char **id) { - FILE *f; - size_t l; + FILE *f; + size_t l; - ca_return_val_if_fail(id, CA_ERROR_INVALID); + ca_return_val_if_fail(id, CA_ERROR_INVALID); - /* First we try the D-Bus machine id */ + /* First we try the D-Bus machine id */ - if ((f = fopen(CA_MACHINE_ID, "r"))) { - char ln[34] = "", *r; + if ((f = fopen(CA_MACHINE_ID, "r"))) { + char ln[34] = "", *r; - r = fgets(ln, sizeof(ln)-1, f); - fclose(f); + r = fgets(ln, sizeof(ln)-1, f); + fclose(f); - if (r) { - ln[strcspn(ln, " \n\r\t")] = 0; + if (r) { + ln[strcspn(ln, " \n\r\t")] = 0; - if (!(*id = ca_strdup(ln))) - return CA_ERROR_OOM; + if (!(*id = ca_strdup(ln))) + return CA_ERROR_OOM; - return CA_SUCCESS; + return CA_SUCCESS; + } } - } - /* Then we try the host name */ + /* Then we try the host name */ - l = 100; + l = 100; - for (;;) { - if (!(*id = ca_new(char, l))) - return CA_ERROR_OOM; + for (;;) { + if (!(*id = ca_new(char, l))) + return CA_ERROR_OOM; - if (sensible_gethostbyname(*id, l) >= 0) - return CA_SUCCESS; + if (sensible_gethostbyname(*id, l) >= 0) + return CA_SUCCESS; - ca_free(*id); + ca_free(*id); - if (errno != EINVAL && errno != ENAMETOOLONG) - break; + if (errno != EINVAL && errno != ENAMETOOLONG) + break; - l *= 2; - } + l *= 2; + } - /* Then we use the POSIX host id */ + /* Then we use the POSIX host id */ - *id = ca_sprintf_malloc("%08lx", (unsigned long) gethostid()); - return CA_SUCCESS; + *id = ca_sprintf_malloc("%08lx", (unsigned long) gethostid()); + return CA_SUCCESS; } static int db_open(void) { - int ret; - char *c, *id, *pn; + int ret; + char *c, *id, *pn; - if ((ret = allocate_mutex()) < 0) - return ret; + if ((ret = allocate_mutex()) < 0) + return ret; - ca_mutex_lock(mutex); + ca_mutex_lock(mutex); - if (database) { - ret = CA_SUCCESS; - goto finish; - } + if (database) { + ret = CA_SUCCESS; + goto finish; + } - if ((ret = get_cache_home(&c)) < 0) - goto finish; + if ((ret = get_cache_home(&c)) < 0) + goto finish; + + /* Try to create, just in case it doesn't exist yet. We don't do + * this recursively however. */ + mkdir(c, 0755); + + if ((ret = get_machine_id(&id)) < 0) { + ca_free(c); + goto finish; + } - /* Try to create, just in case it doesn't exist yet. We don't do - * this recursively however. */ - mkdir(c, 0755); + /* This data is machine specific, hence we include some kind of + * stable machine id here in the name. Also, we don't want to care + * abouth endianess/packing issues, hence we include the compiler + * target in the name, too. */ - if ((ret = get_machine_id(&id)) < 0) { + pn = ca_sprintf_malloc("%s/" FILENAME ".%s." CANONICAL_HOST, c, id); ca_free(c); - goto finish; - } - - /* This data is machine specific, hence we include some kind of - * stable machine id here in the name. Also, we don't want to care - * abouth endianess/packing issues, hence we include the compiler - * target in the name, too. */ - - pn = ca_sprintf_malloc("%s/" FILENAME ".%s." CANONICAL_HOST, c, id); - ca_free(c); - ca_free(id); - - if (!pn) { - ret = CA_ERROR_OOM; - goto finish; - } - - /* We pass TDB_NOMMAP here as long as rhbz 460851 is not fixed in - * tdb. */ - database = tdb_open(pn, 0, TDB_NOMMAP, O_RDWR|O_CREAT|O_NOCTTY + ca_free(id); + + if (!pn) { + ret = CA_ERROR_OOM; + goto finish; + } + + /* We pass TDB_NOMMAP here as long as rhbz 460851 is not fixed in + * tdb. */ + database = tdb_open(pn, 0, TDB_NOMMAP, O_RDWR|O_CREAT|O_NOCTTY #ifdef O_CLOEXEC - | O_CLOEXEC + | O_CLOEXEC #endif - , 0644); - ca_free(pn); + , 0644); + ca_free(pn); - if (!database) { - ret = CA_ERROR_CORRUPT; - goto finish; - } + if (!database) { + ret = CA_ERROR_CORRUPT; + goto finish; + } - ret = CA_SUCCESS; + ret = CA_SUCCESS; finish: - ca_mutex_unlock(mutex); + ca_mutex_unlock(mutex); - return ret; + return ret; } #ifdef CA_GCC_DESTRUCTOR @@ -224,358 +226,358 @@ finish: static void db_close(void) CA_GCC_DESTRUCTOR; static void db_close(void) { - /* Only here to make this valgrind clean */ - if (mutex) { - ca_mutex_free(mutex); - mutex = NULL; - } - - if (database) { - tdb_close(database); - database = NULL; - } + /* Only here to make this valgrind clean */ + if (mutex) { + ca_mutex_free(mutex); + mutex = NULL; + } + + if (database) { + tdb_close(database); + database = NULL; + } } #endif static int db_lookup(const void *key, size_t klen, void **data, size_t *dlen) { - int ret; - TDB_DATA k, d; + int ret; + TDB_DATA k, d; - ca_return_val_if_fail(key, CA_ERROR_INVALID); - ca_return_val_if_fail(klen > 0, CA_ERROR_INVALID); - ca_return_val_if_fail(data, CA_ERROR_INVALID); - ca_return_val_if_fail(dlen, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(klen > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(data, CA_ERROR_INVALID); + ca_return_val_if_fail(dlen, CA_ERROR_INVALID); - if ((ret = db_open()) < 0) - return ret; + if ((ret = db_open()) < 0) + return ret; - k.dptr = (void*) key; - k.dsize = klen; + k.dptr = (void*) key; + k.dsize = klen; - ca_mutex_lock(mutex); + ca_mutex_lock(mutex); - ca_assert(database); - d = tdb_fetch(database, k); - if (!d.dptr) { - ret = CA_ERROR_NOTFOUND; - goto finish; - } + ca_assert(database); + d = tdb_fetch(database, k); + if (!d.dptr) { + ret = CA_ERROR_NOTFOUND; + goto finish; + } - *data = d.dptr; - *dlen = d.dsize; + *data = d.dptr; + *dlen = d.dsize; finish: - ca_mutex_unlock(mutex); + ca_mutex_unlock(mutex); - return ret; + return ret; } static int db_store(const void *key, size_t klen, const void *data, size_t dlen) { - int ret; - TDB_DATA k, d; + int ret; + TDB_DATA k, d; - ca_return_val_if_fail(key, CA_ERROR_INVALID); - ca_return_val_if_fail(klen > 0, CA_ERROR_INVALID); - ca_return_val_if_fail(data || dlen == 0, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(klen > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(data || dlen == 0, CA_ERROR_INVALID); - if ((ret = db_open()) < 0) - return ret; + if ((ret = db_open()) < 0) + return ret; - k.dptr = (void*) key; - k.dsize = klen; + k.dptr = (void*) key; + k.dsize = klen; - d.dptr = (void*) data; - d.dsize = dlen; + d.dptr = (void*) data; + d.dsize = dlen; - ca_mutex_lock(mutex); + ca_mutex_lock(mutex); - ca_assert(database); - if (tdb_store(database, k, d, TDB_REPLACE) < 0) { - ret = CA_ERROR_CORRUPT; - goto finish; - } + ca_assert(database); + if (tdb_store(database, k, d, TDB_REPLACE) < 0) { + ret = CA_ERROR_CORRUPT; + goto finish; + } - ret = CA_SUCCESS; + ret = CA_SUCCESS; finish: - ca_mutex_unlock(mutex); + ca_mutex_unlock(mutex); - return ret; + return ret; } static int db_remove(const void *key, size_t klen) { - int ret; - TDB_DATA k; + int ret; + TDB_DATA k; - ca_return_val_if_fail(key, CA_ERROR_INVALID); - ca_return_val_if_fail(klen > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(klen > 0, CA_ERROR_INVALID); - if ((ret = db_open()) < 0) - return ret; + if ((ret = db_open()) < 0) + return ret; - k.dptr = (void*) key; - k.dsize = klen; + k.dptr = (void*) key; + k.dsize = klen; - ca_mutex_lock(mutex); + ca_mutex_lock(mutex); - ca_assert(database); - if (tdb_delete(database, k) < 0) { - ret = CA_ERROR_CORRUPT; - goto finish; - } + ca_assert(database); + if (tdb_delete(database, k) < 0) { + ret = CA_ERROR_CORRUPT; + goto finish; + } - ret = CA_SUCCESS; + ret = CA_SUCCESS; finish: - ca_mutex_unlock(mutex); + ca_mutex_unlock(mutex); - return ret; + return ret; } static char *build_key( - const char *theme, - const char *name, - const char *locale, - const char *profile, - size_t *klen) { - - char *key, *k; - size_t tl, nl, ll, pl; - - tl = strlen(theme); - nl = strlen(name); - ll = strlen(locale); - pl = strlen(profile); - *klen = tl+1+nl+1+ll+1+pl+1; - - if (!(key = ca_new(char, *klen))) - return NULL; - - k = key; - strcpy(k, theme); - k += tl+1; - strcpy(k, name); - k += nl+1; - strcpy(k, locale); - k += ll+1; - strcpy(k, profile); - - return key; + const char *theme, + const char *name, + const char *locale, + const char *profile, + size_t *klen) { + + char *key, *k; + size_t tl, nl, ll, pl; + + tl = strlen(theme); + nl = strlen(name); + ll = strlen(locale); + pl = strlen(profile); + *klen = tl+1+nl+1+ll+1+pl+1; + + if (!(key = ca_new(char, *klen))) + return NULL; + + k = key; + strcpy(k, theme); + k += tl+1; + strcpy(k, name); + k += nl+1; + strcpy(k, locale); + k += ll+1; + strcpy(k, profile); + + return key; } static int get_last_change(time_t *t) { - int ret; - char *e, *k; - struct stat st; - static time_t last_check = 0, last_change = 0; - time_t now; - const char *g; + int ret; + char *e, *k; + struct stat st; + static time_t last_check = 0, last_change = 0; + time_t now; + const char *g; - ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(t, CA_ERROR_INVALID); - if ((ret = allocate_mutex()) < 0) - return ret; + if ((ret = allocate_mutex()) < 0) + return ret; - ca_mutex_lock(mutex); + ca_mutex_lock(mutex); - ca_assert_se(time(&now) != (time_t) -1); + ca_assert_se(time(&now) != (time_t) -1); - if (now < last_check + UPDATE_INTERVAL) { - *t = last_change; - ret = CA_SUCCESS; - goto finish; - } + if (now < last_check + UPDATE_INTERVAL) { + *t = last_change; + ret = CA_SUCCESS; + goto finish; + } + + if ((ret = ca_get_data_home(&e)) < 0) + goto finish; - if ((ret = ca_get_data_home(&e)) < 0) - goto finish; + if (!(k = ca_new(char, strlen(e) + sizeof("/sounds")))) { + ca_free(e); + ret = CA_ERROR_OOM; + goto finish; + } - if (!(k = ca_new(char, strlen(e) + sizeof("/sounds")))) { + sprintf(k, "%s/sounds", e); ca_free(e); - ret = CA_ERROR_OOM; - goto finish; - } - - sprintf(k, "%s/sounds", e); - ca_free(e); - if (stat(k, &st) >= 0) - *t = st.st_mtime; - else - *t = 0; + if (stat(k, &st) >= 0) + *t = st.st_mtime; + else + *t = 0; - ca_free(k); + ca_free(k); - g = ca_get_data_dirs(); + g = ca_get_data_dirs(); - for (;;) { - size_t j = strcspn(g, ":"); + for (;;) { + size_t j = strcspn(g, ":"); - if (g[0] == '/' && j > 0) { + if (g[0] == '/' && j > 0) { - if (!(k = ca_new(char, j + sizeof("/sounds")))) { - ret = CA_ERROR_OOM; - goto finish; - } + if (!(k = ca_new(char, j + sizeof("/sounds")))) { + ret = CA_ERROR_OOM; + goto finish; + } - memcpy(k, g, j); - strcpy(k+j, "/sounds"); + memcpy(k, g, j); + strcpy(k+j, "/sounds"); - if (stat(k, &st) >= 0) - if (st.st_mtime >= *t) - *t = st.st_mtime; + if (stat(k, &st) >= 0) + if (st.st_mtime >= *t) + *t = st.st_mtime; - ca_free(k); - } + ca_free(k); + } - if (g[j] == 0) - break; + if (g[j] == 0) + break; - g += j+1; - } + g += j+1; + } - last_change = *t; - last_check = now; + last_change = *t; + last_check = now; - ret = 0; + ret = 0; finish: - ca_mutex_unlock(mutex); + ca_mutex_unlock(mutex); - return ret; + return ret; } int ca_cache_lookup_sound( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme, - const char *name, - const char *locale, - const char *profile) { - - char *key = NULL; - void *data = NULL; - size_t klen, dlen; - int ret; - uint32_t timestamp; - time_t last_change, now; - ca_bool_t remove_entry = FALSE; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(theme, CA_ERROR_INVALID); - ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - ca_return_val_if_fail(locale, CA_ERROR_INVALID); - ca_return_val_if_fail(profile, CA_ERROR_INVALID); - - if (sound_path) - *sound_path = NULL; - - if (!(key = build_key(theme, name, locale, profile, &klen))) - return CA_ERROR_OOM; - - ret = db_lookup(key, klen, &data, &dlen); - - if (ret < 0) - goto finish; - - ca_assert(data); - - if (dlen < sizeof(uint32_t) || - (dlen > sizeof(uint32_t) && ((char*) data)[dlen-1] != 0)) { - - /* Corrupt entry */ - ret = CA_ERROR_NOTFOUND; - remove_entry = TRUE; - goto finish; - } - - memcpy(×tamp, data, sizeof(timestamp)); - - if ((ret = get_last_change(&last_change)) < 0) - goto finish; - - ca_assert_se(time(&now) != (time_t) -1); - - /* Hmm, is the entry older than the last change to our sound theme - * dirs? Also, check for clock skews */ - if ((time_t) timestamp < last_change || ((time_t) timestamp > now)) { - remove_entry = TRUE; - ret = CA_ERROR_NOTFOUND; - goto finish; - } - - if (dlen <= sizeof(uint32_t)) { - /* Negative caching entry. */ - *f = NULL; - ret = CA_SUCCESS; - goto finish; - } + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme, + const char *name, + const char *locale, + const char *profile) { + + char *key = NULL; + void *data = NULL; + size_t klen, dlen; + int ret; + uint32_t timestamp; + time_t last_change, now; + ca_bool_t remove_entry = FALSE; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(theme, CA_ERROR_INVALID); + ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); + ca_return_val_if_fail(locale, CA_ERROR_INVALID); + ca_return_val_if_fail(profile, CA_ERROR_INVALID); + + if (sound_path) + *sound_path = NULL; + + if (!(key = build_key(theme, name, locale, profile, &klen))) + return CA_ERROR_OOM; - if (sound_path) { - if (!(*sound_path = ca_strdup((const char*) data + sizeof(uint32_t)))) { - ret = CA_ERROR_OOM; - goto finish; - } - } + ret = db_lookup(key, klen, &data, &dlen); - if ((ret = sfopen(f, (const char*) data + sizeof(uint32_t))) < 0) - remove_entry = TRUE; + if (ret < 0) + goto finish; -finish: + ca_assert(data); - if (remove_entry) - db_remove(key, klen); + if (dlen < sizeof(uint32_t) || + (dlen > sizeof(uint32_t) && ((char*) data)[dlen-1] != 0)) { - if (sound_path && ret < 0) - ca_free(*sound_path); + /* Corrupt entry */ + ret = CA_ERROR_NOTFOUND; + remove_entry = TRUE; + goto finish; + } - ca_free(key); - ca_free(data); + memcpy(×tamp, data, sizeof(timestamp)); - return ret; -} + if ((ret = get_last_change(&last_change)) < 0) + goto finish; -int ca_cache_store_sound( - const char *theme, - const char *name, - const char *locale, - const char *profile, - const char *fname) { + ca_assert_se(time(&now) != (time_t) -1); + + /* Hmm, is the entry older than the last change to our sound theme + * dirs? Also, check for clock skews */ + if ((time_t) timestamp < last_change || ((time_t) timestamp > now)) { + remove_entry = TRUE; + ret = CA_ERROR_NOTFOUND; + goto finish; + } + + if (dlen <= sizeof(uint32_t)) { + /* Negative caching entry. */ + *f = NULL; + ret = CA_SUCCESS; + goto finish; + } + + if (sound_path) { + if (!(*sound_path = ca_strdup((const char*) data + sizeof(uint32_t)))) { + ret = CA_ERROR_OOM; + goto finish; + } + } - char *key; - void *data; - size_t klen, dlen; - int ret; - time_t now; + if ((ret = sfopen(f, (const char*) data + sizeof(uint32_t))) < 0) + remove_entry = TRUE; - ca_return_val_if_fail(theme, CA_ERROR_INVALID); - ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - ca_return_val_if_fail(locale, CA_ERROR_INVALID); - ca_return_val_if_fail(profile, CA_ERROR_INVALID); +finish: - if (!(key = build_key(theme, name, locale, profile, &klen))) - return CA_ERROR_OOM; + if (remove_entry) + db_remove(key, klen); - dlen = sizeof(uint32_t) + (fname ? strlen(fname) + 1 : 0); + if (sound_path && ret < 0) + ca_free(*sound_path); - if (!(data = ca_malloc(dlen))) { ca_free(key); - return CA_ERROR_OOM; - } + ca_free(data); - ca_assert_se(time(&now) != (time_t) -1); - *(uint32_t*) data = (uint32_t) now; + return ret; +} + +int ca_cache_store_sound( + const char *theme, + const char *name, + const char *locale, + const char *profile, + const char *fname) { + + char *key; + void *data; + size_t klen, dlen; + int ret; + time_t now; + + ca_return_val_if_fail(theme, CA_ERROR_INVALID); + ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); + ca_return_val_if_fail(locale, CA_ERROR_INVALID); + ca_return_val_if_fail(profile, CA_ERROR_INVALID); + + if (!(key = build_key(theme, name, locale, profile, &klen))) + return CA_ERROR_OOM; - if (fname) - strcpy((char*) data + sizeof(uint32_t), fname); + dlen = sizeof(uint32_t) + (fname ? strlen(fname) + 1 : 0); - ret = db_store(key, klen, data, dlen); + if (!(data = ca_malloc(dlen))) { + ca_free(key); + return CA_ERROR_OOM; + } - ca_free(key); - ca_free(data); + ca_assert_se(time(&now) != (time_t) -1); + *(uint32_t*) data = (uint32_t) now; - return ret; + if (fname) + strcpy((char*) data + sizeof(uint32_t), fname); + + ret = db_store(key, klen, data, dlen); + + ca_free(key); + ca_free(data); + + return ret; } diff --git a/src/cache.h b/src/cache.h index 31a697c..dc3426e 100644 --- a/src/cache.h +++ b/src/cache.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberracachehfoo #define foocanberracachehfoo @@ -24,19 +26,19 @@ #include "read-sound-file.h" int ca_cache_lookup_sound( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme, - const char *name, - const char *locale, - const char *profile); + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme, + const char *name, + const char *locale, + const char *profile); int ca_cache_store_sound( - const char *theme, - const char *name, - const char *locale, - const char *profile, - const char *fname); + const char *theme, + const char *name, + const char *locale, + const char *profile, + const char *fname); #endif diff --git a/src/canberra-gtk-module.c b/src/canberra-gtk-module.c index 88e213b..da37756 100644 --- a/src/canberra-gtk-module.c +++ b/src/canberra-gtk-module.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -29,11 +31,11 @@ #include "canberra-gtk.h" typedef struct { - guint signal_id; - gboolean arg1_is_set; - GObject *object; - GValue arg1; - GdkEvent *event; + guint signal_id; + gboolean arg1_is_set; + GObject *object; + GValue arg1; + GdkEvent *event; } SoundEventData; /* @@ -86,888 +88,888 @@ static GQueue sound_event_queue = G_QUEUE_INIT; static guint idle_id = 0; static guint - signal_id_dialog_response, - signal_id_widget_show, - signal_id_widget_hide, - signal_id_check_menu_item_toggled, - signal_id_menu_item_activate, - signal_id_toggle_button_toggled, - signal_id_button_pressed, - signal_id_button_released, - signal_id_widget_window_state_event, - signal_id_notebook_switch_page, - signal_id_tree_view_cursor_changed, - signal_id_icon_view_selection_changed, - signal_id_widget_drag_begin, - signal_id_widget_drag_failed, - signal_id_widget_drag_drop, - signal_id_expander_activate; + signal_id_dialog_response, + signal_id_widget_show, + signal_id_widget_hide, + signal_id_check_menu_item_toggled, + signal_id_menu_item_activate, + signal_id_toggle_button_toggled, + signal_id_button_pressed, + signal_id_button_released, + signal_id_widget_window_state_event, + signal_id_notebook_switch_page, + signal_id_tree_view_cursor_changed, + signal_id_icon_view_selection_changed, + signal_id_widget_drag_begin, + signal_id_widget_drag_failed, + signal_id_widget_drag_drop, + signal_id_expander_activate; static GQuark - disable_sound_quark, - was_iconized_quark, - is_xembed_quark; + disable_sound_quark, + was_iconized_quark, + is_xembed_quark; /* Make sure GCC doesn't warn us about a missing prototype for this * exported function */ void gtk_module_init(gint *argc, gchar ***argv[]); static const char *translate_message_tye(GtkMessageType mt) { - static const char *const message_type_table[] = { - [GTK_MESSAGE_INFO] = "dialog-information", - [GTK_MESSAGE_WARNING] = "dialog-warning", - [GTK_MESSAGE_QUESTION] = "dialog-question", - [GTK_MESSAGE_ERROR] = "dialog-error", - [GTK_MESSAGE_OTHER] = NULL - }; - - if (mt >= G_N_ELEMENTS(message_type_table)) - return NULL; - - return message_type_table[mt]; + static const char *const message_type_table[] = { + [GTK_MESSAGE_INFO] = "dialog-information", + [GTK_MESSAGE_WARNING] = "dialog-warning", + [GTK_MESSAGE_QUESTION] = "dialog-question", + [GTK_MESSAGE_ERROR] = "dialog-error", + [GTK_MESSAGE_OTHER] = NULL + }; + + if (mt >= G_N_ELEMENTS(message_type_table)) + return NULL; + + return message_type_table[mt]; } static const char *translate_response(int response) { - static const char *const response_table[] = { - [-GTK_RESPONSE_NONE] = NULL, - [-GTK_RESPONSE_REJECT] = "dialog-cancel", - [-GTK_RESPONSE_DELETE_EVENT] = "dialog-cancel", - [-GTK_RESPONSE_ACCEPT] = "dialog-ok", - [-GTK_RESPONSE_OK] = "dialog-ok", - [-GTK_RESPONSE_CANCEL] = "dialog-cancel", - [-GTK_RESPONSE_CLOSE] = "dialog-ok", - [-GTK_RESPONSE_YES] = "dialog-ok", - [-GTK_RESPONSE_NO] = "dialog-cancel", - [-GTK_RESPONSE_APPLY] = "dialog-ok", - [-GTK_RESPONSE_HELP] = NULL, - }; - - if (response >= 0) - return NULL; - - if ((unsigned) -response >= G_N_ELEMENTS(response_table)) - return NULL; - - return response_table[-response]; + static const char *const response_table[] = { + [-GTK_RESPONSE_NONE] = NULL, + [-GTK_RESPONSE_REJECT] = "dialog-cancel", + [-GTK_RESPONSE_DELETE_EVENT] = "dialog-cancel", + [-GTK_RESPONSE_ACCEPT] = "dialog-ok", + [-GTK_RESPONSE_OK] = "dialog-ok", + [-GTK_RESPONSE_CANCEL] = "dialog-cancel", + [-GTK_RESPONSE_CLOSE] = "dialog-ok", + [-GTK_RESPONSE_YES] = "dialog-ok", + [-GTK_RESPONSE_NO] = "dialog-cancel", + [-GTK_RESPONSE_APPLY] = "dialog-ok", + [-GTK_RESPONSE_HELP] = NULL, + }; + + if (response >= 0) + return NULL; + + if ((unsigned) -response >= G_N_ELEMENTS(response_table)) + return NULL; + + return response_table[-response]; } static gboolean is_child_of_combo_box(GtkWidget *w) { - while (w) { + while (w) { - if (GTK_IS_COMBO_BOX(w)) - return TRUE; + if (GTK_IS_COMBO_BOX(w)) + return TRUE; - w = gtk_widget_get_parent(w); - } + w = gtk_widget_get_parent(w); + } - return FALSE; + return FALSE; } static GtkDialog* find_parent_dialog(GtkWidget *w) { - while (w) { + while (w) { - if (GTK_IS_DIALOG(w)) - return GTK_DIALOG(w); + if (GTK_IS_DIALOG(w)) + return GTK_DIALOG(w); - w = gtk_widget_get_parent(w); - } + w = gtk_widget_get_parent(w); + } - return NULL; + return NULL; } static void free_sound_event(SoundEventData *d) { - g_object_unref(d->object); + g_object_unref(d->object); - if (d->arg1_is_set) - g_value_unset(&d->arg1); + if (d->arg1_is_set) + g_value_unset(&d->arg1); - if (d->event) - gdk_event_free(d->event); + if (d->event) + gdk_event_free(d->event); - g_slice_free(SoundEventData, d); + g_slice_free(SoundEventData, d); } static gboolean is_menu_hint(GdkWindowTypeHint hint) { - return - hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU || - hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU || - hint == GDK_WINDOW_TYPE_HINT_MENU; + return + hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU || + hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU || + hint == GDK_WINDOW_TYPE_HINT_MENU; } static SoundEventData* filter_sound_event(SoundEventData *d) { - GList *i, *n; + GList *i, *n; - do { + do { - for (i = sound_event_queue.head; i; i = n) { - SoundEventData *j; + for (i = sound_event_queue.head; i; i = n) { + SoundEventData *j; - j = i->data; - n = i->next; + j = i->data; + n = i->next; - if (d->object == j->object) { + if (d->object == j->object) { - /* Let's drop a show event immediately followed by a - * hide event */ + /* Let's drop a show event immediately followed by a + * hide event */ - if (d->signal_id == signal_id_widget_show && - j->signal_id == signal_id_widget_hide) { + if (d->signal_id == signal_id_widget_show && + j->signal_id == signal_id_widget_hide) { - free_sound_event(d); - free_sound_event(j); - g_queue_delete_link(&sound_event_queue, i); + free_sound_event(d); + free_sound_event(j); + g_queue_delete_link(&sound_event_queue, i); - return NULL; - } + return NULL; + } - /* Let's drop widget hide events in favour of dialog - * response. - * - * Let's drop widget window state events in favour of - * widget hide/show. - * - * Let's drop double events */ + /* Let's drop widget hide events in favour of dialog + * response. + * + * Let's drop widget window state events in favour of + * widget hide/show. + * + * Let's drop double events */ - if ((d->signal_id == signal_id_widget_hide && - j->signal_id == signal_id_dialog_response) || + if ((d->signal_id == signal_id_widget_hide && + j->signal_id == signal_id_dialog_response) || - (d->signal_id == signal_id_widget_window_state_event && - j->signal_id == signal_id_widget_hide) || + (d->signal_id == signal_id_widget_window_state_event && + j->signal_id == signal_id_widget_hide) || - (d->signal_id == signal_id_widget_window_state_event && - j->signal_id == signal_id_widget_show)) { + (d->signal_id == signal_id_widget_window_state_event && + j->signal_id == signal_id_widget_show)) { - free_sound_event(d); - d = j; - g_queue_delete_link(&sound_event_queue, i); - break; - } + free_sound_event(d); + d = j; + g_queue_delete_link(&sound_event_queue, i); + break; + } - if ((d->signal_id == signal_id_dialog_response && - j->signal_id == signal_id_widget_hide) || + if ((d->signal_id == signal_id_dialog_response && + j->signal_id == signal_id_widget_hide) || - (d->signal_id == signal_id_widget_show && - j->signal_id == signal_id_widget_window_state_event) || + (d->signal_id == signal_id_widget_show && + j->signal_id == signal_id_widget_window_state_event) || - (d->signal_id == signal_id_widget_hide && - j->signal_id == signal_id_widget_window_state_event) || + (d->signal_id == signal_id_widget_hide && + j->signal_id == signal_id_widget_window_state_event) || - (d->signal_id == j->signal_id)) { + (d->signal_id == j->signal_id)) { - free_sound_event(j); - g_queue_delete_link(&sound_event_queue, i); - } + free_sound_event(j); + g_queue_delete_link(&sound_event_queue, i); + } - } else if (GTK_IS_WINDOW(d->object) && GTK_IS_WINDOW(j->object)) { + } else if (GTK_IS_WINDOW(d->object) && GTK_IS_WINDOW(j->object)) { - GdkWindowTypeHint dhint, jhint; + GdkWindowTypeHint dhint, jhint; - dhint = gtk_window_get_type_hint(GTK_WINDOW(d->object)); - jhint = gtk_window_get_type_hint(GTK_WINDOW(j->object)); + dhint = gtk_window_get_type_hint(GTK_WINDOW(d->object)); + jhint = gtk_window_get_type_hint(GTK_WINDOW(j->object)); - if (is_menu_hint(dhint) && is_menu_hint(jhint)) { + if (is_menu_hint(dhint) && is_menu_hint(jhint)) { - if (d->signal_id == signal_id_widget_hide && - j->signal_id == signal_id_widget_show) { - free_sound_event(d); - d = j; - g_queue_delete_link(&sound_event_queue, i); - break; - } + if (d->signal_id == signal_id_widget_hide && + j->signal_id == signal_id_widget_show) { + free_sound_event(d); + d = j; + g_queue_delete_link(&sound_event_queue, i); + break; + } - if (d->signal_id == signal_id_widget_show && - j->signal_id == signal_id_widget_hide) { + if (d->signal_id == signal_id_widget_show && + j->signal_id == signal_id_widget_hide) { - free_sound_event(j); - g_queue_delete_link(&sound_event_queue, i); - } + free_sound_event(j); + g_queue_delete_link(&sound_event_queue, i); + } + } + } } - } - } - /* If we exited the iteration early, let's retry. */ + /* If we exited the iteration early, let's retry. */ - } while (i); + } while (i); - /* FIXME: Filter menu hide on menu show */ + /* FIXME: Filter menu hide on menu show */ - return d; + return d; } static gint window_get_desktop(GdkDisplay *d, GdkWindow *w) { - Atom type_return; - gint format_return; - gulong nitems_return; - gulong bytes_after_return; - guchar *data = NULL; - gint ret = -1; - - if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w), - gdk_x11_get_xatom_by_name_for_display(d, "_NET_WM_DESKTOP"), - 0, G_MAXLONG, False, XA_CARDINAL, &type_return, - &format_return, &nitems_return, &bytes_after_return, - &data) != Success) - return -1; - - if (type_return == XA_CARDINAL && format_return == 32 && data) { - guint32 desktop = *(guint32*) data; - - if (desktop != 0xFFFFFFFF) - ret = (gint) desktop; - } - - if (type_return != None && data != NULL) - XFree(data); - - return ret; -} - -static gint display_get_desktop(GdkDisplay *d) { - Atom type_return; - gint format_return; - gulong nitems_return; - gulong bytes_after_return; - guchar *data = NULL; - gint ret = -1; - - if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), DefaultRootWindow(GDK_DISPLAY_XDISPLAY(d)), - gdk_x11_get_xatom_by_name_for_display(d, "_NET_CURRENT_DESKTOP"), - 0, G_MAXLONG, False, XA_CARDINAL, &type_return, - &format_return, &nitems_return, &bytes_after_return, - &data) != Success) - return -1; + Atom type_return; + gint format_return; + gulong nitems_return; + gulong bytes_after_return; + guchar *data = NULL; + gint ret = -1; + + if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w), + gdk_x11_get_xatom_by_name_for_display(d, "_NET_WM_DESKTOP"), + 0, G_MAXLONG, False, XA_CARDINAL, &type_return, + &format_return, &nitems_return, &bytes_after_return, + &data) != Success) + return -1; + + if (type_return == XA_CARDINAL && format_return == 32 && data) { + guint32 desktop = *(guint32*) data; + + if (desktop != 0xFFFFFFFF) + ret = (gint) desktop; + } - if (type_return == XA_CARDINAL && format_return == 32 && data) { + if (type_return != None && data != NULL) + XFree(data); - guint32 desktop = *(guint32*) data; + return ret; +} - if (desktop != 0xFFFFFFFF) - ret = (gint) desktop; - } +static gint display_get_desktop(GdkDisplay *d) { + Atom type_return; + gint format_return; + gulong nitems_return; + gulong bytes_after_return; + guchar *data = NULL; + gint ret = -1; + + if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), DefaultRootWindow(GDK_DISPLAY_XDISPLAY(d)), + gdk_x11_get_xatom_by_name_for_display(d, "_NET_CURRENT_DESKTOP"), + 0, G_MAXLONG, False, XA_CARDINAL, &type_return, + &format_return, &nitems_return, &bytes_after_return, + &data) != Success) + return -1; + + if (type_return == XA_CARDINAL && format_return == 32 && data) { + + guint32 desktop = *(guint32*) data; + + if (desktop != 0xFFFFFFFF) + ret = (gint) desktop; + } - if (type_return != None && data != NULL) - XFree(data); + if (type_return != None && data != NULL) + XFree(data); - return ret; + return ret; } static gboolean window_is_xembed(GdkDisplay *d, GdkWindow *w) { - Atom type_return; - gint format_return; - gulong nitems_return; - gulong bytes_after_return; - guchar *data = NULL; - gboolean ret = FALSE; - Atom xembed; - - /* Gnome Panel applets are XEMBED windows. We need to make sure we - * ignore them */ - - xembed = gdk_x11_get_xatom_by_name_for_display(d, "_XEMBED_INFO"); - - if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w), - xembed, - 0, 2, False, xembed, &type_return, - &format_return, &nitems_return, &bytes_after_return, - &data) != Success) { - return FALSE; - } + Atom type_return; + gint format_return; + gulong nitems_return; + gulong bytes_after_return; + guchar *data = NULL; + gboolean ret = FALSE; + Atom xembed; + + /* Gnome Panel applets are XEMBED windows. We need to make sure we + * ignore them */ + + xembed = gdk_x11_get_xatom_by_name_for_display(d, "_XEMBED_INFO"); + + if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w), + xembed, + 0, 2, False, xembed, &type_return, + &format_return, &nitems_return, &bytes_after_return, + &data) != Success) { + return FALSE; + } - if (type_return == xembed && format_return == 32 && data) - ret = TRUE; + if (type_return == xembed && format_return == 32 && data) + ret = TRUE; - if (type_return != None && data != NULL) - XFree(data); + if (type_return != None && data != NULL) + XFree(data); - return ret; + return ret; } static void dispatch_sound_event(SoundEventData *d) { - int ret = CA_SUCCESS; - static gboolean menu_is_popped_up = FALSE; + int ret = CA_SUCCESS; + static gboolean menu_is_popped_up = FALSE; - if (g_object_get_qdata(d->object, disable_sound_quark)) - return; + if (g_object_get_qdata(d->object, disable_sound_quark)) + return; - /* The GdkWindow of the the widget might have changed while this - * event was queued for us. Make sure to update it from the - * current one if necessary. */ - if (d->event && d->event->any.window) { - GdkWindow *window; + /* The GdkWindow of the the widget might have changed while this + * event was queued for us. Make sure to update it from the + * current one if necessary. */ + if (d->event && d->event->any.window) { + GdkWindow *window; - g_object_unref(G_OBJECT(d->event->any.window)); + g_object_unref(G_OBJECT(d->event->any.window)); - if ((window = gtk_widget_get_window(GTK_WIDGET(d->object)))) - d->event->any.window = GDK_WINDOW(g_object_ref(G_OBJECT(window))); - else - d->event->any.window = NULL; - } + if ((window = gtk_widget_get_window(GTK_WIDGET(d->object)))) + d->event->any.window = GDK_WINDOW(g_object_ref(G_OBJECT(window))); + else + d->event->any.window = NULL; + } - if (d->signal_id == signal_id_widget_show) { - GdkWindowTypeHint hint; + if (d->signal_id == signal_id_widget_show) { + GdkWindowTypeHint hint; - /* Show/hide signals for non-windows have already been filtered out - * by the emission hook! */ + /* Show/hide signals for non-windows have already been filtered out + * by the emission hook! */ - hint = gtk_window_get_type_hint(GTK_WINDOW(d->object)); + hint = gtk_window_get_type_hint(GTK_WINDOW(d->object)); - if (is_menu_hint(hint)) { + if (is_menu_hint(hint)) { - if (!menu_is_popped_up) { + if (!menu_is_popped_up) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "menu-popup", - CA_PROP_EVENT_DESCRIPTION, "Menu popped up", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } else { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "menu-replace", - CA_PROP_EVENT_DESCRIPTION, "Menu replaced", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "menu-popup", + CA_PROP_EVENT_DESCRIPTION, "Menu popped up", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } else { + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "menu-replace", + CA_PROP_EVENT_DESCRIPTION, "Menu replaced", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } - menu_is_popped_up = TRUE; + menu_is_popped_up = TRUE; - } else if (hint == GDK_WINDOW_TYPE_HINT_TOOLTIP) { + } else if (hint == GDK_WINDOW_TYPE_HINT_TOOLTIP) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "tooltip-popup", - CA_PROP_EVENT_DESCRIPTION, "Tooltip popped up", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "tooltip-popup", + CA_PROP_EVENT_DESCRIPTION, "Tooltip popped up", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - } else if (hint == GDK_WINDOW_TYPE_HINT_NORMAL || - hint == GDK_WINDOW_TYPE_HINT_DIALOG) { + } else if (hint == GDK_WINDOW_TYPE_HINT_NORMAL || + hint == GDK_WINDOW_TYPE_HINT_DIALOG) { - gboolean played_sound = FALSE; - gboolean is_xembed; + gboolean played_sound = FALSE; + gboolean is_xembed; - is_xembed = - GTK_WIDGET_REALIZED(GTK_WIDGET(d->object)) && - window_is_xembed( - gtk_widget_get_display(GTK_WIDGET(d->object)), - gtk_widget_get_window(GTK_WIDGET(d->object))); + is_xembed = + GTK_WIDGET_REALIZED(GTK_WIDGET(d->object)) && + window_is_xembed( + gtk_widget_get_display(GTK_WIDGET(d->object)), + gtk_widget_get_window(GTK_WIDGET(d->object))); - g_object_set_qdata(d->object, is_xembed_quark, GINT_TO_POINTER(is_xembed)); + g_object_set_qdata(d->object, is_xembed_quark, GINT_TO_POINTER(is_xembed)); - if (GTK_IS_MESSAGE_DIALOG(d->object)) { - GtkMessageType mt; - const char *id; + if (GTK_IS_MESSAGE_DIALOG(d->object)) { + GtkMessageType mt; + const char *id; - g_object_get(d->object, "message_type", &mt, NULL); + g_object_get(d->object, "message_type", &mt, NULL); - if ((id = translate_message_tye(mt))) { + if ((id = translate_message_tye(mt))) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, id, - CA_PROP_EVENT_DESCRIPTION, "Message dialog shown", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - played_sound = TRUE; - } + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, id, + CA_PROP_EVENT_DESCRIPTION, "Message dialog shown", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + played_sound = TRUE; + } - } + } - if (!played_sound && - !is_xembed && - gtk_window_get_decorated(GTK_WINDOW(d->object))) { + if (!played_sound && + !is_xembed && + gtk_window_get_decorated(GTK_WINDOW(d->object))) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-new", - CA_PROP_EVENT_DESCRIPTION, "Window shown", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-new", + CA_PROP_EVENT_DESCRIPTION, "Window shown", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - } + } + } } - } - - if (GTK_IS_DIALOG(d->object) && d->signal_id == signal_id_dialog_response) { - - int response; - const char *id; - response = g_value_get_int(&d->arg1); + if (GTK_IS_DIALOG(d->object) && d->signal_id == signal_id_dialog_response) { - if ((id = translate_response(response))) { + int response; + const char *id; - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, id, - CA_PROP_EVENT_DESCRIPTION, "Dialog closed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } else { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-close", - CA_PROP_EVENT_DESCRIPTION, "Window closed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } + response = g_value_get_int(&d->arg1); + + if ((id = translate_response(response))) { + + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, id, + CA_PROP_EVENT_DESCRIPTION, "Dialog closed", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } else { + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-close", + CA_PROP_EVENT_DESCRIPTION, "Window closed", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } - } else if (d->signal_id == signal_id_widget_hide) { - GdkWindowTypeHint hint; + } else if (d->signal_id == signal_id_widget_hide) { + GdkWindowTypeHint hint; - hint = gtk_window_get_type_hint(GTK_WINDOW(d->object)); + hint = gtk_window_get_type_hint(GTK_WINDOW(d->object)); - if (is_menu_hint(hint)) { + if (is_menu_hint(hint)) { - if (GTK_IS_MENU(gtk_bin_get_child(GTK_BIN(d->object)))) { + if (GTK_IS_MENU(gtk_bin_get_child(GTK_BIN(d->object)))) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "menu-popdown", - CA_PROP_EVENT_DESCRIPTION, "Menu popped down", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "menu-popdown", + CA_PROP_EVENT_DESCRIPTION, "Menu popped down", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } - menu_is_popped_up = FALSE; + menu_is_popped_up = FALSE; - } else if (hint == GDK_WINDOW_TYPE_HINT_TOOLTIP) { + } else if (hint == GDK_WINDOW_TYPE_HINT_TOOLTIP) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "tooltip-popdown", - CA_PROP_EVENT_DESCRIPTION, "Tooltip popped down", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "tooltip-popdown", + CA_PROP_EVENT_DESCRIPTION, "Tooltip popped down", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - } else if ((hint == GDK_WINDOW_TYPE_HINT_NORMAL || - hint == GDK_WINDOW_TYPE_HINT_DIALOG)) { + } else if ((hint == GDK_WINDOW_TYPE_HINT_NORMAL || + hint == GDK_WINDOW_TYPE_HINT_DIALOG)) { - gboolean is_xembed; + gboolean is_xembed; - is_xembed = !!g_object_get_qdata(d->object, is_xembed_quark); + is_xembed = !!g_object_get_qdata(d->object, is_xembed_quark); - if (!is_xembed && - gtk_window_get_decorated(GTK_WINDOW(d->object))) - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-close", - CA_PROP_EVENT_DESCRIPTION, "Window closed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + if (!is_xembed && + gtk_window_get_decorated(GTK_WINDOW(d->object))) + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-close", + CA_PROP_EVENT_DESCRIPTION, "Window closed", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } } - } - if (GTK_IS_WINDOW(d->object) && d->signal_id == signal_id_widget_window_state_event) { - GdkEventWindowState *e; - gint w_desktop = -1, c_desktop = -1; + if (GTK_IS_WINDOW(d->object) && d->signal_id == signal_id_widget_window_state_event) { + GdkEventWindowState *e; + gint w_desktop = -1, c_desktop = -1; - e = (GdkEventWindowState*) d->event; + e = (GdkEventWindowState*) d->event; - /* Unfortunately GDK_WINDOW_STATE_ICONIFIED is used both for - * proper minimizing and when a window becomes invisible - * because the desktop was switched. To handle this we check - * if the window becoming invisible is actually on the current - * desktop, and only if that's the case we assume it is being - * minimized. We then store this information, so that we know - * later on when the window is unminimized again. */ + /* Unfortunately GDK_WINDOW_STATE_ICONIFIED is used both for + * proper minimizing and when a window becomes invisible + * because the desktop was switched. To handle this we check + * if the window becoming invisible is actually on the current + * desktop, and only if that's the case we assume it is being + * minimized. We then store this information, so that we know + * later on when the window is unminimized again. */ - if (GTK_WIDGET_REALIZED(GTK_WIDGET(d->object))) { - GdkDisplay *display; + if (GTK_WIDGET_REALIZED(GTK_WIDGET(d->object))) { + GdkDisplay *display; - display = gtk_widget_get_display(GTK_WIDGET(d->object)); - w_desktop = window_get_desktop(display, gtk_widget_get_window(GTK_WIDGET(d->object))); - c_desktop = display_get_desktop(display); - } + display = gtk_widget_get_display(GTK_WIDGET(d->object)); + w_desktop = window_get_desktop(display, gtk_widget_get_window(GTK_WIDGET(d->object))); + c_desktop = display_get_desktop(display); + } - if ((e->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && - (e->new_window_state & GDK_WINDOW_STATE_ICONIFIED) && - (w_desktop == c_desktop || w_desktop < 0)) { + if ((e->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && + (e->new_window_state & GDK_WINDOW_STATE_ICONIFIED) && + (w_desktop == c_desktop || w_desktop < 0)) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-minimized", - CA_PROP_EVENT_DESCRIPTION, "Window minimized", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-minimized", + CA_PROP_EVENT_DESCRIPTION, "Window minimized", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(1)); + g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(1)); - } else if ((e->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) && - (e->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN))) { + } else if ((e->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) && + (e->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN))) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-maximized", - CA_PROP_EVENT_DESCRIPTION, "Window maximized", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-maximized", + CA_PROP_EVENT_DESCRIPTION, "Window maximized", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(0)); + g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(0)); - } else if ((e->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && - !(e->new_window_state & GDK_WINDOW_STATE_ICONIFIED) && - g_object_get_qdata(d->object, was_iconized_quark)) { + } else if ((e->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && + !(e->new_window_state & GDK_WINDOW_STATE_ICONIFIED) && + g_object_get_qdata(d->object, was_iconized_quark)) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-unminimized", - CA_PROP_EVENT_DESCRIPTION, "Window unminimized", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-unminimized", + CA_PROP_EVENT_DESCRIPTION, "Window unminimized", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(0)); + g_object_set_qdata(d->object, was_iconized_quark, GINT_TO_POINTER(0)); - } else if ((e->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) && - !(e->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN))) { + } else if ((e->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) && + !(e->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN))) { - ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, - CA_PROP_EVENT_ID, "window-unmaximized", - CA_PROP_EVENT_DESCRIPTION, "Window unmaximized", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + ret = ca_gtk_play_for_widget(GTK_WIDGET(d->object), 0, + CA_PROP_EVENT_ID, "window-unmaximized", + CA_PROP_EVENT_DESCRIPTION, "Window unmaximized", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } } - } - - if (GTK_IS_CHECK_MENU_ITEM(d->object) && d->signal_id == signal_id_check_menu_item_toggled) { - - if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(d->object))) - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "button-toggle-on", - CA_PROP_EVENT_DESCRIPTION, "Check menu item checked", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - else - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "button-toggle-off", - CA_PROP_EVENT_DESCRIPTION, "Check menu item unchecked", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - - } else if (GTK_IS_MENU_ITEM(d->object) && d->signal_id == signal_id_menu_item_activate) { - - if (!GTK_MENU_ITEM(d->object)->submenu) - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "menu-click", - CA_PROP_EVENT_DESCRIPTION, "Menu item clicked", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } - - if (GTK_IS_TOGGLE_BUTTON(d->object)) { - - if (d->signal_id == signal_id_toggle_button_toggled) { - - if (!is_child_of_combo_box(GTK_WIDGET(d->object))) { - - /* We don't want to play this sound if this is a toggle - * button belonging to combo box. */ - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d->object))) - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "button-toggle-on", - CA_PROP_EVENT_DESCRIPTION, "Toggle button checked", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + + if (GTK_IS_CHECK_MENU_ITEM(d->object) && d->signal_id == signal_id_check_menu_item_toggled) { + + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(d->object))) + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "button-toggle-on", + CA_PROP_EVENT_DESCRIPTION, "Check menu item checked", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); else - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "button-toggle-off", - CA_PROP_EVENT_DESCRIPTION, "Toggle button unchecked", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "button-toggle-off", + CA_PROP_EVENT_DESCRIPTION, "Check menu item unchecked", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + + } else if (GTK_IS_MENU_ITEM(d->object) && d->signal_id == signal_id_menu_item_activate) { + + if (!GTK_MENU_ITEM(d->object)->submenu) + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "menu-click", + CA_PROP_EVENT_DESCRIPTION, "Menu item clicked", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); } - } else if (GTK_IS_LINK_BUTTON(d->object)) { + if (GTK_IS_TOGGLE_BUTTON(d->object)) { - if (d->signal_id == signal_id_button_pressed) { - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "link-pressed", - CA_PROP_EVENT_DESCRIPTION, "Link pressed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + if (d->signal_id == signal_id_toggle_button_toggled) { - } else if (d->signal_id == signal_id_button_released) { + if (!is_child_of_combo_box(GTK_WIDGET(d->object))) { - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "link-released", - CA_PROP_EVENT_DESCRIPTION, "Link released", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - } + /* We don't want to play this sound if this is a toggle + * button belonging to combo box. */ - } else if (GTK_IS_BUTTON(d->object) && !GTK_IS_TOGGLE_BUTTON(d->object)) { + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d->object))) + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "button-toggle-on", + CA_PROP_EVENT_DESCRIPTION, "Toggle button checked", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + else + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "button-toggle-off", + CA_PROP_EVENT_DESCRIPTION, "Toggle button unchecked", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } + } - if (d->signal_id == signal_id_button_pressed) { - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "button-pressed", - CA_PROP_EVENT_DESCRIPTION, "Button pressed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); + } else if (GTK_IS_LINK_BUTTON(d->object)) { - } else if (d->signal_id == signal_id_button_released) { - GtkDialog *dialog; - gboolean dont_play = FALSE; + if (d->signal_id == signal_id_button_pressed) { + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "link-pressed", + CA_PROP_EVENT_DESCRIPTION, "Link pressed", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); - if ((dialog = find_parent_dialog(GTK_WIDGET(d->object)))) { - int response; + } else if (d->signal_id == signal_id_button_released) { - /* Don't play the click sound if this is a response widget - * we will generate a dialog-xxx event sound anyway. */ + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "link-released", + CA_PROP_EVENT_DESCRIPTION, "Link released", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } + + } else if (GTK_IS_BUTTON(d->object) && !GTK_IS_TOGGLE_BUTTON(d->object)) { + + if (d->signal_id == signal_id_button_pressed) { + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "button-pressed", + CA_PROP_EVENT_DESCRIPTION, "Button pressed", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + + } else if (d->signal_id == signal_id_button_released) { + GtkDialog *dialog; + gboolean dont_play = FALSE; + + if ((dialog = find_parent_dialog(GTK_WIDGET(d->object)))) { + int response; + + /* Don't play the click sound if this is a response widget + * we will generate a dialog-xxx event sound anyway. */ - response = gtk_dialog_get_response_for_widget(dialog, GTK_WIDGET(d->object)); - dont_play = !!translate_response(response); - } + response = gtk_dialog_get_response_for_widget(dialog, GTK_WIDGET(d->object)); + dont_play = !!translate_response(response); + } - if (!dont_play) + if (!dont_play) + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "button-released", + CA_PROP_EVENT_DESCRIPTION, "Button released", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + } + } + + if (GTK_IS_NOTEBOOK(d->object) && d->signal_id == signal_id_notebook_switch_page) { ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "button-released", - CA_PROP_EVENT_DESCRIPTION, "Button released", + CA_PROP_EVENT_ID, "notebook-tab-changed", + CA_PROP_EVENT_DESCRIPTION, "Tab changed", CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", NULL); + goto finish; } - } - - if (GTK_IS_NOTEBOOK(d->object) && d->signal_id == signal_id_notebook_switch_page) { - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "notebook-tab-changed", - CA_PROP_EVENT_DESCRIPTION, "Tab changed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - goto finish; - } - - if (GTK_IS_TREE_VIEW(d->object) && d->signal_id == signal_id_tree_view_cursor_changed) { - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "item-selected", - CA_PROP_EVENT_DESCRIPTION, "Item selected", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - goto finish; - } - - if (GTK_IS_ICON_VIEW(d->object) && d->signal_id == signal_id_icon_view_selection_changed) { - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "item-selected", - CA_PROP_EVENT_DESCRIPTION, "Item selected", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - goto finish; - } - - if (GTK_IS_EXPANDER(d->object) && d->signal_id == signal_id_expander_activate) { - - if (gtk_expander_get_expanded(GTK_EXPANDER(d->object))) - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "expander-toggle-on", - CA_PROP_EVENT_DESCRIPTION, "Expander expanded", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - else - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "expander-toggle-off", - CA_PROP_EVENT_DESCRIPTION, "Expander unexpanded", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - - goto finish; - } - - if (GTK_IS_WIDGET(d->object)) { - - if (d->signal_id == signal_id_widget_drag_begin) { - - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "drag-start", - CA_PROP_EVENT_DESCRIPTION, "Drag started", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - goto finish; - - } else if (d->signal_id == signal_id_widget_drag_drop) { - - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "drag-accept", - CA_PROP_EVENT_DESCRIPTION, "Drag accepted", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - goto finish; - - } else if (d->signal_id == signal_id_widget_drag_failed) { - - ret = ca_gtk_play_for_event(d->event, 0, - CA_PROP_EVENT_ID, "drag-fail", - CA_PROP_EVENT_DESCRIPTION, "Drag failed", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - goto finish; + + if (GTK_IS_TREE_VIEW(d->object) && d->signal_id == signal_id_tree_view_cursor_changed) { + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "item-selected", + CA_PROP_EVENT_DESCRIPTION, "Item selected", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + goto finish; + } + + if (GTK_IS_ICON_VIEW(d->object) && d->signal_id == signal_id_icon_view_selection_changed) { + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "item-selected", + CA_PROP_EVENT_DESCRIPTION, "Item selected", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + goto finish; + } + + if (GTK_IS_EXPANDER(d->object) && d->signal_id == signal_id_expander_activate) { + + if (gtk_expander_get_expanded(GTK_EXPANDER(d->object))) + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "expander-toggle-on", + CA_PROP_EVENT_DESCRIPTION, "Expander expanded", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + else + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "expander-toggle-off", + CA_PROP_EVENT_DESCRIPTION, "Expander unexpanded", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + + goto finish; + } + + if (GTK_IS_WIDGET(d->object)) { + + if (d->signal_id == signal_id_widget_drag_begin) { + + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "drag-start", + CA_PROP_EVENT_DESCRIPTION, "Drag started", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + goto finish; + + } else if (d->signal_id == signal_id_widget_drag_drop) { + + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "drag-accept", + CA_PROP_EVENT_DESCRIPTION, "Drag accepted", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + goto finish; + + } else if (d->signal_id == signal_id_widget_drag_failed) { + + ret = ca_gtk_play_for_event(d->event, 0, + CA_PROP_EVENT_ID, "drag-fail", + CA_PROP_EVENT_DESCRIPTION, "Drag failed", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + goto finish; + } } - } finish: - ; - /* if (ret != CA_SUCCESS) */ - /* g_warning("Failed to play event sound: %s", ca_strerror(ret)); */ + ; + /* if (ret != CA_SUCCESS) */ + /* g_warning("Failed to play event sound: %s", ca_strerror(ret)); */ } static void dispatch_queue(void) { - SoundEventData *d; + SoundEventData *d; - while ((d = g_queue_pop_head(&sound_event_queue))) { + while ((d = g_queue_pop_head(&sound_event_queue))) { - if (!(d = filter_sound_event(d))) - continue; + if (!(d = filter_sound_event(d))) + continue; - dispatch_sound_event(d); - free_sound_event(d); - } + dispatch_sound_event(d); + free_sound_event(d); + } } static gboolean idle_cb(void *userdata) { - idle_id = 0; + idle_id = 0; - dispatch_queue(); + dispatch_queue(); - return FALSE; + return FALSE; } static void connect_settings(void); static gboolean emission_hook_cb(GSignalInvocationHint *hint, guint n_param_values, const GValue *param_values, gpointer data) { - static SoundEventData *d = NULL; - GdkEvent *e; - GObject *object; + static SoundEventData *d = NULL; + GdkEvent *e; + GObject *object; - connect_settings(); + connect_settings(); - if (disabled) - return TRUE; + if (disabled) + return TRUE; - object = g_value_get_object(¶m_values[0]); + object = g_value_get_object(¶m_values[0]); - /* g_message("signal '%s' on object of type '%s' with name '%s'", */ - /* g_signal_name(hint->signal_id), */ - /* G_OBJECT_TYPE_NAME(object), */ - /* gtk_widget_get_name(GTK_WIDGET(object))); */ + /* g_message("signal '%s' on object of type '%s' with name '%s'", */ + /* g_signal_name(hint->signal_id), */ + /* G_OBJECT_TYPE_NAME(object), */ + /* gtk_widget_get_name(GTK_WIDGET(object))); */ - /* if (GTK_IS_WINDOW(object)) */ - /* g_message("window role='%s' title='%s' type='%u'", */ - /* gtk_window_get_role(GTK_WINDOW(object)), */ - /* gtk_window_get_title(GTK_WINDOW(object)), */ - /* gtk_window_get_type_hint(GTK_WINDOW(object))); */ + /* if (GTK_IS_WINDOW(object)) */ + /* g_message("window role='%s' title='%s' type='%u'", */ + /* gtk_window_get_role(GTK_WINDOW(object)), */ + /* gtk_window_get_title(GTK_WINDOW(object)), */ + /* gtk_window_get_type_hint(GTK_WINDOW(object))); */ - /* Filter a few very often occuring signals as quickly as possible */ - if ((hint->signal_id == signal_id_widget_hide || - hint->signal_id == signal_id_widget_show || - hint->signal_id == signal_id_widget_window_state_event) && - !GTK_IS_WINDOW(object)) - return TRUE; + /* Filter a few very often occuring signals as quickly as possible */ + if ((hint->signal_id == signal_id_widget_hide || + hint->signal_id == signal_id_widget_show || + hint->signal_id == signal_id_widget_window_state_event) && + !GTK_IS_WINDOW(object)) + return TRUE; - if (hint->signal_id != signal_id_widget_hide && - hint->signal_id != signal_id_dialog_response && - !GTK_WIDGET_DRAWABLE(object)) - return TRUE; + if (hint->signal_id != signal_id_widget_hide && + hint->signal_id != signal_id_dialog_response && + !GTK_WIDGET_DRAWABLE(object)) + return TRUE; - d = g_slice_new0(SoundEventData); + d = g_slice_new0(SoundEventData); - d->object = g_object_ref(object); + d->object = g_object_ref(object); - d->signal_id = hint->signal_id; + d->signal_id = hint->signal_id; - if (d->signal_id == signal_id_widget_window_state_event) { - d->event = gdk_event_copy(g_value_peek_pointer(¶m_values[1])); - } else if ((e = gtk_get_current_event())) - d->event = gdk_event_copy(e); + if (d->signal_id == signal_id_widget_window_state_event) { + d->event = gdk_event_copy(g_value_peek_pointer(¶m_values[1])); + } else if ((e = gtk_get_current_event())) + d->event = gdk_event_copy(e); - if (n_param_values > 1) { - g_value_init(&d->arg1, G_VALUE_TYPE(¶m_values[1])); - g_value_copy(¶m_values[1], &d->arg1); - d->arg1_is_set = TRUE; - } + if (n_param_values > 1) { + g_value_init(&d->arg1, G_VALUE_TYPE(¶m_values[1])); + g_value_copy(¶m_values[1], &d->arg1); + d->arg1_is_set = TRUE; + } - g_queue_push_tail(&sound_event_queue, d); + g_queue_push_tail(&sound_event_queue, d); - if (idle_id == 0) - idle_id = gdk_threads_add_idle_full(GDK_PRIORITY_REDRAW-1, (GSourceFunc) idle_cb, NULL, NULL); + if (idle_id == 0) + idle_id = gdk_threads_add_idle_full(GDK_PRIORITY_REDRAW-1, (GSourceFunc) idle_cb, NULL, NULL); - return TRUE; + return TRUE; } static void install_hook(GType type, const char *sig, guint *sn) { - GTypeClass *type_class; + GTypeClass *type_class; - type_class = g_type_class_ref(type); + type_class = g_type_class_ref(type); - *sn = g_signal_lookup(sig, type); - g_signal_add_emission_hook(*sn, 0, emission_hook_cb, NULL, NULL); + *sn = g_signal_lookup(sig, type); + g_signal_add_emission_hook(*sn, 0, emission_hook_cb, NULL, NULL); - g_type_class_unref(type_class); + g_type_class_unref(type_class); } static void read_enable_input_feedback_sounds(GtkSettings *s) { - gboolean enabled = !disabled; - - if (g_getenv("CANBERRA_FORCE_INPUT_FEEDBACK_SOUNDS")) - disabled = FALSE; - else { - g_object_get(G_OBJECT(s), "gtk-enable-input-feedback-sounds", &enabled, NULL); - disabled = !enabled; - } + gboolean enabled = !disabled; + + if (g_getenv("CANBERRA_FORCE_INPUT_FEEDBACK_SOUNDS")) + disabled = FALSE; + else { + g_object_get(G_OBJECT(s), "gtk-enable-input-feedback-sounds", &enabled, NULL); + disabled = !enabled; + } } static void enable_input_feedback_sounds_changed(GtkSettings *s, GParamSpec *arg1, gpointer userdata) { - read_enable_input_feedback_sounds(s); + read_enable_input_feedback_sounds(s); } static void connect_settings(void) { - GtkSettings *s; - static gboolean connected = FALSE; + GtkSettings *s; + static gboolean connected = FALSE; - if (connected) - return; + if (connected) + return; - if (!(s = gtk_settings_get_default())) - return; + if (!(s = gtk_settings_get_default())) + return; - if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-enable-input-feedback-sounds")) { - g_signal_connect(G_OBJECT(s), "notify::gtk-enable-input-feedback-sounds", G_CALLBACK(enable_input_feedback_sounds_changed), NULL); - read_enable_input_feedback_sounds(s); - } else - g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-enable-input-feedback-sounds property."); + if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-enable-input-feedback-sounds")) { + g_signal_connect(G_OBJECT(s), "notify::gtk-enable-input-feedback-sounds", G_CALLBACK(enable_input_feedback_sounds_changed), NULL); + read_enable_input_feedback_sounds(s); + } else + g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-enable-input-feedback-sounds property."); - connected = TRUE; + connected = TRUE; } static gboolean quit_handler(gpointer data) { - dispatch_queue(); - return FALSE; + dispatch_queue(); + return FALSE; } G_MODULE_EXPORT void gtk_module_init(gint *argc, gchar ***argv[]) { - /* This is the same quark libgnomeui uses! */ - disable_sound_quark = g_quark_from_string("gnome_disable_sound_events"); - was_iconized_quark = g_quark_from_string("canberra_was_iconized"); - is_xembed_quark = g_quark_from_string("canberra_is_xembed"); - - /* Hook up the gtk setting */ - connect_settings(); - - install_hook(GTK_TYPE_WINDOW, "show", &signal_id_widget_show); - install_hook(GTK_TYPE_WINDOW, "hide", &signal_id_widget_hide); - install_hook(GTK_TYPE_DIALOG, "response", &signal_id_dialog_response); - install_hook(GTK_TYPE_MENU_ITEM, "activate", &signal_id_menu_item_activate); - install_hook(GTK_TYPE_CHECK_MENU_ITEM, "toggled", &signal_id_check_menu_item_toggled); - install_hook(GTK_TYPE_TOGGLE_BUTTON, "toggled", &signal_id_toggle_button_toggled); - install_hook(GTK_TYPE_BUTTON, "pressed", &signal_id_button_pressed); - install_hook(GTK_TYPE_BUTTON, "released", &signal_id_button_released); - install_hook(GTK_TYPE_WIDGET, "window-state-event", &signal_id_widget_window_state_event); - install_hook(GTK_TYPE_NOTEBOOK, "switch-page", &signal_id_notebook_switch_page); - install_hook(GTK_TYPE_TREE_VIEW, "cursor-changed", &signal_id_tree_view_cursor_changed); - install_hook(GTK_TYPE_ICON_VIEW, "selection-changed", &signal_id_icon_view_selection_changed); - install_hook(GTK_TYPE_WIDGET, "drag-begin", &signal_id_widget_drag_begin); - install_hook(GTK_TYPE_WIDGET, "drag-drop", &signal_id_widget_drag_drop); - install_hook(GTK_TYPE_WIDGET, "drag-failed", &signal_id_widget_drag_failed); - install_hook(GTK_TYPE_EXPANDER, "activate", &signal_id_expander_activate); - - gtk_quit_add(1, quit_handler, NULL); + /* This is the same quark libgnomeui uses! */ + disable_sound_quark = g_quark_from_string("gnome_disable_sound_events"); + was_iconized_quark = g_quark_from_string("canberra_was_iconized"); + is_xembed_quark = g_quark_from_string("canberra_is_xembed"); + + /* Hook up the gtk setting */ + connect_settings(); + + install_hook(GTK_TYPE_WINDOW, "show", &signal_id_widget_show); + install_hook(GTK_TYPE_WINDOW, "hide", &signal_id_widget_hide); + install_hook(GTK_TYPE_DIALOG, "response", &signal_id_dialog_response); + install_hook(GTK_TYPE_MENU_ITEM, "activate", &signal_id_menu_item_activate); + install_hook(GTK_TYPE_CHECK_MENU_ITEM, "toggled", &signal_id_check_menu_item_toggled); + install_hook(GTK_TYPE_TOGGLE_BUTTON, "toggled", &signal_id_toggle_button_toggled); + install_hook(GTK_TYPE_BUTTON, "pressed", &signal_id_button_pressed); + install_hook(GTK_TYPE_BUTTON, "released", &signal_id_button_released); + install_hook(GTK_TYPE_WIDGET, "window-state-event", &signal_id_widget_window_state_event); + install_hook(GTK_TYPE_NOTEBOOK, "switch-page", &signal_id_notebook_switch_page); + install_hook(GTK_TYPE_TREE_VIEW, "cursor-changed", &signal_id_tree_view_cursor_changed); + install_hook(GTK_TYPE_ICON_VIEW, "selection-changed", &signal_id_icon_view_selection_changed); + install_hook(GTK_TYPE_WIDGET, "drag-begin", &signal_id_widget_drag_begin); + install_hook(GTK_TYPE_WIDGET, "drag-drop", &signal_id_widget_drag_drop); + install_hook(GTK_TYPE_WIDGET, "drag-failed", &signal_id_widget_drag_failed); + install_hook(GTK_TYPE_EXPANDER, "activate", &signal_id_expander_activate); + + gtk_quit_add(1, quit_handler, NULL); } G_MODULE_EXPORT gchar* g_module_check_init(GModule *module); G_MODULE_EXPORT gchar* g_module_check_init(GModule *module) { - g_module_make_resident(module); - return NULL; + g_module_make_resident(module); + return NULL; } diff --git a/src/canberra-gtk-play.c b/src/canberra-gtk-play.c index b8191dd..4ab0c89 100644 --- a/src/canberra-gtk-play.c +++ b/src/canberra-gtk-play.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -35,161 +37,161 @@ static int n_loops = 1; static void callback(ca_context *c, uint32_t id, int error, void *userdata); static gboolean idle_quit(gpointer userdata) { - gtk_main_quit(); - return FALSE; + gtk_main_quit(); + return FALSE; } static gboolean idle_play(gpointer userdata) { - int r; + int r; - g_assert(n_loops > 1); + g_assert(n_loops > 1); - n_loops--; + n_loops--; - r = ca_context_play_full(ca_gtk_context_get(), 1, proplist, callback, NULL); + r = ca_context_play_full(ca_gtk_context_get(), 1, proplist, callback, NULL); - if (r < 0) { - g_printerr("Failed to play sound: %s\n", ca_strerror(r)); - ret = 1; - gtk_main_quit(); - } + if (r < 0) { + g_printerr("Failed to play sound: %s\n", ca_strerror(r)); + ret = 1; + gtk_main_quit(); + } - return FALSE; + return FALSE; } static void callback(ca_context *c, uint32_t id, int error, void *userdata) { - if (error < 0) { - g_printerr("Failed to play sound (callback): %s\n", ca_strerror(error)); - ret = 1; - - } else if (n_loops > 1) { - /* So, why don't we call ca_context_play_full() here directly? - -- Because the context this callback is called from is - explicitly documented as undefined and no libcanberra function - may be called from it. */ - - g_idle_add(idle_play, NULL); - return; - } - - /* So, why don't we call gtk_main_quit() here directly? -- Because - * otherwise we might end up with a small race condition: this - * callback might get called before the main loop actually started - * running */ - g_idle_add(idle_quit, NULL); + if (error < 0) { + g_printerr("Failed to play sound (callback): %s\n", ca_strerror(error)); + ret = 1; + + } else if (n_loops > 1) { + /* So, why don't we call ca_context_play_full() here directly? + -- Because the context this callback is called from is + explicitly documented as undefined and no libcanberra function + may be called from it. */ + + g_idle_add(idle_play, NULL); + return; + } + + /* So, why don't we call gtk_main_quit() here directly? -- Because + * otherwise we might end up with a small race condition: this + * callback might get called before the main loop actually started + * running */ + g_idle_add(idle_quit, NULL); } static GQuark error_domain(void) { - return g_quark_from_static_string("canberra-error-quark"); + return g_quark_from_static_string("canberra-error-quark"); } static gboolean property_callback( - const gchar *option_name, - const gchar *value, - gpointer data, - GError **error) { + const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) { - const char *equal; - char *t; + const char *equal; + char *t; - if (!(equal = strchr(value, '='))) { - g_set_error(error, error_domain(), 0, "Property lacks '='."); - return FALSE; - } + if (!(equal = strchr(value, '='))) { + g_set_error(error, error_domain(), 0, "Property lacks '='."); + return FALSE; + } - t = g_strndup(value, equal - value); + t = g_strndup(value, equal - value); - if (ca_proplist_sets(proplist, t, equal + 1) < 0) { - g_set_error(error, error_domain(), 0, "Invalid property."); - g_free(t); - return FALSE; - } + if (ca_proplist_sets(proplist, t, equal + 1) < 0) { + g_set_error(error, error_domain(), 0, "Invalid property."); + g_free(t); + return FALSE; + } - g_free(t); - return TRUE; + g_free(t); + return TRUE; } int main (int argc, char *argv[]) { - GOptionContext *oc; - static gchar *event_id = NULL, *filename = NULL, *event_description = NULL, *cache_control = NULL, *volume = NULL; - int r; - static gboolean version = FALSE; - GError *error = NULL; - - static const GOptionEntry options[] = { - { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display version number and quit", NULL }, - { "id", 'i', 0, G_OPTION_ARG_STRING, &event_id, "Event sound identifier", "STRING" }, - { "file", 'f', 0, G_OPTION_ARG_STRING, &filename, "Play file", "PATH" }, - { "description", 'd', 0, G_OPTION_ARG_STRING, &event_description, "Event sound description", "STRING" }, - { "cache-control", 'c', 0, G_OPTION_ARG_STRING, &cache_control, "Cache control (permanent, volatile, never)", "STRING" }, - { "loop", 'l', 0, G_OPTION_ARG_INT, &n_loops, "Loop how many times (detault: 1)", "INTEGER" }, - { "volume", 'V', 0, G_OPTION_ARG_STRING, &volume, "A floating point dB value for the sample volume (ex: 0.0)", "STRING" }, - { "property", 0, 0, G_OPTION_ARG_CALLBACK, (void*) property_callback, "An arbitrary property", "STRING" }, - { NULL, 0, 0, 0, NULL, NULL, NULL } - }; - - setlocale(LC_ALL, ""); - - g_type_init(); - g_thread_init(NULL); - - ca_proplist_create(&proplist); - - oc = g_option_context_new("- canberra-gtk-play"); - g_option_context_add_main_entries(oc, options, NULL); - g_option_context_add_group(oc, gtk_get_option_group(TRUE)); - g_option_context_set_help_enabled(oc, TRUE); - - if (!(g_option_context_parse(oc, &argc, &argv, &error))) { - g_print("Option parsing failed: %s\n", error->message); - return 1; - } - g_option_context_free(oc); - - if (version) { - g_print("canberra-gtk-play from %s\n", PACKAGE_STRING); - return 0; - } - - if (!event_id && !filename) { - g_printerr("No event id or file specified.\n"); - return 1; - } - - ca_context_change_props(ca_gtk_context_get(), - CA_PROP_APPLICATION_NAME, "canberra-gtk-play", - CA_PROP_APPLICATION_ID, "org.freedesktop.libcanberra.GtkPlay", - NULL); - - if (event_id) - ca_proplist_sets(proplist, CA_PROP_EVENT_ID, event_id); - - if (filename) - ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME, filename); - - if (cache_control) - ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL, cache_control); - - if (event_description) - ca_proplist_sets(proplist, CA_PROP_EVENT_DESCRIPTION, event_description); - - if (volume) - ca_proplist_sets(proplist, CA_PROP_CANBERRA_VOLUME, volume); - - r = ca_context_play_full(ca_gtk_context_get(), 1, proplist, callback, NULL); - - if (r < 0) { - g_printerr("Failed to play sound: %s\n", ca_strerror(r)); - ret = 1; - goto finish; - } - - gtk_main(); + GOptionContext *oc; + static gchar *event_id = NULL, *filename = NULL, *event_description = NULL, *cache_control = NULL, *volume = NULL; + int r; + static gboolean version = FALSE; + GError *error = NULL; + + static const GOptionEntry options[] = { + { "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display version number and quit", NULL }, + { "id", 'i', 0, G_OPTION_ARG_STRING, &event_id, "Event sound identifier", "STRING" }, + { "file", 'f', 0, G_OPTION_ARG_STRING, &filename, "Play file", "PATH" }, + { "description", 'd', 0, G_OPTION_ARG_STRING, &event_description, "Event sound description", "STRING" }, + { "cache-control", 'c', 0, G_OPTION_ARG_STRING, &cache_control, "Cache control (permanent, volatile, never)", "STRING" }, + { "loop", 'l', 0, G_OPTION_ARG_INT, &n_loops, "Loop how many times (detault: 1)", "INTEGER" }, + { "volume", 'V', 0, G_OPTION_ARG_STRING, &volume, "A floating point dB value for the sample volume (ex: 0.0)", "STRING" }, + { "property", 0, 0, G_OPTION_ARG_CALLBACK, (void*) property_callback, "An arbitrary property", "STRING" }, + { NULL, 0, 0, 0, NULL, NULL, NULL } + }; + + setlocale(LC_ALL, ""); + + g_type_init(); + g_thread_init(NULL); + + ca_proplist_create(&proplist); + + oc = g_option_context_new("- canberra-gtk-play"); + g_option_context_add_main_entries(oc, options, NULL); + g_option_context_add_group(oc, gtk_get_option_group(TRUE)); + g_option_context_set_help_enabled(oc, TRUE); + + if (!(g_option_context_parse(oc, &argc, &argv, &error))) { + g_print("Option parsing failed: %s\n", error->message); + return 1; + } + g_option_context_free(oc); + + if (version) { + g_print("canberra-gtk-play from %s\n", PACKAGE_STRING); + return 0; + } + + if (!event_id && !filename) { + g_printerr("No event id or file specified.\n"); + return 1; + } + + ca_context_change_props(ca_gtk_context_get(), + CA_PROP_APPLICATION_NAME, "canberra-gtk-play", + CA_PROP_APPLICATION_ID, "org.freedesktop.libcanberra.GtkPlay", + NULL); + + if (event_id) + ca_proplist_sets(proplist, CA_PROP_EVENT_ID, event_id); + + if (filename) + ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME, filename); + + if (cache_control) + ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL, cache_control); + + if (event_description) + ca_proplist_sets(proplist, CA_PROP_EVENT_DESCRIPTION, event_description); + + if (volume) + ca_proplist_sets(proplist, CA_PROP_CANBERRA_VOLUME, volume); + + r = ca_context_play_full(ca_gtk_context_get(), 1, proplist, callback, NULL); + + if (r < 0) { + g_printerr("Failed to play sound: %s\n", ca_strerror(r)); + ret = 1; + goto finish; + } + + gtk_main(); finish: - ca_proplist_destroy(proplist); + ca_proplist_destroy(proplist); - return ret; + return ret; } diff --git a/src/canberra-gtk.c b/src/canberra-gtk.c index 6d9a6d9..9f8a31d 100644 --- a/src/canberra-gtk.c +++ b/src/canberra-gtk.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -49,31 +51,31 @@ */ static void read_sound_theme_name(ca_context *c, GtkSettings *s) { - gchar *theme_name = NULL; + gchar *theme_name = NULL; - g_object_get(G_OBJECT(s), "gtk-sound-theme-name", &theme_name, NULL); + g_object_get(G_OBJECT(s), "gtk-sound-theme-name", &theme_name, NULL); - if (theme_name) { - ca_context_change_props(c, CA_PROP_CANBERRA_XDG_THEME_NAME, theme_name, NULL); - g_free(theme_name); - } + if (theme_name) { + ca_context_change_props(c, CA_PROP_CANBERRA_XDG_THEME_NAME, theme_name, NULL); + g_free(theme_name); + } } static void read_enable_event_sounds(ca_context *c, GtkSettings *s) { - gboolean enable_event_sounds = TRUE; + gboolean enable_event_sounds = TRUE; - if (!g_getenv("CANBERRA_FORCE_EVENT_SOUNDS")) - g_object_get(G_OBJECT(s), "gtk-enable-event-sounds", &enable_event_sounds, NULL); + if (!g_getenv("CANBERRA_FORCE_EVENT_SOUNDS")) + g_object_get(G_OBJECT(s), "gtk-enable-event-sounds", &enable_event_sounds, NULL); - ca_context_change_props(c, CA_PROP_CANBERRA_ENABLE, enable_event_sounds ? "1" : "0", NULL); + ca_context_change_props(c, CA_PROP_CANBERRA_ENABLE, enable_event_sounds ? "1" : "0", NULL); } static void sound_theme_name_changed(GtkSettings *s, GParamSpec *arg1, ca_context *c) { - read_sound_theme_name(c, s); + read_sound_theme_name(c, s); } static void enable_event_sounds_changed(GtkSettings *s, GParamSpec *arg1, ca_context *c) { - read_enable_event_sounds(c, s); + read_enable_event_sounds(c, s); } /** @@ -86,7 +88,7 @@ static void enable_event_sounds_changed(GtkSettings *s, GParamSpec *arg1, ca_con * and must not be destroyed */ ca_context *ca_gtk_context_get(void) { - return ca_gtk_context_get_for_screen(NULL); + return ca_gtk_context_get_for_screen(NULL); } /** @@ -107,92 +109,92 @@ ca_context *ca_gtk_context_get(void) { * Since: 0.13 */ ca_context *ca_gtk_context_get_for_screen(GdkScreen *screen) { - ca_context *c = NULL; - ca_proplist *p = NULL; - const char *name; - GtkSettings *s; + ca_context *c = NULL; + ca_proplist *p = NULL; + const char *name; + GtkSettings *s; - if (!screen) - screen = gdk_screen_get_default(); + if (!screen) + screen = gdk_screen_get_default(); - if ((c = g_object_get_data(G_OBJECT(screen), "canberra::gtk::context"))) - return c; + if ((c = g_object_get_data(G_OBJECT(screen), "canberra::gtk::context"))) + return c; - if (ca_context_create(&c) != CA_SUCCESS) - return NULL; + if (ca_context_create(&c) != CA_SUCCESS) + return NULL; - if (ca_proplist_create(&p) != CA_SUCCESS) { - ca_context_destroy(c); - return NULL; - } + if (ca_proplist_create(&p) != CA_SUCCESS) { + ca_context_destroy(c); + return NULL; + } - if ((name = g_get_application_name())) - ca_proplist_sets(p, CA_PROP_APPLICATION_NAME, name); + if ((name = g_get_application_name())) + ca_proplist_sets(p, CA_PROP_APPLICATION_NAME, name); - if ((name = gdk_display_get_name(gdk_screen_get_display(screen)))) - ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, name); + if ((name = gdk_display_get_name(gdk_screen_get_display(screen)))) + ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, name); - ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen)); + ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen)); - ca_context_change_props_full(c, p); - ca_proplist_destroy(p); + ca_context_change_props_full(c, p); + ca_proplist_destroy(p); - if ((s = gtk_settings_get_for_screen(screen))) { + if ((s = gtk_settings_get_for_screen(screen))) { - if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-sound-theme-name")) { - g_signal_connect(G_OBJECT(s), "notify::gtk-sound-theme-name", G_CALLBACK(sound_theme_name_changed), c); - read_sound_theme_name(c, s); - } else - g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-sound-theme-name property."); + if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-sound-theme-name")) { + g_signal_connect(G_OBJECT(s), "notify::gtk-sound-theme-name", G_CALLBACK(sound_theme_name_changed), c); + read_sound_theme_name(c, s); + } else + g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-sound-theme-name property."); - if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-enable-event-sounds")) { - g_signal_connect(G_OBJECT(s), "notify::gtk-enable-event-sounds", G_CALLBACK(enable_event_sounds_changed), c); - read_enable_event_sounds(c, s); - } else - g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-enable-event-sounds property."); - } + if (g_object_class_find_property(G_OBJECT_GET_CLASS(s), "gtk-enable-event-sounds")) { + g_signal_connect(G_OBJECT(s), "notify::gtk-enable-event-sounds", G_CALLBACK(enable_event_sounds_changed), c); + read_enable_event_sounds(c, s); + } else + g_debug("This Gtk+ version doesn't have the GtkSettings::gtk-enable-event-sounds property."); + } - g_object_set_data_full(G_OBJECT(screen), "canberra::gtk::context", c, (GDestroyNotify) ca_context_destroy); + g_object_set_data_full(G_OBJECT(screen), "canberra::gtk::context", c, (GDestroyNotify) ca_context_destroy); - return c; + return c; } static GtkWindow* get_toplevel(GtkWidget *w) { - if (!(w = gtk_widget_get_toplevel(w))) - return NULL; + if (!(w = gtk_widget_get_toplevel(w))) + return NULL; - if (!GTK_IS_WINDOW(w)) - return NULL; + if (!GTK_IS_WINDOW(w)) + return NULL; - return GTK_WINDOW(w); + return GTK_WINDOW(w); } static gint window_get_desktop(GdkDisplay *d, GdkWindow *w) { - Atom type_return; - gint format_return; - gulong nitems_return; - gulong bytes_after_return; - guchar *data = NULL; - gint ret = -1; - - if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w), - gdk_x11_get_xatom_by_name_for_display(d, "_NET_WM_DESKTOP"), - 0, G_MAXLONG, False, XA_CARDINAL, &type_return, - &format_return, &nitems_return, &bytes_after_return, - &data) != Success) - return -1; - - if (type_return == XA_CARDINAL && format_return == 32 && data) { - guint32 desktop = *(guint32*) data; - - if (desktop != 0xFFFFFFFF) - ret = (gint) desktop; - } - - if (type_return != None && data != NULL) - XFree(data); - - return ret; + Atom type_return; + gint format_return; + gulong nitems_return; + gulong bytes_after_return; + guchar *data = NULL; + gint ret = -1; + + if (XGetWindowProperty(GDK_DISPLAY_XDISPLAY(d), GDK_WINDOW_XID(w), + gdk_x11_get_xatom_by_name_for_display(d, "_NET_WM_DESKTOP"), + 0, G_MAXLONG, False, XA_CARDINAL, &type_return, + &format_return, &nitems_return, &bytes_after_return, + &data) != Success) + return -1; + + if (type_return == XA_CARDINAL && format_return == 32 && data) { + guint32 desktop = *(guint32*) data; + + if (desktop != 0xFFFFFFFF) + ret = (gint) desktop; + } + + if (type_return != None && data != NULL) + XFree(data); + + return ret; } /** @@ -208,122 +210,124 @@ static gint window_get_desktop(GdkDisplay *d, GdkWindow *w) { */ int ca_gtk_proplist_set_for_widget(ca_proplist *p, GtkWidget *widget) { - GtkWindow *w; - int ret; - const char *t, *role; + GtkWindow *w; + int ret; + const char *t, *role; - ca_return_val_if_fail(p, CA_ERROR_INVALID); - ca_return_val_if_fail(widget, CA_ERROR_INVALID); - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(widget, CA_ERROR_INVALID); + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - if (!(w = get_toplevel(widget))) - return CA_ERROR_INVALID; + if (!(w = get_toplevel(widget))) + return CA_ERROR_INVALID; - if ((t = gtk_window_get_title(w))) - if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_NAME, t)) < 0) - return ret; + if ((t = gtk_window_get_title(w))) + if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_NAME, t)) < 0) + return ret; - if ((role = gtk_window_get_role(w))) { - if (role && t) { - char *id = ca_sprintf_malloc("%s#%s", t, role); + if ((role = gtk_window_get_role(w))) { + if (role && t) { + char *id = ca_sprintf_malloc("%s#%s", t, role); - if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, id)) < 0) { - ca_free(id); - return ret; - } + if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, id)) < 0) { + ca_free(id); + return ret; + } - ca_free(id); - } - } else if (t) - if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, t)) < 0) - return ret; - - if ((t = gtk_window_get_icon_name(w))) - if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ICON_NAME, t)) < 0) - return ret; - - if (GTK_WIDGET_REALIZED(GTK_WIDGET(w))) { - GdkWindow *dw = NULL; - GdkScreen *screen = NULL; - GdkDisplay *display = NULL; - gint x = -1, y = -1, width = -1, height = -1, screen_width = -1, screen_height = -1; - - if ((dw = gtk_widget_get_window(GTK_WIDGET(w)))) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long) GDK_WINDOW_XID(dw))) < 0) - return ret; + ca_free(id); + } + } else if (t) + if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ID, t)) < 0) + return ret; - if ((display = gtk_widget_get_display(GTK_WIDGET(w)))) { - if ((t = gdk_display_get_name(display))) - if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, t)) < 0) - return ret; + if ((t = gtk_window_get_icon_name(w))) + if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ICON_NAME, t)) < 0) + return ret; - if (dw) { - gint desktop = window_get_desktop(display, dw); + if (GTK_WIDGET_REALIZED(GTK_WIDGET(w))) { + GdkWindow *dw = NULL; + GdkScreen *screen = NULL; + GdkDisplay *display = NULL; + gint x = -1, y = -1, width = -1, height = -1, screen_width = -1, screen_height = -1; - if (desktop >= 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_DESKTOP, "%i", desktop)) < 0) - return ret; - } - } + if ((dw = gtk_widget_get_window(GTK_WIDGET(w)))) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long) GDK_WINDOW_XID(dw))) < 0) + return ret; - if ((screen = gtk_widget_get_screen(GTK_WIDGET(w)))) { + if ((display = gtk_widget_get_display(GTK_WIDGET(w)))) { + if ((t = gdk_display_get_name(display))) + if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, t)) < 0) + return ret; - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen))) < 0) - return ret; + if (dw) { + gint desktop = window_get_desktop(display, dw); - if (dw) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_MONITOR, "%i", gdk_screen_get_monitor_at_window(screen, dw))) < 0) - return ret; - } + if (desktop >= 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_DESKTOP, "%i", desktop)) < 0) + return ret; + } + } - /* FIXME, this might cause a round trip */ + if ((screen = gtk_widget_get_screen(GTK_WIDGET(w)))) { - if (dw) { - gdk_window_get_origin(dw, &x, &y); + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen))) < 0) + return ret; - if (x >= 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X, "%i", x)) < 0) - return ret; - if (y >= 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_Y, "%i", y)) < 0) - return ret; - } + if (dw) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_MONITOR, "%i", gdk_screen_get_monitor_at_window(screen, dw))) < 0) + return ret; + } - gtk_window_get_size(w, &width, &height); + /* FIXME, this might cause a round trip */ - if (width > 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_WIDTH, "%i", width)) < 0) - return ret; - if (height > 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HEIGHT, "%i", height)) < 0) - return ret; + if (dw) { + gdk_window_get_origin(dw, &x, &y); - if (x >= 0 && width > 0) { - screen_width = gdk_screen_get_width(gtk_widget_get_screen(GTK_WIDGET(w))); + if (x >= 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X, "%i", x)) < 0) + return ret; + if (y >= 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_Y, "%i", y)) < 0) + return ret; + } - x += width/2; - x = CA_CLAMP(x, 0, screen_width-1); + gtk_window_get_size(w, &width, &height); - /* We use these strange format strings here to avoid that libc - * applies locale information on the formatting of floating - * numbers. */ + if (width > 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_WIDTH, "%i", width)) < 0) + return ret; + if (height > 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HEIGHT, "%i", height)) < 0) + return ret; - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HPOS, "%i.%03i", (int) (x/(screen_width-1)), (int) (1000.0*x/(screen_width-1)) % 1000)) < 0) - return ret; - } + if (x >= 0 && width > 0) { + screen_width = gdk_screen_get_width(gtk_widget_get_screen(GTK_WIDGET(w))); - if (y >= 0 && height > 0) { - screen_height = gdk_screen_get_height(gtk_widget_get_screen(GTK_WIDGET(w))); + x += width/2; + x = CA_CLAMP(x, 0, screen_width-1); - y += height/2; - y = CA_CLAMP(y, 0, screen_height-1); + /* We use these strange format strings here to avoid that libc + * applies locale information on the formatting of floating + * numbers. */ - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_VPOS, "%i.%03i", (int) (y/(screen_height-1)), (int) (1000.0*y/(screen_height-1)) % 1000)) < 0) - return ret; + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HPOS, "%i.%03i", + (int) (x/(screen_width-1)), (int) (1000.0*x/(screen_width-1)) % 1000)) < 0) + return ret; + } + + if (y >= 0 && height > 0) { + screen_height = gdk_screen_get_height(gtk_widget_get_screen(GTK_WIDGET(w))); + + y += height/2; + y = CA_CLAMP(y, 0, screen_height-1); + + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_VPOS, "%i.%03i", + (int) (y/(screen_height-1)), (int) (1000.0*y/(screen_height-1)) % 1000)) < 0) + return ret; + } } - } - return CA_SUCCESS; + return CA_SUCCESS; } /** @@ -341,59 +345,61 @@ int ca_gtk_proplist_set_for_widget(ca_proplist *p, GtkWidget *widget) { */ int ca_gtk_proplist_set_for_event(ca_proplist *p, GdkEvent *e) { - gdouble x, y; - GdkWindow *gw; - GtkWidget *w = NULL; - int ret; + gdouble x, y; + GdkWindow *gw; + GtkWidget *w = NULL; + int ret; - ca_return_val_if_fail(p, CA_ERROR_INVALID); - ca_return_val_if_fail(e, CA_ERROR_INVALID); - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(e, CA_ERROR_INVALID); + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - if ((gw = e->any.window)) { - gdk_window_get_user_data(gw, (gpointer*) &w); + if ((gw = e->any.window)) { + gdk_window_get_user_data(gw, (gpointer*) &w); - if (w) - if ((ret = ca_gtk_proplist_set_for_widget(p, w)) < 0) - return ret; - } + if (w) + if ((ret = ca_gtk_proplist_set_for_widget(p, w)) < 0) + return ret; + } - if (gdk_event_get_root_coords(e, &x, &y)) { + if (gdk_event_get_root_coords(e, &x, &y)) { - if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_X, "%0.0f", x)) < 0) - return ret; + if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_X, "%0.0f", x)) < 0) + return ret; - if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_Y, "%0.0f", y)) < 0) - return ret; + if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_Y, "%0.0f", y)) < 0) + return ret; - if (w) { - int width, height; + if (w) { + int width, height; - width = gdk_screen_get_width(gtk_widget_get_screen(w)); - height = gdk_screen_get_height(gtk_widget_get_screen(w)); + width = gdk_screen_get_width(gtk_widget_get_screen(w)); + height = gdk_screen_get_height(gtk_widget_get_screen(w)); - /* We use these strange format strings here to avoid that - * libc applies locale information on the formatting of - * floating numbers. */ + /* We use these strange format strings here to avoid that + * libc applies locale information on the formatting of + * floating numbers. */ - if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_HPOS, "%i.%03i", (int) (x/(width-1)), (int) (1000.0*x/(width-1)) % 1000)) < 0) - return ret; + if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_HPOS, "%i.%03i", + (int) (x/(width-1)), (int) (1000.0*x/(width-1)) % 1000)) < 0) + return ret; - if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_VPOS, "%i.%03i", (int) (y/(height-1)), (int) (1000.0*y/(height-1)) % 1000)) < 0) - return ret; + if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_VPOS, "%i.%03i", + (int) (y/(height-1)), (int) (1000.0*y/(height-1)) % 1000)) < 0) + return ret; + } } - } - if (e->type == GDK_BUTTON_PRESS || - e->type == GDK_2BUTTON_PRESS || - e->type == GDK_3BUTTON_PRESS || - e->type == GDK_BUTTON_RELEASE) { + if (e->type == GDK_BUTTON_PRESS || + e->type == GDK_2BUTTON_PRESS || + e->type == GDK_3BUTTON_PRESS || + e->type == GDK_BUTTON_RELEASE) { - if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_BUTTON, "%u", e->button.button)) < 0) - return ret; - } + if ((ret = ca_proplist_setf(p, CA_PROP_EVENT_MOUSE_BUTTON, "%u", e->button.button)) < 0) + return ret; + } - return CA_SUCCESS; + return CA_SUCCESS; } /** @@ -417,35 +423,35 @@ int ca_gtk_proplist_set_for_event(ca_proplist *p, GdkEvent *e) { */ int ca_gtk_play_for_widget(GtkWidget *w, uint32_t id, ...) { - va_list ap; - int ret; - ca_proplist *p; - GdkScreen *s; + va_list ap; + int ret; + ca_proplist *p; + GdkScreen *s; - ca_return_val_if_fail(w, CA_ERROR_INVALID); - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(w, CA_ERROR_INVALID); + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - if ((ret = ca_proplist_create(&p)) < 0) - return ret; + if ((ret = ca_proplist_create(&p)) < 0) + return ret; - if ((ret = ca_gtk_proplist_set_for_widget(p, w)) < 0) - goto fail; + if ((ret = ca_gtk_proplist_set_for_widget(p, w)) < 0) + goto fail; - va_start(ap, id); - ret = ca_proplist_merge_ap(p, ap); - va_end(ap); + va_start(ap, id); + ret = ca_proplist_merge_ap(p, ap); + va_end(ap); - if (ret < 0) - goto fail; + if (ret < 0) + goto fail; - s = gtk_widget_get_screen(w); - ret = ca_context_play_full(ca_gtk_context_get_for_screen(s), id, p, NULL, NULL); + s = gtk_widget_get_screen(w); + ret = ca_context_play_full(ca_gtk_context_get_for_screen(s), id, p, NULL, NULL); fail: - ca_assert_se(ca_proplist_destroy(p) == 0); + ca_assert_se(ca_proplist_destroy(p) == 0); - return ret; + return ret; } /** @@ -469,39 +475,39 @@ fail: */ int ca_gtk_play_for_event(GdkEvent *e, uint32_t id, ...) { - va_list ap; - int ret; - ca_proplist *p; - GdkScreen *s; + va_list ap; + int ret; + ca_proplist *p; + GdkScreen *s; - ca_return_val_if_fail(e, CA_ERROR_INVALID); - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(e, CA_ERROR_INVALID); + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - if ((ret = ca_proplist_create(&p)) < 0) - return ret; + if ((ret = ca_proplist_create(&p)) < 0) + return ret; - if ((ret = ca_gtk_proplist_set_for_event(p, e)) < 0) - goto fail; + if ((ret = ca_gtk_proplist_set_for_event(p, e)) < 0) + goto fail; - va_start(ap, id); - ret = ca_proplist_merge_ap(p, ap); - va_end(ap); + va_start(ap, id); + ret = ca_proplist_merge_ap(p, ap); + va_end(ap); - if (ret < 0) - goto fail; + if (ret < 0) + goto fail; - if (e->any.window) - s = gdk_drawable_get_screen(GDK_DRAWABLE(e->any.window)); - else - s = gdk_screen_get_default(); + if (e->any.window) + s = gdk_drawable_get_screen(GDK_DRAWABLE(e->any.window)); + else + s = gdk_screen_get_default(); - ret = ca_context_play_full(ca_gtk_context_get_for_screen(s), id, p, NULL, NULL); + ret = ca_context_play_full(ca_gtk_context_get_for_screen(s), id, p, NULL, NULL); fail: - ca_assert_se(ca_proplist_destroy(p) == 0); + ca_assert_se(ca_proplist_destroy(p) == 0); - return ret; + return ret; } /** @@ -516,11 +522,11 @@ fail: */ void ca_gtk_widget_disable_sounds(GtkWidget *w, gboolean enable) { - static GQuark disable_sound_quark = 0; + static GQuark disable_sound_quark = 0; - /* This is the same quark used by libgnomeui! */ - if (!disable_sound_quark) - disable_sound_quark = g_quark_from_static_string("gnome_disable_sound_events"); + /* This is the same quark used by libgnomeui! */ + if (!disable_sound_quark) + disable_sound_quark = g_quark_from_static_string("gnome_disable_sound_events"); - g_object_set_qdata(G_OBJECT(w), disable_sound_quark, GINT_TO_POINTER(!!enable)); + g_object_set_qdata(G_OBJECT(w), disable_sound_quark, GINT_TO_POINTER(!!enable)); } diff --git a/src/canberra-gtk.h b/src/canberra-gtk.h index 8daddc9..ec451c5 100644 --- a/src/canberra-gtk.h +++ b/src/canberra-gtk.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberragtkhfoo #define foocanberragtkhfoo diff --git a/src/canberra.h.in b/src/canberra.h.in index 49ec326..095f008 100644 --- a/src/canberra.h.in +++ b/src/canberra.h.in @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberrahfoo #define foocanberrahfoo @@ -54,9 +56,9 @@ extern "C" { * Evaluates to TRUE when the library version is newer than the * specified parameters. */ -#define CA_CHECK_VERSION(major,minor) \ - ((CA_MAJOR > (major)) || \ - (CA_MAJOR == (major) && CA_MINOR >= (minor))) +#define CA_CHECK_VERSION(major,minor) \ + ((CA_MAJOR > (major)) || \ + (CA_MAJOR == (major) && CA_MINOR >= (minor))) /** * CA_PROP_MEDIA_NAME: @@ -519,26 +521,26 @@ typedef void (*ca_finish_callback_t)(ca_context *c, uint32_t id, int error_code, * Error codes */ enum { - CA_SUCCESS = 0, - CA_ERROR_NOTSUPPORTED = -1, - CA_ERROR_INVALID = -2, - CA_ERROR_STATE = -3, - CA_ERROR_OOM = -4, - CA_ERROR_NODRIVER = -5, - CA_ERROR_SYSTEM = -6, - CA_ERROR_CORRUPT = -7, - CA_ERROR_TOOBIG = -8, - CA_ERROR_NOTFOUND = -9, - CA_ERROR_DESTROYED = -10, - CA_ERROR_CANCELED = -11, - CA_ERROR_NOTAVAILABLE = -12, - CA_ERROR_ACCESS = -13, - CA_ERROR_IO = -14, - CA_ERROR_INTERNAL = -15, - CA_ERROR_DISABLED = -16, - CA_ERROR_FORKED = -17, - CA_ERROR_DISCONNECTED = -18, - _CA_ERROR_MAX = -19 + CA_SUCCESS = 0, + CA_ERROR_NOTSUPPORTED = -1, + CA_ERROR_INVALID = -2, + CA_ERROR_STATE = -3, + CA_ERROR_OOM = -4, + CA_ERROR_NODRIVER = -5, + CA_ERROR_SYSTEM = -6, + CA_ERROR_CORRUPT = -7, + CA_ERROR_TOOBIG = -8, + CA_ERROR_NOTFOUND = -9, + CA_ERROR_DESTROYED = -10, + CA_ERROR_CANCELED = -11, + CA_ERROR_NOTAVAILABLE = -12, + CA_ERROR_ACCESS = -13, + CA_ERROR_IO = -14, + CA_ERROR_INTERNAL = -15, + CA_ERROR_DISABLED = -16, + CA_ERROR_FORKED = -17, + CA_ERROR_DISCONNECTED = -18, + _CA_ERROR_MAX = -19 }; /** diff --git a/src/common.c b/src/common.c index db60aa0..f18f13d 100644 --- a/src/common.c +++ b/src/common.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -124,42 +126,42 @@ */ int ca_context_create(ca_context **_c) { - ca_context *c; - int ret; - const char *d; + ca_context *c; + int ret; + const char *d; - 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(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(_c, CA_ERROR_INVALID); - if (!(c = ca_new0(ca_context, 1))) - return CA_ERROR_OOM; + if (!(c = ca_new0(ca_context, 1))) + return CA_ERROR_OOM; - if (!(c->mutex = ca_mutex_new())) { - ca_context_destroy(c); - return CA_ERROR_OOM; - } + if (!(c->mutex = ca_mutex_new())) { + ca_context_destroy(c); + return CA_ERROR_OOM; + } - if ((ret = ca_proplist_create(&c->props)) < 0) { - ca_context_destroy(c); - return ret; - } + if ((ret = ca_proplist_create(&c->props)) < 0) { + ca_context_destroy(c); + return ret; + } - if ((d = getenv("CANBERRA_DRIVER"))) { - if ((ret = ca_context_set_driver(c, d)) < 0) { - ca_context_destroy(c); - return ret; + if ((d = getenv("CANBERRA_DRIVER"))) { + if ((ret = ca_context_set_driver(c, d)) < 0) { + ca_context_destroy(c); + return ret; + } } - } - if ((d = getenv("CANBERRA_DEVICE"))) { - if ((ret = ca_context_change_device(c, d)) < 0) { - ca_context_destroy(c); - return ret; + if ((d = getenv("CANBERRA_DEVICE"))) { + if ((ret = ca_context_change_device(c, d)) < 0) { + ca_context_destroy(c); + return ret; + } } - } - *_c = c; - return CA_SUCCESS; + *_c = c; + return CA_SUCCESS; } /** @@ -171,29 +173,29 @@ int ca_context_create(ca_context **_c) { * Returns: 0 on success, negative error code on error. */ int ca_context_destroy(ca_context *c) { - int ret = CA_SUCCESS; + int ret = CA_SUCCESS; - 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(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - /* There's no locking necessary here, because the application is - * broken anyway if it destructs this object in one thread and - * still is calling a method of it in another. */ + /* There's no locking necessary here, because the application is + * broken anyway if it destructs this object in one thread and + * still is calling a method of it in another. */ - if (c->opened) - ret = driver_destroy(c); + if (c->opened) + ret = driver_destroy(c); - if (c->props) - ca_assert_se(ca_proplist_destroy(c->props) == CA_SUCCESS); + if (c->props) + ca_assert_se(ca_proplist_destroy(c->props) == CA_SUCCESS); - if (c->mutex) - ca_mutex_free(c->mutex); + if (c->mutex) + ca_mutex_free(c->mutex); - ca_free(c->driver); - ca_free(c->device); - ca_free(c); + ca_free(c->driver); + ca_free(c->device); + ca_free(c); - return ret; + return ret; } /** @@ -209,30 +211,30 @@ int ca_context_destroy(ca_context *c) { * Returns: 0 on success, negative error code on error. */ int ca_context_set_driver(ca_context *c, const char *driver) { - char *n; - int ret; - - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); - ca_return_val_if_fail_unlock(!c->opened, CA_ERROR_STATE, c->mutex); - - if (!driver) - n = NULL; - else if (!(n = ca_strdup(driver))) { - ret = CA_ERROR_OOM; - goto fail; - } + char *n; + int ret; + + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_mutex_lock(c->mutex); + ca_return_val_if_fail_unlock(!c->opened, CA_ERROR_STATE, c->mutex); + + if (!driver) + n = NULL; + else if (!(n = ca_strdup(driver))) { + ret = CA_ERROR_OOM; + goto fail; + } - ca_free(c->driver); - c->driver = n; + ca_free(c->driver); + c->driver = n; - ret = CA_SUCCESS; + ret = CA_SUCCESS; fail: - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } /** @@ -251,47 +253,47 @@ fail: * Returns: 0 on success, negative error code on error. */ int ca_context_change_device(ca_context *c, const char *device) { - char *n; - int ret; - - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); - - if (!device) - n = NULL; - else if (!(n = ca_strdup(device))) { - ret = CA_ERROR_OOM; - goto fail; - } + char *n; + int ret; + + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_mutex_lock(c->mutex); + + if (!device) + n = NULL; + else if (!(n = ca_strdup(device))) { + ret = CA_ERROR_OOM; + goto fail; + } - ret = c->opened ? driver_change_device(c, n) : CA_SUCCESS; + ret = c->opened ? driver_change_device(c, n) : CA_SUCCESS; - if (ret == CA_SUCCESS) { - ca_free(c->device); - c->device = n; - } else - ca_free(n); + if (ret == CA_SUCCESS) { + ca_free(c->device); + c->device = n; + } else + ca_free(n); fail: - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } static int context_open_unlocked(ca_context *c) { - int ret; + 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(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - if (c->opened) - return CA_SUCCESS; + if (c->opened) + return CA_SUCCESS; - if ((ret = driver_open(c)) == CA_SUCCESS) - c->opened = TRUE; + if ((ret = driver_open(c)) == CA_SUCCESS) + c->opened = TRUE; - return ret; + return ret; } /** @@ -306,18 +308,18 @@ static int context_open_unlocked(ca_context *c) { * Returns: 0 on success, negative error code on error. */ int ca_context_open(ca_context *c) { - int ret; + int ret; - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); - ca_return_val_if_fail_unlock(!c->opened, CA_ERROR_STATE, c->mutex); + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_mutex_lock(c->mutex); + ca_return_val_if_fail_unlock(!c->opened, CA_ERROR_STATE, c->mutex); - ret = context_open_unlocked(c); + ret = context_open_unlocked(c); - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } /** @@ -339,25 +341,25 @@ int ca_context_open(ca_context *c) { */ int ca_context_change_props(ca_context *c, ...) { - va_list ap; - int ret; - ca_proplist *p = NULL; + va_list ap; + int ret; + ca_proplist *p = NULL; - 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(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - va_start(ap, c); - ret = ca_proplist_from_ap(&p, ap); - va_end(ap); + va_start(ap, c); + ret = ca_proplist_from_ap(&p, ap); + va_end(ap); - if (ret < 0) - return ret; + if (ret < 0) + return ret; - ret = ca_context_change_props_full(c, p); + ret = ca_context_change_props_full(c, p); - ca_assert_se(ca_proplist_destroy(p) == 0); + ca_assert_se(ca_proplist_destroy(p) == 0); - return ret; + return ret; } /** @@ -373,31 +375,31 @@ int ca_context_change_props(ca_context *c, ...) { */ int ca_context_change_props_full(ca_context *c, ca_proplist *p) { - int ret; - ca_proplist *merged; + int ret; + ca_proplist *merged; - 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(p, CA_ERROR_INVALID); + 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(p, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); + ca_mutex_lock(c->mutex); - if ((ret = ca_proplist_merge(&merged, c->props, p)) < 0) - goto finish; + if ((ret = ca_proplist_merge(&merged, c->props, p)) < 0) + goto finish; - ret = c->opened ? driver_change_props(c, p, merged) : CA_SUCCESS; + ret = c->opened ? driver_change_props(c, p, merged) : CA_SUCCESS; - if (ret == CA_SUCCESS) { - ca_assert_se(ca_proplist_destroy(c->props) == CA_SUCCESS); - c->props = merged; - } else - ca_assert_se(ca_proplist_destroy(merged) == CA_SUCCESS); + if (ret == CA_SUCCESS) { + ca_assert_se(ca_proplist_destroy(c->props) == CA_SUCCESS); + c->props = merged; + } else + ca_assert_se(ca_proplist_destroy(merged) == CA_SUCCESS); finish: - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } /** @@ -443,25 +445,25 @@ finish: */ int ca_context_play(ca_context *c, uint32_t id, ...) { - int ret; - va_list ap; - ca_proplist *p = NULL; + int ret; + va_list ap; + ca_proplist *p = NULL; - 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(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - va_start(ap, id); - ret = ca_proplist_from_ap(&p, ap); - va_end(ap); + va_start(ap, id); + ret = ca_proplist_from_ap(&p, ap); + va_end(ap); - if (ret < 0) - return ret; + if (ret < 0) + return ret; - ret = ca_context_play_full(c, id, p, NULL, NULL); + ret = ca_context_play_full(c, id, p, NULL, NULL); - ca_assert_se(ca_proplist_destroy(p) == 0); + ca_assert_se(ca_proplist_destroy(p) == 0); - return ret; + return ret; } /** @@ -484,46 +486,46 @@ int ca_context_play(ca_context *c, uint32_t id, ...) { */ int ca_context_play_full(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t cb, void *userdata) { - int ret; - const char *t; - ca_bool_t enabled = TRUE; + int ret; + const char *t; + ca_bool_t enabled = TRUE; - 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(p, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + 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(p, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); + ca_mutex_lock(c->mutex); - ca_return_val_if_fail_unlock(ca_proplist_contains(p, CA_PROP_EVENT_ID) || - ca_proplist_contains(c->props, CA_PROP_EVENT_ID) || - ca_proplist_contains(p, CA_PROP_MEDIA_FILENAME) || - ca_proplist_contains(c->props, CA_PROP_MEDIA_FILENAME), CA_ERROR_INVALID, c->mutex); + ca_return_val_if_fail_unlock(ca_proplist_contains(p, CA_PROP_EVENT_ID) || + ca_proplist_contains(c->props, CA_PROP_EVENT_ID) || + ca_proplist_contains(p, CA_PROP_MEDIA_FILENAME) || + ca_proplist_contains(c->props, CA_PROP_MEDIA_FILENAME), CA_ERROR_INVALID, c->mutex); - ca_mutex_lock(c->props->mutex); - if ((t = ca_proplist_gets_unlocked(c->props, CA_PROP_CANBERRA_ENABLE))) - enabled = !ca_streq(t, "0"); - ca_mutex_unlock(c->props->mutex); + ca_mutex_lock(c->props->mutex); + if ((t = ca_proplist_gets_unlocked(c->props, CA_PROP_CANBERRA_ENABLE))) + enabled = !ca_streq(t, "0"); + ca_mutex_unlock(c->props->mutex); - ca_mutex_lock(p->mutex); - if ((t = ca_proplist_gets_unlocked(p, CA_PROP_CANBERRA_ENABLE))) - enabled = !ca_streq(t, "0"); - ca_mutex_unlock(p->mutex); + ca_mutex_lock(p->mutex); + if ((t = ca_proplist_gets_unlocked(p, CA_PROP_CANBERRA_ENABLE))) + enabled = !ca_streq(t, "0"); + ca_mutex_unlock(p->mutex); - ca_return_val_if_fail_unlock(enabled, CA_ERROR_DISABLED, c->mutex); + ca_return_val_if_fail_unlock(enabled, CA_ERROR_DISABLED, c->mutex); - if ((ret = context_open_unlocked(c)) < 0) - goto finish; + if ((ret = context_open_unlocked(c)) < 0) + goto finish; - ca_assert(c->opened); + ca_assert(c->opened); - ret = driver_play(c, id, p, cb, userdata); + ret = driver_play(c, id, p, cb, userdata); finish: - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } /** @@ -541,18 +543,18 @@ finish: * Returns: 0 on success, negative error code on error. */ int ca_context_cancel(ca_context *c, uint32_t id) { - int ret; + int ret; - ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); - ca_return_val_if_fail_unlock(c->opened, CA_ERROR_STATE, c->mutex); + ca_return_val_if_fail(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_mutex_lock(c->mutex); + ca_return_val_if_fail_unlock(c->opened, CA_ERROR_STATE, c->mutex); - ret = driver_cancel(c, id); + ret = driver_cancel(c, id); - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } /** @@ -574,25 +576,25 @@ int ca_context_cancel(ca_context *c, uint32_t id) { */ int ca_context_cache(ca_context *c, ...) { - int ret; - va_list ap; - ca_proplist *p = NULL; + int ret; + va_list ap; + ca_proplist *p = NULL; - 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(!ca_detect_fork(), CA_ERROR_FORKED); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - va_start(ap, c); - ret = ca_proplist_from_ap(&p, ap); - va_end(ap); + va_start(ap, c); + ret = ca_proplist_from_ap(&p, ap); + va_end(ap); - if (ret < 0) - return ret; + if (ret < 0) + return ret; - ret = ca_context_cache_full(c, p); + ret = ca_context_cache_full(c, p); - ca_assert_se(ca_proplist_destroy(p) == 0); + ca_assert_se(ca_proplist_destroy(p) == 0); - return ret; + return ret; } /** @@ -610,29 +612,29 @@ int ca_context_cache(ca_context *c, ...) { * Returns: 0 on success, negative error code on error. */ int ca_context_cache_full(ca_context *c, ca_proplist *p) { - int ret; + 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(p, CA_ERROR_INVALID); + 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(p, CA_ERROR_INVALID); - ca_mutex_lock(c->mutex); + ca_mutex_lock(c->mutex); - ca_return_val_if_fail_unlock(ca_proplist_contains(p, CA_PROP_EVENT_ID) || - ca_proplist_contains(c->props, CA_PROP_EVENT_ID), CA_ERROR_INVALID, c->mutex); + ca_return_val_if_fail_unlock(ca_proplist_contains(p, CA_PROP_EVENT_ID) || + ca_proplist_contains(c->props, CA_PROP_EVENT_ID), CA_ERROR_INVALID, c->mutex); - if ((ret = context_open_unlocked(c)) < 0) - goto finish; + if ((ret = context_open_unlocked(c)) < 0) + goto finish; - ca_assert(c->opened); + ca_assert(c->opened); - ret = driver_cache(c, p); + ret = driver_cache(c, p); finish: - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } /** @@ -645,49 +647,49 @@ finish: */ const char *ca_strerror(int code) { - const char * const error_table[-_CA_ERROR_MAX] = { - [-CA_SUCCESS] = "Success", - [-CA_ERROR_NOTSUPPORTED] = "Operation not supported", - [-CA_ERROR_INVALID] = "Invalid argument", - [-CA_ERROR_STATE] = "Invalid state", - [-CA_ERROR_OOM] = "Out of memory", - [-CA_ERROR_NODRIVER] = "No such driver", - [-CA_ERROR_SYSTEM] = "System error", - [-CA_ERROR_CORRUPT] = "File or data corrupt", - [-CA_ERROR_TOOBIG] = "File or data too large", - [-CA_ERROR_NOTFOUND] = "File or data not found", - [-CA_ERROR_DESTROYED] = "Destroyed", - [-CA_ERROR_CANCELED] = "Canceled", - [-CA_ERROR_NOTAVAILABLE] = "Not available", - [-CA_ERROR_ACCESS] = "Access forbidden", - [-CA_ERROR_IO] = "IO error", - [-CA_ERROR_INTERNAL] = "Internal error", - [-CA_ERROR_DISABLED] = "Sound disabled", - [-CA_ERROR_FORKED] = "Process forked", - [-CA_ERROR_DISCONNECTED] = "Disconnected" - }; - - ca_return_val_if_fail(code <= 0, NULL); - ca_return_val_if_fail(code > _CA_ERROR_MAX, NULL); - - return error_table[-code]; + const char * const error_table[-_CA_ERROR_MAX] = { + [-CA_SUCCESS] = "Success", + [-CA_ERROR_NOTSUPPORTED] = "Operation not supported", + [-CA_ERROR_INVALID] = "Invalid argument", + [-CA_ERROR_STATE] = "Invalid state", + [-CA_ERROR_OOM] = "Out of memory", + [-CA_ERROR_NODRIVER] = "No such driver", + [-CA_ERROR_SYSTEM] = "System error", + [-CA_ERROR_CORRUPT] = "File or data corrupt", + [-CA_ERROR_TOOBIG] = "File or data too large", + [-CA_ERROR_NOTFOUND] = "File or data not found", + [-CA_ERROR_DESTROYED] = "Destroyed", + [-CA_ERROR_CANCELED] = "Canceled", + [-CA_ERROR_NOTAVAILABLE] = "Not available", + [-CA_ERROR_ACCESS] = "Access forbidden", + [-CA_ERROR_IO] = "IO error", + [-CA_ERROR_INTERNAL] = "Internal error", + [-CA_ERROR_DISABLED] = "Sound disabled", + [-CA_ERROR_FORKED] = "Process forked", + [-CA_ERROR_DISCONNECTED] = "Disconnected" + }; + + ca_return_val_if_fail(code <= 0, NULL); + ca_return_val_if_fail(code > _CA_ERROR_MAX, NULL); + + return error_table[-code]; } /* Not exported */ int ca_parse_cache_control(ca_cache_control_t *control, const char *c) { - ca_return_val_if_fail(control, CA_ERROR_INVALID); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - - if (ca_streq(c, "never")) - *control = CA_CACHE_CONTROL_NEVER; - else if (ca_streq(c, "permanent")) - *control = CA_CACHE_CONTROL_PERMANENT; - else if (ca_streq(c, "volatile")) - *control = CA_CACHE_CONTROL_VOLATILE; - else - return CA_ERROR_INVALID; - - return CA_SUCCESS; + ca_return_val_if_fail(control, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + + if (ca_streq(c, "never")) + *control = CA_CACHE_CONTROL_NEVER; + else if (ca_streq(c, "permanent")) + *control = CA_CACHE_CONTROL_PERMANENT; + else if (ca_streq(c, "volatile")) + *control = CA_CACHE_CONTROL_VOLATILE; + else + return CA_ERROR_INVALID; + + return CA_SUCCESS; } /** @@ -704,17 +706,17 @@ int ca_parse_cache_control(ca_cache_control_t *control, const char *c) { * Since: 0.16 */ int ca_context_playing(ca_context *c, uint32_t id, int *playing) { - int ret; + 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); + 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); + ret = driver_playing(c, id, playing); - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - return ret; + return ret; } diff --git a/src/common.h b/src/common.h index 1d93034..116a25a 100644 --- a/src/common.h +++ b/src/common.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberracommonh #define foocanberracommonh @@ -26,24 +28,24 @@ #include "mutex.h" struct ca_context { - ca_bool_t opened; - ca_mutex *mutex; + ca_bool_t opened; + ca_mutex *mutex; - ca_proplist *props; + ca_proplist *props; - char *driver; - char *device; + char *driver; + char *device; - void *private; + void *private; #ifdef HAVE_DSO - void *private_dso; + void *private_dso; #endif }; typedef enum ca_cache_control { - CA_CACHE_CONTROL_NEVER, - CA_CACHE_CONTROL_PERMANENT, - CA_CACHE_CONTROL_VOLATILE + CA_CACHE_CONTROL_NEVER, + CA_CACHE_CONTROL_PERMANENT, + CA_CACHE_CONTROL_VOLATILE } ca_cache_control_t; int ca_parse_cache_control(ca_cache_control_t *control, const char *c); diff --git a/src/driver-order.c b/src/driver-order.c index 263b130..64f464d 100644 --- a/src/driver-order.c +++ b/src/driver-order.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -29,17 +31,17 @@ const char* const ca_driver_order[] = { #ifdef HAVE_PULSE - "pulse", + "pulse", #endif #ifdef HAVE_ALSA - "alsa", + "alsa", #endif #ifdef HAVE_OSS - "oss", + "oss", #endif #ifdef HAVE_GSTREAMER - "gstreamer", + "gstreamer", #endif - /* ... */ - NULL + /* ... */ + NULL }; diff --git a/src/driver-order.h b/src/driver-order.h index 44f7eff..3702847 100644 --- a/src/driver-order.h +++ b/src/driver-order.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberradriverorderhfoo #define foocanberradriverorderhfoo diff --git a/src/driver.h b/src/driver.h index c843b8d..62c96ec 100644 --- a/src/driver.h +++ b/src/driver.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberradriverhfoo #define foocanberradriverhfoo diff --git a/src/dso.c b/src/dso.c index 97c04d4..54500dc 100644 --- a/src/dso.c +++ b/src/dso.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -32,347 +34,347 @@ #include "driver-order.h" struct private_dso { - lt_dlhandle module; - ca_bool_t ltdl_initialized; - - int (*driver_open)(ca_context *c); - int (*driver_destroy)(ca_context *c); - int (*driver_change_device)(ca_context *c, const char *device); - int (*driver_change_props)(ca_context *c, ca_proplist *changed, ca_proplist *merged); - 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); + lt_dlhandle module; + ca_bool_t ltdl_initialized; + + int (*driver_open)(ca_context *c); + int (*driver_destroy)(ca_context *c); + int (*driver_change_device)(ca_context *c, const char *device); + int (*driver_change_props)(ca_context *c, ca_proplist *changed, ca_proplist *merged); + 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)) static int ca_error_from_lt_error(int code) { - static const int table[] = { - [LT_ERROR_UNKNOWN] = CA_ERROR_INTERNAL, - [LT_ERROR_DLOPEN_NOT_SUPPORTED] = CA_ERROR_NOTSUPPORTED, - [LT_ERROR_INVALID_LOADER] = CA_ERROR_INTERNAL, - [LT_ERROR_INIT_LOADER] = CA_ERROR_INTERNAL, - [LT_ERROR_REMOVE_LOADER] = CA_ERROR_INTERNAL, - [LT_ERROR_FILE_NOT_FOUND] = CA_ERROR_NOTFOUND, - [LT_ERROR_DEPLIB_NOT_FOUND] = CA_ERROR_NOTFOUND, - [LT_ERROR_NO_SYMBOLS] = CA_ERROR_NOTFOUND, - [LT_ERROR_CANNOT_OPEN] = CA_ERROR_ACCESS, - [LT_ERROR_CANNOT_CLOSE] = CA_ERROR_INTERNAL, - [LT_ERROR_SYMBOL_NOT_FOUND] = CA_ERROR_NOTFOUND, - [LT_ERROR_NO_MEMORY] = CA_ERROR_OOM, - [LT_ERROR_INVALID_HANDLE] = CA_ERROR_INVALID, - [LT_ERROR_BUFFER_OVERFLOW] = CA_ERROR_TOOBIG, - [LT_ERROR_INVALID_ERRORCODE] = CA_ERROR_INVALID, - [LT_ERROR_SHUTDOWN] = CA_ERROR_INTERNAL, - [LT_ERROR_CLOSE_RESIDENT_MODULE] = CA_ERROR_INTERNAL, - [LT_ERROR_INVALID_MUTEX_ARGS] = CA_ERROR_INTERNAL, - [LT_ERROR_INVALID_POSITION] = CA_ERROR_INTERNAL + static const int table[] = { + [LT_ERROR_UNKNOWN] = CA_ERROR_INTERNAL, + [LT_ERROR_DLOPEN_NOT_SUPPORTED] = CA_ERROR_NOTSUPPORTED, + [LT_ERROR_INVALID_LOADER] = CA_ERROR_INTERNAL, + [LT_ERROR_INIT_LOADER] = CA_ERROR_INTERNAL, + [LT_ERROR_REMOVE_LOADER] = CA_ERROR_INTERNAL, + [LT_ERROR_FILE_NOT_FOUND] = CA_ERROR_NOTFOUND, + [LT_ERROR_DEPLIB_NOT_FOUND] = CA_ERROR_NOTFOUND, + [LT_ERROR_NO_SYMBOLS] = CA_ERROR_NOTFOUND, + [LT_ERROR_CANNOT_OPEN] = CA_ERROR_ACCESS, + [LT_ERROR_CANNOT_CLOSE] = CA_ERROR_INTERNAL, + [LT_ERROR_SYMBOL_NOT_FOUND] = CA_ERROR_NOTFOUND, + [LT_ERROR_NO_MEMORY] = CA_ERROR_OOM, + [LT_ERROR_INVALID_HANDLE] = CA_ERROR_INVALID, + [LT_ERROR_BUFFER_OVERFLOW] = CA_ERROR_TOOBIG, + [LT_ERROR_INVALID_ERRORCODE] = CA_ERROR_INVALID, + [LT_ERROR_SHUTDOWN] = CA_ERROR_INTERNAL, + [LT_ERROR_CLOSE_RESIDENT_MODULE] = CA_ERROR_INTERNAL, + [LT_ERROR_INVALID_MUTEX_ARGS] = CA_ERROR_INTERNAL, + [LT_ERROR_INVALID_POSITION] = CA_ERROR_INTERNAL #ifdef LT_ERROR_CONFLICTING_FLAGS - , [LT_ERROR_CONFLICTING_FLAGS] = CA_ERROR_INTERNAL + , [LT_ERROR_CONFLICTING_FLAGS] = CA_ERROR_INTERNAL #endif -}; + }; - if (code < 0 || code >= (int) CA_ELEMENTSOF(table)) - return CA_ERROR_INTERNAL; + if (code < 0 || code >= (int) CA_ELEMENTSOF(table)) + return CA_ERROR_INTERNAL; - return table[code]; + return table[code]; } static int lt_error_from_string(const char *t) { - struct lt_error_code { - int code; - const char *text; - }; + struct lt_error_code { + int code; + const char *text; + }; - static const struct lt_error_code lt_error_codes[] = { - /* This is so disgustingly ugly, it makes me vomit. But that's - * all ltdl's fault. */ + static const struct lt_error_code lt_error_codes[] = { + /* This is so disgustingly ugly, it makes me vomit. But that's + * all ltdl's fault. */ #define LT_ERROR(u, s) { .code = LT_ERROR_ ## u, .text = s }, - lt_dlerror_table + lt_dlerror_table #undef LT_ERROR - { .code = 0, .text = NULL } - }; + { .code = 0, .text = NULL } + }; - const struct lt_error_code *c; + const struct lt_error_code *c; - for (c = lt_error_codes; c->text; c++) - if (ca_streq(t, c->text)) - return c->code; + for (c = lt_error_codes; c->text; c++) + if (ca_streq(t, c->text)) + return c->code; - return -1; + return -1; } static int ca_error_from_string(const char *t) { - int err; + int err; - if ((err = lt_error_from_string(t)) < 0) - return CA_ERROR_INTERNAL; + if ((err = lt_error_from_string(t)) < 0) + return CA_ERROR_INTERNAL; - return ca_error_from_lt_error(err); + return ca_error_from_lt_error(err); } static int try_open(ca_context *c, const char *t) { - char *mn; - struct private_dso *p; + char *mn; + struct private_dso *p; - p = PRIVATE_DSO(c); + p = PRIVATE_DSO(c); - if (!(mn = ca_sprintf_malloc(CA_PLUGIN_PATH "/libcanberra-%s", t))) - return CA_ERROR_OOM; + if (!(mn = ca_sprintf_malloc(CA_PLUGIN_PATH "/libcanberra-%s", t))) + return CA_ERROR_OOM; - errno = 0; - p->module = lt_dlopenext(mn); - ca_free(mn); + errno = 0; + p->module = lt_dlopenext(mn); + ca_free(mn); - if (!p->module) { - int ret; + if (!p->module) { + int ret; - if (errno == ENOENT) - ret = CA_ERROR_NOTFOUND; - else - ret = ca_error_from_string(lt_dlerror()); + if (errno == ENOENT) + ret = CA_ERROR_NOTFOUND; + else + ret = ca_error_from_string(lt_dlerror()); - if (ret == CA_ERROR_NOTFOUND) - ret = CA_ERROR_NODRIVER; + if (ret == CA_ERROR_NOTFOUND) + ret = CA_ERROR_NODRIVER; - return ret; - } + return ret; + } - return CA_SUCCESS; + return CA_SUCCESS; } static void* real_dlsym(lt_module m, const char *name, const char *symbol) { - char sn[256]; - char *s; - void *r; - - ca_return_null_if_fail(m); - ca_return_null_if_fail(name); - ca_return_null_if_fail(symbol); - - snprintf(sn, sizeof(sn), "%s_%s", name, symbol); - sn[sizeof(sn)-1] = 0; - - for (s = sn; *s; s++) { - if (*s >= 'a' && *s <= 'z') - continue; - if (*s >= 'A' && *s <= 'Z') - continue; - if (*s >= '0' && *s <= '9') - continue; - - *s = '_'; - } + char sn[256]; + char *s; + void *r; + + ca_return_null_if_fail(m); + ca_return_null_if_fail(name); + ca_return_null_if_fail(symbol); + + snprintf(sn, sizeof(sn), "%s_%s", name, symbol); + sn[sizeof(sn)-1] = 0; + + for (s = sn; *s; s++) { + if (*s >= 'a' && *s <= 'z') + continue; + if (*s >= 'A' && *s <= 'Z') + continue; + if (*s >= '0' && *s <= '9') + continue; + + *s = '_'; + } - if ((r = lt_dlsym(m, sn))) - return r; + if ((r = lt_dlsym(m, sn))) + return r; - return lt_dlsym(m, symbol); + return lt_dlsym(m, symbol); } #define MAKE_FUNC_PTR(ret, args, x) ((ret (*) args ) (size_t) (x)) #define GET_FUNC_PTR(module, name, symbol, ret, args) MAKE_FUNC_PTR(ret, args, real_dlsym((module), (name), (symbol))) int driver_open(ca_context *c) { - int ret; - struct private_dso *p; - char *driver; + int ret; + struct private_dso *p; + char *driver; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!PRIVATE_DSO(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!PRIVATE_DSO(c), CA_ERROR_STATE); - if (!(c->private_dso = p = ca_new0(struct private_dso, 1))) - return CA_ERROR_OOM; + if (!(c->private_dso = p = ca_new0(struct private_dso, 1))) + return CA_ERROR_OOM; - if (lt_dlinit() != 0) { - ret = ca_error_from_string(lt_dlerror()); - driver_destroy(c); - return ret; - } + if (lt_dlinit() != 0) { + ret = ca_error_from_string(lt_dlerror()); + driver_destroy(c); + return ret; + } - p->ltdl_initialized = TRUE; + p->ltdl_initialized = TRUE; - if (c->driver) { - char *e; - size_t n; + if (c->driver) { + char *e; + size_t n; - if (!(e = ca_strdup(c->driver))) { - driver_destroy(c); - return CA_ERROR_OOM; - } + if (!(e = ca_strdup(c->driver))) { + driver_destroy(c); + return CA_ERROR_OOM; + } - n = strcspn(e, ",:"); - e[n] = 0; + n = strcspn(e, ",:"); + e[n] = 0; - if (n == 0) { - driver_destroy(c); - ca_free(e); - return CA_ERROR_INVALID; - } + if (n == 0) { + driver_destroy(c); + ca_free(e); + return CA_ERROR_INVALID; + } - if ((ret = try_open(c, e)) < 0) { - driver_destroy(c); - ca_free(e); - return ret; - } + if ((ret = try_open(c, e)) < 0) { + driver_destroy(c); + ca_free(e); + return ret; + } - driver = e; + driver = e; - } else { - const char *const * e; + } else { + const char *const * e; - for (e = ca_driver_order; *e; e++) { + for (e = ca_driver_order; *e; e++) { - if ((ret = try_open(c, *e)) == CA_SUCCESS) - break; + if ((ret = try_open(c, *e)) == CA_SUCCESS) + break; - if (ret != CA_ERROR_NODRIVER && - ret != CA_ERROR_NOTAVAILABLE && - ret != CA_ERROR_NOTFOUND) { + if (ret != CA_ERROR_NODRIVER && + ret != CA_ERROR_NOTAVAILABLE && + ret != CA_ERROR_NOTFOUND) { - driver_destroy(c); - return ret; - } - } + driver_destroy(c); + return ret; + } + } - if (!*e) { - driver_destroy(c); - return CA_ERROR_NODRIVER; - } + if (!*e) { + driver_destroy(c); + return CA_ERROR_NODRIVER; + } - if (!(driver = ca_strdup(*e))) { - driver_destroy(c); - return CA_ERROR_OOM; + if (!(driver = ca_strdup(*e))) { + driver_destroy(c); + return CA_ERROR_OOM; + } } - } - ca_assert(p->module); + ca_assert(p->module); - if (!(p->driver_open = GET_FUNC_PTR(p->module, driver, "driver_open", int, (ca_context*))) || - !(p->driver_destroy = GET_FUNC_PTR(p->module, driver, "driver_destroy", int, (ca_context*))) || - !(p->driver_change_device = GET_FUNC_PTR(p->module, driver, "driver_change_device", int, (ca_context*, const char *))) || - !(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_playing = GET_FUNC_PTR(p->module, driver, "driver_playing", int, (ca_context*, uint32_t, int*)))) { + if (!(p->driver_open = GET_FUNC_PTR(p->module, driver, "driver_open", int, (ca_context*))) || + !(p->driver_destroy = GET_FUNC_PTR(p->module, driver, "driver_destroy", int, (ca_context*))) || + !(p->driver_change_device = GET_FUNC_PTR(p->module, driver, "driver_change_device", int, (ca_context*, const char *))) || + !(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_playing = GET_FUNC_PTR(p->module, driver, "driver_playing", int, (ca_context*, uint32_t, int*)))) { - ca_free(driver); - driver_destroy(c); - return CA_ERROR_CORRUPT; - } + ca_free(driver); + driver_destroy(c); + return CA_ERROR_CORRUPT; + } - ca_free(driver); + ca_free(driver); - if ((ret = p->driver_open(c)) < 0) { - p->driver_destroy = NULL; - driver_destroy(c); - return ret; - } + if ((ret = p->driver_open(c)) < 0) { + p->driver_destroy = NULL; + driver_destroy(c); + return ret; + } - return CA_SUCCESS; + return CA_SUCCESS; } int driver_destroy(ca_context *c) { - struct private_dso *p; - int ret = CA_SUCCESS; + struct private_dso *p; + int ret = CA_SUCCESS; - 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); - p = PRIVATE_DSO(c); + p = PRIVATE_DSO(c); - if (p->driver_destroy) - ret = p->driver_destroy(c); + if (p->driver_destroy) + ret = p->driver_destroy(c); - if (p->module) - lt_dlclose(p->module); + if (p->module) + lt_dlclose(p->module); - if (p->ltdl_initialized) { - lt_dlexit(); - p->ltdl_initialized = FALSE; - } + if (p->ltdl_initialized) { + lt_dlexit(); + p->ltdl_initialized = FALSE; + } - ca_free(p); + ca_free(p); - c->private_dso = NULL; + c->private_dso = NULL; - return ret; + return ret; } int driver_change_device(ca_context *c, const char *device) { - struct private_dso *p; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); - p = PRIVATE_DSO(c); - ca_return_val_if_fail(p->driver_change_device, CA_ERROR_STATE); + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_change_device, CA_ERROR_STATE); - return p->driver_change_device(c, device); + return p->driver_change_device(c, device); } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - struct private_dso *p; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); - p = PRIVATE_DSO(c); - ca_return_val_if_fail(p->driver_change_props, CA_ERROR_STATE); + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_change_props, CA_ERROR_STATE); - return p->driver_change_props(c, changed, merged); + return p->driver_change_props(c, changed, merged); } int driver_play(ca_context *c, uint32_t id, ca_proplist *pl, ca_finish_callback_t cb, void *userdata) { - struct private_dso *p; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); - p = PRIVATE_DSO(c); - ca_return_val_if_fail(p->driver_play, CA_ERROR_STATE); + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_play, CA_ERROR_STATE); - return p->driver_play(c, id, pl, cb, userdata); + return p->driver_play(c, id, pl, cb, userdata); } int driver_cancel(ca_context *c, uint32_t id) { - struct private_dso *p; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); - p = PRIVATE_DSO(c); - ca_return_val_if_fail(p->driver_cancel, CA_ERROR_STATE); + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_cancel, CA_ERROR_STATE); - return p->driver_cancel(c, id); + return p->driver_cancel(c, id); } int driver_cache(ca_context *c, ca_proplist *pl) { - struct private_dso *p; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE); - p = PRIVATE_DSO(c); - ca_return_val_if_fail(p->driver_cache, CA_ERROR_STATE); + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_cache, CA_ERROR_STATE); - return p->driver_cache(c, pl); + return p->driver_cache(c, pl); } int driver_playing(ca_context *c, uint32_t id, int *playing) { - struct private_dso *p; + 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); + 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); + p = PRIVATE_DSO(c); + ca_return_val_if_fail(p->driver_playing, CA_ERROR_STATE); - return p->driver_playing(c, id, playing); + return p->driver_playing(c, id, playing); } diff --git a/src/fork-detect.c b/src/fork-detect.c index 622037c..d416eb3 100644 --- a/src/fork-detect.c +++ b/src/fork-detect.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -28,24 +30,24 @@ #include "fork-detect.h" int ca_detect_fork(void) { - static volatile pid_t pid = (pid_t) -1; - pid_t v; + static volatile pid_t pid = (pid_t) -1; + pid_t v; - /* Some really stupid applications (Hey, vim, that means you!) - * love to fork after initializing gtk/libcanberra. This is really - * bad style. We however have to deal with this cleanly, so we try - * to detect the forks making sure all our calls fail cleanly - * after the fork. */ + /* Some really stupid applications (Hey, vim, that means you!) + * love to fork after initializing gtk/libcanberra. This is really + * bad style. We however have to deal with this cleanly, so we try + * to detect the forks making sure all our calls fail cleanly + * after the fork. */ - /* Ideally we'd use atomic operations here, but we don't have them - * and this is not exactly crucial, so we don't care */ + /* Ideally we'd use atomic operations here, but we don't have them + * and this is not exactly crucial, so we don't care */ - v = pid; + v = pid; - if (v == getpid() || v == (pid_t) -1) { - pid = getpid(); - return 0; - } + if (v == getpid() || v == (pid_t) -1) { + pid = getpid(); + return 0; + } - return 1; + return 1; } diff --git a/src/fork-detect.h b/src/fork-detect.h index 9050ef8..6acf159 100644 --- a/src/fork-detect.h +++ b/src/fork-detect.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberraforkdetecth #define foocanberraforkdetecth diff --git a/src/gstreamer.c b/src/gstreamer.c index 54919ea..3496e6b 100644 --- a/src/gstreamer.c +++ b/src/gstreamer.c @@ -1,23 +1,25 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** - This file is part of libcanberra. + This file is part of libcanberra. - Copyright 2008 Nokia Corporation and/or its subsidiary(-ies). + Copyright 2008 Nokia Corporation and/or its subsidiary(-ies). - Author: Marc-Andre Lureau + Author: Marc-Andre Lureau - libcanberra is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 2.1 of the - License, or (at your option) any later version. + libcanberra is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 2.1 of the + License, or (at your option) any later version. - libcanberra is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + libcanberra is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with libcanberra. If not, see - . + You should have received a copy of the GNU Lesser General Public + License along with libcanberra. If not, see + . ***/ #ifdef HAVE_CONFIG_H @@ -44,28 +46,28 @@ #include "malloc.h" struct outstanding { - CA_LLIST_FIELDS(struct outstanding); - ca_bool_t dead; - uint32_t id; - int err; - ca_finish_callback_t callback; - void *userdata; - GstElement *pipeline; - struct ca_context *context; + CA_LLIST_FIELDS(struct outstanding); + ca_bool_t dead; + uint32_t id; + int err; + ca_finish_callback_t callback; + void *userdata; + GstElement *pipeline; + struct ca_context *context; }; struct private { - ca_theme_data *theme; - ca_bool_t signal_semaphore; - sem_t semaphore; + ca_theme_data *theme; + ca_bool_t signal_semaphore; + sem_t semaphore; - GstBus *mgr_bus; + GstBus *mgr_bus; - /* Everything below protected by the outstanding_mutex */ - ca_mutex *outstanding_mutex; - ca_bool_t mgr_thread_running; - ca_bool_t semaphore_allocated; - CA_LLIST_HEAD(struct outstanding, outstanding); + /* Everything below protected by the outstanding_mutex */ + ca_mutex *outstanding_mutex; + ca_bool_t mgr_thread_running; + ca_bool_t semaphore_allocated; + CA_LLIST_HEAD(struct outstanding, outstanding); }; #define PRIVATE(c) ((struct private *) ((c)->private)) @@ -75,512 +77,511 @@ static void send_eos_msg(struct outstanding *out, int err); static void send_mgr_exit_msg (struct private *p); static void outstanding_free(struct outstanding *o) { - GstBus *bus; + GstBus *bus; - ca_assert(o); + ca_assert(o); - if (o->pipeline) { - bus = gst_pipeline_get_bus(GST_PIPELINE (o->pipeline)); - if (bus != NULL) { - gst_bus_set_sync_handler(bus, NULL, NULL); - gst_object_unref(bus); - } + if (o->pipeline) { + bus = gst_pipeline_get_bus(GST_PIPELINE (o->pipeline)); + if (bus != NULL) { + gst_bus_set_sync_handler(bus, NULL, NULL); + gst_object_unref(bus); + } - gst_object_unref(GST_OBJECT(o->pipeline)); - } + gst_object_unref(GST_OBJECT(o->pipeline)); + } - ca_free(o); + ca_free(o); } int driver_open(ca_context *c) { - GError *error = NULL; - struct private *p; - pthread_t thread; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "gstreamer"), CA_ERROR_NODRIVER); - - gst_init_check(NULL, NULL, &error); - if (error != NULL) { - g_warning("gst_init: %s ", error->message); - g_error_free(error); - return CA_ERROR_INVALID; - } - - if (!(p = ca_new0(struct private, 1))) - return CA_ERROR_OOM; - c->private = p; - - if (!(p->outstanding_mutex = ca_mutex_new())) { - driver_destroy(c); - return CA_ERROR_OOM; - } - - if (sem_init(&p->semaphore, 0, 0) < 0) { - driver_destroy(c); - return CA_ERROR_OOM; - } - p->semaphore_allocated = TRUE; - - p->mgr_bus = gst_bus_new(); - if (p->mgr_bus == NULL) { - driver_destroy(c); - return CA_ERROR_OOM; - } - gst_bus_set_flushing(p->mgr_bus, FALSE); - - /* Give a reference to the bus to the mgr thread */ - if (pthread_create(&thread, NULL, thread_func, p) < 0) { - driver_destroy(c); - return CA_ERROR_OOM; - } - p->mgr_thread_running = TRUE; - - return CA_SUCCESS; -} + GError *error = NULL; + struct private *p; + pthread_t thread; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_INVALID); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "gstreamer"), CA_ERROR_NODRIVER); + + gst_init_check(NULL, NULL, &error); + if (error != NULL) { + g_warning("gst_init: %s ", error->message); + g_error_free(error); + return CA_ERROR_INVALID; + } -int driver_destroy(ca_context *c) { - struct private *p; - struct outstanding *out; + if (!(p = ca_new0(struct private, 1))) + return CA_ERROR_OOM; + c->private = p; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); + if (!(p->outstanding_mutex = ca_mutex_new())) { + driver_destroy(c); + return CA_ERROR_OOM; + } - p = PRIVATE(c); + if (sem_init(&p->semaphore, 0, 0) < 0) { + driver_destroy(c); + return CA_ERROR_OOM; + } + p->semaphore_allocated = TRUE; - if (p->outstanding_mutex) { - ca_mutex_lock(p->outstanding_mutex); + p->mgr_bus = gst_bus_new(); + if (p->mgr_bus == NULL) { + driver_destroy(c); + return CA_ERROR_OOM; + } + gst_bus_set_flushing(p->mgr_bus, FALSE); - /* Tell all player threads to terminate */ - out = p->outstanding; - while (out) { - if (!out->dead) - send_eos_msg(out, CA_ERROR_DESTROYED); - out = out->next; + /* Give a reference to the bus to the mgr thread */ + if (pthread_create(&thread, NULL, thread_func, p) < 0) { + driver_destroy(c); + return CA_ERROR_OOM; } + p->mgr_thread_running = TRUE; - /* Now that we've sent EOS for all pending players, append a - * message to wait for the mgr thread to exit */ - if (p->mgr_thread_running && p->semaphore_allocated) { - send_mgr_exit_msg(p); + return CA_SUCCESS; +} - p->signal_semaphore = TRUE; - while (p->mgr_thread_running) { - ca_mutex_unlock(p->outstanding_mutex); - sem_wait(&p->semaphore); +int driver_destroy(ca_context *c) { + struct private *p; + struct outstanding *out; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); + + p = PRIVATE(c); + + if (p->outstanding_mutex) { ca_mutex_lock(p->outstanding_mutex); - } - } - ca_mutex_unlock(p->outstanding_mutex); - ca_mutex_free(p->outstanding_mutex); - } + /* Tell all player threads to terminate */ + out = p->outstanding; + while (out) { + if (!out->dead) + send_eos_msg(out, CA_ERROR_DESTROYED); + out = out->next; + } + + /* Now that we've sent EOS for all pending players, append a + * message to wait for the mgr thread to exit */ + if (p->mgr_thread_running && p->semaphore_allocated) { + send_mgr_exit_msg(p); + + p->signal_semaphore = TRUE; + while (p->mgr_thread_running) { + ca_mutex_unlock(p->outstanding_mutex); + sem_wait(&p->semaphore); + ca_mutex_lock(p->outstanding_mutex); + } + } + + ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_free(p->outstanding_mutex); + } - if (p->mgr_bus) - g_object_unref(p->mgr_bus); + if (p->mgr_bus) + g_object_unref(p->mgr_bus); - if (p->theme) - ca_theme_data_free(p->theme); + if (p->theme) + ca_theme_data_free(p->theme); - if (p->semaphore_allocated) - sem_destroy(&p->semaphore); + if (p->semaphore_allocated) + sem_destroy(&p->semaphore); - ca_free(p); + ca_free(p); - /* no gst_deinit(), see doc */ + /* no gst_deinit(), see doc */ - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_device(ca_context *c, const char *device) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(changed, CA_ERROR_INVALID); - ca_return_val_if_fail(merged, CA_ERROR_INVALID); - ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); - return CA_SUCCESS; + return CA_SUCCESS; } static void send_eos_msg(struct outstanding *out, int err) { - struct private *p; - GstMessage *m; - GstStructure *s; + struct private *p; + GstMessage *m; + GstStructure *s; - out->dead = TRUE; - out->err = err; + out->dead = TRUE; + out->err = err; - p = PRIVATE(out->context); - s = gst_structure_new("application/eos", "info", G_TYPE_POINTER, out, NULL); - m = gst_message_new_application (GST_OBJECT (out->pipeline), s); + p = PRIVATE(out->context); + s = gst_structure_new("application/eos", "info", G_TYPE_POINTER, out, NULL); + m = gst_message_new_application (GST_OBJECT (out->pipeline), s); - gst_bus_post (p->mgr_bus, m); + gst_bus_post (p->mgr_bus, m); } static GstBusSyncReply bus_cb(GstBus *bus, GstMessage *message, gpointer data) { - int err; - struct outstanding *out; - struct private *p; + int err; + struct outstanding *out; + struct private *p; - ca_return_val_if_fail(bus, GST_BUS_DROP); - ca_return_val_if_fail(message, GST_BUS_DROP); - ca_return_val_if_fail(data, GST_BUS_DROP); + ca_return_val_if_fail(bus, GST_BUS_DROP); + ca_return_val_if_fail(message, GST_BUS_DROP); + ca_return_val_if_fail(data, GST_BUS_DROP); - out = data; - p = PRIVATE(out->context); + out = data; + p = PRIVATE(out->context); - switch (GST_MESSAGE_TYPE(message)) { - /* for all elements */ + switch (GST_MESSAGE_TYPE(message)) { + /* for all elements */ case GST_MESSAGE_ERROR: - err = CA_ERROR_SYSTEM; - break; + err = CA_ERROR_SYSTEM; + break; case GST_MESSAGE_EOS: - /* only respect EOS from the toplevel pipeline */ - if (GST_OBJECT(out->pipeline) != GST_MESSAGE_SRC(message)) - return GST_BUS_PASS; + /* only respect EOS from the toplevel pipeline */ + if (GST_OBJECT(out->pipeline) != GST_MESSAGE_SRC(message)) + return GST_BUS_PASS; - err = CA_SUCCESS; - break; + err = CA_SUCCESS; + break; default: - return GST_BUS_PASS; - } + return GST_BUS_PASS; + } - /* Bin finished playback: ask the manager thread to shut it - * down, since we can't from the sync message handler */ - ca_mutex_lock(p->outstanding_mutex); - if (!out->dead) - send_eos_msg(out, err); - ca_mutex_unlock(p->outstanding_mutex); + /* Bin finished playback: ask the manager thread to shut it + * down, since we can't from the sync message handler */ + ca_mutex_lock(p->outstanding_mutex); + if (!out->dead) + send_eos_msg(out, err); + ca_mutex_unlock(p->outstanding_mutex); - return GST_BUS_PASS; + return GST_BUS_PASS; } struct ca_sound_file { - GstElement *fdsrc; + GstElement *fdsrc; }; static int ca_gst_sound_file_open(ca_sound_file **_f, const char *fn) { - int fd; - ca_sound_file *f; + int fd; + ca_sound_file *f; - ca_return_val_if_fail(_f, CA_ERROR_INVALID); - ca_return_val_if_fail(fn, CA_ERROR_INVALID); + ca_return_val_if_fail(_f, CA_ERROR_INVALID); + ca_return_val_if_fail(fn, CA_ERROR_INVALID); - if ((fd = open(fn, O_RDONLY)) == -1) - return errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; + if ((fd = open(fn, O_RDONLY)) == -1) + return errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; - if (!(f = ca_new0(ca_sound_file, 1))) { - close(fd); - return CA_ERROR_OOM; - } + if (!(f = ca_new0(ca_sound_file, 1))) { + close(fd); + return CA_ERROR_OOM; + } - if (!(f->fdsrc = gst_element_factory_make("fdsrc", NULL))) { - close(fd); - ca_free(f); - return CA_ERROR_OOM; - } + if (!(f->fdsrc = gst_element_factory_make("fdsrc", NULL))) { + close(fd); + ca_free(f); + return CA_ERROR_OOM; + } - g_object_set(GST_OBJECT(f->fdsrc), "fd", fd, NULL); - *_f = f; + g_object_set(GST_OBJECT(f->fdsrc), "fd", fd, NULL); + *_f = f; - return CA_SUCCESS; + return CA_SUCCESS; } static void on_pad_added(GstElement *element, GstPad *pad, gboolean arg1, gpointer data) { - GstStructure *structure; - GstElement *sinkelement; - GstCaps *caps; - GstPad *vpad; - const char *type; - - sinkelement = GST_ELEMENT(data); + GstStructure *structure; + GstElement *sinkelement; + GstCaps *caps; + GstPad *vpad; + const char *type; + + sinkelement = GST_ELEMENT(data); + + caps = gst_pad_get_caps(pad); + if (gst_caps_is_empty(caps) || gst_caps_is_any(caps)) { + gst_caps_unref(caps); + return; + } - caps = gst_pad_get_caps(pad); - if (gst_caps_is_empty(caps) || gst_caps_is_any(caps)) { + structure = gst_caps_get_structure(caps, 0); + type = gst_structure_get_name(structure); + if (g_str_has_prefix(type, "audio/x-raw") == TRUE) { + vpad = gst_element_get_pad(sinkelement, "sink"); + gst_pad_link(pad, vpad); + gst_object_unref(vpad); + } gst_caps_unref(caps); - return; - } - - structure = gst_caps_get_structure(caps, 0); - type = gst_structure_get_name(structure); - if (g_str_has_prefix(type, "audio/x-raw") == TRUE) { - vpad = gst_element_get_pad(sinkelement, "sink"); - gst_pad_link(pad, vpad); - gst_object_unref(vpad); - } - gst_caps_unref(caps); } static void send_mgr_exit_msg (struct private *p) { - GstMessage *m; - GstStructure *s; + GstMessage *m; + GstStructure *s; - s = gst_structure_new("application/mgr-exit", NULL); - m = gst_message_new_application (NULL, s); + s = gst_structure_new("application/mgr-exit", NULL); + m = gst_message_new_application (NULL, s); - gst_bus_post (p->mgr_bus, m); + gst_bus_post (p->mgr_bus, m); } /* Global manager thread that shuts down GStreamer pipelines when ordered */ static void* thread_func(void *userdata) { - struct private *p = userdata; - GstBus *bus = g_object_ref(p->mgr_bus); + struct private *p = userdata; + GstBus *bus = g_object_ref(p->mgr_bus); + + pthread_detach(pthread_self()); + + /* Pop messages from the manager bus until we see an exit command */ + do { + GstMessage *m = gst_bus_timed_pop(bus, GST_CLOCK_TIME_NONE); + const GstStructure *s; + const GValue *v; + struct outstanding *out; + + if (m == NULL) + break; + if (GST_MESSAGE_TYPE(m) != GST_MESSAGE_APPLICATION) { + gst_message_unref (m); + break; + } + + s = gst_message_get_structure(m); + if (gst_structure_has_name(s, "application/mgr-exit")) { + gst_message_unref (m); + break; + } + + /* Otherwise, this must be an EOS message for an outstanding pipe */ + ca_assert(gst_structure_has_name(s, "application/eos")); + v = gst_structure_get_value(s, "info"); + ca_assert(v); + out = g_value_get_pointer(v); + ca_assert(out); + + /* Set pipeline back to NULL to close things. By the time this + * completes, we can be sure bus_cb won't be called */ + if (gst_element_set_state(out->pipeline, GST_STATE_NULL) == + GST_STATE_CHANGE_FAILURE) { + gst_message_unref (m); + break; + } + if (out->callback) + out->callback(out->context, out->id, out->err, out->userdata); - pthread_detach(pthread_self()); + ca_mutex_lock(p->outstanding_mutex); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + outstanding_free(out); + ca_mutex_unlock(p->outstanding_mutex); - /* Pop messages from the manager bus until we see an exit command */ - do { - GstMessage *m = gst_bus_timed_pop(bus, GST_CLOCK_TIME_NONE); - const GstStructure *s; - const GValue *v; - struct outstanding *out; + gst_message_unref(m); + } while (TRUE); - if (m == NULL) - break; - if (GST_MESSAGE_TYPE(m) != GST_MESSAGE_APPLICATION) { - gst_message_unref (m); - break; - } + /* Signal the semaphore and exit */ + ca_mutex_lock(p->outstanding_mutex); + if (p->signal_semaphore) + sem_post(&p->semaphore); + p->mgr_thread_running = FALSE; + ca_mutex_unlock(p->outstanding_mutex); - s = gst_message_get_structure(m); - if (gst_structure_has_name(s, "application/mgr-exit")) { - gst_message_unref (m); - break; - } + gst_bus_set_flushing(bus, TRUE); + g_object_unref (bus); + return NULL; +} - /* Otherwise, this must be an EOS message for an outstanding pipe */ - ca_assert(gst_structure_has_name(s, "application/eos")); - v = gst_structure_get_value(s, "info"); - ca_assert(v); - out = g_value_get_pointer(v); - ca_assert(out); - - /* Set pipeline back to NULL to close things. By the time this - * completes, we can be sure bus_cb won't be called */ - if (gst_element_set_state(out->pipeline, GST_STATE_NULL) == - GST_STATE_CHANGE_FAILURE) { - gst_message_unref (m); - break; - } - if (out->callback) - out->callback(out->context, out->id, out->err, out->userdata); - ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - outstanding_free(out); - ca_mutex_unlock(p->outstanding_mutex); +int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { + struct private *p; + struct outstanding *out; + ca_sound_file *f; + GstElement *decodebin, *sink, *audioconvert, *audioresample, *abin; + GstBus *bus; + GstPad *audiopad; + int ret; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + + out = NULL; + f = NULL; + sink = NULL; + decodebin = NULL; + audioconvert = NULL; + audioresample = NULL; + abin = NULL; + p = PRIVATE(c); + + if ((ret = ca_lookup_sound_with_callback(&f, ca_gst_sound_file_open, NULL, &p->theme, c->props, proplist)) < 0) + goto fail; + + if (!(out = ca_new0(struct outstanding, 1))) + return CA_ERROR_OOM; + + out->id = id; + out->callback = cb; + out->userdata = userdata; + out->context = c; + + if (!(out->pipeline = gst_pipeline_new(NULL)) + || !(decodebin = gst_element_factory_make("decodebin2", NULL)) + || !(audioconvert = gst_element_factory_make("audioconvert", NULL)) + || !(audioresample = gst_element_factory_make("audioresample", NULL)) + || !(sink = gst_element_factory_make("autoaudiosink", NULL)) + || !(abin = gst_bin_new ("audiobin"))) { + + /* At this point, if there is a failure, free each plugin separately. */ + if (out->pipeline != NULL) + g_object_unref (out->pipeline); + if (decodebin != NULL) + g_object_unref(decodebin); + if (audioconvert != NULL) + g_object_unref(audioconvert); + if (audioresample != NULL) + g_object_unref(audioresample); + if (sink != NULL) + g_object_unref(sink); + if (abin != NULL) + g_object_unref(abin); + + ca_free(out); + + ret = CA_ERROR_OOM; + goto fail; + } - gst_message_unref(m); - } while (TRUE); + bus = gst_pipeline_get_bus(GST_PIPELINE (out->pipeline)); + gst_bus_set_sync_handler(bus, bus_cb, out); + gst_object_unref(bus); - /* Signal the semaphore and exit */ - ca_mutex_lock(p->outstanding_mutex); - if (p->signal_semaphore) - sem_post(&p->semaphore); - p->mgr_thread_running = FALSE; - ca_mutex_unlock(p->outstanding_mutex); + g_signal_connect(decodebin, "new-decoded-pad", + G_CALLBACK (on_pad_added), abin); + gst_bin_add_many(GST_BIN (abin), audioconvert, audioresample, sink, NULL); + gst_element_link_many(audioconvert, audioresample, sink, NULL); - gst_bus_set_flushing(bus, TRUE); - g_object_unref (bus); - return NULL; -} + audiopad = gst_element_get_pad(audioconvert, "sink"); + gst_element_add_pad(abin, gst_ghost_pad_new("sink", audiopad)); + gst_object_unref(audiopad); + gst_bin_add_many(GST_BIN (out->pipeline), + f->fdsrc, decodebin, abin, NULL); + if (!gst_element_link(f->fdsrc, decodebin)) { + /* Bin now owns the fdsrc... */ + f->fdsrc = NULL; -int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { - struct private *p; - struct outstanding *out; - ca_sound_file *f; - GstElement *decodebin, *sink, *audioconvert, *audioresample, *abin; - GstBus *bus; - GstPad *audiopad; - int ret; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - - out = NULL; - f = NULL; - sink = NULL; - decodebin = NULL; - audioconvert = NULL; - audioresample = NULL; - abin = NULL; - p = PRIVATE(c); - - if ((ret = ca_lookup_sound_with_callback(&f, ca_gst_sound_file_open, NULL, &p->theme, c->props, proplist)) < 0) - goto fail; - - if (!(out = ca_new0(struct outstanding, 1))) - return CA_ERROR_OOM; - - out->id = id; - out->callback = cb; - out->userdata = userdata; - out->context = c; - - if (!(out->pipeline = gst_pipeline_new(NULL)) - || !(decodebin = gst_element_factory_make("decodebin2", NULL)) - || !(audioconvert = gst_element_factory_make("audioconvert", NULL)) - || !(audioresample = gst_element_factory_make("audioresample", NULL)) - || !(sink = gst_element_factory_make("autoaudiosink", NULL)) - || !(abin = gst_bin_new ("audiobin"))) { - - /* At this point, if there is a failure, free each plugin separately. */ - if (out->pipeline != NULL) - g_object_unref (out->pipeline); - if (decodebin != NULL) - g_object_unref(decodebin); - if (audioconvert != NULL) - g_object_unref(audioconvert); - if (audioresample != NULL) - g_object_unref(audioresample); - if (sink != NULL) - g_object_unref(sink); - if (abin != NULL) - g_object_unref(abin); - - ca_free(out); - - ret = CA_ERROR_OOM; - goto fail; - } - - bus = gst_pipeline_get_bus(GST_PIPELINE (out->pipeline)); - gst_bus_set_sync_handler(bus, bus_cb, out); - gst_object_unref(bus); - - g_signal_connect(decodebin, "new-decoded-pad", - G_CALLBACK (on_pad_added), abin); - gst_bin_add_many(GST_BIN (abin), audioconvert, audioresample, sink, NULL); - gst_element_link_many(audioconvert, audioresample, sink, NULL); - - audiopad = gst_element_get_pad(audioconvert, "sink"); - gst_element_add_pad(abin, gst_ghost_pad_new("sink", audiopad)); - gst_object_unref(audiopad); - - gst_bin_add_many(GST_BIN (out->pipeline), - f->fdsrc, decodebin, abin, NULL); - if (!gst_element_link(f->fdsrc, decodebin)) { + outstanding_free(out); + ret = CA_ERROR_OOM; + goto fail; + } /* Bin now owns the fdsrc... */ f->fdsrc = NULL; - outstanding_free(out); - ret = CA_ERROR_OOM; - goto fail; - } - /* Bin now owns the fdsrc... */ - f->fdsrc = NULL; - - ca_free(f); - f = NULL; + ca_free(f); + f = NULL; - ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); + CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); - if (gst_element_set_state(out->pipeline, - GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { - ret = CA_ERROR_NOTAVAILABLE; - goto fail; - } + if (gst_element_set_state(out->pipeline, + GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { + ret = CA_ERROR_NOTAVAILABLE; + goto fail; + } - return CA_SUCCESS; + return CA_SUCCESS; fail: - if (f && f->fdsrc) - gst_object_unref(f->fdsrc); + if (f && f->fdsrc) + gst_object_unref(f->fdsrc); - if (f) - ca_free(f); + if (f) + ca_free(f); - return ret; + return ret; } int driver_cancel(ca_context *c, uint32_t id) { - struct private *p; - struct outstanding *out = NULL; + struct private *p; + struct outstanding *out = NULL; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); + p = PRIVATE(c); - p = PRIVATE(c); + ca_mutex_lock(p->outstanding_mutex); - ca_mutex_lock(p->outstanding_mutex); + for (out = p->outstanding; out;/* out = out->next*/) { + struct outstanding *next; - for (out = p->outstanding; out;/* out = out->next*/) { - struct outstanding *next; + if (out->id != id || out->pipeline == NULL || out->dead == TRUE) { + out = out->next; + continue; + } - if (out->id != id || out->pipeline == NULL || out->dead == TRUE) - { - out = out->next; - continue; - } + if (gst_element_set_state(out->pipeline, GST_STATE_NULL) == + GST_STATE_CHANGE_FAILURE) + goto error; - if (gst_element_set_state(out->pipeline, GST_STATE_NULL) == - GST_STATE_CHANGE_FAILURE) { - goto error; + if (out->callback) + out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); + next = out->next; + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + outstanding_free(out); + out = next; } - if (out->callback) - out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); - next = out->next; - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - outstanding_free(out); - out = next; - } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; error: - ca_mutex_unlock(p->outstanding_mutex); - return CA_ERROR_SYSTEM; + ca_mutex_unlock(p->outstanding_mutex); + return CA_ERROR_SYSTEM; } int driver_cache(ca_context *c, ca_proplist *proplist) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(PRIVATE(c), CA_ERROR_STATE); - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; } int driver_playing(ca_context *c, uint32_t id, int *playing) { - struct private *p; - struct outstanding *out; + 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); + 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); + p = PRIVATE(c); - *playing = 0; + *playing = 0; - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = out->next) { + for (out = p->outstanding; out; out = out->next) { - if (out->id != id || out->pipeline == NULL || out->dead == TRUE) - continue; + if (out->id != id || out->pipeline == NULL || out->dead == TRUE) + continue; - *playing = 1; - break; - } + *playing = 1; + break; + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; } diff --git a/src/llist.h b/src/llist.h index cf49bef..5464cb9 100644 --- a/src/llist.h +++ b/src/llist.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberrallistfoo #define foocanberrallistfoo @@ -27,80 +29,80 @@ /* The head of the linked list. Use this in the structure that shall * contain the head of the linked list */ -#define CA_LLIST_HEAD(t,name) \ - t *name +#define CA_LLIST_HEAD(t,name) \ + t *name /* The pointers in the linked list's items. Use this in the item structure */ -#define CA_LLIST_FIELDS(t) \ - t *next, *prev +#define CA_LLIST_FIELDS(t) \ + t *next, *prev /* Initialize the list's head */ -#define CA_LLIST_HEAD_INIT(t,item) \ - do { \ - (item) = (t*) NULL; } \ - while(0) +#define CA_LLIST_HEAD_INIT(t,item) \ + do { \ + (item) = (t*) NULL; } \ + while(0) /* Initialize a list item */ -#define CA_LLIST_INIT(t,item) \ - do { \ - t *_item = (item); \ - ca_assert(_item); \ - _item->prev = _item->next = NULL; \ - } while(0) +#define CA_LLIST_INIT(t,item) \ + do { \ + t *_item = (item); \ + ca_assert(_item); \ + _item->prev = _item->next = NULL; \ + } while(0) /* Prepend an item to the list */ -#define CA_LLIST_PREPEND(t,head,item) \ - do { \ - t **_head = &(head), *_item = (item); \ - ca_assert(_item); \ - if ((_item->next = *_head)) \ - _item->next->prev = _item; \ - _item->prev = NULL; \ - *_head = _item; \ - } while (0) +#define CA_LLIST_PREPEND(t,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + ca_assert(_item); \ + if ((_item->next = *_head)) \ + _item->next->prev = _item; \ + _item->prev = NULL; \ + *_head = _item; \ + } while (0) /* Remove an item from the list */ -#define CA_LLIST_REMOVE(t,head,item) \ - do { \ - t **_head = &(head), *_item = (item); \ - ca_assert(_item); \ - if (_item->next) \ - _item->next->prev = _item->prev; \ - if (_item->prev) \ - _item->prev->next = _item->next; \ - else { \ - ca_assert(*_head == _item); \ - *_head = _item->next; \ - } \ - _item->next = _item->prev = NULL; \ - } while(0) +#define CA_LLIST_REMOVE(t,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + ca_assert(_item); \ + if (_item->next) \ + _item->next->prev = _item->prev; \ + if (_item->prev) \ + _item->prev->next = _item->next; \ + else { \ + ca_assert(*_head == _item); \ + *_head = _item->next; \ + } \ + _item->next = _item->prev = NULL; \ + } while(0) /* Find the head of the list */ -#define CA_LLIST_FIND_HEAD(t,item,head) \ - do { \ - t **_head = (head), *_item = (item); \ - *_head = _item; \ - ca_assert(_head); \ - while ((*_head)->prev) \ - *_head = (*_head)->prev; \ - } while (0) +#define CA_LLIST_FIND_HEAD(t,item,head) \ + do { \ + t **_head = (head), *_item = (item); \ + *_head = _item; \ + ca_assert(_head); \ + while ((*_head)->prev) \ + *_head = (*_head)->prev; \ + } while (0) /* Insert an item after another one (a = where, b = what) */ -#define CA_LLIST_INSERT_AFTER(t,head,a,b) \ - do { \ - t **_head = &(head), *_a = (a), *_b = (b); \ - ca_assert(_b); \ - if (!_a) { \ - if ((_b->next = *_head)) \ - _b->next->prev = _b; \ - _b->prev = NULL; \ - *_head = _b; \ - } else { \ - if ((_b->next = _a->next)) \ - _b->next->prev = _b; \ - _b->prev = _a; \ - _a->next = _b; \ - } \ - } while (0) +#define CA_LLIST_INSERT_AFTER(t,head,a,b) \ + do { \ + t **_head = &(head), *_a = (a), *_b = (b); \ + ca_assert(_b); \ + if (!_a) { \ + if ((_b->next = *_head)) \ + _b->next->prev = _b; \ + _b->prev = NULL; \ + *_head = _b; \ + } else { \ + if ((_b->next = _a->next)) \ + _b->next->prev = _b; \ + _b->prev = _a; \ + _a->next = _b; \ + } \ + } while (0) #endif diff --git a/src/macro.c b/src/macro.c index f47aa21..113287f 100644 --- a/src/macro.c +++ b/src/macro.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -25,10 +27,10 @@ #include "macro.h" ca_bool_t ca_debug(void) { - const char *d; + const char *d; - if ((d = getenv("CANBERRA_DEBUG"))) - return !!*d; + if ((d = getenv("CANBERRA_DEBUG"))) + return !!*d; - return FALSE; + return FALSE; } diff --git a/src/macro.h b/src/macro.h index 0ad892f..293c071 100644 --- a/src/macro.h +++ b/src/macro.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberramacrohfoo #define foocanberramacrohfoo @@ -43,56 +45,56 @@ #endif #define ca_return_if_fail(expr) \ - do { \ - if (CA_UNLIKELY(!(expr))) { \ - if (ca_debug()) \ - fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ - return; \ - } \ - } while(FALSE) - -#define ca_return_val_if_fail(expr, val) \ - do { \ - if (CA_UNLIKELY(!(expr))) { \ - if (ca_debug()) \ - fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ - return (val); \ - } \ - } while(FALSE) + do { \ + if (CA_UNLIKELY(!(expr))) { \ + if (ca_debug()) \ + fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ + return; \ + } \ + } while(FALSE) + +#define ca_return_val_if_fail(expr, val) \ + do { \ + if (CA_UNLIKELY(!(expr))) { \ + if (ca_debug()) \ + fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ + return (val); \ + } \ + } while(FALSE) #define ca_return_null_if_fail(expr) ca_return_val_if_fail(expr, NULL) #define ca_return_if_fail_unlock(expr, mutex) \ - do { \ - if (CA_UNLIKELY(!(expr))) { \ - if (ca_debug()) \ - fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ - ca_mutex_unlock(mutex); \ - return; \ - } \ - } while(FALSE) + do { \ + if (CA_UNLIKELY(!(expr))) { \ + if (ca_debug()) \ + fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ + ca_mutex_unlock(mutex); \ + return; \ + } \ + } while(FALSE) #define ca_return_val_if_fail_unlock(expr, val, mutex) \ - do { \ - if (CA_UNLIKELY(!(expr))) { \ - if (ca_debug()) \ - fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ - ca_mutex_unlock(mutex); \ - return (val); \ - } \ - } while(FALSE) + do { \ + if (CA_UNLIKELY(!(expr))) { \ + if (ca_debug()) \ + fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s().\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ + ca_mutex_unlock(mutex); \ + return (val); \ + } \ + } while(FALSE) #define ca_return_null_if_fail_unlock(expr, mutex) ca_return_val_if_fail_unlock(expr, NULL, mutex) /* An assert which guarantees side effects of x, i.e. is never * optimized away */ #define ca_assert_se(expr) \ - do { \ - if (CA_UNLIKELY(!(expr))) { \ - fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s(). Aborting.\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ - abort(); \ - } \ - } while (FALSE) + do { \ + if (CA_UNLIKELY(!(expr))) { \ + fprintf(stderr, "Assertion '%s' failed at %s:%u, function %s(). Aborting.\n", #expr , __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ + abort(); \ + } \ + } while (FALSE) /* An assert that may be optimized away by defining NDEBUG */ #ifdef NDEBUG @@ -102,40 +104,40 @@ #endif #define ca_assert_not_reached() \ - do { \ - fprintf(stderr, "Code should not be reached at %s:%u, function %s(). Aborting.\n", __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ - abort(); \ - } while (FALSE) + do { \ + fprintf(stderr, "Code should not be reached at %s:%u, function %s(). Aborting.\n", __FILE__, __LINE__, CA_PRETTY_FUNCTION); \ + abort(); \ + } while (FALSE) #define CA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) #ifdef __GNUC__ #define CA_MAX(a,b) \ - __extension__ ({ typeof(a) _a = (a); \ - typeof(b) _b = (b); \ - _a > _b ? _a : _b; \ - }) + __extension__ ({ typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + _a > _b ? _a : _b; \ + }) #else #define CA_MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifdef __GNUC__ #define CA_MIN(a,b) \ - __extension__ ({ typeof(a) _a = (a); \ - typeof(b) _b = (b); \ - _a < _b ? _a : _b; \ - }) + __extension__ ({ typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + _a < _b ? _a : _b; \ + }) #else #define CA_MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifdef __GNUC__ #define CA_CLAMP(x, low, high) \ - __extension__ ({ typeof(x) _x = (x); \ - typeof(low) _low = (low); \ - typeof(high) _high = (high); \ - ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \ - }) + __extension__ ({ typeof(x) _x = (x); \ + typeof(low) _low = (low); \ + typeof(high) _high = (high); \ + ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \ + }) #else #define CA_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) #endif @@ -165,7 +167,7 @@ typedef int ca_bool_t; ca_bool_t ca_debug(void); static inline size_t ca_align(size_t l) { - return (((l + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)); + return (((l + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)); } #define CA_ALIGN(x) (ca_align(x)) @@ -177,15 +179,15 @@ typedef void (*ca_free_cb_t)(void *); #endif #ifdef HAVE_BYTESWAP_H -#define CA_INT16_SWAP(x) ((int16_t) bswap_16((uint16_t) x)) -#define CA_UINT16_SWAP(x) ((uint16_t) bswap_16((uint16_t) x)) -#define CA_INT32_SWAP(x) ((int32_t) bswap_32((uint32_t) x)) -#define CA_UINT32_SWAP(x) ((uint32_t) bswap_32((uint32_t) x)) + #define CA_INT16_SWAP(x) ((int16_t) bswap_16((uint16_t) x)) + #define CA_UINT16_SWAP(x) ((uint16_t) bswap_16((uint16_t) x)) + #define CA_INT32_SWAP(x) ((int32_t) bswap_32((uint32_t) x)) + #define CA_UINT32_SWAP(x) ((uint32_t) bswap_32((uint32_t) x)) #else -#define CA_INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) -#define CA_UINT16_SWAP(x) ( (uint16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) -#define CA_INT32_SWAP(x) ( (int32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) -#define CA_UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) + #define CA_INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) + #define CA_UINT16_SWAP(x) ( (uint16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) + #define CA_INT32_SWAP(x) ( (int32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) + #define CA_UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) #endif #ifdef WORDS_BIGENDIAN diff --git a/src/malloc.c b/src/malloc.c index 4586d4d..0cb24c5 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -30,69 +32,69 @@ #include "macro.h" void* ca_memdup(const void* p, size_t size) { - void *r; + void *r; - ca_assert(p); + ca_assert(p); - if (!(r = ca_malloc(size))) - return NULL; + if (!(r = ca_malloc(size))) + return NULL; - memcpy(r, p, size); - return r; + memcpy(r, p, size); + return r; } char *ca_sprintf_malloc(const char *format, ...) { - size_t size = 100; - char *c = NULL; + size_t size = 100; + char *c = NULL; - ca_assert(format); + ca_assert(format); - for(;;) { - int r; - va_list ap; + for(;;) { + int r; + va_list ap; - ca_free(c); + ca_free(c); - if (!(c = ca_new(char, size))) - return NULL; + if (!(c = ca_new(char, size))) + return NULL; - va_start(ap, format); - r = vsnprintf(c, size, format, ap); - va_end(ap); + va_start(ap, format); + r = vsnprintf(c, size, format, ap); + va_end(ap); - c[size-1] = 0; + c[size-1] = 0; - if (r > -1 && (size_t) r < size) - return c; + if (r > -1 && (size_t) r < size) + return c; - if (r > -1) /* glibc 2.1 */ - size = (size_t) r+1; - else /* glibc 2.0 */ - size *= 2; - } + if (r > -1) /* glibc 2.1 */ + size = (size_t) r+1; + else /* glibc 2.0 */ + size *= 2; + } } #ifndef HAVE_STRNDUP char *ca_strndup(const char *s, size_t n) { - size_t n_avail; - char *p; + size_t n_avail; + char *p; - if (!s) - return NULL; + if (!s) + return NULL; - if (memchr(s, '\0', n)) { - n_avail = strlen(s); - if (n_avail > n) - n_avail = n; - } else - n_avail = n; + if (memchr(s, '\0', n)) { + n_avail = strlen(s); + if (n_avail > n) + n_avail = n; + } else + n_avail = n; - if (!(p = ca_new(char, n_avail + 1))) - return NULL; + if (!(p = ca_new(char, n_avail + 1))) + return NULL; - memcpy(p, s, n_avail); - p[n_avail] = '\0'; + memcpy(p, s, n_avail); + p[n_avail] = '\0'; - return p; + return p; } #endif diff --git a/src/malloc.h b/src/malloc.h index 6073e03..91ab68b 100644 --- a/src/malloc.h +++ b/src/malloc.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberramallochfoo #define foocanberramallochfoo diff --git a/src/multi.c b/src/multi.c index 233e635..6ee06a9 100644 --- a/src/multi.c +++ b/src/multi.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -29,333 +31,333 @@ #include "driver-order.h" struct backend { - CA_LLIST_FIELDS(struct backend); - ca_context *context; + CA_LLIST_FIELDS(struct backend); + ca_context *context; }; struct private { - ca_context *context; - CA_LLIST_HEAD(struct backend, backends); + ca_context *context; + CA_LLIST_HEAD(struct backend, backends); }; #define PRIVATE(c) ((struct private *) ((c)->private)) static int add_backend(struct private *p, const char *name) { - struct backend *b, *last; - int ret; + struct backend *b, *last; + int ret; - ca_assert(p); - ca_assert(name); + ca_assert(p); + ca_assert(name); - if (ca_streq(name, "multi")) - return CA_ERROR_NOTAVAILABLE; + if (ca_streq(name, "multi")) + return CA_ERROR_NOTAVAILABLE; - for (b = p->backends; b; b = b->next) - if (ca_streq(b->context->driver, name)) - return CA_ERROR_NOTAVAILABLE; + for (b = p->backends; b; b = b->next) + if (ca_streq(b->context->driver, name)) + return CA_ERROR_NOTAVAILABLE; - if (!(b = ca_new0(struct backend, 1))) - return CA_ERROR_OOM; + if (!(b = ca_new0(struct backend, 1))) + return CA_ERROR_OOM; - if ((ret = ca_context_create(&b->context)) < 0) - goto fail; + if ((ret = ca_context_create(&b->context)) < 0) + goto fail; - if ((ret = ca_context_change_props_full(b->context, p->context->props)) < 0) - goto fail; + if ((ret = ca_context_change_props_full(b->context, p->context->props)) < 0) + goto fail; - if ((ret = ca_context_set_driver(b->context, name)) < 0) - goto fail; + if ((ret = ca_context_set_driver(b->context, name)) < 0) + goto fail; - if ((ret = ca_context_open(b->context)) < 0) - goto fail; + if ((ret = ca_context_open(b->context)) < 0) + goto fail; - for (last = p->backends; last; last = last->next) - if (!last->next) - break; + for (last = p->backends; last; last = last->next) + if (!last->next) + break; - CA_LLIST_INSERT_AFTER(struct backend, p->backends, last, b); + CA_LLIST_INSERT_AFTER(struct backend, p->backends, last, b); - return CA_SUCCESS; + return CA_SUCCESS; fail: - if (b->context) - ca_context_destroy(b->context); + if (b->context) + ca_context_destroy(b->context); - ca_free(b); + ca_free(b); - return ret; + return ret; } static int remove_backend(struct private *p, struct backend *b) { - int ret; + int ret; - ca_assert(p); - ca_assert(b); + ca_assert(p); + ca_assert(b); - ret = ca_context_destroy(b->context); - CA_LLIST_REMOVE(struct backend, p->backends, b); - ca_free(b); + ret = ca_context_destroy(b->context); + CA_LLIST_REMOVE(struct backend, p->backends, b); + ca_free(b); - return ret; + return ret; } int driver_open(ca_context *c) { - struct private *p; - int ret = CA_SUCCESS; + struct private *p; + int ret = CA_SUCCESS; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->driver, CA_ERROR_NODRIVER); - ca_return_val_if_fail(!strncmp(c->driver, "multi", 5), CA_ERROR_NODRIVER); - ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->driver, CA_ERROR_NODRIVER); + ca_return_val_if_fail(!strncmp(c->driver, "multi", 5), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); - if (!(c->private = p = ca_new0(struct private, 1))) - return CA_ERROR_OOM; + if (!(c->private = p = ca_new0(struct private, 1))) + return CA_ERROR_OOM; - p->context = c; + p->context = c; - if (c->driver) { - char *e, *k; + if (c->driver) { + char *e, *k; - if (!(e = ca_strdup(c->driver))) { - driver_destroy(c); - return CA_ERROR_OOM; - } + if (!(e = ca_strdup(c->driver))) { + driver_destroy(c); + return CA_ERROR_OOM; + } - k = e; - for (;;) { - size_t n; - ca_bool_t last; + k = e; + for (;;) { + size_t n; + ca_bool_t last; - n = strcspn(k, ",:"); - last = k[n] == 0; - k[n] = 0; + n = strcspn(k, ",:"); + last = k[n] == 0; + k[n] = 0; - if (n > 0) { - int r; + if (n > 0) { + int r; - r = add_backend(p, k); + r = add_backend(p, k); - if (ret == CA_SUCCESS) - ret = r; - } + if (ret == CA_SUCCESS) + ret = r; + } - if (last) - break; + if (last) + break; - k += n+1 ; - } + k += n+1 ; + } - ca_free(e); + ca_free(e); - } else { + } else { - const char *const *e; + const char *const *e; - for (e = ca_driver_order; *e; e++) { - int r; + for (e = ca_driver_order; *e; e++) { + int r; - r = add_backend(p, *e); + r = add_backend(p, *e); - /* We return the error code of the first module that fails only */ - if (ret == CA_SUCCESS) - ret = r; + /* We return the error code of the first module that fails only */ + if (ret == CA_SUCCESS) + ret = r; + } } - } - if (!p->backends) { - driver_destroy(c); - return ret == CA_SUCCESS ? CA_ERROR_NODRIVER : ret; - } + if (!p->backends) { + driver_destroy(c); + return ret == CA_SUCCESS ? CA_ERROR_NODRIVER : ret; + } - return CA_SUCCESS; + return CA_SUCCESS; } int driver_destroy(ca_context *c) { - int ret = CA_SUCCESS; - struct private *p; + int ret = CA_SUCCESS; + struct private *p; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - while (p->backends) { - int r; + while (p->backends) { + int r; - r = remove_backend(p, p->backends); + r = remove_backend(p, p->backends); - if (ret == CA_SUCCESS) - ret = r; - } + if (ret == CA_SUCCESS) + ret = r; + } - ca_free(p); + ca_free(p); - c->private = NULL; + c->private = NULL; - return ret; + return ret; } int driver_change_device(ca_context *c, const char *device) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - int ret = CA_SUCCESS; - struct private *p; - struct backend *b; + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(changed, CA_ERROR_INVALID); - ca_return_val_if_fail(merged, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - for (b = p->backends; b; b = b->next) { - int r; + for (b = p->backends; b; b = b->next) { + int r; - r = ca_context_change_props_full(b->context, changed); + r = ca_context_change_props_full(b->context, changed); - /* We only return the first failure */ - if (ret == CA_SUCCESS) - ret = r; - } + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } - return ret; + return ret; } struct closure { - ca_context *context; - ca_finish_callback_t callback; - void *userdata; + ca_context *context; + ca_finish_callback_t callback; + void *userdata; }; static void call_closure(ca_context *c, uint32_t id, int error_code, void *userdata) { - struct closure *closure = userdata; + struct closure *closure = userdata; - closure->callback(closure->context, id, error_code, closure->userdata); - ca_free(closure); + closure->callback(closure->context, id, error_code, closure->userdata); + ca_free(closure); } int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { - int ret = CA_SUCCESS; - struct private *p; - struct backend *b; - struct closure *closure; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - - p = PRIVATE(c); - - if (cb) { - if (!(closure = ca_new(struct closure, 1))) - return CA_ERROR_OOM; - - closure->context = c; - closure->callback = cb; - closure->userdata = userdata; - } else - closure = NULL; - - /* The first backend that can play this, takes it */ - for (b = p->backends; b; b = b->next) { - int r; + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; + struct closure *closure; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + if (cb) { + if (!(closure = ca_new(struct closure, 1))) + return CA_ERROR_OOM; + + closure->context = c; + closure->callback = cb; + closure->userdata = userdata; + } else + closure = NULL; + + /* The first backend that can play this, takes it */ + for (b = p->backends; b; b = b->next) { + int r; - if ((r = ca_context_play_full(b->context, id, proplist, closure ? call_closure : NULL, closure)) == CA_SUCCESS) - return r; + if ((r = ca_context_play_full(b->context, id, proplist, closure ? call_closure : NULL, closure)) == CA_SUCCESS) + return r; - /* We only return the first failure */ - if (ret == CA_SUCCESS) - ret = r; - } + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } - ca_free(closure); + ca_free(closure); - return ret; + return ret; } int driver_cancel(ca_context *c, uint32_t id) { - int ret = CA_SUCCESS; - struct private *p; - struct backend *b; + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - for (b = p->backends; b; b = b->next) { - int r; + for (b = p->backends; b; b = b->next) { + int r; - r = ca_context_cancel(b->context, id); + r = ca_context_cancel(b->context, id); - /* We only return the first failure */ - if (ret == CA_SUCCESS) - ret = r; - } + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } - return ret; + return ret; } int driver_cache(ca_context *c, ca_proplist *proplist) { - int ret = CA_SUCCESS; - struct private *p; - struct backend *b; + int ret = CA_SUCCESS; + struct private *p; + struct backend *b; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - /* The first backend that can cache this, takes it */ - for (b = p->backends; b; b = b->next) { - int r; + /* The first backend that can cache this, takes it */ + for (b = p->backends; b; b = b->next) { + int r; - if ((r = ca_context_cache_full(b->context, proplist)) == CA_SUCCESS) - return r; + if ((r = ca_context_cache_full(b->context, proplist)) == CA_SUCCESS) + return r; - /* We only return the first failure */ - if (ret == CA_SUCCESS) - ret = r; - } + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; + } - return ret; + return ret; } int driver_playing(ca_context *c, uint32_t id, int *playing) { - int ret = CA_SUCCESS; - struct private *p; - struct backend *b; + 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); + 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); + p = PRIVATE(c); - *playing = 0; + *playing = 0; - for (b = p->backends; b; b = b->next) { - int r, _playing = 0; + for (b = p->backends; b; b = b->next) { + int r, _playing = 0; - r = ca_context_playing(b->context, id, &_playing); + r = ca_context_playing(b->context, id, &_playing); - /* We only return the first failure */ - if (ret == CA_SUCCESS) - ret = r; + /* We only return the first failure */ + if (ret == CA_SUCCESS) + ret = r; - if (_playing) - *playing = 1; - } + if (_playing) + *playing = 1; + } - return ret; + return ret; } diff --git a/src/mutex-posix.c b/src/mutex-posix.c index 8d8b88b..0875c52 100644 --- a/src/mutex-posix.c +++ b/src/mutex-posix.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -29,50 +31,50 @@ #include "malloc.h" struct ca_mutex { - pthread_mutex_t mutex; + pthread_mutex_t mutex; }; ca_mutex* ca_mutex_new(void) { - ca_mutex *m; + ca_mutex *m; - if (!(m = ca_new(ca_mutex, 1))) - return NULL; + if (!(m = ca_new(ca_mutex, 1))) + return NULL; - if (pthread_mutex_init(&m->mutex, NULL) < 0) { - ca_free(m); - return NULL; - } + if (pthread_mutex_init(&m->mutex, NULL) < 0) { + ca_free(m); + return NULL; + } - return m; + return m; } void ca_mutex_free(ca_mutex *m) { - ca_assert(m); + ca_assert(m); - ca_assert_se(pthread_mutex_destroy(&m->mutex) == 0); - ca_free(m); + ca_assert_se(pthread_mutex_destroy(&m->mutex) == 0); + ca_free(m); } void ca_mutex_lock(ca_mutex *m) { - ca_assert(m); + ca_assert(m); - ca_assert_se(pthread_mutex_lock(&m->mutex) == 0); + ca_assert_se(pthread_mutex_lock(&m->mutex) == 0); } ca_bool_t ca_mutex_try_lock(ca_mutex *m) { - int r; - ca_assert(m); + int r; + ca_assert(m); - if ((r = pthread_mutex_trylock(&m->mutex)) != 0) { - ca_assert(r == EBUSY); - return FALSE; - } + if ((r = pthread_mutex_trylock(&m->mutex)) != 0) { + ca_assert(r == EBUSY); + return FALSE; + } - return TRUE; + return TRUE; } void ca_mutex_unlock(ca_mutex *m) { - ca_assert(m); + ca_assert(m); - ca_assert_se(pthread_mutex_unlock(&m->mutex) == 0); + ca_assert_se(pthread_mutex_unlock(&m->mutex) == 0); } diff --git a/src/mutex.h b/src/mutex.h index e0575ba..a02e6c2 100644 --- a/src/mutex.h +++ b/src/mutex.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberramutexhfoo #define foocanberramutexhfoo diff --git a/src/null.c b/src/null.c index da91e44..c0f88d6 100644 --- a/src/null.c +++ b/src/null.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -29,52 +31,52 @@ #include "driver.h" int driver_open(ca_context *c) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "null"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "null"), CA_ERROR_NODRIVER); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_destroy(ca_context *c) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_device(ca_context *c, const char *device) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(changed, CA_ERROR_INVALID); - ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - if (cb) - cb(c, id, CA_SUCCESS, userdata); + if (cb) + cb(c, id, CA_SUCCESS, userdata); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_cancel(ca_context *c, uint32_t id) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_cache(ca_context *c, ca_proplist *proplist) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; } diff --git a/src/oss.c b/src/oss.c index eebc2f8..222503c 100644 --- a/src/oss.c +++ b/src/oss.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -57,474 +59,474 @@ struct private; struct outstanding { - CA_LLIST_FIELDS(struct outstanding); - ca_bool_t dead; - uint32_t id; - ca_finish_callback_t callback; - void *userdata; - ca_sound_file *file; - int pcm; - int pipe_fd[2]; - ca_context *context; + CA_LLIST_FIELDS(struct outstanding); + ca_bool_t dead; + uint32_t id; + ca_finish_callback_t callback; + void *userdata; + ca_sound_file *file; + int pcm; + int pipe_fd[2]; + ca_context *context; }; struct private { - ca_theme_data *theme; - ca_mutex *outstanding_mutex; - ca_bool_t signal_semaphore; - sem_t semaphore; - ca_bool_t semaphore_allocated; - CA_LLIST_HEAD(struct outstanding, outstanding); + ca_theme_data *theme; + ca_mutex *outstanding_mutex; + ca_bool_t signal_semaphore; + sem_t semaphore; + ca_bool_t semaphore_allocated; + CA_LLIST_HEAD(struct outstanding, outstanding); }; #define PRIVATE(c) ((struct private *) ((c)->private)) static void outstanding_free(struct outstanding *o) { - ca_assert(o); + ca_assert(o); - if (o->pipe_fd[1] >= 0) - close(o->pipe_fd[1]); + if (o->pipe_fd[1] >= 0) + close(o->pipe_fd[1]); - if (o->pipe_fd[0] >= 0) - close(o->pipe_fd[0]); + if (o->pipe_fd[0] >= 0) + close(o->pipe_fd[0]); - if (o->file) - ca_sound_file_close(o->file); + if (o->file) + ca_sound_file_close(o->file); - if (o->pcm >= 0) { - close(o->pcm); - o->pcm = -1; - } + if (o->pcm >= 0) { + close(o->pcm); + o->pcm = -1; + } - ca_free(o); + ca_free(o); } int driver_open(ca_context *c) { - struct private *p; + struct private *p; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "oss"), CA_ERROR_NODRIVER); - ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "oss"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); - if (!(c->private = p = ca_new0(struct private, 1))) - return CA_ERROR_OOM; + if (!(c->private = p = ca_new0(struct private, 1))) + return CA_ERROR_OOM; - if (!(p->outstanding_mutex = ca_mutex_new())) { - driver_destroy(c); - return CA_ERROR_OOM; - } + if (!(p->outstanding_mutex = ca_mutex_new())) { + driver_destroy(c); + return CA_ERROR_OOM; + } - if (sem_init(&p->semaphore, 0, 0) < 0) { - driver_destroy(c); - return CA_ERROR_OOM; - } + if (sem_init(&p->semaphore, 0, 0) < 0) { + driver_destroy(c); + return CA_ERROR_OOM; + } - p->semaphore_allocated = TRUE; + p->semaphore_allocated = TRUE; - return CA_SUCCESS; + return CA_SUCCESS; } int driver_destroy(ca_context *c) { - struct private *p; - struct outstanding *out; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - if (p->outstanding_mutex) { - ca_mutex_lock(p->outstanding_mutex); + if (p->outstanding_mutex) { + ca_mutex_lock(p->outstanding_mutex); - /* Tell all player threads to terminate */ - for (out = p->outstanding; out; out = out->next) { + /* Tell all player threads to terminate */ + for (out = p->outstanding; out; out = out->next) { - if (out->dead) - continue; + if (out->dead) + continue; - out->dead = TRUE; + out->dead = TRUE; - if (out->callback) - out->callback(c, out->id, CA_ERROR_DESTROYED, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_ERROR_DESTROYED, out->userdata); - /* This will cause the thread to wakeup and terminate */ - if (out->pipe_fd[1] >= 0) { - close(out->pipe_fd[1]); - out->pipe_fd[1] = -1; - } - } + /* This will cause the thread to wakeup and terminate */ + if (out->pipe_fd[1] >= 0) { + close(out->pipe_fd[1]); + out->pipe_fd[1] = -1; + } + } + + if (p->semaphore_allocated) { + /* Now wait until all players are destroyed */ + p->signal_semaphore = TRUE; + while (p->outstanding) { + ca_mutex_unlock(p->outstanding_mutex); + sem_wait(&p->semaphore); + ca_mutex_lock(p->outstanding_mutex); + } + } - if (p->semaphore_allocated) { - /* Now wait until all players are destroyed */ - p->signal_semaphore = TRUE; - while (p->outstanding) { ca_mutex_unlock(p->outstanding_mutex); - sem_wait(&p->semaphore); - ca_mutex_lock(p->outstanding_mutex); - } + ca_mutex_free(p->outstanding_mutex); } - ca_mutex_unlock(p->outstanding_mutex); - ca_mutex_free(p->outstanding_mutex); - } - - if (p->theme) - ca_theme_data_free(p->theme); + if (p->theme) + ca_theme_data_free(p->theme); - if (p->semaphore_allocated) - sem_destroy(&p->semaphore); + if (p->semaphore_allocated) + sem_destroy(&p->semaphore); - ca_free(p); + ca_free(p); - c->private = NULL; + c->private = NULL; - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_device(ca_context *c, const char *device) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(changed, CA_ERROR_INVALID); - ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_cache(ca_context *c, ca_proplist *proplist) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; } static int translate_error(int error) { - switch (error) { + switch (error) { case ENODEV: case ENOENT: - return CA_ERROR_NOTFOUND; + return CA_ERROR_NOTFOUND; case EACCES: case EPERM: - return CA_ERROR_ACCESS; + return CA_ERROR_ACCESS; case ENOMEM: - return CA_ERROR_OOM; + return CA_ERROR_OOM; case EBUSY: - return CA_ERROR_NOTAVAILABLE; + return CA_ERROR_NOTAVAILABLE; case EINVAL: - return CA_ERROR_INVALID; + return CA_ERROR_INVALID; case ENOSYS: - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; default: - if (ca_debug()) - fprintf(stderr, "Got unhandled error from OSS: %s\n", strerror(error)); - return CA_ERROR_IO; - } + if (ca_debug()) + fprintf(stderr, "Got unhandled error from OSS: %s\n", strerror(error)); + return CA_ERROR_IO; + } } static int open_oss(ca_context *c, struct outstanding *out) { - struct private *p; - int mode, val, test, ret; + struct private *p; + int mode, val, test, ret; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - ca_return_val_if_fail(out, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(out, CA_ERROR_INVALID); - /* In OSS we have no way to configure a channel mapping for - * multichannel streams. We cannot support those files hence */ - ca_return_val_if_fail(ca_sound_file_get_nchannels(out->file) <= 2, CA_ERROR_NOTSUPPORTED); + /* In OSS we have no way to configure a channel mapping for + * multichannel streams. We cannot support those files hence */ + ca_return_val_if_fail(ca_sound_file_get_nchannels(out->file) <= 2, CA_ERROR_NOTSUPPORTED); - p = PRIVATE(c); + p = PRIVATE(c); - if ((out->pcm = open(c->device ? c->device : "/dev/dsp", O_WRONLY | O_NONBLOCK, 0)) < 0) - goto finish_errno; + if ((out->pcm = open(c->device ? c->device : "/dev/dsp", O_WRONLY | O_NONBLOCK, 0)) < 0) + goto finish_errno; - if ((mode = fcntl(out->pcm, F_GETFL)) < 0) - goto finish_errno; + if ((mode = fcntl(out->pcm, F_GETFL)) < 0) + goto finish_errno; - mode &= ~O_NONBLOCK; + mode &= ~O_NONBLOCK; - if (fcntl(out->pcm, F_SETFL, mode) < 0) - goto finish_errno; + if (fcntl(out->pcm, F_SETFL, mode) < 0) + goto finish_errno; - switch (ca_sound_file_get_sample_type(out->file)) { + switch (ca_sound_file_get_sample_type(out->file)) { case CA_SAMPLE_U8: - val = AFMT_U8; - break; + val = AFMT_U8; + break; case CA_SAMPLE_S16NE: - val = AFMT_S16_NE; - break; + val = AFMT_S16_NE; + break; case CA_SAMPLE_S16RE: #if __BYTE_ORDER == __LITTLE_ENDIAN - val = AFMT_S16_BE; + val = AFMT_S16_BE; #else - val = AFMT_S16_LE; + val = AFMT_S16_LE; #endif - break; - } + break; + } - test = val; - if (ioctl(out->pcm, SNDCTL_DSP_SETFMT, &val) < 0) - goto finish_errno; + test = val; + if (ioctl(out->pcm, SNDCTL_DSP_SETFMT, &val) < 0) + goto finish_errno; - if (val != test) { - ret = CA_ERROR_NOTSUPPORTED; - goto finish_ret; - } + if (val != test) { + ret = CA_ERROR_NOTSUPPORTED; + goto finish_ret; + } - test = val = (int) ca_sound_file_get_nchannels(out->file); - if (ioctl(out->pcm, SNDCTL_DSP_CHANNELS, &val) < 0) - goto finish_errno; + test = val = (int) ca_sound_file_get_nchannels(out->file); + if (ioctl(out->pcm, SNDCTL_DSP_CHANNELS, &val) < 0) + goto finish_errno; - if (val != test) { - ret = CA_ERROR_NOTSUPPORTED; - goto finish_ret; - } + if (val != test) { + ret = CA_ERROR_NOTSUPPORTED; + goto finish_ret; + } - test = val = (int) ca_sound_file_get_rate(out->file); - if (ioctl(out->pcm, SNDCTL_DSP_SPEED, &val) < 0) - goto finish_errno; + test = val = (int) ca_sound_file_get_rate(out->file); + if (ioctl(out->pcm, SNDCTL_DSP_SPEED, &val) < 0) + goto finish_errno; - /* Check to make sure the configured rate is close enough to the - * requested rate. */ - if (fabs((double) (val - test)) > test * 0.05) { - ret = CA_ERROR_NOTSUPPORTED; - goto finish_ret; - } + /* Check to make sure the configured rate is close enough to the + * requested rate. */ + if (fabs((double) (val - test)) > test * 0.05) { + ret = CA_ERROR_NOTSUPPORTED; + goto finish_ret; + } - return CA_SUCCESS; + return CA_SUCCESS; finish_errno: - return translate_error(errno); + return translate_error(errno); finish_ret: - return ret; + return ret; } #define BUFSIZE (4*1024) static void* thread_func(void *userdata) { - struct outstanding *out = userdata; - int ret; - void *data, *d = NULL; - size_t fs, data_size; - size_t nbytes = 0; - struct pollfd pfd[2]; - nfds_t n_pfd = 2; - struct private *p; - - p = PRIVATE(out->context); - - pthread_detach(pthread_self()); - - fs = ca_sound_file_frame_size(out->file); - data_size = (BUFSIZE/fs)*fs; - - if (!(data = ca_malloc(data_size))) { - ret = CA_ERROR_OOM; - goto finish; - } - - pfd[0].fd = out->pipe_fd[0]; - pfd[0].events = POLLIN; - pfd[0].revents = 0; - pfd[1].fd = out->pcm; - pfd[1].events = POLLOUT; - pfd[1].revents = 0; - - for (;;) { - ssize_t bytes_written; - - if (out->dead) - break; - - if (poll(pfd, n_pfd, -1) < 0) { - ret = CA_ERROR_SYSTEM; - goto finish; - } + struct outstanding *out = userdata; + int ret; + void *data, *d = NULL; + size_t fs, data_size; + size_t nbytes = 0; + struct pollfd pfd[2]; + nfds_t n_pfd = 2; + struct private *p; - /* We have been asked to shut down */ - if (pfd[0].revents) - break; + p = PRIVATE(out->context); - if (pfd[1].revents != POLLOUT) { - ret = CA_ERROR_IO; - goto finish; - } + pthread_detach(pthread_self()); - if (nbytes <= 0) { - nbytes = data_size; + fs = ca_sound_file_frame_size(out->file); + data_size = (BUFSIZE/fs)*fs; - if ((ret = ca_sound_file_read_arbitrary(out->file, data, &nbytes)) < 0) + if (!(data = ca_malloc(data_size))) { + ret = CA_ERROR_OOM; goto finish; - - d = data; } - if (nbytes <= 0) - break; + pfd[0].fd = out->pipe_fd[0]; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + pfd[1].fd = out->pcm; + pfd[1].events = POLLOUT; + pfd[1].revents = 0; - if ((bytes_written = write(out->pcm, d, nbytes)) <= 0) { - ret = translate_error(errno); - goto finish; - } + for (;;) { + ssize_t bytes_written; + + if (out->dead) + break; + + if (poll(pfd, n_pfd, -1) < 0) { + ret = CA_ERROR_SYSTEM; + goto finish; + } + + /* We have been asked to shut down */ + if (pfd[0].revents) + break; + + if (pfd[1].revents != POLLOUT) { + ret = CA_ERROR_IO; + goto finish; + } + + if (nbytes <= 0) { + nbytes = data_size; + + if ((ret = ca_sound_file_read_arbitrary(out->file, data, &nbytes)) < 0) + goto finish; + + d = data; + } + + if (nbytes <= 0) + break; - nbytes -= (size_t) bytes_written; - d = (uint8_t*) d + (size_t) bytes_written; - } + if ((bytes_written = write(out->pcm, d, nbytes)) <= 0) { + ret = translate_error(errno); + goto finish; + } - ret = CA_SUCCESS; + nbytes -= (size_t) bytes_written; + d = (uint8_t*) d + (size_t) bytes_written; + } + + ret = CA_SUCCESS; finish: - ca_free(data); + ca_free(data); - if (!out->dead) - if (out->callback) - out->callback(out->context, out->id, ret, out->userdata); + if (!out->dead) + if (out->callback) + out->callback(out->context, out->id, ret, out->userdata); - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - if (!p->outstanding && p->signal_semaphore) - sem_post(&p->semaphore); + if (!p->outstanding && p->signal_semaphore) + sem_post(&p->semaphore); - outstanding_free(out); + outstanding_free(out); - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return NULL; + return NULL; } int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { - struct private *p; - struct outstanding *out = NULL; - int ret; - pthread_t thread; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - - p = PRIVATE(c); + struct private *p; + struct outstanding *out = NULL; + int ret; + pthread_t thread; - if (!(out = ca_new0(struct outstanding, 1))) { - ret = CA_ERROR_OOM; - goto finish; - } + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - out->context = c; - out->id = id; - out->callback = cb; - out->userdata = userdata; - out->pipe_fd[0] = out->pipe_fd[1] = -1; - out->pcm = -1; + p = PRIVATE(c); - if (pipe(out->pipe_fd) < 0) { - ret = CA_ERROR_SYSTEM; - goto finish; - } + if (!(out = ca_new0(struct outstanding, 1))) { + ret = CA_ERROR_OOM; + goto finish; + } - if ((ret = ca_lookup_sound(&out->file, NULL, &p->theme, c->props, proplist)) < 0) - goto finish; + out->context = c; + out->id = id; + out->callback = cb; + out->userdata = userdata; + out->pipe_fd[0] = out->pipe_fd[1] = -1; + out->pcm = -1; - if ((ret = open_oss(c, out)) < 0) - goto finish; + if (pipe(out->pipe_fd) < 0) { + ret = CA_ERROR_SYSTEM; + goto finish; + } - /* OK, we're ready to go, so let's add this to our list */ - ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + if ((ret = ca_lookup_sound(&out->file, NULL, &p->theme, c->props, proplist)) < 0) + goto finish; - if (pthread_create(&thread, NULL, thread_func, out) < 0) { - ret = CA_ERROR_OOM; + if ((ret = open_oss(c, out)) < 0) + goto finish; + /* OK, we're ready to go, so let's add this to our list */ ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); ca_mutex_unlock(p->outstanding_mutex); - goto finish; - } + if (pthread_create(&thread, NULL, thread_func, out) < 0) { + ret = CA_ERROR_OOM; - ret = CA_SUCCESS; + ca_mutex_lock(p->outstanding_mutex); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); + + goto finish; + } + + ret = CA_SUCCESS; finish: - /* We keep the outstanding struct around if we need clean up later to */ - if (ret != CA_SUCCESS) - outstanding_free(out); + /* We keep the outstanding struct around if we need clean up later to */ + if (ret != CA_SUCCESS) + outstanding_free(out); - return ret; + return ret; } int driver_cancel(ca_context *c, uint32_t id) { - struct private *p; - struct outstanding *out; + 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(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = out->next) { + for (out = p->outstanding; out; out = out->next) { - if (out->id != id) - continue; + if (out->id != id) + continue; - if (out->dead) - continue; + if (out->dead) + continue; - out->dead = TRUE; + out->dead = TRUE; - if (out->callback) - out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); - /* This will cause the thread to wakeup and terminate */ - if (out->pipe_fd[1] >= 0) { - close(out->pipe_fd[1]); - out->pipe_fd[1] = -1; + /* This will cause the thread to wakeup and terminate */ + if (out->pipe_fd[1] >= 0) { + close(out->pipe_fd[1]); + out->pipe_fd[1] = -1; + } } - } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; } int driver_playing(ca_context *c, uint32_t id, int *playing) { - struct private *p; - struct outstanding *out; + 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); + 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); + p = PRIVATE(c); - *playing = 0; + *playing = 0; - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = out->next) { + for (out = p->outstanding; out; out = out->next) { - if (out->dead || - out->id != id) - continue; + if (out->dead || + out->id != id) + continue; - *playing = 1; - break; - } + *playing = 1; + break; + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; } diff --git a/src/proplist.c b/src/proplist.c index 6c4b9dc..d8170d9 100644 --- a/src/proplist.c +++ b/src/proplist.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -30,12 +32,12 @@ #include "malloc.h" static unsigned calc_hash(const char *c) { - unsigned hash = 0; + unsigned hash = 0; - for (; *c; c++) - hash = 31 * hash + (unsigned) *c; + for (; *c; c++) + hash = 31 * hash + (unsigned) *c; - return hash; + return hash; } /** @@ -47,55 +49,55 @@ static unsigned calc_hash(const char *c) { * Returns: 0 on success, negative error code on error. */ int ca_proplist_create(ca_proplist **_p) { - ca_proplist *p; - ca_return_val_if_fail(_p, CA_ERROR_INVALID); + ca_proplist *p; + ca_return_val_if_fail(_p, CA_ERROR_INVALID); - if (!(p = ca_new0(ca_proplist, 1))) - return CA_ERROR_OOM; + if (!(p = ca_new0(ca_proplist, 1))) + return CA_ERROR_OOM; - if (!(p->mutex = ca_mutex_new())) { - ca_free(p); - return CA_ERROR_OOM; - } + if (!(p->mutex = ca_mutex_new())) { + ca_free(p); + return CA_ERROR_OOM; + } - *_p = p; + *_p = p; - return CA_SUCCESS; + return CA_SUCCESS; } static int _unset(ca_proplist *p, const char *key) { - ca_prop *prop, *nprop; - unsigned i; + ca_prop *prop, *nprop; + unsigned i; - ca_return_val_if_fail(p, CA_ERROR_INVALID); - ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); - i = calc_hash(key) % N_HASHTABLE; + i = calc_hash(key) % N_HASHTABLE; - nprop = NULL; - for (prop = p->prop_hashtable[i]; prop; nprop = prop, prop = prop->next_in_slot) - if (strcmp(prop->key, key) == 0) - break; + nprop = NULL; + for (prop = p->prop_hashtable[i]; prop; nprop = prop, prop = prop->next_in_slot) + if (strcmp(prop->key, key) == 0) + break; - if (prop) { - if (nprop) - nprop->next_in_slot = prop->next_in_slot; - else - p->prop_hashtable[i] = prop->next_in_slot; + if (prop) { + if (nprop) + nprop->next_in_slot = prop->next_in_slot; + else + p->prop_hashtable[i] = prop->next_in_slot; - if (prop->prev_item) - prop->prev_item->next_item = prop->next_item; - else - p->first_item = prop->next_item; + if (prop->prev_item) + prop->prev_item->next_item = prop->next_item; + else + p->first_item = prop->next_item; - if (prop->next_item) - prop->next_item->prev_item = prop->prev_item; + if (prop->next_item) + prop->next_item->prev_item = prop->prev_item; - ca_free(prop->key); - ca_free(prop); - } + ca_free(prop->key); + ca_free(prop); + } - return CA_SUCCESS; + return CA_SUCCESS; } /** @@ -110,11 +112,11 @@ static int _unset(ca_proplist *p, const char *key) { */ int ca_proplist_sets(ca_proplist *p, const char *key, const char *value) { - ca_return_val_if_fail(p, CA_ERROR_INVALID); - ca_return_val_if_fail(key, CA_ERROR_INVALID); - ca_return_val_if_fail(value, CA_ERROR_INVALID); + ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(value, CA_ERROR_INVALID); - return ca_proplist_set(p, key, value, strlen(value)+1); + return ca_proplist_set(p, key, value, strlen(value)+1); } /** @@ -132,73 +134,73 @@ int ca_proplist_sets(ca_proplist *p, const char *key, const char *value) { */ int ca_proplist_setf(ca_proplist *p, const char *key, const char *format, ...) { - int ret; - char *k; - ca_prop *prop; - size_t size = 100; - unsigned h; - - ca_return_val_if_fail(p, CA_ERROR_INVALID); - ca_return_val_if_fail(key, CA_ERROR_INVALID); - ca_return_val_if_fail(format, CA_ERROR_INVALID); - - if (!(k = ca_strdup(key))) - return CA_ERROR_OOM; - - for (;;) { - va_list ap; - int r; - - if (!(prop = ca_malloc(CA_ALIGN(sizeof(ca_prop)) + size))) { - ca_free(k); - return CA_ERROR_OOM; - } + int ret; + char *k; + ca_prop *prop; + size_t size = 100; + unsigned h; + ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(format, CA_ERROR_INVALID); - va_start(ap, format); - r = vsnprintf(CA_PROP_DATA(prop), size, format, ap); - va_end(ap); + if (!(k = ca_strdup(key))) + return CA_ERROR_OOM; - ((char*) CA_PROP_DATA(prop))[size-1] = 0; + for (;;) { + va_list ap; + int r; + + if (!(prop = ca_malloc(CA_ALIGN(sizeof(ca_prop)) + size))) { + ca_free(k); + return CA_ERROR_OOM; + } - if (r > -1 && (size_t) r < size) { - prop->nbytes = (size_t) r+1; - break; - } - if (r > -1) /* glibc 2.1 */ - size = (size_t) r+1; - else /* glibc 2.0 */ - size *= 2; + va_start(ap, format); + r = vsnprintf(CA_PROP_DATA(prop), size, format, ap); + va_end(ap); - ca_free(prop); - } + ((char*) CA_PROP_DATA(prop))[size-1] = 0; - prop->key = k; + if (r > -1 && (size_t) r < size) { + prop->nbytes = (size_t) r+1; + break; + } - ca_mutex_lock(p->mutex); + if (r > -1) /* glibc 2.1 */ + size = (size_t) r+1; + else /* glibc 2.0 */ + size *= 2; - if ((ret = _unset(p, key)) < 0) { - ca_free(prop); - ca_free(k); - goto finish; - } + ca_free(prop); + } + + prop->key = k; - h = calc_hash(key) % N_HASHTABLE; + ca_mutex_lock(p->mutex); + + if ((ret = _unset(p, key)) < 0) { + ca_free(prop); + ca_free(k); + goto finish; + } - prop->next_in_slot = p->prop_hashtable[h]; - p->prop_hashtable[h] = prop; + h = calc_hash(key) % N_HASHTABLE; - prop->prev_item = NULL; - if ((prop->next_item = p->first_item)) - prop->next_item->prev_item = prop; - p->first_item = prop; + prop->next_in_slot = p->prop_hashtable[h]; + p->prop_hashtable[h] = prop; + + prop->prev_item = NULL; + if ((prop->next_item = p->first_item)) + prop->next_item->prev_item = prop; + p->first_item = prop; finish: - ca_mutex_unlock(p->mutex); + ca_mutex_unlock(p->mutex); - return ret; + return ret; } /** @@ -214,83 +216,83 @@ finish: */ int ca_proplist_set(ca_proplist *p, const char *key, const void *data, size_t nbytes) { - int ret; - char *k; - ca_prop *prop; - unsigned h; + int ret; + char *k; + ca_prop *prop; + unsigned h; - ca_return_val_if_fail(p, CA_ERROR_INVALID); - ca_return_val_if_fail(key, CA_ERROR_INVALID); - ca_return_val_if_fail(!nbytes || data, CA_ERROR_INVALID); + ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(key, CA_ERROR_INVALID); + ca_return_val_if_fail(!nbytes || data, CA_ERROR_INVALID); - if (!(k = ca_strdup(key))) - return CA_ERROR_OOM; + if (!(k = ca_strdup(key))) + return CA_ERROR_OOM; - if (!(prop = ca_malloc(CA_ALIGN(sizeof(ca_prop)) + nbytes))) { - ca_free(k); - return CA_ERROR_OOM; - } + if (!(prop = ca_malloc(CA_ALIGN(sizeof(ca_prop)) + nbytes))) { + ca_free(k); + return CA_ERROR_OOM; + } - prop->key = k; - prop->nbytes = nbytes; - memcpy(CA_PROP_DATA(prop), data, nbytes); + prop->key = k; + prop->nbytes = nbytes; + memcpy(CA_PROP_DATA(prop), data, nbytes); - ca_mutex_lock(p->mutex); + ca_mutex_lock(p->mutex); - if ((ret = _unset(p, key)) < 0) { - ca_free(prop); - ca_free(k); - goto finish; - } + if ((ret = _unset(p, key)) < 0) { + ca_free(prop); + ca_free(k); + goto finish; + } - h = calc_hash(key) % N_HASHTABLE; + h = calc_hash(key) % N_HASHTABLE; - prop->next_in_slot = p->prop_hashtable[h]; - p->prop_hashtable[h] = prop; + prop->next_in_slot = p->prop_hashtable[h]; + p->prop_hashtable[h] = prop; - prop->prev_item = NULL; - if ((prop->next_item = p->first_item)) - prop->next_item->prev_item = prop; - p->first_item = prop; + prop->prev_item = NULL; + if ((prop->next_item = p->first_item)) + prop->next_item->prev_item = prop; + p->first_item = prop; finish: - ca_mutex_unlock(p->mutex); + ca_mutex_unlock(p->mutex); - return ret; + return ret; } /* Not exported, not self-locking */ ca_prop* ca_proplist_get_unlocked(ca_proplist *p, const char *key) { - ca_prop *prop; - unsigned i; + ca_prop *prop; + unsigned i; - ca_return_val_if_fail(p, NULL); - ca_return_val_if_fail(key, NULL); + ca_return_val_if_fail(p, NULL); + ca_return_val_if_fail(key, NULL); - i = calc_hash(key) % N_HASHTABLE; + i = calc_hash(key) % N_HASHTABLE; - for (prop = p->prop_hashtable[i]; prop; prop = prop->next_in_slot) - if (strcmp(prop->key, key) == 0) - return prop; + for (prop = p->prop_hashtable[i]; prop; prop = prop->next_in_slot) + if (strcmp(prop->key, key) == 0) + return prop; - return NULL; + return NULL; } /* Not exported, not self-locking */ const char* ca_proplist_gets_unlocked(ca_proplist *p, const char *key) { - ca_prop *prop; + ca_prop *prop; - ca_return_val_if_fail(p, NULL); - ca_return_val_if_fail(key, NULL); + ca_return_val_if_fail(p, NULL); + ca_return_val_if_fail(key, NULL); - if (!(prop = ca_proplist_get_unlocked(p, key))) - return NULL; + if (!(prop = ca_proplist_get_unlocked(p, key))) + return NULL; - if (!memchr(CA_PROP_DATA(prop), 0, prop->nbytes)) - return NULL; + if (!memchr(CA_PROP_DATA(prop), 0, prop->nbytes)) + return NULL; - return CA_PROP_DATA(prop); + return CA_PROP_DATA(prop); } /** @@ -303,114 +305,114 @@ const char* ca_proplist_gets_unlocked(ca_proplist *p, const char *key) { */ int ca_proplist_destroy(ca_proplist *p) { - ca_prop *prop, *nprop; + ca_prop *prop, *nprop; - ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(p, CA_ERROR_INVALID); - for (prop = p->first_item; prop; prop = nprop) { - nprop = prop->next_item; - ca_free(prop->key); - ca_free(prop); - } + for (prop = p->first_item; prop; prop = nprop) { + nprop = prop->next_item; + ca_free(prop->key); + ca_free(prop); + } - ca_mutex_free(p->mutex); + ca_mutex_free(p->mutex); - ca_free(p); + ca_free(p); - return CA_SUCCESS; + return CA_SUCCESS; } static int merge_into(ca_proplist *a, ca_proplist *b) { - int ret = CA_SUCCESS; - ca_prop *prop; + int ret = CA_SUCCESS; + ca_prop *prop; - ca_return_val_if_fail(a, CA_ERROR_INVALID); - ca_return_val_if_fail(b, CA_ERROR_INVALID); + ca_return_val_if_fail(a, CA_ERROR_INVALID); + ca_return_val_if_fail(b, CA_ERROR_INVALID); - ca_mutex_lock(b->mutex); + ca_mutex_lock(b->mutex); - for (prop = b->first_item; prop; prop = prop->next_item) - if ((ret = ca_proplist_set(a, prop->key, CA_PROP_DATA(prop), prop->nbytes)) < 0) - break; + for (prop = b->first_item; prop; prop = prop->next_item) + if ((ret = ca_proplist_set(a, prop->key, CA_PROP_DATA(prop), prop->nbytes)) < 0) + break; - ca_mutex_unlock(b->mutex); + ca_mutex_unlock(b->mutex); - return ret; + return ret; } int ca_proplist_merge(ca_proplist **_a, ca_proplist *b, ca_proplist *c) { - ca_proplist *a; - int ret; + ca_proplist *a; + int ret; - ca_return_val_if_fail(_a, CA_ERROR_INVALID); - ca_return_val_if_fail(b, CA_ERROR_INVALID); - ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(_a, CA_ERROR_INVALID); + ca_return_val_if_fail(b, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - if ((ret = ca_proplist_create(&a)) < 0) - return ret; + if ((ret = ca_proplist_create(&a)) < 0) + return ret; - if ((ret = merge_into(a, b)) < 0 || - (ret = merge_into(a, c)) < 0) { - ca_proplist_destroy(a); - return ret; - } + if ((ret = merge_into(a, b)) < 0 || + (ret = merge_into(a, c)) < 0) { + ca_proplist_destroy(a); + return ret; + } - *_a = a; - return CA_SUCCESS; + *_a = a; + return CA_SUCCESS; } ca_bool_t ca_proplist_contains(ca_proplist *p, const char *key) { - ca_bool_t b; + ca_bool_t b; - ca_return_val_if_fail(p, FALSE); - ca_return_val_if_fail(key, FALSE); + ca_return_val_if_fail(p, FALSE); + ca_return_val_if_fail(key, FALSE); - ca_mutex_lock(p->mutex); - b = !!ca_proplist_get_unlocked(p, key); - ca_mutex_unlock(p->mutex); + ca_mutex_lock(p->mutex); + b = !!ca_proplist_get_unlocked(p, key); + ca_mutex_unlock(p->mutex); - return b; + return b; } int ca_proplist_merge_ap(ca_proplist *p, va_list ap) { - int ret; + int ret; - ca_return_val_if_fail(p, CA_ERROR_INVALID); + ca_return_val_if_fail(p, CA_ERROR_INVALID); - for (;;) { - const char *key, *value; + for (;;) { + const char *key, *value; - if (!(key = va_arg(ap, const char*))) - break; + if (!(key = va_arg(ap, const char*))) + break; - if (!(value = va_arg(ap, const char*))) - return CA_ERROR_INVALID; + if (!(value = va_arg(ap, const char*))) + return CA_ERROR_INVALID; - if ((ret = ca_proplist_sets(p, key, value)) < 0) - return ret; - } + if ((ret = ca_proplist_sets(p, key, value)) < 0) + return ret; + } - return CA_SUCCESS; + return CA_SUCCESS; } int ca_proplist_from_ap(ca_proplist **_p, va_list ap) { - int ret; - ca_proplist *p; + int ret; + ca_proplist *p; - ca_return_val_if_fail(_p, CA_ERROR_INVALID); + ca_return_val_if_fail(_p, CA_ERROR_INVALID); - if ((ret = ca_proplist_create(&p)) < 0) - return ret; + if ((ret = ca_proplist_create(&p)) < 0) + return ret; - if ((ret = ca_proplist_merge_ap(p, ap)) < 0) - goto fail; + if ((ret = ca_proplist_merge_ap(p, ap)) < 0) + goto fail; - *_p = p; + *_p = p; - return CA_SUCCESS; + return CA_SUCCESS; fail: - ca_assert_se(ca_proplist_destroy(p) == CA_SUCCESS); + ca_assert_se(ca_proplist_destroy(p) == CA_SUCCESS); - return ret; + return ret; } diff --git a/src/proplist.h b/src/proplist.h index 1359e2b..f48ab22 100644 --- a/src/proplist.h +++ b/src/proplist.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberraproplisthfoo #define foocanberraproplisthfoo @@ -29,18 +31,18 @@ #define N_HASHTABLE 31 typedef struct ca_prop { - char *key; - size_t nbytes; - struct ca_prop *next_in_slot, *next_item, *prev_item; + char *key; + size_t nbytes; + struct ca_prop *next_in_slot, *next_item, *prev_item; } ca_prop; #define CA_PROP_DATA(p) ((void*) ((char*) (p) + CA_ALIGN(sizeof(ca_prop)))) struct ca_proplist { - ca_mutex *mutex; + ca_mutex *mutex; - ca_prop *prop_hashtable[N_HASHTABLE]; - ca_prop *first_item; + ca_prop *prop_hashtable[N_HASHTABLE]; + ca_prop *first_item; }; int ca_proplist_merge(ca_proplist **_a, ca_proplist *b, ca_proplist *c); diff --git a/src/pulse.c b/src/pulse.c index 4d0d428..540d968 100644 --- a/src/pulse.c +++ b/src/pulse.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -45,36 +47,36 @@ #include "malloc.h" enum outstanding_type { - OUTSTANDING_SAMPLE, - OUTSTANDING_STREAM, - OUTSTANDING_UPLOAD + OUTSTANDING_SAMPLE, + OUTSTANDING_STREAM, + OUTSTANDING_UPLOAD }; struct outstanding { - CA_LLIST_FIELDS(struct outstanding); - enum outstanding_type type; - ca_context *context; - uint32_t id; - uint32_t sink_input; - pa_stream *stream; - pa_operation *drain_operation; - ca_finish_callback_t callback; - void *userdata; - ca_sound_file *file; - int error; - unsigned clean_up:1; /* Handler needs to clean up the outstanding struct */ - unsigned finished:1; /* finished playing */ + CA_LLIST_FIELDS(struct outstanding); + enum outstanding_type type; + ca_context *context; + uint32_t id; + uint32_t sink_input; + pa_stream *stream; + pa_operation *drain_operation; + ca_finish_callback_t callback; + void *userdata; + ca_sound_file *file; + int error; + unsigned clean_up:1; /* Handler needs to clean up the outstanding struct */ + unsigned finished:1; /* finished playing */ }; struct private { - pa_threaded_mainloop *mainloop; - pa_context *context; - ca_theme_data *theme; - ca_bool_t subscribed; - ca_bool_t reconnect; - - ca_mutex *outstanding_mutex; - CA_LLIST_HEAD(struct outstanding, outstanding); + pa_threaded_mainloop *mainloop; + pa_context *context; + ca_theme_data *theme; + ca_bool_t subscribed; + ca_bool_t reconnect; + + ca_mutex *outstanding_mutex; + CA_LLIST_HEAD(struct outstanding, outstanding); }; #define PRIVATE(c) ((struct private *) ((c)->private)) @@ -83,1257 +85,1257 @@ static void context_state_cb(pa_context *pc, void *userdata); static void context_subscribe_cb(pa_context *pc, pa_subscription_event_type_t t, uint32_t idx, void *userdata); static void outstanding_disconnect(struct outstanding *o) { - ca_assert(o); + ca_assert(o); - if (o->stream) { - if (o->drain_operation) { - pa_operation_cancel(o->drain_operation); - pa_operation_unref(o->drain_operation); - o->drain_operation = NULL; - } + if (o->stream) { + if (o->drain_operation) { + pa_operation_cancel(o->drain_operation); + pa_operation_unref(o->drain_operation); + o->drain_operation = NULL; + } - pa_stream_set_write_callback(o->stream, NULL, NULL); - pa_stream_set_state_callback(o->stream, NULL, NULL); - pa_stream_disconnect(o->stream); - pa_stream_unref(o->stream); - o->stream = NULL; - } + pa_stream_set_write_callback(o->stream, NULL, NULL); + pa_stream_set_state_callback(o->stream, NULL, NULL); + pa_stream_disconnect(o->stream); + pa_stream_unref(o->stream); + o->stream = NULL; + } } static void outstanding_free(struct outstanding *o) { - ca_assert(o); + ca_assert(o); - outstanding_disconnect(o); + outstanding_disconnect(o); - if (o->file) - ca_sound_file_close(o->file); + if (o->file) + ca_sound_file_close(o->file); - ca_free(o); + ca_free(o); } static int convert_proplist(pa_proplist **_l, ca_proplist *c) { - pa_proplist *l; - ca_prop *i; + pa_proplist *l; + ca_prop *i; - ca_return_val_if_fail(_l, CA_ERROR_INVALID); - ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(_l, CA_ERROR_INVALID); + ca_return_val_if_fail(c, CA_ERROR_INVALID); - if (!(l = pa_proplist_new())) - return CA_ERROR_OOM; + if (!(l = pa_proplist_new())) + return CA_ERROR_OOM; - ca_mutex_lock(c->mutex); + ca_mutex_lock(c->mutex); - for (i = c->first_item; i; i = i->next_item) - if (pa_proplist_set(l, i->key, CA_PROP_DATA(i), i->nbytes) < 0) { - ca_mutex_unlock(c->mutex); - pa_proplist_free(l); - return CA_ERROR_INVALID; - } + for (i = c->first_item; i; i = i->next_item) + if (pa_proplist_set(l, i->key, CA_PROP_DATA(i), i->nbytes) < 0) { + ca_mutex_unlock(c->mutex); + pa_proplist_free(l); + return CA_ERROR_INVALID; + } - ca_mutex_unlock(c->mutex); + ca_mutex_unlock(c->mutex); - *_l = l; + *_l = l; - return CA_SUCCESS; + return CA_SUCCESS; } static pa_proplist *strip_prefix(pa_proplist *l, const char *prefix) { - const char *key; - void *state = NULL; - ca_assert(l); + const char *key; + void *state = NULL; + ca_assert(l); - while ((key = pa_proplist_iterate(l, &state))) - if (strncmp(key, prefix, strlen(prefix)) == 0) - pa_proplist_unset(l, key); + while ((key = pa_proplist_iterate(l, &state))) + if (strncmp(key, prefix, strlen(prefix)) == 0) + pa_proplist_unset(l, key); - return l; + return l; } static void add_common(pa_proplist *l) { - ca_assert(l); + ca_assert(l); - if (!pa_proplist_contains(l, CA_PROP_MEDIA_ROLE)) - pa_proplist_sets(l, CA_PROP_MEDIA_ROLE, "event"); + if (!pa_proplist_contains(l, CA_PROP_MEDIA_ROLE)) + pa_proplist_sets(l, CA_PROP_MEDIA_ROLE, "event"); - if (!pa_proplist_contains(l, CA_PROP_MEDIA_NAME)) { - const char *t; + if (!pa_proplist_contains(l, CA_PROP_MEDIA_NAME)) { + const char *t; - if ((t = pa_proplist_gets(l, CA_PROP_EVENT_ID))) - pa_proplist_sets(l, CA_PROP_MEDIA_NAME, t); - else if ((t = pa_proplist_gets(l, CA_PROP_MEDIA_FILENAME))) - pa_proplist_sets(l, CA_PROP_MEDIA_NAME, t); - } + if ((t = pa_proplist_gets(l, CA_PROP_EVENT_ID))) + pa_proplist_sets(l, CA_PROP_MEDIA_NAME, t); + else if ((t = pa_proplist_gets(l, CA_PROP_MEDIA_FILENAME))) + pa_proplist_sets(l, CA_PROP_MEDIA_NAME, t); + } } static int translate_error(int error) { - static const int table[PA_ERR_MAX] = { - [PA_OK] = CA_SUCCESS, - [PA_ERR_ACCESS] = CA_ERROR_ACCESS, - [PA_ERR_COMMAND] = CA_ERROR_IO, - [PA_ERR_INVALID] = CA_ERROR_INVALID, - [PA_ERR_EXIST] = CA_ERROR_IO, - [PA_ERR_NOENTITY] = CA_ERROR_NOTFOUND, - [PA_ERR_CONNECTIONREFUSED] = CA_ERROR_NOTAVAILABLE, - [PA_ERR_PROTOCOL] = CA_ERROR_IO, - [PA_ERR_TIMEOUT] = CA_ERROR_IO, - [PA_ERR_AUTHKEY] = CA_ERROR_ACCESS, - [PA_ERR_INTERNAL] = CA_ERROR_IO, - [PA_ERR_CONNECTIONTERMINATED] = CA_ERROR_IO, - [PA_ERR_KILLED] = CA_ERROR_DESTROYED, - [PA_ERR_INVALIDSERVER] = CA_ERROR_INVALID, - [PA_ERR_MODINITFAILED] = CA_ERROR_NODRIVER, - [PA_ERR_BADSTATE] = CA_ERROR_STATE, - [PA_ERR_NODATA] = CA_ERROR_IO, - [PA_ERR_VERSION] = CA_ERROR_NOTSUPPORTED, - [PA_ERR_TOOLARGE] = CA_ERROR_TOOBIG, + static const int table[PA_ERR_MAX] = { + [PA_OK] = CA_SUCCESS, + [PA_ERR_ACCESS] = CA_ERROR_ACCESS, + [PA_ERR_COMMAND] = CA_ERROR_IO, + [PA_ERR_INVALID] = CA_ERROR_INVALID, + [PA_ERR_EXIST] = CA_ERROR_IO, + [PA_ERR_NOENTITY] = CA_ERROR_NOTFOUND, + [PA_ERR_CONNECTIONREFUSED] = CA_ERROR_NOTAVAILABLE, + [PA_ERR_PROTOCOL] = CA_ERROR_IO, + [PA_ERR_TIMEOUT] = CA_ERROR_IO, + [PA_ERR_AUTHKEY] = CA_ERROR_ACCESS, + [PA_ERR_INTERNAL] = CA_ERROR_IO, + [PA_ERR_CONNECTIONTERMINATED] = CA_ERROR_IO, + [PA_ERR_KILLED] = CA_ERROR_DESTROYED, + [PA_ERR_INVALIDSERVER] = CA_ERROR_INVALID, + [PA_ERR_MODINITFAILED] = CA_ERROR_NODRIVER, + [PA_ERR_BADSTATE] = CA_ERROR_STATE, + [PA_ERR_NODATA] = CA_ERROR_IO, + [PA_ERR_VERSION] = CA_ERROR_NOTSUPPORTED, + [PA_ERR_TOOLARGE] = CA_ERROR_TOOBIG, #ifdef PA_ERR_NOTSUPPORTED - [PA_ERR_NOTSUPPORTED] = CA_ERROR_NOTSUPPORTED, + [PA_ERR_NOTSUPPORTED] = CA_ERROR_NOTSUPPORTED, #endif #ifdef PA_ERR_UNKNOWN - [PA_ERR_UNKNOWN] = CA_ERROR_IO, + [PA_ERR_UNKNOWN] = CA_ERROR_IO, #endif #ifdef PA_ERR_NOEXTENSION - [PA_ERR_NOEXTENSION] = CA_ERROR_NOTSUPPORTED, + [PA_ERR_NOEXTENSION] = CA_ERROR_NOTSUPPORTED, #endif #ifdef PA_ERR_OBSOLETE - [PA_ERR_OBSOLETE] = CA_ERROR_NOTSUPPORTED, + [PA_ERR_OBSOLETE] = CA_ERROR_NOTSUPPORTED, #endif #ifdef PA_ERR_NOTIMPLEMENTED - [PA_ERR_NOTIMPLEMENTED] = CA_ERROR_NOTSUPPORTED + [PA_ERR_NOTIMPLEMENTED] = CA_ERROR_NOTSUPPORTED #endif - }; + }; - ca_assert(error >= 0); + ca_assert(error >= 0); - if (error >= PA_ERR_MAX || !table[error]) - return CA_ERROR_IO; + if (error >= PA_ERR_MAX || !table[error]) + return CA_ERROR_IO; - return table[error]; + return table[error]; } static int context_connect(ca_context *c, ca_bool_t nofail) { - pa_proplist *l; - struct private *p; - int ret; + pa_proplist *l; + struct private *p; + int ret; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(p = c->private, CA_ERROR_STATE); - ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - ca_return_val_if_fail(!p->context, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(p = c->private, CA_ERROR_STATE); + ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); + ca_return_val_if_fail(!p->context, CA_ERROR_STATE); - if ((ret = convert_proplist(&l, c->props)) < 0) - return ret; + if ((ret = convert_proplist(&l, c->props)) < 0) + return ret; + + strip_prefix(l, "canberra."); - strip_prefix(l, "canberra."); + if (!(p->context = pa_context_new_with_proplist(pa_threaded_mainloop_get_api(p->mainloop), "libcanberra", l))) { + pa_proplist_free(l); + return CA_ERROR_OOM; + } - if (!(p->context = pa_context_new_with_proplist(pa_threaded_mainloop_get_api(p->mainloop), "libcanberra", l))) { pa_proplist_free(l); - return CA_ERROR_OOM; - } - pa_proplist_free(l); + pa_context_set_state_callback(p->context, context_state_cb, c); + pa_context_set_subscribe_callback(p->context, context_subscribe_cb, c); - pa_context_set_state_callback(p->context, context_state_cb, c); - pa_context_set_subscribe_callback(p->context, context_subscribe_cb, c); + if (pa_context_connect(p->context, NULL, nofail ? PA_CONTEXT_NOFAIL : 0, NULL) < 0) { + ret = translate_error(p->context ? pa_context_errno(p->context) : PA_ERR_CONNECTIONREFUSED); - if (pa_context_connect(p->context, NULL, nofail ? PA_CONTEXT_NOFAIL : 0, NULL) < 0) { - ret = translate_error(p->context ? pa_context_errno(p->context) : PA_ERR_CONNECTIONREFUSED); + if (p->context) { + pa_context_disconnect(p->context); + pa_context_unref(p->context); + p->context = NULL; + } - if (p->context) { - pa_context_disconnect(p->context); - pa_context_unref(p->context); - p->context = NULL; + return ret; } - return ret; - } - - return CA_SUCCESS; + return CA_SUCCESS; } static void context_state_cb(pa_context *pc, void *userdata) { - ca_context *c = userdata; - pa_context_state_t state; - struct private *p; + ca_context *c = userdata; + pa_context_state_t state; + struct private *p; - ca_assert(pc); - ca_assert(c); + ca_assert(pc); + ca_assert(c); - p = PRIVATE(c); + p = PRIVATE(c); - state = pa_context_get_state(pc); - if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) { - struct outstanding *out; - int ret; + state = pa_context_get_state(pc); + if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) { + struct outstanding *out; + int ret; - if (state == PA_CONTEXT_TERMINATED) - ret = CA_ERROR_DESTROYED; - else - ret = translate_error(pa_context_errno(pc)); + if (state == PA_CONTEXT_TERMINATED) + ret = CA_ERROR_DESTROYED; + else + ret = translate_error(pa_context_errno(pc)); - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - while ((out = p->outstanding)) { + while ((out = p->outstanding)) { - outstanding_disconnect(out); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + outstanding_disconnect(out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - if (out->callback) - out->callback(c, out->id, ret, out->userdata); + if (out->callback) + out->callback(c, out->id, ret, out->userdata); - outstanding_free(out); + outstanding_free(out); - ca_mutex_lock(p->outstanding_mutex); - } + ca_mutex_lock(p->outstanding_mutex); + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - if (state == PA_CONTEXT_FAILED && p->reconnect) { + if (state == PA_CONTEXT_FAILED && p->reconnect) { - if (p->context) { - pa_context_disconnect(p->context); - pa_context_unref(p->context); - p->context = NULL; - } + if (p->context) { + pa_context_disconnect(p->context); + pa_context_unref(p->context); + p->context = NULL; + } - p->subscribed = FALSE; + p->subscribed = FALSE; - /* If we managed to connect once, then let's try to - * reconnect, and pass NOFAIL */ - context_connect(c, TRUE); + /* If we managed to connect once, then let's try to + * reconnect, and pass NOFAIL */ + context_connect(c, TRUE); + } } - } - pa_threaded_mainloop_signal(p->mainloop, FALSE); + pa_threaded_mainloop_signal(p->mainloop, FALSE); } static void context_subscribe_cb(pa_context *pc, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { - struct outstanding *out, *n; - CA_LLIST_HEAD(struct outstanding, l); - ca_context *c = userdata; - struct private *p; + struct outstanding *out, *n; + CA_LLIST_HEAD(struct outstanding, l); + ca_context *c = userdata; + struct private *p; - ca_assert(pc); - ca_assert(c); + ca_assert(pc); + ca_assert(c); - if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE)) - return; + if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE)) + return; - p = PRIVATE(c); + p = PRIVATE(c); - CA_LLIST_HEAD_INIT(struct outstanding, l); + CA_LLIST_HEAD_INIT(struct outstanding, l); - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = n) { - n = out->next; + for (out = p->outstanding; out; out = n) { + n = out->next; - if (!out->clean_up ||out->type != OUTSTANDING_SAMPLE || out->sink_input != idx) - continue; + if (!out->clean_up ||out->type != OUTSTANDING_SAMPLE || out->sink_input != idx) + continue; - outstanding_disconnect(out); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + outstanding_disconnect(out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - CA_LLIST_PREPEND(struct outstanding, l, out); - } + CA_LLIST_PREPEND(struct outstanding, l, out); + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - while (l) { - out = l; + while (l) { + out = l; - CA_LLIST_REMOVE(struct outstanding, l, out); + CA_LLIST_REMOVE(struct outstanding, l, out); - if (out->callback) - out->callback(c, out->id, CA_SUCCESS, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_SUCCESS, out->userdata); - outstanding_free(out); - } + outstanding_free(out); + } } int driver_open(ca_context *c) { - struct private *p; - int ret; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "pulse"), CA_ERROR_NODRIVER); - ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); - - if (!(c->private = p = ca_new0(struct private, 1))) - return CA_ERROR_OOM; - - if (!(p->outstanding_mutex = ca_mutex_new())) { - driver_destroy(c); - return CA_ERROR_OOM; - } - - if (!(p->mainloop = pa_threaded_mainloop_new())) { - driver_destroy(c); - return CA_ERROR_OOM; - } - - /* The initial connection is without NOFAIL, since we want to have - * this call fail cleanly if we cannot connect. */ - if ((ret = context_connect(c, FALSE)) != CA_SUCCESS) { - driver_destroy(c); - return ret; - } + struct private *p; + int ret; - pa_threaded_mainloop_lock(p->mainloop); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(!c->driver || ca_streq(c->driver, "pulse"), CA_ERROR_NODRIVER); + ca_return_val_if_fail(!PRIVATE(c), CA_ERROR_STATE); - if (pa_threaded_mainloop_start(p->mainloop) < 0) { - pa_threaded_mainloop_unlock(p->mainloop); - driver_destroy(c); - return CA_ERROR_OOM; - } + if (!(c->private = p = ca_new0(struct private, 1))) + return CA_ERROR_OOM; - for (;;) { - pa_context_state_t state; + if (!(p->outstanding_mutex = ca_mutex_new())) { + driver_destroy(c); + return CA_ERROR_OOM; + } - if (!p->context) { - ret = translate_error(PA_ERR_CONNECTIONREFUSED); - pa_threaded_mainloop_unlock(p->mainloop); - driver_destroy(c); - return ret; + if (!(p->mainloop = pa_threaded_mainloop_new())) { + driver_destroy(c); + return CA_ERROR_OOM; } - state = pa_context_get_state(p->context); + /* The initial connection is without NOFAIL, since we want to have + * this call fail cleanly if we cannot connect. */ + if ((ret = context_connect(c, FALSE)) != CA_SUCCESS) { + driver_destroy(c); + return ret; + } - if (state == PA_CONTEXT_READY) - break; + pa_threaded_mainloop_lock(p->mainloop); - if (state == PA_CONTEXT_FAILED) { - ret = translate_error(pa_context_errno(p->context)); - pa_threaded_mainloop_unlock(p->mainloop); - driver_destroy(c); - return ret; + if (pa_threaded_mainloop_start(p->mainloop) < 0) { + pa_threaded_mainloop_unlock(p->mainloop); + driver_destroy(c); + return CA_ERROR_OOM; } - ca_assert(state != PA_CONTEXT_TERMINATED); + for (;;) { + pa_context_state_t state; + + if (!p->context) { + ret = translate_error(PA_ERR_CONNECTIONREFUSED); + pa_threaded_mainloop_unlock(p->mainloop); + driver_destroy(c); + return ret; + } + + state = pa_context_get_state(p->context); + + if (state == PA_CONTEXT_READY) + break; - pa_threaded_mainloop_wait(p->mainloop); - } + if (state == PA_CONTEXT_FAILED) { + ret = translate_error(pa_context_errno(p->context)); + pa_threaded_mainloop_unlock(p->mainloop); + driver_destroy(c); + return ret; + } - /* OK, the connection suceeded once, if it dies now try to - * reconnect */ - p->reconnect = TRUE; + ca_assert(state != PA_CONTEXT_TERMINATED); - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_wait(p->mainloop); + } - return CA_SUCCESS; + /* OK, the connection suceeded once, if it dies now try to + * reconnect */ + p->reconnect = TRUE; + + pa_threaded_mainloop_unlock(p->mainloop); + + return CA_SUCCESS; } int driver_destroy(ca_context *c) { - struct private *p; + struct private *p; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - if (p->mainloop) - pa_threaded_mainloop_stop(p->mainloop); + if (p->mainloop) + pa_threaded_mainloop_stop(p->mainloop); - if (p->context) { - pa_context_disconnect(p->context); - pa_context_unref(p->context); - } + if (p->context) { + pa_context_disconnect(p->context); + pa_context_unref(p->context); + } - while (p->outstanding) { - struct outstanding *out = p->outstanding; - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + while (p->outstanding) { + struct outstanding *out = p->outstanding; + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - if (out->callback) - out->callback(c, out->id, CA_ERROR_DESTROYED, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_ERROR_DESTROYED, out->userdata); - outstanding_free(out); - } + outstanding_free(out); + } - if (p->mainloop) - pa_threaded_mainloop_free(p->mainloop); + if (p->mainloop) + pa_threaded_mainloop_free(p->mainloop); - if (p->theme) - ca_theme_data_free(p->theme); + if (p->theme) + ca_theme_data_free(p->theme); - if (p->outstanding_mutex) - ca_mutex_free(p->outstanding_mutex); + if (p->outstanding_mutex) + ca_mutex_free(p->outstanding_mutex); - ca_free(p); + ca_free(p); - c->private = NULL; + c->private = NULL; - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_device(ca_context *c, const char *device) { - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - /* We're happy with any device change. We might however add code - * here eventually to move all currently played back event sounds - * to the new device. */ + /* We're happy with any device change. We might however add code + * here eventually to move all currently played back event sounds + * to the new device. */ - return CA_SUCCESS; + return CA_SUCCESS; } int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) { - struct private *p; - pa_operation *o; - pa_proplist *l; - int ret = CA_SUCCESS; + struct private *p; + pa_operation *o; + pa_proplist *l; + int ret = CA_SUCCESS; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(changed, CA_ERROR_INVALID); - ca_return_val_if_fail(merged, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(changed, CA_ERROR_INVALID); + ca_return_val_if_fail(merged, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); + ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - pa_threaded_mainloop_lock(p->mainloop); + pa_threaded_mainloop_lock(p->mainloop); - if (!p->context) { - pa_threaded_mainloop_unlock(p->mainloop); - return CA_ERROR_STATE; /* can be silently ignored */ - } + if (!p->context) { + pa_threaded_mainloop_unlock(p->mainloop); + return CA_ERROR_STATE; /* can be silently ignored */ + } - if ((ret = convert_proplist(&l, changed)) < 0) - return ret; + if ((ret = convert_proplist(&l, changed)) < 0) + return ret; - strip_prefix(l, "canberra."); + strip_prefix(l, "canberra."); - /* We start these asynchronously and don't care about the return - * value */ + /* We start these asynchronously and don't care about the return + * value */ - if (!(o = pa_context_proplist_update(p->context, PA_UPDATE_REPLACE, l, NULL, NULL))) - ret = translate_error(pa_context_errno(p->context)); - else - pa_operation_unref(o); + if (!(o = pa_context_proplist_update(p->context, PA_UPDATE_REPLACE, l, NULL, NULL))) + ret = translate_error(pa_context_errno(p->context)); + else + pa_operation_unref(o); - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_unlock(p->mainloop); - pa_proplist_free(l); + pa_proplist_free(l); - return ret; + return ret; } static int subscribe(ca_context *c) { - struct private *p; - pa_operation *o; - int ret = CA_SUCCESS; + struct private *p; + pa_operation *o; + int ret = CA_SUCCESS; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + p = PRIVATE(c); - ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); + ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - if (p->subscribed) - return CA_SUCCESS; + if (p->subscribed) + return CA_SUCCESS; - pa_threaded_mainloop_lock(p->mainloop); + pa_threaded_mainloop_lock(p->mainloop); - if (!p->context) { - pa_threaded_mainloop_unlock(p->mainloop); - return CA_ERROR_STATE; - } + if (!p->context) { + pa_threaded_mainloop_unlock(p->mainloop); + return CA_ERROR_STATE; + } - /* We start these asynchronously and don't care about the return - * value */ + /* We start these asynchronously and don't care about the return + * value */ - if (!(o = pa_context_subscribe(p->context, PA_SUBSCRIPTION_MASK_SINK_INPUT, NULL, NULL))) - ret = translate_error(pa_context_errno(p->context)); - else - pa_operation_unref(o); + if (!(o = pa_context_subscribe(p->context, PA_SUBSCRIPTION_MASK_SINK_INPUT, NULL, NULL))) + ret = translate_error(pa_context_errno(p->context)); + else + pa_operation_unref(o); - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_unlock(p->mainloop); - p->subscribed = TRUE; + p->subscribed = TRUE; - return ret; + return ret; } static void play_sample_cb(pa_context *c, uint32_t idx, void *userdata) { - struct private *p; - struct outstanding *out = userdata; + struct private *p; + struct outstanding *out = userdata; - ca_assert(c); - ca_assert(out); + ca_assert(c); + ca_assert(out); - p = PRIVATE(out->context); + p = PRIVATE(out->context); - if (idx != PA_INVALID_INDEX) { - out->error = CA_SUCCESS; - out->sink_input = idx; - } else - out->error = translate_error(pa_context_errno(c)); + if (idx != PA_INVALID_INDEX) { + out->error = CA_SUCCESS; + out->sink_input = idx; + } else + out->error = translate_error(pa_context_errno(c)); - pa_threaded_mainloop_signal(p->mainloop, FALSE); + pa_threaded_mainloop_signal(p->mainloop, FALSE); } static void stream_state_cb(pa_stream *s, void *userdata) { - struct private *p; - struct outstanding *out = userdata; - pa_stream_state_t state; + struct private *p; + struct outstanding *out = userdata; + pa_stream_state_t state; - ca_assert(s); - ca_assert(out); + ca_assert(s); + ca_assert(out); - p = PRIVATE(out->context); + p = PRIVATE(out->context); - state = pa_stream_get_state(s); + state = pa_stream_get_state(s); - switch (state) { + switch (state) { case PA_STREAM_CREATING: case PA_STREAM_UNCONNECTED: - break; + break; case PA_STREAM_READY: - out->sink_input = pa_stream_get_index(out->stream); - break; + out->sink_input = pa_stream_get_index(out->stream); + break; case PA_STREAM_FAILED: case PA_STREAM_TERMINATED: { - int err; + int err; - err = state == PA_STREAM_FAILED ? translate_error(pa_context_errno(pa_stream_get_context(s))) : CA_ERROR_DESTROYED; + err = state == PA_STREAM_FAILED ? translate_error(pa_context_errno(pa_stream_get_context(s))) : CA_ERROR_DESTROYED; - if (out->clean_up) { - ca_mutex_lock(p->outstanding_mutex); - outstanding_disconnect(out); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + if (out->clean_up) { + ca_mutex_lock(p->outstanding_mutex); + outstanding_disconnect(out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); - if (out->callback) - out->callback(out->context, out->id, out->error, out->userdata); + if (out->callback) + out->callback(out->context, out->id, out->error, out->userdata); - outstanding_free(out); - } else { - out->finished = TRUE; - out->error = err; - } + outstanding_free(out); + } else { + out->finished = TRUE; + out->error = err; + } - break; + break; + } } - } - pa_threaded_mainloop_signal(p->mainloop, FALSE); + pa_threaded_mainloop_signal(p->mainloop, FALSE); } static void stream_drain_cb(pa_stream *s, int success, void *userdata) { - struct private *p; - struct outstanding *out = userdata; - int err; + struct private *p; + struct outstanding *out = userdata; + int err; - ca_assert(s); - ca_assert(out); - ca_assert(out->type == OUTSTANDING_STREAM); + ca_assert(s); + ca_assert(out); + ca_assert(out->type == OUTSTANDING_STREAM); - p = PRIVATE(out->context); - err = success ? CA_SUCCESS : translate_error(pa_context_errno(p->context)); + p = PRIVATE(out->context); + err = success ? CA_SUCCESS : translate_error(pa_context_errno(p->context)); - if (out->clean_up) { - ca_mutex_lock(p->outstanding_mutex); - outstanding_disconnect(out); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + if (out->clean_up) { + ca_mutex_lock(p->outstanding_mutex); + outstanding_disconnect(out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); - if (out->callback) - out->callback(out->context, out->id, err, out->userdata); + if (out->callback) + out->callback(out->context, out->id, err, out->userdata); - outstanding_free(out); + outstanding_free(out); - } else { - pa_stream_disconnect(s); - out->error = err; - out->finished = TRUE; - } + } else { + pa_stream_disconnect(s); + out->error = err; + out->finished = TRUE; + } - if (out->drain_operation) { - pa_operation_unref(out->drain_operation); - out->drain_operation = NULL; - } + if (out->drain_operation) { + pa_operation_unref(out->drain_operation); + out->drain_operation = NULL; + } - pa_threaded_mainloop_signal(p->mainloop, FALSE); + pa_threaded_mainloop_signal(p->mainloop, FALSE); } static void stream_write_cb(pa_stream *s, size_t bytes, void *userdata) { - struct outstanding *out = userdata; - struct private *p; - void *data; - int ret; - ca_bool_t eof = FALSE; + struct outstanding *out = userdata; + struct private *p; + void *data; + int ret; + ca_bool_t eof = FALSE; - ca_assert(s); - ca_assert(bytes > 0); - ca_assert(out); + ca_assert(s); + ca_assert(bytes > 0); + ca_assert(out); - p = PRIVATE(out->context); + p = PRIVATE(out->context); - while (bytes > 0) { - size_t rbytes = bytes; + while (bytes > 0) { + size_t rbytes = bytes; - if (!(data = ca_malloc(rbytes))) { - ret = CA_ERROR_OOM; - goto finish; - } + if (!(data = ca_malloc(rbytes))) { + ret = CA_ERROR_OOM; + goto finish; + } - if ((ret = ca_sound_file_read_arbitrary(out->file, data, &rbytes)) < 0) - goto finish; + if ((ret = ca_sound_file_read_arbitrary(out->file, data, &rbytes)) < 0) + goto finish; - if (rbytes <= 0) { - eof = TRUE; - break; - } + if (rbytes <= 0) { + eof = TRUE; + break; + } - ca_assert(rbytes <= bytes); + ca_assert(rbytes <= bytes); - if ((ret = pa_stream_write(s, data, rbytes, ca_free, 0, PA_SEEK_RELATIVE)) < 0) { - ret = translate_error(ret); - goto finish; - } + if ((ret = pa_stream_write(s, data, rbytes, ca_free, 0, PA_SEEK_RELATIVE)) < 0) { + ret = translate_error(ret); + goto finish; + } - data = NULL; + data = NULL; - bytes -= rbytes; - } + bytes -= rbytes; + } - if (eof || ca_sound_file_get_size(out->file) <= 0) { + if (eof || ca_sound_file_get_size(out->file) <= 0) { - /* We reached EOF */ + /* We reached EOF */ - if (out->type == OUTSTANDING_UPLOAD) { + if (out->type == OUTSTANDING_UPLOAD) { - if (pa_stream_finish_upload(s) < 0) { - ret = translate_error(pa_context_errno(p->context)); - goto finish; - } + if (pa_stream_finish_upload(s) < 0) { + ret = translate_error(pa_context_errno(p->context)); + goto finish; + } - /* Let's just signal driver_cache() which has been waiting for us */ - pa_threaded_mainloop_signal(p->mainloop, FALSE); + /* Let's just signal driver_cache() which has been waiting for us */ + pa_threaded_mainloop_signal(p->mainloop, FALSE); - } else { - ca_assert(out->type == OUTSTANDING_STREAM); + } else { + ca_assert(out->type == OUTSTANDING_STREAM); - if (out->drain_operation) { - pa_operation_cancel(out->drain_operation); - pa_operation_unref(out->drain_operation); - } + if (out->drain_operation) { + pa_operation_cancel(out->drain_operation); + pa_operation_unref(out->drain_operation); + } - if (!(out->drain_operation = pa_stream_drain(s, stream_drain_cb, out))) { - ret = translate_error(pa_context_errno(p->context)); - goto finish; - } - } + if (!(out->drain_operation = pa_stream_drain(s, stream_drain_cb, out))) { + ret = translate_error(pa_context_errno(p->context)); + goto finish; + } + } - pa_stream_set_write_callback(s, NULL, NULL); - } + pa_stream_set_write_callback(s, NULL, NULL); + } - ca_free(data); + ca_free(data); - return; + return; finish: - ca_free(data); + ca_free(data); - if (out->clean_up) { - ca_mutex_lock(p->outstanding_mutex); - outstanding_disconnect(out); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); + if (out->clean_up) { + ca_mutex_lock(p->outstanding_mutex); + outstanding_disconnect(out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); - if (out->callback) - out->callback(out->context, out->id, ret, out->userdata); + if (out->callback) + out->callback(out->context, out->id, ret, out->userdata); - outstanding_free(out); + outstanding_free(out); - } else { - pa_stream_disconnect(s); - out->error = ret; - out->finished = TRUE; - } + } else { + pa_stream_disconnect(s); + out->error = ret; + out->finished = TRUE; + } - pa_threaded_mainloop_signal(p->mainloop, FALSE); + pa_threaded_mainloop_signal(p->mainloop, FALSE); } static const pa_sample_format_t sample_type_table[] = { - [CA_SAMPLE_S16NE] = PA_SAMPLE_S16NE, - [CA_SAMPLE_S16RE] = PA_SAMPLE_S16RE, - [CA_SAMPLE_U8] = PA_SAMPLE_U8 + [CA_SAMPLE_S16NE] = PA_SAMPLE_S16NE, + [CA_SAMPLE_S16RE] = PA_SAMPLE_S16RE, + [CA_SAMPLE_U8] = PA_SAMPLE_U8 }; static const pa_channel_position_t channel_table[_CA_CHANNEL_POSITION_MAX] = { - [CA_CHANNEL_MONO] = PA_CHANNEL_POSITION_MONO, - [CA_CHANNEL_FRONT_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT, - [CA_CHANNEL_FRONT_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT, - [CA_CHANNEL_FRONT_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER, - [CA_CHANNEL_REAR_LEFT] = PA_CHANNEL_POSITION_REAR_LEFT, - [CA_CHANNEL_REAR_RIGHT] = PA_CHANNEL_POSITION_REAR_RIGHT, - [CA_CHANNEL_REAR_CENTER] = PA_CHANNEL_POSITION_REAR_CENTER, - [CA_CHANNEL_LFE] = PA_CHANNEL_POSITION_LFE, - [CA_CHANNEL_FRONT_LEFT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, - [CA_CHANNEL_FRONT_RIGHT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, - [CA_CHANNEL_SIDE_LEFT] = PA_CHANNEL_POSITION_SIDE_LEFT, - [CA_CHANNEL_SIDE_RIGHT] = PA_CHANNEL_POSITION_SIDE_RIGHT, - [CA_CHANNEL_TOP_CENTER] = PA_CHANNEL_POSITION_TOP_CENTER, - [CA_CHANNEL_TOP_FRONT_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT, - [CA_CHANNEL_TOP_FRONT_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT, - [CA_CHANNEL_TOP_FRONT_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER, - [CA_CHANNEL_TOP_REAR_LEFT] = PA_CHANNEL_POSITION_REAR_LEFT, - [CA_CHANNEL_TOP_REAR_RIGHT] = PA_CHANNEL_POSITION_REAR_RIGHT, - [CA_CHANNEL_TOP_REAR_CENTER] = PA_CHANNEL_POSITION_TOP_REAR_CENTER + [CA_CHANNEL_MONO] = PA_CHANNEL_POSITION_MONO, + [CA_CHANNEL_FRONT_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT, + [CA_CHANNEL_FRONT_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT, + [CA_CHANNEL_FRONT_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER, + [CA_CHANNEL_REAR_LEFT] = PA_CHANNEL_POSITION_REAR_LEFT, + [CA_CHANNEL_REAR_RIGHT] = PA_CHANNEL_POSITION_REAR_RIGHT, + [CA_CHANNEL_REAR_CENTER] = PA_CHANNEL_POSITION_REAR_CENTER, + [CA_CHANNEL_LFE] = PA_CHANNEL_POSITION_LFE, + [CA_CHANNEL_FRONT_LEFT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + [CA_CHANNEL_FRONT_RIGHT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + [CA_CHANNEL_SIDE_LEFT] = PA_CHANNEL_POSITION_SIDE_LEFT, + [CA_CHANNEL_SIDE_RIGHT] = PA_CHANNEL_POSITION_SIDE_RIGHT, + [CA_CHANNEL_TOP_CENTER] = PA_CHANNEL_POSITION_TOP_CENTER, + [CA_CHANNEL_TOP_FRONT_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT, + [CA_CHANNEL_TOP_FRONT_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT, + [CA_CHANNEL_TOP_FRONT_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER, + [CA_CHANNEL_TOP_REAR_LEFT] = PA_CHANNEL_POSITION_REAR_LEFT, + [CA_CHANNEL_TOP_REAR_RIGHT] = PA_CHANNEL_POSITION_REAR_RIGHT, + [CA_CHANNEL_TOP_REAR_CENTER] = PA_CHANNEL_POSITION_TOP_REAR_CENTER }; static ca_bool_t convert_channel_map(ca_sound_file *f, pa_channel_map *cm) { - const ca_channel_position_t *positions; - unsigned c; + const ca_channel_position_t *positions; + unsigned c; - ca_assert(f); - ca_assert(cm); + ca_assert(f); + ca_assert(cm); - if (!(positions = ca_sound_file_get_channel_map(f))) - return FALSE; + if (!(positions = ca_sound_file_get_channel_map(f))) + return FALSE; - cm->channels = ca_sound_file_get_nchannels(f); - for (c = 0; c < cm->channels; c++) - cm->map[c] = channel_table[positions[c]]; + cm->channels = ca_sound_file_get_nchannels(f); + for (c = 0; c < cm->channels; c++) + cm->map[c] = channel_table[positions[c]]; - return TRUE; + return TRUE; } int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_callback_t cb, void *userdata) { - struct private *p; - pa_proplist *l = NULL; - const char *n, *vol, *ct, *channel; - char *name = NULL; + struct private *p; + pa_proplist *l = NULL; + const char *n, *vol, *ct, *channel; + char *name = NULL; #if defined(PA_MAJOR) && ((PA_MAJOR > 0) || (PA_MAJOR == 0 && PA_MINOR > 9) || (PA_MAJOR == 0 && PA_MINOR == 9 && PA_MICRO >= 15)) - pa_volume_t v = (pa_volume_t) -1; + pa_volume_t v = (pa_volume_t) -1; #else - pa_volume_t v = PA_VOLUME_NORM; + pa_volume_t v = PA_VOLUME_NORM; #endif - ca_bool_t volume_set = FALSE; - pa_cvolume cvol; - pa_sample_spec ss; - pa_channel_map cm; - pa_channel_position_t position = PA_CHANNEL_POSITION_INVALID; - ca_bool_t cm_good; - ca_cache_control_t cache_control = CA_CACHE_CONTROL_NEVER; - struct outstanding *out = NULL; - int try = 3; - int ret; - pa_operation *o; - char *sp; - pa_buffer_attr ba; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - - p = PRIVATE(c); - - ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - - if (!(out = ca_new0(struct outstanding, 1))) { - ret = CA_ERROR_OOM; - goto finish_unlocked; - } - - out->type = OUTSTANDING_SAMPLE; - out->context = c; - out->sink_input = PA_INVALID_INDEX; - out->id = id; - out->callback = cb; - out->userdata = userdata; - - if ((ret = convert_proplist(&l, proplist)) < 0) - goto finish_unlocked; - - if ((n = pa_proplist_gets(l, CA_PROP_EVENT_ID))) - if (!(name = ca_strdup(n))) { - ret = CA_ERROR_OOM; - goto finish_unlocked; - } + ca_bool_t volume_set = FALSE; + pa_cvolume cvol; + pa_sample_spec ss; + pa_channel_map cm; + pa_channel_position_t position = PA_CHANNEL_POSITION_INVALID; + ca_bool_t cm_good; + ca_cache_control_t cache_control = CA_CACHE_CONTROL_NEVER; + struct outstanding *out = NULL; + int try = 3; + int ret; + pa_operation *o; + char *sp; + pa_buffer_attr ba; - if ((vol = pa_proplist_gets(l, CA_PROP_CANBERRA_VOLUME))) { - char *e = NULL; - double dvol; + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(!userdata || cb, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - errno = 0; - dvol = strtod(vol, &e); - if (errno != 0 || !e || *e) { - ret = CA_ERROR_INVALID; - goto finish_unlocked; - } + p = PRIVATE(c); - v = pa_sw_volume_from_dB(dvol); - volume_set = TRUE; - } + ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - if ((ct = pa_proplist_gets(l, CA_PROP_CANBERRA_CACHE_CONTROL))) - if ((ret = ca_parse_cache_control(&cache_control, ct)) < 0) { - ret = CA_ERROR_INVALID; - goto finish_unlocked; + if (!(out = ca_new0(struct outstanding, 1))) { + ret = CA_ERROR_OOM; + goto finish_unlocked; } - if ((channel = pa_proplist_gets(l, CA_PROP_CANBERRA_FORCE_CHANNEL))) { - pa_channel_map t; + out->type = OUTSTANDING_SAMPLE; + out->context = c; + out->sink_input = PA_INVALID_INDEX; + out->id = id; + out->callback = cb; + out->userdata = userdata; + + if ((ret = convert_proplist(&l, proplist)) < 0) + goto finish_unlocked; + + if ((n = pa_proplist_gets(l, CA_PROP_EVENT_ID))) + if (!(name = ca_strdup(n))) { + ret = CA_ERROR_OOM; + goto finish_unlocked; + } + + if ((vol = pa_proplist_gets(l, CA_PROP_CANBERRA_VOLUME))) { + char *e = NULL; + double dvol; + + errno = 0; + dvol = strtod(vol, &e); + if (errno != 0 || !e || *e) { + ret = CA_ERROR_INVALID; + goto finish_unlocked; + } - if (!pa_channel_map_parse(&t, channel) || - t.channels != 1) { - ret = CA_ERROR_INVALID; - goto finish_unlocked; + v = pa_sw_volume_from_dB(dvol); + volume_set = TRUE; } - position = t.map[0]; + if ((ct = pa_proplist_gets(l, CA_PROP_CANBERRA_CACHE_CONTROL))) + if ((ret = ca_parse_cache_control(&cache_control, ct)) < 0) { + ret = CA_ERROR_INVALID; + goto finish_unlocked; + } + + if ((channel = pa_proplist_gets(l, CA_PROP_CANBERRA_FORCE_CHANNEL))) { + pa_channel_map t; + + if (!pa_channel_map_parse(&t, channel) || + t.channels != 1) { + ret = CA_ERROR_INVALID; + goto finish_unlocked; + } + + position = t.map[0]; - /* We cannot remap cached samples, so let's fail when cacheing - * shall be used */ - if (cache_control != CA_CACHE_CONTROL_NEVER) { - ret = CA_ERROR_NOTSUPPORTED; - goto finish_unlocked; + /* We cannot remap cached samples, so let's fail when cacheing + * shall be used */ + if (cache_control != CA_CACHE_CONTROL_NEVER) { + ret = CA_ERROR_NOTSUPPORTED; + goto finish_unlocked; + } } - } - strip_prefix(l, "canberra."); - add_common(l); + strip_prefix(l, "canberra."); + add_common(l); - if ((ret = subscribe(c)) < 0) - goto finish_unlocked; + if ((ret = subscribe(c)) < 0) + goto finish_unlocked; - if (name && cache_control != CA_CACHE_CONTROL_NEVER) { + if (name && cache_control != CA_CACHE_CONTROL_NEVER) { - /* Ok, this sample has an event id, let's try to play it from the cache */ + /* Ok, this sample has an event id, let's try to play it from the cache */ - for (;;) { - ca_bool_t canceled; + for (;;) { + ca_bool_t canceled; - pa_threaded_mainloop_lock(p->mainloop); + pa_threaded_mainloop_lock(p->mainloop); - if (!p->context) { - ret = CA_ERROR_STATE; - goto finish_locked; - } + if (!p->context) { + ret = CA_ERROR_STATE; + goto finish_locked; + } - /* Let's try to play the sample */ - if (!(o = pa_context_play_sample_with_proplist(p->context, name, c->device, v, l, play_sample_cb, out))) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; - } + /* Let's try to play the sample */ + if (!(o = pa_context_play_sample_with_proplist(p->context, name, c->device, v, l, play_sample_cb, out))) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; + } - for (;;) { - pa_operation_state_t state = pa_operation_get_state(o); + for (;;) { + pa_operation_state_t state = pa_operation_get_state(o); - if (state == PA_OPERATION_DONE) { - canceled = FALSE; - break; - } else if (state == PA_OPERATION_CANCELED) { - canceled = TRUE; - break; - } + if (state == PA_OPERATION_DONE) { + canceled = FALSE; + break; + } else if (state == PA_OPERATION_CANCELED) { + canceled = TRUE; + break; + } - pa_threaded_mainloop_wait(p->mainloop); - } + pa_threaded_mainloop_wait(p->mainloop); + } - pa_operation_unref(o); + pa_operation_unref(o); - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_unlock(p->mainloop); - /* The operation might have been canceled due to connection termination */ - if (canceled || !p->context) { - ret = CA_ERROR_DISCONNECTED; - goto finish_unlocked; - } + /* The operation might have been canceled due to connection termination */ + if (canceled || !p->context) { + ret = CA_ERROR_DISCONNECTED; + goto finish_unlocked; + } - /* Did we manage to play the sample or did some other error occur? */ - if (out->error != CA_ERROR_NOTFOUND) { - ret = out->error; - goto finish_unlocked; - } + /* Did we manage to play the sample or did some other error occur? */ + if (out->error != CA_ERROR_NOTFOUND) { + ret = out->error; + goto finish_unlocked; + } - /* Hmm, we need to play it directly */ - if (cache_control != CA_CACHE_CONTROL_PERMANENT) - break; + /* Hmm, we need to play it directly */ + if (cache_control != CA_CACHE_CONTROL_PERMANENT) + break; - /* Don't loop forever */ - if (--try <= 0) - break; + /* Don't loop forever */ + if (--try <= 0) + break; - /* Let's upload the sample and retry playing */ - if ((ret = driver_cache(c, proplist)) < 0) - goto finish_unlocked; + /* Let's upload the sample and retry playing */ + if ((ret = driver_cache(c, proplist)) < 0) + goto finish_unlocked; + } } - } - out->type = OUTSTANDING_STREAM; + out->type = OUTSTANDING_STREAM; - /* Let's stream the sample directly */ - if ((ret = ca_lookup_sound(&out->file, &sp, &p->theme, c->props, proplist)) < 0) - goto finish_unlocked; + /* Let's stream the sample directly */ + if ((ret = ca_lookup_sound(&out->file, &sp, &p->theme, c->props, proplist)) < 0) + goto finish_unlocked; - if (sp) - if (!pa_proplist_contains(l, CA_PROP_MEDIA_FILENAME)) - pa_proplist_sets(l, CA_PROP_MEDIA_FILENAME, sp); + if (sp) + if (!pa_proplist_contains(l, CA_PROP_MEDIA_FILENAME)) + pa_proplist_sets(l, CA_PROP_MEDIA_FILENAME, sp); - ca_free(sp); + ca_free(sp); - ss.format = sample_type_table[ca_sound_file_get_sample_type(out->file)]; - ss.channels = (uint8_t) ca_sound_file_get_nchannels(out->file); - ss.rate = ca_sound_file_get_rate(out->file); + ss.format = sample_type_table[ca_sound_file_get_sample_type(out->file)]; + ss.channels = (uint8_t) ca_sound_file_get_nchannels(out->file); + ss.rate = ca_sound_file_get_rate(out->file); - if (position != PA_CHANNEL_POSITION_INVALID) { - unsigned u; - /* Apply canberra.force_channel */ + if (position != PA_CHANNEL_POSITION_INVALID) { + unsigned u; + /* Apply canberra.force_channel */ - cm.channels = ss.channels; - for (u = 0; u < cm.channels; u++) - cm.map[u] = position; + cm.channels = ss.channels; + for (u = 0; u < cm.channels; u++) + cm.map[u] = position; - cm_good = TRUE; - } else - cm_good = convert_channel_map(out->file, &cm); + cm_good = TRUE; + } else + cm_good = convert_channel_map(out->file, &cm); - if (!name) { - if (!(n = pa_proplist_gets(l, CA_PROP_MEDIA_NAME))) - if (!(n = pa_proplist_gets(l, CA_PROP_MEDIA_NAME))) - n = "libcanberra"; + if (!name) { + if (!(n = pa_proplist_gets(l, CA_PROP_MEDIA_NAME))) + if (!(n = pa_proplist_gets(l, CA_PROP_MEDIA_NAME))) + n = "libcanberra"; - name = ca_strdup(n); - } + name = ca_strdup(n); + } - pa_threaded_mainloop_lock(p->mainloop); + pa_threaded_mainloop_lock(p->mainloop); - if (!p->context) { - ret = CA_ERROR_STATE; - goto finish_locked; - } + if (!p->context) { + ret = CA_ERROR_STATE; + goto finish_locked; + } - if (!(out->stream = pa_stream_new_with_proplist(p->context, name, &ss, cm_good ? &cm : NULL, l))) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; - } + if (!(out->stream = pa_stream_new_with_proplist(p->context, name, &ss, cm_good ? &cm : NULL, l))) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; + } - pa_stream_set_state_callback(out->stream, stream_state_cb, out); - pa_stream_set_write_callback(out->stream, stream_write_cb, out); + pa_stream_set_state_callback(out->stream, stream_state_cb, out); + pa_stream_set_write_callback(out->stream, stream_write_cb, out); - if (volume_set) - pa_cvolume_set(&cvol, ss.channels, v); + if (volume_set) + pa_cvolume_set(&cvol, ss.channels, v); - /* Make sure we get the longest latency possible, to minimize CPU - * consumption */ - ba.maxlength = (uint32_t) -1; - ba.tlength = (uint32_t) -1; - ba.prebuf = (uint32_t) -1; - ba.minreq = (uint32_t) -1; - ba.fragsize = (uint32_t) -1; + /* Make sure we get the longest latency possible, to minimize CPU + * consumption */ + ba.maxlength = (uint32_t) -1; + ba.tlength = (uint32_t) -1; + ba.prebuf = (uint32_t) -1; + ba.minreq = (uint32_t) -1; + ba.fragsize = (uint32_t) -1; - if (pa_stream_connect_playback(out->stream, c->device, &ba, + if (pa_stream_connect_playback(out->stream, c->device, &ba, #ifdef PA_STREAM_FAIL_ON_SUSPEND - PA_STREAM_FAIL_ON_SUSPEND + PA_STREAM_FAIL_ON_SUSPEND #else - 0 + 0 #endif - | (position != PA_CHANNEL_POSITION_INVALID ? PA_STREAM_NO_REMIX_CHANNELS : 0) - , volume_set ? &cvol : NULL, NULL) < 0) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; - } + | (position != PA_CHANNEL_POSITION_INVALID ? PA_STREAM_NO_REMIX_CHANNELS : 0) + , volume_set ? &cvol : NULL, NULL) < 0) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; + } - for (;;) { - pa_stream_state_t state; + for (;;) { + pa_stream_state_t state; - if (!p->context || !out->stream) { - ret = CA_ERROR_STATE; - goto finish_locked; - } + if (!p->context || !out->stream) { + ret = CA_ERROR_STATE; + goto finish_locked; + } - state = pa_stream_get_state(out->stream); + state = pa_stream_get_state(out->stream); - /* Stream sucessfully created */ - if (state == PA_STREAM_READY) - break; + /* Stream sucessfully created */ + if (state == PA_STREAM_READY) + break; - /* Check for failure */ - if (state == PA_STREAM_FAILED) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; - } + /* Check for failure */ + if (state == PA_STREAM_FAILED) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; + } - /* Prematurely ended */ - if (state == PA_STREAM_TERMINATED) { - ret = out->error; - goto finish_locked; - } + /* Prematurely ended */ + if (state == PA_STREAM_TERMINATED) { + ret = out->error; + goto finish_locked; + } - pa_threaded_mainloop_wait(p->mainloop); - } + pa_threaded_mainloop_wait(p->mainloop); + } - ret = CA_SUCCESS; + ret = CA_SUCCESS; finish_locked: - /* We keep the outstanding struct around to clean up later if the sound din't finish yet*/ - if (ret == CA_SUCCESS && !out->finished) { - out->clean_up = TRUE; + /* We keep the outstanding struct around to clean up later if the sound din't finish yet*/ + if (ret == CA_SUCCESS && !out->finished) { + out->clean_up = TRUE; - ca_mutex_lock(p->outstanding_mutex); - CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); - ca_mutex_unlock(p->outstanding_mutex); - } else - outstanding_free(out); + ca_mutex_lock(p->outstanding_mutex); + CA_LLIST_PREPEND(struct outstanding, p->outstanding, out); + ca_mutex_unlock(p->outstanding_mutex); + } else + outstanding_free(out); - out = NULL; + out = NULL; - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_unlock(p->mainloop); finish_unlocked: - if (out) - outstanding_free(out); + if (out) + outstanding_free(out); - if (l) - pa_proplist_free(l); + if (l) + pa_proplist_free(l); - ca_free(name); + ca_free(name); - return ret; + return ret; } int driver_cancel(ca_context *c, uint32_t id) { - struct private *p; - pa_operation *o; - int ret = CA_SUCCESS; - struct outstanding *out, *n; + struct private *p; + pa_operation *o; + int ret = CA_SUCCESS; + struct outstanding *out, *n; - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); - p = PRIVATE(c); + p = PRIVATE(c); - ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); + ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - pa_threaded_mainloop_lock(p->mainloop); + pa_threaded_mainloop_lock(p->mainloop); - if (!p->context) { - pa_threaded_mainloop_unlock(p->mainloop); - return CA_ERROR_STATE; - } + if (!p->context) { + pa_threaded_mainloop_unlock(p->mainloop); + return CA_ERROR_STATE; + } - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - /* We start these asynchronously and don't care about the return - * value */ + /* We start these asynchronously and don't care about the return + * value */ - for (out = p->outstanding; out; out = n) { - int ret2 = CA_SUCCESS; - n = out->next; + for (out = p->outstanding; out; out = n) { + int ret2 = CA_SUCCESS; + n = out->next; - if (out->type == OUTSTANDING_UPLOAD || - out->id != id || - out->sink_input == PA_INVALID_INDEX) - continue; + if (out->type == OUTSTANDING_UPLOAD || + out->id != id || + out->sink_input == PA_INVALID_INDEX) + continue; - if (!(o = pa_context_kill_sink_input(p->context, out->sink_input, NULL, NULL))) - ret2 = translate_error(pa_context_errno(p->context)); - else - pa_operation_unref(o); + if (!(o = pa_context_kill_sink_input(p->context, out->sink_input, NULL, NULL))) + ret2 = translate_error(pa_context_errno(p->context)); + else + pa_operation_unref(o); - /* We make sure here to kill all streams identified by the id - * here. However, we will return only the first error we - * encounter */ + /* We make sure here to kill all streams identified by the id + * here. However, we will return only the first error we + * encounter */ - if (ret2 && ret == CA_SUCCESS) - ret = ret2; + if (ret2 && ret == CA_SUCCESS) + ret = ret2; - if (out->callback) - out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); + if (out->callback) + out->callback(c, out->id, CA_ERROR_CANCELED, out->userdata); - outstanding_disconnect(out); - CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); - outstanding_free(out); - } + outstanding_disconnect(out); + CA_LLIST_REMOVE(struct outstanding, p->outstanding, out); + outstanding_free(out); + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_unlock(p->mainloop); - return ret; + return ret; } int driver_cache(ca_context *c, ca_proplist *proplist) { - struct private *p; - pa_proplist *l = NULL; - const char *n, *ct; - char *name = NULL; - pa_sample_spec ss; - pa_channel_map cm; - ca_bool_t cm_good; - ca_cache_control_t cache_control = CA_CACHE_CONTROL_PERMANENT; - struct outstanding *out; - int ret; - char *sp; - - ca_return_val_if_fail(c, CA_ERROR_INVALID); - ca_return_val_if_fail(proplist, CA_ERROR_INVALID); - ca_return_val_if_fail(c->private, CA_ERROR_STATE); - - p = PRIVATE(c); - - ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); - - if (!(out = ca_new0(struct outstanding, 1))) { - ret = CA_ERROR_OOM; - goto finish_unlocked; - } - - out->type = OUTSTANDING_UPLOAD; - out->context = c; - out->sink_input = PA_INVALID_INDEX; - - if ((ret = convert_proplist(&l, proplist)) < 0) - goto finish_unlocked; - - if (!(n = pa_proplist_gets(l, CA_PROP_EVENT_ID))) { - ret = CA_ERROR_INVALID; - goto finish_unlocked; - } - - if (!(name = ca_strdup(n))) { - ret = CA_ERROR_OOM; - goto finish_unlocked; - } - - if ((ct = pa_proplist_gets(l, CA_PROP_CANBERRA_CACHE_CONTROL))) - if ((ret = ca_parse_cache_control(&cache_control, ct)) < 0) { - ret = CA_ERROR_INVALID; - goto finish_unlocked; + struct private *p; + pa_proplist *l = NULL; + const char *n, *ct; + char *name = NULL; + pa_sample_spec ss; + pa_channel_map cm; + ca_bool_t cm_good; + ca_cache_control_t cache_control = CA_CACHE_CONTROL_PERMANENT; + struct outstanding *out; + int ret; + char *sp; + + ca_return_val_if_fail(c, CA_ERROR_INVALID); + ca_return_val_if_fail(proplist, CA_ERROR_INVALID); + ca_return_val_if_fail(c->private, CA_ERROR_STATE); + + p = PRIVATE(c); + + ca_return_val_if_fail(p->mainloop, CA_ERROR_STATE); + + if (!(out = ca_new0(struct outstanding, 1))) { + ret = CA_ERROR_OOM; + goto finish_unlocked; } - if (cache_control != CA_CACHE_CONTROL_PERMANENT) { - ret = CA_ERROR_INVALID; - goto finish_unlocked; - } + out->type = OUTSTANDING_UPLOAD; + out->context = c; + out->sink_input = PA_INVALID_INDEX; - if ((ct = pa_proplist_gets(l, CA_PROP_CANBERRA_FORCE_CHANNEL))) { - ret = CA_ERROR_NOTSUPPORTED; - goto finish_unlocked; - } + if ((ret = convert_proplist(&l, proplist)) < 0) + goto finish_unlocked; - strip_prefix(l, "canberra."); - strip_prefix(l, "event.mouse."); - strip_prefix(l, "window."); - add_common(l); + if (!(n = pa_proplist_gets(l, CA_PROP_EVENT_ID))) { + ret = CA_ERROR_INVALID; + goto finish_unlocked; + } - /* Let's stream the sample directly */ - if ((ret = ca_lookup_sound(&out->file, &sp, &p->theme, c->props, proplist)) < 0) - goto finish_unlocked; + if (!(name = ca_strdup(n))) { + ret = CA_ERROR_OOM; + goto finish_unlocked; + } - if (sp) - if (!pa_proplist_contains(l, CA_PROP_MEDIA_FILENAME)) - pa_proplist_sets(l, CA_PROP_MEDIA_FILENAME, sp); + if ((ct = pa_proplist_gets(l, CA_PROP_CANBERRA_CACHE_CONTROL))) + if ((ret = ca_parse_cache_control(&cache_control, ct)) < 0) { + ret = CA_ERROR_INVALID; + goto finish_unlocked; + } - ca_free(sp); + if (cache_control != CA_CACHE_CONTROL_PERMANENT) { + ret = CA_ERROR_INVALID; + goto finish_unlocked; + } - ss.format = sample_type_table[ca_sound_file_get_sample_type(out->file)]; - ss.channels = (uint8_t) ca_sound_file_get_nchannels(out->file); - ss.rate = ca_sound_file_get_rate(out->file); + if ((ct = pa_proplist_gets(l, CA_PROP_CANBERRA_FORCE_CHANNEL))) { + ret = CA_ERROR_NOTSUPPORTED; + goto finish_unlocked; + } - cm_good = convert_channel_map(out->file, &cm); + strip_prefix(l, "canberra."); + strip_prefix(l, "event.mouse."); + strip_prefix(l, "window."); + add_common(l); - pa_threaded_mainloop_lock(p->mainloop); + /* Let's stream the sample directly */ + if ((ret = ca_lookup_sound(&out->file, &sp, &p->theme, c->props, proplist)) < 0) + goto finish_unlocked; - if (!p->context) { - ret = CA_ERROR_STATE; - goto finish_locked; - } + if (sp) + if (!pa_proplist_contains(l, CA_PROP_MEDIA_FILENAME)) + pa_proplist_sets(l, CA_PROP_MEDIA_FILENAME, sp); - if (!(out->stream = pa_stream_new_with_proplist(p->context, name, &ss, cm_good ? &cm : NULL, l))) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; - } + ca_free(sp); - pa_stream_set_state_callback(out->stream, stream_state_cb, out); - pa_stream_set_write_callback(out->stream, stream_write_cb, out); + ss.format = sample_type_table[ca_sound_file_get_sample_type(out->file)]; + ss.channels = (uint8_t) ca_sound_file_get_nchannels(out->file); + ss.rate = ca_sound_file_get_rate(out->file); - if (pa_stream_connect_upload(out->stream, (size_t) ca_sound_file_get_size(out->file)) < 0) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; - } + cm_good = convert_channel_map(out->file, &cm); - for (;;) { - pa_stream_state_t state; + pa_threaded_mainloop_lock(p->mainloop); - if (!p->context || !out->stream) { - ret = CA_ERROR_STATE; - goto finish_locked; + if (!p->context) { + ret = CA_ERROR_STATE; + goto finish_locked; } - state = pa_stream_get_state(out->stream); + if (!(out->stream = pa_stream_new_with_proplist(p->context, name, &ss, cm_good ? &cm : NULL, l))) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; + } - /* Stream sucessfully created and uploaded */ - if (state == PA_STREAM_TERMINATED) - break; + pa_stream_set_state_callback(out->stream, stream_state_cb, out); + pa_stream_set_write_callback(out->stream, stream_write_cb, out); - /* Check for failure */ - if (state == PA_STREAM_FAILED) { - ret = translate_error(pa_context_errno(p->context)); - goto finish_locked; + if (pa_stream_connect_upload(out->stream, (size_t) ca_sound_file_get_size(out->file)) < 0) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; } - pa_threaded_mainloop_wait(p->mainloop); - } + for (;;) { + pa_stream_state_t state; + + if (!p->context || !out->stream) { + ret = CA_ERROR_STATE; + goto finish_locked; + } + + state = pa_stream_get_state(out->stream); + + /* Stream sucessfully created and uploaded */ + if (state == PA_STREAM_TERMINATED) + break; - ret = CA_SUCCESS; + /* Check for failure */ + if (state == PA_STREAM_FAILED) { + ret = translate_error(pa_context_errno(p->context)); + goto finish_locked; + } + + pa_threaded_mainloop_wait(p->mainloop); + } + + ret = CA_SUCCESS; finish_locked: - outstanding_free(out); - out = NULL; + outstanding_free(out); + out = NULL; - pa_threaded_mainloop_unlock(p->mainloop); + pa_threaded_mainloop_unlock(p->mainloop); finish_unlocked: - if (out) - outstanding_free(out); + if (out) + outstanding_free(out); - if (l) - pa_proplist_free(l); + if (l) + pa_proplist_free(l); - ca_free(name); + ca_free(name); - return ret; + return ret; } int driver_playing(ca_context *c, uint32_t id, int *playing) { - struct private *p; - struct outstanding *out; + 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); + 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); + p = PRIVATE(c); - *playing = 0; + *playing = 0; - ca_mutex_lock(p->outstanding_mutex); + ca_mutex_lock(p->outstanding_mutex); - for (out = p->outstanding; out; out = out->next) { + for (out = p->outstanding; out; out = out->next) { - if (out->type == OUTSTANDING_UPLOAD || - out->id != id || - out->sink_input == PA_INVALID_INDEX) - continue; + if (out->type == OUTSTANDING_UPLOAD || + out->id != id || + out->sink_input == PA_INVALID_INDEX) + continue; - *playing = 1; - break; - } + *playing = 1; + break; + } - ca_mutex_unlock(p->outstanding_mutex); + ca_mutex_unlock(p->outstanding_mutex); - return CA_SUCCESS; + return CA_SUCCESS; } diff --git a/src/read-sound-file.c b/src/read-sound-file.c index ef20010..5544188 100644 --- a/src/read-sound-file.c +++ b/src/read-sound-file.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -32,184 +34,184 @@ #include "canberra.h" struct ca_sound_file { - ca_wav *wav; - ca_vorbis *vorbis; - char *filename; + ca_wav *wav; + ca_vorbis *vorbis; + char *filename; - unsigned nchannels; - unsigned rate; - ca_sample_type_t type; + unsigned nchannels; + unsigned rate; + ca_sample_type_t type; }; int ca_sound_file_open(ca_sound_file **_f, const char *fn) { - FILE *file; - ca_sound_file *f; - int ret; - - ca_return_val_if_fail(_f, CA_ERROR_INVALID); - ca_return_val_if_fail(fn, CA_ERROR_INVALID); - - if (!(f = ca_new0(ca_sound_file, 1))) - return CA_ERROR_OOM; - - if (!(f->filename = ca_strdup(fn))) { - ret = CA_ERROR_OOM; - goto fail; - } - - if (!(file = fopen(fn, "r"))) { - ret = errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; - goto fail; - } - - if ((ret = ca_wav_open(&f->wav, file)) == CA_SUCCESS) { - f->nchannels = ca_wav_get_nchannels(f->wav); - f->rate = ca_wav_get_rate(f->wav); - f->type = ca_wav_get_sample_type(f->wav); - *_f = f; - return CA_SUCCESS; - } - - if (ret == CA_ERROR_CORRUPT) { - - if (fseek(file, 0, SEEK_SET) < 0) { - ret = CA_ERROR_SYSTEM; - goto fail; + FILE *file; + ca_sound_file *f; + int ret; + + ca_return_val_if_fail(_f, CA_ERROR_INVALID); + ca_return_val_if_fail(fn, CA_ERROR_INVALID); + + if (!(f = ca_new0(ca_sound_file, 1))) + return CA_ERROR_OOM; + + if (!(f->filename = ca_strdup(fn))) { + ret = CA_ERROR_OOM; + goto fail; + } + + if (!(file = fopen(fn, "r"))) { + ret = errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; + goto fail; } - if ((ret = ca_vorbis_open(&f->vorbis, file)) == CA_SUCCESS) { - f->nchannels = ca_vorbis_get_nchannels(f->vorbis); - f->rate = ca_vorbis_get_rate(f->vorbis); - f->type = CA_SAMPLE_S16NE; - *_f = f; - return CA_SUCCESS; + if ((ret = ca_wav_open(&f->wav, file)) == CA_SUCCESS) { + f->nchannels = ca_wav_get_nchannels(f->wav); + f->rate = ca_wav_get_rate(f->wav); + f->type = ca_wav_get_sample_type(f->wav); + *_f = f; + return CA_SUCCESS; + } + + if (ret == CA_ERROR_CORRUPT) { + + if (fseek(file, 0, SEEK_SET) < 0) { + ret = CA_ERROR_SYSTEM; + goto fail; + } + + if ((ret = ca_vorbis_open(&f->vorbis, file)) == CA_SUCCESS) { + f->nchannels = ca_vorbis_get_nchannels(f->vorbis); + f->rate = ca_vorbis_get_rate(f->vorbis); + f->type = CA_SAMPLE_S16NE; + *_f = f; + return CA_SUCCESS; + } } - } fail: - ca_free(f->filename); - ca_free(f); + ca_free(f->filename); + ca_free(f); - return ret; + return ret; } void ca_sound_file_close(ca_sound_file *f) { - ca_assert(f); + ca_assert(f); - if (f->wav) - ca_wav_close(f->wav); - if (f->vorbis) - ca_vorbis_close(f->vorbis); + if (f->wav) + ca_wav_close(f->wav); + if (f->vorbis) + ca_vorbis_close(f->vorbis); - ca_free(f->filename); - ca_free(f); + ca_free(f->filename); + ca_free(f); } unsigned ca_sound_file_get_nchannels(ca_sound_file *f) { - ca_assert(f); - return f->nchannels; + ca_assert(f); + return f->nchannels; } unsigned ca_sound_file_get_rate(ca_sound_file *f) { - ca_assert(f); - return f->rate; + ca_assert(f); + return f->rate; } ca_sample_type_t ca_sound_file_get_sample_type(ca_sound_file *f) { - ca_assert(f); - return f->type; + ca_assert(f); + return f->type; } const ca_channel_position_t* ca_sound_file_get_channel_map(ca_sound_file *f) { - ca_assert(f); + ca_assert(f); - if (f->wav) - return ca_wav_get_channel_map(f->wav); - else - return ca_vorbis_get_channel_map(f->vorbis); + if (f->wav) + return ca_wav_get_channel_map(f->wav); + else + return ca_vorbis_get_channel_map(f->vorbis); } int ca_sound_file_read_int16(ca_sound_file *f, int16_t *d, size_t *n) { - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(d, CA_ERROR_INVALID); - ca_return_val_if_fail(n, CA_ERROR_INVALID); - ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); - ca_return_val_if_fail(f->wav || f->vorbis, CA_ERROR_STATE); - ca_return_val_if_fail(f->type == CA_SAMPLE_S16NE || f->type == CA_SAMPLE_S16RE, CA_ERROR_STATE); - - if (f->wav) - return ca_wav_read_s16le(f->wav, d, n); - else - return ca_vorbis_read_s16ne(f->vorbis, d, n); + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(d, CA_ERROR_INVALID); + ca_return_val_if_fail(n, CA_ERROR_INVALID); + ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(f->wav || f->vorbis, CA_ERROR_STATE); + ca_return_val_if_fail(f->type == CA_SAMPLE_S16NE || f->type == CA_SAMPLE_S16RE, CA_ERROR_STATE); + + if (f->wav) + return ca_wav_read_s16le(f->wav, d, n); + else + return ca_vorbis_read_s16ne(f->vorbis, d, n); } int ca_sound_file_read_uint8(ca_sound_file *f, uint8_t *d, size_t *n) { - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(d, CA_ERROR_INVALID); - ca_return_val_if_fail(n, CA_ERROR_INVALID); - ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); - ca_return_val_if_fail(f->wav && !f->vorbis, CA_ERROR_STATE); - ca_return_val_if_fail(f->type == CA_SAMPLE_U8, CA_ERROR_STATE); + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(d, CA_ERROR_INVALID); + ca_return_val_if_fail(n, CA_ERROR_INVALID); + ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(f->wav && !f->vorbis, CA_ERROR_STATE); + ca_return_val_if_fail(f->type == CA_SAMPLE_U8, CA_ERROR_STATE); - if (f->wav) - return ca_wav_read_u8(f->wav, d, n); + if (f->wav) + return ca_wav_read_u8(f->wav, d, n); - return CA_ERROR_STATE; + return CA_ERROR_STATE; } int ca_sound_file_read_arbitrary(ca_sound_file *f, void *d, size_t *n) { - int ret; + int ret; - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(d, CA_ERROR_INVALID); - ca_return_val_if_fail(n, CA_ERROR_INVALID); - ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(d, CA_ERROR_INVALID); + ca_return_val_if_fail(n, CA_ERROR_INVALID); + ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); - switch (f->type) { + switch (f->type) { case CA_SAMPLE_S16NE: case CA_SAMPLE_S16RE: { - size_t k; + size_t k; - k = *n / sizeof(int16_t); - if ((ret = ca_sound_file_read_int16(f, d, &k)) == CA_SUCCESS) - *n = k * sizeof(int16_t); + k = *n / sizeof(int16_t); + if ((ret = ca_sound_file_read_int16(f, d, &k)) == CA_SUCCESS) + *n = k * sizeof(int16_t); - break; + break; } case CA_SAMPLE_U8: { - size_t k; + size_t k; - k = *n; - if ((ret = ca_sound_file_read_uint8(f, d, &k)) == CA_SUCCESS) - *n = k; + k = *n; + if ((ret = ca_sound_file_read_uint8(f, d, &k)) == CA_SUCCESS) + *n = k; - break; + break; } default: - ca_assert_not_reached(); - } + ca_assert_not_reached(); + } - return ret; + return ret; } off_t ca_sound_file_get_size(ca_sound_file *f) { - ca_return_val_if_fail(f, (off_t) -1); + ca_return_val_if_fail(f, (off_t) -1); - if (f->wav) - return ca_wav_get_size(f->wav); - else - return ca_vorbis_get_size(f->vorbis); + if (f->wav) + return ca_wav_get_size(f->wav); + else + return ca_vorbis_get_size(f->vorbis); } size_t ca_sound_file_frame_size(ca_sound_file *f) { - unsigned c; + unsigned c; - ca_assert(f); + ca_assert(f); - c = ca_sound_file_get_nchannels(f); + c = ca_sound_file_get_nchannels(f); - return c * (ca_sound_file_get_sample_type(f) == CA_SAMPLE_U8 ? 1U : 2U); + return c * (ca_sound_file_get_sample_type(f) == CA_SAMPLE_U8 ? 1U : 2U); } diff --git a/src/read-sound-file.h b/src/read-sound-file.h index d221324..b24a6dd 100644 --- a/src/read-sound-file.h +++ b/src/read-sound-file.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberrareadsoundfilehfoo #define foocanberrareadsoundfilehfoo @@ -25,32 +27,32 @@ #include typedef enum ca_sample_type { - CA_SAMPLE_S16NE, - CA_SAMPLE_S16RE, - CA_SAMPLE_U8 + CA_SAMPLE_S16NE, + CA_SAMPLE_S16RE, + CA_SAMPLE_U8 } ca_sample_type_t; typedef enum ca_channel_position { - CA_CHANNEL_MONO, - CA_CHANNEL_FRONT_LEFT, - CA_CHANNEL_FRONT_RIGHT, - CA_CHANNEL_FRONT_CENTER, - CA_CHANNEL_REAR_LEFT, - CA_CHANNEL_REAR_RIGHT, - CA_CHANNEL_REAR_CENTER, - CA_CHANNEL_LFE, - CA_CHANNEL_FRONT_LEFT_OF_CENTER, - CA_CHANNEL_FRONT_RIGHT_OF_CENTER, - CA_CHANNEL_SIDE_LEFT, - CA_CHANNEL_SIDE_RIGHT, - CA_CHANNEL_TOP_CENTER, - CA_CHANNEL_TOP_FRONT_LEFT, - CA_CHANNEL_TOP_FRONT_RIGHT, - CA_CHANNEL_TOP_FRONT_CENTER, - CA_CHANNEL_TOP_REAR_LEFT, - CA_CHANNEL_TOP_REAR_RIGHT, - CA_CHANNEL_TOP_REAR_CENTER, - _CA_CHANNEL_POSITION_MAX + CA_CHANNEL_MONO, + CA_CHANNEL_FRONT_LEFT, + CA_CHANNEL_FRONT_RIGHT, + CA_CHANNEL_FRONT_CENTER, + CA_CHANNEL_REAR_LEFT, + CA_CHANNEL_REAR_RIGHT, + CA_CHANNEL_REAR_CENTER, + CA_CHANNEL_LFE, + CA_CHANNEL_FRONT_LEFT_OF_CENTER, + CA_CHANNEL_FRONT_RIGHT_OF_CENTER, + CA_CHANNEL_SIDE_LEFT, + CA_CHANNEL_SIDE_RIGHT, + CA_CHANNEL_TOP_CENTER, + CA_CHANNEL_TOP_FRONT_LEFT, + CA_CHANNEL_TOP_FRONT_RIGHT, + CA_CHANNEL_TOP_FRONT_CENTER, + CA_CHANNEL_TOP_REAR_LEFT, + CA_CHANNEL_TOP_REAR_RIGHT, + CA_CHANNEL_TOP_REAR_CENTER, + _CA_CHANNEL_POSITION_MAX } ca_channel_position_t; typedef struct ca_sound_file ca_sound_file; diff --git a/src/read-vorbis.c b/src/read-vorbis.c index fb2150a..45beb81 100644 --- a/src/read-vorbis.c +++ b/src/read-vorbis.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -33,212 +35,212 @@ #define FILE_SIZE_MAX ((off_t) (64U*1024U*1024U)) struct ca_vorbis { - OggVorbis_File ovf; - off_t size; - ca_channel_position_t channel_map[8]; + OggVorbis_File ovf; + off_t size; + ca_channel_position_t channel_map[8]; }; static int convert_error(int or) { - switch (or) { + switch (or) { case OV_ENOSEEK: case OV_EBADPACKET: case OV_EBADLINK: case OV_EFAULT: case OV_EREAD: case OV_HOLE: - return CA_ERROR_IO; + return CA_ERROR_IO; case OV_EIMPL: case OV_EVERSION: case OV_ENOTAUDIO: - return CA_ERROR_NOTSUPPORTED; + return CA_ERROR_NOTSUPPORTED; case OV_ENOTVORBIS: case OV_EBADHEADER: case OV_EOF: - return CA_ERROR_CORRUPT; + return CA_ERROR_CORRUPT; case OV_EINVAL: - return CA_ERROR_INVALID; + return CA_ERROR_INVALID; default: - return CA_ERROR_IO; - } + return CA_ERROR_IO; + } } int ca_vorbis_open(ca_vorbis **_v, FILE *f) { - int ret, or; - ca_vorbis *v; - int64_t n; + int ret, or; + ca_vorbis *v; + int64_t n; - ca_return_val_if_fail(_v, CA_ERROR_INVALID); - ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(_v, CA_ERROR_INVALID); + ca_return_val_if_fail(f, CA_ERROR_INVALID); - if (!(v = ca_new0(ca_vorbis, 1))) - return CA_ERROR_OOM; + if (!(v = ca_new0(ca_vorbis, 1))) + return CA_ERROR_OOM; - if ((or = ov_open(f, &v->ovf, NULL, 0)) < 0) { - ret = convert_error(or); - goto fail; - } + if ((or = ov_open(f, &v->ovf, NULL, 0)) < 0) { + ret = convert_error(or); + goto fail; + } - if ((n = ov_pcm_total(&v->ovf, -1)) < 0) { - ret = convert_error(or); - ov_clear(&v->ovf); - goto fail; - } + if ((n = ov_pcm_total(&v->ovf, -1)) < 0) { + ret = convert_error(or); + ov_clear(&v->ovf); + goto fail; + } - if (((off_t) n * (off_t) sizeof(int16_t)) > FILE_SIZE_MAX) { - ret = CA_ERROR_TOOBIG; - ov_clear(&v->ovf); - goto fail; - } + if (((off_t) n * (off_t) sizeof(int16_t)) > FILE_SIZE_MAX) { + ret = CA_ERROR_TOOBIG; + ov_clear(&v->ovf); + goto fail; + } - v->size = (off_t) n * (off_t) sizeof(int16_t) * ca_vorbis_get_nchannels(v); + v->size = (off_t) n * (off_t) sizeof(int16_t) * ca_vorbis_get_nchannels(v); - *_v = v; + *_v = v; - return CA_SUCCESS; + return CA_SUCCESS; fail: - ca_free(v); - return ret; + ca_free(v); + return ret; } void ca_vorbis_close(ca_vorbis *v) { - ca_assert(v); + ca_assert(v); - ov_clear(&v->ovf); - ca_free(v); + ov_clear(&v->ovf); + ca_free(v); } unsigned ca_vorbis_get_nchannels(ca_vorbis *v) { - const vorbis_info *vi; - ca_assert(v); + const vorbis_info *vi; + ca_assert(v); - ca_assert_se(vi = ov_info(&v->ovf, -1)); + ca_assert_se(vi = ov_info(&v->ovf, -1)); - return (unsigned) vi->channels; + return (unsigned) vi->channels; } unsigned ca_vorbis_get_rate(ca_vorbis *v) { - const vorbis_info *vi; - ca_assert(v); + const vorbis_info *vi; + ca_assert(v); - ca_assert_se(vi = ov_info(&v->ovf, -1)); + ca_assert_se(vi = ov_info(&v->ovf, -1)); - return (unsigned) vi->rate; + return (unsigned) vi->rate; } const ca_channel_position_t* ca_vorbis_get_channel_map(ca_vorbis *v) { - /* See http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */ + /* See http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */ - switch (ca_vorbis_get_nchannels(v)) { + switch (ca_vorbis_get_nchannels(v)) { case 8: - v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; - v->channel_map[1] = CA_CHANNEL_FRONT_CENTER; - v->channel_map[2] = CA_CHANNEL_FRONT_RIGHT; - v->channel_map[3] = CA_CHANNEL_SIDE_LEFT; - v->channel_map[4] = CA_CHANNEL_SIDE_RIGHT; - v->channel_map[5] = CA_CHANNEL_REAR_LEFT; - v->channel_map[6] = CA_CHANNEL_REAR_RIGHT; - v->channel_map[7] = CA_CHANNEL_LFE; - return v->channel_map; + v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; + v->channel_map[1] = CA_CHANNEL_FRONT_CENTER; + v->channel_map[2] = CA_CHANNEL_FRONT_RIGHT; + v->channel_map[3] = CA_CHANNEL_SIDE_LEFT; + v->channel_map[4] = CA_CHANNEL_SIDE_RIGHT; + v->channel_map[5] = CA_CHANNEL_REAR_LEFT; + v->channel_map[6] = CA_CHANNEL_REAR_RIGHT; + v->channel_map[7] = CA_CHANNEL_LFE; + return v->channel_map; case 7: - v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; - v->channel_map[1] = CA_CHANNEL_FRONT_CENTER; - v->channel_map[2] = CA_CHANNEL_FRONT_RIGHT; - v->channel_map[3] = CA_CHANNEL_SIDE_LEFT; - v->channel_map[4] = CA_CHANNEL_SIDE_RIGHT; - v->channel_map[5] = CA_CHANNEL_REAR_CENTER; - v->channel_map[6] = CA_CHANNEL_LFE; - return v->channel_map; + v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; + v->channel_map[1] = CA_CHANNEL_FRONT_CENTER; + v->channel_map[2] = CA_CHANNEL_FRONT_RIGHT; + v->channel_map[3] = CA_CHANNEL_SIDE_LEFT; + v->channel_map[4] = CA_CHANNEL_SIDE_RIGHT; + v->channel_map[5] = CA_CHANNEL_REAR_CENTER; + v->channel_map[6] = CA_CHANNEL_LFE; + return v->channel_map; case 6: - v->channel_map[5] = CA_CHANNEL_LFE; - /* fall through */ + v->channel_map[5] = CA_CHANNEL_LFE; + /* fall through */ case 5: - v->channel_map[3] = CA_CHANNEL_REAR_LEFT; - v->channel_map[4] = CA_CHANNEL_REAR_RIGHT; - /* fall through */ + v->channel_map[3] = CA_CHANNEL_REAR_LEFT; + v->channel_map[4] = CA_CHANNEL_REAR_RIGHT; + /* fall through */ case 3: - v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; - v->channel_map[1] = CA_CHANNEL_FRONT_CENTER; - v->channel_map[2] = CA_CHANNEL_FRONT_RIGHT; - return v->channel_map; + v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; + v->channel_map[1] = CA_CHANNEL_FRONT_CENTER; + v->channel_map[2] = CA_CHANNEL_FRONT_RIGHT; + return v->channel_map; case 4: - v->channel_map[2] = CA_CHANNEL_REAR_LEFT; - v->channel_map[3] = CA_CHANNEL_REAR_RIGHT; - /* fall through */ + v->channel_map[2] = CA_CHANNEL_REAR_LEFT; + v->channel_map[3] = CA_CHANNEL_REAR_RIGHT; + /* fall through */ case 2: - v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; - v->channel_map[1] = CA_CHANNEL_FRONT_RIGHT; - return v->channel_map; + v->channel_map[0] = CA_CHANNEL_FRONT_LEFT; + v->channel_map[1] = CA_CHANNEL_FRONT_RIGHT; + return v->channel_map; case 1: - v->channel_map[0] = CA_CHANNEL_MONO; - return v->channel_map; - } + v->channel_map[0] = CA_CHANNEL_MONO; + return v->channel_map; + } - return NULL; + return NULL; } int ca_vorbis_read_s16ne(ca_vorbis *v, int16_t *d, size_t *n){ - long r; - int section; - int length; - size_t n_read = 0; + long r; + int section; + int length; + size_t n_read = 0; - ca_return_val_if_fail(v, CA_ERROR_INVALID); - ca_return_val_if_fail(d, CA_ERROR_INVALID); - ca_return_val_if_fail(n, CA_ERROR_INVALID); - ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(v, CA_ERROR_INVALID); + ca_return_val_if_fail(d, CA_ERROR_INVALID); + ca_return_val_if_fail(n, CA_ERROR_INVALID); + ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); - length = (int) (*n * sizeof(int16_t)); + length = (int) (*n * sizeof(int16_t)); - do { + do { - r = ov_read(&v->ovf, (char*) d, length, + r = ov_read(&v->ovf, (char*) d, length, #ifdef WORDS_BIGENDIAN - 1, + 1, #else - 0, + 0, #endif - 2, 1, §ion); + 2, 1, §ion); - if (r < 0) - return convert_error((int) r); + if (r < 0) + return convert_error((int) r); - if (r == 0) - break; + if (r == 0) + break; - /* We only read the first section */ - if (section != 0) - break; + /* We only read the first section */ + if (section != 0) + break; - length -= (int) r; - d += r/sizeof(int16_t); - n_read += (size_t) r; + length -= (int) r; + d += r/sizeof(int16_t); + n_read += (size_t) r; - } while (length >= 4096); + } while (length >= 4096); - ca_assert(v->size >= (off_t) n_read); - v->size -= (off_t) n_read; + ca_assert(v->size >= (off_t) n_read); + v->size -= (off_t) n_read; - *n = n_read/sizeof(int16_t); + *n = n_read/sizeof(int16_t); - return CA_SUCCESS; + return CA_SUCCESS; } off_t ca_vorbis_get_size(ca_vorbis *v) { - ca_return_val_if_fail(v, (off_t) -1); + ca_return_val_if_fail(v, (off_t) -1); - return v->size; + return v->size; } diff --git a/src/read-vorbis.h b/src/read-vorbis.h index 6edbcaf..03749c8 100644 --- a/src/read-vorbis.h +++ b/src/read-vorbis.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberrareadvorbishfoo #define foocanberrareadvorbishfoo diff --git a/src/read-wav.c b/src/read-wav.c index 95c46c8..0d3a62d 100644 --- a/src/read-wav.c +++ b/src/read-wav.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -31,334 +33,334 @@ /* Stores the bit indexes in dwChannelMask */ enum { - BIT_FRONT_LEFT, - BIT_FRONT_RIGHT, - BIT_FRONT_CENTER, - BIT_LOW_FREQUENCY, - BIT_BACK_LEFT, - BIT_BACK_RIGHT, - BIT_FRONT_LEFT_OF_CENTER, - BIT_FRONT_RIGHT_OF_CENTER, - BIT_BACK_CENTER, - BIT_SIDE_LEFT, - BIT_SIDE_RIGHT, - BIT_TOP_CENTER, - BIT_TOP_FRONT_LEFT, - BIT_TOP_FRONT_CENTER, - BIT_TOP_FRONT_RIGHT, - BIT_TOP_BACK_LEFT, - BIT_TOP_BACK_CENTER, - BIT_TOP_BACK_RIGHT, - _BIT_MAX + BIT_FRONT_LEFT, + BIT_FRONT_RIGHT, + BIT_FRONT_CENTER, + BIT_LOW_FREQUENCY, + BIT_BACK_LEFT, + BIT_BACK_RIGHT, + BIT_FRONT_LEFT_OF_CENTER, + BIT_FRONT_RIGHT_OF_CENTER, + BIT_BACK_CENTER, + BIT_SIDE_LEFT, + BIT_SIDE_RIGHT, + BIT_TOP_CENTER, + BIT_TOP_FRONT_LEFT, + BIT_TOP_FRONT_CENTER, + BIT_TOP_FRONT_RIGHT, + BIT_TOP_BACK_LEFT, + BIT_TOP_BACK_CENTER, + BIT_TOP_BACK_RIGHT, + _BIT_MAX }; static const ca_channel_position_t channel_table[_BIT_MAX] = { - [BIT_FRONT_LEFT] = CA_CHANNEL_FRONT_LEFT, - [BIT_FRONT_RIGHT] = CA_CHANNEL_FRONT_RIGHT, - [BIT_FRONT_CENTER] = CA_CHANNEL_FRONT_CENTER, - [BIT_LOW_FREQUENCY] = CA_CHANNEL_LFE, - [BIT_BACK_LEFT] = CA_CHANNEL_REAR_LEFT, - [BIT_BACK_RIGHT] = CA_CHANNEL_REAR_RIGHT, - [BIT_FRONT_LEFT_OF_CENTER] = CA_CHANNEL_FRONT_LEFT_OF_CENTER, - [BIT_FRONT_RIGHT_OF_CENTER] = CA_CHANNEL_FRONT_RIGHT_OF_CENTER, - [BIT_BACK_CENTER] = CA_CHANNEL_REAR_CENTER, - [BIT_SIDE_LEFT] = CA_CHANNEL_SIDE_LEFT, - [BIT_SIDE_RIGHT] = CA_CHANNEL_SIDE_RIGHT, - [BIT_TOP_CENTER] = CA_CHANNEL_TOP_CENTER, - [BIT_TOP_FRONT_LEFT] = CA_CHANNEL_TOP_FRONT_LEFT, - [BIT_TOP_FRONT_CENTER] = CA_CHANNEL_TOP_FRONT_CENTER, - [BIT_TOP_FRONT_RIGHT] = CA_CHANNEL_TOP_FRONT_RIGHT, - [BIT_TOP_BACK_LEFT] = CA_CHANNEL_TOP_REAR_LEFT, - [BIT_TOP_BACK_CENTER] = CA_CHANNEL_TOP_REAR_CENTER, - [BIT_TOP_BACK_RIGHT] = CA_CHANNEL_TOP_REAR_RIGHT + [BIT_FRONT_LEFT] = CA_CHANNEL_FRONT_LEFT, + [BIT_FRONT_RIGHT] = CA_CHANNEL_FRONT_RIGHT, + [BIT_FRONT_CENTER] = CA_CHANNEL_FRONT_CENTER, + [BIT_LOW_FREQUENCY] = CA_CHANNEL_LFE, + [BIT_BACK_LEFT] = CA_CHANNEL_REAR_LEFT, + [BIT_BACK_RIGHT] = CA_CHANNEL_REAR_RIGHT, + [BIT_FRONT_LEFT_OF_CENTER] = CA_CHANNEL_FRONT_LEFT_OF_CENTER, + [BIT_FRONT_RIGHT_OF_CENTER] = CA_CHANNEL_FRONT_RIGHT_OF_CENTER, + [BIT_BACK_CENTER] = CA_CHANNEL_REAR_CENTER, + [BIT_SIDE_LEFT] = CA_CHANNEL_SIDE_LEFT, + [BIT_SIDE_RIGHT] = CA_CHANNEL_SIDE_RIGHT, + [BIT_TOP_CENTER] = CA_CHANNEL_TOP_CENTER, + [BIT_TOP_FRONT_LEFT] = CA_CHANNEL_TOP_FRONT_LEFT, + [BIT_TOP_FRONT_CENTER] = CA_CHANNEL_TOP_FRONT_CENTER, + [BIT_TOP_FRONT_RIGHT] = CA_CHANNEL_TOP_FRONT_RIGHT, + [BIT_TOP_BACK_LEFT] = CA_CHANNEL_TOP_REAR_LEFT, + [BIT_TOP_BACK_CENTER] = CA_CHANNEL_TOP_REAR_CENTER, + [BIT_TOP_BACK_RIGHT] = CA_CHANNEL_TOP_REAR_RIGHT }; struct ca_wav { - FILE *file; + FILE *file; - off_t data_size; - unsigned nchannels; - unsigned rate; - unsigned depth; - uint32_t channel_mask; + off_t data_size; + unsigned nchannels; + unsigned rate; + unsigned depth; + uint32_t channel_mask; - ca_channel_position_t channel_map[_BIT_MAX]; + ca_channel_position_t channel_map[_BIT_MAX]; }; #define CHUNK_ID_DATA 0x61746164U #define CHUNK_ID_FMT 0x20746d66U static const uint8_t pcm_guid[16] = { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; static int skip_to_chunk(ca_wav *w, uint32_t id, uint32_t *size) { - ca_return_val_if_fail(w, CA_ERROR_INVALID); - ca_return_val_if_fail(size, CA_ERROR_INVALID); + ca_return_val_if_fail(w, CA_ERROR_INVALID); + ca_return_val_if_fail(size, CA_ERROR_INVALID); - for (;;) { - uint32_t chunk[2]; - uint32_t s; + for (;;) { + uint32_t chunk[2]; + uint32_t s; - if (fread(chunk, sizeof(uint32_t), CA_ELEMENTSOF(chunk), w->file) != CA_ELEMENTSOF(chunk)) - goto fail_io; + if (fread(chunk, sizeof(uint32_t), CA_ELEMENTSOF(chunk), w->file) != CA_ELEMENTSOF(chunk)) + goto fail_io; - s = CA_UINT32_FROM_LE(chunk[1]); + s = CA_UINT32_FROM_LE(chunk[1]); - if (s <= 0 || s >= FILE_SIZE_MAX) - return CA_ERROR_TOOBIG; + if (s <= 0 || s >= FILE_SIZE_MAX) + return CA_ERROR_TOOBIG; - if (CA_UINT32_FROM_LE(chunk[0]) == id) { - *size = s; - break; - } + if (CA_UINT32_FROM_LE(chunk[0]) == id) { + *size = s; + break; + } - if (fseek(w->file, (long) s, SEEK_CUR) < 0) - return CA_ERROR_SYSTEM; - } + if (fseek(w->file, (long) s, SEEK_CUR) < 0) + return CA_ERROR_SYSTEM; + } - return CA_SUCCESS; + return CA_SUCCESS; fail_io: - if (feof(w->file)) - return CA_ERROR_CORRUPT; - else if (ferror(w->file)) - return CA_ERROR_SYSTEM; + if (feof(w->file)) + return CA_ERROR_CORRUPT; + else if (ferror(w->file)) + return CA_ERROR_SYSTEM; - ca_assert_not_reached(); + ca_assert_not_reached(); } int ca_wav_open(ca_wav **_w, FILE *f) { - uint32_t header[3], fmt_chunk[10]; - int ret; - ca_wav *w; - uint32_t file_size, fmt_size, data_size; - ca_bool_t extensible; - uint32_t format; + uint32_t header[3], fmt_chunk[10]; + int ret; + ca_wav *w; + uint32_t file_size, fmt_size, data_size; + ca_bool_t extensible; + uint32_t format; - ca_return_val_if_fail(_w, CA_ERROR_INVALID); - ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(_w, CA_ERROR_INVALID); + ca_return_val_if_fail(f, CA_ERROR_INVALID); - if (!(w = ca_new(ca_wav, 1))) - return CA_ERROR_OOM; + if (!(w = ca_new(ca_wav, 1))) + return CA_ERROR_OOM; - w->file = f; + w->file = f; - if (fread(header, sizeof(uint32_t), CA_ELEMENTSOF(header), f) != CA_ELEMENTSOF(header)) - goto fail_io; + if (fread(header, sizeof(uint32_t), CA_ELEMENTSOF(header), f) != CA_ELEMENTSOF(header)) + goto fail_io; - if (CA_UINT32_FROM_LE(header[0]) != 0x46464952U || - CA_UINT32_FROM_LE(header[2]) != 0x45564157U) { - ret = CA_ERROR_CORRUPT; - goto fail; - } + if (CA_UINT32_FROM_LE(header[0]) != 0x46464952U || + CA_UINT32_FROM_LE(header[2]) != 0x45564157U) { + ret = CA_ERROR_CORRUPT; + goto fail; + } - file_size = CA_UINT32_FROM_LE(header[1]); + file_size = CA_UINT32_FROM_LE(header[1]); - if (file_size <= 0 || file_size >= FILE_SIZE_MAX) { - ret = CA_ERROR_TOOBIG; - goto fail; - } + if (file_size <= 0 || file_size >= FILE_SIZE_MAX) { + ret = CA_ERROR_TOOBIG; + goto fail; + } - /* Skip to the fmt chunk */ - if ((ret = skip_to_chunk(w, CHUNK_ID_FMT, &fmt_size)) < 0) - goto fail; + /* Skip to the fmt chunk */ + if ((ret = skip_to_chunk(w, CHUNK_ID_FMT, &fmt_size)) < 0) + goto fail; - switch (fmt_size) { + switch (fmt_size) { case 14: /* WAVEFORMAT */ case 16: case 18: /* WAVEFORMATEX */ - extensible = FALSE; - break; + extensible = FALSE; + break; case 40: /* WAVEFORMATEXTENSIBLE */ - extensible = TRUE; - break; + extensible = TRUE; + break; default: - ret = CA_ERROR_NOTSUPPORTED; - goto fail; - } - - if (fread(fmt_chunk, 1, fmt_size, f) != fmt_size) - goto fail_io; - - /* PCM? or WAVEX? */ - format = (CA_UINT32_FROM_LE(fmt_chunk[0]) & 0xFFFF); - if ((!extensible && format != 0x0001) || - (extensible && format != 0xFFFE)) { - ret = CA_ERROR_NOTSUPPORTED; - goto fail; - } - - if (extensible) { - if (memcmp(fmt_chunk + 6, pcm_guid, 16) != 0) { - ret = CA_ERROR_NOTSUPPORTED; - goto fail; + ret = CA_ERROR_NOTSUPPORTED; + goto fail; + } + + if (fread(fmt_chunk, 1, fmt_size, f) != fmt_size) + goto fail_io; + + /* PCM? or WAVEX? */ + format = (CA_UINT32_FROM_LE(fmt_chunk[0]) & 0xFFFF); + if ((!extensible && format != 0x0001) || + (extensible && format != 0xFFFE)) { + ret = CA_ERROR_NOTSUPPORTED; + goto fail; } - w->channel_mask = CA_UINT32_FROM_LE(fmt_chunk[5]); - } else - w->channel_mask = 0; + if (extensible) { + if (memcmp(fmt_chunk + 6, pcm_guid, 16) != 0) { + ret = CA_ERROR_NOTSUPPORTED; + goto fail; + } + + w->channel_mask = CA_UINT32_FROM_LE(fmt_chunk[5]); + } else + w->channel_mask = 0; - w->nchannels = CA_UINT32_FROM_LE(fmt_chunk[0]) >> 16; - w->rate = CA_UINT32_FROM_LE(fmt_chunk[1]); - w->depth = CA_UINT32_FROM_LE(fmt_chunk[3]) >> 16; + w->nchannels = CA_UINT32_FROM_LE(fmt_chunk[0]) >> 16; + w->rate = CA_UINT32_FROM_LE(fmt_chunk[1]); + w->depth = CA_UINT32_FROM_LE(fmt_chunk[3]) >> 16; - if (w->nchannels <= 0 || w->rate <= 0) { - ret = CA_ERROR_CORRUPT; - goto fail; - } + if (w->nchannels <= 0 || w->rate <= 0) { + ret = CA_ERROR_CORRUPT; + goto fail; + } - if (w->depth != 16 && w->depth != 8) { - ret = CA_ERROR_NOTSUPPORTED; - goto fail; - } + if (w->depth != 16 && w->depth != 8) { + ret = CA_ERROR_NOTSUPPORTED; + goto fail; + } - /* Skip to the data chunk */ - if ((ret = skip_to_chunk(w, CHUNK_ID_DATA, &data_size)) < 0) - goto fail; - w->data_size = (off_t) data_size; + /* Skip to the data chunk */ + if ((ret = skip_to_chunk(w, CHUNK_ID_DATA, &data_size)) < 0) + goto fail; + w->data_size = (off_t) data_size; - if ((w->data_size % (w->depth/8)) != 0) { - ret = CA_ERROR_CORRUPT; - goto fail; - } + if ((w->data_size % (w->depth/8)) != 0) { + ret = CA_ERROR_CORRUPT; + goto fail; + } - *_w = w; + *_w = w; - return CA_SUCCESS; + return CA_SUCCESS; fail_io: - if (feof(f)) - ret = CA_ERROR_CORRUPT; - else if (ferror(f)) - ret = CA_ERROR_SYSTEM; - else - ca_assert_not_reached(); + if (feof(f)) + ret = CA_ERROR_CORRUPT; + else if (ferror(f)) + ret = CA_ERROR_SYSTEM; + else + ca_assert_not_reached(); fail: - ca_free(w); + ca_free(w); - return ret; + return ret; } void ca_wav_close(ca_wav *w) { - ca_assert(w); + ca_assert(w); - fclose(w->file); - ca_free(w); + fclose(w->file); + ca_free(w); } unsigned ca_wav_get_nchannels(ca_wav *w) { - ca_assert(w); + ca_assert(w); - return w->nchannels; + return w->nchannels; } unsigned ca_wav_get_rate(ca_wav *w) { - ca_assert(w); + ca_assert(w); - return w->rate; + return w->rate; } const ca_channel_position_t* ca_wav_get_channel_map(ca_wav *w) { - unsigned c; - ca_channel_position_t *p; + unsigned c; + ca_channel_position_t *p; - ca_assert(w); + ca_assert(w); - if (!w->channel_mask) - return NULL; + if (!w->channel_mask) + return NULL; - p = w->channel_map; + p = w->channel_map; - for (c = 0; c < _BIT_MAX; c++) - if ((w->channel_mask & (1 << c))) - *(p++) = channel_table[c]; + for (c = 0; c < _BIT_MAX; c++) + if ((w->channel_mask & (1 << c))) + *(p++) = channel_table[c]; - ca_assert(p <= w->channel_map + _BIT_MAX); + ca_assert(p <= w->channel_map + _BIT_MAX); - if (p != w->channel_map + w->nchannels) - return NULL; + if (p != w->channel_map + w->nchannels) + return NULL; - return w->channel_map; + return w->channel_map; } ca_sample_type_t ca_wav_get_sample_type(ca_wav *w) { - ca_assert(w); + ca_assert(w); - return w->depth == 16 ? + return w->depth == 16 ? #ifdef WORDS_BIGENDIAN - CA_SAMPLE_S16RE + CA_SAMPLE_S16RE #else - CA_SAMPLE_S16NE + CA_SAMPLE_S16NE #endif - : CA_SAMPLE_U8; + : CA_SAMPLE_U8; } int ca_wav_read_s16le(ca_wav *w, int16_t *d, size_t *n) { - off_t remaining; + off_t remaining; - ca_return_val_if_fail(w, CA_ERROR_INVALID); - ca_return_val_if_fail(w->depth == 16, CA_ERROR_INVALID); - ca_return_val_if_fail(d, CA_ERROR_INVALID); - ca_return_val_if_fail(n, CA_ERROR_INVALID); - ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(w, CA_ERROR_INVALID); + ca_return_val_if_fail(w->depth == 16, CA_ERROR_INVALID); + ca_return_val_if_fail(d, CA_ERROR_INVALID); + ca_return_val_if_fail(n, CA_ERROR_INVALID); + ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); - remaining = w->data_size / (off_t) sizeof(int16_t); + remaining = w->data_size / (off_t) sizeof(int16_t); - if ((off_t) *n > remaining) - *n = (size_t) remaining; + if ((off_t) *n > remaining) + *n = (size_t) remaining; - if (*n > 0) { - *n = fread(d, sizeof(int16_t), *n, w->file); + if (*n > 0) { + *n = fread(d, sizeof(int16_t), *n, w->file); - if (*n <= 0 && ferror(w->file)) - return CA_ERROR_SYSTEM; + if (*n <= 0 && ferror(w->file)) + return CA_ERROR_SYSTEM; - ca_assert(w->data_size >= (off_t) *n * (off_t) sizeof(int16_t)); - w->data_size -= (off_t) *n * (off_t) sizeof(int16_t); - } + ca_assert(w->data_size >= (off_t) *n * (off_t) sizeof(int16_t)); + w->data_size -= (off_t) *n * (off_t) sizeof(int16_t); + } - return CA_SUCCESS; + return CA_SUCCESS; } int ca_wav_read_u8(ca_wav *w, uint8_t *d, size_t *n) { - off_t remaining; + off_t remaining; - ca_return_val_if_fail(w, CA_ERROR_INVALID); - ca_return_val_if_fail(w->depth == 8, CA_ERROR_INVALID); - ca_return_val_if_fail(d, CA_ERROR_INVALID); - ca_return_val_if_fail(n, CA_ERROR_INVALID); - ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); + ca_return_val_if_fail(w, CA_ERROR_INVALID); + ca_return_val_if_fail(w->depth == 8, CA_ERROR_INVALID); + ca_return_val_if_fail(d, CA_ERROR_INVALID); + ca_return_val_if_fail(n, CA_ERROR_INVALID); + ca_return_val_if_fail(*n > 0, CA_ERROR_INVALID); - remaining = w->data_size / (off_t) sizeof(uint8_t); + remaining = w->data_size / (off_t) sizeof(uint8_t); - if ((off_t) *n > remaining) - *n = (size_t) remaining; + if ((off_t) *n > remaining) + *n = (size_t) remaining; - if (*n > 0) { - *n = fread(d, sizeof(uint8_t), *n, w->file); + if (*n > 0) { + *n = fread(d, sizeof(uint8_t), *n, w->file); - if (*n <= 0 && ferror(w->file)) - return CA_ERROR_SYSTEM; + if (*n <= 0 && ferror(w->file)) + return CA_ERROR_SYSTEM; - ca_assert(w->data_size >= (off_t) *n * (off_t) sizeof(uint8_t)); - w->data_size -= (off_t) *n * (off_t) sizeof(uint8_t); - } + ca_assert(w->data_size >= (off_t) *n * (off_t) sizeof(uint8_t)); + w->data_size -= (off_t) *n * (off_t) sizeof(uint8_t); + } - return CA_SUCCESS; + return CA_SUCCESS; } off_t ca_wav_get_size(ca_wav *v) { - ca_return_val_if_fail(v, (off_t) -1); + ca_return_val_if_fail(v, (off_t) -1); - return v->data_size; + return v->data_size; } diff --git a/src/read-wav.h b/src/read-wav.h index e7c6178..a19fa34 100644 --- a/src/read-wav.h +++ b/src/read-wav.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberrareadwavhfoo #define foocanberrareadwavhfoo diff --git a/src/sound-theme-spec.c b/src/sound-theme-spec.c index 3f8a9a9..32affd0 100644 --- a/src/sound-theme-spec.c +++ b/src/sound-theme-spec.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -40,827 +42,827 @@ typedef struct ca_data_dir ca_data_dir; struct ca_data_dir { - CA_LLIST_FIELDS(ca_data_dir); + CA_LLIST_FIELDS(ca_data_dir); - char *theme_name; - char *dir_name; - char *output_profile; + char *theme_name; + char *dir_name; + char *output_profile; }; struct ca_theme_data { - char *name; + char *name; - CA_LLIST_HEAD(ca_data_dir, data_dirs); - ca_data_dir *last_dir; + CA_LLIST_HEAD(ca_data_dir, data_dirs); + ca_data_dir *last_dir; - unsigned n_theme_dir; - ca_bool_t loaded_fallback_theme; + unsigned n_theme_dir; + ca_bool_t loaded_fallback_theme; }; int ca_get_data_home(char **e) { - const char *env, *subdir; - char *r; - ca_return_val_if_fail(e, CA_ERROR_INVALID); - - if ((env = getenv("XDG_DATA_HOME")) && *env == '/') - subdir = ""; - else if ((env = getenv("HOME")) && *env == '/') - subdir = "/.local/share"; - else { - *e = NULL; - return CA_SUCCESS; - } + const char *env, *subdir; + char *r; + ca_return_val_if_fail(e, CA_ERROR_INVALID); + + if ((env = getenv("XDG_DATA_HOME")) && *env == '/') + subdir = ""; + else if ((env = getenv("HOME")) && *env == '/') + subdir = "/.local/share"; + else { + *e = NULL; + return CA_SUCCESS; + } - if (!(r = ca_new(char, strlen(env) + strlen(subdir) + 1))) - return CA_ERROR_OOM; + if (!(r = ca_new(char, strlen(env) + strlen(subdir) + 1))) + return CA_ERROR_OOM; - sprintf(r, "%s%s", env, subdir); - *e = r; + sprintf(r, "%s%s", env, subdir); + *e = r; - return CA_SUCCESS; + return CA_SUCCESS; } static ca_bool_t data_dir_matches(ca_data_dir *d, const char*output_profile) { - ca_assert(d); - ca_assert(output_profile); + ca_assert(d); + ca_assert(output_profile); - /* We might want to add more elaborate matching here eventually */ + /* We might want to add more elaborate matching here eventually */ - if (!d->output_profile) - return TRUE; + if (!d->output_profile) + return TRUE; - return ca_streq(d->output_profile, output_profile); + return ca_streq(d->output_profile, output_profile); } static ca_data_dir* find_data_dir(ca_theme_data *t, const char *theme_name, const char *dir_name) { - ca_data_dir *d; + ca_data_dir *d; - ca_assert(t); - ca_assert(theme_name); - ca_assert(dir_name); + ca_assert(t); + ca_assert(theme_name); + ca_assert(dir_name); - for (d = t->data_dirs; d; d = d->next) - if (ca_streq(d->theme_name, theme_name) && - ca_streq(d->dir_name, dir_name)) - return d; + for (d = t->data_dirs; d; d = d->next) + if (ca_streq(d->theme_name, theme_name) && + ca_streq(d->dir_name, dir_name)) + return d; - return NULL; + return NULL; } static int add_data_dir(ca_theme_data *t, const char *theme_name, const char *dir_name) { - ca_data_dir *d; + ca_data_dir *d; - ca_return_val_if_fail(t, CA_ERROR_INVALID); - ca_return_val_if_fail(theme_name, CA_ERROR_INVALID); - ca_return_val_if_fail(dir_name, CA_ERROR_INVALID); + ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(theme_name, CA_ERROR_INVALID); + ca_return_val_if_fail(dir_name, CA_ERROR_INVALID); - if (find_data_dir(t, theme_name, dir_name)) - return CA_SUCCESS; + if (find_data_dir(t, theme_name, dir_name)) + return CA_SUCCESS; - if (!(d = ca_new0(ca_data_dir, 1))) - return CA_ERROR_OOM; + if (!(d = ca_new0(ca_data_dir, 1))) + return CA_ERROR_OOM; - if (!(d->theme_name = ca_strdup(theme_name))) { - ca_free(d); - return CA_ERROR_OOM; - } + if (!(d->theme_name = ca_strdup(theme_name))) { + ca_free(d); + return CA_ERROR_OOM; + } - if (!(d->dir_name = ca_strdup(dir_name))) { - ca_free(d->theme_name); - ca_free(d); - return CA_ERROR_OOM; - } + if (!(d->dir_name = ca_strdup(dir_name))) { + ca_free(d->theme_name); + ca_free(d); + return CA_ERROR_OOM; + } - CA_LLIST_INSERT_AFTER(ca_data_dir, t->data_dirs, t->last_dir, d); - t->last_dir = d; + CA_LLIST_INSERT_AFTER(ca_data_dir, t->data_dirs, t->last_dir, d); + t->last_dir = d; - return CA_SUCCESS; + return CA_SUCCESS; } static int load_theme_dir(ca_theme_data *t, const char *name); static int load_theme_path(ca_theme_data *t, const char *prefix, const char *name) { - char *fn, *inherits = NULL; - FILE *f; - ca_bool_t in_sound_theme_section = FALSE; - ca_data_dir *current_data_dir = NULL; - int ret; + char *fn, *inherits = NULL; + FILE *f; + ca_bool_t in_sound_theme_section = FALSE; + ca_data_dir *current_data_dir = NULL; + int ret; - ca_return_val_if_fail(t, CA_ERROR_INVALID); - ca_return_val_if_fail(prefix, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); + ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(prefix, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); - if (!(fn = ca_new(char, strlen(prefix) + sizeof("/sounds/")-1 + strlen(name) + sizeof("/index.theme")))) - return CA_ERROR_OOM; + if (!(fn = ca_new(char, strlen(prefix) + sizeof("/sounds/")-1 + strlen(name) + sizeof("/index.theme")))) + return CA_ERROR_OOM; - sprintf(fn, "%s/sounds/%s/index.theme", prefix, name); - f = fopen(fn, "r"); - ca_free(fn); + sprintf(fn, "%s/sounds/%s/index.theme", prefix, name); + f = fopen(fn, "r"); + ca_free(fn); - if (!f) { - if (errno == ENOENT) - return CA_ERROR_NOTFOUND; + if (!f) { + if (errno == ENOENT) + return CA_ERROR_NOTFOUND; - return CA_ERROR_SYSTEM; - } + return CA_ERROR_SYSTEM; + } - for (;;) { - char ln[1024]; + for (;;) { + char ln[1024]; - if (!(fgets(ln, sizeof(ln), f))) { + if (!(fgets(ln, sizeof(ln), f))) { - if (feof(f)) - break; + if (feof(f)) + break; - ca_assert(ferror(f)); - ret = CA_ERROR_SYSTEM; - goto fail; - } + ca_assert(ferror(f)); + ret = CA_ERROR_SYSTEM; + goto fail; + } - ln[strcspn(ln, "\n\r#")] = 0; + ln[strcspn(ln, "\n\r#")] = 0; - if (!ln[0]) - continue; + if (!ln[0]) + continue; - if (ca_streq(ln, "[Sound Theme]")) { - in_sound_theme_section = TRUE; - current_data_dir = NULL; - continue; - } + if (ca_streq(ln, "[Sound Theme]")) { + in_sound_theme_section = TRUE; + current_data_dir = NULL; + continue; + } - if (ln[0] == '[' && ln[strlen(ln)-1] == ']') { - char *d; + if (ln[0] == '[' && ln[strlen(ln)-1] == ']') { + char *d; - if (!(d = ca_strndup(ln+1, strlen(ln)-2))) { - ret = CA_ERROR_OOM; - goto fail; - } + if (!(d = ca_strndup(ln+1, strlen(ln)-2))) { + ret = CA_ERROR_OOM; + goto fail; + } - current_data_dir = find_data_dir(t, name, d); - ca_free(d); + current_data_dir = find_data_dir(t, name, d); + ca_free(d); - in_sound_theme_section = FALSE; - continue; - } + in_sound_theme_section = FALSE; + continue; + } - ca_assert(!in_sound_theme_section || !current_data_dir); - ca_assert(!current_data_dir || !in_sound_theme_section); + ca_assert(!in_sound_theme_section || !current_data_dir); + ca_assert(!current_data_dir || !in_sound_theme_section); - if (in_sound_theme_section) { + if (in_sound_theme_section) { - if (!strncmp(ln, "Inherits=", 9)) { + if (!strncmp(ln, "Inherits=", 9)) { - if (inherits) { - ret = CA_ERROR_CORRUPT; - goto fail; - } + if (inherits) { + ret = CA_ERROR_CORRUPT; + goto fail; + } - if (!(inherits = ca_strdup(ln + 9))) { - ret = CA_ERROR_OOM; - goto fail; - } + if (!(inherits = ca_strdup(ln + 9))) { + ret = CA_ERROR_OOM; + goto fail; + } - continue; - } + continue; + } - if (!strncmp(ln, "Directories=", 12)) { - char *d; + if (!strncmp(ln, "Directories=", 12)) { + char *d; - d = ln+12; - for (;;) { - size_t k = strcspn(d, ", "); + d = ln+12; + for (;;) { + size_t k = strcspn(d, ", "); - if (k > 0) { - char *p; + if (k > 0) { + char *p; - if (!(p = ca_strndup(d, k))) { - ret = CA_ERROR_OOM; - goto fail; - } + if (!(p = ca_strndup(d, k))) { + ret = CA_ERROR_OOM; + goto fail; + } - ret = add_data_dir(t, name, p); - ca_free(p); + ret = add_data_dir(t, name, p); + ca_free(p); - if (ret != CA_SUCCESS) - goto fail; - } + if (ret != CA_SUCCESS) + goto fail; + } - if (d[k] == 0) - break; + if (d[k] == 0) + break; + + d += k+1; + } - d += k+1; + continue; + } } - continue; - } - } + if (current_data_dir) { - if (current_data_dir) { + if (!strncmp(ln, "OutputProfile=", 14)) { - if (!strncmp(ln, "OutputProfile=", 14)) { + if (!current_data_dir->output_profile) { - if (!current_data_dir->output_profile) { + if (!(current_data_dir->output_profile = ca_strdup(ln+14))) { + ret = CA_ERROR_OOM; + goto fail; + } - if (!(current_data_dir->output_profile = ca_strdup(ln+14))) { - ret = CA_ERROR_OOM; - goto fail; - } + } else if (!ca_streq(current_data_dir->output_profile, ln+14)) { + ret = CA_ERROR_CORRUPT; + goto fail; + } - } else if (!ca_streq(current_data_dir->output_profile, ln+14)) { - ret = CA_ERROR_CORRUPT; - goto fail; + continue; + } } - - continue; - } } - } - t->n_theme_dir ++; + t->n_theme_dir ++; - if (inherits) { - char *i = inherits; - for (;;) { - size_t k = strcspn(i, ", "); + if (inherits) { + char *i = inherits; + for (;;) { + size_t k = strcspn(i, ", "); - if (k > 0) { - char *p; + if (k > 0) { + char *p; - if (!(p = ca_strndup(i, k))) { - ret = CA_ERROR_OOM; - goto fail; - } + if (!(p = ca_strndup(i, k))) { + ret = CA_ERROR_OOM; + goto fail; + } - ret = load_theme_dir(t, p); - ca_free(p); + ret = load_theme_dir(t, p); + ca_free(p); - if (ret != CA_SUCCESS) - goto fail; - } + if (ret != CA_SUCCESS) + goto fail; + } - if (i[k] == 0) - break; + if (i[k] == 0) + break; - i += k+1; + i += k+1; + } } - } - ret = CA_SUCCESS; + ret = CA_SUCCESS; fail: - ca_free(inherits); - fclose(f); + ca_free(inherits); + fclose(f); - return ret; + return ret; } const char *ca_get_data_dirs(void) { - const char *g; + const char *g; - if (!(g = getenv("XDG_DATA_DIRS")) || *g == 0) - return "/usr/local/share:/usr/share"; + if (!(g = getenv("XDG_DATA_DIRS")) || *g == 0) + return "/usr/local/share:/usr/share"; - return g; + return g; } static int load_theme_dir(ca_theme_data *t, const char *name) { - int ret; - char *e; - const char *g; + int ret; + char *e; + const char *g; - ca_return_val_if_fail(t, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); - ca_return_val_if_fail(t->n_theme_dir < N_THEME_DIR_MAX, CA_ERROR_CORRUPT); + ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); + ca_return_val_if_fail(t->n_theme_dir < N_THEME_DIR_MAX, CA_ERROR_CORRUPT); - if (ca_streq(name, FALLBACK_THEME)) - t->loaded_fallback_theme = TRUE; + if (ca_streq(name, FALLBACK_THEME)) + t->loaded_fallback_theme = TRUE; - if ((ret = ca_get_data_home(&e)) < 0) - return ret; + if ((ret = ca_get_data_home(&e)) < 0) + return ret; - if (e) { - ret = load_theme_path(t, e, name); - ca_free(e); + if (e) { + ret = load_theme_path(t, e, name); + ca_free(e); - if (ret != CA_ERROR_NOTFOUND) - return ret; - } + if (ret != CA_ERROR_NOTFOUND) + return ret; + } - g = ca_get_data_dirs(); + g = ca_get_data_dirs(); - for (;;) { - size_t k; + for (;;) { + size_t k; - k = strcspn(g, ":"); + k = strcspn(g, ":"); - if (g[0] == '/' && k > 0) { - char *p; + if (g[0] == '/' && k > 0) { + char *p; - if (!(p = ca_strndup(g, k))) - return CA_ERROR_OOM; + if (!(p = ca_strndup(g, k))) + return CA_ERROR_OOM; - ret = load_theme_path(t, p, name); - ca_free(p); + ret = load_theme_path(t, p, name); + ca_free(p); - if (ret != CA_ERROR_NOTFOUND) - return ret; - } + if (ret != CA_ERROR_NOTFOUND) + return ret; + } - if (g[k] == 0) - break; + if (g[k] == 0) + break; - g += k+1; - } + g += k+1; + } - return CA_ERROR_NOTFOUND; + return CA_ERROR_NOTFOUND; } static int load_theme_data(ca_theme_data **_t, const char *name) { - ca_theme_data *t; - int ret; + ca_theme_data *t; + int ret; - ca_return_val_if_fail(_t, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); + ca_return_val_if_fail(_t, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); - if (*_t) - if (ca_streq((*_t)->name, name)) - return CA_SUCCESS; + if (*_t) + if (ca_streq((*_t)->name, name)) + return CA_SUCCESS; - if (!(t = ca_new0(ca_theme_data, 1))) - return CA_ERROR_OOM; + if (!(t = ca_new0(ca_theme_data, 1))) + return CA_ERROR_OOM; - if (!(t->name = ca_strdup(name))) { - ret = CA_ERROR_OOM; - goto fail; - } + if (!(t->name = ca_strdup(name))) { + ret = CA_ERROR_OOM; + goto fail; + } - if ((ret = load_theme_dir(t, name)) < 0) - goto fail; + if ((ret = load_theme_dir(t, name)) < 0) + goto fail; - /* The fallback theme may intentionally not exist so ignore failure */ - if (!t->loaded_fallback_theme) - load_theme_dir(t, FALLBACK_THEME); + /* The fallback theme may intentionally not exist so ignore failure */ + if (!t->loaded_fallback_theme) + load_theme_dir(t, FALLBACK_THEME); - if (*_t) - ca_theme_data_free(*_t); + if (*_t) + ca_theme_data_free(*_t); - *_t = t; + *_t = t; - return CA_SUCCESS; + return CA_SUCCESS; fail: - if (t) - ca_theme_data_free(t); + if (t) + ca_theme_data_free(t); - return ret; + return ret; } static int find_sound_for_suffix( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme_name, - const char *name, - const char *path, - const char *suffix, - const char *locale, - const char *subdir) { - - char *fn; - int ret; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); - ca_return_val_if_fail(path, CA_ERROR_INVALID); - ca_return_val_if_fail(path[0] == '/', CA_ERROR_INVALID); - - if (!(fn = ca_sprintf_malloc("%s%s%s%s%s%s%s/%s%s", - path, - theme_name ? "/" : "", - theme_name ? theme_name : "", - subdir ? "/" : "", - subdir ? subdir : "", - locale ? "/" : "", - locale ? locale : "", - name, suffix))) - return CA_ERROR_OOM; - - if (ca_streq(suffix, ".disabled")) { - - if (access(fn, F_OK) == 0) - ret = CA_ERROR_DISABLED; - else - ret = errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme_name, + const char *name, + const char *path, + const char *suffix, + const char *locale, + const char *subdir) { + + char *fn; + int ret; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); + ca_return_val_if_fail(path, CA_ERROR_INVALID); + ca_return_val_if_fail(path[0] == '/', CA_ERROR_INVALID); + + if (!(fn = ca_sprintf_malloc("%s%s%s%s%s%s%s/%s%s", + path, + theme_name ? "/" : "", + theme_name ? theme_name : "", + subdir ? "/" : "", + subdir ? subdir : "", + locale ? "/" : "", + locale ? locale : "", + name, suffix))) + return CA_ERROR_OOM; - } else - ret = sfopen(f, fn); + if (ca_streq(suffix, ".disabled")) { - if (ret == CA_SUCCESS && sound_path) - *sound_path = fn; - else - ca_free(fn); + if (access(fn, F_OK) == 0) + ret = CA_ERROR_DISABLED; + else + ret = errno == ENOENT ? CA_ERROR_NOTFOUND : CA_ERROR_SYSTEM; - return ret; -} - -static int find_sound_in_locale( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme_name, - const char *name, - const char *path, - const char *locale, - const char *subdir) { + } else + ret = sfopen(f, fn); - int ret; - char *p; + if (ret == CA_SUCCESS && sound_path) + *sound_path = fn; + else + ca_free(fn); - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - ca_return_val_if_fail(path, CA_ERROR_INVALID); - ca_return_val_if_fail(path[0] == '/', CA_ERROR_INVALID); + return ret; +} - if (!(p = ca_new(char, strlen(path) + sizeof("/sounds")))) - return CA_ERROR_OOM; +static int find_sound_in_locale( + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme_name, + const char *name, + const char *path, + const char *locale, + const char *subdir) { + + int ret; + char *p; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); + ca_return_val_if_fail(path, CA_ERROR_INVALID); + ca_return_val_if_fail(path[0] == '/', CA_ERROR_INVALID); + + if (!(p = ca_new(char, strlen(path) + sizeof("/sounds")))) + return CA_ERROR_OOM; - sprintf(p, "%s/sounds", path); + sprintf(p, "%s/sounds", path); - if ((ret = find_sound_for_suffix(f, sfopen, sound_path, theme_name, name, p, ".disabled", locale, subdir)) == CA_ERROR_NOTFOUND) - if ((ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".oga", locale, subdir)) == CA_ERROR_NOTFOUND) - if ((ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".ogg", locale, subdir)) == CA_ERROR_NOTFOUND) - ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".wav", locale, subdir); + if ((ret = find_sound_for_suffix(f, sfopen, sound_path, theme_name, name, p, ".disabled", locale, subdir)) == CA_ERROR_NOTFOUND) + if ((ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".oga", locale, subdir)) == CA_ERROR_NOTFOUND) + if ((ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".ogg", locale, subdir)) == CA_ERROR_NOTFOUND) + ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".wav", locale, subdir); - ca_free(p); + ca_free(p); - return ret; + return ret; } static int find_sound_for_locale( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme_name, - const char *name, - const char *path, - const char *locale, - const char *subdir) { - - const char *e; - int ret; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - ca_return_val_if_fail(path, CA_ERROR_INVALID); - ca_return_val_if_fail(locale, CA_ERROR_INVALID); - - /* First, try the locale def itself */ - if ((ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) - return ret; + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme_name, + const char *name, + const char *path, + const char *locale, + const char *subdir) { + + const char *e; + int ret; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); + ca_return_val_if_fail(path, CA_ERROR_INVALID); + ca_return_val_if_fail(locale, CA_ERROR_INVALID); + + /* First, try the locale def itself */ + if ((ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) + return ret; - /* Then, try to truncate at the @ */ - if ((e = strchr(locale, '@'))) { - char *t; + /* Then, try to truncate at the @ */ + if ((e = strchr(locale, '@'))) { + char *t; - if (!(t = ca_strndup(locale, (size_t) (e - locale)))) - return CA_ERROR_OOM; + if (!(t = ca_strndup(locale, (size_t) (e - locale)))) + return CA_ERROR_OOM; - ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, t, subdir); - ca_free(t); + ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, t, subdir); + ca_free(t); - if (ret != CA_ERROR_NOTFOUND) - return ret; - } + if (ret != CA_ERROR_NOTFOUND) + return ret; + } - /* Followed by truncating at the _ */ - if ((e = strchr(locale, '_'))) { - char *t; + /* Followed by truncating at the _ */ + if ((e = strchr(locale, '_'))) { + char *t; - if (!(t = ca_strndup(locale, (size_t) (e - locale)))) - return CA_ERROR_OOM; + if (!(t = ca_strndup(locale, (size_t) (e - locale)))) + return CA_ERROR_OOM; - ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, t, subdir); - ca_free(t); + ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, t, subdir); + ca_free(t); - if (ret != CA_ERROR_NOTFOUND) - return ret; - } + if (ret != CA_ERROR_NOTFOUND) + return ret; + } - /* Then, try "C" as fallback locale */ - if (strcmp(locale, "C")) - if ((ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, "C", subdir)) != CA_ERROR_NOTFOUND) - return ret; + /* Then, try "C" as fallback locale */ + if (strcmp(locale, "C")) + if ((ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, "C", subdir)) != CA_ERROR_NOTFOUND) + return ret; - /* Try without locale */ - return find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, NULL, subdir); + /* Try without locale */ + return find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, NULL, subdir); } static int find_sound_for_name( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme_name, - const char *name, - const char *path, - const char *locale, - const char *subdir) { - - int ret; - const char *k; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - - if ((ret = find_sound_for_locale(f, sfopen, sound_path, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) - return ret; + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme_name, + const char *name, + const char *path, + const char *locale, + const char *subdir) { + + int ret; + const char *k; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); + + if ((ret = find_sound_for_locale(f, sfopen, sound_path, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) + return ret; - k = strchr(name, 0); - for (;;) { - char *n; + k = strchr(name, 0); + for (;;) { + char *n; - do { - k--; + do { + k--; - if (k <= name) - return CA_ERROR_NOTFOUND; + if (k <= name) + return CA_ERROR_NOTFOUND; - } while (*k != '-'); + } while (*k != '-'); - if (!(n = ca_strndup(name, (size_t) (k-name)))) - return CA_ERROR_OOM; + if (!(n = ca_strndup(name, (size_t) (k-name)))) + return CA_ERROR_OOM; - if ((ret = find_sound_for_locale(f, sfopen, sound_path, theme_name, n, path, locale, subdir)) != CA_ERROR_NOTFOUND) { - ca_free(n); - return ret; - } + if ((ret = find_sound_for_locale(f, sfopen, sound_path, theme_name, n, path, locale, subdir)) != CA_ERROR_NOTFOUND) { + ca_free(n); + return ret; + } - ca_free(n); - } + ca_free(n); + } } static int find_sound_in_subdir( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - const char *theme_name, - const char *name, - const char *locale, - const char *subdir) { - - int ret; - char *e = NULL; - const char *g; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); - - if ((ret = ca_get_data_home(&e)) < 0) - return ret; + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + const char *theme_name, + const char *name, + const char *locale, + const char *subdir) { + + int ret; + char *e = NULL; + const char *g; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); + + if ((ret = ca_get_data_home(&e)) < 0) + return ret; - if (e) { - ret = find_sound_for_name(f, sfopen, sound_path, theme_name, name, e, locale, subdir); - ca_free(e); + if (e) { + ret = find_sound_for_name(f, sfopen, sound_path, theme_name, name, e, locale, subdir); + ca_free(e); - if (ret != CA_ERROR_NOTFOUND) - return ret; - } + if (ret != CA_ERROR_NOTFOUND) + return ret; + } - g = ca_get_data_dirs(); + g = ca_get_data_dirs(); - for (;;) { - size_t k; + for (;;) { + size_t k; - k = strcspn(g, ":"); + k = strcspn(g, ":"); - if (g[0] == '/' && k > 0) { - char *p; + if (g[0] == '/' && k > 0) { + char *p; - if (!(p = ca_strndup(g, k))) - return CA_ERROR_OOM; + if (!(p = ca_strndup(g, k))) + return CA_ERROR_OOM; - ret = find_sound_for_name(f, sfopen, sound_path, theme_name, name, p, locale, subdir); - ca_free(p); + ret = find_sound_for_name(f, sfopen, sound_path, theme_name, name, p, locale, subdir); + ca_free(p); - if (ret != CA_ERROR_NOTFOUND) - return ret; - } + if (ret != CA_ERROR_NOTFOUND) + return ret; + } - if (g[k] == 0) - break; + if (g[k] == 0) + break; - g += k+1; - } + g += k+1; + } - return CA_ERROR_NOTFOUND; + return CA_ERROR_NOTFOUND; } static int find_sound_in_profile( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - ca_theme_data *t, - const char *name, - const char *locale, - const char *profile) { - - ca_data_dir *d; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(t, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); - - for (d = t->data_dirs; d; d = d->next) - if (data_dir_matches(d, profile)) { - int ret; - - if ((ret = find_sound_in_subdir(f, sfopen, sound_path, d->theme_name, name, locale, d->dir_name)) != CA_ERROR_NOTFOUND) - return ret; - } + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + ca_theme_data *t, + const char *name, + const char *locale, + const char *profile) { + + ca_data_dir *d; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); + + for (d = t->data_dirs; d; d = d->next) + if (data_dir_matches(d, profile)) { + int ret; + + if ((ret = find_sound_in_subdir(f, sfopen, sound_path, d->theme_name, name, locale, d->dir_name)) != CA_ERROR_NOTFOUND) + return ret; + } - return CA_ERROR_NOTFOUND; + return CA_ERROR_NOTFOUND; } static int find_sound_in_theme( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - ca_theme_data *t, - const char *name, - const char *locale, - const char *profile) { - - int ret; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(name, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(profile, CA_ERROR_INVALID); - - if (t) { - /* First, try the profile def itself */ - if ((ret = find_sound_in_profile(f, sfopen, sound_path, t, name, locale, profile)) != CA_ERROR_NOTFOUND) - return ret; - - /* Then, fall back to stereo */ - if (!ca_streq(profile, DEFAULT_OUTPUT_PROFILE)) - if ((ret = find_sound_in_profile(f, sfopen, sound_path, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND) - return ret; - } + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + ca_theme_data *t, + const char *name, + const char *locale, + const char *profile) { + + int ret; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(name, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(profile, CA_ERROR_INVALID); + + if (t) { + /* First, try the profile def itself */ + if ((ret = find_sound_in_profile(f, sfopen, sound_path, t, name, locale, profile)) != CA_ERROR_NOTFOUND) + return ret; + + /* Then, fall back to stereo */ + if (!ca_streq(profile, DEFAULT_OUTPUT_PROFILE)) + if ((ret = find_sound_in_profile(f, sfopen, sound_path, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND) + return ret; + } - /* And fall back to no profile */ - return find_sound_in_subdir(f, sfopen, sound_path, t ? t->name : NULL, name, locale, NULL); + /* And fall back to no profile */ + return find_sound_in_subdir(f, sfopen, sound_path, t ? t->name : NULL, name, locale, NULL); } static int find_sound_for_theme( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - ca_theme_data **t, - const char *theme, - const char *name, - const char *locale, - const char *profile) { - - int ret; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(t, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - ca_return_val_if_fail(theme, CA_ERROR_INVALID); - ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - ca_return_val_if_fail(locale, CA_ERROR_INVALID); - ca_return_val_if_fail(profile, CA_ERROR_INVALID); - - /* First, try in the theme itself, and if that fails the fallback theme */ - if ((ret = load_theme_data(t, theme)) == CA_ERROR_NOTFOUND) - if (!ca_streq(theme, FALLBACK_THEME)) - ret = load_theme_data(t, FALLBACK_THEME); - - if (ret == CA_SUCCESS) - if ((ret = find_sound_in_theme(f, sfopen, sound_path, *t, name, locale, profile)) != CA_ERROR_NOTFOUND) - return ret; - - /* Then, fall back to "unthemed" files */ - return find_sound_in_theme(f, sfopen, sound_path, NULL, name, locale, profile); + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + ca_theme_data **t, + const char *theme, + const char *name, + const char *locale, + const char *profile) { + + int ret; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + ca_return_val_if_fail(theme, CA_ERROR_INVALID); + ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); + ca_return_val_if_fail(locale, CA_ERROR_INVALID); + ca_return_val_if_fail(profile, CA_ERROR_INVALID); + + /* First, try in the theme itself, and if that fails the fallback theme */ + if ((ret = load_theme_data(t, theme)) == CA_ERROR_NOTFOUND) + if (!ca_streq(theme, FALLBACK_THEME)) + ret = load_theme_data(t, FALLBACK_THEME); + + if (ret == CA_SUCCESS) + if ((ret = find_sound_in_theme(f, sfopen, sound_path, *t, name, locale, profile)) != CA_ERROR_NOTFOUND) + return ret; + + /* Then, fall back to "unthemed" files */ + return find_sound_in_theme(f, sfopen, sound_path, NULL, name, locale, profile); } int ca_lookup_sound_with_callback( - ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - char **sound_path, - ca_theme_data **t, - ca_proplist *cp, - ca_proplist *sp) { - int ret = CA_ERROR_INVALID; - const char *name, *fname; - - ca_return_val_if_fail(f, CA_ERROR_INVALID); - ca_return_val_if_fail(t, CA_ERROR_INVALID); - ca_return_val_if_fail(cp, CA_ERROR_INVALID); - ca_return_val_if_fail(sp, CA_ERROR_INVALID); - ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); - - *f = NULL; - - if (sound_path) - *sound_path = NULL; - - ca_mutex_lock(cp->mutex); - ca_mutex_lock(sp->mutex); - - if ((name = ca_proplist_gets_unlocked(sp, CA_PROP_EVENT_ID))) { - const char *theme, *locale, *profile; - - if (!(theme = ca_proplist_gets_unlocked(sp, CA_PROP_CANBERRA_XDG_THEME_NAME))) - if (!(theme = ca_proplist_gets_unlocked(cp, CA_PROP_CANBERRA_XDG_THEME_NAME))) - theme = DEFAULT_THEME; - - if (!(locale = ca_proplist_gets_unlocked(sp, CA_PROP_MEDIA_LANGUAGE))) - if (!(locale = ca_proplist_gets_unlocked(sp, CA_PROP_APPLICATION_LANGUAGE))) - if (!(locale = ca_proplist_gets_unlocked(cp, CA_PROP_MEDIA_LANGUAGE))) - if (!(locale = ca_proplist_gets_unlocked(cp, CA_PROP_APPLICATION_LANGUAGE))) - if (!(locale = setlocale(LC_MESSAGES, NULL))) - locale = "C"; - - if (!(profile = ca_proplist_gets_unlocked(sp, CA_PROP_CANBERRA_XDG_THEME_OUTPUT_PROFILE))) - if (!(profile = ca_proplist_gets_unlocked(cp, CA_PROP_CANBERRA_XDG_THEME_OUTPUT_PROFILE))) - profile = DEFAULT_OUTPUT_PROFILE; + ca_sound_file **f, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + ca_theme_data **t, + ca_proplist *cp, + ca_proplist *sp) { + int ret = CA_ERROR_INVALID; + const char *name, *fname; + + ca_return_val_if_fail(f, CA_ERROR_INVALID); + ca_return_val_if_fail(t, CA_ERROR_INVALID); + ca_return_val_if_fail(cp, CA_ERROR_INVALID); + ca_return_val_if_fail(sp, CA_ERROR_INVALID); + ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + + *f = NULL; + + if (sound_path) + *sound_path = NULL; + + ca_mutex_lock(cp->mutex); + ca_mutex_lock(sp->mutex); + + if ((name = ca_proplist_gets_unlocked(sp, CA_PROP_EVENT_ID))) { + const char *theme, *locale, *profile; + + if (!(theme = ca_proplist_gets_unlocked(sp, CA_PROP_CANBERRA_XDG_THEME_NAME))) + if (!(theme = ca_proplist_gets_unlocked(cp, CA_PROP_CANBERRA_XDG_THEME_NAME))) + theme = DEFAULT_THEME; + + if (!(locale = ca_proplist_gets_unlocked(sp, CA_PROP_MEDIA_LANGUAGE))) + if (!(locale = ca_proplist_gets_unlocked(sp, CA_PROP_APPLICATION_LANGUAGE))) + if (!(locale = ca_proplist_gets_unlocked(cp, CA_PROP_MEDIA_LANGUAGE))) + if (!(locale = ca_proplist_gets_unlocked(cp, CA_PROP_APPLICATION_LANGUAGE))) + if (!(locale = setlocale(LC_MESSAGES, NULL))) + locale = "C"; + + if (!(profile = ca_proplist_gets_unlocked(sp, CA_PROP_CANBERRA_XDG_THEME_OUTPUT_PROFILE))) + if (!(profile = ca_proplist_gets_unlocked(cp, CA_PROP_CANBERRA_XDG_THEME_OUTPUT_PROFILE))) + profile = DEFAULT_OUTPUT_PROFILE; #ifdef HAVE_CACHE - if ((ret = ca_cache_lookup_sound(f, sfopen, sound_path, theme, name, locale, profile)) >= 0) { + if ((ret = ca_cache_lookup_sound(f, sfopen, sound_path, theme, name, locale, profile)) >= 0) { - /* This entry is available in the cache, let's transform - * negative cache entries to CA_ERROR_NOTFOUND */ + /* This entry is available in the cache, let's transform + * negative cache entries to CA_ERROR_NOTFOUND */ - if (!*f) - ret = CA_ERROR_NOTFOUND; + if (!*f) + ret = CA_ERROR_NOTFOUND; - } else { - char *spath = NULL; + } else { + char *spath = NULL; - /* Either this entry was not available in the database, - * neither positive nor negative, or the database was - * corrupt, or it was out-of-date. In all cases try to - * find the entry manually. */ + /* Either this entry was not available in the database, + * neither positive nor negative, or the database was + * corrupt, or it was out-of-date. In all cases try to + * find the entry manually. */ - if ((ret = find_sound_for_theme(f, sfopen, sound_path ? sound_path : &spath, t, theme, name, locale, profile)) >= 0) - /* Ok, we found it. Let's update the cache */ - ca_cache_store_sound(theme, name, locale, profile, sound_path ? *sound_path : spath); - else if (ret == CA_ERROR_NOTFOUND) - /* Doesn't seem to be around, let's create a negative cache entry */ - ca_cache_store_sound(theme, name, locale, profile, NULL); + if ((ret = find_sound_for_theme(f, sfopen, sound_path ? sound_path : &spath, t, theme, name, locale, profile)) >= 0) + /* Ok, we found it. Let's update the cache */ + ca_cache_store_sound(theme, name, locale, profile, sound_path ? *sound_path : spath); + else if (ret == CA_ERROR_NOTFOUND) + /* Doesn't seem to be around, let's create a negative cache entry */ + ca_cache_store_sound(theme, name, locale, profile, NULL); - ca_free(spath); - } + ca_free(spath); + } #else - ret = find_sound_for_theme(f, sfopen, sound_path, t, theme, name, locale, profile); + ret = find_sound_for_theme(f, sfopen, sound_path, t, theme, name, locale, profile); #endif - } + } - if (ret == CA_ERROR_NOTFOUND || !name) { - if ((fname = ca_proplist_gets_unlocked(sp, CA_PROP_MEDIA_FILENAME))) - ret = sfopen(f, fname); - } + if (ret == CA_ERROR_NOTFOUND || !name) { + if ((fname = ca_proplist_gets_unlocked(sp, CA_PROP_MEDIA_FILENAME))) + ret = sfopen(f, fname); + } - ca_mutex_unlock(cp->mutex); - ca_mutex_unlock(sp->mutex); + ca_mutex_unlock(cp->mutex); + ca_mutex_unlock(sp->mutex); - return ret; + return ret; } int ca_lookup_sound( - ca_sound_file **f, - char **sound_path, - ca_theme_data **t, - ca_proplist *cp, - ca_proplist *sp) { + ca_sound_file **f, + char **sound_path, + ca_theme_data **t, + ca_proplist *cp, + ca_proplist *sp) { - return ca_lookup_sound_with_callback(f, ca_sound_file_open, sound_path, t, cp, sp); + return ca_lookup_sound_with_callback(f, ca_sound_file_open, sound_path, t, cp, sp); } void ca_theme_data_free(ca_theme_data *t) { - ca_assert(t); + ca_assert(t); - while (t->data_dirs) { - ca_data_dir *d = t->data_dirs; + while (t->data_dirs) { + ca_data_dir *d = t->data_dirs; - CA_LLIST_REMOVE(ca_data_dir, t->data_dirs, d); + CA_LLIST_REMOVE(ca_data_dir, t->data_dirs, d); - ca_free(d->theme_name); - ca_free(d->dir_name); - ca_free(d->output_profile); - ca_free(d); - } + ca_free(d->theme_name); + ca_free(d->dir_name); + ca_free(d->output_profile); + ca_free(d); + } - ca_free(t->name); - ca_free(t); + ca_free(t->name); + ca_free(t); } diff --git a/src/sound-theme-spec.h b/src/sound-theme-spec.h index c80142d..b44821a 100644 --- a/src/sound-theme-spec.h +++ b/src/sound-theme-spec.h @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + #ifndef foocanberrasoundthemespechfoo #define foocanberrasoundthemespechfoo diff --git a/src/test-canberra.c b/src/test-canberra.c index d87e276..e384803 100644 --- a/src/test-canberra.c +++ b/src/test-canberra.c @@ -1,3 +1,5 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + /*** This file is part of libcanberra. @@ -18,7 +20,6 @@ . ***/ - #ifdef HAVE_CONFIG_H #include #endif @@ -31,74 +32,74 @@ #include "canberra.h" static void callback(ca_context *c, uint32_t id, int error, void *userdata) { - fprintf(stderr, "callback called for id %u, error '%s', userdata=%p\n", id, ca_strerror(error), userdata); + fprintf(stderr, "callback called for id %u, error '%s', userdata=%p\n", id, ca_strerror(error), userdata); } int main(int argc, char *argv[]) { - ca_context *c; - ca_proplist *p; - int ret; - - setlocale(LC_ALL, ""); - - ret = ca_context_create(&c); - fprintf(stderr, "create: %s\n", ca_strerror(ret)); - - /* Initialize a few meta variables for the following play() - * calls. They stay valid until they are overwritten with - * ca_context_change_props() again. */ - ret = ca_context_change_props(c, - CA_PROP_APPLICATION_NAME, "An example", - CA_PROP_APPLICATION_ID, "org.freedesktop.libcanberra.Test", - CA_PROP_WINDOW_X11_SCREEN, getenv("DISPLAY"), - NULL); - fprintf(stderr, "change_props: %s\n", ca_strerror(ret)); - - ret = ca_context_open(c); - fprintf(stderr, "open: %s\n", ca_strerror(ret)); - - /* Now trigger a sound event, the quick version */ - ret = ca_context_play(c, 0, - CA_PROP_EVENT_ID, "desktop-login", - CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/bar.wav", - CA_PROP_MEDIA_NAME, "User has logged off from session", - CA_PROP_MEDIA_LANGUAGE, "en_EN", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - fprintf(stderr, "play: %s\n", ca_strerror(ret)); - - /* Now trigger a sound event, the complex version */ - ca_proplist_create(&p); - ca_proplist_sets(p, CA_PROP_EVENT_ID, "desktop-logout"); - ca_proplist_sets(p, CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/uxknkurz.wav"); - ca_proplist_sets(p, CA_PROP_MEDIA_NAME, "New email received"); - ca_proplist_setf(p, "test.foo", "%u", 4711); - ret = ca_context_play_full(c, 1, p, callback, (void*) 0x4711); - ca_proplist_destroy(p); - fprintf(stderr, "play_full: %s\n", ca_strerror(ret)); - - /* Now trigger a sound event, by filename */ - ret = ca_context_play(c, 2, - CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/freedesktop/stereo/audio-channel-front-left.ogg", - CA_PROP_MEDIA_NAME, "Front Left", - CA_PROP_MEDIA_LANGUAGE, "en_EN", - NULL); - fprintf(stderr, "play (by filename): %s\n", ca_strerror(ret)); - - fprintf(stderr, "Sleep half a second ...\n"); - usleep(500000); - - /* Stop one sound */ + ca_context *c; + ca_proplist *p; + int ret; + + setlocale(LC_ALL, ""); + + ret = ca_context_create(&c); + fprintf(stderr, "create: %s\n", ca_strerror(ret)); + + /* Initialize a few meta variables for the following play() + * calls. They stay valid until they are overwritten with + * ca_context_change_props() again. */ + ret = ca_context_change_props(c, + CA_PROP_APPLICATION_NAME, "An example", + CA_PROP_APPLICATION_ID, "org.freedesktop.libcanberra.Test", + CA_PROP_WINDOW_X11_SCREEN, getenv("DISPLAY"), + NULL); + fprintf(stderr, "change_props: %s\n", ca_strerror(ret)); + + ret = ca_context_open(c); + fprintf(stderr, "open: %s\n", ca_strerror(ret)); + + /* Now trigger a sound event, the quick version */ + ret = ca_context_play(c, 0, + CA_PROP_EVENT_ID, "desktop-login", + CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/bar.wav", + CA_PROP_MEDIA_NAME, "User has logged off from session", + CA_PROP_MEDIA_LANGUAGE, "en_EN", + CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", + NULL); + fprintf(stderr, "play: %s\n", ca_strerror(ret)); + + /* Now trigger a sound event, the complex version */ + ca_proplist_create(&p); + ca_proplist_sets(p, CA_PROP_EVENT_ID, "desktop-logout"); + ca_proplist_sets(p, CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/uxknkurz.wav"); + ca_proplist_sets(p, CA_PROP_MEDIA_NAME, "New email received"); + ca_proplist_setf(p, "test.foo", "%u", 4711); + ret = ca_context_play_full(c, 1, p, callback, (void*) 0x4711); + ca_proplist_destroy(p); + fprintf(stderr, "play_full: %s\n", ca_strerror(ret)); + + /* Now trigger a sound event, by filename */ + ret = ca_context_play(c, 2, + CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/freedesktop/stereo/audio-channel-front-left.ogg", + CA_PROP_MEDIA_NAME, "Front Left", + CA_PROP_MEDIA_LANGUAGE, "en_EN", + NULL); + fprintf(stderr, "play (by filename): %s\n", ca_strerror(ret)); + + fprintf(stderr, "Sleep half a second ...\n"); + usleep(500000); + + /* Stop one sound */ /* ret = ca_context_cancel(c, 0); */ /* fprintf(stderr, "cancel: %s\n", ca_strerror(ret)); */ - fprintf(stderr, "Sleep 2s ...\n"); - sleep(2); + fprintf(stderr, "Sleep 2s ...\n"); + sleep(2); - /* .. */ + /* .. */ - ret = ca_context_destroy(c); - fprintf(stderr, "destroy: %s\n", ca_strerror(ret)); + ret = ca_context_destroy(c); + fprintf(stderr, "destroy: %s\n", ca_strerror(ret)); - return 0; + return 0; } -- cgit