mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Merge branch 'master' of git://0pointer.de/pulseaudio
This commit is contained in:
		
						commit
						ed7642ebac
					
				
					 20 changed files with 255 additions and 75 deletions
				
			
		| 
						 | 
				
			
			@ -20,21 +20,6 @@ pulseconfdir=$(sysconfdir)/pulse
 | 
			
		|||
CLEANFILES = \
 | 
			
		||||
	$(noinst_DATA)
 | 
			
		||||
 | 
			
		||||
dist_man_MANS = \
 | 
			
		||||
	pulseaudio.1 \
 | 
			
		||||
	esdcompat.1 \
 | 
			
		||||
	pax11publish.1 \
 | 
			
		||||
	paplay.1 \
 | 
			
		||||
	pacat.1 \
 | 
			
		||||
	pacmd.1 \
 | 
			
		||||
	pactl.1 \
 | 
			
		||||
	pasuspender.1 \
 | 
			
		||||
	padsp.1 \
 | 
			
		||||
	pabrowse.1 \
 | 
			
		||||
	pulse-daemon.conf.5 \
 | 
			
		||||
	pulse-client.conf.5 \
 | 
			
		||||
	default.pa.5
 | 
			
		||||
 | 
			
		||||
noinst_DATA = \
 | 
			
		||||
	pulseaudio.1.xml \
 | 
			
		||||
	esdcompat.1.xml \
 | 
			
		||||
| 
						 | 
				
			
			@ -50,24 +35,39 @@ noinst_DATA = \
 | 
			
		|||
	pulse-client.conf.5.xml \
 | 
			
		||||
	default.pa.5.xml
 | 
			
		||||
 | 
			
		||||
if BUILD_MANPAGES
 | 
			
		||||
 | 
			
		||||
CLEANFILES += \
 | 
			
		||||
	$(dist_man_MANS)
 | 
			
		||||
 | 
			
		||||
%.xml: %.xml.in Makefile
 | 
			
		||||
	sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
 | 
			
		||||
	    -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
 | 
			
		||||
            -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
 | 
			
		||||
 | 
			
		||||
%: %.xml Makefile
 | 
			
		||||
	perl $(srcdir)/xmltoman $< > $@ || rm -f $@
 | 
			
		||||
 | 
			
		||||
xmllint: $(noinst_DATA)
 | 
			
		||||
	for f in $(noinst_DATA) ; do \
 | 
			
		||||
			xmllint --noout --valid "$$f" || exit 1 ; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
if BUILD_MANPAGES
 | 
			
		||||
 | 
			
		||||
dist_man_MANS = \
 | 
			
		||||
	pulseaudio.1 \
 | 
			
		||||
	esdcompat.1 \
 | 
			
		||||
	pax11publish.1 \
 | 
			
		||||
	paplay.1 \
 | 
			
		||||
	pacat.1 \
 | 
			
		||||
	pacmd.1 \
 | 
			
		||||
	pactl.1 \
 | 
			
		||||
	pasuspender.1 \
 | 
			
		||||
	padsp.1 \
 | 
			
		||||
	pabrowse.1 \
 | 
			
		||||
	pulse-daemon.conf.5 \
 | 
			
		||||
	pulse-client.conf.5 \
 | 
			
		||||
	default.pa.5
 | 
			
		||||
 | 
			
		||||
CLEANFILES += \
 | 
			
		||||
	$(dist_man_MANS)
 | 
			
		||||
 | 
			
		||||
