From e6a666d8d5fffbc9847b51b35349b88d74970079 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 6 Sep 2009 22:33:04 +0200 Subject: libpulse: introduce PA_BYTES_SNPRINT_MAX and make use of it wherever applicable --- src/pulse/context.h | 1 - src/pulse/sample.h | 7 +++++++ src/pulse/stream.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/context.h b/src/pulse/context.h index cd129313..670b23e8 100644 --- a/src/pulse/context.h +++ b/src/pulse/context.h @@ -267,7 +267,6 @@ pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_even for mainloop->time_restart). \since 0.9.16 */ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec); - PA_C_DECL_END #endif diff --git a/src/pulse/sample.h b/src/pulse/sample.h index 53d7dea3..7a4a55a0 100644 --- a/src/pulse/sample.h +++ b/src/pulse/sample.h @@ -302,6 +302,13 @@ pa_sample_format_t pa_parse_sample_format(const char *format) PA_GCC_PURE; /** Pretty print a sample type specification to a string */ char* pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec); +/** Maximum required string length for pa_bytes_snprint(). Please note + * that this value can change with any release without warning and + * without being considered API or ABI breakage. You should not use + * this definition anywhere where it might become part of an + * ABI. \since 0.9.16 */ +#define PA_BYTES_SNPRINT_MAX 11 + /** Pretty print a byte size value. (i.e. "2.5 MiB") */ char* pa_bytes_snprint(char *s, size_t l, unsigned v); diff --git a/src/pulse/stream.h b/src/pulse/stream.h index 8a08421f..21dd0a85 100644 --- a/src/pulse/stream.h +++ b/src/pulse/stream.h @@ -319,7 +319,7 @@ typedef struct pa_stream pa_stream; typedef void (*pa_stream_success_cb_t) (pa_stream*s, int success, void *userdata); /** A generic request callback */ -typedef void (*pa_stream_request_cb_t)(pa_stream *p, size_t bytes, void *userdata); +typedef void (*pa_stream_request_cb_t)(pa_stream *p, size_t nbytes, void *userdata); /** A generic notification callback */ typedef void (*pa_stream_notify_cb_t)(pa_stream *p, void *userdata); -- cgit From 5cf0c1e544a5fce97d514c793256b2e301277136 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 6 Sep 2009 23:14:15 +0200 Subject: introspect: rearrange order of functions a bit --- src/pulse/introspect.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index ee982100..68cfc874 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -331,6 +331,12 @@ pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, i /** Set the mute switch of a source device specified by its name */ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata); +/** Suspend/Resume a source. \since 0.9.7 */ +pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Suspend/Resume a source. If idx is PA_INVALID_INDEX all sources will be suspended. \since 0.9.7 */ +pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata); + /** Change the profile of a source. \since 0.9.16 */ pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata); @@ -557,12 +563,6 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, /** Move the specified source output to a different source. \since 0.9.5 */ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata); -/** Suspend/Resume a source. \since 0.9.7 */ -pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata); - -/** Suspend/Resume a source. If idx is PA_INVALID_INDEX all sources will be suspended. \since 0.9.7 */ -pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata); - /** Kill a source output. */ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); -- cgit From 3bbc5e6a4d0211d8cedd2fe6698c2e2c07d1c4b9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Sep 2009 19:53:39 +0200 Subject: volume: fix definition of PA_VOLUME_MAX and introduce PA_VOLUME_INVALID and use it wherever applicable --- src/pulse/scache.c | 4 ++-- src/pulse/scache.h | 4 ++-- src/pulse/volume.c | 10 +++++----- src/pulse/volume.h | 9 ++++++--- 4 files changed, 15 insertions(+), 12 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/scache.c b/src/pulse/scache.c index 77f60d72..43dc5296 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -187,7 +187,7 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, dev); - if (volume == (pa_volume_t) -1 && c->version < 15) + if (volume == PA_VOLUME_INVALID && c->version < 15) volume = PA_VOLUME_NORM; pa_tagstruct_putu32(t, volume); @@ -228,7 +228,7 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, dev); - if (volume == (pa_volume_t) -1 && c->version < 15) + if (volume == PA_VOLUME_INVALID && c->version < 15) volume = PA_VOLUME_NORM; pa_tagstruct_putu32(t, volume); diff --git a/src/pulse/scache.h b/src/pulse/scache.h index cd579d2e..31cf7b01 100644 --- a/src/pulse/scache.h +++ b/src/pulse/scache.h @@ -101,7 +101,7 @@ pa_operation* pa_context_play_sample( pa_context *c /**< Context */, const char *name /**< Name of the sample to play */, const char *dev /**< Sink to play this sample on */, - pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here (pa_volume_t) -1 which will leave the decision about the volume to the server side which is a good idea. */ , + pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here PA_VOLUME_INVALID which will leave the decision about the volume to the server side which is a good idea. */ , pa_context_success_cb_t cb /**< Call this function after successfully starting playback, or NULL */, void *userdata /**< Userdata to pass to the callback */); @@ -113,7 +113,7 @@ pa_operation* pa_context_play_sample_with_proplist( pa_context *c /**< Context */, const char *name /**< Name of the sample to play */, const char *dev /**< Sink to play this sample on */, - pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here (pa_volume_t) -1 which will leave the decision about the volume to the server side which is a good idea. */ , + pa_volume_t volume /**< Volume to play this sample with. Starting with 0.9.15 you may pass here PA_VOLUME_INVALID which will leave the decision about the volume to the server side which is a good idea. */ , pa_proplist *proplist /**< Property list for this sound. The property list of the cached entry will be merged into this property list */, pa_context_play_sample_cb_t cb /**< Call this function after successfully starting playback, or NULL */, void *userdata /**< Userdata to pass to the callback */); diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 234c3f72..4991e5c8 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -64,7 +64,7 @@ pa_cvolume* pa_cvolume_init(pa_cvolume *a) { a->channels = 0; for (c = 0; c < PA_CHANNELS_MAX; c++) - a->values[c] = (pa_volume_t) -1; + a->values[c] = PA_VOLUME_INVALID; return a; } @@ -307,7 +307,7 @@ char *pa_volume_snprint(char *s, size_t l, pa_volume_t v) { pa_init_i18n(); - if (v == (pa_volume_t) -1) { + if (v == PA_VOLUME_INVALID) { pa_snprintf(s, l, _("(invalid)")); return s; } @@ -357,7 +357,7 @@ char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) { pa_init_i18n(); - if (v == (pa_volume_t) -1) { + if (v == PA_VOLUME_INVALID) { pa_snprintf(s, l, _("(invalid)")); return s; } @@ -459,7 +459,7 @@ int pa_cvolume_valid(const pa_cvolume *v) { return 0; for (c = 0; c < v->channels; c++) - if (v->values[c] == (pa_volume_t) -1) + if (v->values[c] == PA_VOLUME_INVALID) return 0; return 1; @@ -679,7 +679,7 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) { pa_assert(v); pa_return_val_if_fail(pa_cvolume_valid(v), NULL); - pa_return_val_if_fail(max != (pa_volume_t) -1, NULL); + pa_return_val_if_fail(max != PA_VOLUME_INVALID, NULL); t = pa_cvolume_max(v); diff --git a/src/pulse/volume.h b/src/pulse/volume.h index 543b0af1..c964020a 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -106,11 +106,14 @@ typedef uint32_t pa_volume_t; /** Normal volume (100%, 0 dB) */ #define PA_VOLUME_NORM ((pa_volume_t) 0x10000U) -/** Muted volume (0%, -inf dB) */ +/** Muted (minimal valid) volume (0%, -inf dB) */ #define PA_VOLUME_MUTED ((pa_volume_t) 0U) -/** Maximum volume we can store. \since 0.9.15 */ -#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX) +/** Maximum valid volume we can store. \since 0.9.15 */ +#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX-1) + +/** Special 'invalid' volume. \since 0.9.16 */ +#define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX) /** A structure encapsulating a per-channel volume */ typedef struct pa_cvolume { -- cgit From cc6c4fe91f916451bbea9073619c11a6b122b684 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Sep 2009 19:59:18 +0200 Subject: volume: add a couple of validity checks for pa_volume_t arguments --- src/pulse/volume.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/pulse') diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 4991e5c8..1bbb07f2 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -201,6 +201,9 @@ pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, p pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) { + pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID); + pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID); + /* cbrt((a/PA_VOLUME_NORM)^3*(b/PA_VOLUME_NORM)^3)*PA_VOLUME_NORM = a*b/PA_VOLUME_NORM */ return (pa_volume_t) (((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM); @@ -208,6 +211,9 @@ pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) { pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) { + pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID); + pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID); + if (b <= PA_VOLUME_MUTED) return 0; @@ -232,6 +238,8 @@ pa_volume_t pa_sw_volume_from_dB(double dB) { double pa_sw_volume_to_dB(pa_volume_t v) { + pa_return_val_if_fail(v != PA_VOLUME_INVALID, PA_DECIBEL_MININFTY); + if (v <= PA_VOLUME_MUTED) return PA_DECIBEL_MININFTY; @@ -259,6 +267,8 @@ pa_volume_t pa_sw_volume_from_linear(double v) { double pa_sw_volume_to_linear(pa_volume_t v) { double f; + pa_return_val_if_fail(v != PA_VOLUME_INVALID, 0.0); + if (v <= PA_VOLUME_MUTED) return 0.0; @@ -374,6 +384,7 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) { pa_assert(a); pa_return_val_if_fail(pa_cvolume_valid(a), 0); + pa_return_val_if_fail(v != PA_VOLUME_INVALID, 0); for (c = 0; c < a->channels; c++) if (a->values[c] != v) @@ -407,6 +418,7 @@ pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_assert(a); pa_return_val_if_fail(pa_cvolume_valid(a), NULL); + pa_return_val_if_fail(b != PA_VOLUME_INVALID, NULL); for (i = 0; i < a->channels; i++) dest->values[i] = pa_sw_volume_multiply(a->values[i], b); @@ -441,6 +453,7 @@ pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, p pa_assert(a); pa_return_val_if_fail(pa_cvolume_valid(a), NULL); + pa_return_val_if_fail(b != PA_VOLUME_INVALID, NULL); for (i = 0; i < a->channels; i++) dest->values[i] = pa_sw_volume_divide(a->values[i], b); @@ -827,6 +840,7 @@ pa_cvolume* pa_cvolume_set_position( pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(cv, map), NULL); pa_return_val_if_fail(t < PA_CHANNEL_POSITION_MAX, NULL); + pa_return_val_if_fail(v != PA_VOLUME_INVALID, NULL); for (c = 0; c < map->channels; c++) if (map->map[c] == t) { @@ -883,6 +897,7 @@ pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) { pa_assert(v); pa_return_val_if_fail(pa_cvolume_valid(v), NULL); + pa_return_val_if_fail(inc != PA_VOLUME_INVALID, NULL); m = pa_cvolume_max(v); @@ -900,6 +915,7 @@ pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) { pa_assert(v); pa_return_val_if_fail(pa_cvolume_valid(v), NULL); + pa_return_val_if_fail(dec != PA_VOLUME_INVALID, NULL); m = pa_cvolume_max(v); -- cgit From 9755bfa58af0c27b478d5d8cc56013527a6f660b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Sep 2009 20:00:02 +0200 Subject: volume: drop some redundant but expensive validity checks --- src/pulse/volume.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 1bbb07f2..1b26cc78 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -510,8 +510,6 @@ pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa pa_assert(from); pa_assert(to); - pa_return_val_if_fail(pa_cvolume_valid(v), NULL); - pa_return_val_if_fail(pa_channel_map_valid(from), NULL); pa_return_val_if_fail(pa_channel_map_valid(to), NULL); pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, from), NULL); @@ -613,8 +611,6 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) { pa_assert(v); pa_assert(map); - pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f); - pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f); pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f); if (!pa_channel_map_can_balance(map)) @@ -711,8 +707,8 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map pa_assert(v); - pa_return_val_if_fail(pa_cvolume_valid(v), NULL); pa_return_val_if_fail(max != (pa_volume_t) -1, NULL); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, cm), NULL); t = pa_cvolume_max_mask(v, cm, mask); @@ -763,8 +759,6 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) { pa_assert(v); pa_assert(map); - pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f); - pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f); pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f); if (!pa_channel_map_can_fade(map)) -- cgit From d000dd6f4b976894558613f69bdad2974cce7d1e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Sep 2009 20:00:58 +0200 Subject: volume: when passing NULL as channel map to pa_cvolume_scale_mask() handle this the same way as pa_cvolume_scale() --- src/pulse/volume.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 1b26cc78..8a28b334 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -707,7 +707,11 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map pa_assert(v); - pa_return_val_if_fail(max != (pa_volume_t) -1, NULL); + pa_return_val_if_fail(max != PA_VOLUME_INVALID, NULL); + + if (!cm) + return pa_cvolume_scale(v, max); + pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, cm), NULL); t = pa_cvolume_max_mask(v, cm, mask); -- cgit From 41a0dc1e9987ae00b605fd88bf887becbdf097d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Sep 2009 20:08:07 +0200 Subject: volume: if pa_cvolume_set_{balance|fade}() is called with invalid fade/balance value log, but don't assert --- src/pulse/volume.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 8a28b334..47bccad2 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -642,12 +642,10 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo pa_assert(map); pa_assert(v); - pa_assert(new_balance >= -1.0f); - pa_assert(new_balance <= 1.0f); - pa_return_val_if_fail(pa_cvolume_valid(v), NULL); - pa_return_val_if_fail(pa_channel_map_valid(map), NULL); pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL); + pa_return_val_if_fail(new_balance >= -1.0f, NULL); + pa_return_val_if_fail(new_balance <= 1.0f, NULL); if (!pa_channel_map_can_balance(map)) return v; @@ -785,12 +783,10 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float pa_assert(map); pa_assert(v); - pa_assert(new_fade >= -1.0f); - pa_assert(new_fade <= 1.0f); - pa_return_val_if_fail(pa_cvolume_valid(v), NULL); - pa_return_val_if_fail(pa_channel_map_valid(map), NULL); pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL); + pa_return_val_if_fail(new_fade >= -1.0f, NULL); + pa_return_val_if_fail(new_fade <= 1.0f, NULL); if (!pa_channel_map_can_fade(map)) return v; -- cgit From 08a4d57ce2f20173ea8a90e597a3ebcd28398242 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Sep 2009 22:43:35 +0200 Subject: libpulse: allow invocation of pa_context_play_sample_with_proplist() with NULL proplist --- src/pulse/scache.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/scache.c b/src/pulse/scache.c index 43dc5296..27da6887 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -216,7 +216,6 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); PA_CHECK_VALIDITY_RETURN_NULL(c, !dev || *dev, PA_ERR_INVALID); - PA_CHECK_VALIDITY_RETURN_NULL(c, p, PA_ERR_INVALID); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED); o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); @@ -233,7 +232,14 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na pa_tagstruct_putu32(t, volume); pa_tagstruct_puts(t, name); - pa_tagstruct_put_proplist(t, p); + + if (p) + pa_tagstruct_put_proplist(t, p); + else { + p = pa_proplist_new(); + pa_tagstruct_put_proplist(t, p); + pa_proplist_free(p); + } pa_pstream_send_tagstruct(c->pstream, t); pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, play_sample_with_proplist_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); -- cgit From f5046759cdd72daf5ba3b31c9dfc7b8d5be6bc9b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 8 Sep 2009 23:46:23 +0200 Subject: llvm-clang-analyzer: drop a few unnecessary assignments and other trivial fixes --- src/pulse/utf8.c | 4 +--- src/pulse/volume.c | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 6b58bde3..9dddf4a3 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -120,10 +120,8 @@ static char* utf8_validate(const char *str, char *output) { size = 4; min = (1 << 16); val = (uint32_t) (*p & 0x07); - } else { - size = 1; + } else goto error; - } p++; if (!is_continuation_char(*p)) diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 47bccad2..2d2bba25 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -155,7 +155,7 @@ pa_volume_t pa_cvolume_min(const pa_cvolume *a) { pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) { pa_volume_t m = PA_VOLUME_MUTED; - unsigned c, n; + unsigned c; pa_assert(a); @@ -164,7 +164,7 @@ pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, p pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(a, cm), PA_VOLUME_MUTED); - for (c = n = 0; c < a->channels; c++) { + for (c = 0; c < a->channels; c++) { if (!(PA_CHANNEL_POSITION_MASK(cm->map[c]) & mask)) continue; @@ -178,7 +178,7 @@ pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, p pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) { pa_volume_t m = PA_VOLUME_MAX; - unsigned c, n; + unsigned c; pa_assert(a); @@ -187,7 +187,7 @@ pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, p pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(a, cm), PA_VOLUME_MUTED); - for (c = n = 0; c < a->channels; c++) { + for (c = 0; c < a->channels; c++) { if (!(PA_CHANNEL_POSITION_MASK(cm->map[c]) & mask)) continue; -- cgit From 05506d7dc228f83d3ad0fccc831c493aec7f62be Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 8 Sep 2009 23:49:42 +0200 Subject: utf8: minor simplification --- src/pulse/utf8.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 9dddf4a3..fe7bcd26 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -148,12 +148,9 @@ ONE_REMAINING: if (o) { memcpy(o, last, (size_t) size); - o += size - 1; + o += size; } - if (o) - o++; - continue; error: -- cgit From 12c7460e404c94a364a23434ca28ec2bcc698431 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 10 Sep 2009 02:16:00 +0200 Subject: libpulse: don't support pa_context_get_card_info_list() on servers that cannot handle it --- src/pulse/introspect.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/pulse') diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 27a587cb..100413ee 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -834,6 +834,8 @@ pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char*name, p } pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata) { + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED); + return pa_context_send_simple_command(c, PA_COMMAND_GET_CARD_INFO_LIST, context_get_card_info_callback, (pa_operation_cb_t) cb, userdata); } -- cgit From 54609675e5bf50eaf405c8259129d074135de20a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Sep 2009 01:20:45 +0200 Subject: libpulse: add new error code PA_ERR_BUSY --- src/pulse/def.h | 1 + src/pulse/error.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/def.h b/src/pulse/def.h index 08399ca8..1a7da974 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -394,6 +394,7 @@ enum { PA_ERR_NOTIMPLEMENTED, /**< Missing implementation. \since 0.9.15 */ PA_ERR_FORKED, /**< The caller forked without calling execve() and tried to reuse the context. \since 0.9.15 */ PA_ERR_IO, /**< An IO error happened. \since 0.9.16 */ + PA_ERR_BUSY, /**< Device or resource busy. \since 0.9.17 */ PA_ERR_MAX /**< Not really an error but the first invalid error code */ }; diff --git a/src/pulse/error.c b/src/pulse/error.c index 93a13fc6..e8276990 100644 --- a/src/pulse/error.c +++ b/src/pulse/error.c @@ -64,7 +64,9 @@ const char*pa_strerror(int error) { [PA_ERR_NOEXTENSION] = N_("No such extension"), [PA_ERR_OBSOLETE] = N_("Obsolete functionality"), [PA_ERR_NOTIMPLEMENTED] = N_("Missing implementation"), - [PA_ERR_FORKED] = N_("Client forked") + [PA_ERR_FORKED] = N_("Client forked"), + [PA_ERR_IO] = N_("Input/Output error"), + [PA_ERR_BUSY] = N_("Device or resource busy") }; pa_init_i18n(); -- cgit From 297f31820617a22091764485f4dec2eabf3c74c5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Sep 2009 01:49:16 +0200 Subject: doxygen: drop references to pacat.c and paplay.c as examples since tehy are not useful as such and in the case of paplay not even existant anymore --- src/pulse/context.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/context.h b/src/pulse/context.h index 670b23e8..ecff58df 100644 --- a/src/pulse/context.h +++ b/src/pulse/context.h @@ -147,12 +147,6 @@ * server. A pa_context object wraps a connection to a PulseAudio * server using its native protocol. */ -/** \example pacat.c - * A playback and recording tool using the asynchronous API */ - -/** \example paplay.c - * A sound file playback tool using the asynchronous API, based on libsndfile */ - PA_C_DECL_BEGIN /** An opaque connection context to a daemon */ -- cgit From 4e3f7d5577577729d95d249ba05a931a05487583 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Sep 2009 01:49:39 +0200 Subject: doxygen: add rtclock.h to documentation --- src/pulse/pulseaudio.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/pulseaudio.h b/src/pulse/pulseaudio.h index aa369e69..793ba9b1 100644 --- a/src/pulse/pulseaudio.h +++ b/src/pulse/pulseaudio.h @@ -44,15 +44,17 @@ #include #include #include +#include /** \file - * Include all libpulse header files at once. The following - * files are included: \ref mainloop-api.h, \ref sample.h, \ref def.h, - * \ref context.h, \ref stream.h, \ref introspect.h, \ref subscribe.h, - * \ref scache.h, \ref version.h, \ref error.h, \ref channelmap.h, - * \ref operation.h,\ref volume.h, \ref xmalloc.h, \ref utf8.h, \ref - * thread-mainloop.h, \ref mainloop.h, \ref util.h, \ref proplist.h, \ref timeval.h and - * \ref mainloop-signal.h at once */ + * Include all libpulse header files at once. The following files are + * included: \ref mainloop-api.h, \ref sample.h, \ref def.h, \ref + * context.h, \ref stream.h, \ref introspect.h, \ref subscribe.h, \ref + * scache.h, \ref version.h, \ref error.h, \ref channelmap.h, \ref + * operation.h,\ref volume.h, \ref xmalloc.h, \ref utf8.h, \ref + * thread-mainloop.h, \ref mainloop.h, \ref util.h, \ref proplist.h, + * \ref timeval.h, \ref rtclock.h and \ref mainloop-signal.h at + * once */ /** \mainpage * -- cgit From 42b795b408925b13c9cc9db362b3f2d48d498449 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Sep 2009 01:49:55 +0200 Subject: doxygen: don't confuse doxygen with spurious .. --- src/pulse/proplist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index bc4dbd8a..260c26c8 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -197,7 +197,7 @@ PA_C_DECL_BEGIN /** For filter devices: master device id if applicable. */ #define PA_PROP_DEVICE_MASTER_DEVICE "device.master_device" -/** For devices: buffer size in bytes, integer formatted as string.. */ +/** For devices: buffer size in bytes, integer formatted as string. */ #define PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE "device.buffering.buffer_size" /** For devices: fragment size in bytes, integer formatted as string. */ -- cgit From 5919337433e97c36be904c4f7839f22045aa7947 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Sep 2009 02:16:17 +0200 Subject: proplist: define properties for storing window position --- src/pulse/proplist.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/pulse') diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index 260c26c8..8bf9c482 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -97,6 +97,24 @@ PA_C_DECL_BEGIN /** For streams that belong to a window on the screen: an XDG icon name for the window. e.g. "totem" */ #define PA_PROP_WINDOW_ICON_NAME "window.icon_name" +/** For streams that belong to a window on the screen: absolute horizontal window position on the screen, integer formatted as text string. e.g. "865". \since 0.9.17 */ +#define PA_PROP_WINDOW_X "window.x" + +/** For streams that belong to a window on the screen: absolute vertical window position on the screen, integer formatted as text string. e.g. "343". \since 0.9.17 */ +#define PA_PROP_WINDOW_Y "window.y" + +/** For streams that belong to a window on the screen: window width on the screen, integer formatted as text string. e.g. "365". \since 0.9.17 */ +#define PA_PROP_WINDOW_WIDTH "window.width" + +/** For streams that belong to a window on the screen: window height on the screen, integer formatted as text string. e.g. "643". \since 0.9.17 */ +#define PA_PROP_WINDOW_HEIGHT "window.height" + +/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). e.g. "0.65". \since 0.9.17 */ +#define PA_PROP_WINDOW_HPOS "window.hpos" + +/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). e.g. "0.43". \since 0.9.17 */ +#define PA_PROP_WINDOW_VPOS "window.vpos" + /** For streams that belong to an X11 window on the screen: the X11 display string. e.g. ":0.0" */ #define PA_PROP_WINDOW_X11_DISPLAY "window.x11.display" -- cgit From 12f211105e843d8b10f7d2a85d0ef451b7becd9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 15 Sep 2009 04:31:54 +0200 Subject: gccmacro: enable weakrefs only on ELF --- src/pulse/gccmacro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/gccmacro.h b/src/pulse/gccmacro.h index e85ecb66..57e80509 100644 --- a/src/pulse/gccmacro.h +++ b/src/pulse/gccmacro.h @@ -118,7 +118,7 @@ #endif #ifndef PA_GCC_WEAKREF -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 4)) +#if defined(__GNUC__) && defined(__ELF__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 4)) /** Macro for usgae of GCC's weakref attribute */ #define PA_GCC_WEAKREF(x) __attribute__((weakref(#x))); #endif -- cgit From 6b8fdc41693a710a29c4d3851a8c870031f1af88 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Sep 2009 01:19:55 +0200 Subject: CANCELLED vs. CANCELED Define CANCELLED as alias for CANCELED --- src/pulse/def.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/def.h b/src/pulse/def.h index 1a7da974..e839bd92 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -95,13 +95,14 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) { typedef enum pa_operation_state { PA_OPERATION_RUNNING, /**< The operation is still running */ PA_OPERATION_DONE, /**< The operation has been completed */ - PA_OPERATION_CANCELED /**< The operation has been canceled */ + PA_OPERATION_CANCELLED /**< The operation has been cancelled. Before 0.9.18 this was called PA_OPERATION_CANCELED. That name is still available for compatibility. */ } pa_operation_state_t; /** \cond fulldocs */ #define PA_OPERATION_RUNNING PA_OPERATION_RUNNING #define PA_OPERATION_DONE PA_OPERATION_DONE -#define PA_OPERATION_CANCELED PA_OPERATION_CANCELED +#define PA_OPERATION_CANCELED PA_OPERATION_CANCELLED +#define PA_OPERATION_CANCELLED PA_OPERATION_CANCELLED /** \endcond */ /** An invalid index */ -- cgit From cdbeac6b6961b5e071250f539b7011efe65ef513 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Sep 2009 01:37:23 +0200 Subject: libpulse: as a special exception, don't require a non-NULL context in pa_context_errno --- src/pulse/context.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/context.c b/src/pulse/context.c index 894ab2e0..23ae30ce 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -1045,7 +1045,10 @@ pa_context_state_t pa_context_get_state(pa_context *c) { } int pa_context_errno(pa_context *c) { - pa_assert(c); + + if (!c) + return PA_ERR_INVALID; + pa_assert(PA_REFCNT_VALUE(c) >= 1); return c->error; -- cgit From 94f28b9d4b7448c1e9bb6fb8a3b44f53988f6aa5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Sep 2009 02:22:41 +0200 Subject: proplist: introduce PA_PROP_WINDOW_DESKTOP property --- src/pulse/proplist.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/pulse') diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index 8bf9c482..8dff8df4 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -115,6 +115,9 @@ PA_C_DECL_BEGIN /** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). e.g. "0.43". \since 0.9.17 */ #define PA_PROP_WINDOW_VPOS "window.vpos" +/** For streams that belong to a window on the screen: if the windowing system supports multiple desktops, a comma seperated list of indexes of the desktops this window is visible on. If this property is an empty string, it is visible on all desktops (i.e. 'sticky'). The first desktop is 0. e.g. "0,2,3" \since 0.9.18 */ +#define PA_PROP_WINDOW_DESKTOP "window.desktop" + /** For streams that belong to an X11 window on the screen: the X11 display string. e.g. ":0.0" */ #define PA_PROP_WINDOW_X11_DISPLAY "window.x11.display" -- cgit From a43118b730c60a17b032b882b10ff9b93ab59460 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 03:48:55 +0200 Subject: mainloop: properly convert time to wallclock time when handing it to the user --- src/pulse/mainloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 93a4742d..379f88a8 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -806,7 +806,7 @@ static int dispatch_timeout(pa_mainloop *m) { /* Disable time event */ mainloop_time_restart(e, NULL); - e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, TRUE), e->userdata); + e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, FALSE), e->userdata); r++; } -- cgit From a049909a7044813cb6237d22757ac24081b59af8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 03:59:40 +0200 Subject: mainloop: calculate in pa_usec_t everywhere --- src/pulse/mainloop.c | 67 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 21 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 379f88a8..d2cc7aec 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -112,7 +112,7 @@ struct pa_mainloop { struct pollfd *pollfds; unsigned max_pollfds, n_pollfds; - int prepared_timeout; + pa_usec_t prepared_timeout; pa_time_event *cached_next_time_event; pa_mainloop_api api; @@ -320,21 +320,19 @@ static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy } /* Time events */ -static pa_usec_t timeval_load(const struct timeval *tv) { - pa_bool_t is_rtclock; +static pa_usec_t make_rt(const struct timeval *tv) { struct timeval ttv; if (!tv) return PA_USEC_INVALID; - ttv = *tv; - is_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK); - ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; - - if (!is_rtclock) - pa_rtclock_from_wallclock(&ttv); + if (tv->tv_usec & PA_TIMEVAL_RTCLOCK) { + ttv = *tv; + ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; + tv = pa_rtclock_from_wallclock(&ttv); + } - return pa_timeval_load(&ttv); + return pa_timeval_load(tv); } static pa_time_event* mainloop_time_new( @@ -351,7 +349,7 @@ static pa_time_event* mainloop_time_new( pa_assert(a->userdata); pa_assert(callback); - t = timeval_load(tv); + t = make_rt(tv); m = a->userdata; pa_assert(a == &m->api); @@ -392,7 +390,7 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { pa_assert(e); pa_assert(!e->dead); - t = timeval_load(tv); + t = make_rt(tv); valid = (t != PA_USEC_INVALID); if (e->enabled && !valid) { @@ -763,12 +761,12 @@ static pa_time_event* find_next_time_event(pa_mainloop *m) { return n; } -static int calc_next_timeout(pa_mainloop *m) { +static pa_usec_t calc_next_timeout(pa_mainloop *m) { pa_time_event *t; pa_usec_t clock_now; - if (!m->n_enabled_time_events) - return -1; + if (m->n_enabled_time_events <= 0) + return PA_USEC_INVALID; pa_assert_se(t = find_next_time_event(m)); @@ -780,7 +778,7 @@ static int calc_next_timeout(pa_mainloop *m) { if (t->time <= clock_now) return 0; - return (int) ((t->time - clock_now) / 1000); /* in milliseconds */ + return t->time - clock_now; } static int dispatch_timeout(pa_mainloop *m) { @@ -850,12 +848,17 @@ int pa_mainloop_prepare(pa_mainloop *m, int timeout) { goto quit; if (m->n_enabled_defer_events <= 0) { + if (m->rebuild_pollfds) rebuild_pollfds(m); m->prepared_timeout = calc_next_timeout(m); - if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0)) - m->prepared_timeout = timeout; + if (timeout >= 0) { + uint64_t u = (uint64_t) timeout * PA_USEC_PER_MSEC; + + if (u < m->prepared_timeout || m->prepared_timeout == PA_USEC_INVALID) + m->prepared_timeout = timeout; + } } m->state = STATE_PREPARED; @@ -866,6 +869,13 @@ quit: return -2; } +static int usec_to_timeout(pa_usec_t u) { + if (u == PA_USEC_INVALID) + return -1; + + return (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC; +} + int pa_mainloop_poll(pa_mainloop *m) { pa_assert(m); pa_assert(m->state == STATE_PREPARED); @@ -881,9 +891,24 @@ int pa_mainloop_poll(pa_mainloop *m) { pa_assert(!m->rebuild_pollfds); if (m->poll_func) - m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata); - else - m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout); + m->poll_func_ret = m->poll_func( + m->pollfds, m->n_pollfds, + usec_to_timeout(m->prepared_timeout), + m->poll_func_userdata); + else { +#ifdef HAVE_PPOLL + struct timespec ts; + + m->poll_func_ret = ppoll( + m->pollfds, m->n_pollfds, + m->prepared_timeout == PA_USEC_INVALID ? NULL : pa_timespec_store(&ts, m->prepared_timeout), + NULL); +#else + m->poll_func_ret = poll( + m->pollfds, m->n_pollfds, + usec_to_timeout(m->prepared_timeout)); +#endif + } if (m->poll_func_ret < 0) { if (errno == EINTR) -- cgit From b32f5994e9d1872c3a2ed8fd44d6d1866bb8387f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:00:38 +0200 Subject: mainloop: don't initialize fields we don't have to --- src/pulse/mainloop.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index d2cc7aec..4f3b676f 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -172,17 +172,14 @@ static pa_io_event* mainloop_io_new( m = a->userdata; pa_assert(a == &m->api); - e = pa_xnew(pa_io_event, 1); + e = pa_xnew0(pa_io_event, 1); e->mainloop = m; - e->dead = FALSE; e->fd = fd; e->events = events; - e->pollfd = NULL; e->callback = callback; e->userdata = userdata; - e->destroy_callback = NULL; #ifdef OS_IS_WIN32 { @@ -265,16 +262,14 @@ static pa_defer_event* mainloop_defer_new( m = a->userdata; pa_assert(a == &m->api); - e = pa_xnew(pa_defer_event, 1); + e = pa_xnew0(pa_defer_event, 1); e->mainloop = m; - e->dead = FALSE; e->enabled = TRUE; m->n_enabled_defer_events++; e->callback = callback; e->userdata = userdata; - e->destroy_callback = NULL; PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e); @@ -354,9 +349,8 @@ static pa_time_event* mainloop_time_new( m = a->userdata; pa_assert(a == &m->api); - e = pa_xnew(pa_time_event, 1); + e = pa_xnew0(pa_time_event, 1); e->mainloop = m; - e->dead = FALSE; if ((e->enabled = (t != PA_USEC_INVALID))) { e->time = t; @@ -373,7 +367,6 @@ static pa_time_event* mainloop_time_new( e->callback = callback; e->userdata = userdata; - e->destroy_callback = NULL; PA_LLIST_PREPEND(pa_time_event, m->time_events, e); @@ -478,9 +471,8 @@ pa_mainloop *pa_mainloop_new(void) { pa_init_i18n(); - m = pa_xnew(pa_mainloop, 1); + m = pa_xnew0(pa_mainloop, 1); - m->wakeup_pipe_type = 0; if (pipe(m->wakeup_pipe) < 0) { pa_log_error("ERROR: cannot create wakeup pipe"); pa_xfree(m); @@ -491,32 +483,14 @@ 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 = FALSE; - PA_LLIST_HEAD_INIT(pa_io_event, m->io_events); - PA_LLIST_HEAD_INIT(pa_time_event, m->time_events); - PA_LLIST_HEAD_INIT(pa_defer_event, m->defer_events); - - m->n_enabled_defer_events = m->n_enabled_time_events = m->n_io_events = 0; - m->io_events_please_scan = m->time_events_please_scan = m->defer_events_please_scan = 0; - - m->cached_next_time_event = NULL; - m->prepared_timeout = 0; - - m->pollfds = NULL; - m->max_pollfds = m->n_pollfds = 0; m->rebuild_pollfds = TRUE; - m->quit = FALSE; - m->retval = 0; - m->api = vtable; m->api.userdata = m; m->state = STATE_PASSIVE; - m->poll_func = NULL; - m->poll_func_userdata = NULL; m->poll_func_ret = -1; return m; -- cgit From 18d69c5d9d04d81135f078d7f49bad3214418622 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:03:49 +0200 Subject: mainloop: use PA_LLIST_FOREACH macros where applicable --- src/pulse/mainloop.c | 56 ++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 26 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 4f3b676f..67f095be 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -497,11 +497,9 @@ pa_mainloop *pa_mainloop_new(void) { } static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) { - pa_io_event *e; + pa_io_event *e, *n; - e = m->io_events; - while (e) { - pa_io_event *n = e->next; + PA_LLIST_FOREACH_SAFE(e, n, m->io_events) { if (!force && m->io_events_please_scan <= 0) break; @@ -521,19 +519,15 @@ static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) { m->rebuild_pollfds = TRUE; } - - e = n; } pa_assert(m->io_events_please_scan == 0); } static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) { - pa_time_event *e; + pa_time_event *e, *n; - e = m->time_events; - while (e) { - pa_time_event *n = e->next; + PA_LLIST_FOREACH_SAFE(e, n, m->time_events) { if (!force && m->time_events_please_scan <= 0) break; @@ -557,19 +551,15 @@ static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) { pa_xfree(e); } - - e = n; } pa_assert(m->time_events_please_scan == 0); } static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) { - pa_defer_event *e; + pa_defer_event *e, *n; - e = m->defer_events; - while (e) { - pa_defer_event *n = e->next; + PA_LLIST_FOREACH_SAFE(e, n, m->defer_events) { if (!force && m->defer_events_please_scan <= 0) break; @@ -593,8 +583,6 @@ static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) { pa_xfree(e); } - - e = n; } pa_assert(m->defer_events_please_scan == 0); @@ -651,7 +639,7 @@ static void rebuild_pollfds(pa_mainloop *m) { m->n_pollfds++; } - for (e = m->io_events; e; e = e->next) { + PA_LLIST_FOREACH(e, m->io_events) { if (e->dead) { e->pollfd = NULL; continue; @@ -675,16 +663,22 @@ static int dispatch_pollfds(pa_mainloop *m) { pa_assert(m->poll_func_ret > 0); - for (e = m->io_events, k = m->poll_func_ret; e && !m->quit && k > 0; e = e->next) { + k = m->poll_func_ret; + + PA_LLIST_FOREACH(e, m->io_events) { + + if (k <= 0 || m->quit) + break; + if (e->dead || !e->pollfd || !e->pollfd->revents) continue; pa_assert(e->pollfd->fd == e->fd); pa_assert(e->callback); + e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata); e->pollfd->revents = 0; r++; - k--; } @@ -698,7 +692,11 @@ static int dispatch_defer(pa_mainloop *m) { if (m->n_enabled_defer_events <= 0) return 0; - for (e = m->defer_events; e && !m->quit; e = e->next) { + PA_LLIST_FOREACH(e, m->defer_events) { + + if (m->quit) + break; + if (e->dead || !e->enabled) continue; @@ -717,7 +715,7 @@ static pa_time_event* find_next_time_event(pa_mainloop *m) { if (m->cached_next_time_event) return m->cached_next_time_event; - for (t = m->time_events; t; t = t->next) { + PA_LLIST_FOREACH(t, m->time_events) { if (t->dead || !t->enabled) continue; @@ -766,7 +764,10 @@ static int dispatch_timeout(pa_mainloop *m) { now = pa_rtclock_now(); - for (e = m->time_events; e && !m->quit; e = e->next) { + PA_LLIST_FOREACH(e, m->time_events) { + + if (m->quit) + break; if (e->dead || !e->enabled) continue; @@ -806,7 +807,8 @@ static void clear_wakeup(pa_mainloop *m) { return; if (m->wakeup_requested) { - while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c)); + while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c)) + ; m->wakeup_requested = 0; } } @@ -964,7 +966,8 @@ quit: int pa_mainloop_run(pa_mainloop *m, int *retval) { int r; - while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0); + while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0) + ; if (r == -2) return 1; @@ -984,6 +987,7 @@ void pa_mainloop_quit(pa_mainloop *m, int retval) { pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) { pa_assert(m); + return &m->api; } -- cgit From fb4a2a1bbbd35601b5da62037c1cee40be859428 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:05:10 +0200 Subject: mainloop: sum up dispatched events in an unsigned to clarify range --- src/pulse/mainloop.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 67f095be..62659d89 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -657,9 +657,9 @@ static void rebuild_pollfds(pa_mainloop *m) { m->rebuild_pollfds = FALSE; } -static int dispatch_pollfds(pa_mainloop *m) { +static unsigned dispatch_pollfds(pa_mainloop *m) { pa_io_event *e; - int r = 0, k; + unsigned r = 0, k; pa_assert(m->poll_func_ret > 0); @@ -685,9 +685,9 @@ static int dispatch_pollfds(pa_mainloop *m) { return r; } -static int dispatch_defer(pa_mainloop *m) { +static unsigned dispatch_defer(pa_mainloop *m) { pa_defer_event *e; - int r = 0; + unsigned r = 0; if (m->n_enabled_defer_events <= 0) return 0; @@ -753,10 +753,10 @@ static pa_usec_t calc_next_timeout(pa_mainloop *m) { return t->time - clock_now; } -static int dispatch_timeout(pa_mainloop *m) { +static unsigned dispatch_timeout(pa_mainloop *m) { pa_time_event *e; pa_usec_t now; - int r = 0; + unsigned r = 0; pa_assert(m); if (m->n_enabled_time_events <= 0) @@ -903,7 +903,7 @@ quit: } int pa_mainloop_dispatch(pa_mainloop *m) { - int dispatched = 0; + unsigned dispatched = 0; pa_assert(m); pa_assert(m->state == STATE_POLLED); @@ -929,7 +929,7 @@ int pa_mainloop_dispatch(pa_mainloop *m) { m->state = STATE_PASSIVE; - return dispatched; + return (int) dispatched; quit: m->state = STATE_QUIT; @@ -938,6 +938,7 @@ quit: int pa_mainloop_get_retval(pa_mainloop *m) { pa_assert(m); + return m->retval; } -- cgit From f7d38965b355b4932e7a17774e4625f57248f845 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:07:12 +0200 Subject: timeval: introduce PA_USEC_MAX --- src/pulse/timeval.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index 48c6cdb3..3cea5d3b 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -51,12 +51,15 @@ PA_C_DECL_BEGIN /** The number of nanoseconds in a microsecond */ #define PA_NSEC_PER_USEC ((unsigned long long) 1000ULL) -/** Invalid time in usec */ +/** Invalid time in usec. \since 0.9.15 */ #define PA_USEC_INVALID ((pa_usec_t) -1) +/** Biggest time in usec. \since 0.9.18 */ +#define PA_USEC_MAX ((pa_usec_t) -2) + struct timeval; -/** Return the current timestamp, just like UNIX gettimeofday() */ +/** Return the current wallclock timestamp, just like UNIX gettimeofday(). */ struct timeval *pa_gettimeofday(struct timeval *tv); /** Calculate the difference between the two specified timeval -- cgit From 05f6236a83414573587c73dbc439e68dae5f529e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:10:26 +0200 Subject: timeval: make pa_timeval_sub saturating --- src/pulse/timeval.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 376cf13c..1a0d3cef 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -33,6 +33,7 @@ #include #include +#include #include "timeval.h" @@ -54,9 +55,9 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { #define EPOCHFILETIME (116444736000000000LL) #endif - FILETIME ft; - LARGE_INTEGER li; - __int64 t; + FILETIME ft; + LARGE_INTEGER li; + int64_t t; pa_assert(tv); @@ -128,40 +129,65 @@ pa_usec_t pa_timeval_age(const struct timeval *tv) { } struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { - unsigned long secs; + time_t secs; pa_assert(tv); - secs = (unsigned long) (v/PA_USEC_PER_SEC); - tv->tv_sec += (time_t) secs; - v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; + secs = (time_t) (v/PA_USEC_PER_SEC); + if (PA_UNLIKELY(tv->tv_sec > PA_INT_TYPE_MAX(time_t) - secs)) + goto overflow; + + tv->tv_sec += secs; + v -= (pa_usec_t) secs * PA_USEC_PER_SEC; tv->tv_usec += (suseconds_t) v; /* Normalize */ - while ((unsigned) tv->tv_usec >= PA_USEC_PER_SEC) { + while ((pa_usec_t) tv->tv_usec >= PA_USEC_PER_SEC) { + + if (PA_UNLIKELY(tv->tv_sec >= PA_INT_TYPE_MAX(time_t))) + goto overflow; + tv->tv_sec++; tv->tv_usec -= (suseconds_t) PA_USEC_PER_SEC; } return tv; + +overflow: + tv->tv_sec = PA_INT_TYPE_MAX(time_t); + tv->tv_usec = (suseconds_t) (PA_USEC_PER_SEC-1); + return tv; } struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) { - unsigned long secs; + time_t secs; pa_assert(tv); - secs = (unsigned long) (v/PA_USEC_PER_SEC); - tv->tv_sec -= (time_t) secs; - v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; + secs = (time_t) (v/PA_USEC_PER_SEC); + + if (PA_UNLIKELY(tv->tv_sec < secs)) + goto underflow; + + tv->tv_sec -= secs; + v -= (pa_usec_t) secs * PA_USEC_PER_SEC; if (tv->tv_usec >= (suseconds_t) v) tv->tv_usec -= (suseconds_t) v; else { + + if (PA_UNLIKELY(tv->tv_sec <= 0)) + goto underflow; + tv->tv_sec --; tv->tv_usec += (suseconds_t) (PA_USEC_PER_SEC - v); } return tv; + +underflow: + tv->tv_sec = 0; + tv->tv_usec = 0; + return tv; } struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { -- cgit From a1da83b206d4a73bfa537ab3694bac7244bd19a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:11:02 +0200 Subject: timeval: add UNLIKELY annotation --- src/pulse/timeval.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 1a0d3cef..87569cf1 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -83,7 +83,7 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { pa_assert(b); /* Check which whan is the earlier time and swap the two arguments if required. */ - if (pa_timeval_cmp(a, b) < 0) { + if (PA_UNLIKELY(pa_timeval_cmp(a, b) < 0)) { const struct timeval *c; c = a; a = b; @@ -95,9 +95,9 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { /* Calculate the microsecond difference */ if (a->tv_usec > b->tv_usec) - r += ((pa_usec_t) a->tv_usec - (pa_usec_t) 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 - (pa_usec_t) a->tv_usec); + r -= (pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec; return r; } -- cgit From c024aeaae91c139914dc928df975ea311729052c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:11:59 +0200 Subject: timeval: make timeval conversion routines handle PA_USEC_INVALID special --- src/pulse/timeval.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 87569cf1..cde4417c 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -193,6 +193,13 @@ underflow: struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { pa_assert(tv); + if (PA_UNLIKELY(v == PA_USEC_INVALID)) { + tv->tv_sec = PA_INT_TYPE_MAX(time_t); + tv->tv_usec = (suseconds_t) (PA_USEC_PER_SEC-1); + + return tv; + } + tv->tv_sec = (time_t) (v / PA_USEC_PER_SEC); tv->tv_usec = (suseconds_t) (v % PA_USEC_PER_SEC); @@ -200,7 +207,9 @@ struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { } pa_usec_t pa_timeval_load(const struct timeval *tv) { - pa_assert(tv); + + if (PA_UNLIKELY(!tv)) + return PA_USEC_INVALID; return (pa_usec_t) tv->tv_sec * PA_USEC_PER_SEC + -- cgit From d6291511a25d29c51cc3b22b72b69426f68e461d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:21:01 +0200 Subject: mainloop: pass monotonic times back to user if he passed monotonic times to us --- src/pulse/mainloop.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 62659d89..c5443f23 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -78,6 +78,7 @@ struct pa_time_event { pa_bool_t dead:1; pa_bool_t enabled:1; + pa_bool_t use_rtclock:1; pa_usec_t time; pa_time_event_cb_t callback; @@ -315,17 +316,22 @@ static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy } /* Time events */ -static pa_usec_t make_rt(const struct timeval *tv) { +static pa_usec_t make_rt(const struct timeval *tv, pa_bool_t *use_rtclock) { struct timeval ttv; - if (!tv) + if (!tv) { + *use_rtclock = FALSE; return PA_USEC_INVALID; + } if (tv->tv_usec & PA_TIMEVAL_RTCLOCK) { ttv = *tv; ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; tv = pa_rtclock_from_wallclock(&ttv); - } + + *use_rtclock = TRUE; + } else + *use_rtclock = FALSE; return pa_timeval_load(tv); } @@ -339,12 +345,13 @@ static pa_time_event* mainloop_time_new( pa_mainloop *m; pa_time_event *e; pa_usec_t t; + pa_bool_t use_rtclock = FALSE; pa_assert(a); pa_assert(a->userdata); pa_assert(callback); - t = make_rt(tv); + t = make_rt(tv, &use_rtclock); m = a->userdata; pa_assert(a == &m->api); @@ -354,6 +361,7 @@ static pa_time_event* mainloop_time_new( if ((e->enabled = (t != PA_USEC_INVALID))) { e->time = t; + e->use_rtclock= use_rtclock; m->n_enabled_time_events++; @@ -379,11 +387,12 @@ static pa_time_event* mainloop_time_new( static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { pa_bool_t valid; pa_usec_t t; + pa_bool_t use_rtclock = FALSE; pa_assert(e); pa_assert(!e->dead); - t = make_rt(tv); + t = make_rt(tv, &use_rtclock); valid = (t != PA_USEC_INVALID); if (e->enabled && !valid) { @@ -394,6 +403,7 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { if ((e->enabled = valid)) { e->time = t; + e->use_rtclock = use_rtclock; pa_mainloop_wakeup(e->mainloop); } @@ -779,7 +789,7 @@ static unsigned dispatch_timeout(pa_mainloop *m) { /* Disable time event */ mainloop_time_restart(e, NULL); - e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, FALSE), e->userdata); + e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, e->use_rtclock), e->userdata); r++; } -- cgit From f84d755d6a90ce8752e063a8a04a5d91239eb348 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 22:14:55 +0200 Subject: mainloop: fix detection of rt clocks --- src/pulse/mainloop.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index c5443f23..090ac8c2 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -324,16 +324,15 @@ static pa_usec_t make_rt(const struct timeval *tv, pa_bool_t *use_rtclock) { return PA_USEC_INVALID; } - if (tv->tv_usec & PA_TIMEVAL_RTCLOCK) { - ttv = *tv; - ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; - tv = pa_rtclock_from_wallclock(&ttv); + ttv = *tv; + *use_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK); - *use_rtclock = TRUE; - } else - *use_rtclock = FALSE; + if (*use_rtclock) + ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; + else + pa_rtclock_from_wallclock(&ttv); - return pa_timeval_load(tv); + return pa_timeval_load(&ttv); } static pa_time_event* mainloop_time_new( -- cgit From 8f4940b17aa185f69a66b5a91ed6deeb3dde9226 Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Tue, 22 Sep 2009 18:43:03 +0100 Subject: libpulse: Add *_NOFLAGS flags with value 0 for various enums This avoids the need for ugly casting in client implementations. --- src/pulse/def.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/pulse') diff --git a/src/pulse/def.h b/src/pulse/def.h index e839bd92..5d0a0b4b 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -110,6 +110,8 @@ typedef enum pa_operation_state { /** Some special flags for contexts. */ typedef enum pa_context_flags { + PA_CONTEXT_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ PA_CONTEXT_NOAUTOSPAWN = 0x0001U, /**< Disabled autospawning of the PulseAudio daemon if required */ PA_CONTEXT_NOFAIL = 0x0002U @@ -140,6 +142,9 @@ typedef enum pa_stream_direction { /** Some special flags for stream connections. */ typedef enum pa_stream_flags { + PA_STREAM_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + PA_STREAM_START_CORKED = 0x0001U, /**< Create the stream corked, requiring an explicit * pa_stream_cork() call to uncork it. */ @@ -688,6 +693,9 @@ typedef enum pa_seek_mode { /** Special sink flags. */ typedef enum pa_sink_flags { + PA_SINK_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + PA_SINK_HW_VOLUME_CTRL = 0x0001U, /**< Supports hardware volume control */ @@ -775,6 +783,9 @@ static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) { /** Special source flags. */ typedef enum pa_source_flags { + PA_SOURCE_NOFLAGS = 0x0000U, + /**< Flag to pass when no specific options are needed (used to avoid casting) \since 0.9.19 */ + PA_SOURCE_HW_VOLUME_CTRL = 0x0001U, /**< Supports hardware volume control */ -- cgit