diff options
Diffstat (limited to 'src')
177 files changed, 4789 insertions, 2550 deletions
diff --git a/src/.gitignore b/src/.gitignore index 6902eb9f..543f4e8e 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +lock-autospawn-test  *.lo  *.o  *.la diff --git a/src/Makefile.am b/src/Makefile.am index 298eb658..21584ad9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/daemon/caps.c b/src/daemon/caps.c index 8a49e373..f7b6658b 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -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); diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 4b2466ce..fbd6dc32 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -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; diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 42a71f7e..59552828 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -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;  } diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 50b812dc..40e0a170 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -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)); diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index be2fe1ab..c42984f9 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -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, diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index 41c26e2a..33b1d61d 100644 --- a/src/daemon/daemon.conf.in +++ b/src/daemon/daemon.conf.in @@ -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 diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index cdaa8bbd..5f35e3ec 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -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 diff --git a/src/daemon/dumpmodules.c b/src/daemon/dumpmodules.c index cd6866aa..9c9f1c81 100644 --- a/src/daemon/dumpmodules.c +++ b/src/daemon/dumpmodules.c @@ -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)) { diff --git a/src/daemon/ltdl-bind-now.c b/src/daemon/ltdl-bind-now.c index b1770674..92e5d40d 100644 --- a/src/daemon/ltdl-bind-now.c +++ b/src/daemon/ltdl-bind-now.c @@ -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  } - diff --git a/src/daemon/main.c b/src/daemon/main.c index 5fc9f01c..b57a74a2 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -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); +    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(_("Machine ID is %s."), s); +    pa_xfree(s); +      if (!(s = pa_get_runtime_dir()))          goto finish; -    pa_log_info("Using runtime directory %s.", s); +    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); +        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())); +    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) diff --git a/src/daemon/polkit.c b/src/daemon/polkit.c index 08155cf2..921e5d1d 100644 --- a/src/daemon/polkit.c +++ b/src/daemon/polkit.c @@ -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; diff --git a/src/map-file b/src/map-file index 8d1c582e..b6d3b63d 100644 --- a/src/map-file +++ b/src/map-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; diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 8abf834d..e8c7e146 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -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; +} diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index 4de8bcd2..7991a107 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -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 diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 8e0066bc..d2abf087 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -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 diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c index a2a43278..6e8ab6ea 100644 --- a/src/modules/gconf/module-gconf.c +++ b/src/modules/gconf/module-gconf.c @@ -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);      }  } diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index aad6801e..e3f9a5ff 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -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(×tamp); */      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; -            u->hw_dB_supported = FALSE; +#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)); +            }          } -        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; -            u->hw_dB_supported = FALSE; +                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)); +            }          } -        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; + +        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 ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0) +        if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 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)); +        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); +                pa_assert(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; +            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 -                    } else if (u->hw_dB_min >= u->hw_dB_max) { +                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; +            } -                        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; +            if (suitable && +                !u->hw_dB_supported && +                u->hw_volume_max - u->hw_volume_min < 3) { -                    } else { +                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 (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; -                        } +            if (suitable) { +                u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0; -                        u->hw_dB_supported = TRUE; -                    } -                } +                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"); -                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."); -            } +            } 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(); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 1cc467d9..54ffde57 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -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; -            u->hw_dB_supported = FALSE; +#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)); +            }          } -        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; -            u->hw_dB_supported = FALSE; +                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)); +            }          } -        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; + +        pa_assert(u->hw_dB_supported); + +        vol = pa_cvolume_max(&s->volume); -        if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 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 ((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); +                pa_assert(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) { +            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("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; +                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; +            } -                    } else -                        u->hw_dB_supported = TRUE; -                } +            if (suitable && +                !u->hw_dB_supported && +                u->hw_volume_max - u->hw_volume_min < 3) { -                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"); +                pa_log_info("Device has less than 4 volume levels. Falling back to software volume control."); +                suitable = FALSE; +            } -                } 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."); -            } +            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(); diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c index 8b67a36d..9d60c29e 100644 --- a/src/modules/module-always-sink.c +++ b/src/modules/module-always-sink.c @@ -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); diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index df7783fa..439aa8b0 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -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) { diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 0a0b8d20..d61d127a 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -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);      } diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c index 7f21efa0..d2cc24f3 100644 --- a/src/modules/module-default-device-restore.c +++ b/src/modules/module-default-device-restore.c @@ -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); diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 13bcfcd1..1616d47c 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -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); diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c index c0d2ddb7..920b4517 100644 --- a/src/modules/module-device-restore.c +++ b/src/modules/module-device-restore.c @@ -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) diff --git a/src/modules/module-esound-compat-spawnfd.c b/src/modules/module-esound-compat-spawnfd.c index 8eb4985b..578ad3b5 100644 --- a/src/modules/module-esound-compat-spawnfd.c +++ b/src/modules/module-esound-compat-spawnfd.c @@ -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; diff --git a/src/modules/module-esound-compat-spawnpid.c b/src/modules/module-esound-compat-spawnpid.c index 67f0a231..882dba8c 100644 --- a/src/modules/module-esound-compat-spawnpid.c +++ b/src/modules/module-esound-compat-spawnpid.c @@ -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; diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index 6ca64978..14f1810a 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -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; diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index bfabd91a..c76a366c 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -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 diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index edc543a8..555cb825 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -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; diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index 03f9d15c..9eccbbfa 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -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; diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index eae80086..9127af01 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -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: diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index 0570a6a1..97e97dc7 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -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);  } diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 4388e49c..21f176a4 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -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))) diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c index fa9c0e4f..f17f435a 100644 --- a/src/modules/module-native-protocol-fd.c +++ b/src/modules/module-native-protocol-fd.c @@ -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;      } -    options = pa_native_options_new(); -    options->module = m; -    options->auth_anonymous = TRUE; +    m->userdata = pa_native_protocol_get(m->core);      io = pa_iochannel_new(m->core->mainloop, fd, fd); -    m->userdata = pa_native_protocol_get(m->core); +    options = pa_native_options_new(); +    options->module = m; +    options->auth_anonymous = TRUE;      pa_native_protocol_connect(m->userdata, io, options); -    pa_native_options_unref(options); -      r = 0;  finish: diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 15b1e956..23a32549 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -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;      } diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index f389cd06..ae230b2c 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -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; diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index b0de34ca..25151d95 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -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; diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index 8136c6fc..0e98b1c3 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -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) { diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index bd86f4d6..5b2be118 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -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 */ diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index 38780f24..21565cc4 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -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); diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 22e2ff62..37e8b067 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -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);  } diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index af27ce74..de3c7274 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -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;      } diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index d862c203..aac0d046 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -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 || diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c index f7be48f7..e93721c1 100644 --- a/src/modules/module-x11-bell.c +++ b/src/modules/module-x11-bell.c @@ -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) { diff --git a/src/modules/module-x11-publish.c b/src/modules/module-x11-publish.c index c29535e6..c6c5bacd 100644 --- a/src/modules/module-x11-publish.c +++ b/src/modules/module-x11-publish.c @@ -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; diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c index 0b2e375a..57d182fd 100644 --- a/src/modules/module-x11-xsmp.c +++ b/src/modules/module-x11-xsmp.c @@ -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; diff --git a/src/modules/module-zeroconf-discover.c b/src/modules/module-zeroconf-discover.c index 2fc81370..c8087abb 100644 --- a/src/modules/module-zeroconf-discover.c +++ b/src/modules/module-zeroconf-discover.c @@ -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);          } diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 78929179..985564f4 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -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);                  }              } diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 2791e165..f766030d 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -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; diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index e04e4611..01637892 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -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);          } diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index d0d06c4d..280067a5 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -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); diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index 5a33ebc2..88351010 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -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."); diff --git a/src/modules/rtp/sap.c b/src/modules/rtp/sap.c index 5d9b58fa..b0c95aa5 100644 --- a/src/modules/rtp/sap.c +++ b/src/modules/rtp/sap.c @@ -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); diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c index cef90433..59989e1a 100644 --- a/src/modules/rtp/sdp.c +++ b/src/modules/rtp/sdp.c @@ -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; diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index 7348b32e..1766e729 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -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_FRONT_CENTER] = "Front Center", -    [PA_CHANNEL_POSITION_FRONT_LEFT] = "Front Left", -    [PA_CHANNEL_POSITION_FRONT_RIGHT] = "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_LFE] = "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_SIDE_LEFT] = "Side Left", -    [PA_CHANNEL_POSITION_SIDE_RIGHT] = "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_TOP_CENTER] = "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_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_MONO] = N_("Mono"), + +    [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] = N_("Rear Center"), +    [PA_CHANNEL_POSITION_REAR_LEFT] = N_("Rear Left"), +    [PA_CHANNEL_POSITION_REAR_RIGHT] = N_("Rear Right"), + +    [PA_CHANNEL_POSITION_LFE] = N_("Low Frequency Emmiter"), + +    [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] = N_("Side Left"), +    [PA_CHANNEL_POSITION_SIDE_RIGHT] = N_("Side Right"), + +    [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] = N_("Top Center"), + +    [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] = 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; diff --git a/src/pulse/client-conf-x11.c b/src/pulse/client-conf-x11.c index 393a7cd3..a8a90fb8 100644 --- a/src/pulse/client-conf-x11.c +++ b/src/pulse/client-conf-x11.c @@ -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;          } diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index 915d0ccb..739ef161 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -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;          } diff --git a/src/pulse/context.c b/src/pulse/context.c index f56cb241..99a47a18 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -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; + +    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; +    } -static char *get_legacy_runtime_dir(void) { +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; + +            pa_assert(c->autospawn_fd < 0); +            pa_assert(!c->autospawn_locked); -            if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) { +            /* 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); +} diff --git a/src/pulse/error.c b/src/pulse/error.c index 50bbf703..d9d0a8c6 100644 --- a/src/pulse/error.c +++ b/src/pulse/error.c @@ -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]);  } diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c new file mode 100644 index 00000000..703179c5 --- /dev/null +++ b/src/pulse/ext-stream-restore.c @@ -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); + +} diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h new file mode 100644 index 00000000..2038eb4a --- /dev/null +++ b/src/pulse/ext-stream-restore.h @@ -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 diff --git a/src/pulse/glib-mainloop.c b/src/pulse/glib-mainloop.c index 6ddb0faa..5f5dc494 100644 --- a/src/pulse/glib-mainloop.c +++ b/src/pulse/glib-mainloop.c @@ -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; diff --git a/src/pulse/i18n.c b/src/pulse/i18n.c new file mode 100644 index 00000000..7f25b20d --- /dev/null +++ b/src/pulse/i18n.c @@ -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; +} diff --git a/src/pulse/i18n.h b/src/pulse/i18n.h new file mode 100644 index 00000000..4c0ef9d3 --- /dev/null +++ b/src/pulse/i18n.h @@ -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 diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 9ed541d1..9167bf1b 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -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 diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 4be2c62a..4e362fd8 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -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; diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index 6a6755e7..ca79f5b7 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -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 diff --git a/src/pulse/lock-autospawn.c b/src/pulse/lock-autospawn.c new file mode 100644 index 00000000..d36b669e --- /dev/null +++ b/src/pulse/lock-autospawn.c @@ -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); +} diff --git a/src/pulse/lock-autospawn.h b/src/pulse/lock-autospawn.h new file mode 100644 index 00000000..c04c4bd1 --- /dev/null +++ b/src/pulse/lock-autospawn.h @@ -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 diff --git a/src/pulse/mainloop-api.c b/src/pulse/mainloop-api.c index 90aff164..4b862f9a 100644 --- a/src/pulse/mainloop-api.c +++ b/src/pulse/mainloop-api.c @@ -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; diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index 9161dec4..d09f4b0a 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -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; diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index aaed3caf..60e5d1ff 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -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);  } diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c index 74aea20a..93bc0034 100644 --- a/src/pulse/proplist.c +++ b/src/pulse/proplist.c @@ -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); diff --git a/src/pulse/sample.c b/src/pulse/sample.c index 4aef5bb0..93da2465 100644 --- a/src/pulse/sample.c +++ b/src/pulse/sample.c @@ -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); diff --git a/src/pulse/scache.c b/src/pulse/scache.c index 5e31e7af..fd3b9876 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -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); diff --git a/src/pulse/simple.c b/src/pulse/simple.c index 70396835..51160ad7 100644 --- a/src/pulse/simple.c +++ b/src/pulse/simple.c @@ -453,4 +453,3 @@ unlock_and_fail:      pa_threaded_mainloop_unlock(p->mainloop);      return (pa_usec_t) -1;  } - diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 585518f0..536a82ce 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -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); diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c index d9c06b7e..e12d1446 100644 --- a/src/pulse/subscribe.c +++ b/src/pulse/subscribe.c @@ -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; diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 6b66696c..fb73ff1b 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -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())) { diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 9708a735..376cf13c 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -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;  } diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 119be542..91aa9c81 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -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() */ diff --git a/src/pulse/util.c b/src/pulse/util.c index c0911b51..b20ea46a 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -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 diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 70d6f86a..768bf49c 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -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; +} diff --git a/src/pulse/volume.h b/src/pulse/volume.h index 5cce083e..d612c7f9 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -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 diff --git a/src/pulse/xmalloc.c b/src/pulse/xmalloc.c index 90237013..d1138d65 100644 --- a/src/pulse/xmalloc.c +++ b/src/pulse/xmalloc.c @@ -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); diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index 03e9f0df..f64931a5 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -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) { diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index a91c4d56..072943ab 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -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 { diff --git a/src/pulsecore/authkey-prop.c b/src/pulsecore/authkey-prop.c deleted file mode 100644 index d52bdcf4..00000000 --- a/src/pulsecore/authkey-prop.c +++ /dev/null @@ -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); -    } -} diff --git a/src/pulsecore/authkey-prop.h b/src/pulsecore/authkey-prop.h deleted file mode 100644 index de02d2aa..00000000 --- a/src/pulsecore/authkey-prop.h +++ /dev/null @@ -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 diff --git a/src/pulsecore/autoload.c b/src/pulsecore/autoload.c index 26c294b2..8c84cee5 100644 --- a/src/pulsecore/autoload.c +++ b/src/pulsecore/autoload.c @@ -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); diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 0bd4070c..1624165d 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -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));      } diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index c92fca20..7bbc2660 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -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( diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c index 0ffd2330..ab6e5df4 100644 --- a/src/pulsecore/client.c +++ b/src/pulsecore/client.c @@ -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) { diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c index 4aec45d7..6b0e1d56 100644 --- a/src/pulsecore/conf-parser.c +++ b/src/pulsecore/conf-parser.c @@ -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); diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index 75fa2ff1..814dff59 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -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); diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c index 6107002b..c70d8adc 100644 --- a/src/pulsecore/core-subscribe.c +++ b/src/pulsecore/core-subscribe.c @@ -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;              }          } diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index c4818e39..89416d8b 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -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 (!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 (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; +    } -        if (st.st_uid != getuid()) { -            pa_log_error("Home directory %s not ours.", d); +    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; -        } -        d = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h); -    } +    /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same +     * dir then this will break. */ -    if (pa_make_secure_dir(d, m, (pid_t) -1, (pid_t) -1) < 0)  { +    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; +    } +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 2ed81fc5..7167972b 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -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 diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index aa8de8df..b9f04b68 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -56,7 +56,7 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o      switch (code) {          case PA_CORE_MESSAGE_UNLOAD_MODULE: -            pa_module_unload(c, userdata); +            pa_module_unload(c, userdata, TRUE);              return 0;          default: @@ -125,7 +125,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {      c->mempool = pool;      pa_silence_cache_init(&c->silence_cache); -    c->quit_event = NULL; +    c->exit_event = NULL;      c->exit_idle_time = -1;      c->module_idle_time = 20; @@ -134,6 +134,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {      c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;      c->disallow_module_loading = FALSE; +    c->disallow_exit = FALSE;      c->realtime_scheduling = FALSE;      c->realtime_priority = 5;      c->disable_remixing = FALSE; @@ -149,7 +150,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {      pa_check_signal_is_blocked(SIGPIPE);  #endif -    pa_core_check_quit(c); +    pa_core_check_idle(c);      return c;  } @@ -182,8 +183,8 @@ static void core_free(pa_object *o) {      pa_autoload_free(c);      pa_subscription_free_all(c); -    if (c->quit_event) -        c->mainloop->time_free(c->quit_event); +    if (c->exit_event) +        c->mainloop->time_free(c->exit_event);      pa_xfree(c->default_source_name);      pa_xfree(c->default_sink_name); @@ -199,17 +200,17 @@ static void core_free(pa_object *o) {      pa_xfree(c);  } -static void quit_callback(pa_mainloop_api*m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void exit_callback(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) {      pa_core *c = userdata; -    pa_assert(c->quit_event == e); +    pa_assert(c->exit_event == e); -    m->quit(m, 0); +    pa_core_exit(c, TRUE, 0);  } -void pa_core_check_quit(pa_core *c) { +void pa_core_check_idle(pa_core *c) {      pa_assert(c); -    if (!c->quit_event && +    if (!c->exit_event &&          c->exit_idle_time >= 0 &&          pa_idxset_size(c->clients) == 0) { @@ -217,10 +218,20 @@ void pa_core_check_quit(pa_core *c) {          pa_gettimeofday(&tv);          tv.tv_sec+= c->exit_idle_time; -        c->quit_event = c->mainloop->time_new(c->mainloop, &tv, quit_callback, c); +        c->exit_event = c->mainloop->time_new(c->mainloop, &tv, exit_callback, c); -    } else if (c->quit_event && pa_idxset_size(c->clients) > 0) { -        c->mainloop->time_free(c->quit_event); -        c->quit_event = NULL; +    } else if (c->exit_event && pa_idxset_size(c->clients) > 0) { +        c->mainloop->time_free(c->exit_event); +        c->exit_event = NULL;      }  } + +int pa_core_exit(pa_core *c, pa_bool_t force, int retval) { +    pa_assert(c); + +    if (c->disallow_exit && !force) +        return -1; + +    c->mainloop->quit(c->mainloop, retval); +    return 0; +} diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index e11655ef..eb768418 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -115,11 +115,12 @@ struct pa_core {      int exit_idle_time, module_idle_time, scache_idle_time; -    pa_time_event *quit_event; +    pa_time_event *exit_event;      pa_time_event *scache_auto_unload_event;      pa_bool_t disallow_module_loading:1; +    pa_bool_t disallow_exit:1;      pa_bool_t running_as_daemon:1;      pa_bool_t realtime_scheduling:1;      pa_bool_t disable_remixing:1; @@ -142,6 +143,8 @@ enum {  pa_core* pa_core_new(pa_mainloop_api *m, int shared);  /* Check whether noone is connected to this core */ -void pa_core_check_quit(pa_core *c); +void pa_core_check_idle(pa_core *c); + +int pa_core_exit(pa_core *c, pa_bool_t force, int retval);  #endif diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h index 26336918..1b94de17 100644 --- a/src/pulsecore/endianmacros.h +++ b/src/pulsecore/endianmacros.h @@ -46,9 +46,14 @@  #endif  static inline float PA_FLOAT32_SWAP(float x) { -    uint32_t i = *(uint32_t*) &x; -    i = PA_UINT32_SWAP(i); -    return *(float*) &i; +    union { +        float f; +        uint32_t u; +    } t; + +    t.f = x; +    t.u = PA_UINT32_SWAP(t.u); +    return t.f;  }  #define PA_MAYBE_INT16_SWAP(c,x) ((c) ? PA_INT32_SWAP(x) : x) diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c index e2691611..7f2252e9 100644 --- a/src/pulsecore/envelope.c +++ b/src/pulsecore/envelope.c @@ -153,11 +153,11 @@ void pa_envelope_free(pa_envelope *e) {  }  static int32_t linear_interpolate_int(pa_usec_t x1, int32_t _y1, pa_usec_t x2, int32_t y2, pa_usec_t x3) { -    return (int32_t) (_y1 + (x3 - x1) * (float) (y2 - _y1) / (float) (x2 - x1)); +    return (int32_t) ((double) _y1 + (double) (x3 - x1) * (double) (y2 - _y1) / (double) (x2 - x1));  }  static float linear_interpolate_float(pa_usec_t x1, float _y1, pa_usec_t x2, float y2, pa_usec_t x3) { -    return _y1 + (x3 - x1) * (y2 - _y1) / (x2 - x1); +    return _y1 + ((float) x3 - (float) x1) * (y2 - _y1) / ((float) x2 - (float) x1);  }  static int32_t item_get_int(pa_envelope_item *i, pa_usec_t x) { @@ -573,11 +573,11 @@ static float linear_get_float(pa_envelope *e, int v) {      if (!e->points[v].cached_valid) {          e->points[v].cached_dy_dx =              (e->points[v].y.f[e->points[v].n_current+1] - e->points[v].y.f[e->points[v].n_current]) / -            (e->points[v].x[e->points[v].n_current+1] - e->points[v].x[e->points[v].n_current]); +            ((float) e->points[v].x[e->points[v].n_current+1] - (float) e->points[v].x[e->points[v].n_current]);          e->points[v].cached_valid = TRUE;      } -    return e->points[v].y.f[e->points[v].n_current] + (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx; +    return e->points[v].y.f[e->points[v].n_current] + (float) (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx;  }  void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { @@ -605,7 +605,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {                  uint8_t *t;                  for (t = p; n > 0; n -= fs) { -                    int16_t factor = linear_get_int(e, v); +                    int32_t factor = linear_get_int(e, v);                      unsigned c;                      e->x += fs; @@ -620,13 +620,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {                  uint8_t *t;                  for (t = p; n > 0; n -= fs) { -                    int16_t factor = linear_get_int(e, v); +                    int32_t factor = linear_get_int(e, v);                      unsigned c;                      e->x += fs;                      for (c = 0; c < e->sample_spec.channels; c++, t++) {                          int16_t k = st_ulaw2linear16(*t); -                        *t = (uint8_t) st_14linear2ulaw(((factor * k) / 0x10000) >> 2); +                        *t = (uint8_t) st_14linear2ulaw((int16_t) (((factor * k) / 0x10000) >> 2));                      }                  } @@ -637,13 +637,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {                  uint8_t *t;                  for (t = p; n > 0; n -= fs) { -                    int16_t factor = linear_get_int(e, v); +                    int32_t factor = linear_get_int(e, v);                      unsigned c;                      e->x += fs;                      for (c = 0; c < e->sample_spec.channels; c++, t++) {                          int16_t k = st_alaw2linear16(*t); -                        *t = (uint8_t) st_13linear2alaw(((factor * k) / 0x10000) >> 3); +                        *t = (uint8_t) st_13linear2alaw((int16_t) (((factor * k) / 0x10000) >> 3));                      }                  } @@ -659,7 +659,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {                      e->x += fs;                      for (c = 0; c < e->sample_spec.channels; c++, t++) -                        *t = (factor * *t) / 0x10000; +                        *t = (int16_t) ((factor * *t) / 0x10000);                  }                  break; @@ -674,7 +674,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {                      e->x += fs;                      for (c = 0; c < e->sample_spec.channels; c++, t++) { -                        int16_t r = (factor * PA_INT16_SWAP(*t)) / 0x10000; +                        int16_t r = (int16_t) ((factor * PA_INT16_SWAP(*t)) / 0x10000);                          *t = PA_INT16_SWAP(r);                      }                  } diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 1531e3db..380f34f5 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -41,39 +41,15 @@  #include <pulsecore/pipe.h>  #endif -#ifdef __linux__ - -#if !defined(__NR_eventfd) && defined(__i386__) -#define __NR_eventfd 323 -#endif - -#if !defined(__NR_eventfd) && defined(__x86_64__) -#define __NR_eventfd 284 -#endif - -#if !defined(__NR_eventfd) && defined(__arm__) -#define __NR_eventfd (__NR_SYSCALL_BASE+351) -#endif - -#if !defined(SYS_eventfd) && defined(__NR_eventfd) -#define SYS_eventfd __NR_eventfd -#endif - -#ifdef SYS_eventfd -#define HAVE_EVENTFD - -static inline long eventfd(unsigned count) { -    return syscall(SYS_eventfd, count); -} - -#endif +#ifdef HAVE_SYS_EVENTFD_H +#include <sys/eventfd.h>  #endif  #include "fdsem.h"  struct pa_fdsem {      int fds[2]; -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H      int efd;  #endif @@ -85,8 +61,8 @@ pa_fdsem *pa_fdsem_new(void) {      f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data))); -#ifdef HAVE_EVENTFD -    if ((f->efd = eventfd(0)) >= 0) { +#ifdef HAVE_SYS_EVENTFD_H +    if ((f->efd = eventfd(0, 0)) >= 0) {          pa_make_fd_cloexec(f->efd);          f->fds[0] = f->fds[1] = -1;      } else @@ -116,7 +92,7 @@ pa_fdsem *pa_fdsem_open_shm(pa_fdsem_data *data, int event_fd) {      pa_assert(data);      pa_assert(event_fd >= 0); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H      f = pa_xnew(pa_fdsem, 1);      f->efd = event_fd; @@ -134,11 +110,11 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {      pa_assert(data);      pa_assert(event_fd); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H      f = pa_xnew(pa_fdsem, 1); -    if ((f->efd = eventfd(0)) < 0) { +    if ((f->efd = eventfd(0, 0)) < 0) {          pa_xfree(f);          return NULL;      } @@ -159,7 +135,7 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {  void pa_fdsem_free(pa_fdsem *f) {      pa_assert(f); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H      if (f->efd >= 0)          pa_close(f->efd);  #endif @@ -178,7 +154,7 @@ static void flush(pa_fdsem *f) {      do {          char x[10]; -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H          if (f->efd >= 0) {              uint64_t u; @@ -195,7 +171,7 @@ static void flush(pa_fdsem *f) {              continue;          } -    } while (pa_atomic_sub(&f->data->in_pipe, r) > r); +    } while (pa_atomic_sub(&f->data->in_pipe, (int) r) > (int) r);  }  void pa_fdsem_post(pa_fdsem *f) { @@ -211,7 +187,7 @@ void pa_fdsem_post(pa_fdsem *f) {              for (;;) { -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H                  if (f->efd >= 0) {                      uint64_t u = 1; @@ -247,7 +223,7 @@ void pa_fdsem_wait(pa_fdsem *f) {          char x[10];          ssize_t r; -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H          if (f->efd >= 0) {              uint64_t u; @@ -265,7 +241,7 @@ void pa_fdsem_wait(pa_fdsem *f) {              continue;          } -        pa_atomic_sub(&f->data->in_pipe, r); +        pa_atomic_sub(&f->data->in_pipe, (int) r);      }      pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1); @@ -285,7 +261,7 @@ int pa_fdsem_try(pa_fdsem *f) {  int pa_fdsem_get(pa_fdsem *f) {      pa_assert(f); -#ifdef HAVE_EVENTFD +#ifdef HAVE_SYS_EVENTFD_H      if (f->efd >= 0)          return f->efd;  #endif diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c index fb4497b8..b6423efd 100644 --- a/src/pulsecore/idxset.c +++ b/src/pulsecore/idxset.c @@ -66,7 +66,7 @@ unsigned pa_idxset_string_hash_func(const void *p) {      const char *c;      for (c = p; *c; c++) -        hash = 31 * hash + *c; +        hash = 31 * hash + (unsigned) *c;      return hash;  } diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index 90afaafd..88174c05 100644 --- a/src/pulsecore/ioline.c +++ b/src/pulsecore/ioline.c @@ -164,7 +164,7 @@ void pa_ioline_puts(pa_ioline *l, const char *c) {          /* In case the allocated buffer is too small, enlarge it. */          if (l->wbuf_valid_length + len > l->wbuf_length) {              size_t n = l->wbuf_valid_length+len; -            char *new = pa_xnew(char, n); +            char *new = pa_xnew(char, (unsigned) n);              if (l->wbuf) {                  memcpy(new, l->wbuf+l->wbuf_index, l->wbuf_valid_length); @@ -285,7 +285,7 @@ static int do_read(pa_ioline *l) {                      memmove(l->rbuf, l->rbuf+l->rbuf_index, l->rbuf_valid_length);              } else {                  /* Enlarge the buffer */ -                char *new = pa_xnew(char, n); +                char *new = pa_xnew(char, (unsigned) n);                  if (l->rbuf_valid_length)                      memcpy(new, l->rbuf+l->rbuf_index, l->rbuf_valid_length);                  pa_xfree(l->rbuf); @@ -315,10 +315,10 @@ static int do_read(pa_ioline *l) {              return -1;          } -        l->rbuf_valid_length += r; +        l->rbuf_valid_length += (size_t) r;          /* Look if a line has been terminated in the newly read data */ -        scan_for_lines(l, l->rbuf_valid_length - r); +        scan_for_lines(l, l->rbuf_valid_length - (size_t) r);      }      return 0; @@ -346,8 +346,8 @@ static int do_write(pa_ioline *l) {              return -1;          } -        l->wbuf_index += r; -        l->wbuf_valid_length -= r; +        l->wbuf_index += (size_t) r; +        l->wbuf_valid_length -= (size_t) r;          /* A shortcut for the next time */          if (l->wbuf_valid_length == 0) diff --git a/src/pulsecore/ipacl.c b/src/pulsecore/ipacl.c index 7b5f865b..6d5080fb 100644 --- a/src/pulsecore/ipacl.c +++ b/src/pulsecore/ipacl.c @@ -122,7 +122,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) {              if (e.bits < 128) {                  int t = 0, i; -                for (i = 0, bits = e.bits; i < 16; i++) { +                for (i = 0, bits = (uint32_t) e.bits; i < 16; i++) {                      if (bits >= 8)                          bits -= 8; diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index b43113d6..6d12acdc 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -31,6 +31,10 @@  #include <signal.h>  #include <errno.h> +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include <valgrind/memcheck.h> +#endif +  #include <pulse/xmalloc.h>  #include <pulse/def.h> @@ -158,14 +162,14 @@ static void stat_add(pa_memblock*b) {      pa_assert(b->pool);      pa_atomic_inc(&b->pool->stat.n_allocated); -    pa_atomic_add(&b->pool->stat.allocated_size, b->length); +    pa_atomic_add(&b->pool->stat.allocated_size, (int) b->length);      pa_atomic_inc(&b->pool->stat.n_accumulated); -    pa_atomic_add(&b->pool->stat.accumulated_size, b->length); +    pa_atomic_add(&b->pool->stat.accumulated_size, (int) b->length);      if (b->type == PA_MEMBLOCK_IMPORTED) {          pa_atomic_inc(&b->pool->stat.n_imported); -        pa_atomic_add(&b->pool->stat.imported_size, b->length); +        pa_atomic_add(&b->pool->stat.imported_size, (int) b->length);      }      pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]); @@ -181,14 +185,14 @@ static void stat_remove(pa_memblock *b) {      pa_assert(pa_atomic_load(&b->pool->stat.allocated_size) >= (int) b->length);      pa_atomic_dec(&b->pool->stat.n_allocated); -    pa_atomic_sub(&b->pool->stat.allocated_size,  b->length); +    pa_atomic_sub(&b->pool->stat.allocated_size, (int) b->length);      if (b->type == PA_MEMBLOCK_IMPORTED) {          pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0);          pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length);          pa_atomic_dec(&b->pool->stat.n_imported); -        pa_atomic_sub(&b->pool->stat.imported_size, b->length); +        pa_atomic_sub(&b->pool->stat.imported_size, (int) b->length);      }      pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]); @@ -248,7 +252,7 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {          if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks)              pa_atomic_dec(&p->n_init);          else -            slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * idx)); +            slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * (size_t) idx));          if (!slot) {              pa_log_info("Pool full"); @@ -257,6 +261,10 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {          }      } +#ifdef HAVE_VALGRIND_MEMCHECK_H +    VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0); +#endif +      return slot;  } @@ -272,7 +280,7 @@ static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) {      pa_assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr);      pa_assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size); -    return ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size; +    return (unsigned) ((size_t) ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size);  }  /* No lock necessary */ @@ -519,7 +527,7 @@ static void memblock_free(pa_memblock *b) {          case PA_MEMBLOCK_POOL_EXTERNAL:          case PA_MEMBLOCK_POOL: {              struct mempool_slot *slot; -            int call_free; +            pa_bool_t call_free;              slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data));              pa_assert(slot); @@ -532,6 +540,10 @@ static void memblock_free(pa_memblock *b) {              while (pa_flist_push(b->pool->free_slots, slot) < 0)                  ; +#ifdef HAVE_VALGRIND_MEMCHECK_H +            VALGRIND_FREELIKE_BLOCK(slot, b->pool->block_size); +#endif +              if (call_free)                  if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0)                      pa_xfree(b); @@ -647,7 +659,7 @@ static void memblock_replace_import(pa_memblock *b) {      pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0);      pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length);      pa_atomic_dec(&b->pool->stat.n_imported); -    pa_atomic_sub(&b->pool->stat.imported_size, b->length); +    pa_atomic_sub(&b->pool->stat.imported_size, (int) b->length);      seg = b->per_type.imported.segment;      pa_assert(seg); @@ -754,7 +766,7 @@ void pa_mempool_vacuum(pa_mempool *p) {              ;      while ((slot = pa_flist_pop(list))) { -        pa_shm_punch(&p->memory, (uint8_t*) slot - (uint8_t*) p->memory.ptr, p->block_size); +        pa_shm_punch(&p->memory, (size_t) ((uint8_t*) slot - (uint8_t*) p->memory.ptr), p->block_size);          while (pa_flist_push(p->free_slots, slot))              ; @@ -967,7 +979,7 @@ void pa_memexport_free(pa_memexport *e) {      pa_mutex_lock(e->mutex);      while (e->used_slots) -        pa_memexport_process_release(e, e->used_slots - e->slots); +        pa_memexport_process_release(e, (uint32_t) (e->used_slots - e->slots));      pa_mutex_unlock(e->mutex);      pa_mutex_lock(e->pool->mutex); @@ -1006,7 +1018,7 @@ int pa_memexport_process_release(pa_memexport *e, uint32_t id) {      pa_assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length);      pa_atomic_dec(&e->pool->stat.n_exported); -    pa_atomic_sub(&e->pool->stat.exported_size, b->length); +    pa_atomic_sub(&e->pool->stat.exported_size, (int) b->length);      pa_memblock_unref(b); @@ -1034,7 +1046,7 @@ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) {              slot->block->per_type.imported.segment->import != i)              continue; -        idx = slot - e->slots; +        idx = (uint32_t) (slot - e->slots);          e->revoke_cb(e, idx, e->userdata);          pa_memexport_process_release(e, idx);      } @@ -1095,7 +1107,7 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32      PA_LLIST_PREPEND(struct memexport_slot, e->used_slots, slot);      slot->block = b; -    *block_id = slot - e->slots; +    *block_id = (uint32_t) (slot - e->slots);      pa_mutex_unlock(e->mutex);  /*     pa_log("Got block id %u", *block_id); */ @@ -1115,13 +1127,13 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32      pa_assert((uint8_t*) data + b->length <= (uint8_t*) memory->ptr + memory->size);      *shm_id = memory->id; -    *offset = (uint8_t*) data - (uint8_t*) memory->ptr; +    *offset = (size_t) ((uint8_t*) data - (uint8_t*) memory->ptr);      *size = b->length;      pa_memblock_release(b);      pa_atomic_inc(&e->pool->stat.n_exported); -    pa_atomic_add(&e->pool->stat.exported_size, b->length); +    pa_atomic_add(&e->pool->stat.exported_size, (int) b->length);      return 0;  } diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index 841b9075..265da37f 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -84,7 +84,8 @@ pa_memblockq* pa_memblockq_new(      pa_log_debug("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",                   (unsigned long) maxlength, (unsigned long) tlength, (unsigned long) base, (unsigned long) prebuf, (unsigned long) minreq, (unsigned long) maxrewind); -    bq->missing = bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0; +    bq->missing = 0; +    bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0;      bq->in_prebuf = TRUE;      pa_memblockq_set_maxlength(bq, maxlength); @@ -215,7 +216,7 @@ static void drop_backlog(pa_memblockq *bq) {      int64_t boundary;      pa_assert(bq); -    boundary = bq->read_index - bq->maxrewind; +    boundary = bq->read_index - (int64_t) bq->maxrewind;      while (bq->blocks && (bq->blocks->index + (int64_t) bq->blocks->chunk.length <= boundary))          drop_block(bq, bq->blocks); @@ -227,10 +228,10 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) {      pa_assert(bq);      if (bq->read_index > bq->write_index) { -        size_t d =  bq->read_index - bq->write_index; +        int64_t d = bq->read_index - bq->write_index; -        if (l > d) -            l -= d; +        if ((int64_t) l > d) +            l -= (size_t) d;          else              return TRUE;      } @@ -239,7 +240,7 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) {      /* Make sure that the list doesn't get too long */      if (bq->write_index + (int64_t) l > end) -        if (bq->write_index + l - bq->read_index > bq->maxlength) +        if (bq->write_index + (int64_t) l - bq->read_index > (int64_t) bq->maxlength)              return FALSE;      return TRUE; @@ -294,7 +295,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {              /* This entry isn't touched at all, let's skip it */              q = q->prev;          } else if (bq->write_index <= q->index && -            bq->write_index + chunk.length >= q->index + q->chunk.length) { +                   bq->write_index + (int64_t) chunk.length >= q->index + (int64_t) q->chunk.length) {              /* This entry is fully replaced by the new entry, so let's drop it */ @@ -306,7 +307,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {              /* The write index points into this memblock, so let's               * truncate or split it */ -            if (bq->write_index + chunk.length < q->index + q->chunk.length) { +            if (bq->write_index + (int64_t) chunk.length < q->index + (int64_t) q->chunk.length) {                  /* We need to save the end of this memchunk */                  struct list_item *p; @@ -320,11 +321,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {                  pa_memblock_ref(p->chunk.memblock);                  /* Calculate offset */ -                d = bq->write_index + chunk.length - q->index; +                d = (size_t) (bq->write_index + (int64_t) chunk.length - q->index);                  pa_assert(d > 0);                  /* Drop it from the new entry */ -                p->index = q->index + d; +                p->index = q->index + (int64_t) d;                  p->chunk.length -= d;                  /* Add it to the list */ @@ -339,7 +340,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {              }              /* Truncate the chunk */ -            if (!(q->chunk.length = bq->write_index - q->index)) { +            if (!(q->chunk.length = (size_t) (bq->write_index - q->index))) {                  struct list_item *p;                  p = q;                  q = q->prev; @@ -357,8 +358,8 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {              /* The job overwrites the current entry at the end, so let's drop the beginning of this entry */ -            d = bq->write_index + chunk.length - q->index; -            q->index += d; +            d = (size_t) (bq->write_index + (int64_t) chunk.length - q->index); +            q->index += (int64_t) d;              q->chunk.index += d;              q->chunk.length -= d; @@ -373,11 +374,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {          /* Try to merge memory blocks */          if (q->chunk.memblock == chunk.memblock && -            q->chunk.index + (int64_t)q->chunk.length == chunk.index && -            bq->write_index == q->index + (int64_t)q->chunk.length) { +            q->chunk.index + q->chunk.length == chunk.index && +            bq->write_index == q->index + (int64_t) q->chunk.length) {              q->chunk.length += chunk.length; -            bq->write_index += chunk.length; +            bq->write_index += (int64_t) chunk.length;              goto finish;          }      } else @@ -389,7 +390,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {      n->chunk = chunk;      pa_memblock_ref(n->chunk.memblock);      n->index = bq->write_index; -    bq->write_index += n->chunk.length; +    bq->write_index += (int64_t) n->chunk.length;      n->next = q ? q->next : bq->blocks;      n->prev = q; @@ -411,10 +412,10 @@ finish:      delta = bq->write_index - old;      if (delta >= (int64_t) bq->requested) { -        delta -= bq->requested; +        delta -= (int64_t) bq->requested;          bq->requested = 0;      } else { -        bq->requested -= delta; +        bq->requested -= (size_t) delta;          delta = 0;      } @@ -471,7 +472,7 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {          /* How much silence shall we return? */          if (bq->current_read) -            length = bq->current_read->index - bq->read_index; +            length = (size_t) (bq->current_read->index - bq->read_index);          else if (bq->write_index > bq->read_index)              length = (size_t) (bq->write_index - bq->read_index);          else @@ -506,8 +507,8 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {      pa_assert(bq->read_index >= bq->current_read->index);      d = bq->read_index - bq->current_read->index; -    chunk->index += d; -    chunk->length -= d; +    chunk->index += (size_t) d; +    chunk->length -= (size_t) d;      return 0;  } @@ -533,20 +534,20 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) {              /* We go through this piece by piece to make sure we don't               * drop more than allowed by prebuf */ -            p = bq->current_read->index + bq->current_read->chunk.length; +            p = bq->current_read->index + (int64_t) bq->current_read->chunk.length;              pa_assert(p >= bq->read_index);              d = p - bq->read_index;              if (d > (int64_t) length) -                d = length; +                d = (int64_t) length;              bq->read_index += d; -            length -= d; +            length -= (size_t) d;          } else {              /* The list is empty, there's nothing we could drop */ -            bq->read_index += length; +            bq->read_index += (int64_t) length;              break;          }      } @@ -563,8 +564,8 @@ void pa_memblockq_rewind(pa_memblockq *bq, size_t length) {      /* This is kind of the inverse of pa_memblockq_drop() */ -    bq->read_index -= length; -    bq->missing -= length; +    bq->read_index -= (int64_t) length; +    bq->missing -= (int64_t) length;  }  pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq) { @@ -628,10 +629,10 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) {      delta = bq->write_index - old;      if (delta >= (int64_t) bq->requested) { -        delta -= bq->requested; +        delta -= (int64_t) bq->requested;          bq->requested = 0;      } else if (delta >= 0) { -        bq->requested -= delta; +        bq->requested -= (size_t) delta;          delta = 0;      } @@ -652,10 +653,10 @@ void pa_memblockq_flush_write(pa_memblockq *bq) {      delta = bq->write_index - old;      if (delta >= (int64_t) bq->requested) { -        delta -= bq->requested; +        delta -= (int64_t) bq->requested;          bq->requested = 0;      } else if (delta >= 0) { -        bq->requested -= delta; +        bq->requested -= (size_t) delta;          delta = 0;      } @@ -874,7 +875,7 @@ int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) {              pa_memblock_unref(chunk.memblock);          } else -            pa_memblockq_seek(bq, chunk.length, PA_SEEK_RELATIVE); +            pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE);          pa_memblockq_drop(bq, chunk.length);      } diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index d257b4ce..9e60125e 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -183,7 +183,7 @@ fail:      return NULL;  } -static void free_func(void *p, PA_GCC_UNUSED void*userdata) { +static void free_func(void *p, void*userdata) {      struct entry *e = p;      pa_assert(e); diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index edd0b0a7..29003af8 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -48,7 +48,7 @@  #define UNLOAD_POLL_TIME 2 -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 = PA_CORE(userdata);      struct timeval ntv; @@ -156,9 +156,6 @@ static void pa_module_free(pa_module *m) {      pa_assert(m);      pa_assert(m->core); -    if (m->core->disallow_module_loading) -        return; -      pa_log_info("Unloading \"%s\" (index: #%u).", m->name, m->index);      if (m->done) @@ -175,22 +172,27 @@ static void pa_module_free(pa_module *m) {      pa_xfree(m);  } -void pa_module_unload(pa_core *c, pa_module *m) { +void pa_module_unload(pa_core *c, pa_module *m, pa_bool_t force) {      pa_assert(c);      pa_assert(m); -    pa_assert(c->modules); +    if (m->core->disallow_module_loading && !force) +        return; +      if (!(m = pa_idxset_remove_by_data(c->modules, m, NULL)))          return;      pa_module_free(m);  } -void pa_module_unload_by_index(pa_core *c, uint32_t idx) { +void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force) {      pa_module *m;      pa_assert(c);      pa_assert(idx != PA_IDXSET_INVALID); +    if (c->disallow_module_loading && !force) +        return; +      if (!(m = pa_idxset_remove_by_index(c->modules, idx)))          return; @@ -198,7 +200,6 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx) {  }  void pa_module_unload_all(pa_core *c) { -      pa_assert(c);      if (c->modules) { @@ -245,7 +246,7 @@ void pa_module_unload_unused(pa_core *c) {          if (m->last_used_time + m->core->module_idle_time > now)              continue; -        pa_module_unload(c, m); +        pa_module_unload(c, m, FALSE);      }  } @@ -262,12 +263,15 @@ static void defer_cb(pa_mainloop_api*api, pa_defer_event *e, void *userdata) {      while ((m = pa_idxset_iterate(c->modules, &state, NULL)))          if (m->unload_requested) -            pa_module_unload(c, m); +            pa_module_unload(c, m, TRUE);  } -void pa_module_unload_request(pa_module *m) { +void pa_module_unload_request(pa_module *m, pa_bool_t force) {      pa_assert(m); +    if (m->core->disallow_module_loading && !force) +        return; +      m->unload_requested = TRUE;      if (!m->core->module_defer_unload_event) diff --git a/src/pulsecore/module.h b/src/pulsecore/module.h index bb3a3f57..365ab67e 100644 --- a/src/pulsecore/module.h +++ b/src/pulsecore/module.h @@ -52,13 +52,13 @@ struct pa_module {  };  pa_module* pa_module_load(pa_core *c, const char *name, const char*argument); -void pa_module_unload(pa_core *c, pa_module *m); -void pa_module_unload_by_index(pa_core *c, uint32_t idx); +void pa_module_unload(pa_core *c, pa_module *m, pa_bool_t force); +void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force);  void pa_module_unload_all(pa_core *c);  void pa_module_unload_unused(pa_core *c); -void pa_module_unload_request(pa_module *m); +void pa_module_unload_request(pa_module *m, pa_bool_t force);  void pa_module_set_used(pa_module*m, int used); diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c index 30420546..ad697ed5 100644 --- a/src/pulsecore/namereg.c +++ b/src/pulsecore/namereg.c @@ -45,7 +45,7 @@ struct namereg_entry {      void *data;  }; -static int is_valid_char(char c) { +static pa_bool_t is_valid_char(char c) {      return          (c >= 'a' && c <= 'z') ||          (c >= 'A' && c <= 'Z') || @@ -77,10 +77,10 @@ char* pa_namereg_make_valid_name(const char *name) {      if (*name == 0)          return NULL; -    n = pa_xnew(char, strlen(name)+1); +    n = pa_xmalloc(strlen(name)+1);      for (a = name, b = n; *a && (a-name < PA_NAME_MAX); a++, b++) -        *b = is_valid_char(*a) ? *a : '_'; +        *b = (char) (is_valid_char(*a) ? *a : '_');      *b = 0; @@ -136,7 +136,7 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t              return NULL;          } -        k = pa_xnew(char, l+4); +        k = pa_xmalloc(l+4);          for (i = 2; i <= 99; i++) {              pa_snprintf(k, l+4, "%s.%u", name, i); diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c index f2b6b2cf..c5cd7fe7 100644 --- a/src/pulsecore/parseaddr.c +++ b/src/pulsecore/parseaddr.c @@ -51,20 +51,29 @@ static char *parse_host(const char *s, uint16_t *ret_port) {          if (!(e = strchr(s+1, ']')))              return NULL; -        if (e[1] == ':') -            *ret_port = atoi(e+2); -        else if (e[1] != 0) +        if (e[1] == ':') { +            uint32_t p; + +            if (pa_atou(e+2, &p) < 0) +                return NULL; + +            *ret_port = (uint16_t) p; +        } else if (e[1] != 0)              return NULL; -        return pa_xstrndup(s+1, e-s-1); +        return pa_xstrndup(s+1, (size_t) (e-s-1));      } else {          char *e; +        uint32_t p;          if (!(e = strrchr(s, ':')))              return pa_xstrdup(s); -        *ret_port = atoi(e+1); -        return pa_xstrndup(s, e-s); +        if (pa_atou(e+1, &p) < 0) +            return NULL; + +        *ret_port = (uint16_t) p; +        return pa_xstrndup(s, (size_t) (e-s));      }  } diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c index e6a6ae4d..00df0f79 100644 --- a/src/pulsecore/pdispatch.c +++ b/src/pulsecore/pdispatch.c @@ -255,7 +255,7 @@ finish:      return ret;  } -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) {      struct reply_info*r = userdata;      pa_assert(r); diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index addb17cc..1c0851ba 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -73,6 +73,7 @@ static pid_t read_pid(const char *fn, int fd) {      if (pa_atou(t, &pid) < 0) {          pa_log_warn("Failed to parse PID file '%s'", fn); +        errno = EINVAL;          return (pid_t) -1;      } @@ -110,7 +111,7 @@ static int open_pid_file(const char *fn, int mode) {              goto fail;          } -        /* Does the file still exist in the file system? When ye, w're done, otherwise restart */ +        /* Does the file still exist in the file system? When yes, we're done, otherwise restart */          if (st.st_nlink >= 1)              break; @@ -131,8 +132,10 @@ static int open_pid_file(const char *fn, int mode) {  fail:      if (fd >= 0) { +        int saved_errno = errno;          pa_lock_fd(fd, 0);          pa_close(fd); +        errno = saved_errno;      }      return -1; @@ -154,8 +157,11 @@ static int proc_name_ours(pid_t pid, const char *procname) {          char stored[64];          if (!(fgets(stored, sizeof(stored), f))) { +            int saved_errno = feof(f) ? EINVAL : errno;              pa_log_info("Failed to read from %s: %s", bn, feof(f) ? "EOF" : pa_cstrerror(errno));              fclose(f); + +            errno = saved_errno;              return -1;          } @@ -176,9 +182,11 @@ static int proc_name_ours(pid_t pid, const char *procname) {          return !!good;      } -#endif +#else      return 1; +#endif +  }  /* Create a new PID file for the current process. */ @@ -342,8 +350,13 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {      if (!(fn = pa_runtime_path("pid")))          goto fail; -    if ((fd = open_pid_file(fn, O_RDONLY)) < 0) +    if ((fd = open_pid_file(fn, O_RDONLY)) < 0) { + +        if (errno == ENOENT) +            errno = ESRCH; +          goto fail; +    }      if ((*pid = read_pid(fn, fd)) == (pid_t) -1)          goto fail; @@ -354,8 +367,10 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {          if ((ours = proc_name_ours(*pid, procname)) < 0)              goto fail; -        if (!ours) +        if (!ours) { +            errno = ESRCH;              goto fail; +        }      }      ret = kill(*pid, sig); @@ -363,8 +378,10 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {  fail:      if (fd >= 0) { +        int saved_errno = errno;          pa_lock_fd(fd, 0);          pa_close(fd); +        errno = saved_errno;      }  #ifdef __linux__ diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 8b3e79b9..86edfe98 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -146,7 +146,6 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {      memblockq_stream *u;      pa_sink_input_assert_ref(i); -    pa_assert(nbytes > 0);      u = MEMBLOCKQ_STREAM(i->userdata);      memblockq_stream_assert_ref(u); diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 4f121a3a..460119a9 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -184,7 +184,7 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = {      { sizeof(int),                    esd_proto_sample_free_or_play, "sample play" },                /* 8 */      { sizeof(int),                    NULL, "sample loop" },      { sizeof(int),                    NULL, "sample stop" }, -    { -1,                             NULL, "TODO: sample kill" }, +    { (size_t) -1,                    NULL, "TODO: sample kill" },      { ESD_KEY_LEN + sizeof(int),      esd_proto_standby_or_resume, "standby" },  /* NOOP! */      { ESD_KEY_LEN + sizeof(int),      esd_proto_standby_or_resume, "resume" },   /* NOOP! */         /* 13 */ @@ -194,8 +194,8 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = {      { sizeof(int),                    esd_proto_server_info, "server info" },      { sizeof(int),                    esd_proto_all_info, "all info" }, -    { -1,                             NULL, "TODO: subscribe" }, -    { -1,                             NULL, "TODO: unsubscribe" }, +    { (size_t) -1,                    NULL, "TODO: subscribe" }, +    { (size_t) -1,                    NULL, "TODO: unsubscribe" },      { 3 * sizeof(int),                esd_proto_stream_pan, "stream pan"},      { 3 * sizeof(int),                NULL, "sample pan" }, @@ -309,7 +309,7 @@ static void connection_write(connection *c, const void *data, size_t length) {  static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) {      pa_assert(ss); -    ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1; +    ss->channels = (uint8_t) (((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1);      if ((format & ESD_MASK_BITS) == ESD_BITS16)          ss->format = swap_bytes ? PA_SAMPLE_S16RE : PA_SAMPLE_S16NE;      else @@ -334,7 +334,7 @@ static int format_native2esd(pa_sample_spec *ss) {  /*** esound commands ***/ -static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length) {      uint32_t ekey;      int ok; @@ -377,7 +377,7 @@ static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, c      return 0;  } -static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length) {      char name[ESD_NAME_MAX], *utf8_name;      int32_t format, rate;      pa_sample_spec ss; @@ -397,7 +397,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques      rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);      data = (const char*) data + sizeof(int32_t); -    ss.rate = rate; +    ss.rate = (uint32_t) rate;      format_esd2native(format, c->swap_byte_order, &ss);      CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification"); @@ -430,7 +430,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques      CHECK_VALIDITY(c->sink_input, "Failed to create sink input."); -    l = (size_t) (pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS); +    l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);      c->input_memblockq = pa_memblockq_new(              0,              l, @@ -455,7 +455,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques      c->protocol->n_player++; -    pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); +    pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));      pa_sink_input_put(c->sink_input); @@ -482,7 +482,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi      rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);      data = (const char*) data + sizeof(int32_t); -    ss.rate = rate; +    ss.rate = (uint32_t) rate;      format_esd2native(format, c->swap_byte_order, &ss);      CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); @@ -561,7 +561,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi      return 0;  } -static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length) {      pa_sink *sink;      int32_t latency; @@ -572,7 +572,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques      if (!(sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1)))          latency = 0;      else { -        double usec = pa_sink_get_latency(sink); +        double usec = (double) pa_sink_get_latency(sink);          latency = (int) ((usec*44100)/1000000);      } @@ -581,7 +581,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques      return 0;  } -static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length) {      int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16;      int32_t response;      pa_sink *sink; @@ -591,7 +591,7 @@ static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t reques      pa_assert(length == sizeof(int32_t));      if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1))) { -        rate = sink->sample_spec.rate; +        rate = (int32_t) sink->sample_spec.rate;          format = format_native2esd(&sink->sample_spec);      } @@ -641,9 +641,9 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da          if (conn->sink_input) {              pa_cvolume volume = *pa_sink_input_get_volume(conn->sink_input); -            rate = conn->sink_input->sample_spec.rate; -            lvolume = (volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM; -            rvolume = (volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM; +            rate = (int32_t) conn->sink_input->sample_spec.rate; +            lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); +            rvolume = (int32_t) ((volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);              format = format_native2esd(&conn->sink_input->sample_spec);          } @@ -706,15 +706,15 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da              connection_write(c, name, ESD_NAME_MAX);              /* rate */ -            rate = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, ce->sample_spec.rate); +            rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ce->sample_spec.rate);              connection_write(c, &rate, sizeof(int32_t));              /* left */ -            lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); +            lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));              connection_write(c, &lvolume, sizeof(int32_t));              /*right*/ -            rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); +            rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));              connection_write(c, &rvolume, sizeof(int32_t));              /*format*/ @@ -736,7 +736,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da      return 0;  } -static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length) {      int32_t ok;      uint32_t idx, lvolume, rvolume;      connection *conn; @@ -772,7 +772,7 @@ static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request      return 0;  } -static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length) {      pa_sample_spec ss;      int32_t format, rate, sc_length;      uint32_t idx; @@ -790,7 +790,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque      rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);      data = (const char*)data + sizeof(int32_t); -    ss.rate = rate; +    ss.rate = (uint32_t) rate;      format_esd2native(format, c->swap_byte_order, &ss);      CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); @@ -807,9 +807,9 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque      CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");      pa_assert(!c->scache.memchunk.memblock); -    c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, sc_length); +    c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length);      c->scache.memchunk.index = 0; -    c->scache.memchunk.length = sc_length; +    c->scache.memchunk.length = (size_t) sc_length;      c->scache.sample_spec = ss;      pa_assert(!c->scache.name);      c->scache.name = pa_xstrdup(name); @@ -824,7 +824,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque      return 0;  } -static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length) {      int32_t ok;      uint32_t idx;      char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1]; @@ -840,7 +840,7 @@ static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t requ      ok = -1;      if ((idx = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID) -        ok = idx + 1; +        ok = (int32_t) idx + 1;      connection_write(c, &ok, sizeof(int32_t)); @@ -867,12 +867,12 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con              if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1)))                  if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM, c->client->proplist, NULL) >= 0) -                    ok = idx + 1; +                    ok = (int32_t) idx + 1;          } else {              pa_assert(request == ESD_PROTO_SAMPLE_FREE);              if (pa_scache_remove_item(c->protocol->core, name) >= 0) -                ok = idx + 1; +                ok = (int32_t) idx + 1;          }      } @@ -881,7 +881,7 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con      return 0;  } -static int esd_proto_standby_or_resume(connection *c, PA_GCC_UNUSED esd_proto_t request, PA_GCC_UNUSED const void *data, PA_GCC_UNUSED size_t length) { +static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length) {      int32_t ok;      connection_assert_ref(c); @@ -919,7 +919,9 @@ static int do_read(connection *c) {              return -1;          } -        if ((c->read_data_length+= r) >= sizeof(c->request)) { +        c->read_data_length += (size_t) r; + +        if (c->read_data_length >= sizeof(c->request)) {              struct proto_handler *handler;              c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request); @@ -970,7 +972,8 @@ static int do_read(connection *c) {              return -1;          } -        if ((c->read_data_length += r) >= handler->data_length) { +        c->read_data_length += (size_t) r; +        if (c->read_data_length >= handler->data_length) {              size_t l = c->read_data_length;              pa_assert(handler->proc); @@ -1000,7 +1003,7 @@ static int do_read(connection *c) {              return -1;          } -        c->scache.memchunk.index += r; +        c->scache.memchunk.index += (size_t) r;          pa_assert(c->scache.memchunk.index <= c->scache.memchunk.length);          if (c->scache.memchunk.index == c->scache.memchunk.length) { @@ -1033,7 +1036,7 @@ static int do_read(connection *c) {  /*         pa_log("STREAMING_DATA"); */ -        if (!(l = pa_atomic_load(&c->playback.missing))) +        if (!(l = (size_t) pa_atomic_load(&c->playback.missing)))              return 0;          if (c->playback.current_memblock) { @@ -1071,12 +1074,12 @@ static int do_read(connection *c) {          chunk.memblock = c->playback.current_memblock;          chunk.index = c->playback.memblock_index; -        chunk.length = r; +        chunk.length = (size_t) r; -        c->playback.memblock_index += r; +        c->playback.memblock_index += (size_t) r;          pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL); -        pa_atomic_sub(&c->playback.missing, r); +        pa_atomic_sub(&c->playback.missing, (int) r);      }      return 0; @@ -1100,7 +1103,8 @@ static int do_write(connection *c) {              return -1;          } -        if ((c->write_data_index +=r) >= c->write_data_length) +        c->write_data_index += (size_t) r; +        if (c->write_data_index >= c->write_data_length)              c->write_data_length = c->write_data_index = 0;      } else if (c->state == ESD_STREAMING_DATA && c->source_output) { @@ -1129,7 +1133,7 @@ static int do_write(connection *c) {              return -1;          } -        pa_memblockq_drop(c->output_memblockq, r); +        pa_memblockq_drop(c->output_memblockq, (size_t) r);      }      return 0; @@ -1288,7 +1292,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk          m = pa_memblockq_pop_missing(c->input_memblockq);          if (m > 0) -            if (pa_atomic_add(&c->playback.missing, m) <= 0) +            if (pa_atomic_add(&c->playback.missing, (int) m) <= 0)                  pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);          return 0; @@ -1574,7 +1578,7 @@ int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {      if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {          pa_ip_acl *ipa; -        if (!(o->auth_ip_acl = pa_ip_acl_new(acl))) { +        if (!(ipa = pa_ip_acl_new(acl))) {              pa_log("Failed to parse IP ACL '%s'", acl);              return -1;          } diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index ef56a6f4..1ee7a971 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -50,7 +50,6 @@  #include <pulsecore/core-subscribe.h>  #include <pulsecore/log.h>  #include <pulsecore/autoload.h> -#include <pulsecore/authkey-prop.h>  #include <pulsecore/strlist.h>  #include <pulsecore/shared.h>  #include <pulsecore/sample-util.h> @@ -73,13 +72,12 @@  #define DEFAULT_PROCESS_MSEC 20   /* 20ms */  #define DEFAULT_FRAGSIZE_MSEC DEFAULT_TLENGTH_MSEC -typedef struct connection connection;  struct pa_native_protocol;  typedef struct record_stream {      pa_msgobject parent; -    connection *connection; +    pa_native_connection *connection;      uint32_t index;      pa_source_output *source_output; @@ -103,7 +101,7 @@ static PA_DEFINE_CHECK_TYPE(output_stream, pa_msgobject);  typedef struct playback_stream {      output_stream parent; -    connection *connection; +    pa_native_connection *connection;      uint32_t index;      pa_sink_input *sink_input; @@ -129,7 +127,7 @@ static PA_DEFINE_CHECK_TYPE(playback_stream, output_stream);  typedef struct upload_stream {      output_stream parent; -    connection *connection; +    pa_native_connection *connection;      uint32_t index;      pa_memchunk memchunk; @@ -144,7 +142,7 @@ PA_DECLARE_CLASS(upload_stream);  #define UPLOAD_STREAM(o) (upload_stream_cast(o))  static PA_DEFINE_CHECK_TYPE(upload_stream, output_stream); -struct connection { +struct pa_native_connection {      pa_msgobject parent;      pa_native_protocol *protocol;      pa_native_options *options; @@ -160,9 +158,9 @@ struct connection {      pa_time_event *auth_timeout_event;  }; -PA_DECLARE_CLASS(connection); -#define CONNECTION(o) (connection_cast(o)) -static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject); +PA_DECLARE_CLASS(pa_native_connection); +#define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o)) +static PA_DEFINE_CHECK_TYPE(pa_native_connection, pa_msgobject);  struct pa_native_protocol {      PA_REFCNT_DECLARE; @@ -171,10 +169,9 @@ struct pa_native_protocol {      pa_idxset *connections;      pa_strlist *servers; -    pa_hook servers_changed; +    pa_hook hooks[PA_NATIVE_HOOK_MAX];      pa_hashmap *extensions; -  };  enum { @@ -212,8 +209,8 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes);  static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes);  static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes); -static void send_memblock(connection *c); -static void request_bytes(struct playback_stream*s); +static void native_connection_send_memblock(pa_native_connection *c); +static void playback_stream_request_bytes(struct playback_stream*s);  static void source_output_kill_cb(pa_source_output *o);  static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk); @@ -389,7 +386,7 @@ static void upload_stream_free(pa_object *o) {  }  static upload_stream* upload_stream_new( -        connection *c, +        pa_native_connection *c,          const pa_sample_spec *ss,          const pa_channel_map *map,          const char *name, @@ -464,7 +461,7 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i              }              if (!pa_pstream_is_pending(s->connection->pstream)) -                send_memblock(s->connection); +                native_connection_send_memblock(s->connection);              break;      } @@ -480,12 +477,12 @@ static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latenc      if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH)          *maxlength = MAX_MEMBLOCKQ_LENGTH;      if (*maxlength <= 0) -        *maxlength = pa_frame_size(&s->source_output->sample_spec); +        *maxlength = (uint32_t) pa_frame_size(&s->source_output->sample_spec);      if (*fragsize == (uint32_t) -1) -        *fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec); +        *fragsize = (uint32_t) pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec);      if (*fragsize <= 0) -        *fragsize = pa_frame_size(&s->source_output->sample_spec); +        *fragsize = (uint32_t) pa_frame_size(&s->source_output->sample_spec);      if (adjust_latency) {          pa_usec_t fragsize_usec; @@ -504,7 +501,7 @@ static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latenc          else              fragsize_usec = s->source_latency; -        *fragsize = pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec); +        *fragsize = (uint32_t) pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec);      } else          s->source_latency = 0;  } @@ -516,7 +513,7 @@ static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, u      pa_assert(maxlength);      pa_assert(fragsize); -    *maxlength = pa_memblockq_get_maxlength(s->memblockq); +    *maxlength = (uint32_t) pa_memblockq_get_maxlength(s->memblockq);      base = pa_frame_size(&s->source_output->sample_spec); @@ -527,11 +524,11 @@ static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, u      if (s->fragment_size > *maxlength)          s->fragment_size = *maxlength; -    *fragsize = s->fragment_size; +    *fragsize = (uint32_t) s->fragment_size;  }  static record_stream* record_stream_new( -        connection *c, +        pa_native_connection *c,          pa_source *source,          pa_sample_spec *ss,          pa_channel_map *map, @@ -615,6 +612,17 @@ static record_stream* record_stream_new(      return s;  } +static void record_stream_send_killed(record_stream *r) { +    pa_tagstruct *t; +    record_stream_assert_ref(r); + +    t = pa_tagstruct_new(NULL, 0); +    pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED); +    pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ +    pa_tagstruct_putu32(t, r->index); +    pa_pstream_send_tagstruct(r->connection->pstream, t); +} +  static void playback_stream_unlink(playback_stream *s) {      pa_assert(s); @@ -658,10 +666,10 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,              uint32_t l = 0;              for (;;) { -                if ((l = pa_atomic_load(&s->missing)) <= 0) +                if ((l = (uint32_t) pa_atomic_load(&s->missing)) <= 0)                      break; -                if (pa_atomic_cmpxchg(&s->missing, l, 0)) +                if (pa_atomic_cmpxchg(&s->missing, (int) l, 0))                      break;              } @@ -741,20 +749,20 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la      if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH)          *maxlength = MAX_MEMBLOCKQ_LENGTH;      if (*maxlength <= 0) -        *maxlength = frame_size; +        *maxlength = (uint32_t) frame_size;      if (*tlength == (uint32_t) -1) -        *tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec); +        *tlength = (uint32_t) pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);      if (*tlength <= 0) -        *tlength = frame_size; +        *tlength = (uint32_t) frame_size;      if (*minreq == (uint32_t) -1) -        *minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec); +        *minreq = (uint32_t) pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);      if (*minreq <= 0) -        *minreq = frame_size; +        *minreq = (uint32_t) frame_size;      if (*tlength < *minreq+frame_size) -        *tlength = *minreq+frame_size; +        *tlength = *minreq+(uint32_t) frame_size;      tlength_usec = pa_bytes_to_usec(*tlength, &s->sink_input->sample_spec);      minreq_usec = pa_bytes_to_usec(*minreq, &s->sink_input->sample_spec); @@ -815,16 +823,16 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la      if (tlength_usec < s->sink_latency + 2*minreq_usec)          tlength_usec = s->sink_latency + 2*minreq_usec; -    *tlength = pa_usec_to_bytes(tlength_usec, &s->sink_input->sample_spec); -    *minreq = pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec); +    *tlength = (uint32_t) pa_usec_to_bytes(tlength_usec, &s->sink_input->sample_spec); +    *minreq = (uint32_t) pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec);      if (*minreq <= 0) { -        *minreq += frame_size; -        *tlength += frame_size*2; +        *minreq += (uint32_t) frame_size; +        *tlength += (uint32_t) frame_size*2;      }      if (*tlength <= *minreq) -        *tlength =  *minreq*2 + frame_size; +        *tlength = *minreq*2 + (uint32_t) frame_size;      if (*prebuf == (uint32_t) -1 || *prebuf > *tlength)          *prebuf = *tlength; @@ -846,7 +854,7 @@ static void fix_playback_buffer_attr_post(playback_stream *s, uint32_t *maxlengt  }  static playback_stream* playback_stream_new( -        connection *c, +        pa_native_connection *c,          pa_sink *sink,          pa_sample_spec *ss,          pa_channel_map *map, @@ -875,7 +883,6 @@ static playback_stream* playback_stream_new(      pa_assert(tlength);      pa_assert(prebuf);      pa_assert(minreq); -    pa_assert(volume);      pa_assert(missing);      pa_assert(p); @@ -908,7 +915,8 @@ static playback_stream* playback_stream_new(      data.sink = sink;      pa_sink_input_new_data_set_sample_spec(&data, ss);      pa_sink_input_new_data_set_channel_map(&data, map); -    pa_sink_input_new_data_set_volume(&data, volume); +    if (volume) +        pa_sink_input_new_data_set_volume(&data, volume);      pa_sink_input_new_data_set_muted(&data, muted);      data.sync_base = ssync ? ssync->sink_input : NULL; @@ -974,9 +982,42 @@ static playback_stream* playback_stream_new(      return s;  } -static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { -    connection *c = CONNECTION(o); -    connection_assert_ref(c); + +/* Called from thread context */ +static void playback_stream_request_bytes(playback_stream *s) { +    size_t m, previous_missing; + +    playback_stream_assert_ref(s); + +    m = pa_memblockq_pop_missing(s->memblockq); + +    if (m <= 0) +        return; + +/*     pa_log("request_bytes(%lu)", (unsigned long) m); */ + +    previous_missing = (size_t) pa_atomic_add(&s->missing, (int) m); + +    if (pa_memblockq_prebuf_active(s->memblockq) || +        (previous_missing < s->minreq && previous_missing+m >= s->minreq)) +        pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); +} + + +static void playback_stream_send_killed(playback_stream *p) { +    pa_tagstruct *t; +    playback_stream_assert_ref(p); + +    t = pa_tagstruct_new(NULL, 0); +    pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED); +    pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ +    pa_tagstruct_putu32(t, p->index); +    pa_pstream_send_tagstruct(p->connection->pstream, t); +} + +static int native_connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(o); +    pa_native_connection_assert_ref(c);      if (!c->protocol)          return -1; @@ -995,7 +1036,7 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6      return 0;  } -static void connection_unlink(connection *c) { +static void native_connection_unlink(pa_native_connection *c) {      record_stream *r;      output_stream *o; @@ -1004,6 +1045,8 @@ static void connection_unlink(connection *c) {      if (!c->protocol)          return; +    pa_hook_fire(&c->protocol->hooks[PA_NATIVE_HOOK_CONNECTION_UNLINK], c); +      if (c->options)          pa_native_options_unref(c->options); @@ -1029,15 +1072,15 @@ static void connection_unlink(connection *c) {      pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c);      c->protocol = NULL; -    connection_unref(c); +    pa_native_connection_unref(c);  } -static void connection_free(pa_object *o) { -    connection *c = CONNECTION(o); +static void native_connection_free(pa_object *o) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(o);      pa_assert(c); -    connection_unlink(c); +    native_connection_unlink(c);      pa_idxset_free(c->record_streams, NULL, NULL);      pa_idxset_free(c->output_streams, NULL, NULL); @@ -1049,27 +1092,7 @@ static void connection_free(pa_object *o) {      pa_xfree(c);  } -/* Called from thread context */ -static void request_bytes(playback_stream *s) { -    size_t m, previous_missing; - -    playback_stream_assert_ref(s); - -    m = pa_memblockq_pop_missing(s->memblockq); - -    if (m <= 0) -        return; - -/*     pa_log("request_bytes(%lu)", (unsigned long) m); */ - -    previous_missing = pa_atomic_add(&s->missing, m); - -    if (pa_memblockq_prebuf_active(s->memblockq) || -        (previous_missing < s->minreq && previous_missing+m >= s->minreq)) -        pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); -} - -static void send_memblock(connection *c) { +static void native_connection_send_memblock(pa_native_connection *c) {      uint32_t start;      record_stream *r; @@ -1101,28 +1124,6 @@ static void send_memblock(connection *c) {      }  } -static void send_playback_stream_killed(playback_stream *p) { -    pa_tagstruct *t; -    playback_stream_assert_ref(p); - -    t = pa_tagstruct_new(NULL, 0); -    pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED); -    pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ -    pa_tagstruct_putu32(t, p->index); -    pa_pstream_send_tagstruct(p->connection->pstream, t); -} - -static void send_record_stream_killed(record_stream *r) { -    pa_tagstruct *t; -    record_stream_assert_ref(r); - -    t = pa_tagstruct_new(NULL, 0); -    pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED); -    pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ -    pa_tagstruct_putu32(t, r->index); -    pa_pstream_send_tagstruct(r->connection->pstream, t); -} -  /*** sink input callbacks ***/  static void handle_seek(playback_stream *s, int64_t indexw) { @@ -1141,7 +1142,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) {              pa_log_debug("Requesting rewind due to end of underrun.");              pa_sink_input_request_rewind(s->sink_input, -                                         s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for, +                                         (size_t) (s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for),                                           FALSE, TRUE);          } @@ -1155,11 +1156,11 @@ static void handle_seek(playback_stream *s, int64_t indexw) {               * let's have it usk us again */              pa_log_debug("Requesting rewind due to rewrite."); -            pa_sink_input_request_rewind(s->sink_input, indexr - indexw, TRUE, FALSE); +            pa_sink_input_request_rewind(s->sink_input, (size_t) (indexr - indexw), TRUE, FALSE);          }      } -    request_bytes(s); +    playback_stream_request_bytes(s);  }  /* Called from thread context */ @@ -1195,7 +1196,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int              if (pa_memblockq_push_align(s->memblockq, chunk) < 0) {                  pa_log_warn("Failed to push data into queue");                  pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL); -                pa_memblockq_seek(s->memblockq, chunk->length, PA_SEEK_RELATIVE); +                pa_memblockq_seek(s->memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE);              }              handle_seek(s, windex); @@ -1321,7 +1322,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk          s->is_underrun = TRUE; -        request_bytes(s); +        playback_stream_request_bytes(s);      }      /* This call will not fail with prebuf=0, hence we check for @@ -1335,7 +1336,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk          pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_STARTED, NULL, 0, NULL, NULL);      pa_memblockq_drop(s->memblockq, chunk->length); -    request_bytes(s); +    playback_stream_request_bytes(s);      return 0;  } @@ -1386,7 +1387,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {      s = PLAYBACK_STREAM(i->userdata);      playback_stream_assert_ref(s); -    send_playback_stream_killed(s); +    playback_stream_send_killed(s);      playback_stream_unlink(s);  } @@ -1475,7 +1476,7 @@ static void source_output_kill_cb(pa_source_output *o) {      s = RECORD_STREAM(o->userdata);      record_stream_assert_ref(s); -    send_record_stream_killed(s); +    record_stream_send_killed(s);      record_stream_unlink(s);  } @@ -1550,9 +1551,9 @@ static void source_output_moved_cb(pa_source_output *o) {  /*** pdispatch callbacks ***/ -static void protocol_error(connection *c) { +static void protocol_error(pa_native_connection *c) {      pa_log("protocol error, kicking client"); -    connection_unlink(c); +    native_connection_unlink(c);  }  #define CHECK_VALIDITY(pstream, expression, tag, error) do { \ @@ -1571,8 +1572,8 @@ static pa_tagstruct *reply_new(uint32_t tag) {      return reply;  } -static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      playback_stream *s;      uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid, missing;      const char *name = NULL, *sink_name; @@ -1595,8 +1596,9 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC      pa_sink_input_flags_t flags = 0;      pa_proplist *p; +    pa_bool_t volume_set = TRUE; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if ((c->version < 13 && (pa_tagstruct_gets(t, &name) < 0 || !name)) || @@ -1620,7 +1622,9 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(sink_name)), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); @@ -1659,6 +1663,15 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC          }      } +    if (c->version >= 14) { + +        if (pa_tagstruct_get_boolean(t, &volume_set) < 0) { +            protocol_error(c); +            pa_proplist_free(p); +            return; +        } +    } +      if (!pa_tagstruct_eof(t)) {          protocol_error(c);          pa_proplist_free(p); @@ -1692,7 +1705,7 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC          (no_move ?  PA_SINK_INPUT_DONT_MOVE : 0) |          (variable_rate ?  PA_SINK_INPUT_VARIABLE_RATE : 0); -    s = playback_stream_new(c, sink, &ss, &map, &maxlength, &tlength, &prebuf, &minreq, &volume, muted, syncid, &missing, flags, p, adjust_latency); +    s = playback_stream_new(c, sink, &ss, &map, &maxlength, &tlength, &prebuf, &minreq, volume_set ? &volume : NULL, muted, syncid, &missing, flags, p, adjust_latency);      pa_proplist_free(p);      CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); @@ -1734,11 +1747,11 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t channel; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &channel) < 0 || @@ -1792,8 +1805,8 @@ static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      record_stream *s;      uint32_t maxlength, fragment_size;      uint32_t source_index; @@ -1818,7 +1831,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      uint32_t direct_on_input_idx = PA_INVALID_INDEX;      pa_sink_input *direct_on_input = NULL; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if ((c->version < 13 && (pa_tagstruct_gets(t, &name) < 0 || !name)) || @@ -1834,9 +1847,11 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); +    CHECK_VALIDITY(c->pstream, !source_name || pa_namereg_is_valid_name(source_name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, source_index == PA_INVALID_INDEX || !source_name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !source_name || source_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID); -    CHECK_VALIDITY(c->pstream, source_index != PA_INVALID_INDEX || !source_name || (*source_name && pa_utf8_valid(source_name)), tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID);      p = pa_proplist_new(); @@ -1952,10 +1967,11 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); +    int ret; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (!pa_tagstruct_eof(t)) { @@ -1964,18 +1980,19 @@ static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); +    ret = pa_core_exit(c->protocol->core, FALSE, 0); +    CHECK_VALIDITY(c->pstream, ret >= 0, tag, PA_ERR_ACCESS); -    c->protocol->core->mainloop->quit(c->protocol->core->mainloop, 0);      pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */  } -static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const void*cookie;      pa_tagstruct *reply;      pa_bool_t shm_on_remote, do_shm; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &c->version) < 0 || @@ -1992,7 +2009,7 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t      }      /* Starting with protocol version 13 the MSB of the version tag -       reflects if shm is available for this connection or +       reflects if shm is available for this pa_native_connection or         not. */      if (c->version >= 13) {          shm_on_remote = !!(c->version & 0x80000000U); @@ -2100,13 +2117,13 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t  #endif  } -static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const char *name = NULL;      pa_proplist *p;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      p = pa_proplist_new(); @@ -2140,12 +2157,12 @@ static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const char *name;      uint32_t idx = PA_IDXSET_INVALID; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_gets(t, &name) < 0 || @@ -2155,7 +2172,7 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);      if (command == PA_COMMAND_LOOKUP_SINK) {          pa_sink *sink; @@ -2178,12 +2195,12 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin      }  } -static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      playback_stream *s; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2200,12 +2217,12 @@ static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC      pa_asyncmsgq_post(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_DRAIN, PA_UINT_TO_PTR(tag), 0, NULL, NULL);  } -static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_tagstruct *reply;      const pa_mempool_stat *stat; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (!pa_tagstruct_eof(t)) { @@ -2222,19 +2239,19 @@ static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t      pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->allocated_size));      pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->n_accumulated));      pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->accumulated_size)); -    pa_tagstruct_putu32(reply, pa_scache_total_size(c->protocol->core)); +    pa_tagstruct_putu32(reply, (uint32_t) pa_scache_total_size(c->protocol->core));      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_playback_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_tagstruct *reply;      playback_stream *s;      struct timeval tv, now;      uint32_t idx;      pa_usec_t latency; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2272,14 +2289,14 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_tagstruct *reply;      record_stream *s;      struct timeval tv, now;      uint32_t idx; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2304,8 +2321,8 @@ static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      upload_stream *s;      uint32_t length;      const char *name = NULL; @@ -2314,7 +2331,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      pa_tagstruct *reply;      pa_proplist *p; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_gets(t, &name) < 0 || @@ -2346,7 +2363,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_          if (!(name = pa_proplist_gets(p, PA_PROP_EVENT_ID)))              name = pa_proplist_gets(p, PA_PROP_MEDIA_NAME); -    CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);      s = upload_stream_new(c, &ss, &map, name, length, p);      pa_proplist_free(p); @@ -2359,13 +2376,13 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_finish_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t channel;      upload_stream *s;      uint32_t idx; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &channel) < 0 || @@ -2388,8 +2405,8 @@ static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      upload_stream_unlink(s);  } -static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t sink_index;      pa_volume_t volume;      pa_sink *sink; @@ -2398,7 +2415,7 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui      pa_proplist *p;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); @@ -2411,8 +2428,10 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui          return;      } -    CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); -    CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);      if (sink_index != PA_INVALID_INDEX)          sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index); @@ -2430,6 +2449,8 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui          return;      } +    pa_proplist_update(p, PA_UPDATE_MERGE, c->client->proplist); +      if (pa_scache_play_item(c->protocol->core, name, sink, volume, p, &idx) < 0) {          pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);          pa_proplist_free(p); @@ -2446,11 +2467,11 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_remove_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const char *name; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_gets(t, &name) < 0 || @@ -2460,7 +2481,7 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);      if (pa_scache_remove_item(c->protocol->core, name) < 0) {          pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); @@ -2470,7 +2491,7 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void fixup_sample_spec(connection *c, pa_sample_spec *fixed, const pa_sample_spec *original) { +static void fixup_sample_spec(pa_native_connection *c, pa_sample_spec *fixed, const pa_sample_spec *original) {      pa_assert(c);      pa_assert(fixed);      pa_assert(original); @@ -2488,7 +2509,7 @@ static void fixup_sample_spec(connection *c, pa_sample_spec *fixed, const pa_sam      }  } -static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) { +static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sink *sink) {      pa_sample_spec fixed_ss;      pa_assert(t); @@ -2504,8 +2525,8 @@ static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) {          PA_TAG_SAMPLE_SPEC, &fixed_ss,          PA_TAG_CHANNEL_MAP, &sink->channel_map,          PA_TAG_U32, sink->module ? sink->module->index : PA_INVALID_INDEX, -        PA_TAG_CVOLUME, pa_sink_get_volume(sink), -        PA_TAG_BOOLEAN, pa_sink_get_mute(sink), +        PA_TAG_CVOLUME, pa_sink_get_volume(sink, FALSE), +        PA_TAG_BOOLEAN, pa_sink_get_mute(sink, FALSE),          PA_TAG_U32, sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX,          PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL,          PA_TAG_USEC, pa_sink_get_latency(sink), @@ -2519,7 +2540,7 @@ static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) {      }  } -static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *source) { +static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source *source) {      pa_sample_spec fixed_ss;      pa_assert(t); @@ -2535,8 +2556,8 @@ static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *sou          PA_TAG_SAMPLE_SPEC, &fixed_ss,          PA_TAG_CHANNEL_MAP, &source->channel_map,          PA_TAG_U32, source->module ? source->module->index : PA_INVALID_INDEX, -        PA_TAG_CVOLUME, pa_source_get_volume(source), -        PA_TAG_BOOLEAN, pa_source_get_mute(source), +        PA_TAG_CVOLUME, pa_source_get_volume(source, FALSE), +        PA_TAG_BOOLEAN, pa_source_get_mute(source, FALSE),          PA_TAG_U32, source->monitor_of ? source->monitor_of->index : PA_INVALID_INDEX,          PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL,          PA_TAG_USEC, pa_source_get_latency(source), @@ -2551,7 +2572,7 @@ static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *sou  } -static void client_fill_tagstruct(connection *c, pa_tagstruct *t, pa_client *client) { +static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_client *client) {      pa_assert(t);      pa_assert(client); @@ -2572,11 +2593,11 @@ static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) {      pa_tagstruct_putu32(t, module->index);      pa_tagstruct_puts(t, module->name);      pa_tagstruct_puts(t, module->argument); -    pa_tagstruct_putu32(t, module->n_used); +    pa_tagstruct_putu32(t, (uint32_t) module->n_used);      pa_tagstruct_put_boolean(t, module->auto_unload);  } -static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_input *s) { +static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sink_input *s) {      pa_sample_spec fixed_ss;      pa_usec_t sink_latency; @@ -2603,7 +2624,7 @@ static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_in          pa_tagstruct_put_proplist(t, s->proplist);  } -static void source_output_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source_output *s) { +static void source_output_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source_output *s) {      pa_sample_spec fixed_ss;      pa_usec_t source_latency; @@ -2628,7 +2649,7 @@ static void source_output_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sour          pa_tagstruct_put_proplist(t, s->proplist);  } -static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entry *e) { +static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_scache_entry *e) {      pa_sample_spec fixed_ss;      pa_assert(t); @@ -2645,7 +2666,7 @@ static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entr      pa_tagstruct_put_usec(t, e->memchunk.memblock ? pa_bytes_to_usec(e->memchunk.length, &e->sample_spec) : 0);      pa_tagstruct_put_sample_spec(t, &fixed_ss);      pa_tagstruct_put_channel_map(t, &e->channel_map); -    pa_tagstruct_putu32(t, e->memchunk.length); +    pa_tagstruct_putu32(t, (uint32_t) e->memchunk.length);      pa_tagstruct_put_boolean(t, e->lazy);      pa_tagstruct_puts(t, e->filename); @@ -2653,8 +2674,8 @@ static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entr          pa_tagstruct_put_proplist(t, e->proplist);  } -static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      pa_sink *sink = NULL;      pa_source *source = NULL; @@ -2666,7 +2687,7 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u      const char *name;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2681,7 +2702,10 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      if (command == PA_COMMAND_GET_SINK_INFO) {          if (idx != PA_INVALID_INDEX) @@ -2732,14 +2756,14 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_idxset *i;      uint32_t idx;      void *p;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (!pa_tagstruct_eof(t)) { @@ -2792,14 +2816,14 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_tagstruct *reply;      char txt[256];      const char *n;      pa_sample_spec fixed_ss; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (!pa_tagstruct_eof(t)) { @@ -2830,9 +2854,9 @@ static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE  static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) {      pa_tagstruct *t; -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      t = pa_tagstruct_new(NULL, 0);      pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT); @@ -2842,11 +2866,11 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint3      pa_pstream_send_tagstruct(c->pstream, t);  } -static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_subscription_mask_t m; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &m) < 0 || @@ -2871,13 +2895,13 @@ static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint  }  static void command_set_volume( -        PA_GCC_UNUSED pa_pdispatch *pd, +        pa_pdispatch *pd,          uint32_t command,          uint32_t tag,          pa_tagstruct *t,          void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      pa_cvolume volume;      pa_sink *sink = NULL; @@ -2885,7 +2909,7 @@ static void command_set_volume(      pa_sink_input *si = NULL;      const char *name = NULL; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2898,7 +2922,10 @@ static void command_set_volume(      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID);      switch (command) { @@ -2938,13 +2965,13 @@ static void command_set_volume(  }  static void command_set_mute( -        PA_GCC_UNUSED pa_pdispatch *pd, +        pa_pdispatch *pd,          uint32_t command,          uint32_t tag,          pa_tagstruct *t,          void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      pa_bool_t mute;      pa_sink *sink = NULL; @@ -2952,7 +2979,7 @@ static void command_set_mute(      pa_sink_input *si = NULL;      const char *name = NULL; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -2965,7 +2992,10 @@ static void command_set_mute(      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      switch (command) { @@ -3006,13 +3036,13 @@ static void command_set_mute(      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      pa_bool_t b;      playback_stream *s; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3032,12 +3062,12 @@ static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      playback_stream *s; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3072,13 +3102,13 @@ static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      record_stream *s;      pa_bool_t b; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3097,12 +3127,12 @@ static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      record_stream *s; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3120,12 +3150,12 @@ static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_U  }  static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      uint32_t maxlength, tlength, prebuf, minreq, fragsize;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0) { @@ -3207,11 +3237,11 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u  }  static void command_update_stream_sample_rate(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      uint32_t rate; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3247,12 +3277,12 @@ static void command_update_stream_sample_rate(pa_pdispatch *pd, uint32_t command  }  static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      uint32_t mode;      pa_proplist *p; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); @@ -3312,13 +3342,13 @@ static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t  }  static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      unsigned changed = 0;      pa_proplist *p;      pa_strlist *l = NULL; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); @@ -3382,7 +3412,7 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t          if (!z)              break; -        changed += pa_proplist_unset(p, z) >= 0; +        changed += (unsigned) (pa_proplist_unset(p, z) >= 0);          pa_xfree(z);      } @@ -3408,11 +3438,11 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t      }  } -static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const char *s; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_gets(t, &s) < 0 || @@ -3422,18 +3452,18 @@ static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, u      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, !s || (*s && pa_utf8_valid(s)), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !s || pa_namereg_is_valid_name(s), tag, PA_ERR_INVALID);      pa_namereg_set_default(c->protocol->core, s, command == PA_COMMAND_SET_DEFAULT_SOURCE ? PA_NAMEREG_SOURCE : PA_NAMEREG_SINK);      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      const char *name; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3468,11 +3498,11 @@ static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t com      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3489,7 +3519,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3          client = pa_idxset_get_by_index(c->protocol->core->clients, idx);          CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY); -        connection_ref(c); +        pa_native_connection_ref(c);          pa_client_kill(client);      } else if (command == PA_COMMAND_KILL_SINK_INPUT) { @@ -3498,7 +3528,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3          s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);          CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); -        connection_ref(c); +        pa_native_connection_ref(c);          pa_sink_input_kill(s);      } else {          pa_source_output *s; @@ -3508,21 +3538,21 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3          s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);          CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); -        connection_ref(c); +        pa_native_connection_ref(c);          pa_source_output_kill(s);      }      pa_pstream_send_simple_ack(c->pstream, tag); -    connection_unref(c); +    pa_native_connection_unref(c);  } -static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_module *m;      const char *name, *argument;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_gets(t, &name) < 0 || @@ -3546,12 +3576,12 @@ static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx;      pa_module *m; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3564,18 +3594,18 @@ static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED      m = pa_idxset_get_by_index(c->protocol->core->modules, idx);      CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY); -    pa_module_unload_request(m); +    pa_module_unload_request(m, FALSE);      pa_pstream_send_simple_ack(c->pstream, tag);  } -static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_add_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const char *name, *module, *argument;      uint32_t type;      uint32_t idx;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_gets(t, &name) < 0 || @@ -3603,13 +3633,13 @@ static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED u      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_remove_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const char *name = NULL;      uint32_t type, idx = PA_IDXSET_INVALID;      int r; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if ((pa_tagstruct_getu32(t, &idx) < 0 && @@ -3639,19 +3669,19 @@ static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e)      pa_tagstruct_putu32(t, e->index);      pa_tagstruct_puts(t, e->name); -    pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1); +    pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0U : 1U);      pa_tagstruct_puts(t, e->module);      pa_tagstruct_puts(t, e->argument);  } -static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_autoload_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      const pa_autoload_entry *a = NULL;      uint32_t type, idx;      const char *name;      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if ((pa_tagstruct_getu32(t, &idx) < 0 && @@ -3678,11 +3708,11 @@ static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNU      pa_pstream_send_tagstruct(c->pstream, reply);  } -static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +static void command_get_autoload_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_tagstruct *reply; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (!pa_tagstruct_eof(t)) { @@ -3706,16 +3736,16 @@ static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC  }  static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx = PA_INVALID_INDEX, idx_device = PA_INVALID_INDEX; -    const char *name = NULL; +    const char *name_device = NULL; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 ||          pa_tagstruct_getu32(t, &idx_device) < 0 || -        pa_tagstruct_gets(t, &name) < 0 || +        pa_tagstruct_gets(t, &name_device) < 0 ||          !pa_tagstruct_eof(t)) {          protocol_error(c);          return; @@ -3723,7 +3753,11 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);      CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); -    CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); + +    CHECK_VALIDITY(c->pstream, !name_device || pa_namereg_is_valid_name(name_device), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || name_device, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx_device == PA_INVALID_INDEX || !name_device, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name_device || idx_device == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      if (command == PA_COMMAND_MOVE_SINK_INPUT) {          pa_sink_input *si = NULL; @@ -3734,7 +3768,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag          if (idx_device != PA_INVALID_INDEX)              sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx_device);          else -            sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); +            sink = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SINK, 1);          CHECK_VALIDITY(c->pstream, si && sink, tag, PA_ERR_NOENTITY); @@ -3753,7 +3787,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag          if (idx_device != PA_INVALID_INDEX)              source = pa_idxset_get_by_index(c->protocol->core->sources, idx_device);          else -            source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); +            source = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SOURCE, 1);          CHECK_VALIDITY(c->pstream, so && source, tag, PA_ERR_NOENTITY); @@ -3767,12 +3801,12 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag  }  static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx = PA_INVALID_INDEX;      const char *name = NULL;      pa_bool_t b; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3784,7 +3818,10 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      if (command == PA_COMMAND_SUSPEND_SINK) { @@ -3841,13 +3878,13 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa  }  static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      uint32_t idx = PA_INVALID_INDEX;      const char *name = NULL;      pa_module *m;      pa_native_protocol_ext_cb_t cb; -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(t);      if (pa_tagstruct_getu32(t, &idx) < 0 || @@ -3857,7 +3894,10 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,      }      CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || pa_utf8_valid(name), tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID); +    CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);      if (idx != PA_INVALID_INDEX)          m = pa_idxset_get_by_index(c->protocol->core->modules, idx); @@ -3873,32 +3913,33 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,      cb = (pa_native_protocol_ext_cb_t) pa_hashmap_get(c->protocol->extensions, m);      CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOEXTENSION); -    cb(c->protocol, m, c->pstream, tag, t); +    if (cb(c->protocol, m, c, tag, t) < 0) +        protocol_error(c);  }  /*** pstream callbacks ***/  static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_assert(p);      pa_assert(packet); -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0) {          pa_log("invalid packet."); -        connection_unlink(c); +        native_connection_unlink(c);      }  }  static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      output_stream *stream;      pa_assert(p);      pa_assert(chunk); -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      if (!(stream = OUTPUT_STREAM(pa_idxset_get_by_index(c->output_streams, channel)))) {          pa_log("client sent block for invalid stream."); @@ -3954,22 +3995,22 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o  }  static void pstream_die_callback(pa_pstream *p, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_assert(p); -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c); -    connection_unlink(c); -    pa_log_info("connection died."); +    native_connection_unlink(c); +    pa_log_info("Connection died.");  }  static void pstream_drain_callback(pa_pstream *p, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_assert(p); -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c); -    send_memblock(c); +    native_connection_send_memblock(c);  }  static void pstream_revoke_callback(pa_pstream *p, uint32_t block_id, void *userdata) { @@ -3995,25 +4036,28 @@ static void pstream_release_callback(pa_pstream *p, uint32_t block_id, void *use  static void client_kill_cb(pa_client *c) {      pa_assert(c); -    connection_unlink(CONNECTION(c->userdata)); +    native_connection_unlink(PA_NATIVE_CONNECTION(c->userdata)); +    pa_log_info("Connection killed.");  }  /*** module entry points ***/  static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { -    connection *c = CONNECTION(userdata); +    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);      pa_assert(m);      pa_assert(tv); -    connection_assert_ref(c); +    pa_native_connection_assert_ref(c);      pa_assert(c->auth_timeout_event == e); -    if (!c->authorized) -        connection_unlink(c); +    if (!c->authorized) { +        native_connection_unlink(c); +        pa_log_info("Connection terminated due to authentication timeout."); +    }  }  void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *o) { -    connection *c; +    pa_native_connection *c;      char cname[256], pname[128];      pa_assert(p); @@ -4026,9 +4070,9 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati          return;      } -    c = pa_msgobject_new(connection); -    c->parent.parent.free = connection_free; -    c->parent.process_msg = connection_process_msg; +    c = pa_msgobject_new(pa_native_connection); +    c->parent.parent.free = native_connection_free; +    c->parent.process_msg = native_connection_process_msg;      c->protocol = p;      c->options = pa_native_options_ref(o);      c->authorized = FALSE; @@ -4087,10 +4131,12 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati      if (pa_iochannel_creds_supported(io))          pa_iochannel_creds_enable(io);  #endif + +    pa_hook_fire(&p->hooks[PA_NATIVE_HOOK_CONNECTION_PUT], c);  }  void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m) { -    connection *c; +    pa_native_connection *c;      void *state = NULL;      pa_assert(p); @@ -4098,11 +4144,12 @@ void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m) {      while ((c = pa_idxset_iterate(p->connections, &state, NULL)))          if (c->options->module == m) -            connection_unlink(c); +            native_connection_unlink(c);  }  static pa_native_protocol* native_protocol_new(pa_core *c) {      pa_native_protocol *p; +    pa_native_hook_t h;      pa_assert(c); @@ -4112,7 +4159,11 @@ static pa_native_protocol* native_protocol_new(pa_core *c) {      p->connections = pa_idxset_new(NULL, NULL);      p->servers = NULL; -    pa_hook_init(&p->servers_changed, p); + +    p->extensions = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + +    for (h = 0; h < PA_NATIVE_HOOK_MAX; h++) +        pa_hook_init(&p->hooks[h], p);      pa_assert_se(pa_shared_set(c, "native-protocol", p) >= 0); @@ -4138,7 +4189,9 @@ pa_native_protocol* pa_native_protocol_ref(pa_native_protocol *p) {  }  void pa_native_protocol_unref(pa_native_protocol *p) { -    connection *c; +    pa_native_connection *c; +    pa_native_hook_t h; +      pa_assert(p);      pa_assert(PA_REFCNT_VALUE(p) >= 1); @@ -4146,12 +4199,16 @@ void pa_native_protocol_unref(pa_native_protocol *p) {          return;      while ((c = pa_idxset_first(p->connections, NULL))) -        connection_unlink(c); +        native_connection_unlink(c);      pa_idxset_free(p->connections, NULL, NULL);      pa_strlist_free(p->servers); -    pa_hook_done(&p->servers_changed); + +    for (h = 0; h < PA_NATIVE_HOOK_MAX; h++) +        pa_hook_done(&p->hooks[h]); + +    pa_hashmap_free(p->extensions, NULL, NULL);      pa_assert_se(pa_shared_remove(p->core, "native-protocol") >= 0); @@ -4165,7 +4222,7 @@ void pa_native_protocol_add_server_string(pa_native_protocol *p, const char *nam      p->servers = pa_strlist_prepend(p->servers, name); -    pa_hook_fire(&p->servers_changed, p->servers); +    pa_hook_fire(&p->hooks[PA_NATIVE_HOOK_SERVERS_CHANGED], p->servers);  }  void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *name) { @@ -4175,14 +4232,14 @@ void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *      p->servers = pa_strlist_remove(p->servers, name); -    pa_hook_fire(&p->servers_changed, p->servers); +    pa_hook_fire(&p->hooks[PA_NATIVE_HOOK_SERVERS_CHANGED], p->servers);  } -pa_hook *pa_native_protocol_servers_changed(pa_native_protocol *p) { +pa_hook *pa_native_protocol_hooks(pa_native_protocol *p) {      pa_assert(p);      pa_assert(PA_REFCNT_VALUE(p) >= 1); -    return &p->servers_changed; +    return p->hooks;  }  pa_strlist *pa_native_protocol_servers(pa_native_protocol *p) { @@ -4277,7 +4334,7 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {      if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {          pa_ip_acl *ipa; -        if (!(o->auth_ip_acl = pa_ip_acl_new(acl))) { +        if (!(ipa = pa_ip_acl_new(acl))) {              pa_log("Failed to parse IP ACL '%s'", acl);              return -1;          } @@ -4314,3 +4371,9 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {      return 0;  } + +pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c) { +    pa_native_connection_assert_ref(c); + +    return c->pstream; +} diff --git a/src/pulsecore/protocol-native.h b/src/pulsecore/protocol-native.h index b3db305c..06731c0c 100644 --- a/src/pulsecore/protocol-native.h +++ b/src/pulsecore/protocol-native.h @@ -36,6 +36,8 @@  typedef struct pa_native_protocol pa_native_protocol; +typedef struct pa_native_connection pa_native_connection; +  typedef struct pa_native_options {      PA_REFCNT_DECLARE; @@ -48,22 +50,37 @@ typedef struct pa_native_options {  } pa_native_options; +typedef enum pa_native_hook { +    PA_NATIVE_HOOK_SERVERS_CHANGED, +    PA_NATIVE_HOOK_CONNECTION_PUT, +    PA_NATIVE_HOOK_CONNECTION_UNLINK, +    PA_NATIVE_HOOK_MAX +} pa_native_hook_t; +  pa_native_protocol* pa_native_protocol_get(pa_core *core);  pa_native_protocol* pa_native_protocol_ref(pa_native_protocol *p);  void pa_native_protocol_unref(pa_native_protocol *p);  void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *a);  void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m); +pa_hook *pa_native_protocol_hooks(pa_native_protocol *p); +  void pa_native_protocol_add_server_string(pa_native_protocol *p, const char *name);  void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *name); - -pa_hook *pa_native_protocol_servers_changed(pa_native_protocol *p);  pa_strlist *pa_native_protocol_servers(pa_native_protocol *p); -typedef void (*pa_native_protocol_ext_cb_t)(pa_native_protocol *p, pa_module *m, pa_pstream *ps, uint32_t tag, pa_tagstruct *t); +typedef int (*pa_native_protocol_ext_cb_t)( +        pa_native_protocol *p, +        pa_module *m, +        pa_native_connection *c, +        uint32_t tag, +        pa_tagstruct *t); +  int pa_native_protocol_install_ext(pa_native_protocol *p, pa_module *m, pa_native_protocol_ext_cb_t cb);  void pa_native_protocol_remove_ext(pa_native_protocol *p, pa_module *m); +pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c); +  pa_native_options* pa_native_options_new(void);  pa_native_options* pa_native_options_ref(pa_native_options *o);  void pa_native_options_unref(pa_native_options *o); diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 78874bb9..65e67737 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -159,7 +159,7 @@ static int do_read(connection *c) {      connection_assert_ref(c); -    if (!c->sink_input || (l = pa_atomic_load(&c->playback.missing)) <= 0) +    if (!c->sink_input || (l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0)          return 0;      if (c->playback.current_memblock) { @@ -197,12 +197,12 @@ static int do_read(connection *c) {      chunk.memblock = c->playback.current_memblock;      chunk.index = c->playback.memblock_index; -    chunk.length = r; +    chunk.length = (size_t) r; -    c->playback.memblock_index += r; +    c->playback.memblock_index += (size_t) r;      pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL); -    pa_atomic_sub(&c->playback.missing, r); +    pa_atomic_sub(&c->playback.missing, (int) r);      return 0;  } @@ -240,7 +240,7 @@ static int do_write(connection *c) {          return -1;      } -    pa_memblockq_drop(c->output_memblockq, r); +    pa_memblockq_drop(c->output_memblockq, (size_t) r);      return 0;  } @@ -377,7 +377,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk          m = pa_memblockq_pop_missing(c->input_memblockq);          if (m > 0) -            if (pa_atomic_add(&c->playback.missing, m) <= 0) +            if (pa_atomic_add(&c->playback.missing, (int) m) <= 0)                  pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);          return 0; @@ -546,7 +546,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp          pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY); -        l = (size_t) (pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS); +        l = (size_t) ((double) pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS);          c->input_memblockq = pa_memblockq_new(                  0,                  l, @@ -558,7 +558,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp                  NULL);          pa_iochannel_socket_set_rcvbuf(io, l); -        pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); +        pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));          pa_sink_input_put(c->sink_input);      } diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 6b1af67b..7ff8edc9 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -283,7 +283,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo      return p;  } -static void item_free(void *item, PA_GCC_UNUSED void *q) { +static void item_free(void *item, void *q) {      struct item_info *i = item;      pa_assert(i); @@ -488,7 +488,7 @@ static void prepare_next_write_item(pa_pstream *p) {          pa_assert(p->write.current->packet);          p->write.data = p->write.current->packet->data; -        p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->packet->length); +        p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->packet->length);      } else if (p->write.current->type == PA_PSTREAM_ITEM_SHMRELEASE) { @@ -511,7 +511,7 @@ static void prepare_next_write_item(pa_pstream *p) {          p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = htonl((uint32_t) (((uint64_t) p->write.current->offset) >> 32));          p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = htonl((uint32_t) ((uint64_t) p->write.current->offset)); -        flags = p->write.current->seek_mode & PA_FLAG_SEEKMASK; +        flags = (uint32_t) (p->write.current->seek_mode & PA_FLAG_SEEKMASK);          if (p->use_shm) {              uint32_t block_id, shm_id; @@ -542,7 +542,7 @@ static void prepare_next_write_item(pa_pstream *p) {          }          if (send_payload) { -            p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->chunk.length); +            p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->chunk.length);              p->write.memchunk = p->write.current->chunk;              pa_memblock_ref(p->write.memchunk.memblock);              p->write.data = NULL; @@ -607,7 +607,7 @@ static int do_write(pa_pstream *p) {      if (release_memblock)          pa_memblock_release(release_memblock); -    p->write.index += r; +    p->write.index += (size_t) r;      if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE + ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) {          pa_assert(p->write.current); @@ -675,7 +675,7 @@ static int do_read(pa_pstream *p) {      if (release_memblock)          pa_memblock_release(release_memblock); -    p->read.index += r; +    p->read.index += (size_t) r;      if (p->read.index == PA_PSTREAM_DESCRIPTOR_SIZE) {          uint32_t flags, length, channel; @@ -769,7 +769,7 @@ static int do_read(pa_pstream *p) {          if (p->read.memblock && p->recieve_memblock_callback) {              /* Is this memblock data? Than pass it to the user */ -            l = (p->read.index - r) < PA_PSTREAM_DESCRIPTOR_SIZE ? p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE : (size_t) r; +            l = (p->read.index - (size_t) r) < PA_PSTREAM_DESCRIPTOR_SIZE ? (size_t) (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE) : (size_t) r;              if (l > 0) {                  pa_memchunk chunk; diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index c82f4c1e..b20fc61f 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -373,7 +373,7 @@ size_t pa_resampler_max_block_size(pa_resampler *r) {      /* We deduce the "largest" sample spec we're using during the       * conversion */ -    ss.channels = PA_MAX(r->i_ss.channels, r->o_ss.channels); +    ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));      /* We silently assume that the format enum is ordered by size */      ss.format = PA_MAX(r->i_ss.format, r->o_ss.format); @@ -642,7 +642,7 @@ static void calc_map_table(pa_resampler *r) {                  if (n > 0)                      for (ic = 0; ic < r->i_ss.channels; ic++)                          if (on_left(r->i_cm.map[ic])) { -                            r->map_table[oc][ic] = 1.0 / n; +                            r->map_table[oc][ic] = 1.0f / (float) n;                              ic_connected[ic] = TRUE;                          } @@ -663,7 +663,7 @@ static void calc_map_table(pa_resampler *r) {                  if (n > 0)                      for (ic = 0; ic < r->i_ss.channels; ic++)                          if (on_right(r->i_cm.map[ic])) { -                            r->map_table[oc][ic] = 1.0 / n; +                            r->map_table[oc][ic] = 1.0f / (float) n;                              ic_connected[ic] = TRUE;                          } @@ -684,7 +684,7 @@ static void calc_map_table(pa_resampler *r) {                  if (n > 0) {                      for (ic = 0; ic < r->i_ss.channels; ic++)                          if (on_center(r->i_cm.map[ic])) { -                            r->map_table[oc][ic] = 1.0 / n; +                            r->map_table[oc][ic] = 1.0f / (float) n;                              ic_connected[ic] = TRUE;                          }                  } else { @@ -701,7 +701,7 @@ static void calc_map_table(pa_resampler *r) {                      if (n > 0)                          for (ic = 0; ic < r->i_ss.channels; ic++)                              if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) { -                                r->map_table[oc][ic] = 1.0 / n; +                                r->map_table[oc][ic] = 1.0f / (float) n;                                  ic_connected[ic] = TRUE;                              } @@ -716,7 +716,7 @@ static void calc_map_table(pa_resampler *r) {                   * channels for LFE. */                  for (ic = 0; ic < r->i_ss.channels; ic++) { -                    r->map_table[oc][ic] = 1.0 / r->i_ss.channels; +                    r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;                      /* Please note that a channel connected to LFE                       * doesn't really count as connected. */ @@ -763,12 +763,12 @@ static void calc_map_table(pa_resampler *r) {                  for (ic = 0; ic < r->i_ss.channels; ic++) {                      if (ic_connected[ic]) { -                        r->map_table[oc][ic] *= .9; +                        r->map_table[oc][ic] *= .9f;                          continue;                      }                      if (on_left(r->i_cm.map[ic])) -                        r->map_table[oc][ic] = .1 / ic_unconnected_left; +                        r->map_table[oc][ic] = .1f / (float) ic_unconnected_left;                  }              }          } @@ -788,12 +788,12 @@ static void calc_map_table(pa_resampler *r) {                  for (ic = 0; ic < r->i_ss.channels; ic++) {                      if (ic_connected[ic]) { -                        r->map_table[oc][ic] *= .9; +                        r->map_table[oc][ic] *= .9f;                          continue;                      }                      if (on_right(r->i_cm.map[ic])) -                        r->map_table[oc][ic] = .1 / ic_unconnected_right; +                        r->map_table[oc][ic] = .1f / (float) ic_unconnected_right;                  }              }          } @@ -814,12 +814,12 @@ static void calc_map_table(pa_resampler *r) {                  for (ic = 0; ic < r->i_ss.channels; ic++)  {                      if (ic_connected[ic]) { -                        r->map_table[oc][ic] *= .9; +                        r->map_table[oc][ic] *= .9f;                          continue;                      }                      if (on_center(r->i_cm.map[ic])) { -                        r->map_table[oc][ic] = .1 / ic_unconnected_center; +                        r->map_table[oc][ic] = .1f / (float) ic_unconnected_center;                          mixed_in = TRUE;                      }                  } @@ -840,12 +840,12 @@ static void calc_map_table(pa_resampler *r) {                      for (ic = 0; ic < r->i_ss.channels; ic++)  {                          if (ic_connected[ic]) { -                            r->map_table[oc][ic] *= .75; +                            r->map_table[oc][ic] *= .75f;                              continue;                          }                          if (on_center(r->i_cm.map[ic])) -                            r->map_table[oc][ic] = .375 / ic_unconnected_center; +                            r->map_table[oc][ic] = .375f / (float) ic_unconnected_center;                      }                  }              } @@ -862,7 +862,7 @@ static void calc_map_table(pa_resampler *r) {                      continue;                  for (oc = 0; oc < r->o_ss.channels; oc++) -                    r->map_table[oc][ic] = 0.375 / ic_unconnected_lfe; +                    r->map_table[oc][ic] = 0.375f / (float) ic_unconnected_lfe;              }          }      } @@ -905,7 +905,7 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)      if (!r->to_work_format_func || !input->length)          return input; -    n_samples = (input->length / r->i_fz) * r->i_ss.channels; +    n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);      r->buf1.index = 0;      r->buf1.length = r->w_sz * n_samples; @@ -974,7 +974,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {      if (!r->map_required || !input->length)          return input; -    in_n_samples = input->length / r->w_sz; +    in_n_samples = (unsigned) (input->length / r->w_sz);      n_frames = in_n_samples / r->i_ss.channels;      out_n_samples = n_frames * r->o_ss.channels; @@ -994,8 +994,8 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {      memset(dst, 0, r->buf2.length); -    o_skip = r->w_sz * r->o_ss.channels; -    i_skip = r->w_sz * r->i_ss.channels; +    o_skip = (int) (r->w_sz * r->o_ss.channels); +    i_skip = (int) (r->w_sz * r->i_ss.channels);      switch (r->work_format) {          case PA_SAMPLE_FLOAT32NE: @@ -1013,7 +1013,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {                              (float*) dst + oc, o_skip,                              (float*) dst + oc, o_skip,                              (float*) src + ic, i_skip, -                            n_frames, +                            (int) n_frames,                              &one, &r->map_table[oc][ic]);                  }              } @@ -1037,7 +1037,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {                                  (int16_t*) dst + oc, o_skip,                                  (int16_t*) dst + oc, o_skip,                                  (int16_t*) src + ic, i_skip, -                                n_frames, +                                (int) n_frames,                                  &one, &one);                      } else @@ -1046,7 +1046,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {                                  (int16_t*) dst + oc, o_skip,                                  (int16_t*) dst + oc, o_skip,                                  (int16_t*) src + ic, i_skip, -                                n_frames, +                                (int) n_frames,                                  1.0, r->map_table[oc][ic]);                  }              } @@ -1077,8 +1077,8 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {      if (!r->impl_resample || !input->length)          return input; -    in_n_samples = input->length / r->w_sz; -    in_n_frames = in_n_samples / r->o_ss.channels; +    in_n_samples = (unsigned) (input->length / r->w_sz); +    in_n_frames = (unsigned) (in_n_samples / r->o_ss.channels);      out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES;      out_n_samples = out_n_frames * r->o_ss.channels; @@ -1112,8 +1112,8 @@ static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input      if (!r->from_work_format_func || !input->length)          return input; -    n_samples = input->length / r->w_sz; -    n_frames =  n_samples / r->o_ss.channels; +    n_samples = (unsigned) (input->length / r->w_sz); +    n_frames = n_samples / r->o_ss.channels;      r->buf4.index = 0;      r->buf4.length = r->o_fz * n_frames; @@ -1178,10 +1178,10 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un      memset(&data, 0, sizeof(data));      data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); -    data.input_frames = in_n_frames; +    data.input_frames = (long int) in_n_frames;      data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); -    data.output_frames = *out_n_frames; +    data.output_frames = (long int) *out_n_frames;      data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;      data.end_of_input = 0; @@ -1192,7 +1192,7 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un      pa_memblock_release(input->memblock);      pa_memblock_release(output->memblock); -    *out_n_frames = data.output_frames_gen; +    *out_n_frames = (unsigned) data.output_frames_gen;  }  static void libsamplerate_update_rates(pa_resampler *r) { @@ -1354,7 +1354,7 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned          pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));          oil_memcpy((uint8_t*) dst + fz * o_index, -                   (uint8_t*) src + fz * j, fz); +                   (uint8_t*) src + fz * j, (int) fz);      }      pa_memblock_release(input->memblock); @@ -1430,7 +1430,7 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i                  for (c = 0; c < r->o_ss.channels; c++, s++) {                      int16_t n; -                    n = *s < 0 ? -*s : *s; +                    n = (int16_t) (*s < 0 ? -*s : *s);                      if (n > r->peaks.max_i[c])                          r->peaks.max_i[c] = n; @@ -1523,7 +1523,7 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned          p = pa_memblock_acquire(b);          /* Copy the remaining data into it */ -        l = r->ffmpeg.buf[c].length; +        l = (unsigned) r->ffmpeg.buf[c].length;          if (r->ffmpeg.buf[c].memblock) {              t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);              memcpy(p, t, l); @@ -1543,18 +1543,18 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned          pa_memblock_release(input->memblock);          /* Calculate the resulting number of frames */ -        in = in_n_frames + l / sizeof(int16_t); +        in = (unsigned) in_n_frames + l / (unsigned) sizeof(int16_t);          /* Allocate buffer for the result */          w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));          q = pa_memblock_acquire(w);          /* Now, resample */ -        used_frames = av_resample(r->ffmpeg.state, -                                  q, p, -                                  &consumed_frames, -                                  in, *out_n_frames, -                                  c >= (unsigned) r->o_ss.channels-1); +        used_frames = (unsigned) av_resample(r->ffmpeg.state, +                                             q, p, +                                             &consumed_frames, +                                             (int) in, (int) *out_n_frames, +                                             c >= (unsigned) (r->o_ss.channels-1));          pa_memblock_release(b); @@ -1562,8 +1562,8 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned          pa_assert(consumed_frames <= (int) in);          if (consumed_frames < (int) in) {              r->ffmpeg.buf[c].memblock = b; -            r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t); -            r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t); +            r->ffmpeg.buf[c].index = (size_t) consumed_frames * sizeof(int16_t); +            r->ffmpeg.buf[c].length = (size_t) (in - (unsigned) consumed_frames) * sizeof(int16_t);          } else              pa_memblock_unref(b); @@ -1605,7 +1605,7 @@ static int ffmpeg_init(pa_resampler *r) {       * internally only uses these hardcoded values, so let's use them       * here for now as well until ffmpeg makes this configurable. */ -    if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8))) +    if (!(r->ffmpeg.state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8)))          return -1;      r->impl_free = ffmpeg_free; diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index 705de48f..aa2cdace 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -23,6 +23,7 @@  ***/  #include <pulsecore/macro.h> +#include <pulse/sample.h>  struct timeval; diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index a67a5516..543262bc 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -394,7 +394,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {  #endif  #endif -        r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (timeout.tv_sec*1000) + (timeout.tv_usec / 1000) : -1); +        r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);      if (r < 0) {          if (errno == EAGAIN || errno == EINTR) diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index 4df217c3..4cd6aa8f 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -40,7 +40,7 @@ static void _free_rtsig(void *p) {      pa_rtsig_put(PA_PTR_TO_INT(p));  } -PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two(SIGRTMAX-SIGRTMIN+1), NULL); +PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two((unsigned) (SIGRTMAX-SIGRTMIN+1)), NULL);  PA_STATIC_TLS_DECLARE(rtsig_tls, _free_rtsig);  static pa_atomic_t rtsig_current = PA_ATOMIC_INIT(-1); diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index b42b79d1..4b2efe5e 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -85,7 +85,6 @@ static uint8_t silence_byte(pa_sample_format_t format) {          default:              pa_assert_not_reached();      } -    return 0;  }  void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { @@ -134,7 +133,7 @@ static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nst          for (channel = 0; channel < spec->channels; channel++) {              pa_mix_info *m = streams + k; -            m->linear[channel].f = pa_sw_volume_to_linear(m->volume.values[channel]); +            m->linear[channel].f = (float) pa_sw_volume_to_linear(m->volume.values[channel]);          }      }  } @@ -146,7 +145,7 @@ static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {      pa_assert(volume);      for (channel = 0; channel < volume->channels; channel++) -        linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); +        linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);  }  size_t pa_mix( @@ -160,7 +159,8 @@ size_t pa_mix(      pa_cvolume full_volume;      unsigned k; -    size_t d = 0; +    unsigned z; +    void *end;      pa_assert(streams);      pa_assert(data); @@ -170,9 +170,20 @@ size_t pa_mix(      if (!volume)          volume = pa_cvolume_reset(&full_volume, spec->channels); +    if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) { +        pa_silence_memory(data, length, spec); +        return length; +    } +      for (k = 0; k < nstreams; k++)          streams[k].ptr = (uint8_t*) pa_memblock_acquire(streams[k].chunk.memblock) + streams[k].chunk.index; +    for (z = 0; z < nstreams; z++) +        if (length > streams[z].chunk.length) +            length = streams[z].chunk.length; + +    end = (uint8_t*) data + length; +      switch (spec->format) {          case PA_SAMPLE_S16NE:{ @@ -182,21 +193,15 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d += sizeof(int16_t)) { +            while (data < end) {                  int32_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int32_t v, cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = *((int16_t*) m->ptr); @@ -207,8 +212,8 @@ size_t pa_mix(                      m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);                  } -                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);                  sum = (sum * linear[channel]) / 0x10000; +                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);                  *((int16_t*) data) = (int16_t) sum;                  data = (uint8_t*) data + sizeof(int16_t); @@ -227,21 +232,15 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d += sizeof(int16_t)) { +            while (data < end) {                  int32_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int32_t v, cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = PA_INT16_SWAP(*((int16_t*) m->ptr)); @@ -252,8 +251,8 @@ size_t pa_mix(                      m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);                  } -                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);                  sum = (sum * linear[channel]) / 0x10000; +                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);                  *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum);                  data = (uint8_t*) data + sizeof(int16_t); @@ -272,22 +271,16 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d += sizeof(int32_t)) { +            while (data < end) {                  int64_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int64_t v;                      int32_t cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = *((int32_t*) m->ptr); @@ -298,8 +291,8 @@ size_t pa_mix(                      m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);                  } -                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);                  sum = (sum * linear[channel]) / 0x10000; +                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);                  *((int32_t*) data) = (int32_t) sum;                  data = (uint8_t*) data + sizeof(int32_t); @@ -318,22 +311,16 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d += sizeof(int32_t)) { +            while (data < end) {                  int64_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int64_t v;                      int32_t cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = PA_INT32_SWAP(*((int32_t*) m->ptr)); @@ -344,8 +331,8 @@ size_t pa_mix(                      m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);                  } -                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);                  sum = (sum * linear[channel]) / 0x10000; +                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);                  *((int32_t*) data) = PA_INT32_SWAP((int32_t) sum);                  data = (uint8_t*) data + sizeof(int32_t); @@ -364,21 +351,15 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d ++) { +            while (data < end) {                  int32_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int32_t v, cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = (int32_t) *((uint8_t*) m->ptr) - 0x80; @@ -409,21 +390,15 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d ++) { +            while (data < end) {                  int32_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int32_t v, cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr)); @@ -434,9 +409,9 @@ size_t pa_mix(                      m->ptr = (uint8_t*) m->ptr + 1;                  } -                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);                  sum = (sum * linear[channel]) / 0x10000; -                *((uint8_t*) data) = (uint8_t) st_14linear2ulaw(sum >> 2); +                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); +                *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);                  data = (uint8_t*) data + 1; @@ -454,21 +429,15 @@ size_t pa_mix(              calc_linear_integer_stream_volumes(streams, nstreams, spec);              calc_linear_integer_volume(linear, volume); -            for (d = 0;; d ++) { +            while (data < end) {                  int32_t sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      int32_t v, cv = m->linear[channel].i; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr)); @@ -479,9 +448,9 @@ size_t pa_mix(                      m->ptr = (uint8_t*) m->ptr + 1;                  } -                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);                  sum = (sum * linear[channel]) / 0x10000; -                *((uint8_t*) data) = (uint8_t) st_13linear2alaw(sum >> 3); +                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); +                *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);                  data = (uint8_t*) data + 1; @@ -499,21 +468,15 @@ size_t pa_mix(              calc_linear_float_stream_volumes(streams, nstreams, spec);              calc_linear_float_volume(linear, volume); -            for (d = 0;; d += sizeof(float)) { +            while (data < end) {                  float sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      float v, cv = m->linear[channel].f; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0;                      else {                          v = *((float*) m->ptr); @@ -543,35 +506,25 @@ size_t pa_mix(              calc_linear_float_stream_volumes(streams, nstreams, spec);              calc_linear_float_volume(linear, volume); -            for (d = 0;; d += sizeof(float)) { +            while (data < end) {                  float sum = 0;                  unsigned i; -                if (PA_UNLIKELY(d >= length)) -                    goto finish; -                  for (i = 0; i < nstreams; i++) {                      pa_mix_info *m = streams + i;                      float v, cv = m->linear[channel].f; -                    if (PA_UNLIKELY(d >= m->chunk.length)) -                        goto finish; - -                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0)) +                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))                          v = 0; -                    else { -                        uint32_t z = *(uint32_t*) m->ptr; -                        z = PA_UINT32_SWAP(z); -                        v = *((float*) &z); -                        v *= cv; -                    } +                    else +                        v = PA_FLOAT32_SWAP(*(float*) m->ptr) *cv;                      sum += v;                      m->ptr = (uint8_t*) m->ptr + sizeof(float);                  }                  sum *= linear[channel]; -                *((uint32_t*) data) = PA_UINT32_SWAP(*(uint32_t*) &sum); +                *((float*) data) = PA_FLOAT32_SWAP(sum);                  data = (uint8_t*) data + sizeof(float); @@ -583,16 +536,14 @@ size_t pa_mix(          }          default: -            pa_log_error("ERROR: Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format)); +            pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format));              pa_assert_not_reached();      } -finish: -      for (k = 0; k < nstreams; k++)          pa_memblock_release(streams[k].chunk.memblock); -    return d; +    return length;  } @@ -624,14 +575,15 @@ void pa_volume_memchunk(      switch (spec->format) {          case PA_SAMPLE_S16NE: { -            int16_t *d; -            size_t n; +            int16_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length/sizeof(int16_t); n > 0; d++, n--) { +            e = (int16_t*) ptr + c->length/sizeof(int16_t); + +            for (channel = 0, d = ptr; d < e; d++) {                  int32_t t;                  t = (int32_t)(*d); @@ -646,17 +598,18 @@ void pa_volume_memchunk(          }          case PA_SAMPLE_S16RE: { -            int16_t *d; -            size_t n; +            int16_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length/sizeof(int16_t); n > 0; d++, n--) { +            e = (int16_t*) ptr + c->length/sizeof(int16_t); + +            for (channel = 0, d = ptr; d < e; d++) {                  int32_t t; -                t = (int32_t)(PA_INT16_SWAP(*d)); +                t = (int32_t) PA_INT16_SWAP(*d);                  t = (t * linear[channel]) / 0x10000;                  t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);                  *d = PA_INT16_SWAP((int16_t) t); @@ -669,14 +622,15 @@ void pa_volume_memchunk(          }          case PA_SAMPLE_S32NE: { -            int32_t *d; -            size_t n; +            int32_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length/sizeof(int32_t); n > 0; d++, n--) { +            e = (int32_t*) ptr + c->length/sizeof(int32_t); + +            for (channel = 0, d = ptr; d < e; d++) {                  int64_t t;                  t = (int64_t)(*d); @@ -691,17 +645,18 @@ void pa_volume_memchunk(          }          case PA_SAMPLE_S32RE: { -            int32_t *d; -            size_t n; +            int32_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length/sizeof(int32_t); n > 0; d++, n--) { +            e = (int32_t*) ptr + c->length/sizeof(int32_t); + +            for (channel = 0, d = ptr; d < e; d++) {                  int64_t t; -                t = (int64_t)(PA_INT32_SWAP(*d)); +                t = (int64_t) PA_INT32_SWAP(*d);                  t = (t * linear[channel]) / 0x10000;                  t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);                  *d = PA_INT32_SWAP((int32_t) t); @@ -714,14 +669,15 @@ void pa_volume_memchunk(          }          case PA_SAMPLE_U8: { -            uint8_t *d; -            size_t n; +            uint8_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) { +            e = (uint8_t*) ptr + c->length; + +            for (channel = 0, d = ptr; d < e; d++) {                  int32_t t;                  t = (int32_t) *d - 0x80; @@ -736,20 +692,21 @@ void pa_volume_memchunk(          }          case PA_SAMPLE_ULAW: { -            uint8_t *d; -            size_t n; +            uint8_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) { +            e = (uint8_t*) ptr + c->length; + +            for (channel = 0, d = ptr; d < e; d++) {                  int32_t t;                  t = (int32_t) st_ulaw2linear16(*d);                  t = (t * linear[channel]) / 0x10000;                  t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); -                *d = (uint8_t) st_14linear2ulaw(t >> 2); +                *d = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);                  if (PA_UNLIKELY(++channel >= spec->channels))                      channel = 0; @@ -758,20 +715,21 @@ void pa_volume_memchunk(          }          case PA_SAMPLE_ALAW: { -            uint8_t *d; -            size_t n; +            uint8_t *d, *e;              unsigned channel;              int32_t linear[PA_CHANNELS_MAX];              calc_linear_integer_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) { +            e = (uint8_t*) ptr + c->length; + +            for (channel = 0, d = ptr; d < e; d++) {                  int32_t t;                  t = (int32_t) st_alaw2linear16(*d);                  t = (t * linear[channel]) / 0x10000;                  t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF); -                *d = (uint8_t) st_13linear2alaw(t >> 3); +                *d = (uint8_t) st_13linear2alaw((int16_t) t >> 3);                  if (PA_UNLIKELY(++channel >= spec->channels))                      channel = 0; @@ -786,8 +744,8 @@ void pa_volume_memchunk(              unsigned channel;              d = ptr; -            skip = spec->channels * sizeof(float); -            n = c->length/sizeof(float)/spec->channels; +            skip = (int) (spec->channels * sizeof(float)); +            n = (unsigned) (c->length/sizeof(float)/spec->channels);              for (channel = 0; channel < spec->channels; channel ++) {                  float v, *t; @@ -797,28 +755,26 @@ void pa_volume_memchunk(                  v = (float) pa_sw_volume_to_linear(volume->values[channel]);                  t = d + channel; -                oil_scalarmult_f32(t, skip, t, skip, &v, n); +                oil_scalarmult_f32(t, skip, t, skip, &v, (int) n);              }              break;          }          case PA_SAMPLE_FLOAT32RE: { -            uint32_t *d; -            size_t n; +            float *d, *e;              unsigned channel;              float linear[PA_CHANNELS_MAX];              calc_linear_float_volume(linear, volume); -            for (channel = 0, d = ptr, n = c->length/sizeof(float); n > 0; d++, n--) { +            e = (float*) ptr + c->length/sizeof(float); + +            for (channel = 0, d = ptr; d < e; d++) {                  float t; -                uint32_t z; -                z = PA_UINT32_SWAP(*d); -                t = *(float*) &z; +                t = PA_FLOAT32_SWAP(*d);                  t *= linear[channel]; -                z = *(uint32_t*) &t; -                *d = PA_UINT32_SWAP(z); +                *d = PA_FLOAT32_SWAP(t);                  if (PA_UNLIKELY(++channel >= spec->channels))                      channel = 0; @@ -877,7 +833,7 @@ void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, u          d = (uint8_t*) dst + c * ss;          for (j = 0; j < n; j ++) { -            oil_memcpy(d, s, ss); +            oil_memcpy(d, s, (int) ss);              s = (uint8_t*) s + ss;              d = (uint8_t*) d + fs;          } @@ -905,7 +861,7 @@ void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss,          d = dst[c];          for (j = 0; j < n; j ++) { -            oil_memcpy(d, s, ss); +            oil_memcpy(d, s, (int) ss);              s = (uint8_t*) s + fs;              d = (uint8_t*) d + ss;          } @@ -1008,7 +964,7 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo      if (format == PA_SAMPLE_FLOAT32NE) {          float minus_one = -1.0, plus_one = 1.0; -        oil_clip_f32(d, dstr, s, sstr, n, &minus_one, &plus_one); +        oil_clip_f32(d, (int) dstr, s, (int) sstr, (int) n, &minus_one, &plus_one);      } else {          pa_assert(format == PA_SAMPLE_FLOAT32RE); @@ -1017,7 +973,7 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo              float f;              f = PA_FLOAT32_SWAP(*s); -            f = PA_CLAMP_UNLIKELY(f, -1.0, 1.0); +            f = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);              *d = PA_FLOAT32_SWAP(f);              s = (const float*) ((const uint8_t*) s + sstr); diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c index 41670f27..693d529b 100644 --- a/src/pulsecore/sconv-s16le.c +++ b/src/pulsecore/sconv-s16le.c @@ -70,13 +70,13 @@ void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {      for (; n > 0; n--) {          int16_t s = *(a++); -        *(b++) = ((float) INT16_FROM(s))/0x7FFF; +        *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;      }  #else  {      static const double add = 0, factor = 1.0/0x7FFF; -    oil_scaleconv_f32_s16(b, a, n, &add, &factor); +    oil_scaleconv_f32_s16(b, a, (int) n, &add, &factor);  }  #endif  } @@ -95,7 +95,7 @@ void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {  #else  {      static const double add = 0, factor = 1.0/0x7FFFFFFF; -    oil_scaleconv_f32_s32(b, a, n, &add, &factor); +    oil_scaleconv_f32_s32(b, a, (int) n, &add, &factor);  }  #endif  } @@ -110,7 +110,7 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {          int16_t s;          float v = *(a++); -        v = PA_CLAMP_UNLIKELY(v, -1, 1); +        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);          s = (int16_t) (v * 0x7FFF);          *(b++) = INT16_TO(s);      } @@ -118,7 +118,7 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {  #else  {      static const double add = 0, factor = 0x7FFF; -    oil_scaleconv_s16_f32(b, a, n, &add, &factor); +    oil_scaleconv_s16_f32(b, a, (int) n, &add, &factor);  }  #endif  } @@ -133,7 +133,7 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {          int32_t s;          float v = *(a++); -        v = PA_CLAMP_UNLIKELY(v, -1, 1); +        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);          s = (int32_t) ((double) v * (double) 0x7FFFFFFF);          *(b++) = INT32_TO(s);      } @@ -141,7 +141,7 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {  #else  {      static const double add = 0, factor = 0x7FFFFFFF; -    oil_scaleconv_s32_f32(b, a, n, &add, &factor); +    oil_scaleconv_s32_f32(b, a, (int) n, &add, &factor);  }  #endif  } @@ -181,7 +181,7 @@ void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {          float v = *(a++);          uint32_t *j = (uint32_t*) &v;          *j = PA_UINT32_SWAP(*j); -        v = PA_CLAMP_UNLIKELY(v, -1, 1); +        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);          s = (int16_t) (v * 0x7FFF);          *(b++) = INT16_TO(s);      } @@ -196,7 +196,7 @@ void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {          float v = *(a++);          uint32_t *j = (uint32_t*) &v;          *j = PA_UINT32_SWAP(*j); -        v = PA_CLAMP_UNLIKELY(v, -1, 1); +        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);          s = (int32_t) ((double) v * 0x7FFFFFFF);          *(b++) = INT32_TO(s);      } @@ -219,7 +219,7 @@ void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {      for (; n > 0; n--) {          int16_t s = (int16_t) (INT32_FROM(*a) >> 16); -        *b = PA_UINT32_SWAP(s); +        *b = PA_INT16_SWAP(s);          a++;          b++;      } @@ -241,7 +241,7 @@ void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {      pa_assert(b);      for (; n > 0; n--) { -        int32_t s = ((int32_t) PA_UINT16_SWAP(*a)) << 16; +        int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16;          *b = INT32_TO(s);          a++;          b++; diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c index 581e4681..733a46ae 100644 --- a/src/pulsecore/sconv.c +++ b/src/pulsecore/sconv.c @@ -46,7 +46,7 @@ static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) {      pa_assert(a);      pa_assert(b); -    oil_scaleconv_f32_u8(b, a, n, &add, &factor); +    oil_scaleconv_f32_u8(b, a, (int) n, &add, &factor);  }  static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) { @@ -55,7 +55,7 @@ static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) {      pa_assert(a);      pa_assert(b); -    oil_scaleconv_u8_f32(b, a, n, &add, &factor); +    oil_scaleconv_u8_f32(b, a, (int) n, &add, &factor);  }  static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { @@ -64,9 +64,9 @@ static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {      pa_assert(a);      pa_assert(b); -    oil_conv_s16_u8(b, 2, a, 1, n); -    oil_scalaradd_s16(b, 2, b, 2, &add, n); -    oil_scalarmult_s16(b, 2, b, 2, &factor, n); +    oil_conv_s16_u8(b, 2, a, 1, (int) n); +    oil_scalaradd_s16(b, 2, b, 2, &add, (int) n); +    oil_scalarmult_s16(b, 2, b, 2, &factor, (int) n);  }  static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { @@ -84,7 +84,7 @@ static void float32ne_to_float32ne(unsigned n, const float *a, float *b) {      pa_assert(a);      pa_assert(b); -    oil_memcpy(b, a, sizeof(float) * n); +    oil_memcpy(b, a, (int) (sizeof(float) * n));  }  static void float32re_to_float32ne(unsigned n, const float *a, float *b) { @@ -101,7 +101,7 @@ static void s16ne_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {      pa_assert(a);      pa_assert(b); -    oil_memcpy(b, a, sizeof(int16_t) * n); +    oil_memcpy(b, a, (int) (sizeof(int16_t) * n));  }  static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { @@ -109,7 +109,7 @@ static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {      pa_assert(b);      for (; n > 0; n--, a++, b++) -        *b = PA_UINT16_SWAP(*a); +        *b = PA_INT16_SWAP(*a);  }  /* ulaw */ @@ -128,7 +128,7 @@ static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {      for (; n > 0; n--) {          float v = *(a++); -        v = PA_CLAMP_UNLIKELY(v, -1, 1); +        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);          v *= 0x1FFF;          *(b++) = st_14linear2ulaw((int16_t) v);      } @@ -166,7 +166,7 @@ static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {      for (; n > 0; n--, a++, b++) {          float v = *a; -        v = PA_CLAMP_UNLIKELY(v, -1, 1); +        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);          v *= 0xFFF;          *b = st_13linear2alaw((int16_t) v);      } @@ -177,7 +177,7 @@ static void alaw_to_s16ne(unsigned n, const int8_t *a, int16_t *b) {      pa_assert(b);      for (; n > 0; n--, a++, b++) -        *b = st_alaw2linear16(*a); +        *b = st_alaw2linear16((uint8_t) *a);  }  static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 298bf716..b0870202 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -138,7 +138,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {          m->size = size + PA_ALIGN(sizeof(struct shm_marker)); -        if (ftruncate(fd, m->size) < 0) { +        if (ftruncate(fd, (off_t) m->size) < 0) {              pa_log("ftruncate() failed: %s", pa_cstrerror(errno));              goto fail;          } @@ -235,7 +235,7 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) {      /* Align this to multiples of the page size */      ptr = (uint8_t*) m->ptr + offset; -    o = (uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr); +    o = (size_t) ((uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr));      if (o > 0) {          ps = PA_PAGE_SIZE; @@ -289,7 +289,7 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) {          goto fail;      } -    m->size = st.st_size; +    m->size = (size_t) st.st_size;      if ((m->ptr = mmap(NULL, m->size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {          pa_log("mmap() failed: %s", pa_cstrerror(errno)); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 64a6cdf9..f4e803d0 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -535,7 +535,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa               * data, so let's just hand out silence */              pa_atomic_store(&i->thread_info.drained, 1); -            pa_memblockq_seek(i->thread_info.render_memblockq, slength, PA_SEEK_RELATIVE); +            pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE);              i->thread_info.playing_for = 0;              if (i->thread_info.underrun_for != (uint64_t) -1)                  i->thread_info.underrun_for += ilength; diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index c07a7404..7663f22c 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -212,19 +212,19 @@ typedef struct pa_sink_input_new_data {      pa_sink *sink; +    pa_resample_method_t resample_method; + +    pa_sink_input *sync_base; +      pa_sample_spec sample_spec; -    pa_bool_t sample_spec_is_set;      pa_channel_map channel_map; -    pa_bool_t channel_map_is_set; -      pa_cvolume volume; -    pa_bool_t volume_is_set; -    pa_bool_t muted; -    pa_bool_t muted_is_set; - -    pa_resample_method_t resample_method; +    pa_bool_t muted:1; -    pa_sink_input *sync_base; +    pa_bool_t sample_spec_is_set:1; +    pa_bool_t channel_map_is_set:1; +    pa_bool_t volume_is_set:1; +    pa_bool_t muted_is_set:1;  } pa_sink_input_new_data;  pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 4102f31d..24fb8913 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -856,18 +856,29 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) {          s->set_volume = NULL;      if (!s->set_volume) -        pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, volume, 0, NULL); +        pa_sink_set_soft_volume(s, volume);      if (changed)          pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);  }  /* Called from main thread */ -const pa_cvolume *pa_sink_get_volume(pa_sink *s) { +void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) { +    pa_sink_assert_ref(s); +    pa_assert(volume); + +    if (PA_SINK_IS_LINKED(s->state)) +        pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, volume, 0, NULL); +    else +        s->thread_info.soft_volume = *volume; +} + +/* Called from main thread */ +const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {      pa_sink_assert_ref(s);      pa_assert(PA_SINK_IS_LINKED(s->state)); -    if (s->refresh_volume) { +    if (s->refresh_volume || force_refresh) {          struct pa_cvolume old_volume = s->volume;          if (s->get_volume && s->get_volume(s) < 0) @@ -904,12 +915,12 @@ void pa_sink_set_mute(pa_sink *s, pa_bool_t mute) {  }  /* Called from main thread */ -pa_bool_t pa_sink_get_mute(pa_sink *s) { +pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {      pa_sink_assert_ref(s);      pa_assert(PA_SINK_IS_LINKED(s->state)); -    if (s->refresh_muted) { +    if (s->refresh_muted || force_refresh) {          pa_bool_t old_muted = s->muted;          if (s->get_mute && s->get_mute(s) < 0) diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 604be269..672bdd39 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -180,21 +180,22 @@ typedef enum pa_sink_message {  typedef struct pa_sink_new_data {      char *name; -    pa_bool_t namereg_fail;      pa_proplist *proplist;      const char *driver;      pa_module *module;      pa_sample_spec sample_spec; -    pa_bool_t sample_spec_is_set;      pa_channel_map channel_map; -    pa_bool_t channel_map_is_set; -      pa_cvolume volume; -    pa_bool_t volume_is_set; -    pa_bool_t muted; -    pa_bool_t muted_is_set; +    pa_bool_t muted :1; + +    pa_bool_t sample_spec_is_set:1; +    pa_bool_t channel_map_is_set:1; +    pa_bool_t volume_is_set:1; +    pa_bool_t muted_is_set:1; + +    pa_bool_t namereg_fail:1;  } pa_sink_new_data;  pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data); @@ -239,9 +240,10 @@ int pa_sink_suspend(pa_sink *s, pa_bool_t suspend);  int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend);  void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume); -const pa_cvolume *pa_sink_get_volume(pa_sink *sink); +void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume); +const pa_cvolume *pa_sink_get_volume(pa_sink *sink, pa_bool_t force_refresh);  void pa_sink_set_mute(pa_sink *sink, pa_bool_t mute); -pa_bool_t pa_sink_get_mute(pa_sink *sink); +pa_bool_t pa_sink_get_mute(pa_sink *sink, pa_bool_t force_refres);  unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */  unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */ diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index e69a63da..3bde40d0 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -187,7 +187,7 @@ static void connect_defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userda      do_call(c);  } -static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {      pa_socket_client *c = userdata;      pa_assert(m); @@ -283,7 +283,7 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size      else          pa_make_socket_low_delay(c->fd); -    if (do_connect(c, sa, salen) < 0) +    if (do_connect(c, sa, (socklen_t) salen) < 0)          return -1;      return 0; @@ -370,7 +370,7 @@ pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[  #ifdef HAVE_LIBASYNCNS -static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {      pa_socket_client *c = userdata;      struct addrinfo *res = NULL;      int ret; diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index 9885a02b..a600e0a6 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -199,7 +199,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file      pa_make_socket_low_delay(fd); -    if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) { +    if (bind(fd, (struct sockaddr*) &sa, (socklen_t) SUN_LEN(&sa)) < 0) {          pa_log("bind(): %s", pa_cstrerror(errno));          goto fail;      } diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 8eedf830..c30c16eb 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -170,10 +170,10 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk          if (u->readf_function) {              fs = pa_frame_size(&i->sample_spec); -            n = u->readf_function(u->sndfile, p, length/fs); +            n = u->readf_function(u->sndfile, p, (sf_count_t) (length/fs));          } else {              fs = 1; -            n = sf_read_raw(u->sndfile, p, length); +            n = sf_read_raw(u->sndfile, p, (sf_count_t) length);          }          pa_memblock_release(tchunk.memblock); @@ -186,7 +186,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk              break;          } -        tchunk.length = n * fs; +        tchunk.length = (size_t) n * fs;          pa_memblockq_push(u->memblockq, &tchunk);          pa_memblock_unref(tchunk.memblock); @@ -206,12 +206,9 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {      file_stream *u;      pa_sink_input_assert_ref(i); -    pa_assert(nbytes > 0);      u = FILE_STREAM(i->userdata);      file_stream_assert_ref(u); -    pa_log("backwards %lu", (unsigned long) nbytes); -      if (!u->memblockq)          return; @@ -313,8 +310,8 @@ int pa_play_file(              break;      } -    ss.rate = sfinfo.samplerate; -    ss.channels = sfinfo.channels; +    ss.rate = (uint32_t) sfinfo.samplerate; +    ss.channels = (uint8_t) sfinfo.channels;      if (!pa_sample_spec_valid(&ss)) {          pa_log("Unsupported sample format in file %s", fname); diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 3183ede6..74338f9a 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -108,8 +108,8 @@ int pa_sound_file_load(              break;      } -    ss->rate = sfinfo.samplerate; -    ss->channels = sfinfo.channels; +    ss->rate = (uint32_t) sfinfo.samplerate; +    ss->channels = (uint8_t) sfinfo.channels;      if (!pa_sample_spec_valid(ss)) {          pa_log("Unsupported sample format in file %s", fname); @@ -119,7 +119,7 @@ int pa_sound_file_load(      if (map)          pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT); -    if ((l = pa_frame_size(ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { +    if ((l = pa_frame_size(ss) * (size_t) sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {          pa_log("File too large");          goto finish;      } @@ -131,7 +131,7 @@ int pa_sound_file_load(      ptr = pa_memblock_acquire(chunk->memblock);      if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) || -        (!readf_function && sf_read_raw(sf, ptr, l) != (sf_count_t) l)) { +        (!readf_function && sf_read_raw(sf, ptr, (sf_count_t) l) != (sf_count_t) l)) {          pa_log("Premature file end");          goto finish;      } @@ -189,15 +189,15 @@ int pa_sound_file_too_big_to_cache(const char *fname) {              break;      } -    ss.rate = sfinfo.samplerate; -    ss.channels = sfinfo.channels; +    ss.rate = (uint32_t) sfinfo.samplerate; +    ss.channels = (uint8_t) sfinfo.channels;      if (!pa_sample_spec_valid(&ss)) {          pa_log("Unsupported sample format in file %s", fname);          return -1;      } -    if ((pa_frame_size(&ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { +    if ((pa_frame_size(&ss) * (size_t) sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {          pa_log("File too large: %s", fname);          return 1;      } diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 3d1abe30..4257154e 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -397,7 +397,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {      if (pa_memblockq_push(o->thread_info.delay_memblockq, chunk) < 0) {          pa_log_debug("Delay queue overflow!"); -        pa_memblockq_seek(o->thread_info.delay_memblockq, chunk->length, PA_SEEK_RELATIVE); +        pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE);      }      limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind; @@ -441,7 +441,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {  }  /* Called from thread context */ -void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in sink sample spec */) { +void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in source sample spec */) {      pa_source_output_assert_ref(o);      pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->thread_info.state)); @@ -512,7 +512,7 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t      if (PA_SOURCE_OUTPUT_IS_LINKED(o->state))          pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);      else { -        /* If this sink input is not realized yet, we have to touch +        /* If this source output is not realized yet, we have to touch           * the thread info data directly */          usec = fixup_latency(o->source, usec); @@ -532,7 +532,7 @@ pa_usec_t pa_source_output_get_requested_latency(pa_source_output *o) {      if (PA_SOURCE_OUTPUT_IS_LINKED(o->state))          pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);      else -        /* If this sink input is not realized yet, we have to touch +        /* If this source output is not realized yet, we have to touch           * the thread info data directly */          usec = o->thread_info.requested_source_latency; @@ -752,7 +752,7 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int              return 0;          } -        case PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY: { +        case PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY: {              pa_usec_t *r = userdata;              *r = o->thread_info.requested_source_latency; diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 61825b22..a7aac814 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -174,12 +174,13 @@ typedef struct pa_source_output_new_data {      pa_source *source; +    pa_resample_method_t resample_method; +      pa_sample_spec sample_spec; -    pa_bool_t sample_spec_is_set;      pa_channel_map channel_map; -    pa_bool_t channel_map_is_set; -    pa_resample_method_t resample_method; +    pa_bool_t sample_spec_is_set:1; +    pa_bool_t channel_map_is_set:1;  } pa_source_output_new_data;  pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 95007af4..7ed32e92 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -260,7 +260,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {          for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx)))              if (o->suspend) -                o->suspend(o, state == PA_SINK_SUSPENDED); +                o->suspend(o, state == PA_SOURCE_SUSPENDED);      }      if (state != PA_SOURCE_UNLINKED) /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */ @@ -273,7 +273,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {  void pa_source_put(pa_source *s) {      pa_source_assert_ref(s); -    pa_assert(s->state == PA_SINK_INIT); +    pa_assert(s->state == PA_SOURCE_INIT);      /* The following fields must be initialized properly when calling _put() */      pa_assert(s->asyncmsgq); @@ -520,18 +520,29 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) {          s->set_volume = NULL;      if (!s->set_volume) -        pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, volume, 0, NULL); +        pa_source_set_soft_volume(s, volume);      if (changed)          pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);  }  /* Called from main thread */ -const pa_cvolume *pa_source_get_volume(pa_source *s) { +void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) { +    pa_source_assert_ref(s); +    pa_assert(volume); + +    if (PA_SOURCE_IS_LINKED(s->state)) +        pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, volume, 0, NULL); +    else +        s->thread_info.soft_volume = *volume; +} + +/* Called from main thread */ +const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {      pa_source_assert_ref(s);      pa_assert(PA_SOURCE_IS_LINKED(s->state)); -    if (s->refresh_volume) { +    if (s->refresh_volume || force_refresh) {          pa_cvolume old_volume = s->volume;          if (s->get_volume && s->get_volume(s) < 0) @@ -568,12 +579,12 @@ void pa_source_set_mute(pa_source *s, pa_bool_t mute) {  }  /* Called from main thread */ -pa_bool_t pa_source_get_mute(pa_source *s) { +pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {      pa_source_assert_ref(s);      pa_assert(PA_SOURCE_IS_LINKED(s->state)); -    if (s->refresh_muted) { +    if (s->refresh_muted || force_refresh) {          pa_bool_t old_muted = s->muted;          if (s->get_mute && s->get_mute(s) < 0) @@ -932,7 +943,7 @@ void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t      pa_assert(!min_latency || !max_latency ||                min_latency <= max_latency); -    if (PA_SINK_IS_LINKED(s->state)) { +    if (PA_SOURCE_IS_LINKED(s->state)) {          pa_usec_t r[2];          r[0] = min_latency; diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index f4a17e8d..cae78693 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -168,21 +168,22 @@ typedef enum pa_source_message {  typedef struct pa_source_new_data {      char *name; -    pa_bool_t namereg_fail;      pa_proplist *proplist;      const char *driver;      pa_module *module;      pa_sample_spec sample_spec; -    pa_bool_t sample_spec_is_set;      pa_channel_map channel_map; -    pa_bool_t channel_map_is_set; -      pa_cvolume volume; -    pa_bool_t volume_is_set; -    pa_bool_t muted; -    pa_bool_t muted_is_set; +    pa_bool_t muted:1; + +    pa_bool_t volume_is_set:1; +    pa_bool_t muted_is_set:1; +    pa_bool_t sample_spec_is_set:1; +    pa_bool_t channel_map_is_set:1; + +    pa_bool_t namereg_fail:1;  } pa_source_new_data;  pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data); @@ -226,9 +227,10 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend);  int pa_source_suspend_all(pa_core *c, pa_bool_t suspend);  void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); -const pa_cvolume *pa_source_get_volume(pa_source *source); +void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume); +const pa_cvolume *pa_source_get_volume(pa_source *source, pa_bool_t force_refresh);  void pa_source_set_mute(pa_source *source, pa_bool_t mute); -pa_bool_t pa_source_get_mute(pa_source *source); +pa_bool_t pa_source_get_mute(pa_source *source, pa_bool_t force_refresh);  unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */  unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */ diff --git a/src/pulsecore/start-child.c b/src/pulsecore/start-child.c index 1661383d..7774bde6 100644 --- a/src/pulsecore/start-child.c +++ b/src/pulsecore/start-child.c @@ -66,11 +66,6 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {          return pipe_fds[0];      } else { -#ifdef __linux__ -        DIR* d; -#endif -        int max_fd, i; -          /* child */          pa_reset_priority(); @@ -87,48 +82,9 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {          pa_close(2);          pa_assert_se(open("/dev/null", O_WRONLY) == 2); -#ifdef __linux__ - -        if ((d = opendir("/proc/self/fd/"))) { - -            struct dirent *de; - -            while ((de = readdir(d))) { -                char *e = NULL; -                int fd; - -                if (de->d_name[0] == '.') -                    continue; - -                errno = 0; -                fd = strtol(de->d_name, &e, 10); -                pa_assert(errno == 0 && e && *e == 0); - -                if (fd >= 3 && dirfd(d) != fd) -                    pa_close(fd); -            } - -            closedir(d); -        } else { - -#endif - -            max_fd = 1024; - -#ifdef HAVE_SYS_RESOURCE_H -            { -                struct rlimit r; -                if (getrlimit(RLIMIT_NOFILE, &r) == 0) -                    max_fd = r.rlim_max; -            } -#endif - -            for (i = 3; i < max_fd; i++) -                pa_close(i); - -#ifdef __linux__ -        } -#endif +        pa_close_all(-1); +        pa_reset_sigs(-1); +        pa_unblock_sigs(-1);  #ifdef PR_SET_PDEATHSIG          /* On Linux we can use PR_SET_PDEATHSIG to have the helper @@ -139,16 +95,6 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {          prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);  #endif -#ifdef SIGPIPE -        /* Make sure that SIGPIPE kills the child process */ -        signal(SIGPIPE, SIG_DFL); -#endif - -#ifdef SIGTERM -        /* Make sure that SIGTERM kills the child process */ -        signal(SIGTERM, SIG_DFL); -#endif -          execl(name, name, argv1, NULL);          _exit(1);      } diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c index b59b6f49..540faef9 100644 --- a/src/pulsecore/strbuf.c +++ b/src/pulsecore/strbuf.c @@ -77,7 +77,7 @@ char *pa_strbuf_tostring(pa_strbuf *sb) {      pa_assert(sb); -    e = t = pa_xnew(char, sb->length+1); +    e = t = pa_xmalloc(sb->length+1);      for (c = sb->head; c; c = c->next) {          pa_assert((size_t) (e-t) <= sb->length); @@ -150,8 +150,8 @@ void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) {  /* Append a printf() style formatted string to the string buffer. */  /* The following is based on an example from the GNU libc documentation */ -int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { -    int size = 100; +size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { +    size_t size = 100;      struct chunk *c = NULL;      pa_assert(sb); @@ -168,14 +168,14 @@ int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {          CHUNK_TO_TEXT(c)[size-1] = 0;          va_end(ap); -        if (r > -1 && r < size) { -            c->length = r; +        if (r > -1 && (size_t) r < size) { +            c->length = (size_t) r;              append(sb, c); -            return r; +            return (size_t) r;          }          if (r > -1)    /* glibc 2.1 */ -            size = r+1; +            size = (size_t) r+1;          else           /* glibc 2.0 */              size *= 2;      } diff --git a/src/pulsecore/strbuf.h b/src/pulsecore/strbuf.h index 24c876d5..ac68d7be 100644 --- a/src/pulsecore/strbuf.h +++ b/src/pulsecore/strbuf.h @@ -31,7 +31,7 @@ void pa_strbuf_free(pa_strbuf *sb);  char *pa_strbuf_tostring(pa_strbuf *sb);  char *pa_strbuf_tostring_free(pa_strbuf *sb); -int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...)  PA_GCC_PRINTF_ATTR(2,3); +size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...)  PA_GCC_PRINTF_ATTR(2,3);  void pa_strbuf_puts(pa_strbuf *sb, const char *t);  void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t m); diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c index b0ed59ef..62a30144 100644 --- a/src/pulsecore/tagstruct.c +++ b/src/pulsecore/tagstruct.c @@ -154,7 +154,7 @@ void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) {      extend(t, 5+length);      t->data[t->length] = PA_TAG_ARBITRARY; -    tmp = htonl(length); +    tmp = htonl((uint32_t) length);      memcpy(t->data+t->length+1, &tmp, 4);      if (length)          memcpy(t->data+t->length+5, p, length); @@ -165,7 +165,7 @@ void pa_tagstruct_put_boolean(pa_tagstruct*t, pa_bool_t b) {      pa_assert(t);      extend(t, 1); -    t->data[t->length] = b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE; +    t->data[t->length] = (uint8_t) (b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE);      t->length += 1;  } @@ -175,9 +175,9 @@ void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) {      extend(t, 9);      t->data[t->length] = PA_TAG_TIMEVAL; -    tmp = htonl(tv->tv_sec); +    tmp = htonl((uint32_t) tv->tv_sec);      memcpy(t->data+t->length+1, &tmp, 4); -    tmp = htonl(tv->tv_usec); +    tmp = htonl((uint32_t) tv->tv_usec);      memcpy(t->data+t->length+5, &tmp, 4);      t->length += 9;  } @@ -228,7 +228,7 @@ void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) {      unsigned i;      pa_assert(t); -    extend(t, 2 + map->channels); +    extend(t, 2 + (size_t) map->channels);      t->data[t->length++] = PA_TAG_CHANNEL_MAP;      t->data[t->length++] = map->channels; @@ -435,9 +435,9 @@ int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) {          return -1;      memcpy(&tv->tv_sec, t->data+t->rindex+1, 4); -    tv->tv_sec = ntohl(tv->tv_sec); +    tv->tv_sec = (time_t) ntohl((uint32_t) tv->tv_sec);      memcpy(&tv->tv_usec, t->data+t->rindex+5, 4); -    tv->tv_usec = ntohl(tv->tv_usec); +    tv->tv_usec = (suseconds_t) ntohl((uint32_t) tv->tv_usec);      t->rindex += 9;      return 0;  } @@ -523,7 +523,7 @@ int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map) {      for (i = 0; i < map->channels; i ++)          map->map[i] = (int8_t) t->data[t->rindex + 2 + i]; -    t->rindex += 2 + map->channels; +    t->rindex += 2 + (size_t) map->channels;      return 0;  } diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 20ed16d9..ade398f9 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -41,6 +41,7 @@ struct pa_thread {      pa_thread_func_t thread_func;      void *userdata;      pa_atomic_t running; +    pa_bool_t joined;  };  struct pa_tls { @@ -82,6 +83,7 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {      t = pa_xnew(pa_thread, 1);      t->thread_func = thread_func;      t->userdata = userdata; +    t->joined = FALSE;      pa_atomic_store(&t->running, 0);      if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) { @@ -115,7 +117,12 @@ void pa_thread_free(pa_thread *t) {  int pa_thread_join(pa_thread *t) {      pa_assert(t); +    pa_assert(t->thread_func); + +    if (t->joined) +        return -1; +    t->joined = TRUE;      return pthread_join(t->id, NULL);  } @@ -132,6 +139,7 @@ pa_thread* pa_thread_self(void) {      t->id = pthread_self();      t->thread_func = NULL;      t->userdata = NULL; +    t->joined = TRUE;      pa_atomic_store(&t->running, 2);      PA_STATIC_TLS_SET(current_thread, t); @@ -192,4 +200,3 @@ void *pa_tls_set(pa_tls *t, void *userdata) {      pa_assert_se(pthread_setspecific(t->key, userdata) == 0);      return r;  } - diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index f3aca13e..87e850d6 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -86,7 +86,7 @@ void *pa_tls_set(pa_tls *t, void *userdata);      }                                                                   \      struct __stupid_useless_struct_to_allow_trailing_semicolon -#ifdef HAVE_TLS_BUILTIN +#ifdef SUPPORT_TLS___THREAD  /* An optimized version of the above that requires no dynamic   * allocation if the compiler supports __thread */  #define PA_STATIC_TLS_DECLARE_NO_FREE(name)                             \ diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c index d0231486..b165f4a8 100644 --- a/src/pulsecore/time-smoother.c +++ b/src/pulsecore/time-smoother.c @@ -209,8 +209,8 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {      i = s->history_idx;      for (j = s->n_history; j > 0; j--) { -        ax += s->history_x[i]; -        ay += s->history_y[i]; +        ax += (int64_t) s->history_x[i]; +        ay += (int64_t) s->history_y[i];          c++;          REDUCE_INC(i); @@ -236,7 +236,7 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {          REDUCE_INC(i);      } -    r = (double) k / t; +    r = (double) k / (double) t;      return (s->monotonic && r < 0) ? 0 : r;  } @@ -268,8 +268,8 @@ static void calc_abc(pa_smoother *s) {      /* Calculate a, b, c for y=ax^3+bx^2+cx */      s->c = de; -    s->b = (((double) (3*ky)/kx - dp - 2*de)) / kx; -    s->a = (dp/kx - 2*s->b - de/kx) / (3*kx); +    s->b = (((double) (3*ky)/ (double) kx - dp - (double) (2*de))) / (double) kx; +    s->a = (dp/(double) kx - 2*s->b - de/(double) kx) / (double) (3*kx);      s->abc_valid = TRUE;  } @@ -284,7 +284,7 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {          /* The requested point is right of the point where we wanted           * to be on track again, thus just linearly estimate */ -        t = (int64_t) s->py + (int64_t) (s->dp * (x - s->px)); +        t = (int64_t) s->py + (int64_t) (s->dp * (double) (x - s->px));          if (t < 0)              t = 0; @@ -360,7 +360,7 @@ void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) {      /* And calculate when we want to be on track again */      s->px = s->ex + s->adjust_time; -    s->py = s->ry + s->dp *s->adjust_time; +    s->py = s->ry + (pa_usec_t) (s->dp * (double) s->adjust_time);      s->abc_valid = FALSE; diff --git a/src/pulsecore/tokenizer.c b/src/pulsecore/tokenizer.c index d1e0836b..07a9f3ac 100644 --- a/src/pulsecore/tokenizer.c +++ b/src/pulsecore/tokenizer.c @@ -34,7 +34,7 @@  #include "tokenizer.h" -static void token_free(void *p, PA_GCC_UNUSED void *userdata) { +static void token_free(void *p, void *userdata) {      pa_xfree(p);  } diff --git a/src/pulsecore/x11prop.c b/src/pulsecore/x11prop.c index 9e75f63a..7f91ba3c 100644 --- a/src/pulsecore/x11prop.c +++ b/src/pulsecore/x11prop.c @@ -32,7 +32,7 @@  void pa_x11_set_prop(Display *d, const char *name, const char *data) {      Atom a = XInternAtom(d, name, False); -    XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, strlen(data)+1); +    XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1));  }  void pa_x11_del_prop(Display *d, const char *name) { @@ -49,7 +49,7 @@ char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {      char *ret = NULL;      Atom a = XInternAtom(d, name, False); -    if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (l+2)/4, False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success) +    if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success)          goto finish;      if (actual_type != XA_STRING) diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c index 17f8e6a4..332ebb2e 100644 --- a/src/pulsecore/x11wrap.c +++ b/src/pulsecore/x11wrap.c @@ -91,7 +91,7 @@ static void work(pa_x11_wrapper *w) {  }  /* IO notification event for the X11 display connection */ -static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {      pa_x11_wrapper *w = userdata;      pa_assert(m); @@ -118,7 +118,7 @@ static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {  }  /* IO notification event for X11 internal connections */ -static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { +static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {      pa_x11_wrapper *w = userdata;      pa_assert(m); diff --git a/src/tests/channelmap-test.c b/src/tests/channelmap-test.c index 9c234602..12b39f10 100644 --- a/src/tests/channelmap-test.c +++ b/src/tests/channelmap-test.c @@ -4,7 +4,7 @@  #include <pulse/channelmap.h>  #include <pulse/gccmacro.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) {      char cm[PA_CHANNEL_MAP_SNPRINT_MAX];      pa_channel_map map, map2; diff --git a/src/tests/cpulimit-test.c b/src/tests/cpulimit-test.c index b7145e8a..fdc0162e 100644 --- a/src/tests/cpulimit-test.c +++ b/src/tests/cpulimit-test.c @@ -42,7 +42,7 @@ static time_t start;  #ifdef TEST2 -static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UNUSED int sig, PA_GCC_UNUSED void *userdata) { +static void func(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) {      time_t now;      time(&now); @@ -55,7 +55,7 @@ static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UN  #endif -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) {      pa_mainloop *m;      m = pa_mainloop_new(); diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c index 9f914553..d71eff1c 100644 --- a/src/tests/envelope-test.c +++ b/src/tests/envelope-test.c @@ -40,7 +40,7 @@ const pa_envelope_def ramp_down = {      .n_points = 2,      .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },      .points_y = { -        .f = { 1.0, 0.2 }, +        .f = { 1.0f, 0.2f },          .i = { 0x10000, 0x10000/5 }      }  }; @@ -49,7 +49,7 @@ const pa_envelope_def ramp_up = {      .n_points = 2,      .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },      .points_y = { -        .f = { 0.2, 1.0 }, +        .f = { 0.2f, 1.0f },          .i = { 0x10000/5, 0x10000 }      }  }; @@ -58,7 +58,7 @@ const pa_envelope_def ramp_down2 = {      .n_points = 2,      .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },      .points_y = { -        .f = { 0.8, 0.7 }, +        .f = { 0.8f, 0.7f },          .i = { 0x10000*4/5, 0x10000*7/10 }      }  }; @@ -67,7 +67,7 @@ const pa_envelope_def ramp_up2 = {      .n_points = 2,      .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },      .points_y = { -        .f = { 0.7, 0.9 }, +        .f = { 0.7f, 0.9f },          .i = { 0x10000*7/10, 0x10000*9/10 }      }  }; @@ -140,7 +140,7 @@ static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss)      unsigned n_samples;      block = pa_memblock_new(pool, pa_bytes_per_second(ss)); -    n_samples = pa_memblock_get_length(block) / pa_sample_size(ss); +    n_samples = (unsigned) (pa_memblock_get_length(block) / pa_sample_size(ss));      d = pa_memblock_acquire(block); @@ -171,7 +171,7 @@ static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss)              float *f;              for (f = d; n_samples > 0; n_samples--, f++) -                *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0); +                *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0f);              break;          } diff --git a/src/tests/lock-autospawn-test.c b/src/tests/lock-autospawn-test.c new file mode 100644 index 00000000..cb3dc87c --- /dev/null +++ b/src/tests/lock-autospawn-test.c @@ -0,0 +1,109 @@ +/*** +  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 <sys/poll.h> +#include <string.h> + +#include <pulsecore/macro.h> +#include <pulsecore/thread.h> +#include <pulse/lock-autospawn.h> +#include <pulse/util.h> + +static void thread_func(void*k) { +    pa_assert_se(pa_autospawn_lock_init() >= 0); + +    pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k)); + +    pa_assert_se(pa_autospawn_lock_acquire(TRUE) > 0); + +    pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k)); + +    pa_msleep(5000); + +    pa_log("%i, Releasing", PA_PTR_TO_INT(k)); + +    pa_autospawn_lock_release(); + +    pa_autospawn_lock_done(FALSE); +} + +static void thread_func2(void *k) { +    int fd; + +    pa_assert_se((fd = pa_autospawn_lock_init()) >= 0); + +    pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k)); + +    for (;;) { +        struct pollfd pollfd; +        int j; + +        if ((j = pa_autospawn_lock_acquire(FALSE)) > 0) +            break; + +        pa_assert(j == 0); + +        memset(&pollfd, 0, sizeof(pollfd)); +        pollfd.fd = fd; +        pollfd.events = POLLIN; + +        pa_assert_se(poll(&pollfd, 1, -1) == 1); + +        pa_log("%i, woke up", PA_PTR_TO_INT(k)); +    } + +    pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k)); + +    pa_msleep(5000); + +    pa_log("%i, Releasing", PA_PTR_TO_INT(k)); + +    pa_autospawn_lock_release(); + +    pa_autospawn_lock_done(FALSE); +} + +int main(int argc, char**argv) { +    pa_thread *a, *b, *c, *d; + +    pa_assert_se((a = pa_thread_new(thread_func, PA_INT_TO_PTR(1)))); +    pa_assert_se((b = pa_thread_new(thread_func2, PA_INT_TO_PTR(2)))); +    pa_assert_se((c = pa_thread_new(thread_func2, PA_INT_TO_PTR(3)))); +    pa_assert_se((d = pa_thread_new(thread_func, PA_INT_TO_PTR(4)))); + +    pa_thread_join(a); +    pa_thread_join(b); +    pa_thread_join(c); +    pa_thread_join(d); + +    pa_thread_free(a); +    pa_thread_free(b); +    pa_thread_free(c); +    pa_thread_free(d); + +    pa_log("End"); + +    return 0; +} diff --git a/src/tests/mainloop-test.c b/src/tests/mainloop-test.c index 9fa2e466..2580fa72 100644 --- a/src/tests/mainloop-test.c +++ b/src/tests/mainloop-test.c @@ -66,7 +66,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v  #endif  } -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) {      pa_mainloop_api *a;      pa_io_event *ioe;      pa_time_event *te; diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c index 9e358359..c0665822 100644 --- a/src/tests/mcalign-test.c +++ b/src/tests/mcalign-test.c @@ -36,7 +36,7 @@  /* A simple program for testing pa_mcalign */ -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) {      pa_mempool *p;      pa_mcalign *a;      pa_memchunk c; @@ -47,7 +47,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {      pa_memchunk_reset(&c); -    srand(time(NULL)); +    srand((unsigned) time(NULL));      for (;;) {          ssize_t r; @@ -62,7 +62,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {          l = pa_memblock_get_length(c.memblock) - c.index; -        l = l <= 1 ? l : rand() % (l-1) +1 ; +        l = l <= 1 ? l : (size_t) rand() % (l-1) +1;          p = pa_memblock_acquire(c.memblock); @@ -74,11 +74,11 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {          pa_memblock_release(c.memblock); -        c.length = r; +        c.length = (size_t) r;          pa_mcalign_push(a, &c);          fprintf(stderr, "Read %ld bytes\n", (long)r); -        c.index += r; +        c.index += (size_t) r;          if (c.index >= pa_memblock_get_length(c.memblock)) {              pa_memblock_unref(c.memblock); diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c index f3f6f829..544121fd 100644 --- a/src/tests/mix-test.c +++ b/src/tests/mix-test.c @@ -166,16 +166,16 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {          case PA_SAMPLE_FLOAT32RE: {              float *u = d; -            u[0] = 0.0; -            u[1] = -1.0; -            u[2] = 1.0; -            u[3] = 4711; -            u[4] = 0.222; -            u[5] = 0.33; -            u[6] = -.3; -            u[7] = 99; -            u[8] = -0.555; -            u[9] = -.123; +            u[0] = 0.0f; +            u[1] = -1.0f; +            u[2] = 1.0f; +            u[3] = 4711.0f; +            u[4] = 0.222f; +            u[5] = 0.33f; +            u[6] = -.3f; +            u[7] = 99.0f; +            u[8] = -0.555f; +            u[9] = -.123f;              if (ss->format == PA_SAMPLE_FLOAT32RE)                  for (i = 0; i < 10; i++) diff --git a/src/tests/pacat-simple.c b/src/tests/pacat-simple.c index b26e4b68..ffe3176a 100644 --- a/src/tests/pacat-simple.c +++ b/src/tests/pacat-simple.c @@ -33,7 +33,7 @@  #define BUFSIZE 1024 -int main(PA_GCC_UNUSED int argc, char*argv[]) { +int main(int argc, char*argv[]) {      /* The Sample format to use */      static const pa_sample_spec ss = { @@ -94,7 +94,7 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) {          }          /* ... and play it */ -        if (pa_simple_write(s, buf, r, &error) < 0) { +        if (pa_simple_write(s, buf, (size_t) r, &error) < 0) {              fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));              goto finish;          } diff --git a/src/tests/parec-simple.c b/src/tests/parec-simple.c index 6c0d529b..0312005d 100644 --- a/src/tests/parec-simple.c +++ b/src/tests/parec-simple.c @@ -47,13 +47,13 @@ static ssize_t loop_write(int fd, const void*data, size_t size) {          ret += r;          data = (const uint8_t*) data + r; -        size -= r; +        size -= (size_t) r;      }      return ret;  } -int main(PA_GCC_UNUSED int argc, char*argv[]) { +int main(int argc, char*argv[]) {      /* The sample type to use */      static const pa_sample_spec ss = {          .format = PA_SAMPLE_S16LE, @@ -80,6 +80,9 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) {              goto finish;          } +        if (r == 0) +            break; +          /* And write it to STDOUT */          if ((r = loop_write(STDOUT_FILENO, buf, sizeof(buf))) <= 0) {              fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno)); diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c index 1a20be2c..6959127b 100644 --- a/src/tests/resampler-test.c +++ b/src/tests/resampler-test.c @@ -166,16 +166,16 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {          case PA_SAMPLE_FLOAT32RE: {              float *u = d; -            u[0] = 0.0; -            u[1] = -1.0; -            u[2] = 1.0; -            u[3] = 4711; -            u[4] = 0.222; -            u[5] = 0.33; -            u[6] = -.3; -            u[7] = 99; -            u[8] = -0.555; -            u[9] = -.123; +            u[0] = 0.0f; +            u[1] = -1.0f; +            u[2] = 1.0f; +            u[3] = 4711.0f; +            u[4] = 0.222f; +            u[5] = 0.33f; +            u[6] = -.3f; +            u[7] = 99.0f; +            u[8] = -0.555f; +            u[9] = -.123f;              if (ss->format == PA_SAMPLE_FLOAT32RE)                  for (i = 0; i < 10; i++) diff --git a/src/tests/rtstutter.c b/src/tests/rtstutter.c index 91e85c36..6b0cb8f7 100644 --- a/src/tests/rtstutter.c +++ b/src/tests/rtstutter.c @@ -52,7 +52,7 @@ static void* work(void *p) {      pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) == 0);      CPU_ZERO(&mask); -    CPU_SET(PA_PTR_TO_INT(p), &mask); +    CPU_SET((size_t) PA_PTR_TO_INT(p), &mask);      pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0);      for (;;) { @@ -65,17 +65,17 @@ static void* work(void *p) {          pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0);          nsec = -            (uint64_t) ((((double) rand())*(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) + -            (uint64_t) (msec_lower*PA_NSEC_PER_MSEC); +            (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) + +            (uint64_t) ((uint64_t) msec_lower*PA_NSEC_PER_MSEC);          pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_INT(p), (int) (nsec/PA_NSEC_PER_MSEC)); -        end.tv_sec += nsec / PA_NSEC_PER_SEC; -        end.tv_nsec += nsec % PA_NSEC_PER_SEC; +        end.tv_sec += (time_t) (nsec / PA_NSEC_PER_SEC); +        end.tv_nsec += (long int) (nsec % PA_NSEC_PER_SEC);          while ((pa_usec_t) end.tv_nsec > PA_NSEC_PER_SEC) {              end.tv_sec++; -            end.tv_nsec -= PA_NSEC_PER_SEC; +            end.tv_nsec -= (long int) PA_NSEC_PER_SEC;          }          do { @@ -88,7 +88,7 @@ static void* work(void *p) {  int main(int argc, char*argv[]) {      int n; -    srand(time(NULL)); +    srand((unsigned) time(NULL));      if (argc >= 3) {          msec_lower = atoi(argv[1]); diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c index b78f3c91..15700ec2 100644 --- a/src/tests/smoother-test.c +++ b/src/tests/smoother-test.c @@ -64,7 +64,7 @@ int main(int argc, char*argv[]) {      for (x = 0, u = 0; x < PA_USEC_PER_SEC * 10; x += PA_USEC_PER_MSEC) {          while (u < PA_ELEMENTSOF(msec) && (pa_usec_t) msec[u]*PA_USEC_PER_MSEC < x) { -            pa_smoother_put(s, msec[u]*PA_USEC_PER_MSEC, msec[u+1]*PA_USEC_PER_MSEC); +            pa_smoother_put(s, (pa_usec_t) msec[u] * PA_USEC_PER_MSEC, (pa_usec_t) msec[u+1] * PA_USEC_PER_MSEC);              printf("%i\t\t%i\n", msec[u],  msec[u+1]);              u += 2;          } diff --git a/src/tests/stripnul.c b/src/tests/stripnul.c index 0ab06776..2b8aa083 100644 --- a/src/tests/stripnul.c +++ b/src/tests/stripnul.c @@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {      uint8_t *zero;      pa_assert_se(argc >= 2); -    pa_assert_se((granularity = atoi(argv[1])) >= 1); +    pa_assert_se((granularity = (size_t) atoi(argv[1])) >= 1);      pa_assert_se((i = (argc >= 3) ? fopen(argv[2], "r") : stdin));      pa_assert_se((o = (argc >= 4) ? fopen(argv[3], "w") : stdout)); @@ -53,11 +53,11 @@ int main(int argc, char *argv[]) {          if (found)              pa_assert_se(fwrite(buffer, granularity, k, o) == k);          else { -            for (p = buffer; (p-buffer)/granularity < k; p += granularity) +            for (p = buffer; ((size_t) (p-buffer)/granularity) < k; p += granularity)                  if (memcmp(p, zero, granularity)) {                      size_t left;                      found = TRUE; -                    left = k - (p-buffer)/granularity; +                    left = (size_t) (k - (size_t) (p-buffer)/granularity);                      pa_assert_se(fwrite(p, granularity, left, o) == left);                      break;                  } diff --git a/src/tests/strlist-test.c b/src/tests/strlist-test.c index 2bd1645c..10f370c2 100644 --- a/src/tests/strlist-test.c +++ b/src/tests/strlist-test.c @@ -5,7 +5,7 @@  #include <pulsecore/strlist.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char* argv[]) { +int main(int argc, char* argv[]) {      char *t, *u;      pa_strlist *l = NULL; diff --git a/src/tests/sync-playback.c b/src/tests/sync-playback.c index 7e364685..42c479a1 100644 --- a/src/tests/sync-playback.c +++ b/src/tests/sync-playback.c @@ -89,7 +89,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) {              fprintf(stderr, "Writing data to stream %i.\n", i); -            r = pa_stream_write(s, data, sizeof(data), nop_free_cb, sizeof(data) * i, PA_SEEK_ABSOLUTE); +            r = pa_stream_write(s, data, sizeof(data), nop_free_cb, (int64_t) sizeof(data) * (int64_t) i, PA_SEEK_ABSOLUTE);              assert(r == 0);              /* Be notified when this stream is drained */ diff --git a/src/tests/thread-mainloop-test.c b/src/tests/thread-mainloop-test.c index 7a62f85a..263cd57d 100644 --- a/src/tests/thread-mainloop-test.c +++ b/src/tests/thread-mainloop-test.c @@ -39,7 +39,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v      fprintf(stderr, "TIME EVENT END\n");  } -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) {      pa_mainloop_api *a;      pa_threaded_mainloop *m;      struct timeval tv; diff --git a/src/tests/voltest.c b/src/tests/voltest.c index d2c0ff69..5b26c0f1 100644 --- a/src/tests/voltest.c +++ b/src/tests/voltest.c @@ -3,7 +3,7 @@  #include <pulse/volume.h>  #include <pulse/gccmacro.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { +int main(int argc, char *argv[]) {      pa_volume_t v;      for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) { diff --git a/src/utils/pacat.c b/src/utils/pacat.c index 78b9cef8..c1826d7b 100644 --- a/src/utils/pacat.c +++ b/src/utils/pacat.c @@ -33,15 +33,13 @@  #include <stdlib.h>  #include <getopt.h>  #include <fcntl.h> +#include <locale.h> +#include <pulse/i18n.h>  #include <pulse/pulseaudio.h>  #define TIME_EVENT_USEC 50000 -#if PA_API_VERSION < 10 -#error Invalid PulseAudio API version -#endif -  #define CLEAR_LINE "\x1B[K"  static enum { RECORD, PLAYBACK } mode = PLAYBACK; @@ -92,7 +90,7 @@ static void do_stream_write(size_t length) {          l = buffer_length;      if (pa_stream_write(stream, (uint8_t*) buffer + buffer_index, l, NULL, 0, PA_SEEK_RELATIVE) < 0) { -        fprintf(stderr, "pa_stream_write() failed: %s\n", pa_strerror(pa_context_errno(context))); +        fprintf(stderr, _("pa_stream_write() failed: %s\n"), pa_strerror(pa_context_errno(context)));          quit(1);          return;      } @@ -131,7 +129,7 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {          mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT);      if (pa_stream_peek(s, &data, &length) < 0) { -        fprintf(stderr, "pa_stream_peek() failed: %s\n", pa_strerror(pa_context_errno(context))); +        fprintf(stderr, _("pa_stream_peek() failed: %s\n"), pa_strerror(pa_context_errno(context)));          quit(1);          return;      } @@ -140,9 +138,9 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {      assert(length > 0);      if (buffer) { -        fprintf(stderr, "Buffer overrun, dropping incoming data\n"); +        fprintf(stderr, _("Buffer overrun, dropping incoming data\n"));          if (pa_stream_drop(s) < 0) { -            fprintf(stderr, "pa_stream_drop() failed: %s\n", pa_strerror(pa_context_errno(context))); +            fprintf(stderr, _("pa_stream_drop() failed: %s\n"), pa_strerror(pa_context_errno(context)));              quit(1);          }          return; @@ -168,25 +166,25 @@ static void stream_state_callback(pa_stream *s, void *userdata) {                  const pa_buffer_attr *a;                  char cmt[PA_CHANNEL_MAP_SNPRINT_MAX], sst[PA_SAMPLE_SPEC_SNPRINT_MAX]; -                fprintf(stderr, "Stream successfully created.\n"); +                fprintf(stderr, _("Stream successfully created.\n"));                  if (!(a = pa_stream_get_buffer_attr(s))) -                    fprintf(stderr, "pa_stream_get_buffer_attr() failed: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); +                    fprintf(stderr, _("pa_stream_get_buffer_attr() failed: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s))));                  else {                      if (mode == PLAYBACK) -                        fprintf(stderr, "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n", a->maxlength, a->tlength, a->prebuf, a->minreq); +                        fprintf(stderr, _("Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"), a->maxlength, a->tlength, a->prebuf, a->minreq);                      else {                          assert(mode == RECORD); -                        fprintf(stderr, "Buffer metrics: maxlength=%u, fragsize=%u\n", a->maxlength, a->fragsize); +                        fprintf(stderr, _("Buffer metrics: maxlength=%u, fragsize=%u\n"), a->maxlength, a->fragsize);                      }                  } -                fprintf(stderr, "Using sample spec '%s', channel map '%s'.\n", +                fprintf(stderr, _("Using sample spec '%s', channel map '%s'.\n"),                          pa_sample_spec_snprint(sst, sizeof(sst), pa_stream_get_sample_spec(s)),                          pa_channel_map_snprint(cmt, sizeof(cmt), pa_stream_get_channel_map(s))); -                fprintf(stderr, "Connected to device %s (%u, %ssuspended).\n", +                fprintf(stderr, _("Connected to device %s (%u, %ssuspended).\n"),                          pa_stream_get_device_name(s),                          pa_stream_get_device_index(s),                          pa_stream_is_suspended(s) ? "" : "not "); @@ -196,7 +194,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) {          case PA_STREAM_FAILED:          default: -            fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); +            fprintf(stderr, _("Stream error: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s))));              quit(1);      }  } @@ -206,9 +204,9 @@ static void stream_suspended_callback(pa_stream *s, void *userdata) {      if (verbose) {          if (pa_stream_is_suspended(s)) -            fprintf(stderr, "Stream device suspended." CLEAR_LINE " \n"); +            fprintf(stderr, _("Stream device suspended.%s \n"), CLEAR_LINE);          else -            fprintf(stderr, "Stream device resumed." CLEAR_LINE " \n"); +            fprintf(stderr, _("Stream device resumed.%s \n"), CLEAR_LINE);      }  } @@ -216,28 +214,28 @@ static void stream_underflow_callback(pa_stream *s, void *userdata) {      assert(s);      if (verbose) -        fprintf(stderr, "Stream underrun." CLEAR_LINE " \n"); +        fprintf(stderr, _("Stream underrun.%s \n"),  CLEAR_LINE);  }  static void stream_overflow_callback(pa_stream *s, void *userdata) {      assert(s);      if (verbose) -        fprintf(stderr, "Stream overrun." CLEAR_LINE " \n"); +        fprintf(stderr, _("Stream overrun.%s \n"), CLEAR_LINE);  }  static void stream_started_callback(pa_stream *s, void *userdata) {      assert(s);      if (verbose) -        fprintf(stderr, "Stream started." CLEAR_LINE " \n"); +        fprintf(stderr, _("Stream started.%s \n"), CLEAR_LINE);  }  static void stream_moved_callback(pa_stream *s, void *userdata) {      assert(s);      if (verbose) -        fprintf(stderr, "Stream moved to device %s (%u, %ssuspended)." CLEAR_LINE " \n", pa_stream_get_device_name(s), pa_stream_get_device_index(s), pa_stream_is_suspended(s) ? "" : "not "); +        fprintf(stderr, _("Stream moved to device %s (%u, %ssuspended).%s \n"), pa_stream_get_device_name(s), pa_stream_get_device_index(s), pa_stream_is_suspended(s) ? "" : _("not "),  CLEAR_LINE);  }  /* This is called whenever the context status changes */ @@ -258,10 +256,10 @@ static void context_state_callback(pa_context *c, void *userdata) {              assert(!stream);              if (verbose) -                fprintf(stderr, "Connection established." CLEAR_LINE " \n"); +                fprintf(stderr, _("Connection established.%s \n"), CLEAR_LINE);              if (!(stream = pa_stream_new(c, stream_name, &sample_spec, channel_map_set ? &channel_map : NULL))) { -                fprintf(stderr, "pa_stream_new() failed: %s\n", pa_strerror(pa_context_errno(c))); +                fprintf(stderr, _("pa_stream_new() failed: %s\n"), pa_strerror(pa_context_errno(c)));                  goto fail;              } @@ -276,8 +274,8 @@ static void context_state_callback(pa_context *c, void *userdata) {              if (latency > 0) {                  memset(&buffer_attr, 0, sizeof(buffer_attr)); -                buffer_attr.tlength = latency; -                buffer_attr.minreq = process_time; +                buffer_attr.tlength = (uint32_t) latency; +                buffer_attr.minreq = (uint32_t) process_time;                  buffer_attr.maxlength = (uint32_t) -1;                  buffer_attr.prebuf = (uint32_t) -1;                  flags |= PA_STREAM_ADJUST_LATENCY; @@ -286,13 +284,13 @@ static void context_state_callback(pa_context *c, void *userdata) {              if (mode == PLAYBACK) {                  pa_cvolume cv;                  if ((r = pa_stream_connect_playback(stream, device, latency > 0 ? &buffer_attr : NULL, flags, pa_cvolume_set(&cv, sample_spec.channels, volume), NULL)) < 0) { -                    fprintf(stderr, "pa_stream_connect_playback() failed: %s\n", pa_strerror(pa_context_errno(c))); +                    fprintf(stderr, _("pa_stream_connect_playback() failed: %s\n"), pa_strerror(pa_context_errno(c)));                      goto fail;                  }              } else {                  if ((r = pa_stream_connect_record(stream, device, latency > 0 ? &buffer_attr : NULL, flags)) < 0) { -                    fprintf(stderr, "pa_stream_connect_record() failed: %s\n", pa_strerror(pa_context_errno(c))); +                    fprintf(stderr, _("pa_stream_connect_record() failed: %s\n"), pa_strerror(pa_context_errno(c)));                      goto fail;                  }              } @@ -306,7 +304,7 @@ static void context_state_callback(pa_context *c, void *userdata) {          case PA_CONTEXT_FAILED:          default: -            fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); +            fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c)));              goto fail;      } @@ -327,12 +325,12 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) {      pa_operation *o;      if (!success) { -        fprintf(stderr, "Failed to drain stream: %s\n", pa_strerror(pa_context_errno(context))); +        fprintf(stderr, _("Failed to drain stream: %s\n"), pa_strerror(pa_context_errno(context)));          quit(1);      }      if (verbose) -        fprintf(stderr, "Playback stream drained.\n"); +        fprintf(stderr, _("Playback stream drained.\n"));      pa_stream_disconnect(stream);      pa_stream_unref(stream); @@ -342,7 +340,7 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) {          pa_context_disconnect(context);      else {          if (verbose) -            fprintf(stderr, "Draining connection to server.\n"); +            fprintf(stderr, _("Draining connection to server.\n"));      }  } @@ -368,13 +366,13 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even      if ((r = read(fd, buffer, l)) <= 0) {          if (r == 0) {              if (verbose) -                fprintf(stderr, "Got EOF.\n"); +                fprintf(stderr, _("Got EOF.\n"));              if (stream) {                  pa_operation *o;                  if (!(o = pa_stream_drain(stream, stream_drain_complete, NULL))) { -                    fprintf(stderr, "pa_stream_drain(): %s\n", pa_strerror(pa_context_errno(context))); +                    fprintf(stderr, _("pa_stream_drain(): %s\n"), pa_strerror(pa_context_errno(context)));                      quit(1);                      return;                  } @@ -384,7 +382,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even                  quit(0);          } else { -            fprintf(stderr, "read() failed: %s\n", strerror(errno)); +            fprintf(stderr, _("read() failed: %s\n"), strerror(errno));              quit(1);          } @@ -393,7 +391,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even          return;      } -    buffer_length = r; +    buffer_length = (uint32_t) r;      buffer_index = 0;      if (w) @@ -416,7 +414,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve      assert(buffer_length);      if ((r = write(fd, (uint8_t*) buffer+buffer_index, buffer_length)) <= 0) { -        fprintf(stderr, "write() failed: %s\n", strerror(errno)); +        fprintf(stderr, _("write() failed: %s\n"), strerror(errno));          quit(1);          mainloop_api->io_free(stdio_event); @@ -424,8 +422,8 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve          return;      } -    buffer_length -= r; -    buffer_index += r; +    buffer_length -= (uint32_t) r; +    buffer_index += (uint32_t) r;      if (!buffer_length) {          pa_xfree(buffer); @@ -437,7 +435,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve  /* UNIX signal to quit recieved */  static void exit_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {      if (verbose) -        fprintf(stderr, "Got signal, exiting.\n"); +        fprintf(stderr, _("Got signal, exiting.\n"));      quit(0);  } @@ -451,14 +449,14 @@ static void stream_update_timing_callback(pa_stream *s, int success, void *userd      if (!success ||          pa_stream_get_time(s, &usec) < 0 ||          pa_stream_get_latency(s, &l, &negative) < 0) { -        fprintf(stderr, "Failed to get latency: %s\n", pa_strerror(pa_context_errno(context))); +        fprintf(stderr, _("Failed to get latency: %s\n"), pa_strerror(pa_context_errno(context)));          quit(1);          return;      } -    fprintf(stderr, "Time: %0.3f sec; Latency: %0.0f usec.  \r", +    fprintf(stderr, _("Time: %0.3f sec; Latency: %0.0f usec.  \r"),              (float) usec / 1000000, -            (float) l * (negative?-1:1)); +            (float) l * (negative?-1.0f:1.0f));  }  /* Someone requested that the latency is shown */ @@ -476,7 +474,7 @@ static void time_event_callback(pa_mainloop_api*m, pa_time_event *e, const struc      if (stream && pa_stream_get_state(stream) == PA_STREAM_READY) {          pa_operation *o;          if (!(o = pa_stream_update_timing_info(stream, stream_update_timing_callback, NULL))) -            fprintf(stderr, "pa_stream_update_timing_info() failed: %s\n", pa_strerror(pa_context_errno(context))); +            fprintf(stderr, _("pa_stream_update_timing_info() failed: %s\n"), pa_strerror(pa_context_errno(context)));          else              pa_operation_unref(o);      } @@ -489,7 +487,7 @@ static void time_event_callback(pa_mainloop_api*m, pa_time_event *e, const struc  static void help(const char *argv0) { -    printf("%s [options]\n\n" +    printf(_("%s [options]\n\n"             "  -h, --help                            Show this help\n"             "      --version                         Show version\n\n"             "  -r, --record                          Create a connection for recording\n" @@ -515,7 +513,7 @@ static void help(const char *argv0) {             "      --no-remix                        Don't upmix or downmix channels.\n"             "      --no-remap                        Map channels by index instead of name.\n"             "      --latency=BYTES                   Request the specified latency in bytes.\n" -           "      --process-time=BYTES              Request the specified process time per request in bytes.\n" +           "      --process-time=BYTES              Request the specified process time per request in bytes.\n")             ,             argv0);  } @@ -568,6 +566,9 @@ int main(int argc, char *argv[]) {          {NULL,           0, NULL, 0}      }; +    setlocale(LC_ALL, ""); +    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); +      if (!(bn = strrchr(argv[0], '/')))          bn = argv[0];      else @@ -587,7 +588,7 @@ int main(int argc, char *argv[]) {                  goto quit;              case ARG_VERSION: -                printf("pacat "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); +                printf(_("pacat %s\nCompiled with libpulse %s\nLinked with libpulse %s\n"), PACKAGE_VERSION, pa_get_headers_version(), pa_get_library_version());                  ret = 0;                  goto quit; @@ -625,12 +626,12 @@ int main(int argc, char *argv[]) {              case ARG_VOLUME: {                  int v = atoi(optarg); -                volume = v < 0 ? 0 : v; +                volume = v < 0 ? 0U : (pa_volume_t) v;                  break;              }              case ARG_CHANNELS: -                sample_spec.channels = atoi(optarg); +                sample_spec.channels = (uint8_t) atoi(optarg);                  break;              case ARG_SAMPLEFORMAT: @@ -638,12 +639,12 @@ int main(int argc, char *argv[]) {                  break;              case ARG_SAMPLERATE: -                sample_spec.rate = atoi(optarg); +                sample_spec.rate = (uint32_t) atoi(optarg);                  break;              case ARG_CHANNELMAP:                  if (!pa_channel_map_parse(&channel_map, optarg)) { -                    fprintf(stderr, "Invalid channel map '%s'\n", optarg); +                    fprintf(stderr, _("Invalid channel map '%s'\n"), optarg);                      goto quit;                  } @@ -671,15 +672,15 @@ int main(int argc, char *argv[]) {                  break;              case ARG_LATENCY: -                if (((latency = atoi(optarg))) <= 0) { -                    fprintf(stderr, "Invalid latency specification '%s'\n", optarg); +                if (((latency = (size_t) atoi(optarg))) <= 0) { +                    fprintf(stderr, _("Invalid latency specification '%s'\n"), optarg);                      goto quit;                  }                  break;              case ARG_PROCESS_TIME: -                if (((process_time = atoi(optarg))) <= 0) { -                    fprintf(stderr, "Invalid process time specification '%s'\n", optarg); +                if (((process_time = (size_t) atoi(optarg))) <= 0) { +                    fprintf(stderr, _("Invalid process time specification '%s'\n"), optarg);                      goto quit;                  }                  break; @@ -690,19 +691,19 @@ int main(int argc, char *argv[]) {      }      if (!pa_sample_spec_valid(&sample_spec)) { -        fprintf(stderr, "Invalid sample specification\n"); +        fprintf(stderr, _("Invalid sample specification\n"));          goto quit;      }      if (channel_map_set && channel_map.channels != sample_spec.channels) { -        fprintf(stderr, "Channel map doesn't match sample specification\n"); +        fprintf(stderr, _("Channel map doesn't match sample specification\n"));          goto quit;      }      if (verbose) {          char t[PA_SAMPLE_SPEC_SNPRINT_MAX];          pa_sample_spec_snprint(t, sizeof(t), &sample_spec); -        fprintf(stderr, "Opening a %s stream with sample specification '%s'.\n", mode == RECORD ? "recording" : "playback", t); +        fprintf(stderr, _("Opening a %s stream with sample specification '%s'.\n"), mode == RECORD ? _("recording") : _("playback"), t);      }      if (!(optind >= argc)) { @@ -710,12 +711,12 @@ int main(int argc, char *argv[]) {              int fd;              if ((fd = open(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) { -                fprintf(stderr, "open(): %s\n", strerror(errno)); +                fprintf(stderr, _("open(): %s\n"), strerror(errno));                  goto quit;              }              if (dup2(fd, mode == PLAYBACK ? 0 : 1) < 0) { -                fprintf(stderr, "dup2(): %s\n", strerror(errno)); +                fprintf(stderr, _("dup2(): %s\n"), strerror(errno));                  goto quit;              } @@ -725,7 +726,7 @@ int main(int argc, char *argv[]) {                  stream_name = pa_xstrdup(argv[optind]);          } else { -            fprintf(stderr, "Too many arguments.\n"); +            fprintf(stderr, _("Too many arguments.\n"));              goto quit;          }      } @@ -738,7 +739,7 @@ int main(int argc, char *argv[]) {      /* Set up a new main loop */      if (!(m = pa_mainloop_new())) { -        fprintf(stderr, "pa_mainloop_new() failed.\n"); +        fprintf(stderr, _("pa_mainloop_new() failed.\n"));          goto quit;      } @@ -759,13 +760,13 @@ int main(int argc, char *argv[]) {                                               mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,                                               mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,                                               mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) { -        fprintf(stderr, "io_new() failed.\n"); +        fprintf(stderr, _("io_new() failed.\n"));          goto quit;      }      /* Create a new connection context */      if (!(context = pa_context_new(mainloop_api, client_name))) { -        fprintf(stderr, "pa_context_new() failed.\n"); +        fprintf(stderr, _("pa_context_new() failed.\n"));          goto quit;      } @@ -781,14 +782,14 @@ int main(int argc, char *argv[]) {          pa_timeval_add(&tv, TIME_EVENT_USEC);          if (!(time_event = mainloop_api->time_new(mainloop_api, &tv, time_event_callback, NULL))) { -            fprintf(stderr, "time_new() failed.\n"); +            fprintf(stderr, _("time_new() failed.\n"));              goto quit;          }      }      /* Run the main loop */      if (pa_mainloop_run(m, &ret) < 0) { -        fprintf(stderr, "pa_mainloop_run() failed.\n"); +        fprintf(stderr, _("pa_mainloop_run() failed.\n"));          goto quit;      } diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c index 67d95252..2c89c8d9 100644 --- a/src/utils/pacmd.c +++ b/src/utils/pacmd.c @@ -31,16 +31,18 @@  #include <errno.h>  #include <string.h>  #include <sys/un.h> +#include <locale.h>  #include <pulse/error.h>  #include <pulse/util.h>  #include <pulse/xmalloc.h> +#include <pulse/i18n.h>  #include <pulsecore/core-util.h>  #include <pulsecore/log.h>  #include <pulsecore/pid.h> -int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) { +int main(int argc, char*argv[]) {      pid_t pid ;      int fd = -1;      int ret = 1, i; @@ -50,13 +52,16 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {      fd_set ifds, ofds;      char *cli; +    setlocale(LC_ALL, ""); +    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); +      if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) { -        pa_log("no PulseAudio daemon running"); +        pa_log("No PulseAudio daemon running");          goto fail;      }      if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { -        pa_log("socket(PF_UNIX, SOCK_STREAM, 0): %s", strerror(errno)); +        pa_log(_("socket(PF_UNIX, SOCK_STREAM, 0): %s"), strerror(errno));          goto fail;      } @@ -73,7 +78,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {          int r;          if ((r = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && (errno != ECONNREFUSED && errno != ENOENT)) { -            pa_log("connect(): %s", strerror(errno)); +            pa_log(_("connect(): %s"), strerror(errno));              goto fail;          } @@ -81,7 +86,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {              break;          if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0) { -            pa_log("failed to kill PulseAudio daemon."); +            pa_log(_("Failed to kill PulseAudio daemon."));              goto fail;          } @@ -89,7 +94,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {      }      if (i >= 5) { -        pa_log("daemon not responding."); +        pa_log(_("Daemon not responding."));          goto fail;      } @@ -104,7 +109,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {      for (;;) {          if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) { -            pa_log("select(): %s", strerror(errno)); +            pa_log(_("select(): %s"), strerror(errno));              goto fail;          } @@ -116,7 +121,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {                  if (r == 0)                      break; -                pa_log("read(): %s", strerror(errno)); +                pa_log(_("read(): %s"), strerror(errno));                  goto fail;              } @@ -132,7 +137,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {                  if (r == 0)                      break; -                pa_log("read(): %s", strerror(errno)); +                pa_log(_("read(): %s"), strerror(errno));                  goto fail;              } @@ -145,7 +150,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {              assert(obuf_length);              if ((r = write(1, obuf + obuf_index, obuf_length)) < 0) { -                pa_log("write(): %s", strerror(errno)); +                pa_log(_("write(): %s"), strerror(errno));                  goto fail;              } @@ -159,7 +164,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {              assert(ibuf_length);              if ((r = write(fd, ibuf + ibuf_index, ibuf_length)) < 0) { -                pa_log("write(): %s", strerror(errno)); +                pa_log(_("write(): %s"), strerror(errno));                  goto fail;              } @@ -182,7 +187,6 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {              FD_SET(fd, &ofds);      } -      ret = 0;  fail: diff --git a/src/utils/pactl.c b/src/utils/pactl.c index 4cca2f86..2f430ca7 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -32,16 +32,14 @@  #include <stdlib.h>  #include <limits.h>  #include <getopt.h> +#include <locale.h>  #include <sndfile.h> +#include <pulse/i18n.h>  #include <pulse/pulseaudio.h>  #include <pulsecore/core-util.h> -#if PA_API_VERSION < 10 -#error Invalid PulseAudio API version -#endif -  #define BUFSIZE 1024  static pa_context *context = NULL; @@ -106,19 +104,19 @@ static void complete_action(void) {  static void stat_callback(pa_context *c, const pa_stat_info *i, void *userdata) {      char s[128];      if (!i) { -        fprintf(stderr, "Failed to get statistics: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get statistics: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      }      pa_bytes_snprint(s, sizeof(s), i->memblock_total_size); -    printf("Currently in use: %u blocks containing %s bytes total.\n", i->memblock_total, s); +    printf(_("Currently in use: %u blocks containing %s bytes total.\n"), i->memblock_total, s);      pa_bytes_snprint(s, sizeof(s), i->memblock_allocated_size); -    printf("Allocated during whole lifetime: %u blocks containing %s bytes total.\n", i->memblock_allocated, s); +    printf(_("Allocated during whole lifetime: %u blocks containing %s bytes total.\n"), i->memblock_allocated, s);      pa_bytes_snprint(s, sizeof(s), i->scache_size); -    printf("Sample cache size: %s\n", s); +    printf(_("Sample cache size: %s\n"), s);      complete_action();  } @@ -127,21 +125,21 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi      char s[PA_SAMPLE_SPEC_SNPRINT_MAX];      if (!i) { -        fprintf(stderr, "Failed to get server information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get server information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      }      pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec); -    printf("User name: %s\n" +    printf(_("User name: %s\n"             "Host Name: %s\n"             "Server Name: %s\n"             "Server Version: %s\n"             "Default Sample Specification: %s\n"             "Default Sink: %s\n"             "Default Source: %s\n" -           "Cookie: %08x\n", +           "Cookie: %08x\n"),             i->user_name,             i->host_name,             i->server_name, @@ -159,7 +157,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_      char *pl;      if (is_last < 0) { -        fprintf(stderr, "Failed to get sink information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get sink information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -175,7 +173,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_          printf("\n");      nl = 1; -    printf("*** Sink #%u ***\n" +    printf(_("*** Sink #%u ***\n"             "Name: %s\n"             "Driver: %s\n"             "Sample Specification: %s\n" @@ -185,14 +183,14 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_             "Monitor Source: %s\n"             "Latency: %0.0f usec, configured %0.0f usec\n"             "Flags: %s%s%s%s%s%s\n" -           "Properties:\n%s", +           "Properties:\n%s"),             i->index,             i->name,             pa_strnull(i->driver),             pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),             pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),             i->owner_module, -           i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), +           i->mute ? _("muted") : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),             pa_strnull(i->monitor_source_name),             (double) i->latency, (double) i->configured_latency,             i->flags & PA_SINK_HARDWARE ? "HARDWARE " : "", @@ -211,7 +209,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int      char *pl;      if (is_last < 0) { -        fprintf(stderr, "Failed to get source information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get source information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -227,7 +225,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int          printf("\n");      nl = 1; -    printf("*** Source #%u ***\n" +    printf(_("*** Source #%u ***\n"             "Name: %s\n"             "Driver: %s\n"             "Sample Specification: %s\n" @@ -237,7 +235,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int             "Monitor of Sink: %s\n"             "Latency: %0.0f usec, configured %0.0f usec\n"             "Flags: %s%s%s%s%s%s\n" -           "Properties:\n%s", +           "Properties:\n%s"),             i->index,             i->name,             pa_strnull(i->driver), @@ -245,7 +243,7 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int             pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),             i->owner_module,             i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), -           i->monitor_of_sink_name ? i->monitor_of_sink_name : "n/a", +           i->monitor_of_sink_name ? i->monitor_of_sink_name : _("n/a"),             (double) i->latency, (double) i->configured_latency,             i->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "",             i->flags & PA_SOURCE_NETWORK ? "NETWORK " : "", @@ -262,7 +260,7 @@ static void get_module_info_callback(pa_context *c, const pa_module_info *i, int      char t[32];      if (is_last < 0) { -        fprintf(stderr, "Failed to get module information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get module information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -280,15 +278,15 @@ static void get_module_info_callback(pa_context *c, const pa_module_info *i, int      snprintf(t, sizeof(t), "%u", i->n_used); -    printf("*** Module #%u ***\n" +    printf(_("*** Module #%u ***\n"             "Name: %s\n"             "Argument: %s\n"             "Usage counter: %s\n" -           "Auto unload: %s\n", +           "Auto unload: %s\n"),             i->index,             i->name,             i->argument ? i->argument : "", -           i->n_used != PA_INVALID_INDEX ? t : "n/a", +           i->n_used != PA_INVALID_INDEX ? t : _("n/a"),             pa_yes_no(i->auto_unload));  } @@ -297,7 +295,7 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int      char *pl;      if (is_last < 0) { -        fprintf(stderr, "Failed to get client information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get client information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -315,13 +313,13 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int      snprintf(t, sizeof(t), "%u", i->owner_module); -    printf("*** Client #%u ***\n" +    printf(_("*** Client #%u ***\n"             "Driver: %s\n"             "Owner Module: %s\n" -           "Properties:\n%s", +           "Properties:\n%s"),             i->index,             pa_strnull(i->driver), -           i->owner_module != PA_INVALID_INDEX ? t : "n/a", +           i->owner_module != PA_INVALID_INDEX ? t : _("n/a"),             pl = pa_proplist_to_string(i->proplist));      pa_xfree(pl); @@ -332,7 +330,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info      char *pl;      if (is_last < 0) { -        fprintf(stderr, "Failed to get sink input information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get sink input information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -351,7 +349,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info      snprintf(t, sizeof(t), "%u", i->owner_module);      snprintf(k, sizeof(k), "%u", i->client); -    printf("*** Sink Input #%u ***\n" +    printf(_("*** Sink Input #%u ***\n"             "Driver: %s\n"             "Owner Module: %s\n"             "Client: %s\n" @@ -362,18 +360,18 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info             "Buffer Latency: %0.0f usec\n"             "Sink Latency: %0.0f usec\n"             "Resample method: %s\n" -           "Properties:\n%s", +             "Properties:\n%s"),             i->index,             pa_strnull(i->driver), -           i->owner_module != PA_INVALID_INDEX ? t : "n/a", -           i->client != PA_INVALID_INDEX ? k : "n/a", +           i->owner_module != PA_INVALID_INDEX ? t : _("n/a"), +           i->client != PA_INVALID_INDEX ? k : _("n/a"),             i->sink,             pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),             pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), -           i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), +           i->mute ? _("muted") : pa_cvolume_snprint(cv, sizeof(cv), &i->volume),             (double) i->buffer_usec,             (double) i->sink_usec, -           i->resample_method ? i->resample_method : "n/a", +           i->resample_method ? i->resample_method : _("n/a"),             pl = pa_proplist_to_string(i->proplist));      pa_xfree(pl); @@ -384,7 +382,7 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu      char *pl;      if (is_last < 0) { -        fprintf(stderr, "Failed to get source output information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get source output information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -404,7 +402,7 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu      snprintf(t, sizeof(t), "%u", i->owner_module);      snprintf(k, sizeof(k), "%u", i->client); -    printf("*** Source Output #%u ***\n" +    printf(_("*** Source Output #%u ***\n"             "Driver: %s\n"             "Owner Module: %s\n"             "Client: %s\n" @@ -414,17 +412,17 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu             "Buffer Latency: %0.0f usec\n"             "Source Latency: %0.0f usec\n"             "Resample method: %s\n" -           "Properties:\n%s", +           "Properties:\n%s"),             i->index,             pa_strnull(i->driver), -           i->owner_module != PA_INVALID_INDEX ? t : "n/a", -           i->client != PA_INVALID_INDEX ? k : "n/a", +           i->owner_module != PA_INVALID_INDEX ? t : _("n/a"), +           i->client != PA_INVALID_INDEX ? k : _("n/a"),             i->source,             pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),             pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),             (double) i->buffer_usec,             (double) i->source_usec, -           i->resample_method ? i->resample_method : "n/a", +           i->resample_method ? i->resample_method : _("n/a"),             pl = pa_proplist_to_string(i->proplist));      pa_xfree(pl); @@ -435,7 +433,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int      char *pl;      if (is_last < 0) { -        fprintf(stderr, "Failed to get sample information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get sample information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -454,7 +452,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int      pa_bytes_snprint(t, sizeof(t), i->bytes); -    printf("*** Sample #%u ***\n" +    printf(_("*** Sample #%u ***\n"             "Name: %s\n"             "Volume: %s\n"             "Sample Specification: %s\n" @@ -463,16 +461,16 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int             "Size: %s\n"             "Lazy: %s\n"             "Filename: %s\n" -           "Properties:\n%s", +           "Properties:\n%s"),             i->index,             i->name,             pa_cvolume_snprint(cv, sizeof(cv), &i->volume), -           pa_sample_spec_valid(&i->sample_spec) ? pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec) : "n/a", -           pa_sample_spec_valid(&i->sample_spec) ? pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map) : "n/a", +           pa_sample_spec_valid(&i->sample_spec) ? pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec) : _("n/a"), +           pa_sample_spec_valid(&i->sample_spec) ? pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map) : _("n/a"),             (double) i->duration/1000000,             t,             pa_yes_no(i->lazy), -           i->filename ? i->filename : "n/a", +           i->filename ? i->filename : _("n/a"),             pl = pa_proplist_to_string(i->proplist));      pa_xfree(pl); @@ -480,7 +478,7 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int  static void get_autoload_info_callback(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata) {      if (is_last < 0) { -        fprintf(stderr, "Failed to get autoload information: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failed to get autoload information: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -496,21 +494,21 @@ static void get_autoload_info_callback(pa_context *c, const pa_autoload_info *i,          printf("\n");      nl = 1; -    printf("*** Autoload Entry #%u ***\n" +    printf(_("*** Autoload Entry #%u ***\n"             "Name: %s\n"             "Type: %s\n"             "Module: %s\n" -           "Argument: %s\n", +             "Argument: %s\n"),             i->index,             i->name, -           i->type == PA_AUTOLOAD_SINK ? "sink" : "source", +           i->type == PA_AUTOLOAD_SINK ? _("sink") : _("source"),             i->module,             i->argument ? i->argument : "");  }  static void simple_callback(pa_context *c, int success, void *userdata) {      if (!success) { -        fprintf(stderr, "Failure: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failure: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -520,7 +518,7 @@ static void simple_callback(pa_context *c, int success, void *userdata) {  static void index_callback(pa_context *c, uint32_t idx, void *userdata) {      if (idx == PA_INVALID_INDEX) { -        fprintf(stderr, "Failure: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failure: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -544,7 +542,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) {          case PA_STREAM_FAILED:          default: -            fprintf(stderr, "Failed to upload sample: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); +            fprintf(stderr, _("Failed to upload sample: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s))));              quit(1);      }  } @@ -557,11 +555,11 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {      d = pa_xmalloc(length);      assert(sample_length >= length); -    l = length/pa_frame_size(&sample_spec); +    l = (sf_count_t) (length/pa_frame_size(&sample_spec));      if ((sf_readf_float(sndfile, d, l)) != l) {          pa_xfree(d); -        fprintf(stderr, "Premature end of file\n"); +        fprintf(stderr, _("Premature end of file\n"));          quit(1);      } @@ -609,8 +607,8 @@ static void context_state_callback(pa_context *c, void *userdata) {                      break;                  case EXIT: -                    pa_operation_unref(pa_context_exit_daemon(c, NULL, NULL)); -                    drain(); +                    pa_operation_unref(pa_context_exit_daemon(c, simple_callback, NULL)); +                    break;                  case LIST:                      actions = 8; @@ -665,19 +663,19 @@ static void context_state_callback(pa_context *c, void *userdata) {          case PA_CONTEXT_FAILED:          default: -            fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); +            fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c)));              quit(1);      }  }  static void exit_signal_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { -    fprintf(stderr, "Got SIGINT, exiting.\n"); +    fprintf(stderr, _("Got SIGINT, exiting.\n"));      quit(0);  }  static void help(const char *argv0) { -    printf("%s [options] stat\n" +    printf(_("%s [options] stat\n"             "%s [options] list\n"             "%s [options] exit\n"             "%s [options] upload-sample FILENAME [NAME]\n" @@ -692,7 +690,7 @@ static void help(const char *argv0) {             "  -h, --help                            Show this help\n"             "      --version                         Show version\n\n"             "  -s, --server=SERVER                   The name of the server to connect to\n" -           "  -n, --client-name=NAME                How to call this client on the server\n", +           "  -n, --client-name=NAME                How to call this client on the server\n"),             argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0);  } @@ -712,6 +710,9 @@ int main(int argc, char *argv[]) {          {NULL,          0, NULL, 0}      }; +    setlocale(LC_ALL, ""); +    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); +      if (!(bn = strrchr(argv[0], '/')))          bn = argv[0];      else @@ -725,7 +726,12 @@ int main(int argc, char *argv[]) {                  goto quit;              case ARG_VERSION: -                printf("pactl "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); +                printf(_("pactl %s\n" +                         "Compiled with libpulse %s\n" +                         "Linked with libpulse %s\n"), +                       PACKAGE_VERSION, +                       pa_get_headers_version(), +                       pa_get_library_version());                  ret = 0;                  goto quit; @@ -759,7 +765,7 @@ int main(int argc, char *argv[]) {              action = UPLOAD_SAMPLE;              if (optind+1 >= argc) { -                fprintf(stderr, "Please specify a sample file to load\n"); +                fprintf(stderr, _("Please specify a sample file to load\n"));                  goto quit;              } @@ -781,19 +787,19 @@ int main(int argc, char *argv[]) {              memset(&sfinfo, 0, sizeof(sfinfo));              if (!(sndfile = sf_open(argv[optind+1], SFM_READ, &sfinfo))) { -                fprintf(stderr, "Failed to open sound file.\n"); +                fprintf(stderr, _("Failed to open sound file.\n"));                  goto quit;              } -            sample_spec.format =  PA_SAMPLE_FLOAT32; -            sample_spec.rate = sfinfo.samplerate; -            sample_spec.channels = sfinfo.channels; +            sample_spec.format = PA_SAMPLE_FLOAT32; +            sample_spec.rate = (uint32_t) sfinfo.samplerate; +            sample_spec.channels = (uint8_t) sfinfo.channels; -            sample_length = sfinfo.frames*pa_frame_size(&sample_spec); +            sample_length = (size_t)sfinfo.frames*pa_frame_size(&sample_spec);          } else if (!strcmp(argv[optind], "play-sample")) {              action = PLAY_SAMPLE;              if (argc != optind+2 && argc != optind+3) { -                fprintf(stderr, "You have to specify a sample name to play\n"); +                fprintf(stderr, _("You have to specify a sample name to play\n"));                  goto quit;              } @@ -805,7 +811,7 @@ int main(int argc, char *argv[]) {          } else if (!strcmp(argv[optind], "remove-sample")) {              action = REMOVE_SAMPLE;              if (argc != optind+2) { -                fprintf(stderr, "You have to specify a sample name to remove\n"); +                fprintf(stderr, _("You have to specify a sample name to remove\n"));                  goto quit;              } @@ -813,20 +819,20 @@ int main(int argc, char *argv[]) {          } else if (!strcmp(argv[optind], "move-sink-input")) {              action = MOVE_SINK_INPUT;              if (argc != optind+3) { -                fprintf(stderr, "You have to specify a sink input index and a sink\n"); +                fprintf(stderr, _("You have to specify a sink input index and a sink\n"));                  goto quit;              } -            sink_input_idx = atoi(argv[optind+1]); +            sink_input_idx = (uint32_t) atoi(argv[optind+1]);              sink_name = pa_xstrdup(argv[optind+2]);          } else if (!strcmp(argv[optind], "move-source-output")) {              action = MOVE_SOURCE_OUTPUT;              if (argc != optind+3) { -                fprintf(stderr, "You have to specify a source output index and a source\n"); +                fprintf(stderr, _("You have to specify a source output index and a source\n"));                  goto quit;              } -            source_output_idx = atoi(argv[optind+1]); +            source_output_idx = (uint32_t) atoi(argv[optind+1]);              source_name = pa_xstrdup(argv[optind+2]);          } else if (!strcmp(argv[optind], "load-module")) {              int i; @@ -836,7 +842,7 @@ int main(int argc, char *argv[]) {              action = LOAD_MODULE;              if (argc <= optind+1) { -                fprintf(stderr, "You have to specify a module name and arguments.\n"); +                fprintf(stderr, _("You have to specify a module name and arguments.\n"));                  goto quit;              } @@ -846,7 +852,7 @@ int main(int argc, char *argv[]) {                  n += strlen(argv[i])+1;              if (n > 0) { -                p = module_args = pa_xnew0(char, n); +                p = module_args = pa_xmalloc(n);                  for (i = optind+2; i < argc; i++)                      p += sprintf(p, "%s%s", p == module_args ? "" : " ", argv[i]); @@ -856,17 +862,17 @@ int main(int argc, char *argv[]) {              action = UNLOAD_MODULE;              if (argc != optind+2) { -                fprintf(stderr, "You have to specify a module index\n"); +                fprintf(stderr, _("You have to specify a module index\n"));                  goto quit;              } -            module_index = atoi(argv[optind+1]); +            module_index = (uint32_t) atoi(argv[optind+1]);          } else if (!strcmp(argv[optind], "suspend-sink")) {              action = SUSPEND_SINK;              if (argc > optind+3 || optind+1 >= argc) { -                fprintf(stderr, "You may not specify more than one sink. You have to specify at least one boolean value.\n"); +                fprintf(stderr, _("You may not specify more than one sink. You have to specify at least one boolean value.\n"));                  goto quit;              } @@ -879,7 +885,7 @@ int main(int argc, char *argv[]) {              action = SUSPEND_SOURCE;              if (argc > optind+3 || optind+1 >= argc) { -                fprintf(stderr, "You may not specify more than one source. You have to specify at least one boolean value.\n"); +                fprintf(stderr, _("You may not specify more than one source. You have to specify at least one boolean value.\n"));                  goto quit;              } @@ -895,12 +901,12 @@ int main(int argc, char *argv[]) {      }      if (action == NONE) { -        fprintf(stderr, "No valid command specified.\n"); +        fprintf(stderr, _("No valid command specified.\n"));          goto quit;      }      if (!(m = pa_mainloop_new())) { -        fprintf(stderr, "pa_mainloop_new() failed.\n"); +        fprintf(stderr, _("pa_mainloop_new() failed.\n"));          goto quit;      } @@ -914,7 +920,7 @@ int main(int argc, char *argv[]) {  #endif      if (!(context = pa_context_new(mainloop_api, client_name))) { -        fprintf(stderr, "pa_context_new() failed.\n"); +        fprintf(stderr, _("pa_context_new() failed.\n"));          goto quit;      } @@ -922,7 +928,7 @@ int main(int argc, char *argv[]) {      pa_context_connect(context, server, 0, NULL);      if (pa_mainloop_run(m, &ret) < 0) { -        fprintf(stderr, "pa_mainloop_run() failed.\n"); +        fprintf(stderr, _("pa_mainloop_run() failed.\n"));          goto quit;      } diff --git a/src/utils/padsp.c b/src/utils/padsp.c index d650707e..134a7e58 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -748,7 +748,7 @@ static void fix_metrics(fd_info *i) {      /* Number of fragments set? */      if (i->n_fragments < 2) {          if (i->fragment_size > 0) { -            i->n_fragments = pa_bytes_per_second(&i->sample_spec) / 2 / i->fragment_size; +            i->n_fragments = (unsigned) (pa_bytes_per_second(&i->sample_spec) / 2 / i->fragment_size);              if (i->n_fragments < 2)                  i->n_fragments = 2;          } else @@ -864,7 +864,7 @@ static int fd_info_copy_data(fd_info *i, int force) {                  return -1;              } -            if (pa_stream_write(i->play_stream, i->buf, r, free, 0, PA_SEEK_RELATIVE) < 0) { +            if (pa_stream_write(i->play_stream, i->buf, (size_t) r, free, 0, PA_SEEK_RELATIVE) < 0) {                  debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_write(): %s\n", pa_strerror(pa_context_errno(i->context)));                  return -1;              } @@ -872,7 +872,7 @@ static int fd_info_copy_data(fd_info *i, int force) {              i->buf = NULL;              assert(n >= (size_t) r); -            n -= r; +            n -= (size_t) r;          }          if (n >= i->fragment_size) @@ -916,7 +916,7 @@ static int fd_info_copy_data(fd_info *i, int force) {              }              assert((size_t)r <= len - i->rec_offset); -            i->rec_offset += r; +            i->rec_offset += (size_t) r;              if (i->rec_offset == len) {                  if (pa_stream_drop(i->rec_stream) < 0) { @@ -927,7 +927,7 @@ static int fd_info_copy_data(fd_info *i, int force) {              }              assert(n >= (size_t) r); -            n -= r; +            n -= (size_t) r;          }          if (n >= i->fragment_size) @@ -998,10 +998,10 @@ static int create_playback_stream(fd_info *i) {      pa_stream_set_latency_update_callback(i->play_stream, stream_latency_update_cb, i);      memset(&attr, 0, sizeof(attr)); -    attr.maxlength = i->fragment_size * (i->n_fragments+1); -    attr.tlength = i->fragment_size * i->n_fragments; -    attr.prebuf = i->fragment_size; -    attr.minreq = i->fragment_size; +    attr.maxlength = (uint32_t) (i->fragment_size * (i->n_fragments+1)); +    attr.tlength = (uint32_t) (i->fragment_size * i->n_fragments); +    attr.prebuf = (uint32_t) i->fragment_size; +    attr.minreq = (uint32_t) i->fragment_size;      flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;      if (i->play_precork) { @@ -1013,9 +1013,9 @@ static int create_playback_stream(fd_info *i) {          goto fail;      } -    n = i->fragment_size; +    n = (int) i->fragment_size;      setsockopt(i->app_fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)); -    n = i->fragment_size; +    n = (int) i->fragment_size;      setsockopt(i->thread_fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));      return 0; @@ -1042,8 +1042,8 @@ static int create_record_stream(fd_info *i) {      pa_stream_set_latency_update_callback(i->rec_stream, stream_latency_update_cb, i);      memset(&attr, 0, sizeof(attr)); -    attr.maxlength = i->fragment_size * (i->n_fragments+1); -    attr.fragsize = i->fragment_size; +    attr.maxlength = (uint32_t) (i->fragment_size * (i->n_fragments+1)); +    attr.fragsize = (uint32_t) i->fragment_size;      flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;      if (i->rec_precork) { @@ -1055,9 +1055,9 @@ static int create_record_stream(fd_info *i) {          goto fail;      } -    n = i->fragment_size; +    n = (int) i->fragment_size;      setsockopt(i->app_fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)); -    n = i->fragment_size; +    n = (int) i->fragment_size;      setsockopt(i->thread_fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n));      return 0; @@ -1474,7 +1474,7 @@ int open(const char *filename, int flags, ...) {      if (flags & O_CREAT) {          va_start(args, flags);          if (sizeof(mode_t) < sizeof(int)) -            mode = va_arg(args, int); +            mode = (mode_t) va_arg(args, int);          else              mode = va_arg(args, mode_t);          va_end(args); @@ -2250,7 +2250,7 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno)              for (;;) {                  pa_usec_t usec; -                PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, exit_loop); +                PLAYBACK_STREAM_CHECK_DEAD_GOTO(i, exit_loop2);                  if (pa_stream_get_time(i->play_stream, &usec) >= 0) {                      size_t k = pa_usec_to_bytes(usec, &i->sample_spec); @@ -2272,6 +2272,8 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno)                  pa_threaded_mainloop_wait(i->mainloop);              } +        exit_loop2: +              pa_threaded_mainloop_unlock(i->mainloop);              debug(DEBUG_LEVEL_NORMAL, __FILE__": GETOPTR bytes=%i, blocks=%i, ptr=%i\n", info->bytes, info->blocks, info->ptr); diff --git a/src/utils/paplay.c b/src/utils/paplay.c index 1b6228b1..df2edf62 100644 --- a/src/utils/paplay.c +++ b/src/utils/paplay.c @@ -37,10 +37,7 @@  #include <sndfile.h>  #include <pulse/pulseaudio.h> - -#if PA_API_VERSION < 9 -#error Invalid PulseAudio API version -#endif +#include <pulse/i18n.h>  static pa_context *context = NULL;  static pa_stream *stream = NULL; @@ -75,12 +72,12 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) {      pa_operation *o;      if (!success) { -        fprintf(stderr, "Failed to drain stream: %s\n", pa_strerror(pa_context_errno(context))); +        fprintf(stderr, _("Failed to drain stream: %s\n"), pa_strerror(pa_context_errno(context)));          quit(1);      }      if (verbose) -        fprintf(stderr, "Playback stream drained.\n"); +        fprintf(stderr, _("Playback stream drained.\n"));      pa_stream_disconnect(stream);      pa_stream_unref(stream); @@ -92,7 +89,7 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) {          pa_operation_unref(o);          if (verbose) -            fprintf(stderr, "Draining connection to server.\n"); +            fprintf(stderr, _("Draining connection to server.\n"));      }  } @@ -110,14 +107,14 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {      if (readf_function) {          size_t k = pa_frame_size(&sample_spec); -        if ((bytes = readf_function(sndfile, data, length/k)) > 0) -            bytes *= k; +        if ((bytes = readf_function(sndfile, data, (sf_count_t) (length/k))) > 0) +            bytes *= (sf_count_t) k;      } else -        bytes = sf_read_raw(sndfile, data, length); +        bytes = sf_read_raw(sndfile, data, (sf_count_t) length);      if (bytes > 0) -        pa_stream_write(s, data, bytes, pa_xfree, 0, PA_SEEK_RELATIVE); +        pa_stream_write(s, data, (size_t) bytes, pa_xfree, 0, PA_SEEK_RELATIVE);      else          pa_xfree(data); @@ -139,12 +136,12 @@ static void stream_state_callback(pa_stream *s, void *userdata) {          case PA_STREAM_READY:              if (verbose) -                fprintf(stderr, "Stream successfully created\n"); +                fprintf(stderr, _("Stream successfully created\n"));              break;          case PA_STREAM_FAILED:          default: -            fprintf(stderr, "Stream errror: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); +            fprintf(stderr, _("Stream errror: %s\n"), pa_strerror(pa_context_errno(pa_stream_get_context(s))));              quit(1);      }  } @@ -165,7 +162,7 @@ static void context_state_callback(pa_context *c, void *userdata) {              assert(c && !stream);              if (verbose) -                fprintf(stderr, "Connection established.\n"); +                fprintf(stderr, _("Connection established.\n"));              stream = pa_stream_new(c, stream_name, &sample_spec, channel_map_set ? &channel_map : NULL);              assert(stream); @@ -183,7 +180,7 @@ static void context_state_callback(pa_context *c, void *userdata) {          case PA_CONTEXT_FAILED:          default: -            fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); +            fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c)));              quit(1);      }  } @@ -191,14 +188,14 @@ static void context_state_callback(pa_context *c, void *userdata) {  /* UNIX signal to quit recieved */  static void exit_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {      if (verbose) -        fprintf(stderr, "Got SIGINT, exiting.\n"); +        fprintf(stderr, _("Got SIGINT, exiting.\n"));      quit(0);  }  static void help(const char *argv0) { -    printf("%s [options] [FILE]\n\n" +    printf(_("%s [options] [FILE]\n\n"             "  -h, --help                            Show this help\n"             "      --version                         Show version\n\n"             "  -v, --verbose                         Enable verbose operation\n\n" @@ -207,7 +204,7 @@ static void help(const char *argv0) {             "  -n, --client-name=NAME                How to call this client on the server\n"             "      --stream-name=NAME                How to call this stream on the server\n"             "      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n" -           "      --channel-map=CHANNELMAP          Set the channel map to the use\n", +             "      --channel-map=CHANNELMAP          Set the channel map to the use\n"),             argv0);  } @@ -239,6 +236,7 @@ int main(int argc, char *argv[]) {      };      setlocale(LC_ALL, ""); +    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);      if (!(bn = strrchr(argv[0], '/')))          bn = argv[0]; @@ -254,7 +252,8 @@ int main(int argc, char *argv[]) {                  goto quit;              case ARG_VERSION: -                printf("paplay "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); +                printf(_("paplay %s\nCompiled with libpulse %s\n" +                        "Linked with libpulse %s\n"), PACKAGE_VERSION, pa_get_headers_version(), pa_get_library_version());                  ret = 0;                  goto quit; @@ -284,13 +283,13 @@ int main(int argc, char *argv[]) {              case ARG_VOLUME: {                  int v = atoi(optarg); -                volume = v < 0 ? 0 : v; +                volume = v < 0 ? 0U : (pa_volume_t) v;                  break;              }              case ARG_CHANNELMAP:                  if (!pa_channel_map_parse(&channel_map, optarg)) { -                    fprintf(stderr, "Invalid channel map\n"); +                    fprintf(stderr, _("Invalid channel map\n"));                      goto quit;                  } @@ -312,12 +311,12 @@ int main(int argc, char *argv[]) {          sndfile = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0);      if (!sndfile) { -        fprintf(stderr, "Failed to open file '%s'\n", filename); +        fprintf(stderr, _("Failed to open file '%s'\n"), filename);          goto quit;      } -    sample_spec.rate = sfinfo.samplerate; -    sample_spec.channels = sfinfo.channels; +    sample_spec.rate = (uint32_t) sfinfo.samplerate; +    sample_spec.channels = (uint8_t) sfinfo.channels;      readf_function = NULL; @@ -348,7 +347,7 @@ int main(int argc, char *argv[]) {      assert(pa_sample_spec_valid(&sample_spec));      if (channel_map_set && channel_map.channels != sample_spec.channels) { -        fprintf(stderr, "Channel map doesn't match file.\n"); +        fprintf(stderr, _("Channel map doesn't match file.\n"));          goto quit;      } @@ -374,12 +373,12 @@ int main(int argc, char *argv[]) {      if (verbose) {          char t[PA_SAMPLE_SPEC_SNPRINT_MAX];          pa_sample_spec_snprint(t, sizeof(t), &sample_spec); -        fprintf(stderr, "Using sample spec '%s'\n", t); +        fprintf(stderr, _("Using sample spec '%s'\n"), t);      }      /* Set up a new main loop */      if (!(m = pa_mainloop_new())) { -        fprintf(stderr, "pa_mainloop_new() failed.\n"); +        fprintf(stderr, _("pa_mainloop_new() failed.\n"));          goto quit;      } @@ -394,7 +393,7 @@ int main(int argc, char *argv[]) {      /* Create a new connection context */      if (!(context = pa_context_new(mainloop_api, client_name))) { -        fprintf(stderr, "pa_context_new() failed.\n"); +        fprintf(stderr, _("pa_context_new() failed.\n"));          goto quit;      } @@ -405,7 +404,7 @@ int main(int argc, char *argv[]) {      /* Run the main loop */      if (pa_mainloop_run(m, &ret) < 0) { -        fprintf(stderr, "pa_mainloop_run() failed.\n"); +        fprintf(stderr, _("pa_mainloop_run() failed.\n"));          goto quit;      } diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c index 5b4885db..8a59d5e4 100644 --- a/src/utils/pasuspender.c +++ b/src/utils/pasuspender.c @@ -35,20 +35,16 @@  #include <stdlib.h>  #include <limits.h>  #include <getopt.h> - -#include <sndfile.h> +#include <locale.h>  #ifdef __linux__  #include <sys/prctl.h>  #endif +#include <pulse/i18n.h>  #include <pulse/pulseaudio.h>  #include <pulsecore/macro.h> -#if PA_API_VERSION < 10 -#error Invalid PulseAudio API version -#endif -  #define BUFSIZE 1024  static pa_context *context = NULL; @@ -82,7 +78,7 @@ static void start_child(void) {      if ((child_pid = fork()) < 0) { -        fprintf(stderr, "fork(): %s\n", strerror(errno)); +        fprintf(stderr, _("fork(): %s\n"), strerror(errno));          quit(1);      } else if (child_pid == 0) { @@ -93,7 +89,7 @@ static void start_child(void) {  #endif          if (execvp(child_argv[0], child_argv) < 0) -            fprintf(stderr, "execvp(): %s\n", strerror(errno)); +            fprintf(stderr, _("execvp(): %s\n"), strerror(errno));          _exit(1); @@ -110,7 +106,7 @@ static void suspend_complete(pa_context *c, int success, void *userdata) {      n++;      if (!success) { -        fprintf(stderr, "Failure to suspend: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failure to suspend: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -125,7 +121,7 @@ static void resume_complete(pa_context *c, int success, void *userdata) {      n++;      if (!success) { -        fprintf(stderr, "Failure to resume: %s\n", pa_strerror(pa_context_errno(c))); +        fprintf(stderr, _("Failure to resume: %s\n"), pa_strerror(pa_context_errno(c)));          quit(1);          return;      } @@ -148,7 +144,7 @@ static void context_state_callback(pa_context *c, void *userdata) {                  pa_operation_unref(pa_context_suspend_sink_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL));                  pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL));              } else { -                fprintf(stderr, "WARNING: Sound server is not local, not suspending.\n"); +                fprintf(stderr, _("WARNING: Sound server is not local, not suspending.\n"));                  start_child();              } @@ -160,7 +156,7 @@ static void context_state_callback(pa_context *c, void *userdata) {          case PA_CONTEXT_FAILED:          default: -            fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); +            fprintf(stderr, _("Connection failure: %s\n"), pa_strerror(pa_context_errno(c)));              pa_context_unref(context);              context = NULL; @@ -177,7 +173,7 @@ static void context_state_callback(pa_context *c, void *userdata) {  }  static void sigint_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { -    fprintf(stderr, "Got SIGINT, exiting.\n"); +    fprintf(stderr, _("Got SIGINT, exiting.\n"));      quit(0);  } @@ -195,7 +191,7 @@ static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, vo      if (WIFEXITED(status))          child_ret = WEXITSTATUS(status);      else if (WIFSIGNALED(status)) { -        fprintf(stderr, "WARNING: Child process terminated by signal %u\n", WTERMSIG(status)); +        fprintf(stderr, _("WARNING: Child process terminated by signal %u\n"), WTERMSIG(status));          child_ret = 1;      } @@ -213,10 +209,10 @@ static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, vo  static void help(const char *argv0) { -    printf("%s [options] ... \n\n" +    printf(_("%s [options] ... \n\n"             "  -h, --help                            Show this help\n"             "      --version                         Show version\n" -           "  -s, --server=SERVER                   The name of the server to connect to\n\n", +           "  -s, --server=SERVER                   The name of the server to connect to\n\n"),             argv0);  } @@ -236,6 +232,9 @@ int main(int argc, char *argv[]) {          {NULL,          0, NULL, 0}      }; +    setlocale(LC_ALL, ""); +    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); +      if (!(bn = strrchr(argv[0], '/')))          bn = argv[0];      else @@ -249,7 +248,12 @@ int main(int argc, char *argv[]) {                  goto quit;              case ARG_VERSION: -                printf("pasuspender "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); +                printf(_("pasuspender %s\n" +                         "Compiled with libpulse %s\n" +                         "Linked with libpulse %s\n"), +                       PACKAGE_VERSION, +                       pa_get_headers_version(), +                       pa_get_library_version());                  ret = 0;                  goto quit; @@ -273,7 +277,7 @@ int main(int argc, char *argv[]) {      }      if (!(m = pa_mainloop_new())) { -        fprintf(stderr, "pa_mainloop_new() failed.\n"); +        fprintf(stderr, _("pa_mainloop_new() failed.\n"));          goto quit;      } @@ -286,7 +290,7 @@ int main(int argc, char *argv[]) {  #endif      if (!(context = pa_context_new(mainloop_api, bn))) { -        fprintf(stderr, "pa_context_new() failed.\n"); +        fprintf(stderr, _("pa_context_new() failed.\n"));          goto quit;      } @@ -294,7 +298,7 @@ int main(int argc, char *argv[]) {      pa_context_connect(context, server, PA_CONTEXT_NOAUTOSPAWN, NULL);      if (pa_mainloop_run(m, &ret) < 0) { -        fprintf(stderr, "pa_mainloop_run() failed.\n"); +        fprintf(stderr, _("pa_mainloop_run() failed.\n"));          goto quit;      } diff --git a/src/utils/pax11publish.c b/src/utils/pax11publish.c index eee7b6a8..50d621d4 100644 --- a/src/utils/pax11publish.c +++ b/src/utils/pax11publish.c @@ -27,11 +27,13 @@  #include <getopt.h>  #include <string.h>  #include <assert.h> +#include <locale.h>  #include <X11/Xlib.h>  #include <X11/Xatom.h>  #include <pulse/util.h> +#include <pulse/i18n.h>  #include <pulsecore/core-util.h>  #include <pulsecore/log.h> @@ -47,17 +49,20 @@ int main(int argc, char *argv[]) {      Display *d = NULL;      enum { DUMP, EXPORT, IMPORT, REMOVE } mode = DUMP; +    setlocale(LC_ALL, ""); +    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); +      while ((c = getopt(argc, argv, "deiD:S:O:I:c:hr")) != -1) {          switch (c) {              case 'D' :                  dname = optarg;                  break;              case 'h': -                printf("%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n\n" +                printf(_("%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n\n"                         " -d    Show current PulseAudio data attached to X11 display (default)\n"                         " -e    Export local PulseAudio data to X11 display\n"                         " -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n" -                       " -r    Remove PulseAudio data from X11 display\n", +                       " -r    Remove PulseAudio data from X11 display\n"),                         pa_path_get_filename(argv[0]));                  ret = 0;                  goto finish; @@ -86,13 +91,13 @@ int main(int argc, char *argv[]) {                  server = optarg;                  break;              default: -                fprintf(stderr, "Failed to parse command line.\n"); +                fprintf(stderr, _("Failed to parse command line.\n"));                  goto finish;          }      }      if (!(d = XOpenDisplay(dname))) { -        pa_log("XOpenDisplay() failed"); +        pa_log(_("XOpenDisplay() failed"));          goto finish;      } @@ -100,13 +105,13 @@ int main(int argc, char *argv[]) {          case DUMP: {              char t[1024];              if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t))) -                printf("Server: %s\n", t); +                printf(_("Server: %s\n"), t);              if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t))) -                printf("Source: %s\n", t); +                printf(_("Source: %s\n"), t);              if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t))) -                printf("Sink: %s\n", t); +                printf(_("Sink: %s\n"), t);              if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t))) -                printf("Cookie: %s\n", t); +                printf(_("Cookie: %s\n"), t);              break;          } @@ -124,12 +129,12 @@ int main(int argc, char *argv[]) {                  uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];                  size_t l;                  if ((l = pa_parsehex(t, cookie, sizeof(cookie))) != sizeof(cookie)) { -                    fprintf(stderr, "Failed to parse cookie data\n"); +                    fprintf(stderr, _("Failed to parse cookie data\n"));                      goto finish;                  }                  if (pa_authkey_save(cookie_file, cookie, l) < 0) { -                    fprintf(stderr, "Failed to save cookie data\n"); +                    fprintf(stderr, _("Failed to save cookie data\n"));                      goto finish;                  }              } @@ -144,12 +149,12 @@ int main(int argc, char *argv[]) {              assert(conf);              if (pa_client_conf_load(conf, NULL) < 0) { -                fprintf(stderr, "Failed to load client configuration file.\n"); +                fprintf(stderr, _("Failed to load client configuration file.\n"));                  goto finish;              }              if (pa_client_conf_env(conf) < 0) { -                fprintf(stderr, "Failed to read environment configuration data.\n"); +                fprintf(stderr, _("Failed to read environment configuration data.\n"));                  goto finish;              } @@ -166,7 +171,7 @@ int main(int argc, char *argv[]) {              else {                  char hn[256];                  if (!pa_get_fqdn(hn, sizeof(hn))) { -                    fprintf(stderr, "Failed to get FQDN.\n"); +                    fprintf(stderr, _("Failed to get FQDN.\n"));                      goto finish;                  } @@ -186,7 +191,7 @@ int main(int argc, char *argv[]) {              pa_client_conf_free(conf);              if (pa_authkey_load_auto(cookie_file, cookie, sizeof(cookie)) < 0) { -                fprintf(stderr, "Failed to load cookie data\n"); +                fprintf(stderr, _("Failed to load cookie data\n"));                  goto finish;              } @@ -203,7 +208,7 @@ int main(int argc, char *argv[]) {              break;          default: -            fprintf(stderr, "No yet implemented.\n"); +            fprintf(stderr, _("Not yet implemented.\n"));              goto finish;      }  | 
