Merge branch 'master' of git://git.0pointer.de/pulseaudio

This commit is contained in:
Colin Guthrie 2008-08-22 10:56:45 +01:00
commit 4282b726ee
196 changed files with 7704 additions and 3300 deletions

1
src/.gitignore vendored
View file

@ -1,3 +1,4 @@
lock-autospawn-test
*.lo
*.o
*.la

View file

@ -56,6 +56,8 @@ AM_CFLAGS += -DPA_SYSTEM_RUNTIME_PATH=\"$(PA_SYSTEM_RUNTIME_PATH)\"
AM_CFLAGS += -DPA_SYSTEM_CONFIG_PATH=\"$(PA_SYSTEM_CONFIG_PATH)\"
AM_CFLAGS += -DPA_SYSTEM_STATE_PATH=\"$(PA_SYSTEM_STATE_PATH)\"
AM_CFLAGS += -DAO_REQUIRE_CAS
AM_CFLAGS += -DPULSE_LOCALEDIR=\"$(pulselocaledir)\"
AM_CFLAGS += -DPA_MACHINE_ID=\"$(localstatedir)/lib/dbus/machine-id\"
# This cool debug trap works on i386/gcc only
AM_CFLAGS += '-DDEBUG_TRAP=__asm__("int $$3")'
@ -260,7 +262,8 @@ noinst_PROGRAMS = \
envelope-test \
proplist-test \
rtstutter \
stripnul
stripnul \
lock-autospawn-test
if HAVE_SIGXCPU
noinst_PROGRAMS += \
@ -450,6 +453,11 @@ stripnul_LDADD = $(AM_LDADD) libpulsecore.la
stripnul_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
stripnul_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
lock_autospawn_test_SOURCES = tests/lock-autospawn-test.c
lock_autospawn_test_LDADD = $(AM_LDADD) libpulsecore.la
lock_autospawn_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
lock_autospawn_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
###################################
# Client library #
###################################
@ -479,7 +487,8 @@ pulseinclude_HEADERS = \
pulse/volume.h \
pulse/xmalloc.h \
pulse/proplist.h \
pulse/gccmacro.h
pulse/gccmacro.h \
pulse/ext-stream-restore.h
if HAVE_AVAHI
pulseinclude_HEADERS += \
@ -530,7 +539,10 @@ libpulse_la_SOURCES = \
pulse/util.c pulse/util.h \
pulse/volume.c pulse/volume.h \
pulse/xmalloc.c pulse/xmalloc.h \
pulse/proplist.c pulse/proplist.h
pulse/proplist.c pulse/proplist.h \
pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
pulse/i18n.c pulse/i18n.h \
pulse/lock-autospawn.c pulse/lock-autospawn.h
# Internal stuff that is shared with libpulsecore
libpulse_la_SOURCES += \
@ -725,7 +737,9 @@ libpulsecore_la_SOURCES = \
pulse/util.c pulse/util.h \
pulse/volume.c pulse/volume.h \
pulse/xmalloc.c pulse/xmalloc.h \
pulse/proplist.c pulse/proplist.h
pulse/proplist.c pulse/proplist.h \
pulse/i18n.c pulse/i18n.h \
pulse/lock-autospawn.c pulse/lock-autospawn.h
# Pure core stuff (some are shared in libpulse though).
libpulsecore_la_SOURCES += \
@ -1609,7 +1623,7 @@ update-ffmpeg:
update-map-file:
( echo "PULSE_0 {" ; \
echo "global:" ; \
ctags -I PA_GCC_PURE,PA_GCC_CONST -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
ctags -I PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
echo "local:" ; \
echo "*;" ; \
echo "};" ) > $(srcdir)/map-file

View file