%: %.xml Makefile
 | 
			
		||||
	perl $(srcdir)/xmltoman $< > $@ || rm -f $@
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -648,7 +648,6 @@ int main(int argc, char *argv[]) {
 | 
			
		|||
 | 
			
		||||
    if (conf->daemonize) {
 | 
			
		||||
        pid_t child;
 | 
			
		||||
        int tty_fd;
 | 
			
		||||
 | 
			
		||||
        if (pa_stdio_acquire() < 0) {
 | 
			
		||||
            pa_log(_("Failed to acquire stdio."));
 | 
			
		||||
| 
						 | 
				
			
			@ -781,6 +780,8 @@ int main(int argc, char *argv[]) {
 | 
			
		|||
 | 
			
		||||
    pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
 | 
			
		||||
 | 
			
		||||
    pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm()));
 | 
			
		||||
 | 
			
		||||
#ifdef __OPTIMIZE__
 | 
			
		||||
    pa_log_debug(_("Optimized build: yes"));
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,6 +130,7 @@ pa_cvolume_get_balance;
 | 
			
		|||
pa_cvolume_get_fade;
 | 
			
		||||
pa_cvolume_get_position;
 | 
			
		||||
pa_cvolume_inc;
 | 
			
		||||
pa_cvolume_inc_clamp;
 | 
			
		||||
pa_cvolume_init;
 | 
			
		||||
pa_cvolume_max;
 | 
			
		||||
pa_cvolume_max_mask;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1712,7 +1712,9 @@ static int option_verify(pa_alsa_option *o) {
 | 
			
		|||
        { "input-boost-on",            N_("Boost") },
 | 
			
		||||
        { "input-boost-off",           N_("No Boost") },
 | 
			
		||||
        { "output-amplifier-on",       N_("Amplifier") },
 | 
			
		||||
        { "output-amplifier-off",      N_("No Amplifier") }
 | 
			
		||||
        { "output-amplifier-off",      N_("No Amplifier") },
 | 
			
		||||
        { "output-speaker",            N_("Speaker") },
 | 
			
		||||
        { "output-headphones",         N_("Headphones") }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    pa_assert(o);
 | 
			
		||||
| 
						 | 
				
			
			@ -1778,7 +1780,9 @@ static int path_verify(pa_alsa_path *p) {
 | 
			
		|||
        { "analog-output",              N_("Analog Output") },
 | 
			
		||||
        { "analog-output-headphones",   N_("Analog Headphones") },
 | 
			
		||||
        { "analog-output-lfe-on-mono",  N_("Analog Output (LFE)") },
 | 
			
		||||
        { "analog-output-mono",        N_("Analog Mono Output") }
 | 
			
		||||
        { "analog-output-mono",         N_("Analog Mono Output") },
 | 
			
		||||
        { "analog-output-headphones-2", N_("Analog Headphones 2") },
 | 
			
		||||
        { "analog-output-speaker",      N_("Analog Speaker") }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    pa_alsa_element *e;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1698,10 +1698,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (use_tsched && !pa_rtclock_hrtimer()) {
 | 
			
		||||
        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
 | 
			
		||||
        use_tsched = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    use_tsched = pa_alsa_may_tsched(use_tsched);
 | 
			
		||||
 | 
			
		||||
    u = pa_xnew0(struct userdata, 1);
 | 
			
		||||
    u->core = m->core;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1541,10 +1541,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (use_tsched && !pa_rtclock_hrtimer()) {
 | 
			
		||||
        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
 | 
			
		||||
        use_tsched = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    use_tsched = pa_alsa_may_tsched(use_tsched);
 | 
			
		||||
 | 
			
		||||
    u = pa_xnew0(struct userdata, 1);
 | 
			
		||||
    u->core = m->core;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,7 @@
 | 
			
		|||
#include <pulsecore/once.h>
 | 
			
		||||
#include <pulsecore/thread.h>
 | 
			
		||||
#include <pulsecore/conf-parser.h>
 | 
			
		||||
#include <pulsecore/core-rtclock.h>
 | 
			
		||||
 | 
			
		||||
#include "alsa-util.h"
 | 
			
		||||
#include "alsa-mixer.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1308,3 +1309,26 @@ const char* pa_alsa_strerror(int errnum) {
 | 
			
		|||
 | 
			
		||||
    return translated;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pa_bool_t pa_alsa_may_tsched(pa_bool_t want) {
 | 
			
		||||
 | 
			
		||||
    if (!want)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    if (!pa_rtclock_hrtimer()) {
 | 
			
		||||
        /* We cannot depend on being woken up in time when the timers
 | 
			
		||||
        are inaccurate, so let's fallback to classic IO based playback
 | 
			
		||||
        then. */
 | 
			
		||||
        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
 | 
			
		||||
        return FALSE; }
 | 
			
		||||
 | 
			
		||||
    if (pa_running_in_vm()) {
 | 
			
		||||
        /* We cannot depend on being woken up when we ask for in a VM,
 | 
			
		||||
         * so let's fallback to classic IO based playback then. */
 | 
			
		||||
        pa_log_notice("Disabling timer-based scheduling because running inside a VM.");
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -142,4 +142,6 @@ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm);
 | 
			
		|||
 | 
			
		||||
const char* pa_alsa_strerror(int errnum);
 | 
			
		||||
 | 
			
		||||
pa_bool_t pa_alsa_may_tsched(pa_bool_t want);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,3 +109,20 @@ priority = 10
 | 
			
		|||
[Option External Amplifier:off]
 | 
			
		||||
name = output-amplifier-off
 | 
			
		||||
priority = 0
 | 
			
		||||
 | 
			
		||||
;;; 'Analog Output'
 | 
			
		||||
 | 
			
		||||
[Element Analog Output]
 | 
			
		||||
enumeration = select
 | 
			
		||||
 | 
			
		||||
[Option Analog Output:Speakers]
 | 
			
		||||
name = output-speaker
 | 
			
		||||
priority = 10
 | 
			
		||||
 | 
			
		||||
[Option Analog Output:Headphones]
 | 
			
		||||
name = output-headphones
 | 
			
		||||
priority = 9
 | 
			
		||||
 | 
			
		||||
[Option Analog Output:FP Headphones]
 | 
			
		||||
name = output-headphones
 | 
			
		||||
priority = 8
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -334,7 +334,7 @@ int pa__init(pa_module*m) {
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
 | 
			
		||||
    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);
 | 
			
		||||
 | 
			
		||||
    channels = 0;
 | 
			
		||||
    for (p = ports; *p; p++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -286,7 +286,7 @@ int pa__init(pa_module*m) {
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
 | 
			
		||||
    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput);
 | 
			
		||||
 | 
			
		||||
    channels = 0;
 | 
			
		||||
    for (p = ports; *p; p++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,12 +45,14 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 | 
			
		|||
PA_MODULE_DESCRIPTION("LIRC volume control");
 | 
			
		||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
			
		||||
PA_MODULE_LOAD_ONCE(TRUE);
 | 
			
		||||
PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name>");
 | 
			
		||||
PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name> volume_limit=<volume limit> volume_step=<volume change step>");
 | 
			
		||||
 | 
			
		||||
static const char* const valid_modargs[] = {
 | 
			
		||||
    "config",
 | 
			
		||||
    "sink",
 | 
			
		||||
    "appname",
 | 
			
		||||
    "volume_limit",
 | 
			
		||||
    "volume_step",
 | 
			
		||||
    NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,10 +63,10 @@ struct userdata {
 | 
			
		|||
    char *sink_name;
 | 
			
		||||
    pa_module *module;
 | 
			
		||||
    float mute_toggle_save;
 | 
			
		||||
    pa_volume_t volume_limit;
 | 
			
		||||
    pa_volume_t volume_step;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DELTA (PA_VOLUME_NORM/20)
 | 
			
		||||
 | 
			
		||||
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
    char *name = NULL, *code = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +127,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
 | 
			
		|||
 | 
			
		||||
                    switch (volchange) {
 | 
			
		||||
                        case UP:
 | 
			
		||||
                            pa_cvolume_inc(&cv, DELTA);
 | 
			
		||||
                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
 | 
			
		||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case DOWN:
 | 
			
		||||
                            pa_cvolume_dec(&cv, DELTA);
 | 
			
		||||
                            pa_cvolume_dec(&cv, u->volume_step);
 | 
			
		||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,6 +172,8 @@ fail:
 | 
			
		|||
int pa__init(pa_module*m) {
 | 
			
		||||
    pa_modargs *ma = NULL;
 | 
			
		||||
    struct userdata *u;
 | 
			
		||||
    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
 | 
			
		||||
    pa_volume_t volume_step = PA_VOLUME_NORM/20;
 | 
			
		||||
 | 
			
		||||
    pa_assert(m);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -178,6 +182,16 @@ int pa__init(pa_module*m) {
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
 | 
			
		||||
        pa_log("Failed to parse volume limit");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
 | 
			
		||||
        pa_log("Failed to parse volume step");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
			
		||||
    u->module = m;
 | 
			
		||||
    u->io = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -185,6 +199,8 @@ int pa__init(pa_module*m) {
 | 
			
		|||
    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
			
		||||
    u->lirc_fd = -1;
 | 
			
		||||
    u->mute_toggle_save = 0;
 | 
			
		||||
    u->volume_limit = volume_limit;
 | 
			
		||||
    u->volume_step = volume_step;
 | 
			
		||||
 | 
			
		||||
    if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
 | 
			
		||||
        pa_log("lirc_init() failed.");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,13 +48,15 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 | 
			
		|||
PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");
 | 
			
		||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
			
		||||
PA_MODULE_LOAD_ONCE(FALSE);
 | 
			
		||||
PA_MODULE_USAGE("device=<evdev device> sink=<sink name>");
 | 
			
		||||
PA_MODULE_USAGE("device=<evdev device> sink=<sink name> volume_limit=<volume limit> volume_step=<volume change step>");
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_DEVICE "/dev/input/event0"
 | 
			
		||||
 | 
			
		||||
static const char* const valid_modargs[] = {
 | 
			
		||||
    "device",
 | 
			
		||||
    "sink",
 | 
			
		||||
    "volume_limit",
 | 
			
		||||
    "volume_step",
 | 
			
		||||
    NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,10 +65,10 @@ struct userdata {
 | 
			
		|||
    pa_io_event *io;
 | 
			
		||||
    char *sink_name;
 | 
			
		||||
    pa_module *module;
 | 
			
		||||
    pa_volume_t volume_limit;
 | 
			
		||||
    pa_volume_t volume_step;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DELTA (PA_VOLUME_NORM/20)
 | 
			
		||||
 | 
			
		||||
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
 | 
			
		||||
    struct userdata *u = userdata;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,12 +122,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
 | 
			
		|||
 | 
			
		||||
                    switch (volchange) {
 | 
			
		||||
                        case UP:
 | 
			
		||||
                            pa_cvolume_inc(&cv, DELTA);
 | 
			
		||||
                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
 | 
			
		||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case DOWN:
 | 
			
		||||
                            pa_cvolume_dec(&cv, DELTA);
 | 
			
		||||
                            pa_cvolume_dec(&cv, u->volume_step);
 | 
			
		||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +162,8 @@ int pa__init(pa_module*m) {
 | 
			
		|||
    struct input_id input_id;
 | 
			
		||||
    char name[256];
 | 
			
		||||
    uint8_t evtype_bitmask[EV_MAX/8 + 1];
 | 
			
		||||
    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
 | 
			
		||||
    pa_volume_t volume_step = PA_VOLUME_NORM/20;
 | 
			
		||||
 | 
			
		||||
    pa_assert(m);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -168,12 +172,24 @@ int pa__init(pa_module*m) {
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
 | 
			
		||||
        pa_log("Failed to parse volume limit");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
 | 
			
		||||
        pa_log("Failed to parse volume step");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
			
		||||
    u->module = m;
 | 
			
		||||
    u->io = NULL;
 | 
			
		||||
    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
			
		||||
    u->fd = -1;
 | 
			
		||||
    u->fd_type = 0;
 | 
			
		||||
    u->volume_limit = volume_limit;
 | 
			
		||||
    u->volume_step = volume_step;
 | 
			
		||||
 | 
			
		||||
    if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
 | 
			
		||||
        pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ typedef struct pa_ext_device_manager_role_priority_info {
 | 
			
		|||
} pa_ext_device_manager_role_priority_info;
 | 
			
		||||
 | 
			
		||||
/** Stores information about one device in the device database that is
 | 
			
		||||
 * maintained by module-device-manager. \since 0.9.19 */
 | 
			
		||||
 * maintained by module-device-manager. \since 0.9.20 */
 | 
			
		||||
typedef struct pa_ext_device_manager_info {
 | 
			
		||||
    const char *name;            /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */
 | 
			
		||||
    const char *description;     /**< The description of the device when it was last seen, if applicable and saved */
 | 
			
		||||
| 
						 | 
				
			
			@ -49,32 +49,32 @@ typedef struct pa_ext_device_manager_info {
 | 
			
		|||
    pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */
 | 
			
		||||
} pa_ext_device_manager_info;
 | 
			
		||||
 | 
			
		||||
/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.19 */
 | 
			
		||||
/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.20 */
 | 
			
		||||
typedef void (*pa_ext_device_manager_test_cb_t)(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        uint32_t version,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Test if this extension module is available in the server. \since 0.9.19 */
 | 
			
		||||
/** Test if this extension module is available in the server. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_test(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        pa_ext_device_manager_test_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.19 */
 | 
			
		||||
/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.20 */
 | 
			
		||||
typedef void (*pa_ext_device_manager_read_cb_t)(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        const pa_ext_device_manager_info *info,
 | 
			
		||||
        int eol,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Read all entries from the device database. \since 0.9.19 */
 | 
			
		||||
/** Read all entries from the device database. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_read(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        pa_ext_device_manager_read_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Sets the description for a device. \since 0.9.19 */
 | 
			
		||||
/** Sets the description for a device. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_set_device_description(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        const char* device,
 | 
			
		||||
| 
						 | 
				
			
			@ -82,21 +82,21 @@ pa_operation *pa_ext_device_manager_set_device_description(
 | 
			
		|||
        pa_context_success_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Delete entries from the device database. \since 0.9.19 */
 | 
			
		||||
/** Delete entries from the device database. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_delete(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        const char *const s[],
 | 
			
		||||
        pa_context_success_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Enable the role-based device-priority routing mode. \since 0.9.19 */
 | 
			
		||||
/** Enable the role-based device-priority routing mode. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        int enable,
 | 
			
		||||
        pa_context_success_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Prefer a given device in the priority list. \since 0.9.19 */
 | 
			
		||||
/** Prefer a given device in the priority list. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_reorder_devices_for_role(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        const char* role,
 | 
			
		||||
| 
						 | 
				
			
			@ -104,20 +104,20 @@ pa_operation *pa_ext_device_manager_reorder_devices_for_role(
 | 
			
		|||
        pa_context_success_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Subscribe to changes in the device database. \since 0.9.19 */
 | 
			
		||||
/** Subscribe to changes in the device database. \since 0.9.20 */
 | 
			
		||||
pa_operation *pa_ext_device_manager_subscribe(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        int enable,
 | 
			
		||||
        pa_context_success_cb_t cb,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.19 */
 | 
			
		||||
/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.20 */
 | 
			
		||||
typedef void (*pa_ext_device_manager_subscribe_cb_t)(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        void *userdata);
 | 
			
		||||
 | 
			
		||||
/** Set the subscription callback that is called when
 | 
			
		||||
 * pa_ext_device_manager_subscribe() was called. \since 0.9.19 */
 | 
			
		||||
 * pa_ext_device_manager_subscribe() was called. \since 0.9.20 */
 | 
			
		||||
void pa_ext_device_manager_set_subscribe_cb(
 | 
			
		||||
        pa_context *c,
 | 
			
		||||
        pa_ext_device_manager_subscribe_cb_t cb,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -885,7 +885,7 @@ pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvo
 | 
			
		|||
    return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
 | 
			
		||||
pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit) {
 | 
			
		||||
    pa_volume_t m;
 | 
			
		||||
 | 
			
		||||
    pa_assert(v);
 | 
			
		||||
| 
						 | 
				
			
			@ -895,14 +895,18 @@ pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
 | 
			
		|||
 | 
			
		||||
    m = pa_cvolume_max(v);
 | 
			
		||||
 | 
			
		||||
    if (m >= PA_VOLUME_MAX - inc)
 | 
			
		||||
        m = PA_VOLUME_MAX;
 | 
			
		||||
    if (m >= limit - inc)
 | 
			
		||||
        m = limit;
 | 
			
		||||
    else
 | 
			
		||||
        m += inc;
 | 
			
		||||
 | 
			
		||||
    return pa_cvolume_scale(v, m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc){
 | 
			
		||||
    return pa_cvolume_inc_clamp(v, inc, PA_VOLUME_MAX);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
 | 
			
		||||
    pa_volume_t m;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,6 +348,10 @@ pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, p
 | 
			
		|||
 * and dest may point to the same structure. \since 0.9.16 */
 | 
			
		||||
pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
 | 
			
		||||
 | 
			
		||||
/** Increase the volume passed in by 'inc', but not exceeding 'limit'.
 | 
			
		||||
 * The proportions between the channels are kept. \since 0.9.19 */
 | 
			
		||||
pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit);
 | 
			
		||||
 | 
			
		||||
/** Increase the volume passed in by 'inc'. The proportions between
 | 
			
		||||
 * the channels are kept. \since 0.9.16 */
 | 
			
		||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,7 @@
 | 
			
		|||
#include <pulsecore/strbuf.h>
 | 
			
		||||
#include <pulsecore/usergroup.h>
 | 
			
		||||
#include <pulsecore/strlist.h>
 | 
			
		||||
#include <pulsecore/cpu-x86.h>
 | 
			
		||||
 | 
			
		||||
#include "core-util.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2944,6 +2945,7 @@ int pa_pipe_cloexec(int pipefd[2]) {
 | 
			
		|||
 | 
			
		||||
    if (errno != EINVAL && errno != ENOSYS)
 | 
			
		||||
        return r;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if ((r = pipe(pipefd)) < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -2965,6 +2967,7 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
 | 
			
		|||
 | 
			
		||||
    if (errno != EINVAL && errno != ENOSYS)
 | 
			
		||||
        return fd;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if ((fd = accept(sockfd, addr, addrlen)) < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -3015,3 +3018,93 @@ void pa_nullify_stdfds(void) {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *pa_read_line_from_file(const char *fn) {
 | 
			
		||||
    FILE *f;
 | 
			
		||||
    char ln[256] = "", *r;
 | 
			
		||||
 | 
			
		||||
    if (!(f = pa_fopen_cloexec(fn, "r")))
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    r = fgets(ln, sizeof(ln)-1, f);
 | 
			
		||||
    fclose(f);
 | 
			
		||||
 | 
			
		||||
    if (!r) {
 | 
			
		||||
        errno = EIO;
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pa_strip_nl(ln);
 | 
			
		||||
    return pa_xstrdup(ln);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pa_bool_t pa_running_in_vm(void) {
 | 
			
		||||
 | 
			
		||||
#if defined(__i386__) || defined(__x86_64__)
 | 
			
		||||
 | 
			
		||||
    /* Both CPUID and DMI are x86 specific interfaces... */
 | 
			
		||||
 | 
			
		||||
    uint32_t eax = 0x40000000;
 | 
			
		||||
    union {
 | 
			
		||||
        uint32_t sig32[3];
 | 
			
		||||
        char text[13];
 | 
			
		||||
    } sig;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    const char *const dmi_vendors[] = {
 | 
			
		||||
        "/sys/class/dmi/id/sys_vendor",
 | 
			
		||||
        "/sys/class/dmi/id/board_vendor",
 | 
			
		||||
        "/sys/class/dmi/id/bios_vendor"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    unsigned i;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
 | 
			
		||||
        char *s;
 | 
			
		||||
 | 
			
		||||
        if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
 | 
			
		||||
 | 
			
		||||
            if (pa_startswith(s, "QEMU") ||
 | 
			
		||||
                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
 | 
			
		||||
                pa_startswith(s, "VMware") ||
 | 
			
		||||
                pa_startswith(s, "VMW") ||
 | 
			
		||||
                pa_startswith(s, "Microsoft Corporation") ||
 | 
			
		||||
                pa_startswith(s, "innotek GmbH") ||
 | 
			
		||||
                pa_startswith(s, "Xen")) {
 | 
			
		||||
 | 
			
		||||
                pa_xfree(s);
 | 
			
		||||
                return TRUE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pa_xfree(s);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* http://lwn.net/Articles/301888/ */
 | 
			
		||||
    pa_zero(sig);
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__ (
 | 
			
		||||
        /* ebx/rbx is being used for PIC! */
 | 
			
		||||
        "  push %%"PA_REG_b"         \n\t"
 | 
			
		||||
        "  cpuid                     \n\t"
 | 
			
		||||
        "  mov %%ebx, %1             \n\t"
 | 
			
		||||
        "  pop %%"PA_REG_b"          \n\t"
 | 
			
		||||
 | 
			
		||||
        : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
 | 
			
		||||
        : "0" (eax)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (pa_streq(sig.text, "XenVMMXenVMM") ||
 | 
			
		||||
        pa_streq(sig.text, "KVMKVMKVM") ||
 | 
			
		||||
        /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
 | 
			
		||||
        pa_streq(sig.text, "VMwareVMware") ||
 | 
			
		||||
        /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
 | 
			
		||||
        pa_streq(sig.text, "Microsoft Hv"))
 | 
			
		||||
        return TRUE;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -267,4 +267,7 @@ FILE* pa_fopen_cloexec(const char *path, const char *mode);
 | 
			
		|||
 | 
			
		||||
void pa_nullify_stdfds(void);
 | 
			
		||||
 | 
			
		||||
char *pa_read_line_from_file(const char *fn);
 | 
			
		||||
pa_bool_t pa_running_in_vm(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2631,7 +2631,7 @@ static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint3
 | 
			
		|||
    pa_tagstruct_put_usec(reply, s->current_monitor_latency);
 | 
			
		||||
    pa_tagstruct_put_usec(reply,
 | 
			
		||||
                          s->current_source_latency +
 | 
			
		||||
                          pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->sample_spec));
 | 
			
		||||
                          pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->source->sample_spec));
 | 
			
		||||
    pa_tagstruct_put_boolean(reply,
 | 
			
		||||
                             pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING &&
 | 
			
		||||
                             pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -717,14 +717,15 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 | 
			
		|||
                pa_memchunk rchunk;
 | 
			
		||||
                pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
 | 
			
		||||
 | 
			
		||||
/*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
 | 
			
		||||
 | 
			
		||||
                if (rchunk.memblock) {
 | 
			
		||||
 | 
			
		||||
                    if (nvfs) {
 | 
			
		||||
                        pa_memchunk_make_writable(&rchunk, 0);
 | 
			
		||||
                        pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
/*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
 | 
			
		||||
 | 
			
		||||
                if (rchunk.memblock) {
 | 
			
		||||
                    pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
 | 
			
		||||
                    pa_memblock_unref(rchunk.memblock);
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue