summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/macro.h2
-rw-r--r--src/read-wav.c2
-rw-r--r--src/sound-theme-spec.c273
3 files changed, 166 insertions, 111 deletions
diff --git a/src/macro.h b/src/macro.h
index 4b9324f..db8affe 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -28,7 +28,7 @@
#error "Please include config.h before including this file!"
#endif
-#ifdef __GNUC__
+#if defined (__GNUC__) && __GNUC__ >= 3
#define CA_LIKELY(x) (__builtin_expect(!!(x),1))
#define CA_UNLIKELY(x) (__builtin_expect((x),0))
#else
diff --git a/src/read-wav.c b/src/read-wav.c
index 792b913..23c0e7e 100644
--- a/src/read-wav.c
+++ b/src/read-wav.c
@@ -244,7 +244,7 @@ int ca_wav_read_u8(ca_wav *w, uint8_t *d, unsigned *n) {
if (*n <= 0 && ferror(w->file))
return CA_ERROR_SYSTEM;
- ca_assert(w->data_size >= *n * sizeof(int16_t));
+ ca_assert(w->data_size >= *n * sizeof(uint8_t));
w->data_size -= *n * sizeof(uint8_t);
}
diff --git a/src/sound-theme-spec.c b/src/sound-theme-spec.c
index 485acb3..611b008 100644
--- a/src/sound-theme-spec.c
+++ b/src/sound-theme-spec.c
@@ -23,6 +23,8 @@
#endif
#include <errno.h>
+#include <unistd.h>
+
#include <locale.h>
#include "sound-theme-spec.h"
@@ -82,6 +84,9 @@ static ca_bool_t data_dir_matches(ca_data_dir *d, const char*output_profile) {
/* We might want to add more elaborate matching here eventually */
+ if (!d->output_profile)
+ return TRUE;
+
return ca_streq(d->output_profile, output_profile);
}
@@ -391,7 +396,15 @@ fail:
return ret;
}
-static int find_sound_for_suffix(ca_sound_file **f, ca_theme_data *t, const char *name, const char *path, const char *suffix, const char *locale, const char *subdir) {
+static int find_sound_for_suffix(
+ ca_sound_file **f,
+ ca_theme_data *t,
+ const char *name,
+ const char *path,
+ const char *suffix,
+ const char *locale,
+ const char *subdir) {
+
char *fn;
int ret;
@@ -399,7 +412,6 @@ static int find_sound_for_suffix(ca_sound_file **f, ca_theme_data *t, const char
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);
- ca_return_val_if_fail(suffix, CA_ERROR_INVALID);
if (!(fn = ca_sprintf_malloc("%s%s%s%s%s%s%s/%s%s",
path,
@@ -412,18 +424,34 @@ static int find_sound_for_suffix(ca_sound_file **f, ca_theme_data *t, const char
name, suffix)))
return CA_ERROR_OOM;
- ret = ca_sound_file_open(f, fn);
+ 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;
+
+ } else
+ ret = ca_sound_file_open(f, fn);
+
ca_free(fn);
return ret;
}
-static int find_sound_in_path(ca_sound_file **f, ca_theme_data *t, const char *name, const char *path, const char *locale, const char *subdir) {
+static int find_sound_in_locale(
+ ca_sound_file **f,
+ ca_theme_data *t,
+ 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(name, 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);
@@ -432,15 +460,120 @@ static int find_sound_in_path(ca_sound_file **f, ca_theme_data *t, const char *n
sprintf(p, "%s/sounds", path);
- if ((ret = find_sound_for_suffix(f, t, name, p, ".ogg", locale, subdir)) == CA_ERROR_NOTFOUND)
- ret = find_sound_for_suffix(f, t, name, p, ".wav", locale, subdir);
+ if ((ret = find_sound_for_suffix(f, t, name, p, ".disabled", locale, subdir)) == CA_ERROR_NOTFOUND)
+ if ((ret = find_sound_for_suffix(f, t, name, p, ".ogg", locale, subdir)) == CA_ERROR_NOTFOUND)
+ ret = find_sound_for_suffix(f, t, name, p, ".wav", locale, subdir);
ca_free(p);
return ret;
}
-static int find_sound_in_subdir(ca_sound_file **f, ca_theme_data *t, const char *name, const char *locale, const char *subdir) {
+static int find_sound_for_locale(
+ ca_sound_file **f,
+ ca_theme_data *theme,
+ 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(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, theme, name, path, locale, subdir)) != CA_ERROR_NOTFOUND)
+ return ret;
+
+ /* Then, try to truncate at the @ */
+ if ((e = strchr(locale, '@'))) {
+ char *t;
+
+ if (!(t = ca_strndup(locale, e - locale)))
+ return CA_ERROR_OOM;
+
+ ret = find_sound_in_locale(f, theme, name, path, t, subdir);
+ ca_free(t);
+
+ if (ret != CA_ERROR_NOTFOUND)
+ return ret;
+ }
+
+ /* Followed by truncating at the _ */
+ if ((e = strchr(locale, '_'))) {
+ char *t;
+
+ if (!(t = ca_strndup(locale, e - locale)))
+ return CA_ERROR_OOM;
+
+ ret = find_sound_in_locale(f, theme, name, path, t, subdir);
+ ca_free(t);
+
+ if (ret != CA_ERROR_NOTFOUND)
+ return ret;
+ }
+
+ /* Then, try "C" as fallback locale */
+ if (strcmp(locale, "C"))
+ if ((ret = find_sound_in_locale(f, theme, name, path, "C", subdir)) != CA_ERROR_NOTFOUND)
+ return ret;
+
+ /* Try without locale */
+ return find_sound_in_locale(f, theme, name, path, NULL, subdir);
+}
+
+static int find_sound_for_name(
+ ca_sound_file **f,
+ ca_theme_data *t,
+ 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(name && *name, CA_ERROR_INVALID);
+
+ if ((ret = find_sound_for_locale(f, t, name, path, locale, subdir)) != CA_ERROR_NOTFOUND)
+ return ret;
+
+ k = strchr(name, 0);
+ for (;;) {
+ char *n;
+
+ do {
+ k--;
+
+ if (k <= name)
+ return CA_ERROR_NOTFOUND;
+
+ } while (*k != '-');
+
+ if (!(n = ca_strndup(name, k-name)))
+ return CA_ERROR_OOM;
+
+ if ((ret = find_sound_for_locale(f, t, n, path, locale, subdir)) != CA_ERROR_NOTFOUND) {
+ ca_free(n);
+ return ret;
+ }
+
+ ca_free(n);
+ }
+}
+
+static int find_sound_in_subdir(
+ ca_sound_file **f,
+ ca_theme_data *t,
+ const char *name,
+ const char *locale,
+ const char *subdir) {
+
int ret;
char *e = NULL;
const char *g;
@@ -452,7 +585,7 @@ static int find_sound_in_subdir(ca_sound_file **f, ca_theme_data *t, const char
return ret;
if (e) {
- ret = find_sound_in_path(f, t, name, e, locale, subdir);
+ ret = find_sound_for_name(f, t, name, e, locale, subdir);
ca_free(e);
if (ret != CA_ERROR_NOTFOUND)
@@ -473,7 +606,7 @@ static int find_sound_in_subdir(ca_sound_file **f, ca_theme_data *t, const char
if (!(p = ca_strndup(g, k)))
return CA_ERROR_OOM;
- ret = find_sound_in_path(f, t, name, p, locale, subdir);
+ ret = find_sound_for_name(f, t, name, p, locale, subdir);
ca_free(p);
if (ret != CA_ERROR_NOTFOUND)
@@ -489,7 +622,13 @@ static int find_sound_in_subdir(ca_sound_file **f, ca_theme_data *t, const char
return CA_ERROR_NOTFOUND;
}
-static int find_sound_for_profile(ca_sound_file **f, ca_theme_data *t, const char *name, const char *locale, const char *profile) {
+static int find_sound_in_profile(
+ ca_sound_file **f,
+ 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);
@@ -507,7 +646,13 @@ static int find_sound_for_profile(ca_sound_file **f, ca_theme_data *t, const cha
return CA_ERROR_NOTFOUND;
}
-static int find_sound_for_subname(ca_sound_file **f, ca_theme_data *t, const char *name, const char *locale, const char *profile) {
+static int find_sound_in_theme(
+ ca_sound_file **f,
+ ca_theme_data *t,
+ const char *name,
+ const char *locale,
+ const char *profile) {
+
int ret;
ca_return_val_if_fail(f, CA_ERROR_INVALID);
@@ -516,12 +661,12 @@ static int find_sound_for_subname(ca_sound_file **f, ca_theme_data *t, const cha
if (t) {
/* First, try the profile def itself */
- if ((ret = find_sound_for_profile(f, t, name, locale, profile)) != CA_ERROR_NOTFOUND)
+ if ((ret = find_sound_in_profile(f, 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_for_profile(f, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND)
+ if ((ret = find_sound_in_profile(f, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND)
return ret;
}
@@ -529,105 +674,15 @@ static int find_sound_for_subname(ca_sound_file **f, ca_theme_data *t, const cha
return find_sound_in_subdir(f, t, name, locale, NULL);
}
-static int find_sound_in_locale(
+static int find_sound_for_theme(
ca_sound_file **f,
- ca_theme_data *t,
+ ca_theme_data **t,
+ const char *theme,
const char *name,
const char *locale,
const char *profile) {
int ret;
- const char *k;
-
- ca_return_val_if_fail(f, CA_ERROR_INVALID);
- ca_return_val_if_fail(name && *name, CA_ERROR_INVALID);
- ca_return_val_if_fail(profile, CA_ERROR_INVALID);
-
- if ((ret = find_sound_for_subname(f, t, name, locale, profile)) != CA_ERROR_NOTFOUND)
- return ret;
-
- k = strchr(name, 0);
- for (;;) {
- char *n;
-
- do {
- k--;
-
- if (k <= name)
- return CA_ERROR_NOTFOUND;
-
- } while (*k != '-');
-
- if (!(n = ca_strndup(name, k-name)))
- return CA_ERROR_OOM;
-
- if ((ret = find_sound_for_subname(f, t, n, locale, profile)) != CA_ERROR_NOTFOUND) {
- ca_free(n);
- return ret;
- }
-
- ca_free(n);
- }
-}
-
-static int find_sound_for_locale(
- ca_sound_file **f,
- ca_theme_data *theme,
- const char *name,
- const char *locale,
- const char *profile) {
-
- const char *e;
- int ret;
-
- ca_return_val_if_fail(f, 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 the locale def itself */
- if ((ret = find_sound_in_locale(f, theme, name, locale, profile)) != CA_ERROR_NOTFOUND)
- return ret;
-
- /* Then, try to truncate at the @ */
- if ((e = strchr(locale, '@'))) {
- char *t;
-
- if (!(t = ca_strndup(locale, e - locale)))
- return CA_ERROR_OOM;
-
- ret = find_sound_in_locale(f, theme, name, t, profile);
- ca_free(t);
-
- if (ret != CA_ERROR_NOTFOUND)
- return ret;
- }
-
- /* Followed by truncating at the _ */
- if ((e = strchr(locale, '_'))) {
- char *t;
-
- if (!(t = ca_strndup(locale, e - locale)))
- return CA_ERROR_OOM;
-
- ret = find_sound_in_locale(f, theme, name, t, profile);
- ca_free(t);
-
- if (ret != CA_ERROR_NOTFOUND)
- return ret;
- }
-
- /* Then, try "C" as fallback locale */
- if (strcmp(locale, "C"))
- if ((ret = find_sound_in_locale(f, theme, name, "C", profile)) != CA_ERROR_NOTFOUND)
- return ret;
-
- /* Try without locale */
- return find_sound_in_locale(f, theme, name, NULL, profile);
-}
-
-static int find_sound_for_theme(ca_sound_file **f, 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);
@@ -642,11 +697,11 @@ static int find_sound_for_theme(ca_sound_file **f, ca_theme_data **t, const char
ret = load_theme_data(t, FALLBACK_THEME);
if (ret == CA_SUCCESS)
- if ((ret = find_sound_for_locale(f, *t, name, locale, profile)) != CA_ERROR_NOTFOUND)
+ if ((ret = find_sound_in_theme(f, *t, name, locale, profile)) != CA_ERROR_NOTFOUND)
return ret;
/* Then, fall back to "unthemed" files */
- return find_sound_for_locale(f, NULL, name, locale, profile);
+ return find_sound_in_theme(f, NULL, name, locale, profile);
}
int ca_lookup_sound(ca_sound_file **f, ca_theme_data **t, ca_proplist *cp, ca_proplist *sp) {