@ -28,7 +28,12 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <pulse/i18n.h>
#include <pulsecore/macro.h>
#include <pulsecore/core-error.h>
#include <pulsecore/log.h>
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
@ -37,10 +42,6 @@
#include <sys/prctl.h>
#endif
#include <pulsecore/core-error.h>
#include <pulsecore/log.h>
#include "caps.h"
/* Glibc <= 2.2 has broken unistd.h */
@ -58,7 +59,7 @@ void pa_drop_root(void) {
if (uid == 0 || geteuid() != 0)
return;
pa_log_info("Dropping root priviliges.");
pa_log_info(_("Dropping root priviliges."));
#if defined(HAVE_SETRESUID)
pa_assert_se(setresuid(uid, uid, uid) >= 0);
@ -98,7 +99,7 @@ void pa_limit_caps(void) {
* that */
pa_drop_caps();
else
pa_log_info("Limited capabilities successfully to CAP_SYS_NICE.");
pa_log_info(_("Limited capabilities successfully to CAP_SYS_NICE."));
pa_assert_se(cap_free(caps) == 0);

View file

@ -30,6 +30,7 @@
#include <sys/stat.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulsecore/core-util.h>
#include <pulsecore/strbuf.h>
@ -49,6 +50,7 @@ enum {
ARG_HIGH_PRIORITY,
ARG_REALTIME,
ARG_DISALLOW_MODULE_LOADING,
ARG_DISALLOW_EXIT,
ARG_EXIT_IDLE_TIME,
ARG_MODULE_IDLE_TIME,
ARG_SCACHE_IDLE_TIME,
@ -81,6 +83,7 @@ static const struct option long_options[] = {
{"high-priority", 2, 0, ARG_HIGH_PRIORITY},
{"realtime", 2, 0, ARG_REALTIME},
{"disallow-module-loading", 2, 0, ARG_DISALLOW_MODULE_LOADING},
{"disallow-exit", 2, 0, ARG_DISALLOW_EXIT},
{"exit-idle-time", 2, 0, ARG_EXIT_IDLE_TIME},
{"module-idle-time", 2, 0, ARG_MODULE_IDLE_TIME},
{"scache-idle-time", 2, 0, ARG_SCACHE_IDLE_TIME},
@ -111,7 +114,7 @@ void pa_cmdline_help(const char *argv0) {
else
e = argv0;
printf("%s [options]\n\n"
printf(_("%s [options]\n\n"
"COMMANDS:\n"
" -h, --help Show this help\n"
" --version Show version\n"
@ -133,7 +136,9 @@ void pa_cmdline_help(const char *argv0) {
" --realtime[=BOOL] Try to enable realtime scheduling\n"
" (only available as root, when SUID or\n"
" with elevated RLIMIT_RTPRIO)\n"
" --disallow-module-loading[=BOOL] Disallow module loading after startup\n"
" --disallow-module-loading[=BOOL] Disallow module user requested module\n"
" loading/unloading after startup\n"
" --disallow-exit[=BOOL] Disallow user requested exit\n"
" --exit-idle-time=SECS Terminate the daemon when idle and this\n"
" time passed\n"
" --module-idle-time=SECS Unload autoloaded modules when idle and\n"
@ -160,7 +165,7 @@ void pa_cmdline_help(const char *argv0) {
" -C Open a command line on the running TTY\n"
" after startup\n\n"
" -n Don't load default script file\n", e);
" -n Don't load default script file\n"), e);
}
int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) {
@ -237,14 +242,14 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
case ARG_DAEMONIZE:
case 'D':
if ((conf->daemonize = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--daemonize expects boolean argument");
pa_log(_("--daemonize expects boolean argument"));
goto fail;
}
break;
case ARG_FAIL:
if ((conf->fail = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--fail expects boolean argument");
pa_log(_("--fail expects boolean argument"));
goto fail;
}
break;
@ -254,7 +259,7 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
if (optarg) {
if (pa_daemon_conf_set_log_level(conf, optarg) < 0) {
pa_log("--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error).");
pa_log(_("--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."));
goto fail;
}
} else {
@ -266,28 +271,35 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
case ARG_HIGH_PRIORITY:
if ((conf->high_priority = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--high-priority expects boolean argument");
pa_log(_("--high-priority expects boolean argument"));
goto fail;
}
break;
case ARG_REALTIME:
if ((conf->realtime_scheduling = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--realtime expects boolean argument");
pa_log(_("--realtime expects boolean argument"));
goto fail;
}
break;
case ARG_DISALLOW_MODULE_LOADING:
if ((conf->disallow_module_loading = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--disallow-module-loading expects boolean argument");
pa_log(_("--disallow-module-loading expects boolean argument"));
goto fail;
}
break;
case ARG_DISALLOW_EXIT:
if ((conf->disallow_exit = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log(_("--disallow-exit boolean argument"));
goto fail;
}
break;
case ARG_USE_PID_FILE:
if ((conf->use_pid_file = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--use-pid-file expects boolean argument");
pa_log(_("--use-pid-file expects boolean argument"));
goto fail;
}
break;
@ -304,7 +316,7 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
case ARG_LOG_TARGET:
if (pa_daemon_conf_set_log_target(conf, optarg) < 0) {
pa_log("Invalid log target: use either 'syslog', 'stderr' or 'auto'.");
pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto'."));
goto fail;
}
break;
@ -323,28 +335,28 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
case ARG_RESAMPLE_METHOD:
if (pa_daemon_conf_set_resample_method(conf, optarg) < 0) {
pa_log("Invalid resample method '%s'.", optarg);
pa_log(_("Invalid resample method '%s'."), optarg);
goto fail;
}
break;
case ARG_SYSTEM:
if ((conf->system_instance = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--system expects boolean argument");
pa_log(_("--system expects boolean argument"));
goto fail;
}
break;
case ARG_NO_CPU_LIMIT:
if ((conf->no_cpu_limit = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--no-cpu-limit expects boolean argument");
pa_log(_("--no-cpu-limit expects boolean argument"));
goto fail;
}
break;
case ARG_DISABLE_SHM:
if ((conf->disable_shm = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
pa_log("--disable-shm expects boolean argument");
pa_log(_("--disable-shm expects boolean argument"));
goto fail;
}
break;

View file

@ -24,11 +24,13 @@
#endif
#include <pulse/error.h>
#include <pulse/timeval.h>
#include <pulsecore/core-util.h>
#include <pulsecore/core-error.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/rtclock.h>
#include "cpulimit.h"
@ -67,7 +69,7 @@
#define CPUTIME_INTERVAL_HARD (5)
/* Time of the last CPU load check */
static time_t last_time = 0;
static pa_usec_t last_time = 0;
/* Pipe for communicating with the main loop */
static int the_pipe[2] = {-1, -1};
@ -100,7 +102,7 @@ static void reset_cpu_time(int t) {
n = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec + t;
pa_assert_se(getrlimit(RLIMIT_CPU, &rl) >= 0);
rl.rlim_cur = n;
rl.rlim_cur = (rlim_t) n;
pa_assert_se(setrlimit(RLIMIT_CPU, &rl) >= 0);
}
@ -117,20 +119,21 @@ static void signal_handler(int sig) {
pa_assert(sig == SIGXCPU);
if (phase == PHASE_IDLE) {
time_t now;
pa_usec_t now, elapsed;
#ifdef PRINT_CPU_LOAD
char t[256];
#endif
time(&now);
now = pa_rtclock_usec();
elapsed = now - last_time;
#ifdef PRINT_CPU_LOAD
pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100);
pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", ((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) / (double) elapsed * 100.0);
write_err(t);
#endif
if (CPUTIME_INTERVAL_SOFT >= ((now-last_time)*(double)CPUTIME_PERCENT/100)) {
if (((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) >= ((double) elapsed * (double) CPUTIME_PERCENT / 100.0)) {
static const char c = 'X';
write_err("Soft CPU time limit exhausted, terminating.\n");
@ -179,7 +182,7 @@ int pa_cpu_limit_init(pa_mainloop_api *m) {
pa_assert(the_pipe[1] == -1);
pa_assert(!installed);
time(&last_time);
last_time = pa_rtclock_usec();
/* Prepare the main loop pipe */
if (pipe(the_pipe) < 0) {
@ -235,7 +238,7 @@ void pa_cpu_limit_done(void) {
#else /* HAVE_SIGXCPU */
int pa_cpu_limit_init(PA_GCC_UNUSED pa_mainloop_api *m) {
int pa_cpu_limit_init(pa_mainloop_api *m) {
return 0;
}

View file

@ -32,6 +32,7 @@
#include <pulse/xmalloc.h>
#include <pulse/timeval.h>
#include <pulse/i18n.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core-util.h>
@ -62,6 +63,7 @@ static const pa_daemon_conf default_conf = {
.realtime_scheduling = FALSE,
.realtime_priority = 5, /* Half of JACK's default rtprio */
.disallow_module_loading = FALSE,
.disallow_exit = FALSE,
.exit_idle_time = 20,
.module_idle_time = 20,
.scache_idle_time = 20,
@ -189,7 +191,7 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
return 0;
}
static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_assert(filename);
@ -198,14 +200,14 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva
pa_assert(data);
if (pa_daemon_conf_set_log_target(c, rvalue) < 0) {
pa_log("[%s:%u] Invalid log target '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid log target '%s'."), filename, line, rvalue);
return -1;
}
return 0;
}
static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_assert(filename);
@ -214,14 +216,14 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval
pa_assert(data);
if (pa_daemon_conf_set_log_level(c, rvalue) < 0) {
pa_log("[%s:%u] Invalid log level '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid log level '%s'."), filename, line, rvalue);
return -1;
}
return 0;
}
static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_assert(filename);
@ -230,14 +232,14 @@ static int parse_resample_method(const char *filename, unsigned line, const char
pa_assert(data);
if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) {
pa_log("[%s:%u] Invalid resample method '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid resample method '%s'."), filename, line, rvalue);
return -1;
}
return 0;
}
static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
#ifdef HAVE_SYS_RESOURCE_H
struct pa_rlimit *r = data;
@ -253,20 +255,20 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue,
} else {
int32_t k;
if (pa_atoi(rvalue, &k) < 0) {
pa_log("[%s:%u] Invalid rlimit '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid rlimit '%s'."), filename, line, rvalue);
return -1;
}
r->is_set = k >= 0;
r->value = k >= 0 ? (rlim_t) k : 0;
}
#else
pa_log_warn("[%s:%u] rlimit not supported on this platform.", filename, line);
pa_log_warn(_("[%s:%u] rlimit not supported on this platform."), filename, line);
#endif
return 0;
}
static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_sample_format_t f;
@ -276,7 +278,7 @@ static int parse_sample_format(const char *filename, unsigned line, const char *
pa_assert(data);
if ((f = pa_parse_sample_format(rvalue)) < 0) {
pa_log("[%s:%u] Invalid sample format '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid sample format '%s'."), filename, line, rvalue);
return -1;
}
@ -284,17 +286,17 @@ static int parse_sample_format(const char *filename, unsigned line, const char *
return 0;
}
static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t r;
uint32_t r;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
if (pa_atoi(rvalue, &r) < 0 || r > (int32_t) PA_RATE_MAX || r <= 0) {
pa_log("[%s:%u] Invalid sample rate '%s'.", filename, line, rvalue);
if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0) {
pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
return -1;
}
@ -302,7 +304,7 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *lv
return 0;
}
static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
@ -312,7 +314,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char
pa_assert(data);
if (pa_atoi(rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
pa_log("[%s:%u] Invalid sample channels '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid sample channels '%s'."), filename, line, rvalue);
return -1;
}
@ -320,7 +322,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char
return 0;
}
static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
@ -330,7 +332,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval
pa_assert(data);
if (pa_atoi(rvalue, &n) < 0 || n < 2) {
pa_log("[%s:%u] Invalid number of fragments '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid number of fragments '%s'."), filename, line, rvalue);
return -1;
}
@ -338,7 +340,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval
return 0;
}
static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
@ -348,7 +350,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c
pa_assert(data);
if (pa_atoi(rvalue, &n) < 0 || n < 1) {
pa_log("[%s:%u] Invalid fragment size '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid fragment size '%s'."), filename, line, rvalue);
return -1;
}
@ -356,7 +358,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c
return 0;
}
static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t level;
@ -366,7 +368,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva
pa_assert(data);
if (pa_atoi(rvalue, &level) < 0 || level < -20 || level > 19) {
pa_log("[%s:%u] Invalid nice level '%s'.", filename, line, rvalue);
pa_log(_("[%s:%u] Invalid nice level '%s'."), filename, line, rvalue);
return -1;
}
@ -374,7 +376,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva
return 0;
}
static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t rtprio;
@ -402,6 +404,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "high-priority", pa_config_parse_bool, NULL },
{ "realtime-scheduling", pa_config_parse_bool, NULL },
{ "disallow-module-loading", pa_config_parse_bool, NULL },
{ "disallow-exit", pa_config_parse_bool, NULL },
{ "use-pid-file", pa_config_parse_bool, NULL },
{ "system-instance", pa_config_parse_bool, NULL },
{ "no-cpu-limit", pa_config_parse_bool, NULL },
@ -465,17 +468,17 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
table[2].data = &c->high_priority;
table[3].data = &c->realtime_scheduling;
table[4].data = &c->disallow_module_loading;
table[5].data = &c->use_pid_file;
table[6].data = &c->system_instance;
table[7].data = &c->no_cpu_limit;
table[8].data = &c->disable_shm;
table[9].data = &c->exit_idle_time;
table[10].data = &c->module_idle_time;
table[11].data = &c->scache_idle_time;
table[12].data = c;
table[13].data = &c->dl_search_path;
table[14].data = &c->default_script_file;
table[15].data = c;
table[5].data = &c->disallow_exit;
table[6].data = &c->use_pid_file;
table[7].data = &c->system_instance;
table[8].data = &c->no_cpu_limit;
table[9].data = &c->disable_shm;
table[10].data = &c->exit_idle_time;
table[11].data = &c->module_idle_time;
table[12].data = &c->scache_idle_time;
table[13].data = c;
table[14].data = &c->dl_search_path;
table[15].data = &c->default_script_file;
table[16].data = c;
table[17].data = c;
table[18].data = c;
@ -485,67 +488,68 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
table[22].data = c;
table[23].data = c;
table[24].data = c;
table[25].data = &c->disable_remixing;
table[26].data = &c->load_default_script_file;
table[25].data = c;
table[26].data = &c->disable_remixing;
table[27].data = &c->load_default_script_file;
#ifdef HAVE_SYS_RESOURCE_H
table[27].data = &c->rlimit_fsize;
table[28].data = &c->rlimit_data;
table[29].data = &c->rlimit_stack;
table[30].data = &c->rlimit_as;
table[31].data = &c->rlimit_core;
table[32].data = &c->rlimit_nofile;
table[33].data = &c->rlimit_as;
table[28].data = &c->rlimit_fsize;
table[29].data = &c->rlimit_data;
table[30].data = &c->rlimit_stack;
table[31].data = &c->rlimit_as;
table[32].data = &c->rlimit_core;
table[33].data = &c->rlimit_nofile;
table[34].data = &c->rlimit_as;
#ifdef RLIMIT_NPROC
table[34].data = &c->rlimit_nproc;
table[35].data = &c->rlimit_nproc;
#endif
#ifdef RLIMIT_MEMLOCK
#ifndef RLIMIT_NPROC
#error "Houston, we have a numbering problem!"
#endif
table[35].data = &c->rlimit_memlock;
table[36].data = &c->rlimit_memlock;
#endif
#ifdef RLIMIT_LOCKS
#ifndef RLIMIT_MEMLOCK
#error "Houston, we have a numbering problem!"
#endif
table[36].data = &c->rlimit_locks;
table[37].data = &c->rlimit_locks;
#endif
#ifdef RLIMIT_SIGPENDING
#ifndef RLIMIT_LOCKS
#error "Houston, we have a numbering problem!"
#endif
table[37].data = &c->rlimit_sigpending;
table[38].data = &c->rlimit_sigpending;
#endif
#ifdef RLIMIT_MSGQUEUE
#ifndef RLIMIT_SIGPENDING
#error "Houston, we have a numbering problem!"
#endif
table[38].data = &c->rlimit_msgqueue;
table[39].data = &c->rlimit_msgqueue;
#endif
#ifdef RLIMIT_NICE
#ifndef RLIMIT_MSGQUEUE
#error "Houston, we have a numbering problem!"
#endif
table[39].data = &c->rlimit_nice;
table[40].data = &c->rlimit_nice;
#endif
#ifdef RLIMIT_RTPRIO
#ifndef RLIMIT_NICE
#error "Houston, we have a numbering problem!"
#endif
table[40].data = &c->rlimit_rtprio;
table[41].data = &c->rlimit_rtprio;
#endif
#ifdef RLIMIT_RTTIME
#ifndef RLIMIT_RTTIME
#error "Houston, we have a numbering problem!"
#endif
table[41].data = &c->rlimit_rttime;
table[42].data = &c->rlimit_rttime;
#endif
#endif
@ -557,7 +561,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file);
if (!f && errno != ENOENT) {
pa_log_warn("Failed to open configuration file: %s", pa_cstrerror(errno));
pa_log_warn(_("Failed to open configuration file: %s"), pa_cstrerror(errno));
goto finish;
}
@ -631,7 +635,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
s = pa_strbuf_new();
if (c->config_file)
pa_strbuf_printf(s, "### Read from configuration file: %s ###\n", c->config_file);
pa_strbuf_printf(s, _("### Read from configuration file: %s ###\n"), c->config_file);
pa_assert(c->log_level <= PA_LOG_LEVEL_MAX);
@ -642,6 +646,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "realtime-scheduling = %s\n", pa_yes_no(c->realtime_scheduling));
pa_strbuf_printf(s, "realtime-priority = %i\n", c->realtime_priority);
pa_strbuf_printf(s, "disallow-module-loading = %s\n", pa_yes_no(c->disallow_module_loading));
pa_strbuf_printf(s, "disallow-exit = %s\n", pa_yes_no(c->disallow_exit));
pa_strbuf_printf(s, "use-pid-file = %s\n", pa_yes_no(c->use_pid_file));
pa_strbuf_printf(s, "system-instance = %s\n", pa_yes_no(c->system_instance));
pa_strbuf_printf(s, "no-cpu-limit = %s\n", pa_yes_no(c->no_cpu_limit));

View file

@ -66,7 +66,8 @@ typedef struct pa_daemon_conf {
no_cpu_limit,
disable_shm,
disable_remixing,
load_default_script_file;
load_default_script_file,
disallow_exit;
int exit_idle_time,
module_idle_time,
scache_idle_time,

View file

@ -22,6 +22,7 @@
; daemonize = no
; fail = yes
; disallow-module-loading = no
; disallow-exit = no
; use-pid-file = yes
; system-instance = no
; disable-shm = no

View file

@ -23,7 +23,7 @@
### Load something into the sample cache
#load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav
load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-access /usr/share/sounds/generic.wav

View file

@ -30,6 +30,7 @@
#include <ltdl.h>
#include <pulse/util.h>
#include <pulse/i18n.h>
#include <pulsecore/modinfo.h>
#include <pulsecore/core-util.h>
@ -39,7 +40,7 @@
#define PREFIX "module-"
static void short_info(const char *name, PA_GCC_UNUSED const char *path, pa_modinfo *i) {
static void short_info(const char *name, const char *path, pa_modinfo *i) {
pa_assert(name);
pa_assert(i);
@ -56,24 +57,24 @@ static void long_info(const char *name, const char *path, pa_modinfo *i) {
nl = 1;
printf("Name: %s\n", name);
printf(_("Name: %s\n"), name);
if (!i->description && !i->version && !i->author && !i->usage)
printf("No module information available\n");
printf(_("No module information available\n"));
else {
if (i->version)
printf("Version: %s\n", i->version);
printf(_("Version: %s\n"), i->version);
if (i->description)
printf("Description: %s\n", i->description);
printf(_("Description: %s\n"), i->description);
if (i->author)
printf("Author: %s\n", i->author);
printf(_("Author: %s\n"), i->author);
if (i->usage)
printf("Usage: %s\n", i->usage);
printf("Load Once: %s\n", pa_yes_no(i->load_once));
printf(_("Usage: %s\n"), i->usage);
printf(_("Load Once: %s\n"), pa_yes_no(i->load_once));
}
if (path)
printf("Path: %s\n", path);
printf(_("Path: %s\n"), path);
}
static void show_info(const char *name, const char *path, void (*info)(const char *name, const char *path, pa_modinfo*i)) {

View file

@ -24,21 +24,20 @@
#include <config.h>
#endif
#if HAVE_DLFCN_H
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if HAVE_SYS_DL_H
#ifdef HAVE_SYS_DL_H
#include <sys/dl.h>
#endif
#ifndef HAVE_STRUCT_LT_USER_DLLOADER
/* Only used with ltdl 2.2 */
#include <string.h>
#endif
#include <ltdl.h>
#include <pulse/i18n.h>
#include <pulsecore/macro.h>
#include <pulsecore/mutex.h>
#include <pulsecore/thread.h>
@ -54,9 +53,9 @@
#undef PA_BIND_NOW
#endif
static pa_mutex *libtool_mutex = NULL;
#ifdef HAVE_LT_DLMUTEX_REGISTER
PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls);
static pa_mutex *libtool_mutex = NULL;
static void libtool_lock(void) {
pa_mutex_lock(libtool_mutex);
@ -66,6 +65,10 @@ static void libtool_unlock(void) {
pa_mutex_unlock(libtool_mutex);
}
#endif
PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls);
static void libtool_set_error(const char *error) {
PA_STATIC_TLS_SET(libtool_tls, (char*) error);
}
@ -89,16 +92,19 @@ static const char *libtool_get_error(void) {
*/
#ifndef HAVE_LT_DLADVISE
static lt_module bind_now_open(lt_user_data d, const char *fname) {
static lt_module bind_now_open(lt_user_data d, const char *fname)
#else
static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise advise) {
static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise advise)
#endif
{
lt_module m;
pa_assert(fname);
if (!(m = dlopen(fname, PA_BIND_NOW))) {
#ifdef HAVE_LT_DLMUTEX_REGISTER
libtool_set_error(dlerror());
#endif
return NULL;
}
@ -110,7 +116,9 @@ static int bind_now_close(lt_user_data d, lt_module m) {
pa_assert(m);
if (dlclose(m) != 0){
#ifdef HAVE_LT_DLMUTEX_REGISTER
libtool_set_error(dlerror());
#endif
return 1;
}
@ -124,7 +132,9 @@ static lt_ptr bind_now_find_sym(lt_user_data d, lt_module m, const char *symbol)
pa_assert(symbol);
if (!(ptr = dlsym(m, symbol))) {
#ifdef HAVE_LT_DLMUTEX_REGISTER
libtool_set_error(dlerror());
#endif
return NULL;
}
@ -150,8 +160,9 @@ void pa_ltdl_init(void) {
#endif
pa_assert_se(lt_dlinit() == 0);
pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE));
#ifdef HAVE_LT_DLMUTEX_REGISTER
pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE));
pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0);
#endif
@ -163,14 +174,15 @@ void pa_ltdl_init(void) {
/* Add our BIND_NOW loader as the default module loader. */
if (lt_dlloader_add(place, &loader, "bind-now-loader") != 0)
pa_log_warn("Failed to add bind-now-loader.");
pa_log_warn(_("Failed to add bind-now-loader."));
# else
/* Already initialised */
if ( dlopen_loader != NULL ) return;
if (dlopen_loader)
return;
if (!(dlopen_loader = lt_dlloader_find("dlopen"))) {
pa_log_warn("Failed to find original dlopen loader.");
return;
pa_log_warn(_("Failed to find original dlopen loader."));
return;
}
memcpy(&bindnow_loader, dlopen_loader, sizeof(bindnow_loader));
@ -182,14 +194,16 @@ void pa_ltdl_init(void) {
/* Add our BIND_NOW loader as the default module loader. */
if (lt_dlloader_add(&bindnow_loader) != 0)
pa_log_warn("Failed to add bind-now-loader.");
pa_log_warn(_("Failed to add bind-now-loader."));
# endif
#endif
}
void pa_ltdl_done(void) {
pa_assert_se(lt_dlexit() == 0);
#ifdef HAVE_LT_DLMUTEX_REGISTER
pa_mutex_free(libtool_mutex);
libtool_mutex = NULL;
#endif
}

View file

@ -64,6 +64,8 @@
#include <pulse/mainloop-signal.h>
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulse/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
@ -94,8 +96,6 @@
#include "ltdl-bind-now.h"
#include "polkit.h"
#define AUTOSPAWN_LOCK "autospawn.lock"
#ifdef HAVE_LIBWRAP
/* Only one instance of these variables */
int allow_severity = LOG_INFO;
@ -111,7 +111,7 @@ int __padsp_disabled__ = 7;
#ifdef OS_IS_WIN32
static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) {
MSG msg;
struct timeval tvnext;
@ -130,8 +130,8 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const s
#endif
static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, int sig, void *userdata) {
pa_log_info("Got signal %s.", pa_sig2str(sig));
static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
pa_log_info(_("Got signal %s."), pa_sig2str(sig));
switch (sig) {
#ifdef SIGUSR1
@ -158,7 +158,7 @@ static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e,
case SIGINT:
case SIGTERM:
default:
pa_log_info("Exiting.");
pa_log_info(_("Exiting."));
m->quit(m, 1);
break;
}
@ -176,41 +176,41 @@ static int change_user(void) {
* afterwards. */
if (!(pw = getpwnam(PA_SYSTEM_USER))) {
pa_log("Failed to find user '%s'.", PA_SYSTEM_USER);
pa_log(_("Failed to find user '%s'."), PA_SYSTEM_USER);
return -1;
}
if (!(gr = getgrnam(PA_SYSTEM_GROUP))) {
pa_log("Failed to find group '%s'.", PA_SYSTEM_GROUP);
pa_log(_("Failed to find group '%s'."), PA_SYSTEM_GROUP);
return -1;
}
pa_log_info("Found user '%s' (UID %lu) and group '%s' (GID %lu).",
pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."),
PA_SYSTEM_USER, (unsigned long) pw->pw_uid,
PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid);
if (pw->pw_gid != gr->gr_gid) {
pa_log("GID of user '%s' and of group '%s' don't match.", PA_SYSTEM_USER, PA_SYSTEM_GROUP);
pa_log(_("GID of user '%s' and of group '%s' don't match."), PA_SYSTEM_USER, PA_SYSTEM_GROUP);
return -1;
}
if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
pa_log_warn("Warning: home directory of user '%s' is not '%s', ignoring.", PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
pa_log("Failed to create '%s': %s", PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
return -1;
}
if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
pa_log("Failed to create '%s': %s", PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
return -1;
}
/* We don't create the config dir here, because we don't need to write to it */
if (initgroups(PA_SYSTEM_USER, gr->gr_gid) != 0) {
pa_log("Failed to change group list: %s", pa_cstrerror(errno));
pa_log(_("Failed to change group list: %s"), pa_cstrerror(errno));
return -1;
}
@ -226,7 +226,7 @@ static int change_user(void) {
#endif
if (r < 0) {
pa_log("Failed to change GID: %s", pa_cstrerror(errno));
pa_log(_("Failed to change GID: %s"), pa_cstrerror(errno));
return -1;
}
@ -242,7 +242,7 @@ static int change_user(void) {
#endif
if (r < 0) {
pa_log("Failed to change UID: %s", pa_cstrerror(errno));
pa_log(_("Failed to change UID: %s"), pa_cstrerror(errno));
return -1;
}
@ -256,7 +256,7 @@ static int change_user(void) {
pa_set_env("PULSE_CONFIG_PATH", PA_SYSTEM_CONFIG_PATH);
pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
pa_log_info("Successfully dropped root privileges.");
pa_log_info(_("Successfully dropped root privileges."));
return 0;
}
@ -264,7 +264,7 @@ static int change_user(void) {
#else /* HAVE_PWD_H && HAVE_GRP_H */
static int change_user(void) {
pa_log("System wide mode unsupported on this platform.");
pa_log(_("System wide mode unsupported on this platform."));
return -1;
}
@ -282,7 +282,7 @@ static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) {
rl.rlim_cur = rl.rlim_max = r->value;
if (setrlimit(resource, &rl) < 0) {
pa_log_info("setrlimit(%s, (%u, %u)) failed: %s", name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno));
return -1;
}
@ -345,7 +345,8 @@ int main(int argc, char *argv[]) {
struct timeval win32_tv;
#endif
char *lf = NULL;
int autospawn_lock_fd = -1;
int autospawn_fd = -1;
pa_bool_t autospawn_locked = FALSE;
#if defined(__linux__) && defined(__OPTIMIZE__)
/*
@ -407,6 +408,8 @@ int main(int argc, char *argv[]) {
* still are normal root. */
setlocale(LC_ALL, "");
pa_init_i18n();
pa_log_set_maximal_level(PA_LOG_INFO);
pa_log_set_ident("pulseaudio");
@ -419,7 +422,7 @@ int main(int argc, char *argv[]) {
goto finish;
if (pa_cmdline_parse(conf, argc, argv, &d) < 0) {
pa_log("Failed to parse command line.");
pa_log(_("Failed to parse command line."));
goto finish;
}
@ -435,14 +438,14 @@ int main(int argc, char *argv[]) {
if (conf->high_priority && !allow_high_priority) {
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing high-priority scheduling.");
pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP);
allow_high_priority = TRUE;
}
}
if (conf->realtime_scheduling && !allow_realtime) {
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
pa_log_info("We're in the group '"PA_REALTIME_GROUP"', allowing real-time scheduling.");
pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP);
allow_realtime = TRUE;
}
}
@ -450,18 +453,18 @@ int main(int argc, char *argv[]) {
#ifdef HAVE_POLKIT
if (conf->high_priority && !allow_high_priority) {
if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
pa_log_info("PolicyKit grants us acquire-high-priority privilege.");
pa_log_info(_("PolicyKit grants us acquire-high-priority privilege."));
allow_high_priority = TRUE;
} else
pa_log_info("PolicyKit refuses acquire-high-priority privilege.");
pa_log_info(_("PolicyKit refuses acquire-high-priority privilege."));
}
if (conf->realtime_scheduling && !allow_realtime) {
if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
pa_log_info("PolicyKit grants us acquire-real-time privilege.");
pa_log_info(_("PolicyKit grants us acquire-real-time privilege."));
allow_realtime = TRUE;
} else
pa_log_info("PolicyKit refuses acquire-real-time privilege.");
pa_log_info(_("PolicyKit refuses acquire-real-time privilege."));
}
#endif
@ -473,9 +476,9 @@ int main(int argc, char *argv[]) {
pa_drop_caps();
if (conf->high_priority || conf->realtime_scheduling)
pa_log_notice("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
"We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user.");
pa_log_notice(_("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
"We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."));
}
}
@ -491,7 +494,7 @@ int main(int argc, char *argv[]) {
#endif
if (conf->high_priority && !pa_can_high_priority())
pa_log_warn("High-priority scheduling enabled in configuration but not allowed by policy.");
pa_log_warn(_("High-priority scheduling enabled in configuration but not allowed by policy."));
if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
pa_raise_priority(conf->nice_level);
@ -516,24 +519,24 @@ int main(int argc, char *argv[]) {
rl.rlim_max = rl.rlim_cur = 9;
if (setrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
pa_log_info("Successfully increased RLIMIT_RTPRIO");
pa_log_info(_("Successfully increased RLIMIT_RTPRIO"));
drop = TRUE;
} else
pa_log_warn("RLIMIT_RTPRIO failed: %s", pa_cstrerror(errno));
pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno));
}
}
}
#endif
if (drop) {
pa_log_info("Giving up CAP_NICE");
pa_log_info(_("Giving up CAP_NICE"));
pa_drop_caps();
suid_root = FALSE;
}
}
if (conf->realtime_scheduling && !pa_can_realtime())
pa_log_warn("Real-time scheduling enabled in configuration but not allowed by policy.");
pa_log_warn(_("Real-time scheduling enabled in configuration but not allowed by policy."));
pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
@ -591,9 +594,9 @@ int main(int argc, char *argv[]) {
pid_t pid;
if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
pa_log_info("Daemon not running");
pa_log_info(_("Daemon not running"));
else {
pa_log_info("Daemon running as PID %u", pid);
pa_log_info(_("Daemon running as PID %u"), pid);
retval = 0;
}
@ -603,7 +606,7 @@ int main(int argc, char *argv[]) {
case PA_CMD_KILL:
if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
pa_log("Failed to kill daemon.");
pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
else
retval = 0;
@ -621,24 +624,49 @@ int main(int argc, char *argv[]) {
}
if (real_root && !conf->system_instance)
pa_log_warn("This program is not intended to be run as root (unless --system is specified).");
pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
else if (!real_root && conf->system_instance) {
pa_log("Root priviliges required.");
pa_log(_("Root priviliges required."));
goto finish;
}
if (conf->cmd == PA_CMD_START && conf->system_instance) {
pa_log("--start not supported for system instances.");
pa_log(_("--start not supported for system instances."));
goto finish;
}
if (conf->system_instance && !conf->disallow_exit)
pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
if (conf->system_instance && !conf->disallow_module_loading)
pa_log_warn(_("Running in system mode, but --disallow-module-loading not set!"));
if (conf->system_instance && !conf->disable_shm) {
pa_log_notice(_("Running in system mode, forcibly disabling SHM mode!"));
conf->disable_shm = TRUE;
}
if (conf->system_instance && conf->exit_idle_time > 0) {
pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
conf->exit_idle_time = 0;
}
if (conf->cmd == PA_CMD_START) {
/* If we shall start PA only when it is not running yet, we
* first take the autospawn lock to make things
* synchronous. */
lf = pa_runtime_path(AUTOSPAWN_LOCK);
autospawn_lock_fd = pa_lock_lockfile(lf);
if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
pa_log("Failed to initialize autospawn lock");
goto finish;
}
if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
pa_log("Failed to acquire autospawn lock");
goto finish;
}
autospawn_locked = TRUE;
}
if (conf->daemonize) {
@ -646,18 +674,18 @@ int main(int argc, char *argv[]) {
int tty_fd;
if (pa_stdio_acquire() < 0) {
pa_log("Failed to acquire stdio.");
pa_log(_("Failed to acquire stdio."));
goto finish;
}
#ifdef HAVE_FORK
if (pipe(daemon_pipe) < 0) {
pa_log("pipe failed: %s", pa_cstrerror(errno));
pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
goto finish;
}
if ((child = fork()) < 0) {
pa_log("fork() failed: %s", pa_cstrerror(errno));
pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
goto finish;
}
@ -671,25 +699,28 @@ int main(int argc, char *argv[]) {
if ((n = pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
if (n < 0)
pa_log("read() failed: %s", pa_cstrerror(errno));
pa_log(_("read() failed: %s"), pa_cstrerror(errno));
retval = 1;
}
if (retval)
pa_log("Daemon startup failed.");
pa_log(_("Daemon startup failed."));
else
pa_log_info("Daemon startup successful.");
pa_log_info(_("Daemon startup successful."));
goto finish;
}
if (autospawn_lock_fd >= 0) {
if (autospawn_fd >= 0) {
/* The lock file is unlocked from the parent, so we need
* to close it in the child */
pa_close(autospawn_lock_fd);
autospawn_lock_fd = -1;
pa_autospawn_lock_release();
pa_autospawn_lock_done(TRUE);
autospawn_locked = FALSE;
autospawn_fd = -1;
}
pa_assert_se(pa_close(daemon_pipe[0]) == 0);
@ -746,17 +777,27 @@ int main(int argc, char *argv[]) {
pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
pa_log_info("This is PulseAudio " PACKAGE_VERSION);
pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE);
if (!(s = pa_get_runtime_dir()))
pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
if (!(s = pa_machine_id())) {
pa_log(_("Failed to get machine ID"));
goto finish;
pa_log_info("Using runtime directory %s.", s);
pa_xfree(s);
if (!(s = pa_get_state_dir()))
pa_log_info("Using state directory %s.", s);
}
pa_log_info(_("Machine ID is %s."), s);
pa_xfree(s);
pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode()));
if (!(s = pa_get_runtime_dir()))
goto finish;
pa_log_info(_("Using runtime directory %s."), s);
pa_xfree(s);
if (!(s = pa_get_state_dir()))
goto finish;
pa_log_info(_("Using state directory %s."), s);
pa_xfree(s);
pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode()));
if (conf->use_pid_file) {
int z;
@ -771,7 +812,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
pa_log("pa_pid_file_create() failed.");
pa_log(_("pa_pid_file_create() failed."));
goto finish;
}
@ -783,9 +824,9 @@ int main(int argc, char *argv[]) {
#endif
if (pa_rtclock_hrtimer())
pa_log_info("Fresh high-resolution timers available! Bon appetit!");
pa_log_info(_("Fresh high-resolution timers available! Bon appetit!"));
else
pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!");
pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
#ifdef SIGRTMIN
/* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
@ -795,7 +836,7 @@ int main(int argc, char *argv[]) {
pa_assert_se(mainloop = pa_mainloop_new());
if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) {
pa_log("pa_core_new() failed.");
pa_log(_("pa_core_new() failed."));
goto finish;
}
@ -810,6 +851,7 @@ int main(int argc, char *argv[]) {
c->realtime_scheduling = !!conf->realtime_scheduling;
c->disable_remixing = !!conf->disable_remixing;
c->running_as_daemon = !!conf->daemonize;
c->disallow_exit = conf->disallow_exit;
pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
pa_signal_new(SIGINT, signal_callback, c);
@ -854,17 +896,17 @@ int main(int argc, char *argv[]) {
c->disallow_module_loading = !!conf->disallow_module_loading;
if (r < 0 && conf->fail) {
pa_log("Failed to initialize daemon.");
pa_log(_("Failed to initialize daemon."));
goto finish;
}
if (!c->modules || pa_idxset_size(c->modules) == 0) {
pa_log("Daemon startup without any loaded modules, refusing to work.");
pa_log(_("Daemon startup without any loaded modules, refusing to work."));
goto finish;
}
if (c->default_sink_name && !pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, TRUE) && conf->fail) {
pa_log_error("Default sink name (%s) does not exist in name register.", c->default_sink_name);
pa_log_error(_("Default sink name (%s) does not exist in name register."), c->default_sink_name);
goto finish;
}
@ -877,18 +919,22 @@ int main(int argc, char *argv[]) {
}
#endif
pa_log_info("Daemon startup complete.");
pa_log_info(_("Daemon startup complete."));
retval = 0;
if (pa_mainloop_run(mainloop, &retval) < 0)
goto finish;
pa_log_info("Daemon shutdown initiated.");
pa_log_info(_("Daemon shutdown initiated."));
finish:
if (autospawn_lock_fd >= 0)
pa_unlock_lockfile(lf, autospawn_lock_fd);
if (autospawn_fd >= 0) {
if (autospawn_locked)
pa_autospawn_lock_release();
pa_autospawn_lock_done(FALSE);
}
if (lf)
pa_xfree(lf);
@ -900,7 +946,7 @@ finish:
if (c) {
pa_core_unref(c);
pa_log_info("Daemon terminated.");
pa_log_info(_("Daemon terminated."));
}
if (!conf->no_cpu_limit)

View file

@ -31,6 +31,8 @@
#include <dbus/dbus.h>
#include <polkit-dbus/polkit-dbus.h>
#include <pulse/i18n.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
@ -50,7 +52,7 @@ int pa_polkit_check(const char *action_id) {
dbus_error_init(&dbus_error);
if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error))) {
pa_log_error("Cannot connect to system bus: %s", dbus_error.message);
pa_log_error(_("Cannot connect to system bus: %s"), dbus_error.message);
goto finish;
}
@ -60,7 +62,7 @@ int pa_polkit_check(const char *action_id) {
dbus_connection_set_exit_on_disconnect(bus, FALSE);
if (!(caller = polkit_caller_new_from_pid(bus, getpid(), &dbus_error))) {
pa_log_error("Cannot get caller from PID: %s", dbus_error.message);
pa_log_error(_("Cannot get caller from PID: %s"), dbus_error.message);
goto finish;
}
@ -72,12 +74,12 @@ int pa_polkit_check(const char *action_id) {
* -- an not the EUID or any other user id. */
if (!(polkit_caller_set_uid(caller, getuid()))) {
pa_log_error("Cannot set UID on caller object.");
pa_log_error(_("Cannot set UID on caller object."));
goto finish;
}
if (!(polkit_caller_get_ck_session(caller, &session))) {
pa_log_error("Failed to get CK session.");
pa_log_error(_("Failed to get CK session."));
goto finish;
}
@ -85,27 +87,27 @@ int pa_polkit_check(const char *action_id) {
* object */
if (!(polkit_session_set_uid(session, getuid()))) {
pa_log_error("Cannot set UID on session object.");
pa_log_error(_("Cannot set UID on session object."));
goto finish;
}
if (!(action = polkit_action_new())) {
pa_log_error("Cannot allocate PolKitAction.");
pa_log_error(_("Cannot allocate PolKitAction."));
goto finish;
}
if (!polkit_action_set_action_id(action, action_id)) {
pa_log_error("Cannot set action_id");
pa_log_error(_("Cannot set action_id"));
goto finish;
}
if (!(context = polkit_context_new())) {
pa_log_error("Cannot allocate PolKitContext.");
pa_log_error(_("Cannot allocate PolKitContext."));
goto finish;
}
if (!polkit_context_init(context, &polkit_error)) {
pa_log_error("Cannot initialize PolKitContext: %s", polkit_error_get_error_message(polkit_error));
pa_log_error(_("Cannot initialize PolKitContext: %s"), polkit_error_get_error_message(polkit_error));
goto finish;
}
@ -114,7 +116,7 @@ int pa_polkit_check(const char *action_id) {
polkit_result = polkit_context_is_caller_authorized(context, action, caller, TRUE, &polkit_error);
if (polkit_error_is_set(polkit_error)) {
pa_log_error("Could not determine whether caller is authorized: %s", polkit_error_get_error_message(polkit_error));
pa_log_error(_("Could not determine whether caller is authorized: %s"), polkit_error_get_error_message(polkit_error));
goto finish;
}
@ -134,7 +136,7 @@ int pa_polkit_check(const char *action_id) {
}
if (dbus_error_is_set(&dbus_error)) {
pa_log_error("Cannot obtain auth: %s", dbus_error.message);
pa_log_error(_("Cannot obtain auth: %s"), dbus_error.message);
goto finish;
}
}
@ -143,7 +145,7 @@ int pa_polkit_check(const char *action_id) {
}
if (polkit_result != POLKIT_RESULT_YES && polkit_result != POLKIT_RESULT_NO)
pa_log_warn("PolicyKit responded with '%s'", polkit_result_to_string_representation(polkit_result));
pa_log_warn(_("PolicyKit responded with '%s'"), polkit_result_to_string_representation(polkit_result));
ret = polkit_result == POLKIT_RESULT_YES;

View file

@ -98,9 +98,16 @@ pa_context_unref;
pa_cvolume_avg;
pa_cvolume_channels_equal_to;
pa_cvolume_equal;
pa_cvolume_remap;
pa_cvolume_set;
pa_cvolume_snprint;
pa_cvolume_valid;
pa_ext_stream_restore_delete;
pa_ext_stream_restore_read;
pa_ext_stream_restore_set_subscribe_cb;
pa_ext_stream_restore_subscribe;
pa_ext_stream_restore_test;
pa_ext_stream_restore_write;
pa_frame_size;
pa_get_binary_name;
pa_get_fqdn;
@ -133,21 +140,21 @@ pa_operation_ref;
pa_operation_unref;
pa_parse_sample_format;
pa_path_get_filename;
pa_proplist_free;
pa_proplist_contains;
pa_proplist_clear;
pa_proplist_contains;
pa_proplist_copy;
pa_proplist_free;
pa_proplist_get;
pa_proplist_gets;
pa_proplist_iterate;
pa_proplist_update;
pa_proplist_new;
pa_proplist_set;
pa_proplist_sets;
pa_proplist_setf;
pa_proplist_sets;
pa_proplist_to_string;
pa_proplist_unset;
pa_proplist_unset_many;
pa_proplist_to_string;
pa_proplist_update;
pa_sample_format_to_string;
pa_sample_size;
pa_sample_spec_equal;
@ -198,8 +205,8 @@ pa_stream_readable_size;
pa_stream_ref;
pa_stream_set_buffer_attr;
pa_stream_set_latency_update_callback;
pa_stream_set_moved_callback;
pa_stream_set_monitor_stream;
pa_stream_set_moved_callback;
pa_stream_set_name;
pa_stream_set_overflow_callback;
pa_stream_set_read_callback;

View file

@ -39,7 +39,7 @@
#include "alsa-util.h"
struct pa_alsa_fdlist {
int num_fds;
unsigned num_fds;
struct pollfd *fds;
/* This is a temporary buffer used to avoid lots of mallocs */
struct pollfd *work_fds;
@ -50,16 +50,17 @@ struct pa_alsa_fdlist {
pa_defer_event *defer;
pa_io_event **ios;
int polled;
pa_bool_t polled;
void (*cb)(void *userdata);
void *userdata;
};
static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) {
static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {
struct pa_alsa_fdlist *fdl = userdata;
int err, i;
int err;
unsigned i;
unsigned short revents;
pa_assert(a);
@ -71,11 +72,11 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io
if (fdl->polled)
return;
fdl->polled = 1;
fdl->polled = TRUE;
memcpy(fdl->work_fds, fdl->fds, sizeof(struct pollfd) * fdl->num_fds);
for (i = 0;i < fdl->num_fds; i++) {
for (i = 0; i < fdl->num_fds; i++) {
if (e == fdl->ios[i]) {
if (events & PA_IO_EVENT_INPUT)
fdl->work_fds[i].revents |= POLLIN;
@ -102,9 +103,10 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io
snd_mixer_handle_events(fdl->mixer);
}
static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *userdata) {
static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
struct pa_alsa_fdlist *fdl = userdata;
int num_fds, i, err;
unsigned num_fds, i;
int err;
struct pollfd *temp;
pa_assert(a);
@ -113,8 +115,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u
a->defer_enable(fdl->defer, 0);
num_fds = snd_mixer_poll_descriptors_count(fdl->mixer);
pa_assert(num_fds > 0);
num_fds = (unsigned) snd_mixer_poll_descriptors_count(fdl->mixer);
if (num_fds != fdl->num_fds) {
if (fdl->fds)
@ -132,7 +133,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u
return;
}
fdl->polled = 0;
fdl->polled = FALSE;
if (memcmp(fdl->fds, fdl->work_fds, sizeof(struct pollfd) * num_fds) == 0)
return;
@ -176,7 +177,7 @@ struct pa_alsa_fdlist *pa_alsa_fdlist_new(void) {
fdl->m = NULL;
fdl->defer = NULL;
fdl->ios = NULL;
fdl->polled = 0;
fdl->polled = FALSE;
return fdl;
}
@ -190,9 +191,9 @@ void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl) {
}
if (fdl->ios) {
int i;
unsigned i;
pa_assert(fdl->m);
for (i = 0;i < fdl->num_fds;i++)
for (i = 0; i < fdl->num_fds; i++)
fdl->m->io_free(fdl->ios[i]);
pa_xfree(fdl->ios);
}
@ -403,7 +404,7 @@ int pa_alsa_set_hw_params(
/* If the sample rate deviates too much, we need to resample */
if (r < ss->rate*.95 || r > ss->rate*1.05)
ss->rate = r;
ss->channels = c;
ss->channels = (uint8_t) c;
ss->format = f;
pa_assert(_periods > 0);
@ -808,7 +809,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
if (channel_map->channels > 1 &&
((playback && snd_mixer_selem_has_playback_volume_joined(elem)) ||
(!playback && snd_mixer_selem_has_capture_volume_joined(elem)))) {
pa_log_info("ALSA device lacks independant volume controls for each channel, falling back to software volume control.");
pa_log_info("ALSA device lacks independant volume controls for each channel.");
return -1;
}
@ -820,7 +821,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
id = alsa_channel_ids[channel_map->map[i]];
if (!is_mono && id == SND_MIXER_SCHN_UNKNOWN) {
pa_log_info("Configured channel map contains channel '%s' that is unknown to the ALSA mixer. Falling back to software volume control.", pa_channel_position_to_string(channel_map->map[i]));
pa_log_info("Configured channel map contains channel '%s' that is unknown to the ALSA mixer.", pa_channel_position_to_string(channel_map->map[i]));
return -1;
}
@ -832,7 +833,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
if ((playback && (!snd_mixer_selem_has_playback_channel(elem, id) || (is_mono && !snd_mixer_selem_is_playback_mono(elem)))) ||
(!playback && (!snd_mixer_selem_has_capture_channel(elem, id) || (is_mono && !snd_mixer_selem_is_capture_mono(elem))))) {
pa_log_info("ALSA device lacks separate volumes control for channel '%s', falling back to software volume control.", pa_channel_position_to_string(channel_map->map[i]));
pa_log_info("ALSA device lacks separate volumes control for channel '%s'", pa_channel_position_to_string(channel_map->map[i]));
return -1;
}
@ -850,56 +851,6 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
return 0;
}
void pa_alsa_0dB_playback(snd_mixer_elem_t *elem) {
long min, max, v;
pa_assert(elem);
/* Try to enable 0 dB if possible. If ALSA cannot do dB, then use
* raw volume levels and fix them to 75% */
if (snd_mixer_selem_set_playback_dB_all(elem, 0, -1) >= 0)
return;
if (snd_mixer_selem_set_playback_dB_all(elem, 0, 1) >= 0)
return;
if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) < 0)
return;
v = min + ((max - min) * 3) / 4; /* 75% */
if (v <= min)
v = max;
snd_mixer_selem_set_playback_volume_all(elem, v);
}
void pa_alsa_0dB_capture(snd_mixer_elem_t *elem) {
long min, max, v;
pa_assert(elem);
/* Try to enable 0 dB if possible. If ALSA cannot do dB, then use
* raw volume levels and fix them to 75% */
if (snd_mixer_selem_set_capture_dB_all(elem, 0, -1) >= 0)
return;
if (snd_mixer_selem_set_capture_dB_all(elem, 0, 1) >= 0)
return;
if (snd_mixer_selem_get_capture_volume_range(elem, &min, &max) < 0)
return;
v = min + ((max - min) * 3) / 4; /* 75% */
if (v <= min)
v = max;
snd_mixer_selem_set_capture_volume_all(elem, v);
}
void pa_alsa_dump(snd_pcm_t *pcm) {
int err;
snd_output_t *out;
@ -1106,10 +1057,10 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
return NULL;
}
item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, n);
item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, (unsigned) n);
pollfd = pa_rtpoll_item_get_pollfd(item, NULL);
if ((err = snd_pcm_poll_descriptors(pcm, pollfd, n)) < 0) {
if ((err = snd_pcm_poll_descriptors(pcm, pollfd, (unsigned) n)) < 0) {
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
pa_rtpoll_item_free(item);
return NULL;
@ -1117,3 +1068,27 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
return item;
}
pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t) {
unsigned i;
pa_assert(r);
pa_assert(t);
pa_assert(r->channels == t->channels);
for (i = 0; i < r->channels; i++) {
double a, b, c;
a = pa_sw_volume_to_linear(r->values[i]); /* the hw volume */
b = pa_sw_volume_to_linear(t->values[i]); /* the intended volume */
if (a <= 0)
c = 0;
else
c = b / a;
r->values[i] = pa_sw_volume_from_linear(c);
}
return r;
}

View file

@ -26,6 +26,7 @@
#include <asoundlib.h>
#include <pulse/sample.h>
#include <pulse/volume.h>
#include <pulse/mainloop-api.h>
#include <pulse/channelmap.h>
#include <pulse/proplist.h>
@ -79,9 +80,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel_map, snd_mixer_selem_channel_id_t mixer_map[], pa_bool_t playback);
void pa_alsa_0dB_playback(snd_mixer_elem_t *elem);
void pa_alsa_0dB_capture(snd_mixer_elem_t *elem);
void pa_alsa_dump(snd_pcm_t *pcm);
void pa_alsa_dump_status(snd_pcm_t *pcm);
@ -94,4 +92,6 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents);
pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll);
pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t);
#endif

View file

@ -90,7 +90,7 @@ static pa_io_event_flags_t get_watch_flags(DBusWatch *watch) {
}
/* pa_io_event_cb_t IO event handler */
static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
static void handle_io_event(pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
unsigned int flags = 0;
DBusWatch *watch = userdata;
@ -126,7 +126,7 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struc
dbus_timeout_handle(timeout);
/* restart it for the next scheduled time */
pa_timeval_add(&next, dbus_timeout_get_interval(timeout) * 1000);
pa_timeval_add(&next, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
ea->time_restart(e, &next);
}
}
@ -192,7 +192,7 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {
return FALSE;
pa_gettimeofday(&tv);
pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000);
pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
ev = c->mainloop->time_new(c->mainloop, &tv, handle_time_event, timeout);
@ -227,7 +227,7 @@ static void toggle_timeout(DBusTimeout *timeout, void *data) {
struct timeval tv;
pa_gettimeofday(&tv);
pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000);
pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
c->mainloop->time_restart(ev, &tv);
} else

View file

@ -96,7 +96,7 @@ static int fill_buf(struct userdata *u) {
if ((r = pa_read(u->fd, u->buf + u->buf_fill, BUF_MAX - u->buf_fill, &u->fd_type)) <= 0)
return -1;
u->buf_fill += r;
u->buf_fill += (size_t) r;
return 0;
}
@ -123,7 +123,7 @@ static char *read_string(struct userdata *u) {
if ((e = memchr(u->buf, 0, u->buf_fill))) {
char *ret = pa_xstrdup(u->buf);
u->buf_fill -= e - u->buf +1;
u->buf_fill -= (size_t) (e - u->buf +1);
memmove(u->buf, e+1, u->buf_fill);
return ret;
}
@ -142,7 +142,7 @@ static void unload_one_module(struct userdata *u, struct module_info*m, unsigned
return;
pa_log_debug("Unloading module #%i", m->items[i].index);
pa_module_unload_by_index(u->core, m->items[i].index);
pa_module_unload_by_index(u->core, m->items[i].index, TRUE);
m->items[i].index = PA_INVALID_INDEX;
pa_xfree(m->items[i].name);
pa_xfree(m->items[i].args);
@ -164,10 +164,10 @@ static void unload_all_modules(struct userdata *u, struct module_info*m) {
static void load_module(
struct userdata *u,
struct module_info *m,
int i,
unsigned i,
const char *name,
const char *args,
int is_new) {
pa_bool_t is_new) {
pa_module *mod;
@ -324,7 +324,7 @@ static void io_event_cb(
u->io_event = NULL;
}
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
}

View file

@ -28,6 +28,10 @@
#include <asoundlib.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#include <pulse/xmalloc.h>
#include <pulse/util.h>
#include <pulse/timeval.h>
@ -68,8 +72,7 @@ PA_MODULE_USAGE(
"mmap=<enable memory mapping?> "
"tsched=<enable system timer based scheduling mode?> "
"tsched_buffer_size=<buffer size when using timer based scheduling> "
"tsched_buffer_watermark=<lower fill watermark> "
"mixer_reset=<reset hw volume and mute settings to sane defaults when falling back to software?>");
"tsched_buffer_watermark=<lower fill watermark>");
static const char* const valid_modargs[] = {
"sink_name",
@ -85,7 +88,6 @@ static const char* const valid_modargs[] = {
"tsched",
"tsched_buffer_size",
"tsched_buffer_watermark",
"mixer_reset",
NULL
};
@ -112,6 +114,8 @@ struct userdata {
long hw_volume_max, hw_volume_min;
long hw_dB_max, hw_dB_min;
pa_bool_t hw_dB_supported;
pa_bool_t mixer_seperate_channels;
pa_cvolume hardware_volume;
size_t frame_size, fragment_size, hwbuf_size, tsched_watermark;
unsigned nfragments;
@ -139,7 +143,7 @@ static void fix_tsched_watermark(struct userdata *u) {
size_t min_sleep, min_wakeup;
pa_assert(u);
max_use = u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size;
max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size;
min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->sink->sample_spec);
min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->sink->sample_spec);
@ -212,8 +216,8 @@ static int try_recover(struct userdata *u, const char *call, int err) {
static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) {
size_t left_to_play;
if (n*u->frame_size < u->hwbuf_size)
left_to_play = u->hwbuf_size - (n*u->frame_size);
if ((size_t) n*u->frame_size < u->hwbuf_size)
left_to_play = u->hwbuf_size - ((size_t) n*u->frame_size);
else
left_to_play = 0;
@ -239,7 +243,7 @@ static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) {
static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
int work_done = 0;
pa_usec_t max_sleep_usec, process_usec;
pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_play;
pa_assert(u);
@ -259,7 +263,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@ -291,6 +295,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
int err;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n;
snd_pcm_sframes_t sframes;
/* pa_log_debug("%lu frames to write", (unsigned long) frames); */
@ -326,9 +331,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
* a little bit longer around? */
pa_memblock_unref_fixed(chunk.memblock);
if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
if ((r = try_recover(u, "snd_pcm_mmap_commit", err)) == 0)
if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
continue;
return r;
@ -336,7 +341,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
work_done = 1;
u->frame_index += frames;
u->frame_index += (int64_t) frames;
u->since_start += frames * u->frame_size;
/* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
@ -344,7 +349,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
if (frames >= (snd_pcm_uframes_t) n)
break;
n -= frames;
n -= (snd_pcm_sframes_t) frames;
}
}
@ -354,7 +359,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
int work_done = 0;
pa_usec_t max_sleep_usec, process_usec;
pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_play;
pa_assert(u);
@ -371,7 +376,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@ -402,31 +407,31 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
/* pa_log_debug("%lu frames to write", (unsigned long) frames); */
if (u->memchunk.length <= 0)
pa_sink_render(u->sink, n * u->frame_size, &u->memchunk);
pa_sink_render(u->sink, (size_t) n * u->frame_size, &u->memchunk);
pa_assert(u->memchunk.length > 0);
frames = u->memchunk.length / u->frame_size;
frames = (snd_pcm_sframes_t) (u->memchunk.length / u->frame_size);
if (frames > n)
frames = n;
p = pa_memblock_acquire(u->memchunk.memblock);
frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, frames);
frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, (snd_pcm_uframes_t) frames);
pa_memblock_release(u->memchunk.memblock);
pa_assert(frames != 0);
if (PA_UNLIKELY(frames < 0)) {
if ((r = try_recover(u, "snd_pcm_writei", n)) == 0)
if ((r = try_recover(u, "snd_pcm_writei", (int) frames)) == 0)
continue;
return r;
}
u->memchunk.index += frames * u->frame_size;
u->memchunk.length -= frames * u->frame_size;
u->memchunk.index += (size_t) frames * u->frame_size;
u->memchunk.length -= (size_t) frames * u->frame_size;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@ -436,7 +441,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
work_done = 1;
u->frame_index += frames;
u->since_start += frames * u->frame_size;
u->since_start += (size_t) frames * u->frame_size;
/* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
@ -490,7 +495,7 @@ static void update_smoother(struct userdata *u) {
/* now1 = pa_timeval_load(&timestamp); */
now1 = pa_rtclock_usec();
now2 = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec);
now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->sink->sample_spec);
pa_smoother_put(u->smoother, now1, now2);
}
@ -504,7 +509,7 @@ static pa_usec_t sink_get_latency(struct userdata *u) {
now1 = pa_rtclock_usec();
now2 = pa_smoother_get(u->smoother, now1);
delay = (int64_t) pa_bytes_to_usec(u->frame_index * u->frame_size, &u->sink->sample_spec) - (int64_t) now2;
delay = (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->sink->sample_spec) - (int64_t) now2;
if (delay > 0)
r = (pa_usec_t) delay;
@ -573,9 +578,9 @@ static int update_sw_params(struct userdata *u) {
if (PA_UNLIKELY(b < u->frame_size))
b = u->frame_size;
u->hwbuf_unused_frames =
PA_LIKELY(b < u->hwbuf_size) ?
((u->hwbuf_size - b) / u->frame_size) : 0;
u->hwbuf_unused_frames = (snd_pcm_sframes_t)
(PA_LIKELY(b < u->hwbuf_size) ?
((u->hwbuf_size - b) / u->frame_size) : 0);
fix_tsched_watermark(u);
}
@ -584,7 +589,7 @@ static int update_sw_params(struct userdata *u) {
pa_log_debug("hwbuf_unused_frames=%lu", (unsigned long) u->hwbuf_unused_frames);
/* We need at last one frame in the used part of the buffer */
avail_min = u->hwbuf_unused_frames + 1;
avail_min = (snd_pcm_uframes_t) u->hwbuf_unused_frames + 1;
if (u->use_tsched) {
pa_usec_t sleep_usec, process_usec;
@ -600,7 +605,7 @@ static int update_sw_params(struct userdata *u) {
return err;
}
pa_sink_set_max_request(u->sink, u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size);
pa_sink_set_max_request(u->sink, u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size);
return 0;
}
@ -737,8 +742,8 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
return 0;
if (mask & SND_CTL_EVENT_MASK_VALUE) {
pa_sink_get_volume(u->sink);
pa_sink_get_mute(u->sink);
pa_sink_get_volume(u->sink, TRUE);
pa_sink_get_mute(u->sink, TRUE);
}
return 0;
@ -747,30 +752,68 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
static int sink_get_volume_cb(pa_sink *s) {
struct userdata *u = s->userdata;
int err;
int i;
unsigned i;
pa_cvolume r;
char t[PA_CVOLUME_SNPRINT_MAX];
pa_assert(u);
pa_assert(u->mixer_elem);
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
if (u->mixer_seperate_channels) {
pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, u->mixer_map[i]));
r.channels = s->sample_spec.channels;
if (u->hw_dB_supported) {
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) >= 0) {
s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
continue;
if (u->hw_dB_supported) {
if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
#endif
r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0);
} else {
if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
}
u->hw_dB_supported = FALSE;
}
if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
} else {
long alsa_vol;
pa_assert(u->hw_dB_supported);
if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
goto fail;
s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
#endif
pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
}
pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
if (!pa_cvolume_equal(&u->hardware_volume, &r)) {
u->hardware_volume = s->volume = r;
if (u->hw_dB_supported) {
pa_cvolume reset;
/* Hmm, so the hardware volume changed, let's reset our software volume */
pa_cvolume_reset(&reset, s->sample_spec.channels);
pa_sink_set_soft_volume(s, &reset);
}
}
return 0;
@ -784,45 +827,90 @@ fail:
static int sink_set_volume_cb(pa_sink *s) {
struct userdata *u = s->userdata;
int err;
int i;
unsigned i;
pa_cvolume r;
pa_assert(u);
pa_assert(u->mixer_elem);
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
pa_volume_t vol;
if (u->mixer_seperate_channels) {
pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, u->mixer_map[i]));
r.channels = s->sample_spec.channels;
vol = PA_MIN(s->volume.values[i], PA_VOLUME_NORM);
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
pa_volume_t vol;
if (u->hw_dB_supported) {
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
vol = s->volume.values[i];
if ((err = snd_mixer_selem_set_playback_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, -1)) >= 0) {
if (u->hw_dB_supported) {
if (snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
continue;
if ((err = snd_mixer_selem_set_playback_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0)
goto fail;
if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0);
} else {
alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
goto fail;
if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
}
u->hw_dB_supported = FALSE;
}
alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
} else {
pa_volume_t vol;
long alsa_vol;
if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
pa_assert(u->hw_dB_supported);
vol = pa_cvolume_max(&s->volume);
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
if ((err = snd_mixer_selem_set_playback_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
goto fail;
if (snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
goto fail;
pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
}
u->hardware_volume = r;
if (u->hw_dB_supported) {
char t[PA_CVOLUME_SNPRINT_MAX];
/* Match exactly what the user requested by software */
pa_alsa_volume_divide(&r, &s->volume);
pa_sink_set_soft_volume(s, &r);
pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
} else
/* We can't match exactly what the user requested, hence let's
* at least tell the user about it */
s->volume = r;
return 0;
fail:
@ -903,7 +991,7 @@ static int process_rewind(struct userdata *u) {
snd_pcm_hwsync(u->pcm_handle);
if ((unused = snd_pcm_avail_update(u->pcm_handle)) < 0) {
pa_log("snd_pcm_avail_update() failed: %s", snd_strerror(unused));
pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused));
return -1;
}
@ -922,15 +1010,15 @@ static int process_rewind(struct userdata *u) {
pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes);
in_frames = (snd_pcm_sframes_t) rewind_nbytes / u->frame_size;
in_frames = (snd_pcm_sframes_t) (rewind_nbytes / u->frame_size);
pa_log_debug("before: %lu", (unsigned long) in_frames);
if ((out_frames = snd_pcm_rewind(u->pcm_handle, in_frames)) < 0) {
pa_log("snd_pcm_rewind() failed: %s", snd_strerror(out_frames));
if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) {
pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames));
return -1;
}
pa_log_debug("after: %lu", (unsigned long) out_frames);
rewind_nbytes = out_frames * u->frame_size;
rewind_nbytes = (size_t) out_frames * u->frame_size;
if (rewind_nbytes <= 0)
pa_log_info("Tried rewind, but was apparently not possible.");
@ -974,7 +1062,7 @@ static void thread_func(void *userdata) {
/* Render some data and write it to the dsp */
if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
int work_done;
pa_usec_t sleep_usec;
pa_usec_t sleep_usec = 0;
if (u->sink->thread_info.rewind_requested)
if (process_rewind(u) < 0)
@ -1100,7 +1188,7 @@ int pa__init(pa_module*m) {
const char *name;
char *name_buf = NULL;
pa_bool_t namereg_fail;
pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, mixer_reset = TRUE;
pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
pa_usec_t usec;
pa_sink_new_data data;
@ -1124,11 +1212,11 @@ int pa__init(pa_module*m) {
frame_size = pa_frame_size(&ss);
nfrags = m->core->default_n_fragments;
frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
if (frag_size <= 0)
frag_size = frame_size;
tsched_size = pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
tsched_watermark = pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
frag_size = (uint32_t) frame_size;
tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
@ -1157,11 +1245,6 @@ int pa__init(pa_module*m) {
use_tsched = FALSE;
}
if (pa_modargs_get_value_boolean(ma, "mixer_reset", &mixer_reset) < 0) {
pa_log("Failed to parse mixer_reset argument.");
goto fail;
}
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
@ -1313,7 +1396,7 @@ int pa__init(pa_module*m) {
pa_sink_set_rtpoll(u->sink, u->rtpoll);
u->frame_size = frame_size;
u->fragment_size = frag_size = period_frames * frame_size;
u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
u->nfragments = nfrags;
u->hwbuf_size = u->fragment_size * nfrags;
u->hwbuf_unused_frames = 0;
@ -1322,6 +1405,8 @@ int pa__init(pa_module*m) {
u->hw_dB_supported = FALSE;
u->hw_dB_min = u->hw_dB_max = 0;
u->hw_volume_min = u->hw_volume_max = 0;
u->mixer_seperate_channels = FALSE;
pa_cvolume_mute(&u->hardware_volume, u->sink->sample_spec.channels);
if (use_tsched)
fix_tsched_watermark(u);
@ -1349,76 +1434,56 @@ int pa__init(pa_module*m) {
if (u->mixer_handle) {
pa_assert(u->mixer_elem);
if (snd_mixer_selem_has_playback_volume(u->mixer_elem))
if (pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0 &&
snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) >= 0) {
pa_bool_t suitable = TRUE;
if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) {
pa_bool_t suitable = TRUE;
if (snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0) {
pa_log_info("Failed to get volume range. Falling back to software volume control.");
suitable = FALSE;
} else {
pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max);
if (u->hw_volume_min > u->hw_volume_max) {
pa_log_info("Minimal volume %li larger than maximum volume %li. Strange stuff Falling back to software volume control.", u->hw_volume_min, u->hw_volume_max);
suitable = FALSE;
} else if (u->hw_volume_max - u->hw_volume_min < 3) {
pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
suitable = FALSE;
} else if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) >= 0) {
/* u->hw_dB_max = 0; u->hw_dB_min = -3000; Use this to make valgrind shut up */
pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", u->hw_dB_min/100.0, u->hw_dB_max/100.0);
/* Let's see if this thing actually is useful for muting */
if (u->hw_dB_min > -6000) {
pa_log_info("Device cannot attenuate for more than -60 dB (only %0.2f dB supported), falling back to software volume control.", ((double) u->hw_dB_min) / 100);
suitable = FALSE;
} else if (u->hw_dB_max < 0) {
pa_log_info("Device is still attenuated at maximum volume setting (%0.2f dB is maximum). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_max) / 100);
suitable = FALSE;
} else if (u->hw_dB_min >= u->hw_dB_max) {
pa_log_info("Minimal dB (%0.2f) larger or equal to maximum dB (%0.2f). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_min) / 100, ((double) u->hw_dB_max) / 100);
suitable = FALSE;
} else {
if (u->hw_dB_max > 0) {
/* dB > 0 means overamplification, and clipping, we don't want that here */
pa_log_info("Device can do overamplification for %0.2f dB. Limiting to 0 db", ((double) u->hw_dB_max) / 100);
u->hw_dB_max = 0;
}
u->hw_dB_supported = TRUE;
}
}
if (suitable) {
u->sink->get_volume = sink_get_volume_cb;
u->sink->set_volume = sink_set_volume_cb;
u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0);
pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
} else if (mixer_reset) {
pa_log_info("Using software volume control. Trying to reset sound card to 0 dB.");
pa_alsa_0dB_playback(u->mixer_elem);
} else
pa_log_info("Using software volume control. Leaving hw mixer controls untouched.");
pa_assert(u->hw_volume_min < u->hw_volume_max);
}
if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
pa_log_info("Mixer doesn't support dB information.");
else {
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min));
VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
#endif
pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
pa_assert(u->hw_dB_min < u->hw_dB_max);
u->hw_dB_supported = TRUE;
}
if (suitable &&
!u->hw_dB_supported &&
u->hw_volume_max - u->hw_volume_min < 3) {
pa_log_info("Device doesn't do dB volume and has less than 4 volume levels. Falling back to software volume control.");
suitable = FALSE;
}
if (suitable) {
u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0;
u->sink->get_volume = sink_get_volume_cb;
u->sink->set_volume = sink_set_volume_cb;
u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0);
pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
} else
pa_log_info("Using software volume control.");
}
if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) {
u->sink->get_mute = sink_get_mute_cb;
u->sink->set_mute = sink_set_mute_cb;
u->sink->flags |= PA_SINK_HW_MUTE_CTRL;
}
} else
pa_log_info("Using software mute control.");
u->mixer_fdl = pa_alsa_fdlist_new();

