summaryrefslogtreecommitdiffstats
path: root/src/pulsecore
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore')
-rw-r--r--src/pulsecore/authkey.c10
-rw-r--r--src/pulsecore/cli-command.c2
-rw-r--r--src/pulsecore/conf-parser.c2
-rw-r--r--src/pulsecore/core-rtclock.c54
-rw-r--r--src/pulsecore/core-util.c126
-rw-r--r--src/pulsecore/core-util.h7
-rw-r--r--src/pulsecore/cpu-arm.c2
-rw-r--r--src/pulsecore/database-simple.c4
-rw-r--r--src/pulsecore/database-tdb.c43
-rw-r--r--src/pulsecore/fdsem.c13
-rw-r--r--src/pulsecore/lock-autospawn.c5
-rw-r--r--src/pulsecore/memblock.c2
-rw-r--r--src/pulsecore/pid.c7
-rw-r--r--src/pulsecore/protocol-native.c29
-rw-r--r--src/pulsecore/random.c6
-rw-r--r--src/pulsecore/sample-util.c2
-rw-r--r--src/pulsecore/semaphore-osx.c63
-rw-r--r--src/pulsecore/sink.c26
-rw-r--r--src/pulsecore/socket-client.c4
-rw-r--r--src/pulsecore/socket-server.c16
-rw-r--r--src/pulsecore/socket-util.c30
-rw-r--r--src/pulsecore/sound-file-stream.c6
-rw-r--r--src/pulsecore/sound-file.c6
-rw-r--r--src/pulsecore/svolume_mmx.c11
-rw-r--r--src/pulsecore/svolume_sse.c10
-rw-r--r--src/pulsecore/time-smoother.c7
-rw-r--r--src/pulsecore/x11prop.c20
27 files changed, 384 insertions, 129 deletions
diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c
index 15613e27..d671e367 100644
--- a/src/pulsecore/authkey.c
+++ b/src/pulsecore/authkey.c
@@ -70,10 +70,6 @@ static int generate(int fd, void *ret_data, size_t length) {
#define O_BINARY 0
#endif
-#ifndef O_NOCTTY
-#define O_NOCTTY 0
-#endif
-
/* Load an euthorization cookie from file fn and store it in data. If
* the cookie file doesn't exist, create it */
static int load(const char *fn, void *data, size_t length) {
@@ -86,9 +82,9 @@ static int load(const char *fn, void *data, size_t length) {
pa_assert(data);
pa_assert(length > 0);
- if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) {
+ if ((fd = pa_open_cloexec(fn, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
- if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY|O_NOCTTY)) < 0) {
+ if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) {
pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
goto finish;
} else
@@ -204,7 +200,7 @@ int pa_authkey_save(const char *fn, const void *data, size_t length) {
if (!(p = normalize_path(fn)))
return -2;
- if ((fd = open(p, O_RDWR|O_CREAT|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) {
+ if ((fd = pa_open_cloexec(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
goto finish;
}
diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index b57919a4..82a44d84 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -1804,7 +1804,7 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_b
if (!fail)
fail = &_fail;
- if (!(f = fopen(fn, "r"))) {
+ if (!(f = pa_fopen_cloexec(fn, "r"))) {
pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno));
if (!*fail)
ret = 0;
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index dd4a99ee..34b4d6fe 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -168,7 +168,7 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
pa_assert(filename);
pa_assert(t);
- if (!f && !(f = fopen(filename, "r"))) {
+ if (!f && !(f = pa_fopen_cloexec(filename, "r"))) {
if (errno == ENOENT) {
pa_log_debug("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
r = 0;
diff --git a/src/pulsecore/core-rtclock.c b/src/pulsecore/core-rtclock.c
index 1420470a..4fe0a47b 100644
--- a/src/pulsecore/core-rtclock.c
+++ b/src/pulsecore/core-rtclock.c
@@ -33,6 +33,12 @@
#include <sys/prctl.h>
#endif
+#ifdef OS_IS_DARWIN
+#include <CoreServices/CoreServices.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#endif
+
#include <pulse/timeval.h>
#include <pulsecore/macro.h>
#include <pulsecore/core-error.h>
@@ -47,7 +53,8 @@ pa_usec_t pa_rtclock_age(const struct timeval *tv) {
}
struct timeval *pa_rtclock_get(struct timeval *tv) {
-#ifdef HAVE_CLOCK_GETTIME
+
+#if defined(HAVE_CLOCK_GETTIME)
struct timespec ts;
#ifdef CLOCK_MONOTONIC
@@ -59,7 +66,7 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
no_monotonic = TRUE;
if (no_monotonic)
-#endif
+#endif /* CLOCK_MONOTONIC */
pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
pa_assert(tv);
@@ -69,7 +76,30 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
return tv;
-#else /* HAVE_CLOCK_GETTIME */
+#elif defined(OS_IS_DARWIN)
+ static mach_timebase_info_data_t tbi;
+ uint64_t nticks;
+ uint64_t time_nsec;
+
+ /* Refer Apple ADC QA1398
+ Also: http://devworld.apple.com/documentation/Darwin/Conceptual/KernelProgramming/services/services.html
+
+ Note: argument is timespec NOT timeval (timespec uses nsec, timeval uses usec)
+ */
+
+ /* try and be a mite efficient - maybe I should keep the N/D as a float !? */
+ if (tbi.denom == 0)
+ mach_timebase_info(&tbi);
+
+ nticks = mach_absolute_time();
+ time_nsec = nticks * tbi.numer / tbi.denom; // see above
+
+ tv->tv_sec = time_nsec / PA_NSEC_PER_SEC;
+ tv->tv_usec = time_nsec / PA_NSEC_PER_USEC;
+
+ return tv;
+
+#else /* OS_IS_DARWIN */
return pa_gettimeofday(tv);
@@ -77,19 +107,30 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
}
pa_bool_t pa_rtclock_hrtimer(void) {
-#ifdef HAVE_CLOCK_GETTIME
+
+#if defined(HAVE_CLOCK_GETTIME)
struct timespec ts;
#ifdef CLOCK_MONOTONIC
+
if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0)
return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
-#endif
+#endif /* CLOCK_MONOTONIC */
pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0);
return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
-#else /* HAVE_CLOCK_GETTIME */
+#elif defined (OS_IS_DARWIN)
+ mach_timebase_info_data_t tbi;
+ uint64_t time_nsec;
+
+ mach_timebase_info(&tbi);
+ /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */
+ time_nsec = tbi.numer / tbi.denom;
+ return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
+
+#else /* OS_IS_DARWIN */
return FALSE;
#endif
@@ -98,6 +139,7 @@ pa_bool_t pa_rtclock_hrtimer(void) {
#define TIMER_SLACK_NS (int) ((500 * PA_NSEC_PER_USEC))
void pa_rtclock_hrtimer_enable(void) {
+
#ifdef PR_SET_TIMERSLACK
int slack_ns;
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 27e09cbc..738bf065 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -1200,10 +1200,7 @@ int pa_lock_lockfile(const char *fn) {
for (;;) {
struct stat st;
- if ((fd = open(fn, O_CREAT|O_RDWR
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
+ if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR
#ifdef O_NOFOLLOW
|O_NOFOLLOW
#endif
@@ -1603,7 +1600,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
fn = buf;
#endif
- if ((f = fopen(fn, "r"))) {
+ if ((f = pa_fopen_cloexec(fn, "r"))) {
if (result)
*result = pa_xstrdup(fn);
@@ -1637,7 +1634,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
fn = buf;
#endif
- if ((f = fopen(fn, "r"))) {
+ if ((f = pa_fopen_cloexec(fn, "r"))) {
if (result)
*result = pa_xstrdup(fn);
@@ -1664,7 +1661,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
global = buf;
#endif
- if ((f = fopen(global, "r"))) {
+ if ((f = pa_fopen_cloexec(global, "r"))) {
if (result)
*result = pa_xstrdup(global);
@@ -2563,7 +2560,7 @@ char *pa_machine_id(void) {
* since it fits perfectly our needs and is not as volatile as the
* hostname which might be set from dhcp. */
- if ((f = fopen(PA_MACHINE_ID, "r"))) {
+ if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r"))) {
char ln[34] = "", *r;
r = fgets(ln, sizeof(ln)-1, f);
@@ -2889,3 +2886,116 @@ const char *pa_get_temp_dir(void) {
return "/tmp";
}
+
+int pa_open_cloexec(const char *fn, int flags, mode_t mode) {
+ int fd;
+
+#ifdef O_NOCTTY
+ flags |= O_NOCTTY;
+#endif
+
+#ifdef O_CLOEXEC
+ if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0)
+ goto finish;
+
+ if (errno != EINVAL)
+ return fd;
+#endif
+
+ if ((fd = open(fn, flags, mode)) < 0)
+ return fd;
+
+finish:
+ /* Some implementations might simply ignore O_CLOEXEC if it is not
+ * understood, make sure FD_CLOEXEC is enabled anyway */
+
+ pa_make_fd_cloexec(fd);
+ return fd;
+}
+
+int pa_socket_cloexec(int domain, int type, int protocol) {
+ int fd;
+
+#ifdef SOCK_CLOEXEC
+ if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0)
+ goto finish;
+
+ if (errno != EINVAL)
+ return fd;
+#endif
+
+ if ((fd = socket(domain, type, protocol)) < 0)
+ return fd;
+
+finish:
+ /* Some implementations might simply ignore SOCK_CLOEXEC if it is
+ * not understood, make sure FD_CLOEXEC is enabled anyway */
+
+ pa_make_fd_cloexec(fd);
+ return fd;
+}
+
+int pa_pipe_cloexec(int pipefd[2]) {
+ int r;
+
+#ifdef HAVE_PIPE2
+ if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0)
+ goto finish;
+
+ if (errno != EINVAL && errno != ENOSYS)
+ return r;
+#endif
+
+ if ((r = pipe(pipefd)) < 0)
+ return r;
+
+finish:
+ pa_make_fd_cloexec(pipefd[0]);
+ pa_make_fd_cloexec(pipefd[1]);
+
+ return 0;
+}
+
+int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+ int fd;
+
+#ifdef HAVE_ACCEPT4
+ if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0)
+ goto finish;
+
+ if (errno != EINVAL && errno != ENOSYS)
+ return fd;
+#endif
+
+ if ((fd = accept(sockfd, addr, addrlen)) < 0)
+ return fd;
+
+finish:
+ pa_make_fd_cloexec(fd);
+ return fd;
+}
+
+FILE* pa_fopen_cloexec(const char *path, const char *mode) {
+ FILE *f;
+ char *m;
+
+ m = pa_sprintf_malloc("%se", mode);
+
+ errno = 0;
+ if ((f = fopen(path, m))) {
+ pa_xfree(m);
+ goto finish;
+ }
+
+ pa_xfree(m);
+
+ if (errno != EINVAL)
+ return NULL;
+
+ if (!(f = fopen(path, mode)))
+ return NULL;
+
+finish:
+ pa_make_fd_cloexec(fileno(f));
+ return f;
+}
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 9986b14a..d50f79a2 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -28,6 +28,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <sys/socket.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
@@ -258,4 +259,10 @@ pa_bool_t pa_run_from_build_tree(void);
const char *pa_get_temp_dir(void);
+int pa_open_cloexec(const char *fn, int flags, mode_t mode);
+int pa_socket_cloexec(int domain, int type, int protocol);
+int pa_pipe_cloexec(int pipefd[2]);
+int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+FILE* pa_fopen_cloexec(const char *path, const char *mode);
+
#endif
diff --git a/src/pulsecore/cpu-arm.c b/src/pulsecore/cpu-arm.c
index 453b7848..6bb2eadd 100644
--- a/src/pulsecore/cpu-arm.c
+++ b/src/pulsecore/cpu-arm.c
@@ -62,7 +62,7 @@ static char *get_cpuinfo(void) {
cpuinfo = pa_xmalloc(MAX_BUFFER);
- if ((fd = open("/proc/cpuinfo", O_RDONLY)) < 0) {
+ if ((fd = pa_open_cloexec("/proc/cpuinfo", O_RDONLY, 0)) < 0) {
pa_xfree(cpuinfo);
return NULL;
}
diff --git a/src/pulsecore/database-simple.c b/src/pulsecore/database-simple.c
index 1f4caf71..754930db 100644
--- a/src/pulsecore/database-simple.c
+++ b/src/pulsecore/database-simple.c
@@ -237,7 +237,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
path = pa_sprintf_malloc("%s."CANONICAL_HOST".simple", fn);
errno = 0;
- f = fopen(path, "r");
+ f = pa_fopen_cloexec(path, "r");
if (f || errno == ENOENT) { /* file not found is ok */
db = pa_xnew0(simple_data, 1);
@@ -480,7 +480,7 @@ int pa_database_sync(pa_database *database) {
errno = 0;
- f = fopen(db->tmp_filename, "w");
+ f = pa_fopen_cloexec(db->tmp_filename, "w");
if (!f)
goto fail;
diff --git a/src/pulsecore/database-tdb.c b/src/pulsecore/database-tdb.c
index b79d2837..4e782d65 100644
--- a/src/pulsecore/database-tdb.c
+++ b/src/pulsecore/database-tdb.c
@@ -66,6 +66,39 @@ void pa_datum_free(pa_datum *d) {
pa_zero(d);
}
+static struct tdb_context *tdb_open_cloexec(
+ const char *name,
+ int hash_size,
+ int tdb_flags,
+ int open_flags,
+ mode_t mode) {
+
+ /* Mimics pa_open_cloexec() */
+
+ struct tdb_context *c;
+
+#ifdef O_NOCTTY
+ open_flags |= O_NOCTTY;
+#endif
+
+#ifdef O_CLOEXEC
+ errno = 0;
+ if ((c = tdb_open(name, hash_size, tdb_flags, open_flags | O_CLOEXEC, mode)))
+ goto finish;
+
+ if (errno != EINVAL)
+ return NULL;
+#endif
+
+ errno = 0;
+ if (!(c = tdb_open(name, hash_size, tdb_flags, open_flags, mode)))
+ return NULL;
+
+finish:
+ pa_make_fd_cloexec(tdb_fd(c));
+ return c;
+}
+
pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
struct tdb_context *c;
char *path;
@@ -73,15 +106,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
pa_assert(fn);
path = pa_sprintf_malloc("%s.tdb", fn);
- errno = 0;
- c = tdb_open(path, 0, TDB_NOSYNC|TDB_NOLOCK,
- (for_write ? O_RDWR|O_CREAT : O_RDONLY)|O_NOCTTY
-#ifdef O_CLOEXEC
- |O_CLOEXEC
-#endif
- , 0644);
-
- if (c)
+ if ((c = tdb_open_cloexec(path, 0, TDB_NOSYNC|TDB_NOLOCK, (for_write ? O_RDWR|O_CREAT : O_RDONLY), 0644)))
pa_log_debug("Opened TDB database '%s'", path);
pa_xfree(path);
diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c
index 380f34f5..ea14e8a7 100644
--- a/src/pulsecore/fdsem.c
+++ b/src/pulsecore/fdsem.c
@@ -62,19 +62,15 @@ pa_fdsem *pa_fdsem_new(void) {
f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data)));
#ifdef HAVE_SYS_EVENTFD_H
- if ((f->efd = eventfd(0, 0)) >= 0) {
- pa_make_fd_cloexec(f->efd);
+ if ((f->efd = eventfd(0, EFD_CLOEXEC)) >= 0)
f->fds[0] = f->fds[1] = -1;
- } else
+ else
#endif
{
- if (pipe(f->fds) < 0) {
+ if (pa_pipe_cloexec(f->fds) < 0) {
pa_xfree(f);
return NULL;
}
-
- pa_make_fd_cloexec(f->fds[0]);
- pa_make_fd_cloexec(f->fds[1]);
}
f->data = (pa_fdsem_data*) ((uint8_t*) f + PA_ALIGN(sizeof(pa_fdsem)));
@@ -114,12 +110,11 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {
f = pa_xnew(pa_fdsem, 1);
- if ((f->efd = eventfd(0, 0)) < 0) {
+ if ((f->efd = eventfd(0, EFD_CLOEXEC)) < 0) {
pa_xfree(f);
return NULL;
}
- pa_make_fd_cloexec(f->efd);
f->fds[0] = f->fds[1] = -1;
f->data = data;
diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c
index c0df7938..65e35634 100644
--- a/src/pulsecore/lock-autospawn.c
+++ b/src/pulsecore/lock-autospawn.c
@@ -87,12 +87,9 @@ static int ref(void) {
pa_assert(pipe_fd[0] < 0);
pa_assert(pipe_fd[1] < 0);
- if (pipe(pipe_fd) < 0)
+ if (pa_pipe_cloexec(pipe_fd) < 0)
return -1;
- 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]);
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index eac4a59b..f38b17c6 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -54,7 +54,7 @@
* stored in SHM and our OS does not commit the memory before we use
* it for the first time. */
#define PA_MEMPOOL_SLOTS_MAX 1024
-#define PA_MEMPOOL_SLOT_SIZE (128*1024)
+#define PA_MEMPOOL_SLOT_SIZE (64*1024)
#define PA_MEMEXPORT_SLOTS_MAX 128
diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c
index 996946c2..213e7983 100644
--- a/src/pulsecore/pid.c
+++ b/src/pulsecore/pid.c
@@ -88,10 +88,7 @@ static int open_pid_file(const char *fn, int mode) {
for (;;) {
struct stat st;
- if ((fd = open(fn, mode
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
+ if ((fd = pa_open_cloexec(fn, mode
#ifdef O_NOFOLLOW
|O_NOFOLLOW
#endif
@@ -146,7 +143,7 @@ static int proc_name_ours(pid_t pid, const char *procname) {
pa_snprintf(bn, sizeof(bn), "/proc/%lu/stat", (unsigned long) pid);
- if (!(f = fopen(bn, "r"))) {
+ if (!(f = pa_fopen_cloexec(bn, "r"))) {
pa_log_info("Failed to open %s: %s", bn, pa_cstrerror(errno));
return -1;
} else {
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index d06dd4eb..bb29a196 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1002,6 +1002,7 @@ static playback_stream* playback_stream_new(
pa_proplist *p,
pa_bool_t adjust_latency,
pa_bool_t early_requests,
+ pa_bool_t relative_volume,
int *ret) {
playback_stream *s, *ssync;
@@ -1044,13 +1045,21 @@ static playback_stream* playback_stream_new(
data.driver = __FILE__;
data.module = c->options->module;
data.client = c->client;
- data.sink = sink;
+ if (sink) {
+ data.sink = sink;
+ data.save_sink = TRUE;
+ }
pa_sink_input_new_data_set_sample_spec(&data, ss);
pa_sink_input_new_data_set_channel_map(&data, map);
- if (volume)
+ if (volume) {
pa_sink_input_new_data_set_volume(&data, volume);
- if (muted_set)
+ data.volume_is_absolute = !relative_volume;
+ data.save_volume = TRUE;
+ }
+ if (muted_set) {
pa_sink_input_new_data_set_muted(&data, muted);
+ data.save_muted = TRUE;
+ }
data.sync_base = ssync ? ssync->sink_input : NULL;
data.flags = flags;
@@ -1838,7 +1847,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
early_requests = FALSE,
dont_inhibit_auto_suspend = FALSE,
muted_set = FALSE,
- fail_on_suspend = FALSE;
+ fail_on_suspend = FALSE,
+ relative_volume = FALSE;
pa_sink_input_flags_t flags = 0;
pa_proplist *p;
pa_bool_t volume_set = TRUE;
@@ -1931,6 +1941,15 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
}
}
+ if (c->version >= 17) {
+
+ if (pa_tagstruct_get_boolean(t, &relative_volume) < 0) {
+ protocol_error(c);
+ pa_proplist_free(p);
+ return;
+ }
+ }
+
if (!pa_tagstruct_eof(t)) {
protocol_error(c);
pa_proplist_free(p);
@@ -1970,7 +1989,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
* flag. For older versions we synthesize it here */
muted_set = muted_set || muted;
- s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, &ret);
+ s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, relative_volume, &ret);
pa_proplist_free(p);
CHECK_VALIDITY(c->pstream, s, tag, ret);
diff --git a/src/pulsecore/random.c b/src/pulsecore/random.c
index 518c281a..a87d24e3 100644
--- a/src/pulsecore/random.c
+++ b/src/pulsecore/random.c
@@ -62,11 +62,7 @@ static int random_proper(void *ret_data, size_t length) {
while (*device) {
ret = 0;
- if ((fd = open(*device, O_RDONLY
-#ifdef O_NOCTTY
- | O_NOCTTY
-#endif
- )) >= 0) {
+ if ((fd = pa_open_cloexec(*device, O_RDONLY, 0)) >= 0) {
if ((r = pa_loop_read(fd, ret_data, length, NULL)) < 0 || (size_t) r != length)
ret = -1;
diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index a26dc876..74600dec 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -1007,7 +1007,7 @@ void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) {
/* Only for debugging purposes */
- f = fopen(fn, "a");
+ f = pa_fopen_cloexec(fn, "a");
if (!f) {
pa_log_warn("Failed to open '%s': %s", fn, pa_cstrerror(errno));
diff --git a/src/pulsecore/semaphore-osx.c b/src/pulsecore/semaphore-osx.c
new file mode 100644
index 00000000..73f43559
--- /dev/null
+++ b/src/pulsecore/semaphore-osx.c
@@ -0,0 +1,63 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2009 Kim Lester <kim@dfusion.com.au>
+
+ 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
+ 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 <Multiprocessing.h>
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/macro.h>
+
+#include "semaphore.h"
+
+struct pa_semaphore
+{
+ MPSemaphoreID sema;
+};
+
+pa_semaphore* pa_semaphore_new(unsigned int value) {
+ /* NOTE: Can't assume boolean - ie value = 0,1, so use UINT_MAX (boolean more efficient ?) */
+ pa_semaphore *s;
+
+ s = pa_xnew(pa_semaphore, 1);
+ pa_assert_se(MPCreateSemaphore(UINT_MAX, value, &s->sema) == 0);
+
+ return s;
+}
+
+void pa_semaphore_free(pa_semaphore *s) {
+ pa_assert(s);
+ pa_assert_se(MPDeleteSemaphore(s->sema) == 0);
+ pa_xfree(s);
+}
+
+void pa_semaphore_post(pa_semaphore *s) {
+ pa_assert(s);
+ pa_assert_se(MPSignalSemaphore(s->sema) == 0);
+}
+
+void pa_semaphore_wait(pa_semaphore *s) {
+ pa_assert(s);
+ /* should probably check return value (-ve is error), noErr is ok. */
+ pa_assert_se(MPWaitOnSemaphore(s->sema, kDurationForever) == 0);
+}
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index bda92fcc..971436d3 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -926,18 +926,16 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
- if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) {
- if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
- pa_memblock_unref(result->memblock);
- pa_silence_memchunk_get(&s->core->silence_cache,
- s->core->mempool,
- result,
- &s->sample_spec,
- result->length);
- } else {
- pa_memchunk_make_writable(result, 0);
- pa_volume_memchunk(result, &s->sample_spec, &volume);
- }
+ if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
+ pa_memblock_unref(result->memblock);
+ pa_silence_memchunk_get(&s->core->silence_cache,
+ s->core->mempool,
+ result,
+ &s->sample_spec,
+ result->length);
+ } else if (!pa_cvolume_is_norm(&volume)) {
+ pa_memchunk_make_writable(result, 0);
+ pa_volume_memchunk(result, &s->sample_spec, &volume);
}
} else {
void *ptr;
@@ -1342,7 +1340,7 @@ static void propagate_reference_volume(pa_sink *s) {
void pa_sink_set_volume(
pa_sink *s,
const pa_cvolume *volume,
- pa_bool_t sendmsg,
+ pa_bool_t send_msg,
pa_bool_t save) {
pa_cvolume old_reference_volume;
@@ -1411,7 +1409,7 @@ void pa_sink_set_volume(
s->soft_volume = s->real_volume;
/* This tells the sink that soft and/or virtual volume changed */
- if (sendmsg)
+ if (send_msg)
pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
if (reference_changed)
diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c
index b9d69505..ef3c29ee 100644
--- a/src/pulsecore/socket-client.c
+++ b/src/pulsecore/socket-client.c
@@ -257,13 +257,11 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size
c->local = pa_socket_address_is_local(sa);
- if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
+ if ((c->fd = pa_socket_cloexec(sa->sa_family, SOCK_STREAM, 0)) < 0) {
pa_log("socket(): %s", pa_cstrerror(errno));
return -1;
}
- pa_make_fd_cloexec(c->fd);
-
#ifdef HAVE_IPV6
if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
#else
diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c
index e660700c..5d55de3e 100644
--- a/src/pulsecore/socket-server.c
+++ b/src/pulsecore/socket-server.c
@@ -104,13 +104,11 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_ev
pa_socket_server_ref(s);
- if ((nfd = accept(fd, NULL, NULL)) < 0) {
+ if ((nfd = pa_accept_cloexec(fd, NULL, NULL)) < 0) {
pa_log("accept(): %s", pa_cstrerror(errno));
goto finish;
}
- pa_make_fd_cloexec(nfd);
-
if (!s->on_connection) {
pa_close(nfd);
goto finish;
@@ -186,13 +184,11 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
pa_assert(m);
pa_assert(filename);
- if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+ if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
pa_log("socket(): %s", pa_cstrerror(errno));
goto fail;
}
- pa_make_fd_cloexec(fd);
-
memset(&sa, 0, sizeof(sa));
sa.sun_family = AF_UNIX;
pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path));
@@ -246,13 +242,11 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
pa_assert(m);
pa_assert(port);
- if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ if ((fd = pa_socket_cloexec(PF_INET, SOCK_STREAM, 0)) < 0) {
pa_log("socket(PF_INET): %s", pa_cstrerror(errno));
goto fail;
}
- pa_make_fd_cloexec(fd);
-
#ifdef SO_REUSEADDR
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
pa_log("setsockopt(): %s", pa_cstrerror(errno));
@@ -299,13 +293,11 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad
pa_assert(m);
pa_assert(port > 0);
- if ((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0) {
+ if ((fd = pa_socket_cloexec(PF_INET6, SOCK_STREAM, 0)) < 0) {
pa_log("socket(PF_INET6): %s", pa_cstrerror(errno));
goto fail;
}
- pa_make_fd_cloexec(fd);
-
#ifdef IPV6_V6ONLY
on = 1;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c
index 5fd5dd67..2cc9882a 100644
--- a/src/pulsecore/socket-util.c
+++ b/src/pulsecore/socket-util.c
@@ -85,12 +85,11 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
#ifndef OS_IS_WIN32
pa_assert_se(fstat(fd, &st) == 0);
-#endif
-#ifndef OS_IS_WIN32
if (S_ISSOCK(st.st_mode)) {
#endif
union {
+ struct sockaddr_storage storage;
struct sockaddr sa;
struct sockaddr_in in;
#ifdef HAVE_IPV6
@@ -152,7 +151,7 @@ void pa_make_socket_low_delay(int fd) {
pa_assert(fd >= 0);
priority = 6;
- if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) < 0)
pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno));
#endif
}
@@ -166,9 +165,9 @@ void pa_make_tcp_socket_low_delay(int fd) {
{
int on = 1;
#if defined(SOL_TCP)
- if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0)
+ if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
#else
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0)
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
#endif
pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno));
}
@@ -178,9 +177,9 @@ void pa_make_tcp_socket_low_delay(int fd) {
{
int tos = IPTOS_LOWDELAY;
#ifdef SOL_IP
- if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+ if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0)
#else
- if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+ if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
#endif
pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
}
@@ -196,9 +195,9 @@ void pa_make_udp_socket_low_delay(int fd) {
{
int tos = IPTOS_LOWDELAY;
#ifdef SOL_IP
- if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+ if (setsockopt(fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0)
#else
- if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+ if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
#endif
pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
}
@@ -206,11 +205,11 @@ void pa_make_udp_socket_low_delay(int fd) {
}
int pa_socket_set_rcvbuf(int fd, size_t l) {
- int bufsz = (int)l;
+ int bufsz = (int) l;
pa_assert(fd >= 0);
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsz, sizeof(bufsz)) < 0) {
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsz, sizeof(bufsz)) < 0) {
pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno));
return -1;
}
@@ -219,12 +218,12 @@ int pa_socket_set_rcvbuf(int fd, size_t l) {
}
int pa_socket_set_sndbuf(int fd, size_t l) {
- int bufsz = (int)l;
+ int bufsz = (int) l;
pa_assert(fd >= 0);
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsz, sizeof(bufsz)) < 0) {
- pa_log("SO_SNDBUF: %s", pa_cstrerror(errno));
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsz, sizeof(bufsz)) < 0) {
+ pa_log_warn("SO_SNDBUF: %s", pa_cstrerror(errno));
return -1;
}
@@ -239,7 +238,7 @@ int pa_unix_socket_is_stale(const char *fn) {
pa_assert(fn);
- if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+ if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
pa_log("socket(): %s", pa_cstrerror(errno));
goto finish;
}
@@ -315,6 +314,7 @@ pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) {
pa_bool_t pa_socket_is_local(int fd) {
union {
+ struct sockaddr_storage storage;
struct sockaddr sa;
struct sockaddr_in in;
#ifdef HAVE_IPV6
diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c
index 16de4923..53674ba1 100644
--- a/src/pulsecore/sound-file-stream.c
+++ b/src/pulsecore/sound-file-stream.c
@@ -252,11 +252,7 @@ int pa_play_file(
u->readf_function = NULL;
u->memblockq = NULL;
- if ((fd = open(fname, O_RDONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- )) < 0) {
+ if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) {
pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno));
goto fail;
}
diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c
index 2d9b76ad..d8c10b1e 100644
--- a/src/pulsecore/sound-file.c
+++ b/src/pulsecore/sound-file.c
@@ -62,11 +62,7 @@ int pa_sound_file_load(
pa_memchunk_reset(chunk);
- if ((fd = open(fname, O_RDONLY
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
- )) < 0) {
+ if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) {
pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno));
goto finish;
}
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 745c7de0..a011789c 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -25,6 +25,8 @@
#endif
#include <pulse/timeval.h>
+#include <pulse/rtclock.h>
+
#include <pulsecore/random.h>
#include <pulsecore/macro.h>
#include <pulsecore/g711.h>
@@ -60,7 +62,9 @@
" movq "#s", %%mm5 \n\t" \
" pmulhw "#v", "#s" \n\t" /* .. | 0 | vl*p0 | */ \
" paddw %%mm4, "#s" \n\t" /* .. | 0 | vl*p0 | + sign correct */ \
+ " pslld $16, "#s" \n\t" /* .. | vl*p0 | 0 | */ \
" psrld $16, "#v" \n\t" /* .. | 0 | vh | */ \
+ " psrad $16, "#s" \n\t" /* .. | vl*p0 | sign extend */ \
" pmaddwd %%mm5, "#v" \n\t" /* .. | p0 * vh | */ \
" paddd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \
" packssdw "#v", "#v" \n\t" /* .. | p1*v1 | p0*v0 | */
@@ -255,11 +259,14 @@ static void run_test (void) {
printf ("checking MMX %zd\n", sizeof (samples));
pa_random (samples, sizeof (samples));
+ /* for (i = 0; i < SAMPLES; i++)
+ samples[i] = -1; */
memcpy (samples_ref, samples, sizeof (samples));
memcpy (samples_orig, samples, sizeof (samples));
for (i = 0; i < CHANNELS; i++)
volumes[i] = rand() >> 1;
+ /* volumes[i] = 0x0000ffff; */
for (padding = 0; padding < PADDING; padding++, i++)
volumes[i] = volumes[padding];
@@ -267,7 +274,7 @@ static void run_test (void) {
pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
for (i = 0; i < SAMPLES; i++) {
if (samples[i] != samples_ref[i]) {
- printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
+ printf ("%d: %04x != %04x (%04x * %08x)\n", i, samples[i], samples_ref[i],
samples_orig[i], volumes[i % CHANNELS]);
}
}
@@ -287,6 +294,8 @@ static void run_test (void) {
}
stop = pa_rtclock_now();
pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
+
+ pa_assert_se(memcmp(samples_ref, samples, sizeof(samples)) == 0);
}
#endif
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 1cc4e0aa..620524fa 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -25,6 +25,8 @@
#endif
#include <pulse/timeval.h>
+#include <pulse/rtclock.h>
+
#include <pulsecore/random.h>
#include <pulsecore/macro.h>
#include <pulsecore/g711.h>
@@ -261,7 +263,7 @@ static void run_test (void) {
func = pa_get_volume_func (PA_SAMPLE_S16NE);
- printf ("checking SSE %zd\n", sizeof (samples));
+ printf ("checking SSE2 %zd\n", sizeof (samples));
pa_random (samples, sizeof (samples));
memcpy (samples_ref, samples, sizeof (samples));
@@ -273,7 +275,7 @@ static void run_test (void) {
volumes[i] = volumes[padding];
func (samples_ref, volumes, CHANNELS, sizeof (samples));
- pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
+ pa_volume_s16ne_sse2 (samples, volumes, CHANNELS, sizeof (samples));
for (i = 0; i < SAMPLES; i++) {
if (samples[i] != samples_ref[i]) {
printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
@@ -284,7 +286,7 @@ static void run_test (void) {
start = pa_rtclock_now();
for (j = 0; j < TIMES; j++) {
memcpy (samples, samples_orig, sizeof (samples));
- pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
+ pa_volume_s16ne_sse2 (samples, volumes, CHANNELS, sizeof (samples));
}
stop = pa_rtclock_now();
pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start));
@@ -296,6 +298,8 @@ static void run_test (void) {
}
stop = pa_rtclock_now();
pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
+
+ pa_assert_se(memcmp(samples_ref, samples, sizeof(samples)) == 0);
}
#endif
#endif /* defined (__i386__) || defined (__amd64__) */
diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c
index d6c37878..1371ad56 100644
--- a/src/pulsecore/time-smoother.c
+++ b/src/pulsecore/time-smoother.c
@@ -196,6 +196,13 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
int64_t ax = 0, ay = 0, k, t;
double r;
+ /* FIXME: Optimization: Jason Newton suggested that instead of
+ * going through the history on each iteration we could calculated
+ * avg_gradient() as we go.
+ *
+ * Second idea: it might make sense to weight history entries:
+ * more recent entries should matter more than old ones. */
+
/* Too few measurements, assume gradient of 1 */
if (s->n_history < s->min_history)
return 1;
diff --git a/src/pulsecore/x11prop.c b/src/pulsecore/x11prop.c
index 873a76e7..dc8ec294 100644
--- a/src/pulsecore/x11prop.c
+++ b/src/pulsecore/x11prop.c
@@ -32,12 +32,12 @@
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, (int) (strlen(data)+1));
+ XChangeProperty(d, DefaultRootWindow(d), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1));
}
void pa_x11_del_prop(Display *d, const char *name) {
Atom a = XInternAtom(d, name, False);
- XDeleteProperty(d, RootWindow(d, 0), a);
+ XDeleteProperty(d, DefaultRootWindow(d), a);
}
char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {
@@ -47,13 +47,21 @@ char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {
unsigned long nbytes_after;
unsigned char *prop = NULL;
char *ret = NULL;
+ int window_ret;
Atom a = XInternAtom(d, name, False);
- 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)
- goto finish;
+ window_ret = XGetWindowProperty(d, DefaultRootWindow(d), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop);
+
+ if (window_ret != Success || actual_type != XA_STRING) {
+ if (DefaultScreen(d) != 0) {
+ window_ret = XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop);
+
+ if (window_ret != Success || actual_type != XA_STRING)
+ goto finish;
+ } else
+ goto finish;
+ }
memcpy(p, prop, nitems);
p[nitems] = 0;