View file

@ -28,6 +28,10 @@
#include <asoundlib.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
#include <pulse/xmalloc.h>
#include <pulse/util.h>
#include <pulse/timeval.h>
@ -69,8 +73,7 @@ PA_MODULE_USAGE(
"mmap=<enable memory mapping?> "
"tsched=<enable system timer based scheduling mode?> "
"tsched_buffer_size=<buffer size when using timer based scheduling> "
"tsched_buffer_watermark=<upper fill watermark> "
"mixer_reset=<reset hw volume and mute settings to sane defaults when falling back to software?>");
"tsched_buffer_watermark=<upper fill watermark>");
static const char* const valid_modargs[] = {
"source_name",
@ -86,7 +89,6 @@ static const char* const valid_modargs[] = {
"tsched",
"tsched_buffer_size",
"tsched_buffer_watermark",
"mixer_reset",
NULL
};
@ -113,6 +115,9 @@ struct userdata {
long hw_volume_max, hw_volume_min;
long hw_dB_max, hw_dB_min;
pa_bool_t hw_dB_supported;
pa_bool_t mixer_seperate_channels;
pa_cvolume hardware_volume;
size_t frame_size, fragment_size, hwbuf_size, tsched_watermark;
unsigned nfragments;
@ -136,7 +141,7 @@ static void fix_tsched_watermark(struct userdata *u) {
size_t min_sleep, min_wakeup;
pa_assert(u);
max_use = u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size;
max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size;
min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->source->sample_spec);
min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->source->sample_spec);
@ -207,8 +212,8 @@ static int try_recover(struct userdata *u, const char *call, int err) {
static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
size_t left_to_record;
if (n*u->frame_size < u->hwbuf_size)
left_to_record = u->hwbuf_size - (n*u->frame_size);
if ((size_t) n*u->frame_size < u->hwbuf_size)
left_to_record = u->hwbuf_size - ((size_t) n*u->frame_size);
else
left_to_record = 0;
@ -234,7 +239,7 @@ static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
int work_done = 0;
pa_usec_t max_sleep_usec, process_usec;
pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_record;
pa_assert(u);
@ -251,7 +256,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@ -272,6 +277,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n;
pa_memchunk chunk;
void *p;
snd_pcm_sframes_t sframes;
/* pa_log_debug("%lu frames to read", (unsigned long) frames); */
@ -304,9 +310,9 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
pa_source_post(u->source, &chunk);
pa_memblock_unref_fixed(chunk.memblock);
if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
if ((r = try_recover(u, "snd_pcm_mmap_commit", err)) == 0)
if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
continue;
return r;
@ -314,14 +320,14 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
work_done = 1;
u->frame_index += frames;
u->frame_index += (int64_t) frames;
/* pa_log_debug("read %lu frames", (unsigned long) frames); */
if (frames >= (snd_pcm_uframes_t) n)
break;
n -= frames;
n -= (snd_pcm_sframes_t) frames;
}
}
@ -331,7 +337,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
int work_done = 0;
pa_usec_t max_sleep_usec, process_usec;
pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_record;
pa_assert(u);
@ -348,7 +354,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@ -370,7 +376,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
frames = pa_memblock_get_length(chunk.memblock) / u->frame_size;
frames = (snd_pcm_sframes_t) (pa_memblock_get_length(chunk.memblock) / u->frame_size);
if (frames > n)
frames = n;
@ -378,7 +384,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
/* pa_log_debug("%lu frames to read", (unsigned long) n); */
p = pa_memblock_acquire(chunk.memblock);
frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, frames);
frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames);
pa_memblock_release(chunk.memblock);
pa_assert(frames != 0);
@ -386,14 +392,14 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
if (PA_UNLIKELY(frames < 0)) {
pa_memblock_unref(chunk.memblock);
if ((r = try_recover(u, "snd_pcm_readi", n)) == 0)
if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0)
continue;
return r;
}
chunk.index = 0;
chunk.length = frames * u->frame_size;
chunk.length = (size_t) frames * u->frame_size;
pa_source_post(u->source, &chunk);
pa_memblock_unref(chunk.memblock);
@ -437,7 +443,7 @@ static void update_smoother(struct userdata *u) {
frames = u->frame_index + delay;
now1 = pa_rtclock_usec();
now2 = pa_bytes_to_usec(frames * u->frame_size, &u->source->sample_spec);
now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->source->sample_spec);
pa_smoother_put(u->smoother, now1, now2);
}
@ -452,7 +458,7 @@ static pa_usec_t source_get_latency(struct userdata *u) {
now1 = pa_rtclock_usec();
now2 = pa_smoother_get(u->smoother, now1);
delay = (int64_t) now2 - pa_bytes_to_usec(u->frame_index * u->frame_size, &u->source->sample_spec);
delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->source->sample_spec);
if (delay > 0)
r = (pa_usec_t) delay;
@ -517,9 +523,9 @@ static int update_sw_params(struct userdata *u) {
if (PA_UNLIKELY(b < u->frame_size))
b = u->frame_size;
u->hwbuf_unused_frames =
PA_LIKELY(b < u->hwbuf_size) ?
((u->hwbuf_size - b) / u->frame_size) : 0;
u->hwbuf_unused_frames = (snd_pcm_sframes_t)
(PA_LIKELY(b < u->hwbuf_size) ?
((u->hwbuf_size - b) / u->frame_size) : 0);
fix_tsched_watermark(u);
}
@ -680,8 +686,8 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
return 0;
if (mask & SND_CTL_EVENT_MASK_VALUE) {
pa_source_get_volume(u->source);
pa_source_get_mute(u->source);
pa_source_get_volume(u->source, TRUE);
pa_source_get_mute(u->source, TRUE);
}
return 0;
@ -690,30 +696,68 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
static int source_get_volume_cb(pa_source *s) {
struct userdata *u = s->userdata;
int err;
int i;
unsigned i;
pa_cvolume r;
char t[PA_CVOLUME_SNPRINT_MAX];
pa_assert(u);
pa_assert(u->mixer_elem);
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
if (u->mixer_seperate_channels) {
pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, u->mixer_map[i]));
r.channels = s->sample_spec.channels;
if (u->hw_dB_supported) {
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) >= 0) {
s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
continue;
if (u->hw_dB_supported) {
if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
#endif
r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0);
} else {
if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
}
u->hw_dB_supported = FALSE;
}
if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
} else {
long alsa_vol;
pa_assert(u->hw_dB_supported);
if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
goto fail;
s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
#endif
pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
}
pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
if (!pa_cvolume_equal(&u->hardware_volume, &r)) {
u->hardware_volume = s->volume = r;
if (u->hw_dB_supported) {
pa_cvolume reset;
/* Hmm, so the hardware volume changed, let's reset our software volume */
pa_cvolume_reset(&reset, s->sample_spec.channels);
pa_source_set_soft_volume(s, &reset);
}
}
return 0;
@ -727,45 +771,90 @@ fail:
static int source_set_volume_cb(pa_source *s) {
struct userdata *u = s->userdata;
int err;
int i;
unsigned i;
pa_cvolume r;
pa_assert(u);
pa_assert(u->mixer_elem);
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
pa_volume_t vol;
if (u->mixer_seperate_channels) {
pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, u->mixer_map[i]));
r.channels = s->sample_spec.channels;
vol = PA_MIN(s->volume.values[i], PA_VOLUME_NORM);
for (i = 0; i < s->sample_spec.channels; i++) {
long alsa_vol;
pa_volume_t vol;
if (u->hw_dB_supported) {
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
vol = s->volume.values[i];
if (u->hw_dB_supported) {
if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, -1)) >= 0) {
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
if (snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0)
goto fail;
continue;
if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0);
} else {
alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
goto fail;
if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
goto fail;
r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
}
u->hw_dB_supported = FALSE;
}
alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
} else {
pa_volume_t vol;
long alsa_vol;
if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
pa_assert(u->hw_dB_supported);
vol = pa_cvolume_max(&s->volume);
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
if ((err = snd_mixer_selem_set_capture_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
goto fail;
if (snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
goto fail;
pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
}
u->hardware_volume = r;
if (u->hw_dB_supported) {
char t[PA_CVOLUME_SNPRINT_MAX];
/* Match exactly what the user requested by software */
pa_alsa_volume_divide(&r, &s->volume);
pa_source_set_soft_volume(s, &r);
pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
} else
/* We can't match exactly what the user requested, hence let's
* at least tell the user about it */
s->volume = r;
return 0;
fail:
@ -837,7 +926,7 @@ static void thread_func(void *userdata) {
/* Read some data and pass it to the sources */
if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
int work_done = 0;
pa_usec_t sleep_usec;
pa_usec_t sleep_usec = 0;
if (u->use_mmap)
work_done = mmap_read(u, &sleep_usec);
@ -932,7 +1021,7 @@ int pa__init(pa_module*m) {
const char *name;
char *name_buf = NULL;
pa_bool_t namereg_fail;
pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, mixer_reset = TRUE;
pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
pa_source_new_data data;
snd_pcm_info_alloca(&pcm_info);
@ -955,11 +1044,11 @@ int pa__init(pa_module*m) {
frame_size = pa_frame_size(&ss);
nfrags = m->core->default_n_fragments;
frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
if (frag_size <= 0)
frag_size = frame_size;
tsched_size = pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
tsched_watermark = pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
frag_size = (uint32_t) frame_size;
tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
@ -988,11 +1077,6 @@ int pa__init(pa_module*m) {
use_tsched = FALSE;
}
if (pa_modargs_get_value_boolean(ma, "mixer_reset", &mixer_reset) < 0) {
pa_log("Failed to parse mixer_reset argument.");
goto fail;
}
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
@ -1137,7 +1221,7 @@ int pa__init(pa_module*m) {
pa_source_set_rtpoll(u->source, u->rtpoll);
u->frame_size = frame_size;
u->fragment_size = frag_size = period_frames * frame_size;
u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
u->nfragments = nfrags;
u->hwbuf_size = u->fragment_size * nfrags;
u->hwbuf_unused_frames = 0;
@ -1146,6 +1230,8 @@ int pa__init(pa_module*m) {
u->hw_dB_supported = FALSE;
u->hw_dB_min = u->hw_dB_max = 0;
u->hw_volume_min = u->hw_volume_max = 0;
u->mixer_seperate_channels = FALSE;
pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels);
if (use_tsched)
fix_tsched_watermark(u);
@ -1168,67 +1254,56 @@ int pa__init(pa_module*m) {
if (u->mixer_handle) {
pa_assert(u->mixer_elem);
if (snd_mixer_selem_has_capture_volume(u->mixer_elem))
if (pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0 &&
snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) >= 0) {
pa_bool_t suitable = TRUE;
if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
pa_bool_t suitable = TRUE;
if (snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0) {
pa_log_info("Failed to get volume range. Falling back to software volume control.");
suitable = FALSE;
} else {
pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max);
if (u->hw_volume_min > u->hw_volume_max) {
pa_log_info("Minimal volume %li larger than maximum volume %li. Strange stuff Falling back to software volume control.", u->hw_volume_min, u->hw_volume_max);
suitable = FALSE;
} else if (u->hw_volume_max - u->hw_volume_min < 3) {
pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
suitable = FALSE;
} else if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) >= 0) {
pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", u->hw_dB_min/100.0, u->hw_dB_max/100.0);
/* Let's see if this thing actually is useful for muting */
if (u->hw_dB_min > -6000) {
pa_log_info("Device cannot attenuate for more than -60 dB (only %0.2f dB supported), falling back to software volume control.", ((double) u->hw_dB_min) / 100);
suitable = FALSE;
} else if (u->hw_dB_max < 0) {
pa_log_info("Device is still attenuated at maximum volume setting (%0.2f dB is maximum). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_max) / 100);
suitable = FALSE;
} else if (u->hw_dB_min >= u->hw_dB_max) {
pa_log_info("Minimal dB (%0.2f) larger or equal to maximum dB (%0.2f). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_min) / 100, ((double) u->hw_dB_max) / 100);
suitable = FALSE;
} else
u->hw_dB_supported = TRUE;
}
if (suitable) {
u->source->get_volume = source_get_volume_cb;
u->source->set_volume = source_set_volume_cb;
u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0);
pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
} else if (mixer_reset) {
pa_log_info("Using software volume control. Trying to reset sound card to 0 dB.");
pa_alsa_0dB_capture(u->mixer_elem);
} else
pa_log_info("Using software volume control. Leaving hw mixer controls untouched.");
pa_assert(u->hw_volume_min < u->hw_volume_max);
}
if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
pa_log_info("Mixer doesn't support dB information.");
else {
#ifdef HAVE_VALGRIND_MEMCHECK_H
VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min));
VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
#endif
pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
pa_assert(u->hw_dB_min < u->hw_dB_max);
u->hw_dB_supported = TRUE;
}
if (suitable &&
!u->hw_dB_supported &&
u->hw_volume_max - u->hw_volume_min < 3) {
pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
suitable = FALSE;
}
if (suitable) {
u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0;
u->source->get_volume = source_get_volume_cb;
u->source->set_volume = source_set_volume_cb;
u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0);
pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
} else
pa_log_info("Using software volume control.");
}
if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) {
u->source->get_mute = source_get_mute_cb;
u->source->set_mute = source_set_mute_cb;
u->source->flags |= PA_SOURCE_HW_MUTE_CTRL;
}
} else
pa_log_info("Using software mute control.");
u->mixer_fdl = pa_alsa_fdlist_new();

View file

@ -108,7 +108,7 @@ static pa_hook_result_t put_hook_callback(pa_core *c, pa_sink *sink, void* userd
pa_log_info("A new sink has been discovered. Unloading null-sink.");
pa_module_unload_request(u->null_module);
pa_module_unload_request(u->null_module, TRUE);
u->null_module = NULL;
return PA_HOOK_OK;
@ -171,7 +171,7 @@ void pa__done(pa_module*m) {
if (u->unlink_slot)
pa_hook_slot_free(u->unlink_slot);
if (u->null_module)
pa_module_unload_request(u->null_module);
pa_module_unload_request(u->null_module, TRUE);
pa_xfree(u->sink_name);
pa_xfree(u);

View file

@ -53,7 +53,7 @@ static void eof_and_unload_cb(pa_cli*c, void *userdata) {
pa_assert(c);
pa_assert(m);
pa_module_unload_request(m);
pa_module_unload_request(m, TRUE);
}
static void eof_and_exit_cb(pa_cli*c, void *userdata) {
@ -62,7 +62,7 @@ static void eof_and_exit_cb(pa_cli*c, void *userdata) {
pa_assert(c);
pa_assert(m);
m->core->mainloop->quit(m->core->mainloop, 0);
pa_core_exit(m->core, FALSE, 0);
}
int pa__init(pa_module*m) {

View file

@ -206,9 +206,9 @@ static void adjust_rates(struct userdata *u) {
continue;
if (o->total_latency < target_latency)
r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/PA_USEC_PER_SEC);
r -= (uint32_t) ((((double) (target_latency - o->total_latency))/(double)u->adjust_time)*(double)r/PA_USEC_PER_SEC);
else if (o->total_latency > target_latency)
r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/PA_USEC_PER_SEC);
r += (uint32_t) ((((double) (o->total_latency - target_latency))/(double)u->adjust_time)*(double)r/PA_USEC_PER_SEC);
if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) {
pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", pa_proplist_gets(o->sink_input->proplist, PA_PROP_MEDIA_NAME), base_rate, r);
@ -233,7 +233,7 @@ static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct time
adjust_rates(u);
pa_gettimeofday(&n);
n.tv_sec += u->adjust_time;
n.tv_sec += (time_t) u->adjust_time;
u->sink->core->mainloop->time_restart(e, &n);
}
@ -389,7 +389,7 @@ static void request_memblock(struct output *o, size_t length) {
/* OK, we need to prepare new data, but only if the sink is actually running */
if (pa_atomic_load(&o->userdata->thread_info.running))
pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, length, NULL);
pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, (int64_t) length, NULL);
}
/* Called from I/O thread context */
@ -489,7 +489,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
pa_sink_input_assert_ref(i);
pa_assert(o = i->userdata);
pa_module_unload_request(o->userdata->module);
pa_module_unload_request(o->userdata->module, TRUE);
output_free(o);
}
@ -1159,7 +1159,7 @@ int pa__init(pa_module*m) {
if (u->adjust_time > 0) {
struct timeval tv;
pa_gettimeofday(&tv);
tv.tv_sec += u->adjust_time;
tv.tv_sec += (time_t) u->adjust_time;
u->time_event = m->core->mainloop->time_new(m->core->mainloop, &tv, time_callback, u);
}

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
#include <pulsecore/core-util.h>
#include <pulsecore/module.h>
@ -41,8 +42,6 @@ PA_MODULE_DESCRIPTION("Automatically restore the default sink and source");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(TRUE);
#define DEFAULT_SINK_FILE "default-sink"
#define DEFAULT_SOURCE_FILE "default-source"
#define DEFAULT_SAVE_INTERVAL 5
struct userdata {
@ -161,10 +160,10 @@ int pa__init(pa_module *m) {
m->userdata = u = pa_xnew0(struct userdata, 1);
u->core = m->core;
if (!(u->sink_filename = pa_state_path(DEFAULT_SINK_FILE)))
if (!(u->sink_filename = pa_state_path("default-sink", TRUE)))
goto fail;
if (!(u->source_filename = pa_state_path(DEFAULT_SOURCE_FILE)))
if (!(u->source_filename = pa_state_path("default-source", TRUE)))
goto fail;
load(u);

View file

@ -236,16 +236,16 @@ int pa__init(pa_module*m) {
goto fail;
}
#if HAVE_ALSA
#ifdef HAVE_ALSA
if ((n = detect_alsa(m->core, just_one)) <= 0)
#endif
#if HAVE_OSS
if ((n = detect_oss(m->core, just_one)) <= 0)
#endif
#if HAVE_SOLARIS
#ifdef HAVE_SOLARIS
if ((n = detect_solaris(m->core, just_one)) <= 0)
#endif
#if OS_IS_WIN32
#ifdef OS_IS_WIN32
if ((n = detect_waveout(m->core, just_one)) <= 0)
#endif
{
@ -256,7 +256,7 @@ int pa__init(pa_module*m) {
pa_log_info("loaded %i modules.", n);
/* We were successful and can unload ourselves now. */
pa_module_unload_request(m);
pa_module_unload_request(m, TRUE);
pa_modargs_free(ma);

View file

@ -1,7 +1,7 @@
/***
This file is part of PulseAudio.
Copyright 2006 Lennart Poettering
Copyright 2006-2008 Lennart Poettering
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
@ -64,6 +64,7 @@ static const char* const valid_modargs[] = {
struct userdata {
pa_core *core;
pa_module *module;
pa_subscription *subscription;
pa_hook_slot
*sink_fixate_hook_slot,
@ -76,6 +77,7 @@ struct userdata {
};
struct entry {
pa_channel_map channel_map;
pa_cvolume volume;
pa_bool_t muted:1;
};
@ -104,7 +106,7 @@ static struct entry* read_entry(struct userdata *u, char *name) {
pa_assert(name);
key.dptr = name;
key.dsize = strlen(name);
key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@ -123,6 +125,16 @@ static struct entry* read_entry(struct userdata *u, char *name) {
goto fail;
}
if (!(pa_channel_map_valid(&e->channel_map))) {
pa_log_warn("Invalid channel map stored in database for device %s", name);
goto fail;
}
if (e->volume.channels != e->channel_map.channels) {
pa_log_warn("Volume and channel map don't match in database entry for device %s", name);
goto fail;
}
return e;
fail:
@ -131,6 +143,17 @@ fail:
return NULL;
}
static void trigger_save(struct userdata *u) {
struct timeval tv;
if (u->save_time_event)
return;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
}
static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
struct userdata *u = userdata;
struct entry entry, *old;
@ -146,6 +169,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE))
return;
memset(&entry, 0, sizeof(entry));
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) {
pa_sink *sink;
@ -153,8 +178,9 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
return;
name = pa_sprintf_malloc("sink:%s", sink->name);
entry.volume = *pa_sink_get_volume(sink);
entry.muted = pa_sink_get_mute(sink);
entry.channel_map = sink->channel_map;
entry.volume = *pa_sink_get_volume(sink, FALSE);
entry.muted = pa_sink_get_mute(sink, FALSE);
} else {
pa_source *source;
@ -165,13 +191,14 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
return;
name = pa_sprintf_malloc("source:%s", source->name);
entry.volume = *pa_source_get_volume(source);
entry.muted = pa_source_get_mute(source);
entry.channel_map = source->channel_map;
entry.volume = *pa_source_get_volume(source, FALSE);
entry.muted = pa_source_get_mute(source, FALSE);
}
if ((old = read_entry(u, name))) {
if (pa_cvolume_equal(&old->volume, &entry.volume) &&
if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) &&
!old->muted == !entry.muted) {
pa_xfree(old);
@ -183,7 +210,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
}
key.dptr = name;
key.dsize = strlen(name);
key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
@ -192,14 +219,9 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
gdbm_store(u->gdbm_file, key, data, GDBM_REPLACE);
if (!u->save_time_event) {
struct timeval tv;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
}
pa_xfree(name);
trigger_save(u);
}
static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
@ -212,11 +234,9 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *
if ((e = read_entry(u, name))) {
if (u->restore_volume &&
e->volume.channels == new_data->sample_spec.channels) {
if (u->restore_volume) {
pa_log_info("Restoring volume for sink %s.", new_data->name);
pa_sink_new_data_set_volume(new_data, &e->volume);
pa_sink_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
}
if (u->restore_muted) {
@ -242,11 +262,9 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
if ((e = read_entry(u, name))) {
if (u->restore_volume &&
e->volume.channels == new_data->sample_spec.channels) {
if (u->restore_volume) {
pa_log_info("Restoring volume for source %s.", new_data->name);
pa_source_new_data_set_volume(new_data, &e->volume);
pa_source_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
}
if (u->restore_muted) {
@ -266,7 +284,6 @@ int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
struct userdata *u;
char *fname, *fn;
char hn[256];
pa_sink *sink;
pa_source *source;
uint32_t idx;
@ -290,9 +307,11 @@ int pa__init(pa_module*m) {
m->userdata = u = pa_xnew(struct userdata, 1);
u->core = m->core;
u->module = m;
u->save_time_event = NULL;
u->restore_volume = restore_volume;
u->restore_muted = restore_muted;
u->gdbm_file = NULL;
u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE, subscribe_callback, u);
@ -301,11 +320,12 @@ int pa__init(pa_module*m) {
u->source_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_fixate_hook_callback, u);
}
if (!pa_get_host_name(hn, sizeof(hn)))
goto fail;
/* We include the host identifier in the file name because gdbm
* files are CPU dependant, and we don't want things to go wrong
* if we are on a multiarch system. */
fn = pa_sprintf_malloc("device-volumes.%s."CANONICAL_HOST".gdbm", hn);
fname = pa_state_path(fn);
fn = pa_sprintf_malloc("device-volumes."CANONICAL_HOST".gdbm");
fname = pa_state_path(fn, TRUE);
pa_xfree(fn);
if (!fname)

View file

@ -66,7 +66,7 @@ int pa__init(pa_module*m) {
pa_assert_se(pa_close(fd) == 0);
pa_module_unload_request(m);
pa_module_unload_request(m, TRUE);
ret = 0;

View file

@ -62,10 +62,10 @@ int pa__init(pa_module*m) {
goto finish;
}
if (kill(pid, SIGUSR1) < 0)
if (kill((pid_t) pid, SIGUSR1) < 0)
pa_log_warn("kill(%u) failed: %s", pid, pa_cstrerror(errno));
pa_module_unload_request(m);
pa_module_unload_request(m, TRUE);
ret = 0;

View file

@ -165,7 +165,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_usec_t w, r;
r = pa_smoother_get(u->smoother, pa_rtclock_usec());
w = pa_bytes_to_usec(u->offset + u->memchunk.length, &u->sink->sample_spec);
w = pa_bytes_to_usec((uint64_t) u->offset + u->memchunk.length, &u->sink->sample_spec);
*((pa_usec_t*) data) = w > r ? w - r : 0;
break;
@ -250,8 +250,8 @@ static void thread_func(void *userdata) {
} else {
u->offset += l;
u->memchunk.index += l;
u->memchunk.length -= l;
u->memchunk.index += (size_t) l;
u->memchunk.length -= (size_t) l;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@ -285,7 +285,7 @@ static void thread_func(void *userdata) {
}
#endif
usec = pa_bytes_to_usec(n, &u->sink->sample_spec);
usec = pa_bytes_to_usec((uint64_t) n, &u->sink->sample_spec);
if (usec > u->latency)
usec -= u->latency;
@ -296,7 +296,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
pollfd->events = PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0;
pollfd->events = (short) (PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0);
}
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
@ -342,7 +342,7 @@ static int do_write(struct userdata *u) {
return -1;
}
u->write_index += r;
u->write_index += (size_t) r;
pa_assert(u->write_index <= u->write_length);
if (u->write_index == u->write_length) {
@ -458,7 +458,7 @@ static int do_read(struct userdata *u) {
return -1;
}
u->read_index += r;
u->read_index += (size_t) r;
pa_assert(u->read_index <= u->read_length);
if (u->read_index == u->read_length)
@ -468,7 +468,7 @@ static int do_read(struct userdata *u) {
return 0;
}
static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) {
static void io_callback(pa_iochannel *io, void*userdata) {
struct userdata *u = userdata;
pa_assert(u);
@ -479,11 +479,11 @@ static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) {
u->io = NULL;
}
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
}
static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, void *userdata) {
static void on_connection(pa_socket_client *c, pa_iochannel*io, void *userdata) {
struct userdata *u = userdata;
pa_socket_client_unref(u->client);
@ -491,7 +491,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, vo
if (!io) {
pa_log("Connection failed: %s", pa_cstrerror(errno));
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
return;
}
@ -545,7 +545,7 @@ int pa__init(pa_module*m) {
u->format =
(ss.format == PA_SAMPLE_U8 ? ESD_BITS8 : ESD_BITS16) |
(ss.channels == 2 ? ESD_STEREO : ESD_MONO);
u->rate = ss.rate;
u->rate = (int32_t) ss.rate;
u->block_size = pa_usec_to_bytes(PA_USEC_PER_SEC/20, &ss);
u->read_data = u->write_data = NULL;

View file

@ -108,7 +108,7 @@ static void hal_device_free(struct device* d) {
pa_xfree(d);
}
static void hal_device_free_cb(void *d, PA_GCC_UNUSED void *data) {
static void hal_device_free_cb(void *d, void *data) {
hal_device_free(d);
}
@ -405,7 +405,7 @@ static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const s
dbus_error_init(&error);
if (!pa_hashmap_get(td->u->devices, td->udi)) {
int b;
dbus_bool_t b;
struct device *d;
b = libhal_device_exists(td->u->context, td->udi, &error);
@ -433,7 +433,7 @@ static void device_added_cb(LibHalContext *context, const char *udi) {
struct timeval tv;
struct timerdata *t;
struct userdata *u;
int good = 0;
pa_bool_t good = FALSE;
pa_assert_se(u = libhal_ctx_get_user_data(context));
@ -511,7 +511,7 @@ static void device_removed_cb(LibHalContext* context, const char *udi) {
pa_log_debug("Device removed: %s", udi);
if ((d = pa_hashmap_remove(u->devices, udi))) {
pa_module_unload_by_index(u->core, d->index);
pa_module_unload_by_index(u->core, d->index, TRUE);
hal_device_free(d);
}
}
@ -749,17 +749,17 @@ int pa__init(pa_module*m) {
}
if ((api = pa_modargs_get_value(ma, "api", NULL))) {
int good = 0;
pa_bool_t good = FALSE;
#ifdef HAVE_ALSA
if (strcmp(api, CAPABILITY_ALSA) == 0) {
good = 1;
good = TRUE;
api = CAPABILITY_ALSA;
}
#endif
#ifdef HAVE_OSS
if (strcmp(api, CAPABILITY_OSS) == 0) {
good = 1;
good = TRUE;
api = CAPABILITY_OSS;
}
#endif

View file

@ -130,12 +130,12 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
void *p;
pa_assert(offset > 0);
nbytes = offset * pa_frame_size(&u->sink->sample_spec);
nbytes = (size_t) offset * pa_frame_size(&u->sink->sample_spec);
pa_sink_render_full(u->sink, nbytes, &chunk);
p = (uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index;
pa_deinterleave(p, u->buffer, u->channels, sizeof(float), offset);
pa_deinterleave(p, u->buffer, u->channels, sizeof(float), (unsigned) offset);
pa_memblock_release(chunk.memblock);
pa_memblock_unref(chunk.memblock);
@ -149,10 +149,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
ss.channels = 1;
for (c = 0; c < u->channels; c++)
pa_silence_memory(u->buffer[c], offset * pa_sample_size(&ss), &ss);
pa_silence_memory(u->buffer[c], (size_t) offset * pa_sample_size(&ss), &ss);
}
u->frames_in_buffer = offset;
u->frames_in_buffer = (jack_nframes_t) offset;
u->saved_frame_time = * (jack_nframes_t*) data;
u->saved_frame_time_valid = TRUE;
@ -342,7 +342,7 @@ int pa__init(pa_module*m) {
pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client));
ss.channels = u->channels = channels;
u->channels = ss.channels = (uint8_t) channels;
ss.rate = jack_get_sample_rate(u->client);
ss.format = PA_SAMPLE_FLOAT32NE;

View file

@ -116,7 +116,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
if (u->source->thread_info.state == PA_SOURCE_RUNNING)
pa_source_post(u->source, chunk);
u->saved_frame_time = offset;
u->saved_frame_time = (jack_nframes_t) offset;
u->saved_frame_time_valid = TRUE;
return 0;
@ -309,7 +309,7 @@ int pa__init(pa_module*m) {
pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client));
ss.channels = u->channels = channels;
u->channels = ss.channels = (uint8_t) channels;
ss.rate = jack_get_sample_rate(u->client);
ss.format = PA_SAMPLE_FLOAT32NE;

View file

@ -187,7 +187,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
pa_assert(tchunk.length > 0);
fs = pa_frame_size(&i->sample_spec);
n = PA_MIN(tchunk.length, u->block_size) / fs;
n = (unsigned) (PA_MIN(tchunk.length, u->block_size) / fs);
pa_assert(n > 0);
@ -340,7 +340,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
pa_sink_input_unref(u->sink_input);
u->sink_input = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from IO thread context */
@ -502,9 +502,9 @@ int pa__init(pa_module*m) {
u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss);
u->input = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size);
u->input = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
if (LADSPA_IS_INPLACE_BROKEN(d->Properties))
u->output = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size);
u->output = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
else
u->output = u->input;
@ -530,8 +530,8 @@ int pa__init(pa_module*m) {
char *k;
unsigned long h;
u->control = pa_xnew(LADSPA_Data, n_control);
use_default = pa_xnew(pa_bool_t, n_control);
u->control = pa_xnew(LADSPA_Data, (unsigned) n_control);
use_default = pa_xnew(pa_bool_t, (unsigned) n_control);
p = 0;
while ((k = pa_split(cdata, ",", &state)) && p < n_control) {
@ -552,7 +552,7 @@ int pa__init(pa_module*m) {
pa_xfree(k);
use_default[p] = FALSE;
u->control[p++] = f;
u->control[p++] = (LADSPA_Data) f;
}
/* The previous loop doesn't take the last control value into account
@ -601,8 +601,8 @@ int pa__init(pa_module*m) {
upper = d->PortRangeHints[p].UpperBound;
if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) {
lower *= ss.rate;
upper *= ss.rate;
lower *= (LADSPA_Data) ss.rate;
upper *= (LADSPA_Data) ss.rate;
}
switch (hint & LADSPA_HINT_DEFAULT_MASK) {
@ -617,23 +617,23 @@ int pa__init(pa_module*m) {
case LADSPA_HINT_DEFAULT_LOW:
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
u->control[h] = exp(log(lower) * 0.75 + log(upper) * 0.25);
u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25);
else
u->control[h] = lower * 0.75 + upper * 0.25;
u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25);
break;
case LADSPA_HINT_DEFAULT_MIDDLE:
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
u->control[h] = exp(log(lower) * 0.5 + log(upper) * 0.5);
u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5);
else
u->control[h] = lower * 0.5 + upper * 0.5;
u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5);
break;
case LADSPA_HINT_DEFAULT_HIGH:
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
u->control[h] = exp(log(lower) * 0.25 + log(upper) * 0.75);
u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75);
else
u->control[h] = lower * 0.25 + upper * 0.75;
u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75);
break;
case LADSPA_HINT_DEFAULT_0:

View file

@ -65,7 +65,7 @@ struct userdata {
static int lirc_in_use = 0;
static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) {
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
struct userdata *u = userdata;
char *name = NULL, *code = NULL;
@ -122,7 +122,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
pa_log("Failed to get sink '%s'", u->sink_name);
else {
int i;
pa_cvolume cv = *pa_sink_get_volume(s);
pa_cvolume cv = *pa_sink_get_volume(s, FALSE);
#define DELTA (PA_VOLUME_NORM/20)
@ -159,7 +159,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
case MUTE_TOGGLE:
pa_sink_set_mute(s, !pa_sink_get_mute(s));
pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE));
break;
case INVALID:
@ -178,7 +178,7 @@ fail:
u->module->core->mainloop->io_free(u->io);
u->io = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
pa_xfree(code);
}

View file

@ -76,7 +76,7 @@ struct userdata {
pa_module *module;
};
static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) {
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
struct userdata *u = userdata;
pa_assert(io);
@ -113,7 +113,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
pa_log("Failed to get sink '%s'", u->sink_name);
else {
int i;
pa_cvolume cv = *pa_sink_get_volume(s);
pa_cvolume cv = *pa_sink_get_volume(s, FALSE);
#define DELTA (PA_VOLUME_NORM/20)
@ -142,7 +142,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
case MUTE_TOGGLE:
pa_sink_set_mute(s, !pa_sink_get_mute(s));
pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE));
break;
case INVALID:
@ -159,7 +159,7 @@ fail:
u->module->core->mainloop->io_free(u->io);
u->io = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))

View file

@ -48,7 +48,8 @@ static const char* const valid_modargs[] = {
int pa__init(pa_module*m) {
pa_iochannel *io;
pa_modargs *ma;
int fd, r = -1;
int32_t fd;
int r = -1;
pa_native_options *options = NULL;
pa_assert(m);
@ -63,18 +64,16 @@ int pa__init(pa_module*m) {
goto finish;
}
m->userdata = pa_native_protocol_get(m->core);
io = pa_iochannel_new(m->core->mainloop, fd, fd);
options = pa_native_options_new();
options->module = m;
options->auth_anonymous = TRUE;
io = pa_iochannel_new(m->core->mainloop, fd, fd);
m->userdata = pa_native_protocol_get(m->core);
pa_native_protocol_connect(m->userdata, io, options);
pa_native_options_unref(options);
r = 0;
finish:

View file

@ -258,7 +258,7 @@ static int mmap_write(struct userdata *u) {
u->out_mmap_saved_nfrags = 0;
if (info.blocks > 0)
mmap_fill_memblocks(u, info.blocks);
mmap_fill_memblocks(u, (unsigned) info.blocks);
return info.blocks;
}
@ -336,7 +336,7 @@ static int mmap_read(struct userdata *u) {
u->in_mmap_saved_nfrags = 0;
if (info.blocks > 0) {
mmap_post_memblocks(u, info.blocks);
mmap_post_memblocks(u, (unsigned) info.blocks);
mmap_clear_memblocks(u, u->in_nfrags/2);
}
@ -356,12 +356,12 @@ static pa_usec_t mmap_sink_get_latency(struct userdata *u) {
u->out_mmap_saved_nfrags += info.blocks;
bpos = ((u->out_mmap_current + u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size;
bpos = ((u->out_mmap_current + (unsigned) u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size;
if (bpos <= (size_t) info.ptr)
n = u->out_hwbuf_size - (info.ptr - bpos);
n = u->out_hwbuf_size - ((size_t) info.ptr - bpos);
else
n = bpos - info.ptr;
n = bpos - (size_t) info.ptr;
/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->out_fragment_size, u->out_fragments); */
@ -380,12 +380,12 @@ static pa_usec_t mmap_source_get_latency(struct userdata *u) {
}
u->in_mmap_saved_nfrags += info.blocks;
bpos = ((u->in_mmap_current + u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size;
bpos = ((u->in_mmap_current + (unsigned) u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size;
if (bpos <= (size_t) info.ptr)
n = info.ptr - bpos;
n = (size_t) info.ptr - bpos;
else
n = u->in_hwbuf_size - bpos + info.ptr;
n = u->in_hwbuf_size - bpos + (size_t) info.ptr;
/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->in_fragment_size, u->in_fragments); */
@ -404,7 +404,7 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) {
pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno));
u->use_getodelay = 0;
} else
r = pa_bytes_to_usec(arg, &u->sink->sample_spec);
r = pa_bytes_to_usec((size_t) arg, &u->sink->sample_spec);
}
@ -415,7 +415,7 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) {
pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno));
u->use_getospace = 0;
} else
r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec);
r = pa_bytes_to_usec((size_t) info.bytes, &u->sink->sample_spec);
}
if (u->memchunk.memblock)
@ -437,7 +437,7 @@ static pa_usec_t io_source_get_latency(struct userdata *u) {
pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno));
u->use_getispace = 0;
} else
r = pa_bytes_to_usec(info.bytes, &u->source->sample_spec);
r = pa_bytes_to_usec((size_t) info.bytes, &u->source->sample_spec);
}
return r;
@ -528,8 +528,9 @@ static int unsuspend(struct userdata *u) {
if ((u->fd = pa_oss_open(u->device_name, &m, NULL)) < 0) {
pa_log_warn("Resume failed, device busy (%s)", pa_cstrerror(errno));
return -1;
}
if (m != u->mode)
if (m != u->mode) {
pa_log_warn("Resume failed, couldn't open device with original access mode.");
goto fail;
}
@ -859,7 +860,7 @@ static int source_set_volume(pa_source *s) {
static void thread_func(void *userdata) {
struct userdata *u = userdata;
int write_type = 0, read_type = 0;
unsigned short revents = 0;
short revents = 0;
pa_assert(u);
@ -898,7 +899,7 @@ static void thread_func(void *userdata) {
ssize_t l;
pa_bool_t loop = FALSE, work_done = FALSE;
l = u->out_fragment_size;
l = (ssize_t) u->out_fragment_size;
if (u->use_getospace) {
audio_buf_info info;
@ -919,14 +920,14 @@ static void thread_func(void *userdata) {
/* Round down to multiples of the fragment size,
* because OSS needs that (at least some versions
* do) */
l = (l/u->out_fragment_size) * u->out_fragment_size;
l = (l/(ssize_t) u->out_fragment_size) * (ssize_t) u->out_fragment_size;
/* Hmm, so poll() signalled us that we can read
* something, but GETOSPACE told us there was nothing?
* Hmm, make the best of it, try to read some data, to
* avoid spinning forever. */
if (l <= 0 && (revents & POLLOUT)) {
l = u->out_fragment_size;
l = (ssize_t) u->out_fragment_size;
loop = FALSE;
}
@ -935,7 +936,7 @@ static void thread_func(void *userdata) {
ssize_t t;
if (u->memchunk.length <= 0)
pa_sink_render(u->sink, l, &u->memchunk);
pa_sink_render(u->sink, (size_t) l, &u->memchunk);
pa_assert(u->memchunk.length > 0);
@ -965,8 +966,8 @@ static void thread_func(void *userdata) {
} else {
u->memchunk.index += t;
u->memchunk.length -= t;
u->memchunk.index += (size_t) t;
u->memchunk.length -= (size_t) t;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@ -1009,7 +1010,7 @@ static void thread_func(void *userdata) {
pa_memchunk memchunk;
pa_bool_t loop = FALSE, work_done = FALSE;
l = u->in_fragment_size;
l = (ssize_t) u->in_fragment_size;
if (u->use_getispace) {
audio_buf_info info;
@ -1023,15 +1024,16 @@ static void thread_func(void *userdata) {
}
}
l = (l/u->in_fragment_size) * u->in_fragment_size;
l = (l/(ssize_t) u->in_fragment_size) * (ssize_t) u->in_fragment_size;
if (l <= 0 && (revents & POLLIN)) {
l = u->in_fragment_size;
l = (ssize_t) u->in_fragment_size;
loop = FALSE;
}
while (l > 0) {
ssize_t t, k;
ssize_t t;
size_t k;
pa_assert(l > 0);
@ -1039,8 +1041,8 @@ static void thread_func(void *userdata) {
k = pa_memblock_get_length(memchunk.memblock);
if (k > l)
k = l;
if (k > (size_t) l)
k = (size_t) l;
k = (k/u->frame_size)*u->frame_size;
@ -1071,7 +1073,7 @@ static void thread_func(void *userdata) {
} else {
memchunk.index = 0;
memchunk.length = t;
memchunk.length = (size_t) t;
pa_source_post(u->source, &memchunk);
pa_memblock_unref(memchunk.memblock);
@ -1099,9 +1101,9 @@ static void thread_func(void *userdata) {
pa_assert(u->fd >= 0);
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
pollfd->events =
((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) |
((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0);
pollfd->events = (short)
(((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) |
((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0));
}
/* Hmm, nothing to do. Let's sleep */
@ -1179,10 +1181,10 @@ int pa__init(pa_module*m) {
goto fail;
}
nfrags = m->core->default_n_fragments;
frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss);
nfrags = (int) m->core->default_n_fragments;
frag_size = (int) pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss);
if (frag_size <= 0)
frag_size = pa_frame_size(&ss);
frag_size = (int) pa_frame_size(&ss);
if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) {
pa_log("Failed to parse fragments arguments");
@ -1238,8 +1240,8 @@ int pa__init(pa_module*m) {
u->mode = mode;
u->frame_size = pa_frame_size(&ss);
u->device_name = pa_xstrdup(dev);
u->in_nfrags = u->out_nfrags = u->nfrags = nfrags;
u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size;
u->in_nfrags = u->out_nfrags = (uint32_t) (u->nfrags = nfrags);
u->out_fragment_size = u->in_fragment_size = (uint32_t) (u->frag_size = frag_size);
u->use_mmap = use_mmap;
u->rtpoll = pa_rtpoll_new();
pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
@ -1248,15 +1250,15 @@ int pa__init(pa_module*m) {
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) {
pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize);
u->in_fragment_size = info.fragsize;
u->in_nfrags = info.fragstotal;
u->in_fragment_size = (uint32_t) info.fragsize;
u->in_nfrags = (uint32_t) info.fragstotal;
u->use_getispace = TRUE;
}
if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) {
pa_log_info("Output -- %u fragments of size %u.", info.fragstotal, info.fragsize);
u->out_fragment_size = info.fragsize;
u->out_nfrags = info.fragstotal;
u->out_fragment_size = (uint32_t) info.fragsize;
u->out_nfrags = (uint32_t) info.fragstotal;
u->use_getospace = TRUE;
}

View file

@ -145,8 +145,8 @@ static int process_render(struct userdata *u) {
} else {
u->memchunk.index += l;
u->memchunk.length -= l;
u->memchunk.index += (size_t) l;
u->memchunk.length -= (size_t) l;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@ -189,7 +189,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0;
pollfd->events = (short) (u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0);
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;

View file

@ -135,9 +135,9 @@ static void thread_func(void *userdata) {
} else {
u->memchunk.length = l;
u->memchunk.length = (size_t) l;
pa_source_post(u->source, &u->memchunk);
u->memchunk.index += l;
u->memchunk.index += (size_t) l;
if (u->memchunk.index >= pa_memblock_get_length(u->memchunk.memblock)) {
pa_memblock_unref(u->memchunk.memblock);
@ -149,7 +149,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
pollfd->events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0;
pollfd->events = (short) (u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0);
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;

View file

@ -260,7 +260,7 @@ int pa__init(pa_module*m) {
goto fail;
}
u = pa_xnew0(struct userdata, 1);
m->userdata = u = pa_xnew0(struct userdata, 1);
u->module = m;
#if defined(USE_PROTOCOL_SIMPLE)
@ -299,11 +299,11 @@ int pa__init(pa_module*m) {
listen_on = pa_modargs_get_value(ma, "listen", NULL);
if (listen_on) {
u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE);
u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE);
u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE);
u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE);
} else {
u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, port, TCPWRAP_SERVICE);
u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, port, TCPWRAP_SERVICE);
u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE);
u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE);
}
if (!u->socket_server_ipv4 && !u->socket_server_ipv6)
@ -327,7 +327,7 @@ int pa__init(pa_module*m) {
/* This socket doesn't reside in our own runtime dir but in
* /tmp/.esd/, hence we have to create the dir first */
if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) {
if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1) < 0) {
pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno));
goto fail;
}
@ -368,8 +368,6 @@ int pa__init(pa_module*m) {
# endif
#endif
m->userdata = u;
if (ma)
pa_modargs_free(ma);
@ -390,7 +388,8 @@ void pa__done(pa_module*m) {
pa_assert(m);
u = m->userdata;
if (!(u = m->userdata))
return;
#if defined(USE_PROTOCOL_SIMPLE)
if (u->simple_protocol) {

View file

@ -255,7 +255,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
pa_sink_input_unref(u->sink_input);
u->sink_input = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from IO thread context */

View file

@ -99,7 +99,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
pa_sink_input_unref(u->sink_input);
u->sink_input = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from IO thread context */
@ -116,13 +116,13 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
}
static void calc_sine(float *f, size_t l, float freq) {
static void calc_sine(float *f, size_t l, double freq) {
size_t i;
l /= sizeof(float);
for (i = 0; i < l; i++)
f[i] = (float) sin((double) i/l*M_PI*2*freq)/2;
f[i] = (float) sin((double) i/(double)l*M_PI*2*freq)/2;
}
int pa__init(pa_module*m) {
@ -163,7 +163,7 @@ int pa__init(pa_module*m) {
u->memblock = pa_memblock_new(m->core->mempool, pa_bytes_per_second(&ss));
p = pa_memblock_acquire(u->memblock);
calc_sine(p, pa_memblock_get_length(u->memblock), frequency);
calc_sine(p, pa_memblock_get_length(u->memblock), (double) frequency);
pa_memblock_release(u->memblock);
pa_sink_input_new_data_init(&data);

View file

@ -46,6 +46,9 @@
#include <pulsecore/sink-input.h>
#include <pulsecore/source-output.h>
#include <pulsecore/namereg.h>
#include <pulsecore/protocol-native.h>
#include <pulsecore/pstream.h>
#include <pulsecore/pstream-util.h>
#include "module-stream-restore-symdef.h"
@ -65,25 +68,41 @@ static const char* const valid_modargs[] = {
struct userdata {
pa_core *core;
pa_module *module;
pa_subscription *subscription;
pa_hook_slot
*sink_input_new_hook_slot,
*sink_input_fixate_hook_slot,
*source_output_new_hook_slot;
*source_output_new_hook_slot,
*connection_unlink_hook_slot;
pa_time_event *save_time_event;
GDBM_FILE gdbm_file;
pa_bool_t restore_device:1;
pa_bool_t restore_volume:1;
pa_bool_t restore_muted:1;
pa_native_protocol *protocol;
pa_idxset *subscribed;
};
struct entry {
pa_cvolume volume;
char device[PA_NAME_MAX];
pa_channel_map channel_map;
pa_cvolume volume;
pa_bool_t muted:1;
};
enum {
SUBCOMMAND_TEST,
SUBCOMMAND_READ,
SUBCOMMAND_WRITE,
SUBCOMMAND_DELETE,
SUBCOMMAND_SUBSCRIBE,
SUBCOMMAND_EVENT
};
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
struct userdata *u = userdata;
@ -126,7 +145,7 @@ static struct entry* read_entry(struct userdata *u, char *name) {
pa_assert(name);
key.dptr = name;
key.dsize = strlen(name);
key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@ -146,7 +165,17 @@ static struct entry* read_entry(struct userdata *u, char *name) {
}
if (!(pa_cvolume_valid(&e->volume))) {
pa_log_warn("Invalid volume stored in database for device %s", name);
pa_log_warn("Invalid volume stored in database for stream %s", name);
goto fail;
}
if (!(pa_channel_map_valid(&e->channel_map))) {
pa_log_warn("Invalid channel map stored in database for stream %s", name);
goto fail;
}
if (e->volume.channels != e->channel_map.channels) {
pa_log_warn("Volume and channel map don't match in database entry for stream %s", name);
goto fail;
}
@ -158,6 +187,32 @@ fail:
return NULL;
}
static void trigger_save(struct userdata *u) {
struct timeval tv;
pa_native_connection *c;
uint32_t idx;
for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(u->subscribed, &idx)) {
pa_tagstruct *t;
t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
pa_tagstruct_putu32(t, 0);
pa_tagstruct_putu32(t, u->module->index);
pa_tagstruct_puts(t, u->module->name);
pa_tagstruct_putu32(t, SUBCOMMAND_EVENT);
pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t);
}
if (u->save_time_event)
return;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
}
static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
struct userdata *u = userdata;
struct entry entry, *old;
@ -173,6 +228,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
return;
memset(&entry, 0, sizeof(entry));
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
pa_sink_input *sink_input;
@ -182,6 +239,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
if (!(name = get_name(sink_input->proplist, "sink-input")))
return;
entry.channel_map = sink_input->channel_map;
entry.volume = *pa_sink_input_get_volume(sink_input);
entry.muted = pa_sink_input_get_mute(sink_input);
pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device));
@ -197,15 +255,16 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
if (!(name = get_name(source_output->proplist, "source-output")))
return;
memset(&entry.volume, 0, sizeof(entry.volume));
entry.muted = FALSE;
/* The following fields are filled in to make the entry valid
* according to read_entry(). They are otherwise useless */
entry.channel_map = source_output->channel_map;
pa_cvolume_reset(&entry.volume, entry.channel_map.channels);
pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device));
}
if ((old = read_entry(u, name))) {
if (pa_cvolume_equal(&old->volume, &entry.volume) &&
if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) &&
!old->muted == !entry.muted &&
strcmp(old->device, entry.device) == 0) {
@ -218,7 +277,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
}
key.dptr = name;
key.dsize = strlen(name);
key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
@ -227,14 +286,9 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
gdbm_store(u->gdbm_file, key, data, GDBM_REPLACE);
if (!u->save_time_event) {
struct timeval tv;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
}
pa_xfree(name);
trigger_save(u);
}
static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
@ -250,11 +304,13 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
pa_sink *s;
if (u->restore_device &&
e->device[0] &&
(s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK, TRUE))) {
pa_log_info("Restoring device for stream %s.", name);
new_data->sink = s;
if (!new_data->sink) {
pa_log_info("Restoring device for stream %s.", name);
new_data->sink = s;
} else
pa_log_info("Not restore device for stream %s, because already set.", name);
}
pa_xfree(e);
@ -276,16 +332,21 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
if ((e = read_entry(u, name))) {
if (u->restore_volume &&
e->volume.channels == new_data->sample_spec.channels) {
if (u->restore_volume) {
pa_log_info("Restoring volume for sink input %s.", name);
pa_sink_input_new_data_set_volume(new_data, &e->volume);
if (!new_data->volume_is_set) {
pa_log_info("Restoring volume for sink input %s.", name);
pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
} else
pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
}
if (u->restore_muted) {
pa_log_info("Restoring mute state for sink input %s.", name);
pa_sink_input_new_data_set_muted(new_data, e->muted);
if (!new_data->muted_is_set) {
pa_log_info("Restoring mute state for sink input %s.", name);
pa_sink_input_new_data_set_muted(new_data, e->muted);
} else
pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
}
pa_xfree(e);
@ -309,11 +370,14 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
pa_source *s;
if (u->restore_device &&
e->device[0] &&
!new_data->direct_on_input &&
(s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE, TRUE))) {
pa_log_info("Restoring device for stream %s.", name);
new_data->source = s;
if (!new_data->source) {
pa_log_info("Restoring device for stream %s.", name);
new_data->source = s;
} else
pa_log_info("Not restroing device for stream %s, because already set", name);
}
pa_xfree(e);
@ -324,11 +388,300 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
return PA_HOOK_OK;
}
#define EXT_VERSION 1
static void clear_db(struct userdata *u) {
datum key;
pa_assert(u);
key = gdbm_firstkey(u->gdbm_file);
while (key.dptr) {
datum next_key;
next_key = gdbm_nextkey(u->gdbm_file, key);
gdbm_delete(u->gdbm_file, key);
pa_xfree(key.dptr);
key = next_key;
}
gdbm_reorganize(u->gdbm_file);
}
static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
pa_sink_input *si;
pa_source_output *so;
uint32_t idx;
pa_assert(u);
pa_assert(name);
pa_assert(e);
for (si = pa_idxset_first(u->core->sink_inputs, &idx); si; si = pa_idxset_next(u->core->sink_inputs, &idx)) {
char *n;
pa_sink *s;
if (!(n = get_name(si->proplist, "sink-input")))
continue;
if (strcmp(name, n)) {
pa_xfree(n);
continue;
}
if (u->restore_volume) {
pa_cvolume v = e->volume;
pa_log_info("Restoring volume for sink input %s.", name);
pa_sink_input_set_volume(si, pa_cvolume_remap(&v, &e->channel_map, &si->channel_map));
}
if (u->restore_muted) {
pa_log_info("Restoring mute state for sink input %s.", name);
pa_sink_input_set_mute(si, e->muted);
}
if (u->restore_device &&
(s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE, TRUE))) {
pa_log_info("Restoring device for stream %s.", name);
pa_sink_input_move_to(si, s);
}
}
for (so = pa_idxset_first(u->core->source_outputs, &idx); so; so = pa_idxset_next(u->core->source_outputs, &idx)) {
char *n;
pa_source *s;
if (!(n = get_name(so->proplist, "source-output")))
continue;
if (strcmp(name, n)) {
pa_xfree(n);
continue;
}
if (u->restore_device &&
(s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE, TRUE))) {
pa_log_info("Restoring device for stream %s.", name);
pa_source_output_move_to(so, s);
}
}
}
#if 0
static void dump_database(struct userdata *u) {
datum key;
key = gdbm_firstkey(u->gdbm_file);
while (key.dptr) {
datum next_key;
struct entry *e;
char *name;
next_key = gdbm_nextkey(u->gdbm_file, key);
name = pa_xstrndup(key.dptr, key.dsize);
pa_xfree(key.dptr);
if ((e = read_entry(u, name))) {
char t[256];
pa_log("name=%s", name);
pa_log("device=%s", e->device);
pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map));
pa_log("volume=%s", pa_cvolume_snprint(t, sizeof(t), &e->volume));
pa_log("mute=%s", pa_yes_no(e->muted));
pa_xfree(e);
}
pa_xfree(name);
key = next_key;
}
}
#endif
static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
struct userdata *u;
uint32_t command;
pa_tagstruct *reply = NULL;
pa_assert(p);
pa_assert(m);
pa_assert(c);
pa_assert(t);
u = m->userdata;
if (pa_tagstruct_getu32(t, &command) < 0)
goto fail;
reply = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
pa_tagstruct_putu32(reply, tag);
switch (command) {
case SUBCOMMAND_TEST: {
if (!pa_tagstruct_eof(t))
goto fail;
pa_tagstruct_putu32(reply, EXT_VERSION);
break;
}
case SUBCOMMAND_READ: {
datum key;
if (!pa_tagstruct_eof(t))
goto fail;
key = gdbm_firstkey(u->gdbm_file);
while (key.dptr) {
datum next_key;
struct entry *e;
char *name;
next_key = gdbm_nextkey(u->gdbm_file, key);
name = pa_xstrndup(key.dptr, (size_t) key.dsize);
pa_xfree(key.dptr);
if ((e = read_entry(u, name))) {
pa_tagstruct_puts(reply, name);
pa_tagstruct_put_channel_map(reply, &e->channel_map);
pa_tagstruct_put_cvolume(reply, &e->volume);
pa_tagstruct_puts(reply, e->device);
pa_tagstruct_put_boolean(reply, e->muted);
pa_xfree(e);
}
pa_xfree(name);
key = next_key;
}
break;
}
case SUBCOMMAND_WRITE: {
uint32_t mode;
pa_bool_t apply_immediately = FALSE;
if (pa_tagstruct_getu32(t, &mode) < 0 ||
pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
goto fail;
if (mode != PA_UPDATE_MERGE &&
mode != PA_UPDATE_REPLACE &&
mode != PA_UPDATE_SET)
goto fail;
if (mode == PA_UPDATE_SET)
clear_db(u);
while (!pa_tagstruct_eof(t)) {
const char *name, *device;
pa_bool_t muted;
struct entry entry;
datum key, data;
int k;
memset(&entry, 0, sizeof(entry));
if (pa_tagstruct_gets(t, &name) < 0 ||
pa_tagstruct_get_channel_map(t, &entry.channel_map) ||
pa_tagstruct_get_cvolume(t, &entry.volume) < 0 ||
pa_tagstruct_gets(t, &device) < 0 ||
pa_tagstruct_get_boolean(t, &muted) < 0)
goto fail;
if (entry.channel_map.channels != entry.volume.channels)
goto fail;
entry.muted = muted;
pa_strlcpy(entry.device, device, sizeof(entry.device));
key.dptr = (void*) name;
key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
if ((k = gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT)) == 0)
if (apply_immediately)
apply_entry(u, name, &entry);
}
trigger_save(u);
break;
}
case SUBCOMMAND_DELETE:
while (!pa_tagstruct_eof(t)) {
const char *name;
datum key;
if (pa_tagstruct_gets(t, &name) < 0)
goto fail;
key.dptr = (void*) name;
key.dsize = (int) strlen(name);
gdbm_delete(u->gdbm_file, key);
}
trigger_save(u);
break;
case SUBCOMMAND_SUBSCRIBE: {
pa_bool_t enabled;
if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
!pa_tagstruct_eof(t))
goto fail;
if (enabled)
pa_idxset_put(u->subscribed, c, NULL);
else
pa_idxset_remove_by_data(u->subscribed, c, NULL);
break;
}
default:
goto fail;
}
pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
return 0;
fail:
if (reply)
pa_tagstruct_free(reply);
return -1;
}
static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
pa_assert(p);
pa_assert(c);
pa_assert(u);
pa_idxset_remove_by_data(u->subscribed, c, NULL);
return PA_HOOK_OK;
}
int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
struct userdata *u;
char *fname, *fn;
char hn[256];
pa_sink_input *si;
pa_source_output *so;
uint32_t idx;
@ -353,10 +706,18 @@ int pa__init(pa_module*m) {
m->userdata = u = pa_xnew(struct userdata, 1);
u->core = m->core;
u->module = m;
u->save_time_event = NULL;
u->restore_device = restore_device;
u->restore_volume = restore_volume;
u->restore_muted = restore_muted;
u->gdbm_file = NULL;
u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
u->protocol = pa_native_protocol_get(m->core);
pa_native_protocol_install_ext(u->protocol, m, extension_cb);
u->connection_unlink_hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_CONNECTION_UNLINK], PA_HOOK_NORMAL, (pa_hook_cb_t) connection_unlink_hook_cb, u);
u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u);
@ -368,11 +729,12 @@ int pa__init(pa_module*m) {
if (restore_volume || restore_muted)
u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
if (!pa_get_host_name(hn, sizeof(hn)))
goto fail;
/* We include the host identifier in the file name because gdbm
* files are CPU dependant, and we don't want things to go wrong
* if we are on a multiarch system. */
fn = pa_sprintf_malloc("stream-volumes.%s."CANONICAL_HOST".gdbm", hn);
fname = pa_state_path(fn);
fn = pa_sprintf_malloc("stream-volumes."CANONICAL_HOST".gdbm");
fname = pa_state_path(fn, TRUE);
pa_xfree(fn);
if (!fname)
@ -423,11 +785,22 @@ void pa__done(pa_module*m) {
if (u->source_output_new_hook_slot)
pa_hook_slot_free(u->source_output_new_hook_slot);
if (u->connection_unlink_hook_slot)
pa_hook_slot_free(u->connection_unlink_hook_slot);
if (u->save_time_event)
u->core->mainloop->time_free(u->save_time_event);
if (u->gdbm_file)
gdbm_close(u->gdbm_file);
if (u->protocol) {
pa_native_protocol_remove_ext(u->protocol, m);
pa_native_protocol_unref(u->protocol);
}
if (u->subscribed)
pa_idxset_free(u->subscribed, NULL, NULL);
pa_xfree(u);
}

View file

@ -178,7 +178,7 @@ struct userdata {
#ifdef TUNNEL_SINK
char *sink_name;
pa_sink *sink;
int32_t requested_bytes;
size_t requested_bytes;
#else
char *source_name;
pa_source *source;
@ -231,7 +231,7 @@ static void command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t
pa_assert(u->pdispatch == pd);
pa_log_warn("Stream killed");
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from main context */
@ -262,7 +262,7 @@ static void command_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag
pa_tagstruct_get_boolean(t, &suspended) < 0 ||
!pa_tagstruct_eof(t)) {
pa_log("Invalid packet");
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
return;
}
@ -389,7 +389,7 @@ static void send_data(struct userdata *u) {
u->requested_bytes -= memchunk.length;
u->counter += memchunk.length;
u->counter += (int64_t) memchunk.length;
}
}
@ -417,7 +417,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
case PA_SINK_MESSAGE_GET_LATENCY: {
pa_usec_t yl, yr, *usec = data;
yl = pa_bytes_to_usec(u->counter, &u->sink->sample_spec);
yl = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec);
yr = pa_smoother_get(u->smoother, pa_rtclock_usec());
*usec = yl > yr ? yl - yr : 0;
@ -444,10 +444,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
case SINK_MESSAGE_UPDATE_LATENCY: {
pa_usec_t y;
y = pa_bytes_to_usec(u->counter, &u->sink->sample_spec);
y = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec);
if (y > (pa_usec_t) offset || offset < 0)
y -= offset;
y -= (pa_usec_t) offset;
else
y = 0;
@ -465,7 +465,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_pstream_send_memblock(u->pstream, u->channel, 0, PA_SEEK_RELATIVE, chunk);
u->counter_delta += chunk->length;
u->counter_delta += (int64_t) chunk->length;
return 0;
}
@ -520,7 +520,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
case PA_SOURCE_MESSAGE_GET_LATENCY: {
pa_usec_t yr, yl, *usec = data;
yl = pa_bytes_to_usec(u->counter, &PA_SINK(o)->sample_spec);
yl = pa_bytes_to_usec((uint64_t) u->counter, &PA_SINK(o)->sample_spec);
yr = pa_smoother_get(u->smoother, pa_rtclock_usec());
*usec = yr > yl ? yr - yl : 0;
@ -532,7 +532,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
if (PA_SOURCE_IS_OPENED(u->source->thread_info.state))
pa_source_post(u->source, chunk);
u->counter += chunk->length;
u->counter += (int64_t) chunk->length;
return 0;
@ -544,10 +544,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
case SOURCE_MESSAGE_UPDATE_LATENCY: {
pa_usec_t y;
y = pa_bytes_to_usec(u->counter, &u->source->sample_spec);
y = pa_bytes_to_usec((uint64_t) u->counter, &u->source->sample_spec);
if (offset >= 0 || y > (pa_usec_t) -offset)
y += offset;
y += (pa_usec_t) offset;
else
y = 0;
@ -652,7 +652,7 @@ static void command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
return;
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
#endif
@ -736,9 +736,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
/* Add the length of our server-side buffer */
if (write_index >= read_index)
delay += (int64_t) pa_bytes_to_usec(write_index-read_index, ss);
delay += (int64_t) pa_bytes_to_usec((uint64_t) (write_index-read_index), ss);
else
delay -= (int64_t) pa_bytes_to_usec(read_index-write_index, ss);
delay -= (int64_t) pa_bytes_to_usec((uint64_t) (read_index-write_index), ss);
/* Our measurements are already out of date, hence correct by the *
* transport latency */
@ -750,9 +750,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
/* Now correct by what we have have read/written since we requested the update */
#ifdef TUNNEL_SINK
delay += (int64_t) pa_bytes_to_usec(u->counter_delta, ss);
delay += (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss);
#else
delay -= (int64_t) pa_bytes_to_usec(u->counter_delta, ss);
delay -= (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss);
#endif
#ifdef TUNNEL_SINK
@ -765,7 +765,7 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from main context */
@ -902,7 +902,7 @@ static void server_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
return;
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
#ifdef TUNNEL_SINK
@ -979,7 +979,7 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t
return;
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
pa_proplist_free(pl);
}
@ -1066,7 +1066,7 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag
return;
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
pa_proplist_free(pl);
}
@ -1142,7 +1142,7 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
return;
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
pa_proplist_free(pl);
}
@ -1204,7 +1204,7 @@ static void command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32
if (pa_tagstruct_getu32(t, &e) < 0 ||
pa_tagstruct_getu32(t, &idx) < 0) {
pa_log("Invalid protocol reply");
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
return;
}
@ -1344,7 +1344,7 @@ parse_error:
pa_log("Invalid reply. (Create stream)");
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
@ -1425,11 +1425,11 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
u->maxlength = 4*1024*1024;
#ifdef TUNNEL_SINK
u->tlength = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
u->minreq = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
u->tlength = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
u->minreq = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
u->prebuf = u->tlength;
#else
u->fragsize = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
u->fragsize = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
#endif
#ifdef TUNNEL_SINK
@ -1502,7 +1502,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
return;
fail:
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from main context */
@ -1513,7 +1513,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
pa_assert(u);
pa_log_warn("Stream died.");
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
/* Called from main context */
@ -1526,7 +1526,7 @@ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_c
if (pa_pdispatch_run(u->pdispatch, packet, creds, u) < 0) {
pa_log("Invalid packet");
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
return;
}
}
@ -1542,13 +1542,13 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
if (channel != u->channel) {
pa_log("Recieved memory block on bad channel.");
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
return;
}
pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_POST, PA_UINT_TO_PTR(seek), offset, chunk);
u->counter_delta += chunk->length;
u->counter_delta += (int64_t) chunk->length;
}
#endif
@ -1568,7 +1568,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
if (!io) {
pa_log("Connection failed: %s", pa_cstrerror(errno));
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
return;
}

View file

@ -103,7 +103,7 @@ static pa_cvolume* parse_volume(const char *s, pa_cvolume *v) {
if (k <= 0 || k > (long) PA_CHANNELS_MAX)
return NULL;
v->channels = (unsigned) k;
v->channels = (uint8_t) k;
for (i = 0; i < v->channels; i++) {
p += strspn(p, WHITESPACE);
@ -493,7 +493,7 @@ int pa__init(pa_module*m) {
m->userdata = u;
if (!(u->table_file = pa_state_path(pa_modargs_get_value(ma, "table", DEFAULT_VOLUME_TABLE_FILE))))
if (!(u->table_file = pa_state_path(pa_modargs_get_value(ma, "table", DEFAULT_VOLUME_TABLE_FILE), TRUE)))
goto fail;
if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 ||

View file

@ -82,7 +82,7 @@ static int x11_event_cb(pa_x11_wrapper *w, XEvent *e, void *userdata) {
bne = (XkbBellNotifyEvent*) e;
if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, TRUE, (bne->percent*PA_VOLUME_NORM)/100, NULL, NULL) < 0) {
if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, TRUE, ((pa_volume_t) bne->percent*PA_VOLUME_NORM)/100U, NULL, NULL) < 0) {
pa_log_info("Ringing bell failed, reverting to X11 device bell.");
XkbForceDeviceBell(pa_x11_wrapper_get_display(w), bne->device, bne->bell_class, bne->bell_id, bne->percent);
}
@ -106,7 +106,7 @@ static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) {
u->x11_client = NULL;
u->x11_wrapper = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
int pa__init(pa_module*m) {

View file

@ -126,7 +126,7 @@ static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) {
u->x11_client = NULL;
u->x11_wrapper = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
int pa__init(pa_module*m) {
@ -152,7 +152,7 @@ int pa__init(pa_module*m) {
u->x11_client = NULL;
u->x11_wrapper = NULL;
u->hook_slot = pa_hook_connect(pa_native_protocol_servers_changed(u->protocol), PA_HOOK_NORMAL, servers_changed_cb, u);
u->hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_SERVERS_CHANGED], PA_HOOK_NORMAL, servers_changed_cb, u);
if (!(u->auth_cookie = pa_auth_cookie_get(m->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), PA_NATIVE_COOKIE_LENGTH)))
goto fail;

View file

@ -77,7 +77,7 @@ static void die_cb(SmcConn connection, SmPointer client_data){
pa_x11_wrapper_unref(u->x11);
u->x11 = NULL;
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
static void save_complete_cb(SmcConn connection, SmPointer client_data) {
@ -181,7 +181,7 @@ int pa__init(pa_module*m) {
prop_program.name = (char*) SmProgram;
prop_program.type = (char*) SmARRAY8;
val_program.value = (char*) PACKAGE_NAME;
val_program.length = strlen(val_program.value);
val_program.length = (int) strlen(val_program.value);
prop_program.num_vals = 1;
prop_program.vals = &val_program;
prop_list[0] = &prop_program;
@ -190,7 +190,7 @@ int pa__init(pa_module*m) {
prop_user.type = (char*) SmARRAY8;
pa_get_user_name(t, sizeof(t));
val_user.value = t;
val_user.length = strlen(val_user.value);
val_user.length = (int) strlen(val_user.value);
prop_user.num_vals = 1;
prop_user.vals = &val_user;
prop_list[1] = &prop_user;

View file

@ -173,9 +173,9 @@ static void resolver_cb(
device = value;
value = NULL;
} else if (strcmp(key, "rate") == 0)
ss.rate = atoi(value);
ss.rate = (uint32_t) atoi(value);
else if (strcmp(key, "channels") == 0)
ss.channels = atoi(value);
ss.channels = (uint8_t) atoi(value);
else if (strcmp(key, "format") == 0)
ss.format = pa_parse_sample_format(value);
else if (strcmp(key, "channel_map") == 0) {
@ -286,7 +286,7 @@ static void browser_cb(
struct tunnel *t2;
if ((t2 = pa_hashmap_get(u->tunnels, t))) {
pa_module_unload_by_index(u->core, t2->module_index);
pa_module_unload_by_index(u->core, t2->module_index, TRUE);
pa_hashmap_remove(u->tunnels, t2);
tunnel_free(t2);
}
@ -319,7 +319,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
browser_cb, u))) {
pa_log("avahi_service_browser_new() failed: %s", avahi_strerror(avahi_client_errno(c)));
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
}
@ -334,7 +334,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
browser_cb, u))) {
pa_log("avahi_service_browser_new() failed: %s", avahi_strerror(avahi_client_errno(c)));
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
}
@ -348,7 +348,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) {
pa_log("avahi_client_new() failed: %s", avahi_strerror(error));
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
}
@ -427,7 +427,7 @@ void pa__done(pa_module*m) {
struct tunnel *t;
while ((t = pa_hashmap_steal_first(u->tunnels))) {
pa_module_unload_by_index(u->core, t->module_index);
pa_module_unload_by_index(u->core, t->module_index, TRUE);
tunnel_free(t);
}

View file

@ -539,7 +539,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) {
pa_log("avahi_client_new() failed: %s", avahi_strerror(error));
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
}
}

View file

@ -204,10 +204,10 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) {
if (ss->channels != channels) {
pa_log_warn("device doesn't support %i channels, using %i channels.", ss->channels, channels);
ss->channels = channels;
ss->channels = (uint8_t) channels;
}
speed = ss->rate;
speed = (int) ss->rate;
if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) {
pa_log("SNDCTL_DSP_SPEED: %s", pa_cstrerror(errno));
return -1;
@ -219,7 +219,7 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) {
/* If the sample rate deviates too much, we need to resample */
if (speed < ss->rate*.95 || speed > ss->rate*1.05)
ss->rate = speed;
ss->rate = (uint32_t) speed;
}
return 0;

View file

@ -238,15 +238,15 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
else
delta = j;
pa_memblockq_seek(s->memblockq, delta * s->rtp_context.frame_size, PA_SEEK_RELATIVE);
pa_memblockq_seek(s->memblockq, delta * (int64_t) s->rtp_context.frame_size, PA_SEEK_RELATIVE);
pa_rtclock_get(&now);
pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec(pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec));
pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec((uint64_t) pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec));
if (pa_memblockq_push(s->memblockq, &chunk) < 0) {
pa_log_warn("Queue overrun");
pa_memblockq_seek(s->memblockq, chunk.length, PA_SEEK_RELATIVE);
pa_memblockq_seek(s->memblockq, (int64_t) chunk.length, PA_SEEK_RELATIVE);
}
pa_log("blocks in q: %u", pa_memblockq_get_nblocks(s->memblockq));
@ -254,9 +254,9 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
pa_memblock_unref(chunk.memblock);
/* The next timestamp we expect */
s->offset = s->rtp_context.timestamp + (chunk.length / s->rtp_context.frame_size);
s->offset = s->rtp_context.timestamp + (uint32_t) (chunk.length / s->rtp_context.frame_size);
pa_atomic_store(&s->timestamp, now.tv_sec);
pa_atomic_store(&s->timestamp, (int) now.tv_sec);
if (s->last_rate_update + RATE_UPDATE_INTERVAL < pa_timeval_load(&now)) {
pa_usec_t wi, ri, render_delay, sink_delay = 0, latency, fix;
@ -265,7 +265,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
pa_log("Updating sample rate");
wi = pa_smoother_get(s->smoother, pa_timeval_load(&now));
ri = pa_bytes_to_usec(pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec);
ri = pa_bytes_to_usec((uint64_t) pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec);
if (PA_MSGOBJECT(s->sink_input->sink)->process_msg(PA_MSGOBJECT(s->sink_input->sink), PA_SINK_MESSAGE_GET_LATENCY, &sink_delay, 0, NULL) < 0)
sink_delay = 0;
@ -291,7 +291,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
fix = latency - s->intended_latency;
/* How many samples is this per second? */
fix_samples = fix * s->sink_input->thread_info.sample_spec.rate / RATE_UPDATE_INTERVAL;
fix_samples = (unsigned) (fix * (pa_usec_t) s->sink_input->thread_info.sample_spec.rate / (pa_usec_t) RATE_UPDATE_INTERVAL);
/* Check if deviation is in bounds */
if (fix_samples > s->sink_input->sample_spec.rate*.20)
@ -431,7 +431,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
s->smoother = pa_smoother_new(PA_USEC_PER_SEC*5, PA_USEC_PER_SEC*2, TRUE, 10);
pa_smoother_set_time_offset(s->smoother, pa_timeval_load(&now));
s->last_rate_update = pa_timeval_load(&now);
pa_atomic_store(&s->timestamp, now.tv_sec);
pa_atomic_store(&s->timestamp, (int) now.tv_sec);
if ((fd = mcast_socket((const struct sockaddr*) &sdp_info->sa, sdp_info->salen)) < 0)
goto fail;
@ -566,7 +566,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event
} else {
struct timeval now;
pa_rtclock_get(&now);
pa_atomic_store(&s->timestamp, now.tv_sec);
pa_atomic_store(&s->timestamp, (int) now.tv_sec);
pa_sdp_info_destroy(&info);
}

View file

@ -67,10 +67,12 @@ PA_MODULE_USAGE(
"destination=<destination IP address> "
"port=<port number> "
"mtu=<maximum transfer unit> "
"loop=<loopback to local host?>"
"loop=<loopback to local host?> "
"ttl=<ttl value>"
);
#define DEFAULT_PORT 46000
#define DEFAULT_TTL 1
#define SAP_PORT 9875
#define DEFAULT_DESTINATION "224.0.0.56"
#define MEMBLOCKQ_MAXLENGTH (1024*170)
@ -86,6 +88,7 @@ static const char* const valid_modargs[] = {
"port",
"mtu" ,
"loop",
"ttl",
NULL
};
@ -139,7 +142,7 @@ static void source_output_kill(pa_source_output* o) {
pa_source_output_assert_ref(o);
pa_assert_se(u = o->userdata);
pa_module_unload_request(u->module);
pa_module_unload_request(u->module, TRUE);
pa_source_output_unlink(u->source_output);
pa_source_output_unref(u->source_output);
@ -167,7 +170,9 @@ int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
const char *dest;
uint32_t port = DEFAULT_PORT, mtu;
int af, fd = -1, sap_fd = -1;
uint32_t ttl = DEFAULT_TTL;
sa_family_t af;
int fd = -1, sap_fd = -1;
pa_source *s;
pa_sample_spec ss;
pa_channel_map cm;
@ -219,14 +224,14 @@ int pa__init(pa_module*m) {
payload = pa_rtp_payload_from_sample_spec(&ss);
mtu = pa_frame_align(DEFAULT_MTU, &ss);
mtu = (uint32_t) pa_frame_align(DEFAULT_MTU, &ss);
if (pa_modargs_get_value_u32(ma, "mtu", &mtu) < 0 || mtu < 1 || mtu % pa_frame_size(&ss) != 0) {
pa_log("Invalid MTU.");
goto fail;
}
port = DEFAULT_PORT + ((rand() % 512) << 1);
port = DEFAULT_PORT + ((uint32_t) (rand() % 512) << 1);
if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) {
pa_log("port= expects a numerical argument between 1 and 65535.");
goto fail;
@ -235,16 +240,21 @@ int pa__init(pa_module*m) {
if (port & 1)
pa_log_warn("Port number not even as suggested in RFC3550!");
if (pa_modargs_get_value_u32(ma, "ttl", &ttl) < 0 || ttl < 1 || ttl > 0xFF) {
pa_log("ttl= expects a numerical argument between 1 and 255.");
goto fail;
}
dest = pa_modargs_get_value(ma, "destination", DEFAULT_DESTINATION);
if (inet_pton(AF_INET6, dest, &sa6.sin6_addr) > 0) {
sa6.sin6_family = af = AF_INET6;
sa6.sin6_port = htons(port);
sa6.sin6_port = htons((uint16_t) port);
sap_sa6 = sa6;
sap_sa6.sin6_port = htons(SAP_PORT);
} else if (inet_pton(AF_INET, dest, &sa4.sin_addr) > 0) {
sa4.sin_family = af = AF_INET;
sa4.sin_port = htons(port);
sa4.sin_port = htons((uint16_t) port);
sap_sa4 = sa4;
sap_sa4.sin_port = htons(SAP_PORT);
} else {
@ -257,7 +267,7 @@ int pa__init(pa_module*m) {
goto fail;
}
if (connect(fd, af == AF_INET ? (struct sockaddr*) &sa4 : (struct sockaddr*) &sa6, af == AF_INET ? sizeof(sa4) : sizeof(sa6)) < 0) {
if (connect(fd, af == AF_INET ? (struct sockaddr*) &sa4 : (struct sockaddr*) &sa6, (socklen_t) (af == AF_INET ? sizeof(sa4) : sizeof(sa6))) < 0) {
pa_log("connect() failed: %s", pa_cstrerror(errno));
goto fail;
}
@ -267,7 +277,7 @@ int pa__init(pa_module*m) {
goto fail;
}
if (connect(sap_fd, af == AF_INET ? (struct sockaddr*) &sap_sa4 : (struct sockaddr*) &sap_sa6, af == AF_INET ? sizeof(sap_sa4) : sizeof(sap_sa6)) < 0) {
if (connect(sap_fd, af == AF_INET ? (struct sockaddr*) &sap_sa4 : (struct sockaddr*) &sap_sa6, (socklen_t) (af == AF_INET ? sizeof(sap_sa4) : sizeof(sap_sa6))) < 0) {
pa_log("connect() failed: %s", pa_cstrerror(errno));
goto fail;
}
@ -279,6 +289,15 @@ int pa__init(pa_module*m) {
goto fail;
}
if (ttl != DEFAULT_TTL) {
int _ttl = (int) ttl;
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &_ttl, sizeof(_ttl)) < 0) {
pa_log("IP_MULTICAST_TTL failed: %s", pa_cstrerror(errno));
goto fail;
}
}
/* If the socket queue is full, let's drop packets */
pa_make_fd_nonblock(fd);
pa_make_udp_socket_low_delay(fd);
@ -290,6 +309,7 @@ int pa__init(pa_module*m) {
pa_proplist_sets(data.proplist, "rtp.destination", dest);
pa_proplist_setf(data.proplist, "rtp.mtu", "%lu", (unsigned long) mtu);
pa_proplist_setf(data.proplist, "rtp.port", "%lu", (unsigned long) port);
pa_proplist_setf(data.proplist, "rtp.ttl", "%lu", (unsigned long) ttl);
data.driver = __FILE__;
data.module = m;
data.source = s;
@ -335,14 +355,14 @@ int pa__init(pa_module*m) {
p = pa_sdp_build(af,
af == AF_INET ? (void*) &((struct sockaddr_in*) &sa_dst)->sin_addr : (void*) &((struct sockaddr_in6*) &sa_dst)->sin6_addr,
af == AF_INET ? (void*) &sa4.sin_addr : (void*) &sa6.sin6_addr,
n, port, payload, &ss);
n, (uint16_t) port, payload, &ss);
pa_xfree(n);
pa_rtp_context_init_send(&u->rtp_context, fd, m->core->cookie, payload, pa_frame_size(&ss));
pa_sap_context_init_send(&u->sap_context, sap_fd, p);
pa_log_info("RTP stream initialized with mtu %u on %s:%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, u->rtp_context.ssrc, payload, u->rtp_context.sequence);
pa_log_info("RTP stream initialized with mtu %u on %s:%u ttl=%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, ttl, u->rtp_context.ssrc, payload, u->rtp_context.sequence);
pa_log_info("SDP-Data:\n%s\nEOF", p);
pa_sap_send(&u->sap_context, 0);

View file

@ -50,7 +50,7 @@ pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssr
c->sequence = (uint16_t) (rand()*rand());
c->timestamp = 0;
c->ssrc = ssrc ? ssrc : (uint32_t) (rand()*rand());
c->payload = payload & 127;
c->payload = (uint8_t) (payload & 127U);
c->frame_size = frame_size;
pa_memchunk_reset(&c->memchunk);
@ -99,7 +99,8 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
if (r < 0 || n >= size || iov_idx >= MAX_IOVECS) {
uint32_t header[3];
struct msghdr m;
int k, i;
ssize_t k;
int i;
if (n > 0) {
header[0] = htonl(((uint32_t) 2 << 30) | ((uint32_t) c->payload << 16) | ((uint32_t) c->sequence));
@ -112,7 +113,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
m.msg_name = NULL;
m.msg_namelen = 0;
m.msg_iov = iov;
m.msg_iovlen = iov_idx;
m.msg_iovlen = (size_t) iov_idx;
m.msg_control = NULL;
m.msg_controllen = 0;
m.msg_flags = 0;
@ -128,7 +129,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
} else
k = 0;
c->timestamp += n/c->frame_size;
c->timestamp += (unsigned) (n/c->frame_size);
if (k < 0) {
if (errno != EAGAIN && errno != EINTR) /* If the queue is full, just ignore it */
@ -162,7 +163,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
struct msghdr m;
struct iovec iov;
uint32_t header;
int cc;
unsigned cc;
ssize_t r;
pa_assert(c);
@ -197,7 +198,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
chunk->index = c->memchunk.index;
iov.iov_base = (uint8_t*) pa_memblock_acquire(chunk->memblock) + chunk->index;
iov.iov_len = size;
iov.iov_len = (size_t) size;
m.msg_name = NULL;
m.msg_namelen = 0;
@ -246,16 +247,16 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
}
cc = (header >> 24) & 0xF;
c->payload = (header >> 16) & 127;
c->sequence = header & 0xFFFF;
c->payload = (uint8_t) ((header >> 16) & 127U);
c->sequence = (uint16_t) (header & 0xFFFFU);
if (12 + cc*4 > size) {
if (12 + cc*4 > (unsigned) size) {
pa_log_warn("RTP packet too short. (CSRC)");
goto fail;
}
chunk->index += 12 + cc*4;
chunk->length = size - 12 + cc*4;
chunk->length = (size_t) size - 12 + cc*4;
if (chunk->length % c->frame_size != 0) {
pa_log_warn("Bad RTP packet size.");

View file

@ -76,7 +76,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) {
socklen_t salen = sizeof(sa_buf);
struct iovec iov[4];
struct msghdr m;
int k;
ssize_t k;
if (getsockname(c->fd, sa, &salen) < 0) {
pa_log("getsockname() failed: %s\n", pa_cstrerror(errno));
@ -94,7 +94,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) {
iov[0].iov_len = sizeof(header);
iov[1].iov_base = sa->sa_family == AF_INET ? (void*) &((struct sockaddr_in*) sa)->sin_addr : (void*) &((struct sockaddr_in6*) sa)->sin6_addr;
iov[1].iov_len = sa->sa_family == AF_INET ? 4 : 16;
iov[1].iov_len = sa->sa_family == AF_INET ? 4U : 16U;
iov[2].iov_base = (char*) MIME_TYPE;
iov[2].iov_len = sizeof(MIME_TYPE);
@ -113,7 +113,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) {
if ((k = sendmsg(c->fd, &m, MSG_DONTWAIT)) < 0)
pa_log_warn("sendmsg() failed: %s\n", pa_cstrerror(errno));
return k;
return (int) k;
}
pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) {
@ -128,10 +128,10 @@ pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) {
int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
struct msghdr m;
struct iovec iov;
int size, k;
int size;
char *buf = NULL, *e;
uint32_t header;
int six, ac;
unsigned six, ac, k;
ssize_t r;
pa_assert(c);
@ -142,11 +142,11 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
goto fail;
}
buf = pa_xnew(char, size+1);
buf = pa_xnew(char, (unsigned) size+1);
buf[size] = 0;
iov.iov_base = buf;
iov.iov_len = size;
iov.iov_len = (size_t) size;
m.msg_name = NULL;
m.msg_namelen = 0;
@ -184,21 +184,21 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
goto fail;
}
six = (header >> 28) & 1;
ac = (header >> 16) & 0xFF;
six = (header >> 28) & 1U;
ac = (header >> 16) & 0xFFU;
k = 4 + (six ? 16 : 4) + ac*4;
if (size < k) {
k = 4 + (six ? 16U : 4U) + ac*4U;
if ((unsigned) size < k) {
pa_log_warn("SAP packet too short (AD).");
goto fail;
}
e = buf + k;
size -= k;
size -= (int) k;
if ((unsigned) size >= sizeof(MIME_TYPE) && !strcmp(e, MIME_TYPE)) {
e += sizeof(MIME_TYPE);
size -= sizeof(MIME_TYPE);
size -= (int) sizeof(MIME_TYPE);
} else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) {
pa_log_warn("Invalid SDP header.");
goto fail;
@ -207,7 +207,7 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
if (c->sdp_data)
pa_xfree(c->sdp_data);
c->sdp_data = pa_xstrndup(e, size);
c->sdp_data = pa_xstrndup(e, (unsigned) size);
pa_xfree(buf);
*goodbye = !!((header >> 26) & 1);

View file

@ -55,7 +55,7 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u
if (!(u = pa_get_user_name(un, sizeof(un))))
u = "-";
ntp = time(NULL) + 2208988800U;
ntp = (uint32_t) time(NULL) + 2208988800U;
pa_assert_se(a = inet_ntop(af, src, buf_src, sizeof(buf_src)));
pa_assert_se(a = inet_ntop(af, dst, buf_dst, sizeof(buf_dst)));
@ -99,10 +99,10 @@ static pa_sample_spec *parse_sdp_sample_spec(pa_sample_spec *ss, char *c) {
return NULL;
if (sscanf(c, "%u/%u", &rate, &channels) == 2) {
ss->rate = rate;
ss->channels = channels;
ss->rate = (uint32_t) rate;
ss->channels = (uint8_t) channels;
} else if (sscanf(c, "%u", &rate) == 2) {
ss->rate = rate;
ss->rate = (uint32_t) rate;
ss->channels = 1;
} else
return NULL;

View file

@ -29,6 +29,7 @@
#include <string.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulsecore/core-util.h>
#include <pulsecore/macro.h>
@ -98,66 +99,66 @@ const char *const table[PA_CHANNEL_POSITION_MAX] = {
};
const char *const pretty_table[PA_CHANNEL_POSITION_MAX] = {
[PA_CHANNEL_POSITION_MONO] = "Mono",
[PA_CHANNEL_POSITION_MONO] = N_("Mono"),
[PA_CHANNEL_POSITION_FRONT_CENTER] = "Front Center",
[PA_CHANNEL_POSITION_FRONT_LEFT] = "Front Left",
[PA_CHANNEL_POSITION_FRONT_RIGHT] = "Front Right",
[PA_CHANNEL_POSITION_FRONT_CENTER] = N_("Front Center"),
[PA_CHANNEL_POSITION_FRONT_LEFT] = N_("Front Left"),
[PA_CHANNEL_POSITION_FRONT_RIGHT] = N_("Front Right"),
[PA_CHANNEL_POSITION_REAR_CENTER] = "Rear Center",
[PA_CHANNEL_POSITION_REAR_LEFT] = "Rear Left",
[PA_CHANNEL_POSITION_REAR_RIGHT] = "Rear Right",
[PA_CHANNEL_POSITION_REAR_CENTER] = N_("Rear Center"),
[PA_CHANNEL_POSITION_REAR_LEFT] = N_("Rear Left"),
[PA_CHANNEL_POSITION_REAR_RIGHT] = N_("Rear Right"),
[PA_CHANNEL_POSITION_LFE] = "Low Frequency Emmiter",
[PA_CHANNEL_POSITION_LFE] = N_("Low Frequency Emmiter"),
[PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "Front Left-of-center",
[PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "Front Right-of-center",
[PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = N_("Front Left-of-center"),
[PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = N_("Front Right-of-center"),
[PA_CHANNEL_POSITION_SIDE_LEFT] = "Side Left",
[PA_CHANNEL_POSITION_SIDE_RIGHT] = "Side Right",
[PA_CHANNEL_POSITION_SIDE_LEFT] = N_("Side Left"),
[PA_CHANNEL_POSITION_SIDE_RIGHT] = N_("Side Right"),
[PA_CHANNEL_POSITION_AUX0] = "Auxiliary 0",
[PA_CHANNEL_POSITION_AUX1] = "Auxiliary 1",
[PA_CHANNEL_POSITION_AUX2] = "Auxiliary 2",
[PA_CHANNEL_POSITION_AUX3] = "Auxiliary 3",
[PA_CHANNEL_POSITION_AUX4] = "Auxiliary 4",
[PA_CHANNEL_POSITION_AUX5] = "Auxiliary 5",
[PA_CHANNEL_POSITION_AUX6] = "Auxiliary 6",
[PA_CHANNEL_POSITION_AUX7] = "Auxiliary 7",
[PA_CHANNEL_POSITION_AUX8] = "Auxiliary 8",
[PA_CHANNEL_POSITION_AUX9] = "Auxiliary 9",
[PA_CHANNEL_POSITION_AUX10] = "Auxiliary 10",
[PA_CHANNEL_POSITION_AUX11] = "Auxiliary 11",
[PA_CHANNEL_POSITION_AUX12] = "Auxiliary 12",
[PA_CHANNEL_POSITION_AUX13] = "Auxiliary 13",
[PA_CHANNEL_POSITION_AUX14] = "Auxiliary 14",
[PA_CHANNEL_POSITION_AUX15] = "Auxiliary 15",
[PA_CHANNEL_POSITION_AUX16] = "Auxiliary 16",
[PA_CHANNEL_POSITION_AUX17] = "Auxiliary 17",
[PA_CHANNEL_POSITION_AUX18] = "Auxiliary 18",
[PA_CHANNEL_POSITION_AUX19] = "Auxiliary 19",
[PA_CHANNEL_POSITION_AUX20] = "Auxiliary 20",
[PA_CHANNEL_POSITION_AUX21] = "Auxiliary 21",
[PA_CHANNEL_POSITION_AUX22] = "Auxiliary 22",
[PA_CHANNEL_POSITION_AUX23] = "Auxiliary 23",
[PA_CHANNEL_POSITION_AUX24] = "Auxiliary 24",
[PA_CHANNEL_POSITION_AUX25] = "Auxiliary 25",
[PA_CHANNEL_POSITION_AUX26] = "Auxiliary 26",
[PA_CHANNEL_POSITION_AUX27] = "Auxiliary 27",
[PA_CHANNEL_POSITION_AUX28] = "Auxiliary 28",
[PA_CHANNEL_POSITION_AUX29] = "Auxiliary 29",
[PA_CHANNEL_POSITION_AUX30] = "Auxiliary 30",
[PA_CHANNEL_POSITION_AUX31] = "Auxiliary 31",
[PA_CHANNEL_POSITION_AUX0] = N_("Auxiliary 0"),
[PA_CHANNEL_POSITION_AUX1] = N_("Auxiliary 1"),
[PA_CHANNEL_POSITION_AUX2] = N_("Auxiliary 2"),
[PA_CHANNEL_POSITION_AUX3] = N_("Auxiliary 3"),
[PA_CHANNEL_POSITION_AUX4] = N_("Auxiliary 4"),
[PA_CHANNEL_POSITION_AUX5] = N_("Auxiliary 5"),
[PA_CHANNEL_POSITION_AUX6] = N_("Auxiliary 6"),
[PA_CHANNEL_POSITION_AUX7] = N_("Auxiliary 7"),
[PA_CHANNEL_POSITION_AUX8] = N_("Auxiliary 8"),
[PA_CHANNEL_POSITION_AUX9] = N_("Auxiliary 9"),
[PA_CHANNEL_POSITION_AUX10] = N_("Auxiliary 10"),
[PA_CHANNEL_POSITION_AUX11] = N_("Auxiliary 11"),
[PA_CHANNEL_POSITION_AUX12] = N_("Auxiliary 12"),
[PA_CHANNEL_POSITION_AUX13] = N_("Auxiliary 13"),
[PA_CHANNEL_POSITION_AUX14] = N_("Auxiliary 14"),
[PA_CHANNEL_POSITION_AUX15] = N_("Auxiliary 15"),
[PA_CHANNEL_POSITION_AUX16] = N_("Auxiliary 16"),
[PA_CHANNEL_POSITION_AUX17] = N_("Auxiliary 17"),
[PA_CHANNEL_POSITION_AUX18] = N_("Auxiliary 18"),
[PA_CHANNEL_POSITION_AUX19] = N_("Auxiliary 19"),
[PA_CHANNEL_POSITION_AUX20] = N_("Auxiliary 20"),
[PA_CHANNEL_POSITION_AUX21] = N_("Auxiliary 21"),
[PA_CHANNEL_POSITION_AUX22] = N_("Auxiliary 22"),
[PA_CHANNEL_POSITION_AUX23] = N_("Auxiliary 23"),
[PA_CHANNEL_POSITION_AUX24] = N_("Auxiliary 24"),
[PA_CHANNEL_POSITION_AUX25] = N_("Auxiliary 25"),
[PA_CHANNEL_POSITION_AUX26] = N_("Auxiliary 26"),
[PA_CHANNEL_POSITION_AUX27] = N_("Auxiliary 27"),
[PA_CHANNEL_POSITION_AUX28] = N_("Auxiliary 28"),
[PA_CHANNEL_POSITION_AUX29] = N_("Auxiliary 29"),
[PA_CHANNEL_POSITION_AUX30] = N_("Auxiliary 30"),
[PA_CHANNEL_POSITION_AUX31] = N_("Auxiliary 31"),
[PA_CHANNEL_POSITION_TOP_CENTER] = "Top Center",
[PA_CHANNEL_POSITION_TOP_CENTER] = N_("Top Center"),
[PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "Top Front Center",
[PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "Top Front Left",
[PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "Top Front Right",
[PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = N_("Top Front Center"),
[PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = N_("Top Front Left"),
[PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = N_("Top Front Right"),
[PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "Top Rear Center",
[PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "Top Rear left",
[PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "Top Rear Right"
[PA_CHANNEL_POSITION_TOP_REAR_CENTER] = N_("Top Rear Center"),
[PA_CHANNEL_POSITION_TOP_REAR_LEFT] = N_("Top Rear Left"),
[PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = N_("Top Rear Right")
};
pa_channel_map* pa_channel_map_init(pa_channel_map *m) {
@ -200,7 +201,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
pa_channel_map_init(m);
m->channels = channels;
m->channels = (uint8_t) channels;
switch (def) {
case PA_CHANNEL_MAP_AIFF:
@ -414,7 +415,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels,
i++;
}
m->channels = channels;
m->channels = (uint8_t) channels;
return m;
}
@ -432,10 +433,13 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) {
}
const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) {
pa_init_i18n();
if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
return NULL;
return pretty_table[pos];
return _(pretty_table[pos]);
}
int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
@ -456,7 +460,7 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
unsigned channel;
int first = 1;
pa_bool_t first = TRUE;
char *e;
pa_assert(s);
@ -471,7 +475,7 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
pa_channel_position_to_string(map->map[channel]));
e = strchr(e, 0);
first = 0;
first = FALSE;
}
return s;
@ -552,7 +556,6 @@ int pa_channel_map_valid(const pa_channel_map *map) {
if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
return 0;
}
return 1;

View file

@ -29,6 +29,7 @@
#include <X11/Xatom.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulsecore/x11prop.h>
#include <pulsecore/log.h>
@ -51,7 +52,7 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) {
goto finish;
if (!(d = XOpenDisplay(dname))) {
pa_log("XOpenDisplay() failed");
pa_log(_("XOpenDisplay() failed"));
goto finish;
}
@ -74,7 +75,7 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) {
uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
if (pa_parsehex(t, cookie, sizeof(cookie)) != sizeof(cookie)) {
pa_log("failed to parse cookie data");
pa_log(_("Failed to parse cookie data"));
goto finish;
}

View file

@ -30,6 +30,7 @@
#include <string.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulsecore/macro.h>
#include <pulsecore/core-error.h>
@ -113,7 +114,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
if (filename) {
if (!(f = fopen(filename, "r"))) {
pa_log("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno));
pa_log(_("Failed to open configuration file '%s': %s"), fn, pa_cstrerror(errno));
goto finish;
}

View file

@ -53,6 +53,8 @@
#include <pulse/xmalloc.h>
#include <pulse/utf8.h>
#include <pulse/util.h>
#include <pulse/i18n.h>
#include <pulse/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
@ -80,7 +82,7 @@
#include "context.h"
#define AUTOSPAWN_LOCK "autospawn.lock"
void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_REQUEST] = pa_command_request,
@ -93,23 +95,27 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
[PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
[PA_COMMAND_STARTED] = pa_command_stream_started,
[PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event
[PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
[PA_COMMAND_EXTENSION] = pa_command_extension
};
static void unlock_autospawn_lock_file(pa_context *c) {
static void unlock_autospawn(pa_context *c) {
pa_assert(c);
if (c->autospawn_lock_fd >= 0) {
char *lf;
if (c->autospawn_fd >= 0) {
if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
pa_log_warn("Cannot unlock autospawn because runtime path is no more.");
if (c->autospawn_locked)
pa_autospawn_lock_release();
pa_unlock_lockfile(lf, c->autospawn_lock_fd);
pa_xfree(lf);
if (c->autospawn_event)
c->mainloop->io_free(c->autospawn_event);
c->autospawn_lock_fd = -1;
pa_autospawn_lock_done(FALSE);
}
c->autospawn_locked = FALSE;
c->autospawn_fd = -1;
c->autospawn_event = NULL;
}
static void context_free(pa_context *c);
@ -126,6 +132,9 @@ static void reset_callbacks(pa_context *c) {
c->subscribe_callback = NULL;
c->subscribe_userdata = NULL;
c->ext_stream_restore.callback = NULL;
c->ext_stream_restore.userdata = NULL;
}
pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) {
@ -133,6 +142,8 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
pa_assert(mainloop);
pa_init_i18n();
if (!name && !pa_proplist_contains(p, PA_PROP_APPLICATION_NAME))
return NULL;
@ -165,11 +176,15 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
c->is_local = FALSE;
c->server_list = NULL;
c->server = NULL;
c->autospawn_lock_fd = -1;
memset(&c->spawn_api, 0, sizeof(c->spawn_api));
c->do_autospawn = FALSE;
c->do_shm = FALSE;
c->do_autospawn = FALSE;
c->autospawn_fd = -1;
c->autospawn_locked = FALSE;
c->autospawn_event = NULL;
memset(&c->spawn_api, 0, sizeof(c->spawn_api));
#ifndef MSG_NOSIGNAL
#ifdef SIGPIPE
pa_check_signal_is_blocked(SIGPIPE);
@ -237,7 +252,7 @@ static void context_free(pa_context *c) {
context_unlink(c);
unlock_autospawn_lock_file(c);
unlock_autospawn(c);
if (c->record_streams)
pa_dynarray_free(c->record_streams, NULL, NULL);
@ -398,11 +413,11 @@ int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa
err = PA_ERR_UNKNOWN;
if (fail) {
pa_context_fail(c, err);
pa_context_fail(c, (int) err);
return -1;
}
pa_context_set_error(c, err);
pa_context_set_error(c, (int) err);
return 0;
}
@ -424,7 +439,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
switch(c->state) {
case PA_CONTEXT_AUTHORIZING: {
pa_tagstruct *reply;
pa_bool_t shm_on_remote;
pa_bool_t shm_on_remote = FALSE;
if (pa_tagstruct_getu32(t, &c->version) < 0 ||
!pa_tagstruct_eof(t)) {
@ -524,7 +539,7 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
if (!c->conf->cookie_valid)
pa_log_info("No cookie loaded. Attempting to connect without.");
pa_log_info(_("No cookie loaded. Attempting to connect without."));
t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
@ -578,7 +593,7 @@ static int context_connect_spawn(pa_context *c) {
pa_context_ref(c);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
pa_log_error("socketpair(): %s", pa_cstrerror(errno));
pa_log_error(_("socketpair(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
}
@ -592,7 +607,7 @@ static int context_connect_spawn(pa_context *c) {
c->spawn_api.prefork();
if ((pid = fork()) < 0) {
pa_log_error("fork(): %s", pa_cstrerror(errno));
pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
if (c->spawn_api.postfork)
@ -655,7 +670,7 @@ static int context_connect_spawn(pa_context *c) {
c->spawn_api.postfork();
if (r < 0) {
pa_log("waitpid(): %s", pa_cstrerror(errno));
pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
} else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
@ -665,7 +680,7 @@ static int context_connect_spawn(pa_context *c) {
c->is_local = TRUE;
unlock_autospawn_lock_file(c);
unlock_autospawn(c);
io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
setup_context(c, io);
@ -677,7 +692,7 @@ static int context_connect_spawn(pa_context *c) {
fail:
pa_close_pipe(fds);
unlock_autospawn_lock_file(c);
unlock_autospawn(c);
pa_context_unref(c);
@ -759,15 +774,48 @@ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userd
goto finish;
}
unlock_autospawn_lock_file(c);
unlock_autospawn(c);
setup_context(c, io);
finish:
pa_context_unref(c);
}
static void autospawn_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
pa_context *c = userdata;
int k;
static char *get_legacy_runtime_dir(void) {
pa_assert(a);
pa_assert(e);
pa_assert(fd >= 0);
pa_assert(events == PA_IO_EVENT_INPUT);
pa_assert(c);
pa_assert(e == c->autospawn_event);
pa_assert(fd == c->autospawn_fd);
pa_context_ref(c);
/* Check whether we can get the lock right now*/
if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
pa_context_fail(c, PA_ERR_ACCESS);
goto finish;
}
if (k > 0) {
/* So we got it, rock on! */
c->autospawn_locked = TRUE;
try_next_connection(c);
c->mainloop->io_free(c->autospawn_event);
c->autospawn_event = NULL;
}
finish:
pa_context_unref(c);
}
static char *get_old_legacy_runtime_dir(void) {
char *p, u[128];
struct stat st;
@ -789,6 +837,28 @@ static char *get_legacy_runtime_dir(void) {
return p;
}
static char *get_very_old_legacy_runtime_dir(void) {
char *p, h[128];
struct stat st;
if (!pa_get_home_dir(h, sizeof(h)))
return NULL;
p = pa_sprintf_malloc("%s/.pulse", h);
if (stat(p, &st) < 0) {
pa_xfree(p);
return NULL;
}
if (st.st_uid != getuid()) {
pa_xfree(p);
return NULL;
}
return p;
}
int pa_context_connect(
pa_context *c,
const char *server,
@ -816,6 +886,7 @@ int pa_context_connect(
pa_context_fail(c, PA_ERR_INVALIDSERVER);
goto finish;
}
} else {
char *d, *ufn;
static char *legacy_dir;
@ -840,8 +911,16 @@ int pa_context_connect(
/* The system wide instance */
c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
/* The old per-user instance path. This is supported only to ease upgrades */
if ((legacy_dir = get_legacy_runtime_dir())) {
/* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
c->server_list = pa_strlist_prepend(c->server_list, p);
pa_xfree(p);
pa_xfree(legacy_dir);
}
/* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
if ((legacy_dir = get_old_legacy_runtime_dir())) {
char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
c->server_list = pa_strlist_prepend(c->server_list, p);
pa_xfree(p);
@ -856,21 +935,40 @@ int pa_context_connect(
/* Wrap the connection attempts in a single transaction for sane autospawn locking */
if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
char *lf;
int k;
if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
pa_assert(c->autospawn_fd < 0);
pa_assert(!c->autospawn_locked);
/* Start the locking procedure */
if ((c->autospawn_fd = pa_autospawn_lock_init()) < 0) {
pa_context_fail(c, PA_ERR_ACCESS);
goto finish;
}
pa_assert(c->autospawn_lock_fd <= 0);
c->autospawn_lock_fd = pa_lock_lockfile(lf);
pa_xfree(lf);
if (api)
c->spawn_api = *api;
c->do_autospawn = TRUE;
/* Check whether we can get the lock right now*/
if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
pa_context_fail(c, PA_ERR_ACCESS);
goto finish;
}
if (k > 0)
/* So we got it, rock on! */
c->autospawn_locked = TRUE;
else {
/* Hmm, we didn't get it, so let's wait for it */
c->autospawn_event = c->mainloop->io_new(c->mainloop, c->autospawn_fd, PA_IO_EVENT_INPUT, autospawn_cb, c);
pa_context_set_state(c, PA_CONTEXT_CONNECTING);
r = 0;
goto finish;
}
}
}
@ -929,11 +1027,11 @@ int pa_context_is_pending(pa_context *c) {
static void set_dispatch_callbacks(pa_operation *o);
static void pdispatch_drain_callback(PA_GCC_UNUSED pa_pdispatch*pd, void *userdata) {
static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
set_dispatch_callbacks(userdata);
}
static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) {
static void pstream_drain_callback(pa_pstream *s, void *userdata) {
set_dispatch_callbacks(userdata);
}
@ -985,7 +1083,7 @@ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *u
return o;
}
void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@ -1137,7 +1235,7 @@ const char* pa_context_get_server(pa_context *c) {
return c->server;
}
uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) {
uint32_t pa_context_get_protocol_version(pa_context *c) {
return PA_PROTOCOL_VERSION;
}
@ -1230,3 +1328,31 @@ pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[]
return o;
}
void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
uint32_t idx;
const char *name;
pa_assert(pd);
pa_assert(command == PA_COMMAND_EXTENSION);
pa_assert(t);
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_context_ref(c);
if (pa_tagstruct_getu32(t, &idx) < 0 ||
pa_tagstruct_gets(t, &name) < 0) {
pa_context_fail(c, PA_ERR_PROTOCOL);
goto finish;
}
if (!strcmp(name, "module-stream-restore"))
pa_ext_stream_restore_command(c, tag, t);
else
pa_log(_("Received message for unknown extension '%s'"), name);
finish:
pa_context_unref(c);
}

View file

@ -30,6 +30,7 @@
#include <string.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulsecore/core-util.h>
#include <pulsecore/native-common.h>
@ -39,32 +40,34 @@
const char*pa_strerror(int error) {
static const char* const errortab[PA_ERR_MAX] = {
[PA_OK] = "OK",
[PA_ERR_ACCESS] = "Access denied",
[PA_ERR_COMMAND] = "Unknown command",
[PA_ERR_INVALID] = "Invalid argument",
[PA_ERR_EXIST] = "Entity exists",
[PA_ERR_NOENTITY] = "No such entity",
[PA_ERR_CONNECTIONREFUSED] = "Connection refused",
[PA_ERR_PROTOCOL] = "Protocol error",
[PA_ERR_TIMEOUT] = "Timeout",
[PA_ERR_AUTHKEY] = "No authorization key",
[PA_ERR_INTERNAL] = "Internal error",
[PA_ERR_CONNECTIONTERMINATED] = "Connection terminated",
[PA_ERR_KILLED] = "Entity killed",
[PA_ERR_INVALIDSERVER] = "Invalid server",
[PA_ERR_MODINITFAILED] = "Module initalization failed",
[PA_ERR_BADSTATE] = "Bad state",
[PA_ERR_NODATA] = "No data",
[PA_ERR_VERSION] = "Incompatible protocol version",
[PA_ERR_TOOLARGE] = "Too large",
[PA_ERR_NOTSUPPORTED] = "Not supported",
[PA_ERR_UNKNOWN] = "Unknown error code",
[PA_ERR_NOEXTENSION] = "No such extension"
[PA_OK] = N_("OK"),
[PA_ERR_ACCESS] = N_("Access denied"),
[PA_ERR_COMMAND] = N_("Unknown command"),
[PA_ERR_INVALID] = N_("Invalid argument"),
[PA_ERR_EXIST] = N_("Entity exists"),
[PA_ERR_NOENTITY] = N_("No such entity"),
[PA_ERR_CONNECTIONREFUSED] = N_("Connection refused"),
[PA_ERR_PROTOCOL] = N_("Protocol error"),
[PA_ERR_TIMEOUT] = N_("Timeout"),
[PA_ERR_AUTHKEY] = N_("No authorization key"),
[PA_ERR_INTERNAL] = N_("Internal error"),
[PA_ERR_CONNECTIONTERMINATED] = N_("Connection terminated"),
[PA_ERR_KILLED] = N_("Entity killed"),
[PA_ERR_INVALIDSERVER] = N_("Invalid server"),
[PA_ERR_MODINITFAILED] = N_("Module initalization failed"),
[PA_ERR_BADSTATE] = N_("Bad state"),
[PA_ERR_NODATA] = N_("No data"),
[PA_ERR_VERSION] = N_("Incompatible protocol version"),
[PA_ERR_TOOLARGE] = N_("Too large"),
[PA_ERR_NOTSUPPORTED] = N_("Not supported"),
[PA_ERR_UNKNOWN] = N_("Unknown error code"),
[PA_ERR_NOEXTENSION] = N_("No such extension")
};
pa_init_i18n();
if (error < 0 || error >= PA_ERR_MAX)
return NULL;
return errortab[error];
return _(errortab[error]);
}

View file

@ -0,0 +1,326 @@
/***
This file is part of PulseAudio.
Copyright 2008 Lennart Poettering
PulseAudio 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 of the License,
or (at your option) any later version.
PulseAudio 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
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pulse/context.h>
#include <pulse/gccmacro.h>
#include <pulsecore/macro.h>
#include <pulsecore/pstream-util.h>
#include "internal.h"
#include "ext-stream-restore.h"
enum {
SUBCOMMAND_TEST,
SUBCOMMAND_READ,
SUBCOMMAND_WRITE,
SUBCOMMAND_DELETE,
SUBCOMMAND_SUBSCRIBE,
SUBCOMMAND_EVENT
};
static void ext_stream_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
uint32_t version = PA_INVALID_INDEX;
pa_assert(pd);
pa_assert(o);
pa_assert(PA_REFCNT_VALUE(o) >= 1);
if (!o->context)
goto finish;
if (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
goto finish;
} else if (pa_tagstruct_getu32(t, &version) < 0 ||
!pa_tagstruct_eof(t)) {
pa_context_fail(o->context, PA_ERR_PROTOCOL);
goto finish;
}
if (o->callback) {
pa_ext_stream_restore_test_cb_t cb = (pa_ext_stream_restore_test_cb_t) o->callback;
cb(o->context, version, o->userdata);
}
finish:
pa_operation_done(o);
pa_operation_unref(o);
}
pa_operation *pa_ext_stream_restore_test(
pa_context *c,
pa_ext_stream_restore_test_cb_t cb,
void *userdata) {
uint32_t tag;
pa_operation *o;
pa_tagstruct *t;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
pa_tagstruct_putu32(t, PA_INVALID_INDEX);
pa_tagstruct_puts(t, "module-stream-restore");
pa_tagstruct_putu32(t, SUBCOMMAND_TEST);
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_stream_restore_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
}
static void ext_stream_restore_read_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
pa_assert(pd);
pa_assert(o);
pa_assert(PA_REFCNT_VALUE(o) >= 1);
if (!o->context)
goto finish;
if (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
goto finish;
eol = -1;
} else {
while (!pa_tagstruct_eof(t)) {
pa_ext_stream_restore_info i;
pa_bool_t mute = FALSE;
memset(&i, 0, sizeof(i));
if (pa_tagstruct_gets(t, &i.name) < 0 ||
pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
pa_tagstruct_gets(t, &i.device) < 0 ||
pa_tagstruct_get_boolean(t, &mute) < 0) {
pa_context_fail(o->context, PA_ERR_PROTOCOL);
goto finish;
}
i.mute = (int) mute;
if (o->callback) {
pa_ext_stream_restore_read_cb_t cb = (pa_ext_stream_restore_read_cb_t) o->callback;
cb(o->context, &i, 0, o->userdata);
}
}
}
if (o->callback) {
pa_ext_stream_restore_read_cb_t cb = (pa_ext_stream_restore_read_cb_t) o->callback;
cb(o->context, NULL, eol, o->userdata);
}
finish:
pa_operation_done(o);
pa_operation_unref(o);
}
pa_operation *pa_ext_stream_restore_read(
pa_context *c,
pa_ext_stream_restore_read_cb_t cb,
void *userdata) {
uint32_t tag;
pa_operation *o;
pa_tagstruct *t;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
pa_tagstruct_putu32(t, PA_INVALID_INDEX);
pa_tagstruct_puts(t, "module-stream-restore");
pa_tagstruct_putu32(t, SUBCOMMAND_READ);
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_stream_restore_read_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
}
pa_operation *pa_ext_stream_restore_write(
pa_context *c,
pa_update_mode_t mode,
const pa_ext_stream_restore_info data[],
unsigned n,
int apply_immediately,
pa_context_success_cb_t cb,
void *userdata) {
uint32_t tag;
pa_operation *o;
pa_tagstruct *t;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_assert(mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE || mode == PA_UPDATE_SET);
pa_assert(data);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
pa_tagstruct_putu32(t, PA_INVALID_INDEX);
pa_tagstruct_puts(t, "module-stream-restore");
pa_tagstruct_putu32(t, SUBCOMMAND_WRITE);
pa_tagstruct_putu32(t, mode);
pa_tagstruct_put_boolean(t, apply_immediately);
for (; n > 0; n--, data++) {
pa_tagstruct_puts(t, data->name);
pa_tagstruct_put_channel_map(t, &data->channel_map);
pa_tagstruct_put_cvolume(t, &data->volume);
pa_tagstruct_puts(t, data->device);
pa_tagstruct_put_boolean(t, data->mute);
}
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
}
pa_operation *pa_ext_stream_restore_delete(
pa_context *c,
const char *const s[],
pa_context_success_cb_t cb,
void *userdata) {
uint32_t tag;
pa_operation *o;
pa_tagstruct *t;
const char *const *k;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_assert(s);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
pa_tagstruct_putu32(t, PA_INVALID_INDEX);
pa_tagstruct_puts(t, "module-stream-restore");
pa_tagstruct_putu32(t, SUBCOMMAND_DELETE);
for (k = s; *k; k++)
pa_tagstruct_puts(t, *k);
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
}
pa_operation *pa_ext_stream_restore_subscribe(
pa_context *c,
int enable,
pa_context_success_cb_t cb,
void *userdata) {
uint32_t tag;
pa_operation *o;
pa_tagstruct *t;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
pa_tagstruct_putu32(t, PA_INVALID_INDEX);
pa_tagstruct_puts(t, "module-stream-restore");
pa_tagstruct_putu32(t, SUBCOMMAND_SUBSCRIBE);
pa_tagstruct_put_boolean(t, enable);
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
}
void pa_ext_stream_restore_set_subscribe_cb(
pa_context *c,
pa_ext_stream_restore_subscribe_cb_t cb,
void *userdata) {
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
c->ext_stream_restore.callback = cb;
c->ext_stream_restore.userdata = userdata;
}
void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t) {
uint32_t subcommand;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_assert(t);
if (pa_tagstruct_getu32(t, &subcommand) < 0 ||
!pa_tagstruct_eof(t)) {
pa_context_fail(c, PA_ERR_PROTOCOL);
return;
}
if (subcommand != SUBCOMMAND_EVENT) {
pa_context_fail(c, PA_ERR_PROTOCOL);
return;
}
if (c->ext_stream_restore.callback)
c->ext_stream_restore.callback(c, c->ext_stream_restore.userdata);
}

View file

@ -0,0 +1,107 @@
#ifndef foopulseextstreamrestorehfoo
#define foopulseextstreamrestorehfoo
/***
This file is part of PulseAudio.
Copyright 2008 Lennart Poettering
PulseAudio 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 of the License,
or (at your option) any later version.
PulseAudio 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
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#include <pulse/context.h>
/** \file
*
* Routines for controlling module-stream-restore
*/
PA_C_DECL_BEGIN
/** Stores information about one entry in the stream database that is
* maintained by module-stream-restore. \since 0.9.12 */
typedef struct pa_ext_stream_restore_info {
const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */
pa_channel_map channel_map; /**< The channel map for the volume field */
pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable */
const char *device; /**< The sink/source of the stream when it was last seen */
int mute; /**< The boolean mute state of the stream when it was last seen, if applicable */
} pa_ext_stream_restore_info;
/** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */
typedef void (*pa_ext_stream_restore_test_cb_t)(
pa_context *c,
uint32_t version,
void *userdata);
/** Test if this extension module is available in the server. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_test(
pa_context *c,
pa_ext_stream_restore_test_cb_t cb,
void *userdata);
/** Callback prototype for pa_ext_stream_restore_read(). \since 0.9.12 */
typedef void (*pa_ext_stream_restore_read_cb_t)(
pa_context *c,
const pa_ext_stream_restore_info *info,
int eol,
void *userdata);
/** Read all entries from the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_read(
pa_context *c,
pa_ext_stream_restore_read_cb_t cb,
void *userdata);
/** Store entries in the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_write(
pa_context *c,
pa_update_mode_t mode,
const pa_ext_stream_restore_info data[],
unsigned n,
int apply_immediately,
pa_context_success_cb_t cb,
void *userdata);
/** Delete entries from the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_delete(
pa_context *c,
const char *const s[],
pa_context_success_cb_t cb,
void *userdata);
/** Subscribe to changes in the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_subscribe(
pa_context *c,
int enable,
pa_context_success_cb_t cb,
void *userdata);
/** Callback prototype for pa_ext_stream_restore_set_subscribe_cb(). \since 0.9.12 */
typedef void (*pa_ext_stream_restore_subscribe_cb_t)(
pa_context *c,
void *userdata);
/** Set the subscription callback that is called when
* pa_ext_stream_restore_subscribe() was called. \since 0.9.12 */
void pa_ext_stream_restore_set_subscribe_cb(
pa_context *c,
pa_ext_stream_restore_subscribe_cb_t cb,
void *userdata);
PA_C_DECL_END
#endif

View file

@ -195,11 +195,11 @@ static void cleanup_defer_events(pa_glib_mainloop *g, int force) {
}
static gushort map_flags_to_glib(pa_io_event_flags_t flags) {
return
(flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) |
(flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) |
(flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) |
(flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0);
return (gushort)
((flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) |
(flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) |
(flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) |
(flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0));
}
static pa_io_event_flags_t map_flags_from_glib(gushort flags) {
@ -425,7 +425,7 @@ static void glib_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_
/* quit() */
static void glib_quit(pa_mainloop_api*a, PA_GCC_UNUSED int retval) {
static void glib_quit(pa_mainloop_api*a, int retval) {
g_warning("quit() ignored");
@ -536,7 +536,7 @@ static gboolean check_func(GSource *source) {
return FALSE;
}
static gboolean dispatch_func(GSource *source, PA_GCC_UNUSED GSourceFunc callback, PA_GCC_UNUSED gpointer userdata) {
static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer userdata) {
pa_glib_mainloop *g = (pa_glib_mainloop*) source;
pa_io_event *e;

38
src/pulse/i18n.c Normal file
View file

@ -0,0 +1,38 @@
/***
This file is part of PulseAudio.
Copyright 2008 Lennart Poettering
PulseAudio 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.
PulseAudio 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 PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pulsecore/once.h>
#include "i18n.h"
void pa_init_i18n(void) {
PA_ONCE_BEGIN {
bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
} PA_ONCE_END;
}

62
src/pulse/i18n.h Normal file
View file

@ -0,0 +1,62 @@
#ifndef foopulsei18nhfoo
#define foopulsei18nhfoo
/***
This file is part of PulseAudio.
Copyright 2008 Lennart Poettering
PulseAudio 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.
PulseAudio 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 PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#include <pulse/cdecl.h>
#include <pulse/gccmacro.h>
PA_C_DECL_BEGIN
#if !defined(GETTEXT_PACKAGE)
#error "Something is very wrong here, config.h needs to be included first"
#endif
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) dgettext(GETTEXT_PACKAGE, String)
#ifdef gettext_noop
#define N_(String) gettext_noop(String)
#else
#define N_(String) (String)
#endif
#else /* NLS is disabled */
#define _(String) (String)
#define N_(String) (String)
#define textdomain(String) (String)
#define gettext(String) (String)
#define dgettext(Domain,String) (String)
#define dcgettext(Domain,String,Type) (String)
#define bindtextdomain(Domain,Directory) (Domain)
#define bind_textdomain_codeset(Domain,Codeset) (Codeset)
#endif /* ENABLE_NLS */
void pa_init_i18n(void);
PA_C_DECL_END
#endif

View file

@ -28,6 +28,7 @@
#include <pulse/stream.h>
#include <pulse/operation.h>
#include <pulse/subscribe.h>
#include <pulse/ext-stream-restore.h>
#include <pulsecore/socket-client.h>
#include <pulsecore/pstream.h>
@ -63,7 +64,7 @@ struct pa_context {
uint32_t version;
uint32_t ctag;
uint32_t csyncid;
uint32_t error;
int error;
pa_context_state_t state;
pa_context_notify_cb_t state_callback;
@ -74,9 +75,12 @@ struct pa_context {
pa_mempool *mempool;
pa_bool_t is_local:1;
pa_bool_t do_autospawn:1;
pa_bool_t do_shm:1;
int autospawn_lock_fd;
pa_bool_t do_autospawn:1;
pa_bool_t autospawn_locked:1;
int autospawn_fd;
pa_io_event *autospawn_event;
pa_spawn_api spawn_api;
pa_strlist *server_list;
@ -86,6 +90,12 @@ struct pa_context {
pa_client_conf *conf;
uint32_t client_index;
/* Extension specific data */
struct {
pa_ext_stream_restore_subscribe_cb_t callback;
void *userdata;
} ext_stream_restore;
};
#define PA_MAX_WRITE_INDEX_CORRECTIONS 32
@ -233,4 +243,6 @@ pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *ta
#define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error) PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, NULL)
void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
#endif

View file

@ -36,7 +36,7 @@
/*** Statistics ***/
static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
pa_stat_info i, *p = &i;
@ -79,7 +79,7 @@ pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdat
/*** Server Info ***/
static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
pa_server_info i, *p = &i;
@ -127,7 +127,7 @@ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb,
/*** Sink Info ***/
static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -248,7 +248,7 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name,
/*** Source info ***/
static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -369,7 +369,7 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name
/*** Client info ***/
static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -451,7 +451,7 @@ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t
/*** Module info ***/
static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -530,7 +530,7 @@ pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t
/*** Sink input info ***/
static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -624,7 +624,7 @@ pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_c
/*** Source output info ***/
static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -954,7 +954,7 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name
/** Sample Cache **/
static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@ -1098,7 +1098,7 @@ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_cont
return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
}
static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
uint32_t idx;
@ -1159,7 +1159,7 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_s
/*** Autoload stuff ***/
static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;

View file

@ -52,14 +52,14 @@
* Some objects can have multiple entries at the server. When requesting all
* of these at once, the callback will be called multiple times, once for
* each object. When the list has been exhausted, the callback will be called
* without an information structure and the eol parameter set to a non-zero
* without an information structure and the eol parameter set to a positive
* value.
*
* Note that even if a single object is requested, and not the entire list,
* the terminating call will still be made.
*
* If an error occurs, the callback will be called without and information
* structure and eol set to zero.
* structure and eol set to a negative value..
*
* Data members in the information structures are only valid during the
* duration of the callback. If they are required after the callback is
@ -210,11 +210,6 @@
PA_C_DECL_BEGIN
#define PA_PORT_DIGITAL "spdif"
#define PA_PORT_ANALOG_STEREO "analog-stereo"
#define PA_PORT_ANALOG_5_1 "analog-5-1"
#define PA_PORT_ANALOG_4_0 "analog-4-0"
/** @{ \name Sinks */
/** Stores information about sinks. Please note that this structure

330
src/pulse/lock-autospawn.c Normal file
View file

@ -0,0 +1,330 @@
/***
This file is part of PulseAudio.
Copyright 2008 Lennart Poettering
PulseAudio 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 of the License,
or (at your option) any later version.
PulseAudio 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
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/poll.h>
#include <signal.h>
#include <pthread.h>
#include <pulse/i18n.h>
#include <pulse/xmalloc.h>
#include <pulsecore/mutex.h>
#include <pulsecore/thread.h>
#include <pulsecore/core-util.h>
#include "lock-autospawn.h"
/* So, why do we have this complex code here with threads and pipes
* and stuff? For two reasons: POSIX file locks are per-process, not
* per-file descriptor. That means that two contexts within the same
* process that try to create the autospawn lock might end up assuming
* they both managed to lock the file. And then, POSIX locking
* operations are synchronous. If two contexts run from the same event
* loop it must be made sure that they do not block each other, but
* that the locking operation can happen asynchronously. */
#define AUTOSPAWN_LOCK "autospawn.lock"
static pa_mutex *mutex;
static unsigned n_ref = 0;
static int lock_fd = -1;
static pa_mutex *lock_fd_mutex = NULL;
static pa_bool_t taken = FALSE;
static pa_thread *thread;
static int pipe_fd[2] = { -1, -1 };
static void destroy_mutex(void) PA_GCC_DESTRUCTOR;
static int ref(void) {
if (n_ref > 0) {
pa_assert(pipe_fd[0] >= 0);
pa_assert(pipe_fd[1] >= 0);
n_ref++;
return 0;
}
pa_assert(lock_fd < 0);
pa_assert(!lock_fd_mutex);
pa_assert(!taken);
pa_assert(!thread);
pa_assert(pipe_fd[0] < 0);
pa_assert(pipe_fd[1] < 0);
if (pipe(pipe_fd) < 0)
return -1;
lock_fd_mutex = pa_mutex_new(FALSE, FALSE);
pa_make_fd_cloexec(pipe_fd[0]);
pa_make_fd_cloexec(pipe_fd[1]);
pa_make_fd_nonblock(pipe_fd[1]);
pa_make_fd_nonblock(pipe_fd[0]);
n_ref = 1;
return 0;
}
static void unref(pa_bool_t after_fork) {
pa_assert(n_ref > 0);
pa_assert(pipe_fd[0] >= 0);
pa_assert(pipe_fd[1] >= 0);
pa_assert(lock_fd_mutex);
n_ref--;
if (n_ref > 0)
return;
pa_assert(!taken);
if (thread) {
pa_thread_free(thread);
thread = NULL;
}
pa_mutex_lock(lock_fd_mutex);
if (lock_fd >= 0) {
if (after_fork)
pa_close(lock_fd);
else {
char *lf;
if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
pa_log_warn(_("Cannot access autospawn lock."));
pa_unlock_lockfile(lf, lock_fd);
pa_xfree(lf);
lock_fd = -1;
}
}
pa_mutex_unlock(lock_fd_mutex);
pa_mutex_free(lock_fd_mutex);
lock_fd_mutex = NULL;
pa_close(pipe_fd[0]);
pa_close(pipe_fd[1]);
pipe_fd[0] = pipe_fd[1] = -1;
}
static void ping(void) {
ssize_t s;
pa_assert(pipe_fd[1] >= 0);
for (;;) {
char x = 'x';
if ((s = write(pipe_fd[1], &x, 1)) == 1)
break;
pa_assert(s < 0);
if (errno == EAGAIN)
break;
pa_assert(errno == EINTR);
}
}
static void wait_for_ping(void) {
ssize_t s;
char x;
struct pollfd pfd;
int k;
pa_assert(pipe_fd[0] >= 0);
memset(&pfd, 0, sizeof(pfd));
pfd.fd = pipe_fd[0];
pfd.events = POLLIN;
if ((k = poll(&pfd, 1, -1)) != 1) {
pa_assert(k < 0);
pa_assert(errno == EINTR);
} else if ((s = read(pipe_fd[0], &x, 1)) != 1) {
pa_assert(s < 0);
pa_assert(errno == EAGAIN);
}
}
static void empty_pipe(void) {
char x[16];
ssize_t s;
pa_assert(pipe_fd[0] >= 0);
if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) {
pa_assert(s < 0);
pa_assert(errno == EAGAIN);
}
}
static void thread_func(void *u) {
int fd;
char *lf;
sigset_t fullset;
/* No signals in this thread please */
sigfillset(&fullset);
pthread_sigmask(SIG_BLOCK, &fullset, NULL);
if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
pa_log_warn(_("Cannot access autospawn lock."));
goto finish;
}
if ((fd = pa_lock_lockfile(lf)) < 0)
goto finish;
pa_mutex_lock(lock_fd_mutex);
pa_assert(lock_fd < 0);
lock_fd = fd;
pa_mutex_unlock(lock_fd_mutex);
finish:
pa_xfree(lf);
ping();
}
static int start_thread(void) {
if (!thread)
if (!(thread = pa_thread_new(thread_func, NULL)))
return -1;
return 0;
}
static void create_mutex(void) {
PA_ONCE_BEGIN {
mutex = pa_mutex_new(FALSE, FALSE);
} PA_ONCE_END;
}
static void destroy_mutex(void) {
if (mutex)
pa_mutex_free(mutex);
}
int pa_autospawn_lock_init(void) {
int ret = -1;
create_mutex();
pa_mutex_lock(mutex);
if (ref() < 0)
ret = -1;
else
ret = pipe_fd[0];
pa_mutex_unlock(mutex);
return ret;
}
int pa_autospawn_lock_acquire(pa_bool_t block) {
int ret = -1;
create_mutex();
pa_mutex_lock(mutex);
pa_assert(n_ref >= 1);
pa_mutex_lock(lock_fd_mutex);
for (;;) {
empty_pipe();
if (lock_fd >= 0 && !taken) {
taken = TRUE;
ret = 1;
break;
}
if (lock_fd < 0)
if (start_thread() < 0)
break;
if (!block) {
ret = 0;
break;
}
pa_mutex_unlock(lock_fd_mutex);
pa_mutex_unlock(mutex);
wait_for_ping();
pa_mutex_lock(mutex);
pa_mutex_lock(lock_fd_mutex);
}
pa_mutex_unlock(lock_fd_mutex);
pa_mutex_unlock(mutex);
return ret;
}
void pa_autospawn_lock_release(void) {
create_mutex();
pa_mutex_lock(mutex);
pa_assert(n_ref >= 1);
pa_assert(taken);
taken = FALSE;
ping();
pa_mutex_unlock(mutex);
}
void pa_autospawn_lock_done(pa_bool_t after_fork) {
create_mutex();
pa_mutex_lock(mutex);
pa_assert(n_ref >= 1);
unref(after_fork);
pa_mutex_unlock(mutex);
}

View file

@ -0,0 +1,32 @@
#ifndef foopulselockautospawnhfoo
#define foopulselockautospawnhfoo
/***
This file is part of PulseAudio.
Copyright 2008 Lennart Poettering
PulseAudio 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.
PulseAudio 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 PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#include <pulsecore/macro.h>
int pa_autospawn_lock_init(void);
int pa_autospawn_lock_acquire(pa_bool_t block);
void pa_autospawn_lock_release(void);
void pa_autospawn_lock_done(pa_bool_t after_fork);
#endif

View file

@ -27,6 +27,7 @@
#include <pulse/xmalloc.h>
#include <pulse/gccmacro.h>
#include <pulse/i18n.h>
#include <pulsecore/macro.h>
@ -50,7 +51,7 @@ static void once_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata)
m->defer_free(e);
}
static void free_callback(pa_mainloop_api *m, PA_GCC_UNUSED pa_defer_event *e, void *userdata) {
static void free_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
struct once_info *i = userdata;
pa_assert(m);
@ -65,6 +66,8 @@ void pa_mainloop_api_once(pa_mainloop_api* m, void (*callback)(pa_mainloop_api *
pa_assert(m);
pa_assert(callback);
pa_init_i18n();
i = pa_xnew(struct once_info, 1);
i->callback = callback;
i->userdata = userdata;

View file

@ -38,6 +38,7 @@
#include <pulse/xmalloc.h>
#include <pulse/gccmacro.h>
#include <pulse/i18n.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core-util.h>
@ -89,7 +90,7 @@ static void dispatch(pa_mainloop_api*a, int sig) {
}
}
static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, PA_GCC_UNUSED void *userdata) {
static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, void *userdata) {
ssize_t r;
int sig;
@ -165,6 +166,8 @@ pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t _callback, void *userdata
pa_assert(sig > 0);
pa_assert(_callback);
pa_init_i18n();
for (e = signals; e; e = e->next)
if (e->sig == sig)
goto fail;

View file

@ -44,6 +44,7 @@
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulsecore/core-util.h>
#include <pulsecore/llist.h>
@ -56,7 +57,7 @@
struct pa_io_event {
pa_mainloop *mainloop;
int dead;
pa_bool_t dead:1;
int fd;
pa_io_event_flags_t events;
@ -71,9 +72,9 @@ struct pa_io_event {
struct pa_time_event {
pa_mainloop *mainloop;
int dead;
pa_bool_t dead:1;
int enabled;
pa_bool_t enabled:1;
struct timeval timeval;
pa_time_event_cb_t callback;
@ -85,9 +86,9 @@ struct pa_time_event {
struct pa_defer_event {
pa_mainloop *mainloop;
int dead;
pa_bool_t dead:1;
int enabled;
pa_bool_t enabled:1;
pa_defer_event_cb_t callback;
void *userdata;
@ -101,22 +102,24 @@ struct pa_mainloop {
PA_LLIST_HEAD(pa_time_event, time_events);
PA_LLIST_HEAD(pa_defer_event, defer_events);
int n_enabled_defer_events, n_enabled_time_events, n_io_events;
int io_events_please_scan, time_events_please_scan, defer_events_please_scan;
unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
pa_bool_t rebuild_pollfds:1;
struct pollfd *pollfds;
unsigned max_pollfds, n_pollfds;
int rebuild_pollfds;
int prepared_timeout;
pa_time_event *cached_next_time_event;
int quit, retval;
pa_mainloop_api api;
int retval;
pa_bool_t quit:1;
pa_bool_t wakeup_requested:1;
int wakeup_pipe[2];
int wakeup_pipe_type;
int wakeup_requested;
enum {
STATE_PASSIVE,
@ -132,11 +135,11 @@ struct pa_mainloop {
};
static short map_flags_to_libc(pa_io_event_flags_t flags) {
return
(flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
(flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
(flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
(flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0);
return (short)
((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
(flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
(flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
(flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0));
}
static pa_io_event_flags_t map_flags_from_libc(short flags) {
@ -168,7 +171,7 @@ static pa_io_event* mainloop_io_new(
e = pa_xnew(pa_io_event, 1);
e->mainloop = m;
e->dead = 0;
e->dead = FALSE;
e->fd = fd;
e->events = events;
@ -193,13 +196,13 @@ static pa_io_event* mainloop_io_new(
SELECT_TYPE_ARG5 &tv) == -1) &&
(WSAGetLastError() == WSAENOTSOCK)) {
pa_log_warn("Cannot monitor non-socket file descriptors.");
e->dead = 1;
e->dead = TRUE;
}
}
#endif
PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
m->rebuild_pollfds = 1;
m->rebuild_pollfds = TRUE;
m->n_io_events ++;
pa_mainloop_wakeup(m);
@ -219,7 +222,7 @@ static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
if (e->pollfd)
e->pollfd->events = map_flags_to_libc(events);
else
e->mainloop->rebuild_pollfds = 1;
e->mainloop->rebuild_pollfds = TRUE;
pa_mainloop_wakeup(e->mainloop);
}
@ -228,11 +231,11 @@ static void mainloop_io_free(pa_io_event *e) {
pa_assert(e);
pa_assert(!e->dead);
e->dead = 1;
e->dead = TRUE;
e->mainloop->io_events_please_scan ++;
e->mainloop->n_io_events --;
e->mainloop->rebuild_pollfds = 1;
e->mainloop->rebuild_pollfds = TRUE;
pa_mainloop_wakeup(e->mainloop);
}
@ -261,9 +264,9 @@ static pa_defer_event* mainloop_defer_new(
e = pa_xnew(pa_defer_event, 1);
e->mainloop = m;
e->dead = 0;
e->dead = FALSE;
e->enabled = 1;
e->enabled = TRUE;
m->n_enabled_defer_events++;
e->callback = callback;
@ -296,13 +299,13 @@ static void mainloop_defer_free(pa_defer_event *e) {
pa_assert(e);
pa_assert(!e->dead);
e->dead = 1;
e->dead = TRUE;
e->mainloop->defer_events_please_scan ++;
if (e->enabled) {
pa_assert(e->mainloop->n_enabled_defer_events > 0);
e->mainloop->n_enabled_defer_events--;
e->enabled = 0;
e->enabled = FALSE;
}
}
@ -332,7 +335,7 @@ static pa_time_event* mainloop_time_new(
e = pa_xnew(pa_time_event, 1);
e->mainloop = m;
e->dead = 0;
e->dead = FALSE;
if ((e->enabled = !!tv)) {
e->timeval = *tv;
@ -387,13 +390,13 @@ static void mainloop_time_free(pa_time_event *e) {
pa_assert(e);
pa_assert(!e->dead);
e->dead = 1;
e->dead = TRUE;
e->mainloop->time_events_please_scan ++;
if (e->enabled) {
pa_assert(e->mainloop->n_enabled_time_events > 0);
e->mainloop->n_enabled_time_events--;
e->enabled = 0;
e->enabled = FALSE;
}
if (e->mainloop->cached_next_time_event == e)
@ -446,6 +449,8 @@ static const pa_mainloop_api vtable = {
pa_mainloop *pa_mainloop_new(void) {
pa_mainloop *m;
pa_init_i18n();
m = pa_xnew(pa_mainloop, 1);
m->wakeup_pipe_type = 0;
@ -459,7 +464,7 @@ pa_mainloop *pa_mainloop_new(void) {
pa_make_fd_nonblock(m->wakeup_pipe[1]);
pa_make_fd_cloexec(m->wakeup_pipe[0]);
pa_make_fd_cloexec(m->wakeup_pipe[1]);
m->wakeup_requested = 0;
m->wakeup_requested = FALSE;
PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
@ -473,9 +478,10 @@ pa_mainloop *pa_mainloop_new(void) {
m->pollfds = NULL;
m->max_pollfds = m->n_pollfds = 0;
m->rebuild_pollfds = 1;
m->rebuild_pollfds = TRUE;
m->quit = m->retval = 0;
m->quit = FALSE;
m->retval = 0;
m->api = vtable;
m->api.userdata = m;
@ -489,7 +495,7 @@ pa_mainloop *pa_mainloop_new(void) {
return m;
}
static void cleanup_io_events(pa_mainloop *m, int force) {
static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
pa_io_event *e;
e = m->io_events;
@ -512,7 +518,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) {
pa_xfree(e);
m->rebuild_pollfds = 1;
m->rebuild_pollfds = TRUE;
}
e = n;
@ -521,7 +527,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) {
pa_assert(m->io_events_please_scan == 0);
}
static void cleanup_time_events(pa_mainloop *m, int force) {
static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
pa_time_event *e;
e = m->time_events;
@ -542,7 +548,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) {
if (!e->dead && e->enabled) {
pa_assert(m->n_enabled_time_events > 0);
m->n_enabled_time_events--;
e->enabled = 0;
e->enabled = FALSE;
}
if (e->destroy_callback)
@ -557,7 +563,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) {
pa_assert(m->time_events_please_scan == 0);
}
static void cleanup_defer_events(pa_mainloop *m, int force) {
static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
pa_defer_event *e;
e = m->defer_events;
@ -578,7 +584,7 @@ static void cleanup_defer_events(pa_mainloop *m, int force) {
if (!e->dead && e->enabled) {
pa_assert(m->n_enabled_defer_events > 0);
m->n_enabled_defer_events--;
e->enabled = 0;
e->enabled = FALSE;
}
if (e->destroy_callback)
@ -597,9 +603,9 @@ static void cleanup_defer_events(pa_mainloop *m, int force) {
void pa_mainloop_free(pa_mainloop* m) {
pa_assert(m);
cleanup_io_events(m, 1);
cleanup_defer_events(m, 1);
cleanup_time_events(m, 1);
cleanup_io_events(m, TRUE);
cleanup_defer_events(m, TRUE);
cleanup_time_events(m, TRUE);
pa_xfree(m->pollfds);
@ -612,13 +618,13 @@ static void scan_dead(pa_mainloop *m) {
pa_assert(m);
if (m->io_events_please_scan)
cleanup_io_events(m, 0);
cleanup_io_events(m, FALSE);
if (m->time_events_please_scan)
cleanup_time_events(m, 0);
cleanup_time_events(m, FALSE);
if (m->defer_events_please_scan)
cleanup_defer_events(m, 0);
cleanup_defer_events(m, FALSE);
}
static void rebuild_pollfds(pa_mainloop *m) {
@ -659,7 +665,7 @@ static void rebuild_pollfds(pa_mainloop *m) {
m->n_pollfds++;
}
m->rebuild_pollfds = 0;
m->rebuild_pollfds = FALSE;
}
static int dispatch_pollfds(pa_mainloop *m) {
@ -945,7 +951,7 @@ int pa_mainloop_run(pa_mainloop *m, int *retval) {
void pa_mainloop_quit(pa_mainloop *m, int retval) {
pa_assert(m);
m->quit = 1;
m->quit = TRUE;
m->retval = retval;
pa_mainloop_wakeup(m);
}

View file

@ -27,6 +27,7 @@
#include <pulse/xmalloc.h>
#include <pulse/utf8.h>
#include <pulse/i18n.h>
#include <pulsecore/hashmap.h>
#include <pulsecore/strbuf.h>
@ -63,6 +64,8 @@ static void property_free(struct property *prop) {
}
pa_proplist* pa_proplist_new(void) {
pa_init_i18n();
return MAKE_PROPLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func));
}
@ -277,7 +280,7 @@ char *pa_proplist_to_string(pa_proplist *p) {
char *c;
pa_assert_se(pa_proplist_get(p, key, &value, &nbytes) == 0);
c = pa_xnew(char, nbytes*2+1);
c = pa_xmalloc(nbytes*2+1);
pa_hexstr((const uint8_t*) value, nbytes, c, nbytes*2+1);
pa_strbuf_printf(buf, "%s = hex:%s\n", key, c);

View file

@ -28,9 +28,11 @@
#include <math.h>
#include <string.h>
#include <pulse/timeval.h>
#include <pulse/i18n.h>
#include <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include <pulse/timeval.h>
#include "sample.h"
@ -126,8 +128,10 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
pa_assert(l);
pa_assert(spec);
pa_init_i18n();
if (!pa_sample_spec_valid(spec))
pa_snprintf(s, l, "Invalid");
pa_snprintf(s, l, _("Invalid"));
else
pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate);

View file

@ -47,6 +47,7 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) {
PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY(s->context, length > 0, PA_ERR_INVALID);
PA_CHECK_VALIDITY(s->context, length == (size_t) (uint32_t) length, PA_ERR_INVALID);
if (!(name = pa_proplist_gets(s->proplist, PA_PROP_EVENT_ID)))
name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME);
@ -63,7 +64,7 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) {
pa_tagstruct_puts(t, name);
pa_tagstruct_put_sample_spec(t, &s->sample_spec);
pa_tagstruct_put_channel_map(t, &s->channel_map);
pa_tagstruct_putu32(t, length);
pa_tagstruct_putu32(t, (uint32_t) length);
if (s->context->version >= 13) {
pa_init_proplist(s->proplist);

View file

@ -453,4 +453,3 @@ unlock_and_fail:
pa_threaded_mainloop_unlock(p->mainloop);
return (pa_usec_t) -1;
}

View file

@ -124,7 +124,7 @@ pa_stream *pa_stream_new_with_proplist(
* what older PA versions provided. */
s->buffer_attr.maxlength = (uint32_t) -1;
s->buffer_attr.tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
s->buffer_attr.minreq = (uint32_t) -1;
s->buffer_attr.prebuf = (uint32_t) -1;
s->buffer_attr.fragsize = (uint32_t) -1;
@ -315,7 +315,7 @@ static void request_auto_timing_update(pa_stream *s, pa_bool_t force) {
}
}
void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
uint32_t channel;
@ -382,7 +382,7 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t
* if prebuf is non-zero! */
}
void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
uint32_t channel;
@ -479,7 +479,7 @@ finish:
pa_context_unref(c);
}
void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
uint32_t channel;
@ -563,7 +563,7 @@ finish:
pa_context_unref(c);
}
void pa_command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s;
pa_context *c = userdata;
uint32_t bytes, channel;
@ -598,7 +598,7 @@ finish:
pa_context_unref(c);
}
void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s;
pa_context *c = userdata;
uint32_t channel;
@ -670,7 +670,7 @@ static void invalidate_indexes(pa_stream *s, pa_bool_t r, pa_bool_t w) {
request_auto_timing_update(s, TRUE);
}
static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC_UNUSED pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
static void auto_timing_update_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) {
pa_stream *s = userdata;
pa_assert(s);
@ -694,7 +694,7 @@ static void create_stream_complete(pa_stream *s) {
if (s->flags & PA_STREAM_AUTO_TIMING_UPDATE) {
struct timeval tv;
pa_gettimeofday(&tv);
tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
tv.tv_usec += (suseconds_t) LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
pa_assert(!s->auto_timing_update_event);
s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s);
@ -722,7 +722,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
attr->maxlength = 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
if (attr->tlength == (uint32_t) -1)
attr->tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
attr->tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
if (attr->minreq == (uint32_t) -1)
attr->minreq = (attr->tlength)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
@ -734,7 +734,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
attr->fragsize = attr->tlength; /* Pass data to the app only when the buffer is filled up once */
}
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s = userdata;
pa_assert(pd);
@ -865,6 +865,7 @@ static int create_stream(
pa_tagstruct *t;
uint32_t tag;
pa_bool_t volume_set = FALSE;
pa_assert(s);
pa_assert(PA_REFCNT_VALUE(s) >= 1);
@ -930,7 +931,7 @@ static int create_stream(
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CREATE_PLAYBACK_STREAM : PA_COMMAND_CREATE_RECORD_STREAM,
(uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CREATE_PLAYBACK_STREAM : PA_COMMAND_CREATE_RECORD_STREAM),
&tag);
if (s->context->version < 13)
@ -957,6 +958,8 @@ static int create_stream(
PA_TAG_U32, s->syncid,
PA_TAG_INVALID);
volume_set = !!volume;
if (!volume)
volume = pa_cvolume_reset(&cv, s->sample_spec.channels);
@ -994,6 +997,15 @@ static int create_stream(
pa_tagstruct_putu32(t, s->direct_on_input);
}
if (s->context->version >= 14 &&
s->direction == PA_STREAM_PLAYBACK) {
pa_tagstruct_put(
t,
PA_TAG_BOOLEAN, volume_set,
PA_TAG_INVALID);
}
pa_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL);
@ -1093,7 +1105,7 @@ int pa_stream_write(
free_cb((void*) data);
if (length < s->requested_bytes)
s->requested_bytes -= length;
s->requested_bytes -= (uint32_t) length;
else
s->requested_bytes = 0;
@ -1107,10 +1119,10 @@ int pa_stream_write(
if (seek == PA_SEEK_ABSOLUTE) {
s->write_index_corrections[s->current_write_index_correction].corrupt = FALSE;
s->write_index_corrections[s->current_write_index_correction].absolute = TRUE;
s->write_index_corrections[s->current_write_index_correction].value = offset + length;
s->write_index_corrections[s->current_write_index_correction].value = offset + (int64_t) length;
} else if (seek == PA_SEEK_RELATIVE) {
if (!s->write_index_corrections[s->current_write_index_correction].corrupt)
s->write_index_corrections[s->current_write_index_correction].value += offset + length;
s->write_index_corrections[s->current_write_index_correction].value += offset + (int64_t) length;
} else
s->write_index_corrections[s->current_write_index_correction].corrupt = TRUE;
}
@ -1120,10 +1132,10 @@ int pa_stream_write(
if (seek == PA_SEEK_ABSOLUTE) {
s->timing_info.write_index_corrupt = FALSE;
s->timing_info.write_index = offset + length;
s->timing_info.write_index = offset + (int64_t) length;
} else if (seek == PA_SEEK_RELATIVE) {
if (!s->timing_info.write_index_corrupt)
s->timing_info.write_index += offset + length;
s->timing_info.write_index += offset + (int64_t) length;
} else
s->timing_info.write_index_corrupt = TRUE;
}
@ -1173,7 +1185,7 @@ int pa_stream_drop(pa_stream *s) {
/* Fix the simulated local read index */
if (s->timing_info_valid && !s->timing_info.read_index_corrupt)
s->timing_info.read_index += s->peek_memchunk.length;
s->timing_info.read_index += (int64_t) s->peek_memchunk.length;
pa_assert(s->peek_data);
pa_memblock_release(s->peek_memchunk.memblock);
@ -1257,7 +1269,9 @@ static pa_usec_t calc_time(pa_stream *s, pa_bool_t ignore_transport) {
usec -= s->timing_info.sink_usec;
}
} else if (s->direction == PA_STREAM_RECORD) {
} else {
pa_assert(s->direction == PA_STREAM_RECORD);
/* The last byte written into the server side queue had
* this time value associated */
usec = pa_bytes_to_usec(s->timing_info.write_index < 0 ? 0 : (uint64_t) s->timing_info.write_index, &s->sample_spec);
@ -1340,7 +1354,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
i->read_index_corrupt = FALSE;
i->playing = (int) playing;
i->since_underrun = playing ? playing_for : underrun_for;
i->since_underrun = (int64_t) (playing ? playing_for : underrun_for);
pa_gettimeofday(&now);
@ -1418,7 +1432,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
/* Read index correction */
if (!i->read_index_corrupt)
i->read_index -= pa_memblockq_get_length(o->stream->record_memblockq);
i->read_index -= (int64_t) pa_memblockq_get_length(o->stream->record_memblockq);
}
/* Update smoother */
@ -1435,7 +1449,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
* speakers. Since we follow that timing here, we need
* to try to fix this up */
su = pa_bytes_to_usec(i->since_underrun, &o->stream->sample_spec);
su = pa_bytes_to_usec((uint64_t) i->since_underrun, &o->stream->sample_spec);
if (su < i->sink_usec)
x += i->sink_usec - su;
@ -1494,7 +1508,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY,
(uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_put_timeval(t, pa_gettimeofday(&now));
@ -1517,7 +1531,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t
return o;
}
void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s = userdata;
pa_assert(pd);
@ -1557,8 +1571,8 @@ int pa_stream_disconnect(pa_stream *s) {
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_DELETE_PLAYBACK_STREAM :
(s->direction == PA_STREAM_RECORD ? PA_COMMAND_DELETE_RECORD_STREAM : PA_COMMAND_DELETE_UPLOAD_STREAM),
(uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_DELETE_PLAYBACK_STREAM :
(s->direction == PA_STREAM_RECORD ? PA_COMMAND_DELETE_RECORD_STREAM : PA_COMMAND_DELETE_UPLOAD_STREAM)),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_pstream_send_tagstruct(s->context->pstream, t);
@ -1667,7 +1681,7 @@ void pa_stream_set_started_callback(pa_stream *s, pa_stream_notify_cb_t cb, void
s->started_userdata = userdata;
}
void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@ -1715,7 +1729,7 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM,
(uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_put_boolean(t, !!b);
@ -1760,7 +1774,7 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE);
if (!(o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata)))
if (!(o = stream_send_simple_command(s, (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM), cb, userdata)))
return NULL;
if (s->direction == PA_STREAM_PLAYBACK) {
@ -1846,7 +1860,7 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe
o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME,
(uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_puts(t, name);
@ -1932,7 +1946,7 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) {
if (cindex < 0)
cindex = 0;
c = pa_bytes_to_usec(cindex, &s->sample_spec);
c = pa_bytes_to_usec((uint64_t) cindex, &s->sample_spec);
if (s->direction == PA_STREAM_PLAYBACK)
*r_usec = time_counter_diff(s, c, t, negative);
@ -1978,7 +1992,7 @@ const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) {
return &s->buffer_attr;
}
static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@ -2046,7 +2060,7 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR : PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
(uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR : PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR),
&tag);
pa_tagstruct_putu32(t, s->channel);
@ -2120,7 +2134,7 @@ int pa_stream_is_corked(pa_stream *s) {
return s->corked;
}
static void stream_update_sample_rate_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
static void stream_update_sample_rate_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@ -2177,7 +2191,7 @@ pa_operation *pa_stream_update_sample_rate(pa_stream *s, uint32_t rate, pa_strea
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE : PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE,
(uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE : PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_putu32(t, rate);
@ -2205,7 +2219,7 @@ pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST : PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST,
(uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST : PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_putu32(t, (uint32_t) mode);
@ -2238,7 +2252,7 @@ pa_operation *pa_stream_proplist_remove(pa_stream *s, const char *const keys[],
t = pa_tagstruct_command(
s->context,
s->direction == PA_STREAM_RECORD ? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST : PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST,
(uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST : PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST),
&tag);
pa_tagstruct_putu32(t, s->channel);

View file

@ -34,7 +34,7 @@
#include "subscribe.h"
void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_subscription_event_type_t e;
uint32_t idx;
@ -61,7 +61,6 @@ finish:
pa_context_unref(c);
}
pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata) {
pa_operation *o;
pa_tagstruct *t;

View file

@ -35,6 +35,7 @@
#include <pulse/xmalloc.h>
#include <pulse/mainloop.h>
#include <pulse/i18n.h>
#include <pulsecore/log.h>
#include <pulsecore/hashmap.h>
@ -94,6 +95,8 @@ static void thread(void *userdata) {
pa_threaded_mainloop *pa_threaded_mainloop_new(void) {
pa_threaded_mainloop *m;
pa_init_i18n();
m = pa_xnew(pa_threaded_mainloop, 1);
if (!(m->real_mainloop = pa_mainloop_new())) {

View file

@ -90,13 +90,13 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) {
}
/* Calculate the second difference*/
r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC;
r = ((pa_usec_t) a->tv_sec - (pa_usec_t) b->tv_sec) * PA_USEC_PER_SEC;
/* Calculate the microsecond difference */
if (a->tv_usec > b->tv_usec)
r += ((pa_usec_t) a->tv_usec - b->tv_usec);
r += ((pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec);
else if (a->tv_usec < b->tv_usec)
r -= ((pa_usec_t) b->tv_usec - a->tv_usec);
r -= ((pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec);
return r;
}
@ -132,7 +132,7 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) {
pa_assert(tv);
secs = (unsigned long) (v/PA_USEC_PER_SEC);
tv->tv_sec += secs;
tv->tv_sec += (time_t) secs;
v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC;
tv->tv_usec += (suseconds_t) v;
@ -140,7 +140,7 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) {
/* Normalize */
while ((unsigned) tv->tv_usec >= PA_USEC_PER_SEC) {
tv->tv_sec++;
tv->tv_usec -= PA_USEC_PER_SEC;
tv->tv_usec -= (suseconds_t) PA_USEC_PER_SEC;
}
return tv;
@ -151,14 +151,14 @@ struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) {
pa_assert(tv);
secs = (unsigned long) (v/PA_USEC_PER_SEC);
tv->tv_sec -= secs;
tv->tv_sec -= (time_t) secs;
v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC;
if (tv->tv_usec >= (suseconds_t) v)
tv->tv_usec -= (suseconds_t) v;
else {
tv->tv_sec --;
tv->tv_usec = tv->tv_usec + PA_USEC_PER_SEC - v;
tv->tv_usec += (suseconds_t) (PA_USEC_PER_SEC - v);
}
return tv;
@ -167,8 +167,8 @@ struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) {
struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) {
pa_assert(tv);
tv->tv_sec = v / PA_USEC_PER_SEC;
tv->tv_usec = v % PA_USEC_PER_SEC;
tv->tv_sec = (time_t) (v / PA_USEC_PER_SEC);
tv->tv_usec = (suseconds_t) (v % PA_USEC_PER_SEC);
return tv;
}

View file

@ -109,17 +109,17 @@ static char* utf8_validate(const char *str, char *output) {
if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
size = 2;
min = 128;
val = *p & 0x1e;
val = (uint32_t) (*p & 0x1e);
goto ONE_REMAINING;
} else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
size = 3;
min = (1 << 11);
val = *p & 0x0f;
val = (uint32_t) (*p & 0x0f);
goto TWO_REMAINING;
} else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
size = 4;
min = (1 << 16);
val = *p & 0x07;
val = (uint32_t) (*p & 0x07);
} else {
size = 1;
goto error;
@ -149,7 +149,7 @@ ONE_REMAINING:
goto error;
if (o) {
memcpy(o, last, size);
memcpy(o, last, (size_t) size);
o += size - 1;
}
@ -189,7 +189,7 @@ char* pa_utf8_filter (const char *str) {
char *new_str;
pa_assert(str);
new_str = pa_xnew(char, strlen(str) + 1);
new_str = pa_xmalloc(strlen(str) + 1);
return utf8_validate(str, new_str);
}
@ -212,7 +212,7 @@ static char* iconv_simple(const char *str, const char *to, const char *from) {
return NULL;
inlen = len = strlen(str) + 1;
new_str = pa_xnew(char, len);
new_str = pa_xmalloc(len);
for (;;) {
inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */

View file

@ -95,12 +95,15 @@ char *pa_get_user_name(char *s, size_t l) {
#elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
DWORD size = sizeof(buf);
if (!GetUserName(buf, &size))
if (!GetUserName(buf, &size)) {
errno = ENOENT;
return NULL;
}
p = buf;
#else /* HAVE_PWD_H */
return NULL;
#endif /* HAVE_PWD_H */
}
@ -113,10 +116,8 @@ char *pa_get_host_name(char *s, size_t l) {
pa_assert(s);
pa_assert(l > 0);
if (gethostname(s, l) < 0) {
pa_log("gethostname(): %s", pa_cstrerror(errno));
if (gethostname(s, l) < 0)
return NULL;
}
s[l-1] = 0;
return s;
@ -140,20 +141,25 @@ char *pa_get_home_dir(char *s, size_t l) {
return pa_strlcpy(s, e, l);
#ifdef HAVE_PWD_H
errno = 0;
#ifdef HAVE_GETPWUID_R
if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
pa_log("getpwuid_r() failed");
#else
/* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
* that do not support getpwuid_r. */
if ((r = getpwuid(getuid())) == NULL) {
pa_log("getpwuid_r() failed");
#endif
if (!errno)
errno = ENOENT;
return NULL;
}
return pa_strlcpy(s, r->pw_dir, l);
#else /* HAVE_PWD_H */
errno = ENOENT;
return NULL;
#endif
}
@ -204,6 +210,7 @@ char *pa_get_binary_name(char *s, size_t l) {
}
#endif
errno = ENOENT;
return NULL;
}
@ -253,8 +260,8 @@ int pa_msleep(unsigned long t) {
#elif defined(HAVE_NANOSLEEP)
struct timespec ts;
ts.tv_sec = t/1000;
ts.tv_nsec = (t % 1000) * 1000000;
ts.tv_sec = (time_t) (t/1000UL);
ts.tv_nsec = (long) ((t % 1000UL) * 1000000UL);
return nanosleep(&ts, NULL);
#else

View file

@ -53,7 +53,7 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
a->channels = channels;
a->channels = (uint8_t) channels;
for (i = 0; i < a->channels; i++)
a->values[i] = v;
@ -74,6 +74,18 @@ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
return (pa_volume_t) sum;
}
pa_volume_t pa_cvolume_max(const pa_cvolume *a) {
pa_volume_t m = 0;
int i;
pa_assert(a);
for (i = 0; i < a->channels; i++)
if (a->values[i] > m)
m = a->values[i];
return m;
}
pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a)* pa_sw_volume_to_linear(b));
}
@ -163,7 +175,7 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
i < b->channels ? b->values[i] : PA_VOLUME_NORM);
}
dest->channels = i;
dest->channels = (uint8_t) i;
return dest;
}
@ -176,3 +188,88 @@ int pa_cvolume_valid(const pa_cvolume *v) {
return 1;
}
static pa_bool_t on_left(pa_channel_position_t p) {
return
p == PA_CHANNEL_POSITION_FRONT_LEFT ||
p == PA_CHANNEL_POSITION_REAR_LEFT ||
p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
p == PA_CHANNEL_POSITION_SIDE_LEFT ||
p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
}
static pa_bool_t on_right(pa_channel_position_t p) {
return
p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
p == PA_CHANNEL_POSITION_REAR_RIGHT ||
p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ||
p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
}
static pa_bool_t on_center(pa_channel_position_t p) {
return
p == PA_CHANNEL_POSITION_FRONT_CENTER ||
p == PA_CHANNEL_POSITION_REAR_CENTER ||
p == PA_CHANNEL_POSITION_TOP_CENTER ||
p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
}
static pa_bool_t on_lfe(pa_channel_position_t p) {
return
p == PA_CHANNEL_POSITION_LFE;
}
pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to) {
int a, b;
pa_cvolume result;
pa_assert(v);
pa_assert(from);
pa_assert(to);
pa_assert(v->channels == from->channels);
if (pa_channel_map_equal(from, to))
return v;
result.channels = to->channels;
for (b = 0; b < to->channels; b++) {
pa_volume_t k = 0;
int n = 0;
for (a = 0; a < from->channels; a++)
if (from->map[a] == to->map[b]) {
k += v->values[a];
n ++;
}
if (n <= 0) {
for (a = 0; a < from->channels; a++)
if ((on_left(from->map[a]) && on_left(to->map[b])) ||
(on_right(from->map[a]) && on_right(to->map[b])) ||
(on_center(from->map[a]) && on_center(to->map[b])) ||
(on_lfe(from->map[a]) && on_lfe(to->map[b]))) {
k += v->values[a];
n ++;
}
}
if (n <= 0)
k = pa_cvolume_avg(v);
else
k /= n;
result.values[b] = k;
}
*v = result;
return v;
}

View file

@ -28,6 +28,7 @@
#include <pulse/cdecl.h>
#include <pulse/gccmacro.h>
#include <pulse/sample.h>
#include <pulse/channelmap.h>
/** \page volume Volume Control
*
@ -133,6 +134,9 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c);
/** Return the average volume of all channels */
pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE;
/** Return the maximum volume of all channels. \since 0.9.12 */
pa_volume_t pa_cvolume_max(const pa_cvolume *a) PA_GCC_PURE;
/** Return TRUE when the passed cvolume structure is valid, FALSE otherwise */
int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE;
@ -170,6 +174,9 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
#define PA_DECIBEL_MININFTY ((double) -200.0)
#endif
/** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */
pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to);
PA_C_DECL_END
#endif

View file

@ -113,7 +113,7 @@ char *pa_xstrndup(const char *s, size_t l) {
return NULL;
if ((e = memchr(s, 0, l)))
return pa_xmemdup(s, e-s+1);
return pa_xmemdup(s, (size_t) (e-s+1));
r = pa_xmalloc(l+1);
memcpy(r, s, l);

View file

@ -71,7 +71,7 @@ PA_STATIC_FLIST_DECLARE(localq, 0, pa_xfree);
#define PA_ASYNCQ_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_asyncq))))
static int reduce(pa_asyncq *l, int value) {
static unsigned reduce(pa_asyncq *l, unsigned value) {
return value & (unsigned) (l->size - 1);
}
@ -132,7 +132,7 @@ void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) {
}
static int push(pa_asyncq*l, void *p, pa_bool_t wait) {
int idx;
unsigned idx;
pa_atomic_ptr_t *cells;
pa_assert(l);
@ -220,7 +220,7 @@ void pa_asyncq_post(pa_asyncq*l, void *p) {
}
void* pa_asyncq_pop(pa_asyncq*l, pa_bool_t wait) {
int idx;
unsigned idx;
void *ret;
pa_atomic_ptr_t *cells;
@ -263,7 +263,7 @@ int pa_asyncq_read_fd(pa_asyncq *q) {
}
int pa_asyncq_read_before_poll(pa_asyncq *l) {
int idx;
unsigned idx;
pa_atomic_ptr_t *cells;
pa_assert(l);
@ -280,8 +280,6 @@ int pa_asyncq_read_before_poll(pa_asyncq *l) {
if (pa_fdsem_before_poll(l->write_fdsem) >= 0)
return 0;
}
return 0;
}
void pa_asyncq_read_after_poll(pa_asyncq *l) {

View file

@ -420,7 +420,7 @@ typedef struct pa_atomic {
volatile AO_t value;
} pa_atomic_t;
#define PA_ATOMIC_INIT(v) { .value = (v) }
#define PA_ATOMIC_INIT(v) { .value = (AO_t) (v) }
static inline int pa_atomic_load(const pa_atomic_t *a) {
return (int) AO_load_full((AO_t*) &a->value);
@ -431,23 +431,23 @@ static inline void pa_atomic_store(pa_atomic_t *a, int i) {
}
static inline int pa_atomic_add(pa_atomic_t *a, int i) {
return AO_fetch_and_add_full(&a->value, (AO_t) i);
return (int) AO_fetch_and_add_full(&a->value, (AO_t) i);
}
static inline int pa_atomic_sub(pa_atomic_t *a, int i) {
return AO_fetch_and_add_full(&a->value, (AO_t) -i);
return (int) AO_fetch_and_add_full(&a->value, (AO_t) -i);
}
static inline int pa_atomic_inc(pa_atomic_t *a) {
return AO_fetch_and_add1_full(&a->value);
return (int) AO_fetch_and_add1_full(&a->value);
}
static inline int pa_atomic_dec(pa_atomic_t *a) {
return AO_fetch_and_sub1_full(&a->value);
return (int) AO_fetch_and_sub1_full(&a->value);
}
static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
return AO_compare_and_swap_full(&a->value, old_i, new_i);
return AO_compare_and_swap_full(&a->value, (unsigned long) old_i, (unsigned long) new_i);
}
typedef struct pa_atomic_ptr {

View file

@ -1,104 +0,0 @@
/***
This file is part of PulseAudio.
Copyright 2004-2006 Lennart Poettering
PulseAudio 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 of the License,
or (at your option) any later version.
PulseAudio 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
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <pulse/xmalloc.h>
#include <pulsecore/shared.h>
#include <pulsecore/macro.h>
#include <pulsecore/log.h>
#include <pulsecore/refcnt.h>
#include "authkey-prop.h"
struct authkey_data {
PA_REFCNT_DECLARE;
size_t length;
};
int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len) {
struct authkey_data *a;
pa_assert(c);
pa_assert(name);
pa_assert(data);
pa_assert(len > 0);
if (!(a = pa_shared_get(c, name)))
return -1;
pa_assert(a->length == len);
memcpy(data, (uint8_t*) a + PA_ALIGN(sizeof(struct authkey_data)), len);
return 0;
}
int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len) {
struct authkey_data *a;
pa_assert(c);
pa_assert(name);
if (pa_shared_get(c, name))
return -1;
a = pa_xmalloc(PA_ALIGN(sizeof(struct authkey_data)) + len);
PA_REFCNT_INIT(a);
a->length = len;
memcpy((uint8_t*) a + PA_ALIGN(sizeof(struct authkey_data)), data, len);
pa_shared_set(c, name, a);
return 0;
}
void pa_authkey_prop_ref(pa_core *c, const char *name) {
struct authkey_data *a;
pa_assert(c);
pa_assert(name);
a = pa_shared_get(c, name);
pa_assert(a);
pa_assert(PA_REFCNT_VALUE(a) >= 1);
PA_REFCNT_INC(a);
}
void pa_authkey_prop_unref(pa_core *c, const char *name) {
struct authkey_data *a;
pa_assert(c);
pa_assert(name);
a = pa_shared_get(c, name);
pa_assert(a);
pa_assert(PA_REFCNT_VALUE(a) >= 1);
if (PA_REFCNT_DEC(a) <= 0) {
pa_shared_remove(c, name);
pa_xfree(a);
}
}

View file

@ -1,43 +0,0 @@
#ifndef fooauthkeyprophfoo
#define fooauthkeyprophfoo
/***
This file is part of PulseAudio.
Copyright 2004-2006 Lennart Poettering
PulseAudio 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 of the License,
or (at your option) any later version.
PulseAudio 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
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#include <pulsecore/core.h>
/* The authkey-prop uses a central property to store a previously
* loaded cookie in memory. Useful for sharing the same cookie between
* several modules. */
/* Return the data of the specified authorization key property. Doesn't alter the refernce count of the key */
int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len);
/* Store data in the specified authorization key property. The initial reference count is set to 1 */
int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len);
/* Increase the reference count of the specified authorization key */
void pa_authkey_prop_ref(pa_core *c, const char *name);
/* Decrease the reference count of the specified authorization key */
void pa_authkey_prop_unref(pa_core *c, const char *name);
#endif

View file

@ -158,7 +158,7 @@ void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type) {
e->in_action = 0;
}
static void free_func(void *p, PA_GCC_UNUSED void *userdata) {
static void free_func(void *p, void *userdata) {
pa_autoload_entry *e = p;
pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL);
entry_free(e);

View file

@ -188,7 +188,9 @@ static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_assert(buf);
pa_assert(fail);
c->mainloop->quit(c->mainloop, 0);
if (pa_core_exit(c, FALSE, 0) < 0)
pa_strbuf_puts(buf, "Not allowed to terminate daemon.\n");
return 0;
}
@ -316,22 +318,22 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_allocated),
pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->allocated_size)));
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->allocated_size)));
pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_accumulated),
pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->accumulated_size)));
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->accumulated_size)));
pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_imported),
pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->imported_size)));
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->imported_size)));
pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_exported),
pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->exported_size)));
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->exported_size)));
pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
pa_bytes_snprint(s, sizeof(s), pa_scache_total_size(c)));
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_scache_total_size(c)));
pa_strbuf_printf(buf, "Default sample spec: %s\n",
pa_sample_spec_snprint(s, sizeof(s), &c->default_sample_spec));
@ -415,7 +417,7 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa
return -1;
}
pa_module_unload_request(m);
pa_module_unload_request(m, FALSE);
return 0;
}
@ -1249,8 +1251,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
nl = 1;
}
pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink)));
pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink)));
pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)));
pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE)));
pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
}
@ -1263,8 +1265,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
nl = 1;
}
pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source)));
pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source)));
pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, FALSE)));
pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE)));
pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
}

View file

@ -149,10 +149,12 @@ char *pa_sink_list_to_string(pa_core *c) {
sink->flags & PA_SINK_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "",
sink->flags & PA_SINK_LATENCY ? "LATENCY " : "",
state_table[pa_sink_get_state(sink)],
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)),
pa_yes_no(pa_sink_get_mute(sink)),
(double) pa_sink_get_latency(sink) / PA_USEC_PER_MSEC,
(double) pa_sink_get_requested_latency(sink) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC,
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, FALSE)),
pa_yes_no(pa_sink_get_mute(sink, FALSE)),
(double) pa_sink_get_latency(sink) / (double) PA_USEC_PER_MSEC,
(double) pa_sink_get_requested_latency(sink) / (double) PA_USEC_PER_MSEC,
(double) min_latency / PA_USEC_PER_MSEC,
(double) max_latency / PA_USEC_PER_MSEC,
(unsigned long) pa_sink_get_max_request(sink) / 1024,
(unsigned long) pa_sink_get_max_rewind(sink) / 1024,
sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX,
@ -222,10 +224,12 @@ char *pa_source_list_to_string(pa_core *c) {
source->flags & PA_SOURCE_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "",
source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
state_table[pa_source_get_state(source)],
pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)),
pa_yes_no(pa_source_get_mute(source)),
pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)),
pa_yes_no(pa_source_get_mute(source, FALSE)),
(double) pa_source_get_latency(source) / PA_USEC_PER_MSEC,
(double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC,
(double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC,
(double) min_latency / PA_USEC_PER_MSEC,
(double) max_latency / PA_USEC_PER_MSEC,
(unsigned long) pa_source_get_max_rewind(source) / 1024,
pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map),
@ -411,7 +415,7 @@ char *pa_scache_list_to_string(pa_core *c) {
if (e->memchunk.memblock) {
pa_sample_spec_snprint(ss, sizeof(ss), &e->sample_spec);
pa_channel_map_snprint(cm, sizeof(cm), &e->channel_map);
l = (double) e->memchunk.length / pa_bytes_per_second(&e->sample_spec);
l = (double) e->memchunk.length / (double) pa_bytes_per_second(&e->sample_spec);
}
pa_strbuf_printf(

View file

@ -58,7 +58,7 @@ pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) {
pa_log_info("Created %u \"%s\"", c->index, pa_strnull(name));
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index);
pa_core_check_quit(core);
pa_core_check_idle(core);
return c;
}
@ -78,7 +78,7 @@ void pa_client_free(pa_client *c) {
pa_xfree(c->driver);
pa_xfree(c);
pa_core_check_quit(core);
pa_core_check_idle(core);
}
void pa_client_kill(pa_client *c) {

View file

@ -148,7 +148,7 @@ finish:
return r;
}
int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
int *i = data;
int32_t k;
@ -166,7 +166,7 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue,
return 0;
}
int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
int k;
pa_bool_t *b = data;
@ -185,7 +185,7 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue
return 0;
}
int pa_config_parse_string(const char *filename, PA_GCC_UNUSED unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
char **s = data;
pa_assert(filename);

View file

@ -63,7 +63,7 @@
#define UNLOAD_POLL_TIME 60
static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) {
pa_core *c = userdata;
struct timeval ntv;
@ -282,7 +282,7 @@ int pa_scache_remove_item(pa_core *c, const char *name) {
return 0;
}
static void free_cb(void *p, PA_GCC_UNUSED void *userdata) {
static void free_cb(void *p, void *userdata) {
pa_scache_entry *e = p;
pa_assert(e);

View file

@ -42,7 +42,7 @@
struct pa_subscription {
pa_core *core;
int dead;
pa_bool_t dead;
pa_subscription_cb_t callback;
void *userdata;
@ -72,7 +72,7 @@ pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_su
s = pa_xnew(pa_subscription, 1);
s->core = c;
s->dead = 0;
s->dead = FALSE;
s->callback = callback;
s->userdata = userdata;
s->mask = m;
@ -86,7 +86,7 @@ void pa_subscription_free(pa_subscription*s) {
pa_assert(s);
pa_assert(!s->dead);
s->dead = 1;
s->dead = TRUE;
sched_event(s->core);
}
@ -145,7 +145,7 @@ static void dump_event(const char * prefix, pa_subscription_event*e) {
[PA_SUBSCRIPTION_EVENT_REMOVE] = "REMOVE"
};
pa_log("%s event (%s|%s|%u)",
pa_log_debug("%s event (%s|%s|%u)",
prefix,
fac_table[e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK],
type_table[e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK],
@ -234,7 +234,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
* entry in the queue. */
free_event(i);
pa_log_debug("dropped redundant event.");
pa_log_debug("Dropped redundant event due to remove event.");
continue;
}
@ -242,7 +242,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
/* This object has changed. If a "new" or "change" event for
* this object is still in the queue we can exit. */
pa_log_debug("dropped redundant event.");
pa_log_debug("Dropped redundant event due to change event.");
return;
}
}

View file

@ -40,6 +40,8 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <dirent.h>
#include <regex.h>
#include <langinfo.h>
#ifdef HAVE_STRTOF_L
#include <locale.h>
@ -111,6 +113,8 @@ int pa_set_root(HANDLE handle) {
strcpy(library_path, PULSE_ROOTENV "=");
/* FIXME: Needs to set errno */
if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH))
return 0;
@ -168,7 +172,7 @@ void pa_make_fd_cloexec(int fd) {
/** Creates a directory securely */
int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
struct stat st;
int r;
int r, saved_errno;
pa_assert(dir);
@ -220,7 +224,10 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
return 0;
fail:
saved_errno = errno;
rmdir(dir);
errno = saved_errno;
return -1;
}
@ -230,6 +237,7 @@ char *pa_parent_dir(const char *fn) {
if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
pa_xfree(dir);
errno = ENOENT;
return NULL;
}
@ -337,7 +345,7 @@ ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
ret += r;
data = (uint8_t*) data + r;
size -= r;
size -= (size_t) r;
}
return ret;
@ -368,7 +376,7 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
ret += r;
data = (const uint8_t*) data + r;
size -= r;
size -= (size_t) r;
}
return ret;
@ -437,7 +445,7 @@ void pa_check_signal_is_blocked(int sig) {
/* The following function is based on an example from the GNU libc
* documentation. This function is similar to GNU's asprintf(). */
char *pa_sprintf_malloc(const char *format, ...) {
int size = 100;
size_t size = 100;
char *c = NULL;
pa_assert(format);
@ -454,11 +462,11 @@ char *pa_sprintf_malloc(const char *format, ...) {
c[size-1] = 0;
if (r > -1 && r < size)
if (r > -1 && (size_t) r < size)
return c;
if (r > -1) /* glibc 2.1 */
size = r+1;
size = (size_t) r+1;
else /* glibc 2.0 */
size *= 2;
}
@ -467,7 +475,7 @@ char *pa_sprintf_malloc(const char *format, ...) {
/* Same as the previous function, but use a va_list instead of an
* ellipsis */
char *pa_vsprintf_malloc(const char *format, va_list ap) {
int size = 100;
size_t size = 100;
char *c = NULL;
pa_assert(format);
@ -484,11 +492,11 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) {
c[size-1] = 0;
if (r > -1 && r < size)
if (r > -1 && (size_t) r < size)
return c;
if (r > -1) /* glibc 2.1 */
size = r+1;
size = (size_t) r+1;
else /* glibc 2.0 */
size *= 2;
}
@ -546,6 +554,8 @@ int pa_make_realtime(int rtprio) {
pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
return 0;
#else
errno = ENOTSUP;
return -1;
#endif
}
@ -653,6 +663,7 @@ int pa_raise_priority(int nice_level) {
if (nice_level < 0) {
if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
errno = EPERM;
return .-1;
} else
pa_log_info("Successfully gained high priority class.");
@ -679,15 +690,55 @@ void pa_reset_priority(void) {
#endif
}
static int match(const char *expr, const char *v) {
int k;
regex_t re;
int r;
if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
errno = EINVAL;
return -1;
}
if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
r = 1;
else if (k == REG_NOMATCH)
r = 0;
else
r = -1;
regfree(&re);
if (r < 0)
errno = EINVAL;
return r;
}
/* Try to parse a boolean string value.*/
int pa_parse_boolean(const char *v) {
const char *expr;
int r;
pa_assert(v);
/* First we check language independant */
if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
return 1;
else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
return 0;
/* And then we check language dependant */
if ((expr = nl_langinfo(YESEXPR)))
if (expr[0])
if ((r = match(expr, v)) > 0)
return 1;
if ((expr = nl_langinfo(NOEXPR)))
if (expr[0])
if ((r = match(expr, v)) > 0)
return 0;
errno = EINVAL;
return -1;
}
@ -875,11 +926,18 @@ static int is_group(gid_t gid, const char *name) {
#else
n = -1;
#endif
if (n < 0) n = 512;
data = pa_xmalloc(n);
if (n < 0)
n = 512;
data = pa_xmalloc((size_t) n);
errno = 0;
if (getgrgid_r(gid, &group, data, (size_t) n, &result) < 0 || !result) {
pa_log("getgrgid_r(%u): %s", (unsigned) gid, pa_cstrerror(errno));
if (!errno)
errno = ENOENT;
if (getgrgid_r(gid, &group, data, n, &result) < 0 || !result) {
pa_log("getgrgid_r(%u): %s", (unsigned)gid, pa_cstrerror(errno));
goto finish;
}
@ -890,8 +948,14 @@ finish:
#else
/* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
* support getgrgid_r. */
errno = 0;
if ((result = getgrgid(gid)) == NULL) {
pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
if (!errno)
errno = ENOENT;
goto finish;
}
@ -906,27 +970,32 @@ finish:
/* Check the current user is member of the specified group */
int pa_own_uid_in_group(const char *name, gid_t *gid) {
GETGROUPS_T *gids, tgid;
int n = sysconf(_SC_NGROUPS_MAX);
int r = -1, i;
long n = sysconf(_SC_NGROUPS_MAX);
int r = -1, i, k;
pa_assert(n > 0);
gids = pa_xmalloc(sizeof(GETGROUPS_T)*n);
gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
if ((n = getgroups(n, gids)) < 0) {
if ((n = getgroups((int) n, gids)) < 0) {
pa_log("getgroups(): %s", pa_cstrerror(errno));
goto finish;
}
for (i = 0; i < n; i++) {
if (is_group(gids[i], name) > 0) {
if ((k = is_group(gids[i], name)) < 0)
goto finish;
else if (k > 0) {
*gid = gids[i];
r = 1;
goto finish;
}
}
if (is_group(tgid = getgid(), name) > 0) {
if ((k = is_group(tgid = getgid(), name)) < 0)
goto finish;
else if (k > 0) {
*gid = tgid;
r = 1;
goto finish;
@ -949,18 +1018,25 @@ int pa_uid_in_group(uid_t uid, const char *name) {
int r = -1;
g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
g_buf = pa_xmalloc(g_n);
g_buf = pa_xmalloc((size_t) g_n);
p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
p_buf = pa_xmalloc(p_n);
p_buf = pa_xmalloc((size_t) p_n);
errno = 0;
if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
if (!errno)
errno = ENOENT;
if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
goto finish;
}
r = 0;
for (i = gr->gr_mem; *i; i++) {
struct passwd pwbuf, *pw;
errno = 0;
if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
continue;
@ -985,10 +1061,16 @@ gid_t pa_get_gid_of_group(const char *name) {
struct group grbuf, *gr;
g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
g_buf = pa_xmalloc(g_n);
g_buf = pa_xmalloc((size_t) g_n);
errno = 0;
if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
if (!errno)
errno = ENOENT;
if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
goto finish;
}
ret = gr->gr_gid;
@ -1014,19 +1096,23 @@ int pa_check_in_group(gid_t g) {
#else /* HAVE_GRP_H */
int pa_own_uid_in_group(const char *name, gid_t *gid) {
errno = ENOSUP;
return -1;
}
int pa_uid_in_group(uid_t uid, const char *name) {
errno = ENOSUP;
return -1;
}
gid_t pa_get_gid_of_group(const char *name) {
errno = ENOSUP;
return (gid_t) -1;
}
int pa_check_in_group(gid_t g) {
errno = ENOSUP;
return -1;
}
@ -1040,7 +1126,7 @@ int pa_lock_fd(int fd, int b) {
/* Try a R/W lock first */
flock.l_type = b ? F_WRLCK : F_UNLCK;
flock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
flock.l_whence = SEEK_SET;
flock.l_start = 0;
flock.l_len = 0;
@ -1067,6 +1153,8 @@ int pa_lock_fd(int fd, int b) {
return 0;
pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
/* FIXME: Needs to set errno! */
#endif
return -1;
@ -1133,8 +1221,11 @@ int pa_lock_lockfile(const char *fn) {
fail:
if (fd >= 0)
if (fd >= 0) {
int saved_errno = errno;
pa_close(fd);
errno = saved_errno;
}
return -1;
}
@ -1164,48 +1255,245 @@ int pa_unlock_lockfile(const char *fn, int fd) {
return r;
}
static char *get_dir(mode_t m, const char *env_name) {
const char *e;
char *d;
static char *get_pulse_home(void) {
char h[PATH_MAX];
struct stat st;
if ((e = getenv(env_name)))
d = pa_xstrdup(e);
else {
char h[PATH_MAX];
struct stat st;
if (!pa_get_home_dir(h, sizeof(h))) {
pa_log_error("Failed to get home directory.");
return NULL;
}
if (stat(h, &st) < 0) {
pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
return NULL;
}
if (st.st_uid != getuid()) {
pa_log_error("Home directory %s not ours.", d);
return NULL;
}
d = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
if (!pa_get_home_dir(h, sizeof(h))) {
pa_log_error("Failed to get home directory.");
return NULL;
}
if (pa_make_secure_dir(d, m, (pid_t) -1, (pid_t) -1) < 0) {
if (stat(h, &st) < 0) {
pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
return NULL;
}
if (st.st_uid != getuid()) {
pa_log_error("Home directory %s not ours.", h);
errno = EACCES;
return NULL;
}
return pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
}
char *pa_get_state_dir(void) {
char *d;
/* The state directory shall contain dynamic data that should be
* kept across reboots, and is private to this user */
if (!(d = pa_xstrdup(getenv("PULSE_STATE_PATH"))))
if (!(d = get_pulse_home()))
return NULL;
/* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
* dir then this will break. */
if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
pa_xfree(d);
return NULL;
}
return d;
}
char *pa_get_runtime_dir(void) {
return get_dir(pa_in_system_mode() ? 0755 : 0700, "PULSE_RUNTIME_PATH");
static char* make_random_dir(mode_t m) {
static const char table[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
char fn[24] = "/tmp/pulse-";
fn[sizeof(fn)-1] = 0;
for (;;) {
unsigned i;
int r;
mode_t u;
int saved_errno;
for (i = 11; i < sizeof(fn)-1; i++)
fn[i] = table[rand() % (sizeof(table)-1)];
u = umask((~m) & 0777);
r = mkdir(fn, m);
saved_errno = errno;
umask(u);
if (r >= 0)
return pa_xstrdup(fn);
errno = saved_errno;
if (errno != EEXIST) {
pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
return NULL;
}
}
}
char *pa_get_state_dir(void) {
return get_dir(0700, "PULSE_STATE_PATH");
static int make_random_dir_and_link(mode_t m, const char *k) {
char *p;
if (!(p = make_random_dir(m)))
return -1;
if (symlink(p, k) < 0) {
int saved_errno = errno;
if (errno != EEXIST)
pa_log_error("Failed to symlink %s to %s: %s", k, p, pa_cstrerror(errno));
rmdir(p);
pa_xfree(p);
errno = saved_errno;
return -1;
}
return 0;
}
char *pa_get_runtime_dir(void) {
char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
struct stat st;
/* The runtime directory shall contain dynamic data that needs NOT
* to be kept accross reboots and is usuallly private to the user,
* except in system mode, where it might be accessible by other
* users, too. Since we need POSIX locking and UNIX sockets in
* this directory, we link it to a random subdir in /tmp, if it
* was not explicitly configured. */
if ((d = getenv("PULSE_RUNTIME_PATH"))) {
mode_t m;
m = pa_in_system_mode() ? 0755U : 0700U;
if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0) {
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
goto fail;
}
return pa_xstrdup(d);
}
if (!(d = get_pulse_home()))
goto fail;
if (!(mid = pa_machine_id())) {
pa_xfree(d);
goto fail;
}
k = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:runtime", d, mid);
pa_xfree(d);
pa_xfree(mid);
for (;;) {
/* OK, first let's check if the "runtime" symlink is already
* existant */
if (!(p = pa_readlink(k))) {
if (errno != ENOENT) {
pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
goto fail;
}
/* Hmm, so the runtime directory didn't exist yet, so let's
* create one in /tmp and symlink that to it */
if (make_random_dir_and_link(0700, k) < 0) {
/* Mhmm, maybe another process was quicker than us,
* let's check if that was valid */
if (errno == EEXIST)
continue;
goto fail;
}
return k;
}
/* Make sure that this actually makes sense */
if (!pa_is_path_absolute(p)) {
pa_log_error("Path %s in link %s is not absolute.", p, k);
errno = ENOENT;
goto fail;
}
/* Hmm, so this symlink is still around, make sure nobody fools
* us */
if (lstat(p, &st) < 0) {
if (errno != ENOENT) {
pa_log_error("Failed to stat runtime directory %s: %s", p, pa_cstrerror(errno));
goto fail;
}
} else {
if (S_ISDIR(st.st_mode) &&
(st.st_uid == getuid()) &&
((st.st_mode & 0777) == 0700)) {
pa_xfree(p);
return k;
}
pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
}
pa_xfree(p);
p = NULL;
/* Hmm, so the link points to some nonexisting or invalid
* dir. Let's replace it by a new link. We first create a
* temporary link and then rename that to allow concurrent
* execution of this function. */
t = pa_sprintf_malloc("%s.tmp", k);
if (make_random_dir_and_link(0700, t) < 0) {
if (errno != EEXIST) {
pa_log_error("Failed to symlink %s: %s", t, pa_cstrerror(errno));
goto fail;
}
pa_xfree(t);
t = NULL;
/* Hmm, someone lese was quicker then us. Let's give
* him some time to finish, and retry. */
pa_msleep(10);
continue;
}
/* OK, we succeeded in creating the temporary symlink, so
* let's rename it */
if (rename(t, k) < 0) {
pa_log_error("Failed to rename %s to %s: %s", t, k, pa_cstrerror(errno));
goto fail;
}
pa_xfree(t);
return k;
}
fail:
pa_xfree(p);
pa_xfree(k);
pa_xfree(t);
return NULL;
}
/* Try to open a configuration file. If "env" is specified, open the
@ -1228,6 +1516,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
/* FIXME: Needs to set errno! */
return NULL;
fn = buf;
#endif
@ -1253,9 +1542,12 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
else if (pa_get_home_dir(h, sizeof(h)))
fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
else
return NULL;
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
/* FIXME: Needs to set errno! */
pa_xfree(lfn);
return NULL;
}
@ -1284,6 +1576,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
/* FIXME: Needs to set errno! */
return NULL;
global = buf;
#endif
@ -1295,9 +1588,9 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
return f;
}
} else
errno = ENOENT;
}
errno = ENOENT;
return NULL;
}
@ -1311,8 +1604,10 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
#endif
if (env && (fn = getenv(env))) {
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
/* FIXME: Needs to set errno! */
return NULL;
fn = buf;
#endif
@ -1333,9 +1628,12 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
else if (pa_get_home_dir(h, sizeof(h)))
fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
else
return NULL;
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
/* FIXME: Needs to set errno! */
pa_xfree(lfn);
return NULL;
}
@ -1360,14 +1658,16 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
if (global) {
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
/* FIXME: Needs to set errno! */
return NULL;
global = buf;
#endif
if (access(fn, R_OK) == 0)
if (access(global, R_OK) == 0)
return pa_xstrdup(global);
} else
errno = ENOENT;
}
errno = ENOENT;
return NULL;
}
@ -1404,6 +1704,7 @@ static int hexc(char c) {
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
errno = EINVAL;
return -1;
}
@ -1490,7 +1791,7 @@ char *pa_make_path_absolute(const char *p) {
/* if fn is null return the PulseAudio run time path in s (~/.pulse)
* if fn is non-null and starts with / return fn
* otherwise append fn to the run time path and return it */
static char *get_path(const char *fn, pa_bool_t rt) {
static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
char *rtp;
if (pa_is_path_absolute(fn))
@ -1503,7 +1804,20 @@ static char *get_path(const char *fn, pa_bool_t rt) {
if (fn) {
char *r;
r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
if (prependmid) {
char *mid;
if (!(mid = pa_machine_id())) {
pa_xfree(rtp);
return NULL;
}
r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s:%s", rtp, mid, fn);
pa_xfree(mid);
} else
r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
pa_xfree(rtp);
return r;
} else
@ -1511,11 +1825,11 @@ static char *get_path(const char *fn, pa_bool_t rt) {
}
char *pa_runtime_path(const char *fn) {
return get_path(fn, 1);
return get_path(fn, FALSE, TRUE);
}
char *pa_state_path(const char *fn) {
return get_path(fn, 0);
char *pa_state_path(const char *fn, pa_bool_t appendmid) {
return get_path(fn, appendmid, FALSE);
}
/* Convert the string s to a signed integer in *ret_i */
@ -1529,11 +1843,16 @@ int pa_atoi(const char *s, int32_t *ret_i) {
errno = 0;
l = strtol(s, &x, 0);
if (!x || *x || errno != 0)
if (!x || *x || errno) {
if (!errno)
errno = EINVAL;
return -1;
}
if ((int32_t) l != l)
if ((int32_t) l != l) {
errno = ERANGE;
return -1;
}
*ret_i = (int32_t) l;
@ -1551,11 +1870,16 @@ int pa_atou(const char *s, uint32_t *ret_u) {
errno = 0;
l = strtoul(s, &x, 0);
if (!x || *x || errno != 0)
if (!x || *x || errno) {
if (!errno)
errno = EINVAL;
return -1;
}
if ((uint32_t) l != l)
if ((uint32_t) l != l) {
errno = ERANGE;
return -1;
}
*ret_u = (uint32_t) l;
@ -1573,7 +1897,6 @@ static void c_locale_destroy(void) {
int pa_atod(const char *s, double *ret_d) {
char *x = NULL;
double f;
int r = 0;
pa_assert(s);
pa_assert(ret_d);
@ -1599,17 +1922,20 @@ int pa_atod(const char *s, double *ret_d) {
f = strtod(s, &x);
}
if (!x || *x || errno != 0)
r = -1;
else
*ret_d = f;
if (!x || *x || errno) {
if (!errno)
errno = EINVAL;
return -1;
}
return r;
*ret_d = f;
return 0;
}
/* Same as snprintf, but guarantees NUL-termination on every platform */
int pa_snprintf(char *str, size_t size, const char *format, ...) {
int ret;
size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
size_t ret;
va_list ap;
pa_assert(str);
@ -1624,7 +1950,7 @@ int pa_snprintf(char *str, size_t size, const char *format, ...) {
}
/* Same as vsnprintf, but guarantees NUL-termination on every platform */
int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
int ret;
pa_assert(str);
@ -1636,9 +1962,12 @@ int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
str[size-1] = 0;
if (ret < 0)
ret = strlen(str);
return strlen(str);
return PA_MIN((int) size-1, ret);
if ((size_t) ret > size-1)
return size-1;
return (size_t) ret;
}
/* Truncate the specified string, but guarantee that the string
@ -1662,7 +1991,7 @@ char *pa_getcwd(void) {
size_t l = 128;
for (;;) {
char *p = pa_xnew(char, l);
char *p = pa_xmalloc(l);
if (getcwd(p, l))
return p;
@ -1687,7 +2016,7 @@ void *pa_will_need(const void *p, size_t l) {
pa_assert(l > 0);
a = PA_PAGE_ALIGN_PTR(p);
size = (const uint8_t*) p + l - (const uint8_t*) a;
size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
#ifdef HAVE_POSIX_MADVISE
if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
@ -1708,10 +2037,11 @@ void *pa_will_need(const void *p, size_t l) {
if (rlim.rlim_cur < PA_PAGE_SIZE) {
pa_log_debug("posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r));
errno = EPERM;
return (void*) p;
}
bs = PA_PAGE_ALIGN(rlim.rlim_cur);
bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
#else
bs = PA_PAGE_SIZE*4;
#endif
@ -1763,7 +2093,7 @@ char *pa_readlink(const char *p) {
char *c;
ssize_t n;
c = pa_xnew(char, l);
c = pa_xmalloc(l);
if ((n = readlink(p, c, l-1)) < 0) {
pa_xfree(c);
@ -1782,8 +2112,8 @@ char *pa_readlink(const char *p) {
int pa_close_all(int except_fd, ...) {
va_list ap;
int n = 0, i, r;
int *p;
unsigned n = 0, i;
int r, *p;
va_start(ap, except_fd);
@ -1910,8 +2240,8 @@ int pa_close_allv(const int except_fds[]) {
int pa_unblock_sigs(int except, ...) {
va_list ap;
int n = 0, i, r;
int *p;
unsigned n = 0, i;
int r, *p;
va_start(ap, except);
@ -1959,8 +2289,8 @@ int pa_unblock_sigsv(const int except[]) {
int pa_reset_sigs(int except, ...) {
va_list ap;
int n = 0, i, r;
int *p;
unsigned n = 0, i;
int *p, r;
va_start(ap, except);
@ -2048,3 +2378,47 @@ pa_bool_t pa_in_system_mode(void) {
return !!atoi(e);
}
char *pa_machine_id(void) {
FILE *f;
size_t l;
if ((f = fopen(PA_MACHINE_ID, "r"))) {
char ln[34] = "", *r;
r = fgets(ln, sizeof(ln)-1, f);
fclose(f);
if (r)
return pa_xstrdup(pa_strip_nl(ln));
}
l = 100;
for (;;) {
char *c;
c = pa_xmalloc(l);
if (!pa_get_host_name(c, l)) {
if (errno == EINVAL || errno == ENAMETOOLONG) {
pa_xfree(c);
l *= 2;
continue;
}
return NULL;
}
if (strlen(c) < l-1)
return c;
/* Hmm, the hostname is as long the space we offered the
* function, we cannot know if it fully fit in, so let's play
* safe and retry. */
pa_xfree(c);
l *= 2;
}
}

View file

@ -121,14 +121,14 @@ char* pa_find_config_file(const char *global, const char *local, const char *env
char *pa_get_runtime_dir(void);
char *pa_get_state_dir(void);
char *pa_runtime_path(const char *fn);
char *pa_state_path(const char *fn);
char *pa_state_path(const char *fn, pa_bool_t prepend_machine_id);
int pa_atoi(const char *s, int32_t *ret_i);
int pa_atou(const char *s, uint32_t *ret_u);
int pa_atod(const char *s, double *ret_d);
int pa_snprintf(char *str, size_t size, const char *format, ...);
int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap);
size_t pa_snprintf(char *str, size_t size, const char *format, ...);
size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap);
char *pa_truncate_utf8(char *c, size_t l);
@ -184,4 +184,6 @@ pa_bool_t pa_in_system_mode(void);
#define pa_streq(a,b) (!strcmp((a),(b)))
char *pa_machine_id(void);
#endif

Some files were not shown because too many files have changed in this diff Show more